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:
Vincent Palatin
2017-02-21 14:39:52 +01:00
committed by chrome-bot
parent 569b5e8f0f
commit 4cbf0cc358
6 changed files with 102 additions and 0 deletions

View File

@@ -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

View File

@@ -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
View 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;
}

View File

@@ -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

View File

@@ -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 */

View File

@@ -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.
*