1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-03-28 14:05:43 +00:00
This commit is contained in:
TychoVrahe 2025-03-20 15:39:44 +01:00 committed by GitHub
commit fdbfd71d6f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
36 changed files with 213 additions and 94 deletions

View File

@ -0,0 +1 @@
Migrate storage to version 6.

View File

@ -1,7 +1,8 @@
/* Auto-generated file, do not edit.*/
NORCOW_SECTOR_SIZE = 0x10000;
FLASH_START = 0x8000000;
NORCOW_SECTOR_SIZE = 0x10000;
NORCOW_MIN_VERSION = 0x0;
BOARDLOADER_START = 0x8000000;
BOARDLOADER_MAXSIZE = 0xc000;
BOARDLOADER_SECTOR_START = 0x0;

View File

@ -31,8 +31,9 @@
// SHARED WITH MAKEFILE
// common
#define NORCOW_SECTOR_SIZE (1 * 64 * 1024) // 64 kB
#define FLASH_START 0x08000000
#define NORCOW_SECTOR_SIZE (1 * 64 * 1024) // 64 kB
#define NORCOW_MIN_VERSION 0x00000000
// FLASH layout
#define BOARDLOADER_START 0x08000000

View File

@ -2,6 +2,7 @@
FLASH_START = 0xc004000;
NORCOW_SECTOR_SIZE = 0x20000;
NORCOW_MIN_VERSION = 0x6;
SECRET_START = 0xc000000;
SECRET_MAXSIZE = 0x4000;
SECRET_SECTOR_START = 0x0;
@ -26,7 +27,6 @@ FIRMWARE_SECTOR_START = 0x22;
FIRMWARE_SECTOR_END = 0x1cf;
KERNEL_START = 0xc044000;
KERNEL_MAXSIZE = 0x80000;
KERNEL_U_FLASH_SIZE = 0x200;
STORAGE_1_START = 0xc3a0000;
STORAGE_1_MAXSIZE = 0x20000;
STORAGE_1_SECTOR_START = 0x1d0;
@ -44,9 +44,7 @@ BOOTARGS_SIZE = 0x200;
FB1_RAM_START = 0x30000200;
FB1_RAM_SIZE = 0xbfe00;
MAIN_RAM_START = 0x300c0000;
MAIN_RAM_SIZE = 0xfe00;
SAES_RAM_START = 0x300cfe00;
SAES_RAM_SIZE = 0x200;
MAIN_RAM_SIZE = 0x10000;
FB2_RAM_START = 0x300d0000;
FB2_RAM_SIZE = 0xc0000;
AUX1_RAM_START = 0x30190000;

View File

@ -34,6 +34,7 @@
// misc
#define FLASH_START 0x0C004000
#define NORCOW_SECTOR_SIZE (16 * 8 * 1024) // 128 kB
#define NORCOW_MIN_VERSION 0x00000006
// FLASH layout
#define SECRET_START 0x0C000000
@ -66,7 +67,6 @@
#define FIRMWARE_SECTOR_END 0x1CF
#define KERNEL_START 0x0C044000
#define KERNEL_MAXSIZE (512 * 1024) // 512 kB
#define KERNEL_U_FLASH_SIZE 512
#define STORAGE_1_START 0x0C3A0000
#define STORAGE_1_MAXSIZE (16 * 8 * 1024) // 128 kB
@ -91,10 +91,7 @@
#define FB1_RAM_SIZE (768 * 1024 - 512)
#define MAIN_RAM_START 0x300C0000
#define MAIN_RAM_SIZE (64 * 1024 - 512)
#define SAES_RAM_START 0x300CFE00
#define SAES_RAM_SIZE 512
#define MAIN_RAM_SIZE (64 * 1024)
#define FB2_RAM_START 0x300D0000
#define FB2_RAM_SIZE (768 * 1024)

View File

@ -1,7 +1,8 @@
/* Auto-generated file, do not edit.*/
NORCOW_SECTOR_SIZE = 0x10000;
FLASH_START = 0x8000000;
NORCOW_SECTOR_SIZE = 0x10000;
NORCOW_MIN_VERSION = 0x0;
BOARDLOADER_START = 0x8000000;
BOARDLOADER_MAXSIZE = 0xc000;
BOARDLOADER_SECTOR_START = 0x0;

View File

@ -32,8 +32,9 @@
// SHARED WITH MAKEFILE
// common
#define NORCOW_SECTOR_SIZE (1 * 64 * 1024) // 64 kB
#define FLASH_START 0x08000000
#define NORCOW_SECTOR_SIZE (1 * 64 * 1024) // 64 kB
#define NORCOW_MIN_VERSION 0x00000000
// FLASH layout
#define BOARDLOADER_START 0x08000000

