Skip to content

Commit edde456

Browse files
committed
Added TRNG support for the Vorago VA416XX
1 parent 29f14ed commit edde456

2 files changed

Lines changed: 154 additions & 4 deletions

File tree

.wolfssl_known_macro_extras

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -955,6 +955,7 @@ WOLFSSL_USE_ESP32C3_CRYPT_HASH_HW
955955
WOLFSSL_USE_FLASHMEM
956956
WOLFSSL_USE_FORCE_ZERO
957957
WOLFSSL_USE_OPTIONS_H
958+
WOLFSSL_VA416X0_TRNG
958959
WOLFSSL_VALIDATE_DH_KEYGEN
959960
WOLFSSL_WC_SLHDSA_RECURSIVE
960961
WOLFSSL_WC_XMSS_NO_SHA256

wolfcrypt/src/random.c

Lines changed: 153 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)