Ejemplo n.º 1
0
/* Populates private/public key pair - caller code allocates memory
* Parameters:
*   Return: sgx_status_t  - SGX_SUCCESS or failure as defined sgx_error.h
*   Inputs: sgx_ecc_state_handle_t ecc_handle - Handle to ECC crypto system
*   Outputs: sgx_ec256_private_t *p_private - Pointer to the private key
*            sgx_ec256_public_t *p_public - Pointer to the public key  */
sgx_status_t sgx_ecc256_create_key_pair(sgx_ec256_private_t *p_private,
    sgx_ec256_public_t *p_public,
    sgx_ecc_state_handle_t ecc_handle)
{
    if ((ecc_handle == NULL) || (p_private == NULL) || (p_public == NULL))
    {
        return SGX_ERROR_INVALID_PARAMETER;
    }

    IppsBigNumState*    dh_priv_BN = NULL;
    IppsECCPPointState* point_pub = NULL;
    IppsBigNumState*    pub_gx = NULL;
    IppsBigNumState*    pub_gy = NULL;
    IppStatus           ipp_ret = ippStsNoErr;
    int                 ecPointSize = 0;
    IppsECCPState* p_ecc_state = (IppsECCPState*)ecc_handle;

    do
    {
        //init eccp point
        ipp_ret = ippsECCPPointGetSize(256, &ecPointSize);
        ERROR_BREAK(ipp_ret);
        point_pub = (IppsECCPPointState*)(malloc(ecPointSize));
        if (!point_pub)
        {
            ipp_ret = ippStsNoMemErr;
            break;
        }
        ipp_ret = ippsECCPPointInit(256, point_pub);
        ERROR_BREAK(ipp_ret);

        ipp_ret = sgx_ipp_newBN(NULL, SGX_ECP256_KEY_SIZE, &dh_priv_BN);
        ERROR_BREAK(ipp_ret);
        // Use the true random number (DRNG)
        // Notice that IPP ensures the private key generated is non-zero
        ipp_ret = ippsECCPGenKeyPair(dh_priv_BN, point_pub, p_ecc_state, (IppBitSupplier)sgx_ipp_DRNGen, NULL);
        ERROR_BREAK(ipp_ret);

        //convert point_result to oct string
        ipp_ret = sgx_ipp_newBN(NULL, SGX_ECP256_KEY_SIZE, &pub_gx);
        ERROR_BREAK(ipp_ret);
        ipp_ret = sgx_ipp_newBN(NULL, SGX_ECP256_KEY_SIZE, &pub_gy);
        ERROR_BREAK(ipp_ret);
        ipp_ret = ippsECCPGetPoint(pub_gx, pub_gy, point_pub, p_ecc_state);
        ERROR_BREAK(ipp_ret);

        IppsBigNumSGN sgn = IppsBigNumPOS;
        Ipp32u *pdata = NULL;
        // ippsRef_BN is in bits not bytes (versus old ippsGet_BN)
        int length = 0;
        ipp_ret = ippsRef_BN(&sgn, &length, &pdata, pub_gx);
        ERROR_BREAK(ipp_ret);
        memset(p_public->gx, 0, sizeof(p_public->gx));
        ipp_ret = check_copy_size(sizeof(p_public->gx), ROUND_TO(length, 8) / 8);
        ERROR_BREAK(ipp_ret);
        memcpy(p_public->gx, pdata, ROUND_TO(length, 8) / 8);
        ipp_ret = ippsRef_BN(&sgn, &length, &pdata, pub_gy);
        ERROR_BREAK(ipp_ret);
        memset(p_public->gy, 0, sizeof(p_public->gy));
        ipp_ret = check_copy_size(sizeof(p_public->gy), ROUND_TO(length, 8) / 8);
        ERROR_BREAK(ipp_ret);
        memcpy(p_public->gy, pdata, ROUND_TO(length, 8) / 8);
        ipp_ret = ippsRef_BN(&sgn, &length, &pdata, dh_priv_BN);
        ERROR_BREAK(ipp_ret);
        memset(p_private->r, 0, sizeof(p_private->r));
        ipp_ret = check_copy_size(sizeof(p_private->r), ROUND_TO(length, 8) / 8);
        ERROR_BREAK(ipp_ret);
        memcpy(p_private->r, pdata, ROUND_TO(length, 8) / 8);
    } while (0);

    //Clear temp buffer before free.
    if (point_pub) memset_s(point_pub, ecPointSize, 0, ecPointSize);
    SAFE_FREE(point_pub);
    sgx_ipp_secure_free_BN(pub_gx, SGX_ECP256_KEY_SIZE);
    sgx_ipp_secure_free_BN(pub_gy, SGX_ECP256_KEY_SIZE);
    sgx_ipp_secure_free_BN(dh_priv_BN, SGX_ECP256_KEY_SIZE);

    switch (ipp_ret)
    {
    case ippStsNoErr: return SGX_SUCCESS;
    case ippStsNoMemErr:
    case ippStsMemAllocErr: return SGX_ERROR_OUT_OF_MEMORY;
    case ippStsNullPtrErr:
    case ippStsLengthErr:
    case ippStsOutOfRangeErr:
    case ippStsSizeErr:
    case ippStsBadArgErr: return SGX_ERROR_INVALID_PARAMETER;
    default: return SGX_ERROR_UNEXPECTED;
    }
}
Ejemplo n.º 2
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;
}