parent
067b37ad32
commit
aa7422df0e
@ -0,0 +1,104 @@
|
||||
/* Trezor v2 boardloader linker script */
|
||||
|
||||
ENTRY(reset_handler)
|
||||
|
||||
MEMORY {
|
||||
FLASH (rx) : ORIGIN = 0x0C004000, LENGTH = 48K
|
||||
SRAM1 (wal) : ORIGIN = 0x30000000, LENGTH = 768K
|
||||
SRAM2 (wal) : ORIGIN = 0x300C0000, LENGTH = 64K
|
||||
SRAM3 (wal) : ORIGIN = 0x300D0000, LENGTH = 832K
|
||||
SRAM5 (wal) : ORIGIN = 0x301A0000, LENGTH = 832K
|
||||
SRAM6 (wal) : ORIGIN = 0x30270000, LENGTH = 512K
|
||||
SRAM4 (wal) : ORIGIN = 0x38000000, LENGTH = 16K
|
||||
}
|
||||
|
||||
main_stack_base = ORIGIN(SRAM2) + SIZEOF(.stack); /* 8-byte aligned full descending stack */
|
||||
_sstack = ORIGIN(SRAM2) + 0x100;
|
||||
_estack = main_stack_base;
|
||||
|
||||
/* used by the startup code to populate variables used by the C code */
|
||||
data_lma = LOADADDR(.data);
|
||||
data_vma = ADDR(.data);
|
||||
data_size = SIZEOF(.data);
|
||||
|
||||
/* used by the startup code to populate variables used by the C code */
|
||||
sensitive_lma = LOADADDR(.sensitive);
|
||||
sensitive_vma = ADDR(.sensitive);
|
||||
sensitive_size = SIZEOF(.sensitive);
|
||||
|
||||
/* used by the startup code to wipe memory */
|
||||
sram1_start = ORIGIN(SRAM1);
|
||||
sram1_end = ORIGIN(SRAM1) + LENGTH(SRAM1);
|
||||
sram2_start = ORIGIN(SRAM2);
|
||||
sram2_end = ORIGIN(SRAM2) + LENGTH(SRAM2);
|
||||
sram3_start = ORIGIN(SRAM3);
|
||||
sram3_end = ORIGIN(SRAM3) + LENGTH(SRAM3);
|
||||
sram4_start = ORIGIN(SRAM4);
|
||||
sram4_end = ORIGIN(SRAM4) + LENGTH(SRAM4);
|
||||
sram5_start = ORIGIN(SRAM5);
|
||||
sram5_end = ORIGIN(SRAM5) + LENGTH(SRAM5);
|
||||
sram6_start = ORIGIN(SRAM6);
|
||||
sram6_end = ORIGIN(SRAM6) + LENGTH(SRAM6);
|
||||
|
||||
/* IMAGE_HEADER_SIZE is 0x400, this is for interaction-less firmware update start */
|
||||
firmware_header_start = sram1_end - 0x400;
|
||||
_stay_in_bootloader_flag_addr = ABSOLUTE(sram1_end - 0x400 - 4);
|
||||
|
||||
|
||||
|
||||
SECTIONS {
|
||||
.vector_table : ALIGN(512) {
|
||||
KEEP(*(.vector_table));
|
||||
} >FLASH AT>FLASH
|
||||
|
||||
.text : ALIGN(4) {
|
||||
*(.text*);
|
||||
. = ALIGN(4); /* make the section size a multiple of the word size */
|
||||
} >FLASH AT>FLASH
|
||||
|
||||
.rodata : ALIGN(4) {
|
||||
*(.rodata*);
|
||||
. = ALIGN(4); /* make the section size a multiple of the word size */
|
||||
} >FLASH AT>FLASH
|
||||
|
||||
.data : ALIGN(4) {
|
||||
*(.data*);
|
||||
. = ALIGN(512);
|
||||
} >SRAM1 AT>FLASH
|
||||
|
||||
/DISCARD/ : {
|
||||
*(.ARM.exidx*);
|
||||
}
|
||||
|
||||
.bss : ALIGN(4) {
|
||||
*(.bss*);
|
||||
. = ALIGN(4);
|
||||
} >SRAM1
|
||||
|
||||
.buf : ALIGN(4) {
|
||||
*(.buf*);
|
||||
. = ALIGN(4);
|
||||
} >SRAM1
|
||||
|
||||
.stack : ALIGN(8) {
|
||||
. = 16K + 0x100; /* Exactly 16K allocated for stack. Overflow causes MemManage fault (when using MPU). */
|
||||
} >SRAM2
|
||||
|
||||
.sensitive : ALIGN(8) {
|
||||
*(.sensitive*);
|
||||
. = ALIGN(4);
|
||||
} >SRAM2 AT>FLASH
|
||||
|
||||
.fb1 : ALIGN(4) {
|
||||
*(.fb1*);
|
||||
. = ALIGN(4);
|
||||
} >SRAM3
|
||||
|
||||
.fb2 : ALIGN(4) {
|
||||
*(.fb2*);
|
||||
. = ALIGN(4);
|
||||
} >SRAM5
|
||||
|
||||
/* Hard-coded address for capabilities structure */
|
||||
.capabilities 0x0C00FF00 : {KEEP(*(.capabilities_section))}
|
||||
}
|
@ -0,0 +1,110 @@
|
||||
.syntax unified
|
||||
|
||||
.text
|
||||
|
||||
.global reset_handler
|
||||
.type reset_handler, STT_FUNC
|
||||
reset_handler:
|
||||
bl SystemInit
|
||||
|
||||
// read the first rng data and save it
|
||||
ldr r0, =0 // r0 - previous value
|
||||
ldr r1, =0 // r1 - whether to compare the previous value
|
||||
bl rng_read
|
||||
|
||||
// read the next rng data and make sure it is different than previous
|
||||
// r0 - value returned from previous call
|
||||
ldr r1, =1 // r1 - whether to compare the previous value
|
||||
bl rng_read
|
||||
mov r4, r0 // save TRNG output in r4
|
||||
|
||||
// wipe memory to remove any possible vestiges of sensitive data
|
||||
|
||||
ldr r1, =_stay_in_bootloader_flag_addr // r0 - address of storage for "stay in bootloader" flag
|
||||
ldr r2, [r1]
|
||||
ldr r3, =0x0FC35A96
|
||||
sub r2, r2, r3
|
||||
cbz r2, fill_ram
|
||||
|
||||
|
||||
ldr r1, =sram1_end // r1 - point to byte after the end of SRAM
|
||||
|
||||
fill_ram:
|
||||
ldr r0, =sram1_start // r0 - point to beginning of SRAM
|
||||
mov r2, r4 // r2 - the word-sized value to be written
|
||||
bl memset_reg
|
||||
|
||||
ldr r0, =sram2_start // r0 - point to beginning of SRAM
|
||||
ldr r1, =sram2_end // r1 - point to byte after the end of SRAM
|
||||
mov r2, r4 // r2 - the word-sized value to be written
|
||||
bl memset_reg
|
||||
|
||||
ldr r0, =sram3_start // r0 - point to beginning of SRAM
|
||||
ldr r1, =sram3_end // r1 - point to byte after the end of SRAM
|
||||
mov r2, r4 // r2 - the word-sized value to be written
|
||||
bl memset_reg
|
||||
|
||||
ldr r0, =sram4_start // r0 - point to beginning of SRAM
|
||||
ldr r1, =sram4_end // r1 - point to byte after the end of SRAM
|
||||
mov r2, r4 // r2 - the word-sized value to be written
|
||||
bl memset_reg
|
||||
|
||||
ldr r0, =sram5_start // r0 - point to beginning of SRAM
|
||||
ldr r1, =sram5_end // r1 - point to byte after the end of SRAM
|
||||
mov r2, r4 // r2 - the word-sized value to be written
|
||||
bl memset_reg
|
||||
|
||||
|
||||
// setup environment for subsequent stage of code
|
||||
|
||||
|
||||
|
||||
ldr r1, =_stay_in_bootloader_flag_addr // r0 - address of storage for "stay in bootloader" flag
|
||||
ldr r2, [r1]
|
||||
ldr r3, =0x0FC35A96
|
||||
sub r2, r2, r3
|
||||
cbz r2, clear_ram
|
||||
|
||||
ldr r1, =sram1_end // r1 - point to byte after the end of SRAM
|
||||
|
||||
clear_ram:
|
||||
ldr r2, =0 // r2 - the word-sized value to be written
|
||||
|
||||
ldr r0, =sram1_start // r0 - point to beginning of SRAM
|
||||
bl memset_reg
|
||||
ldr r0, =sram2_start // r0 - point to beginning of SRAM
|
||||
ldr r1, =sram2_end // r1 - point to byte after the end of SRAM
|
||||
bl memset_reg
|
||||
ldr r0, =sram3_start // r0 - point to beginning of SRAM
|
||||
ldr r1, =sram3_end // r1 - point to byte after the end of SRAM
|
||||
bl memset_reg
|
||||
ldr r0, =sram4_start // r0 - point to beginning of SRAM
|
||||
ldr r1, =sram4_end // r1 - point to byte after the end of SRAM
|
||||
bl memset_reg
|
||||
ldr r0, =sram5_start // r0 - point to beginning of SRAM
|
||||
ldr r1, =sram5_end // r1 - point to byte after the end of SRAM
|
||||
bl memset_reg
|
||||
|
||||
// copy data in from flash
|
||||
ldr r0, =data_vma // dst addr
|
||||
ldr r1, =data_lma // src addr
|
||||
ldr r2, =data_size // size in bytes
|
||||
bl memcpy
|
||||
|
||||
// copy sensitive data in from flash
|
||||
ldr r0, =sensitive_vma // dst addr
|
||||
ldr r1, =sensitive_lma // src addr
|
||||
ldr r2, =sensitive_size // size in bytes
|
||||
bl memcpy
|
||||
|
||||
// setup the stack protector (see build script "-fstack-protector-all") with an unpredictable value
|
||||
bl rng_get
|
||||
ldr r1, = __stack_chk_guard
|
||||
str r0, [r1]
|
||||
|
||||
// enter the application code
|
||||
bl main
|
||||
|
||||
b shutdown_privileged
|
||||
|
||||
.end
|
@ -0,0 +1,100 @@
|
||||
/* Trezor v2 bootloader linker script */
|
||||
|
||||
ENTRY(reset_handler)
|
||||
|
||||
MEMORY {
|
||||
FLASH (rx) : ORIGIN = 0x0C010000, LENGTH = 128K
|
||||
SRAM1 (wal) : ORIGIN = 0x30000000, LENGTH = 768K
|
||||
SRAM2 (wal) : ORIGIN = 0x300C0000, LENGTH = 64K
|
||||
SRAM3 (wal) : ORIGIN = 0x300D0000, LENGTH = 832K
|
||||
SRAM5 (wal) : ORIGIN = 0x301A0000, LENGTH = 832K
|
||||
SRAM6 (wal) : ORIGIN = 0x30270000, LENGTH = 512K
|
||||
SRAM4 (wal) : ORIGIN = 0x38000000, LENGTH = 16K
|
||||
}
|
||||
|
||||
main_stack_base = ORIGIN(SRAM2) + SIZEOF(.stack); /* 8-byte aligned full descending stack */
|
||||
_sstack = ORIGIN(SRAM2) + 0x100;
|
||||
_estack = main_stack_base;
|
||||
|
||||
/* used by the startup code to populate variables used by the C code */
|
||||
data_lma = LOADADDR(.data);
|
||||
data_vma = ADDR(.data);
|
||||
data_size = SIZEOF(.data);
|
||||
|
||||
/* used by the startup code to populate variables used by the C code */
|
||||
sensitive_lma = LOADADDR(.sensitive);
|
||||
sensitive_vma = ADDR(.sensitive);
|
||||
sensitive_size = SIZEOF(.sensitive);
|
||||
|
||||
/* used by the startup code to wipe memory */
|
||||
sram1_start = ORIGIN(SRAM1);
|
||||
sram1_end = ORIGIN(SRAM1) + LENGTH(SRAM1);
|
||||
sram2_start = ORIGIN(SRAM2);
|
||||
sram2_end = ORIGIN(SRAM2) + LENGTH(SRAM2);
|
||||
sram3_start = ORIGIN(SRAM3);
|
||||
sram3_end = ORIGIN(SRAM3) + LENGTH(SRAM3);
|
||||
sram4_start = ORIGIN(SRAM4);
|
||||
sram4_end = ORIGIN(SRAM4) + LENGTH(SRAM4);
|
||||
sram5_start = ORIGIN(SRAM5);
|
||||
sram5_end = ORIGIN(SRAM5) + LENGTH(SRAM5);
|
||||
sram6_start = ORIGIN(SRAM6);
|
||||
sram6_end = ORIGIN(SRAM6) + LENGTH(SRAM6);
|
||||
|
||||
/* IMAGE_HEADER_SIZE is 0x400, this is for interaction-less firmware update start */
|
||||
firmware_header_start = sram1_end - 0x400;
|
||||
_stay_in_bootloader_flag_addr = ABSOLUTE(sram1_end - 0x400 - 4);
|
||||
|
||||
_codelen = SIZEOF(.flash) + SIZEOF(.data) + SIZEOF(.sensitive);
|
||||
|
||||
SECTIONS {
|
||||
.header : ALIGN(4) {
|
||||
KEEP(*(.header));
|
||||
} >FLASH AT>FLASH
|
||||
|
||||
.flash : ALIGN(512) {
|
||||
KEEP(*(.vector_table));
|
||||
. = ALIGN(4);
|
||||
*(.text*);
|
||||
. = ALIGN(4);
|
||||
*(.rodata*);
|
||||
. = ALIGN(512);
|
||||
} >FLASH AT>FLASH
|
||||
|
||||
.data : ALIGN(4) {
|
||||
*(.data*);
|
||||
. = ALIGN(512);
|
||||
} >SRAM1 AT>FLASH
|
||||
|
||||
/DISCARD/ : {
|
||||
*(.ARM.exidx*);
|
||||
}
|
||||
|
||||
.bss : ALIGN(4) {
|
||||
*(.bss*);
|
||||
. = ALIGN(4);
|
||||
} >SRAM1
|
||||
|
||||
.buf : ALIGN(4) {
|
||||
*(.buf*);
|
||||
. = ALIGN(4);
|
||||
} >SRAM1
|
||||
|
||||
.stack : ALIGN(8) {
|
||||
. = 16K + 0x100; /* Exactly 16K allocated for stack. Overflow causes MemManage fault (when using MPU). */
|
||||
} >SRAM2
|
||||
|
||||
.sensitive : ALIGN(512) {
|
||||
*(.sensitive*);
|
||||
. = ALIGN(512);
|
||||
} >SRAM2 AT>FLASH
|
||||
|
||||
.fb1 : ALIGN(4) {
|
||||
*(.fb1*);
|
||||
. = ALIGN(4);
|
||||
} >SRAM3
|
||||
|
||||
.fb2 : ALIGN(4) {
|
||||
*(.fb2*);
|
||||
. = ALIGN(4);
|
||||
} >SRAM5
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
.syntax unified
|
||||
|
||||
.text
|
||||
|
||||
.global reset_handler
|
||||
.type reset_handler, STT_FUNC
|
||||
reset_handler:
|
||||
// setup environment for subsequent stage of code
|
||||
ldr r2, =0 // r2 - the word-sized value to be written
|
||||
|
||||
ldr r0, =sram1_start // r0 - point to beginning of SRAM
|
||||
ldr r1, =sram1_end // r1 - point to byte after the end of SRAM
|
||||
bl memset_reg
|
||||
|
||||
ldr r0, =sram2_start // r0 - point to beginning of SRAM
|
||||
ldr r1, =sram2_end // r1 - point to byte after the end of SRAM
|
||||
bl memset_reg
|
||||
|
||||
ldr r0, =sram3_start // r0 - point to beginning of SRAM
|
||||
ldr r1, =sram3_end // r1 - point to byte after the end of SRAM
|
||||
bl memset_reg
|
||||
|
||||
ldr r0, =sram4_start // r0 - point to beginning of SRAM
|
||||
ldr r1, =sram4_end // r1 - point to byte after the end of SRAM
|
||||
bl memset_reg
|
||||
|
||||
ldr r0, =sram5_start // r0 - point to beginning of SRAM
|
||||
ldr r1, =sram5_end // r1 - point to byte after the end of SRAM
|
||||
bl memset_reg
|
||||
|
||||
// copy data in from flash
|
||||
ldr r0, =data_vma // dst addr
|
||||
ldr r1, =data_lma // src addr
|
||||
ldr r2, =data_size // size in bytes
|
||||
bl memcpy
|
||||
|
||||
// copy sensitive data in from flash
|
||||
ldr r0, =sensitive_vma // dst addr
|
||||
ldr r1, =sensitive_lma // src addr
|
||||
ldr r2, =sensitive_size // size in bytes
|
||||
bl memcpy
|
||||
|
||||
// setup the stack protector (see build script "-fstack-protector-all") with an unpredictable value
|
||||
bl rng_get
|
||||
ldr r1, = __stack_chk_guard
|
||||
str r0, [r1]
|
||||
|
||||
// re-enable exceptions
|
||||
// according to "ARM Cortex-M Programming Guide to Memory Barrier Instructions" Application Note 321, section 4.7:
|
||||
// "If it is not necessary to ensure that a pended interrupt is recognized immediately before
|
||||
// subsequent operations, it is not necessary to insert a memory barrier instruction."
|
||||
cpsie f
|
||||
|
||||
// enter the application code
|
||||
bl main
|
||||
|
||||
b shutdown_privileged
|
||||
|
||||
.end
|
@ -0,0 +1,100 @@
|
||||
/* Trezor v2 bootloader linker script */
|
||||
|
||||
ENTRY(reset_handler)
|
||||
|
||||
MEMORY {
|
||||
FLASH (rx) : ORIGIN = 0x0C010000, LENGTH = 128K
|
||||
SRAM1 (wal) : ORIGIN = 0x30000000, LENGTH = 768K
|
||||
SRAM2 (wal) : ORIGIN = 0x300C0000, LENGTH = 64K
|
||||
SRAM3 (wal) : ORIGIN = 0x300D0000, LENGTH = 832K
|
||||
SRAM5 (wal) : ORIGIN = 0x301A0000, LENGTH = 832K
|
||||
SRAM6 (wal) : ORIGIN = 0x30270000, LENGTH = 512K
|
||||
SRAM4 (wal) : ORIGIN = 0x38000000, LENGTH = 16K
|
||||
}
|
||||
|
||||
main_stack_base = ORIGIN(SRAM2) + SIZEOF(.stack); /* 8-byte aligned full descending stack */
|
||||
_sstack = ORIGIN(SRAM2) + 0x100;
|
||||
_estack = main_stack_base;
|
||||
|
||||
/* used by the startup code to populate variables used by the C code */
|
||||
data_lma = LOADADDR(.data);
|
||||
data_vma = ADDR(.data);
|
||||
data_size = SIZEOF(.data);
|
||||
|
||||
/* used by the startup code to populate variables used by the C code */
|
||||
sensitive_lma = LOADADDR(.sensitive);
|
||||
sensitive_vma = ADDR(.sensitive);
|
||||
sensitive_size = SIZEOF(.sensitive);
|
||||
|
||||
/* used by the startup code to wipe memory */
|
||||
sram1_start = ORIGIN(SRAM1);
|
||||
sram1_end = ORIGIN(SRAM1) + LENGTH(SRAM1);
|
||||
sram2_start = ORIGIN(SRAM2);
|
||||
sram2_end = ORIGIN(SRAM2) + LENGTH(SRAM2);
|
||||
sram3_start = ORIGIN(SRAM3);
|
||||
sram3_end = ORIGIN(SRAM3) + LENGTH(SRAM3);
|
||||
sram4_start = ORIGIN(SRAM4);
|
||||
sram4_end = ORIGIN(SRAM4) + LENGTH(SRAM4);
|
||||
sram5_start = ORIGIN(SRAM5);
|
||||
sram5_end = ORIGIN(SRAM5) + LENGTH(SRAM5);
|
||||
sram6_start = ORIGIN(SRAM6);
|
||||
sram6_end = ORIGIN(SRAM6) + LENGTH(SRAM6);
|
||||
|
||||
/* IMAGE_HEADER_SIZE is 0x400, this is for interaction-less firmware update start */
|
||||
firmware_header_start = sram1_end - 0x400;
|
||||
_stay_in_bootloader_flag_addr = ABSOLUTE(sram1_end - 0x400 - 4);
|
||||
|
||||
_codelen = SIZEOF(.flash) + SIZEOF(.data) + SIZEOF(.sensitive);
|
||||
|
||||
SECTIONS {
|
||||
.header : ALIGN(4) {
|
||||
KEEP(*(.header));
|
||||
} >FLASH AT>FLASH
|
||||
|
||||
.flash : ALIGN(512) {
|
||||
KEEP(*(.vector_table));
|
||||
. = ALIGN(4);
|
||||
*(.text*);
|
||||
. = ALIGN(4);
|
||||
*(.rodata*);
|
||||
. = ALIGN(512);
|
||||
} >FLASH AT>FLASH
|
||||
|
||||
.data : ALIGN(4) {
|
||||
*(.data*);
|
||||
. = ALIGN(512);
|
||||
} >SRAM1 AT>FLASH
|
||||
|
||||
/DISCARD/ : {
|
||||
*(.ARM.exidx*);
|
||||
}
|
||||
|
||||
.bss : ALIGN(4) {
|
||||
*(.bss*);
|
||||
. = ALIGN(4);
|
||||
} >SRAM1
|
||||
|
||||
.buf : ALIGN(4) {
|
||||
*(.buf*);
|
||||
. = ALIGN(4);
|
||||
} >SRAM1
|
||||
|
||||
.stack : ALIGN(8) {
|
||||
. = 16K + 0x100; /* Exactly 16K allocated for stack. Overflow causes MemManage fault (when using MPU). */
|
||||
} >SRAM2
|
||||
|
||||
.sensitive : ALIGN(512) {
|
||||
*(.sensitive*);
|
||||
. = ALIGN(512);
|
||||
} >SRAM2 AT>FLASH
|
||||
|
||||
.fb1 : ALIGN(4) {
|
||||
*(.fb1*);
|
||||
. = ALIGN(4);
|
||||
} >SRAM3
|
||||
|
||||
.fb2 : ALIGN(4) {
|
||||
*(.fb2*);
|
||||
. = ALIGN(4);
|
||||
} >SRAM5
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
.syntax unified
|
||||
|
||||
.text
|
||||
|
||||
.global reset_handler
|
||||
.type reset_handler, STT_FUNC
|
||||
reset_handler:
|
||||
// setup environment for subsequent stage of code
|
||||
ldr r2, =0 // r2 - the word-sized value to be written
|
||||
|
||||
ldr r0, =sram1_start // r0 - point to beginning of SRAM
|
||||
ldr r1, =sram1_end // r1 - point to byte after the end of SRAM
|
||||
bl memset_reg
|
||||
|
||||
ldr r0, =sram2_start // r0 - point to beginning of SRAM
|
||||
ldr r1, =sram2_end // r1 - point to byte after the end of SRAM
|
||||
bl memset_reg
|
||||
|
||||
ldr r0, =sram3_start // r0 - point to beginning of SRAM
|
||||
ldr r1, =sram3_end // r1 - point to byte after the end of SRAM
|
||||
bl memset_reg
|
||||
|
||||
ldr r0, =sram4_start // r0 - point to beginning of SRAM
|
||||
ldr r1, =sram4_end // r1 - point to byte after the end of SRAM
|
||||
bl memset_reg
|
||||
|
||||
ldr r0, =sram5_start // r0 - point to beginning of SRAM
|
||||
ldr r1, =sram5_end // r1 - point to byte after the end of SRAM
|
||||
bl memset_reg
|
||||
|
||||
// copy data in from flash
|
||||
ldr r0, =data_vma // dst addr
|
||||
ldr r1, =data_lma // src addr
|
||||
ldr r2, =data_size // size in bytes
|
||||
bl memcpy
|
||||
|
||||
// copy sensitive data in from flash
|
||||
ldr r0, =sensitive_vma // dst addr
|
||||
ldr r1, =sensitive_lma // src addr
|
||||
ldr r2, =sensitive_size // size in bytes
|
||||
bl memcpy
|
||||
|
||||
// setup the stack protector (see build script "-fstack-protector-all") with an unpredictable value
|
||||
bl rng_get
|
||||
ldr r1, = __stack_chk_guard
|
||||
str r0, [r1]
|
||||
|
||||
// re-enable exceptions
|
||||
// according to "ARM Cortex-M Programming Guide to Memory Barrier Instructions" Application Note 321, section 4.7:
|
||||
// "If it is not necessary to ensure that a pended interrupt is recognized immediately before
|
||||
// subsequent operations, it is not necessary to insert a memory barrier instruction."
|
||||
cpsie f
|
||||
|
||||
// enter the application code
|
||||
bl main
|
||||
|
||||
b shutdown_privileged
|
||||
|
||||
.end
|
@ -0,0 +1,52 @@
|
||||
.syntax unified
|
||||
|
||||
.text
|
||||
|
||||
.global reset_handler
|
||||
.type reset_handler, STT_FUNC
|
||||
reset_handler:
|
||||
// setup environment for subsequent stage of code
|
||||
ldr r2, =0 // r2 - the word-sized value to be written
|
||||
|
||||
ldr r0, =sram1_start // r0 - point to beginning of SRAM
|
||||
ldr r1, =sram1_end // r1 - point to byte after the end of SRAM
|
||||
bl memset_reg
|
||||
|
||||
ldr r0, =sram2_start // r0 - point to beginning of SRAM
|
||||
ldr r1, =sram2_end // r1 - point to byte after the end of SRAM
|
||||
bl memset_reg
|
||||
|
||||
ldr r0, =sram4_start // r0 - point to beginning of SRAM
|
||||
ldr r1, =sram4_end // r1 - point to byte after the end of SRAM
|
||||
bl memset_reg
|
||||
|
||||
|
||||
// copy data in from flash
|
||||
ldr r0, =data_vma // dst addr
|
||||
ldr r1, =data_lma // src addr
|
||||
ldr r2, =data_size // size in bytes
|
||||
bl memcpy
|
||||
|
||||
// copy sensitive data in from flash
|
||||
ldr r0, =sensitive_vma // dst addr
|
||||
ldr r1, =sensitive_lma // src addr
|
||||
ldr r2, =sensitive_size // size in bytes
|
||||
bl memcpy
|
||||
|
||||
// setup the stack protector (see build script "-fstack-protector-all") with an unpredictable value
|
||||
bl rng_get
|
||||
ldr r1, = __stack_chk_guard
|
||||
str r0, [r1]
|
||||
|
||||
// re-enable exceptions
|
||||
// according to "ARM Cortex-M Programming Guide to Memory Barrier Instructions" Application Note 321, section 4.7:
|
||||
// "If it is not necessary to ensure that a pended interrupt is recognized immediately before
|
||||
// subsequent operations, it is not necessary to insert a memory barrier instruction."
|
||||
cpsie f
|
||||
|
||||
// enter the application code
|
||||
bl main
|
||||
|
||||
b shutdown_privileged
|
||||
|
||||
.end
|
@ -0,0 +1,112 @@
|
||||
/* TREZORv2 firmware linker script */
|
||||
|
||||
ENTRY(reset_handler)
|
||||
|
||||
MEMORY {
|
||||
FLASH (rx) : ORIGIN = 0x0C050000, LENGTH = 3648K
|
||||
SRAM1 (wal) : ORIGIN = 0x30000000, LENGTH = 768K
|
||||
SRAM2 (wal) : ORIGIN = 0x300C0000, LENGTH = 64K
|
||||
SRAM3 (wal) : ORIGIN = 0x300D0000, LENGTH = 832K
|
||||
SRAM5 (wal) : ORIGIN = 0x301A0000, LENGTH = 832K
|
||||
SRAM6 (wal) : ORIGIN = 0x30270000, LENGTH = 512K
|
||||
SRAM4 (wal) : ORIGIN = 0x38000000, LENGTH = 16K
|
||||
}
|
||||
|
||||
main_stack_base = ORIGIN(SRAM2) + SIZEOF(.stack); /* 8-byte aligned full descending stack */
|
||||
_sstack = ORIGIN(SRAM2) + 0x100;
|
||||
_estack = main_stack_base;
|
||||
|
||||
/* used by the startup code to populate variables used by the C code */
|
||||
data_lma = LOADADDR(.data);
|
||||
data_vma = ADDR(.data);
|
||||
data_size = SIZEOF(.data);
|
||||
|
||||
/* used by the startup code to populate variables used by the C code */
|
||||
sensitive_lma = LOADADDR(.sensitive);
|
||||
sensitive_vma = ADDR(.sensitive);
|
||||
sensitive_size = SIZEOF(.sensitive);
|
||||
|
||||
/* used by the startup code to wipe memory */
|
||||
sram1_start = ORIGIN(SRAM1);
|
||||
sram1_end = ORIGIN(SRAM1) + LENGTH(SRAM1);
|
||||
sram2_start = ORIGIN(SRAM2);
|
||||
sram2_end = ORIGIN(SRAM2) + LENGTH(SRAM2);
|
||||
sram3_start = ORIGIN(SRAM3);
|
||||
sram3_end = ORIGIN(SRAM3) + LENGTH(SRAM3);
|
||||
sram4_start = ORIGIN(SRAM4);
|
||||
sram4_end = ORIGIN(SRAM4) + LENGTH(SRAM4);
|
||||
sram5_start = ORIGIN(SRAM5);
|
||||
sram5_end = ORIGIN(SRAM5) + LENGTH(SRAM5);
|
||||
sram6_start = ORIGIN(SRAM6);
|
||||
sram6_end = ORIGIN(SRAM6) + LENGTH(SRAM6);
|
||||
|
||||
_codelen = SIZEOF(.flash) + SIZEOF(.data) + SIZEOF(.sensitive);
|
||||
_flash_start = ORIGIN(FLASH);
|
||||
_flash_end = ORIGIN(FLASH) + LENGTH(FLASH);
|
||||
_heap_start = ADDR(.heap);
|
||||
_heap_end = ADDR(.heap) + SIZEOF(.heap);
|
||||
|
||||
SECTIONS {
|
||||
.vendorheader : ALIGN(4) {
|
||||
KEEP(*(.vendorheader))
|
||||
} >FLASH AT>FLASH
|
||||
|
||||
.header : ALIGN(4) {
|
||||
KEEP(*(.header));
|
||||
} >FLASH AT>FLASH
|
||||
|
||||
.flash : ALIGN(512) {
|
||||
KEEP(*(.vector_table));
|
||||
. = ALIGN(4);
|
||||
*(.text*);
|
||||
. = ALIGN(4);
|
||||
*(.rodata*);
|
||||
. = ALIGN(4);
|
||||
KEEP(*(.bootloader));
|
||||
*(.bootloader*);
|
||||
. = ALIGN(512);
|
||||
} >FLASH AT>FLASH
|
||||
|
||||
.data : ALIGN(4) {
|
||||
*(.data*);
|
||||
. = ALIGN(512);
|
||||
} >SRAM1 AT>FLASH
|
||||
|
||||
/DISCARD/ : {
|
||||
*(.ARM.exidx*);
|
||||
}
|
||||
|
||||
.bss : ALIGN(4) {
|
||||
*(.bss*);
|
||||
. = ALIGN(4);
|
||||
} >SRAM1
|
||||
|
||||
.data_ccm : ALIGN(4) {
|
||||
*(.no_dma_buffers*);
|
||||
. = ALIGN(4);
|
||||
} >SRAM1
|
||||
|
||||
.heap : ALIGN(4) {
|
||||
. = 37K; /* this acts as a build time assertion that at least this much memory is available for heap use */
|
||||
. = ABSOLUTE(sram1_end); /* this explicitly sets the end of the heap */
|
||||
} >SRAM1
|
||||
|
||||
.stack : ALIGN(8) {
|
||||
. = 16K + 0x100; /* Exactly 16K allocated for stack. Overflow causes MemManage fault (when using MPU). */
|
||||
} >SRAM2
|
||||
|
||||
.sensitive : ALIGN(512) {
|
||||
*(.sensitive*);
|
||||
. = ALIGN(512);
|
||||
} >SRAM2 AT>FLASH
|
||||
|
||||
.fb1 : ALIGN(4) {
|
||||
*(.fb1*);
|
||||
. = ALIGN(4);
|
||||
} >SRAM3
|
||||
|
||||
.fb2 : ALIGN(4) {
|
||||
*(.fb2*);
|
||||
. = ALIGN(4);
|
||||
} >SRAM5
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
.syntax unified
|
||||
|
||||
.text
|
||||
|
||||
.global reset_handler
|
||||
.type reset_handler, STT_FUNC
|
||||
reset_handler:
|
||||
// setup environment for subsequent stage of code
|
||||
ldr r2, =0 // r2 - the word-sized value to be written
|
||||
|
||||
ldr r0, =sram1_start // r0 - point to beginning of SRAM
|
||||
ldr r1, =sram1_end // r1 - point to byte after the end of SRAM
|
||||
bl memset_reg
|
||||
|
||||
ldr r0, =sram2_start // r0 - point to beginning of SRAM
|
||||
ldr r1, =sram2_end // r1 - point to byte after the end of SRAM
|
||||
bl memset_reg
|
||||
|
||||
ldr r0, =sram4_start // r0 - point to beginning of SRAM
|
||||
ldr r1, =sram4_end // r1 - point to byte after the end of SRAM
|
||||
bl memset_reg
|
||||
|
||||
|
||||
// copy data in from flash
|
||||
ldr r0, =data_vma // dst addr
|
||||
ldr r1, =data_lma // src addr
|
||||
ldr r2, =data_size // size in bytes
|
||||
bl memcpy
|
||||
|
||||
// copy sensitive data in from flash
|
||||
ldr r0, =sensitive_vma // dst addr
|
||||
ldr r1, =sensitive_lma // src addr
|
||||
ldr r2, =sensitive_size // size in bytes
|
||||
bl memcpy
|
||||
|
||||
// setup the stack protector (see build script "-fstack-protector-all") with an unpredictable value
|
||||
bl rng_get
|
||||
ldr r1, = __stack_chk_guard
|
||||
str r0, [r1]
|
||||
|
||||
// re-enable exceptions
|
||||
// according to "ARM Cortex-M Programming Guide to Memory Barrier Instructions" Application Note 321, section 4.7:
|
||||
// "If it is not necessary to ensure that a pended interrupt is recognized immediately before
|
||||
// subsequent operations, it is not necessary to insert a memory barrier instruction."
|
||||
cpsie f
|
||||
|
||||
// enter the application code
|
||||
bl main
|
||||
|
||||
b shutdown_privileged
|
||||
|
||||
.end
|
@ -0,0 +1,112 @@
|
||||
/* TREZORv2 firmware linker script */
|
||||
|
||||
ENTRY(reset_handler)
|
||||
|
||||
MEMORY {
|
||||
FLASH (rx) : ORIGIN = 0x0C050000, LENGTH = 3648K
|
||||
SRAM1 (wal) : ORIGIN = 0x30000000, LENGTH = 768K
|
||||
SRAM2 (wal) : ORIGIN = 0x300C0000, LENGTH = 64K
|
||||
SRAM3 (wal) : ORIGIN = 0x300D0000, LENGTH = 832K
|
||||
SRAM5 (wal) : ORIGIN = 0x301A0000, LENGTH = 832K
|
||||
SRAM6 (wal) : ORIGIN = 0x30270000, LENGTH = 512K
|
||||
SRAM4 (wal) : ORIGIN = 0x38000000, LENGTH = 16K
|
||||
}
|
||||
|
||||
main_stack_base = ORIGIN(SRAM2) + SIZEOF(.stack); /* 8-byte aligned full descending stack */
|
||||
_sstack = ORIGIN(SRAM2) + 0x100;
|
||||
_estack = main_stack_base;
|
||||
|
||||
/* used by the startup code to populate variables used by the C code */
|
||||
data_lma = LOADADDR(.data);
|
||||
data_vma = ADDR(.data);
|
||||
data_size = SIZEOF(.data);
|
||||
|
||||
/* used by the startup code to populate variables used by the C code */
|
||||
sensitive_lma = LOADADDR(.sensitive);
|
||||
sensitive_vma = ADDR(.sensitive);
|
||||
sensitive_size = SIZEOF(.sensitive);
|
||||
|
||||
/* used by the startup code to wipe memory */
|
||||
sram1_start = ORIGIN(SRAM1);
|
||||
sram1_end = ORIGIN(SRAM1) + LENGTH(SRAM1);
|
||||
sram2_start = ORIGIN(SRAM2);
|
||||
sram2_end = ORIGIN(SRAM2) + LENGTH(SRAM2);
|
||||
sram3_start = ORIGIN(SRAM3);
|
||||
sram3_end = ORIGIN(SRAM3) + LENGTH(SRAM3);
|
||||
sram4_start = ORIGIN(SRAM4);
|
||||
sram4_end = ORIGIN(SRAM4) + LENGTH(SRAM4);
|
||||
sram5_start = ORIGIN(SRAM5);
|
||||
sram5_end = ORIGIN(SRAM5) + LENGTH(SRAM5);
|
||||
sram6_start = ORIGIN(SRAM6);
|
||||
sram6_end = ORIGIN(SRAM6) + LENGTH(SRAM6);
|
||||
|
||||
_codelen = SIZEOF(.flash) + SIZEOF(.data) + SIZEOF(.sensitive);
|
||||
_flash_start = ORIGIN(FLASH);
|
||||
_flash_end = ORIGIN(FLASH) + LENGTH(FLASH);
|
||||
_heap_start = ADDR(.heap);
|
||||
_heap_end = ADDR(.heap) + SIZEOF(.heap);
|
||||
|
||||
SECTIONS {
|
||||
.vendorheader : ALIGN(4) {
|
||||
KEEP(*(.vendorheader))
|
||||
} >FLASH AT>FLASH
|
||||
|
||||
.header : ALIGN(4) {
|
||||
KEEP(*(.header));
|
||||
} >FLASH AT>FLASH
|
||||
|
||||
.flash : ALIGN(512) {
|
||||
KEEP(*(.vector_table));
|
||||
. = ALIGN(4);
|
||||
*(.text*);
|
||||
. = ALIGN(4);
|
||||
*(.rodata*);
|
||||
. = ALIGN(4);
|
||||
KEEP(*(.bootloader));
|
||||
*(.bootloader*);
|
||||
. = ALIGN(512);
|
||||
} >FLASH AT>FLASH
|
||||
|
||||
.data : ALIGN(4) {
|
||||
*(.data*);
|
||||
. = ALIGN(512);
|
||||
} >SRAM1 AT>FLASH
|
||||
|
||||
/DISCARD/ : {
|
||||
*(.ARM.exidx*);
|
||||
}
|
||||
|
||||
.bss : ALIGN(4) {
|
||||
*(.bss*);
|
||||
. = ALIGN(4);
|
||||
} >SRAM1
|
||||
|
||||
.data_ccm : ALIGN(4) {
|
||||
*(.no_dma_buffers*);
|
||||
. = ALIGN(4);
|
||||
} >SRAM1
|
||||
|
||||
.heap : ALIGN(4) {
|
||||
. = 37K; /* this acts as a build time assertion that at least this much memory is available for heap use */
|
||||
. = ABSOLUTE(sram1_end); /* this explicitly sets the end of the heap */
|
||||
} >SRAM1
|
||||
|
||||
.stack : ALIGN(8) {
|
||||
. = 16K + 0x100; /* Exactly 16K allocated for stack. Overflow causes MemManage fault (when using MPU). */
|
||||
} >SRAM2
|
||||
|
||||
.sensitive : ALIGN(512) {
|
||||
*(.sensitive*);
|
||||
. = ALIGN(512);
|
||||
} >SRAM2 AT>FLASH
|
||||
|
||||
.fb1 : ALIGN(4) {
|
||||
*(.fb1*);
|
||||
. = ALIGN(4);
|
||||
} >SRAM3
|
||||
|
||||
.fb2 : ALIGN(4) {
|
||||
*(.fb2*);
|
||||
. = ALIGN(4);
|
||||
} >SRAM5
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
.syntax unified
|
||||
|
||||
.text
|
||||
|
||||
.global reset_handler
|
||||
.type reset_handler, STT_FUNC
|
||||
reset_handler:
|
||||
// setup environment for subsequent stage of code
|
||||
ldr r2, =0 // r2 - the word-sized value to be written
|
||||
|
||||
ldr r0, =sram1_start // r0 - point to beginning of SRAM
|
||||
ldr r1, =sram1_end // r1 - point to byte after the end of SRAM
|
||||
bl memset_reg
|
||||
|
||||
ldr r0, =sram2_start // r0 - point to beginning of SRAM
|
||||
ldr r1, =sram2_end // r1 - point to byte after the end of SRAM
|
||||
bl memset_reg
|
||||
|
||||
ldr r0, =sram4_start // r0 - point to beginning of SRAM
|
||||
ldr r1, =sram4_end // r1 - point to byte after the end of SRAM
|
||||
bl memset_reg
|
||||
|
||||
|
||||
// copy data in from flash
|
||||
ldr r0, =data_vma // dst addr
|
||||
ldr r1, =data_lma // src addr
|
||||
ldr r2, =data_size // size in bytes
|
||||
bl memcpy
|
||||
|
||||
// copy sensitive data in from flash
|
||||
ldr r0, =sensitive_vma // dst addr
|
||||
ldr r1, =sensitive_lma // src addr
|
||||
ldr r2, =sensitive_size // size in bytes
|
||||
bl memcpy
|
||||
|
||||
// setup the stack protector (see build script "-fstack-protector-all") with an unpredictable value
|
||||
bl rng_get
|
||||
ldr r1, = __stack_chk_guard
|
||||
str r0, [r1]
|
||||
|
||||
// re-enable exceptions
|
||||
// according to "ARM Cortex-M Programming Guide to Memory Barrier Instructions" Application Note 321, section 4.7:
|
||||
// "If it is not necessary to ensure that a pended interrupt is recognized immediately before
|
||||
// subsequent operations, it is not necessary to insert a memory barrier instruction."
|
||||
cpsie f
|
||||
|
||||
// enter the application code
|
||||
bl main
|
||||
|
||||
b shutdown_privileged
|
||||
|
||||
.end
|
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* This file is part of the Trezor project, https://trezor.io/
|
||||
*
|
||||
* Copyright (c) SatoshiLabs
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TREZOR_HAL_SECURE_AES_H
|
||||
#define TREZOR_HAL_SECURE_AES_H
|
||||
|
||||
#include <secbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// Initializes secure AES module
|
||||
secbool secure_aes_init(void);
|
||||
|
||||
// Encrypts a block of data using AES-256 CBC and DHUK key
|
||||
// Input and output must be aligned to 32 bits, size is in bytes
|
||||
secbool secure_aes_encrypt(uint32_t* input, size_t size, uint32_t* output);
|
||||
|
||||
// Decrypts a block of data using AES-256 CBC and DHUK key
|
||||
// Input and output must be aligned to 32 bits, size is in bytes
|
||||
secbool secure_aes_decrypt(uint32_t* input, size_t size, uint32_t* output);
|
||||
|
||||
void secure_aes_test();
|
||||
|
||||
#endif // TREZOR_HAL_SECURE_AES_H
|
@ -0,0 +1,18 @@
|
||||
#include "common.h"
|
||||
|
||||
void HardFault_Handler(void) { error_shutdown("INTERNAL ERROR", "(HF)"); }
|
||||
|
||||
void MemManage_Handler(void) { error_shutdown("INTERNAL ERROR", "(MM)"); }
|
||||
|
||||
void MemManage_Handler_SO(void) { error_shutdown("INTERNAL ERROR", "(SO)"); }
|
||||
|
||||
void BusFault_Handler(void) { error_shutdown("INTERNAL ERROR", "(BF)"); }
|
||||
|
||||
void UsageFault_Handler(void) { error_shutdown("INTERNAL ERROR", "(UF)"); }
|
||||
|
||||
void NMI_Handler(void) {
|
||||
// Clock Security System triggered NMI
|
||||
if ((RCC->CIR & RCC_CIR_CSSF) != 0) {
|
||||
error_shutdown("INTERNAL ERROR", "(CS)");
|
||||
}
|
||||
}
|
@ -0,0 +1 @@
|
||||
../stm32f4/board_capabilities.c
|
@ -0,0 +1,204 @@
|
||||
/*
|
||||
* This file is part of the Trezor project, https://trezor.io/
|
||||
*
|
||||
* Copyright (c) SatoshiLabs
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include STM32_HAL_H
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "display.h"
|
||||
#include "secret.h"
|
||||
#ifdef FANCY_FATAL_ERROR
|
||||
#include "rust_ui.h"
|
||||
#endif
|
||||
#include "flash.h"
|
||||
#include "model.h"
|
||||
#include "platform.h"
|
||||
#include "rand.h"
|
||||
#include "supervise.h"
|
||||
|
||||
#include "mini_printf.h"
|
||||
#include "stm32u5xx_ll_utils.h"
|
||||
|
||||
#ifdef RGB16
|
||||
#define COLOR_FATAL_ERROR RGB16(0x7F, 0x00, 0x00)
|
||||
#else
|
||||
#define COLOR_FATAL_ERROR COLOR_BLACK
|
||||
#endif
|
||||
|
||||
uint32_t systick_val_copy = 0;
|
||||
|
||||
// from util.s
|
||||
extern void shutdown_privileged(void);
|
||||
|
||||
void __attribute__((noreturn)) trezor_shutdown(void) {
|
||||
__HAL_RCC_SAES_CLK_DISABLE();
|
||||
// Erase all secrets
|
||||
TAMP->CR2 |= TAMP_CR2_BKERASE;
|
||||
|
||||
#ifdef USE_SVC_SHUTDOWN
|
||||
svc_shutdown();
|
||||
#else
|
||||
// It won't work properly unless called from the privileged mode
|
||||
shutdown_privileged();
|
||||
#endif
|
||||
|
||||
for (;;)
|
||||
;
|
||||
}
|
||||
|
||||
void __attribute__((noreturn))
|
||||
error_uni(const char *label, const char *msg, const char *footer) {
|
||||
display_orientation(0);
|
||||
|
||||
#ifdef FANCY_FATAL_ERROR
|
||||
|
||||
screen_fatal_error_rust(label, msg, "PLEASE VISIT\nTREZOR.IO/RSOD");
|
||||
display_refresh();
|
||||
#else
|
||||
display_print_color(COLOR_WHITE, COLOR_FATAL_ERROR);
|
||||
if (label) {
|
||||
display_printf("%s\n", label);
|
||||
}
|
||||
if (msg) {
|
||||
display_printf("%s\n", msg);
|
||||
}
|
||||
if (footer) {
|
||||
display_printf("\n%s\n", footer);
|
||||
}
|
||||
#endif
|
||||
display_backlight(255);
|
||||
display_refresh();
|
||||
trezor_shutdown();
|
||||
}
|
||||
|
||||
void __attribute__((noreturn))
|
||||
__fatal_error(const char *expr, const char *msg, const char *file, int line,
|
||||
const char *func) {
|
||||
display_orientation(0);
|
||||
display_backlight(255);
|
||||
|
||||
#ifdef FANCY_FATAL_ERROR
|
||||
char buf[256] = {0};
|
||||
mini_snprintf(buf, sizeof(buf), "%s: %d", file, line);
|
||||
screen_fatal_error_rust("INTERNAL ERROR", msg != NULL ? msg : buf,
|
||||
"PLEASE VISIT\nTREZOR.IO/RSOD");
|
||||
display_refresh();
|
||||
#else
|
||||
display_print_color(COLOR_WHITE, COLOR_FATAL_ERROR);
|
||||
display_printf("\nINTERNAL ERROR:\n");
|
||||
if (expr) {
|
||||
display_printf("expr: %s\n", expr);
|
||||
}
|
||||
if (msg) {
|
||||
display_printf("msg : %s\n", msg);
|
||||
}
|
||||
if (file) {
|
||||
display_printf("file: %s:%d\n", file, line);
|
||||
}
|
||||
if (func) {
|
||||
display_printf("func: %s\n", func);
|
||||
}
|
||||
#ifdef SCM_REVISION
|
||||
const uint8_t *rev = (const uint8_t *)SCM_REVISION;
|
||||
display_printf("rev : %02x%02x%02x%02x%02x\n", rev[0], rev[1], rev[2], rev[3],
|
||||
rev[4]);
|
||||
#endif
|
||||
display_printf("\nPlease contact Trezor support.\n");
|
||||
#endif
|
||||
trezor_shutdown();
|
||||
}
|
||||
|
||||
void __attribute__((noreturn))
|
||||
error_shutdown(const char *label, const char *msg) {
|
||||
display_orientation(0);
|
||||
|
||||
#ifdef FANCY_FATAL_ERROR
|
||||
|
||||
screen_fatal_error_rust(label, msg, "PLEASE VISIT\nTREZOR.IO/RSOD");
|
||||
display_refresh();
|
||||
#else
|
||||
display_print_color(COLOR_WHITE, COLOR_FATAL_ERROR);
|
||||
if (label) {
|
||||
display_printf("%s\n", label);
|
||||
}
|
||||
if (msg) {
|
||||
display_printf("%s\n", msg);
|
||||
}
|
||||
display_printf("\nPLEASE VISIT TREZOR.IO/RSOD\n");
|
||||
#endif
|
||||
display_backlight(255);
|
||||
trezor_shutdown();
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
void __assert_func(const char *file, int line, const char *func,
|
||||
const char *expr) {
|
||||
__fatal_error(expr, "assert failed", file, line, func);
|
||||
}
|
||||
#endif
|
||||
|
||||
void hal_delay(uint32_t ms) { HAL_Delay(ms); }
|
||||
uint32_t hal_ticks_ms() { return HAL_GetTick(); }
|
||||
|
||||
uint32_t __stack_chk_guard = 0;
|
||||
|
||||
void __attribute__((noreturn)) __stack_chk_fail(void) {
|
||||
error_shutdown("INTERNAL ERROR", "(SS)");
|
||||
}
|
||||
|
||||
uint8_t HW_ENTROPY_DATA[HW_ENTROPY_LEN];
|
||||
|
||||
void collect_hw_entropy(void) {
|
||||
// collect entropy from UUID
|
||||
uint32_t w = LL_GetUID_Word0();
|
||||
memcpy(HW_ENTROPY_DATA, &w, 4);
|
||||
w = LL_GetUID_Word1();
|
||||
memcpy(HW_ENTROPY_DATA + 4, &w, 4);
|
||||
w = LL_GetUID_Word2();
|
||||
memcpy(HW_ENTROPY_DATA + 8, &w, 4);
|
||||
|
||||
// set entropy in the OTP randomness block
|
||||
if (secfalse == flash_otp_is_locked(FLASH_OTP_BLOCK_RANDOMNESS)) {
|
||||
uint8_t entropy[FLASH_OTP_BLOCK_SIZE];
|
||||
random_buffer(entropy, FLASH_OTP_BLOCK_SIZE);
|
||||
ensure(flash_otp_write(FLASH_OTP_BLOCK_RANDOMNESS, 0, entropy,
|
||||
FLASH_OTP_BLOCK_SIZE),
|
||||
NULL);
|
||||
// ensure(flash_otp_lock(FLASH_OTP_BLOCK_RANDOMNESS), NULL);
|
||||
}
|
||||
// collect entropy from OTP randomness block
|
||||
ensure(flash_otp_read(FLASH_OTP_BLOCK_RANDOMNESS, 0, HW_ENTROPY_DATA + 12,
|
||||
FLASH_OTP_BLOCK_SIZE),
|
||||
NULL);
|
||||
}
|
||||
|
||||
// this function resets settings changed in one layer (bootloader/firmware),
|
||||
// which might be incompatible with the other layers older versions,
|
||||
// where this setting might be unknown
|
||||
void ensure_compatible_settings(void) {}
|
||||
|
||||
void show_wipe_code_screen(void) {
|
||||
error_uni("WIPE CODE ENTERED", "All data has been erased from the device",
|
||||
"PLEASE RECONNECT\nTHE DEVICE");
|
||||
}
|
||||
void show_pin_too_many_screen(void) {
|
||||
error_uni("TOO MANY PIN ATTEMPTS", "All data has been erased from the device",
|
||||
"PLEASE RECONNECT\nTHE DEVICE");
|
||||
}
|
@ -0,0 +1,173 @@
|
||||
/*
|
||||
* This file is part of the Trezor project, https://trezor.io/
|
||||
*
|
||||
* Copyright (c) SatoshiLabs
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "dma2d.h"
|
||||
#include "colors.h"
|
||||
#include STM32_HAL_H
|
||||
#include "display_interface.h"
|
||||
|
||||
typedef enum {
|
||||
DMA2D_LAYER_FG = 1,
|
||||
DMA2D_LAYER_BG = 0,
|
||||
} dma2d_layer_t;
|
||||
|
||||
static DMA2D_HandleTypeDef dma2d_handle = {0};
|
||||
static uint16_t current_width = 0;
|
||||
static uint16_t current_height = 0;
|
||||
|
||||
void dma2d_init(void) {
|
||||
__HAL_RCC_DMA2D_CLK_ENABLE();
|
||||
|
||||
dma2d_handle.Instance = (DMA2D_TypeDef*)DMA2D_BASE;
|
||||
dma2d_handle.Init.ColorMode = DISPLAY_COLOR_MODE;
|
||||
dma2d_handle.Init.OutputOffset = 0;
|
||||
}
|
||||
|
||||
static void dma2d_init_clut(uint16_t fg, uint16_t bg, dma2d_layer_t layer) {
|
||||
volatile uint32_t* table = NULL;
|
||||
if (layer == DMA2D_LAYER_BG) {
|
||||
table = dma2d_handle.Instance->BGCLUT;
|
||||
} else {
|
||||
table = dma2d_handle.Instance->FGCLUT;
|
||||
}
|
||||
|
||||
uint32_t fg32 = rgb565_to_rgb888(fg);
|
||||
uint32_t bg32 = rgb565_to_rgb888(bg);
|
||||
|
||||
for (uint8_t i = 0; i < 16; i++) {
|
||||
table[i] = interpolate_rgb888_color(fg32, bg32, i);
|
||||
}
|
||||
|
||||
DMA2D_CLUTCfgTypeDef clut;
|
||||
clut.CLUTColorMode = DMA2D_CCM_ARGB8888;
|
||||
clut.Size = 0xf;
|
||||
clut.pCLUT = 0; // loading directly
|
||||
|
||||
HAL_DMA2D_ConfigCLUT(&dma2d_handle, clut, layer);
|
||||
}
|
||||
|
||||
void dma2d_setup_const(void) {
|
||||
dma2d_handle.Init.Mode = DMA2D_R2M;
|
||||
dma2d_handle.Init.OutputOffset = display_get_window_offset();
|
||||
HAL_DMA2D_Init(&dma2d_handle);
|
||||
}
|
||||
|
||||
void dma2d_setup_4bpp(uint16_t fg_color, uint16_t bg_color) {
|
||||
dma2d_handle.Init.Mode = DMA2D_M2M_PFC;
|
||||
dma2d_handle.Init.OutputOffset = display_get_window_offset();
|
||||
dma2d_handle.LayerCfg[1].InputColorMode = DMA2D_INPUT_L4;
|
||||
dma2d_handle.LayerCfg[1].InputOffset = 0;
|
||||
dma2d_handle.LayerCfg[1].AlphaMode = 0;
|
||||
dma2d_handle.LayerCfg[1].InputAlpha = 0;
|
||||
|
||||
dma2d_init_clut(fg_color, bg_color, DMA2D_LAYER_FG);
|
||||
|
||||
HAL_DMA2D_Init(&dma2d_handle);
|
||||
HAL_DMA2D_ConfigLayer(&dma2d_handle, 1);
|
||||
}
|
||||
|
||||
void dma2d_setup_16bpp(void) {
|
||||
dma2d_handle.Init.Mode = DMA2D_M2M_PFC;
|
||||
dma2d_handle.Init.OutputOffset = display_get_window_offset();
|
||||
dma2d_handle.LayerCfg[1].InputColorMode = DMA2D_INPUT_RGB565;
|
||||
dma2d_handle.LayerCfg[1].InputOffset = 0;
|
||||
dma2d_handle.LayerCfg[1].AlphaMode = 0;
|
||||
dma2d_handle.LayerCfg[1].InputAlpha = 0;
|
||||
|
||||
HAL_DMA2D_Init(&dma2d_handle);
|
||||
HAL_DMA2D_ConfigLayer(&dma2d_handle, 1);
|
||||
}
|
||||
|
||||
void dma2d_setup_4bpp_over_16bpp(uint16_t overlay_color) {
|
||||
dma2d_handle.Init.Mode = DMA2D_M2M_BLEND;
|
||||
dma2d_handle.Init.OutputOffset = display_get_window_offset();
|
||||
dma2d_handle.LayerCfg[1].InputColorMode = DMA2D_INPUT_A4;
|
||||
dma2d_handle.LayerCfg[1].InputOffset = 0;
|
||||
dma2d_handle.LayerCfg[1].AlphaMode = 0;
|
||||
dma2d_handle.LayerCfg[1].InputAlpha =
|
||||
0xFF000000 | rgb565_to_rgb888(overlay_color);
|
||||
|
||||
dma2d_handle.LayerCfg[0].InputColorMode = DMA2D_INPUT_RGB565;
|
||||
dma2d_handle.LayerCfg[0].InputOffset = 0;
|
||||
dma2d_handle.LayerCfg[0].AlphaMode = 0;
|
||||
dma2d_handle.LayerCfg[0].InputAlpha = 0;
|
||||
|
||||
HAL_DMA2D_Init(&dma2d_handle);
|
||||
HAL_DMA2D_ConfigLayer(&dma2d_handle, 1);
|
||||
HAL_DMA2D_ConfigLayer(&dma2d_handle, 0);
|
||||
}
|
||||
|
||||
void dma2d_setup_4bpp_over_4bpp(uint16_t fg_color, uint16_t bg_color,
|
||||
uint16_t overlay_color) {
|
||||
dma2d_handle.Init.Mode = DMA2D_M2M_BLEND;
|
||||
dma2d_handle.Init.OutputOffset = display_get_window_offset();
|
||||
dma2d_handle.LayerCfg[1].InputColorMode = DMA2D_INPUT_A4;
|
||||
dma2d_handle.LayerCfg[1].InputOffset = 0;
|
||||
dma2d_handle.LayerCfg[1].AlphaMode = 0;
|
||||
dma2d_handle.LayerCfg[1].InputAlpha = rgb565_to_rgb888(overlay_color);
|
||||
|
||||
dma2d_handle.LayerCfg[0].InputColorMode = DMA2D_INPUT_L4;
|
||||
dma2d_handle.LayerCfg[0].InputOffset = 0;
|
||||
dma2d_handle.LayerCfg[0].AlphaMode = DMA2D_REPLACE_ALPHA;
|
||||
dma2d_handle.LayerCfg[0].InputAlpha = 0xFF;
|
||||
|
||||
dma2d_init_clut(fg_color, bg_color, DMA2D_LAYER_BG);
|
||||
|
||||
HAL_DMA2D_Init(&dma2d_handle);
|
||||
HAL_DMA2D_ConfigLayer(&dma2d_handle, 1);
|
||||
HAL_DMA2D_ConfigLayer(&dma2d_handle, 0);
|
||||
}
|
||||
|
||||
void dma2d_start(uint8_t* in_addr, uint8_t* out_addr, int32_t pixels) {
|
||||
current_width = pixels;
|
||||
current_height = 1;
|
||||
HAL_DMA2D_Start(&dma2d_handle, (uint32_t)in_addr, (uint32_t)out_addr, pixels,
|
||||
1);
|
||||
}
|
||||
|
||||
void dma2d_start_const(uint16_t color, uint8_t* out_addr, int32_t pixels) {
|
||||
current_width = pixels;
|
||||
current_height = 1;
|
||||
HAL_DMA2D_Start(&dma2d_handle, rgb565_to_rgb888(color), (uint32_t)out_addr,
|
||||
pixels, 1);
|
||||
}
|
||||
|
||||
void dma2d_start_const_multiline(uint16_t color, uint8_t* out_addr,
|
||||
int32_t width, int32_t height) {
|
||||
current_width = width;
|
||||
current_height = height;
|
||||
HAL_DMA2D_Start(&dma2d_handle, rgb565_to_rgb888(color), (uint32_t)out_addr,
|
||||
width, height);
|
||||
}
|
||||
|
||||
void dma2d_start_blend(uint8_t* overlay_addr, uint8_t* bg_addr,
|
||||
uint8_t* out_addr, int32_t pixels) {
|
||||
current_width = pixels;
|
||||
current_height = 1;
|
||||
HAL_DMA2D_BlendingStart(&dma2d_handle, (uint32_t)overlay_addr,
|
||||
(uint32_t)bg_addr, (uint32_t)out_addr, pixels, 1);
|
||||
}
|
||||
|
||||
void dma2d_wait_for_transfer(void) {
|
||||
while (HAL_DMA2D_PollForTransfer(&dma2d_handle, 10) != HAL_OK)
|
||||
;
|
||||
display_shift_window(current_width * current_height);
|
||||
current_width = 0;
|
||||
current_height = 0;
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
#include "common.h"
|
||||
|
||||
void HardFault_Handler(void) { error_shutdown("INTERNAL ERROR", "(HF)"); }
|
||||
|
||||
void MemManage_Handler_MM(void) { error_shutdown("INTERNAL ERROR", "(MM)"); }
|
||||
|
||||
void MemManage_Handler_SO(void) { error_shutdown("INTERNAL ERROR", "(SO)"); }
|
||||
|
||||
void BusFault_Handler(void) { error_shutdown("INTERNAL ERROR", "(BF)"); }
|
||||
|
||||
void UsageFault_Handler(void) { error_shutdown("INTERNAL ERROR", "(UF)"); }
|
||||
|
||||
void SecureFault_Handler(void) { error_shutdown("INTERNAL ERROR", "(SF)"); }
|
||||
|
||||
void NMI_Handler(void) {
|
||||
// Clock Security System triggered NMI
|
||||
if ((RCC->CIFR & RCC_CIFR_CSSF) != 0) {
|
||||
error_shutdown("INTERNAL ERROR", "(CS)");
|
||||
}
|
||||
}
|
@ -0,0 +1,477 @@
|
||||
/*
|
||||
* This file is part of the Trezor project, https://trezor.io/
|
||||
*
|
||||
* Copyright (c) SatoshiLabs
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include STM32_HAL_H
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "flash.h"
|
||||
#include "model.h"
|
||||
|
||||
#define FLASH_SEC_START_ADDRESS 0x0C000000
|
||||
#define FLASH_START_ADDRESS 0x08000000
|
||||
|
||||
#define FLASH_SECTOR_COUNT (256 * 2)
|
||||
|
||||
#define FLASH_STATUS_ALL_FLAGS \
|
||||
(FLASH_NSSR_PGSERR | FLASH_NSSR_PGAERR | FLASH_NSSR_WRPERR | FLASH_NSSR_EOP)
|
||||
|
||||
uint32_t flash_wait_and_clear_status_flags(void) {
|
||||
while (FLASH->NSSR & FLASH_NSSR_BSY)
|
||||
; // wait for all previous flash operations to complete
|
||||
|
||||
uint32_t result =
|
||||
FLASH->NSSR & FLASH_STATUS_ALL_FLAGS; // get the current status flags
|
||||
FLASH->NSSR |= FLASH_STATUS_ALL_FLAGS; // clear all status flags
|
||||
|
||||
#if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
|
||||
while (FLASH->SECSR & FLASH_SECSR_BSY)
|
||||
; // wait for all previous flash operations to complete
|
||||
result |=
|
||||
FLASH->SECSR & FLASH_STATUS_ALL_FLAGS; // get the current status flags
|
||||
FLASH->SECSR |= FLASH_STATUS_ALL_FLAGS; // clear all status flags
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
secbool flash_unlock_write(void) {
|
||||
HAL_FLASH_Unlock();
|
||||
FLASH->NSSR |= FLASH_STATUS_ALL_FLAGS; // clear all status flags
|
||||
#if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
|
||||
FLASH->SECSR |= FLASH_STATUS_ALL_FLAGS; // clear all status flags
|
||||
#endif
|
||||
return sectrue;
|
||||
}
|
||||
|
||||
secbool flash_lock_write(void) {
|
||||
HAL_FLASH_Lock();
|
||||
return sectrue;
|
||||
}
|
||||
|
||||
const void *flash_get_address(uint16_t sector, uint32_t offset, uint32_t size,
|
||||
bool secure_area) {
|
||||
if (sector >= FLASH_SECTOR_COUNT) {
|
||||
return NULL;
|
||||
}
|
||||
uint32_t base_addr = FLASH_START_ADDRESS;
|
||||
|
||||
if (secure_area) {
|
||||
base_addr = FLASH_SEC_START_ADDRESS;
|
||||
}
|
||||
|
||||
const uint32_t addr = base_addr + (FLASH_PAGE_SIZE * sector) + offset;
|
||||
const uint32_t next = base_addr + (FLASH_PAGE_SIZE * (sector + 1));
|
||||
if (addr + size > next) {
|
||||
return NULL;
|
||||
}
|
||||
return (const void *)addr;
|
||||
}
|
||||
|
||||
uint32_t flash_sector_size(uint16_t sector) {
|
||||
if (sector >= FLASH_SECTOR_COUNT) {
|
||||
return 0;
|
||||
}
|
||||
return FLASH_PAGE_SIZE;
|
||||
}
|
||||
|
||||
uint32_t flash_subarea_get_size(const flash_subarea_t *sub) {
|
||||
return FLASH_PAGE_SIZE * sub->num_sectors;
|
||||
}
|
||||
|
||||
uint32_t flash_area_get_size(const flash_area_t *area) {
|
||||
uint32_t size = 0;
|
||||
for (int i = 0; i < area->num_subareas; i++) {
|
||||
size += flash_subarea_get_size(&area->subarea[i]);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
uint16_t flash_total_sectors(const flash_area_t *area) {
|
||||
uint16_t total = 0;
|
||||
for (int i = 0; i < area->num_subareas; i++) {
|
||||
total += area->subarea[i].num_sectors;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
const void *flash_area_get_address(const flash_area_t *area, uint32_t offset,
|
||||
uint32_t size) {
|
||||
uint32_t tmp_offset = offset;
|
||||
|
||||
for (int i = 0; i < area->num_subareas; i++) {
|
||||
uint16_t sector = area->subarea[i].first_sector;
|
||||
|
||||
if (tmp_offset >= flash_subarea_get_size(area->subarea)) {
|
||||
tmp_offset -= flash_subarea_get_size(area->subarea);
|
||||
continue;
|
||||
}
|
||||
|
||||
uint32_t base_addr = FLASH_START_ADDRESS;
|
||||
|
||||
if (area->secure_area) {
|
||||
base_addr = FLASH_SEC_START_ADDRESS;
|
||||
}
|
||||
|
||||
const uint32_t addr = base_addr + (FLASH_PAGE_SIZE * sector) + tmp_offset;
|
||||
const uint32_t area_end =
|
||||
base_addr + (FLASH_PAGE_SIZE * (area->subarea[i].first_sector +
|
||||
area->subarea[i].num_sectors));
|
||||
if (addr + size > area_end) {
|
||||
return NULL;
|
||||
}
|
||||
return (const void *)addr;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int32_t flash_get_sector_num(const flash_area_t *area,
|
||||
uint32_t sector_inner_num) {
|
||||
uint16_t sector = 0;
|
||||
uint16_t remaining = sector_inner_num;
|
||||
for (int i = 0; i < area->num_subareas; i++) {
|
||||
if (remaining < area->subarea[i].num_sectors) {
|
||||
sector = area->subarea[i].first_sector + remaining;
|
||||
return sector;
|
||||
} else {
|
||||
remaining -= area->subarea[i].num_sectors;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
secbool flash_area_erase(const flash_area_t *area,
|
||||
void (*progress)(int pos, int len)) {
|
||||
ensure(flash_unlock_write(), NULL);
|
||||
FLASH_EraseInitTypeDef EraseInitStruct;
|
||||
EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
|
||||
EraseInitStruct.NbPages = 1;
|
||||
|
||||
int total_pages = 0;
|
||||
int done_pages = 0;
|
||||
for (int i = 0; i < area->num_subareas; i++) {
|
||||
total_pages += area->subarea[i].num_sectors;
|
||||
}
|
||||
|
||||
if (progress) {
|
||||
progress(0, total_pages);
|
||||
}
|
||||
|
||||
for (int s = 0; s < area->num_subareas; s++) {
|
||||
for (int i = 0; i < area->subarea[s].num_sectors; i++) {
|
||||
int page = area->subarea[s].first_sector + i;
|
||||
if (page >= 256) {
|
||||
EraseInitStruct.Banks = FLASH_BANK_2;
|
||||
} else {
|
||||
EraseInitStruct.Banks = FLASH_BANK_1;
|
||||
}
|
||||
EraseInitStruct.Page = page;
|
||||
uint32_t SectorError;
|
||||
if (HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError) != HAL_OK) {
|
||||
ensure(flash_lock_write(), NULL);
|
||||
return secfalse;
|
||||
}
|
||||
// check whether the sector was really deleted (contains only 0xFF)
|
||||
const uint32_t addr_start =
|
||||
(uint32_t)flash_get_address(page, 0, 0, area->secure_area);
|
||||
const uint32_t addr_end =
|
||||
(uint32_t)flash_get_address(page + 1, 0, 0, area->secure_area);
|
||||
|
||||
for (uint32_t addr = addr_start; addr < addr_end; addr += 4) {
|
||||
if (*((const uint32_t *)addr) != 0xFFFFFFFF) {
|
||||
ensure(flash_lock_write(), NULL);
|
||||
return secfalse;
|
||||
}
|
||||
}
|
||||
done_pages++;
|
||||
if (progress && done_pages % 16 == 0) {
|
||||
progress(done_pages, total_pages);
|
||||
}
|
||||
}
|
||||
}
|
||||
ensure(flash_lock_write(), NULL);
|
||||
return sectrue;
|
||||
}
|
||||
|
||||
secbool flash_area_erase_bulk(const flash_area_t *areas, int count,
|
||||
void (*progress)(int pos, int len)) {
|
||||
ensure(flash_unlock_write(), NULL);
|
||||
FLASH_EraseInitTypeDef EraseInitStruct;
|
||||
EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
|
||||
EraseInitStruct.NbPages = 1;
|
||||
|
||||
int total_pages = 0;
|
||||
int done_pages = 0;
|
||||
for (int c = 0; c < count; c++) {
|
||||
for (int i = 0; i < areas[c].num_subareas; i++) {
|
||||
total_pages += areas[c].subarea[i].num_sectors;
|
||||
}
|
||||
}
|
||||
|
||||
if (progress) {
|
||||
progress(0, total_pages);
|
||||
}
|
||||
|
||||
for (int c = 0; c < count; c++) {
|
||||
for (int s = 0; s < areas[c].num_subareas; s++) {
|
||||
for (int i = 0; i < areas[c].subarea[s].num_sectors; i++) {
|
||||
int page = areas[c].subarea[s].first_sector + i;
|
||||
if (page >= 256) {
|
||||
EraseInitStruct.Banks = FLASH_BANK_2;
|
||||
} else {
|
||||
EraseInitStruct.Banks = FLASH_BANK_1;
|
||||
}
|
||||
EraseInitStruct.Page = page;
|
||||
uint32_t SectorError;
|
||||
if (HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError) != HAL_OK) {
|
||||
ensure(flash_lock_write(), NULL);
|
||||
return secfalse;
|
||||
}
|
||||
// check whether the sector was really deleted (contains only 0xFF)
|
||||
const uint32_t addr_start =
|
||||
(uint32_t)flash_get_address(page, 0, 0, areas[c].secure_area);
|
||||
const uint32_t addr_end =
|
||||
(uint32_t)flash_get_address(page + 1, 0, 0, areas[c].secure_area);
|
||||
|
||||
for (uint32_t addr = addr_start; addr < addr_end; addr += 4) {
|
||||
if (*((const uint32_t *)addr) != 0xFFFFFFFF) {
|
||||
ensure(flash_lock_write(), NULL);
|
||||
return secfalse;
|
||||
}
|
||||
}
|
||||
done_pages++;
|
||||
if (progress) {
|
||||
progress(done_pages, total_pages);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ensure(flash_lock_write(), NULL);
|
||||
return sectrue;
|
||||
}
|
||||
|
||||
secbool flash_write_quadword(uint16_t sector, uint32_t offset,
|
||||
const uint32_t *data, bool secure_area) {
|
||||
uint32_t address = (uint32_t)flash_get_address(
|
||||
sector, offset, 4 * sizeof(uint32_t), secure_area);
|
||||
if (address == 0) {
|
||||
return secfalse;
|
||||
}
|
||||
if (offset % (4 * sizeof(uint32_t))) { // we write only at 16-byte boundary
|
||||
return secfalse;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (data[i] != (data[i] & *((const uint32_t *)address + i))) {
|
||||
return secfalse;
|
||||
}
|
||||
}
|
||||
|
||||
secbool all_match = sectrue;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (data[i] != *((const uint32_t *)address + i)) {
|
||||
all_match = secfalse;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (all_match == sectrue) {
|
||||
return sectrue;
|
||||
}
|
||||
|
||||
if (HAL_OK !=
|
||||
HAL_FLASH_Program(FLASH_TYPEPROGRAM_QUADWORD, address, (uint32_t)data)) {
|
||||
return secfalse;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (data[i] != *((const uint32_t *)address + i)) {
|
||||
return secfalse;
|
||||
}
|
||||
}
|
||||
return sectrue;
|
||||
}
|
||||
|
||||
secbool flash_write_burst(uint16_t sector, uint32_t offset,
|
||||
const uint32_t *data, bool secure_area) {
|
||||
uint32_t address = (uint32_t)flash_get_address(
|
||||
sector, offset, 8 * 4 * sizeof(uint32_t), secure_area);
|
||||
if (address == 0) {
|
||||
return secfalse;
|
||||
}
|
||||
if (offset %
|
||||
(8 * 4 * sizeof(uint32_t))) { // we write only at 16-byte boundary
|
||||
return secfalse;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 8 * 4; i++) {
|
||||
if (data[i] != (data[i] & *((const uint32_t *)address + i))) {
|
||||
return secfalse;
|
||||
}
|
||||
}
|
||||
|
||||
secbool all_match = sectrue;
|
||||
for (int i = 0; i < 8 * 4; i++) {
|
||||
if (data[i] != *((const uint32_t *)address + i)) {
|
||||
all_match = secfalse;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (all_match == sectrue) {
|
||||
return sectrue;
|
||||
}
|
||||
|
||||
if (HAL_OK !=
|
||||
HAL_FLASH_Program(FLASH_TYPEPROGRAM_BURST, address, (uint32_t)data)) {
|
||||
return secfalse;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 8 * 4; i++) {
|
||||
if (data[i] != *((const uint32_t *)address + i)) {
|
||||
return secfalse;
|
||||
}
|
||||
}
|
||||
return sectrue;
|
||||
}
|
||||
|
||||
secbool flash_area_write_quadword(const flash_area_t *area, uint32_t offset,
|
||||
const uint32_t *data) {
|
||||
uint32_t tmp_offset = offset;
|
||||
for (int i = 0; i < area->num_subareas; i++) {
|
||||
uint16_t sector = area->subarea[i].first_sector;
|
||||
|
||||
uint32_t sub_size = flash_subarea_get_size(&area->subarea[i]);
|
||||
if (tmp_offset >= sub_size) {
|
||||
tmp_offset -= sub_size;
|
||||
continue;
|
||||
}
|
||||
|
||||
// in correct subarea
|
||||
for (int s = 0; s < area->subarea[i].num_sectors; s++) {
|
||||
const uint32_t sector_size = flash_sector_size(sector);
|
||||
if (tmp_offset >= sector_size) {
|
||||
tmp_offset -= sector_size;
|
||||
sector++;
|
||||
|
||||
if (s == area->subarea[i].num_sectors - 1) {
|
||||
return secfalse;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// in correct sector
|
||||
return flash_write_quadword(sector, tmp_offset, data, area->secure_area);
|
||||
}
|
||||
}
|
||||
return secfalse;
|
||||
}
|
||||
|
||||
secbool flash_area_write_burst(const flash_area_t *area, uint32_t offset,
|
||||
const uint32_t *data) {
|
||||
uint32_t tmp_offset = offset;
|
||||
for (int i = 0; i < area->num_subareas; i++) {
|
||||
uint16_t sector = area->subarea[i].first_sector;
|
||||
|
||||
uint32_t sub_size = flash_subarea_get_size(&area->subarea[i]);
|
||||
if (tmp_offset >= sub_size) {
|
||||
tmp_offset -= sub_size;
|
||||
continue;
|
||||
}
|
||||
|
||||
// in correct subarea
|
||||
for (int s = 0; s < area->subarea[i].num_sectors; s++) {
|
||||
const uint32_t sector_size = flash_sector_size(sector);
|
||||
if (tmp_offset >= sector_size) {
|
||||
tmp_offset -= sector_size;
|
||||
sector++;
|
||||
|
||||
if (s == area->subarea[i].num_sectors - 1) {
|
||||
return secfalse;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// in correct sector
|
||||
return flash_write_burst(sector, tmp_offset, data, area->secure_area);
|
||||
}
|
||||
}
|
||||
return secfalse;
|
||||
}
|
||||
|
||||
secbool flash_otp_read(uint8_t block, uint8_t offset, uint8_t *data,
|
||||
uint8_t datalen) {
|
||||
if (block >= FLASH_OTP_NUM_BLOCKS ||
|
||||
offset + datalen > FLASH_OTP_BLOCK_SIZE) {
|
||||
return secfalse;
|
||||
}
|
||||
for (uint8_t i = 0; i < datalen; i++) {
|
||||
data[i] = *(__IO uint8_t *)(FLASH_OTP_BASE + block * FLASH_OTP_BLOCK_SIZE +
|
||||
offset + i);
|
||||
}
|
||||
return sectrue;
|
||||
}
|
||||
|
||||
secbool flash_otp_write(uint8_t block, uint8_t offset, const uint8_t *data,
|
||||
uint8_t datalen) {
|
||||
if (datalen % 16 != 0) {
|
||||
return secfalse;
|
||||
}
|
||||
if (block >= FLASH_OTP_NUM_BLOCKS ||
|
||||
offset + datalen > FLASH_OTP_BLOCK_SIZE) {
|
||||
return secfalse;
|
||||
}
|
||||
ensure(flash_unlock_write(), NULL);
|
||||
for (uint8_t i = 0; i < datalen; i++) {
|
||||
uint32_t address =
|
||||
FLASH_OTP_BASE + block * FLASH_OTP_BLOCK_SIZE + offset + i;
|
||||
ensure(sectrue * (HAL_OK == HAL_FLASH_Program(FLASH_TYPEPROGRAM_QUADWORD,
|
||||
address, (uint32_t)data)),
|
||||
NULL);
|
||||
}
|
||||
ensure(flash_lock_write(), NULL);
|
||||
return sectrue;
|
||||
}
|
||||
|
||||
secbool flash_otp_lock(uint8_t block) {
|
||||
// check that all quadwords in the block have been written to
|
||||
volatile uint8_t *addr =
|
||||
(__IO uint8_t *)(FLASH_OTP_BASE + block * FLASH_OTP_BLOCK_SIZE);
|
||||
|
||||
secbool qw_locked = secfalse;
|
||||
for (uint8_t i = 0; i < FLASH_OTP_BLOCK_SIZE; i++) {
|
||||
if (addr[i] != 0xFF) {
|
||||
qw_locked = sectrue;
|
||||
}
|
||||
if (i % 16 == 15 && qw_locked == secfalse) {
|
||||
return secfalse;
|
||||
}
|
||||
}
|
||||
return sectrue;
|
||||
}
|
||||
|
||||
secbool flash_otp_is_locked(uint8_t block) {
|
||||
// considering block locked if any quadword in the block is non-0xFF
|
||||
volatile uint8_t *addr =
|
||||
(__IO uint8_t *)(FLASH_OTP_BASE + block * FLASH_OTP_BLOCK_SIZE);
|
||||
|
||||
for (uint8_t i = 0; i < FLASH_OTP_BLOCK_SIZE; i++) {
|
||||
if (addr[i] != 0xFF) {
|
||||
return sectrue;
|
||||
}
|
||||
}
|
||||
return secfalse;
|
||||
}
|
@ -0,0 +1 @@
|
||||
../stm32f4/irq.h
|
@ -0,0 +1,174 @@
|
||||
.syntax unified
|
||||
|
||||
.text
|
||||
|
||||
.global memset_reg
|
||||
.type memset_reg, STT_FUNC
|
||||
memset_reg:
|
||||
// call with the following (note that the arguments are not validated prior to use):
|
||||
// r0 - address of first word to write (inclusive)
|
||||
// r1 - address of first word following the address in r0 to NOT write (exclusive)
|
||||
// r2 - word value to be written
|
||||
// both addresses in r0 and r1 needs to be divisible by 4!
|
||||
.L_loop_begin:
|
||||
str r2, [r0], 4 // store the word in r2 to the address in r0, post-indexed
|
||||
cmp r0, r1
|
||||
bne .L_loop_begin
|
||||
bx lr
|
||||
|
||||
// Jump to address given in first argument R0 that points to next's stage's VTOR
|
||||
// Clear memory and all registers before jump
|
||||
.global jump_to
|
||||
.type jump_to, STT_FUNC
|
||||
jump_to:
|
||||
mov r4, r0 // save input argument r0 (the address of the next stage's vector table) (r4 is callee save)
|
||||
// this subroutine re-points the exception handlers before the C code
|
||||
// that comprises them has been given a good environment to run.
|
||||
// therefore, this code needs to disable interrupts before the VTOR
|
||||
// update. then, the reset_handler of the next stage needs to re-enable interrupts.
|
||||
// the following prevents activation of all exceptions except Non-Maskable Interrupt (NMI).
|
||||
// according to "ARM Cortex-M Programming Guide to Memory Barrier Instructions" Application Note 321, section 4.8:
|
||||
// "there is no requirement to insert memory barrier instructions after CPSID".
|
||||
cpsid f
|
||||
// wipe memory at the end of the current stage of code
|
||||
ldr r0, =sram1_start // r0 - point to beginning of SRAM
|
||||
ldr r1, =sram1_end // r1 - point to byte after the end of SRAM
|
||||
bl memset_reg
|
||||
ldr r0, =sram2_start // r0 - point to beginning of SRAM
|
||||
ldr r1, =sram2_end // r1 - point to byte after the end of SRAM
|
||||
bl memset_reg
|
||||
ldr r0, =sram4_start // r0 - point to beginning of SRAM
|
||||
ldr r1, =sram4_end // r1 - point to byte after the end of SRAM
|
||||
bl memset_reg
|
||||
mov lr, r4
|
||||
// clear out the general purpose registers before the next stage's code can run (even the NMI exception handler)
|
||||
ldr r0, =0
|
||||
mov r1, r0
|
||||
mov r2, r0
|
||||
mov r3, r0
|
||||
mov r4, r0
|
||||
mov r5, r0
|
||||
mov r6, r0
|
||||
mov r7, r0
|
||||
mov r8, r0
|
||||
mov r9, r0
|
||||
mov r10, r0
|
||||
mov r11, r0
|
||||
mov r12, r0
|
||||
// give the next stage a fresh main stack pointer
|
||||
ldr r0, [lr] // set r0 to the main stack pointer in the next stage's vector table
|
||||
msr msp, r0 // give the next stage its main stack pointer
|
||||
// point to the next stage's exception handlers
|
||||
// AN321, section 4.11: "a memory barrier is not required after a VTOR update"
|
||||
.set SCB_VTOR, 0xE000ED08 // reference "Cortex-M4 Devices Generic User Guide" section 4.3
|
||||
ldr r0, =SCB_VTOR
|
||||
str lr, [r0]
|
||||
mov r0, r1 // zero out r0
|
||||
// go on to the next stage
|
||||
ldr lr, [lr, 4] // set lr to the next stage's reset_handler
|
||||
bx lr
|
||||
|
||||
.global jump_to_with_flag
|
||||
.type jump_to_with_flag, STT_FUNC
|
||||
jump_to_with_flag:
|
||||
mov r4, r0 // save input argument r0 (the address of the next stage's vector table) (r4 is callee save)
|
||||
mov r11, r1 // save second argument in "flag" register because we'll be cleaning RAM
|
||||
// this subroutine re-points the exception handlers before the C code
|
||||
// that comprises them has been given a good environment to run.
|
||||
// therefore, this code needs to disable interrupts before the VTOR
|
||||
// update. then, the reset_handler of the next stage needs to re-enable interrupts.
|
||||
// the following prevents activation of all exceptions except Non-Maskable Interrupt (NMI).
|
||||
// according to "ARM Cortex-M Programming Guide to Memory Barrier Instructions" Application Note 321, section 4.8:
|
||||
// "there is no requirement to insert memory barrier instructions after CPSID".
|
||||
cpsid f
|
||||
// wipe memory at the end of the current stage of code
|
||||
ldr r2, =0 // r2 - the word-sized value to be written
|
||||
ldr r0, =sram1_start // r0 - point to beginning of SRAM
|
||||
ldr r1, =sram1_end // r1 - point to byte after the end of SRAM
|
||||
bl memset_reg
|
||||
ldr r0, =sram2_start // r0 - point to beginning of SRAM
|
||||
ldr r1, =sram2_end // r1 - point to byte after the end of SRAM
|
||||
bl memset_reg
|
||||
ldr r0, =sram4_start // r0 - point to beginning of SRAM
|
||||
ldr r1, =sram4_end // r1 - point to byte after the end of SRAM
|
||||
bl memset_reg
|
||||
|
||||
mov lr, r4
|
||||
// clear out the general purpose registers before the next stage's except the register with flag R11
|
||||
ldr r0, =0
|
||||
mov r1, r0
|
||||
mov r2, r0
|
||||
mov r3, r0
|
||||
mov r4, r0
|
||||
mov r5, r0
|
||||
mov r6, r0
|
||||
mov r7, r0
|
||||
mov r8, r0
|
||||
mov r9, r0
|
||||
mov r10, r0
|
||||
mov r12, r0
|
||||
// give the next stage a fresh main stack pointer
|
||||
ldr r0, [lr] // set r0 to the main stack pointer in the next stage's vector table
|
||||
msr msp, r0 // give the next stage its main stack pointer
|
||||
// point to the next stage's exception handlers
|
||||
// AN321, section 4.11: "a memory barrier is not required after a VTOR update"
|
||||
.set SCB_VTOR, 0xE000ED08 // reference "Cortex-M4 Devices Generic User Guide" section 4.3
|
||||
ldr r0, =SCB_VTOR
|
||||
str lr, [r0]
|
||||
mov r0, r1 // zero out r0
|
||||
// go on to the next stage
|
||||
ldr lr, [lr, 4] // set lr to the next stage's reset_handler
|
||||
bx lr
|
||||
|
||||
|
||||
|
||||
.global shutdown_privileged
|
||||
.type shutdown_privileged, STT_FUNC
|
||||
// The function must be called from the privileged mode
|
||||
shutdown_privileged:
|
||||
cpsid f // disable all exceptions (except for NMI), the instruction is ignored in unprivileged mode
|
||||
// if the exceptions weren't disabled, an exception handler (for example systick handler)
|
||||
// could be called after the memory is erased, which would lead to another exception
|
||||
ldr r0, =0
|
||||
mov r1, r0
|
||||
mov r2, r0
|
||||
mov r3, r0
|
||||
mov r4, r0
|
||||
mov r5, r0
|
||||
mov r6, r0
|
||||
mov r7, r0
|
||||
mov r8, r0
|
||||
mov r9, r0
|
||||
mov r10, r0
|
||||
mov r11, r0
|
||||
mov r12, r0
|
||||
ldr lr, =0xffffffff
|
||||
|
||||
ldr r0, =sram1_start // r0 - point to beginning of SRAM
|
||||
ldr r1, =sram1_end // r1 - point to byte after the end of SRAM
|
||||
bl memset_reg
|
||||
ldr r0, =sram2_start // r0 - point to beginning of SRAM
|
||||
ldr r1, =sram2_end // r1 - point to byte after the end of SRAM
|
||||
bl memset_reg
|
||||
ldr r0, =sram4_start // r0 - point to beginning of SRAM
|
||||
ldr r1, =sram4_end // r1 - point to byte after the end of SRAM
|
||||
bl memset_reg
|
||||
|
||||
ldr r0, =1
|
||||
msr control, r0 // jump to unprivileged mode
|
||||
ldr r0, =0
|
||||
b . // loop forever
|
||||
|
||||
.global MemManage_Handler
|
||||
.type MemManage_Handler, STT_FUNC
|
||||
MemManage_Handler:
|
||||
ldr r2, =_sstack
|
||||
mrs r1, msp
|
||||
ldr r0, =_estack
|
||||
msr msp, r0
|
||||
cmp r1, r2
|
||||
IT lt
|
||||
bllt MemManage_Handler_SO
|
||||
bl MemManage_Handler_MM
|
||||
|
||||
.end
|
@ -0,0 +1,298 @@
|
||||
/*
|
||||
* This file is part of the Trezor project, https://trezor.io/
|
||||
*
|
||||
* Copyright (c) SatoshiLabs
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include STM32_HAL_H
|
||||
|
||||
#include "lowlevel.h"
|
||||
#include "flash.h"
|
||||
#include "model.h"
|
||||
|
||||
#pragma GCC optimize( \
|
||||
"no-stack-protector") // applies to all functions in this file
|
||||
|
||||
#if PRODUCTION
|
||||
#define WANT_RDP_LEVEL (OB_RDP_LEVEL_2)
|
||||
#define WANT_WRP_PAGE_START 1
|
||||
#define WANT_WRP_PAGE_END 6
|
||||
#else
|
||||
#define WANT_RDP_LEVEL (OB_RDP_LEVEL_0)
|
||||
#endif
|
||||
|
||||
// BOR LEVEL 0: Reset level threshold is around 1.7 V
|
||||
#define WANT_BOR_LEVEL (OB_BOR_LEVEL_0)
|
||||
|
||||
#define FLASH_OPTR_VALUE \
|
||||
((WANT_RDP_LEVEL << FLASH_OPTR_RDP_Pos) | FLASH_OPTR_nRST_STDBY | \
|
||||
FLASH_OPTR_nRST_STOP | FLASH_OPTR_IWDG_SW | FLASH_OPTR_IWDG_STOP | \
|
||||
FLASH_OPTR_IWDG_STDBY | FLASH_OPTR_WWDG_SW | FLASH_OPTR_DUALBANK | \
|
||||
FLASH_OPTR_nSWBOOT0 | FLASH_OPTR_nBOOT0 | FLASH_OPTR_PA15_PUPEN | \
|
||||
FLASH_OPTR_BKPRAM_ECC | FLASH_OPTR_SRAM3_ECC | FLASH_OPTR_TZEN | \
|
||||
FLASH_OPTR_SRAM_RST | WANT_BOR_LEVEL)
|
||||
|
||||
// TODO set values according to MCU variant
|
||||
#define FALSH_SECBOOTADD0R_VALUE \
|
||||
((BOARDLOADER_START & 0xFFFFFF80) | FLASH_SECBOOTADD0R_BOOT_LOCK | 0x7C)
|
||||
#define FLASH_SECWM1R1_VALUE \
|
||||
(0 << FLASH_SECWM1R1_SECWM1_PSTRT_Pos | \
|
||||
0xff << FLASH_SECWM1R1_SECWM1_PEND_Pos | 0xFF00FF00)
|
||||
#define FLASH_SECWM1R2_VALUE \
|
||||
(1 << FLASH_SECWM1R2_HDP1_PEND_Pos | FLASH_SECWM1R2_HDP1EN | 0x7F007F00)
|
||||
#define FLASH_SECWM2R1_VALUE \
|
||||
(0 << FLASH_SECWM1R1_SECWM1_PSTRT_Pos | \
|
||||
0xff << FLASH_SECWM1R1_SECWM1_PEND_Pos | 0xFF00FF00)
|
||||
#define FLASH_SECWM2R2_VALUE (0x7F007F00)
|
||||
|
||||
secbool flash_check_option_bytes(void) {
|
||||
flash_wait_and_clear_status_flags();
|
||||
// check values stored in flash interface registers
|
||||
if (FLASH->OPTR !=
|
||||
FLASH_OPTR_VALUE) { // ignore bits 0 and 1 because they are control bits
|
||||
return secfalse;
|
||||
}
|
||||
|
||||
if (FLASH->SECBOOTADD0R != FALSH_SECBOOTADD0R_VALUE) {
|
||||
return secfalse;
|
||||
}
|
||||
|
||||
#if PRODUCTION
|
||||
if (FLASH->WRP1AR != (WANT_WRP_PAGE_START | (WANT_WRP_PAGE_END << 16))) {
|
||||
return secfalse;
|
||||
}
|
||||
#else
|
||||
// TODO set values according to MCU variant
|
||||
if (FLASH->WRP1AR != 0xFF00FFFF) {
|
||||
return secfalse;
|
||||
}
|
||||
#endif
|
||||
|
||||
// TODO set values according to MCU variant
|
||||
if (FLASH->WRP1BR != 0xFF00FFFF) {
|
||||
return secfalse;
|
||||
}
|
||||
// TODO set values according to MCU variant
|
||||
if (FLASH->WRP2AR != 0xFF00FFFF) {
|
||||
return secfalse;
|
||||
}
|
||||
// TODO set values according to MCU variant
|
||||
if (FLASH->WRP2BR != 0xFF00FFFF) {
|
||||
return secfalse;
|
||||
}
|
||||
|
||||
return sectrue;
|
||||
}
|
||||
|
||||
void flash_lock_option_bytes(void) {
|
||||
FLASH->NSCR |= FLASH_NSCR_OPTLOCK; // lock the option bytes
|
||||
}
|
||||
|
||||
void flash_unlock_option_bytes(void) {
|
||||
if ((FLASH->NSCR & FLASH_NSCR_OPTLOCK) == 0) {
|
||||
return; // already unlocked
|
||||
}
|
||||
// reference RM0090 section 3.7.2
|
||||
// write the special sequence to unlock
|
||||
FLASH->OPTKEYR = FLASH_OPTKEY1;
|
||||
FLASH->OPTKEYR = FLASH_OPTKEY2;
|
||||
while (FLASH->NSCR & FLASH_NSCR_OPTLOCK)
|
||||
; // wait until the flash option control register is unlocked
|
||||
}
|
||||
|
||||
uint32_t flash_set_option_bytes(void) {
|
||||
if (flash_unlock_write() != sectrue) {
|
||||
return 0;
|
||||
}
|
||||
flash_wait_and_clear_status_flags();
|
||||
flash_unlock_option_bytes();
|
||||
flash_wait_and_clear_status_flags();
|
||||
|
||||
FLASH->OPTR =
|
||||
FLASH_OPTR_VALUE; // WARNING: dev board safe unless you compile for
|
||||
// PRODUCTION or change this value!!!
|
||||
|
||||
FLASH->SECBOOTADD0R = FALSH_SECBOOTADD0R_VALUE;
|
||||
|
||||
#if PRODUCTION
|
||||
FLASH->WRP1AR = WANT_WRP_PAGE_START | (WANT_WRP_PAGE_END << 16);
|
||||
// TODO set values according to MCU variant
|
||||
FLASH->WRP1BR = 0xFF00FFFF;
|
||||
FLASH->WRP2AR = 0xFF00FFFF FLASH->WRP2BR = 0xFF00FFFF
|
||||
#endif
|
||||
|
||||
FLASH_WaitForLastOperation(HAL_MAX_DELAY);
|
||||
|
||||
FLASH->NSCR |= FLASH_NSCR_OPTSTRT;
|
||||
uint32_t result =
|
||||
flash_wait_and_clear_status_flags(); // wait until changes are committed
|
||||
|
||||
FLASH_WaitForLastOperation(HAL_MAX_DELAY);
|
||||
|
||||
FLASH->NSCR |= FLASH_NSCR_OBL_LAUNCH; // begin committing changes to flash
|
||||
result =
|
||||
flash_wait_and_clear_status_flags(); // wait until changes are committed
|
||||
flash_lock_option_bytes();
|
||||
|
||||
if (flash_lock_write() != sectrue) {
|
||||
return 0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
secbool flash_configure_option_bytes(void) {
|
||||
if (sectrue == flash_check_option_bytes()) {
|
||||
return sectrue; // we DID NOT have to change the option bytes
|
||||
}
|
||||
|
||||
do {
|
||||
flash_set_option_bytes();
|
||||
} while (sectrue != flash_check_option_bytes());
|
||||
|
||||
return secfalse; // notify that we DID have to change the option bytes
|
||||
}
|
||||
|
||||
secbool flash_check_sec_area_ob(void) {
|
||||
flash_wait_and_clear_status_flags();
|
||||
// check values stored in flash interface registers
|
||||
|
||||
if (FLASH->SECWM1R1 != FLASH_SECWM1R1_VALUE) {
|
||||
return secfalse;
|
||||
}
|
||||
if (FLASH->SECWM1R2 != FLASH_SECWM1R2_VALUE) {
|
||||
return secfalse;
|
||||
}
|
||||
if (FLASH->SECWM2R1 != FLASH_SECWM2R1_VALUE) {
|
||||
return secfalse;
|
||||
}
|
||||
if (FLASH->SECWM2R2 != FLASH_SECWM2R2_VALUE) {
|
||||
return secfalse;
|
||||
}
|
||||
|
||||
return sectrue;
|
||||
}
|
||||
|
||||
uint32_t flash_set_sec_area_ob(void) {
|
||||
if (flash_unlock_write() != sectrue) {
|
||||
return 0;
|
||||
}
|
||||
flash_wait_and_clear_status_flags();
|
||||
flash_unlock_option_bytes();
|
||||
flash_wait_and_clear_status_flags();
|
||||
|
||||
FLASH->SECWM1R1 = FLASH_SECWM1R1_VALUE;
|
||||
FLASH->SECWM1R2 = FLASH_SECWM1R2_VALUE;
|
||||
|
||||
FLASH->SECWM2R1 = FLASH_SECWM2R1_VALUE;
|
||||
FLASH->SECWM2R2 = FLASH_SECWM2R2_VALUE;
|
||||
|
||||
FLASH_WaitForLastOperation(HAL_MAX_DELAY);
|
||||
|
||||
FLASH->NSCR |= FLASH_NSCR_OPTSTRT;
|
||||
uint32_t result =
|
||||
flash_wait_and_clear_status_flags(); // wait until changes are committed
|
||||
|
||||
FLASH_WaitForLastOperation(HAL_MAX_DELAY);
|
||||
|
||||
FLASH->NSCR |= FLASH_NSCR_OBL_LAUNCH; // begin committing changes to flash
|
||||
result =
|
||||
flash_wait_and_clear_status_flags(); // wait until changes are committed
|
||||
flash_lock_option_bytes();
|
||||
|
||||
if (flash_lock_write() != sectrue) {
|
||||
return 0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
secbool flash_configure_sec_area_ob(void) {
|
||||
if (sectrue == flash_check_sec_area_ob()) {
|
||||
return sectrue; // we DID NOT have to change the option bytes
|
||||
}
|
||||
|
||||
do {
|
||||
flash_set_sec_area_ob();
|
||||
} while (sectrue != flash_check_sec_area_ob());
|
||||
|
||||
return secfalse; // notify that we DID have to change the option bytes
|
||||
}
|
||||
|
||||
void periph_init(void) {
|
||||
// STM32U5xx HAL library initialization:
|
||||
// - configure the Flash prefetch, instruction and data caches
|
||||
// - configure the Systick to generate an interrupt each 1 msec
|
||||
// - set NVIC Group Priority to 4
|
||||
// - global MSP (MCU Support Package) initialization
|
||||
HAL_Init();
|
||||
|
||||
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
|
||||
|
||||
/** Initializes the common periph clock
|
||||
*/
|
||||
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_LTDC | RCC_PERIPHCLK_DSI;
|
||||
PeriphClkInit.DsiClockSelection = RCC_DSICLKSOURCE_PLL3;
|
||||
PeriphClkInit.LtdcClockSelection = RCC_LTDCCLKSOURCE_PLL3;
|
||||
PeriphClkInit.PLL3.PLL3Source = RCC_PLLSOURCE_HSE;
|
||||
PeriphClkInit.PLL3.PLL3M = 4;
|
||||
PeriphClkInit.PLL3.PLL3N = 125;
|
||||
PeriphClkInit.PLL3.PLL3P = 8;
|
||||
PeriphClkInit.PLL3.PLL3Q = 2;
|
||||
PeriphClkInit.PLL3.PLL3R = 24;
|
||||
PeriphClkInit.PLL3.PLL3RGE = RCC_PLLVCIRANGE_0;
|
||||
PeriphClkInit.PLL3.PLL3FRACN = 0;
|
||||
PeriphClkInit.PLL3.PLL3ClockOut = RCC_PLL3_DIVP | RCC_PLL3_DIVR;
|
||||
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);
|
||||
|
||||
/** Enable instruction cache in 1-way (direct mapped cache)
|
||||
*/
|
||||
HAL_ICACHE_ConfigAssociativityMode(ICACHE_1WAY);
|
||||
|
||||
// Enable GPIO clocks
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOC_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOD_CLK_ENABLE();
|
||||
|
||||
// enable the PVD (programmable voltage detector).
|
||||
// select the "2.8V" threshold (level 5).
|
||||
// this detector will be active regardless of the
|
||||
// flash option byte BOR setting.
|
||||
// __HAL_RCC_PWR_CLK_ENABLE();
|
||||
// PWR_PVDTypeDef pvd_config;
|
||||
// pvd_config.PVDLevel = PWR_PVDLEVEL_5;
|
||||
// pvd_config.Mode = PWR_PVD_MODE_IT_RISING_FALLING;
|
||||
// HAL_PWR_ConfigPVD(&pvd_config);
|
||||
// HAL_PWR_EnablePVD();
|
||||
// NVIC_EnableIRQ(PVD_PVM_IRQn);
|
||||
}
|
||||
|
||||
secbool reset_flags_check(void) {
|
||||
#if PRODUCTION
|
||||
// this is effective enough that it makes development painful, so only use it
|
||||
// for production. check the reset flags to assure that we arrive here due to
|
||||
// a regular full power-on event, and not as a result of a lesser reset.
|
||||
if ((RCC->CSR & (RCC_CSR_LPWRRSTF | RCC_CSR_WWDGRSTF | RCC_CSR_IWDGRSTF |
|
||||
RCC_CSR_SFTRSTF | RCC_CSR_PINRSTF | RCC_CSR_BORRSTF |
|
||||
RCC_CSR_OBLRSTF)) != (RCC_CSR_PINRSTF | RCC_CSR_BORRSTF)) {
|
||||
return secfalse;
|
||||
}
|
||||
#endif
|
||||
return sectrue;
|
||||
}
|
||||
|
||||
void reset_flags_reset(void) {
|
||||
RCC->CSR |= RCC_CSR_RMVF; // clear the reset flags
|
||||
}
|
@ -0,0 +1,257 @@
|
||||
/*
|
||||
* This file is part of the Trezor project, https://trezor.io/
|
||||
*
|
||||
* Copyright (c) SatoshiLabs
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include STM32_HAL_H
|
||||
#include "common.h"
|
||||
#include "flash.h"
|
||||
#include "model.h"
|
||||
#include "stm32u5xx_ll_cortex.h"
|
||||
|
||||
#define ATTR_IDX_FLASH (0 << 1)
|
||||
#define ATTR_IDX_FLASH_NON_CACHABLE (3 << 1)
|
||||
#define ATTR_IDX_SRAM (1 << 1)
|
||||
#define ATTR_IDX_PERIPH (2 << 1)
|
||||
#define REGION_END(x) (((x) & ~0x1F) | 0x01)
|
||||
|
||||
#define SHAREABILITY_FLASH (LL_MPU_ACCESS_NOT_SHAREABLE)
|
||||
#define SHAREABILITY_SRAM \
|
||||
(LL_MPU_ACCESS_INNER_SHAREABLE | LL_MPU_ACCESS_OUTER_SHAREABLE)
|
||||
|
||||
void mpu_config_off(void) {
|
||||
// Disable MPU
|
||||
HAL_MPU_Disable();
|
||||
}
|
||||
|
||||
static uint32_t area_start(const flash_area_t* area) {
|
||||
return (uint32_t)flash_area_get_address(area, 0, 0);
|
||||
}
|
||||
|
||||
static uint32_t area_end(const flash_area_t* area) {
|
||||
uint32_t start = area_start(area);
|
||||
uint32_t size = flash_area_get_size(area);
|
||||
return start + size;
|
||||
}
|
||||
|
||||
void mpu_config_boardloader(void) {
|
||||
// Disable MPU
|
||||
HAL_MPU_Disable();
|
||||
|
||||
// flash memory
|
||||
MPU->MAIR0 = 0xAA;
|
||||
// internal ram
|
||||
MPU->MAIR0 |= 0xAA << 8;
|
||||
// peripherals
|
||||
MPU->MAIR0 |= 0x00 << 16;
|
||||
// non-cachable flash
|
||||
MPU->MAIR0 |= 0x44 << 24;
|
||||
|
||||
// Secret
|
||||
MPU->RNR = MPU_REGION_NUMBER0;
|
||||
MPU->RBAR = FLASH_BASE_S | LL_MPU_REGION_ALL_RW | SHAREABILITY_FLASH |
|
||||
LL_MPU_INSTRUCTION_ACCESS_DISABLE;
|
||||
MPU->RLAR = REGION_END(BOARDLOADER_START - 1) | ATTR_IDX_FLASH_NON_CACHABLE;
|
||||
|
||||
// Flash boardloader (read-write)
|
||||
MPU->RNR = MPU_REGION_NUMBER1;
|
||||
MPU->RBAR = BOARDLOADER_START | LL_MPU_REGION_ALL_RW | SHAREABILITY_FLASH;
|
||||
MPU->RLAR = REGION_END(BOOTLOADER_START - 1) | ATTR_IDX_FLASH;
|
||||
|
||||
// Flash rest
|
||||
MPU->RNR = MPU_REGION_NUMBER2;
|
||||
MPU->RBAR = BOOTLOADER_START | LL_MPU_REGION_ALL_RW |
|
||||
LL_MPU_INSTRUCTION_ACCESS_DISABLE | SHAREABILITY_FLASH;
|
||||
MPU->RLAR =
|
||||
REGION_END(FLASH_BASE_S + 0x400000 - 1) | ATTR_IDX_FLASH_NON_CACHABLE;
|
||||
|
||||
// RAM (read-write, execute never) (SRAM1)
|
||||
MPU->RNR = MPU_REGION_NUMBER3;
|
||||
MPU->RBAR = SRAM1_BASE_S | LL_MPU_REGION_ALL_RW |
|
||||
LL_MPU_INSTRUCTION_ACCESS_DISABLE | SHAREABILITY_SRAM;
|
||||
MPU->RLAR = REGION_END(SRAM1_BASE_S + 0xC0000 - 1) | ATTR_IDX_SRAM;
|
||||
|
||||
// RAM (read-write, execute never) (SRAM2, 3, 5, 6)
|
||||
// reserve 256 bytes for stack overflow detection
|
||||
MPU->RNR = MPU_REGION_NUMBER4;
|
||||
MPU->RBAR = (SRAM2_BASE_S + 0x100) | LL_MPU_REGION_ALL_RW |
|
||||
LL_MPU_INSTRUCTION_ACCESS_DISABLE | SHAREABILITY_SRAM;
|
||||
MPU->RLAR = REGION_END(SRAM1_BASE_S + 0x2F0000 - 1) | ATTR_IDX_SRAM;
|
||||
|
||||
// GFXMMU_VIRTUAL_BUFFERS (read-write, execute never)
|
||||
MPU->RNR = MPU_REGION_NUMBER5;
|
||||
MPU->RBAR = GFXMMU_VIRTUAL_BUFFERS_BASE_S | LL_MPU_REGION_ALL_RW |
|
||||
LL_MPU_INSTRUCTION_ACCESS_DISABLE | SHAREABILITY_SRAM;
|
||||
MPU->RLAR =
|
||||
REGION_END(GFXMMU_VIRTUAL_BUFFERS_BASE_S + 0x1000000 - 1) | ATTR_IDX_SRAM;
|
||||
|
||||
// Peripherals (read-write, execute never)
|
||||
MPU->RNR = MPU_REGION_NUMBER6;
|
||||
MPU->RBAR =
|
||||
PERIPH_BASE_S | LL_MPU_REGION_ALL_RW | LL_MPU_INSTRUCTION_ACCESS_DISABLE;
|
||||
MPU->RLAR = REGION_END(PERIPH_BASE_S + 0x10000000 - 1) | ATTR_IDX_PERIPH;
|
||||
|
||||
// OTP (read-write, execute never)
|
||||
MPU->RNR = MPU_REGION_NUMBER7;
|
||||
MPU->RBAR = FLASH_OTP_BASE | LL_MPU_REGION_ALL_RW |
|
||||
LL_MPU_INSTRUCTION_ACCESS_DISABLE | SHAREABILITY_FLASH;
|
||||
MPU->RLAR = REGION_END(FLASH_OTP_BASE + FLASH_OTP_SIZE - 1) |
|
||||
ATTR_IDX_FLASH_NON_CACHABLE;
|
||||
|
||||
// RAM SRAM4
|
||||
MPU->RNR = MPU_REGION_NUMBER7;
|
||||
MPU->RBAR = SRAM4_BASE_S | LL_MPU_REGION_ALL_RW |
|
||||
LL_MPU_INSTRUCTION_ACCESS_DISABLE | SHAREABILITY_SRAM;
|
||||
MPU->RLAR = REGION_END(SRAM4_BASE_S + 0x4000 - 1) | ATTR_IDX_SRAM;
|
||||
|
||||
// Enable MPU
|
||||
HAL_MPU_Enable(LL_MPU_CTRL_HARDFAULT_NMI);
|
||||
}
|
||||
|
||||
void mpu_config_bootloader(void) {
|
||||
// Disable MPU
|
||||
HAL_MPU_Disable();
|
||||
|
||||
// flash memory
|
||||
MPU->MAIR0 = 0xAA;
|
||||
// internal ram
|
||||
MPU->MAIR0 |= 0xAA << 8;
|
||||
// peripherals
|
||||
MPU->MAIR0 |= 0x00 << 16;
|
||||
// non-cachable flash
|
||||
MPU->MAIR0 |= 0x44 << 24;
|
||||
|
||||
// Secret + boardloader
|
||||
MPU->RNR = MPU_REGION_NUMBER0;
|
||||
MPU->RBAR = FLASH_BASE_S | LL_MPU_REGION_ALL_RW | SHAREABILITY_FLASH;
|
||||
MPU->RLAR = REGION_END(BOOTLOADER_START - 1) | ATTR_IDX_FLASH_NON_CACHABLE;
|
||||
|
||||
// Bootloader (read-write)
|
||||
MPU->RNR = MPU_REGION_NUMBER1;
|
||||
MPU->RBAR = BOOTLOADER_START | LL_MPU_REGION_ALL_RW | SHAREABILITY_FLASH;
|
||||
MPU->RLAR = REGION_END(area_start(&STORAGE_AREAS[0]) - 1) | ATTR_IDX_FLASH;
|
||||
|
||||
// Flash firmware + storage (read-write, execute never), till flash end
|
||||
MPU->RNR = MPU_REGION_NUMBER2;
|
||||
MPU->RBAR = area_start(&STORAGE_AREAS[0]) | LL_MPU_REGION_ALL_RW |
|
||||
LL_MPU_INSTRUCTION_ACCESS_DISABLE | SHAREABILITY_FLASH;
|
||||
MPU->RLAR =
|
||||
REGION_END(FLASH_BASE_S + 0x400000 - 1) | ATTR_IDX_FLASH_NON_CACHABLE;
|
||||
|
||||
// RAM (read-write, execute never) (SRAM1)
|
||||
MPU->RNR = MPU_REGION_NUMBER3;
|
||||
MPU->RBAR = SRAM1_BASE_S | LL_MPU_REGION_ALL_RW |
|
||||
LL_MPU_INSTRUCTION_ACCESS_DISABLE | SHAREABILITY_SRAM;
|
||||
MPU->RLAR = REGION_END(SRAM1_BASE_S + 0xC0000 - 1) | ATTR_IDX_SRAM;
|
||||
|
||||
// RAM (read-write, execute never) (SRAM2, 3, 5, 6)
|
||||
// reserve 256 bytes for stack overflow detection
|
||||
MPU->RNR = MPU_REGION_NUMBER4;
|
||||
MPU->RBAR = (SRAM2_BASE_S + 0x100) | LL_MPU_REGION_ALL_RW |
|
||||
LL_MPU_INSTRUCTION_ACCESS_DISABLE | SHAREABILITY_SRAM;
|
||||
MPU->RLAR = REGION_END(SRAM1_BASE_S + 0x2F0000 - 1) | ATTR_IDX_SRAM;
|
||||
|
||||
// GFXMMU_VIRTUAL_BUFFERS (read-write, execute never)
|
||||
MPU->RNR = MPU_REGION_NUMBER5;
|
||||
MPU->RBAR = GFXMMU_VIRTUAL_BUFFERS_BASE_S | LL_MPU_REGION_ALL_RW |
|
||||
LL_MPU_INSTRUCTION_ACCESS_DISABLE | SHAREABILITY_SRAM;
|
||||
MPU->RLAR =
|
||||
REGION_END(GFXMMU_VIRTUAL_BUFFERS_BASE_S + 0x1000000 - 1) | ATTR_IDX_SRAM;
|
||||
|
||||
// Peripherals (read-write, execute never)
|
||||
MPU->RNR = MPU_REGION_NUMBER6;
|
||||
MPU->RBAR =
|
||||
PERIPH_BASE_S | LL_MPU_REGION_ALL_RW | LL_MPU_INSTRUCTION_ACCESS_DISABLE;
|
||||
MPU->RLAR = REGION_END(PERIPH_BASE_S + 0x10000000 - 1) | ATTR_IDX_PERIPH;
|
||||
|
||||
// OTP (read-write, execute never)
|
||||
MPU->RNR = MPU_REGION_NUMBER7;
|
||||
MPU->RBAR = FLASH_OTP_BASE | LL_MPU_REGION_ALL_RW |
|
||||
LL_MPU_INSTRUCTION_ACCESS_DISABLE | SHAREABILITY_FLASH;
|
||||
MPU->RLAR = REGION_END(FLASH_OTP_BASE + FLASH_OTP_SIZE - 1) |
|
||||
ATTR_IDX_FLASH_NON_CACHABLE;
|
||||
|
||||
// Enable MPU
|
||||
HAL_MPU_Enable(LL_MPU_CTRL_HARDFAULT_NMI);
|
||||
}
|
||||
|
||||
void mpu_config_firmware(void) {
|
||||
// Disable MPU
|
||||
HAL_MPU_Disable();
|
||||
|
||||
// flash memory
|
||||
MPU->MAIR0 = 0xAA;
|
||||
// internal ram
|
||||
MPU->MAIR0 |= 0xAA << 8;
|
||||
// peripherals
|
||||
MPU->MAIR0 |= 0x00 << 16;
|
||||
// non-cachable flash
|
||||
MPU->MAIR0 |= 0x44 << 24;
|
||||
|
||||
// bootloader + boardloader: no access, execute never: need to do everything
|
||||
// before turning on MPU
|
||||
|
||||
// Storage (read-write, execute never)
|
||||
MPU->RNR = MPU_REGION_NUMBER0;
|
||||
MPU->RBAR = area_start(&STORAGE_AREAS[0]) | LL_MPU_REGION_ALL_RW |
|
||||
SHAREABILITY_FLASH | LL_MPU_INSTRUCTION_ACCESS_DISABLE;
|
||||
MPU->RLAR = REGION_END(FIRMWARE_START - 1) | ATTR_IDX_FLASH_NON_CACHABLE;
|
||||
|
||||
// Flash firmware (read-write)
|
||||
MPU->RNR = MPU_REGION_NUMBER1;
|
||||
MPU->RBAR = (FIRMWARE_START) | LL_MPU_REGION_ALL_RO | SHAREABILITY_FLASH;
|
||||
MPU->RLAR = REGION_END(area_end(&FIRMWARE_AREA) - 1) | ATTR_IDX_FLASH;
|
||||
|
||||
// RAM (read-write, execute never) (SRAM1)
|
||||
MPU->RNR = MPU_REGION_NUMBER2;
|
||||
MPU->RBAR = SRAM1_BASE_S | LL_MPU_REGION_ALL_RW |
|
||||
LL_MPU_INSTRUCTION_ACCESS_DISABLE | SHAREABILITY_SRAM;
|
||||
MPU->RLAR = REGION_END(SRAM1_BASE_S + 0xC0000 - 1) | ATTR_IDX_SRAM;
|
||||
|
||||
// RAM (read-write, execute never) (SRAM2, 3, 5, 6)
|
||||
// reserve 256 bytes for stack overflow detection
|
||||
MPU->RNR = MPU_REGION_NUMBER3;
|
||||
MPU->RBAR = (SRAM2_BASE_S + 0x100) | LL_MPU_REGION_ALL_RW |
|
||||
LL_MPU_INSTRUCTION_ACCESS_DISABLE | SHAREABILITY_SRAM;
|
||||
MPU->RLAR = REGION_END(SRAM1_BASE_S + 0x2F0000 - 1) | ATTR_IDX_SRAM;
|
||||
|
||||
// GFXMMU_VIRTUAL_BUFFERS (read-write, execute never)
|
||||
MPU->RNR = MPU_REGION_NUMBER4;
|
||||
MPU->RBAR = GFXMMU_VIRTUAL_BUFFERS_BASE_S | LL_MPU_REGION_ALL_RW |
|
||||
LL_MPU_INSTRUCTION_ACCESS_DISABLE | SHAREABILITY_SRAM;
|
||||
MPU->RLAR =
|
||||
REGION_END(GFXMMU_VIRTUAL_BUFFERS_BASE_S + 0x1000000 - 1) | ATTR_IDX_SRAM;
|
||||
|
||||
// Peripherals (read-write, execute never)
|
||||
MPU->RNR = MPU_REGION_NUMBER5;
|
||||
MPU->RBAR =
|
||||
PERIPH_BASE_S | LL_MPU_REGION_ALL_RW | LL_MPU_INSTRUCTION_ACCESS_DISABLE;
|
||||
MPU->RLAR = REGION_END(PERIPH_BASE_S + 0x10000000 - 1) | ATTR_IDX_PERIPH;
|
||||
|
||||
// OTP (read-write, execute never)
|
||||
MPU->RNR = MPU_REGION_NUMBER6;
|
||||
MPU->RBAR = FLASH_OTP_BASE | LL_MPU_REGION_ALL_RW |
|
||||
LL_MPU_INSTRUCTION_ACCESS_DISABLE | SHAREABILITY_FLASH;
|
||||
MPU->RLAR = REGION_END(FLASH_OTP_BASE + FLASH_OTP_SIZE - 1) |
|
||||
ATTR_IDX_FLASH_NON_CACHABLE;
|
||||
|
||||
// Enable MPU
|
||||
HAL_MPU_Enable(LL_MPU_CTRL_HARDFAULT_NMI);
|
||||
|
||||
__asm__ volatile("dsb");
|
||||
__asm__ volatile("isb");
|
||||
}
|
@ -0,0 +1,205 @@
|
||||
/*
|
||||
* This file is part of the Trezor project, https://trezor.io/
|
||||
*
|
||||
* Copyright (c) SatoshiLabs
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include STM32_HAL_H
|
||||
|
||||
#include "platform.h"
|
||||
#include "rng.h"
|
||||
|
||||
const uint8_t AHBPrescTable[16] = {0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U,
|
||||
1U, 2U, 3U, 4U, 6U, 7U, 8U, 9U};
|
||||
const uint8_t APBPrescTable[8] = {0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U};
|
||||
const uint32_t MSIRangeTable[16] = {48000000U, 24000000U, 16000000U, 12000000U,
|
||||
4000000U, 2000000U, 1330000U, 1000000U,
|
||||
3072000U, 1536000U, 1024000U, 768000U,
|
||||
400000U, 200000U, 133000U, 100000U};
|
||||
typedef struct {
|
||||
uint32_t freq;
|
||||
uint32_t pllq;
|
||||
uint32_t pllp;
|
||||
uint32_t pllm;
|
||||
uint32_t plln;
|
||||
} clock_conf_t;
|
||||
|
||||
#if defined STM32U5
|
||||
// HSE 16MHz
|
||||
#define DEFAULT_FREQ 160U
|
||||
#define DEFAULT_PLLM 1
|
||||
#define DEFAULT_PLLN 10 // mult by 10
|
||||
#define DEFAULT_PLLR 1U // division by 1
|
||||
#define DEFAULT_PLLQ 1U // division by 1
|
||||
#define DEFAULT_PLLP 5U // division by 5
|
||||
#else
|
||||
#error Unsupported MCU
|
||||
#endif
|
||||
|
||||
uint32_t SystemCoreClock = DEFAULT_FREQ * 1000000U;
|
||||
|
||||
// PLLCLK = ((HSE / PLLM) * PLLN) / PLLR
|
||||
|
||||
// assuming HSE 16 MHz
|
||||
clock_conf_t clock_conf[1] = {
|
||||
{
|
||||
// clk = ((16MHz / 1) * 10) / 1 = 160 MHz
|
||||
.freq = 160,
|
||||
.pllp = 1,
|
||||
.pllq = 1,
|
||||
.pllm = 1,
|
||||
.plln = 10,
|
||||
},
|
||||
};
|
||||
|
||||
#pragma GCC optimize( \
|
||||
"no-stack-protector") // applies to all functions in this file
|
||||
|
||||
void SystemInit(void) {
|
||||
// set flash wait states for an increasing HCLK frequency
|
||||
|
||||
FLASH->ACR = FLASH_ACR_LATENCY_5WS;
|
||||
// wait until the new wait state config takes effect -- per section 3.5.1
|
||||
// guidance
|
||||
while ((FLASH->ACR & FLASH_ACR_LATENCY) != FLASH_ACR_LATENCY_5WS)
|
||||
;
|
||||
|
||||
/* Reset the RCC clock configuration to the default reset state ------------*/
|
||||
/* Set MSION bit */
|
||||
RCC->CR = RCC_CR_MSISON;
|
||||
|
||||
/* Reset CFGR register */
|
||||
RCC->CFGR1 = 0U;
|
||||
RCC->CFGR2 = 0U;
|
||||
RCC->CFGR3 = 0U;
|
||||
|
||||
/* Reset HSEON, CSSON , HSION, PLLxON bits */
|
||||
RCC->CR &= ~(RCC_CR_HSEON | RCC_CR_CSSON | RCC_CR_PLL1ON | RCC_CR_PLL2ON |
|
||||
RCC_CR_PLL3ON | RCC_CR_HSI48ON);
|
||||
|
||||
/* Reset PLLCFGR register */
|
||||
RCC->PLL1CFGR = 0U;
|
||||
|
||||
/* Reset HSEBYP bit */
|
||||
RCC->CR &= ~(RCC_CR_HSEBYP);
|
||||
|
||||
/* Disable all interrupts */
|
||||
RCC->CIER = 0U;
|
||||
|
||||
__HAL_RCC_PWR_CLK_ENABLE();
|
||||
|
||||
MODIFY_REG(PWR->VOSR, (PWR_VOSR_VOS | PWR_VOSR_BOOSTEN),
|
||||
PWR_REGULATOR_VOLTAGE_SCALE1);
|
||||
while (HAL_IS_BIT_CLR(PWR->VOSR, PWR_VOSR_VOSRDY))
|
||||
;
|
||||
while (HAL_IS_BIT_CLR(PWR->SVMSR, PWR_SVMSR_ACTVOSRDY))
|
||||
;
|
||||
|
||||
__HAL_RCC_HSE_CONFIG(RCC_HSE_ON);
|
||||
while (READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U)
|
||||
;
|
||||
|
||||
__HAL_RCC_PLL_CONFIG(RCC_PLLSOURCE_HSE, RCC_PLLMBOOST_DIV1, DEFAULT_PLLM,
|
||||
DEFAULT_PLLN, DEFAULT_PLLP, DEFAULT_PLLQ, DEFAULT_PLLR);
|
||||
|
||||
__HAL_RCC_PLL_FRACN_DISABLE();
|
||||
|
||||
__HAL_RCC_PLL_VCIRANGE(RCC_PLLVCIRANGE_1);
|
||||
|
||||
__HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL1_DIVR);
|
||||
|
||||
__HAL_RCC_PLL_ENABLE();
|
||||
while (READ_BIT(RCC->CR, RCC_CR_PLL1RDY) == 0U)
|
||||
;
|
||||
|
||||
__HAL_RCC_HSI48_ENABLE();
|
||||
while (READ_BIT(RCC->CR, RCC_CR_HSI48RDY) == 0U)
|
||||
;
|
||||
|
||||
/** Initializes the CPU, AHB and APB buses clocks
|
||||
*/
|
||||
FLASH->ACR = FLASH_ACR_LATENCY_4WS;
|
||||
// wait until the new wait state config takes effect -- per section 3.5.1
|
||||
// guidance
|
||||
while ((FLASH->ACR & FLASH_ACR_LATENCY) != FLASH_ACR_LATENCY_4WS)
|
||||
;
|
||||
MODIFY_REG(RCC->CFGR3, RCC_CFGR3_PPRE3, RCC_HCLK_DIV1);
|
||||
MODIFY_REG(RCC->CFGR2, RCC_CFGR2_PPRE2, ((RCC_HCLK_DIV1) << 4));
|
||||
MODIFY_REG(RCC->CFGR2, RCC_CFGR2_PPRE1, RCC_HCLK_DIV1);
|
||||
MODIFY_REG(RCC->CFGR2, RCC_CFGR2_HPRE, RCC_SYSCLK_DIV1);
|
||||
|
||||
MODIFY_REG(RCC->CFGR1, RCC_CFGR1_SW, RCC_SYSCLKSOURCE_PLLCLK);
|
||||
|
||||
/*
|
||||
* Disable the internal Pull-Up in Dead Battery pins of UCPD peripheral
|
||||
*/
|
||||
HAL_PWREx_DisableUCPDDeadBattery();
|
||||
|
||||
/*
|
||||
* Switch to SMPS regulator instead of LDO
|
||||
*/
|
||||
SET_BIT(PWR->CR3, PWR_CR3_REGSEL);
|
||||
/* Wait until system switch on new regulator */
|
||||
while (HAL_IS_BIT_CLR(PWR->SVMSR, PWR_SVMSR_REGS))
|
||||
;
|
||||
|
||||
__HAL_RCC_PWR_CLK_DISABLE();
|
||||
|
||||
// this will be overriden by static initialization
|
||||
SystemCoreClock = DEFAULT_FREQ * 1000000U;
|
||||
|
||||
// enable clock security system, HSE clock, and main PLL
|
||||
RCC->CR |= RCC_CR_CSSON;
|
||||
|
||||
// turn off the HSI as it is now unused (it will be turned on again
|
||||
// automatically if a clock security failure occurs)
|
||||
RCC->CR &= ~RCC_CR_HSION;
|
||||
// wait until ths HSI is off
|
||||
while ((RCC->CR & RCC_CR_HSION) == RCC_CR_HSION)
|
||||
;
|
||||
|
||||
// TODO turn off MSI?
|
||||
|
||||
// init the TRNG peripheral
|
||||
rng_init();
|
||||
|
||||
// set CP10 and CP11 to enable full access to the fpu coprocessor;
|
||||
SCB->CPACR |=
|
||||
((3UL << 20U) | (3UL << 22U)); /* set CP10 and CP11 Full Access */
|
||||
|
||||
#if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
|
||||
SCB_NS->CPACR |=
|
||||
((3UL << 20U) | (3UL << 22U)); /* set CP10 and CP11 Full Access */
|
||||
#endif
|
||||
|
||||
// enable instruction cache
|
||||
ICACHE->CR = ICACHE_CR_EN;
|
||||
}
|
||||
|
||||
void drop_privileges(void) {
|
||||
// jump to unprivileged mode
|
||||
// http://infocenter.arm.com/help/topic/com.arm.doc.dui0552a/CHDBIBGJ.html
|
||||
__asm__ volatile("msr control, %0" ::"r"(0x1));
|
||||
__asm__ volatile("isb");
|
||||
}
|
||||
|
||||
// from util.s
|
||||
extern void shutdown_privileged(void);
|
||||
|
||||
void PVD_PVM_IRQHandler(void) {
|
||||
TIM1->CCR1 = 0; // turn off display backlight
|
||||
shutdown_privileged();
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* This file is part of the Trezor project, https://trezor.io/
|
||||
*
|
||||
* Copyright (c) SatoshiLabs
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TREZORHAL_STM32_H
|
||||
#define TREZORHAL_STM32_H
|
||||
|
||||
#include STM32_HAL_H
|
||||
#include <stdint.h>
|
||||
|
||||
#define SENSITIVE __attribute__((section(".sensitive")))
|
||||
|
||||
typedef enum {
|
||||
CLOCK_160_MHZ = 0,
|
||||
} clock_settings_t;
|
||||
|
||||
void set_core_clock(clock_settings_t settings);
|
||||
void ensure_compatible_settings(void);
|
||||
void drop_privileges(void);
|
||||
|
||||
// the following functions are defined in util.s
|
||||
void memset_reg(volatile void *start, volatile void *stop, uint32_t val);
|
||||
void jump_to(uint32_t address);
|
||||
void jump_to_unprivileged(uint32_t address);
|
||||
void jump_to_with_flag(uint32_t address, uint32_t register_flag);
|
||||
|
||||
extern uint32_t __stack_chk_guard;
|
||||
|
||||
// this deletes all secrets and SRAM2 where stack is located
|
||||
// to prevent stack smashing error, do not return from function calling this
|
||||
static inline void __attribute__((always_inline)) delete_secrets(void) {
|
||||
// Disable SAES peripheral clock, so that we don't get tamper events
|
||||
__HAL_RCC_SAES_CLK_DISABLE();
|
||||
|
||||
// Erase all
|
||||
TAMP->CR2 |= TAMP_CR2_BKERASE;
|
||||
}
|
||||
|
||||
#endif // TREZORHAL_STM32_H
|
@ -0,0 +1 @@
|
||||
../stm32f4/random_delays.c
|
@ -0,0 +1 @@
|
||||
../stm32f4/rng.c
|
@ -0,0 +1 @@
|
||||
../stm32f4/sbu.c
|
@ -0,0 +1,162 @@
|
||||
#include "secret.h"
|
||||
#include <string.h>
|
||||
#include "common.h"
|
||||
#include "flash.h"
|
||||
#include "model.h"
|
||||
#include "rng.h"
|
||||
|
||||
static secbool bootloader_locked_set = secfalse;
|
||||
static secbool bootloader_locked = secfalse;
|
||||
|
||||
static secbool verify_header(void) {
|
||||
uint8_t header[SECRET_HEADER_LEN] = {0};
|
||||
|
||||
memcpy(header, flash_area_get_address(&SECRET_AREA, 0, SECRET_HEADER_LEN),
|
||||
SECRET_HEADER_LEN);
|
||||
|
||||
bootloader_locked =
|
||||
memcmp(header, SECRET_HEADER_MAGIC, 4) == 0 ? sectrue : secfalse;
|
||||
bootloader_locked_set = sectrue;
|
||||
return bootloader_locked;
|
||||
}
|
||||
|
||||
secbool secret_bootloader_locked(void) {
|
||||
if (bootloader_locked_set != sectrue) {
|
||||
// Set bootloader_locked.
|
||||
verify_header();
|
||||
}
|
||||
|
||||
return bootloader_locked;
|
||||
}
|
||||
|
||||
void secret_write_header(void) {
|
||||
uint8_t header[SECRET_HEADER_LEN] = {0};
|
||||
memcpy(header, SECRET_HEADER_MAGIC, 4);
|
||||
secret_write(header, 0, SECRET_HEADER_LEN);
|
||||
}
|
||||
|
||||
void secret_write(uint8_t *data, uint32_t offset, uint32_t len) {
|
||||
ensure(flash_unlock_write(), "secret write");
|
||||
for (int i = 0; i < len / 16; i++) {
|
||||
ensure(flash_area_write_quadword(&SECRET_AREA, offset + (i * 16),
|
||||
(uint32_t *)&data[(i * 16)]),
|
||||
"secret write");
|
||||
}
|
||||
ensure(flash_lock_write(), "secret write");
|
||||
}
|
||||
|
||||
secbool secret_read(uint8_t *data, uint32_t offset, uint32_t len) {
|
||||
if (sectrue != verify_header()) {
|
||||
return secfalse;
|
||||
}
|
||||
|
||||
memcpy(data, flash_area_get_address(&SECRET_AREA, offset, len), len);
|
||||
|
||||
return sectrue;
|
||||
}
|
||||
|
||||
void secret_hide(void) {
|
||||
FLASH->SECHDPCR |= FLASH_SECHDPCR_HDP1_ACCDIS_Msk;
|
||||
FLASH->SECHDPCR |= FLASH_SECHDPCR_HDP2_ACCDIS_Msk;
|
||||
}
|
||||
|
||||
void secret_bhk_lock(void) {
|
||||
TAMP_S->SECCFGR = 8 << TAMP_SECCFGR_BKPRWSEC_Pos | TAMP_SECCFGR_BHKLOCK;
|
||||
}
|
||||
|
||||
secbool secret_bhk_locked(void) {
|
||||
return ((TAMP_S->SECCFGR & TAMP_SECCFGR_BHKLOCK) == TAMP_SECCFGR_BHKLOCK) *
|
||||
sectrue;
|
||||
}
|
||||
|
||||
void secret_bhk_provision(void) {
|
||||
uint32_t secret[SECRET_BHK_LEN / sizeof(uint32_t)] = {0};
|
||||
secbool ok =
|
||||
secret_read((uint8_t *)secret, SECRET_BHK_OFFSET, SECRET_BHK_LEN);
|
||||
|
||||
volatile uint32_t *reg1 = &TAMP->BKP0R;
|
||||
if (sectrue == ok) {
|
||||
for (int i = 0; i < 8; i++) {
|
||||
*reg1 = ((uint32_t *)secret)[i];
|
||||
reg1++;
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < 8; i++) {
|
||||
*reg1 = 0;
|
||||
reg1++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void secret_bhk_regenerate(void) {
|
||||
ensure(flash_area_erase(&BHK_AREA, NULL), "Failed regenerating BHK");
|
||||
ensure(flash_unlock_write(), "Failed regenerating BHK");
|
||||
for (int i = 0; i < 2; i++) {
|
||||
uint32_t val[4] = {0};
|
||||
for (int j = 0; j < 4; j++) {
|
||||
val[j] = rng_get();
|
||||
}
|
||||
ensure(flash_area_write_quadword(&BHK_AREA, i * 4 * sizeof(uint32_t), val),
|
||||
"Failed regenerating BHK");
|
||||
}
|
||||
ensure(flash_lock_write(), "Failed regenerating BHK");
|
||||
}
|
||||
|
||||
secbool secret_optiga_present(void) {
|
||||
uint8_t *optiga_secret = (uint8_t *)flash_area_get_address(
|
||||
&SECRET_AREA, SECRET_OPTIGA_KEY_OFFSET, SECRET_OPTIGA_KEY_LEN);
|
||||
|
||||
int optiga_secret_empty_bytes = 0;
|
||||
|
||||
for (int i = 0; i < SECRET_OPTIGA_KEY_LEN; i++) {
|
||||
if (optiga_secret[i] == 0xFF) {
|
||||
optiga_secret_empty_bytes++;
|
||||
}
|
||||
}
|
||||
return sectrue * (optiga_secret_empty_bytes != SECRET_OPTIGA_KEY_LEN);
|
||||
}
|
||||
|
||||
void secret_optiga_backup(void) {
|
||||
uint32_t secret[SECRET_OPTIGA_KEY_LEN / sizeof(uint32_t)] = {0};
|
||||
secbool ok = secret_read((uint8_t *)secret, SECRET_OPTIGA_KEY_OFFSET,
|
||||
SECRET_OPTIGA_KEY_LEN);
|
||||
|
||||
volatile uint32_t *reg1 = &TAMP->BKP8R;
|
||||
if (sectrue == ok) {
|
||||
for (int i = 0; i < 8; i++) {
|
||||
*reg1 = ((uint32_t *)secret)[i];
|
||||
reg1++;
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < 8; i++) {
|
||||
*reg1 = 0;
|
||||
reg1++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
secbool secret_optiga_extract(uint8_t *dest) {
|
||||
bool all_zero = true;
|
||||
volatile uint32_t *reg1 = &TAMP->BKP8R;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
uint32_t val = *reg1++;
|
||||
|
||||
if (val != 0) {
|
||||
all_zero = false;
|
||||
}
|
||||
|
||||
for (int j = 0; j < 4; j++) {
|
||||
dest[i * 4 + j] = (val >> (j * 8)) & 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
return all_zero ? secfalse : sectrue;
|
||||
}
|
||||
|
||||
void secret_optiga_hide(void) {
|
||||
volatile uint32_t *reg1 = &TAMP->BKP8R;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
*reg1 = 0;
|
||||
reg1++;
|
||||
}
|
||||
}
|
@ -0,0 +1,132 @@
|
||||
/*
|
||||
* This file is part of the Trezor project, https://trezor.io/
|
||||
*
|
||||
* Copyright (c) SatoshiLabs
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <secure_aes.h>
|
||||
#include STM32_HAL_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stm32u5xx_hal_cryp.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
static void secure_aes_load_bhk(void) {
|
||||
TAMP->BKP7R;
|
||||
TAMP->BKP6R;
|
||||
TAMP->BKP5R;
|
||||
TAMP->BKP4R;
|
||||
TAMP->BKP3R;
|
||||
TAMP->BKP2R;
|
||||
TAMP->BKP1R;
|
||||
TAMP->BKP0R;
|
||||
}
|
||||
|
||||
secbool secure_aes_encrypt(uint32_t* input, size_t size, uint32_t* output) {
|
||||
CRYP_HandleTypeDef hcryp = {0};
|
||||
uint32_t iv[] = {0, 0, 0, 0};
|
||||
|
||||
hcryp.Instance = SAES;
|
||||
hcryp.Init.DataType = CRYP_NO_SWAP;
|
||||
hcryp.Init.KeySelect = CRYP_KEYSEL_HSW;
|
||||
hcryp.Init.KeySize = CRYP_KEYSIZE_256B;
|
||||
hcryp.Init.pKey = NULL;
|
||||
hcryp.Init.pInitVect = iv;
|
||||
hcryp.Init.Algorithm = CRYP_AES_ECB;
|
||||
hcryp.Init.Header = NULL;
|
||||
hcryp.Init.HeaderSize = 0;
|
||||
hcryp.Init.DataWidthUnit = CRYP_DATAWIDTHUNIT_WORD;
|
||||
hcryp.Init.HeaderWidthUnit = CRYP_HEADERWIDTHUNIT_BYTE;
|
||||
hcryp.Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ALWAYS;
|
||||
hcryp.Init.KeyMode = CRYP_KEYMODE_NORMAL;
|
||||
|
||||
if (HAL_CRYP_Init(&hcryp) != HAL_OK) {
|
||||
return secfalse;
|
||||
}
|
||||
|
||||
secure_aes_load_bhk();
|
||||
|
||||
if (HAL_CRYP_Encrypt(&hcryp, input, size, output, HAL_MAX_DELAY) != HAL_OK) {
|
||||
return secfalse;
|
||||
}
|
||||
|
||||
HAL_CRYP_DeInit(&hcryp);
|
||||
|
||||
return sectrue;
|
||||
}
|
||||
|
||||
secbool secure_aes_decrypt(uint32_t* input, size_t size, uint32_t* output) {
|
||||
CRYP_HandleTypeDef hcryp = {0};
|
||||
uint32_t iv[] = {0, 0, 0, 0};
|
||||
|
||||
hcryp.Instance = SAES;
|
||||
hcryp.Init.DataType = CRYP_NO_SWAP;
|
||||
hcryp.Init.KeySelect = CRYP_KEYSEL_HSW;
|
||||
hcryp.Init.KeySize = CRYP_KEYSIZE_256B;
|
||||
hcryp.Init.pKey = NULL;
|
||||
hcryp.Init.pInitVect = iv;
|
||||
hcryp.Init.Algorithm = CRYP_AES_ECB;
|
||||
hcryp.Init.Header = NULL;
|
||||
hcryp.Init.HeaderSize = 0;
|
||||
hcryp.Init.DataWidthUnit = CRYP_DATAWIDTHUNIT_BYTE;
|
||||
hcryp.Init.HeaderWidthUnit = CRYP_HEADERWIDTHUNIT_BYTE;
|
||||
hcryp.Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ALWAYS;
|
||||
hcryp.Init.KeyMode = CRYP_KEYMODE_NORMAL;
|
||||
|
||||
if (HAL_CRYP_Init(&hcryp) != HAL_OK) {
|
||||
return secfalse;
|
||||
}
|
||||
|
||||
secure_aes_load_bhk();
|
||||
|
||||
if (HAL_CRYP_Decrypt(&hcryp, input, size, output, HAL_MAX_DELAY) != HAL_OK) {
|
||||
return secfalse;
|
||||
}
|
||||
|
||||
HAL_CRYP_DeInit(&hcryp);
|
||||
|
||||
return sectrue;
|
||||
}
|
||||
|
||||
void secure_aes_test() {
|
||||
static uint32_t plain_text[4] = {1, 2, 3, 4};
|
||||
static uint32_t encrypted_text[4];
|
||||
static uint32_t decrypted_text[4];
|
||||
|
||||
secbool status;
|
||||
|
||||
status = secure_aes_encrypt(plain_text, sizeof(plain_text), encrypted_text);
|
||||
printf("encryption done (status=%d)\n", status == sectrue);
|
||||
|
||||
status = secure_aes_decrypt(encrypted_text, sizeof(encrypted_text),
|
||||
decrypted_text);
|
||||
printf("decryption done (status=%d)\n", status == sectrue);
|
||||
}
|
@ -0,0 +1,563 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32u5xx_hal_conf.h
|
||||
* @author MCD Application Team
|
||||
* @brief HAL configuration file.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2021 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef STM32U5xx_HAL_CONF_H
|
||||
#define STM32U5xx_HAL_CONF_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
|
||||
#define USE_USB_HS
|
||||
#define USE_USB_HS_INTERNAL_PHY
|
||||
|
||||
/* ########################## Module Selection ############################## */
|
||||
/**
|
||||
* @brief This is the list of modules to be used in the HAL driver
|
||||
*/
|
||||
|
||||
#define HAL_MODULE_ENABLED
|
||||
|
||||
/*#define HAL_ADC_MODULE_ENABLED */
|
||||
/*#define HAL_MDF_MODULE_ENABLED */
|
||||
/*#define HAL_COMP_MODULE_ENABLED */
|
||||
/*#define HAL_CORDIC_MODULE_ENABLED */
|
||||
/*#define HAL_CRC_MODULE_ENABLED */
|
||||
/*#define HAL_CRYP_MODULE_ENABLED */
|
||||
/*#define HAL_DAC_MODULE_ENABLED */
|
||||
#define HAL_DMA2D_MODULE_ENABLED
|
||||
#define HAL_DSI_MODULE_ENABLED
|
||||
/*#define HAL_FDCAN_MODULE_ENABLED */
|
||||
/*#define HAL_FMAC_MODULE_ENABLED */
|
||||
#define HAL_GFXMMU_MODULE_ENABLED
|
||||
/*#define HAL_GPU2D_MODULE_ENABLED */
|
||||
#define HAL_GTZC_MODULE_ENABLED
|
||||
/*#define HAL_HASH_MODULE_ENABLED */
|
||||
/*#define HAL_HRTIM_MODULE_ENABLED */
|
||||
/*#define HAL_IRDA_MODULE_ENABLED */
|
||||
/*#define HAL_IWDG_MODULE_ENABLED */
|
||||
#define HAL_I2C_MODULE_ENABLED
|
||||
/*#define HAL_I2S_MODULE_ENABLED */
|
||||
/*#define HAL_LPTIM_MODULE_ENABLED */
|
||||
#define HAL_LTDC_MODULE_ENABLED
|
||||
/*#define HAL_NAND_MODULE_ENABLED */
|
||||
/*#define HAL_NOR_MODULE_ENABLED */
|
||||
/*#define HAL_OPAMP_MODULE_ENABLED */
|
||||
/*#define HAL_OSPI_MODULE_ENABLED */
|
||||
/*#define HAL_OTFDEC_MODULE_ENABLED */
|
||||
/*#define HAL_PKA_MODULE_ENABLED */
|
||||
/*#define HAL_QSPI_MODULE_ENABLED */
|
||||
/*#define HAL_RNG_MODULE_ENABLED */
|
||||
#define HAL_RTC_MODULE_ENABLED
|
||||
/*#define HAL_SAI_MODULE_ENABLED */
|
||||
#define HAL_CRYP_MODULE_ENABLED
|
||||
/*#define HAL_SD_MODULE_ENABLED */
|
||||
/*#define HAL_MMC_MODULE_ENABLED */
|
||||
/*#define HAL_SMARTCARD_MODULE_ENABLED */
|
||||
/*#define HAL_SMBUS_MODULE_ENABLED */
|
||||
/*#define HAL_SPI_MODULE_ENABLED */
|
||||
/*#define HAL_SRAM_MODULE_ENABLED */
|
||||
/*#define HAL_TIM_MODULE_ENABLED */
|
||||
/*#define HAL_TSC_MODULE_ENABLED */
|
||||
/*#define HAL_RAMCFG_MODULE_ENABLED */
|
||||
#define HAL_UART_MODULE_ENABLED
|
||||
/*#define HAL_USART_MODULE_ENABLED */
|
||||
/*#define HAL_WWDG_MODULE_ENABLED */
|
||||
/*#define HAL_DCMI_MODULE_ENABLED */
|
||||
/*#define HAL_PSSI_MODULE_ENABLED */
|
||||
#define HAL_ICACHE_MODULE_ENABLED
|
||||
/*#define HAL_DCACHE_MODULE_ENABLED */
|
||||
#define HAL_PCD_MODULE_ENABLED
|
||||
/*#define HAL_HCD_MODULE_ENABLED */
|
||||
/*#define HAL_XSPI_MODULE_ENABLED */
|
||||
|
||||
#define HAL_GPIO_MODULE_ENABLED
|
||||
#define HAL_EXTI_MODULE_ENABLED
|
||||
#define HAL_DMA_MODULE_ENABLED
|
||||
#define HAL_RCC_MODULE_ENABLED
|
||||
#define HAL_FLASH_MODULE_ENABLED
|
||||
#define HAL_PWR_MODULE_ENABLED
|
||||
#define HAL_CORTEX_MODULE_ENABLED
|
||||
|
||||
/* ########################## Oscillator Values adaptation
|
||||
* ####################*/
|
||||
/**
|
||||
* @brief Adjust the value of External High Speed oscillator (HSE) used in your
|
||||
* application. This value is used by the RCC HAL module to compute the system
|
||||
* frequency (when HSE is used as system clock source, directly or through the
|
||||
* PLL).
|
||||
*/
|
||||
#if !defined(HSE_VALUE)
|
||||
#define HSE_VALUE 16000000UL /*!< Value of the External oscillator in Hz */
|
||||
#endif /* HSE_VALUE */
|
||||
|
||||
#if !defined(HSE_STARTUP_TIMEOUT)
|
||||
#define HSE_STARTUP_TIMEOUT 100UL /*!< Time out for HSE start up, in ms */
|
||||
#endif /* HSE_STARTUP_TIMEOUT */
|
||||
|
||||
/**
|
||||
* @brief Internal Multiple Speed oscillator (MSI) default value.
|
||||
* This value is the default MSI range value after Reset.
|
||||
*/
|
||||
#if !defined(MSI_VALUE)
|
||||
#define MSI_VALUE 4000000UL /*!< Value of the Internal oscillator in Hz*/
|
||||
#endif /* MSI_VALUE */
|
||||
|
||||
/**
|
||||
* @brief Internal High Speed oscillator (HSI) value.
|
||||
* This value is used by the RCC HAL module to compute the system
|
||||
* frequency (when HSI is used as system clock source, directly or through the
|
||||
* PLL).
|
||||
*/
|
||||
#if !defined(HSI_VALUE)
|
||||
#define HSI_VALUE 16000000UL /*!< Value of the Internal oscillator in Hz*/
|
||||
#endif /* HSI_VALUE */
|
||||
|
||||
/**
|
||||
* @brief Internal High Speed oscillator (HSI48) value for USB FS, SDMMC and
|
||||
* RNG. This internal oscillator is mainly dedicated to provide a high precision
|
||||
* clock to the USB peripheral by means of a special Clock Recovery System (CRS)
|
||||
* circuitry. When the CRS is not used, the HSI48 RC oscillator runs on it
|
||||
* default frequency which is subject to manufacturing process variations.
|
||||
*/
|
||||
#if !defined(HSI48_VALUE)
|
||||
#define HSI48_VALUE \
|
||||
48000000UL /*!< Value of the Internal High Speed oscillator for USB \
|
||||
FS/SDMMC/RNG in Hz. The real value my vary depending on \
|
||||
manufacturing process variations.*/
|
||||
#endif /* HSI48_VALUE */
|
||||
|
||||
/**
|
||||
* @brief Internal Low Speed oscillator (LSI) value.
|
||||
*/
|
||||
#if !defined(LSI_VALUE)
|
||||
#define LSI_VALUE 32000UL /*!< LSI Typical Value in Hz*/
|
||||
#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz \
|
||||
The real value may vary depending on the \
|
||||
variations in voltage and temperature.*/
|
||||
/**
|
||||
* @brief External Low Speed oscillator (LSE) value.
|
||||
* This value is used by the UART, RTC HAL module to compute the system
|
||||
* frequency
|
||||
*/
|
||||
#if !defined(LSE_VALUE)
|
||||
#define LSE_VALUE \
|
||||
32768UL /*!< Value of the External Low Speed oscillator in Hz */
|
||||
#endif /* LSE_VALUE */
|
||||
|
||||
#if !defined(LSE_STARTUP_TIMEOUT)
|
||||
#define LSE_STARTUP_TIMEOUT 5000UL /*!< Time out for LSE start up, in ms */
|
||||
#endif /* LSE_STARTUP_TIMEOUT */
|
||||
|
||||
/**
|
||||
* @brief External clock source for SAI1 peripheral
|
||||
* This value is used by the RCC HAL module to compute the SAI1 & SAI2
|
||||
* clock source frequency.
|
||||
*/
|
||||
#if !defined(EXTERNAL_SAI1_CLOCK_VALUE)
|
||||
#define EXTERNAL_SAI1_CLOCK_VALUE \
|
||||
48000UL /*!< Value of the SAI1 External clock source in Hz*/
|
||||
#endif /* EXTERNAL_SAI1_CLOCK_VALUE */
|
||||
|
||||
/* Tip: To avoid modifying this file each time you need to use different HSE,
|
||||
=== you can define the HSE value in your toolchain compiler preprocessor. */
|
||||
|
||||
/* ########################### System Configuration ######################### */
|
||||
/**
|
||||
* @brief This is the HAL system configuration section
|
||||
*/
|
||||
|
||||
#define VDD_VALUE 3300UL /*!< Value of VDD in mv */
|
||||
#define TICK_INT_PRIORITY \
|
||||
(15UL) /*!< tick interrupt priority (lowest by default) */
|
||||
#define USE_RTOS 0U
|
||||
#define PREFETCH_ENABLE 1U /*!< Enable prefetch */
|
||||
|
||||
/* ########################## Assert Selection ############################## */
|
||||
/**
|
||||
* @brief Uncomment the line below to expanse the "assert_param" macro in the
|
||||
* HAL drivers code
|
||||
*/
|
||||
|
||||
/* #define USE_FULL_ASSERT 1U */
|
||||
|
||||
/* ################## Register callback feature configuration ############### */
|
||||
/**
|
||||
* @brief Set below the peripheral configuration to "1U" to add the support
|
||||
* of HAL callback registration/unregistration feature for the HAL
|
||||
* driver(s). This allows user application to provide specific callback
|
||||
* functions thanks to HAL_PPP_RegisterCallback() rather than overwriting
|
||||
* the default weak callback functions (see each stm32u5xx_hal_ppp.h file
|
||||
* for possible callback identifiers defined in HAL_PPP_CallbackIDTypeDef
|
||||
* for each PPP peripheral).
|
||||
*/
|
||||
#define USE_HAL_ADC_REGISTER_CALLBACKS \
|
||||
0U /* ADC register callback disabled */
|
||||
#define USE_HAL_COMP_REGISTER_CALLBACKS \
|
||||
0U /* COMP register callback disabled */
|
||||
#define USE_HAL_CORDIC_REGISTER_CALLBACKS \
|
||||
0U /* CORDIC register callback disabled */
|
||||
#define USE_HAL_CRYP_REGISTER_CALLBACKS \
|
||||
0U /* CRYP register callback disabled */
|
||||
#define USE_HAL_DAC_REGISTER_CALLBACKS \
|
||||
0U /* DAC register callback disabled */
|
||||
#define USE_HAL_DCMI_REGISTER_CALLBACKS \
|
||||
0U /* DCMI register callback disabled */
|
||||
#define USE_HAL_DMA2D_REGISTER_CALLBACKS \
|
||||
0U /* DMA2D register callback disabled */
|
||||
#define USE_HAL_DSI_REGISTER_CALLBACKS \
|
||||
0U /* DSI register callback disabled */
|
||||
#define USE_HAL_ETH_REGISTER_CALLBACKS \
|
||||
0U /* ETH register callback disabled */
|
||||
#define USE_HAL_FDCAN_REGISTER_CALLBACKS \
|
||||
0U /* FDCAN register callback disabled */
|
||||
#define USE_HAL_FMAC_REGISTER_CALLBACKS \
|
||||
0U /* FMAC register callback disabled */
|
||||
#define USE_HAL_HASH_REGISTER_CALLBACKS \
|
||||
0U /* HASH register callback disabled */
|
||||
#define USE_HAL_HCD_REGISTER_CALLBACKS \
|
||||
0U /* HCD register callback disabled */
|
||||
#define USE_HAL_GFXMMU_REGISTER_CALLBACKS \
|
||||
0U /* GFXMMU register callback disabled */
|
||||
#define USE_HAL_GPU2D_REGISTER_CALLBACKS \
|
||||
0U /* GPU2D register callback disabled */
|
||||
#define USE_HAL_I2C_REGISTER_CALLBACKS \
|
||||
0U /* I2C register callback disabled */
|
||||
#define USE_HAL_IWDG_REGISTER_CALLBACKS \
|
||||
0U /* IWDG register callback disabled */
|
||||
#define USE_HAL_IRDA_REGISTER_CALLBACKS \
|
||||
0U /* IRDA register callback disabled */
|
||||
#define USE_HAL_LPTIM_REGISTER_CALLBACKS \
|
||||
0U /* LPTIM register callback disabled */
|
||||
#define USE_HAL_LTDC_REGISTER_CALLBACKS \
|
||||
0U /* LTDC register callback disabled */
|
||||
#define USE_HAL_MDF_REGISTER_CALLBACKS \
|
||||
0U /* MDF register callback disabled */
|
||||
#define USE_HAL_MMC_REGISTER_CALLBACKS \
|
||||
0U /* MMC register callback disabled */
|
||||
#define USE_HAL_NAND_REGISTER_CALLBACKS \
|
||||
0U /* NAND register callback disabled */
|
||||
#define USE_HAL_NOR_REGISTER_CALLBACKS \
|
||||
0U /* NOR register callback disabled */
|
||||
#define USE_HAL_OPAMP_REGISTER_CALLBACKS \
|
||||
0U /* MDIO register callback disabled */
|
||||
#define USE_HAL_OTFDEC_REGISTER_CALLBACKS \
|
||||
0U /* OTFDEC register callback disabled */
|
||||
#define USE_HAL_PCD_REGISTER_CALLBACKS \
|
||||
0U /* PCD register callback disabled */
|
||||
#define USE_HAL_PKA_REGISTER_CALLBACKS \
|
||||
0U /* PKA register callback disabled */
|
||||
#define USE_HAL_RAMCFG_REGISTER_CALLBACKS \
|
||||
0U /* RAMCFG register callback disabled */
|
||||
#define USE_HAL_RNG_REGISTER_CALLBACKS \
|
||||
0U /* RNG register callback disabled */
|
||||
#define USE_HAL_RTC_REGISTER_CALLBACKS \
|
||||
0U /* RTC register callback disabled */
|
||||
#define USE_HAL_SAI_REGISTER_CALLBACKS \
|
||||
0U /* SAI register callback disabled */
|
||||
#define USE_HAL_SD_REGISTER_CALLBACKS \
|
||||
0U /* SD register callback disabled */
|
||||
#define USE_HAL_SDRAM_REGISTER_CALLBACKS \
|
||||
0U /* SDRAM register callback disabled */
|
||||
#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS \
|
||||
0U /* SMARTCARD register callback disabled */
|
||||
#define USE_HAL_SMBUS_REGISTER_CALLBACKS \
|
||||
0U /* SMBUS register callback disabled */
|
||||
#define USE_HAL_SPI_REGISTER_CALLBACKS \
|
||||
0U /* SPI register callback disabled */
|
||||
#define USE_HAL_SRAM_REGISTER_CALLBACKS \
|
||||
0U /* SRAM register callback disabled */
|
||||
#define USE_HAL_TIM_REGISTER_CALLBACKS \
|
||||
0U /* TIM register callback disabled */
|
||||
#define USE_HAL_TSC_REGISTER_CALLBACKS \
|
||||
0U /* TSC register callback disabled */
|
||||
#define USE_HAL_UART_REGISTER_CALLBACKS \
|
||||
0U /* UART register callback disabled */
|
||||
#define USE_HAL_USART_REGISTER_CALLBACKS \
|
||||
0U /* USART register callback disabled */
|
||||
#define USE_HAL_WWDG_REGISTER_CALLBACKS \
|
||||
0U /* WWDG register callback disabled */
|
||||
#define USE_HAL_OSPI_REGISTER_CALLBACKS \
|
||||
0U /* OSPI register callback disabled */
|
||||
/* ################## SPI peripheral configuration ########################## */
|
||||
|
||||
/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver
|
||||
* Activated: CRC code is present inside driver
|
||||
* Deactivated: CRC code cleaned from driver
|
||||
*/
|
||||
#define USE_SPI_CRC 0U
|
||||
|
||||
/* ################## SDMMC peripheral configuration #########################
|
||||
*/
|
||||
|
||||
#define USE_SD_TRANSCEIVER 0U /*!< use uSD Transceiver */
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Include module's header file
|
||||
*/
|
||||
|
||||
#ifdef HAL_RCC_MODULE_ENABLED
|
||||
#include "stm32u5xx_hal_rcc.h"
|
||||
#endif /* HAL_RCC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_GPIO_MODULE_ENABLED
|
||||
#include "stm32u5xx_hal_gpio.h"
|
||||
#endif /* HAL_GPIO_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_ICACHE_MODULE_ENABLED
|
||||
#include "stm32u5xx_hal_icache.h"
|
||||
#endif /* HAL_ICACHE_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DCACHE_MODULE_ENABLED
|
||||
#include "stm32u5xx_hal_dcache.h"
|
||||
#endif /* HAL_DCACHE_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_GTZC_MODULE_ENABLED
|
||||
#include "stm32u5xx_hal_gtzc.h"
|
||||
#endif /* HAL_GTZC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DMA_MODULE_ENABLED
|
||||
#include "stm32u5xx_hal_dma.h"
|
||||
#endif /* HAL_DMA_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DMA2D_MODULE_ENABLED
|
||||
#include "stm32u5xx_hal_dma2d.h"
|
||||
#endif /* HAL_DMA2D_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DSI_MODULE_ENABLED
|
||||
#include "stm32u5xx_hal_dsi.h"
|
||||
#endif /* HAL_DSI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CORTEX_MODULE_ENABLED
|
||||
#include "stm32u5xx_hal_cortex.h"
|
||||
#endif /* HAL_CORTEX_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_PKA_MODULE_ENABLED
|
||||
#include "stm32u5xx_hal_pka.h"
|
||||
#endif /* HAL_PKA_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_ADC_MODULE_ENABLED
|
||||
#include "stm32u5xx_hal_adc.h"
|
||||
#endif /* HAL_ADC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_COMP_MODULE_ENABLED
|
||||
#include "stm32u5xx_hal_comp.h"
|
||||
#endif /* HAL_COMP_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CRC_MODULE_ENABLED
|
||||
#include "stm32u5xx_hal_crc.h"
|
||||
#endif /* HAL_CRC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CRYP_MODULE_ENABLED
|
||||
#include "stm32u5xx_hal_cryp.h"
|
||||
#endif /* HAL_CRYP_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DAC_MODULE_ENABLED
|
||||
#include "stm32u5xx_hal_dac.h"
|
||||
#endif /* HAL_DAC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_FLASH_MODULE_ENABLED
|
||||
#include "stm32u5xx_hal_flash.h"
|
||||
#endif /* HAL_FLASH_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_HASH_MODULE_ENABLED
|
||||
#include "stm32u5xx_hal_hash.h"
|
||||
#endif /* HAL_HASH_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SRAM_MODULE_ENABLED
|
||||
#include "stm32u5xx_hal_sram.h"
|
||||
#endif /* HAL_SRAM_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_MMC_MODULE_ENABLED
|
||||
#include "stm32u5xx_hal_mmc.h"
|
||||
#endif /* HAL_MMC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_NOR_MODULE_ENABLED
|
||||
#include "stm32u5xx_hal_nor.h"
|
||||
#endif /* HAL_NOR_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_NAND_MODULE_ENABLED
|
||||
#include "stm32u5xx_hal_nand.h"
|
||||
#endif /* HAL_NAND_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_I2C_MODULE_ENABLED
|
||||
#include "stm32u5xx_hal_i2c.h"
|
||||
#endif /* HAL_I2C_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_IWDG_MODULE_ENABLED
|
||||
#include "stm32u5xx_hal_iwdg.h"
|
||||
#endif /* HAL_IWDG_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_LPTIM_MODULE_ENABLED
|
||||
#include "stm32u5xx_hal_lptim.h"
|
||||
#endif /* HAL_LPTIM_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_LTDC_MODULE_ENABLED
|
||||
#include "stm32u5xx_hal_ltdc.h"
|
||||
#endif /* HAL_LTDC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_OPAMP_MODULE_ENABLED
|
||||
#include "stm32u5xx_hal_opamp.h"
|
||||
#endif /* HAL_OPAMP_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_PWR_MODULE_ENABLED
|
||||
#include "stm32u5xx_hal_pwr.h"
|
||||
#endif /* HAL_PWR_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_OSPI_MODULE_ENABLED
|
||||
#include "stm32u5xx_hal_ospi.h"
|
||||
#endif /* HAL_OSPI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_RNG_MODULE_ENABLED
|
||||
#include "stm32u5xx_hal_rng.h"
|
||||
#endif /* HAL_RNG_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_RTC_MODULE_ENABLED
|
||||
#include "stm32u5xx_hal_rtc.h"
|
||||
#endif /* HAL_RTC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SAI_MODULE_ENABLED
|
||||
#include "stm32u5xx_hal_sai.h"
|
||||
#endif /* HAL_SAI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SD_MODULE_ENABLED
|
||||
#include "stm32u5xx_hal_sd.h"
|
||||
#endif /* HAL_SD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SMBUS_MODULE_ENABLED
|
||||
#include "stm32u5xx_hal_smbus.h"
|
||||
#endif /* HAL_SMBUS_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SPI_MODULE_ENABLED
|
||||
#include "stm32u5xx_hal_spi.h"
|
||||
#endif /* HAL_SPI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_TIM_MODULE_ENABLED
|
||||
#include "stm32u5xx_hal_tim.h"
|
||||
#endif /* HAL_TIM_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_TSC_MODULE_ENABLED
|
||||
#include "stm32u5xx_hal_tsc.h"
|
||||
#endif /* HAL_TSC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_UART_MODULE_ENABLED
|
||||
#include "stm32u5xx_hal_uart.h"
|
||||
#endif /* HAL_UART_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_USART_MODULE_ENABLED
|
||||
#include "stm32u5xx_hal_usart.h"
|
||||
#endif /* HAL_USART_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_IRDA_MODULE_ENABLED
|
||||
#include "stm32u5xx_hal_irda.h"
|
||||
#endif /* HAL_IRDA_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SMARTCARD_MODULE_ENABLED
|
||||
#include "stm32u5xx_hal_smartcard.h"
|
||||
#endif /* HAL_SMARTCARD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_WWDG_MODULE_ENABLED
|
||||
#include "stm32u5xx_hal_wwdg.h"
|
||||
#endif /* HAL_WWDG_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_PCD_MODULE_ENABLED
|
||||
#include "stm32u5xx_hal_pcd.h"
|
||||
#endif /* HAL_PCD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_HCD_MODULE_ENABLED
|
||||
#include "stm32u5xx_hal_hcd.h"
|
||||
#endif /* HAL_HCD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CORDIC_MODULE_ENABLED
|
||||
#include "stm32u5xx_hal_cordic.h"
|
||||
#endif /* HAL_CORDIC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DCMI_MODULE_ENABLED
|
||||
#include "stm32u5xx_hal_dcmi.h"
|
||||
#endif /* HAL_DCMI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_EXTI_MODULE_ENABLED
|
||||
#include "stm32u5xx_hal_exti.h"
|
||||
#endif /* HAL_EXTI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_FDCAN_MODULE_ENABLED
|
||||
#include "stm32u5xx_hal_fdcan.h"
|
||||
#endif /* HAL_FDCAN_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_FMAC_MODULE_ENABLED
|
||||
#include "stm32u5xx_hal_fmac.h"
|
||||
#endif /* HAL_FMAC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_GFXMMU_MODULE_ENABLED
|
||||
#include "stm32u5xx_hal_gfxmmu.h"
|
||||
#endif /* HAL_GFXMMU_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_GPU2D_MODULE_ENABLED
|
||||
#include "stm32u5xx_hal_gpu2d.h"
|
||||
#endif /* HAL_GPU2D_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_OTFDEC_MODULE_ENABLED
|
||||
#include "stm32u5xx_hal_otfdec.h"
|
||||
#endif /* HAL_OTFDEC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_PSSI_MODULE_ENABLED
|
||||
#include "stm32u5xx_hal_pssi.h"
|
||||
#endif /* HAL_PSSI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_RAMCFG_MODULE_ENABLED
|
||||
#include "stm32u5xx_hal_ramcfg.h"
|
||||
#endif /* HAL_RAMCFG_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_MDF_MODULE_ENABLED
|
||||
#include "stm32u5xx_hal_mdf.h"
|
||||
#endif /* HAL_MDF_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_XSPI_MODULE_ENABLED
|
||||
#include "stm32u5xx_hal_xspi.h"
|
||||
#endif /* HAL_XSPI_MODULE_ENABLED */
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
#ifdef USE_FULL_ASSERT
|
||||
/**
|
||||
* @brief The assert_param macro is used for function's parameters check.
|
||||
* @param expr: If expr is false, it calls assert_failed function
|
||||
* which reports the name of the source file and the source
|
||||
* line number of the call that failed.
|
||||
* If expr is true, it returns no value.
|
||||
* @retval None
|
||||
*/
|
||||
#define assert_param(expr) \
|
||||
((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__))
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
void assert_failed(uint8_t *file, uint32_t line);
|
||||
#else
|
||||
#define assert_param(expr) ((void)0U)
|
||||
#endif /* USE_FULL_ASSERT */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* STM32U5xx_HAL_CONF_H */
|
@ -0,0 +1 @@
|
||||
../stm32f4/supervise.h
|
@ -0,0 +1 @@
|
||||
../../firmware/systemview.h
|
@ -0,0 +1 @@
|
||||
../stm32f4/systick.c
|
@ -0,0 +1 @@
|
||||
../stm32f4/systick.h
|
@ -0,0 +1,192 @@
|
||||
/*
|
||||
* This file is part of the Trezor project, https://trezor.io/
|
||||
*
|
||||
* Copyright (c) SatoshiLabs
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <irq.h>
|
||||
#include <supervise.h>
|
||||
#include <tamper.h>
|
||||
#include STM32_HAL_H
|
||||
|
||||
// Fixes a typo in CMSIS Device library for STM32U5
|
||||
#undef TAMP_CR3_ITAMP7NOER_Msk
|
||||
#undef TAMP_CR3_ITAMP7NOER
|
||||
#define TAMP_CR3_ITAMP7NOER_Msk (0x1UL << TAMP_CR3_ITAMP7NOER_Pos)
|
||||
#define TAMP_CR3_ITAMP7NOER TAMP_CR3_ITAMP7NOER_Msk
|
||||
|
||||
void tamper_init() {
|
||||
RCC_PeriphCLKInitTypeDef clk_init_def = {0};
|
||||
RCC_OscInitTypeDef osc_init_def = {0};
|
||||
|
||||
// Enable LSI clock
|
||||
osc_init_def.OscillatorType = RCC_OSCILLATORTYPE_LSI;
|
||||
osc_init_def.LSIState = RCC_LSI_ON;
|
||||
HAL_RCC_OscConfig(&osc_init_def);
|
||||
|
||||
// Select RTC peripheral clock source
|
||||
clk_init_def.PeriphClockSelection = RCC_PERIPHCLK_RTC;
|
||||
clk_init_def.RTCClockSelection = RCC_RTCCLKSOURCE_LSI;
|
||||
HAL_RCCEx_PeriphCLKConfig(&clk_init_def);
|
||||
|
||||
// Enable RTC peripheral (tampers are part of it)
|
||||
__HAL_RCC_RTC_ENABLE();
|
||||
__HAL_RCC_RTCAPB_CLK_ENABLE();
|
||||
|
||||
// Clear all pending interrupts
|
||||
// They may be some as RTC/TAMP peripherals resides inside the
|
||||
// backup voltage domain
|
||||
TAMP->SCR = TAMP_SCR_CTAMP2F | TAMP_SCR_CITAMP1F | TAMP_SCR_CITAMP2F |
|
||||
TAMP_SCR_CITAMP3F | TAMP_SCR_CITAMP5F | TAMP_SCR_CITAMP6F |
|
||||
TAMP_SCR_CITAMP7F | TAMP_SCR_CITAMP8F | TAMP_SCR_CITAMP9F |
|
||||
TAMP_SCR_CITAMP11F | TAMP_SCR_CITAMP12F | TAMP_SCR_CITAMP13F;
|
||||
|
||||
NVIC_ClearPendingIRQ(TAMP_IRQn);
|
||||
|
||||
// Enable battery and power monitoring (!@# rework it)
|
||||
RCC->AHB3ENR |= RCC_AHB3ENR_PWREN;
|
||||
// HAL_PWR_EnableBkUpAccess();
|
||||
HAL_PWREx_EnableMonitoring();
|
||||
// HAL_PWR_DisableBkUpAccess();
|
||||
|
||||
// Enable all internal tampers (4th and 10th are intentionally skipped)
|
||||
// We select all of them despite some of them are never triggered
|
||||
TAMP->CR1 =
|
||||
TAMP_CR1_ITAMP1E | // backup domain voltage monitoring
|
||||
TAMP_CR1_ITAMP2E | // temperature monitoring
|
||||
TAMP_CR1_ITAMP3E | // LSE monitoring (LSECSS)
|
||||
TAMP_CR1_ITAMP5E | // RTC calendar overflow
|
||||
TAMP_CR1_ITAMP6E | // JTAG/SWD access when RDP > 0
|
||||
TAMP_CR1_ITAMP7E | // ADC4 analog watchdog monitoring 1
|
||||
TAMP_CR1_ITAMP8E | // Monotonic counter 1 overflow
|
||||
TAMP_CR1_ITAMP9E | // Crypto periherals fault (SAES, AES, PKA, TRNG)
|
||||
TAMP_CR1_ITAMP11E | // IWDG reset when tamper flag is set
|
||||
TAMP_CR1_ITAMP12E | // ADC4 analog watchdog monitoring 2
|
||||
TAMP_CR1_ITAMP13E; // ADC4 analog watchdog monitoring 3
|
||||
|
||||
// Switch all internal tampers to the "confirmed" mode
|
||||
// => all secrets all deleted when any tamper event is triggered
|
||||
TAMP->CR3 = 0;
|
||||
|
||||
// Setup external tampers
|
||||
// TAMP_IN2 active low, "confirmed" mode
|
||||
TAMP->CR2 = 0;
|
||||
// TAMP_CR2_TAMP2TRG;
|
||||
|
||||
// Set external tamper input filter
|
||||
TAMP->FLTCR =
|
||||
// TAMP_FLTCR_TAMPPUDIS | // disable pre-charge of TAMP_INx pins
|
||||
(3 << TAMP_FLTCR_TAMPPRCH_Pos) | // pre-charge 8 RTCCLK cycles
|
||||
(2 << TAMP_FLTCR_TAMPFLT_Pos) | // activated after 4 same samples
|
||||
(7 << TAMP_FLTCR_TAMPFREQ_Pos); // sampling period RTCCLK / 256 (128Hz)
|
||||
|
||||
// Enable all interrupts for all internal tampers
|
||||
TAMP->IER = TAMP_IER_TAMP2IE | TAMP_IER_ITAMP1IE | TAMP_IER_ITAMP2IE |
|
||||
TAMP_IER_ITAMP3IE | TAMP_IER_ITAMP5IE | TAMP_IER_ITAMP6IE |
|
||||
TAMP_IER_ITAMP7IE | TAMP_IER_ITAMP8IE | TAMP_IER_ITAMP9IE |
|
||||
TAMP_IER_ITAMP11IE | TAMP_IER_ITAMP12IE | TAMP_IER_ITAMP13IE;
|
||||
|
||||
// Enable TAMP interrupt at NVIC controller
|
||||
NVIC_SetPriority(TAMP_IRQn, IRQ_PRI_TAMP);
|
||||
NVIC_EnableIRQ(TAMP_IRQn);
|
||||
}
|
||||
|
||||
// Interrupt handle for all tamper events
|
||||
// It displays an error message
|
||||
void TAMP_IRQHandler(void) {
|
||||
const char* reason = "UNKNOWN";
|
||||
|
||||
uint32_t sr = TAMP->SR;
|
||||
|
||||
if (sr & TAMP_SR_TAMP1F) {
|
||||
reason = "INPUT1";
|
||||
} else if (sr & TAMP_SR_TAMP2F) {
|
||||
reason = "INPUT2";
|
||||
} else if (sr & TAMP_SR_ITAMP1F) {
|
||||
reason = "VOLTAGE";
|
||||
} else if (sr & TAMP_SR_ITAMP2F) {
|
||||
reason = "TEMPERATURE";
|
||||
} else if (sr & TAMP_SR_ITAMP3F) {
|
||||
reason = "LSE CLOCK";
|
||||
} else if (sr & TAMP_SR_ITAMP5F) {
|
||||
reason = "RTC OVERFLOW";
|
||||
} else if (sr & TAMP_SR_ITAMP6F) {
|
||||
reason = "SWD ACCESS";
|
||||
} else if (sr & TAMP_SR_ITAMP7F) {
|
||||
reason = "ANALOG WDG1";
|
||||
} else if (sr & TAMP_SR_ITAMP8F) {
|
||||
reason = "MONO COUNTER";
|
||||
} else if (sr & TAMP_SR_ITAMP9F) {
|
||||
reason = "CRYPTO ERROR";
|
||||
} else if (sr & TAMP_SR_ITAMP11F) {
|
||||
reason = "IWDG";
|
||||
} else if (sr & TAMP_SR_ITAMP12F) {
|
||||
reason = "ANALOG WDG2";
|
||||
} else if (sr & TAMP_SR_ITAMP13F) {
|
||||
reason = "ANALOG WDG3";
|
||||
}
|
||||
|
||||
error_shutdown("INTERNAL TAMPER", reason);
|
||||
}
|
||||
|
||||
// Triggers ITAMP5 by overflowing RTC date/time
|
||||
static void tamper_test_rtc_overflow(void) {
|
||||
RTC_HandleTypeDef hrtc;
|
||||
RTC_DateTypeDef date = {0};
|
||||
RTC_TimeTypeDef time = {0};
|
||||
|
||||
// Initialize RTC and select BCD format for date & time
|
||||
hrtc.Instance = RTC;
|
||||
hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
|
||||
hrtc.Init.AsynchPrediv = 127;
|
||||
hrtc.Init.SynchPrediv = 255;
|
||||
hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
|
||||
hrtc.Init.OutPutRemap = RTC_OUTPUT_REMAP_NONE;
|
||||
hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
|
||||
hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
|
||||
hrtc.Init.OutPutPullUp = RTC_OUTPUT_PULLUP_NONE;
|
||||
hrtc.Init.BinMode = RTC_BINARY_NONE;
|
||||
HAL_RTC_Init(&hrtc);
|
||||
|
||||
// set date 99/12/31
|
||||
date.Year = 0x99;
|
||||
date.Month = 0x12;
|
||||
date.Date = 0x31;
|
||||
date.WeekDay = 0x00;
|
||||
HAL_RTC_SetDate(&hrtc, &date, RTC_FORMAT_BCD);
|
||||
|
||||
// set time 23:59:50
|
||||
time.Hours = 0x23;
|
||||
time.Minutes = 0x59;
|
||||
time.Seconds = 0x50;
|
||||
HAL_RTC_SetTime(&hrtc, &time, RTC_FORMAT_BCD);
|
||||
}
|
||||
|
||||
// Triggers ITAMP8 by overflowing monotonic counter
|
||||
static void tamper_test_counter_overflow(void) {
|
||||
for (uint32_t i = 0; i < UINT32_MAX; i++) {
|
||||
TAMP->COUNTR = 0;
|
||||
}
|
||||
TAMP->COUNTR = 0;
|
||||
}
|
||||
|
||||
void tamper_test(uint32_t tamper_bit) {
|
||||
if (tamper_bit & TAMP_CR1_ITAMP5E) {
|
||||
tamper_test_rtc_overflow();
|
||||
} else if (tamper_bit & TAMP_CR1_ITAMP8E) {
|
||||
tamper_test_counter_overflow();
|
||||
}
|
||||
}
|
@ -0,0 +1,231 @@
|
||||
#include "trustzone.h"
|
||||
|
||||
#ifdef BOARDLOADER
|
||||
|
||||
#include STM32_HAL_H
|
||||
|
||||
void trustzone_init(void) {
|
||||
#if defined(__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U)
|
||||
|
||||
#if defined(SAU_INIT_REGION0) && (SAU_INIT_REGION0 == 1U)
|
||||
SAU_INIT_REGION(0);
|
||||
#endif
|
||||
|
||||
#if defined(SAU_INIT_REGION1) && (SAU_INIT_REGION1 == 1U)
|
||||
SAU_INIT_REGION(1);
|
||||
#endif
|
||||
|
||||
#if defined(SAU_INIT_REGION2) && (SAU_INIT_REGION2 == 1U)
|
||||
SAU_INIT_REGION(2);
|
||||
#endif
|
||||
|
||||
#if defined(SAU_INIT_REGION3) && (SAU_INIT_REGION3 == 1U)
|
||||
SAU_INIT_REGION(3);
|
||||
#endif
|
||||
|
||||
#if defined(SAU_INIT_REGION4) && (SAU_INIT_REGION4 == 1U)
|
||||
SAU_INIT_REGION(4);
|
||||
#endif
|
||||
|
||||
#if defined(SAU_INIT_REGION5) && (SAU_INIT_REGION5 == 1U)
|
||||
SAU_INIT_REGION(5);
|
||||
#endif
|
||||
|
||||
#if defined(SAU_INIT_REGION6) && (SAU_INIT_REGION6 == 1U)
|
||||
SAU_INIT_REGION(6);
|
||||
#endif
|
||||
|
||||
#if defined(SAU_INIT_REGION7) && (SAU_INIT_REGION7 == 1U)
|
||||
SAU_INIT_REGION(7);
|
||||
#endif
|
||||
|
||||
/* repeat this for all possible SAU regions */
|
||||
|
||||
#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */
|
||||
|
||||
#if defined(SAU_INIT_CTRL) && (SAU_INIT_CTRL == 1U)
|
||||
SAU->CTRL =
|
||||
((SAU_INIT_CTRL_ENABLE << SAU_CTRL_ENABLE_Pos) & SAU_CTRL_ENABLE_Msk) |
|
||||
((SAU_INIT_CTRL_ALLNS << SAU_CTRL_ALLNS_Pos) & SAU_CTRL_ALLNS_Msk);
|
||||
#endif
|
||||
|
||||
#if defined(SCB_CSR_AIRCR_INIT) && (SCB_CSR_AIRCR_INIT == 1U)
|
||||
SCB->SCR = (SCB->SCR & ~(SCB_SCR_SLEEPDEEPS_Msk)) |
|
||||
((SCB_CSR_DEEPSLEEPS_VAL << SCB_SCR_SLEEPDEEPS_Pos) &
|
||||
SCB_SCR_SLEEPDEEPS_Msk);
|
||||
|
||||
SCB->AIRCR =
|
||||
(SCB->AIRCR & ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_SYSRESETREQS_Msk |
|
||||
SCB_AIRCR_BFHFNMINS_Msk | SCB_AIRCR_PRIS_Msk)) |
|
||||
((0x05FAU << SCB_AIRCR_VECTKEY_Pos) & SCB_AIRCR_VECTKEY_Msk) |
|
||||
((SCB_AIRCR_SYSRESETREQS_VAL << SCB_AIRCR_SYSRESETREQS_Pos) &
|
||||
SCB_AIRCR_SYSRESETREQS_Msk) |
|
||||
((SCB_AIRCR_PRIS_VAL << SCB_AIRCR_PRIS_Pos) & SCB_AIRCR_PRIS_Msk) |
|
||||
((SCB_AIRCR_BFHFNMINS_VAL << SCB_AIRCR_BFHFNMINS_Pos) &
|
||||
SCB_AIRCR_BFHFNMINS_Msk);
|
||||
#endif /* defined (SCB_CSR_AIRCR_INIT) && (SCB_CSR_AIRCR_INIT == 1U) */
|
||||
|
||||
#if defined(__FPU_USED) && (__FPU_USED == 1U) && defined(TZ_FPU_NS_USAGE) && \
|
||||
(TZ_FPU_NS_USAGE == 1U)
|
||||
|
||||
SCB->NSACR = (SCB->NSACR & ~(SCB_NSACR_CP10_Msk | SCB_NSACR_CP11_Msk)) |
|
||||
((SCB_NSACR_CP10_11_VAL << SCB_NSACR_CP10_Pos) &
|
||||
(SCB_NSACR_CP10_Msk | SCB_NSACR_CP11_Msk));
|
||||
|
||||
FPU->FPCCR = (FPU->FPCCR & ~(FPU_FPCCR_TS_Msk | FPU_FPCCR_CLRONRETS_Msk |
|
||||
FPU_FPCCR_CLRONRET_Msk)) |
|
||||
((FPU_FPCCR_TS_VAL << FPU_FPCCR_TS_Pos) & FPU_FPCCR_TS_Msk) |
|
||||
((FPU_FPCCR_CLRONRETS_VAL << FPU_FPCCR_CLRONRETS_Pos) &
|
||||
FPU_FPCCR_CLRONRETS_Msk) |
|
||||
((FPU_FPCCR_CLRONRET_VAL << FPU_FPCCR_CLRONRET_Pos) &
|
||||
FPU_FPCCR_CLRONRET_Msk);
|
||||
#endif
|
||||
|
||||
#if defined(NVIC_INIT_ITNS0) && (NVIC_INIT_ITNS0 == 1U)
|
||||
NVIC->ITNS[0] = NVIC_INIT_ITNS0_VAL;
|
||||
#endif
|
||||
|
||||
#if defined(NVIC_INIT_ITNS1) && (NVIC_INIT_ITNS1 == 1U)
|
||||
NVIC->ITNS[1] = NVIC_INIT_ITNS1_VAL;
|
||||
#endif
|
||||
|
||||
#if defined(NVIC_INIT_ITNS2) && (NVIC_INIT_ITNS2 == 1U)
|
||||
NVIC->ITNS[2] = NVIC_INIT_ITNS2_VAL;
|
||||
#endif
|
||||
|
||||
#if defined(NVIC_INIT_ITNS3) && (NVIC_INIT_ITNS3 == 1U)
|
||||
NVIC->ITNS[3] = NVIC_INIT_ITNS3_VAL;
|
||||
#endif
|
||||
|
||||
#if defined(NVIC_INIT_ITNS4) && (NVIC_INIT_ITNS4 == 1U)
|
||||
NVIC->ITNS[4] = NVIC_INIT_ITNS4_VAL;
|
||||
#endif
|
||||
}
|
||||
|
||||
void trustzone_run(void) {
|
||||
uint32_t index;
|
||||
MPCBB_ConfigTypeDef MPCBB_desc;
|
||||
|
||||
/* Enable GTZC peripheral clock */
|
||||
__HAL_RCC_GTZC1_CLK_ENABLE();
|
||||
__HAL_RCC_GTZC2_CLK_ENABLE();
|
||||
|
||||
// HAL_GPIO_ConfigPinAttributes(GPIOA, 0xFFFF, GPIO_PIN_NSEC);
|
||||
// HAL_GPIO_ConfigPinAttributes(GPIOB, 0xFFFF, GPIO_PIN_NSEC);
|
||||
// HAL_GPIO_ConfigPinAttributes(GPIOC, 0xFFFF, GPIO_PIN_NSEC);
|
||||
// HAL_GPIO_ConfigPinAttributes(GPIOD, 0xFFFF, GPIO_PIN_NSEC);
|
||||
// HAL_GPIO_ConfigPinAttributes(GPIOE, 0xFFFF, GPIO_PIN_NSEC);
|
||||
// HAL_GPIO_ConfigPinAttributes(GPIOF, 0xFFFF, GPIO_PIN_NSEC);
|
||||
// HAL_GPIO_ConfigPinAttributes(GPIOG, 0xFFFF, GPIO_PIN_NSEC);
|
||||
// HAL_GPIO_ConfigPinAttributes(GPIOH, 0xFFFF, GPIO_PIN_NSEC);
|
||||
|
||||
/* -------------------------------------------------------------------------*/
|
||||
/* Memory isolation configuration */
|
||||
/* Initializes the memory that secure application books for non secure */
|
||||
/* -------------------------------------------------------------------------*/
|
||||
|
||||
/* -------------------------------------------------------------------------*/
|
||||
/* Internal RAM : */
|
||||
/* The booking is done through GTZC MPCBB. */
|
||||
/* Internal SRAMs are secured by default and configured by block */
|
||||
/* of 512 bytes. */
|
||||
/* Internal SRAM3 (starting from 0x20040000) will be configured as */
|
||||
/* fully non-secure. */
|
||||
|
||||
MPCBB_desc.SecureRWIllegalMode = GTZC_MPCBB_SRWILADIS_DISABLE;
|
||||
MPCBB_desc.InvertSecureState = GTZC_MPCBB_INVSECSTATE_NOT_INVERTED;
|
||||
MPCBB_desc.AttributeConfig.MPCBB_LockConfig_array[0] =
|
||||
0x00000000U; /* Unlocked configuration */
|
||||
|
||||
for (index = 0; index < 52; index++) {
|
||||
/* Non-secure blocks */
|
||||
MPCBB_desc.AttributeConfig.MPCBB_SecConfig_array[index] = 0x00000000U;
|
||||
MPCBB_desc.AttributeConfig.MPCBB_PrivConfig_array[index] = 0x00000000U;
|
||||
}
|
||||
|
||||
if (HAL_GTZC_MPCBB_ConfigMem(SRAM1_BASE, &MPCBB_desc) != HAL_OK) {
|
||||
/* Initialization Error */
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
||||
if (HAL_GTZC_MPCBB_ConfigMem(SRAM2_BASE, &MPCBB_desc) != HAL_OK) {
|
||||
/* Initialization Error */
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
||||
if (HAL_GTZC_MPCBB_ConfigMem(SRAM3_BASE, &MPCBB_desc) != HAL_OK) {
|
||||
/* Initialization Error */
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
||||
if (HAL_GTZC_MPCBB_ConfigMem(SRAM4_BASE, &MPCBB_desc) != HAL_OK) {
|
||||
/* Initialization Error */
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
||||
if (HAL_GTZC_MPCBB_ConfigMem(SRAM5_BASE, &MPCBB_desc) != HAL_OK) {
|
||||
/* Initialization Error */
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------*/
|
||||
/* Internal Flash */
|
||||
/* The booking is done in both IDAU/SAU and FLASH interface */
|
||||
|
||||
/* Setup done based on Flash dual-bank mode described with 1 area per bank */
|
||||
/* Non-secure Flash memory area starting from 0x08100000 (Bank2) */
|
||||
/* Flash memory is secured by default and modified with Option Byte Loading */
|
||||
/* Insure SECWM2_PSTRT > SECWM2_PEND in order to have all Bank2 non-secure */
|
||||
|
||||
/* -------------------------------------------------------------------------*/
|
||||
/* External OctoSPI memory */
|
||||
/* The booking is done in both IDAU/SAU and GTZC MPCWM interface */
|
||||
|
||||
/* Default secure configuration */
|
||||
/* Else need to use HAL_GTZC_TZSC_MPCWM_ConfigMemAttributes() */
|
||||
|
||||
/* -------------------------------------------------------------------------*/
|
||||
/* External NOR/FMC memory */
|
||||
/* The booking is done in both IDAU/SAU and GTZC MPCWM interface */
|
||||
|
||||
/* Default secure configuration */
|
||||
/* Else need to use HAL_GTZC_TZSC_MPCWM_ConfigMemAttributes() */
|
||||
|
||||
/* -------------------------------------------------------------------------*/
|
||||
/* External NAND/FMC memory */
|
||||
/* The booking is done in both IDAU/SAU and GTZC MPCWM interface */
|
||||
|
||||
/* Default secure configuration */
|
||||
/* Else need to use HAL_GTZC_TZSC_MPCWM_ConfigMemAttributes() */
|
||||
|
||||
/* -------------------------------------------------------------------------*/
|
||||
/* Peripheral isolation configuration */
|
||||
/* Initializes the peripherals and features that secure application books */
|
||||
/* for secure (RCC, PWR, RTC, EXTI, DMA, OTFDEC, etc..) or leave them to */
|
||||
/* non-secure (GPIO (secured by default)) */
|
||||
/* -------------------------------------------------------------------------*/
|
||||
|
||||
// /* Clear all illegal access flags in GTZC TZIC */
|
||||
// if(HAL_GTZC_TZIC_ClearFlag(GTZC_PERIPH_ALL) != HAL_OK)
|
||||
// {
|
||||
// /* Initialization Error */
|
||||
// while(1);
|
||||
// }
|
||||
//
|
||||
// /* Enable all illegal access interrupts in GTZC TZIC */
|
||||
// if(HAL_GTZC_TZIC_EnableIT(GTZC_PERIPH_ALL) != HAL_OK)
|
||||
// {
|
||||
// /* Initialization Error */
|
||||
// while(1);
|
||||
// }
|
||||
//
|
||||
// /* Enable GTZC secure interrupt */
|
||||
// HAL_NVIC_SetPriority(GTZC_IRQn, 0, 0); /* Highest priority level */
|
||||
// HAL_NVIC_EnableIRQ(GTZC_IRQn);
|
||||
}
|
||||
#endif
|
@ -0,0 +1 @@
|
||||
../stm32f4/usb.c
|
@ -0,0 +1 @@
|
||||
../stm32f4/usb_hid-impl.h
|
@ -0,0 +1 @@
|
||||
../stm32f4/usb_vcp-impl.h
|
@ -0,0 +1 @@
|
||||
../stm32f4/usb_webusb-impl.h
|
@ -0,0 +1 @@
|
||||
../stm32f4/usbd_conf.c
|
@ -0,0 +1 @@
|
||||
../stm32f4/usbd_conf.h
|
@ -0,0 +1 @@
|
||||
../stm32f4/usbd_core.c
|
@ -0,0 +1 @@
|
||||
../stm32f4/usbd_core.h
|
@ -0,0 +1 @@
|
||||
../stm32f4/usbd_ctlreq.c
|
@ -0,0 +1 @@
|
||||
../stm32f4/usbd_ctlreq.h
|
@ -0,0 +1 @@
|
||||
../stm32f4/usbd_def.h
|
@ -0,0 +1 @@
|
||||
../stm32f4/usbd_ioreq.c
|
@ -0,0 +1 @@
|
||||
../stm32f4/usbd_ioreq.h
|
@ -0,0 +1,177 @@
|
||||
.syntax unified
|
||||
|
||||
.text
|
||||
|
||||
.global memset_reg
|
||||
.type memset_reg, STT_FUNC
|
||||
memset_reg:
|
||||
// call with the following (note that the arguments are not validated prior to use):
|
||||
// r0 - address of first word to write (inclusive)
|
||||
// r1 - address of first word following the address in r0 to NOT write (exclusive)
|
||||
// r2 - word value to be written
|
||||
// both addresses in r0 and r1 needs to be divisible by 4!
|
||||
.L_loop_begin:
|
||||
str r2, [r0], 4 // store the word in r2 to the address in r0, post-indexed
|
||||
cmp r0, r1
|
||||
bne .L_loop_begin
|
||||
bx lr
|
||||
|
||||
// Jump to address given in first argument R0 that points to next's stage's VTOR
|
||||
// Clear memory and all registers before jump
|
||||
.global jump_to
|
||||
.type jump_to, STT_FUNC
|
||||
jump_to:
|
||||
ldr r1, =0
|
||||
bl jump_to_with_flag
|
||||
|
||||
// Jump to address given in first argument R0 that points to next's stage's VTOR
|
||||
// Clear memory and all registers before jump. Second argument R1 is copied to R11
|
||||
// and kept after jump.
|
||||
.global jump_to_with_flag
|
||||
.type jump_to_with_flag, STT_FUNC
|
||||
jump_to_with_flag:
|
||||
mov r4, r0 // save input argument r0 (the address of the next stage's vector table) (r4 is callee save)
|
||||
mov r11, r1 // save second argument in "flag" register because we'll be cleaning RAM
|
||||
// this subroutine re-points the exception handlers before the C code
|
||||
// that comprises them has been given a good environment to run.
|
||||
// therefore, this code needs to disable interrupts before the VTOR
|
||||
// update. then, the reset_handler of the next stage needs to re-enable interrupts.
|
||||
// the following prevents activation of all exceptions except Non-Maskable Interrupt (NMI).
|
||||
// according to "ARM Cortex-M Programming Guide to Memory Barrier Instructions" Application Note 321, section 4.8:
|
||||
// "there is no requirement to insert memory barrier instructions after CPSID".
|
||||
cpsid f
|
||||
// wipe memory at the end of the current stage of code
|
||||
ldr r2, =0 // r2 - the word-sized value to be written
|
||||
ldr r0, =sram1_start // r0 - point to beginning of SRAM
|
||||
ldr r1, =_stay_in_bootloader_flag_addr // r1 - point to byte after the end of SRAM
|
||||
bl memset_reg
|
||||
ldr r0, =sram2_start // r0 - point to beginning of SRAM
|
||||
ldr r1, =sram2_end // r1 - point to byte after the end of SRAM
|
||||
bl memset_reg
|
||||
ldr r0, =sram4_start // r0 - point to beginning of SRAM
|
||||
ldr r1, =sram4_end // r1 - point to byte after the end of SRAM
|
||||
bl memset_reg
|
||||
|
||||
mov lr, r4
|
||||
// clear out the general purpose registers before the next stage's except the register with flag R11
|
||||
ldr r0, =0
|
||||
mov r1, r0
|
||||
mov r2, r0
|
||||
mov r3, r0
|
||||
mov r4, r0
|
||||
mov r5, r0
|
||||
mov r6, r0
|
||||
mov r7, r0
|
||||
mov r8, r0
|
||||
mov r9, r0
|
||||
mov r10, r0
|
||||
mov r12, r0
|
||||
// give the next stage a fresh main stack pointer
|
||||
ldr r0, [lr] // set r0 to the main stack pointer in the next stage's vector table
|
||||
msr msp, r0 // give the next stage its main stack pointer
|
||||
// point to the next stage's exception handlers
|
||||
// AN321, section 4.11: "a memory barrier is not required after a VTOR update"
|
||||
.set SCB_VTOR, 0xE000ED08 // reference "Cortex-M4 Devices Generic User Guide" section 4.3
|
||||
ldr r0, =SCB_VTOR
|
||||
str lr, [r0]
|
||||
mov r0, r1 // zero out r0
|
||||
// go on to the next stage
|
||||
ldr lr, [lr, 4] // set lr to the next stage's reset_handler
|
||||
bx lr
|
||||
|
||||
.global jump_to_unprivileged
|
||||
.type jump_to_unprivileged, STT_FUNC
|
||||
jump_to_unprivileged:
|
||||
mov r4, r0 // save input argument r0 (the address of the next stage's vector table) (r4 is callee save)
|
||||
// this subroutine re-points the exception handlers before the C code
|
||||
// that comprises them has been given a good environment to run.
|
||||
// therefore, this code needs to disable interrupts before the VTOR
|
||||
// update. then, the reset_handler of the next stage needs to re-enable interrupts.
|
||||
// the following prevents activation of all exceptions except Non-Maskable Interrupt (NMI).
|
||||
// according to "ARM Cortex-M Programming Guide to Memory Barrier Instructions" Application Note 321, section 4.8:
|
||||
// "there is no requirement to insert memory barrier instructions after CPSID".
|
||||
cpsid f
|
||||
// wipe memory at the end of the current stage of code
|
||||
ldr r2, =0 // r2 - the word-sized value to be written
|
||||
ldr r0, =sram1_start // r0 - point to beginning of SRAM
|
||||
ldr r1, =sram1_end // r1 - point to byte after the end of SRAM
|
||||
bl memset_reg
|
||||
ldr r0, =sram2_start // r0 - point to beginning of SRAM
|
||||
ldr r1, =sram2_end // r1 - point to byte after the end of SRAM
|
||||
bl memset_reg
|
||||
ldr r0, =sram4_start // r0 - point to beginning of SRAM
|
||||
ldr r1, =sram4_end // r1 - point to byte after the end of SRAM
|
||||
bl memset_reg
|
||||
// r2 - the word-sized value to be written
|
||||
bl memset_reg
|
||||
mov lr, r4
|
||||
// clear out the general purpose registers before the next stage's code can run (even the NMI exception handler)
|
||||
ldr r0, =0
|
||||
mov r1, r0
|
||||
mov r2, r0
|
||||
mov r3, r0
|
||||
mov r4, r0
|
||||
mov r5, r0
|
||||
mov r6, r0
|
||||
mov r7, r0
|
||||
mov r8, r0
|
||||
mov r9, r0
|
||||
mov r10, r0
|
||||
mov r11, r0
|
||||
mov r12, r0
|
||||
// give the next stage a fresh main stack pointer
|
||||
ldr r0, [lr] // set r0 to the main stack pointer in the next stage's vector table
|
||||
msr msp, r0 // give the next stage its main stack pointer
|
||||
// point to the next stage's exception handlers
|
||||
// AN321, section 4.11: "a memory barrier is not required after a VTOR update"
|
||||
.set SCB_VTOR, 0xE000ED08 // reference "Cortex-M4 Devices Generic User Guide" section 4.3
|
||||
ldr r0, =SCB_VTOR
|
||||
str lr, [r0]
|
||||
mov r0, r1 // zero out r0
|
||||
// go on to the next stage
|
||||
ldr lr, [lr, 4] // set lr to the next stage's reset_handler
|
||||
// switch to unprivileged mode
|
||||
ldr r0, =1
|
||||
msr control, r0
|
||||
isb
|
||||
// jump
|
||||
bx lr
|
||||
|
||||
.global shutdown_privileged
|
||||
.type shutdown_privileged, STT_FUNC
|
||||
// The function must be called from the privileged mode
|
||||
shutdown_privileged:
|
||||
cpsid f // disable all exceptions (except for NMI), the instruction is ignored in unprivileged mode
|
||||
// if the exceptions weren't disabled, an exception handler (for example systick handler)
|
||||
// could be called after the memory is erased, which would lead to another exception
|
||||
ldr r0, =0
|
||||
mov r1, r0
|
||||
mov r2, r0
|
||||
mov r3, r0
|
||||
mov r4, r0
|
||||
mov r5, r0
|
||||
mov r6, r0
|
||||
mov r7, r0
|
||||
mov r8, r0
|
||||
mov r9, r0
|
||||
mov r10, r0
|
||||
mov r11, r0
|
||||
mov r12, r0
|
||||
ldr lr, =0xffffffff
|
||||
|
||||
ldr r0, =sram1_start // r0 - point to beginning of SRAM
|
||||
ldr r1, =sram1_end // r1 - point to byte after the end of SRAM
|
||||
bl memset_reg
|
||||
ldr r0, =sram2_start // r0 - point to beginning of SRAM
|
||||
ldr r1, =sram2_end // r1 - point to byte after the end of SRAM
|
||||
bl memset_reg
|
||||
ldr r0, =sram4_start // r0 - point to beginning of SRAM
|
||||
ldr r1, =sram4_end // r1 - point to byte after the end of SRAM
|
||||
bl memset_reg
|
||||
|
||||
ldr r0, =1
|
||||
msr control, r0 // jump to unprivileged mode
|
||||
ldr r0, =0
|
||||
b . // loop forever
|
||||
|
||||
.end
|
@ -0,0 +1,177 @@
|
||||
.syntax unified
|
||||
|
||||
.text
|
||||
|
||||
.global default_handler
|
||||
.type default_handler, STT_FUNC
|
||||
default_handler:
|
||||
b shutdown_privileged
|
||||
|
||||
.macro add_handler symbol_name:req
|
||||
.word \symbol_name
|
||||
.weak \symbol_name
|
||||
.thumb_set \symbol_name, default_handler
|
||||
.endm
|
||||
|
||||
// Reference:
|
||||
// Table 62 - STM32F427 Reference manual (RM0090)
|
||||
// Section B1.5 - ARMv7-M Architecture Reference Manual
|
||||
.section .vector_table, "a"
|
||||
vector_table:
|
||||
.word main_stack_base // defined in linker script
|
||||
add_handler reset_handler
|
||||
add_handler NMI_Handler
|
||||
add_handler HardFault_Handler
|
||||
add_handler MemManage_Handler
|
||||
add_handler BusFault_Handler
|
||||
add_handler UsageFault_Handler
|
||||
add_handler SecureFault_Handler
|
||||
add_handler architecture_reserved_handler
|
||||
add_handler architecture_reserved_handler
|
||||
add_handler architecture_reserved_handler
|
||||
add_handler SVC_Handler
|
||||
add_handler DebugMon_Handler
|
||||
add_handler architecture_reserved_handler
|
||||
add_handler PendSV_Handler
|
||||
add_handler SysTick_Handler
|
||||
add_handler WWDG_IRQHandler
|
||||
add_handler PVD_PVM_IRQHandler
|
||||
add_handler RTC_IRQHandler
|
||||
add_handler RTC_S_IRQHandler
|
||||
add_handler TAMP_IRQHandler
|
||||
add_handler RAMCFG_IRQHandler
|
||||
add_handler FLASH_IRQHandler
|
||||
add_handler FLASH_S_IRQHandler
|
||||
add_handler GTZC_IRQHandler
|
||||
add_handler RCC_IRQHandler
|
||||
add_handler RCC_S_IRQHandler
|
||||
add_handler EXTI0_IRQHandler
|
||||
add_handler EXTI1_IRQHandler
|
||||
add_handler EXTI2_IRQHandler
|
||||
add_handler EXTI3_IRQHandler
|
||||
add_handler EXTI4_IRQHandler
|
||||
add_handler EXTI5_IRQHandler
|
||||
add_handler EXTI6_IRQHandler
|
||||
add_handler EXTI7_IRQHandler
|
||||
add_handler EXTI8_IRQHandler
|
||||
add_handler EXTI9_IRQHandler
|
||||
add_handler EXTI10_IRQHandler
|
||||
add_handler EXTI11_IRQHandler
|
||||
add_handler EXTI12_IRQHandler
|
||||
add_handler EXTI13_IRQHandler
|
||||
add_handler EXTI14_IRQHandler
|
||||
add_handler EXTI15_IRQHandler
|
||||
add_handler IWDG_IRQHandler
|
||||
add_handler SAES_IRQHandler
|
||||
add_handler GPDMA1_Channel0_IRQHandler
|
||||
add_handler GPDMA1_Channel1_IRQHandler
|
||||
add_handler GPDMA1_Channel2_IRQHandler
|
||||
add_handler GPDMA1_Channel3_IRQHandler
|
||||
add_handler GPDMA1_Channel4_IRQHandler
|
||||
add_handler GPDMA1_Channel5_IRQHandler
|
||||
add_handler GPDMA1_Channel6_IRQHandler
|
||||
add_handler GPDMA1_Channel7_IRQHandler
|
||||
add_handler ADC1_2_IRQHandler
|
||||
add_handler DAC1_IRQHandler
|
||||
add_handler FDCAN1_IT0_IRQHandler
|
||||
add_handler FDCAN1_IT1_IRQHandler
|
||||
add_handler TIM1_BRK_IRQHandler
|
||||
add_handler TIM1_UP_IRQHandler
|
||||
add_handler TIM1_TRG_COM_IRQHandler
|
||||
add_handler TIM1_CC_IRQHandler
|
||||
add_handler TIM2_IRQHandler
|
||||
add_handler TIM3_IRQHandler
|
||||
add_handler TIM4_IRQHandler
|
||||
add_handler TIM5_IRQHandler
|
||||
add_handler TIM6_IRQHandler
|
||||
add_handler TIM7_IRQHandler
|
||||
add_handler TIM8_BRK_IRQHandler
|
||||
add_handler TIM8_UP_IRQHandler
|
||||
add_handler TIM8_TRG_COM_IRQHandler
|
||||
add_handler TIM8_CC_IRQHandler
|
||||
add_handler I2C1_EV_IRQHandler
|
||||
add_handler I2C1_ER_IRQHandler
|
||||
add_handler I2C2_EV_IRQHandler
|
||||
add_handler I2C2_ER_IRQHandler
|
||||
add_handler SPI1_IRQHandler
|
||||
add_handler SPI2_IRQHandler
|
||||
add_handler USART1_IRQHandler
|
||||
add_handler USART2_IRQHandler
|
||||
add_handler USART3_IRQHandler
|
||||
add_handler UART4_IRQHandler
|
||||
add_handler UART5_IRQHandler
|
||||
add_handler LPUART1_IRQHandler
|
||||
add_handler LPTIM1_IRQHandler
|
||||
add_handler LPTIM2_IRQHandler
|
||||
add_handler TIM15_IRQHandler
|
||||
add_handler TIM16_IRQHandler
|
||||
add_handler TIM17_IRQHandler
|
||||
add_handler COMP_IRQHandler
|
||||
add_handler OTG_HS_IRQHandler
|
||||
add_handler CRS_IRQHandler
|
||||
add_handler FMC_IRQHandler
|
||||
add_handler OCTOSPI1_IRQHandler
|
||||
add_handler PWR_S3WU_IRQHandler
|
||||
add_handler SDMMC1_IRQHandler
|
||||
add_handler SDMMC2_IRQHandler
|
||||
add_handler GPDMA1_Channel8_IRQHandler
|
||||
add_handler GPDMA1_Channel9_IRQHandler
|
||||
add_handler GPDMA1_Channel10_IRQHandler
|
||||
add_handler GPDMA1_Channel11_IRQHandler
|
||||
add_handler GPDMA1_Channel12_IRQHandler
|
||||
add_handler GPDMA1_Channel13_IRQHandler
|
||||
add_handler GPDMA1_Channel14_IRQHandler
|
||||
add_handler GPDMA1_Channel15_IRQHandler
|
||||
add_handler I2C3_EV_IRQHandler
|
||||
add_handler I2C3_ER_IRQHandler
|
||||
add_handler SAI1_IRQHandler
|
||||
add_handler SAI2_IRQHandler
|
||||
add_handler TSC_IRQHandler
|
||||
add_handler AES_IRQHandler
|
||||
add_handler RNG_IRQHandler
|
||||
add_handler FPU_IRQHandler
|
||||
add_handler HASH_IRQHandler
|
||||
add_handler PKA_IRQHandler
|
||||
add_handler LPTIM3_IRQHandler
|
||||
add_handler SPI3_IRQHandler
|
||||
add_handler I2C4_ER_IRQHandler
|
||||
add_handler I2C4_EV_IRQHandler
|
||||
add_handler MDF1_FLT0_IRQHandler
|
||||
add_handler MDF1_FLT1_IRQHandler
|
||||
add_handler MDF1_FLT2_IRQHandler
|
||||
add_handler MDF1_FLT3_IRQHandler
|
||||
add_handler UCPD1_IRQHandler
|
||||
add_handler ICACHE_IRQHandler
|
||||
add_handler OTFDEC1_IRQHandler
|
||||
add_handler OTFDEC2_IRQHandler
|
||||
add_handler LPTIM4_IRQHandler
|
||||
add_handler DCACHE1_IRQHandler
|
||||
add_handler ADF1_IRQHandler
|
||||
add_handler ADC4_IRQHandler
|
||||
add_handler LPDMA1_Channel0_IRQHandler
|
||||
add_handler LPDMA1_Channel1_IRQHandler
|
||||
add_handler LPDMA1_Channel2_IRQHandler
|
||||
add_handler LPDMA1_Channel3_IRQHandler
|
||||
add_handler DMA2D_IRQHandler
|
||||
add_handler DCMI_PSSI_IRQHandler
|
||||
add_handler OCTOSPI2_IRQHandler
|
||||
add_handler MDF1_FLT4_IRQHandler
|
||||
add_handler MDF1_FLT5_IRQHandler
|
||||
add_handler CORDIC_IRQHandler
|
||||
add_handler FMAC_IRQHandler
|
||||
add_handler LSECSSD_IRQHandler
|
||||
add_handler USART6_IRQHandler
|
||||
add_handler I2C5_ER_IRQHandler
|
||||
add_handler I2C5_EV_IRQHandler
|
||||
add_handler I2C6_ER_IRQHandler
|
||||
add_handler I2C6_EV_IRQHandler
|
||||
add_handler HSPI1_IRQHandler
|
||||
add_handler GPU2D_IRQHandler
|
||||
add_handler GPU2D_ER_IRQHandler
|
||||
add_handler GFXMMU_IRQHandler
|
||||
add_handler LTDC_IRQHandler
|
||||
add_handler LTDC_ER_IRQHandler
|
||||
add_handler DSI_IRQHandler
|
||||
add_handler DCACHE2_IRQHandler
|
||||
|
||||
.end
|
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* This file is part of the Trezor project, https://trezor.io/
|
||||
*
|
||||
* Copyright (c) SatoshiLabs
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TREZOR_HAL_TAMPER_H
|
||||
#define TREZOR_HAL_TAMPER_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// Tamper module enables the internal tamper detection on STM32 microcontroller
|
||||
// as well as external tamper input if it's available on the device
|
||||
|
||||
// Initializes the tamper detection
|
||||
void tamper_init(void);
|
||||
|
||||
// Triggers one of internal tampers.
|
||||
// The function is intended for experimentation with internal tamper mechanism
|
||||
// Use TAMP_CR1_xxx constants to as a parameter
|
||||
// Only TAMP_CR1_ITAMP5E (RTC) and TAMP_CR1_ITAMP8E (monotonic counter)
|
||||
// are supported
|
||||
void tamper_test(uint32_t tamper_type);
|
||||
|
||||
#endif // TREZOR_HAL_TAMPER_H
|
@ -0,0 +1,574 @@
|
||||
#ifndef __TREZORHAL_TRUSTZONE__
|
||||
#define __TREZORHAL_TRUSTZONE__
|
||||
|
||||
#ifdef BOARDLOADER
|
||||
#define CMSE_NS_CALL __attribute((cmse_nonsecure_call))
|
||||
#define CMSE_NS_ENTRY __attribute((cmse_nonsecure_entry))
|
||||
|
||||
typedef void CMSE_NS_CALL (*funcptr)(void);
|
||||
|
||||
/* typedef for non-secure callback functions */
|
||||
typedef funcptr funcptr_NS;
|
||||
|
||||
#include STM32_HAL_H
|
||||
|
||||
/*
|
||||
//-------- <<< Use Configuration Wizard in Context Menu >>> -----------------
|
||||
*/
|
||||
|
||||
/*
|
||||
// <e>Initialize Security Attribution Unit (SAU) CTRL register
|
||||
*/
|
||||
#define SAU_INIT_CTRL 1
|
||||
|
||||
/*
|
||||
// <q> Enable SAU
|
||||
// <i> Value for SAU->CTRL register bit ENABLE
|
||||
*/
|
||||
#define SAU_INIT_CTRL_ENABLE 0
|
||||
|
||||
/*
|
||||
// <o> When SAU is disabled
|
||||
// <0=> All Memory is Secure
|
||||
// <1=> All Memory is Non-Secure
|
||||
// <i> Value for SAU->CTRL register bit ALLNS
|
||||
// <i> When all Memory is Non-Secure (ALLNS is 1), IDAU can override memory
|
||||
map configuration.
|
||||
*/
|
||||
#define SAU_INIT_CTRL_ALLNS 1
|
||||
|
||||
/*
|
||||
// </e>
|
||||
*/
|
||||
|
||||
/*
|
||||
// <h>Initialize Security Attribution Unit (SAU) Address Regions
|
||||
// <i>SAU configuration specifies regions to be one of:
|
||||
// <i> - Secure and Non-Secure Callable
|
||||
// <i> - Non-Secure
|
||||
// <i>Note: All memory regions not configured by SAU are Secure
|
||||
*/
|
||||
#define SAU_REGIONS_MAX 8 /* Max. number of SAU regions */
|
||||
|
||||
/*
|
||||
// <e>Initialize SAU Region 0
|
||||
// <i> Setup SAU Region 0 memory attributes
|
||||
*/
|
||||
#define SAU_INIT_REGION0 0
|
||||
|
||||
/*
|
||||
// <o>Start Address <0-0xFFFFFFE0>
|
||||
*/
|
||||
#define SAU_INIT_START0 0x0C1FE000 /* start address of SAU region 0 */
|
||||
|
||||
/*
|
||||
// <o>End Address <0x1F-0xFFFFFFFF>
|
||||
*/
|
||||
#define SAU_INIT_END0 0x0C1FFFFF /* end address of SAU region 0 */
|
||||
|
||||
/*
|
||||
// <o>Region is
|
||||
// <0=>Non-Secure
|
||||
// <1=>Secure, Non-Secure Callable
|
||||
*/
|
||||
#define SAU_INIT_NSC0 1
|
||||
/*
|
||||
// </e>
|
||||
*/
|
||||
|
||||
/*
|
||||
// <e>Initialize SAU Region 1
|
||||
// <i> Setup SAU Region 1 memory attributes
|
||||
*/
|
||||
#define SAU_INIT_REGION1 0
|
||||
|
||||
/*
|
||||
// <o>Start Address <0-0xFFFFFFE0>
|
||||
*/
|
||||
#define SAU_INIT_START1 0x08200000 /* start address of SAU region 1 */
|
||||
|
||||
/*
|
||||
// <o>End Address <0x1F-0xFFFFFFFF>
|
||||
*/
|
||||
#define SAU_INIT_END1 0x083FFFFF /* end address of SAU region 1 */
|
||||
|
||||
/*
|
||||
// <o>Region is
|
||||
// <0=>Non-Secure
|
||||
// <1=>Secure, Non-Secure Callable
|
||||
*/
|
||||
#define SAU_INIT_NSC1 0
|
||||
/*
|
||||
// </e>
|
||||
*/
|
||||
|
||||
/*
|
||||
// <e>Initialize SAU Region 2
|
||||
// <i> Setup SAU Region 2 memory attributes
|
||||
*/
|
||||
#define SAU_INIT_REGION2 0
|
||||
|
||||
/*
|
||||
// <o>Start Address <0-0xFFFFFFE0>
|
||||
*/
|
||||
#define SAU_INIT_START2 0x200D0000 /* start address of SAU region 2 */
|
||||
|
||||
/*
|
||||
// <o>End Address <0x1F-0xFFFFFFFF>
|
||||
*/
|
||||
#define SAU_INIT_END2 0x2026FFFF /* end address of SAU region 2 */
|
||||
|
||||
/*
|
||||
// <o>Region is
|
||||
// <0=>Non-Secure
|
||||
// <1=>Secure, Non-Secure Callable
|
||||
*/
|
||||
#define SAU_INIT_NSC2 0
|
||||
/*
|
||||
// </e>
|
||||
*/
|
||||
|
||||
/*
|
||||
// <e>Initialize SAU Region 3
|
||||
// <i> Setup SAU Region 3 memory attributes
|
||||
*/
|
||||
#define SAU_INIT_REGION3 0
|
||||
|
||||
/*
|
||||
// <o>Start Address <0-0xFFFFFFE0>
|
||||
*/
|
||||
#define SAU_INIT_START3 0x40000000 /* start address of SAU region 3 */
|
||||
|
||||
/*
|
||||
// <o>End Address <0x1F-0xFFFFFFFF>
|
||||
*/
|
||||
#define SAU_INIT_END3 0x4FFFFFFF /* end address of SAU region 3 */
|
||||
|
||||
/*
|
||||
// <o>Region is
|
||||
// <0=>Non-Secure
|
||||
// <1=>Secure, Non-Secure Callable
|
||||
*/
|
||||
#define SAU_INIT_NSC3 0
|
||||
/*
|
||||
// </e>
|
||||
*/
|
||||
|
||||
/*
|
||||
// <e>Initialize SAU Region 4
|
||||
// <i> Setup SAU Region 4 memory attributes
|
||||
*/
|
||||
#define SAU_INIT_REGION4 0
|
||||
|
||||
/*
|
||||
// <o>Start Address <0-0xFFFFFFE0>
|
||||
*/
|
||||
#define SAU_INIT_START4 0x60000000 /* start address of SAU region 4 */
|
||||
|
||||
/*
|
||||
// <o>End Address <0x1F-0xFFFFFFFF>
|
||||
*/
|
||||
#define SAU_INIT_END4 0xAFFFFFFF /* end address of SAU region 4 */
|
||||
|
||||
/*
|
||||
// <o>Region is
|
||||
// <0=>Non-Secure
|
||||
// <1=>Secure, Non-Secure Callable
|
||||
*/
|
||||
#define SAU_INIT_NSC4 0
|
||||
/*
|
||||
// </e>
|
||||
*/
|
||||
|
||||
/*
|
||||
// <e>Initialize SAU Region 5
|
||||
// <i> Setup SAU Region 5 memory attributes
|
||||
*/
|
||||
#define SAU_INIT_REGION5 0
|
||||
|
||||
/*
|
||||
// <o>Start Address <0-0xFFFFFFE0>
|
||||
*/
|
||||
#define SAU_INIT_START5 0x0BF90000 /* start address of SAU region 5 */
|
||||
|
||||
/*
|
||||
// <o>End Address <0x1F-0xFFFFFFFF>
|
||||
*/
|
||||
#define SAU_INIT_END5 0x0BFA8FFF /* end address of SAU region 5 */
|
||||
|
||||
/*
|
||||
// <o>Region is
|
||||
// <0=>Non-Secure
|
||||
// <1=>Secure, Non-Secure Callable
|
||||
*/
|
||||
#define SAU_INIT_NSC5 0
|
||||
/*
|
||||
// </e>
|
||||
*/
|
||||
|
||||
/*
|
||||
// <e>Initialize SAU Region 6
|
||||
// <i> Setup SAU Region 6 memory attributes
|
||||
*/
|
||||
#define SAU_INIT_REGION6 0
|
||||
|
||||
/*
|
||||
// <o>Start Address <0-0xFFFFFFE0>
|
||||
*/
|
||||
#define SAU_INIT_START6 0x00000000 /* start address of SAU region 6 */
|
||||
|
||||
/*
|
||||
// <o>End Address <0x1F-0xFFFFFFFF>
|
||||
*/
|
||||
#define SAU_INIT_END6 0x00000000 /* end address of SAU region 6 */
|
||||
|
||||
/*
|
||||
// <o>Region is
|
||||
// <0=>Non-Secure
|
||||
// <1=>Secure, Non-Secure Callable
|
||||
*/
|
||||
#define SAU_INIT_NSC6 0
|
||||
/*
|
||||
// </e>
|
||||
*/
|
||||
|
||||
/*
|
||||
// <e>Initialize SAU Region 7
|
||||
// <i> Setup SAU Region 7 memory attributes
|
||||
*/
|
||||
#define SAU_INIT_REGION7 0
|
||||
|
||||
/*
|
||||
// <o>Start Address <0-0xFFFFFFE0>
|
||||
*/
|
||||
#define SAU_INIT_START7 0x00000000 /* start address of SAU region 7 */
|
||||
|
||||
/*
|
||||
// <o>End Address <0x1F-0xFFFFFFFF>
|
||||
*/
|
||||
#define SAU_INIT_END7 0x00000000 /* end address of SAU region 7 */
|
||||
|
||||
/*
|
||||
// <o>Region is
|
||||
// <0=>Non-Secure
|
||||
// <1=>Secure, Non-Secure Callable
|
||||
*/
|
||||
#define SAU_INIT_NSC7 0
|
||||
/*
|
||||
// </e>
|
||||
*/
|
||||
|
||||
/*
|
||||
// </h>
|
||||
*/
|
||||
|
||||
/*
|
||||
// <e>Setup behaviour of Sleep and Exception Handling
|
||||
*/
|
||||
#define SCB_CSR_AIRCR_INIT 0
|
||||
|
||||
/*
|
||||
// <o> Deep Sleep can be enabled by
|
||||
// <0=>Secure and Non-Secure state
|
||||
// <1=>Secure state only
|
||||
// <i> Value for SCB->CSR register bit DEEPSLEEPS
|
||||
*/
|
||||
#define SCB_CSR_DEEPSLEEPS_VAL 0
|
||||
|
||||
/*
|
||||
// <o>System reset request accessible from
|
||||
// <0=> Secure and Non-Secure state
|
||||
// <1=> Secure state only
|
||||
// <i> Value for SCB->AIRCR register bit SYSRESETREQS
|
||||
*/
|
||||
#define SCB_AIRCR_SYSRESETREQS_VAL 0
|
||||
|
||||
/*
|
||||
// <o>Priority of Non-Secure exceptions is
|
||||
// <0=> Not altered
|
||||
// <1=> Lowered to 0x04-0x07
|
||||
// <i> Value for SCB->AIRCR register bit PRIS
|
||||
*/
|
||||
#define SCB_AIRCR_PRIS_VAL 0
|
||||
|
||||
/*
|
||||
// <o>BusFault, HardFault, and NMI target
|
||||
// <0=> Secure state
|
||||
// <1=> Non-Secure state
|
||||
// <i> Value for SCB->AIRCR register bit BFHFNMINS
|
||||
*/
|
||||
#define SCB_AIRCR_BFHFNMINS_VAL 0
|
||||
|
||||
/*
|
||||
// </e>
|
||||
*/
|
||||
|
||||
/*
|
||||
// <e>Setup behaviour of Floating Point Unit
|
||||
*/
|
||||
#define TZ_FPU_NS_USAGE 1
|
||||
|
||||
/*
|
||||
// <o>Floating Point Unit usage
|
||||
// <0=> Secure state only
|
||||
// <3=> Secure and Non-Secure state
|
||||
// <i> Value for SCB->NSACR register bits CP10, CP11
|
||||
*/
|
||||
#define SCB_NSACR_CP10_11_VAL 3
|
||||
|
||||
/*
|
||||
// <o>Treat floating-point registers as Secure
|
||||
// <0=> Disabled
|
||||
// <1=> Enabled
|
||||
// <i> Value for FPU->FPCCR register bit TS
|
||||
*/
|
||||
#define FPU_FPCCR_TS_VAL 0
|
||||
|
||||
/*
|
||||
// <o>Clear on return (CLRONRET) accessibility
|
||||
// <0=> Secure and Non-Secure state
|
||||
// <1=> Secure state only
|
||||
// <i> Value for FPU->FPCCR register bit CLRONRETS
|
||||
*/
|
||||
#define FPU_FPCCR_CLRONRETS_VAL 0
|
||||
|
||||
/*
|
||||
// <o>Clear floating-point caller saved registers on exception return
|
||||
// <0=> Disabled
|
||||
// <1=> Enabled
|
||||
// <i> Value for FPU->FPCCR register bit CLRONRET
|
||||
*/
|
||||
#define FPU_FPCCR_CLRONRET_VAL 1
|
||||
|
||||
/*
|
||||
// </e>
|
||||
*/
|
||||
|
||||
/*
|
||||
// <h>Setup Interrupt Target
|
||||
*/
|
||||
|
||||
/*
|
||||
// <e>Initialize ITNS 0 (Interrupts 0..31)
|
||||
*/
|
||||
#define NVIC_INIT_ITNS0 1
|
||||
|
||||
/*
|
||||
// Interrupts 0..31
|
||||
// <o.0> WWDG_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.1> PVD_PVM_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.2> RTC_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.3> RTC_S_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.4> TAMP_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.5> RAMCFG_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.6> FLASH_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.7> FLASH_S_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.8> GTZC_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.9> RCC_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.10> RCC_S_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.11> EXTI0_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.12> EXTI1_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.13> EXTI2_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.14> EXTI3_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.15> EXTI4_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.16> EXTI5_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.17> EXTI6_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.18> EXTI7_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.19> EXTI8_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.20> EXTI9_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.21> EXTI10_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.22> EXTI11_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.23> EXTI12_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.24> EXTI13_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.25> EXTI14_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.26> EXTI15_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.27> IWDG_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.29> GPDMA1_Channel0_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.30> GPDMA1_Channel1_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.31> GPDMA1_Channel2_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
*/
|
||||
#define NVIC_INIT_ITNS0_VAL 0x00000000
|
||||
|
||||
/*
|
||||
// </e>
|
||||
*/
|
||||
|
||||
/*
|
||||
// <e>Initialize ITNS 1 (Interrupts 32..63)
|
||||
*/
|
||||
#define NVIC_INIT_ITNS1 1
|
||||
|
||||
/*
|
||||
// Interrupts 32..63
|
||||
// <o.0> GPDMA1_Channel3_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.1> GPDMA1_Channel4_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.2> GPDMA1_Channel5_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.3> GPDMA1_Channel6_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.4> GPDMA1_Channel7_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.5> ADC1_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.6> DAC1_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.7> FDCAN1_IT0_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.8> FDCAN1_IT1_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.9> TIM1_BRK_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.10> TIM1_UP_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.11> TIM1_TRG_COM_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.12> TIM1_CC_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.13> TIM2_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.14> TIM3_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.15> TIM4_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.16> TIM5_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.17> TIM6_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.18> TIM7_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.19> TIM8_BRK_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.20> TIM8_UP_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.21> TIM8_TRG_COM_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.22> TIM8_CC_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.23> I2C1_EV_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.24> I2C1_ER_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.25> I2C2_EV_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.26> I2C2_ER_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.27> SPI1_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.28> SPI2_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.29> USART1_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.30> USART2_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.31> USART3_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
*/
|
||||
#define NVIC_INIT_ITNS1_VAL 0x00000000
|
||||
|
||||
/*
|
||||
// </e>
|
||||
*/
|
||||
|
||||
/*
|
||||
// <e>Initialize ITNS 2 (Interrupts 64..95)
|
||||
*/
|
||||
#define NVIC_INIT_ITNS2 1
|
||||
|
||||
/*
|
||||
// Interrupts 64..95
|
||||
// <o.0> UART4_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.1> UART5_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.2> LPUART1_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.3> LPTIM1_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.4> LPTIM2_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.5> TIM15_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.6> TIM16_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.7> TIM17_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.8> COMP_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.9> OTG_HS_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.10> CRS_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.11> FMC_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.12> OCTOSPI1_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.13> PWR_S3WU_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.14> SDMMC1_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.15> SDMMC2_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.16> GPDMA1_Channel8_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.17> GPDMA1_Channel9_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.18> GPDMA1_Channel10_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.19> GPDMA1_Channel11_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.20> GPDMA1_Channel12_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.21> GPDMA1_Channel13_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.22> GPDMA1_Channel14_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.23> GPDMA1_Channel15_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.24> I2C3_EV_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.25> I2C3_ER_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.26> SAI1_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.27> SAI2_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.28> TSC_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.30> RNG_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.31> FPU_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
*/
|
||||
#define NVIC_INIT_ITNS2_VAL 0x00000000
|
||||
|
||||
/*
|
||||
// </e>
|
||||
*/
|
||||
|
||||
/*
|
||||
// <e>Initialize ITNS 3 (Interrupts 96..127)
|
||||
*/
|
||||
#define NVIC_INIT_ITNS3 1
|
||||
|
||||
/*
|
||||
// Interrupts 96..127
|
||||
// <o.0> HASH_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.2> LPTIM3_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.3> SPI3_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.4> I2C4_ER_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.5> I2C4_EV_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.6> MDF1_FLT0_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.7> MDF1_FLT1_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.8> MDF1_FLT2_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.9> MDF1_FLT3_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.10> UCPD1_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.11> ICACHE_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.14> LPTIM4_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.15> DCACHE1_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.16> ADF1_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.17> ADC4_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.18> LPDMA1_Channel0_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.19> LPDMA1_Channel1_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.20> LPDMA1_Channel2_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.21> LPDMA1_Channel3_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.22> DMA2D_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.23> DCMI_PSSI_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.24> OCTOSPI2_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.25> MDF1_FLT4_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.26> MDF1_FLT5_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.27> CORDIC_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.28> FMAC_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.30> USART6_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.31> I2C5_ER_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
*/
|
||||
#define NVIC_INIT_ITNS3_VAL 0x00000000
|
||||
|
||||
/*
|
||||
// </e>
|
||||
*/
|
||||
|
||||
/*
|
||||
// <e>Initialize ITNS 4 (Interrupts 109..138)
|
||||
*/
|
||||
#define NVIC_INIT_ITNS4 1
|
||||
|
||||
/*
|
||||
// Interrupts 96..138
|
||||
// <o.0> I2C5_EV_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.1> I2C6_ER_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.2> I2C6_EV_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.3> HSPI1_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.4> GPU2D_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.5> GPU2D_ER_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.6> GFXMMU_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.7> LTDC_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.8> LTDC_ER_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.9> DSI_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
// <o.10> DCACHE2_IRQn <0=> Secure state <1=> Non-Secure state
|
||||
*/
|
||||
#define NVIC_INIT_ITNS4_VAL 0x00000000
|
||||
|
||||
/*
|
||||
// </e>
|
||||
*/
|
||||
|
||||
/*
|
||||
// </h>
|
||||
*/
|
||||
|
||||
/*
|
||||
max 8 SAU regions.
|
||||
SAU regions are defined in partition.h
|
||||
*/
|
||||
|
||||
#define SAU_INIT_REGION(n) \
|
||||
SAU->RNR = (n & SAU_RNR_REGION_Msk); \
|
||||
SAU->RBAR = (SAU_INIT_START##n & SAU_RBAR_BADDR_Msk); \
|
||||
SAU->RLAR = (SAU_INIT_END##n & SAU_RLAR_LADDR_Msk) | \
|
||||
((SAU_INIT_NSC##n << SAU_RLAR_NSC_Pos) & SAU_RLAR_NSC_Msk) | 1U
|
||||
|
||||
extern void trustzone_init(void);
|
||||
|
||||
extern void trustzone_run(void);
|
||||
|
||||
#endif
|
||||
#endif
|
@ -1,4 +1,5 @@
|
||||
|
||||
#define SENSITIVE
|
||||
#define FLASH_BYTE_ACCESS 1
|
||||
|
||||
void emulator_poll_events(void);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue