mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-09 17:11:42 +00:00
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>
This commit is contained in:
committed by
chrome-bot
parent
569b5e8f0f
commit
4cbf0cc358
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
70
chip/stm32/trng.c
Normal file
70
chip/stm32/trng.c
Normal file
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -15,6 +15,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.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user