Skip to content

Commit 9f1578b

Browse files
committed
Add USE_MBEDTLS variant
This variant runs from xip_sram, and uses the MbedTLS AES code instead. This is much faster, but not secure against side channel attacks. Currently no way to enable it, but that can be added if it's going to be useful
1 parent 0bb5e6a commit 9f1578b

7 files changed

+379
-9
lines changed

enc_bootloader/CMakeLists.txt

+24-5
Original file line numberDiff line numberDiff line change
@@ -33,19 +33,39 @@ if (NOT USE_PRECOMPILED)
3333
# Encrypted Bootloader
3434
add_executable(enc_bootloader
3535
enc_bootloader.c
36-
aes.S
3736
)
3837

3938
target_link_libraries(enc_bootloader
4039
pico_stdlib
4140
)
4241

42+
if (USE_MBEDTLS)
43+
target_sources(enc_bootloader PRIVATE mbedtls_aes.c)
44+
45+
target_link_libraries(enc_bootloader pico_mbedtls)
46+
47+
target_compile_definitions(enc_bootloader PRIVATE
48+
PICO_STACK_SIZE=0x800
49+
# 0x20080000 -> 0x20081000 doesn't overlap the stack
50+
ROM_CHAIN_WORKSPACE=0x20080000)
51+
52+
target_include_directories(enc_bootloader PRIVATE ${CMAKE_CURRENT_LIST_DIR})
53+
54+
pico_set_linker_script(enc_bootloader ${CMAKE_CURRENT_LIST_DIR}/memmap_mbedtls.ld)
55+
else()
56+
target_sources(enc_bootloader PRIVATE aes.S)
57+
58+
target_compile_definitions(enc_bootloader PRIVATE
59+
PICO_STACK_SIZE=0x180
60+
# AES Code & workspace from 0x20080044 -> 0x20081604, so 0x20080200 -> 0x20081200 is inside that
61+
ROM_CHAIN_WORKSPACE=0x20080200)
62+
63+
pico_set_linker_script(enc_bootloader ${CMAKE_CURRENT_LIST_DIR}/memmap_enc_bootloader.ld)
64+
endif()
65+
4366
target_compile_definitions(enc_bootloader PRIVATE
44-
# increase startup delay for stability
45-
PICO_XOSC_STARTUP_DELAY_MULTIPLIER=64
4667
# use stack guards, as AES variables are written near the stack
4768
PICO_USE_STACK_GUARDS=1
48-
PICO_STACK_SIZE=0x180
4969
# The following are to reduce the size of the binary
5070
PICO_NO_PROGRAM_INFO=1
5171
# No spinlocks used
@@ -66,7 +86,6 @@ if (NOT USE_PRECOMPILED)
6686
pico_minimize_runtime(enc_bootloader)
6787

6888
pico_set_binary_type(enc_bootloader no_flash)
69-
pico_set_linker_script(enc_bootloader ${CMAKE_CURRENT_LIST_DIR}/memmap_enc_bootloader.ld)
7089
pico_add_dis_output(enc_bootloader)
7190
else()
7291
project(enc_bootloader C CXX ASM)

enc_bootloader/enc_bootloader.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ int main() {
192192

193193
// Chain into decrypted image
194194
rom_chain_image(
195-
(uint8_t*)0x20080200, // AES Code & workspace from 0x20080030 -> 0x20081500
195+
(uint8_t*)ROM_CHAIN_WORKSPACE,
196196
4 * 1024,
197197
data_start_addr,
198198
data_size

enc_bootloader/mbedtls_aes.c

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
#include <mbedtls/aes.h>
2+
#include "pico/stdlib.h"
3+
4+
extern void lock_key();
5+
6+
int mb_aes_crypt_ctr_xor(mbedtls_aes_context *ctx,
7+
size_t length,
8+
unsigned char iv0[16],
9+
unsigned char nonce_xor[16],
10+
unsigned char stream_block[16],
11+
const unsigned char *input,
12+
unsigned char *output)
13+
{
14+
int c;
15+
int ret = 0;
16+
size_t n = 0;
17+
uint32_t counter = 0;
18+
19+
assert(length == (uint32_t)length);
20+
21+
while (length--) {
22+
if (n == 0) {
23+
for (int i = 16; i > 0; i--) {
24+
nonce_xor[i-1] = iv0[i-1];
25+
if (i - (int)(16 - sizeof(counter)) > (int)0) {
26+
nonce_xor[i-1] ^= (unsigned char)(counter >> ((16-i)*8));
27+
}
28+
}
29+
30+
ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_xor, stream_block);
31+
if (ret != 0) {
32+
break;
33+
}
34+
counter++;
35+
}
36+
c = *input++;
37+
*output++ = (unsigned char) (c ^ stream_block[n]);
38+
39+
n = (n + 1) & 0x0F;
40+
}
41+
42+
return ret;
43+
}
44+
45+
void decrypt(uint8_t* key4way, uint8_t* IV_OTPsalt, uint8_t* IV_public, uint8_t(*buf)[16], int nblk) {
46+
mbedtls_aes_context aes;
47+
48+
uint32_t aes_key[8];
49+
uint32_t* key4waywords = (uint32_t*)key4way;
50+
// Key is stored as a 4-way share of each word, ie X[0] = A[0] ^ B[0] ^ C[0] ^ D[0], stored as A[0], B[0], C[0], D[0]
51+
for (int i=0; i < count_of(aes_key); i++) {
52+
aes_key[i] = key4waywords[i*4]
53+
^ key4waywords[i*4 + 1]
54+
^ key4waywords[i*4 + 2]
55+
^ key4waywords[i*4 + 3];
56+
}
57+
58+
uint8_t iv[16];
59+
for (int i=0; i < sizeof(iv); i++) {
60+
iv[i] = IV_OTPsalt[i] ^ IV_public[i];
61+
}
62+
63+
int len = nblk * 16;
64+
65+
mbedtls_aes_setkey_enc(&aes, (uint8_t*)aes_key, 256);
66+
67+
lock_key();
68+
69+
uint8_t xor_working_block[16] = {0};
70+
uint8_t stream_block[16] = {0};
71+
size_t nc_off = 0;
72+
mb_aes_crypt_ctr_xor(&aes, len, (uint8_t*)iv, xor_working_block, stream_block, (uint8_t*)buf, (uint8_t*)buf);
73+
}

enc_bootloader/mbedtls_config.h

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#ifndef _MBEDTLS_CONFIG_H
2+
#define _MBEDTLS_CONFIG_H
3+
4+
#define MBEDTLS_HAVE_ASM
5+
#define MBEDTLS_AES_C
6+
#define MBEDTLS_AES_ROM_TABLES
7+
// #define MBEDTLS_AES_FEWER_TABLES
8+
#define MBEDTLS_CIPHER_MODE_CTR
9+
10+
#endif

enc_bootloader/memmap_enc_bootloader.ld

+4
Original file line numberDiff line numberDiff line change
@@ -257,4 +257,8 @@ SECTIONS
257257

258258
/* todo assert on extra code */
259259
ASSERT(chaff==0x20081000, "Chaff array must be located at 0x20081000")
260+
261+
/* Provide symbols for picotool */
262+
__enc_bootloader_start = ORIGIN(RAM_START);
263+
__enc_bootloader_end = ORIGIN(RAM) + LENGTH(RAM);
260264
}

0 commit comments

Comments
 (0)