/***************************************************************************** * @ingroup IKE_RSA * * @description * This function frees all the dynamically allocated memory used in the * ikeRsaPerform * Each pointer is checked to see if its null and if not it is free'd, * The underlying free function ensures that when freeing the pointer is reset * to NULL ******************************************************************************/ static void ikeRsaMemFree(asym_test_params_t* setup, ike_rsa_client_data_t* alice, ike_rsa_client_data_t* bob, CpaCyRsaPrivateKey *pPrivateKey[], CpaCyRsaPublicKey *pPublicKey[] ) { rsaFreeDataMemory(setup, alice->ppDecryptOpData, alice->ppSignatures, alice->ppEncryptOpData, alice->ppPVverifier); rsaFreeKeyMemory(setup, pPrivateKey, pPublicKey); rsaFreeDataMemory(setup, bob->ppDecryptOpData, bob->ppSignatures, bob->ppEncryptOpData, bob->ppPVverifier); rsaFreeDataMemory(setup, NULL, NULL, bob->ppEncryptOpData2, bob->ppPVverifier2); rsaFreeDataMemory(setup, NULL, NULL, alice->ppEncryptOpData2, alice->ppPVverifier2); /*free the signature pointer arrays because in RSA code this is allocated * as a local variable*/ ikeRsaMemFreeRsaData(alice); ikeRsaMemFreeRsaData(bob); dhMemFreePh1(setup, alice->ppPhase1, alice->ppPublicValues, bob->ppPhase1, bob->ppPublicValues); dhMemFreePh2(setup, alice->ppSecretKeys, alice->ppPhase2, bob->ppSecretKeys, bob->ppPhase2); if (NULL != pPrivateKey) { qaeMemFreeNUMA((void**)&pPrivateKey); } if (NULL != pPublicKey) { qaeMemFreeNUMA((void**)&pPublicKey); } }
/** ***************************************************************************** * @ingroup dsaPerformance * * @description * free all memory used in DSA performance code in this file * *****************************************************************************/ void freeDsaMem(dsa_test_params_t* setup, CpaFlatBuffer* dsaX, CpaFlatBuffer* dsaY, CpaFlatBuffer* dsaK, CpaFlatBuffer* dsaM, CpaFlatBuffer* dsaZ, CpaFlatBuffer* dsaR, CpaFlatBuffer* dsaS, CpaCyDsaVerifyOpData* verifyOpData, CpaFlatBuffer dsaG, CpaFlatBuffer dsaP, CpaFlatBuffer dsaH, CpaFlatBuffer dsaQ) { freeArrayFlatBufferNUMA(dsaX, setup->numBuffers); freeArrayFlatBufferNUMA(dsaY, setup->numBuffers); freeArrayFlatBufferNUMA(dsaK, setup->numBuffers); freeArrayFlatBufferNUMA(dsaM, setup->numBuffers); freeArrayFlatBufferNUMA(dsaZ, setup->numBuffers); freeArrayFlatBufferNUMA(dsaR, setup->numBuffers); freeArrayFlatBufferNUMA(dsaS, setup->numBuffers); qaeMemFree((void**)&verifyOpData); /*free the normal flatBuffer pData */ qaeMemFreeNUMA((void**)&dsaG.pData); qaeMemFreeNUMA((void**)&dsaP.pData); qaeMemFreeNUMA((void**)&dsaH.pData); qaeMemFreeNUMA((void**)&dsaQ.pData); }
void qaeCryptoMemFree(void *ptr) { int rc; MEM_DEBUG("%s: Address: %p\n", __func__, ptr); if (NULL == ptr) { MEM_WARN("qaeCryptoMemFree trying to free NULL pointer.\n"); return; } MEM_DEBUG("%s: pthread_mutex_lock\n", __func__); if ((rc = pthread_mutex_lock(&mem_mutex)) != 0) { MEM_ERROR("pthread_mutex_lock: %s\n", strerror(rc)); return; } qaeMemFreeNUMA(&ptr); if ((rc = pthread_mutex_unlock(&mem_mutex)) != 0) { MEM_ERROR("pthread_mutex_unlock: %s\n", strerror(rc)); return; } MEM_DEBUG("%s: pthread_mutex_unlock\n", __func__); }
/***************************************************************************** * @ingroup IKE_RSA * * @description * This function is free an array of operation data structures for * ikersa operations, any memory allocation is freed in * ikeRsaPerform ******************************************************************************/ static void ikeRsaMemFreeRsaData(ike_rsa_client_data_t* client) { if(NULL != client) { if(NULL != client->ppSignatures) { qaeMemFreeNUMA((void**)&client->ppSignatures); } if(NULL != client->ppDecryptOpData) { qaeMemFreeNUMA((void**)&client->ppDecryptOpData); } if(NULL != client->ppEncryptOpData) { qaeMemFreeNUMA((void**)&client->ppEncryptOpData); } if(NULL != client->ppPVverifier) { qaeMemFreeNUMA((void**)&client->ppPVverifier); } if(NULL != client->ppEncryptOpData2) { qaeMemFreeNUMA((void**)&client->ppEncryptOpData2); } if(NULL != client->ppPVverifier2) { qaeMemFreeNUMA((void**)&client->ppPVverifier2); } } }
/***************************************************************************** * @ingroup IKE_RSA * * @description * This function sets up the QA API asymmetric functions of an IKE * transaction using RSA to sign/verify DH generated keys ******************************************************************************/ static CpaStatus ikeRsaPerform(asym_test_params_t* setup) { CpaStatus status = CPA_STATUS_SUCCESS; Cpa32U i = 0; Cpa32U innerLoop = 0; ike_rsa_client_data_t alice = {0}; ike_rsa_client_data_t bob = {0}; CpaCyRsaPrivateKey **pPrivateKey = NULL; CpaCyRsaPublicKey **pPublicKey = NULL; Cpa32U node = 0; /*functions called in this code over writes the performanceStats->response, * so we use a local counter to count responses */ Cpa32U responses = 0; status = sampleCodeCyGetNode(setup->cyInstanceHandle, &node); if(CPA_STATUS_SUCCESS != status) { PRINT_ERR("sampleCodeCyGetNode failed with status %u\n", status); return status; } /************************************************************************/ /* Allocate all the memory for DH and RSA operations */ /************************************************************************/ /*these macros internally free memory return fail if they fail*/ status = allocArrayOfPointers( setup->cyInstanceHandle, (void**)&pPrivateKey, setup->numBuffers); if(CPA_STATUS_SUCCESS != status) { return CPA_STATUS_FAIL; } status = allocArrayOfPointers( setup->cyInstanceHandle, (void**)&pPublicKey, setup->numBuffers); if(CPA_STATUS_SUCCESS != status) { qaeMemFreeNUMA((void**)&pPrivateKey); return CPA_STATUS_FAIL; } /*Allocate for Alice*/ if(CPA_STATUS_SUCCESS != allocClientMem(setup, &alice)) { PRINT_ERR("allocClientMem error\n"); ikeRsaMemFree(setup, &alice, &bob, pPrivateKey, pPublicKey); return CPA_STATUS_FAIL; } /*Allocate for Bob*/ if(CPA_STATUS_SUCCESS != allocClientMem(setup, &bob)) { PRINT_ERR("allocClientMem error\n"); ikeRsaMemFree(setup, &alice, &bob, pPrivateKey, pPublicKey); return CPA_STATUS_FAIL; } /* ************************************************************************* * STEP 1. Alice & Bob generate public & private RSA keys * ************************************************************************/ status = genKeyArray(setup, pPrivateKey, pPublicKey); if(status != CPA_STATUS_SUCCESS) { PRINT_ERR("Error, failed genKeyArray, status: %d\n", status); ikeRsaMemFree(setup, &alice, &bob, pPrivateKey, pPublicKey); return status; } /************************************************************************** * STEP 2. Alice & Bob agree on a p & g and generate secret random x **************************************************************************/ status = dhPhase1Setup(setup, alice.ppPhase1, bob.ppPhase1, alice.ppPublicValues, bob.ppPublicValues, pPublicKey); if(status != CPA_STATUS_SUCCESS) { PRINT_ERR("Error, failed dhPhase1Setup, status: %d\n", status); ikeRsaMemFree(setup, &alice, &bob, pPrivateKey, pPublicKey); return status; } /************************************************************************** * STEP 3. Alice & Bob Perform DH Phase1 to produce Public Value - * PV = g^x mod p **************************************************************************/ status = dhPhase1(alice.ppPhase1, alice.ppPublicValues, setup, setup->numBuffers, ONE_LOOP); if(status !=CPA_STATUS_SUCCESS) { PRINT_ERR("Error, failed to complete dhPhase1 for Alice, status: %d\n", status); ikeRsaMemFree(setup, &alice, &bob, pPrivateKey, pPublicKey); return status; } /**************************************************************************/ /*Perform DH phase1 for Bob */ /**************************************************************************/ status = dhPhase1(bob.ppPhase1,bob.ppPublicValues, setup, setup->numBuffers, ONE_LOOP); if(CPA_STATUS_SUCCESS != status) { PRINT_ERR("Error, failed to complete dhPhase1 for Bob, status: %d\n", status); ikeRsaMemFree(setup, &alice, &bob, pPrivateKey, pPublicKey); return status; } /**************************************************************************/ /*Perform Phase2 setup for Bob */ /**************************************************************************/ status = dhPhase2Setup(bob.ppSecretKeys, bob.ppPhase1, bob.ppPhase2, alice.ppPublicValues, setup); if(CPA_STATUS_SUCCESS != status) { PRINT_ERR("Error, failed to setup phase2 for Bob, status: %d\n", status); ikeRsaMemFree(setup, &alice, &bob, pPrivateKey, pPublicKey); return status; } /**************************************************************************/ /*Calculate Bobs secret keys */ /**************************************************************************/ status = dhPhase2Perform(bob.ppSecretKeys, bob.ppPhase2, setup, setup->numBuffers, ONE_LOOP); if(CPA_STATUS_SUCCESS != status) { PRINT_ERR("Error, failed to perform phase2 for Bob, status: %d\n", status); ikeRsaMemFree(setup, &alice, &bob, pPrivateKey, pPublicKey); return status; } /*************************************************************************** * STEP 5. Sign Bobs Public Value using peers public key -> * Bobs Signature = RSA decrypt bobsPV * ************************************************************************/ /**************************************************************************/ /*Setup the RSA decrypt structure */ /**************************************************************************/ status = rsaDecryptDataSetup(bob.ppPublicValues, bob.ppDecryptOpData, bob.ppSignatures, setup); if(CPA_STATUS_SUCCESS != status) { PRINT_ERR("Error, failed rsaDecryptDataSetup for Bob, status: %d\n", status); ikeRsaMemFree(setup, &alice, &bob, pPrivateKey, pPublicKey); return status; } /************************************************************************** * setup encryption, we need an encryptOpData structure, because the * rsaSetOpDataKeys generates a public key and needs to copy it into * an encryptOpData structure **************************************************************************/ status = rsaEncryptDataSetup(bob.ppSignatures, bob.ppEncryptOpData, bob.ppPVverifier, setup); if(CPA_STATUS_SUCCESS != status) { PRINT_ERR("Error, failed rsaEncryptDataSetup for Bob, status: %d\n", status); ikeRsaMemFree(setup, &alice, &bob, pPrivateKey, pPublicKey); return status; } status = rsaEncryptDataSetup(bob.ppSignatures, bob.ppEncryptOpData2, bob.ppPVverifier2, setup); if(CPA_STATUS_SUCCESS != status) { PRINT_ERR("Error, failed rsaEncryptDataSetup for Bob, status: %d\n", status); ikeRsaMemFree(setup, &alice, &bob, pPrivateKey, pPublicKey); return status; } /**************************************************************************/ /* Setup decryption opData structure with RSA key */ /**************************************************************************/ rsaSetOpDataKeys(setup, bob.ppDecryptOpData, bob.ppEncryptOpData, pPrivateKey,pPublicKey); rsaSetOpDataKeys(setup, bob.ppDecryptOpData, bob.ppEncryptOpData2, pPrivateKey,pPublicKey); /**************************************************************************/ /* Sign all of Bobs public value buffers, but loop only once */ /**************************************************************************/ status = sampleRsaDecrypt(setup, bob.ppDecryptOpData, bob.ppSignatures, setup->numBuffers, ONE_LOOP); if(CPA_STATUS_SUCCESS != status) { PRINT_ERR("Error, failed sampleRsaDecrypt for Bob, status: %d\n", status); ikeRsaMemFree(setup, &alice, &bob, pPrivateKey, pPublicKey); return status; } /* Copy the RSADecrypt output into the Encrypt Op structure * in the performance loop we verify bobs signature. Bobs signature is * the input the the encrypt operation*/ for(i=0;i<setup->numBuffers;i++) { /*check that the signature is the expected length*/ if(bob.ppEncryptOpData[i]->inputData.dataLenInBytes != bob.ppSignatures[i]->dataLenInBytes) { PRINT_ERR("encrypt data len does not match the signature len\n"); ikeRsaMemFree(setup, &alice, &bob, pPrivateKey, pPublicKey); return status; } memcpy(bob.ppEncryptOpData[i]->inputData.pData, bob.ppSignatures[i]->pData, bob.ppEncryptOpData[i]->inputData.dataLenInBytes); /*check that the signature is the expected length*/ if(bob.ppEncryptOpData2[i]->inputData.dataLenInBytes != bob.ppSignatures[i]->dataLenInBytes) { PRINT_ERR("encrypt data len does not match the signature len\n"); ikeRsaMemFree(setup, &alice, &bob, pPrivateKey, pPublicKey); return status; } memcpy(bob.ppEncryptOpData2[i]->inputData.pData, bob.ppSignatures[i]->pData, bob.ppEncryptOpData2[i]->inputData.dataLenInBytes); } /*************************************************************************** * STEP 6. Setup Alices Decrypt and Diffie Hellman Data for performance Loop * ************************************************************************/ /**************************************************************************/ /* Setup the RSA decrypt structure*/ /**************************************************************************/ status = rsaDecryptDataSetup(alice.ppPublicValues, alice.ppDecryptOpData, alice.ppSignatures, setup); if(CPA_STATUS_SUCCESS != status) { PRINT_ERR("Error, failed rsaDecryptDataSetup for Alice, status: %d\n", status); ikeRsaMemFree(setup, &alice, &bob, pPrivateKey, pPublicKey); return CPA_STATUS_FAIL; } /************************************************************************** * Setup encryption: we need an encryptOpData structure, because the * rsaSetOpDataKeys generates a public key and needs to copy it into * an encryptOpData structure **************************************************************************/ status = rsaEncryptDataSetup(alice.ppSignatures, alice.ppEncryptOpData, alice.ppPVverifier, setup); if(CPA_STATUS_SUCCESS != status) { PRINT_ERR("Error, failed rsaEncryptDataSetup for Alice, status: %d\n", status); ikeRsaMemFree(setup, &alice, &bob, pPrivateKey, pPublicKey); return CPA_STATUS_FAIL; } /**************************************************************************/ /*setup decryption opData structure with RSA key */ /**************************************************************************/ rsaSetOpDataKeys(setup, alice.ppDecryptOpData, alice.ppEncryptOpData, pPrivateKey,pPublicKey); /**************************************************************************/ /* Perform Phase2 setup for Alice */ /**************************************************************************/ status = dhPhase2Setup(alice.ppSecretKeys, alice.ppPhase1, alice.ppPhase2, bob.ppPVverifier, setup); if(CPA_STATUS_SUCCESS != status) { PRINT_ERR("Error, failed to setup phase2 for Alice, status: %d\n", status); ikeRsaMemFree(setup, &alice, &bob, pPrivateKey, pPublicKey); return status; } /*************************************************************************** * STEP 7 IKE main mode Asymmetric steps **************************************************************************/ if(CPA_STATUS_SUCCESS != status) { PRINT_ERR("Error, failed to allcate ppPVverifier2, status: %d\n", status); ikeRsaMemFree(setup, &alice, &bob, pPrivateKey, pPublicKey); return status; } /*this barrier will wait until all threads get to this point*/ sampleCodeBarrier(); memset(setup->performanceStats,0, sizeof(perf_data_t)); setup->performanceStats->startCyclesTimestamp = sampleCodeTimestamp(); /*pre-set the number of ops we plan to submit*/ /*number of responses equals the number of QA APIs we have chained together * multiplied by the number of buffers and how many times we have looped * over the buffers */ setup->performanceStats->numOperations = (Cpa64U)NUMBER_OF_CHAINED_OPS * setup->numBuffers * setup->numLoops; setup->performanceStats->averagePacketSizeInBytes = setup->modulusSizeInBytes; setup->performanceStats->responses=0; /* Completion used in callback */ sampleCodeSemaphoreInit(&setup->performanceStats->comp, 0); for(i = 0; i < setup->numLoops; i++) { for(innerLoop = 0; innerLoop < setup->numBuffers; innerLoop++) { /******************************************************************/ /* Step 7a Perform DH phase1 for Alice * This step, performs setup->NumBuffers DH Phase1 Operations to * Calculate setup->numBuffers Public Values for Alice*/ /******************************************************************/ do { /*****************************************************************/ /* ikeRsaCallback : used in asynchronous mode * performanceStats: Opaque user data * ppPhase1 : Structure containing p, g and x * ppPublicValues : Public value (output) */ /******************************************************************/ status = cpaCyDhKeyGenPhase1(setup->cyInstanceHandle, NULL/*ikeRsaCallback*/, setup->performanceStats, alice.ppPhase1[innerLoop], alice.ppPublicValues[innerLoop]); /*this is a back off mechanism to stop the code * continually submitting requests. Without this the CPU * can report a soft lockup if it continually loops * on busy*/ if(status == CPA_STATUS_RETRY) { setup->performanceStats->retries++; AVOID_SOFTLOCKUP; } } while (CPA_STATUS_RETRY == status); if(CPA_STATUS_SUCCESS != status) { PRINT_ERR("Failed to complete dhPhase1 for Alice, status: %d\n", status); break; } /******************************************************************/ /* Step 7b Perform RSA verify of third party...normally this is done * on at third party to verify that bob is who he says he is, but * here we are performing a second RSA encrypt on Bobs signature to * test the sequence of calls */ /******************************************************************/ do { status = cpaCyRsaEncrypt( setup->cyInstanceHandle, NULL/*ikeRsaCallback*/, setup->performanceStats, bob.ppEncryptOpData[innerLoop], bob.ppPVverifier[innerLoop]); if(status == CPA_STATUS_RETRY) { setup->performanceStats->retries++; AVOID_SOFTLOCKUP; } } while (CPA_STATUS_RETRY == status); if (CPA_STATUS_SUCCESS != status) { PRINT_ERR("Failed on RsaVerify for Bob using buffer=%d \n", innerLoop); break; } /*************************************************************** * Step 7c Perform RSA verify of Bobs signed public values. * Bobs Public values and Bobs RSA Signature have been * pre-calculated Bobs signature is in the EncryptOpData * structure, the verifier value should match bobsPublic value, * but in this code we dont check if they match **************************************************************/ do { status = cpaCyRsaEncrypt( setup->cyInstanceHandle, NULL/*ikeRsaCallback*/, setup->performanceStats, bob.ppEncryptOpData2[innerLoop], bob.ppPVverifier2[innerLoop]); if(status == CPA_STATUS_RETRY) { setup->performanceStats->retries++; AVOID_SOFTLOCKUP; } } while (CPA_STATUS_RETRY == status); if (CPA_STATUS_SUCCESS != status) { PRINT_ERR("Failed on RsaVerify for Bob using buffer=%d \n ", innerLoop); break; } /****************************************************************** * Step 7d Sign all of Alices public value buffers, * Alices Public Value is in the Decrypt opData setup, the signature * is placed in alices signature ******************************************************************/ do { status = cpaCyRsaDecrypt( setup->cyInstanceHandle, NULL/*ikeRsaCallback*/, setup->performanceStats, alice.ppDecryptOpData[innerLoop], alice.ppSignatures[innerLoop]); if(status == CPA_STATUS_RETRY) { setup->performanceStats->retries++; AVOID_SOFTLOCKUP; } } while (CPA_STATUS_RETRY == status); if (CPA_STATUS_SUCCESS != status) { PRINT_ERR("Failed to complete RsaSign for Alice, status: %d\n", innerLoop); break; } /******************************************************************/ /* Step 7e Perform the DH phase2 operation for Alice, * using Bobs verified Public values */ do { status = cpaCyDhKeyGenPhase2Secret(setup->cyInstanceHandle, NULL/*ikeRsaCallback*/, setup->performanceStats, alice.ppPhase2[innerLoop], alice.ppSecretKeys[innerLoop]); /*this is a back off mechanism to stop the code * continually calling the Decrypt operation when the * acceleration units are busy. Without this the CPU * can report a soft lockup if it continually loops * on busy*/ if(status == CPA_STATUS_RETRY) { setup->performanceStats->retries++; AVOID_SOFTLOCKUP; } } while (CPA_STATUS_RETRY == status); if (CPA_STATUS_SUCCESS != status) { PRINT_ERR("Diffie Hellman Phase2 for Alice, status: %d\n", status); break; } /*At this point Bob and Alice should have created the same shared * secret key*/ responses++; } /*end innerLoop*/ if (CPA_STATUS_SUCCESS != status) { break; } } /*end numLoops*/ setup->performanceStats->endCyclesTimestamp = sampleCodeTimestamp(); /*if (CPA_STATUS_SUCCESS == status) { if(sampleCodeSemaphoreWait(&setup->performanceStats->comp, SAMPLE_CODE_WAIT_FOREVER) != CPA_STATUS_SUCCESS) { PRINT_ERR("interruption in ike rsa Loop\n"); status = CPA_STATUS_FAIL; } }*/ sampleCodeSemaphoreDestroy(&setup->performanceStats->comp); if(CPA_STATUS_SUCCESS != status) { ikeRsaMemFree(setup, &alice, &bob, pPrivateKey, pPublicKey); return status; } ikeRsaMemFree(setup, &alice, &bob, pPrivateKey, pPublicKey); /*set the total number of responses and requests. */ setup->performanceStats->numOperations = (Cpa64U)responses * NUMBER_OF_CHAINED_OPS; setup->performanceStats->responses = responses * NUMBER_OF_CHAINED_OPS; if(CPA_STATUS_SUCCESS != setup->performanceStats->threadReturnStatus) { status = CPA_STATUS_FAIL; } return status; }