IppsBigNumState* bnNew(const char* sBN, const int size){
	// get the size of the Big Number context
	int ctxSize;
	const int strSize = (const int)(strlen(sBN)+7)/8;
	if ( strSize > size ){
		std::cerr << "Caution in IppsBigNumState* bnNew(const char* sBN, int size):\n\t size of string number representation greater then params size supplied\n";
		std::cerr << sBN << std::endl;
	}
	IppStatus res; 
	res = ippsBigNumGetSize(size, &ctxSize);
	if (res != ippStsNoErr )
		std::cerr << res;
	// allocate the Big Number context
	IppsBigNumState* pBN = (IppsBigNumState*) ( new Ipp8u[ctxSize] );
	// and initialize one
	res = ippsBigNumInit(size, pBN);
	if (res != ippStsNoErr )
		std::cerr << res;

	Ipp8u* octetStr = new Ipp8u[(strlen(sBN)-1)/2+1+1];
	strtoIpp8u( sBN, octetStr);
	res = ippsSetOctString_BN(octetStr, (int)(strlen(sBN)-1)/2+1, pBN);	
	if (res != ippStsNoErr )
		std::cerr << res;
	delete[] octetStr;
	// return pointer to the Big Number context for future use
	return pBN;
}
Exemplo n.º 2
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;
}
IppsBigNumState* bnNew(const int size, const Ipp8u *pData){
	// get the size of the Big Number context
	int ctxSize;
	IppStatus res; 
	res = ippsBigNumGetSize(size, &ctxSize);
	if (res != ippStsNoErr )
		std::cerr << res;
	// allocate the Big Number context
	IppsBigNumState* pBN = (IppsBigNumState*) ( new Ipp8u[ctxSize] );
	// and initialize one
	res = ippsBigNumInit(size, pBN);
	if (res != ippStsNoErr )
		std::cerr << res;

	res = ippsSetOctString_BN(pData, 4*size, pBN);	
	if (res != ippStsNoErr )
		std::cerr << res;
	// return pointer to the Big Number context for future use
	return pBN;
}
Exemplo n.º 4
0
/** Create an ECC public key based on a given ECC private key.
*
* Parameters:
*   Return: sgx_status_t - SGX_SUCCESS or failure as defined in sgx_error.h
*   Input: p_att_priv_key - Input private key
*   Output: p_att_pub_key - Output public key - LITTLE ENDIAN
*
*/
sgx_status_t sgx_ecc256_calculate_pub_from_priv(const sgx_ec256_private_t *p_att_priv_key, sgx_ec256_public_t  *p_att_pub_key)
{
    if ((p_att_priv_key == NULL) || (p_att_pub_key == NULL)) {
        return SGX_ERROR_INVALID_PARAMETER;
    }

    IppsECCPState* p_ecc_state = NULL;
    sgx_status_t ret = SGX_ERROR_UNEXPECTED;
    int ctx_size = 0;
    int point_size = 0;
    IppsECCPPointState* public_key = NULL;
    IppsBigNumState*    bn_o = NULL;
    IppsBigNumState*    bn_x = NULL;
    IppsBigNumState*    bn_y = NULL;
    sgx_ec256_private_t att_priv_key_be;
    uint8_t* p_temp;
    int size = 0;
    IppsBigNumSGN sgn;

    do {
        //get the size of the IppsECCPState context
        //
        if (ippsECCPGetSize(ECC_FIELD_SIZE, &ctx_size) != ippStsNoErr) {
            break;
        }

        //allocate ecc ctx
        //
        p_ecc_state = (IppsECCPState*)(malloc(ctx_size));
        if (NULL == p_ecc_state) {
            ret = SGX_ERROR_OUT_OF_MEMORY;
            break;
        }

        //init ecc ctx
        //
        if (ippsECCPInit(ECC_FIELD_SIZE, p_ecc_state) != ippStsNoErr) {
            break;
        }

        //set up elliptic curve domain parameters over GF(p)
        //
        if (ippsECCPSetStd(IppECCPStd256r1, p_ecc_state) != ippStsNoErr) {
            break;
        }

        //get point (public key) size
        //
        if (ippsECCPPointGetSize(ECC_FIELD_SIZE, &point_size) != ippStsNoErr) {
            break;
        }

        //allocate point of point_size size
        //
        public_key = (IppsECCPPointState*)(malloc(point_size));
        if (NULL == public_key) {
            ret = SGX_ERROR_OUT_OF_MEMORY;
            break;
        }

        //init point
        //
        if (ippsECCPPointInit(ECC_FIELD_SIZE, public_key) != ippStsNoErr) {
            break;
        }

        //allocate bn_o, will be used for private key
        //
        if (sgx_ipp_newBN(NULL, sizeof(sgx_ec256_private_t), &bn_o) != ippStsNoErr) {
            break;
        }

        //convert private key into big endian
        //
        p_temp = (uint8_t*)p_att_priv_key;
        for (uint32_t i = 0; i<sizeof(att_priv_key_be); i++) {
            att_priv_key_be.r[i] = *(p_temp + sizeof(att_priv_key_be) - 1 - i);
        }

        //assign private key into bn_o
        //
        if (ippsSetOctString_BN(reinterpret_cast<Ipp8u *>(&att_priv_key_be), sizeof(sgx_ec256_private_t), bn_o) != ippStsNoErr) {
            break;
        }

        //compute public key from the given private key (bn_o) of the elliptic cryptosystem (p_ecc_state) over GF(p).
        //
        if (ippsECCPPublicKey(bn_o, public_key, p_ecc_state) != ippStsNoErr) {
            break;
        }

        //allocate BNs
        //
        if (sgx_ipp_newBN(NULL, sizeof(sgx_ec256_private_t), &bn_x) != ippStsNoErr) {
            break;
        }

        if (sgx_ipp_newBN(NULL, sizeof(sgx_ec256_private_t), &bn_y) != ippStsNoErr) {
            break;
        }
        //assign public key into BNs
        //
        if (ippsECCPGetPoint(bn_x, bn_y, public_key, p_ecc_state) != ippStsNoErr) {
            break;
        }

        //output key in little endian order
        //
        //gx value
        if (ippsGetSize_BN(bn_x, &size) != ippStsNoErr) {
            break;
        }
        if (ippsGet_BN(&sgn, &size, reinterpret_cast<Ipp32u *>(p_att_pub_key->gx), bn_x) != ippStsNoErr) {
            break;
        }
        //gy value
        //
        if (ippsGetSize_BN(bn_y, &size) != ippStsNoErr) {
            break;
        }
        if (ippsGet_BN(&sgn, &size, reinterpret_cast<Ipp32u *>(p_att_pub_key->gy), bn_y) != ippStsNoErr) {
            break;
        }

        ret = SGX_SUCCESS;
    } while (0);

    //in case of failure clear public key
    //
    if (ret != SGX_SUCCESS) {
        (void)memset_s(p_att_pub_key, sizeof(sgx_ec256_public_t), 0, sizeof(sgx_ec256_public_t));
    }

    CLEAR_FREE_MEM(p_ecc_state, ctx_size);
    CLEAR_FREE_MEM(public_key, point_size);
    sgx_ipp_secure_free_BN(bn_o, sizeof(sgx_ec256_private_t));
    sgx_ipp_secure_free_BN(bn_x, sizeof(sgx_ec256_private_t));
    sgx_ipp_secure_free_BN(bn_y, sizeof(sgx_ec256_private_t));

    return ret;
}
Exemplo n.º 5
0
/* Computes signature for data based on private key
* Parameters:
*   Return: sample_status_t - SAMPLE_SUCCESS, SAMPLE_SUCCESS on success, error code otherwise.
*   Inputs: sample_ecc_state_handle_t ecc_handle - Handle to ECC crypto system
*           sample_ec256_private_t *p_private - Pointer to the private key - LITTLE ENDIAN
*           sample_uint8_t *p_data - Pointer to the data to be signed
*           uint32_t data_size - Size of the data to be signed
*   Output: sample_ec256_signature_t *p_signature - Pointer to the signature - LITTLE ENDIAN  */
sample_status_t sample_ecdsa_sign(const uint8_t *p_data,
                            uint32_t data_size,
                            sample_ec256_private_t *p_private,
                            sample_ec256_signature_t *p_signature,
                            sample_ecc_state_handle_t ecc_handle)
{
    if ((ecc_handle == NULL) || (p_private == NULL) || (p_signature == NULL) || (p_data == NULL) || (data_size < 1))
    {
        return SAMPLE_ERROR_INVALID_PARAMETER;
    }

    IppStatus ipp_ret = ippStsNoErr;
    IppsECCPState* p_ecc_state = (IppsECCPState*)ecc_handle;
    IppsBigNumState* p_ecp_order = NULL;
    IppsBigNumState* p_hash_bn = NULL;
    IppsBigNumState* p_msg_bn = NULL;
    IppsBigNumState* p_eph_priv_bn = NULL;
    IppsECCPPointState* p_eph_pub = NULL;
    IppsBigNumState* p_reg_priv_bn = NULL;
    IppsBigNumState* p_signx_bn = NULL;
    IppsBigNumState* p_signy_bn = NULL;
    Ipp32u *p_sigx = NULL;
    Ipp32u *p_sigy = NULL;
    int ecp_size = 0;
    const int order_size = sizeof(sample_nistp256_r);
    uint32_t hash[8] = {0};

    do
    {

        ipp_ret = sgx_ipp_newBN(sample_nistp256_r, order_size, &p_ecp_order);
        ERROR_BREAK(ipp_ret);

        // Prepare the message used to sign.
        ipp_ret = ippsHashMessage(p_data, data_size, (Ipp8u*)hash, IPP_ALG_HASH_SHA256);
        ERROR_BREAK(ipp_ret);
        /* Byte swap in creation of Big Number from SHA256 hash output */
        ipp_ret = sgx_ipp_newBN(NULL, sizeof(hash), &p_hash_bn);
        ERROR_BREAK(ipp_ret);
        ipp_ret = ippsSetOctString_BN((Ipp8u*)hash, sizeof(hash), p_hash_bn);
        ERROR_BREAK(ipp_ret);

        ipp_ret = sgx_ipp_newBN(NULL, order_size, &p_msg_bn);
        ERROR_BREAK(ipp_ret);
        ipp_ret = ippsMod_BN(p_hash_bn, p_ecp_order, p_msg_bn);
        ERROR_BREAK(ipp_ret);

        // Get ephemeral key pair.
        ipp_ret = sgx_ipp_newBN(NULL, order_size, &p_eph_priv_bn);
        ERROR_BREAK(ipp_ret);
        //init eccp point
        ipp_ret = ippsECCPPointGetSize(256, &ecp_size);
        ERROR_BREAK(ipp_ret);
        p_eph_pub = (IppsECCPPointState*)(malloc(ecp_size));
        if(!p_eph_pub)
        {
            ipp_ret = ippStsNoMemErr;
            break;
        }
        ipp_ret = ippsECCPPointInit(256, p_eph_pub);
        ERROR_BREAK(ipp_ret);
        // generate ephemeral key pair for signing operation
        ipp_ret = ippsECCPGenKeyPair(p_eph_priv_bn, p_eph_pub, p_ecc_state,
            (IppBitSupplier)sample_ipp_DRNGen, NULL);
        ERROR_BREAK(ipp_ret);
        ipp_ret = ippsECCPSetKeyPair(p_eph_priv_bn, p_eph_pub, ippFalse, p_ecc_state);
        ERROR_BREAK(ipp_ret);

        // Set the regular private key.
        ipp_ret = sgx_ipp_newBN((uint32_t *)p_private->r, sizeof(p_private->r),
            &p_reg_priv_bn);
        ERROR_BREAK(ipp_ret);
        ipp_ret = sgx_ipp_newBN(NULL, order_size, &p_signx_bn);
        ERROR_BREAK(ipp_ret);
        ipp_ret = sgx_ipp_newBN(NULL, order_size, &p_signy_bn);
        ERROR_BREAK(ipp_ret);

        // Sign the message.
        ipp_ret = ippsECCPSignDSA(p_msg_bn, p_reg_priv_bn, p_signx_bn, p_signy_bn,
            p_ecc_state);
        ERROR_BREAK(ipp_ret);

        IppsBigNumSGN sign;
        int length;
        ipp_ret = ippsRef_BN(&sign, &length,(Ipp32u**) &p_sigx, p_signx_bn);
        ERROR_BREAK(ipp_ret);
        memset(p_signature->x, 0, sizeof(p_signature->x));
        ipp_ret = check_copy_size(sizeof(p_signature->x), ROUND_TO(length, 8)/8);
        ERROR_BREAK(ipp_ret);
        memcpy(p_signature->x, p_sigx, ROUND_TO(length, 8)/8);
        memset_s(p_sigx, sizeof(p_signature->x), 0, ROUND_TO(length, 8)/8);
        ipp_ret = ippsRef_BN(&sign, &length,(Ipp32u**) &p_sigy, p_signy_bn);
        ERROR_BREAK(ipp_ret);
        memset(p_signature->y, 0, sizeof(p_signature->y));
        ipp_ret = check_copy_size(sizeof(p_signature->y), ROUND_TO(length, 8)/8);
        ERROR_BREAK(ipp_ret);
        memcpy(p_signature->y, p_sigy, ROUND_TO(length, 8)/8);
        memset_s(p_sigy, sizeof(p_signature->y), 0, ROUND_TO(length, 8)/8);        

    }while(0);

    // Clear buffer before free.
    if(p_eph_pub)
        memset_s(p_eph_pub, ecp_size, 0, ecp_size);
    SAFE_FREE(p_eph_pub);
    sample_ipp_secure_free_BN(p_ecp_order, order_size);
    sample_ipp_secure_free_BN(p_hash_bn, sizeof(hash));
    sample_ipp_secure_free_BN(p_msg_bn, order_size);
    sample_ipp_secure_free_BN(p_eph_priv_bn, order_size);
    sample_ipp_secure_free_BN(p_reg_priv_bn, sizeof(p_private->r));
    sample_ipp_secure_free_BN(p_signx_bn, order_size);
    sample_ipp_secure_free_BN(p_signy_bn, order_size);

    switch (ipp_ret)
    {
    case ippStsNoErr: return SAMPLE_SUCCESS;
    case ippStsNoMemErr:
    case ippStsMemAllocErr: return SAMPLE_ERROR_OUT_OF_MEMORY;
    case ippStsNullPtrErr:
    case ippStsLengthErr:
    case ippStsOutOfRangeErr:
    case ippStsSizeErr:
    case ippStsBadArgErr: return SAMPLE_ERROR_INVALID_PARAMETER;
    default: return SAMPLE_ERROR_UNEXPECTED;
    }
}
void bnSet( IppsBigNumState *pBN, const char * sBN){
	Ipp8u* octetStr = new Ipp8u[strlen(sBN)/2];
	strtoIpp8u( sBN, octetStr);
	ippsSetOctString_BN(octetStr, (int)strlen(sBN)/2, pBN);
	delete[] octetStr;
}