@@ -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,154 @@ 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, WOLFSSL_VA416X0_TRNG_MAX_RETRY and
5190+ * WOLFSSL_VA416X0_TRNG_TIMEOUT have overridable defaults defined below.
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+ /* CONFIG = 0 sets RND_SRC_SEL = 0, which selects the ring-oscillator
5254+ * entropy source (per the VA416x0 reference manual) and clears the
5255+ * rest of the register; set the sample rate and keep the health tests
5256+ * enabled (no DEBUG_CONTROL bypass) */
5257+ VOR_TRNG -> CONFIG = 0 ;
5258+ VOR_TRNG -> SAMPLE_CNT1 = WOLFSSL_VA416X0_TRNG_SAMPLE_CNT ;
5259+ VOR_TRNG -> DEBUG_CONTROL = 0 ;
5260+
5261+ for (i = 0 ; i < sz ; ) {
5262+ retry = 0 ;
5263+ timeout = WOLFSSL_VA416X0_TRNG_TIMEOUT ;
5264+
5265+ /* start entropy collection */
5266+ VOR_TRNG -> RND_SOURCE_ENABLE =
5267+ TRNG_RND_SOURCE_ENABLE_RND_SRC_EN_Msk ;
5268+
5269+ for (;;) {
5270+ reg = VOR_TRNG -> ISR ;
5271+ if ((reg & (TRNG_ISR_AUTOCORR_ERR_Msk |
5272+ TRNG_ISR_CRNGT_ERR_Msk |
5273+ TRNG_ISR_VN_ERR_Msk )) != 0 ) {
5274+ /* health-test failure: stop, then clear the error flags
5275+ * and any latched EHR_VALID so a stale/invalid block is
5276+ * not consumed on the next iteration, then re-collect */
5277+ VOR_TRNG -> RND_SOURCE_ENABLE = 0 ;
5278+ VOR_TRNG -> ICR = TRNG_ICR_EHR_VALID_Msk |
5279+ TRNG_ICR_AUTOCORR_ERR_Msk |
5280+ TRNG_ICR_CRNGT_ERR_Msk |
5281+ TRNG_ICR_VN_ERR_Msk ;
5282+ if (++ retry > WOLFSSL_VA416X0_TRNG_MAX_RETRY ) {
5283+ ForceZero (ehr , sizeof (ehr ));
5284+ wolfSSL_CryptHwMutexUnLock ();
5285+ return RNG_FAILURE_E ;
5286+ }
5287+ timeout = WOLFSSL_VA416X0_TRNG_TIMEOUT ;
5288+ VOR_TRNG -> RND_SOURCE_ENABLE =
5289+ TRNG_RND_SOURCE_ENABLE_RND_SRC_EN_Msk ;
5290+ continue ;
5291+ }
5292+ if ((VOR_TRNG -> VALID & TRNG_VALID_EHR_VALID_Msk ) != 0 ) {
5293+ break ;
5294+ }
5295+ if (-- timeout == 0 ) {
5296+ VOR_TRNG -> RND_SOURCE_ENABLE = 0 ;
5297+ ForceZero (ehr , sizeof (ehr ));
5298+ wolfSSL_CryptHwMutexUnLock ();
5299+ return RNG_FAILURE_E ;
5300+ }
5301+ }
5302+
5303+ /* read 192 bits of entropy (6 x 32-bit words) */
5304+ ehr [0 ] = VOR_TRNG -> EHR_DATA0 ;
5305+ ehr [1 ] = VOR_TRNG -> EHR_DATA1 ;
5306+ ehr [2 ] = VOR_TRNG -> EHR_DATA2 ;
5307+ ehr [3 ] = VOR_TRNG -> EHR_DATA3 ;
5308+ ehr [4 ] = VOR_TRNG -> EHR_DATA4 ;
5309+ ehr [5 ] = VOR_TRNG -> EHR_DATA5 ;
5310+
5311+ /* reading the EHR clears EHR_VALID; stop the source and ack */
5312+ VOR_TRNG -> RND_SOURCE_ENABLE = 0 ;
5313+ VOR_TRNG -> ICR = TRNG_ICR_EHR_VALID_Msk ;
5314+
5315+ chunk = sz - i ;
5316+ if (chunk > sizeof (ehr )) {
5317+ chunk = sizeof (ehr );
5318+ }
5319+ XMEMCPY (& output [i ], (byte * )ehr , chunk );
5320+ i += chunk ;
5321+ }
5322+
5323+ ForceZero (ehr , sizeof (ehr )); /* scrub seed material from stack */
5324+ wolfSSL_CryptHwMutexUnLock ();
5325+ return 0 ;
5326+ }
5327+
51745328#elif defined(DOLPHIN_EMULATOR ) || defined (WOLFSSL_NDS )
51755329
51765330 int wc_GenerateSeed (OS_Seed * os , byte * output , word32 sz )
0 commit comments