bool bnConvertToString ( const IppsBigNumState *pBN, char* sBN ){ // size of Big Number int size; Ipp32u res = ippsGetSize_BN(pBN, &size); if ( res != ippStsNoErr ) std::cerr << res << std::endl; // extract Big Number value and convert it to the string presentation Ipp8u* bnValue = new Ipp8u [size*4+4]; res = ippsGetOctString_BN(bnValue, size*4, pBN); if ( res != ippStsNoErr ){ std::cerr << res << std::endl; return false; } // save representation for(int i=0; i<size*4; i++){ static char xlat[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; sBN[2*i] = xlat[(bnValue[i]&0xF0) >> 4]; sBN[2*i+1] = xlat[bnValue[i]&0x0F]; } sBN[2*size*4] = '\0'; delete[] bnValue; return true; }
void bnGet(const IppsBigNumState* pBN, BYTE* pBuf, const int iBufSize){ int iLocalBufSize = iBufSize; Ipp32u res = ippsGetOctString_BN( pBuf, iLocalBufSize, pBN ); if ( res != ippStsNoErr ) std::cerr << "bnGet: ippsGetOctString_BN return following value - " << res << std::endl; }
static int GenerateSing(const Ipp8u* pMsg, int msgLen, /* message representation */ const Ipp8u* pSalt, int saltLen, /* fied string */ Ipp8u* pSign, const IppsRSAPrivateKeyState* pPrvKey, const IppsRSAPublicKeyState* pPubKey, Ipp8u* pBuffer) { /* size of RSA modulus in bytes and chunks */ cpSize rsaBits = RSA_PRV_KEY_BITSIZE_N(pPrvKey); cpSize k = BITS2WORD8_SIZE(rsaBits); cpSize nsN = BITS_BNU_CHUNK(rsaBits); /* EMSA-PKCS-v1_5 encoding */ int result = EMSA_PKCSv15(pMsg,msgLen, pSalt,saltLen, pSign, k); if(result) { /* align buffer */ BNU_CHUNK_T* pScratchBuffer = (BNU_CHUNK_T*)(IPP_ALIGNED_PTR(pBuffer, (int)sizeof(BNU_CHUNK_T)) ); /* temporary BNs */ __ALIGN8 IppsBigNumState bnC; __ALIGN8 IppsBigNumState bnP; /* make BNs */ BN_Make(pScratchBuffer, pScratchBuffer+nsN+1, nsN, &bnC); pScratchBuffer += (nsN+1)*2; BN_Make(pScratchBuffer, pScratchBuffer+nsN+1, nsN, &bnP); pScratchBuffer += (nsN+1)*2; /* // private-key operation */ ippsSetOctString_BN(pSign, k, &bnC); if(RSA_PRV_KEY1_VALID_ID(pPrvKey)) gsRSAprv_cipher(&bnP, &bnC, pPrvKey, pScratchBuffer); else gsRSAprv_cipher_crt(&bnP, &bnC, pPrvKey, pScratchBuffer); ippsGetOctString_BN(pSign, k, &bnP); /* check the result before send it out (fault attack mitigatioin) */ if(pPubKey) { gsRSApub_cipher(&bnP, &bnP, pPubKey, pScratchBuffer); /* check signature before send it out (fault attack mitigatioin) */ if(0!=cpBN_cmp(&bnP, &bnC)) { PaddBlock(0, pSign, k); result = 0; } } } return result; }
void PrintBigNum(BigNum const* big_num, char const* var_name) { IppStatus sts = ippStsNoErr; unsigned char* buf = NULL; int ipp_word_buf_size; if (!var_name) { var_name = "<no name>"; } PRINT("%s (BigNum):\n", var_name); if (!big_num) { MAKE_INDENT(); PRINT("<null>\n"); return; } if (!big_num->ipp_bn) { MAKE_INDENT(); PRINT("<invalid>\n"); return; } sts = ippsGetSize_BN(big_num->ipp_bn, &ipp_word_buf_size); if (ippStsNoErr != sts) { MAKE_INDENT(); PRINT("<invalid>\n"); return; } do { buf = SAFE_ALLOC(ipp_word_buf_size * sizeof(Ipp32u)); if (!buf) { MAKE_INDENT(); PRINT("<invalid>\n"); break; } sts = ippsGetOctString_BN((Ipp8u*)buf, ipp_word_buf_size * sizeof(Ipp32u), big_num->ipp_bn); if (ippStsNoErr != sts) { MAKE_INDENT(); PRINT("<invalid>\n"); break; } if (0 != PrintBuf((const void*)buf, ipp_word_buf_size * sizeof(Ipp32u))) { MAKE_INDENT(); PRINT("<invalid>\n"); break; } } while (0); SAFE_FREE(buf); }
std::ostream& operator<<(std::ostream& os, const IppsBigNumState* pBN){ // size of Big Number int size; Ipp32u res = ippsGetSize_BN(pBN, &size); if ( res != ippStsNoErr ) std::cerr << res << std::endl; // extract Big Number value and convert it to the string presentation Ipp8u* bnValue = new Ipp8u [size*4+4]; res = ippsGetOctString_BN(bnValue, size*4, pBN); if ( res != ippStsNoErr ) std::cerr << res << std::endl; // type value for(int i=0; i<size*4; i++) os<< std::setfill('0') << std::setw(2) << std::hex <<(int)bnValue[i]; delete[] bnValue; return os; }
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; }