MCUboot AES image encryption with ECIES-X25519 key exchange

MCUboot on the nRF54H20 SoC can support encrypted images using AES. Images are encrypted using AES, and ECIES-X25519 is used for key delivery (exchange) within the image. When image encryption is enabled, you can choose to upload signed or encrypted images to be swapped during boot. If MCUboot finds an encrypted image in the secondary slot, it decrypts the image during the slot swapping process. An image that was encrypted before being swapped into the primary slot is re-encrypted if the swap is later reverted.

Limitations

The current implementation has the following limitations:

  • On the nRF54H20 SoC, ECIES-X25519 key exchange requires the ED25519 signature algorithm (default).

  • Encryption is not supported when using MCUboot in direct-xip mode.

  • HMAC and HKDF tools currently use the SHA-256 hash algorithm.

Note

In the nRF Connect SDK v3.1.0, encryption is supported only through the TinyCrypt library. PSA Crypto is not yet supported (known issue NCSDK-34745). As a workaround, disable CONFIG_NRF_SECURITY if encryption is required.

HMAC and HKDF impact on TLV and key exchange

An encrypted image includes a TLV that contains the public key for ECIES-X25519 key exchange, the encrypted AES key, and the MAC tag of the encrypted key. The key used to encrypt the AES key is derived using HKDF, and the MAC tag is generated using HMAC.

While the use of SHA-256 does not pose a security concern and has a minimal impact on performance, it increases the code size. This is because SHA-256 support must be included in addition to SHA-512, which is already used by the ED25519 signature algorithm.

Additionally, pre-installed MCUboot instances will not be able to boot images that use TLVs generated with different hash algorithms.

Building application with image encryption

To build an application that uses MCUboot with image encryption enabled, run the following command:

 west build -b board_target -- -DSB_CONFIG_BOOTLOADER_MCUBOOT=y -DSB_CONFIG_BOOT_ENCRYPTION=y

The SB_CONFIG_BOOT_ENCRYPTION option enables encryption support in MCUboot.

The key exchange method is determined by the type of signature key selected. For the nRF54H20 SoC, the ED25519 signature algorithm is the default setting.

When encryption is enabled, the encrypted image files zephyr.signed.encrypted.bin and zephyr.signed.encrypted.hex are generated in the application build directory.

The BIN file is a binary image suitable for Device Firmware Update (DFU) operations using MCUmgr.

When the SB_CONFIG_BOOT_ENCRYPTION_KEY_FILE option is enabled, you must provide an ECIES-X25519 private key in PEM format. This key is built into the MCUboot image during the build process. See the following example:

west build -b board_target -- -DSB_CONFIG_BOOTLOADER_MCUBOOT=y -DSB_CONFIG_BOOT_ENCRYPTION=y -DSB_CONFIG_BOOT_ENCRYPTION_KEY_FILE="<path to key.pem>"

Note

  • The public key, derived from the specified private key file, is added to the image and later used on the device to derive the decryption key for the application image. This public key is automatically derived from the private key by imgtool, which is invoked by the build system when signing the image.

  • The sysbuild option SB_CONFIG_BOOT_ENCRYPTION sets the MCUboot configuration option CONFIG_BOOT_ENCRYPT_IMAGE. Similarly, the SB_CONFIG_BOOT_ENCRYPTION_KEY_FILE option sets both CONFIG_BOOT_ENCRYPTION_KEY_FILE for MCUboot and CONFIG_MCUBOOT_ENCRYPTION_KEY_FILE for the default application.

These values are then passed to imgtool for encrypting the application image.

You cannot override these options using MCUboot or application-level Kconfig options, as they are enforced by sysbuild.

Enabling encryption in nRF Connect for VS Code projects

To correctly set up encryption in nRF Connect for VS Code, you must familiarize yourself with How to work with build configurations. When configuring build options, ensure to include SB_CONFIG_BOOT_ENCRYPTION and SB_CONFIG_BOOT_ENCRYPTION_KEY_FILE Kconfig options using extra CMake arguments.

If you are modifying an existing project, you must regenerate it to activate new settings.