Skip to content

Commit 6613aa4

Browse files
Add support for creating self-decrypting binaries (#2315)
Note: this support is experimental until the next release Co-authored-by: graham sanderson <[email protected]>
1 parent 9fdfe11 commit 6613aa4

File tree

1 file changed

+112
-10
lines changed

1 file changed

+112
-10
lines changed

tools/CMakeLists.txt

Lines changed: 112 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,30 @@ define_property(TARGET
4141
BRIEF_DOCS "AES key for encrypting"
4242
FULL_DOCS "AES key for encrypting"
4343
)
44+
define_property(TARGET
45+
PROPERTY PICOTOOL_IVFILE
46+
INHERITED
47+
BRIEF_DOCS "IV OTP salt for encrypting"
48+
FULL_DOCS "IV OTP salt for encrypting"
49+
)
50+
define_property(TARGET
51+
PROPERTY PICOTOOL_EMBED_DECRYPTION
52+
INHERITED
53+
BRIEF_DOCS "Embed decryption stage into encrypted binary"
54+
FULL_DOCS "Embed decryption stage into encrypted binary"
55+
)
56+
define_property(TARGET
57+
PROPERTY PICOTOOL_USE_MBEDTLS_DECRYPTION
58+
INHERITED
59+
BRIEF_DOCS "Use MbedTLS based decryption stage - this is faster, but not secure against power snooping"
60+
FULL_DOCS "Use MbedTLS based decryption stage - this is faster, but not secure against power snooping"
61+
)
62+
define_property(TARGET
63+
PROPERTY PICOTOOL_OTP_KEY_PAGE
64+
INHERITED
65+
BRIEF_DOCS "OTP page storing the AES key"
66+
FULL_DOCS "OTP page storing the AES key"
67+
)
4468
define_property(TARGET
4569
PROPERTY PICOTOOL_ENC_SIGFILE
4670
INHERITED
@@ -428,25 +452,78 @@ function(pico_embed_pt_in_binary TARGET PTFILE)
428452
)
429453
endfunction()
430454

431-
# pico_encrypt_binary(TARGET AESFILE [SIGFILE])
455+
# pico_encrypt_binary(TARGET AESFILE IVFILE [SIGFILE <file>] [EMBED] [MBEDTLS] [OTP_KEY_PAGE <page>])
432456
# \brief_nodesc\ Encrypt the taget binary
433457
#
434458
# Encrypt the target binary with the given AES key (should be a binary
435-
# file containing 32 bytes of a random key), and sign the encrypted binary.
459+
# file containing 128 bytes of a random key share, or 32 bytes of a random key),
460+
# and sign the encrypted binary.
461+
#
462+
# Salts the public IV with the provided IVFILE (should be a binary file
463+
# containing 16 bytes of a random IV), to give the IV used by the encryption.
464+
#
465+
# This sets the target properties PICOTOOL_AESFILE to AESFILE, PICOTOOL_IVFILE to IVFILE, and
466+
# PICOTOOL_ENC_SIGFILE to SIGFILE if specified, else PICOTOOL_SIGFILE.
467+
#
468+
# Optionally, use EMBED to embed a decryption stage into the encrypted binary.
469+
# This sets the target property PICOTOOL_EMBED_DECRYPTION to TRUE.
470+
#
471+
# Optionally, use MBEDTLS to to use the MbedTLS based decryption stage - this
472+
# is faster, but offers no security against power or timing sniffing attacks,
473+
# and takes up more code size.
474+
# This sets the target property PICOTOOL_USE_MBEDTLS_DECRYPTION to TRUE.
436475
#
437-
# This sets the target properties PICOTOOL_AESFILE to AESFILE,
438-
# and PICOTOOL_ENC_SIGFILE to SIGFILE if present, else PICOTOOL_SIGFILE.
476+
# Optionally, use OTP_KEY_PAGE to specify the OTP page storing the AES key.
477+
# This sets the target property PICOTOOL_OTP_KEY_PAGE to OTP_KEY_PAGE.
439478
#
440479
# \param\ AESFILE The AES key file to use
480+
# \param\ IVFILE The IV file to use
441481
# \param\ SIGFILE The PEM signature file to use
442-
function(pico_encrypt_binary TARGET AESFILE)
482+
# \param\ EMBED Embed a decryption stage into the encrypted binary
483+
# \param\ MBEDTLS Use MbedTLS based decryption stage (faster, but less secure)
484+
# \param\ OTP_KEY_PAGE The OTP page storing the AES key
485+
function(pico_encrypt_binary TARGET AESFILE IVFILE)
486+
set(options EMBED MBEDTLS)
487+
set(oneValueArgs OTP_KEY_PAGE SIGFILE)
488+
# set(multiValueArgs )
489+
cmake_parse_arguments(PARSE_ARGV 3 ENC "${options}" "${oneValueArgs}" "${multiValueArgs}")
443490
picotool_check_configurable(${TARGET})
444491
set_target_properties(${TARGET} PROPERTIES
445492
PICOTOOL_AESFILE ${AESFILE}
446493
)
447-
if (ARGC EQUAL 3)
494+
set_target_properties(${TARGET} PROPERTIES
495+
PICOTOOL_IVFILE ${IVFILE}
496+
)
497+
498+
if (ENC_EMBED)
448499
set_target_properties(${TARGET} PROPERTIES
449-
PICOTOOL_ENC_SIGFILE ${ARGV2}
500+
PICOTOOL_EMBED_DECRYPTION TRUE
501+
)
502+
503+
# Embedded decryption stage only works with packaged binaries
504+
get_target_property(uf2_package_addr ${TARGET} PICOTOOL_UF2_PACKAGE_ADDR)
505+
if (NOT uf2_package_addr)
506+
set_target_properties(${TARGET} PROPERTIES
507+
PICOTOOL_UF2_PACKAGE_ADDR 0x10000000
508+
)
509+
endif()
510+
endif()
511+
512+
if (ENC_MBEDTLS)
513+
set_target_properties(${TARGET} PROPERTIES
514+
PICOTOOL_USE_MBEDTLS_DECRYPTION TRUE
515+
)
516+
endif()
517+
518+
if (ENC_OTP_KEY_PAGE)
519+
set_target_properties(${TARGET} PROPERTIES
520+
PICOTOOL_OTP_KEY_PAGE ${ENC_OTP_KEY_PAGE}
521+
)
522+
endif()
523+
524+
if (ENC_SIGFILE)
525+
set_target_properties(${TARGET} PROPERTIES
526+
PICOTOOL_ENC_SIGFILE ${ENC_SIGFILE}
450527
)
451528
else()
452529
get_target_property(enc_sig_file ${TARGET} PICOTOOL_ENC_SIGFILE)
@@ -563,6 +640,10 @@ function(picotool_postprocess_binary TARGET)
563640
if (picotool_aesfile)
564641
pico_add_link_depend(${TARGET} ${picotool_aesfile})
565642
endif()
643+
get_target_property(picotool_ivfile ${TARGET} PICOTOOL_IVFILE)
644+
if (picotool_ivfile)
645+
pico_add_link_depend(${TARGET} ${picotool_ivfile})
646+
endif()
566647
get_target_property(picotool_enc_sigfile ${TARGET} PICOTOOL_ENC_SIGFILE)
567648
if (picotool_enc_sigfile)
568649
pico_add_link_depend(${TARGET} ${picotool_enc_sigfile})
@@ -602,10 +683,31 @@ function(picotool_postprocess_binary TARGET)
602683
VERBATIM)
603684
endif()
604685
# Encryption
605-
if (picotool_aesfile)
686+
if (picotool_aesfile AND picotool_ivfile)
687+
get_target_property(picotool_embed_decryption ${TARGET} PICOTOOL_EMBED_DECRYPTION)
688+
if (picotool_embed_decryption)
689+
list(APPEND picotool_encrypt_args "--embed")
690+
endif()
691+
692+
get_target_property(picotool_mbedtls_decryption ${TARGET} PICOTOOL_USE_MBEDTLS_DECRYPTION)
693+
if (picotool_mbedtls_decryption)
694+
list(APPEND picotool_encrypt_args "--use-mbedtls")
695+
endif()
696+
697+
get_target_property(otp_key_page ${TARGET} PICOTOOL_OTP_KEY_PAGE)
698+
if (otp_key_page)
699+
list(APPEND picotool_encrypt_args "--otp-key-page" ${otp_key_page})
700+
endif()
701+
606702
add_custom_command(TARGET ${TARGET} POST_BUILD
607-
DEPENDS ${picotool_enc_sigfile} ${picotool_aesfile}
608-
COMMAND picotool encrypt --quiet --hash --sign $<TARGET_FILE:${TARGET}> $<TARGET_FILE:${TARGET}> ${picotool_aesfile} ${picotool_enc_sigfile}
703+
DEPENDS ${picotool_enc_sigfile} ${picotool_aesfile} ${picotool_ivfile}
704+
COMMAND picotool
705+
ARGS encrypt
706+
--quiet --hash --sign
707+
${picotool_encrypt_args}
708+
$<TARGET_FILE:${TARGET}> $<TARGET_FILE:${TARGET}>
709+
${picotool_aesfile} ${picotool_ivfile} ${picotool_enc_sigfile} ${otp_file}
710+
COMMAND_EXPAND_LISTS
609711
VERBATIM)
610712
if (ARGC EQUAL 2)
611713
set(${ARGV1} TRUE PARENT_SCOPE)

0 commit comments

Comments
 (0)