ret_code_t nrf_crypto_rng_backend_vector_generate(void * const p_context, uint8_t * const p_target, size_t size, bool use_mutex) { bool mutex_locked; CRYSError_t err_code; ret_code_t ret_val; CRYS_RND_State_t * p_crys_rnd_state = &((nrf_crypto_backend_rng_context_t *)p_context)->crys_rnd_state; if (use_mutex) { mutex_locked = cc310_backend_mutex_trylock(); VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY); } cc310_backend_enable(); err_code = CRYS_RND_GenerateVector(p_crys_rnd_state, size, p_target); cc310_backend_disable(); ret_val = result_get(err_code); if (use_mutex) { cc310_backend_mutex_unlock(); } return ret_val; }
/** Function Name: CRYS_RSA_PKCS1_v1_5_Encode Date: 18-01-2005 Author: Ohad Shperling \brief CRYS_RSA_PKCS1_v1_5_Encode implements EME-PKCS1_v1_5_Encoding algorithm as defined in PKCS#1 v1.5 Sec 8.1 @param[in] K - The modulus size denoted in octets. @param[in] M_ptr - Pointer to the Message to pad the ouput stream @param[in] MSize - Denotes the Message size @param[in] BlockType - BlockType for PUB Key is 02 BlockType for Priv Key is 01 @param[out] Output_ptr - Pointer to a buffer which is at least K octets long @return CRYSError_t - CRYS_OK, */ CRYSError_t CRYS_RSA_PKCS1_v1_5_Encode(DxUint16_t K, CRYS_PKCS1_Block_Type BlockType, DxUint8_t *M_ptr, DxUint32_t MSize, DxUint8_t *Output_ptr) { /* The return error identifier */ CRYSError_t Error; /* Padding String Size */ DxUint16_t PSSize,I,J; /* FUNCTION LOGIC */ /* .................. initializing local variables ................... */ /* ------------------------------------------------------------------- */ /* initializing the Error to O.K */ Error = CRYS_OK; /*Initializing the EB buffer to zero*/ DX_VOS_MemSet(Output_ptr,0x0,K); /* ............... checking the parameters validity ................... */ /* -------------------------------------------------------------------- */ if(MSize>(DxUint32_t)(K-11)) return CRYS_RSA_ENCODE_15_MSG_OUT_OF_RANGE; /*-------------------------------------------*/ /* */ /* Step 1 : Encryption block formating */ /* */ /* 00 || BT || PS || 00 || D */ /* MSByte LSByte */ /* Note: - */ /* - BT for PUBKey is 02 */ /* - PS size is k-3-||D|| , padding */ /* value is pseudorandomly non */ /* zero */ /*-------------------------------------------*/ Output_ptr[0]=0x00; /* set the 00 */ Output_ptr[1]=BlockType; /* set Block Type */ PSSize=(DxUint16_t)(K-3-MSize); /* In PKCS#1 V2 : The padding string PS in EME-PKCS1-v1_5 is at least eight octets long, which is a security condition for public-key operations that prevents an attacker from recovering data by trying all possible encryption blocks. */ if(PSSize<0x08) { return CRYS_RSA_ENCODE_15_PS_TOO_SHORT; } switch(BlockType) { case CRYS_RSA_PKCS1_15_MODE00: /* Please refer to PKCS1 Ver 1.5 Standart for the security argument why not to use this kind of Block Type*/ return CRYS_RSA_PKCS1_15_BLOCK_TYPE_NOT_SUPPORTED ; case CRYS_RSA_PKCS1_15_MODE01: DX_VOS_MemSet(&Output_ptr[2],0xFF,PSSize); break; case CRYS_RSA_PKCS1_15_MODE02: Error = CRYS_RND_GenerateVector((DxUint16_t)(K-2),&Output_ptr[2]); if(Error != CRYS_OK) { return Error; } /*The random generation should not generate a zero octet according to the standart*/ J = K-2; for(I=2;I<PSSize+2;I++) { if(Output_ptr[I] == 0x00) { /*Take a non zero octet from the end of the vector*/ while(Output_ptr[J] == 0) { J--; continue; } /*Change the zero octet*/ Output_ptr[I] = Output_ptr[J]; J--; } if(J == I) { /*This happens in very low probability*/ /*All the extra random generated octets are zero or used*/ /*regenerate */ Error = CRYS_RND_GenerateVector((DxUint16_t)(K-2),&Output_ptr[2]); if(Error != CRYS_OK) { return Error; } J = K-2; I=1;/*go back to the start of the loop*/ } } break; default: return CRYS_RSA_PKCS1_15_BLOCK_TYPE_NOT_SUPPORTED; } /* add 00 */ Output_ptr[K-MSize-1]=0x00; /* copy the data */ DX_VOS_FastMemCpy(&Output_ptr[K-MSize],M_ptr,MSize); return CRYS_OK; }
/*rnd_test - performs basic integration test for RND module*/ int rnd_tests(void) { uint32_t ret = 0/*,MaxVectorSize = 0*/; int test_index = 0; /*Set additional input for rng seed*/ ret = CRYS_RND_AddAdditionalInput(rndContext_ptr, rndVectors[test_index].rndTest_AddInputData, rndVectors[test_index].rndTest_AddInputSize); if (ret != SA_SILIB_RET_OK){ INTEG_TEST_PRINT("\n CRYS_RND_AddAdditionalInput failed with 0x%x \n",ret); return ret; } INTEG_TEST_PRINT("\n CRYS_RND_AddAdditionalInput passed\n"); /*Reseed rnd using added input (new seed will be generated using additional input)*/ ret = CRYS_RND_Reseeding (rndContext_ptr, rndWorkBuff_ptr); if (ret != SA_SILIB_RET_OK){ INTEG_TEST_PRINT("\n CRYS_RND_Reseeding failed with 0x%x \n",ret); return ret; } INTEG_TEST_PRINT("\n CRYS_RND_Reseeding passed\n"); /*Generate random vector 1*/ ret = CRYS_RND_GenerateVector(&rndContext_ptr->rndState, rndVectors[test_index].rndTest_RandomVectorSize, rndVectors[test_index].rndTest_RandomVectorData1); if (ret != SA_SILIB_RET_OK){ INTEG_TEST_PRINT("\n CRYS_RND_GenerateVector for vector 1 failed with 0x%x \n",ret); return ret; } INTEG_TEST_PRINT("\n CRYS_RND_GenerateVector for first vector passed\n"); /*Generate rnadom vector 2*/ ret = CRYS_RND_GenerateVector(&rndContext_ptr->rndState, rndVectors[test_index].rndTest_RandomVectorSize, rndVectors[test_index].rndTest_RandomVectorData2); if (ret != SA_SILIB_RET_OK){ INTEG_TEST_PRINT("\n CRYS_RND_GenerateVector for vector 2 failed with 0x%x \n",ret); return ret; } INTEG_TEST_PRINT("\n CRYS_RND_GenerateVector for second vector passed\n"); /*Compare two generated vectors - should not be the same value*/ ret = SaSi_PalMemCmp(rndVectors[test_index].rndTest_RandomVectorData1, rndVectors[test_index].rndTest_RandomVectorData2, rndVectors[test_index].rndTest_RandomVectorSize); if (ret == SA_SILIB_RET_OK){ INTEG_TEST_PRINT("\n Two random vectors should not are the same \n"); return ret; } INTEG_TEST_PRINT("\n Two generated vectors are different as expected\n"); /*Generate random vector in range when max value is NULL*/ ret = CRYS_RND_GenerateVectorInRange(rndContext_ptr, rndVectors[test_index].rndTest_RandomVectorInRangeSize1, NULL, rndVectors[test_index].rndTest_RandomVectorInRangeData); if (ret != SA_SILIB_RET_OK){ INTEG_TEST_PRINT("\n CRYS_RND_GenerateVectorInRange for vector with fixed size failed with 0x%x \n",ret); return ret; } INTEG_TEST_PRINT("\n CRYS_RND_GenerateVectorInRange 1 passed\n"); /*Generate random vector in range with max vector */ ret = CRYS_RND_GenerateVectorInRange(rndContext_ptr, rndVectors[test_index].rndTest_RandomVectorInRangeSize2, rndVectors[test_index].rndTest_MaxVectorInRange2, rndVectors[test_index].rndTest_RandomVectorInRangeData2); if (ret != SA_SILIB_RET_OK){ INTEG_TEST_PRINT("\n CRYS_RND_GenerateVectorInRange failed with 0x%x \n",ret); return ret; } INTEG_TEST_PRINT("\n CRYS_RND_GenerateVectorInRange 2 passed\n"); /*Perform UnInstantiation*/ ret = CRYS_RND_UnInstantiation(rndContext_ptr); if (ret != SA_SILIB_RET_OK){ INTEG_TEST_PRINT("\n CRYS_RND_UnInstantiation failed with 0x%x \n",ret); return ret; } INTEG_TEST_PRINT("\n CRYS_RND_UnInstantiation passed\n"); /*Try to create random vector without instantiation - should fail*/ ret = CRYS_RND_GenerateVector(&rndContext_ptr->rndState, rndVectors[test_index].rndTest_RandomVectorSize, rndVectors[test_index].rndTest_RandomVectorData2); if (ret != CRYS_RND_STATE_VALIDATION_TAG_ERROR){ INTEG_TEST_PRINT("\n CRYS_RND_GenerateVector returned wrong error 0x%x,\n CRYS_RND_STATE_VALIDATION_TAG_ERROR should be returned\n",ret); return ret; } INTEG_TEST_PRINT("\n CRYS_RND_GenerateVector failed as expected\n"); /*Set additional input for RND seed*/ ret = CRYS_RND_AddAdditionalInput(rndContext_ptr, rndVectors[test_index].rndTest_AddInputData, rndVectors[test_index].rndTest_AddInputSize); if (ret != SA_SILIB_RET_OK){ INTEG_TEST_PRINT("\n CRYS_RND_AddAdditionalInput failed with 0x%x \n",ret); return ret; } INTEG_TEST_PRINT("\n CRYS_RND_AddAdditionalInput passed\n"); /*Perform instantiation for new seed*/ ret = CRYS_RND_Instantiation(rndContext_ptr, rndWorkBuff_ptr); if (ret != SA_SILIB_RET_OK){ INTEG_TEST_PRINT("\n CRYS_RND_Instantiation failed with 0x%x \n",ret); return ret; } INTEG_TEST_PRINT("\n CRYS_RND_Instantiation passed\n"); /*Try to create two vectors and check that the vectors are different*/ ret = CRYS_RND_GenerateVector(&rndContext_ptr->rndState, rndVectors[test_index].rndTest_RandomVectorSize, rndVectors[test_index].rndTest_RandomVectorData1); if (ret != SA_SILIB_RET_OK){ INTEG_TEST_PRINT("\n CRYS_RND_GenerateVector for vector 1 failed with 0x%x \n",ret); return ret; } INTEG_TEST_PRINT("\n CRYS_RND_GenerateVector 1 passed\n"); ret = CRYS_RND_GenerateVector(&rndContext_ptr->rndState, rndVectors[test_index].rndTest_RandomVectorSize, rndVectors[test_index].rndTest_RandomVectorData2); if (ret != SA_SILIB_RET_OK){ INTEG_TEST_PRINT(" CRYS_RND_GenerateVector for vector 2 failed with 0x%x \n",ret); return ret; } INTEG_TEST_PRINT("\n CRYS_RND_GenerateVector 2 passed\n"); ret = SaSi_PalMemCmp(rndVectors[test_index].rndTest_RandomVectorData1, rndVectors[test_index].rndTest_RandomVectorData2, rndVectors[test_index].rndTest_RandomVectorSize); if (ret == SA_SILIB_RET_OK){ INTEG_TEST_PRINT(" Two random vectors should not are the same \n"); return ret; } INTEG_TEST_PRINT("\n Compare passed\n"); INTEG_TEST_PRINT("\n All RND tests passed\n"); INTEG_TEST_PRINT("\n==========================\n"); ret = SA_SILIB_RET_OK; return ret; }