This commit is contained in:
Peter D. Gray 2021-05-21 13:55:34 -04:00
parent 37e4af5451
commit 2ce4b88980
No known key found for this signature in database
GPG Key ID: F0E6CC6AFC16CF7B
19 changed files with 360 additions and 81 deletions

View File

@ -50,6 +50,8 @@ BL_FLASH_BASE = 0x08000000
BL_FLASH_SIZE = 0xe000
BL_FLASH_LAST = 0x0800e000
MPY_FLASH_BASE = 0x08010000
# Final 8k bytes of flash reserved for secret data (not code)
# - must be page-aligned, contains pairing secret
BL_NVROM_BASE = 0x0800e000 # = BL_FLASH_LAST
@ -100,6 +102,7 @@ LDFLAGS += -Wl,-Map=$(TARGET_NAME).map
ASFLAGS += -Wa,--defsym,BL_FLASH_BASE=$(BL_FLASH_BASE) -Wa,--defsym,BL_FLASH_SIZE=$(BL_FLASH_SIZE)
ASFLAGS += -Wa,--defsym,BL_SRAM_BASE=$(BL_SRAM_BASE) -Wa,--defsym,BL_SRAM_SIZE=$(BL_SRAM_SIZE)
ASFLAGS += -Wa,--defsym,MPY_FLASH_BASE=$(MPY_FLASH_BASE)
TARGET_ELF = $(TARGET_NAME).elf
@ -152,8 +155,11 @@ dfu-slow: $(TARGET_NAME).dfu
dfu-util -d 0483:df11 -a 0 -D $<
dfu: $(TARGET_NAME).dfu
echo 'dfu' | nc localhost 4444
$(PYTHON_DO_DFU) -u $<
up: dfu
# upload current production version (or latest release version anyway)
latest:
$(PYTHON_DO_DFU) -u `ls -t1 releases/*/bootloader.dfu | head -1`

View File

@ -3,6 +3,7 @@
*/
#include "basics.h"
#include "ae.h"
#include "clocks.h"
#include "rng.h"
#include "delay.h"
#include "faster_sha256.h"
@ -12,6 +13,7 @@
#include "stm32l4xx_hal.h"
#include "ae_config.h"
#include "oled.h"
#include "console.h"
#include <errno.h>
#include <string.h>
@ -24,6 +26,11 @@
# define ERR(msg)
# define ERRV(val, msg)
#endif
#if 0
// affects timing
# define ERR(msg) puts(msg)
# define ERRV(val, msg) do { puts2(msg); puts2(": "); puthex2(val); putchar('\n'); } while(0)
#endif
// Must be exactly 32 chars:
static const char *copyright_msg = "Copyright 2018- by Coinkite Inc.";
@ -367,7 +374,13 @@ ae_setup(void)
MY_UART->RTOR = 24; // timeout in bit periods: 3 chars or so
MY_UART->CR2 = USART_CR2_RTOEN; // rx timeout enable
MY_UART->CR3 = USART_CR3_HDSEL | USART_CR3_ONEBIT;
MY_UART->BRR = 0x0000015b; // 230400 bps
#if HCLK_FREQUENCY == 80000000
MY_UART->BRR = 0x0000015b; // 230400 bps @ 80 Mhz SYSCLK
#elif HCLK_FREQUENCY == 120000000
MY_UART->BRR = 521; // 230400 bps @ 120 Mhz SYSCLK
#else
# error "needs math"
#endif
// clear rx timeout flag
MY_UART->ICR = USART_ICR_RTOCF;
@ -375,7 +388,7 @@ ae_setup(void)
// finally enable UART
MY_UART->CR1 |= USART_CR1_UE;
// configure pin A0 to be AF8_UART4, PULL_NONE
// configure pin A0 to be AFx_UARTy, PULL_NONE
gpio_setup();
// mark it as ready

View File

