From a6854266dbba16d662967eeff73faa9d1b6ffaa5 Mon Sep 17 00:00:00 2001 From: graham sanderson Date: Wed, 4 Jun 2025 17:29:16 -0500 Subject: [PATCH 1/8] hardening of enc_bootloader --- bintool/bintool.cpp | 4 +- enc_bootloader/CMakeLists.txt | 37 +- enc_bootloader/aes.S | 854 ++++++++++++++++------ enc_bootloader/config.h | 15 + enc_bootloader/enc_bootloader.c | 338 +++++++-- enc_bootloader/enc_bootloader.elf | Bin 21544 -> 37008 bytes enc_bootloader/enc_bootloader_mbedtls.elf | Bin 29876 -> 115964 bytes enc_bootloader/hard_entry_point.S | 200 +++++ enc_bootloader/hard_entry_point.h | 23 + enc_bootloader/memmap_enc_bootloader.ld | 39 +- main.cpp | 10 +- 11 files changed, 1227 insertions(+), 293 deletions(-) create mode 100644 enc_bootloader/hard_entry_point.S create mode 100644 enc_bootloader/hard_entry_point.h diff --git a/bintool/bintool.cpp b/bintool/bintool.cpp index 5cf73180..8d5cb225 100644 --- a/bintool/bintool.cpp +++ b/bintool/bintool.cpp @@ -201,7 +201,7 @@ void set_block_ignored(elf_file *elf, uint32_t block_addr) { uint32_t offset = block_addr + 4 - seg->physical_address(); if ((content[offset] & 0x7f) != PICOBIN_BLOCK_ITEM_PARTITION_TABLE) { DEBUG_LOG("setting block at %08x to ignored\n", block_addr); - content[offset] = 0x7e; + content[offset] = 0x7e; } elf->content(*seg, content); } @@ -233,7 +233,7 @@ void set_block_ignored(std::vector &bin, uint32_t storage_addr, uint32_ uint32_t offset = block_addr + 4 - storage_addr; if ((bin[offset] & 0x7f) != PICOBIN_BLOCK_ITEM_PARTITION_TABLE) { DEBUG_LOG("setting block at %08x to ignored\n", block_addr); - bin[offset] = 0x7e; + bin[offset] = 0x7e; } } diff --git a/enc_bootloader/CMakeLists.txt b/enc_bootloader/CMakeLists.txt index 45f3cc16..cdc747f5 100644 --- a/enc_bootloader/CMakeLists.txt +++ b/enc_bootloader/CMakeLists.txt @@ -46,6 +46,10 @@ if (NOT USE_PRECOMPILED) target_compile_definitions(enc_bootloader PRIVATE PICO_STACK_SIZE=0x800 + # we cannot unreset clk_peri clocked h/w as we don't configure clk_peri + PICO_RUNTIME_SKIP_INIT_POST_CLOCK_RESETS=1 + RC_COUNT=0 # don't use rcp_count + # 0x20080000 -> 0x20081000 doesn't overlap the stack ROM_CHAIN_WORKSPACE=0x20080000) @@ -53,7 +57,7 @@ if (NOT USE_PRECOMPILED) pico_set_linker_script(enc_bootloader ${CMAKE_CURRENT_LIST_DIR}/memmap_mbedtls.ld) else() - target_sources(enc_bootloader PRIVATE aes.S) + target_sources(enc_bootloader PRIVATE aes.S hard_entry_point.S) target_compile_definitions(enc_bootloader PRIVATE PICO_STACK_SIZE=0x180 @@ -61,25 +65,44 @@ if (NOT USE_PRECOMPILED) ROM_CHAIN_WORKSPACE=0x20080200) pico_set_linker_script(enc_bootloader ${CMAKE_CURRENT_LIST_DIR}/memmap_enc_bootloader.ld) + + target_compile_definitions(enc_bootloader PRIVATE + # The following are to reduce the size of the binary + PICO_NO_PROGRAM_INFO=1 + PICO_CRT0_NO_RESET_SECTION=1 + + HARDENING=1 + DOUBLE_HARDENING=1 + + INLINE_REF_ROUNDKEY_SHARES_S=1 # avoid need for canaries/calling check + INLINE_REF_ROUNDKEY_HVPERMS_S=1 # avoid need for canaries/calling check + INLINE_SHIFT_ROWS_S=1 # avoid need for canaries/calling check + INLINE_MAP_SBOX_S=1 # avoid need for canaries/calling check + + CALLER_INIT_RCP_COUNT=1 + ) endif() target_compile_definitions(enc_bootloader PRIVATE + #ALLOW_DEBUGGING=1 + + # The following are to reduce the size of the binary # use stack guards, as AES variables are written near the stack PICO_USE_STACK_GUARDS=1 - # The following are to reduce the size of the binary - PICO_NO_PROGRAM_INFO=1 # No spinlocks used PICO_USE_SW_SPIN_LOCKS=0 # No heap is used PICO_HEAP_SIZE=0 - # These inits are not required - PICO_RUNTIME_SKIP_INIT_SPIN_LOCKS_RESET=1 - PICO_RUNTIME_SKIP_INIT_PER_CORE_IRQ_PRIORITIES=1 + # Note all runtime init is skipped via the linker script + PICO_BOOTROM_LOCKING_ENABLED=0 # Don't need any vtor irqs PICO_MINIMAL_STORED_VECTOR_TABLE=1 PICO_NO_RAM_VECTOR_TABLE=1 - ) + + PICO_USE_GPIO_COPROCESSOR=0 + FIB_WORKAROUND=1 + ) # print memory usage target_link_options(enc_bootloader PUBLIC -Wl,--print-memory-usage) diff --git a/enc_bootloader/aes.S b/enc_bootloader/aes.S index e3ef4644..fb23a21e 100644 --- a/enc_bootloader/aes.S +++ b/enc_bootloader/aes.S @@ -22,6 +22,16 @@ scratch RAM and the stack pointer is overwritten. #include "hardware/regs/trng.h" #include "hardware/rcp.h" +#if HARDENING +@ Number of calls to gen_rand_sha[_nonpres] +#define RND_COUNT_decrypt 394 // From decrypt up to call to ctr_crypt_s +#define RND_COUNT_ctr_crypt_s_init (17 + 32 * CT_BPERM) // Init phase of ctr_crypt_s +#define RND_COUNT_ctr_crypt_mainloop_A (4 + ST_VPERM + ST_SHAREC) +#define RND_COUNT_refreshchaff_and_lfsr 2 +#define RND_COUNT_remap 2 +#define RND_COUNT_decryption_end 3 +#endif + .global decrypt .global chaff @@ -39,19 +49,70 @@ scratch RAM and the stack pointer is overwritten. #define CTAG7 0x32 #define CTAG8 0x33 #define CTAG9 0x34 -#define CTAG10 0x35 @ not used -#define CTAG11 0x36 @ not used +#define CTAG10 0x35 +#define CTAG11 0x36 #define CTAG12 0x37 #define CTAG13 0x38 #define CTAG14 0x39 #define CTAG15 0x3a #define CTAG16 0x3b #define CTAG17 0x3c -#define CTAG18 0x3d @ not used +#define CTAG18 0x3d +#define CTAG19 0x3e +#define CTAG20 0x3f +#define CTAG21 0x29 @ number of blocks from the TRNG processed to initialise rstate_sha #define TRNG_BLOCKS 25 +@ if GEN_RAND_SHA==0 then we don't call the counting version +#if HARDENING && GEN_RAND_SHA +.macro check_rnd_count count +.if !(\count & 0xffffff00) +movs r1, #\count +.else +ldr r1, =\count +.endif +movs r0, #(\count & 1) ^ 1 +bl check_rnd_count_func +rcp_iequal_nodelay r1, r0 +#if DOUBLE_HARDENING +rcp_iequal_nodelay r0, r1 +#endif +.endm + +@ r1 has the expected count +@ Trashes r0 +.macro check_rnd_count_dynamic +mov r0, sp +bl check_rnd_count_func +rcp_iequal_nodelay r1, r0 +#if DOUBLE_HARDENING +rcp_iequal_nodelay r0, r1 +#endif +.endm + +.macro reset_rnd_count +bl reset_rnd_count_func +.endm + +.macro reset_rnd_count_checked +@ This version verifies that the count was actually reset +uxtb r0, r1 +bl reset_rnd_count_func +ldr r0, [r0] +bics r1, #0xff00ff +rcp_iequal_nodelay r1, r0 +.endm + +#else +.macro check_rnd_count count +.endm +.macro reset_rnd_count +.endm +.macro reset_rnd_count_checked +.endm +#endif @ The lower jitterpriorty is, the more the jitter .macro SET_COUNT n,jitterpriority .if RC_COUNT @@ -119,11 +180,12 @@ scratch RAM and the stack pointer is overwritten. workspace_start: @ chaff has to be at the start of scratch_y = 0x20081000 because this is assumed by the following macro, getchaffaddress -@ (It seems ADR does not work, nor is it possible to assert that chaff==0x20081000) -@ getchaffaddress is used by clear03 and clear01 and other sensitive cases which require the first load to be a random one -@ chaff has to be 0 mod 16 for other reasons +@ We need to set the chaff address directly with MOVs, rather than setting it with a load as normal, because at the point +@ the macro is called we have just done a load of a sensitive value at a known memory offset mod 16, and the idea is that +@ the next load is going to be of a random number (in the "chaff" memory) at that same offset mod 16, so we can't afford +@ to do a ldr \rx, =0x20081000 + \offset first, as this will load a non-random value from an uncontrolled memory location mod 16. +@ Ideally we'd avoid the magic number 0x2008100 by using, ADR \rx, chaff+\offset, but the linker does not support this. .macro getchaffaddress rx,offset=0 -@ ldr \rx,=(chaff+\offset) mov \rx,#(0x1000+\offset) movt \rx,#0x2008 .endm @@ -158,7 +220,7 @@ statevperm: @ 12 mod 16 .space 4 @ vperm state rotation: only last two bits are operational; other bits random RKshareC: @ Round key common share C; see comment at init_key_4way for explanation .space 4 -RKshareCchange: @ Temporary used by ref_roundkey_share_s +RKshareCchange: @ Temporary used by ref_roundkey_shares_s .space 4 IV0: @ 2-way share of IV for block 0 .space 36 @ Considering IV0 as a word pointer, the format is IV = IV0[0,1,2,3] ^ (IV0[5,6,7,8],ror#16) @@ -216,6 +278,8 @@ jstate: @ 32-bit jitter state rstate_lfsr: @ 32-bit LFSR random state and constant used to step it .space 4 .word 0x1d872b41 @ constant that defines a maximal-length LFSR +rstate_count: +.space 4 rstate_all_end: @ Mark end of RNG data to allow selective memory wipe .if CT_BPERM @@ -248,6 +312,9 @@ init_rstate: movw r1,#SHA256_CSR_RESET|SHA256_CSR_START_BITS @ initialise SHA internal state by writing START bit str r1,[r5,#SHA256_CSR_OFFSET] str r6,[r4,#TRNG_SAMPLE_CNT1_OFFSET -TRNG_RNG_IMR_OFFSET] +#if HARDENING + movs r3, #0 +#endif movs r6,#TRNG_BLOCKS*2+1 @ odd so that we break out of the loop half-way through loading the SHA hardware, giving @ time for previous SHA computation to complete 2: @@ -256,9 +323,8 @@ init_rstate: str r1,[r4,#TRNG_RND_SOURCE_ENABLE_OFFSET -TRNG_RNG_IMR_OFFSET] @ start ROSC if it is not already started str r1,[r4,#TRNG_RNG_ICR_OFFSET -TRNG_RNG_IMR_OFFSET] @ clear all interrupts (including EHR_VLD) adds r0,r4,#TRNG_EHR_DATA0_OFFSET -TRNG_RNG_IMR_OFFSET - movs r2,#TRNG_TRNG_BUSY_OFFSET -TRNG_RNG_IMR_OFFSET 1: - ldr r1,[r4,r2] @ wait for 192 ROSC samples to fill EHR,should take constant time + ldr r1,[r4,#TRNG_TRNG_BUSY_OFFSET -TRNG_RNG_IMR_OFFSET] @ wait for 192 ROSC samples to fill EHR,should take constant time cmp r1,#0 bne 1b subs r6,#1 @ done? @@ -267,13 +333,31 @@ init_rstate: 1: ldmia r0!,{r2} @ copy 6 EHR words to SHA-256, plus garbage (RND_SOURCE_ENABLE and SAMPLE_CNT1) str r2,[r5,#SHA256_WDATA_OFFSET] @ for a total of half a SHA-256 block +#if HARDENING + adds r3,#1 +#endif subs r1,#1 bne 1b +#if HARDENING + ldr r1, =TRNG_BASE+TRNG_EHR_DATA0_OFFSET+32 + rcp_iequal_nodelay r0, r1 +#endif ldr r2,[r5,#SHA256_SUM0_OFFSET] @ TRNG is now sampling again; use some SHA bits to modulate the chain length str r2,[r4,#TRNG_TRNG_CONFIG_OFFSET -TRNG_RNG_IMR_OFFSET] b.n 2b 3: +#if HARDENING + movs r2, #(TRNG_BLOCKS*2) * 8 + rcp_iequal_nodelay r2, r3 +#endif +#if HARDENING +@ good test that we are dealing with real hardware + ldr r2,[r5,#SHA256_CSR_OFFSET] + movw r1,#SHA256_CSR_RESET + rcp_iequal_nodelay r1, r2 + rcp_iequal_nodelay r2, r1 +#endif CHK_COUNT 25,6 str r1,[r4,#TRNG_TRNG_CONFIG_OFFSET -TRNG_RNG_IMR_OFFSET] @ turn off rand source and wipe SHA bits left in TRNG config; r1=0 str r1,[r4,#TRNG_RND_SOURCE_ENABLE_OFFSET -TRNG_RNG_IMR_OFFSET] @@ -285,7 +369,11 @@ init_rstate: stmia r6,{r0-r3} CHK_COUNT 26,6 movs r0,#0 +#if !HARDENING strb r0,[r6] @ make sure rstate_sha[0] has byte 0 set to 0, representing "out of data" +#else + str r0,[r6] @ make sure rstate_sha[0] has word 0 set to 0, representing "out of data" (24-31) and 0 numbers generated (0-23) +#endif @ try to find a non-zero initialiser to create a non-degenerate LFSR random state ldr r1,[r5,#16] @ SHA SUM4 @@ -295,7 +383,7 @@ init_rstate: mov r1,r6 @ give up and use the address of rstate_sha (which is non-zero); this can't really happen (2^{-64} probability) 1: str r1,[r6,#rstate_lfsr-rstate_sha] - + @ try to find a non-zero initialiser to create a non-degenerate ROSC random state ldr r1,[r5,#24] @ SHA SUM6 cbnz r1,1f @ is word 6 non-zero? then use it @@ -306,7 +394,15 @@ init_rstate: ldr r2,=ROSC_RANDOM_OFFSET+ROSC_BASE str r1,[r2,#0] @ Initialise ROSC LFSR CHK_COUNT 27,6 - +#if HARDENING + ldr r3,=ROSC_RANDOM_OFFSET+ROSC_BASE + cbnz r1, 1f + rcp_panic +1: + ldr r3, [r3] + rcp_iequal_nodelay r1, r3 +#endif + .if GEN_RAND_SHA .if SH_JITTER movs r2,#0 @@ -317,9 +413,102 @@ init_rstate: CHK_COUNT 28,6 bx r14 +.thumb_func +decrypt: +@ r0=4-way key, r1=IV_shareA, r2=IV_shareB, r3=message buffer, [sp]=number of blocks + ldr r12,[sp] @ Pop 5th argument in r12 (which we are allowed to treat as scratch according to AAPCS) + push {r14} + GET_CANARY r14,CTAG3,6 +#if !CALLER_INIT_RCP_COUNT + SET_COUNT 23,6 +#endif + push {r4-r11,r14} + push {r0-r3,r12} @ Save the five arguments + bl reset_sha_trng + bl init_rstate +@ randomly re-share the LUT contents + ldr r4,=lut_a + mov r5,#64 @ 64 words = 256 bytes +1: + bl gen_rand_sha_nonpres + ldr r6,[r4,#lut_b-lut_a] @ EOR a random word into both shares + eors r6,r6,r0 +@if r0 is not EORed into only one share, then the LUT won't be right + str r6,[r4,#lut_b-lut_a] + ldr r6,[r4] +#if HARDENING + eors r7,r6,r0 + eors r8,r7,r6 + rcp_iequal_nodelay r8, r0 + stmia r4!,{r7} +#else + eors r6,r6,r0 + stmia r4!,{r6} +#endif + subs r5,r5,#1 + bne 1b +#if HARDENING + ldr r5,=lut_a + 256 + rcp_iequal_nodelay r4, r5 +#endif + CHK_COUNT 29,6 +#if HARDENING +@check again as this is quite important + rcp_iequal_nodelay r5, r4 +#endif + bl remap @ scramble the LUTs + pop {r0} @ pointer to 4way key data + bl init_key_4way + // todo alex this may trash r12; is that ok? + bl lock_key + CHK_COUNT 32,6 + pop {r0-r3} @ r0=IV_shareA, r1=IV_shareB, r2=message, r3=num blocks + bl ctr_crypt_s + bl randomisechaff + clear03 + pop {r4-r11,r14} + CHK_CANARY r14,CTAG3,6 + pop {r15} + +.thumb_func +reset_sha_trng: + GET_CANARY r0,CTAG19,0 + ldr r1,=RESETS_BASE+RESETS_RESET_OFFSET + ldr r2,[r1] + ldr r3,=#RESETS_RESET_SHA256_BITS|RESETS_RESET_TRNG_BITS + orrs r2,r2,r3 + str r2,[r1] @ reset the SHA hardware and the TRNG hardware + CHK_COUNT 23,6 + bics r2,r2,r3 + str r2,[r1] @ release the reset + CHK_CANARY r0,CTAG19,0 + bx r14 + @ Put AES core code in first scratch area .section .scratch_x.aes,"ax",%progbits +@ if GEN_RAND_SHA==0 then we don't call the counting version +#if HARDENING && GEN_RAND_SHA +check_rnd_count_func: +@ NOTE: we don't bother with a canary here as we don't write anything + ldr r0,=rstate_sha + ldr r0, [r0] + rsbs r0,r0,#0 @ Negate bottom 24 bits to get the number of calls to gen_rand_sha[_nonpres] since the last reset + bfc r0,#24,#8 @ + bx r14 + +reset_rnd_count_func: + push {lr} + GET_CANARY lr,CTAG11,0 + ldr r0,=rstate_sha + ldrb r1, [r0, #3] + orrs r1, #1 + lsls r1, #24 + str r1, [r0] + CHK_CANARY lr,CTAG11,0 + pop {pc} +#endif + .if GEN_RAND_SHA @ we need SHA256_SUM0_OFFSET==8 (see note below) .if SHA256_SUM0_OFFSET!=8 @@ -330,74 +519,119 @@ init_rstate: @ Preserves r1-r13 .balign 4 gen_rand_sha: - push {r14} - GET_CANARY r14,CTAG1,2 - push {r1-r3,r14} + push {r1-r3,lr} + GET_CANARY r1,CTAG1,2 + push {r1} .if SH_JITTER ldr r2,=rstate_sha ldr r0,[r2,#jstate-rstate_sha] + lsls r3,r0,#30 + lsrs r3,#28 movs r1,#1 - ands r3,r0,#3 - movs r3,r3,lsl#2 - movs r3,r1,lsl r3 @ 1<<(4*(r0&3)) + lsls r3,r1,r3 @ 1<<(4*(r0&3)) udiv r3,r3,r1 @ Takes constant + (r0&3) cycles lsrs r0,r0,#2 bne 1f bl gen_rand_sha_nonpres ldr r2,=rstate_sha +#if HARDENING + ldr r1,[r2] @ Make this (SH_JITTER) not affect rnd_count + adds r1,r1,#1 @ (compensating for call to gen_rand_sha_nonpres which decrements the count by 1) + str r1,[r2] @ The purpose is to simplify check_rnd_count calls, and to avoid having to reset jstate frequently +#endif 1: str r0,[r2,#jstate-rstate_sha] .endif bl gen_rand_sha_nonpres - pop {r1-r3,r14} - CHK_CANARY r14,CTAG1,0 - pop {r15} + pop {r1} + CHK_CANARY r1,CTAG1,0 + pop {r1-r3,pc} @ Return single random word in r0 @ Trashes r1-r3 .balign 4 gen_rand_sha_nonpres: - ldr r0,=SHA256_BASE + push {lr} + GET_CANARY lr,CTAG18,0 ldr r2,=rstate_sha +#if !HARDENING + ldr r3,=SHA256_BASE ldrb r1,[r2] @ get word counter from bottom byte of rstate_sha[] (offset into SUM registers) - subs r3,r1,#4 @ decrement it to previous SUM register + subs r0,r1,#4 @ decrement it to previous SUM register ble 1f @ if the offset was 4 or less we have run out of SUM register values - ldr r0,[r0,r1] @ read value from SUM register: note that this relies on SHA256_SUM0_OFFSET==8 - strb r3,[r2] @ save updated SUM register offset in bottom byte of rstate_sha[] - bx r14 + strb r0,[r2] @ save updated SUM register offset in bottom byte of rstate_sha[] + ldr r0,[r3,r1] @ read value from SUM register: note that this relies on SHA256_SUM0_OFFSET==8 +#else + ldr r3,=SHA256_BASE + ldr r1,[r2] @ get word counter (8) : rand counter (24) from first word of rstate_sha[] (offset into SUM registers) + lsls r0, r1, #1 @ clear C (also set N which may force us down BLE path on skip of the sub below) + sbcs r0,r1,#0x04000000 @ decrement word counter for previous SUM register (and decrement rand counter due to C == 0) + str r0,[r2] @ save updated worder counter / rand_counter in bottom word of rstate_sha[] + asrs r1, r0, #24 + ble 1f @ if the offset was 4 or less we have run out of SUM register values + + ldr r2,=SHA256_BASE + 4 + adds r2, r1 + adds r1, r3, r0, asr #24 + ldr r0, [r2], #-4 + rcp_iequal_nodelay r1, r2 +#endif + b gen_rand_sha_nonpres_exit 1: @ [CK_JITTER code was here] - movs r3,#SHA256_SUM6_OFFSET+1 - strb r3,[r2] @ reset word counter: the +1 is compensated for later + movs r0,#SHA256_SUM6_OFFSET+1 +#if !HARDENING + strb r0,[r2] @ reset word counter: the +1 is compensated for later +#else + strb r0,[r2,#3] @ reset word counter: the +1 is compensated for later +#endif movw r1,#(1<>30, vpermB=Bptr[4]>>30, and @ roundkey shareA(i) = Aptr[i+vpermA mod 4] ror ((i+vpermA mod 4)^th byte of Aptr[4]) @ roundkey shareB(i) = Bptr[i+vpermB mod 4] ror ((i+vpermB mod 4)^th byte of Bptr[4])+16 -.balign 4 -.thumb_func -ref_roundkey_shares_s: - mov r11,#15 @ there are 15 expanded keys -ref_roundkey_shares_s_test: @ entry point for test code to do fewer than 15 rounds + +.macro ref_roundkey_shares_s_impl ldr r4,=rkey_s loadlfsr - steplfsr @ r0=change in RKshareC + steplfsr_check @ r0=change in RKshareC ldr r2,=RKshareCchange str r0,[r2] ldr r3,=RKshareC @@ -723,7 +918,7 @@ ref_roundkey_shares_s_loop: steplfsr; eors r5,r5,r0; ands r9,r9,#3; ldr r3,[r4,r9,lsl#2]; ror r2,r0,r12; eors r3,r3,r2,ror#16; mov r12,r12,ror#8; str r3,[r4,r9,lsl#2]; adds r9,r9,#1 steplfsr; eors r6,r6,r0; ands r9,r9,#3; ldr r3,[r4,r9,lsl#2]; ror r2,r0,r12; eors r3,r3,r2,ror#16; mov r12,r12,ror#8; str r3,[r4,r9,lsl#2]; adds r9,r9,#1 steplfsr; eors r7,r7,r0; ands r9,r9,#3; ldr r3,[r4,r9,lsl#2]; ror r2,r0,r12; eors r3,r3,r2,ror#16; mov r12,r12,ror#8; str r3,[r4,r9,lsl#2]; adds r9,r9,#1 - steplfsr; eors r8,r8,r0; ands r9,r9,#3; ldr r3,[r4,r9,lsl#2]; ror r2,r0,r12; eors r3,r3,r2,ror#16; str r3,[r4,r9,lsl#2] + steplfsr_check; eors r8,r8,r0; ands r9,r9,#3; ldr r3,[r4,r9,lsl#2]; ror r2,r0,r12; eors r3,r3,r2,ror#16; str r3,[r4,r9,lsl#2] ldr r3,=RKshareCchange ldr r3,[r3] @@ -740,63 +935,23 @@ ref_roundkey_shares_s_loop: subs r11,r11,#1 bne ref_roundkey_shares_s_loop +#if HARDENING + ldr r5,=rkey_s + 40 * 15 + rcp_iequal_nodelay r4, r5 +#endif ldr r2,=rstate_lfsr @ restore rstate_lfsr savelfsr @ Save lfsr_state clear03 24 -ref_roundkey_shares_s_exit: - bx r14 - -.balign 4 -.thumb_func -@ Rotates roundkey vperms and RK_ROR rotations by random amounts -@ Trashes r0-r10 -@ If i = word number 0..3, -@ Aptr=memory word pointer to block of 20 bytes containing H&V-rotated share A roundkey (similarly B), then -@ vpermA=Aptr[4]>>30, vpermB=Bptr[4]>>30, and -@ roundkey shareA(i) = Aptr[i+vpermA mod 4] ror ((i+vpermA mod 4)^th byte of Aptr[4]) -@ roundkey shareB(i) = Bptr[i+vpermB mod 4] ror ((i+vpermB mod 4)^th byte of Bptr[4])+16 -ref_roundkey_hvperms_s: - movs r7,#30 -ref_roundkey_hvperms_s_test: @ entry point for test code to do fewer than 30 key shares - GET_CANARY r10,CTAG9,6 - push {r10,r14} - ldr r10,=rkey_s -ref_roundkey_hvperms_s_loop: - bl gen_rand_lfsr_nonpres @ r0=new vperm high|rotations - ldmia r10,{r2-r5,r9} @ r2-r5=roundkey share A/B, r9=old vperm high|rotations - str r0,[r10,#16] - mov r8,r0,lsr#30 @ r8=new vperm low - sub r6,r8,r9,lsr#30 @ r6=(new vperm low)-(old vperm low) | junk - mov r8,r6,lsl#3 @ r8=8*((new vperm low)-(old vperm low)) mod 32 - mov r0,r0,ror r8 - usub8 r0,r9,r0 @ i^th byte of r0 = (i^th byte of old rotations) - ((i+newvperm-oldvperm)^th byte of new rotations) - movs r2,r2,ror r0; ands r6,r6,#3; str r2,[r10,r6,lsl#2]; movs r0,r0,ror#8; adds r6,r6,#1 - movs r3,r3,ror r0; ands r6,r6,#3; str r3,[r10,r6,lsl#2]; movs r0,r0,ror#8; adds r6,r6,#1 - movs r4,r4,ror r0; ands r6,r6,#3; str r4,[r10,r6,lsl#2]; movs r0,r0,ror#8; adds r6,r6,#1 - movs r5,r5,ror r0; ands r6,r6,#3; str r5,[r10,r6,lsl#2] - adds r10,r10,#20 - subs r7,r7,#1 - bne ref_roundkey_hvperms_s_loop - clear03 28 -ref_roundkey_hvperms_s_exit: @ label exit point to be to able to specify to analysis code - pop {r10,r14} - CHK_CANARY r10,CTAG9,6 - bx r14 +.endm -.else +.else // RK_ROR @ "refresh" shares of rkeys by random eor into both shares of each word, and also randomise the single word RKshareC @ Trashes r0-r11 -.balign 4 -.thumb_func -ref_roundkey_shares_s: - mov r11,#15 @ there are 15 expanded keys -ref_roundkey_shares_s_test: @ entry point for test code to do fewer than 15 rounds - GET_CANARY r4,CTAG8,6 - push {r4,r14} +.macro ref_roundkey_shares_s_impl ldr r4,=rkey_s loadlfsr - steplfsr @ r0=change in RKshareC + steplfsr_check @ r0=change in RKshareC ldr r3,=RKshareC ldr r5,[r3] eors r5,r5,r0 @@ -815,7 +970,7 @@ ref_roundkey_shares_s_loop: steplfsr; eors r5,r5,r0; and r9,r9,#3; eors r5,r5,r10; ldr r3,[r4,r9,lsl#2]; eors r3,r3,r0,ror#16; str r3,[r4,r9,lsl#2]; adds r9,r9,#1 steplfsr; eors r6,r6,r0; and r9,r9,#3; eors r6,r6,r10; ldr r3,[r4,r9,lsl#2]; eors r3,r3,r0,ror#16; str r3,[r4,r9,lsl#2]; adds r9,r9,#1 steplfsr; eors r7,r7,r0; and r9,r9,#3; eors r7,r7,r10; ldr r3,[r4,r9,lsl#2]; eors r3,r3,r0,ror#16; str r3,[r4,r9,lsl#2]; adds r9,r9,#1 - steplfsr; eors r8,r8,r0; and r9,r9,#3; eors r8,r8,r10; ldr r3,[r4,r9,lsl#2]; eors r3,r3,r0,ror#16; str r3,[r4,r9,lsl#2] + steplfsr_check; eors r8,r8,r0; and r9,r9,#3; eors r8,r8,r10; ldr r3,[r4,r9,lsl#2]; eors r3,r3,r0,ror#16; str r3,[r4,r9,lsl#2] subs r4,r4,#20 stmia r4,{r5-r8} @@ -827,20 +982,69 @@ ref_roundkey_shares_s_loop: bne ref_roundkey_shares_s_loop savelfsr clear03 24 -ref_roundkey_shares_s_exit: - pop {r4,r14} - CHK_CANARY r4,CTAG8,6 - bx r14 +#if HARDENING + ldr r5,=rkey_s + 40 * 15 + rcp_iequal_nodelay r4, r5 +#endif +.endm +.endif +.if INLINE_REF_ROUNDKEY_SHARES_S +.macro inline_ref_roundkey_shares_s +ref_roundkey_shares_s_starts: + mov r11,#15 @ there are 15 expanded keys + ref_roundkey_shares_s_impl +ref_roundkey_shares_s_end: +.endm +.else .balign 4 .thumb_func +ref_roundkey_shares_s: + mov r11,#15 @ there are 15 expanded keys +ref_roundkey_shares_s_test: @ entry point for test code to do fewer than 15 rounds + push {lr} + GET_CANARY lr,CTAG8,6 + ref_roundkey_shares_s_impl + CHK_CANARY lr,CTAG8,6 + pop {pc} +.endif + +.if RK_ROR + +@ Rotates roundkey vperms and RK_ROR rotations by random amounts +@ Trashes r0-r10 +@ If i = word number 0..3, +@ Aptr=memory word pointer to block of 20 bytes containing H&V-rotated share A roundkey (similarly B), then +@ vpermA=Aptr[4]>>30, vpermB=Bptr[4]>>30, and +@ roundkey shareA(i) = Aptr[i+vpermA mod 4] ror ((i+vpermA mod 4)^th byte of Aptr[4]) +@ roundkey shareB(i) = Bptr[i+vpermB mod 4] ror ((i+vpermB mod 4)^th byte of Bptr[4])+16 +.macro ref_roundkey_hvperms_s_impl + ldr r10,=rkey_s +ref_roundkey_hvperms_s_loop: + bl gen_rand_lfsr_nonpres @ r0=new vperm high|rotations + ldmia r10,{r2-r5,r9} @ r2-r5=roundkey share A/B, r9=old vperm high|rotations + str r0,[r10,#16] + mov r8,r0,lsr#30 @ r8=new vperm low + sub r6,r8,r9,lsr#30 @ r6=(new vperm low)-(old vperm low) | junk + mov r8,r6,lsl#3 @ r8=8*((new vperm low)-(old vperm low)) mod 32 + mov r0,r0,ror r8 + usub8 r0,r9,r0 @ i^th byte of r0 = (i^th byte of old rotations) - ((i+newvperm-oldvperm)^th byte of new rotations) + movs r2,r2,ror r0; ands r6,r6,#3; str r2,[r10,r6,lsl#2]; movs r0,r0,ror#8; adds r6,r6,#1 + movs r3,r3,ror r0; ands r6,r6,#3; str r3,[r10,r6,lsl#2]; movs r0,r0,ror#8; adds r6,r6,#1 + movs r4,r4,ror r0; ands r6,r6,#3; str r4,[r10,r6,lsl#2]; movs r0,r0,ror#8; adds r6,r6,#1 + movs r5,r5,ror r0; ands r6,r6,#3; str r5,[r10,r6,lsl#2] + adds r10,r10,#20 + adds r7,r7,#1 + cmp r7, #30 + bne ref_roundkey_hvperms_s_loop + clear03 28 +.endm + +.else + @ Rotates roundkey vperms by random amounts @ Trashes r0-r9 -ref_roundkey_hvperms_s: - movs r7,#30 -ref_roundkey_hvperms_s_test: @ entry point for test code to do fewer than 30 key shares - GET_CANARY r0,CTAG9,6 - push {r0,r14} +.macro ref_roundkey_hvperms_s_impl bl gen_rand_lfsr_nonpres ldr r1,=rkey_s ref_roundkey_hvperms_s_loop: @@ -862,14 +1066,32 @@ ref_roundkey_hvperms_s_loop: ands r6,r6,#3; str r5,[r1,r6,lsl#2] adds r1,r1,#20 movs r0,r0,ror#2 - subs r7,r7,#1 + adds r7,r7,#1 + cmp r7, #30 bne ref_roundkey_hvperms_s_loop clear03 28 -ref_roundkey_hvperms_s_exit: @ label exit point to be to able to specify to analysis code - pop {r0,r14} - CHK_CANARY r0,CTAG9,6 - bx r14 +.endm +.endif +.if INLINE_REF_ROUNDKEY_HVPERMS_S +.macro inline_ref_roundkey_hvperms_s +ref_roundkey_hvperms_s_starts: + movs r7,#0 + ref_roundkey_hvperms_s_impl +ref_roundkey_hvperms_s_end: +.endm +.else +.balign 4 +.thumb_func +ref_roundkey_hvperms_s: + movs r7,#0 +ref_roundkey_hvperms_s_test: @ entry point for test code to do fewer than 15 rounds + GET_CANARY r0,CTAG9,6 + push {r0, lr} + ref_roundkey_hvperms_s_impl + pop {r0} + CHK_CANARY r0,CTAG9,6 + pop {pc} .endif .ltorg @@ -885,6 +1107,8 @@ ref_roundkey_hvperms_s_exit: @ label exit point to be to able to specify to ana @ r8=rorig(8+(-!r1)%4), r9=rorig(8+(1-!r1)%4), ... @ Note: only low 2 bits of !r1 are used. The rest are random to add to the noise. addstatevperm: + push {r14} + GET_CANARY r14,CTAG20,0 ldr r2,[r1] adds r2,r2,r0 str r2,[r1] @@ -916,7 +1140,8 @@ addstatevperm: stmia r1!,{r2,r3} addstatevperm_exit: @ label exit point to be to able to specify to analysis code - bx r14 + CHK_CANARY r14,CTAG20,0 + pop {pc} .endif @ Conjugate lut_a, lut_b with (state) shareC @@ -925,9 +1150,11 @@ addstatevperm_exit: @ label exit point to be to able to specify to ana @ Arbitrarily choosing a0, b1 and d0 .balign 4 conjshareC: + push {r14} + GET_CANARY r14,CTAG21,0 .if ST_SHAREC - ldr r1,=shareC - ldr r0,[r1] @ Get shareC as a word (all bytes the same) + ldr r1,=shareA + ldr r0,[r1, #shareC-shareA] @ Get shareC as a word (all bytes the same) ldr r1,=lut_a @ Need to EOR share C into inputs of both lut_a and lut_b, and one of their outputs... ldr r2,[r1,#0x100] eors r2,r2,r0,lsr#24 @@ -938,11 +1165,10 @@ conjshareC: eors r2,r2,r0,lsl#8 str r2,[r1,#0x100] .endif - bx r14 + CHK_CANARY r14,CTAG21,0 + pop {pc} -.balign 4 -.thumb_func -shift_rows_s: +.macro shift_rows_s_impl @ First "rotate" the two most-significant bytes of the state by two registers @ Trashes r0-r3 @ Slightly faster (but not shorter?) with ubfx/bfi @@ -996,7 +1222,22 @@ shift_rows_s: eors r11,r11,r1 @ state[3]^=tb; clear01 @ barrier +.endm + +.if INLINE_SHIFT_ROWS_S +.macro inline_shift_rows_s +shift_rows_s_starts: + shift_rows_s_impl +shift_rows_s_end: +.endm +.else +.balign 4 +.thumb_func +@ Not going to use canaries here as it doesn't write anything - could be use to perturb register values, but not super worried about that yet +shift_rows_s: + shift_rows_s_impl bx r14 +.endif @ multiply polynomial over GF(2⁸) by c(x) = 0x03x³ + 0x01x² + 0x01x + 0x02 modulo x⁴+1 @ r0x00 is a register holding 0x00000000; r0x1b is a register holding 0x1b1b1b1b @@ -1036,6 +1277,7 @@ shift_rows_s: .balign 4 .thumb_func +@ Not going to use canaries here as it doesn't write anything - could be use to perturb register values, but not super worried about that yet @ Trashes r0-r3,r12 mix_cols_s: mov r2,#0x00000000 @@ -1071,12 +1313,7 @@ mix_cols_s: @ map all bytes of the state through the split LUT, lut_a and lut_b @ Trashes r0-r3,r12 -.balign 4 -.thumb_func -map_sbox_s: - GET_CANARY r12,CTAG12,3 - push {r12,r14} - +.macro map_sbox_s_impl ldr r0,=shareA @ Write out state share A to memory @ stmia r0,{r4-r7} @ Used to do a STM getchaffaddress r1 @@ -1160,10 +1397,29 @@ map_sbox_s: @ steplfsr; eors r6,r6,r0; mov r12,#0; eor r10,r10,r0,ror#16 @ steplfsr; eors r7,r7,r0; mov r12,#0; eor r11,r11,r0,ror#16 @ savelfsr +.endm + +.if INLINE_MAP_SBOX_S +.macro inline_map_sbox_s +map_sbox_s_starts: + // push {lr} + map_sbox_s_impl + // pop {lr} +map_sbox_s_end: +.endm +.else +.balign 4 +.thumb_func +map_sbox_s: + GET_CANARY r12,CTAG12,3 + push {r12,r14} + + map_sbox_s_impl pop {r12,r14} CHK_CANARY r12,CTAG12,5 bx r14 +.endif .ltorg @@ -1206,16 +1462,22 @@ refreshchaff_and_lfsr: bl gen_rand_sha_nonpres ldr r1,=rstate_lfsr ldr r2,[r1] +1: adds r2,r2,r0 - beq 1f @ Don't update LFSR state to 0 +@ note that r2 should not be 0 on entry, so both +@ r2 + r0, and r2 + r0 + r0 on the next loop should not both be 0 +@ if they are, we will loop + beq 1b @ Don't update LFSR state to 0 +#if HARDENING + beq 1b +#endif str r2,[r1] -1: @ Choose a random order to update chaff words to make 2nd order attacks harder movs r0,#12 ldr r1,=permscratch bl makesmallperm - + movs r1,#11 1: push {r1} @@ -1458,24 +1720,24 @@ init_key_4way: GET_CANARY r12,CTAG17,6 push {r0-r12,r14} - + @ Transfer 4-way key into local workspace, rerandomising the shares mov r5,r0 @ r5=4-way key input bl randomisechaff ldr r6,=rkey4way movs r7,#8 - b 1f -2: - adds r5,#64 @ Skip 64 byte gap for FIB workaround - subs r7,r7,#1 1: +#if FIB_WORKAROUND + cmp r7,#4 + bne 2f + adds r5,#64 @ Skip 64 byte gap for FIB workaround +2: +#endif ldmia r5!,{r1-r4} bl gen_rand_sha; eors r1,r1,r0; eors r4,r4,r0 bl gen_rand_sha; eors r2,r2,r0; eors r4,r4,r0 bl gen_rand_sha; eors r3,r3,r0; eors r4,r4,r0 stmia r6!,{r1-r4} - cmp r7,#5 - beq 2b subs r7,r7,#1 bne 1b @@ -1554,6 +1816,7 @@ init_key_expandloop: cmp r2,#52 bne init_key_expandloop + CHK_COUNT 30,6 pop {r0-r12,r14} CHK_CANARY r12,CTAG17,6 bx r14 @@ -1596,7 +1859,7 @@ addrkey_s: clear03_preserve_r3 add r12,r12,#20 @ r0=chaff+16, r3=statevperm, r4-r11=state, r12=roundkeyBptr - + bfi r0,r12,#0,#4 @ match chaff pointer (r0) to roundkey ptr (r12) mod 16 ldr r1,[r12,#16] @ r1=vperm key rotation in top two bits ldr r2,[r0,#16] @ barrier load @@ -1605,7 +1868,7 @@ addrkey_s: bfi r0,r3,#0,#4 ldr r3,[r3] ldr r0,[r0] @ barrier load - + @ Read shareB of roundkey, offset by vpermkeyrot-vpermstaterot, and eor it into shareB of state, offset by -vpermstaterot @ r1=rkeyBrotdata, r2=vpermkeyrot-vpermstaterot, r3=RKshareC, r4-r11=state, r12=roundkeyB ptr .if RK_ROR @@ -1643,8 +1906,10 @@ ctr_crypt_s: push {r0-r12,r14} @ save all registers so that when we restore we overwrite any secrets push {r0-r3} - - SET_COUNT 93,6 + +#if !CALLER_INIT_RCP_COUNT + SET_COUNT 33,6 +#endif .if CT_BPERM @ Initialise 32 random numbers (which fit in half-words) @@ -1674,10 +1939,25 @@ ctr_crypt_s: bl gen_rand_sha_nonpres; eors r6,r6,r0; movs r1,#0; mov r10,r10,ror#16; eor r10,r10,r0,ror#16 bl gen_rand_sha_nonpres; eors r7,r7,r0; movs r1,#0; mov r11,r11,ror#16; eor r11,r11,r0,ror#16 ldr r0,=IV0 - stmia r0,{r4-r7} - adds r0,r0,#20 - stmia r0,{r8-r11} + stmia r0!,{r4-r7} + adds r1,r0,#4 + stmia r1,{r8-r11} @ "Decommission" IV0 so that it doesn't get stacked +#if 1 // approved by Alex - no side channel leakage it seems +#if HARDENING + // if this is skipped, r4 is likely random, so more 1 in 4 chance that ldmia will trap + // in any case very unlikely to load useful data below (and presuambly the faulting address is uninteresting + // since it is already XORed with random data above) + movs r0, #32 + // note if r1 is unset, then we are reading from lut_a + movs r1, #0 + ldmia r1!, {r4, r5, r6, r7, r8, r9, r10, r11} + rcp_iequal_nodelay r0, r1 +#else + movs r0, #0 + ldmia r0, {r4, r5, r6, r7, r8, r9, r10, r11} +#endif +#else bl gen_rand_sha_nonpres; movs r4,r0 bl gen_rand_sha_nonpres; movs r5,r0 bl gen_rand_sha_nonpres; movs r6,r0 @@ -1686,11 +1966,14 @@ ctr_crypt_s: bl gen_rand_sha_nonpres; mov r9,r0 bl gen_rand_sha_nonpres; mov r10,r0 bl gen_rand_sha_nonpres; mov r11,r0 +#endif +@ Trashes r0, r1 + check_rnd_count (RND_COUNT_decrypt+RND_COUNT_ctr_crypt_s_init) pop {r1,r2} @ r1=cipher/plaintext buffer, r2=number of blocks movs r3,#0 - CHK_COUNT 93,6 + CHK_COUNT 33,6 ctr_crypt_mainloop: SET_COUNT 80,6 @@ -1700,31 +1983,98 @@ ctr_crypt_mainloop: push {r1-r3} @ It's OK for execution time to depend on the block counter r3 ("public"), but not the block number (secret) +@ Trashes r0, r1 + reset_rnd_count_checked + + // no point in having a branch if we should never take it (hardening/size fail) +#if REFCHAFF_PERIOD != 1 tst r3,#(REFCHAFF_PERIOD-1) bne 1f +#endif bl refreshchaff_and_lfsr 1: - - ldr r3,[r13,#8] @ get block count off the stack + ldr r3,[sp,#8] @ get block count off the stack + // no point in having a branch if we should never take it (hardening/size fail) +#if REMAP_PERIOD != 1 tst r3,#(REMAP_PERIOD-1) bne 1f +#endif bl remap @ shuffle the LUTs; this preserves R3 1: - CHK_COUNT 80,6 + CHK_COUNT 80,6 + ldr r0,[sp,#8] @ get block count off the stack +#if HARDENING +@ We check the random counts here. Note we start with the combined count and subtract, just because +@ it might make it marginally more difficult to get the right answer if skipping multiple instructions + movs r1, #(RND_COUNT_remap + RND_COUNT_refreshchaff_and_lfsr) +#if REMAP_PERIOD != 1 + tst r0, #(REMAP_PERIOD-1) + it ne + subne r1, #RND_COUNT_remap +#endif +#if REFCHAFF_PERIOD != 1 + tst r0, #(REFCHAFF_PERIOD-1) + it ne + subne r1, #RND_COUNT_refreshchaff_and_lfsr +#endif +@ r0=block count, r1=expected sha rand count, r3=block count + rcp_iequal_nodelay r0, r3 +@ r1=expected sha rand count, r3=block count + check_rnd_count_dynamic +#endif // HARDENING +@ r3=block count + +@ No point in having a branch if we should never take it (hardening/size fail) +#if REFROUNDKEYSHARES_PERIOD != 1 +#if HARDENING +// we want to check that we are calling enough +#warning REFROUNDKEYSHARES_PERIOD check needs hardening +#endif tst r3,#(REFROUNDKEYSHARES_PERIOD-1) - bne 1f + bne skip_ref_roundkey_shares_s +#endif +#if INLINE_REF_ROUNDKEY_SHARES_S + inline_ref_roundkey_shares_s +#else +#if HARDENING + // todo graham we could remove this for space, as I don't think r4 and r5 are equal +@ Make sure r4 != r5 on entry to ref_roundkey_shares_s + subs r4, r5, #1 +#endif bl ref_roundkey_shares_s @ refresh the round key shares -1: +#if HARDENING +@ r4 and r5 are set equal by ref_roundkey_shares (note we don't do a rnd_check as no sha random numbers are generated) + rcp_iequal_nodelay r4, r5 +#endif +#endif +skip_ref_roundkey_shares_s: - ldr r3,[r13,#8] @ get block count off the stack +#if REFROUNDKEYHVPERMS_PERIOD != 1 +#if HARDENING +// we want to check that we are calling enough +#warning REFROUNDKEYHVPERMS_PERIOD check needs hardening +#endif + ldr r3,[sp,#8] @ get block count off the stack tst r3,#(REFROUNDKEYHVPERMS_PERIOD-1) - bne 1f + bne skip_ref_roundkey_hvperm_s +#endif +#if INLINE_REF_ROUNDKEY_HVPERMS_S + inline_ref_roundkey_hvperms_s +#else bl ref_roundkey_hvperms_s @ refresh the round key vperms -1: +#if HARDENING + movs r0, #30 +@ r7 should be 30 on exit from ref_roundkey_hvperms_s + rcp_iequal_nodelay r0, r7 +#endif +#endif +skip_ref_roundkey_hvperms_s: CHK_COUNT 81,6 +@ Trashes r0, r1 + reset_rnd_count pop {r1-r3} @ r1=cipher/plaintext buffer, r2=number of blocks, r3=block counter @@ -1767,6 +2117,7 @@ ctr_crypt_mainloop: adds r4,r4,r7 @ r4=j if top bit of r6, else i subs r1,r1,#1 bpl 1b + // tooo loop check pop {r1} mov r12,r4 .else @@ -1812,29 +2163,59 @@ processIV: @ non-target label to assist power analysis movs r2,#0 str r2,[r1] bl addstatevperm @ Initialise state vperm (use SHA RNG to start with, later refreshes are with LFSR RNG) +#if HARDENING + // r1 is set to lut_b by addstatevperm + ldr r0, =shareB + 0x10 + rcp_iequal_nodelay r0, r1 +#endif .endif +@ Trashes r0, r1 + check_rnd_count RND_COUNT_ctr_crypt_mainloop_A CHK_COUNT 84,6 +.if ST_SHAREC @ Avoid func call if the func is empty bl conjshareC @ Add the effect of shareC to lut_a, lut_b +#if HARDENING + // r1 is set to lut_b by conjshare + ldr r2,=lut_b + rcp_iequal_nodelay r1, r2 +#endif +.endif + // todo graham remove this count CHK_COUNT 85,6 @ now perform the 15 encryption rounds on (key, state=IV+x) @ here r4-r7, r8-r11: state mov r2,#0 @ round counter rounds_s_mainloop: +@ Trashes r0, r1 + reset_rnd_count_checked ldr r12,=rkey_s add r12,r12,r2,lsl#5 @ pointer to key shares for this round add r12,r12,r2,lsl#3 push {r2} @ save round count bl addrkey_s +.if INLINE_MAP_SBOX_S + inline_map_sbox_s +.else bl map_sbox_s +.endif +.if INLINE_SHIFT_ROWS_S + inline_shift_rows_s +.else bl shift_rows_s +.endif .if ST_VPERM - ldr r2,[r13] @ peek at stack to get round count + ldr r2,[sp] @ peek at stack to get round count cmp r2,#NUMREFSTATEVPERM bcs 1f bl gen_rand_lfsr_nonpres ldr r1,=statevperm bl addstatevperm @ V shuffle of r4-r11 +#if HARDENING + // r1 is set to lut_b by addstatevperm + ldr r2, =shareB + 0x10 + rcp_iequal_nodelay r1, r2 +#endif 1: .endif pop {r2} @@ -1846,22 +2227,32 @@ rounds_s_mainloop: pop {r2} b rounds_s_mainloop 2: +#if HARDENING + movs r1, #14 + rcp_iequal_nodelay r1, r2 +#endif CHK_COUNT 86,6 ldr r12,=rkey_s+14*40 @ final round key shares + // todo graham check this is called bl addrkey_s CHK_COUNT 87,6 +.if ST_SHAREC @ Avoid func call if the func is empty + // todo alex, i assume that skipping this will cause bad things to happen anyway? bl conjshareC @ Undo the effect of shareC from lut_a, lut_b +.endif CHK_COUNT 88,6 .if ST_VPERM @ Undo the effects of vperm rotation recorded in statevperm ldr r1,=statevperm ldr r2,[r1] rsbs r0,r2,#0 +@ We don't check this is called since failing to undo this is probably going to break decryption +// todo alex is this fair? bl addstatevperm .endif pop {r1-r3,r12} - push {r3} + push {r1,r3} @ r1=cipher/plaintext buffer, r2=number of blocks, r3=block counter, r12=block to be deciphered decryption_start: @@ -1901,10 +2292,13 @@ decryption_start: eors r3,r3,r0 str r3,[r1,#12] - sub r1,r1,r12,lsl#4 @ Restore r1 to point to start of buffer CHK_COUNT 90,6 - pop {r3} @ Restore block counter +@ Trashes r0, r1 + check_rnd_count RND_COUNT_decryption_end + + pop {r1,r3} @ Restore r1 to point to start of buffer + @ Restore block counter @ r1=cipher/plaintext buffer, r2=number of blocks, r3=block counter decryption_end: @@ -1912,33 +2306,61 @@ decryption_end: cmp r3,r2 CHK_COUNT 91,6 bne ctr_crypt_mainloop + // todo alex, is this necessary - if you don't do the right number of loops, you ain't gonna get far? +#if HARDENING + rcp_iequal_nodelay r2, r3 +#endif #if WIPE_MEMORY @ Wipe memory from workspace_start up to the stack pointer @ First fill everything (except the RNG state itself) with random numbers to avoid any possibly useful power signals ldr r4,=workspace_start - ldr r5,=rstate_all_start + add r5, r4, #rstate_all_start - workspace_start +#if HARDENING + ldr r7,=workspace_start + add r6, r4, #rstate_all_start - workspace_start + rcp_iequal_nodelay r4, r7 +#endif +#if HARDENING + // todo alex, is this necessary - if you don't do the right number of loops, you ain't gonna get far? +@ Recheck of above + rcp_iequal_nodelay r3, r2 +#endif 1: bl gen_rand_sha_nonpres stmia r4!,{r0} cmp r4,r5 bcc 1b +#if HARDENING + rcp_iequal_nodelay r4, r6 + mov r6,sp +#endif + // not if this load is skpped, then we are just erasing from where we left off before +.if rstate_all_end <= rstate_all_start +.err +.endif ldr r4,=rstate_all_end - mov r5,r13 @ gcc arm assembler says cmp r4,r13 is deprecated, so use another register + mov r5,sp @ gcc arm assembler says cmp r4,sp is deprecated, so use another register 1: bl gen_rand_sha_nonpres stmia r4!,{r0} cmp r4,r5 bcc 1b +#if HARDENING + rcp_iequal_nodelay r4, r6 +#endif @ Then fill everything with zeros so as not to leave behind clues about the RNG state ldr r4,=workspace_start movs r0,#0 - mov r5,r13 + mov r5,sp 1: stmia r4!,{r0} cmp r4,r5 bcc 1b +#if HARDENING + rcp_iequal_nodelay r4, r6 +#endif #endif .if GEN_RAND_SHA diff --git a/enc_bootloader/config.h b/enc_bootloader/config.h index 1573fbff..64c7fd90 100644 --- a/enc_bootloader/config.h +++ b/enc_bootloader/config.h @@ -54,6 +54,21 @@ #define CK_JITTER 1 // Use the ROSC clock to make ARM timings unpredictable #endif +#ifndef INLINE_REF_ROUNDKEY_SHARES_S +#define INLINE_REF_ROUNDKEY_SHARES_S 0 +#endif + +#ifndef INLINE_REF_ROUNDKEY_HVPERMS_S +#define INLINE_REF_ROUNDKEY_HVPERMS_S 0 +#endif + +#ifndef INLINE_SHIFT_ROWS_S +#define INLINE_SHIFT_ROWS_S 0 +#endif + +#ifndef INLINE_MAP_SBOX_S +#define INLINE_MAP_SBOX_S 0 +#endif //////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/enc_bootloader/enc_bootloader.c b/enc_bootloader/enc_bootloader.c index 4b7e40f0..2668150b 100644 --- a/enc_bootloader/enc_bootloader.c +++ b/enc_bootloader/enc_bootloader.c @@ -10,16 +10,14 @@ #include "boot/picoboot.h" #include "pico/bootrom.h" #include "hardware/structs/otp.h" - -#include "hardware/structs/trng.h" -#include "hardware/structs/sha256.h" - +#include "hardware/structs/mpu.h" #include "pico/binary_info.h" #include "hardware/clocks.h" -#include "hardware/xosc.h" #include "hardware/structs/rosc.h" +#include "hardware/rcp.h" +#include "hard_entry_point.h" #include "config.h" extern void decrypt(uint8_t* key4way, uint8_t* IV_OTPsalt, uint8_t* IV_public, uint8_t(*buf)[16], int nblk); @@ -32,6 +30,79 @@ extern void decrypt(uint8_t* key4way, uint8_t* IV_OTPsalt, uint8_t* IV_public, u #define XOSC_CALIBRATION 0 #if CK_JITTER + +static inline bool has_glitchless_mux(clock_handle_t clock) { + return clock == clk_sys || clock == clk_ref; +} + +static __force_inline void clock_configure_internal(clock_handle_t clock, uint32_t src, uint32_t auxsrc, uint32_t actual_freq, uint32_t div) { + clock_hw_t *clock_hw = &clocks_hw->clk[clock]; + + // If increasing divisor, set divisor before source. Otherwise set source + // before divisor. This avoids a momentary overspeed when e.g. switching + // to a faster source and increasing divisor to compensate. + if (div > clock_hw->div) + clock_hw->div = div; + + // If switching a glitchless slice (ref or sys) to an aux source, switch + // away from aux *first* to avoid passing glitches when changing aux mux. + // Assume (!!!) glitchless source 0 is no faster than the aux source. + if (has_glitchless_mux(clock) && src == CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLKSRC_CLK_SYS_AUX) { + hw_clear_bits(&clock_hw->ctrl, CLOCKS_CLK_REF_CTRL_SRC_BITS); + while (!(clock_hw->selected & 1u)) + tight_loop_contents(); + } + // If no glitchless mux, cleanly stop the clock to avoid glitches + // propagating when changing aux mux. Note it would be a really bad idea + // to do this on one of the glitchless clocks (clk_sys, clk_ref). + else { + // Disable clock. On clk_ref and clk_sys this does nothing, + // all other clocks have the ENABLE bit in the same position. + if (clock != clk_sys && clock != clk_ref) { + pico_default_asm_volatile("b not_there\n"); // this branch should be elided by compiler in inlined func + hw_clear_bits(&clock_hw->ctrl, CLOCKS_CLK_GPOUT0_CTRL_ENABLE_BITS); + } + // if (configured_freq[clock] > 0) { + // // Delay for 3 cycles of the target clock, for ENABLE propagation. + // // Note XOSC_COUNT is not helpful here because XOSC is not + // // necessarily running, nor is timer... + // uint delay_cyc = configured_freq[clk_sys] / configured_freq[clock] + 1; + // busy_wait_at_least_cycles(delay_cyc * 3); + // } + } + + // Set aux mux first, and then glitchless mux if this clock has one + hw_write_masked(&clock_hw->ctrl, + (auxsrc << CLOCKS_CLK_SYS_CTRL_AUXSRC_LSB), + CLOCKS_CLK_SYS_CTRL_AUXSRC_BITS + ); + + if (has_glitchless_mux(clock)) { + hw_write_masked(&clock_hw->ctrl, + src << CLOCKS_CLK_REF_CTRL_SRC_LSB, + CLOCKS_CLK_REF_CTRL_SRC_BITS + ); + while (!(clock_hw->selected & (1u << src))) + tight_loop_contents(); + } + + // Enable clock. On clk_ref and clk_sys this does nothing, + // all other clocks have the ENABLE bit in the same position. + if (clock != clk_sys && clock != clk_ref) { + pico_default_asm_volatile("b not_there\n"); // code should me omitted + // hw_set_bits(&clock_hw->ctrl, CLOCKS_CLK_GPOUT0_CTRL_ENABLE_BITS); + } + + // Now that the source is configured, we can trust that the user-supplied + // divisor is a safe value. + clock_hw->div = div; + //configured_freq[clock] = actual_freq; +} + +static __force_inline void clock_configure_int_divider_inline(clock_handle_t clock, uint32_t src, uint32_t auxsrc, uint32_t src_freq, uint32_t int_divider) { + clock_configure_internal(clock, src, auxsrc, src_freq / int_divider, int_divider << CLOCKS_CLK_GPOUT0_DIV_INT_LSB); +} + void runtime_init_clocks(void) { // Disable resus that may be enabled from previous software clocks_hw->resus.ctrl = 0; @@ -40,12 +111,12 @@ void runtime_init_clocks(void) { bi_decl(bi_ptr_int32(0, 0, rosc_drive, 0x7777)); // default drives of 0b111 (0x7) // Bump up ROSC speed to ~110MHz - rosc_hw->freqa = 0; // reset the drive strengths + rosc_hw->freqa = 0; // reset the drive strengths (note password not needed for this) rosc_hw->div = rosc_div | ROSC_DIV_VALUE_PASS; // set divider // Increment the freqency range one step at a time - this is safe provided the current config is not TOOHIGH // because ROSC_CTRL_FREQ_RANGE_VALUE_MEDIUM | ROSC_CTRL_FREQ_RANGE_VALUE_HIGH == ROSC_CTRL_FREQ_RANGE_VALUE_HIGH - static_assert((ROSC_CTRL_FREQ_RANGE_VALUE_LOW | ROSC_CTRL_FREQ_RANGE_VALUE_MEDIUM) == ROSC_CTRL_FREQ_RANGE_VALUE_MEDIUM); - static_assert((ROSC_CTRL_FREQ_RANGE_VALUE_MEDIUM | ROSC_CTRL_FREQ_RANGE_VALUE_HIGH) == ROSC_CTRL_FREQ_RANGE_VALUE_HIGH); + static_assert(ROSC_CTRL_FREQ_RANGE_VALUE_LOW | ROSC_CTRL_FREQ_RANGE_VALUE_MEDIUM == ROSC_CTRL_FREQ_RANGE_VALUE_MEDIUM); + static_assert(ROSC_CTRL_FREQ_RANGE_VALUE_MEDIUM | ROSC_CTRL_FREQ_RANGE_VALUE_HIGH == ROSC_CTRL_FREQ_RANGE_VALUE_HIGH); hw_set_bits(&rosc_hw->ctrl, ROSC_CTRL_FREQ_RANGE_VALUE_MEDIUM); hw_set_bits(&rosc_hw->ctrl, ROSC_CTRL_FREQ_RANGE_VALUE_HIGH); @@ -55,8 +126,25 @@ void runtime_init_clocks(void) { // Not used with FREQ_RANGE_VALUE_HIGH, but should still be set to the maximum drive rosc_hw->freqb = (ROSC_FREQB_PASSWD_VALUE_PASS << ROSC_FREQB_PASSWD_LSB) | - ROSC_FREQB_DS7_LSB | ROSC_FREQB_DS6_LSB | ROSC_FREQB_DS5_LSB | ROSC_FREQB_DS4_LSB; + ROSC_FREQB_DS7_BITS | ROSC_FREQB_DS6_BITS | ROSC_FREQB_DS5_BITS | ROSC_FREQB_DS4_BITS; +#if RC_COUNT + rcp_count_check_nodelay(STEP_RUNTIME_CLOCKS_INIT); +#endif +#if HARDENING + // force reload + rosc_hw_t *rosc_hw2; + pico_default_asm_volatile( + "ldr %0, =%c1\n" + : "=&r" (rosc_hw2) : "i" (ROSC_BASE), "r" (rosc_hw)); // note include rosc_hw to use a different register + uint32_t c = (*(volatile uint32_t *)&rosc_drive) | ROSC_FREQA_DS1_RANDOM_BITS | ROSC_FREQA_DS0_RANDOM_BITS; + rcp_iequal_nodelay(c, *(io_ro_16 *)(&rosc_hw2->freqa)); + rcp_iequal_nodelay(ROSC_FREQB_DS7_BITS | ROSC_FREQB_DS6_BITS | ROSC_FREQB_DS5_BITS | ROSC_FREQB_DS4_BITS, *(io_ro_16 *)(&rosc_hw2->freqb)); + rcp_iequal_nodelay((ROSC_CTRL_ENABLE_VALUE_ENABLE << ROSC_CTRL_ENABLE_LSB) | ROSC_CTRL_FREQ_RANGE_VALUE_HIGH, rosc_hw2->ctrl); +#endif +#if RC_COUNT + rcp_count_check_nodelay(STEP_RUNTIME_CLOCKS_INIT2); +#endif #if XOSC_CALIBRATION // Calibrate ROSC frequency if XOSC present - otherwise just configure bi_decl(bi_ptr_int32(0, 0, xosc_hz, 12000000)); // xosc freq in Hz @@ -101,69 +189,173 @@ void runtime_init_clocks(void) { } #endif // XOSC_CALIBRATION // CLK SYS = ROSC directly, as it's running slowly enough - clock_configure_int_divider(clk_sys, + clock_configure_int_divider_inline(clk_sys, CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLKSRC_CLK_SYS_AUX, CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_ROSC_CLKSRC, ROSC_HZ, // this doesn't have to be accurate 1); - // Configure other clocks - none of these need to be accurate +#if RC_COUNT + rcp_count_check_nodelay(STEP_RUNTIME_CLOCKS_INIT3); +#endif // CLK_REF = ROSC / OTHER_CLK_DIV - this and other clocks aren't really used, so just need to be set to a low enough frequency - clock_configure_int_divider(clk_ref, + clock_configure_int_divider_inline(clk_ref, CLOCKS_CLK_REF_CTRL_SRC_VALUE_ROSC_CLKSRC_PH, 0, ROSC_HZ, OTHER_CLK_DIV); - // CLK USB (not used) - clock_configure_int_divider(clk_usb, - 0, // No GLMUX - CLOCKS_CLK_USB_CTRL_AUXSRC_VALUE_ROSC_CLKSRC_PH, - ROSC_HZ, - OTHER_CLK_DIV); - - // CLK ADC (not used) - clock_configure_int_divider(clk_adc, - 0, // No GLMUX - CLOCKS_CLK_ADC_CTRL_AUXSRC_VALUE_ROSC_CLKSRC_PH, - ROSC_HZ, - OTHER_CLK_DIV); - - // CLK PERI Used as reference clock for UART and SPI serial. (not used) - clock_configure_int_divider(clk_peri, - 0, - CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_CLK_SYS, - ROSC_HZ, - OTHER_CLK_DIV); - - // CLK_HSTX Transmit bit clock for the HSTX peripheral. (not used) - clock_configure_int_divider(clk_hstx, - 0, - CLOCKS_CLK_HSTX_CTRL_AUXSRC_VALUE_CLK_SYS, - ROSC_HZ, - OTHER_CLK_DIV); +#if RC_COUNT + rcp_count_check_nodelay(STEP_RUNTIME_CLOCKS_INIT4); +#endif + // we don't need any other clocks +#if HARDENING + static_assert(CLOCKS_CLK_REF_CTRL_OFFSET == clk_ref * sizeof(clock_hw_t), ""); + static_assert(clk_sys > clk_ref, ""); + // prevent GCC from re-using ptr + io_ro_32 *clock_ref_ctrl; + pico_default_asm_volatile( + "ldr %0, =%c1\n" + : "=r" (clock_ref_ctrl) : "i" (CLOCKS_BASE + clk_ref * sizeof(clock_hw_t))); + // check clock_sys + rcp_iequal_nodelay(clock_ref_ctrl[(clk_sys - clk_ref) * sizeof(clock_hw_t) / 4], + (CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_ROSC_CLKSRC << CLOCKS_CLK_SYS_CTRL_AUXSRC_LSB) | + (CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLKSRC_CLK_SYS_AUX << CLOCKS_CLK_SYS_CTRL_SRC_LSB)); + // check clock_ref + rcp_iequal_nodelay(*clock_ref_ctrl, 0); +#endif +#if RC_COUNT + rcp_count_check_nodelay(STEP_RUNTIME_CLOCKS_INIT5); +#endif } #endif bi_decl(bi_ptr_int32(0, 0, otp_key_page, 29)); +// Stop the compiler from constant-folding a hardware base pointer into the +// pointers to individual registers, in cases where constant folding has +// produced redundant 32-bit pointer literals that could have been load/store +// offsets. (Note typeof(ptr+0) gives non-const, for +r constraint.) E.g. +// uart_hw_t *uart0 = __get_opaque_ptr(uart0_hw); +#define __get_opaque_ptr(ptr) ({ \ + typeof((ptr)+0) __opaque_ptr = (ptr); \ + asm ("" : "+r"(__opaque_ptr)); \ + __opaque_ptr; \ +}) + // The function lock_key() is called from decrypt() after key initialisation is complete and before decryption begins. // That is a suitable point to lock the OTP area where key information is stored. void lock_key() { - otp_hw->sw_lock[otp_key_page] = 0xf; - otp_hw->sw_lock[otp_key_page + 1] = 0xf; + io_rw_32 *sw_lock = __get_opaque_ptr(&otp_hw->sw_lock[0]) + otp_key_page; +#if HARDENING + // prevent compiler from re-using sw_lock pointer + io_rw_32 *sw_lock2; + pico_default_asm( + "ldr %0, =%1\n" + : "=r" (sw_lock2) + : "i" (OTP_BASE + OTP_SW_LOCK0_OFFSET) + ); + sw_lock2 += otp_key_page; + sw_lock[0] = 0xf; + sw_lock[1] = 0xf; + uint32_t v = sw_lock2[1]; + v = (v << 4) | sw_lock2[0]; + uint32_t ff1; + pico_default_asm_volatile( + "movs %0, #0xff" + : "=r" (ff1) + ); + uint32_t ff2; + pico_default_asm_volatile( + "movw %0, #0xff" + : "=r" (ff2) + ); + rcp_iequal(v, ff1); +#if RC_COUNT + rcp_count_check_nodelay(31); +#endif + rcp_iequal(ff2, v); +#else + sw_lock[0] = 0xf; + sw_lock[1] = 0xf; +#if RC_COUNT + rcp_count_check_nodelay(31); +#endif +#endif } +static __force_inline void lock_all(void) { + io_rw_32 *sw_lock = __get_opaque_ptr(&otp_hw->sw_lock[0]) + otp_key_page; +#if HARDENING + // we only actually need to lock page 2 but we lock and check 0, 1, 2 anyway + // prevent compiler from re-using sw_lock pointer + io_rw_32 *sw_lock2; + pico_default_asm( + "ldr %0, =%1\n" + : "=r" (sw_lock2) + : "i" (OTP_BASE + OTP_SW_LOCK0_OFFSET) + ); + sw_lock2 += otp_key_page; + sw_lock[0] = 0xf; + sw_lock[1] = 0xf; + uint32_t v = sw_lock2[1]; + sw_lock[2] = 0xf; + v = (v << 4) | sw_lock2[0]; + v = (v << 4) | sw_lock2[2]; + uint32_t fff1; + pico_default_asm_volatile( + "movw %0, #0xfff" + : "=r" (fff1) + ); + uint32_t fff2; + pico_default_asm_volatile( + "movw %0, #0xfff" + : "=r" (fff2) + ); + rcp_iequal(v, fff1); + rcp_iequal(fff2, v); +#else + sw_lock[0] = 0xf; + sw_lock[1] = 0xf; + sw_lock[2] = 0xf; +#endif + +} +#define PIN_R PICO_DEFAULT_LED_PIN +#define PIN_G 6 + +#ifndef USE_LED +#if ALLOW_DEBUGGING +#define USE_LED 1 +#endif +#endif int main() { +#if USE_LED +#if ALLOW_DEBUGGING + reset_block_mask((1u << RESET_IO_BANK0) | (1u << RESET_PADS_BANK0)); + unreset_block_mask_wait_blocking((1u << RESET_IO_BANK0) | (1u << RESET_PADS_BANK0)); +#endif + gpio_init(PIN_G); + gpio_set_dir(PIN_G, GPIO_OUT); + gpio_put(PIN_G, 1); +#endif +#if RC_COUNT + rcp_count_check_nodelay(STEP_MAIN); +#endif + bi_decl(bi_ptr_int32(0, 0, data_start_addr, 0x20000000)); bi_decl(bi_ptr_int32(0, 0, data_size, 0x78000)); bi_decl(bi_ptr_string(0, 0, iv, "0123456789abcdef", 17)); // Read key directly from OTP - guarded reads will throw a bus fault if there are any errors +#if ALLOW_DEBUGGING + uint16_t* otp_data = (uint16_t*)OTP_DATA_BASE; +#else uint16_t* otp_data = (uint16_t*)OTP_DATA_GUARDED_BASE; +#endif decrypt( (uint8_t*)&(otp_data[otp_key_page * 0x40]), (uint8_t*)&(otp_data[(otp_key_page + 2) * 0x40]), @@ -172,23 +364,77 @@ int main() { data_size/16 ); - // Lock the IV salt - otp_hw->sw_lock[otp_key_page + 2] = 0xf; + lock_all(); - // Increase stack limit by 0x100 +#if ALLOW_DEBUGGING && !defined(NDEBUG) + // check locks + io_ro_32 *otp_data_raw = (io_ro_32 *)OTP_DATA_RAW_BASE; + rcp_iequal(otp_data_raw[otp_key_page * 0x40], -1); + rcp_iequal(otp_data_raw[otp_key_page * 0x40 + 0x40], -1); + rcp_iequal(otp_data_raw[otp_key_page * 0x40 + 0x80], -1); +#endif + // Increase stack space by 0x100 pico_default_asm_volatile( "mrs r0, msplim\n" "subs r0, 0x100\n" "msr msplim, r0" :::"r0"); +#if HARDENING + // this is the only one we want to leave in place + static_assert(MPU_REGION_FLASH == 7, ""); + // disable regions 0-3 (note rnr should be 0 already) + // todo we should check here that we decrypted enough + mpu_hw->rlar = 0; + mpu_hw->rlar_a1 = 0; + mpu_hw->rlar_a2 = 0; + mpu_hw->rlar_a3 = 0; + // todo make this configurable (if you want MPU disabled) +#if 1 + // disable region 7 + mpu_hw->rnr = MPU_REGION_FLASH; + mpu_hw->rlar = 0; + // disable MPU + mpu_hw->ctrl = 0; +#endif +#endif + +#if USE_LED + gpio_put(PIN_G, 0); + __compiler_memory_barrier(); +#endif // Chain into decrypted image - rom_chain_image( + // todo make sure the image is NOT in flash (perhaps we also disallow execution from flash as an option) + int chain_result = rom_chain_image( (uint8_t*)ROM_CHAIN_WORKSPACE, 4 * 1024, data_start_addr, data_size ); - __breakpoint(); + chain_result = -chain_result; +#if USE_LED + gpio_init(PIN_R); + gpio_set_dir(PIN_R, GPIO_OUT); + gpio_put(PIN_R, 1); + + + gpio_put(PIN_G, 0); + for (int j = 0; j < 10000000; j++) { __nop(); } + for (int i = 0; i < chain_result; i++) { + gpio_put(PIN_G, 0); + for (int j = 0; j < 5000000; j++) { __nop(); } + gpio_put(PIN_G, 1); + for (int j = 0; j < 5000000; j++) { __nop(); } + } + gpio_put(PIN_G, 0); +#endif + +#if ALLOW_DEBUGGING + rom_connect_internal_flash(); + rom_flash_exit_xip(); + rom_flash_range_erase(0x100000, 0x80000, (1u << 16), 0xd8); + rom_flash_range_program(0x100000, (void *)data_start_addr, data_size); + rom_reset_usb_boot(0, 0); +#endif } diff --git a/enc_bootloader/enc_bootloader.elf b/enc_bootloader/enc_bootloader.elf index e100748894e4d816bd4f49b3648a3eb5a9d6730e..5653efade230f6a83fa1a965f11e87424904eace 100755 GIT binary patch literal 37008 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 RPG_ZRxp_B(rb>w7{lCfwm&^bF literal 21544 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 WFF&$8Dkt_eLg;RQJedix%=h1i=9GH? diff --git a/enc_bootloader/enc_bootloader_mbedtls.elf b/enc_bootloader/enc_bootloader_mbedtls.elf index 5c278639525ba916aa49282e36d14e5f32a646c9..1344c011375e5972fe4a232ecc8c8da0624d5597 100644 GIT binary patch literal 115964 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

hWpFX;{mV6eDe&~}R4LLD zi0gW4pZPXOzK^cd`FP~Uvi1Li%#$$ktN*)P{l7m0WTpAz|B+_QS_ENJ-0?t2w=+@5 zYs~s(kWLu?n&4vAF&yLiwSwFc_Y(LVfcoz!0x|370Ui&V{2bC PB3{H;=+C@%&z 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%0A?%*6IY zDEJw0I#zvd*nlIz+KFw!yt;rhun*FaPXk;4?$_TNyacRGhz$N*z|zw0WfpYYiC~}) z26}&(}3yUV)Sdlr^2WD6Y zy53{0#Bb3IFtbfMeH6kMbeKGVm)-jf_<02WHL%{rry}SMT(IdQjXiA8Ind`~-_l}y zErS0BaKFb5@IPiW5lMwBuNt#ty3vP|jzW?PtPjDs2rNh7a$x$`GPJ1r9*>~c+=soK zJ%Nt?nDqv+K-sgnsM3Z?Nwfu+Rx1o=39$AaUNI(M#v1*XByZDP-W&Wau-@Ra!1Nz$ za3N%zeIFj9&sZey@KToQ1c)IA8x(#2QW-%1GY!xe)860_D4>60lR^tNkFSWX%Mp>@ zf%^EPSt4)(^wDP|nou6_RIDPpKGsslM0E5gk;G;J-^NiwpH_&z6u5uDXto+yKg0FF z{R5hr54b;PME@^3u+j7e---~sKw`Q`|0#n01+a*DYK|X(dFzKA2u!yejb0okz;w;h4EhUj0vt{A z^pYb7;0(HN1`*f}ti4uJ?oR-wJEo?vTE|bB(gNIXpoy&o?hjN9+W;K)uvgtaUeqa| z<$oXo|1tu<7J<7W@H-LsA~3USYayEbxsQ&8P6J-+>j>c+5%^vN{tCXM@4w^$+V70f z_j}L++>KOqfKDFHjG*TOtBV`st2=Tjb?9n$TH;>?dVffw*?QoC&_^4+I)lwR1>}+EBk)TR_>~C!D`4%@1m(!-2>QFgbXC`K z<}NVa^B07-3j>S7_EHtzUdUoQFkSvNfihtIj6Z||`t(j`5QShy1bu=3(S|WhRJX0DXHB3vV!nnKp3Q;h%H-GU$>&Mt-7YZ4Ij8_8=GsF_BE<&o0}FlELquFUyZL>^{q`c zjjXS$u6l86{c=VQXl-5wS!z```tx7sGmBcAS2op=I9$-QqK(a(laEq_Qh-v(T)-}1 z7qAO>*6c;EA9i!zvb`yH?*Vm+yKCnCQeES3C&IBVK8ct5 z`6-?jO$Tx*zA_y2KLl7nchPJ3KgHX$s=^Ot2R&m^=v@qVT6K@_C`P`M7OQ{jDQ=FY z>(<-oo8jM2nrSK6oZ$6+_LbHD2{g?K>1Vk$c^@DybS>0Pj|-%6WJpQ}5Y0k+)`2pX z`xl(y4(V_OW3Lm}WAA{h=kiQp>|b>qTJuj4e2!@_gEZ7%kDxd~IjV{2Xt%>{Z4!5; zGu9r#r$YSby4f21M48 IRQs are used, so we would waste RAM if the vector table were not at the @@ -52,6 +46,7 @@ SECTIONS } > RAM_START .text : { + __text_start = .; __reset_start = .; KEEP (*(.reset)) __reset_end = .; @@ -123,26 +118,29 @@ SECTIONS KEEP(*(.mutex_array)) PROVIDE_HIDDEN (__mutex_array_end = .); + /* We skip all the initializers as we need very little runtime, and preinit_array items + * are __used, so would never be garbage collected even if referenced + */ . = ALIGN(4); /* preinit data */ - PROVIDE_HIDDEN (__preinit_array_start = .); - KEEP(*(SORT(.preinit_array.*))) - KEEP(*(.preinit_array)) - PROVIDE_HIDDEN (__preinit_array_end = .); +/* PROVIDE_HIDDEN (__preinit_array_start = .); */ +/* KEEP(*(SORT(.preinit_array.*)))*/ +/* KEEP(*(.preinit_array))*/ +/* PROVIDE_HIDDEN (__preinit_array_end = .);*/ . = ALIGN(4); /* init data */ - PROVIDE_HIDDEN (__init_array_start = .); - KEEP(*(SORT(.init_array.*))) - KEEP(*(.init_array)) - PROVIDE_HIDDEN (__init_array_end = .); +/* PROVIDE_HIDDEN (__init_array_start = .);*/ +/* KEEP(*(SORT(.init_array.*)))*/ +/* KEEP(*(.init_array))*/ +/* PROVIDE_HIDDEN (__init_array_end = .);*/ . = ALIGN(4); /* finit data */ - PROVIDE_HIDDEN (__fini_array_start = .); - *(SORT(.fini_array.*)) - *(.fini_array) - PROVIDE_HIDDEN (__fini_array_end = .); +/* PROVIDE_HIDDEN (__fini_array_start = .);*/ +/* *(SORT(.fini_array.*))*/ +/* *(.fini_array)*/ +/* PROVIDE_HIDDEN (__fini_array_end = .);*/ *(.jcr) . = ALIGN(4); @@ -237,6 +235,7 @@ SECTIONS __StackOneBottom = __StackOneTop - SIZEOF(.stack1_dummy); __StackBottom = __StackTop - SIZEOF(.stack_dummy); PROVIDE(__stack = __StackTop); + ASSERT(__StackBottom >= __scratch_y_end__, "stack collision in scratch_y") /* picolibc and LLVM */ PROVIDE (__heap_start = __end__); diff --git a/main.cpp b/main.cpp index 61617fd0..063ec535 100644 --- a/main.cpp +++ b/main.cpp @@ -897,7 +897,7 @@ struct seal_command : public cmd { ).force_expand_help(true) % "BIN file options" + named_file_selection_x("outfile", 1) % "File to save to" + optional_untyped_file_selection_x("key", 2) % "Key file (.pem)" + - optional_untyped_file_selection_x("otp", 3) % "JSON file to save OTP to (will edit existing file if it exists)" + + optional_untyped_file_selection_x("otp", 3) % "JSON file to save OTP to (will edit existing file if it exists)" + ( option("--major") & integer("major").set(settings.seal.major_version) @@ -4923,6 +4923,12 @@ void sign_guts_elf(elf_file* elf, private_t private_key, public_t public_key) { image_type->flags |= PICOBIN_IMAGE_TYPE_EXE_TBYB_BITS; } + if (settings.seal.set_tbyb) { + // Set the TBYB bit on the image_type_item + std::shared_ptr image_type = new_block.get_item(); + image_type->flags |= PICOBIN_IMAGE_TYPE_EXE_TBYB_BITS; + } + if (settings.seal.major_version || settings.seal.minor_version || settings.seal.rollback_version) { std::shared_ptr version = new_block.get_item(); if (version != nullptr) { @@ -5283,7 +5289,7 @@ bool encrypt_command::execute(device_map &devices) { // Sign the final thing settings.seal.clear_sram = true; sign_guts_elf(enc_elf, private_key, public_key); - + auto out = get_file_idx(ios::out|ios::binary, 1); enc_elf->write(out); out->close(); From 9cd3d3589bb6f5e7f22fa7d7d3864fdb3d29d13f Mon Sep 17 00:00:00 2001 From: graham sanderson Date: Thu, 5 Jun 2025 11:16:40 -0500 Subject: [PATCH 2/8] fix merge issue, and update ELFs --- enc_bootloader/enc_bootloader.elf | Bin 37008 -> 20144 bytes enc_bootloader/enc_bootloader_mbedtls.elf | Bin 115964 -> 30396 bytes main.cpp | 6 ------ 3 files changed, 6 deletions(-) diff --git a/enc_bootloader/enc_bootloader.elf b/enc_bootloader/enc_bootloader.elf index 5653efade230f6a83fa1a965f11e87424904eace..f6cf6ed55bb18c8beb1799ef3a8a093b5868cbc1 100755 GIT binary patch delta 200 zcmbQRkZHqQ#t90-JG>bf7?>DXO&AmySQs=Igc*c38lTmh9GsWASuvlPar2S_6Y0r@ zJrWZSX>4xj5nysO0BQgOeFg?&7#m14Lh)=M&CI}10FyEXsxyOeKx!rnP7v410g5sR mf)T?qAd>}%1%Q|nh=ID{Aje^H&;&IJUZ68q!v!Ihfw%xN^BH&m literal 37008 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 RPG_ZRxp_B(rb>w7{lCfwm&^bF diff --git a/enc_bootloader/enc_bootloader_mbedtls.elf b/enc_bootloader/enc_bootloader_mbedtls.elf index 1344c011375e5972fe4a232ecc8c8da0624d5597..2a09eba30e44437d6ea21377681eeeb6c327d2c6 100644 GIT binary patch delta 814 zcmZ8fOK1~e5T4oWHrrNfn`CXQ#Vn#yVjq##*Fo@HgZQ|K&o;YFAWbw65It0(6yre) zf&SpdL_`mIs921L22;&R@ZiCtpx{Xmdk`-Q`b|uVWMJm|zM1)FXaC*b1@G!NUbOvB zGeo43F+nyl4bcE?dp154;{DIhhU#H8uQ)L`&O|!e5P2AJ(`$rIB!9g7<9{f5n5G+v zRE|77!r%8F0_eIoBw!kd06i&#xZ{N=Hdh2RV@{Hq_opb`kXD=<5HP(K!06LE^aasu zRsr6tT=Z8D#{%GDU0LFA=MAt&@I}cah(~&5gMFC27v5b!;L*Oz$hn{wCHEMD$9xg+ zGW;&QD@Gh?oD670KCQT1wTkCIKB-*a!ePxE#0lg{l`IZcMqFOwKr)@0u^T~NKbyGb zT*#?toP)|);#)oWR5me_a$@#${8EP0`Vw2}oXghW*sL>~b#kNAl#Qn|IeViKW0b8p zwyQBTmd;Nl9s1YYY?TL1yBV~F?*6!sLqyEg76T@y)^9fB+-H5=kNZl%h0%y4J)8>kky$tywj*1BU+KJ zBX8Tfa#5mTxuT}ECVYTyaVeFKV+onyd}*uHP+9x0wMEyPeGxehyLkd1yH$i1D*mg9 vfQAK5VIzev%86b$tCrw&bxyTt`M1RGiAtMmF1L{ literal 115964 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

