VOID ReadBigNum(BIGNUM*& pBigNum, UINT8*& p) { assert(pBigNum == NULL); pBigNum = NewBigNum(); UINT32 nBigNumSize = *(UINT32*)p; p += sizeof(UINT32); pBigNum->d = SDNew BN_ULONG[nBigNumSize]; memset(pBigNum->d, 0, sizeof(BN_ULONG) * nBigNumSize); memcpy(pBigNum->d, p, nBigNumSize * sizeof(BN_ULONG)); p += nBigNumSize * sizeof(BN_ULONG); pBigNum->top = *(INT32*)p; p += sizeof(INT32); pBigNum->dmax = *(INT32*)p; p += sizeof(INT32); pBigNum->neg = *(INT32*)p; p += sizeof(INT32); pBigNum->flags = *(INT32*)p; p += sizeof(INT32); }
VOID ReadBigNum(BIGNUM*& pBigNum, UINT8*& p, INT32 iNumSize ) { assert(pBigNum == NULL); pBigNum = NewBigNum(); if( iNumSize != 8 ) iNumSize = 4; UINT32 nBigNumSize = *(UINT32*)p; p += sizeof(UINT32); pBigNum->d = SDNew BN_ULONG[nBigNumSize]; memset(pBigNum->d, 0, sizeof(BN_ULONG) * nBigNumSize); if( iNumSize == 4 ) { UINT32* arrData = SDNew UINT32[nBigNumSize]; memset( arrData, 0, sizeof(UINT32) * nBigNumSize ); memcpy( arrData, p, nBigNumSize * 4 ); for( INT32 i = 0; i < (INT32)nBigNumSize; i ++ ) { pBigNum->d[i] = arrData[i]; } p += nBigNumSize * 4; delete [] arrData; } else { UINT64* arrData = SDNew UINT64[nBigNumSize]; memset( arrData, 0, sizeof(UINT64) * nBigNumSize ); memcpy( arrData, p, nBigNumSize * 8 ); for( INT32 i = 0; i < (INT32)nBigNumSize; i ++ ) { pBigNum->d[i] = (UINT32)arrData[i]; } p += nBigNumSize * 8; delete [] arrData; } pBigNum->top = *(INT32*)p; p += sizeof(INT32); pBigNum->dmax = *(INT32*)p; p += sizeof(INT32); pBigNum->neg = *(INT32*)p; p += sizeof(INT32); pBigNum->flags = *(INT32*)p; p += sizeof(INT32); }
BOOL GenerateRsaKey(INT32 nBit, RSA *pstPublicKey, RSA *pstPrivateKey) { RSA* pstRsa = RSA_generate_key(nBit, 65537, NULL, NULL); if(NULL == pstRsa) return false; //Copy Public Key pstPublicKey->n = NewBigNum(); CopyBigNum(pstPublicKey->n, pstRsa->n); pstPublicKey->e = NewBigNum(); CopyBigNum(pstPublicKey->e, pstRsa->e); pstPublicKey->d = NULL; pstPublicKey->p = NULL; pstPublicKey->q = NULL; pstPublicKey->dmp1 = NewBigNum(); CopyBigNum(pstPublicKey->dmp1, pstRsa->dmp1); pstPublicKey->dmq1 = NewBigNum(); CopyBigNum(pstPublicKey->dmq1, pstRsa->dmq1); //Copy Private Key pstPrivateKey->n = NewBigNum(); CopyBigNum(pstPrivateKey->n, pstRsa->n); pstPrivateKey->e = NewBigNum(); CopyBigNum(pstPrivateKey->e, pstRsa->e); pstPrivateKey->d = NewBigNum(); CopyBigNum(pstPrivateKey->d, pstRsa->d); pstPrivateKey->p = NewBigNum(); CopyBigNum(pstPrivateKey->p, pstRsa->p); pstPrivateKey->q = NewBigNum(); CopyBigNum(pstPrivateKey->q, pstRsa->q); pstPrivateKey->dmp1 = NewBigNum(); CopyBigNum(pstPrivateKey->dmp1, pstRsa->dmp1); pstPrivateKey->dmq1 = NewBigNum(); CopyBigNum(pstPrivateKey->dmq1, pstRsa->dmq1); RSA_free(pstRsa); return true; }
EpidStatus CreateEpid2Params(Epid2Params_** params) { EpidStatus result = kEpidErr; Epid2Params_* internal_param = NULL; BigNumStr t_str = {0}; Epid2Params params_str = { #include "epid/common/epid2params_ate.inc" }; if (!params) { return kEpidBadArgErr; } do { internal_param = SAFE_ALLOC(sizeof(Epid2Params_)); if (!internal_param) { result = kEpidMemAllocErr; break; } result = NewBigNum(sizeof(params_str.p), &internal_param->p); if (kEpidNoErr != result) { break; } result = ReadBigNum(¶ms_str.p, sizeof(params_str.p), internal_param->p); if (kEpidNoErr != result) { break; } result = NewBigNum(sizeof(params_str.q), &internal_param->q); if (kEpidNoErr != result) { break; } result = ReadBigNum(¶ms_str.q, sizeof(params_str.q), internal_param->q); if (kEpidNoErr != result) { break; } result = NewBigNum(sizeof(params_str.t), &internal_param->t); if (kEpidNoErr != result) { break; } result = ReadBigNum(¶ms_str.t, sizeof(params_str.t), internal_param->t); if (kEpidNoErr != result) { break; } internal_param->neg = (params_str.neg.data[0]) ? true : false; result = NewFp(¶ms_str, &internal_param->Fp); if (kEpidNoErr != result) { break; } result = NewFq(¶ms_str, &internal_param->Fq); if (kEpidNoErr != result) { break; } result = NewFq2(¶ms_str, internal_param->Fq, &internal_param->Fq2); if (kEpidNoErr != result) { break; } result = NewFfElement(internal_param->Fq2, &internal_param->xi); if (kEpidNoErr != result) { break; } result = ReadFfElement(internal_param->Fq2, ¶ms_str.xi, sizeof(params_str.xi), internal_param->xi); if (kEpidNoErr != result) { break; } result = NewFq6(¶ms_str, internal_param->Fq2, internal_param->xi, &internal_param->Fq6); if (kEpidNoErr != result) { break; } result = NewGT(internal_param->Fq6, &internal_param->GT); if (kEpidNoErr != result) { break; } result = NewG1(¶ms_str, internal_param->Fq, &internal_param->G1); if (kEpidNoErr != result) { break; } result = NewEcPoint(internal_param->G1, &internal_param->g1); if (kEpidNoErr != result) { break; } result = ReadEcPoint(internal_param->G1, ¶ms_str.g1, sizeof(params_str.g1), internal_param->g1); if (kEpidNoErr != result) { break; } result = NewG2(¶ms_str, internal_param->p, internal_param->q, internal_param->Fq, internal_param->Fq2, &internal_param->G2); if (kEpidNoErr != result) { break; } result = NewEcPoint(internal_param->G2, &internal_param->g2); if (kEpidNoErr != result) { break; } result = ReadEcPoint(internal_param->G2, ¶ms_str.g2, sizeof(params_str.g2), internal_param->g2); if (kEpidNoErr != result) { break; } result = WriteBigNum(internal_param->t, sizeof(t_str), &t_str); if (kEpidNoErr != result) { break; } result = NewPairingState(internal_param->G1, internal_param->G2, internal_param->GT, &t_str, internal_param->neg, &internal_param->pairing_state); if (kEpidNoErr != result) { break; } *params = internal_param; result = kEpidNoErr; } while (0); if (kEpidNoErr != result && internal_param) { DeletePairingState(&internal_param->pairing_state); DeleteEcPoint(&internal_param->g2); DeleteEcPoint(&internal_param->g1); DeleteBigNum(&internal_param->p); DeleteBigNum(&internal_param->q); DeleteBigNum(&internal_param->t); DeleteFp(&internal_param->Fp); DeleteFq(&internal_param->Fq); DeleteFq2(&internal_param->Fq2); DeleteFq6(&internal_param->Fq6); DeleteGT(&internal_param->GT); DeleteG1(&internal_param->G1); DeleteG2(&internal_param->G2); SAFE_FREE(internal_param); } return result; }
EpidStatus NewG2(Epid2Params const* param, BigNum* p, BigNum* q, FiniteField* Fq, FiniteField* Fq2, EcGroup** G2) { EpidStatus result = kEpidErr; EcGroup* ec = NULL; FfElement* a = NULL; FfElement* b = NULL; FfElement* fq_param_b = NULL; FfElement* x = NULL; FfElement* y = NULL; BigNum* order = NULL; BigNum* cofactor = NULL; if (!param || !Fq || !Fq2 || !G2) { return kEpidBadArgErr; } do { // 2. Set xi = (xi0, xi1) an element of Fq2. // 3. Let b', xi' be a temporary variable in Fq2. // 4. Compute xi' = Fq2.inverse(xi). // 5. Compute b' = Fq2.mul(xi', b). result = NewFfElement(Fq2, &b); if (kEpidNoErr != result) { break; } result = ReadFfElement(Fq2, ¶m->xi, sizeof(param->xi), b); if (kEpidNoErr != result) { break; } result = FfInv(Fq2, b, b); if (kEpidNoErr != result) { break; } result = NewFfElement(Fq, &fq_param_b); if (kEpidNoErr != result) { break; } result = ReadFfElement(Fq, ¶m->b, sizeof(param->b), fq_param_b); if (kEpidNoErr != result) { break; } result = FfMul(Fq2, b, fq_param_b, b); // ??? overflow fq2*fq if (kEpidNoErr != result) { break; } // 6. Set g2.x = (g2.x[0], g2.x[1]) an element of Fq2. // 7. Set g2.y = (g2.y[0], g2.y[1]) an element of Fq2. result = NewFfElement(Fq2, &x); if (kEpidNoErr != result) { break; } result = ReadFfElement(Fq2, ¶m->g2.x, sizeof(param->g2.x), x); if (kEpidNoErr != result) { break; } result = NewFfElement(Fq2, &y); if (kEpidNoErr != result) { break; } result = ReadFfElement(Fq2, ¶m->g2.y, sizeof(param->g2.y), y); if (kEpidNoErr != result) { break; } // 8. set h = 2q - p, aka cofactor result = NewBigNum(2 * sizeof(param->q), &cofactor); if (kEpidNoErr != result) { break; } result = BigNumAdd(q, q, cofactor); if (kEpidNoErr != result) { break; } result = BigNumSub(cofactor, p, cofactor); if (kEpidNoErr != result) { break; } // 9. set n = p * h, AKA order result = NewBigNum(2 * sizeof(param->q), &order); if (kEpidNoErr != result) { break; } result = BigNumMul(p, cofactor, order); if (kEpidNoErr != result) { break; } // set a to identity, NewFfElement does it by default result = NewFfElement(Fq2, &a); if (kEpidNoErr != result) { break; } // 10. Set G2 = E(Fq2).init(p, param(Fq2), n, h, 0, b', g2.x, g2.y) result = NewEcGroup(Fq2, a, b, x, y, order, cofactor, &ec); if (kEpidNoErr != result) { break; } *G2 = ec; result = kEpidNoErr; } while (0); DeleteBigNum(&cofactor); DeleteBigNum(&order); DeleteFfElement(&y); DeleteFfElement(&x); DeleteFfElement(&b); DeleteFfElement(&a); DeleteFfElement(&fq_param_b); return result; }
EpidStatus NewG1(Epid2Params const* param, FiniteField* Fq, EcGroup** G1) { EpidStatus result = kEpidErr; EcGroup* ec = NULL; FfElement* fq_a = NULL; FfElement* fq_b = NULL; FfElement* g1_x = NULL; FfElement* g1_y = NULL; BigNum* order = NULL; BigNum* cofactor = NULL; // h = 1; const BigNumStr h1 = { {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}}}; if (!param || !Fq || !G1) { return kEpidBadArgErr; } do { // Create G1 // G1 is an elliptic curve group E(Fq).It can be initialized as follows : // 1. Set G1 = E(Fq).init(p, q, n = p, h = 1, a = 0, b, g1.x, g1.y). // a = 0 // NewFfelement is Identidy result = NewFfElement(Fq, &fq_a); if (kEpidNoErr != result) { break; } // b result = NewFfElement(Fq, &fq_b); if (kEpidNoErr != result) { break; } result = ReadFfElement(Fq, ¶m->b, sizeof(param->b), fq_b); if (kEpidNoErr != result) { break; } // g1.x result = NewFfElement(Fq, &g1_x); if (kEpidNoErr != result) { break; } result = ReadFfElement(Fq, ¶m->g1.x, sizeof(param->g1.x), g1_x); if (kEpidNoErr != result) { break; } // g1.y result = NewFfElement(Fq, &g1_y); if (kEpidNoErr != result) { break; } result = ReadFfElement(Fq, ¶m->g1.y, sizeof(param->g1.y), g1_y); if (kEpidNoErr != result) { break; } // order result = NewBigNum(sizeof(BigNumStr), &order); if (kEpidNoErr != result) { break; } result = ReadBigNum(¶m->p, sizeof(param->p), order); if (kEpidNoErr != result) { break; } // cofactor result = NewBigNum(sizeof(BigNumStr), &cofactor); if (kEpidNoErr != result) { break; } result = ReadBigNum(&h1, sizeof(h1), cofactor); if (kEpidNoErr != result) { break; } result = NewEcGroup(Fq, fq_a, fq_b, g1_x, g1_y, order, cofactor, &ec); if (kEpidNoErr != result) { break; } *G1 = ec; result = kEpidNoErr; } while (0); DeleteBigNum(&cofactor); DeleteBigNum(&order); DeleteFfElement(&g1_y); DeleteFfElement(&g1_x); DeleteFfElement(&fq_b); DeleteFfElement(&fq_a); return result; }
BOOL GenerateRsaKey(INT32 nBit, RSAKEY *pPublicKey, RSAKEY *pPrivateKey) { RSA* pstPublicKey = RSA_new(); RSA* pstPrivateKey = RSA_new(); *pPublicKey = pstPublicKey; *pPrivateKey = pstPrivateKey; RSA* pstRsa = RSA_generate_key(nBit, 65537, NULL, NULL); if(NULL == pstRsa) { return FALSE; } //Copy Public Key pstPublicKey->n = NewBigNum(); CopyBigNum(pstPublicKey->n, pstRsa->n); pstPublicKey->e = NewBigNum(); CopyBigNum(pstPublicKey->e, pstRsa->e); pstPublicKey->d = NULL; pstPublicKey->p = NULL; pstPublicKey->q = NULL; pstPublicKey->dmp1 = NewBigNum(); CopyBigNum(pstPublicKey->dmp1, pstRsa->dmp1); pstPublicKey->dmq1 = NewBigNum(); CopyBigNum(pstPublicKey->dmq1, pstRsa->dmq1); //Copy Private Key pstPrivateKey->n = NewBigNum(); CopyBigNum(pstPrivateKey->n, pstRsa->n); pstPrivateKey->e = NewBigNum(); CopyBigNum(pstPrivateKey->e, pstRsa->e); pstPrivateKey->d = NewBigNum(); CopyBigNum(pstPrivateKey->d, pstRsa->d); pstPrivateKey->p = NewBigNum(); CopyBigNum(pstPrivateKey->p, pstRsa->p); pstPrivateKey->q = NewBigNum(); CopyBigNum(pstPrivateKey->q, pstRsa->q); pstPrivateKey->dmp1 = NewBigNum(); CopyBigNum(pstPrivateKey->dmp1, pstRsa->dmp1); pstPrivateKey->dmq1 = NewBigNum(); CopyBigNum(pstPrivateKey->dmq1, pstRsa->dmq1); RSA_free(pstRsa); return TRUE; }
EpidStatus EcdsaSignBuffer(void const* buf, size_t buf_len, EcdsaPrivateKey const* privkey, BitSupplier rnd_func, void* rnd_param, EcdsaSignature* sig) { EpidStatus result = kEpidMathErr; IppsECCPState* ec_ctx = NULL; BigNum* bn_ec_order = NULL; BigNum* bn_hash = NULL; BigNum* bn_reg_private = NULL; BigNum* bn_eph_private = NULL; IppsECCPPointState* ecp_eph_public = NULL; BigNum* bn_sig_x = NULL; BigNum* bn_sig_y = NULL; do { EpidStatus epid_status = kEpidNoErr; IppStatus sts = ippStsNoErr; int ctxsize = 0; // order of EC secp256r1 const uint8_t secp256r1_r[32] = { 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84, 0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51}; Ipp8u hash[IPP_SHA256_DIGEST_BITSIZE / 8] = {0}; unsigned int gen_loop_count = EPHKEYGEN_WATCHDOG; Ipp32u cmp0 = IS_ZERO; Ipp32u cmp_order = IS_ZERO; if ((0 != buf_len && !buf) || !privkey || !rnd_func || !sig) { result = kEpidBadArgErr; break; } if (buf_len > INT_MAX) { result = kEpidBadArgErr; break; } // Define standard elliptic curve secp256r1 sts = ippsECCPGetSizeStd256r1(&ctxsize); if (ippStsNoErr != sts) break; ec_ctx = (IppsECCPState*)SAFE_ALLOC(ctxsize); if (!ec_ctx) { result = kEpidMemAllocErr; break; } sts = ippsECCPInitStd256r1(ec_ctx); if (ippStsNoErr != sts) break; sts = ippsECCPSetStd256r1(ec_ctx); if (ippStsNoErr != sts) break; // Create big number for order of elliptic curve secp256r1 epid_status = NewBigNum(sizeof(secp256r1_r), &bn_ec_order); if (kEpidMemAllocErr == epid_status) { result = kEpidMemAllocErr; break; } if (kEpidNoErr != epid_status) break; epid_status = ReadBigNum(secp256r1_r, sizeof(secp256r1_r), bn_ec_order); if (kEpidNoErr != epid_status) break; // Calculate hash for input message sts = ippsSHA256MessageDigest(buf, (int)buf_len, hash); if (ippStsNoErr != sts) break; // Create big number for hash epid_status = NewBigNum(sizeof(hash), &bn_hash); if (kEpidMemAllocErr == epid_status) { result = kEpidMemAllocErr; break; } if (kEpidNoErr != epid_status) break; epid_status = ReadBigNum(hash, sizeof(hash), bn_hash); if (kEpidNoErr != epid_status) break; sts = ippsMod_BN(bn_hash->ipp_bn, bn_ec_order->ipp_bn, bn_hash->ipp_bn); if (ippStsNoErr != sts) break; // Create big number for regular private key epid_status = NewBigNum(sizeof(*privkey), &bn_reg_private); if (kEpidMemAllocErr == epid_status) { result = kEpidMemAllocErr; break; } if (kEpidNoErr != epid_status) break; epid_status = ReadBigNum(privkey, sizeof(*privkey), bn_reg_private); if (kEpidNoErr != epid_status) break; // Validate private key is in range [1, bn_ec_order-1] sts = ippsCmpZero_BN(bn_reg_private->ipp_bn, &cmp0); if (ippStsNoErr != sts) break; sts = ippsCmp_BN(bn_reg_private->ipp_bn, bn_ec_order->ipp_bn, &cmp_order); if (ippStsNoErr != sts) break; if (IS_ZERO == cmp0 || LESS_THAN_ZERO != cmp_order) { result = kEpidBadArgErr; break; } // Create big number for ephemeral private key epid_status = NewBigNum(sizeof(secp256r1_r), &bn_eph_private); if (kEpidMemAllocErr == epid_status) { result = kEpidMemAllocErr; break; } if (kEpidNoErr != epid_status) break; // Create EC point for ephemeral public key sts = ippsECCPPointGetSize(256, &ctxsize); if (ippStsNoErr != sts) break; ecp_eph_public = (IppsECCPPointState*)SAFE_ALLOC(ctxsize); if (!ecp_eph_public) { result = kEpidMemAllocErr; break; } sts = ippsECCPPointInit(256, ecp_eph_public); if (ippStsNoErr != sts) break; // Create big numbers for signature epid_status = NewBigNum(sizeof(secp256r1_r), &bn_sig_x); if (kEpidMemAllocErr == epid_status) { result = kEpidMemAllocErr; break; } if (kEpidNoErr != epid_status) break; epid_status = NewBigNum(sizeof(secp256r1_r), &bn_sig_y); if (kEpidMemAllocErr == epid_status) { result = kEpidMemAllocErr; break; } if (kEpidNoErr != epid_status) break; do { // Generate ephemeral key pair sts = ippsECCPGenKeyPair(bn_eph_private->ipp_bn, ecp_eph_public, ec_ctx, (IppBitSupplier)rnd_func, rnd_param); if (ippStsNoErr != sts) break; // Set ephemeral key pair sts = ippsECCPSetKeyPair(bn_eph_private->ipp_bn, ecp_eph_public, ippFalse, ec_ctx); if (ippStsNoErr != sts) break; // Compute signature sts = ippsECCPSignDSA(bn_hash->ipp_bn, bn_reg_private->ipp_bn, bn_sig_x->ipp_bn, bn_sig_y->ipp_bn, ec_ctx); if (ippStsEphemeralKeyErr != sts) break; } while (--gen_loop_count); if (ippStsEphemeralKeyErr == sts) { result = kEpidRandMaxIterErr; break; } if (ippStsNoErr != sts) break; sts = ippsGetOctString_BN(sig->x.data, sizeof(sig->x), bn_sig_x->ipp_bn); if (ippStsNoErr != sts) break; sts = ippsGetOctString_BN(sig->y.data, sizeof(sig->y), bn_sig_y->ipp_bn); if (ippStsNoErr != sts) break; result = kEpidNoErr; } while (0); DeleteBigNum(&bn_ec_order); DeleteBigNum(&bn_hash); DeleteBigNum(&bn_reg_private); DeleteBigNum(&bn_eph_private); DeleteBigNum(&bn_sig_x); DeleteBigNum(&bn_sig_y); SAFE_FREE(ec_ctx); SAFE_FREE(ecp_eph_public); return result; }