diff options
-rw-r--r-- | chip/stm32/build.mk | 1 | ||||
-rw-r--r-- | chip/stm32/registers.h | 17 | ||||
-rw-r--r-- | chip/stm32/trng.c | 70 | ||||
-rw-r--r-- | include/config.h | 3 | ||||
-rw-r--r-- | include/software_panic.h | 1 | ||||
-rw-r--r-- | include/trng.h | 10 |
6 files changed, 102 insertions, 0 deletions
diff --git a/chip/stm32/build.mk b/chip/stm32/build.mk index 882e3aa13d..797e4296e3 100644 --- a/chip/stm32/build.mk +++ b/chip/stm32/build.mk @@ -56,6 +56,7 @@ chip-$(CONFIG_ADC)+=adc-$(CHIP_FAMILY).o chip-$(CONFIG_STM32_CHARGER_DETECT)+=charger_detect.o chip-$(CONFIG_DEBUG_PRINTF)+=debug_printf.o chip-$(CONFIG_PWM)+=pwm.o +chip-$(CONFIG_RNG)+=trng.o ifeq ($(CHIP_FAMILY),stm32f4) chip-$(CONFIG_USB)+=usb_dwc.o usb_endpoints.o diff --git a/chip/stm32/registers.h b/chip/stm32/registers.h index 5fde98d02c..c988b33265 100644 --- a/chip/stm32/registers.h +++ b/chip/stm32/registers.h @@ -763,6 +763,7 @@ typedef volatile struct timer_ctlr timer_ctlr_t; #define STM32_RCC_AHB2ENR REG32(STM32_RCC_BASE + 0x4C) #define STM32_RCC_AHB2ENR_GPIOMASK (0xff << 0) +#define STM32_RCC_AHB2ENR_RNGEN (1 << 18) #define STM32_RCC_APB1ENR REG32(STM32_RCC_BASE + 0x58) #define STM32_RCC_PWREN (1 << 28) @@ -849,6 +850,12 @@ typedef volatile struct timer_ctlr timer_ctlr_t; #define STM32_RCC_CSR REG32(STM32_RCC_BASE + 0x94) +#define STM32_RCC_CRRCR REG32(STM32_RCC_BASE + 0x98) + +#define STM32_RCC_CRRCR_HSI48ON (1<<0) +#define STM32_RCC_CRRCR_HSI48RDY (1<<1) +#define STM32_RCC_CRRCR_HSI48CAL_MASK (0x1ff<<7) + #define STM32_RCC_PB2_TIM1 (1 << 11) #define STM32_RCC_PB2_TIM8 (1 << 13) @@ -2157,6 +2164,16 @@ typedef volatile struct stm32_dma_regs stm32_dma_regs_t; STM32_USB_EP(n) = (((STM32_USB_EP(n) & (EP_MASK | (mask))) \ ^ (val)) | (flags)) +/* --- TRNG --- */ +#define STM32_RNG_BASE 0x50060800 /* STM32L4 */ + +#define STM32_RNG_CR REG32(STM32_RNG_BASE + 0x0) +#define STM32_RNG_CR_RNGEN (1<<2) +#define STM32_RNG_CR_IE (1<<3) +#define STM32_RNG_SR REG32(STM32_RNG_BASE + 0x4) +#define STM32_RNG_SR_DRDY (1<<0) +#define STM32_RNG_DR REG32(STM32_RNG_BASE + 0x8) + /* --- MISC --- */ #define STM32_UNIQUE_ID 0x1ffff7ac diff --git a/chip/stm32/trng.c b/chip/stm32/trng.c new file mode 100644 index 0000000000..e19f93d688 --- /dev/null +++ b/chip/stm32/trng.c @@ -0,0 +1,70 @@ +/* Copyright 2017 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Hardware Random Number Generator */ + +#include "common.h" +#include "panic.h" +#include "registers.h" +#include "task.h" +#include "trng.h" +#include "util.h" + +uint32_t rand(void) +{ + int tries = 40; + /* Wait for a valid random number */ + while (!(STM32_RNG_SR & STM32_RNG_SR_DRDY) && --tries) + ; + /* we cannot afford to feed the caller with a dummy number */ + if (!tries) + software_panic(PANIC_SW_BAD_RNG, task_get_current()); + /* Finally the 32-bit of entropy */ + return STM32_RNG_DR; +} + +void rand_bytes(void *buffer, size_t len) +{ + while (len) { + uint32_t number = rand(); + size_t cnt = 4; + /* deal with the lack of alignment guarantee in the API */ + uintptr_t align = (uintptr_t)buffer & 3; + + if (len < 4 || align) { + cnt = MIN(4 - align, len); + memcpy(buffer, &number, cnt); + } else { + *(uint32_t *)buffer = number; + } + len -= cnt; + buffer += cnt; + } +} + +void init_trng(void) +{ + /* Enable the 48Mhz internal RC oscillator */ + STM32_RCC_CRRCR |= STM32_RCC_CRRCR_HSI48ON; + /* no timeout: we watchdog if the oscillator doesn't start */ + while (!(STM32_RCC_CRRCR & STM32_RCC_CRRCR_HSI48RDY)) + ; + + /* Clock the TRNG using the HSI48 */ + STM32_RCC_CCIPR = (STM32_RCC_CCIPR & ~STM32_RCC_CCIPR_CLK48SEL_MASK) + | (0 << STM32_RCC_CCIPR_CLK48SEL_SHIFT); + + /* Enable the RNG logic */ + STM32_RCC_AHB2ENR |= STM32_RCC_AHB2ENR_RNGEN; + /* Start the random number generation */ + STM32_RNG_CR |= STM32_RNG_CR_RNGEN; +} + +void exit_trng(void) +{ + STM32_RNG_CR &= ~STM32_RNG_CR_RNGEN; + STM32_RCC_AHB2ENR &= ~STM32_RCC_AHB2ENR_RNGEN; + STM32_RCC_CRRCR &= ~STM32_RCC_CRRCR_HSI48ON; +} diff --git a/include/config.h b/include/config.h index 3b452b5a47..f6b8c2a443 100644 --- a/include/config.h +++ b/include/config.h @@ -1749,6 +1749,9 @@ /* Support IR357x Link voltage regulator debugging / reprogramming */ #undef CONFIG_REGULATOR_IR357X +/* Enable hardware Random Number generator support */ +#undef CONFIG_RNG + /* Support verifying 2048-bit RSA signature */ #undef CONFIG_RSA diff --git a/include/software_panic.h b/include/software_panic.h index 15070f95ed..4afc20b184 100644 --- a/include/software_panic.h +++ b/include/software_panic.h @@ -20,5 +20,6 @@ #define PANIC_SW_PD_CRASH (PANIC_SW_BASE + 2) #define PANIC_SW_ASSERT (PANIC_SW_BASE + 3) #define PANIC_SW_WATCHDOG (PANIC_SW_BASE + 4) +#define PANIC_SW_BAD_RNG (PANIC_SW_BASE + 5) #endif /* __CROS_EC_SOFTWARE_PANIC_H */ diff --git a/include/trng.h b/include/trng.h index fed113c196..ec56829e54 100644 --- a/include/trng.h +++ b/include/trng.h @@ -16,6 +16,16 @@ void init_trng(void); /** + * Shutdown the true random number generator. + * + * The opposite operation of init_trng(), disable the hardware resources + * used by the TRNG to save power. + * + * Not supported by all platforms. + **/ +void exit_trng(void); + +/** * Retrieve a 32 bit random value. * * Not supported on all platforms. |