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;
}
예제 #3
0
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;
}
예제 #4
0
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;
}
예제 #6
0
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;
}