diff --git a/boot/mbed/CMakeLists.txt b/boot/mbed/CMakeLists.txt index 05199c380..66be70b6a 100644 --- a/boot/mbed/CMakeLists.txt +++ b/boot/mbed/CMakeLists.txt @@ -41,8 +41,10 @@ mcuboot_generate_signing_keys_file(${CMAKE_CURRENT_BINARY_DIR}/signing_keys.c) target_sources(${LIB_TARGET} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/signing_keys.c) if("MCUBOOT_ENCRYPT_RSA=1" IN_LIST MBED_CONFIG_DEFINITIONS) - mcuboot_generate_encryption_key_file(${CMAKE_CURRENT_BINARY_DIR}/enc_keys.c) - target_sources(${LIB_TARGET} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/enc_keys.c) + set(MCUBOOT_ENCRYPTION_PUBLIC_KEY_PATH ${CMAKE_CURRENT_BINARY_DIR}/enc_key_public.pem CACHE INTERNAL "Path to mcuboot encryption public key" FORCE) + mcuboot_generate_encryption_public_key_file(${MCUBOOT_ENCRYPTION_PUBLIC_KEY_PATH}) + mcuboot_generate_encryption_private_key_file(${CMAKE_CURRENT_BINARY_DIR}/enc_key_private.c) + target_sources(${LIB_TARGET} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/enc_key_private.c) endif() # The cross-dependency requires that bootutil have access to the mbed port's diff --git a/boot/mbed/mcuboot_imgtool.cmake b/boot/mbed/mcuboot_imgtool.cmake index 9760196fe..2e7fa5b73 100644 --- a/boot/mbed/mcuboot_imgtool.cmake +++ b/boot/mbed/mcuboot_imgtool.cmake @@ -62,13 +62,13 @@ function(_mcuboot_generate_image TARGET IMAGE_TYPE IMAGE_BASE_PATH) set(TARGET_HEX_FILE ${CMAKE_CURRENT_BINARY_DIR}/$.hex) # Grab header size - if(NOT "${MBED_CONFIG_DEFINITIONS}" MATCHES "MCUBOOT_HEADER_SIZE=(0x[0-9A-Fa-f]+)") + if(NOT "${MBED_CONFIG_DEFINITIONS}" MATCHES "MCUBOOT_HEADER_SIZE=((0x[0-9A-Fa-f]+)|([0-9]+))") message(FATAL_ERROR "Couldn't find MCUBOOT_HEADER_SIZE in Mbed configuration!") endif() set(HEADER_SIZE_HEX ${CMAKE_MATCH_1}) # Grab slot size - if(NOT "${MBED_CONFIG_DEFINITIONS}" MATCHES "MCUBOOT_SLOT_SIZE=(0x[0-9A-Fa-f]+)") + if(NOT "${MBED_CONFIG_DEFINITIONS}" MATCHES "MCUBOOT_SLOT_SIZE=((0x[0-9A-Fa-f]+)|([0-9]+))") message(FATAL_ERROR "Couldn't find MCUBOOT_SLOT_SIZE in Mbed configuration!") endif() set(SLOT_SIZE_HEX ${CMAKE_MATCH_1}) @@ -76,11 +76,12 @@ function(_mcuboot_generate_image TARGET IMAGE_TYPE IMAGE_BASE_PATH) get_property(objcopy GLOBAL PROPERTY ELF2BIN) if(${IMAGE_TYPE} STREQUAL "update" AND "MCUBOOT_ENCRYPT_RSA=1" IN_LIST MBED_CONFIG_DEFINITIONS) - set(IMGTOOL_EXTRA_ARGS --encrypt ${MCUBOOT_ENCRYPTION_KEY_ABSPATH}) + # MCUBOOT_ENCRYPTION_PUBLIC_KEY_PATH is set in CMakeLists.txt + set(IMGTOOL_EXTRA_ARGS --encrypt ${MCUBOOT_ENCRYPTION_PUBLIC_KEY_PATH}) elseif(${IMAGE_TYPE} STREQUAL "initial" AND "MCUBOOT_ENCRYPT_RSA=1" IN_LIST MBED_CONFIG_DEFINITIONS) # If encryption is enabled, generate unencrypted initial image which supports encryption. # See https://github.com/mbed-ce/mbed-os/issues/401#issuecomment-2567099213 - set(IMGTOOL_EXTRA_ARGS --clear) + set(IMGTOOL_EXTRA_ARGS --encrypt ${MCUBOOT_ENCRYPTION_PUBLIC_KEY_PATH} --clear) else() set(IMGTOOL_EXTRA_ARGS "") endif() @@ -88,7 +89,6 @@ function(_mcuboot_generate_image TARGET IMAGE_TYPE IMAGE_BASE_PATH) add_custom_command( TARGET ${TARGET} POST_BUILD - DEPENDS ${MCUBOOT_SIGNING_KEY_ABSPATH} COMMAND ${Python3_EXECUTABLE} -m imgtool.main sign @@ -115,6 +115,9 @@ function(_mcuboot_generate_image TARGET IMAGE_TYPE IMAGE_BASE_PATH) WORKING_DIRECTORY ${CMAKE_BINARY_DIR} VERBATIM ) + if("MCUBOOT_ENCRYPT_RSA=1" IN_LIST MBED_CONFIG_DEFINITIONS) + add_dependencies(${TARGET} mcuboot-gen-enc-public-key) + endif() endfunction(_mcuboot_generate_image) # @@ -141,7 +144,7 @@ function(mcuboot_generate_initial_image TARGET) # optional 2nd arg: initial imag # We need to be slightly creative here -- Mbed thinks that the application start address # is +
, but we actually want to upload to . # So we need to temporarily override MBED_UPLOAD_BASE_ADDR with an offset value - if(NOT "${MBED_CONFIG_DEFINITIONS}" MATCHES "MCUBOOT_HEADER_SIZE=(0x[0-9A-Fa-f]+)") + if(NOT "${MBED_CONFIG_DEFINITIONS}" MATCHES "MCUBOOT_HEADER_SIZE=((0x[0-9A-Fa-f]+)|([0-9]+))") message(FATAL_ERROR "Couldn't find MCUBOOT_HEADER_SIZE in Mbed configuration!") endif() set(HEADER_SIZE_HEX ${CMAKE_MATCH_1}) @@ -202,18 +205,43 @@ endfunction(mcuboot_generate_signing_keys_file) # Generate a C source file with the encryption private key in it at the given location. # The file should be added as a source file to a library built in the same directory. # -function(mcuboot_generate_encryption_key_file ENC_KEY_C_PATH) +function(mcuboot_generate_encryption_private_key_file ENC_PRIVATE_KEY_C_PATH) add_custom_command( - OUTPUT ${ENC_KEY_C_PATH} + OUTPUT ${ENC_PRIVATE_KEY_C_PATH} COMMAND ${Python3_EXECUTABLE} -m imgtool.main getpriv - --key ${MCUBOOT_SIGNING_KEY_ABSPATH} - > ${ENC_KEY_C_PATH} + --key ${MCUBOOT_ENCRYPTION_KEY_ABSPATH} + > ${ENC_PRIVATE_KEY_C_PATH} - DEPENDS ${MCUBOOT_SIGNING_KEY_ABSPATH} + DEPENDS ${MCUBOOT_ENCRYPTION_KEY_ABSPATH} COMMENT "Converting encryption key to C source..." WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} VERBATIM ) -endfunction(mcuboot_generate_encryption_key_file) \ No newline at end of file +endfunction(mcuboot_generate_encryption_private_key_file) + +# +# Generate a PEM file with the encryption public key in it +# This is a temporal file, should be stored in the build folder +# +function(mcuboot_generate_encryption_public_key_file ENC_PUBLIC_KEY_PATH) + add_custom_command( + OUTPUT ${ENC_PUBLIC_KEY_PATH} + COMMAND + ${Python3_EXECUTABLE} -m imgtool.main + getpub + --key ${MCUBOOT_ENCRYPTION_KEY_ABSPATH} + --encoding pem + > ${ENC_PUBLIC_KEY_PATH} + + DEPENDS ${MCUBOOT_ENCRYPTION_KEY_ABSPATH} + COMMENT "Extracting encryption public key to PEM format..." + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + VERBATIM + ) + # Custom target to ensure that public key gets generated + add_custom_target(mcuboot-gen-enc-public-key + ALL + DEPENDS ${ENC_PUBLIC_KEY_PATH}) +endfunction(mcuboot_generate_encryption_public_key_file) diff --git a/docs/encrypted_images.md b/docs/encrypted_images.md index ebc4f46ed..d343bccfe 100644 --- a/docs/encrypted_images.md +++ b/docs/encrypted_images.md @@ -157,14 +157,24 @@ Append it with the `--clear` flag to keep the image unencrypted and ready for us ## [Creating your keys with imgtool](#creating-your-keys-with-imgtool) -`imgtool` can generate keys by using `imgtool keygen -k -t `, - where type can be one of `rsa-2048`, `rsa-3072`, `ecdsa-p256` -or `ed25519`. This will generate a keypair or private key. - -To extract the public key in source file form, use -`imgtool getpub -k -e `, where `encoding` can be one of -`lang-c` or `lang-rust` (defaults to `lang-c`). To extract a public key in PEM -format, use `imgtool getpub -k -e pem`. +`imgtool` can be used to generate keys used for image encryption, similar to +how to generate keys for imaging signing: +``` +./scripts/imgtool.py keygen -k encryption-keys.pem -t rsa-2048 +``` +The type of keys to generate will depend on which type of encryption is supported. +For mbed-os and mbed-ce ports, only RSA is currently supported. + +Once an encryption key is generated, the next step is to extract the private key into +c format, and incorporate into your source files: +``` +./scripts/imgtool.py getpriv -k encryption-keys.pem -f openssl >> enc-key-priv.c +``` +The final step is to extract public key and pass it to `imgtool` during image signing +and encryption process. +``` +./scripts/imgtool.py getpub -k encryption-keys.pem -e pem -o enc-key-pub.pem +``` If using AES-KW, follow the steps in the next section to generate the required keys. diff --git a/docs/imgtool.md b/docs/imgtool.md index 958e1af15..6e669ce48 100644 --- a/docs/imgtool.md +++ b/docs/imgtool.md @@ -189,3 +189,13 @@ public key is incorporated into the bootloader). When the `full` option is used instead, the TLV area will contain the whole public key and thus the bootloader can be independent from the key(s). For more information on the additional requirements of this option, see the [design](design.md) document. + +The encryption key passed to `--encrypt` argument shall be derived from a +different key (not the sign key) per NIST recommendation, please refer to discussion +[here](https://github.com/mcu-tools/mcuboot/pull/2152#issuecomment-2581420713). Also +an extra tag `--clear` shall be provided to generate initial download images +that are not encrypted but support encryption during firmware upgrade, otherwise when +upgrading to encrypted images for the first time, an unencrypted image will be saved into +secondary slot, please refer to discussion [here](https://github.com/mcu-tools/mcuboot/issues/1555). +Please also refer to now partially updated documentation on [encrypted images](encrypted_images.md) +on how to generate and manage keys used for image encryption.