@ -31,18 +31,34 @@
#include "stm32l4xx_hal.h"
// HSE is used and is 8MHz
// - not doing a complete setup here, but enough
// - expect mainline code to refine this more
// - doing a complete setup here, and not changing in MicroPython anymore
// - this chip is well made and can handle later changes to clocks
// - lots of internal RC osc we can use as well... HSI, MSI and HSI48
#define CKCC_CLK_PLLN (40)
#define CKCC_CLK_PLLM (2)
#define CKCC_CLK_PLLR (2)
#define CKCC_CLK_PLLP (7)
#define CKCC_CLK_PLLQ (4)
#if HCLK_FREQUENCY == 80000000
// To get 80Mhz for SYSCLK...
// 8Mhz (HSE) => /2 (M) *40 (N) /2 (R) => 80Mhz
// expected value of HAL_RCC_GetHCLKFreq(): 80Mhz
#define HCLK_FREQUENCY 80000000
# define CKCC_CLK_PLLM (2)
# define CKCC_CLK_PLLN (40)
# define CKCC_CLK_PLLR (2)
# define CKCC_CLK_PLLP (7)
# define CKCC_CLK_PLLQ (4)
#endif
#if HCLK_FREQUENCY == 120000000
// For for 120Mhz SYSCLK...
// 8Mhz (HSE) => /2 (M) *60 (N) /2 (R) => 120Mhz
// R output => main sysclk (target 120)
// Q output => should be 48Mhz for RNG and OCTOSPI maybe
# define CKCC_CLK_PLLM (2)
# define CKCC_CLK_PLLN (60)
# define CKCC_CLK_PLLR (2)
# define CKCC_CLK_PLLP (7)
# define CKCC_CLK_PLLQ (5)
#endif
// systick_setup()
//
@ -64,6 +80,9 @@ clocks_setup(void)
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_OscInitTypeDef RCC_OscInitStruct;
// setup power supplies
HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1_BOOST);
// Configure LSE Drive Capability
__HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_LOW);
@ -95,7 +114,7 @@ clocks_setup(void)
HAL_RCC_OscConfig(&RCC_OscInitStruct);
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4);
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);
// DIS-able MSI-Hardware auto calibration mode with LSE
CLEAR_BIT(RCC->CR, RCC_CR_MSIPLLEN);
@ -112,7 +131,7 @@ clocks_setup(void)
PeriphClkInitStruct.Sai1ClockSelection = RCC_SAI1CLKSOURCE_PLLSAI1;
PeriphClkInitStruct.AdcClockSelection = RCC_ADCCLKSOURCE_PLLSAI1;
PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_PLLSAI1;
PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE; // XXX wrong?
PeriphClkInitStruct.RngClockSelection = RCC_RNGCLKSOURCE_PLLSAI1;
PeriphClkInitStruct.PLLSAI1.PLLSAI1Source = RCC_PLLSOURCE_HSE;
@ -128,10 +147,17 @@ clocks_setup(void)
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
__HAL_RCC_RTC_ENABLE();
__HAL_RCC_HASH_CLK_ENABLE();
__HAL_RCC_HASH_CLK_ENABLE(); // for SHA256
__HAL_RCC_SPI1_CLK_ENABLE(); // for OLED
__HAL_RCC_SPI2_CLK_ENABLE(); // for SPI flash
//__HAL_RCC_DMA1_CLK_ENABLE(); // for SPI from mpy
//__HAL_RCC_DMA2_CLK_ENABLE(); // might not need
__HAL_RCC_DMAMUX1_CLK_ENABLE(); // because code missing in mpy?
// setup SYSTICK, but we don't have the irq hooked up and not using HAL
// but we use it in polling mode for delay_ms()
systick_setup();
}
// EOF

View File

@ -3,6 +3,8 @@
*/
#pragma once
#define HCLK_FREQUENCY 120000000
// call once at startup
void clocks_setup(void);

View File

