Skip to content

Commit b068f46

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

2 files changed

Lines changed: 166 additions & 6 deletions

File tree

.wolfssl_known_macro_extras

Lines changed: 1 addition & 2 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
@@ -969,8 +970,6 @@ WOLFSSL_XIL_MSG_NO_SLEEP
969970
WOLFSSL_ZEPHYR
970971
WOLF_ALLOW_BUILTIN
971972
WOLF_CRYPTO_CB_CMD
972-
WOLF_CRYPTO_CB_NO_SHA512_FALLBACK
973-
WOLF_CRYPTO_CB_ONLY_SHA512
974973
WOLF_CRYPTO_DEV
975974
WOLF_NO_TRAILING_ENUM_COMMAS
976975
WindowsCE

wolfcrypt/src/random.c

Lines changed: 165 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,161 @@ 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 (CryptoCell-style entropy source).
5182+
*
5183+
* Provides entropy to seed the SP800-90A Hash-DRBG (keep HAVE_HASHDRBG
5184+
* enabled). The TRNG produces ~1.25 kb/s of entropy, so it is used as a
5185+
* seed source only; the DRBG expands it for bulk generation.
5186+
*
5187+
* Build requirements:
5188+
* - Define WOLFSSL_VA416X0_TRNG (e.g. in user_settings.h).
5189+
* - The Vorago VA416xx SDK header "va416xx.h" must be on the include
5190+
* path; it provides VOR_SYSCONFIG, VOR_TRNG and the TRNG_* /
5191+
* SYSCONFIG_PERIPHERAL_* register field macros used below. No SDK
5192+
* HAL driver exists for the TRNG, so this accesses it directly.
5193+
*
5194+
* SDK / hardware API used (register block VOR_TRNG @ 0x40027000):
5195+
* - SYSCONFIG.PERIPHERAL_CLK_ENABLE bit TRNG: gate the TRNG clock on.
5196+
* - SYSCONFIG.PERIPHERAL_RESET bit TRNG: active-low reset; it MUST be
5197+
* set (released) or every TRNG register write is silently ignored.
5198+
* - CONFIG.RND_SRC_SEL: entropy source select (0 = ring oscillator).
5199+
* - SAMPLE_CNT1: ring-oscillator sample count (non-zero).
5200+
* - DEBUG_CONTROL: bypass bits for the health tests; left 0 to keep
5201+
* the Von-Neumann conditioner, CRNGT and autocorrelation tests on.
5202+
* - RND_SOURCE_ENABLE.RND_SRC_EN: start/stop entropy collection.
5203+
* - VALID.EHR_VALID: set when a 192-bit block is ready.
5204+
* - ISR / ICR: health-test error status and write-1-to-clear.
5205+
* - EHR_DATA0..EHR_DATA5: the 192-bit (24-byte) entropy block; reading
5206+
* it clears VALID and the source re-collects.
5207+
*
5208+
* On a health-test failure (ISR error bit) the block is re-collected up
5209+
* to WOLFSSL_VA416X0_TRNG_MAX_RETRY times; a per-block iteration cap of
5210+
* WOLFSSL_VA416X0_TRNG_TIMEOUT guards against a non-responsive TRNG.
5211+
* Both, plus WOLFSSL_VA416X0_TRNG_SAMPLE_CNT, are overridable defines.
5212+
*
5213+
* Customization Macros:
5214+
* WOLFSSL_VA416X0_TRNG_SAMPLE_CNT: VA416x0 ring-oscillator sample count,
5215+
* must be non-zero default: 1000
5216+
* WOLFSSL_VA416X0_TRNG_MAX_RETRY: VA416x0 TRNG health-test retry count
5217+
* before failing default: 10
5218+
* WOLFSSL_VA416X0_TRNG_TIMEOUT: VA416x0 TRNG poll-iteration cap per
5219+
* entropy block before failing
5220+
* default: 1000000
5221+
*/
5222+
#include "va416xx.h"
5223+
5224+
/* Ring-oscillator sample count (must be non-zero). May need tuning on
5225+
* hardware: too low results in repeated autocorrelation/CRNGT errors. */
5226+
#ifndef WOLFSSL_VA416X0_TRNG_SAMPLE_CNT
5227+
#define WOLFSSL_VA416X0_TRNG_SAMPLE_CNT 1000
5228+
#endif
5229+
#ifndef WOLFSSL_VA416X0_TRNG_MAX_RETRY
5230+
#define WOLFSSL_VA416X0_TRNG_MAX_RETRY 10
5231+
#endif
5232+
/* Max poll iterations waiting for one 192-bit entropy block before
5233+
* giving up (guards against a non-responsive TRNG). */
5234+
#ifndef WOLFSSL_VA416X0_TRNG_TIMEOUT
5235+
#define WOLFSSL_VA416X0_TRNG_TIMEOUT 1000000
5236+
#endif
5237+
5238+
int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
5239+
{
5240+
word32 i;
5241+
word32 reg;
5242+
word32 chunk;
5243+
word32 timeout;
5244+
word32 ehr[6]; /* 192-bit entropy holding register */
5245+
int retry;
5246+
5247+
(void)os;
5248+
5249+
if (output == NULL) {
5250+
return BUFFER_E;
5251+
}
5252+
5253+
/* enable the TRNG peripheral clock and release it from reset (the
5254+
* reset bit is active low: 0 = held in reset, 1 = released) */
5255+
VOR_SYSCONFIG->PERIPHERAL_CLK_ENABLE |=
5256+
SYSCONFIG_PERIPHERAL_CLK_ENABLE_TRNG_Msk;
5257+
VOR_SYSCONFIG->PERIPHERAL_RESET |=
5258+
SYSCONFIG_PERIPHERAL_RESET_TRNG_Msk;
5259+
5260+
/* mask all interrupts (poll instead) and clear any stale status */
5261+
VOR_TRNG->IMR = TRNG_IMR_EHR_VALID_INT_MASK_Msk |
5262+
TRNG_IMR_AUTOCORR_ERR_INT_MASK_Msk |
5263+
TRNG_IMR_CRNGT_ERR_INT_MASK_Msk |
5264+
TRNG_IMR_VN_ERR_INT_MASK_Msk;
5265+
VOR_TRNG->ICR = TRNG_ICR_EHR_VALID_Msk | TRNG_ICR_AUTOCORR_ERR_Msk |
5266+
TRNG_ICR_CRNGT_ERR_Msk | TRNG_ICR_VN_ERR_Msk;
5267+
5268+
/* select ring-oscillator source, set sample rate, keep health
5269+
* tests enabled (no DEBUG_CONTROL bypass) */
5270+
VOR_TRNG->CONFIG = 0;
5271+
VOR_TRNG->SAMPLE_CNT1 = WOLFSSL_VA416X0_TRNG_SAMPLE_CNT;
5272+
VOR_TRNG->DEBUG_CONTROL = 0;
5273+
5274+
for (i = 0; i < sz; ) {
5275+
retry = 0;
5276+
timeout = WOLFSSL_VA416X0_TRNG_TIMEOUT;
5277+
5278+
/* start entropy collection */
5279+
VOR_TRNG->RND_SOURCE_ENABLE =
5280+
TRNG_RND_SOURCE_ENABLE_RND_SRC_EN_Msk;
5281+
5282+
for (;;) {
5283+
reg = VOR_TRNG->ISR;
5284+
if ((reg & (TRNG_ISR_AUTOCORR_ERR_Msk |
5285+
TRNG_ISR_CRNGT_ERR_Msk |
5286+
TRNG_ISR_VN_ERR_Msk)) != 0) {
5287+
/* health-test failure: stop, clear, re-collect */
5288+
VOR_TRNG->RND_SOURCE_ENABLE = 0;
5289+
VOR_TRNG->ICR = TRNG_ICR_AUTOCORR_ERR_Msk |
5290+
TRNG_ICR_CRNGT_ERR_Msk |
5291+
TRNG_ICR_VN_ERR_Msk;
5292+
if (++retry > WOLFSSL_VA416X0_TRNG_MAX_RETRY) {
5293+
ForceZero(ehr, sizeof(ehr));
5294+
return RNG_FAILURE_E;
5295+
}
5296+
timeout = WOLFSSL_VA416X0_TRNG_TIMEOUT;
5297+
VOR_TRNG->RND_SOURCE_ENABLE =
5298+
TRNG_RND_SOURCE_ENABLE_RND_SRC_EN_Msk;
5299+
continue;
5300+
}
5301+
if ((VOR_TRNG->VALID & TRNG_VALID_EHR_VALID_Msk) != 0) {
5302+
break;
5303+
}
5304+
if (--timeout == 0) {
5305+
VOR_TRNG->RND_SOURCE_ENABLE = 0;
5306+
ForceZero(ehr, sizeof(ehr));
5307+
return RNG_FAILURE_E;
5308+
}
5309+
}
5310+
5311+
/* read 192 bits of entropy (6 x 32-bit words) */
5312+
ehr[0] = VOR_TRNG->EHR_DATA0;
5313+
ehr[1] = VOR_TRNG->EHR_DATA1;
5314+
ehr[2] = VOR_TRNG->EHR_DATA2;
5315+
ehr[3] = VOR_TRNG->EHR_DATA3;
5316+
ehr[4] = VOR_TRNG->EHR_DATA4;
5317+
ehr[5] = VOR_TRNG->EHR_DATA5;
5318+
5319+
/* reading the EHR clears EHR_VALID; stop the source and ack */
5320+
VOR_TRNG->RND_SOURCE_ENABLE = 0;
5321+
VOR_TRNG->ICR = TRNG_ICR_EHR_VALID_Msk;
5322+
5323+
chunk = sz - i;
5324+
if (chunk > sizeof(ehr)) {
5325+
chunk = sizeof(ehr);
5326+
}
5327+
XMEMCPY(&output[i], (byte*)ehr, chunk);
5328+
i += chunk;
5329+
}
5330+
5331+
ForceZero(ehr, sizeof(ehr)); /* scrub seed material from stack */
5332+
return 0;
5333+
}
5334+
51745335
#elif defined(DOLPHIN_EMULATOR) || defined (WOLFSSL_NDS)
51755336

51765337
int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)

0 commit comments

Comments
 (0)