Skip to content

Add support for creating self-decrypting binaries #2315

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

Open
wants to merge 6 commits into
base: develop
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 98 additions & 10 deletions tools/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,30 @@ define_property(TARGET
BRIEF_DOCS "AES key for encrypting"
FULL_DOCS "AES key for encrypting"
)
define_property(TARGET
PROPERTY PICOTOOL_IVFILE
INHERITED
BRIEF_DOCS "IV OTP salt for encrypting"
FULL_DOCS "IV OTP salt for encrypting"
)
define_property(TARGET
PROPERTY PICOTOOL_EMBED_DECRYPTION
INHERITED
BRIEF_DOCS "Embed decryption stage into encrypted binary"
FULL_DOCS "Embed decryption stage into encrypted binary"
)
define_property(TARGET
PROPERTY PICOTOOL_USE_MBEDTLS_DECRYPTION
INHERITED
BRIEF_DOCS "Use MbedTLS based decryption stage - this is faster, but not secure against power snooping"
FULL_DOCS "Use MbedTLS based decryption stage - this is faster, but not secure against power snooping"
)
define_property(TARGET
PROPERTY PICOTOOL_OTP_KEY_PAGE
INHERITED
BRIEF_DOCS "OTP page storing the AES key"
FULL_DOCS "OTP page storing the AES key"
)
define_property(TARGET
PROPERTY PICOTOOL_ENC_SIGFILE
INHERITED
Expand Down Expand Up @@ -380,19 +404,58 @@ function(pico_embed_pt_in_binary TARGET PTFILE)
)
endfunction()

# pico_encrypt_binary(TARGET AESFILE [SIGFILE])
# pico_encrypt_binary(TARGET AESFILE IVFILE [SIGFILE <file>] [EMBED] [MBEDTLS] [OTP_KEY_PAGE <page>])
# Encrypt the target binary with the given AES key (should be a binary
# file containing 32 bytes of a random key), and sign the encrypted binary.
# This sets PICOTOOL_AESFILE to AESFILE, and PICOTOOL_ENC_SIGFILE to SIGFILE
# if present, else PICOTOOL_SIGFILE.
function(pico_encrypt_binary TARGET AESFILE)
# file containing 128 bytes of a random key), and sign the encrypted binary.
Comment on lines 408 to +409
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this is now a 128-byte file (key share) OR a 32 byte file (key) OR a 64-character hex string (key) ?

# Salts the public IV with the provided IVFILE (should be a binary file
# containing 16 bytes of a random IV), to give the IV used by the encryption.
Comment on lines +410 to +411
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And similarly I guess this is now a 16-byte file OR a 32-char hex string?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

...although I guess if you tried specifying a hex-string here that'd mess up the later pico_add_link_depend step!

# This sets PICOTOOL_AESFILE to AESFILE, PICOTOOL_IVFILE to IVFILE, and
# PICOTOOL_ENC_SIGFILE to SIGFILE if specified, else PICOTOOL_SIGFILE.
#
# Optionally, use EMBED to embed a decryption stage into the encrypted binary.
# This sets PICOTOOL_EMBED_DECRYPTION to TRUE.
#
# Optionally, use MBEDTLS to to use the MbedTLS based decryption stage - this
# is faster, but offers no security against power or timing sniffing attacks,
# and takes up more code size.
# This sets PICOTOOL_USE_MBEDTLS_DECRYPTION to TRUE.
#
# Optionally, use OTP_KEY_PAGE to specify the OTP page storing the AES key.
# This sets PICOTOOL_OTP_KEY_PAGE to OTP_KEY_PAGE.
function(pico_encrypt_binary TARGET AESFILE IVFILE)
set(options EMBED MBEDTLS)
set(oneValueArgs OTP_KEY_PAGE SIGFILE)
# set(multiValueArgs )
cmake_parse_arguments(PARSE_ARGV 3 ENC "${options}" "${oneValueArgs}" "${multiValueArgs}")
picotool_check_configurable(${TARGET})
set_target_properties(${TARGET} PROPERTIES
PICOTOOL_AESFILE ${AESFILE}
)
if (ARGC EQUAL 3)
set_target_properties(${TARGET} PROPERTIES
PICOTOOL_IVFILE ${IVFILE}
)

if (ENC_EMBED)
set_target_properties(${TARGET} PROPERTIES
PICOTOOL_ENC_SIGFILE ${ARGV2}
PICOTOOL_EMBED_DECRYPTION TRUE
)
endif()

if (ENC_MBEDTLS)
set_target_properties(${TARGET} PROPERTIES
PICOTOOL_USE_MBEDTLS_DECRYPTION TRUE
)
endif()

if (ENC_OTP_KEY_PAGE)
set_target_properties(${TARGET} PROPERTIES
PICOTOOL_OTP_KEY_PAGE ${ENC_OTP_KEY_PAGE}
)
endif()

if (ENC_SIGFILE)
set_target_properties(${TARGET} PROPERTIES
PICOTOOL_ENC_SIGFILE ${ENC_SIGFILE}
)
else()
get_target_property(enc_sig_file ${TARGET} PICOTOOL_ENC_SIGFILE)
Expand Down Expand Up @@ -507,6 +570,10 @@ function(picotool_postprocess_binary TARGET)
if (picotool_aesfile)
pico_add_link_depend(${TARGET} ${picotool_aesfile})
endif()
get_target_property(picotool_ivfile ${TARGET} PICOTOOL_IVFILE)
if (picotool_ivfile)
pico_add_link_depend(${TARGET} ${picotool_ivfile})
endif()
get_target_property(picotool_enc_sigfile ${TARGET} PICOTOOL_ENC_SIGFILE)
if (picotool_enc_sigfile)
pico_add_link_depend(${TARGET} ${picotool_enc_sigfile})
Expand Down Expand Up @@ -546,10 +613,31 @@ function(picotool_postprocess_binary TARGET)
VERBATIM)
endif()
# Encryption
if (picotool_aesfile)
if (picotool_aesfile AND picotool_ivfile)
get_target_property(picotool_embed_decryption ${TARGET} PICOTOOL_EMBED_DECRYPTION)
if (picotool_embed_decryption)
list(APPEND picotool_encrypt_args "--embed")
endif()

get_target_property(picotool_mbedtls_decryption ${TARGET} PICOTOOL_USE_MBEDTLS_DECRYPTION)
if (picotool_mbedtls_decryption)
list(APPEND picotool_encrypt_args "--use-mbedtls")
endif()

get_target_property(otp_key_page ${TARGET} PICOTOOL_OTP_KEY_PAGE)
if (otp_key_page)
list(APPEND picotool_encrypt_args "--otp-key-page" ${otp_key_page})
endif()

add_custom_command(TARGET ${TARGET} POST_BUILD
DEPENDS ${picotool_enc_sigfile} ${picotool_aesfile}
COMMAND picotool encrypt --quiet --hash --sign $<TARGET_FILE:${TARGET}> $<TARGET_FILE:${TARGET}> ${picotool_aesfile} ${picotool_enc_sigfile}
DEPENDS ${picotool_enc_sigfile} ${picotool_aesfile} ${picotool_ivfile}
COMMAND picotool
ARGS encrypt
--quiet --hash --sign
${picotool_encrypt_args}
$<TARGET_FILE:${TARGET}> $<TARGET_FILE:${TARGET}>
${picotool_aesfile} ${picotool_ivfile} ${picotool_enc_sigfile} ${otp_file}
COMMAND_EXPAND_LISTS
VERBATIM)
if (ARGC EQUAL 2)
set(${ARGV1} TRUE PARENT_SCOPE)
Expand Down
Loading