@@ -88,18 +88,24 @@ This library contains implementation for the random number generator.
8888 * FREESCALE_RNGA: Freescale RNGA default: off
8989 * FREESCALE_K70_RNGA: Freescale K70 RNGA default: off
9090 * FREESCALE_RNGB: Freescale RNGB default: off
91- * FREESCALE_KSDK_2_0_RNGA: Freescale KSDK 2.0 RNGA default: off
92- * FREESCALE_KSDK_2_0_TRNG: Freescale KSDK 2.0 TRNG default: off
93- * MAX3266X_RNG: MAX3266X hardware RNG default: off
91+ * FREESCALE_KSDK_2_0_RNGA: Freescale KSDK 2.0 RNGA default: off
92+ * FREESCALE_KSDK_2_0_TRNG: Freescale KSDK 2.0 TRNG default: off
93+ * MAX3266X_RNG: MAX3266X hardware RNG default: off
9494 * QAT_ENABLE_RNG: Intel QAT hardware RNG default: off
95- * WOLFSSL_ATECC_RNG: ATECC508/608 hardware RNG default: off
95+ * WOLFSSL_ATECC_RNG: ATECC508/608 hardware RNG default: off
9696 * WOLFSSL_SILABS_TRNG: Silicon Labs TRNG default: off
9797 * WOLFSSL_SCE_NO_TRNG: Disable Renesas SCE TRNG default: off
9898 * WOLFSSL_SCE_TRNG_HANDLE: Renesas SCE TRNG handle default: off
9999 * WOLFSSL_SE050_NO_TRNG: Disable SE050 TRNG default: off
100100 * WOLFSSL_PSA_NO_RNG: Disable PSA RNG default: off
101101 * HAVE_IOTSAFE_HWRNG: IoT-Safe hardware RNG default: off
102102 * WOLFSSL_XILINX_CRYPT_VERSAL: Xilinx Versal crypto RNG default: off
103+ * WOLFSSL_VA416X0_TRNG: Vorago VA416x0 hardware TRNG default: off
104+ * (seeds Hash-DRBG; needs the VA416xx
105+ * SDK header va416xx.h on the include
106+ * path). See the wc_GenerateSeed()
107+ * implementation below for SDK API and
108+ * tuning details.
103109 */
104110
105111#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
@@ -5171,6 +5177,149 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
51715177 return 0 ;
51725178 }
51735179
5180+ #elif defined(WOLFSSL_VA416X0_TRNG )
5181+ /* Vorago VA416x0 hardware TRNG (an Arm CryptoCell-style entropy block).
5182+ * Used to seed the SP800-90A Hash-DRBG (keep HAVE_HASHDRBG enabled); the
5183+ * TRNG yields only ~1.25 kb/s of entropy, so the DRBG expands it.
5184+ *
5185+ * Build: define WOLFSSL_VA416X0_TRNG, and have the VA416xx SDK header
5186+ * "va416xx.h" on the include path (provides VOR_SYSCONFIG / VOR_TRNG and
5187+ * the register field macros). There is no SDK HAL driver for the TRNG, so
5188+ * it is accessed at the register level below. The tuning macros
5189+ * (WOLFSSL_VA416X0_TRNG_SAMPLE_CNT / _MAX_RETRY / _TIMEOUT) are documented
5190+ * with the other Hardware RNG build options at the top of this file.
5191+ *
5192+ * Note: the TRNG PERIPHERAL_RESET bit is active low and must be released
5193+ * or every TRNG register write is silently ignored. */
5194+ #include "va416xx.h"
5195+
5196+ /* Ring-oscillator sample count (must be non-zero). May need tuning on
5197+ * hardware: too low results in repeated autocorrelation/CRNGT errors. */
5198+ #ifndef WOLFSSL_VA416X0_TRNG_SAMPLE_CNT
5199+ #define WOLFSSL_VA416X0_TRNG_SAMPLE_CNT 1000
5200+ #endif
5201+ #ifndef WOLFSSL_VA416X0_TRNG_MAX_RETRY
5202+ #define WOLFSSL_VA416X0_TRNG_MAX_RETRY 10
5203+ #endif
5204+ /* Max poll iterations waiting for one 192-bit entropy block before
5205+ * giving up (guards against a non-responsive TRNG). */
5206+ #ifndef WOLFSSL_VA416X0_TRNG_TIMEOUT
5207+ #define WOLFSSL_VA416X0_TRNG_TIMEOUT 1000000
5208+ #endif
5209+ #if WOLFSSL_VA416X0_TRNG_SAMPLE_CNT == 0
5210+ #error "WOLFSSL_VA416X0_TRNG_SAMPLE_CNT must be non-zero"
5211+ #endif
5212+ #if WOLFSSL_VA416X0_TRNG_TIMEOUT == 0
5213+ #error "WOLFSSL_VA416X0_TRNG_TIMEOUT must be non-zero"
5214+ #endif
5215+
5216+ int wc_GenerateSeed (OS_Seed * os , byte * output , word32 sz )
5217+ {
5218+ word32 i ;
5219+ word32 reg ;
5220+ word32 chunk ;
5221+ word32 timeout ;
5222+ word32 ehr [6 ]; /* 192-bit entropy holding register */
5223+ int retry ;
5224+ int ret ;
5225+
5226+ (void )os ;
5227+
5228+ if (output == NULL ) {
5229+ return BUFFER_E ;
5230+ }
5231+
5232+ /* serialize access to the shared TRNG hardware */
5233+ ret = wolfSSL_CryptHwMutexLock ();
5234+ if (ret != 0 ) {
5235+ return ret ;
5236+ }
5237+
5238+ /* enable the TRNG peripheral clock and release it from reset (the
5239+ * reset bit is active low: 0 = held in reset, 1 = released) */
5240+ VOR_SYSCONFIG -> PERIPHERAL_CLK_ENABLE |=
5241+ SYSCONFIG_PERIPHERAL_CLK_ENABLE_TRNG_Msk ;
5242+ VOR_SYSCONFIG -> PERIPHERAL_RESET |=
5243+ SYSCONFIG_PERIPHERAL_RESET_TRNG_Msk ;
5244+
5245+ /* mask all interrupts (poll instead) and clear any stale status */
5246+ VOR_TRNG -> IMR = TRNG_IMR_EHR_VALID_INT_MASK_Msk |
5247+ TRNG_IMR_AUTOCORR_ERR_INT_MASK_Msk |
5248+ TRNG_IMR_CRNGT_ERR_INT_MASK_Msk |
5249+ TRNG_IMR_VN_ERR_INT_MASK_Msk ;
5250+ VOR_TRNG -> ICR = TRNG_ICR_EHR_VALID_Msk | TRNG_ICR_AUTOCORR_ERR_Msk |
5251+ TRNG_ICR_CRNGT_ERR_Msk | TRNG_ICR_VN_ERR_Msk ;
5252+
5253+ /* select ring-oscillator source, set sample rate, keep health
5254+ * tests enabled (no DEBUG_CONTROL bypass) */
5255+ VOR_TRNG -> CONFIG = 0 ;
5256+ VOR_TRNG -> SAMPLE_CNT1 = WOLFSSL_VA416X0_TRNG_SAMPLE_CNT ;
5257+ VOR_TRNG -> DEBUG_CONTROL = 0 ;
5258+
5259+ for (i = 0 ; i < sz ; ) {
5260+ retry = 0 ;
5261+ timeout = WOLFSSL_VA416X0_TRNG_TIMEOUT ;
5262+
5263+ /* start entropy collection */
5264+ VOR_TRNG -> RND_SOURCE_ENABLE =
5265+ TRNG_RND_SOURCE_ENABLE_RND_SRC_EN_Msk ;
5266+
5267+ for (;;) {
5268+ reg = VOR_TRNG -> ISR ;
5269+ if ((reg & (TRNG_ISR_AUTOCORR_ERR_Msk |
5270+ TRNG_ISR_CRNGT_ERR_Msk |
5271+ TRNG_ISR_VN_ERR_Msk )) != 0 ) {
5272+ /* health-test failure: stop, clear, re-collect */
5273+ VOR_TRNG -> RND_SOURCE_ENABLE = 0 ;
5274+ VOR_TRNG -> ICR = TRNG_ICR_AUTOCORR_ERR_Msk |
5275+ TRNG_ICR_CRNGT_ERR_Msk |
5276+ TRNG_ICR_VN_ERR_Msk ;
5277+ if (++ retry > WOLFSSL_VA416X0_TRNG_MAX_RETRY ) {
5278+ ForceZero (ehr , sizeof (ehr ));
5279+ wolfSSL_CryptHwMutexUnLock ();
5280+ return RNG_FAILURE_E ;
5281+ }
5282+ timeout = WOLFSSL_VA416X0_TRNG_TIMEOUT ;
5283+ VOR_TRNG -> RND_SOURCE_ENABLE =
5284+ TRNG_RND_SOURCE_ENABLE_RND_SRC_EN_Msk ;
5285+ continue ;
5286+ }
5287+ if ((VOR_TRNG -> VALID & TRNG_VALID_EHR_VALID_Msk ) != 0 ) {
5288+ break ;
5289+ }
5290+ if (-- timeout == 0 ) {
5291+ VOR_TRNG -> RND_SOURCE_ENABLE = 0 ;
5292+ ForceZero (ehr , sizeof (ehr ));
5293+ wolfSSL_CryptHwMutexUnLock ();
5294+ return RNG_FAILURE_E ;
5295+ }
5296+ }
5297+
5298+ /* read 192 bits of entropy (6 x 32-bit words) */
5299+ ehr [0 ] = VOR_TRNG -> EHR_DATA0 ;
5300+ ehr [1 ] = VOR_TRNG -> EHR_DATA1 ;
5301+ ehr [2 ] = VOR_TRNG -> EHR_DATA2 ;
5302+ ehr [3 ] = VOR_TRNG -> EHR_DATA3 ;
5303+ ehr [4 ] = VOR_TRNG -> EHR_DATA4 ;
5304+ ehr [5 ] = VOR_TRNG -> EHR_DATA5 ;
5305+
5306+ /* reading the EHR clears EHR_VALID; stop the source and ack */
5307+ VOR_TRNG -> RND_SOURCE_ENABLE = 0 ;
5308+ VOR_TRNG -> ICR = TRNG_ICR_EHR_VALID_Msk ;
5309+
5310+ chunk = sz - i ;
5311+ if (chunk > sizeof (ehr )) {
5312+ chunk = sizeof (ehr );
5313+ }
5314+ XMEMCPY (& output [i ], (byte * )ehr , chunk );
5315+ i += chunk ;
5316+ }
5317+
5318+ ForceZero (ehr , sizeof (ehr )); /* scrub seed material from stack */
5319+ wolfSSL_CryptHwMutexUnLock ();
5320+ return 0 ;
5321+ }
5322+
51745323#elif defined(DOLPHIN_EMULATOR ) || defined (WOLFSSL_NDS )
51755324
51765325 int wc_GenerateSeed (OS_Seed * os , byte * output , word32 sz )
0 commit comments