View File

@ -1,7 +1,8 @@
/* Auto-generated file, do not edit.*/
NORCOW_SECTOR_SIZE = 0x10000;
FLASH_START = 0x8000000;
NORCOW_SECTOR_SIZE = 0x10000;
NORCOW_MIN_VERSION = 0x0;
BOARDLOADER_START = 0x8000000;
BOARDLOADER_MAXSIZE = 0xc000;
BOARDLOADER_SECTOR_START = 0x0;

View File

@ -32,8 +32,9 @@
// SHARED WITH MAKEFILE
// common
#define NORCOW_SECTOR_SIZE (1 * 64 * 1024) // 64 kB
#define FLASH_START 0x08000000
#define NORCOW_SECTOR_SIZE (1 * 64 * 1024) // 64 kB
#define NORCOW_MIN_VERSION 0x00000000
// FLASH layout
#define BOARDLOADER_START 0x08000000

View File

@ -2,6 +2,7 @@
FLASH_START = 0xc004000;
NORCOW_SECTOR_SIZE = 0x10000;
NORCOW_MIN_VERSION = 0x0;
SECRET_START = 0xc000000;
SECRET_MAXSIZE = 0x4000;
SECRET_SECTOR_START = 0x0;

View File

@ -34,6 +34,7 @@
// misc
#define FLASH_START 0x0C004000
#define NORCOW_SECTOR_SIZE (8 * 8 * 1024) // 64 kB
#define NORCOW_MIN_VERSION 0x00000000
// FLASH layout
#define SECRET_START 0x0C000000

View File

@ -2,6 +2,7 @@
FLASH_START = 0xc004000;
NORCOW_SECTOR_SIZE = 0x10000;
NORCOW_MIN_VERSION = 0x0;
SECRET_START = 0xc000000;
SECRET_MAXSIZE = 0x4000;
SECRET_SECTOR_START = 0x0;

View File

@ -34,6 +34,7 @@
// misc
#define FLASH_START 0x0C004000
#define NORCOW_SECTOR_SIZE (8 * 8 * 1024) // 64 kB
#define NORCOW_MIN_VERSION 0x00000000
// FLASH layout
#define SECRET_START 0x0C000000

View File

@ -2,6 +2,7 @@
FLASH_START = 0xc004000;
NORCOW_SECTOR_SIZE = 0x20000;
NORCOW_MIN_VERSION = 0x6;
SECRET_START = 0xc000000;
SECRET_MAXSIZE = 0x4000;
SECRET_SECTOR_START = 0x0;
@ -26,7 +27,6 @@ FIRMWARE_SECTOR_START = 0x22;
FIRMWARE_SECTOR_END = 0x1cf;
KERNEL_START = 0xc044000;
KERNEL_MAXSIZE = 0x80000;
KERNEL_U_FLASH_SIZE = 0x200;
STORAGE_1_START = 0xc3a0000;
STORAGE_1_MAXSIZE = 0x20000;
STORAGE_1_SECTOR_START = 0x1d0;
@ -44,9 +44,7 @@ BOOTARGS_SIZE = 0x200;
FB1_RAM_START = 0x30000200;
FB1_RAM_SIZE = 0xbfe00;
MAIN_RAM_START = 0x300c0000;
MAIN_RAM_SIZE = 0xfe00;
SAES_RAM_START = 0x300cfe00;
SAES_RAM_SIZE = 0x200;
MAIN_RAM_SIZE = 0x10000;
FB2_RAM_START = 0x300d0000;
FB2_RAM_SIZE = 0xc0000;
AUX1_RAM_START = 0x30190000;

View File

@ -33,6 +33,7 @@
// misc
#define FLASH_START 0x0C004000
#define NORCOW_SECTOR_SIZE (16 * 8 * 1024) // 128 kB
#define NORCOW_MIN_VERSION 0x00000006
// FLASH layout
#define SECRET_START 0x0C000000
@ -65,7 +66,6 @@
#define FIRMWARE_SECTOR_END 0x1CF
#define KERNEL_START 0x0C044000
#define KERNEL_MAXSIZE (512 * 1024) // 512 kB
#define KERNEL_U_FLASH_SIZE 512
#define STORAGE_1_START 0x0C3A0000
#define STORAGE_1_MAXSIZE (16 * 8 * 1024) // 128 kB
@ -90,10 +90,7 @@
#define FB1_RAM_SIZE (768 * 1024 - 512)
#define MAIN_RAM_START 0x300C0000
#define MAIN_RAM_SIZE (64 * 1024 - 512)
#define SAES_RAM_START 0x300CFE00
#define SAES_RAM_SIZE 512
#define MAIN_RAM_SIZE (64 * 1024)
#define FB2_RAM_START 0x300D0000
#define FB2_RAM_SIZE (768 * 1024)

