mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-31 10:30:58 +00:00
fix(core): use secure-unprivileged SAES XOR key for storage encryption
[no changelog]
This commit is contained in:
parent
28f420189a
commit
57f72d5aa7
@ -40,6 +40,7 @@ typedef enum {
|
||||
MPU_MODE_SECRET, // + secret area (privileged RW)
|
||||
MPU_MODE_STORAGE, // + both storage areas (privileged RW)
|
||||
MPU_MODE_ASSETS, // + assets (privileged RW)
|
||||
MPU_MODE_SAES, // + unprivileged SAES code
|
||||
MPU_MODE_KERNEL_SRAM, // + extra kernel SRAM (STM32F4 Only) (privileged RW)
|
||||
MPU_MODE_UNUSED_FLASH, // + unused flash areas (privileged RW)
|
||||
MPU_MODE_APP, // + unprivileged DMA2D (RW) & Assets (RO)
|
||||
|
@ -24,10 +24,12 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// only some of the keys are supported depending on execution environment
|
||||
typedef enum {
|
||||
SECURE_AES_KEY_DHUK,
|
||||
SECURE_AES_KEY_DHUK_SP, // secure-privileged
|
||||
SECURE_AES_KEY_BHK,
|
||||
SECURE_AES_KEY_XORK,
|
||||
SECURE_AES_KEY_XORK_SP, // secure-privileged
|
||||
SECURE_AES_KEY_XORK_SN, // secure-nonprivileged
|
||||
} secure_aes_keysel_t;
|
||||
|
||||
// Initializes secure AES module
|
||||
|
@ -23,7 +23,7 @@
|
||||
#ifdef SYSCALL_DISPATCH
|
||||
|
||||
__attribute__((naked, no_stack_protector)) static uint32_t _invoke_app_callback(
|
||||
uint32_t arg1, uint32_t arg2, uint32_t arg3, void* callback) {
|
||||
uint32_t arg1, uint32_t arg2, uint32_t arg3, void *callback) {
|
||||
__asm__ volatile(
|
||||
"push {r1-r12, lr} \n"
|
||||
|
||||
@ -71,7 +71,7 @@ __attribute__((naked, no_stack_protector)) static uint32_t _invoke_app_callback(
|
||||
}
|
||||
|
||||
uint32_t invoke_app_callback(uint32_t args1, uint32_t arg2, uint32_t arg3,
|
||||
void* callback) {
|
||||
void *callback) {
|
||||
mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_APP);
|
||||
uint32_t retval = _invoke_app_callback(args1, arg2, arg3, callback);
|
||||
mpu_reconfig(mpu_mode);
|
||||
@ -79,7 +79,7 @@ uint32_t invoke_app_callback(uint32_t args1, uint32_t arg2, uint32_t arg3,
|
||||
}
|
||||
|
||||
__attribute__((naked, no_stack_protector)) void return_from_app_callback(
|
||||
uint32_t retval, uint32_t* msp) {
|
||||
uint32_t retval, uint32_t *msp) {
|
||||
__asm__ volatile(
|
||||
"MSR MSP, R1 \n"
|
||||
"POP {R1} \n"
|
||||
@ -98,4 +98,65 @@ __attribute__((naked, no_stack_protector)) void return_from_app_callback(
|
||||
"BX LR \n");
|
||||
}
|
||||
|
||||
__attribute__((naked, no_stack_protector)) static uint32_t _invoke_unpriv(
|
||||
uint32_t stack_addr, uint32_t stack_lim, void *callback) {
|
||||
__asm__ volatile(
|
||||
"push {r1-r12, lr} \n"
|
||||
|
||||
#if defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8M_BASE__)
|
||||
"mrs r12, PSPLIM \n" // Backup unprivileged stack limit
|
||||
"push {r12} \n"
|
||||
#endif
|
||||
"mrs r12, PSP \n" // Backup unprivileged stack pointer
|
||||
"push {r12} \n"
|
||||
|
||||
"mov r12, r0 \n" // setup stack for unprivileged call inside
|
||||
// kernel
|
||||
"sub r12, r12, #32 \n"
|
||||
"msr PSP, r12 \n"
|
||||
"msr PSPLIM, r1 \n"
|
||||
|
||||
"mov r3, #0 \n"
|
||||
|
||||
"mov r4, r3 \n" // Clear registers r4-r11
|
||||
"mov r5, r3 \n"
|
||||
"mov r6, r3 \n"
|
||||
"mov r7, r3 \n"
|
||||
"mov r8, r3 \n"
|
||||
"mov r9, r3 \n"
|
||||
"mov r10, r3 \n"
|
||||
"mov r11, r3 \n"
|
||||
|
||||
"str r3, [r12, #0] \n" // r0
|
||||
"str r3, [r12, #4] \n" // r1"
|
||||
"str r3, [r12, #8] \n" // r2"
|
||||
"str r3, [r12, #12] \n" // r3"
|
||||
"str r3, [r12, #16] \n" // r12"
|
||||
"str r3, [r12, #20] \n" // lr"
|
||||
|
||||
"bic r3, r2, #1 \n"
|
||||
"str r3, [r12, #24] \n" // return address
|
||||
|
||||
"ldr r1, = 0x01000000 \n"
|
||||
"str r1, [r12, #28] \n" // xPSR
|
||||
|
||||
"vmov r0, s0 \n" // Use FPU instruction to ensure lazy
|
||||
// stacking
|
||||
|
||||
// return to Secure Thread mode (use Secure PSP)
|
||||
"ldr lr, = 0xFFFFFFFD \n"
|
||||
"bx lr \n");
|
||||
}
|
||||
|
||||
extern const void _eustack;
|
||||
extern const void _sustack;
|
||||
|
||||
uint32_t invoke_unpriv(void *func) {
|
||||
uint32_t *stack = (uint32_t *)&_eustack;
|
||||
uint32_t *stack_lim = (uint32_t *)&_sustack;
|
||||
|
||||
uint32_t retval = _invoke_unpriv((uint32_t)stack, (uint32_t)stack_lim, func);
|
||||
return retval;
|
||||
}
|
||||
|
||||
#endif // SYSCALL_DISPATCH
|
||||
|
@ -57,6 +57,13 @@ uint32_t invoke_app_callback(uint32_t args1, uint32_t arg2, uint32_t arg3,
|
||||
// the stack pointer and returns control to the privileged caller.
|
||||
void return_from_app_callback(uint32_t retval, uint32_t* msp);
|
||||
|
||||
// Invokes an unprivileged function from privileged mode.
|
||||
//
|
||||
// This is a *temporary* helper function used to control the STM32 SAES
|
||||
// peripheral from unprivileged mode for backward compatibility (due to
|
||||
// different hardware keys being used in privileged and unprivileged modes).
|
||||
uint32_t invoke_unpriv(void* func);
|
||||
|
||||
#else // KERNEL_MODE
|
||||
|
||||
static inline uint32_t __attribute__((no_stack_protector))
|
||||
@ -199,6 +206,8 @@ syscall_invoke6(uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t arg4,
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif // KERNEL_MODE
|
||||
|
||||
static inline void __attribute__((no_stack_protector))
|
||||
syscall_return_from_callback(uint32_t retval) {
|
||||
register uint32_t r0 __asm__("r0") = retval;
|
||||
@ -208,6 +217,4 @@ syscall_return_from_callback(uint32_t retval) {
|
||||
: "memory");
|
||||
}
|
||||
|
||||
#endif // KERNEL_MODE
|
||||
|
||||
#endif // TREZORHAL_SYSCALL_H
|
||||
|
@ -217,7 +217,6 @@ static void mpu_init_fixed_regions(void) {
|
||||
SET_REGION( 2, BOOTLOADER_START, BOOTLOADER_SIZE, FLASH_DATA, YES, NO );
|
||||
SET_REGION( 3, FIRMWARE_START, FIRMWARE_SIZE, FLASH_DATA, YES, NO );
|
||||
DIS_REGION( 4 );
|
||||
SET_REGION( 5, GRAPHICS_START, GRAPHICS_SIZE, SRAM, YES, NO );
|
||||
#endif
|
||||
#if defined(BOOTLOADER)
|
||||
// REGION ADDRESS SIZE TYPE WRITE UNPRIV
|
||||
@ -226,7 +225,6 @@ static void mpu_init_fixed_regions(void) {
|
||||
SET_REGION( 2, FIRMWARE_START, FIRMWARE_SIZE, FLASH_DATA, YES, NO );
|
||||
DIS_REGION( 3 );
|
||||
DIS_REGION( 4 );
|
||||
SET_REGION( 5, GRAPHICS_START, GRAPHICS_SIZE, SRAM, YES, NO );
|
||||
#endif
|
||||
#if defined(KERNEL)
|
||||
// REGION ADDRESS SIZE TYPE WRITE UNPRIV
|
||||
@ -239,7 +237,6 @@ static void mpu_init_fixed_regions(void) {
|
||||
#else
|
||||
DIS_REGION( 4 );
|
||||
#endif
|
||||
SET_REGION( 5, GRAPHICS_START, GRAPHICS_SIZE, SRAM, YES, YES ); // Frame buffer or display interface
|
||||
#endif
|
||||
#if defined(FIRMWARE)
|
||||
// REGION ADDRESS SIZE TYPE WRITE UNPRIV
|
||||
@ -248,7 +245,6 @@ static void mpu_init_fixed_regions(void) {
|
||||
DIS_REGION( 2 );
|
||||
DIS_REGION( 3 );
|
||||
DIS_REGION( 4 );
|
||||
SET_REGION( 5, GRAPHICS_START, GRAPHICS_SIZE, SRAM, YES, NO );
|
||||
#endif
|
||||
#if defined(TREZOR_PRODTEST)
|
||||
SET_REGION( 0, FIRMWARE_START, 1024, FLASH_DATA, YES, NO );
|
||||
@ -256,11 +252,11 @@ static void mpu_init_fixed_regions(void) {
|
||||
SET_REGION( 2, SRAM1_BASE, SRAM_SIZE, SRAM, YES, NO );
|
||||
DIS_REGION( 3 );
|
||||
DIS_REGION( 4 );
|
||||
SET_REGION( 5, GRAPHICS_START, GRAPHICS_SIZE, SRAM, YES, NO );
|
||||
#endif
|
||||
|
||||
// Regions #6 and #7 are banked
|
||||
|
||||
DIS_REGION( 5 );
|
||||
DIS_REGION( 6 );
|
||||
DIS_REGION( 7 );
|
||||
// clang-format on
|
||||
@ -314,9 +310,12 @@ mpu_mode_t mpu_reconfig(mpu_mode_t mode) {
|
||||
|
||||
// clang-format off
|
||||
switch (mode) {
|
||||
case MPU_MODE_SAES:
|
||||
SET_REGION( 5, PERIPH_BASE_NS, SIZE_512M, PERIPHERAL, YES, YES ); // Peripherals - SAES, TAMP
|
||||
break;
|
||||
default:
|
||||
SET_REGION( 5, GRAPHICS_START, GRAPHICS_SIZE, SRAM, YES, YES ); // Peripherals
|
||||
break;
|
||||
SET_REGION( 5, GRAPHICS_START, GRAPHICS_SIZE, SRAM, YES, YES ); // Frame buffer or display interface
|
||||
break;
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
@ -349,6 +348,9 @@ mpu_mode_t mpu_reconfig(mpu_mode_t mode) {
|
||||
case MPU_MODE_ASSETS:
|
||||
SET_REGION( 6, ASSETS_START, ASSETS_SIZE, FLASH_DATA, YES, NO );
|
||||
break;
|
||||
case MPU_MODE_SAES:
|
||||
SET_REGION( 6, KERNEL_FLASH_U_START, KERNEL_FLASH_U_SIZE,FLASH_CODE, NO, YES ); // Unprivileged kernal flash
|
||||
break;
|
||||
case MPU_MODE_APP:
|
||||
SET_REGION( 6, ASSETS_START, ASSETS_SIZE, FLASH_DATA, NO, YES );
|
||||
break;
|
||||
@ -362,8 +364,11 @@ mpu_mode_t mpu_reconfig(mpu_mode_t mode) {
|
||||
|
||||
// clang-format off
|
||||
switch (mode) {
|
||||
case MPU_MODE_APP:
|
||||
// REGION ADDRESS SIZE TYPE WRITE UNPRIV
|
||||
case MPU_MODE_SAES:
|
||||
SET_REGION( 7, KERNEL_RAM_U_START, KERNEL_RAM_U_SIZE, SRAM, YES, YES ); // Unprivileged kernel SRAM
|
||||
break;
|
||||
case MPU_MODE_APP:
|
||||
// DMA2D peripherals (Unprivileged, Read-Write, Non-Executable)
|
||||
SET_REGION( 7, 0x5002B000, SIZE_3K, PERIPHERAL, YES, YES );
|
||||
break;
|
||||
|
@ -252,7 +252,8 @@ static void secret_optiga_cache(void) {
|
||||
secbool secret_optiga_set(const uint8_t secret[SECRET_OPTIGA_KEY_LEN]) {
|
||||
uint8_t secret_enc[SECRET_OPTIGA_KEY_LEN] = {0};
|
||||
if (sectrue != secure_aes_ecb_encrypt_hw(secret, sizeof(secret_enc),
|
||||
secret_enc, SECURE_AES_KEY_DHUK)) {
|
||||
secret_enc,
|
||||
SECURE_AES_KEY_DHUK_SP)) {
|
||||
return secfalse;
|
||||
}
|
||||
secret_write(secret_enc, SECRET_OPTIGA_KEY_OFFSET, SECRET_OPTIGA_KEY_LEN);
|
||||
@ -279,7 +280,7 @@ secbool secret_optiga_get(uint8_t dest[SECRET_OPTIGA_KEY_LEN]) {
|
||||
}
|
||||
|
||||
secbool res = secure_aes_ecb_decrypt_hw(
|
||||
(uint8_t *)secret, SECRET_OPTIGA_KEY_LEN, dest, SECURE_AES_KEY_DHUK);
|
||||
(uint8_t *)secret, SECRET_OPTIGA_KEY_LEN, dest, SECURE_AES_KEY_DHUK_SP);
|
||||
|
||||
memzero(secret, sizeof(secret));
|
||||
return res;
|
||||
|
@ -17,33 +17,24 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <mpu.h>
|
||||
#include <secure_aes.h>
|
||||
#include STM32_HAL_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stm32u5xx_hal_cryp.h>
|
||||
#include <string.h>
|
||||
#include "model.h"
|
||||
#include "syscall.h"
|
||||
|
||||
#include "memzero.h"
|
||||
|
||||
#define SAES_DATA_SIZE_WITH_UPRIV_KEY 32
|
||||
#define AES_BLOCK_SIZE 16
|
||||
|
||||
#ifdef KERNEL_MODE
|
||||
|
||||
#define AES_BLOCK_SIZE 16
|
||||
|
||||
secbool secure_aes_init(void) {
|
||||
RCC_OscInitTypeDef osc_init_def = {0};
|
||||
osc_init_def.OscillatorType = RCC_OSCILLATORTYPE_SHSI;
|
||||
osc_init_def.SHSIState = RCC_SHSI_ON;
|
||||
|
||||
// Enable SHSI clock
|
||||
if (HAL_RCC_OscConfig(&osc_init_def) != HAL_OK) {
|
||||
return secfalse;
|
||||
}
|
||||
|
||||
// Enable SAES peripheral clock
|
||||
__HAL_RCC_SAES_CLK_ENABLE();
|
||||
|
||||
return sectrue;
|
||||
}
|
||||
#include "irq.h"
|
||||
|
||||
static void secure_aes_load_bhk(void) {
|
||||
TAMP->BKP0R;
|
||||
@ -58,19 +49,159 @@ static void secure_aes_load_bhk(void) {
|
||||
|
||||
static uint32_t get_keysel(secure_aes_keysel_t key) {
|
||||
switch (key) {
|
||||
case SECURE_AES_KEY_DHUK:
|
||||
case SECURE_AES_KEY_DHUK_SP:
|
||||
return CRYP_KEYSEL_HW;
|
||||
case SECURE_AES_KEY_BHK:
|
||||
return CRYP_KEYSEL_SW;
|
||||
case SECURE_AES_KEY_XORK:
|
||||
case SECURE_AES_KEY_XORK_SP:
|
||||
case SECURE_AES_KEY_XORK_SN:
|
||||
return CRYP_KEYSEL_HSW;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static secbool is_key_supported(secure_aes_keysel_t key) {
|
||||
switch (key) {
|
||||
case SECURE_AES_KEY_DHUK_SP:
|
||||
case SECURE_AES_KEY_BHK:
|
||||
case SECURE_AES_KEY_XORK_SP:
|
||||
return sectrue;
|
||||
default:
|
||||
return secfalse;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SYSCALL_DISPATCH
|
||||
|
||||
__attribute__((section(".udata")))
|
||||
uint32_t saes_input[SAES_DATA_SIZE_WITH_UPRIV_KEY / sizeof(uint32_t)];
|
||||
|
||||
__attribute__((section(".udata")))
|
||||
uint32_t saes_output[SAES_DATA_SIZE_WITH_UPRIV_KEY / sizeof(uint32_t)];
|
||||
|
||||
__attribute__((section(".uflash"), used, naked, no_stack_protector)) uint32_t
|
||||
saes_invoke(void) {
|
||||
// reset the key loaded in SAES
|
||||
MODIFY_REG(SAES->CR, AES_CR_KEYSEL, CRYP_KEYSEL_NORMAL);
|
||||
|
||||
while (HAL_IS_BIT_SET(SAES->SR, CRYP_FLAG_BUSY)) {
|
||||
}
|
||||
while (HAL_IS_BIT_SET(SAES->ISR, CRYP_FLAG_RNGEIF)) {
|
||||
}
|
||||
|
||||
MODIFY_REG(SAES->CR,
|
||||
AES_CR_KMOD | AES_CR_DATATYPE | AES_CR_KEYSIZE | AES_CR_CHMOD |
|
||||
AES_CR_KEYSEL | AES_CR_KEYPROT,
|
||||
CRYP_KEYMODE_NORMAL | CRYP_NO_SWAP | CRYP_KEYSIZE_256B |
|
||||
CRYP_AES_ECB | CRYP_KEYSEL_HSW | CRYP_KEYPROT_DISABLE);
|
||||
|
||||
TAMP->BKP0R;
|
||||
TAMP->BKP1R;
|
||||
TAMP->BKP2R;
|
||||
TAMP->BKP3R;
|
||||
TAMP->BKP4R;
|
||||
TAMP->BKP5R;
|
||||
TAMP->BKP6R;
|
||||
TAMP->BKP7R;
|
||||
|
||||
#define CRYP_OPERATINGMODE_ENCRYPT 0x00000000U /*!< Encryption mode(Mode 1) */
|
||||
|
||||
/* Set the operating mode and normal key selection */
|
||||
MODIFY_REG(SAES->CR, AES_CR_MODE | AES_CR_KMOD,
|
||||
CRYP_OPERATINGMODE_ENCRYPT | CRYP_KEYMODE_NORMAL);
|
||||
|
||||
SAES->CR |= AES_CR_EN;
|
||||
|
||||
for (int j = 0; j < SAES_DATA_SIZE_WITH_UPRIV_KEY / AES_BLOCK_SIZE; j++) {
|
||||
/* Write the input block in the IN FIFO */
|
||||
SAES->DINR = saes_input[j * 4 + 0];
|
||||
SAES->DINR = saes_input[j * 4 + 1];
|
||||
SAES->DINR = saes_input[j * 4 + 2];
|
||||
SAES->DINR = saes_input[j * 4 + 3];
|
||||
|
||||
while (HAL_IS_BIT_CLR(SAES->ISR, AES_ISR_CCF)) {
|
||||
}
|
||||
|
||||
/* Clear CCF Flag */
|
||||
SET_BIT(SAES->ICR, CRYP_CLEAR_CCF);
|
||||
|
||||
/* Read the output block from the output FIFO */
|
||||
for (int i = 0U; i < 4U; i++) {
|
||||
saes_output[j * 4 + i] = SAES->DOUTR;
|
||||
}
|
||||
}
|
||||
|
||||
SAES->CR &= ~AES_CR_EN;
|
||||
|
||||
// reset the key loaded in SAES
|
||||
MODIFY_REG(SAES->CR, AES_CR_KEYSEL, CRYP_KEYSEL_NORMAL);
|
||||
|
||||
syscall_return_from_callback(sectrue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern uint32_t sram_u_start;
|
||||
extern uint32_t sram_u_end;
|
||||
|
||||
secbool unpriv_encrypt(const uint8_t* input, size_t size, uint8_t* output,
|
||||
secure_aes_keysel_t key) {
|
||||
if (size != SAES_DATA_SIZE_WITH_UPRIV_KEY) {
|
||||
return secfalse;
|
||||
}
|
||||
|
||||
if (key != SECURE_AES_KEY_XORK_SN) {
|
||||
return secfalse;
|
||||
}
|
||||
|
||||
uint32_t prev_svc_prio = NVIC_GetPriority(SVCall_IRQn);
|
||||
NVIC_SetPriority(SVCall_IRQn, IRQ_PRI_HIGHEST);
|
||||
uint32_t basepri = __get_BASEPRI();
|
||||
__set_BASEPRI(IRQ_PRI_HIGHEST + 1);
|
||||
|
||||
mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_SAES);
|
||||
|
||||
memset(&sram_u_start, 0, &sram_u_end - &sram_u_start);
|
||||
memcpy(saes_input, input, size);
|
||||
|
||||
SAES->CR |= AES_CR_KEYSEL_0;
|
||||
|
||||
__HAL_RCC_SAES_CLK_DISABLE();
|
||||
__HAL_RCC_SAES_FORCE_RESET();
|
||||
__HAL_RCC_SAES_RELEASE_RESET();
|
||||
__HAL_RCC_SAES_CLK_ENABLE();
|
||||
|
||||
secbool retval = invoke_unpriv(saes_invoke);
|
||||
|
||||
__HAL_RCC_SAES_CLK_DISABLE();
|
||||
__HAL_RCC_SAES_FORCE_RESET();
|
||||
__HAL_RCC_SAES_RELEASE_RESET();
|
||||
__HAL_RCC_SAES_CLK_ENABLE();
|
||||
|
||||
memcpy(output, saes_output, size);
|
||||
memset(&sram_u_start, 0, &sram_u_end - &sram_u_start);
|
||||
|
||||
mpu_reconfig(mpu_mode);
|
||||
|
||||
__set_BASEPRI(basepri);
|
||||
NVIC_SetPriority(SVCall_IRQn, prev_svc_prio);
|
||||
|
||||
return retval;
|
||||
}
|
||||
#endif
|
||||
|
||||
secbool secure_aes_ecb_encrypt_hw(const uint8_t* input, size_t size,
|
||||
uint8_t* output, secure_aes_keysel_t key) {
|
||||
#ifdef SYSCALL_DISPATCH
|
||||
if (key == SECURE_AES_KEY_XORK_SN) {
|
||||
return unpriv_encrypt(input, size, output, key);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (sectrue != is_key_supported(key)) {
|
||||
return secfalse;
|
||||
}
|
||||
|
||||
CRYP_HandleTypeDef hcryp = {0};
|
||||
uint32_t iv[] = {0, 0, 0, 0};
|
||||
|
||||
@ -138,6 +269,10 @@ secbool secure_aes_ecb_encrypt_hw(const uint8_t* input, size_t size,
|
||||
|
||||
secbool secure_aes_ecb_decrypt_hw(const uint8_t* input, size_t size,
|
||||
uint8_t* output, secure_aes_keysel_t key) {
|
||||
if (sectrue != is_key_supported(key)) {
|
||||
return secfalse;
|
||||
}
|
||||
|
||||
CRYP_HandleTypeDef hcryp = {0};
|
||||
uint32_t iv[] = {0, 0, 0, 0};
|
||||
|
||||
@ -202,4 +337,20 @@ secbool secure_aes_ecb_decrypt_hw(const uint8_t* input, size_t size,
|
||||
return sectrue;
|
||||
}
|
||||
|
||||
#endif // KERNEL_MODE
|
||||
secbool secure_aes_init(void) {
|
||||
RCC_OscInitTypeDef osc_init_def = {0};
|
||||
osc_init_def.OscillatorType = RCC_OSCILLATORTYPE_SHSI;
|
||||
osc_init_def.SHSIState = RCC_SHSI_ON;
|
||||
|
||||
// Enable SHSI clock
|
||||
if (HAL_RCC_OscConfig(&osc_init_def) != HAL_OK) {
|
||||
return secfalse;
|
||||
}
|
||||
|
||||
// Enable SAES peripheral clock
|
||||
__HAL_RCC_SAES_CLK_ENABLE();
|
||||
|
||||
return sectrue;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -557,7 +557,7 @@ static void derive_kek_v4(const uint8_t *pin, size_t pin_len,
|
||||
uint8_t pre_kek[SHA256_DIGEST_LENGTH] = {0};
|
||||
pbkdf2_hmac_sha256_Final(&ctx, pre_kek);
|
||||
ensure(secure_aes_ecb_encrypt_hw(pre_kek, SHA256_DIGEST_LENGTH, kek,
|
||||
SECURE_AES_KEY_XORK),
|
||||
SECURE_AES_KEY_XORK_SN),
|
||||
"secure_aes derive kek failed");
|
||||
memzero(pre_kek, sizeof(pre_kek));
|
||||
#else
|
||||
@ -615,7 +615,7 @@ static void stretch_pin(const uint8_t *pin, size_t pin_len,
|
||||
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),
|
||||
stretched_pin, SECURE_AES_KEY_XORK_SN),
|
||||
"secure_aes pin stretch failed");
|
||||
memzero(stretched_pin_tmp, sizeof(stretched_pin_tmp));
|
||||
#else
|
||||
|
Loading…
Reference in New Issue
Block a user