@ -212,6 +212,16 @@ hex_dump(const void *d, int len)
#define USART_TEACK_REACK_TIMEOUT 1000U /*!< USART TX or RX enable acknowledge time-out value */
#define USART_DUMMY_DATA ((uint16_t) 0xFFFF) /*!< USART transmitted dummy data */
// WaitOnFlag()
//
static void
WaitOnFlag(uint32_t Flag, FlagStatus Status)
{
while((((MY_UART->ISR & Flag) == Flag) ? SET : RESET) == Status) {
;
}
}
/**
* @brief Handle USART Communication Timeout.
* @param husart USART handle.
@ -481,6 +491,30 @@ HAL_StatusTypeDef HAL_USART_Init(USART_HandleTypeDef *husart)
*/
HAL_StatusTypeDef HAL_USART_Transmit(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size, uint32_t Timeout)
{
while(Size > 0U) {
while(!(MY_UART->ISR & UART_FLAG_TXE)) {
// wait to be able send
}
MY_UART->TDR = *pTxData;
pTxData++;
Size --;
}
while(!(MY_UART->ISR & UART_FLAG_TC)) {
// wait for final byte to be sent
}
// Clear Transmission Complete Flag
MY_UART->ICR = USART_CLEAR_TCF;
// Clear overrun flag and discard the received data
MY_UART->ICR = USART_CLEAR_OREF;
MY_UART->RQR = USART_RXDATA_FLUSH_REQUEST;
MY_UART->RQR = USART_TXDATA_FLUSH_REQUEST;
return HAL_OK;
#if 0
uint8_t *ptxdata8bits;
uint16_t *ptxdata16bits;
uint32_t tickstart;
@ -562,6 +596,7 @@ HAL_StatusTypeDef HAL_USART_Transmit(USART_HandleTypeDef *husart, uint8_t *pTxDa
{
return HAL_BUSY;
}
#endif
}

View File

@ -40,16 +40,19 @@ good_addr(const uint8_t *b, int minlen, int len, bool readonly)
{
uint32_t x = (uint32_t)b;
// XXX needs changes for mk4
if(minlen) {
if(!b) return EFAULT; // gave no buffer
if(len < minlen) return ERANGE; // too small
}
// mk4 is different
STATIC_ASSERT(SRAM1_BASE == BL_SRAM_BASE);
if((x >= SRAM1_BASE) && ((x-SRAM1_BASE) < SRAM1_SIZE_MAX)) {
// inside SRAM1, okay
const uint32_t sram_start = BL_SRAM_BASE + BL_SRAM_SIZE;
const uint32_t sram_end = SRAM3_BASE + SRAM3_SIZE;
if((x >= sram_start) && ((x+len) <= sram_end)) {
// inside the 3 SRAM areas
return 0;
}
@ -97,7 +100,7 @@ firewall_dispatch(int method_num, uint8_t *buf_io, int len_in,
int rv = 0;
#if 0
#if 1
// TODO: re-enable this; causing crash now.
// in case the caller didn't already, but would just lead to a crash anyway
__disable_irq();
@ -169,17 +172,21 @@ firewall_dispatch(int method_num, uint8_t *buf_io, int len_in,
rv = EPERM;
goto fail;
}
puts("Die: DFU");
scr = screen_dfu;
break;
case 1:
// in case some way for Micropython to detect it.
scr = screen_downgrade;
puts("Die: Downgrade");
break;
case 2:
scr = screen_blankish;
puts("Die: Blankish");
break;
case 3:
scr = screen_brick;
puts("Die: Brick");
secure = true; // no point going into DFU, if even possible
break;
}
@ -188,6 +195,7 @@ firewall_dispatch(int method_num, uint8_t *buf_io, int len_in,
oled_show(scr);
wipe_all_sram();
psram_wipe();
if(secure) {
// just die with that message shown; can't start DFU
@ -232,6 +240,8 @@ firewall_dispatch(int method_num, uint8_t *buf_io, int len_in,
// NOT-REACHED (but ok if it does)
}
psram_wipe();
// wait for an interrupt which will never happen (ie. sleep)
LOCKUP_FOREVER()
break;

View File

@ -50,7 +50,7 @@ firewall_setup(void)
uint32_t start = (uint32_t)&firewall_starts;
uint32_t len = BL_FLASH_SIZE - (start - BL_FLASH_BASE);
#if 0
#if 1
ASSERT(start);
ASSERT(!(start & 0xff));
ASSERT(len>256);
@ -65,14 +65,13 @@ firewall_setup(void)
// - many of the bits in these registers are not-implemented and are forced to zero
// - that prevents the firewall being used for things like protecting OTP area
// - (Mk1-3) volatile data is SRAM1 only, so doesn't help us, since we're using SRAM2
// - (Mk4) we are in SRAM1, so we could protect all our RAM ... but errata 2.4.2 fucks that
// - on-chip DFU will erase up to start (0x300), which borks the reset vector
// but sensitive stuff is still there (which would allow bypass)
// - so it's important to enable option bytes to set write-protect on entire bootloader
// - to disable debug and complete protection, must enable write-protect "level 2"
//
// XXX TODO: protect part SRAM1 for us to use?
FIREWALL_InitTypeDef init = {
.CodeSegmentStartAddress = start,
.CodeSegmentLength = len,

View File

@ -25,11 +25,14 @@ gpio_setup(void)
// - try not to limit PCB changes for future revs; leave unused unchanged.
// - oled_setup() uses pins on PA4 thru PA8
// enable clock to that part of chip
// enable clock to GPIO's ... we will be using them all at some point
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOE_CLK_ENABLE();
{ // Onewire bus pins used for ATECC508A comms
{ // Onewire bus pins used for ATECC608 comms
GPIO_InitTypeDef setup = {
.Pin = ONEWIRE_PIN,
.Mode = GPIO_MODE_AF_OD,
@ -45,8 +48,11 @@ gpio_setup(void)
HAL_GPIO_Init(ONEWIRE_PORT, &setup);
}
// debug console: USART1 = PA9=Tx & PA10=Rx
{ GPIO_InitTypeDef setup = {
// Bugfix: re-init of console port pins seems to wreck
// the mpy uart code, so avoid after first time.
if(USART1->BRR == 0) {
// debug console: USART1 = PA9=Tx & PA10=Rx
GPIO_InitTypeDef setup = {
.Pin = GPIO_PIN_9,
.Mode = GPIO_MODE_AF_PP,
.Pull = GPIO_NOPULL,
@ -70,9 +76,30 @@ gpio_setup(void)
};
HAL_GPIO_Init(GPIOC, &setup);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, 1); // turn on
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, 0); // turn LED off
}
#if 0
// TEST CODE -- keep
// enable MCO=PA8 for clock watching. Conflicts w/ OLED normal use.
GPIO_InitTypeDef mco_setup = {
.Pin = GPIO_PIN_8,
.Mode = GPIO_MODE_AF_PP,
.Pull = GPIO_NOPULL,
.Speed = GPIO_SPEED_FREQ_VERY_HIGH,
.Alternate = GPIO_AF0_MCO,
};
HAL_GPIO_Init(GPIOA, &mco_setup);
// select a signal to view here.
// RCC_MCO1SOURCE_SYSCLK => 120Mhz (correct)
// RCC_MCO1SOURCE_PLLCLK (PLL R output) => (same os SYSCLK)
// RCC_MCO1SOURCE_HSI48 => 48Mhz
// RCC_MCO1SOURCE_HSE => 8Mhz (correct)
__HAL_RCC_MCO1_CONFIG(RCC_MCO1SOURCE_SYSCLK, RCC_MCODIV_1);
#endif
#if 0
__HAL_RCC_GPIOB_CLK_ENABLE();
@ -94,4 +121,5 @@ gpio_setup(void)
#endif
}
// EOF

View File

@ -34,6 +34,7 @@ uint32_t HAL_PWREx_GetVoltageRange(void)
}
else
{
// NOTE: this is expected value for this project.
return PWR_REGULATOR_VOLTAGE_SCALE1_BOOST;
}
#else
@ -42,4 +43,140 @@ uint32_t HAL_PWREx_GetVoltageRange(void)
}
/**
* @brief Configure the main internal regulator output voltage.
* @param VoltageScaling specifies the regulator output voltage to achieve
* a tradeoff between performance and power consumption.
* This parameter can be one of the following values:
@if STM32L4S9xx
* @arg @ref PWR_REGULATOR_VOLTAGE_SCALE1_BOOST when available, Regulator voltage output range 1 boost mode,
* typical output voltage at 1.2 V,
* system frequency up to 120 MHz.
@endif
* @arg @ref PWR_REGULATOR_VOLTAGE_SCALE1 Regulator voltage output range 1 mode,
* typical output voltage at 1.2 V,
* system frequency up to 80 MHz.
* @arg @ref PWR_REGULATOR_VOLTAGE_SCALE2 Regulator voltage output range 2 mode,
* typical output voltage at 1.0 V,
* system frequency up to 26 MHz.
* @note When moving from Range 1 to Range 2, the system frequency must be decreased to
* a value below 26 MHz before calling HAL_PWREx_ControlVoltageScaling() API.
* When moving from Range 2 to Range 1, the system frequency can be increased to
* a value up to 80 MHz after calling HAL_PWREx_ControlVoltageScaling() API. For
* some devices, the system frequency can be increased up to 120 MHz.
* @note When moving from Range 2 to Range 1, the API waits for VOSF flag to be
* cleared before returning the status. If the flag is not cleared within
* 50 microseconds, HAL_TIMEOUT status is reported.
* @retval HAL Status
*/
#define PWR_FLAG_SETTING_DELAY_US 50UL /*!< Time out value for REGLPF and VOSF flags setting */
HAL_StatusTypeDef HAL_PWREx_ControlVoltageScaling(uint32_t VoltageScaling)
{
uint32_t wait_loop_index;
assert_param(IS_PWR_VOLTAGE_SCALING_RANGE(VoltageScaling));
#if defined(PWR_CR5_R1MODE)
if (VoltageScaling == PWR_REGULATOR_VOLTAGE_SCALE1_BOOST)
{
/* If current range is range 2 */
if (READ_BIT(PWR->CR1, PWR_CR1_VOS) == PWR_REGULATOR_VOLTAGE_SCALE2)
{
/* Make sure Range 1 Boost is enabled */
CLEAR_BIT(PWR->CR5, PWR_CR5_R1MODE);
/* Set Range 1 */
MODIFY_REG(PWR->CR1, PWR_CR1_VOS, PWR_REGULATOR_VOLTAGE_SCALE1);
/* Wait until VOSF is cleared */
wait_loop_index = ((PWR_FLAG_SETTING_DELAY_US * SystemCoreClock) / 1000000U) + 1;
while ((HAL_IS_BIT_SET(PWR->SR2, PWR_SR2_VOSF)) && (wait_loop_index != 0U))
{
wait_loop_index--;
}
if (HAL_IS_BIT_SET(PWR->SR2, PWR_SR2_VOSF))
{
return HAL_TIMEOUT;
}
}
/* If current range is range 1 normal or boost mode */
else
{
/* Enable Range 1 Boost (no issue if bit already reset) */
CLEAR_BIT(PWR->CR5, PWR_CR5_R1MODE);
}
}
else if (VoltageScaling == PWR_REGULATOR_VOLTAGE_SCALE1)
{
/* If current range is range 2 */
if (READ_BIT(PWR->CR1, PWR_CR1_VOS) == PWR_REGULATOR_VOLTAGE_SCALE2)
{
/* Make sure Range 1 Boost is disabled */
SET_BIT(PWR->CR5, PWR_CR5_R1MODE);
/* Set Range 1 */
MODIFY_REG(PWR->CR1, PWR_CR1_VOS, PWR_REGULATOR_VOLTAGE_SCALE1);
/* Wait until VOSF is cleared */
wait_loop_index = ((PWR_FLAG_SETTING_DELAY_US * SystemCoreClock) / 1000000U) + 1;
while ((HAL_IS_BIT_SET(PWR->SR2, PWR_SR2_VOSF)) && (wait_loop_index != 0U))
{
wait_loop_index--;
}
if (HAL_IS_BIT_SET(PWR->SR2, PWR_SR2_VOSF))
{
return HAL_TIMEOUT;
}
}
/* If current range is range 1 normal or boost mode */
else
{
/* Disable Range 1 Boost (no issue if bit already set) */
SET_BIT(PWR->CR5, PWR_CR5_R1MODE);
}
}
else
{
/* Set Range 2 */
MODIFY_REG(PWR->CR1, PWR_CR1_VOS, PWR_REGULATOR_VOLTAGE_SCALE2);
/* No need to wait for VOSF to be cleared for this transition */
/* PWR_CR5_R1MODE bit setting has no effect in Range 2 */
}
#else
/* If Set Range 1 */
if (VoltageScaling == PWR_REGULATOR_VOLTAGE_SCALE1)
{
if (READ_BIT(PWR->CR1, PWR_CR1_VOS) != PWR_REGULATOR_VOLTAGE_SCALE1)
{
/* Set Range 1 */
MODIFY_REG(PWR->CR1, PWR_CR1_VOS, PWR_REGULATOR_VOLTAGE_SCALE1);
/* Wait until VOSF is cleared */
wait_loop_index = ((PWR_FLAG_SETTING_DELAY_US * SystemCoreClock) / 1000000U) + 1U;
while ((HAL_IS_BIT_SET(PWR->SR2, PWR_SR2_VOSF)) && (wait_loop_index != 0U))
{
wait_loop_index--;
}
if (HAL_IS_BIT_SET(PWR->SR2, PWR_SR2_VOSF))
{
return HAL_TIMEOUT;
}
}
}
else
{
if (READ_BIT(PWR->CR1, PWR_CR1_VOS) != PWR_REGULATOR_VOLTAGE_SCALE2)
{
/* Set Range 2 */
MODIFY_REG(PWR->CR1, PWR_CR1_VOS, PWR_REGULATOR_VOLTAGE_SCALE2);
/* No need to wait for VOSF to be cleared for this transition */
}
}
#endif
return HAL_OK;
}

View File

@ -50,8 +50,8 @@ reboot_seed_setup(void)
// can only do this once, and might be done already
if(SYSCFG->SWPR != (1<<31)) {
ASSERT(((uint32_t)reboot_seed) == 0x10007c00);
ASSERT(((uint32_t)hdr_copy) == RAM_HEADER_BASE);
ASSERT(((uint32_t)reboot_seed) == 0x20007c00);
ASSERT(((uint32_t)hdr_copy) == RAM_HEADER_BASE_MK4);
// populate seed w/ noise
memset(reboot_seed, 0x55, 1024);
@ -149,12 +149,24 @@ system_startup(void)
// wipe all of SRAM (except our own memory, which was already wiped)
wipe_all_sram();
puts("AE setup start");
puts2("AE setup: ");
// secure element setup
ae_setup();
ae_set_gpio(0); // not checking return on purpose
puts("AE setup done");
puts("done");
#if 0
{ uint8_t config[128] = {0};
int x = ae_config_read(config);
if(x == 0) {
puts("config[128]:");
hex_dump(config, 128);
} else {
puts("config read fail");
}
}
#endif
// protect our flash, and/or check it's protected
// - and pick pairing secret if we don't already have one

View File

@ -0,0 +1 @@
../bootloader/mk-sigheader.py

View File

@ -3,12 +3,13 @@
*/
#include "oled.h"
#include "delay.h"
#include "stm32l4xx_hal_gpio.h"
#include "stm32l4xx_hal_rcc.h"
#include "stm32l4xx_hal_dma.h"
#include "stm32l4xx_hal_spi.h"
#include "console.h"
#include "stm32l4xx_hal.h"
#include <string.h>
// OLED pins block use of MCO for testing
#undef DISABLE_OLED
// Reset and config sequence.
//
// As measured! No attempt to understand them here.
@ -48,17 +49,20 @@ static const uint8_t before_show[] = {
#define SPI_SCK GPIO_PIN_5
#define SPI_MOSI GPIO_PIN_7
HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout);
#ifndef DISABLE_OLED
static SPI_HandleTypeDef spi_port;
#endif
// write_bytes()
//
static inline void
write_bytes(int len, const uint8_t *buf)
{
#ifndef DISABLE_OLED
// send via SPI(1)
HAL_SPI_Transmit(&spi_port, (uint8_t *)buf, len, HAL_MAX_DELAY);
#endif
}
// oled_write_cmd()
@ -106,6 +110,7 @@ oled_write_data(int len, const uint8_t *pixels)
void
oled_spi_setup(void)
{
#ifndef DISABLE_OLED
// might already be setup
if(spi_port.Instance == SPI1) return;
@ -126,6 +131,7 @@ oled_spi_setup(void)
spi_port.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED;
HAL_SPI_Init(&spi_port);
#endif
}
// oled_setup()
@ -135,6 +141,10 @@ oled_spi_setup(void)
void
oled_setup(void)
{
#ifdef DISABLE_OLED
puts("oled disabled");return; // disable so I can use MCO
#endif
static uint32_t inited;
if(inited == 0x238a572F) {

View File

@ -291,7 +291,6 @@ pin_prefix_words(const char *pin_prefix, int prefix_len, uint32_t *result)
static void
_hmac_attempt(const pinAttempt_t *args, uint8_t result[32])
{
SHA256_CTX ctx;
sha256_init(&ctx);
@ -307,9 +306,7 @@ _hmac_attempt(const pinAttempt_t *args, uint8_t result[32])
sha256_final(&ctx, result);
// and a second-sha256 on that, just in case.
sha256_init(&ctx);
sha256_update(&ctx, result, 32);
sha256_final(&ctx, result);
sha256_single(result, 32, result);
}
// _validate_attempt()

View File

@ -10,6 +10,7 @@
*/
#include "psram.h"
#include "oled.h"
#include "clocks.h"
#include "assets/screens.h"
#include <string.h>
#include "delay.h"
@ -19,9 +20,13 @@
#include "faster_sha256.h"
#include "misc.h"
#undef INCL_SELFTEST
uint8_t psram_chip_eid[8];
//static void psram_memtest(bool simple);
#ifdef INCL_SELFTEST
static void psram_memtest(bool simple);
#endif
// psram_send_byte()
//
@ -82,7 +87,13 @@ psram_setup(void)
qh.Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_ENABLE; // maybe?
qh.Init.FreeRunningClock = HAL_OSPI_FREERUNCLK_DISABLE; // required!
qh.Init.ClockMode = HAL_OSPI_CLOCK_MODE_0; // low clock between ops (required, see errata)
#if HCLK_FREQUENCY == 80000000
qh.Init.ClockPrescaler = 1; // prescaler (1=>80Mhz, 2=>40Mhz, etc)
#elif HCLK_FREQUENCY == 120000000
qh.Init.ClockPrescaler = 2; // prescaler (1=>120Mhz, 2=>60Mhz, etc)
#else
# error "testing needed"
#endif
qh.Init.DelayBlockBypass = HAL_OSPI_DELAY_BLOCK_BYPASSED; // dont need it?
// ESP-PSRAM64H calls for max of 8us w/ CS low. Needs it for refresh time.
@ -185,13 +196,10 @@ psram_setup(void)
if(rv != HAL_OK) goto fail;
}
#if 0
while(1) {
psram_memtest(1);
psram_memtest(0);
}
#endif
#ifdef INCL_SELFTEST
psram_memtest(1);
psram_memtest(0);
#else
// Only a quick operational check only here. Non-destructive.
{ __IO uint32_t *ptr = (uint32_t *)(PSRAM_BASE+PSRAM_SIZE-4);
uint32_t tmp;
@ -201,6 +209,7 @@ psram_setup(void)
if(*ptr != 0x55aa1234) goto fail;
*ptr = tmp;
}
#endif
return;
@ -218,12 +227,14 @@ fail:
void
psram_wipe(void)
{
if(OCTOSPI1->CR == 0) return; // PSRAM not enabled (yet?)
puts2("PSRAM Wipe: ");
memset4((uint32_t *)PSRAM_BASE, rng_sample(), PSRAM_SIZE);
puts("done");
}
#if 0
#ifdef INCL_SELFTEST
// psram_memtest()
//
static void

View File

@ -0,0 +1 @@
../bootloader/sigheader.h

View File

@ -0,0 +1 @@
../bootloader/sigheader.py

View File

@ -89,8 +89,8 @@ reset_entry:
bl callgate_entry0
// get a ptr to real code
// load R1 with 0x08008000 value: start of firmware's area
movw r1, (0x08008000 >> 12)
// load R1 with first byte of firmware's area
movw r1, (MPY_FLASH_BASE >> 12)
lsl r1, 12
// set stack pointer to their preference

View File

@ -2,8 +2,6 @@
******************************************************************************
* @file stm32l4xx_hal_firewall.c
* @author MCD Application Team
* @version V1.7.2
* @date 16-June-2017
* @brief FIREWALL HAL module driver.
* This file provides firmware functions to manage the Firewall
* Peripheral initialization and enabling.
@ -34,29 +32,13 @@
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
* <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
* All rights reserved.</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
@ -137,19 +119,24 @@ HAL_StatusTypeDef HAL_FIREWALL_Config(FIREWALL_InitTypeDef * fw_init)
/* Check Firewall configuration addresses and lengths when segment is protected */
/* Code segment */
if (fw_init->CodeSegmentLength != 0)
if (fw_init->CodeSegmentLength != 0U)
{
assert_param(IS_FIREWALL_CODE_SEGMENT_ADDRESS(fw_init->CodeSegmentStartAddress));
assert_param(IS_FIREWALL_CODE_SEGMENT_LENGTH(fw_init->CodeSegmentStartAddress, fw_init->CodeSegmentLength));
/* Make sure that NonVDataSegmentLength is properly set to prevent code segment access */
if (fw_init->NonVDataSegmentLength < 0x100U)
{
return HAL_ERROR;
}
}
/* Non volatile data segment */
if (fw_init->NonVDataSegmentLength != 0)
if (fw_init->NonVDataSegmentLength != 0U)
{
assert_param(IS_FIREWALL_NONVOLATILEDATA_SEGMENT_ADDRESS(fw_init->NonVDataSegmentStartAddress));
assert_param(IS_FIREWALL_NONVOLATILEDATA_SEGMENT_LENGTH(fw_init->NonVDataSegmentStartAddress, fw_init->NonVDataSegmentLength));
}
/* Volatile data segment */
if (fw_init->VDataSegmentLength != 0)
if (fw_init->VDataSegmentLength != 0U)
{
assert_param(IS_FIREWALL_VOLATILEDATA_SEGMENT_ADDRESS(fw_init->VDataSegmentStartAddress));
assert_param(IS_FIREWALL_VOLATILEDATA_SEGMENT_LENGTH(fw_init->VDataSegmentStartAddress, fw_init->VDataSegmentLength));
@ -159,21 +146,22 @@ HAL_StatusTypeDef HAL_FIREWALL_Config(FIREWALL_InitTypeDef * fw_init)
assert_param(IS_FIREWALL_VOLATILEDATA_EXECUTE(fw_init->VolatileDataExecution));
assert_param(IS_FIREWALL_VOLATILEDATA_SHARE(fw_init->VolatileDataShared));
/* Configuration */
/* Protected code segment start address configuration */
WRITE_REG(FIREWALL->CSSA, (FW_CSSA_ADD & fw_init->CodeSegmentStartAddress));
/* Protected code segment length configuration */
/* Protected code segment length configuration */
WRITE_REG(FIREWALL->CSL, (FW_CSL_LENG & fw_init->CodeSegmentLength));
/* Protected non volatile data segment start address configuration */
WRITE_REG(FIREWALL->NVDSSA, (FW_NVDSSA_ADD & fw_init->NonVDataSegmentStartAddress));
/* Protected non volatile data segment length configuration */
/* Protected non volatile data segment length configuration */
WRITE_REG(FIREWALL->NVDSL, (FW_NVDSL_LENG & fw_init->NonVDataSegmentLength));
/* Protected volatile data segment start address configuration */
WRITE_REG(FIREWALL->VDSSA, (FW_VDSSA_ADD & fw_init->VDataSegmentStartAddress));
/* Protected volatile data segment length configuration */
/* Protected volatile data segment length configuration */
WRITE_REG(FIREWALL->VDSL, (FW_VDSL_LENG & fw_init->VDataSegmentLength));
/* Set Firewall Configuration Register VDE and VDS bits

View File

@ -237,11 +237,13 @@ verify_firmware(void)
// but only if we arrived at same hash before. It decides.
int not_green = ae_set_gpio_secure(world_check);
#if 0
// XXX change this, no more dev key
// maybe show big warning if not an "approved" key
if(not_green) {
check_factory_key(FW_HDR->pubkey_num);
}
#endif
puts("good firmware");
oled_show_progress(screen_verify, 100);