extern "C" sgx_status_t sgx_ra_get_ga( sgx_ra_context_t context, sgx_ec256_public_t *g_a) { sgx_status_t se_ret; if(vector_size(&g_ra_db) <= context||!g_a) return SGX_ERROR_INVALID_PARAMETER; ra_db_item_t* item = NULL; if(0 != vector_get(&g_ra_db, context, reinterpret_cast<void**>(&item)) || item == NULL ) return SGX_ERROR_INVALID_PARAMETER; sgx_ecc_state_handle_t ecc_state = NULL; sgx_ec256_public_t pub_key; sgx_ec256_private_t priv_key; memset(&pub_key, 0, sizeof(pub_key)); memset(&priv_key, 0, sizeof(priv_key)); sgx_spin_lock(&item->item_lock); do { //sgx_ra_init must have been called if (item->state != ra_inited) { se_ret = SGX_ERROR_INVALID_STATE; break; } // ecc_state should be closed when exit. se_ret = sgx_ecc256_open_context(&ecc_state); if (SGX_SUCCESS != se_ret) { if(SGX_ERROR_OUT_OF_MEMORY != se_ret) se_ret = SGX_ERROR_UNEXPECTED; break; } se_ret = sgx_ecc256_create_key_pair(&priv_key, &pub_key, ecc_state); if (SGX_SUCCESS != se_ret) { if(SGX_ERROR_OUT_OF_MEMORY != se_ret) se_ret = SGX_ERROR_UNEXPECTED; break; } memcpy(&item->a, &priv_key, sizeof(item->a)); memcpy(&item->g_a, &pub_key, sizeof(item->g_a)); memcpy(g_a, &pub_key, sizeof(sgx_ec256_public_t)); item->state = ra_get_gaed; //clear local private key to defense in depth memset_s(&priv_key,sizeof(priv_key),0,sizeof(sgx_ec256_private_t)); }while(0); sgx_spin_unlock(&item->item_lock); if(ecc_state!=NULL) sgx_ecc256_close_context(ecc_state); return se_ret; }
ae_error_t prepare_for_certificate_provisioning ( /*in */ UINT64 nonce64, /*in */ const sgx_target_info_t* pTargetInfo, /*in */ UINT16 nMax_CSR_pse, /*out*/ UINT8* pCSR_pse, /*out*/ UINT16* pnLen_CSR_pse, /*out*/ sgx_report_t* pREPORT, /*i/o*/ pairing_blob_t* pPairingBlob ) { // Flow: 1) Check pointers for buffer data sizes // 2) If buffers are too small, return and tell caller size required // 3) Validate pointers and ensure buffers are within the enclave // 4) Generate a new private/public ECDSA key pair // 5) Request signed CSR template // 6) Calculate HASH_pse of (CSR_pse || nonce64) // 7) Generate REPORT with HASH_pse as the REPORTDATA, targeting QE // 8) Copy private key and public key into unsealed_pairing buffer // 9) Seal pairing blob // 10) Return Sealed pairing blob, generated CSR, REPORT, and status ae_error_t status = AE_FAILURE; pairing_data_t pairingData; EcDsaPrivKey privateKey; EcDsaPubKey publicKey; uint8_t temp_instance_id[16]; SignCSR CSR; size_t nMaxSizeCSR = CSR.GetMaxSize(); sgx_ecc_state_handle_t csr_ecc_handle = NULL; memset(&pairingData, 0, sizeof(pairingData)); ///////////////////////////////////////////////////////////////// do { //********************************************************************* // Validate pointers and sizes //********************************************************************* BREAK_IF_TRUE((NULL == pPairingBlob), status, PSE_PR_BAD_POINTER_ERROR); // save SW_INSTANCE_ID memcpy(temp_instance_id, pPairingBlob->plaintext.pse_instance_id, sizeof(temp_instance_id)); { BREAK_IF_TRUE((NULL == pTargetInfo), status, PSE_PR_BAD_POINTER_ERROR); BREAK_IF_TRUE((NULL == pREPORT), status, PSE_PR_BAD_POINTER_ERROR); BREAK_IF_TRUE((NULL == pCSR_pse || NULL == pnLen_CSR_pse), status, PSE_PR_BAD_POINTER_ERROR); BREAK_IF_TRUE((nMax_CSR_pse < nMaxSizeCSR), status, PSE_PR_PARAMETER_ERROR); BREAK_IF_FALSE(sgx_is_within_enclave(pCSR_pse, nMaxSizeCSR), status, PSE_PR_BAD_POINTER_ERROR); //********************************************************************* // Generate a new ECDSA Key Pair //********************************************************************* sgx_status_t sgx_status = sgx_ecc256_open_context(&csr_ecc_handle); BREAK_IF_TRUE((SGX_ERROR_OUT_OF_MEMORY == sgx_status), status, PSE_PR_INSUFFICIENT_MEMORY_ERROR); BREAK_IF_TRUE((SGX_SUCCESS != sgx_status), status, PSE_PR_KEY_PAIR_GENERATION_ERROR); sgx_status = sgx_ecc256_create_key_pair((sgx_ec256_private_t *)privateKey, (sgx_ec256_public_t*)publicKey, csr_ecc_handle); BREAK_IF_TRUE((SGX_SUCCESS != sgx_status), status, PSE_PR_KEY_PAIR_GENERATION_ERROR); *pnLen_CSR_pse = (uint16_t)nMaxSizeCSR; //********************************************************************* // Get a signed Certificate Signing Request from the template //********************************************************************* status = CSR.GetSignedTemplate(&privateKey, &publicKey, csr_ecc_handle, pCSR_pse, pnLen_CSR_pse); BREAK_IF_FAILED(status); //********************************************************************* // Calculate HASH_pse of (CSR_pse || nonce64) //********************************************************************* PrepareHashSHA256 hash; SHA256_HASH computedHash; status = hash.Update(pCSR_pse, *pnLen_CSR_pse); BREAK_IF_FAILED(status); status = hash.Update(&nonce64, sizeof(nonce64)); BREAK_IF_FAILED(status); status = hash.Finalize(&computedHash); BREAK_IF_FAILED(status); //********************************************************************* // Generate a REPORT with HASH_pse //********************************************************************* sgx_report_data_t report_data = {{0}}; memcpy(&report_data, &computedHash, sizeof(computedHash)); if (SGX_SUCCESS != sgx_create_report(const_cast<sgx_target_info_t*>(pTargetInfo), &report_data, (sgx_report_t*)pREPORT)) { status = PSE_PR_CREATE_REPORT_ERROR; break; } //********************************************************************* // Try to unseal the pairing data //********************************************************************* status = UnsealPairingBlob(pPairingBlob, &pairingData); if (AE_FAILED(status)) memset_s(&pairingData, sizeof(pairingData), 0, sizeof(pairingData)); //********************************************************************* // Seal ECDSA Verifier Private Key into blob //********************************************************************* memcpy(pairingData.secret_data.VerifierPrivateKey, &privateKey, sizeof(EcDsaPrivKey)); } // "Public" PSE Cert // Set pairingData.plaintext.pse_instance_id using saved temp_instance_id memcpy(pairingData.plaintext.pse_instance_id, temp_instance_id, sizeof(pairingData.plaintext.pse_instance_id)); status = SealPairingBlob(&pairingData, pPairingBlob); BREAK_IF_FAILED(status); //********************************************************************* // WE PASSED ALL BARRIERS TO SUCCESS //********************************************************************* status = AE_SUCCESS; // OutputOctets("::tPrepareForCertificateProvisioning:: New CSR generated", NULL, 0); } while (false); // Defense-in-depth: clear the data on stack that contains enclave secret. memset_s(&pairingData, sizeof(pairingData), 0, sizeof(pairingData)); memset_s(&privateKey, sizeof(privateKey), 0, sizeof(privateKey)); if (csr_ecc_handle != NULL) sgx_ecc256_close_context(csr_ecc_handle); return map_error_for_return(status); }