Merge branch 'feature/bootloader_rng' into 'master'

Enable bootloader entropy source for RNG

Enables an entropy source when bootloader starts up, which both seeds the RNG for use before WiFi/BT stack is enabled and provides an adequate RNG for secure boot & flash encryption key generation.

A prerequisite was enabling 80MHz operation, so the CPU is now set to 80MHz as soon as second stage bootloader starts running.

See merge request !363
This commit is contained in:
Ivan Grokhotkov
2017-01-07 18:46:10 +08:00
13 changed files with 617 additions and 59 deletions

View File

@@ -25,6 +25,7 @@
#include "rom/rtc.h"
#include "rom/uart.h"
#include "rom/gpio.h"
#include "rom/secure_boot.h"
#include "soc/soc.h"
#include "soc/cpu.h"
@@ -42,8 +43,9 @@
#include "esp_flash_encrypt.h"
#include "esp_flash_partitions.h"
#include "bootloader_flash.h"
#include "bootloader_random.h"
#include "bootloader_config.h"
#include "rtc.h"
extern int _bss_start;
extern int _bss_end;
@@ -232,6 +234,13 @@ static bool ota_select_valid(const esp_ota_select_entry_t *s)
void bootloader_main()
{
/* Set CPU to 80MHz.
Start by ensuring it is set to XTAL, as PLL must be off first
(may still be on due to soft reset.)
*/
rtc_set_cpu_freq(CPU_XTAL);
rtc_set_cpu_freq(CPU_80M);
uart_console_configure();
ESP_LOGI(TAG, "Espressif ESP32 2nd stage bootloader v. %s", BOOT_VERSION);
#if defined(CONFIG_SECURE_BOOT_ENABLED) || defined(CONFIG_FLASH_ENCRYPTION_ENABLED)
@@ -251,6 +260,9 @@ void bootloader_main()
REG_CLR_BIT( TIMG_WDTCONFIG0_REG(0), TIMG_WDT_FLASHBOOT_MOD_EN );
SPIUnlock();
ESP_LOGI(TAG, "Enabling RNG early entropy source...");
bootloader_random_enable();
if(esp_image_load_header(0x1000, true, &fhdr) != ESP_OK) {
ESP_LOGE(TAG, "failed to load bootloader header!");
return;
@@ -362,6 +374,9 @@ void bootloader_main()
}
#endif
ESP_LOGI(TAG, "Disabling RNG early entropy source...");
bootloader_random_disable();
// copy loaded segments to RAM, set up caches for mapped segments, and start application
ESP_LOGI(TAG, "Loading app partition at offset %08x", load_part_pos);
unpack_load_app(&load_part_pos);
@@ -666,49 +681,28 @@ void print_flash_info(const esp_image_header_t* phdr)
#endif
}
#if CONFIG_CONSOLE_UART_CUSTOM
static uint32_t get_apb_freq(void)
{
// Get the value of APB clock from RTC memory.
// The value is initialized in ROM code, and updated by librtc.a
// when APB clock is changed.
// This value is stored in RTC_CNTL_STORE5_REG as follows:
// RTC_CNTL_STORE5_REG = (freq >> 12) | ((freq >> 12) << 16)
uint32_t apb_freq_reg = REG_READ(RTC_CNTL_STORE5_REG);
uint32_t apb_freq_l = apb_freq_reg & 0xffff;
uint32_t apb_freq_h = apb_freq_reg >> 16;
if (apb_freq_l == apb_freq_h && apb_freq_l != 0) {
return apb_freq_l << 12;
} else {
// fallback value
return APB_CLK_FREQ_ROM;
}
}
#endif
static void uart_console_configure(void)
{
#if CONFIG_CONSOLE_UART_NONE
ets_install_putc1(NULL);
ets_install_putc2(NULL);
#else // CONFIG_CONSOLE_UART_NONE
const int uart_num = CONFIG_CONSOLE_UART_NUM;
uartAttach();
ets_install_uart_printf();
#if CONFIG_CONSOLE_UART_CUSTOM
// Some constants to make the following code less upper-case
const int uart_num = CONFIG_CONSOLE_UART_NUM;
const int uart_baud = CONFIG_CONSOLE_UART_BAUDRATE;
const int uart_tx_gpio = CONFIG_CONSOLE_UART_TX_GPIO;
const int uart_rx_gpio = CONFIG_CONSOLE_UART_RX_GPIO;
// ROM bootloader may have put a lot of text into UART0 FIFO.
// Wait for it to be printed.
uart_tx_wait_idle(0);
#if CONFIG_CONSOLE_UART_CUSTOM
// Some constants to make the following code less upper-case
const int uart_tx_gpio = CONFIG_CONSOLE_UART_TX_GPIO;
const int uart_rx_gpio = CONFIG_CONSOLE_UART_RX_GPIO;
// Switch to the new UART (this just changes UART number used for
// ets_printf in ROM code).
uart_tx_switch(uart_num);
// Set new baud rate
uart_div_modify(uart_num, (((uint64_t) get_apb_freq()) << 4) / uart_baud);
// If console is attached to UART1 or if non-default pins are used,
// need to reconfigure pins using GPIO matrix
if (uart_num != 0 || uart_tx_gpio != 1 || uart_rx_gpio != 3) {
@@ -725,5 +719,19 @@ static void uart_console_configure(void)
gpio_matrix_in(uart_rx_gpio, rx_idx, 0);
}
#endif // CONFIG_CONSOLE_UART_CUSTOM
// Set configured UART console baud rate
const int uart_baud = CONFIG_CONSOLE_UART_BAUDRATE;
uart_div_modify(uart_num, (APB_CLK_FREQ << 4) / uart_baud);
#endif // CONFIG_CONSOLE_UART_NONE
}
/* empty rtc_printf implementation, to work with librtc
linking. Can be removed once -lrtc is removed from bootloader's
main component.mk.
*/
int rtc_printf(void)
{
return 0;
}

View File

@@ -10,3 +10,11 @@ LINKER_SCRIPTS := esp32.bootloader.ld $(IDF_PATH)/components/esp32/ld/esp32.rom.
COMPONENT_ADD_LDFLAGS := -L $(COMPONENT_PATH) -lmain $(addprefix -T ,$(LINKER_SCRIPTS))
COMPONENT_ADD_LINKER_DEPS := $(LINKER_SCRIPTS)
ifdef IS_BOOTLOADER_BUILD
# following lines are a workaround to link librtc into the
# bootloader, until clock setting code is in a source-based esp-idf
# component. See also rtc_printf() in bootloader_start.c
COMPONENT_ADD_LDFLAGS += -L $(IDF_PATH)/components/esp32/lib/ -lrtc
COMPONENT_EXTRA_INCLUDES += $(IDF_PATH)/components/esp32/
endif