int mbedtls_hardware_poll( void *data, unsigned char *output, size_t len, size_t *olen ) { trng_t trng_obj; trng_init(&trng_obj); int ret = trng_get_bytes(&trng_obj, output, len, olen); trng_free(&trng_obj); return ret; }
/** * \internal * \brief Test for TRNG polling mode read. * * This test reads three random data in polling mode and check the result. * * \param test Current test case */ static void run_trng_polling_read_test(const struct test_case *test) { uint32_t i; uint32_t timeout; uint32_t random_result[3]; /* Structure for TRNG configuration */ struct trng_config config; /* Initialize and enable the TRNG */ trng_get_config_defaults(&config); trng_init(&trng_instance, TRNG, &config); trng_enable(&trng_instance); /* Read random data */ for (i = 0; i < 3; i++) { /* A new 32-bits random data will be generated for every * 84 CLK_TRNG_APB clock cycles. */ timeout = 84; if (trng_read(&trng_instance, &random_result[i]) != STATUS_OK) { timeout--; if (timeout == 0) { /* Skip test if fail to read random data */ test_assert_true(test, false, "Fail to read random data in polling mode."); } } } /* Assume there is no probability to read same three * consecutive random number */ if ((random_result[0] == random_result[1]) && (random_result[0] == random_result[2])) { test_assert_true(test, false, "Get same random data in polling mode."); } }
/** **************************************************************************************** * @brief Acquires 128 bits, saves them in trng_bits[]and restores the modified regs **************************************************************************************** */ void trng_acquire(uint8_t *trng_bits_ptr) { uint16_t i,i_acq; uint16_t save_TEST_CTRL_REG, save_RF_ENABLE_CONFIG1_REG,save_RF_ENABLE_CONFIG2_REG,save_RF_DC_OFFSET_CTRL1_REG,save_RF_DC_OFFSET_CTRL2_REG; uint16_t save_RF_ENABLE_CONFIG4_REG,save_RF_ENABLE_CONFIG14_REG,save_RF_SPARE1_REG,save_RF_AGC_CTRL2_REG; uint8_t bit_cnt, rnd_byte, single_rnd_bit; uint16_t byte_idx; uint8_t rfadc_data[NUM_POINTS*2]; uint8_t * vq_uint8=(uint8_t *)&rfadc_data[0]; // The Q RFADC channel uint8_t * vi_uint8=(uint8_t *)&rfadc_data[2]; // The I RFADC channel save_TEST_CTRL_REG =GetWord16(TEST_CTRL_REG); rfpt_init(); // Init system and radio, set pref settings, and perform radio calibrations. Do not Radio Overrule yet... // Implement Save-Modify-Restore for the prefered settings that will be changed for the TRNG mode /////////////////////////////////////////////////////////////////////////////////////////////////////////// save_RF_ENABLE_CONFIG1_REG = GetWord16(RF_ENABLE_CONFIG1_REG); // LNA off save_RF_ENABLE_CONFIG2_REG = GetWord16(RF_ENABLE_CONFIG2_REG); // Mixer off save_RF_DC_OFFSET_CTRL1_REG = GetWord16(RF_DC_OFFSET_CTRL1_REG); // Fixed DC offset compensation values for I and Q save_RF_DC_OFFSET_CTRL2_REG = GetWord16(RF_DC_OFFSET_CTRL2_REG); // Use the manual DC offset compensation values save_RF_ENABLE_CONFIG4_REG = GetWord16(RF_ENABLE_CONFIG4_REG); // VCO_LDO_EN=0, MD_LDO_EN=0. You need this for more isolation from the RF input save_RF_ENABLE_CONFIG14_REG = GetWord16(RF_ENABLE_CONFIG14_REG); // LOBUF_RXIQ_EN=0, DIV2_EN=0. This increases the noise floor for some reason. So you get more entropy. Need to understand it and then decide... save_RF_SPARE1_REG = GetWord16(RF_SPARE1_REG); // Set the IFF in REAL transfer function, to remove I-Q correlation. But it affects the DC offsets! save_RF_AGC_CTRL2_REG = GetWord16(RF_AGC_CTRL2_REG); // AGC=0 i.e. max RX gain // Configure radio for TRNG mode (modifies some pref settings, starts RX in overrule) /////////////////////////////////////////////////////////////////////////////////////////////////////////// trng_init(); // Start acquiring raw IQ RFADC data and then extract the random bits /////////////////////////////////////////////////////////////////////////////////////////////////////////// byte_idx=0; for (i_acq=0; i_acq < 128/(NUM_POINTS*2/16); i_acq++) { trng_get_raw_data((uint32)&rfadc_data[0], NUM_POINTS/2-1); // acquires the raw RFADC IQ samples bit_cnt=0; rnd_byte=0; for (i=0;i<=NUM_POINTS_MUL_2_M_4;i=i+16) { single_rnd_bit = (vq_uint8[i] & 0x01) ^ (vi_uint8[i] & 0x01) ; // This way it can pass ALL the NIST tests! This solves a small bias in 1s or 0s which appears due to the actual value of the DC offset... rnd_byte= rnd_byte | (single_rnd_bit<<bit_cnt++); if(bit_cnt==8) { trng_bits_ptr[byte_idx++] = rnd_byte; bit_cnt=0; rnd_byte=0; } #if (USE_WDOG) SetWord16(WATCHDOG_REG, 0xC8); // Reset WDOG! 200 * 10.24ms active time for normal mode! #endif } } // Restore the modified regs /////////////////////////////////////////////////////////////////////////////////////////////////////////// SetWord16(TEST_CTRL_REG, save_TEST_CTRL_REG); SetWord16(RF_OVERRULE_REG,0x0); SetWord16(RF_ENABLE_CONFIG1_REG, save_RF_ENABLE_CONFIG1_REG); // LNA off SetWord16(RF_ENABLE_CONFIG2_REG, save_RF_ENABLE_CONFIG2_REG); // Mixer off SetWord16(RF_DC_OFFSET_CTRL1_REG, save_RF_DC_OFFSET_CTRL1_REG); // Fixed DC offset compensation values for I and Q SetWord16(RF_DC_OFFSET_CTRL2_REG, save_RF_DC_OFFSET_CTRL2_REG); // Use the manual DC offset compensation values SetWord16(RF_ENABLE_CONFIG4_REG, save_RF_ENABLE_CONFIG4_REG); // VCO_LDO_EN=0, MD_LDO_EN=0. You need this for more isolation from the RF input SetWord16(RF_ENABLE_CONFIG14_REG, save_RF_ENABLE_CONFIG14_REG); // LOBUF_RXIQ_EN=0, DIV2_EN=0. This increases the noise floor for some reason. So you get more entropy. Need to understand it and then decide... SetWord16(RF_SPARE1_REG, save_RF_SPARE1_REG); // Set the IFF in REAL transfer function, to remove I-Q correlation. But it affects the DC offsets! SetWord16(RF_AGC_CTRL2_REG, save_RF_AGC_CTRL2_REG); // AGC=0 i.e. max RX gain SetBits16 (CLK_AMBA_REG, OTP_ENABLE, 0); }