uintptr_t _EINIT(secs_t* secs, enclave_css_t *css, token_t *launch) { CEnclaveMngr *mngr = CEnclaveMngr::get_instance(); assert(mngr != NULL); CEnclaveSim* ce = mngr->get_enclave(secs); GP_ON(ce == NULL); GP_ON((ce->get_secs()->attributes.flags & SGX_FLAGS_INITTED) != 0); // Fill MREnclave, MRSigner, ISVPRODID, ISVSVN secs_t* this_secs = ce->get_secs(); if (css != NULL) { // Check signature if ((css->body.attribute_mask.xfrm & this_secs->attributes.xfrm) != (css->body.attribute_mask.xfrm & css->body.attributes.xfrm)) { SE_TRACE(SE_TRACE_DEBUG, "SECS attributes.xfrm does NOT match signature attributes.xfrm\n"); return SGX_ERROR_INVALID_ATTRIBUTE; } if ((css->body.attribute_mask.flags & this_secs->attributes.flags) != (css->body.attribute_mask.flags & css->body.attributes.flags)) { SE_TRACE(SE_TRACE_DEBUG, "SECS attributes.flag does NOT match signature attributes.flag\n"); return SGX_ERROR_INVALID_ATTRIBUTE; } mcp_same_size(&this_secs->mr_enclave, &css->body.enclave_hash, sizeof(sgx_measurement_t)); this_secs->isv_prod_id = css->body.isv_prod_id; this_secs->isv_svn = css->body.isv_svn; ippsHashMessage(css->key.modulus, SE_KEY_SIZE, (Ipp8u*)&this_secs->mr_signer, IPP_ALG_HASH_SHA256); } // Check launch token if (launch != NULL && launch->body.valid) { if (memcmp(&launch->body.attributes, &this_secs->attributes, sizeof(sgx_attributes_t))) { SE_TRACE(SE_TRACE_DEBUG, "SECS attributes does NOT match launch token attribuets\n"); return SGX_ERROR_INVALID_ATTRIBUTE; } } // Mark it initialized this_secs->attributes.flags |= SGX_FLAGS_INITTED; return SGX_SUCCESS; }
/* SHA Hashing functions * Parameters: * Return: sgx_status_t - SGX_SUCCESS or failure as defined sgx_error.h * Inputs: uint8_t *p_src - Pointer to input stream to be hashed * uint32_t src_len - Length of input stream to be hashed * Output: sgx_sha256_hash_t *p_hash - Resultant hash from operation */ sgx_status_t sgx_sha256_msg(const uint8_t *p_src, uint32_t src_len, sgx_sha256_hash_t *p_hash) { if ((p_src == NULL) || (p_hash == NULL)) { return SGX_ERROR_INVALID_PARAMETER; } IppStatus ipp_ret = ippStsNoErr; ipp_ret = ippsHashMessage((const Ipp8u *) p_src, src_len, (Ipp8u *)p_hash, IPP_ALG_HASH_SHA256); switch (ipp_ret) { case ippStsNoErr: return SGX_SUCCESS; case ippStsMemAllocErr: return SGX_ERROR_OUT_OF_MEMORY; case ippStsNullPtrErr: case ippStsLengthErr: return SGX_ERROR_INVALID_PARAMETER; default: return SGX_ERROR_UNEXPECTED; } }
/* 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; } }