Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for creating self-decrypting binaries, and use 4-way AES key shares instead of just the AES key #207

Open
wants to merge 45 commits into
base: develop
Choose a base branch
from

Conversation

will-v-pi
Copy link
Contributor

@will-v-pi will-v-pi commented Feb 24, 2025

This adds support for creating self-decrypting binaries, which can be created using

picotool encrypt --sign --embed hello_world.elf hello_world.enc.elf my_aesfile.pem my_sigfile.pem my_otp.json

This introduces a breaking change to picotool encrypt to take a 4-way AES key share, rather than just taking an AES key, as this makes it simpler to mask the power signature when decrypting the binary. The only difference from a user perspective is that they now need to use a 1024 bit binary file instead of the 256 bit file used before. The AES key is derived from the 4-way share as follows:

aes_key.words[i] = aes_key_share.words[i*4]
                 ^ aes_key_share.words[i*4 + 1]
                 ^ aes_key_share.words[i*4 + 2]
                 ^ aes_key_share.words[i*4 + 3];

This also introduces a breaking change that picotool encrypt now requires an IV salt binary to be passed to it as the 4th file, so the signing_key is now the 5th file and the OTP JSON is now the 6th file.

This PR requires raspberrypi/pico-sdk#2233 so should be merged after that

The privateaes.bin key file is now 4x256bit numbers (A,B,C,D), and the AES key X is A^B^C^D
This is not required, as you can still load data outside of the region between the metadata blocks which contain the binary - for example, loading code into scratch memory.
You can now use `picotool encrypt --embed ...` to create a self-decrypting binary, using enc_bootloader
Add pico_minimize_runtime and some other runtime skips

Re-use scratch_y for the workarea, without overwriting the stack
Rejig everything to fit into scratch, so full 512k of SRAM is available for the user
Move vtor into main code body, leaving only binary info and embedded block at start

Reduce initial stack size, then increase after AES code to overwrite the workspace

Reduce vector table IRQs (requires pico-sdk pr 2200)
Uses a modified version of get_rand_32 temporarily, until the aes.S code is modified to use rom_get_boot_random

From commit d4f4b2a7d9f00
Add temporary workaround to clone SDK branch with support for PICO_MINIMAL_VECTOR_TABLE define
…n stage metadata

This means that the bootrom will treat the binary with embedded decryption stage the same as the non-encrypted binary, for rollback/versions/tbyb/etc
Allows specifying the OTP page the AES key is stored on
From commit 3d93bdd06c55
Now fits inside 2K, so moved to 0x20081800, giving more room for AES workspace
From commit 052dab85a9ac38
Now uses IV salt in OTP, and IV0_XOR is now enabled and fixed

From commit 627274d21a2d6a30
@will-v-pi will-v-pi marked this pull request as ready for review February 26, 2025 13:00
This will now fail CI checks until raspberrypi/pico-sdk#2233 is merged
From commit d831bb59
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

"ERROR: Found overlapping memory" on encrypted binary
1 participant