summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Palatin <vpalatin@chromium.org>2017-02-21 14:39:52 +0100
committerchrome-bot <chrome-bot@chromium.org>2017-02-23 11:36:21 -0800
commit4cbf0cc358a2983a76dc1d732cf158dc15de8629 (patch)
tree5e67e076d0c6ea0ee31f6e25d8f13089f96b0833
parent569b5e8f0f124f08e2c1e3cab27081dfff2e266c (diff)
downloadchrome-ec-4cbf0cc358a2983a76dc1d732cf158dc15de8629.tar.gz
stm32: add TRNG support
Add a driver for the STM32 True Random Number Generator. Signed-off-by: Vincent Palatin <vpalatin@chromium.org> BRANCH=none BUG=chrome-os-partner:62991 TEST=adhoc on STM32L, craft console command and generate/dump buffers of random numbers. Change-Id: Ie7ce890cfc36a3b9a277715b17051e3e42fdfc96 Reviewed-on: https://chromium-review.googlesource.com/445777 Commit-Ready: Vincent Palatin <vpalatin@chromium.org> Tested-by: Vincent Palatin <vpalatin@chromium.org> Reviewed-by: Shawn N <shawnn@chromium.org>
-rw-r--r--chip/stm32/build.mk1
-rw-r--r--chip/stm32/registers.h17
-rw-r--r--chip/stm32/trng.c70
-rw-r--r--include/config.h3
-rw-r--r--include/software_panic.h1
-rw-r--r--include/trng.h10
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.