diff --git a/boot/boot_serial/include/boot_serial/boot_serial_encryption.h b/boot/boot_serial/include/boot_serial/boot_serial_encryption.h new file mode 100644 index 000000000..b7cf9ff55 --- /dev/null +++ b/boot/boot_serial/include/boot_serial/boot_serial_encryption.h @@ -0,0 +1,32 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2023 Nordic Semiconductor ASA + */ + +#ifndef H_BOOT_SERIAL_ENCRYPTION_ +#define H_BOOT_SERIAL_ENCRYPTION_ +#include "bootutil/fault_injection_hardening.h" + +/** + * Validate hash of a primary boot image doing on the fly decryption as well + * + * @param[in] fa_p flash area pointer + * @param[in] hdr boot image header pointer + * @param[in] buf buffer which is used for validating data + * @param[in] buf_size size of input buffer + * + * @return FIH_SUCCESS on success, error code otherwise + */ +fih_ret +boot_image_validate_encrypted(const struct flash_area *fa_p, + struct image_header *hdr, uint8_t *buf, + uint16_t buf_size); + +/** + * Handle an encrypted firmware in the main flash. + * This will decrypt the image inplace + */ +int boot_handle_enc_fw(const struct flash_area *flash_area); + +#endif diff --git a/boot/boot_serial/src/boot_serial.c b/boot/boot_serial/src/boot_serial.c index 7f6af91e3..cddf8e289 100644 --- a/boot/boot_serial/src/boot_serial.c +++ b/boot/boot_serial/src/boot_serial.c @@ -73,7 +73,7 @@ #endif #ifdef MCUBOOT_ENC_IMAGES -#include "single_loader.h" +#include "boot_serial/boot_serial_encryption.h" #endif #include "bootutil/boot_hooks.h" @@ -293,18 +293,16 @@ bs_list(char *buf, int len) if (FIH_EQ(fih_rc, FIH_BOOT_HOOK_REGULAR)) { #ifdef MCUBOOT_ENC_IMAGES - if (slot == 0 && IS_ENCRYPTED(&hdr)) { - /* Clear the encrypted flag we didn't supply a key - * This flag could be set if there was a decryption in place - * performed before. We will try to validate the image without - * decryption by clearing the flag in the heder. If - * still encrypted the validation will fail. - */ - hdr.ih_flags &= ~(ENCRYPTIONFLAGS); + if (IS_ENCRYPTED(&hdr)) { + FIH_CALL(boot_image_validate_encrypted, fih_rc, fap, + &hdr, tmpbuf, sizeof(tmpbuf)); + } else { +#endif + FIH_CALL(bootutil_img_validate, fih_rc, NULL, 0, &hdr, + fap, tmpbuf, sizeof(tmpbuf), NULL, 0, NULL); +#ifdef MCUBOOT_ENC_IMAGES } #endif - FIH_CALL(bootutil_img_validate, fih_rc, NULL, 0, &hdr, fap, tmpbuf, sizeof(tmpbuf), - NULL, 0, NULL); } } @@ -483,8 +481,17 @@ bs_set(char *buf, int len) fih_rc, image_index, 1); if (FIH_EQ(fih_rc, FIH_BOOT_HOOK_REGULAR)) { - FIH_CALL(bootutil_img_validate, fih_rc, NULL, 0, &hdr, fap, - tmpbuf, sizeof(tmpbuf), NULL, 0, NULL); +#ifdef MCUBOOT_ENC_IMAGES + if (IS_ENCRYPTED(&hdr)) { + FIH_CALL(boot_image_validate_encrypted, fih_rc, fap, + &hdr, tmpbuf, sizeof(tmpbuf)); + } else { +#endif + FIH_CALL(bootutil_img_validate, fih_rc, NULL, 0, &hdr, + fap, tmpbuf, sizeof(tmpbuf), NULL, 0, NULL); +#ifdef MCUBOOT_ENC_IMAGES + } +#endif } if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) { @@ -862,14 +869,23 @@ bs_upload(char *buf, int len) zcbor_map_end_encode(cbor_state, 10); boot_serial_output(); - flash_area_close(fap); #ifdef MCUBOOT_ENC_IMAGES - if (curr_off == img_size) { - /* Last sector received, now start a decryption on the image if it is encrypted*/ - rc = boot_handle_enc_fw(); + /* Check if this upload was for the primary slot */ +#if !defined(MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD) + if (flash_area_id_from_multi_image_slot(img_num, 0) == FLASH_AREA_IMAGE_PRIMARY(0)) +#else + if (flash_area_id_from_direct_image(img_num) == FLASH_AREA_IMAGE_PRIMARY(0)) +#endif + { + if (curr_off == img_size) { + /* Last sector received, now start a decryption on the image if it is encrypted */ + rc = boot_handle_enc_fw(fap); + } } -#endif //#ifdef MCUBOOT_ENC_IMAGES +#endif + + flash_area_close(fap); } #ifdef MCUBOOT_BOOT_MGMT_ECHO diff --git a/boot/boot_serial/src/boot_serial_encryption.c b/boot/boot_serial/src/boot_serial_encryption.c new file mode 100644 index 000000000..6201e6b69 --- /dev/null +++ b/boot/boot_serial/src/boot_serial_encryption.c @@ -0,0 +1,315 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2020-2023 Nordic Semiconductor ASA + * Copyright (c) 2020 Arm Limited + */ + +#include +#include "bootutil/image.h" +#include <../src/bootutil_priv.h> +#include "bootutil/bootutil_log.h" +#include "bootutil/bootutil_public.h" +#include "bootutil/fault_injection_hardening.h" +#include "bootutil/enc_key.h" + +#include "mcuboot_config/mcuboot_config.h" + +#ifdef MCUBOOT_ENC_IMAGES + +BOOT_LOG_MODULE_DECLARE(serial_encryption); + +fih_ret +boot_image_validate_encrypted(const struct flash_area *fa_p, + struct image_header *hdr, uint8_t *buf, + uint16_t buf_size) +{ + FIH_DECLARE(fih_rc, FIH_FAILURE); + + struct boot_loader_state boot_data; + struct boot_loader_state *state = &boot_data; + struct boot_status _bs; + struct boot_status *bs = &_bs; + uint8_t image_index; + int rc; + + memset(&boot_data, 0, sizeof(struct boot_loader_state)); + image_index = BOOT_CURR_IMG(state); + if(IS_ENCRYPTED(hdr)) { + rc = boot_enc_load(BOOT_CURR_ENC(state), image_index, hdr, fa_p, bs); + if (rc < 0) { + FIH_RET(fih_rc); + } + rc = flash_area_id_to_multi_image_slot(image_index, flash_area_get_id(fa_p)); + if (rc < 0) { + FIH_RET(fih_rc); + } + rc = boot_enc_set_key(BOOT_CURR_ENC(state), 1, bs); + if (rc < 0) { + FIH_RET(fih_rc); + } + } + FIH_CALL(bootutil_img_validate, fih_rc, BOOT_CURR_ENC(state), image_index, + hdr, fa_p, buf, buf_size, NULL, 0, NULL); + + FIH_RET(fih_rc); +} + +/* + * Compute the total size of the given image. Includes the size of + * the TLVs. + */ +static int +read_image_size(const struct flash_area *fa_p, + struct image_header *hdr, + uint32_t *size) +{ + struct image_tlv_info info; + uint32_t off; + uint32_t protect_tlv_size; + int rc; + + off = BOOT_TLV_OFF(hdr); + + if (flash_area_read(fa_p, off, &info, sizeof(info))) { + rc = BOOT_EFLASH; + goto done; + } + + protect_tlv_size = hdr->ih_protect_tlv_size; + if (info.it_magic == IMAGE_TLV_PROT_INFO_MAGIC) { + if (protect_tlv_size != info.it_tlv_tot) { + rc = BOOT_EBADIMAGE; + goto done; + } + + if (flash_area_read(fa_p, off + info.it_tlv_tot, &info, sizeof(info))) { + rc = BOOT_EFLASH; + goto done; + } + } else if (protect_tlv_size != 0) { + rc = BOOT_EBADIMAGE; + goto done; + } + + if (info.it_magic != IMAGE_TLV_INFO_MAGIC) { + rc = BOOT_EBADIMAGE; + goto done; + } + + *size = off + protect_tlv_size + info.it_tlv_tot; + rc = 0; + +done: + return rc; +} + +/** + * reads, decrypts in RAM & write back the decrypted image in the same region + * This function is NOT power failsafe since the image is decrypted in the RAM + * buffer. + * + * @param flash_area The ID of the source flash area. + * @param off_src The offset within the flash area to + * copy from. + * @param sz The number of bytes to copy. should match erase sector + * + * @return 0 on success; nonzero on failure. + */ +static int +decrypt_region_inplace(struct boot_loader_state *state, + const struct flash_area *fap, + struct image_header *hdr, + uint32_t off, uint32_t sz) +{ + uint32_t bytes_copied; + int chunk_sz; + int rc; + uint32_t tlv_off; + size_t blk_off; + uint16_t idx; + uint32_t blk_sz; + uint8_t image_index; + + uint8_t buf[sz] __attribute__((aligned)); + assert(sz <= sizeof buf); + + bytes_copied = 0; + while (bytes_copied < sz) { + if (sz - bytes_copied > sizeof buf) { + chunk_sz = sizeof buf; + } else { + chunk_sz = sz - bytes_copied; + } + + rc = flash_area_read(fap, off + bytes_copied, buf, chunk_sz); + if (rc != 0) { + return BOOT_EFLASH; + } + + image_index = BOOT_CURR_IMG(state); + if (IS_ENCRYPTED(hdr)) { + blk_sz = chunk_sz; + idx = 0; + if (off + bytes_copied < hdr->ih_hdr_size) { + /* do not decrypt header */ + if (hdr->ih_hdr_size > (off + bytes_copied + chunk_sz)) { + /* all bytes in header, skip decryption */ + blk_sz = 0; + } + else { + blk_sz = off + bytes_copied + chunk_sz - hdr->ih_hdr_size; + } + + blk_off = 0; + idx = hdr->ih_hdr_size; + } else { + blk_off = ((off + bytes_copied) - hdr->ih_hdr_size) & 0xf; + } + tlv_off = BOOT_TLV_OFF(hdr); + if (off + bytes_copied + chunk_sz > tlv_off) { + /* do not decrypt TLVs */ + if (off + bytes_copied >= tlv_off) { + blk_sz = 0; + } else { + blk_sz = tlv_off - (off + bytes_copied); + } + } + boot_encrypt(BOOT_CURR_ENC(state), image_index, fap, + (off + bytes_copied + idx) - hdr->ih_hdr_size, blk_sz, + blk_off, &buf[idx]); + } + rc = flash_area_erase(fap, off + bytes_copied, chunk_sz); + if (rc != 0) { + return BOOT_EFLASH; + } + rc = flash_area_write(fap, off + bytes_copied, buf, chunk_sz); + if (rc != 0) { + return BOOT_EFLASH; + } + + bytes_copied += chunk_sz; + + MCUBOOT_WATCHDOG_FEED(); + } + + return 0; +} + +/** + * Check if a image was encrypted into the first slot, and decrypt it + * in place. this operation is not power failsafe. + * + * The operation is done by checking the last flash sector, and using it as a + * temporarely scratch partition. The + * + * @param[in] fa_p flash area pointer + * @param[in] hdr boot image header pointer + * + * @return FIH_SUCCESS on success, error code otherwise + */ +inline static fih_ret +decrypt_image_inplace(const struct flash_area *fa_p, + struct image_header *hdr) +{ + FIH_DECLARE(fih_rc, FIH_FAILURE); + int rc; + struct boot_loader_state boot_data; + struct boot_loader_state *state = &boot_data; + struct boot_status _bs; + struct boot_status *bs = &_bs; + size_t size; + size_t sect_size; + size_t sect_count; + size_t sect; + uint8_t image_index; + struct flash_sector sector; + + memset(&boot_data, 0, sizeof(struct boot_loader_state)); + memset(&_bs, 0, sizeof(struct boot_status)); + + /* Get size from last sector to know page/sector erase size */ + rc = flash_area_get_sector(fa_p, boot_status_off(fa_p), §or); + + + image_index = BOOT_CURR_IMG(state); + + if(IS_ENCRYPTED(hdr)) { +#if 0 //Skip this step?, the image will just not boot if it's not decrypted properly + static uint8_t tmpbuf[BOOT_TMPBUF_SZ]; + /* First check if the encrypted image is a good image before decrypting */ + FIH_CALL(boot_image_validate_encrypted,fih_rc,fa_p,&_hdr,tmpbuf,BOOT_TMPBUF_SZ); + if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) { + FIH_RET(fih_rc); + } +#endif + memset(&boot_data, 0, sizeof(struct boot_loader_state)); + /* Load the encryption keys into cache */ + rc = boot_enc_load(BOOT_CURR_ENC(state), image_index, hdr, fa_p, bs); + if (rc < 0) { + FIH_RET(fih_rc); + } + if (rc == 0 && boot_enc_set_key(BOOT_CURR_ENC(state), 0, bs)) { + FIH_RET(fih_rc); + } + } + else + { + /* Expected encrypted image! */ + FIH_RET(fih_rc); + } + + uint32_t src_size = 0; + rc = read_image_size(fa_p,hdr, &src_size); + if (rc != 0) { + FIH_RET(fih_rc); + } + + /* TODO: This assumes every sector has an equal size, should instead use + * flash_area_get_sectors() to get the size of each sector and iterate + * over it. + */ + sect_size = sector.fs_size; + sect_count = fa_p->fa_size / sect_size; + for (sect = 0, size = 0; size < src_size && sect < sect_count; sect++) { + rc = decrypt_region_inplace(state, fa_p,hdr, size, sect_size); + if (rc != 0) { + FIH_RET(fih_rc); + } + size += sect_size; + } + + fih_rc = FIH_SUCCESS; + FIH_RET(fih_rc); +} + +int +boot_handle_enc_fw(const struct flash_area *flash_area) +{ + int rc = -1; + struct image_header _hdr = { 0 }; + FIH_DECLARE(fih_rc, FIH_FAILURE); + + rc = boot_image_load_header(flash_area, &_hdr); + if (rc != 0) { + goto out; + } + + if (IS_ENCRYPTED(&_hdr)) { + //encrypted, we need to decrypt in place + FIH_CALL(decrypt_image_inplace,fih_rc,flash_area,&_hdr); + if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) { + rc = -1; + goto out; + } + } + else + { + rc = 0; + } + +out: + return rc; +} + +#endif diff --git a/boot/bootutil/include/bootutil/bootutil_public.h b/boot/bootutil/include/bootutil/bootutil_public.h index 90b1a1c9c..e8d83a1d2 100644 --- a/boot/bootutil/include/bootutil/bootutil_public.h +++ b/boot/bootutil/include/bootutil/bootutil_public.h @@ -43,6 +43,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { @@ -294,6 +295,18 @@ boot_read_swap_state(const struct flash_area *fa, int boot_set_next(const struct flash_area *fa, bool active, bool confirm); +/** + * Attempts to load image header from flash; verifies flash header fields. + * + * @param[in] fa_p flash area pointer + * @param[out] hdr buffer for image header + * + * @return 0 on success, error code otherwise + */ +int +boot_image_load_header(const struct flash_area *fa_p, + struct image_header *hdr); + #ifdef __cplusplus } #endif diff --git a/boot/bootutil/src/bootutil_public.c b/boot/bootutil/src/bootutil_public.c index f245739b6..8e7008646 100644 --- a/boot/bootutil/src/bootutil_public.c +++ b/boot/bootutil/src/bootutil_public.c @@ -643,3 +643,36 @@ boot_set_confirmed(void) { return boot_set_confirmed_multi(0); } + +int +boot_image_load_header(const struct flash_area *fa_p, + struct image_header *hdr) +{ + uint32_t size; + int rc = flash_area_read(fa_p, 0, hdr, sizeof *hdr); + + if (rc != 0) { + rc = BOOT_EFLASH; + BOOT_LOG_ERR("Failed reading image header"); + return BOOT_EFLASH; + } + + if (hdr->ih_magic != IMAGE_MAGIC) { + BOOT_LOG_ERR("Bad image magic 0x%lx", (unsigned long)hdr->ih_magic); + + return BOOT_EBADIMAGE; + } + + if (hdr->ih_flags & IMAGE_F_NON_BOOTABLE) { + BOOT_LOG_ERR("Image not bootable"); + + return BOOT_EBADIMAGE; + } + + if (!boot_u32_safe_add(&size, hdr->ih_img_size, hdr->ih_hdr_size) || + size >= flash_area_get_size(fa_p)) { + return BOOT_EBADIMAGE; + } + + return 0; +} diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index d9d474e57..d15977e77 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -130,7 +130,7 @@ zephyr_library_sources( ) endif() -if(CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256 OR CONFIG_BOOT_ENCRYPT_EC256 OR CONFIG_BOOT_SERIAL_ENCRYPT_EC256) +if(CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256 OR CONFIG_BOOT_ENCRYPT_EC256) zephyr_library_include_directories( ${MBEDTLS_ASN1_DIR}/include ) @@ -219,7 +219,7 @@ elseif(CONFIG_BOOT_SIGNATURE_TYPE_ED25519 OR CONFIG_BOOT_ENCRYPT_X25519) ) endif() -if(CONFIG_BOOT_ENCRYPT_EC256 OR CONFIG_BOOT_ENCRYPT_X25519 OR CONFIG_BOOT_SERIAL_ENCRYPT_EC256) +if(CONFIG_BOOT_ENCRYPT_EC256 OR CONFIG_BOOT_ENCRYPT_X25519) zephyr_library_sources( ${TINYCRYPT_DIR}/source/aes_encrypt.c ${TINYCRYPT_DIR}/source/aes_decrypt.c @@ -248,6 +248,12 @@ if(CONFIG_MCUBOOT_SERIAL) CONFIG_BOOT_ERASE_PROGRESSIVELY ${BOOT_DIR}/bootutil/src ) + + if(CONFIG_BOOT_ENCRYPT_IMAGE) + zephyr_library_sources( + ${BOOT_DIR}/boot_serial/src/boot_serial_encryption.c + ) + endif() endif() if(NOT CONFIG_BOOT_SIGNATURE_KEY_FILE STREQUAL "") diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 41daac8de..e8b630986 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -77,6 +77,7 @@ config BOOT_SIGNATURE_TYPE_RSA bool "RSA signatures" select BOOT_USE_MBEDTLS select MBEDTLS + select BOOT_ENCRYPTION_SUPPORT if BOOT_SIGNATURE_TYPE_RSA config BOOT_SIGNATURE_TYPE_RSA_LEN @@ -87,6 +88,7 @@ endif config BOOT_SIGNATURE_TYPE_ECDSA_P256 bool "Elliptic curve digital signatures with curve P-256" + select BOOT_ENCRYPTION_SUPPORT if BOOT_SIGNATURE_TYPE_ECDSA_P256 choice BOOT_ECDSA_IMPLEMENTATION @@ -109,6 +111,7 @@ endif config BOOT_SIGNATURE_TYPE_ED25519 bool "Edwards curve digital signatures using ed25519" + select BOOT_ENCRYPTION_SUPPORT if BOOT_SIGNATURE_TYPE_ED25519 choice BOOT_ED25519_IMPLEMENTATION @@ -300,45 +303,57 @@ config BOOT_SWAP_SAVE_ENCTLV JTAG/SWD or primary slot in external flash). If unsure, leave at the default value. -config BOOT_ENCRYPT_IMAGE +endif # !SINGLE_APPLICATION_SLOT + +config BOOT_ENCRYPTION_SUPPORT bool help - Hidden option used to check if any image encryption is enabled. + Hidden option used to check if image encryption is supported. -config BOOT_ENCRYPT_RSA - bool "Support for encrypted upgrade images using RSA" - select BOOT_ENCRYPT_IMAGE +config BOOT_ENCRYPT_IMAGE + bool "Support for encrypted image updates" + depends on BOOT_ENCRYPTION_SUPPORT + select BOOT_ENCRYPT_RSA if BOOT_SIGNATURE_TYPE_RSA + select BOOT_ENCRYPT_EC256 if BOOT_SIGNATURE_TYPE_ECDSA_P256 + select BOOT_ENCRYPT_X25519 if BOOT_SIGNATURE_TYPE_ED25519 + depends on !SINGLE_APPLICATION_SLOT || MCUBOOT_SERIAL help If y, images in the secondary slot can be encrypted and are decrypted on the fly when upgrading to the primary slot, as well as encrypted back when swapping from the primary slot to the secondary slot. The - encryption mechanism used in this case is RSA-OAEP (2048 bits). + encryption mechanism must match the same type as the signature type, + supported types include: + - RSA-OAEP (2048 bits). + - ECIES using primitives described under "ECIES-P256 encryption" in + docs/encrypted_images.md. + - ECIES using primitives described under "ECIES-X25519 encryption" + in docs/encrypted_images.md. + + Note that for single slot operation, this can still be used to allow + loading encrypted images via serial recovery which are then + decrypted on-the-fly without needing a second slot. + +config BOOT_ENCRYPT_RSA + bool + help + Hidden option selecting RSA encryption. config BOOT_ENCRYPT_EC256 - bool "Support for encrypted upgrade images using ECIES-P256" - select BOOT_ENCRYPT_IMAGE + bool help - If y, images in the secondary slot can be encrypted and are decrypted - on the fly when upgrading to the primary slot, as well as encrypted - back when swapping from the primary slot to the secondary slot. The - encryption mechanism used in this case is ECIES using primitives - described under "ECIES-P256 encryption" in docs/encrypted_images.md. + Hidden option selecting EC256 encryption. config BOOT_ENCRYPT_X25519 - bool "Support for encrypted upgrade images using ECIES-X25519" - select BOOT_ENCRYPT_IMAGE + bool help - If y, images in the secondary slot can be encrypted and are decrypted - on the fly when upgrading to the primary slot, as well as encrypted - back when swapping from the primary slot to the secondary slot. The - encryption mechanism used in this case is ECIES using primitives - described under "ECIES-X25519 encryption" in docs/encrypted_images.md. -endif # !SINGLE_APPLICATION_SLOT + Hidden option selecting x25519 encryption. config BOOT_ENCRYPTION_KEY_FILE - string "encryption key file" - depends on BOOT_ENCRYPT_EC256 || BOOT_SERIAL_ENCRYPT_EC256 - default "enc-ec256-priv.pem" if BOOT_SIGNATURE_TYPE_ECDSA_P256 + string "Encryption key file" + depends on BOOT_ENCRYPT_IMAGE + default "enc-rsa2048-priv.pem" if BOOT_ENCRYPT_RSA + default "enc-ec256-priv.pem" if BOOT_ENCRYPT_EC256 + default "enc-x25519-priv.pem" if BOOT_ENCRYPT_X25519 default "" help You can use either absolute or relative path. diff --git a/boot/zephyr/Kconfig.serial_recovery b/boot/zephyr/Kconfig.serial_recovery index 4d8f92f09..52ec3b013 100644 --- a/boot/zephyr/Kconfig.serial_recovery +++ b/boot/zephyr/Kconfig.serial_recovery @@ -48,6 +48,7 @@ endchoice config MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD bool "Allow to select image number for DFU" + depends on !SINGLE_APPLICATION_SLOT help With the option enabled, the mcuboot serial recovery will respect the "image" field in mcumgr image update frame @@ -135,15 +136,6 @@ config BOOT_MGMT_CUSTOM_IMG_LIST endif # ENABLE_MGMT_PERUSER -config BOOT_SERIAL_ENCRYPT_EC256 - bool "Support for encrypted upgrade images using ECIES-P256 in serial recovery upload" - default n - help - If y, uploaded images via serial recovery can be decrypted - on the fly when upgrading to the primary slot. The - encryption mechanism used in this case is ECIES using primitives - described under "ECIES-P256 encryption" in docs/encrypted_images.md. - menu "Entrance methods" menuconfig BOOT_SERIAL_ENTRANCE_GPIO diff --git a/boot/zephyr/include/mcuboot-mbedtls-cfg.h b/boot/zephyr/include/mcuboot-mbedtls-cfg.h index 02bf0b082..2bab537d7 100644 --- a/boot/zephyr/include/mcuboot-mbedtls-cfg.h +++ b/boot/zephyr/include/mcuboot-mbedtls-cfg.h @@ -25,7 +25,6 @@ #include "config-rsa.h" #elif defined(CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256) || \ defined(CONFIG_BOOT_ENCRYPT_EC256) || \ - defined(CONFIG_BOOT_SERIAL_ENCRYPT_EC256) || \ (defined(CONFIG_BOOT_ENCRYPT_X25519) && !defined(CONFIG_BOOT_SIGNATURE_TYPE_ED25519)) #include "config-asn1.h" #elif defined(CONFIG_BOOT_SIGNATURE_TYPE_ED25519) diff --git a/boot/zephyr/include/mcuboot_config/mcuboot_config.h b/boot/zephyr/include/mcuboot_config/mcuboot_config.h index 31cd9160b..e20003bb6 100644 --- a/boot/zephyr/include/mcuboot_config/mcuboot_config.h +++ b/boot/zephyr/include/mcuboot_config/mcuboot_config.h @@ -117,11 +117,6 @@ #define MCUBOOT_ENCRYPT_EC256 #endif -#ifdef CONFIG_BOOT_SERIAL_ENCRYPT_EC256 -#define MCUBOOT_ENC_IMAGES -#define MCUBOOT_ENCRYPT_EC256 -#endif - #ifdef CONFIG_BOOT_ENCRYPT_X25519 #define MCUBOOT_ENC_IMAGES #define MCUBOOT_ENCRYPT_X25519 diff --git a/boot/zephyr/include/single_loader.h b/boot/zephyr/include/single_loader.h deleted file mode 100644 index 347fa098f..000000000 --- a/boot/zephyr/include/single_loader.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - * - * Copyright (c) 2021-2021 Crodeon Technologies - * - */ - -#ifndef H_SINGLE_LOADER_ -#define H_SINGLE_LOADER_ -#include "bootutil/fault_injection_hardening.h" - -/** - * Handle an encrypted firmware in the main flash. - * This will decrypt the image inplace - */ -int boot_handle_enc_fw(); - -fih_ret boot_image_validate(const struct flash_area *fa_p, - struct image_header *hdr); -#endif diff --git a/boot/zephyr/keys.c b/boot/zephyr/keys.c index b7a9edf79..ab403ddc3 100644 --- a/boot/zephyr/keys.c +++ b/boot/zephyr/keys.c @@ -29,19 +29,19 @@ #include #if !defined(MCUBOOT_HW_KEY) -#if defined(MCUBOOT_SIGN_RSA) +#if defined(MCUBOOT_SIGN_RSA) || defined(MCUBOOT_SIGN_EC256) || defined(MCUBOOT_SIGN_ED25519) #define HAVE_KEYS +#if defined(MCUBOOT_SIGN_RSA) extern const unsigned char rsa_pub_key[]; extern unsigned int rsa_pub_key_len; #elif defined(MCUBOOT_SIGN_EC256) -#define HAVE_KEYS extern const unsigned char ecdsa_pub_key[]; extern unsigned int ecdsa_pub_key_len; #elif defined(MCUBOOT_SIGN_ED25519) -#define HAVE_KEYS extern const unsigned char ed25519_pub_key[]; extern unsigned int ed25519_pub_key_len; #endif +#endif /* * NOTE: *_pub_key and *_pub_key_len are autogenerated based on the provided @@ -76,134 +76,13 @@ struct bootutil_key bootutil_keys[1] = { const int bootutil_key_cnt = 1; #endif /* !MCUBOOT_HW_KEY */ -#if defined(MCUBOOT_ENCRYPT_RSA) -unsigned char enc_priv_key[] = { - 0x30, 0x82, 0x04, 0xa4, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, - 0xb4, 0x26, 0x14, 0x49, 0x3d, 0x16, 0x13, 0x3a, 0x6d, 0x9c, 0x84, 0xa9, - 0x8b, 0x6a, 0x10, 0x20, 0x61, 0xef, 0x48, 0x04, 0xa4, 0x4b, 0x24, 0xf3, - 0x00, 0x32, 0xac, 0x22, 0xe0, 0x30, 0x27, 0x70, 0x18, 0xe5, 0x55, 0xc8, - 0xb8, 0x05, 0x34, 0x03, 0xb0, 0xf8, 0xa5, 0x96, 0xd2, 0x48, 0x58, 0xef, - 0x70, 0xb0, 0x09, 0xdb, 0xe3, 0x58, 0x62, 0xef, 0x99, 0x63, 0x01, 0xb2, - 0x89, 0xc4, 0xb3, 0xf6, 0x9e, 0x62, 0xbf, 0x4d, 0xc2, 0x8a, 0xd0, 0xc9, - 0x4d, 0x43, 0xa3, 0xd8, 0xe5, 0x1d, 0xec, 0x62, 0x63, 0x08, 0xe2, 0x20, - 0xa5, 0xfc, 0x78, 0xd0, 0x3e, 0x74, 0xc8, 0xa4, 0x1b, 0x36, 0xad, 0x7b, - 0xf5, 0x06, 0xae, 0x4d, 0x51, 0x9b, 0x40, 0xce, 0x30, 0x4f, 0x6c, 0xea, - 0xf9, 0xe9, 0x74, 0xea, 0x06, 0xee, 0x9c, 0xe4, 0x14, 0x68, 0x20, 0xb9, - 0x3d, 0xe7, 0x11, 0x14, 0x8b, 0x25, 0xa3, 0xff, 0x4c, 0x8a, 0xf3, 0x53, - 0xee, 0x6b, 0x3e, 0xef, 0x34, 0xcd, 0x6a, 0x3f, 0x62, 0x68, 0xc0, 0xff, - 0x78, 0x4c, 0xb0, 0xc3, 0xe6, 0x96, 0x61, 0xfc, 0x1f, 0x18, 0xf1, 0x7a, - 0x82, 0xe2, 0x8f, 0x35, 0xa8, 0x2b, 0x86, 0x16, 0xa4, 0x46, 0xfb, 0xac, - 0x7e, 0x41, 0xdb, 0x02, 0x05, 0x91, 0x6d, 0xdf, 0xc1, 0xde, 0x13, 0x95, - 0x9c, 0xf9, 0x9e, 0x5e, 0x72, 0xba, 0xa7, 0x25, 0x93, 0xfb, 0xdc, 0xe8, - 0xab, 0x86, 0x45, 0x88, 0x47, 0x2d, 0xed, 0xee, 0xee, 0x97, 0x9e, 0xce, - 0x5d, 0x9b, 0x04, 0x04, 0x40, 0x7c, 0xcb, 0x7c, 0x3d, 0x2c, 0x74, 0xab, - 0xa4, 0xcc, 0x64, 0xa3, 0x5c, 0x95, 0x3d, 0xd4, 0xa2, 0xdc, 0x92, 0xb2, - 0xc8, 0x18, 0xcb, 0xf9, 0x00, 0x39, 0x81, 0x8f, 0x8f, 0x40, 0xc2, 0xdf, - 0x99, 0x29, 0xac, 0x8a, 0xc2, 0x3b, 0xd8, 0xa4, 0xf2, 0xad, 0xaf, 0x74, - 0xc0, 0x11, 0xc7, 0x99, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x01, - 0x00, 0x42, 0x47, 0x80, 0x4f, 0x31, 0xda, 0x5d, 0x58, 0xb1, 0xdb, 0x54, - 0x33, 0xcc, 0xc7, 0x49, 0x07, 0xa1, 0x00, 0x98, 0x4e, 0x9c, 0xe3, 0xc8, - 0xc4, 0x5e, 0xde, 0x45, 0xd6, 0xcf, 0x04, 0xe8, 0x7d, 0xa5, 0xab, 0x3a, - 0xd4, 0x8e, 0x5f, 0xdb, 0xb3, 0x3f, 0xf9, 0x3b, 0x73, 0x32, 0x0a, 0xcc, - 0x2d, 0xcc, 0x17, 0xf8, 0x88, 0x9e, 0x2c, 0x76, 0xba, 0x10, 0x85, 0x0c, - 0xaa, 0xd3, 0x65, 0x3b, 0x91, 0x10, 0xd4, 0xe3, 0xed, 0x88, 0x15, 0xea, - 0x9b, 0x25, 0x82, 0x2d, 0x56, 0x2f, 0x75, 0xc2, 0xf2, 0xaf, 0xdd, 0x24, - 0xd5, 0x3e, 0x3c, 0x95, 0x76, 0x88, 0x84, 0x0f, 0x0d, 0xd1, 0xb5, 0x5c, - 0x3e, 0xae, 0xf7, 0xb6, 0x49, 0x5c, 0x2c, 0xf2, 0xba, 0xe9, 0xab, 0x4f, - 0x37, 0x64, 0x9b, 0x30, 0x18, 0xaa, 0x54, 0x40, 0x04, 0xea, 0x3d, 0x25, - 0x4d, 0x02, 0x29, 0x71, 0x6f, 0x4d, 0x82, 0x9b, 0xc3, 0x44, 0x2a, 0x9d, - 0x0c, 0x98, 0xd3, 0xc8, 0x15, 0x0d, 0x04, 0x93, 0x60, 0x30, 0xc7, 0x5e, - 0x79, 0xea, 0x53, 0x9d, 0xc0, 0x0e, 0x81, 0xac, 0x90, 0xbc, 0x9e, 0x1e, - 0xd2, 0x28, 0x0f, 0x10, 0xf5, 0x1f, 0xdf, 0x38, 0x7f, 0x8a, 0x90, 0x8d, - 0x49, 0x07, 0x7d, 0x78, 0xcb, 0xa7, 0xef, 0x92, 0x6d, 0x3b, 0x13, 0x95, - 0x9b, 0xba, 0x83, 0xc6, 0xb3, 0x71, 0x25, 0x27, 0x07, 0x99, 0x54, 0x82, - 0x3d, 0xec, 0xc5, 0xf8, 0xb4, 0xa0, 0x38, 0x7a, 0x59, 0x6a, 0x0b, 0xca, - 0x69, 0x6c, 0x17, 0xa4, 0x18, 0xe0, 0xb4, 0xaa, 0x89, 0x99, 0x8f, 0xcb, - 0x71, 0x34, 0x09, 0x1b, 0x6e, 0xe6, 0x87, 0x00, 0xb5, 0xba, 0x70, 0x8a, - 0x29, 0x3d, 0x9a, 0x06, 0x18, 0x2d, 0x66, 0x5e, 0x61, 0x37, 0xeb, 0xdd, - 0x5e, 0xc8, 0x28, 0x92, 0x05, 0x30, 0xfd, 0xb8, 0x65, 0xb1, 0x7f, 0xbf, - 0x2d, 0x55, 0x12, 0x91, 0xc1, 0x02, 0x81, 0x81, 0x00, 0xda, 0x65, 0xda, - 0x38, 0x7c, 0x18, 0xfb, 0x00, 0x11, 0x60, 0xeb, 0x37, 0x65, 0xb8, 0x83, - 0x62, 0x88, 0xc4, 0x3a, 0x4e, 0x64, 0x6a, 0xf3, 0x3e, 0x4e, 0xc0, 0x34, - 0x19, 0x8a, 0xcb, 0x4a, 0xca, 0x2f, 0x5d, 0x50, 0x7a, 0xac, 0xf7, 0x9e, - 0x87, 0x5a, 0xfc, 0x4d, 0x49, 0xd7, 0xf9, 0x21, 0xf5, 0x0b, 0x6f, 0x57, - 0x41, 0x3d, 0x8f, 0xb8, 0xec, 0x7f, 0xcc, 0x92, 0x09, 0xbe, 0xd3, 0xa4, - 0xc3, 0x14, 0x85, 0x21, 0x5d, 0x05, 0xa3, 0xaa, 0x20, 0xf6, 0x62, 0x44, - 0x50, 0x03, 0x5e, 0x53, 0x4a, 0xcd, 0x6a, 0xb6, 0x65, 0x8e, 0x4e, 0x4b, - 0x3f, 0x25, 0xc6, 0x16, 0x31, 0xf5, 0x99, 0x13, 0x77, 0x42, 0xda, 0xdc, - 0x70, 0x4d, 0x65, 0xb0, 0x99, 0x0f, 0xdf, 0x5a, 0xb1, 0x45, 0xf0, 0xb9, - 0x8e, 0xa0, 0xae, 0x4f, 0x4d, 0x65, 0x09, 0x84, 0xb5, 0x38, 0x29, 0xbf, - 0x69, 0xe0, 0x88, 0x1f, 0x27, 0x02, 0x81, 0x81, 0x00, 0xd3, 0x2a, 0x59, - 0xec, 0x28, 0xc3, 0x0d, 0x4f, 0x92, 0x96, 0xca, 0x67, 0x94, 0xfc, 0x2e, - 0xa6, 0x86, 0x68, 0x45, 0x53, 0x92, 0xcc, 0x86, 0x7f, 0x8a, 0xe1, 0x5d, - 0xe8, 0x1d, 0x9e, 0xbb, 0x1e, 0x00, 0x26, 0x1d, 0x80, 0x12, 0xff, 0x9c, - 0x11, 0x0a, 0xbd, 0xa6, 0xc3, 0x8d, 0x48, 0xda, 0xfc, 0x10, 0xf7, 0x7a, - 0x16, 0x07, 0x15, 0xa0, 0x3a, 0xd3, 0x94, 0xfb, 0x52, 0x87, 0x39, 0xee, - 0xe7, 0xc4, 0x26, 0x49, 0x16, 0xc6, 0xc0, 0x83, 0x25, 0xbf, 0x6a, 0x4e, - 0x8c, 0x0b, 0x10, 0x85, 0x66, 0xab, 0x7e, 0xae, 0xac, 0x4c, 0x69, 0x3c, - 0x44, 0xeb, 0xcd, 0xe9, 0xf6, 0x64, 0x8b, 0x4a, 0xd8, 0x6a, 0x4d, 0x6d, - 0x47, 0xa9, 0xb8, 0x55, 0x72, 0xc1, 0xfd, 0xf4, 0x81, 0x4c, 0x66, 0xbe, - 0x49, 0xf2, 0x75, 0x4f, 0x80, 0xf1, 0x20, 0x38, 0xb8, 0x6a, 0x1b, 0x75, - 0x41, 0x30, 0x0f, 0x1b, 0x3f, 0x02, 0x81, 0x80, 0x09, 0x35, 0xfa, 0x7a, - 0x1f, 0x61, 0xbe, 0x54, 0x46, 0x67, 0x5c, 0x04, 0x3e, 0x1a, 0x06, 0x10, - 0x85, 0xcc, 0x20, 0xd9, 0x65, 0x8a, 0xcd, 0x2f, 0x77, 0x8a, 0xcb, 0xa7, - 0xb8, 0x1e, 0xd2, 0xcc, 0xac, 0x2a, 0xb7, 0x56, 0x35, 0x2d, 0x4c, 0x56, - 0x51, 0x14, 0x0a, 0xfe, 0x6e, 0x49, 0x67, 0x91, 0x3a, 0x26, 0x3b, 0xfb, - 0xd8, 0x68, 0xd3, 0x57, 0xc6, 0x1c, 0x0e, 0x9c, 0xb2, 0x9b, 0xa2, 0x7b, - 0x47, 0xc6, 0x45, 0x9d, 0xf2, 0xba, 0xf0, 0x55, 0xeb, 0x8e, 0x41, 0x6b, - 0x4e, 0x79, 0x0f, 0xf2, 0x3b, 0xaf, 0xa0, 0x79, 0xb0, 0x02, 0xc5, 0x51, - 0xa8, 0x7a, 0x2e, 0x3d, 0x75, 0x2a, 0x3b, 0x93, 0xf0, 0x11, 0xe2, 0xf2, - 0x29, 0x91, 0x7c, 0x5d, 0x38, 0x3a, 0x27, 0x4d, 0x0a, 0xb2, 0x18, 0x61, - 0x57, 0x8d, 0x82, 0x72, 0xb5, 0x2c, 0x2d, 0x98, 0xa7, 0x01, 0xbb, 0xbc, - 0xef, 0x67, 0x4e, 0x49, 0x02, 0x81, 0x81, 0x00, 0xb2, 0x70, 0x53, 0x54, - 0x70, 0x8d, 0x82, 0xad, 0xff, 0x1d, 0x55, 0x24, 0x7a, 0x8d, 0x2f, 0x8e, - 0xa0, 0x7d, 0x74, 0x37, 0xcf, 0x10, 0xed, 0x86, 0xd1, 0x80, 0xe7, 0xad, - 0xc1, 0x79, 0xe4, 0x7c, 0xd1, 0x7b, 0x63, 0xea, 0x5a, 0x23, 0x8d, 0x6a, - 0x09, 0x3d, 0x81, 0xb2, 0x35, 0xad, 0x9e, 0xfe, 0xea, 0x07, 0x76, 0x2f, - 0x2f, 0x05, 0x63, 0x44, 0xd2, 0x8e, 0x4e, 0x61, 0xca, 0xcb, 0x75, 0xca, - 0x7b, 0xc2, 0x2e, 0x79, 0x04, 0xb2, 0xa1, 0x20, 0x40, 0xc4, 0x40, 0x63, - 0xae, 0xe5, 0xe3, 0x14, 0x83, 0x4e, 0xa5, 0xa4, 0x0b, 0x5d, 0xd2, 0x04, - 0x1b, 0x8f, 0x01, 0x69, 0xa8, 0x44, 0xdc, 0x96, 0x4c, 0x1d, 0xe9, 0x7e, - 0x69, 0x38, 0xcf, 0x5c, 0x0d, 0xf9, 0xdf, 0xa7, 0x73, 0x3c, 0x4f, 0x08, - 0x85, 0xce, 0x03, 0xc4, 0xdd, 0xfd, 0x70, 0x70, 0xc5, 0x99, 0x36, 0x58, - 0x43, 0x98, 0x40, 0x59, 0x02, 0x81, 0x81, 0x00, 0xd5, 0xaa, 0xfb, 0xec, - 0x8d, 0xc6, 0xdd, 0xfa, 0x2b, 0x5a, 0x24, 0xd0, 0xda, 0x58, 0xbd, 0x87, - 0x92, 0x1a, 0x29, 0x62, 0x13, 0x1d, 0x4b, 0x79, 0x1b, 0xbe, 0x79, 0x7d, - 0xad, 0x79, 0xca, 0x17, 0x75, 0xda, 0xe8, 0x32, 0xe8, 0xa0, 0x9e, 0xa8, - 0x77, 0x53, 0xac, 0x38, 0xd6, 0xeb, 0xe6, 0x22, 0x65, 0xc4, 0xaa, 0x4c, - 0xc8, 0xd0, 0x33, 0x1a, 0x1e, 0xbe, 0xbd, 0x73, 0x09, 0x4a, 0xfa, 0x85, - 0x5c, 0xf3, 0x0c, 0x9c, 0x81, 0x56, 0x30, 0xa7, 0xf7, 0x9b, 0xf4, 0x92, - 0x9c, 0x6b, 0x93, 0x6a, 0x00, 0x33, 0xdc, 0x2f, 0x54, 0x1e, 0x78, 0xd4, - 0x97, 0xec, 0x24, 0xa2, 0xdb, 0x3d, 0x03, 0x33, 0x09, 0xb2, 0x2c, 0x03, - 0x05, 0x40, 0xde, 0x52, 0xf2, 0x9b, 0xfa, 0x00, 0x8d, 0x4b, 0xfe, 0x5b, - 0x9b, 0x9c, 0x73, 0xad, 0xfb, 0x7a, 0x00, 0x42, 0x62, 0x9e, 0xa0, 0x95, - 0x55, 0x50, 0x32, 0x87 -}; -static unsigned int enc_priv_key_len = 1192; - -const struct bootutil_key bootutil_enc_key = { - .key = enc_priv_key, - .len = &enc_priv_key_len, -}; -#elif defined(MCUBOOT_ENCRYPT_EC256) +#if defined(MCUBOOT_ENCRYPT_RSA) || defined(MCUBOOT_ENCRYPT_X25519) || defined(MCUBOOT_ENCRYPT_EC256) extern const unsigned char enc_priv_key[]; extern unsigned int enc_priv_key_len; const struct bootutil_key bootutil_enc_key = { .key = enc_priv_key, .len = &enc_priv_key_len, }; -#elif defined(MCUBOOT_ENCRYPT_X25519) -unsigned char enc_key[] = { - 0x30, 0x2e, 0x02, 0x01, 0x00, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, 0x6e, - 0x04, 0x22, 0x04, 0x20, 0x28, 0x80, 0x2f, 0xef, 0xef, 0x82, 0x95, 0x50, - 0xf1, 0x41, 0x93, 0x03, 0x6c, 0x1b, 0xb9, 0x49, 0x6c, 0x51, 0xe5, 0x26, - 0x87, 0x8f, 0x77, 0x07, 0xf8, 0xb4, 0x1f, 0x04, 0x45, 0x6d, 0x84, 0x4f, -}; -static unsigned int enc_key_len = 48; -const struct bootutil_key bootutil_enc_key = { - .key = enc_key, - .len = &enc_key_len, -}; #elif defined(MCUBOOT_ENCRYPT_KW) #error "Encrypted images with AES-KW is not implemented yet." #endif diff --git a/boot/zephyr/prj.conf b/boot/zephyr/prj.conf index b6a62a9d6..8d3cdb819 100644 --- a/boot/zephyr/prj.conf +++ b/boot/zephyr/prj.conf @@ -5,9 +5,7 @@ CONFIG_MAIN_STACK_SIZE=10240 CONFIG_MBEDTLS_CFG_FILE="mcuboot-mbedtls-cfg.h" CONFIG_BOOT_SWAP_SAVE_ENCTLV=n -CONFIG_BOOT_ENCRYPT_RSA=n -CONFIG_BOOT_ENCRYPT_EC256=n -CONFIG_BOOT_ENCRYPT_X25519=n +CONFIG_BOOT_ENCRYPT_IMAGE=n CONFIG_BOOT_UPGRADE_ONLY=n CONFIG_BOOT_BOOTSTRAP=n diff --git a/boot/zephyr/single_loader.c b/boot/zephyr/single_loader.c index 86d5052e9..5d1e76fcf 100644 --- a/boot/zephyr/single_loader.c +++ b/boot/zephyr/single_loader.c @@ -9,6 +9,7 @@ #include "bootutil/image.h" #include "bootutil_priv.h" #include "bootutil/bootutil_log.h" +#include "bootutil/bootutil_public.h" #include "bootutil/fault_injection_hardening.h" #include "mcuboot_config/mcuboot_config.h" @@ -57,7 +58,6 @@ boot_image_validate(const struct flash_area *fa_p, } #endif /* MCUBOOT_VALIDATE_PRIMARY_SLOT || MCUBOOT_VALIDATE_PRIMARY_SLOT_ONCE*/ - inline static fih_ret boot_image_validate_once(const struct flash_area *fa_p, struct image_header *hdr) @@ -89,349 +89,6 @@ boot_image_validate_once(const struct flash_area *fa_p, FIH_RET(FIH_SUCCESS); } -/** - * Attempts to load image header from flash; verifies flash header fields. - * - * @param[in] fa_p flash area pointer - * @param[out] hdr buffer for image header - * - * @return 0 on success, error code otherwise - */ -static int -boot_image_load_header(const struct flash_area *fa_p, - struct image_header *hdr) -{ - uint32_t size; - int rc = flash_area_read(fa_p, 0, hdr, sizeof *hdr); - - if (rc != 0) { - rc = BOOT_EFLASH; - BOOT_LOG_ERR("Failed reading image header"); - return BOOT_EFLASH; - } - - if (hdr->ih_magic != IMAGE_MAGIC) { - BOOT_LOG_ERR("Bad image magic 0x%lx", (unsigned long)hdr->ih_magic); - - return BOOT_EBADIMAGE; - } - - if (hdr->ih_flags & IMAGE_F_NON_BOOTABLE) { - BOOT_LOG_ERR("Image not bootable"); - - return BOOT_EBADIMAGE; - } - - if (!boot_u32_safe_add(&size, hdr->ih_img_size, hdr->ih_hdr_size) || - size >= flash_area_get_size(fa_p)) { - return BOOT_EBADIMAGE; - } - - return 0; -} - -#ifdef MCUBOOT_ENC_IMAGES - -/** - * Validate hash of a primary boot image doing on the fly decryption as well - * - * @param[in] fa_p flash area pointer - * @param[in] hdr boot image header pointer - * - * @return FIH_SUCCESS on success, error code otherwise - */ -inline static fih_ret -boot_image_validate_encrypted(const struct flash_area *fa_p, - struct image_header *hdr) -{ - static uint8_t tmpbuf[BOOT_TMPBUF_SZ]; - FIH_DECLARE(fih_rc, FIH_FAILURE); - - struct boot_loader_state boot_data; - struct boot_loader_state *state = &boot_data; - struct boot_status _bs; - struct boot_status *bs = &_bs; - uint8_t image_index; - int rc; - - memset(&boot_data, 0, sizeof(struct boot_loader_state)); - image_index = BOOT_CURR_IMG(state); - if (MUST_DECRYPT(fa_p, image_index, hdr)) { - rc = boot_enc_load(BOOT_CURR_ENC(state), image_index, hdr, fa_p, bs); - if (rc < 0) { - FIH_RET(fih_rc); - } - if (rc == 0 && boot_enc_set_key(BOOT_CURR_ENC(state), 0, bs)) { - FIH_RET(fih_rc); - } - } - FIH_CALL(bootutil_img_validate, fih_rc, BOOT_CURR_ENC(state), image_index, - hdr, fa_p, tmpbuf, BOOT_TMPBUF_SZ, NULL, 0, NULL); - - FIH_RET(fih_rc); -} - -/* - * Compute the total size of the given image. Includes the size of - * the TLVs. - */ -static int -read_image_size(const struct flash_area *fa_p, - struct image_header *hdr, - uint32_t *size) -{ - struct image_tlv_info info; - uint32_t off; - uint32_t protect_tlv_size; - int rc; - - off = BOOT_TLV_OFF(hdr); - - if (flash_area_read(fa_p, off, &info, sizeof(info))) { - rc = BOOT_EFLASH; - goto done; - } - - protect_tlv_size = hdr->ih_protect_tlv_size; - if (info.it_magic == IMAGE_TLV_PROT_INFO_MAGIC) { - if (protect_tlv_size != info.it_tlv_tot) { - rc = BOOT_EBADIMAGE; - goto done; - } - - if (flash_area_read(fa_p, off + info.it_tlv_tot, &info, sizeof(info))) { - rc = BOOT_EFLASH; - goto done; - } - } else if (protect_tlv_size != 0) { - rc = BOOT_EBADIMAGE; - goto done; - } - - if (info.it_magic != IMAGE_TLV_INFO_MAGIC) { - rc = BOOT_EBADIMAGE; - goto done; - } - - *size = off + protect_tlv_size + info.it_tlv_tot; - rc = 0; - -done: - return rc; -} - - -/* Get the SOC's flash erase block size from the DTS, fallback to 1024. */ -#define SOC_FLASH_ERASE_BLK_SZ \ - DT_PROP_OR(DT_CHOSEN(zephyr_flash), erase_block_size,1024) - -/** - * reads, decrypts in RAM & write back the decrypted image in the same region - * This function is NOT power failsafe since the image is decrypted in the RAM - * buffer. - * - * @param flash_area The ID of the source flash area. - * @param off_src The offset within the flash area to - * copy from. - * @param sz The number of bytes to copy. should match erase sector - * - * @return 0 on success; nonzero on failure. - */ -int -decrypt_region_inplace(struct boot_loader_state *state, - const struct flash_area *fap, - struct image_header *hdr, - uint32_t off, uint32_t sz) -{ - uint32_t bytes_copied; - int chunk_sz; - int rc; - uint32_t tlv_off; - size_t blk_off; - uint16_t idx; - uint32_t blk_sz; - uint8_t image_index; - - static uint8_t buf[SOC_FLASH_ERASE_BLK_SZ] __attribute__((aligned)); - assert(sz <= sizeof buf); - - bytes_copied = 0; - while (bytes_copied < sz) { - if (sz - bytes_copied > sizeof buf) { - chunk_sz = sizeof buf; - } else { - chunk_sz = sz - bytes_copied; - } - - rc = flash_area_read(fap, off + bytes_copied, buf, chunk_sz); - if (rc != 0) { - return BOOT_EFLASH; - } - - image_index = BOOT_CURR_IMG(state); - if (IS_ENCRYPTED(hdr)) { - blk_sz = chunk_sz; - idx = 0; - if (off + bytes_copied < hdr->ih_hdr_size) { - /* do not decrypt header */ - if (hdr->ih_hdr_size > (off + bytes_copied + chunk_sz)) { - /* all bytes in header, skip decryption */ - blk_sz = 0; - } - else { - blk_sz = off + bytes_copied + chunk_sz - hdr->ih_hdr_size; - } - - blk_off = 0; - idx = hdr->ih_hdr_size; - } else { - blk_off = ((off + bytes_copied) - hdr->ih_hdr_size) & 0xf; - } - tlv_off = BOOT_TLV_OFF(hdr); - if (off + bytes_copied + chunk_sz > tlv_off) { - /* do not decrypt TLVs */ - if (off + bytes_copied >= tlv_off) { - blk_sz = 0; - } else { - blk_sz = tlv_off - (off + bytes_copied); - } - } - boot_encrypt(BOOT_CURR_ENC(state), image_index, fap, - (off + bytes_copied + idx) - hdr->ih_hdr_size, blk_sz, - blk_off, &buf[idx]); - } - rc = flash_area_erase(fap, off + bytes_copied, chunk_sz); - if (rc != 0) { - return BOOT_EFLASH; - } - rc = flash_area_write(fap, off + bytes_copied, buf, chunk_sz); - if (rc != 0) { - return BOOT_EFLASH; - } - - bytes_copied += chunk_sz; - - MCUBOOT_WATCHDOG_FEED(); - } - - return 0; -} - -/** - * Check if a image was encrypted into the first slot, and decrypt it - * in place. this operation is not power failsafe. - * - * The operation is done by checking the last flash sector, and using it as a - * temporarely scratch partition. The - * - * @param[in] fa_p flash area pointer - * @param[in] hdr boot image header pointer - * - * @return FIH_SUCCESS on success, error code otherwise - */ -inline static fih_ret -decrypt_image_inplace(const struct flash_area *fa_p, - struct image_header *hdr) -{ - FIH_DECLARE(fih_rc, FIH_FAILURE); - int rc; - struct boot_loader_state boot_data; - struct boot_loader_state *state = &boot_data; - struct boot_status _bs; - struct boot_status *bs = &_bs; - size_t size; - size_t sect_size; - size_t sect_count; - size_t sect; - uint8_t image_index; - struct flash_sector sector; - - memset(&boot_data, 0, sizeof(struct boot_loader_state)); - memset(&_bs, 0, sizeof(struct boot_status)); - - /* Get size from last sector to know page/sector erase size */ - rc = flash_area_get_sector(fa_p, boot_status_off(fa_p), §or); - - - image_index = BOOT_CURR_IMG(state); - - if (MUST_DECRYPT(fa_p, image_index, hdr)) { -#if 0 //Skip this step?, the image will just not boot if it's not decrypted properly - /* First check if the encrypted image is a good image before decrypting */ - FIH_CALL(boot_image_validate_encrypted,fih_rc,_fa_p,&_hdr); - if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) { - FIH_RET(fih_rc); - } -#endif - memset(&boot_data, 0, sizeof(struct boot_loader_state)); - /* Load the encryption keys into cache */ - rc = boot_enc_load(BOOT_CURR_ENC(state), image_index, hdr, fa_p, bs); - if (rc < 0) { - FIH_RET(fih_rc); - } - if (rc == 0 && boot_enc_set_key(BOOT_CURR_ENC(state), 0, bs)) { - FIH_RET(fih_rc); - } - } - else - { - /* Expected encrypted image! */ - FIH_RET(fih_rc); - } - - uint32_t src_size = 0; - rc = read_image_size(fa_p,hdr, &src_size); - if (rc != 0) { - FIH_RET(fih_rc); - } - - sect_size = sector.fs_size; - sect_count = fa_p->fa_size / sect_size; - for (sect = 0, size = 0; size < src_size && sect < sect_count; sect++) { - rc = decrypt_region_inplace(state, fa_p,hdr, size, sect_size); - if (rc != 0) { - FIH_RET(fih_rc); - } - size += sect_size; - } - - fih_rc = FIH_SUCCESS; - FIH_RET(fih_rc); -} - -int -boot_handle_enc_fw() -{ - int rc = -1; - FIH_DECLARE(fih_rc, FIH_FAILURE); - - rc = flash_area_open(FLASH_AREA_IMAGE_PRIMARY(0), &_fa_p); - assert(rc == 0); - - rc = boot_image_load_header(_fa_p, &_hdr); - if (rc != 0) { - goto out; - } - - if (IS_ENCRYPTED(&_hdr)) { - //encrypted, we need to decrypt in place - FIH_CALL(decrypt_image_inplace,fih_rc,_fa_p,&_hdr); - if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) { - rc = -1; - goto out; - } - } - else - { - rc = 0; - } - -out: - flash_area_close(_fa_p); - return rc; -} -#endif - /** * Gather information on image and prepare for booting. * diff --git a/docs/readme-zephyr.md b/docs/readme-zephyr.md index 2acc63db1..a8f351df8 100644 --- a/docs/readme-zephyr.md +++ b/docs/readme-zephyr.md @@ -251,12 +251,6 @@ Use the ``CONFIG_ENABLE_MGMT_PERUSER=y`` Kconfig option to enable the following * Storage erase - This command allows erasing the storage partition (enable with ``CONFIG_BOOT_MGMT_CUSTOM_STORAGE_ERASE=y``). * Custom image list - This command allows fetching version and installation status (custom properties) for all images (enable with ``CONFIG_BOOT_MGMT_CUSTOM_IMG_LIST=y``). -### In-place image decryption - -Images uploaded by the serial recovery can be decrypted on the fly by using ECIES primitives described in the [ECIES encryption](encrypted_images.md#ecies-encryption) section. - -Enable support for this feature by using ``CONFIG_BOOT_SERIAL_ENCRYPT_EC256=y``. - ### More configuration For details on other available configuration options for the serial recovery protocol, check the Kconfig options (for example by using ``menuconfig``). diff --git a/docs/release-notes.d/zephyr-encryption.md b/docs/release-notes.d/zephyr-encryption.md new file mode 100644 index 000000000..f60e18f84 --- /dev/null +++ b/docs/release-notes.d/zephyr-encryption.md @@ -0,0 +1,9 @@ +- Reworked image encryption support for Zephyr, static dummy key files + are no longer in the code, a pem file must be supplied to extract + the private and public keys. The Kconfig menu has changed to only + show a single option for enabling encryption and selecting the key + file. +- Serial recovery can now read and handle encrypted seondary slot + partitions. +- Serial recovery with MBEDTLS no longer has undefined operations which + led to usage faults when the secondary slot image was encrypted.