View File

@ -3,11 +3,11 @@
#include "model_version.h"
#define VERSION_MAJOR 2
#define VERSION_MINOR 8
#define VERSION_PATCH 10
#define VERSION_MINOR 9
#define VERSION_PATCH 0
#define VERSION_BUILD 0
#define FIX_VERSION_MAJOR 2
#define FIX_VERSION_MINOR 8
#define FIX_VERSION_MINOR 9
#define FIX_VERSION_PATCH 0
#define FIX_VERSION_BUILD 0

View File

@ -24,12 +24,6 @@
#include <stm32u5xx_hal_cryp.h>
#include <sec/secure_aes.h>
#include <sys/mpu.h>
#include <sys/syscall.h>
#ifdef USE_TRUSTZONE
#include <sys/trustzone.h>
#endif
#include "memzero.h"
@ -38,8 +32,6 @@
#ifdef KERNEL_MODE
#include <sys/irq.h>
static void secure_aes_load_bhk(void) {
TAMP->BKP0R;
TAMP->BKP1R;
@ -76,8 +68,18 @@ static secbool is_key_supported(secure_aes_keysel_t key) {
}
}
#if NORCOW_MIN_VERSION <= 5
#ifdef SYSCALL_DISPATCH
#include <sys/mpu.h>
#include <sys/syscall.h>
#ifdef USE_TRUSTZONE
#include <sys/trustzone.h>
#endif
#include <sys/irq.h>
__attribute__((section(".udata")))
uint32_t saes_input[SAES_DATA_SIZE_WITH_UPRIV_KEY / sizeof(uint32_t)];
@ -220,13 +222,16 @@ secbool unpriv_encrypt(const uint8_t* input, size_t size, uint8_t* output,
return retval;
}
#endif
#endif
secbool secure_aes_ecb_encrypt_hw(const uint8_t* input, size_t size,
uint8_t* output, secure_aes_keysel_t key) {
#if NORCOW_MIN_VERSION <= 5
#ifdef SYSCALL_DISPATCH
if (key == SECURE_AES_KEY_XORK_SN) {
return unpriv_encrypt(input, size, output, key);
}
#endif
#endif
if (sectrue != is_key_supported(key)) {

View File

@ -9,7 +9,6 @@ MEMORY {
MAIN_RAM (wal) : ORIGIN = MAIN_RAM_START, LENGTH = MAIN_RAM_SIZE
AUX1_RAM (wal) : ORIGIN = AUX1_RAM_START, LENGTH = AUX1_RAM_SIZE
BOOT_ARGS (wal) : ORIGIN = BOOTARGS_START, LENGTH = BOOTARGS_SIZE
SAES_RAM (wal) : ORIGIN = SAES_RAM_START, LENGTH = SAES_RAM_SIZE
FB1_RAM (wal) : ORIGIN = FB1_RAM_START, LENGTH = FB1_RAM_SIZE
FB2_RAM (wal) : ORIGIN = FB2_RAM_START, LENGTH = FB2_RAM_SIZE
}

View File

@ -8,7 +8,6 @@ MEMORY {
MAIN_RAM (wal) : ORIGIN = MAIN_RAM_START, LENGTH = MAIN_RAM_SIZE
AUX1_RAM (wal) : ORIGIN = AUX1_RAM_START, LENGTH = AUX1_RAM_SIZE
BOOT_ARGS (wal) : ORIGIN = BOOTARGS_START, LENGTH = BOOTARGS_SIZE
SAES_RAM (wal) : ORIGIN = SAES_RAM_START, LENGTH = SAES_RAM_SIZE
FB1_RAM (wal) : ORIGIN = FB1_RAM_START, LENGTH = FB1_RAM_SIZE
FB2_RAM (wal) : ORIGIN = FB2_RAM_START, LENGTH = FB2_RAM_SIZE
}

View File

@ -7,7 +7,6 @@ MEMORY {
MAIN_RAM (wal) : ORIGIN = MAIN_RAM_START, LENGTH = MAIN_RAM_SIZE
BOOT_ARGS (wal) : ORIGIN = BOOTARGS_START, LENGTH = BOOTARGS_SIZE
SAES_RAM (wal) : ORIGIN = SAES_RAM_START, LENGTH = SAES_RAM_SIZE
FB1_RAM (wal) : ORIGIN = FB1_RAM_START, LENGTH = FB1_RAM_SIZE
FB2_RAM (wal) : ORIGIN = FB2_RAM_START, LENGTH = FB2_RAM_SIZE
}
@ -15,11 +14,6 @@ MEMORY {
_stack_section_start = ADDR(.stack);
_stack_section_end = ADDR(.stack) + SIZEOF(.stack);
ustack_base = ADDR(.udata) + 512;
_sustack = ADDR(.udata) + 256;
_eustack = ustack_base;
_data_section_loadaddr = LOADADDR(.data);
_data_section_start = ADDR(.data);
_data_section_end = ADDR(.data) + SIZEOF(.data);
@ -39,13 +33,10 @@ _accessible_ram_1_end = MCU_SRAM4 + MCU_SRAM4_SIZE;
_bootargs_ram_start = BOOTARGS_START;
_bootargs_ram_end = BOOTARGS_START + BOOTARGS_SIZE;
_codelen = SIZEOF(.vendorheader) + SIZEOF(.header) + SIZEOF(.flash) + SIZEOF(.uflash) + SIZEOF(.data) + SIZEOF(.confidential);
_codelen = SIZEOF(.vendorheader) + SIZEOF(.header) + SIZEOF(.flash) + SIZEOF(.data) + SIZEOF(.confidential);
_flash_start = ORIGIN(FLASH);
_flash_end = ORIGIN(FLASH) + LENGTH(FLASH);
_uflash_start = ADDR(.uflash);
_uflash_end = ADDR(.uflash) + SIZEOF(.uflash);
SECTIONS {
.vendorheader : ALIGN(4) {
KEEP(*(.vendorheader))
@ -87,23 +78,11 @@ SECTIONS {
. = ALIGN(4);
} >MAIN_RAM
/* unprivileged data and stack for SAES */
.udata : ALIGN(512) {
*(.udata*);
. = ALIGN(256);
. = 256; /* Overflow causes UsageFault */
} >SAES_RAM
.confidential : ALIGN(512) {
*(.confidential*);
. = ALIGN(512);
} >MAIN_RAM AT>FLASH
.uflash : ALIGN(512) {
*(.uflash*);
. = ALIGN(COREAPP_ALIGNMENT);
} >FLASH AT>FLASH
.fb1 : ALIGN(4) {
*(.fb1*);
. = ALIGN(4);

View File

@ -8,7 +8,6 @@ MEMORY {
MAIN_RAM (wal) : ORIGIN = MAIN_RAM_START, LENGTH = MAIN_RAM_SIZE
AUX1_RAM (wal) : ORIGIN = AUX1_RAM_START, LENGTH = AUX1_RAM_SIZE
BOOT_ARGS (wal) : ORIGIN = BOOTARGS_START, LENGTH = BOOTARGS_SIZE
SAES_RAM (wal) : ORIGIN = SAES_RAM_START, LENGTH = SAES_RAM_SIZE
FB1_RAM (wal) : ORIGIN = FB1_RAM_START, LENGTH = FB1_RAM_SIZE
FB2_RAM (wal) : ORIGIN = FB2_RAM_START, LENGTH = FB2_RAM_SIZE
}

View File

@ -143,6 +143,7 @@ _Static_assert(NORCOW_SECTOR_SIZE == STORAGE_2_MAXSIZE, "norcow misconfigured");
#ifdef KERNEL
#ifdef KERNEL_FLASH_U_START
extern uint8_t _uflash_start;
extern uint8_t _uflash_end;
#define KERNEL_FLASH_U_START (uint32_t) & _uflash_start
@ -159,6 +160,20 @@ extern uint32_t _codelen;
#define COREAPP_FLASH_SIZE \
(FIRMWARE_MAXSIZE - (COREAPP_FLASH_START - KERNEL_FLASH_START))
#else
extern uint32_t _codelen;
#define KERNEL_SIZE (uint32_t) & _codelen
#define KERNEL_FLASH_START KERNEL_START
#define KERNEL_FLASH_SIZE KERNEL_SIZE
#define COREAPP_FLASH_START \
(COREAPP_CODE_ALIGN(KERNEL_FLASH_START + KERNEL_SIZE))
#define COREAPP_FLASH_SIZE \
(FIRMWARE_MAXSIZE - (COREAPP_FLASH_START - KERNEL_FLASH_START))
#endif
#endif
typedef struct {
@ -402,7 +417,9 @@ mpu_mode_t mpu_reconfig(mpu_mode_t mode) {
// REGION ADDRESS SIZE TYPE WRITE UNPRIV
#ifdef KERNEL
case MPU_MODE_SAES:
#ifdef SAES_RAM_START
SET_REGION( 7, SAES_RAM_START, SAES_RAM_SIZE, SRAM, YES, YES ); // Unprivileged kernel SRAM
#endif
break;
#endif
default:

View File

@ -31,6 +31,6 @@
/*
* Current storage version.
*/
#define NORCOW_VERSION ((uint32_t)0x00000005)
#define NORCOW_VERSION ((uint32_t)0x00000006)
#endif

View File

@ -43,7 +43,7 @@
},
"header": {
"language": "cs-CZ",
"version": "2.8.10"
"version": "2.9.0"
},
"translations": {
"addr_mismatch__contact_support_at": "Kontaktujte naši podporu na",

View File

@ -43,7 +43,7 @@
},
"header": {
"language": "de-DE",
"version": "2.8.10"
"version": "2.9.0"
},
"translations": {
"addr_mismatch__contact_support_at": "Kontaktiere den Trezor Support unter",

View File

@ -1,7 +1,7 @@
{
"header": {
"language": "en-US",
"version": "2.8.10"
"version": "2.9.0"
},
"translations": {
"addr_mismatch__contact_support_at": "Please contact Trezor support at",

View File

@ -43,7 +43,7 @@
},
"header": {
"language": "es-ES",
"version": "2.8.10"
"version": "2.9.0"
},
"translations": {
"addr_mismatch__contact_support_at": "Contacta con atención al cliente de Trezor en",

View File

@ -43,7 +43,7 @@
},
"header": {
"language": "fr-FR",
"version": "2.8.10"
"version": "2.9.0"
},
"translations": {
"addr_mismatch__contact_support_at": "Contactez l'assistance Trezor à l'adr.",

View File

@ -43,7 +43,7 @@
},
"header": {
"language": "it-IT",
"version": "2.8.10"
"version": "2.9.0"
},
"translations": {
"addr_mismatch__contact_support_at": "Contatta l'Assistenza di Trezor all'indirizzo",

View File

@ -43,7 +43,7 @@
},
"header": {
"language": "pt-BR",
"version": "2.8.10"
"version": "2.9.0"
},
"translations": {
"addr_mismatch__contact_support_at": "Entre em contato com o suporte Trezor em",

View File

@ -1,8 +1,8 @@
{
"current": {
"merkle_root": "f00c1c603fb911b9b65dbe30261310c4ed90ac1ff90f9c5e52e0ce34acce2745",
"datetime": "2025-03-06T16:38:48.918299",
"commit": "6509d2b3f29d5bd3ee24a3843a6f3e6d9877cf30"
"merkle_root": "1d498d74141d129493b1625901df1ce796eccf167c08bbb1dca7fc29854fe3ac",
"datetime": "2025-03-12T02:14:31.796699",
"commit": "719972c8178865c10cfc78dac25d79e19da40d90"
},
"history": [
{

View File

@ -43,7 +43,7 @@
},
"header": {
"language": "tr-TR",
"version": "2.8.10"
"version": "2.9.0"
},
"translations": {
"addr_mismatch__contact_support_at": "Lütfen Trezor support ile iletişime geçin:",

View File

@ -38,6 +38,7 @@ extern const flash_area_t STORAGE_AREAS[NORCOW_SECTOR_COUNT];
/*
* Current storage version.
*/
#define NORCOW_VERSION ((uint32_t)0x00000005)
#define NORCOW_VERSION ((uint32_t)0x00000006)
#define NORCOW_MIN_VERSION 0x00000000
#endif

View File

@ -160,7 +160,9 @@ static const uint32_t FALSE_WORD = 0x3CA5965A;
static void __handle_fault(const char *msg, const char *file, int line);
#define handle_fault(msg) (__handle_fault(msg, __FILE_NAME__, __LINE__))
#if NORCOW_MIN_VERSION < 2
static uint32_t pin_to_int(const uint8_t *pin, size_t pin_len);
#endif
static secbool storage_upgrade(void);
static secbool storage_upgrade_unlocked(const uint8_t *pin, size_t pin_len,
const uint8_t *ext_salt);
@ -529,6 +531,7 @@ static void ui_progress_finish(void) {
}
}
#if NORCOW_MIN_VERSION <= 4
#if !USE_OPTIGA
static void derive_kek_v4(const uint8_t *pin, size_t pin_len,
const uint8_t *storage_salt, const uint8_t *ext_salt,
@ -579,11 +582,13 @@ static void derive_kek_v4(const uint8_t *pin, size_t pin_len,
memzero(&salt, sizeof(salt));
}
#endif
#endif
static void stretch_pin(const uint8_t *pin, size_t pin_len,
const uint8_t storage_salt[STORAGE_SALT_SIZE],
const uint8_t *ext_salt,
uint8_t stretched_pin[SHA256_DIGEST_LENGTH]) {
#if NORCOW_MIN_VERSION <= 5
static void stretch_pin_v4(const uint8_t *pin, size_t pin_len,
const uint8_t storage_salt[STORAGE_SALT_SIZE],
const uint8_t *ext_salt,
uint8_t stretched_pin[SHA256_DIGEST_LENGTH]) {
// Combining the PIN with the storage salt aims to ensure that if the
// MCU-Optiga communication is compromised, then a user with a low-entropy PIN
// remains protected against an attacker who is not able to read the contents
@ -627,7 +632,57 @@ static void stretch_pin(const uint8_t *pin, size_t pin_len,
#endif
memzero(&ctx, sizeof(ctx));
}
#endif
static void stretch_pin(const uint8_t *pin, size_t pin_len,
const uint8_t storage_salt[STORAGE_SALT_SIZE],
const uint8_t *ext_salt,
uint8_t stretched_pin[SHA256_DIGEST_LENGTH]) {
// Combining the PIN with the storage salt aims to ensure that if the
// MCU-Optiga communication is compromised, then a user with a low-entropy PIN
// remains protected against an attacker who is not able to read the contents
// of the MCU storage. Stretching the PIN with PBKDF2 ensures that even if
// Optiga itself is completely compromised, it will not reduce the security
// of the device below that of earlier Trezor models which also use PBKDF2
// with the same number of iterations.
uint8_t salt[HARDWARE_SALT_SIZE + STORAGE_SALT_SIZE + EXTERNAL_SALT_SIZE] = {
0};
size_t salt_len = 0;
memcpy(salt + salt_len, hardware_salt, HARDWARE_SALT_SIZE);
salt_len += HARDWARE_SALT_SIZE;
memcpy(salt + salt_len, storage_salt, STORAGE_SALT_SIZE);
salt_len += STORAGE_SALT_SIZE;
if (ext_salt != NULL) {
memcpy(salt + salt_len, ext_salt, EXTERNAL_SALT_SIZE);
salt_len += EXTERNAL_SALT_SIZE;
}
PBKDF2_HMAC_SHA256_CTX ctx = {0};
pbkdf2_hmac_sha256_Init(&ctx, pin, pin_len, salt, salt_len, 1);
memzero(&salt, sizeof(salt));
for (int i = 1; i <= 10; i++) {
pbkdf2_hmac_sha256_Update(&ctx, PIN_ITER_COUNT / 10);
ui_progress();
}
#ifdef USE_STORAGE_HWKEY
uint8_t stretched_pin_tmp[SHA256_DIGEST_LENGTH] = {0};
pbkdf2_hmac_sha256_Final(&ctx, stretched_pin_tmp);
ensure(secure_aes_ecb_encrypt_hw(stretched_pin_tmp, SHA256_DIGEST_LENGTH,
stretched_pin, SECURE_AES_KEY_XORK_SP),
"secure_aes pin stretch failed");
memzero(stretched_pin_tmp, sizeof(stretched_pin_tmp));
#else
pbkdf2_hmac_sha256_Final(&ctx, stretched_pin);
#endif
memzero(&ctx, sizeof(ctx));
}
#if NORCOW_MIN_VERSION <= 4
#if USE_OPTIGA
static void derive_kek_optiga_v4(
// Legacy PIN verification method used in storage versions 3 and 4.
@ -647,6 +702,7 @@ static void derive_kek_optiga_v4(
memzero(&ctx, sizeof(ctx));
}
#endif
#endif
static secbool __wur derive_kek_set(
const uint8_t *pin, size_t pin_len, const uint8_t *storage_salt,
@ -661,6 +717,7 @@ static secbool __wur derive_kek_set(
return sectrue;
}
#if NORCOW_MIN_VERSION <= 4
static secbool __wur derive_kek_unlock_v4(const uint8_t *pin, size_t pin_len,
const uint8_t *storage_salt,
const uint8_t *ext_salt,
@ -670,7 +727,7 @@ static secbool __wur derive_kek_unlock_v4(const uint8_t *pin, size_t pin_len,
#if USE_OPTIGA
uint8_t optiga_secret[OPTIGA_PIN_SECRET_SIZE] = {0};
uint8_t stretched_pin[OPTIGA_PIN_SECRET_SIZE] = {0};
stretch_pin(pin, pin_len, storage_salt, ext_salt, stretched_pin);
stretch_pin_v4(pin, pin_len, storage_salt, ext_salt, stretched_pin);
optiga_pin_result ret =
optiga_pin_verify_v4(ui_progress, stretched_pin, optiga_secret);
memzero(stretched_pin, sizeof(stretched_pin));
@ -692,6 +749,31 @@ static secbool __wur derive_kek_unlock_v4(const uint8_t *pin, size_t pin_len,
#endif
return sectrue;
}
#endif
#if NORCOW_MIN_VERSION <= 5
static secbool __wur derive_kek_unlock_v5(
const uint8_t *pin, size_t pin_len, const uint8_t *storage_salt,
const uint8_t *ext_salt, uint8_t stretched_pin[SHA256_DIGEST_LENGTH]) {
stretch_pin_v4(pin, pin_len, storage_salt, ext_salt, stretched_pin);
#if USE_OPTIGA
optiga_pin_result ret = optiga_pin_verify(ui_progress, stretched_pin);
if (ret != OPTIGA_PIN_SUCCESS) {
memzero(stretched_pin, SHA256_DIGEST_LENGTH);
if (ret == OPTIGA_PIN_COUNTER_EXCEEDED) {
// Unreachable code. Wipe should have already been triggered in unlock().
storage_wipe();
show_pin_too_many_screen();
}
ensure(ret == OPTIGA_PIN_INVALID ? sectrue : secfalse,
"optiga_pin_verify failed");
return secfalse;
}
#endif
return sectrue;
}
#endif
static secbool __wur derive_kek_unlock(
const uint8_t *pin, size_t pin_len, const uint8_t *storage_salt,
@ -925,17 +1007,32 @@ static secbool __wur decrypt_dek(const uint8_t *pin, size_t pin_len,
// Derive the key encryption key and IV.
uint8_t kek[SHA256_DIGEST_LENGTH] = {0};
uint8_t keiv[SHA256_DIGEST_LENGTH] = {0};
if (get_lock_version() >= 5) {
uint32_t lock_version = get_lock_version();
if (lock_version >= 6) {
if (sectrue !=
derive_kek_unlock(pin, pin_len, storage_salt, ext_salt, kek)) {
return secfalse;
}
} else {
}
#if NORCOW_MIN_VERSION <= 5
else if (lock_version == 5) {
if (sectrue !=
derive_kek_unlock_v5(pin, pin_len, storage_salt, ext_salt, kek)) {
return secfalse;
}
}
#endif
#if NORCOW_MIN_VERSION <= 4
else if (lock_version <= 4) {
if (sectrue !=
derive_kek_unlock_v4(pin, pin_len, storage_salt, ext_salt, kek, keiv)) {
return secfalse;
};
}
#endif
else {
handle_fault("Unsupported lock version");
}
uint8_t keys[KEYS_SIZE] = {0};
uint8_t tag[POLY1305_TAG_SIZE] __attribute__((aligned(sizeof(uint32_t))));
@ -972,19 +1069,21 @@ static secbool unlock(const uint8_t *pin, size_t pin_len,
const uint8_t *ext_salt) {
const uint8_t *unlock_pin = pin;
size_t unlock_pin_len = pin_len;
uint32_t legacy_pin = 0;
#if NORCOW_MIN_VERSION <= 2
// In case of an upgrade from version 1 or 2, encode the PIN to the old
// format.
uint32_t legacy_pin = 0;
if (get_lock_version() <= 2) {
legacy_pin = pin_to_int(pin, pin_len);
unlock_pin = (const uint8_t *)&legacy_pin;
unlock_pin_len = sizeof(legacy_pin);
}
#endif
// In case of an upgrade from version 4 or earlier bump the total time of UI
// In case of an upgrade from version 5 or earlier bump the total time of UI
// progress to account for the set_pin() call in storage_upgrade_unlocked().
if (get_lock_version() <= 4) {
if (get_lock_version() <= 5) {
ui_progress_add(ui_estimate_time_ms(STORAGE_PIN_OP_SET));
}
@ -1401,6 +1500,7 @@ end:
}
void storage_ensure_not_wipe_code(const uint8_t *pin, size_t pin_len) {
#if NORCOW_MIN_VERSION <= 2
// If we are unlocking the storage during upgrade from version 2 or lower,
// then encode the PIN to the old format.
uint32_t legacy_pin = 0;
@ -1409,9 +1509,12 @@ void storage_ensure_not_wipe_code(const uint8_t *pin, size_t pin_len) {
pin = (const uint8_t *)&legacy_pin;
pin_len = sizeof(legacy_pin);
}
#endif
ensure_not_wipe_code(pin, pin_len);
#if NORCOW_MIN_VERSION <= 2
memzero(&legacy_pin, sizeof(legacy_pin));
#endif
}
secbool storage_has_wipe_code(void) {
@ -1487,6 +1590,7 @@ static void __handle_fault(const char *msg, const char *file, int line) {
__fatal_error(msg, file, line);
}
#if NORCOW_MIN_VERSION == 0
/*
* Reads the PIN fail counter in version 0 format. Returns the current number of
* failed PIN entries.
@ -1518,7 +1622,9 @@ static secbool v0_pin_get_fails(uint32_t *ctr) {
*ctr = 0;
return sectrue;
}
#endif
#if NORCOW_MIN_VERSION <= 2
// Legacy conversion of PIN to the uint32 scheme that was used prior to storage
// version 3.
static uint32_t pin_to_int(const uint8_t *pin, size_t pin_len) {
@ -1583,6 +1689,7 @@ static char *int_to_wipe_code(uint32_t val) {
}
return &wipe_code[pos];
}
#endif
static secbool storage_upgrade(void) {
// Storage version 0: plaintext norcow
@ -1591,14 +1698,16 @@ static secbool storage_upgrade(void) {
// Storage version 3: adds variable length PIN and wipe code
// Storage version 4: changes data structure of encrypted data
// Storage version 5: unifies KEK derivation for non-Optiga and Optiga
// Storage version 6: changes BHK key from unprivileged to privileged
const uint16_t V0_PIN_KEY = 0x0000;
const uint16_t V0_PIN_FAIL_KEY = 0x0001;
uint16_t key = 0;
uint16_t len = 0;
const void *val = NULL;
secbool ret = secfalse;
#if NORCOW_MIN_VERSION == 0
const uint16_t V0_PIN_KEY = 0x0000;
const uint16_t V0_PIN_FAIL_KEY = 0x0001;
secbool ret = secfalse;
if (norcow_active_version == 0) {
random_buffer(cached_keys, sizeof(cached_keys));
@ -1651,7 +1760,11 @@ static secbool storage_upgrade(void) {
unlocked = secfalse;
memzero(cached_keys, sizeof(cached_keys));
} else if (norcow_active_version < 4) {
} else
#endif
#if NORCOW_MIN_VERSION < 4
if (norcow_active_version < 4) {
// Change data structure for encrypted entries.
uint32_t offset = 0;
while (sectrue == norcow_get_next(&offset, &key, &val, &len)) {
@ -1676,7 +1789,9 @@ static secbool storage_upgrade(void) {
}
}
}
} else {
} else
#endif
{
// Copy all entries.
uint32_t offset = 0;
while (sectrue == norcow_get_next(&offset, &key, &val, &len)) {
@ -1737,15 +1852,18 @@ static secbool storage_upgrade_unlocked(const uint8_t *pin, size_t pin_len,
}
secbool ret = sectrue;
if (version <= 4) {
// Upgrade EDEK_PVC_KEY from the uint32 PIN scheme (versions 1 and 2) or
// from the version 3 and 4 variable-length PIN scheme to the unified PIN
// scheme.
#if NORCOW_MIN_VERSION <= 5
if (version <= 5) {
// Versions 1 and 2: Upgrade EDEK_PVC_KEY from the uint32 PIN scheme
// Versions 3 and 4: variable-length PIN scheme to the unified PIN
// Version 5: unprivilged to privilged BHK key
if (sectrue != set_pin(pin, pin_len, ext_salt)) {
return secfalse;
}
}
#endif
#if NORCOW_MIN_VERSION <= 2
if (version == 2) {
// Upgrade WIPE_CODE_DATA_KEY from the old uint32 scheme to the new
// variable-length scheme.
@ -1766,6 +1884,7 @@ static secbool storage_upgrade_unlocked(const uint8_t *pin, size_t pin_len,
ret = set_wipe_code((const uint8_t *)wipe_code, wipe_code_len);
memzero(wipe_code, wipe_code_len);
}
#endif
return ret;
}

View File

@ -41,6 +41,6 @@
/*
* Current storage version.
*/
#define NORCOW_VERSION ((uint32_t)0x00000005)
#define NORCOW_VERSION ((uint32_t)0x00000006)
#endif

View File

@ -113,7 +113,7 @@ NORCOW_SECTOR_SIZE = 64 * 1024
NORCOW_MAGIC = b"NRC2"
# Norcow version, set in the storage header, but also as an encrypted item.
NORCOW_VERSION = b"\x05\x00\x00\x00"
NORCOW_VERSION = b"\x06\x00\x00\x00"
# Norcow magic combined with the version, which is stored as its negation.
NORCOW_MAGIC_AND_VERSION = NORCOW_MAGIC + bytes(