hWpFX;{mV6eDe&~}R4LLD zi0gW4pZPXOzK^cd`FP~Uvi1Li%#$$ktN*)P{l7m0WTpAz|B+_QS_ENJ-0?t2w=+@5 zYs~s(kWLu?n&4vAF&yLiwSwFc_Y(LVfcoz!0x|370Ui&V{2bC PB3{H;=+C@%&z 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 Cflags |= PICOBIN_IMAGE_TYPE_EXE_TBYB_BITS; } - if (settings.seal.set_tbyb) { - // Set the TBYB bit on the image_type_item - std::shared_ptr image_type = new_block.get_item(); - image_type->flags |= PICOBIN_IMAGE_TYPE_EXE_TBYB_BITS; - } - if (settings.seal.major_version || settings.seal.minor_version || settings.seal.rollback_version) { std::shared_ptr version = new_block.get_item(); if (version != nullptr) { From 1330ac8992671be4098d3f70624fdfc09c4a3899 Mon Sep 17 00:00:00 2001 From: graham sanderson Date: Thu, 5 Jun 2025 12:11:48 -0500 Subject: [PATCH 3/8] add address to not_mapped_exception --- main.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/main.cpp b/main.cpp index cc9ef63c..ee9bdb61 100644 --- a/main.cpp +++ b/main.cpp @@ -184,9 +184,11 @@ const string getFiletypeName(enum filetype type) struct cancelled_exception : std::exception { }; struct not_mapped_exception : std::exception { + explicit not_mapped_exception(uint32_t addr) : addr(addr), std::exception() {} const char *what() const noexcept override { return "Hmm uncaught not mapped"; } + uint32_t addr; }; // from -> to @@ -287,14 +289,14 @@ template struct range_map { auto f = m.upper_bound(p); if (f == m.end()) { if (m.empty()) - throw not_mapped_exception(); + throw not_mapped_exception(p); } else if (f == m.begin()) { - throw not_mapped_exception(); + throw not_mapped_exception(p); } f--; assert(p >= f->first); if (p >= f->second.first) { - throw not_mapped_exception(); + throw not_mapped_exception(p); } return std::make_pair(mapping(p - f->first, f->second.first - f->first), f->second.second); } @@ -2152,14 +2154,14 @@ struct iostream_memory_access : public memory_access { assert(this_size); file->seekg(result.second + result.first.offset, ios::beg); file->read((char*)buffer, this_size); - } catch (not_mapped_exception &e) { + } catch (not_mapped_exception &) { if (zero_fill) { // address is not in a range, so fill up to next range with zeros this_size = rmap.next(address) - address; this_size = std::min(this_size, size); memset(buffer, 0, this_size); } else { - throw e; + throw; } } buffer += this_size; @@ -3794,8 +3796,8 @@ void info_guts(memory_access &raw_access, void *con) { } } fos.flush(); - } catch (not_mapped_exception&) { - std::cout << "\nfailed to read memory\n"; + } catch (not_mapped_exception&e) { + std::cout << "\nfailed to read memory at " << hex_string(e.addr) << "\n"; } } From b27c586def41d481d3d654f7936893c6f4643a77 Mon Sep 17 00:00:00 2001 From: graham sanderson Date: Thu, 5 Jun 2025 12:34:06 -0500 Subject: [PATCH 4/8] fix MPU setup --- enc_bootloader/hard_entry_point.S | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/enc_bootloader/hard_entry_point.S b/enc_bootloader/hard_entry_point.S index efc63487..f7e71e22 100644 --- a/enc_bootloader/hard_entry_point.S +++ b/enc_bootloader/hard_entry_point.S @@ -52,19 +52,20 @@ _reset_handler: adr r6, mpu_regions // set region 7 (flash) ldmia r6!, {r1, r2, r3, r4} - stmia r0!, {r1, r2, r3, r4} + stmia r0, {r1, r2, r3, r4} // sp should have low 3 bits == 0 (which is all the bits RNR is) - str sp, [r0, #M33_MPU_RNR_OFFSET - (M33_MPU_CTRL_OFFSET + 16)] + str sp, [r0, #M33_MPU_RNR_OFFSET - M33_MPU_CTRL_OFFSET] #if HARDENING sub lr, lr // we don't need lr and it is unlikely to be something that ww will read from memory if this is skipped - ldr r1, [r0, #M33_MPU_RNR_OFFSET - (M33_MPU_CTRL_OFFSET + 16)] + ldr r1, [r0, #M33_MPU_RNR_OFFSET - M33_MPU_CTRL_OFFSET] // RNR should read back as zero rcp_iequal_nodelay r1, lr #endif + adds r0, #8 ldmia r6!, {r1, r2, r3, r4, r5, r8, r9, r10} stmia r0!, {r1, r2, r3, r4, r5, r8, r9, r10} #if HARDENING - ldr r1, = PPB_BASE + M33_MPU_CTRL_OFFSET + 48 + ldr r1, = PPB_BASE + M33_MPU_RLAR_A3_OFFSET + 4 rcp_iequal_nodelay r0, r1 adr r7, mpu_regions + 48 rcp_iequal_nodelay r6, r7 From 95a12107e846d781b36179d3ce307b0cca38d3b5 Mon Sep 17 00:00:00 2001 From: graham sanderson Date: Thu, 5 Jun 2025 12:35:16 -0500 Subject: [PATCH 5/8] pass ALLOW_DEBUGGING thru from CMake --- enc_bootloader/CMakeLists.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/enc_bootloader/CMakeLists.txt b/enc_bootloader/CMakeLists.txt index cdc747f5..51f99e14 100644 --- a/enc_bootloader/CMakeLists.txt +++ b/enc_bootloader/CMakeLists.txt @@ -84,8 +84,6 @@ if (NOT USE_PRECOMPILED) endif() target_compile_definitions(enc_bootloader PRIVATE - #ALLOW_DEBUGGING=1 - # The following are to reduce the size of the binary # use stack guards, as AES variables are written near the stack PICO_USE_STACK_GUARDS=1 @@ -103,6 +101,9 @@ if (NOT USE_PRECOMPILED) PICO_USE_GPIO_COPROCESSOR=0 FIB_WORKAROUND=1 ) + if (ALLOW_DEBUGGING) + target_compile_definitions(enc_bootloader PRIVATE ALLOW_DEBUGGING=1) + endif() # print memory usage target_link_options(enc_bootloader PUBLIC -Wl,--print-memory-usage) From daf610419277591107a775809034016d48c158e9 Mon Sep 17 00:00:00 2001 From: graham sanderson Date: Thu, 5 Jun 2025 12:42:39 -0500 Subject: [PATCH 6/8] tweak MPU setup again - silly to waste 2 bytes --- enc_bootloader/hard_entry_point.S | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/enc_bootloader/hard_entry_point.S b/enc_bootloader/hard_entry_point.S index f7e71e22..2a3f8557 100644 --- a/enc_bootloader/hard_entry_point.S +++ b/enc_bootloader/hard_entry_point.S @@ -52,16 +52,16 @@ _reset_handler: adr r6, mpu_regions // set region 7 (flash) ldmia r6!, {r1, r2, r3, r4} - stmia r0, {r1, r2, r3, r4} + stmia r0!, {r1, r2, r3, r4} // sp should have low 3 bits == 0 (which is all the bits RNR is) - str sp, [r0, #M33_MPU_RNR_OFFSET - M33_MPU_CTRL_OFFSET] + str sp, [r0, #M33_MPU_RNR_OFFSET - (M33_MPU_CTRL_OFFSET + 16)] #if HARDENING sub lr, lr // we don't need lr and it is unlikely to be something that ww will read from memory if this is skipped - ldr r1, [r0, #M33_MPU_RNR_OFFSET - M33_MPU_CTRL_OFFSET] + ldr r1, [r0, #M33_MPU_RNR_OFFSET - (M33_MPU_CTRL_OFFSET + 16)] // RNR should read back as zero rcp_iequal_nodelay r1, lr #endif - adds r0, #8 + subs r0, #8 ldmia r6!, {r1, r2, r3, r4, r5, r8, r9, r10} stmia r0!, {r1, r2, r3, r4, r5, r8, r9, r10} #if HARDENING From 15f801849419664d7df26990e1b47424b39039f8 Mon Sep 17 00:00:00 2001 From: graham sanderson Date: Wed, 11 Jun 2025 15:36:53 -0500 Subject: [PATCH 7/8] add an extra rcp_check --- enc_bootloader/hard_entry_point.S | 3 +++ 1 file changed, 3 insertions(+) diff --git a/enc_bootloader/hard_entry_point.S b/enc_bootloader/hard_entry_point.S index 2a3f8557..a7508606 100644 --- a/enc_bootloader/hard_entry_point.S +++ b/enc_bootloader/hard_entry_point.S @@ -62,6 +62,9 @@ _reset_handler: rcp_iequal_nodelay r1, lr #endif subs r0, #8 +#ifdef HARDENING + rcp_iequal_nodelay lr, r1 +#endif ldmia r6!, {r1, r2, r3, r4, r5, r8, r9, r10} stmia r0!, {r1, r2, r3, r4, r5, r8, r9, r10} #if HARDENING From 5fac18166e994b66d33359151851017427bc4930 Mon Sep 17 00:00:00 2001 From: William Vinnicombe Date: Thu, 12 Jun 2025 11:32:20 +0100 Subject: [PATCH 8/8] Update precompiled ELFs --- enc_bootloader/enc_bootloader.elf | Bin 20144 -> 20128 bytes enc_bootloader/enc_bootloader_mbedtls.elf | Bin 30396 -> 30244 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/enc_bootloader/enc_bootloader.elf b/enc_bootloader/enc_bootloader.elf index f6cf6ed55bb18c8beb1799ef3a8a093b5868cbc1..804605507f43e0d66c6f3f37ea59dbe5e0d2d664 100755 GIT binary patch delta 2247 zcmZ9NeQZ-z6u{5x2ko}HwwuWYWwcEr1;$?A>%O`%M!OMR_dP=pC)$pUq|26A=5*6Y zx(`i8{6pr|g+Cyy8Udp*j0T19F~EdB)ES7H7$p%j5oM?a25WTdJm9eif@&SHA6PXM68=x`pq5?0LdJ68EZ9@$0HDJAdjKjdN;s zT&@19Gq0h&cRyOR%ni9$bw!hIU3<@o`*Ca4bjw^kr@eDk53R}UwDgdDR%ccNyS$E% z0C3(QdJB`;-kms(!NkPCz{JGS>3;wO&I=~&L)l&d?Tj{~-_RhOw1f=xs@YL(O~L`( z?5HLb+!bm|IE30;s@x^J_wJI)cRO4jO>WWE-VQs3b315%$njF2KN(Gy>D*23=E9H= zf+q`4O&f~^zu0(zvzWQ9z~Ii1*Ae3D;r>Ar#Lpy*_To?>9jC+NOdFeD4X&6Sg)0fo zh10?935RVoRCCL~V(T3So!wHuHgqX5DY!!Hm-W@w%(}^^-n?fT1DpDI{2b*(@?<#I zyA9edM8Wz;=F!3b*=G{QtU>{2-HsB4 zf{x_ypj|jpDALR}iS|esbrcTS<}u{1l__WF+O%ECs)xK6nNlFz??a{($$XI3BU3u) z%qWf&U6aIW_yk9ac$y>dIVva(kEabT;YcZv7tA12T4W}Njwh5Yb8tyvqs=%%PfCxnQeeUc~_r%k$aDR69xs>lF5RI8Q9w(*+vk z`Fzm8S~MVq(qLQ6T>Lj@-=T>72CP9Pmm$9uvzG?c<|Fu%jJsk>CF~d*_gEueE3{j& z%o@`*Nmi}MCI!EMoULGTvhER9uJ1+ror-ykBfPF)TpxK<0rI1uGN%KmE^xq>VyX)X z(@bTdWU8war?Mu!R7sIqPi2ytC&q{8WK$I`dsaFQIe71*=%*R~d68KT7U&dmE8{Ay zX1OLzn30>P9b_VEVja~j9GXmRd7GHN1-?WUMZPp8 zhWq=9OGUm+K>}a?kZ{)u5Tz5))Loojwk)7h6h&T4pC=)n9y{#Yo5>wu1&vlMCHnyL zH9E8uLl5gliDKN!#!;e34YC`JdF)D~VVN8lf}$o1vo#qc$(f#cw&??IEn94I;Md;l a5Gp^YX1R!(8&w{ delta 2200 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 F`d`q*OymFn delta 7531 zcmai3dw5jUwcmTroOvXZ$s`jX1k6k_AqnKcOu|dWa!4SMfaJ*|IFrnfAd`|p$U_Up zPIw5&Z57;#ARx5TR;l%aPN;A~&Cg9_M_2&N8JYdWp_nv&~ z?EPD>z4qQ~KhEUvKlzEz`A$23epiM=wihv$d#wEJ#IYrB4O?}rrm8OUX9t#`e)Y=s zb%%$Bt>?v5%epa!8*Fg5$_CjD_UgBn&l4YH7bh)~1NN)K)?5(Fu)L^z_4Cf`ikt;G z^UtVTEY)7_SNyZTm^8cEmsM`^DqsDw)8x%8=cUzn@A9U#N*TRh_RN}js`87TqO|7p ziX`vy){FXo{rNAe$Cqy!R5Y5wOPVS^$V$}=dx^JgUPzxMD__58TWBkHv>fuYyq8WT7WeUS;(gACClDe_E_1JvbBTycw5}-X&8K=?**EymkAs}|sH|`MDc;8KU_-;sEB$v&D&raR%i;tZ zT>dS~{cC^RK0YnYGfL&-_>>C8v{yTrsO2ipGwnJjzD&+2*A8h6RqBMQDmAyKO3kuM zQ}9+E3L50a3NLO|40(%G?E=$~*7Rw=_E~LNN4jxnxF~Vj(zN%JIN>q!Oi6-=x78 zm5WG^z^scsla#?%dg2_CmpN*TrCxqzlZFi$q#Y&2{gU65H}#@9ujyi3UUvVIyO)%+ zp+mZomc^Vm5g!&dot>={vn956ULU=7egFDpk91v$sjn`p?v% zkbJdDsc&n^2N>>+mrRZ`m(7mTm#g8h6m<6TT?_9*BYpB~Ep@7Pb+nNmDILma^CO;A zG@>hgxAze=qN7I29udD9Q|h(rq6lHgLmm4-N2cff>LfNdYMl_X#8jJmR2+=r7O0Uoa}$_^4dWg8$8KQbz>Gb zh;^fL9B=xUE7$xVsmsnRP&mrEPb!1HINgwwv+R%5`I|xFmC@ya3q9$_E({pzE)2vu zJ{&NB;!-|RFMa%O?*wxLlE)ZtxnAaHgFP2Mq>TPFxbv!XT92ve4@rZ*06?83<{DQmj#`dd6+?Bype}%FssH3UMe!=tCUeq)DkSs5F^n0&h(sU(2_EDl8|mtTUibKuDA< zVR+mq5ZSJ{q2W8^At$R+Q@g7M4EJcBL_T-hof1lC_wR;Sq87FMZW-^~ZXMoP-TEil zwKJh4i_0KC0mFXd-jCEbHhtV1Z+5Gh_GRedN9u`>k$JjW1-;5_0QdRIS_M5TS&Dk& zjh^eZibpxuE8Vo9JgZfZEFo5y$m-}FSSQe<8R%ddJL4r(-%g$>ZBT;3E28a0%P zSy0GQmV(`>Kw)-+YWHpq#>Xv1#%cEbWPT?m*Qi;p_!MbhWiYK-=lN%Ey`uGK_n9Aa zBSCb{u*%-*N!*2c7VQ#SJr~p|hk)jcHX9z_=4rgK<12aJR?j(1R)exNsK593Sk-~o zJ-U4W*)X5?x(BtgM6*TJ_x)$@>z+4z8>(S=53YwT(k9q@i)+!%j6;7z?qJgGl^F9=em%B*6tRAQ` zn6$b}dAGL#=|?`<6I+AvI?Vwri9AZ!HRyG`?#*6UFUZ1nlBKxSK!zo}kfr^!lzj^3 z3Hj@A`jmQw?Yq%Cj^-E(-{GXJb}L$pR=mzljXEe-ip*}xl2WpvOmQm*ROX~mXsy&L z@>8`6EqR)MYzoMsdeq+RtyQj~GnoN9MXNhN%jEkCJK)BAV|YXH>O))@FPMdBbJ}Q$ ztyfy0MGFmD7#Uh<6ROrn7Fvt)z-Qh6h2`}*=u^-D=+dy&@*7hb&rd2#E7QG~^0MW` z@YmmamELPlh^@D!2fm>D!i#gS&U60T(c!Ok-|$SS%$UKS-80YNkSh{~tUO8OMt-M8 zB345gzr<(W@wS9R|A78_zm#9_{)OJe{JBAS z0%-2E_YV(QOwy3uEDc#S`GbkN%Ha6%znxQJ8qh8-8PF`Y6t&M)MRB?#N0fZiZyJ=e z`Nz)nj-Nvg_k+`RvboG!#`3@DzkXRNODQ`g9!#%r)1{~PPs7%D7Je=QzY>Gr0scb_ zeh+w04E_N4SzuGdo-R)>0Ve?qhs|NPPqi00i>5NV&b~4{^S4!ztL@u^T_w{|e`cq` zHH;uilsO;=$fgy3TW;WOIR6B64J5(d3UYw#eZ$rjC{s|b zK?$Gi{`(obEgYDg_2`+?Ra87>>a^)IZuhNdYF>FSiN3rrY%MrDY^?`<30ot|XFv&{ zM?qbnm(L7aPeTvt$C|&@3wuReuCuVX03CA`I;R&*nP_(b7rLmcF6Xo&mp!+AW$Q{` z$I6LfZpHLKF=tF03Pj8EQJP-E%LwKd@On5TU`(TxTh??k$qcONA2S1mR;#yBVUS5j zYtXimBd+@`A#V5$6&g7}OpX34LRy(rVV6dQK|czG9MI~tTM2W+Nfi1Y!a&L}{s{GG z0DM0#6U^`f#NyZ-3egWD^oEF9lEEKg1 zp7KEP597rPliC7c-ix}In7;(zlar~rpMo9*#WgeT44I~2+LCGNblNt&8BgL9%+`3x zJkFfNlXaFc7@8~=AOF30$$&nL#%SFUe`oyd@#UBtZA5|rloO!@FI1FUe}Fz0@>ye} z$~j}pt>jKgeX?XMhb6{WGDIC|QZYB*VT}3r5;Pn)B~~fSiwEy!1e!2U>{>XAddv_Z z64;C|;xCMK(*BHVN>6_hIy>);2e@_i6zwUh)~!c{7^gF-4)`Ei&}(d`ab zsh~&@MJOQZKiZ+dD81ni@6Z#Ds1S8(LBcoILGlys4?xr;BnesEd`&`)j5u2yH9<9M zfNE5evjE3Ks?h<+0w@dF)>2Ucl307^L8>eYgYJXPsDwwprX5uxbcl-kK+xA7q)Ir3 znp-i{+=?O6&r;+bG{e2uv31NaoOUq8z-v4xG(C|$A-V>m@{vfXZK3Y!DrOIY$gB^IXY=)4^6fP%>*4gEF z-3#(KofYNen`MHufy=47*>XZro}5|$2Sqx2AygJZg@;rV5_K-wsGAmQYPnsOby7}F zp&SQn)D_^(i{u1pon1~H4~CRz*YQGWkzF#{C8kZ(;BGM=}M)o$igtaI+@ZV60+07e6c-1YvsMu;nAU0LxC=P?YlTSy3|oRRtQJ^&H|<@g9UaxGCt47#8Ck`;i!H+ zFkLSq`r>$9Qh76Y&&TMr0n_y(*5}a}pX(tf9QC;kn64@ok+68o-H!qNCPsP)m@YA~ z-d>9F_AAHoaOcx$HKDcmstbw!OP)3C{WOfml?r~B4H(|>m5!iH999fp`%OAm>6NAakvKUNmT4ONDJ4fJ0M&O@`z01alE%g>rSD%t;h%9y7 zQ9{XV8G%!-iXHXo{1@W6dYkL{5w4Doz%RvM3JpV8Zwvf=1h?}K-yOp47)(~|+;`JVyqEV;$maFDm~v$qC2G@g*3Q zA0s*8So!C-DepEebp`OTZCC=Lwx0_*E*TZx`#`HvWa!>$Zjd zV-Qk>?iA?8+Rh(=?*UeCb|sv^(X%dk`q0i1^+&PL?iuS$0J{yXVZu9r=}XTJoC!?x7d=`m$Yc}n`;gPdOZwx1 z&x8jHo9 zt8NoTtE|Qu5zY+ZTV*W{3EMi`UHCS46^C`H9#INOT!k)IRN^X}Ds29Ak>-z|UOeUY zLT6Y2z2d3P!s(I5P>ooG1g^qqQGu(lNOY_!9N+0{?+o2H3tdju?CbP3cC>6*SvZ5W z+*c^7{o9Mn>YS{s&IKw06|2Mh73TZFFq=$T*@327Q!;T!h$##6_OkOPNI~}}MJlL5dKU~4s zbdhwQRh;Ow$bAcNr4jv|j)KmGjM4rVeUP@H=g)XY>%=&OZ!Wu--C-T|_YsmlNKTXI zQG*eQlML`|tilfsVqKSY)Hgt}-coANYAEjKyDS=|M!edU%`b^hyK>~8twVB=yZ;4V CcS?o;