diff --git a/SConscript.boardloader b/SConscript.boardloader index e31e2fdd3d..322a7a4a0c 100644 --- a/SConscript.boardloader +++ b/SConscript.boardloader @@ -82,6 +82,7 @@ SOURCE_TREZORHAL = [ 'embed/trezorhal/sdcard.c', 'embed/trezorhal/stm32_it.c', 'embed/trezorhal/stm32_system.c', + 'embed/trezorhal/rng.c', ] env = Environment(ENV=os.environ, CFLAGS=ARGUMENTS.get('CFLAGS', '')) diff --git a/embed/boardloader/startup.s b/embed/boardloader/startup.s index 6c746c280b..d3fc26a4e3 100644 --- a/embed/boardloader/startup.s +++ b/embed/boardloader/startup.s @@ -395,7 +395,30 @@ memset_reg: reset_handler: bl SystemInit + // read the first rng data and save it + ldr r0, =0 // r0 - previous value + ldr r1, =0 // r1 - whether to compare the previous value + bl rng_read + + // read the next rng data and make sure it is different than previous + // r0 - value returned from previous call + ldr r1, =1 // r1 - whether to compare the previous value + bl rng_read + mov r4, r0 // save TRNG output in r4 + // wipe memory to remove any possible vestiges of sensitive data + // use unpredictable value as a defense against side-channels + ldr r0, =ccmram_start // r0 - point to beginning of CCMRAM + ldr r1, =ccmram_end // r1 - point to byte after the end of CCMRAM + mov r2, r4 // r2 - the word-sized value to be written + bl memset_reg + + ldr r0, =sram_start // r0 - point to beginning of SRAM + ldr r1, =sram_end // r1 - point to byte after the end of SRAM + mov r2, r4 // r2 - the word-sized value to be written + bl memset_reg + + // setup environment for subsequent stage of code ldr r0, =ccmram_start // r0 - point to beginning of CCMRAM ldr r1, =ccmram_end // r1 - point to byte after the end of CCMRAM ldr r2, =0 // r2 - the word-sized value to be written diff --git a/embed/firmware/main.c b/embed/firmware/main.c index 6ccbfcdc5a..83a98615bc 100644 --- a/embed/firmware/main.c +++ b/embed/firmware/main.c @@ -50,10 +50,6 @@ int main(void) { __fatal_error("flash_init", __FILE__, __LINE__, __FUNCTION__); } - if (0 != rng_init()) { - __fatal_error("rng_init", __FILE__, __LINE__, __FUNCTION__); - } - if (0 != sdcard_init()) { __fatal_error("sdcard_init", __FILE__, __LINE__, __FUNCTION__); } diff --git a/embed/trezorhal/rng.c b/embed/trezorhal/rng.c index 7a0fccf97f..b66e7c8fc0 100644 --- a/embed/trezorhal/rng.c +++ b/embed/trezorhal/rng.c @@ -1,15 +1,33 @@ #include STM32_HAL_H -static RNG_HandleTypeDef rng_handle = { - .Instance = RNG, -}; - -int rng_init(void) { - __HAL_RCC_RNG_CLK_ENABLE(); - HAL_RNG_Init(&rng_handle); +int rng_init(void) +{ + RCC->AHB2ENR |= RCC_AHB2ENR_RNGEN; // enable TRNG peripheral clock + RNG->CR = RNG_CR_RNGEN; // enable TRNG return 0; } -uint32_t rng_get(void) { - return HAL_RNG_GetRandomNumber(&rng_handle); +uint32_t rng_read(const uint32_t previous, const uint32_t compare_previous) +{ + uint32_t temp = previous; + do { + while ((RNG->SR & (RNG_SR_SECS | RNG_SR_CECS | RNG_SR_DRDY)) != RNG_SR_DRDY) { + ; // wait until TRNG is ready + } + temp = RNG->DR; // read the data from the TRNG + } while (compare_previous && (temp == previous)); // RM0090 section 24.3.1 FIPS continuous random number generator test + return temp; +} + +uint32_t rng_get(void) +{ + // reason for keeping history: RM0090 section 24.3.1 FIPS continuous random number generator test + static uint32_t previous = 0, current = 0; + if (previous == current) { + previous = rng_read(previous, 0); + } else { + previous = current; + } + current = rng_read(previous, 1); + return current; } diff --git a/embed/trezorhal/rng.h b/embed/trezorhal/rng.h index fcdb51510a..0aef2538dc 100644 --- a/embed/trezorhal/rng.h +++ b/embed/trezorhal/rng.h @@ -3,5 +3,6 @@ int rng_init(void); uint32_t rng_get(void); +uint32_t rng_read(const uint32_t previous, const uint32_t compare_previous); #endif diff --git a/embed/trezorhal/stm32_system.c b/embed/trezorhal/stm32_system.c index 75525145fd..ac2a38c684 100644 --- a/embed/trezorhal/stm32_system.c +++ b/embed/trezorhal/stm32_system.c @@ -96,6 +96,7 @@ #define MICROPY_HW_CLK_LAST_FREQ (1) #include "common.h" +#include "rng.h" /** * @} @@ -216,6 +217,8 @@ void SystemInit(void) while((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL); // turn off the HSI as it is now unused (it will be turned on again automatically if a clock security failure occurs) RCC->CR &= ~RCC_CR_HSION; + // init the TRNG peripheral + rng_init(); // enable full access to the fpu coprocessor #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */