Skip to content

Commit 5b663a9

Browse files
committed
zephyr: Add support for embedded AES key
The commit provides Kconfig options that allow to configure MCUboot to use embedded AES key. Primary option is CONFIG_BOOT_ENCRYPT_IMAGE_WITH_EMBEDDED_KEY that allows to select usage of embedded key in the code. After it follow sets of Kconfigs: - CONFIG_BOOT_ENCRYPT_IMAGE_GENERATE_BASIC_KEY_PROVIDER - CONFIG_BOOT_ENCRYPT_IMAGE_USE_CUSTOM_KEY_PROVIDER The above set allows to select source of the key. The first option will choose to generate default key provider, with a single embedded key, where the key is provided as a string assigned to CONFIG_BOOOT_ENCRYPT_IMAGE_EMBEDDED_RAW_KEY. The second option selects user provided code as source of key; user needs to provide path to directory source using CONFIG_BOOT_ENCRYPT_IMAGE_EMBEDDED_CUSTOM_KEY_PROVIDER_DIR. Within boot/zephyr directory there has been templates directory created, with template source for AES key provider. Signed-off-by: Dominik Ermel <dominik.ermel@nordicsemi.no>
1 parent 20a3085 commit 5b663a9

File tree

7 files changed

+216
-51
lines changed

7 files changed

+216
-51
lines changed

boot/zephyr/CMakeLists.txt

Lines changed: 75 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -393,57 +393,59 @@ if(NOT CONFIG_BOOT_SIGNATURE_KEY_FILE STREQUAL "")
393393
endif()
394394

395395
if(CONFIG_BOOT_ENCRYPTION_KEY_FILE AND NOT CONFIG_BOOT_ENCRYPTION_KEY_FILE STREQUAL "")
396-
# CONF_FILE points to the KConfig configuration files of the bootloader.
397-
unset(CONF_DIR)
398-
foreach(filepath ${CONF_FILE})
399-
file(READ ${filepath} temp_text)
400-
string(FIND "${temp_text}" ${CONFIG_BOOT_ENCRYPTION_KEY_FILE} match)
401-
if(${match} GREATER_EQUAL 0)
402-
if(NOT DEFINED CONF_DIR)
403-
get_filename_component(CONF_DIR ${filepath} DIRECTORY)
404-
else()
405-
message(FATAL_ERROR "Encryption key file defined in multiple conf files")
396+
if(NOT CONFIG_BOOT_ENCRYPT_IMAGE_WITH_EMBEDDED_KEY)
397+
# CONF_FILE points to the KConfig configuration files of the bootloader.
398+
unset(CONF_DIR)
399+
foreach(filepath ${CONF_FILE})
400+
file(READ ${filepath} temp_text)
401+
string(FIND "${temp_text}" ${CONFIG_BOOT_ENCRYPTION_KEY_FILE} match)
402+
if(${match} GREATER_EQUAL 0)
403+
if(NOT DEFINED CONF_DIR)
404+
get_filename_component(CONF_DIR ${filepath} DIRECTORY)
405+
else()
406+
message(FATAL_ERROR "Encryption key file defined in multiple conf files")
407+
endif()
406408
endif()
407-
endif()
408-
endforeach()
409+
endforeach()
409410

410-
if(IS_ABSOLUTE ${CONFIG_BOOT_ENCRYPTION_KEY_FILE})
411-
set(KEY_FILE ${CONFIG_BOOT_ENCRYPTION_KEY_FILE})
412-
elseif((DEFINED CONF_DIR) AND
413-
(EXISTS ${CONF_DIR}/${CONFIG_BOOT_ENCRYPTION_KEY_FILE}))
414-
set(KEY_FILE ${CONF_DIR}/${CONFIG_BOOT_ENCRYPTION_KEY_FILE})
415-
else()
416-
set(KEY_FILE ${MCUBOOT_DIR}/${CONFIG_BOOT_ENCRYPTION_KEY_FILE})
417-
endif()
418-
message("MCUBoot bootloader encryption key file: ${KEY_FILE}")
411+
if(IS_ABSOLUTE ${CONFIG_BOOT_ENCRYPTION_KEY_FILE})
412+
set(KEY_FILE ${CONFIG_BOOT_ENCRYPTION_KEY_FILE})
413+
elseif((DEFINED CONF_DIR) AND
414+
(EXISTS ${CONF_DIR}/${CONFIG_BOOT_ENCRYPTION_KEY_FILE}))
415+
set(KEY_FILE ${CONF_DIR}/${CONFIG_BOOT_ENCRYPTION_KEY_FILE})
416+
else()
417+
set(KEY_FILE ${MCUBOOT_DIR}/${CONFIG_BOOT_ENCRYPTION_KEY_FILE})
418+
endif()
419+
message("MCUBoot bootloader encryption key file: ${KEY_FILE}")
420+
421+
# Emit a warning if using one of the default MCUboot key files
422+
set(mcuboot_default_encryption_files
423+
${MCUBOOT_DIR}/enc-ec256-priv.pem
424+
${MCUBOOT_DIR}/enc-ec256-pub.pem
425+
${MCUBOOT_DIR}/enc-rsa2048-priv.pem
426+
${MCUBOOT_DIR}/enc-rsa2048-pub.pem
427+
${MCUBOOT_DIR}/enc-x25519-priv.pem
428+
${MCUBOOT_DIR}/enc-x25519-pub.pem
429+
)
419430

420-
# Emit a warning if using one of the default MCUboot key files
421-
set(mcuboot_default_encryption_files
422-
${MCUBOOT_DIR}/enc-ec256-priv.pem
423-
${MCUBOOT_DIR}/enc-ec256-pub.pem
424-
${MCUBOOT_DIR}/enc-rsa2048-priv.pem
425-
${MCUBOOT_DIR}/enc-rsa2048-pub.pem
426-
${MCUBOOT_DIR}/enc-x25519-priv.pem
427-
${MCUBOOT_DIR}/enc-x25519-pub.pem
428-
)
431+
if(${KEY_FILE} IN_LIST mcuboot_default_encryption_files)
432+
message(WARNING "WARNING: Using default MCUboot encryption key file, this file is for debug use only and is not secure!")
433+
endif()
429434

430-
if(${KEY_FILE} IN_LIST mcuboot_default_encryption_files)
431-
message(WARNING "WARNING: Using default MCUboot encryption key file, this file is for debug use only and is not secure!")
435+
set(GENERATED_ENCKEY ${ZEPHYR_BINARY_DIR}/autogen-enckey.c)
436+
add_custom_command(
437+
OUTPUT ${GENERATED_ENCKEY}
438+
COMMAND
439+
${PYTHON_EXECUTABLE}
440+
${MCUBOOT_DIR}/scripts/imgtool.py
441+
getpriv
442+
-k
443+
${KEY_FILE}
444+
> ${GENERATED_ENCKEY}
445+
DEPENDS ${KEY_FILE}
446+
)
447+
zephyr_library_sources(${GENERATED_ENCKEY})
432448
endif()
433-
434-
set(GENERATED_ENCKEY ${ZEPHYR_BINARY_DIR}/autogen-enckey.c)
435-
add_custom_command(
436-
OUTPUT ${GENERATED_ENCKEY}
437-
COMMAND
438-
${PYTHON_EXECUTABLE}
439-
${MCUBOOT_DIR}/scripts/imgtool.py
440-
getpriv
441-
-k
442-
${KEY_FILE}
443-
> ${GENERATED_ENCKEY}
444-
DEPENDS ${KEY_FILE}
445-
)
446-
zephyr_library_sources(${GENERATED_ENCKEY})
447449
endif()
448450

449451
if(CONFIG_MCUBOOT_CLEANUP_ARM_CORE)
@@ -731,3 +733,30 @@ if(SYSBUILD)
731733
set(mcuboot_image_footer_size ${required_size} CACHE INTERNAL "Estimated MCUboot image trailer size" FORCE)
732734
set(mcuboot_image_upgrade_footer_size ${required_upgrade_size} CACHE INTERNAL "Estimated MCUboot update image trailer size" FORCE)
733735
endif()
736+
737+
if(${CONFIG_BOOT_ENCRYPT_IMAGE_WITH_EMBEDDED_KEY})
738+
if(${CONFIG_BOOT_ENCRYPT_IMAGE_USE_CUSTOM_KEY_PROVIDER})
739+
# User provides own code for key source
740+
set(CUSTOM_AES_KEY_PROVIDER_DIR ${PROJECT_BINARY_DIR}/custom_aes_provider)
741+
742+
message(STATUS "Building AES Custom key provider from " ${CONFIG_BOOT_ENCRYPT_IMAGE_EMBEDDED_CUSTOM_KEY_PROVIDER_DIR})
743+
message(STATUS "AES Custom key provider bin dir is " ${CUSTOM_AES_KEY_PROVIDER_DIR})
744+
745+
add_subdirectory(${CONFIG_BOOT_ENCRYPT_IMAGE_EMBEDDED_CUSTOM_KEY_PROVIDER_DIR} ${CUSTOM_AES_KEY_PROVIDER_DIR})
746+
elseif(${CONFIG_BOOT_ENCRYPT_IMAGE_GENERATE_BASIC_KEY_PROVIDER})
747+
# Need to generate single key provider source, from template.
748+
# Take provided key, in form of a string and make it into C array, BOOT_AES_RAW_KEY_HEX_ARRAY,
749+
# of byte size hex values.
750+
set(BOOT_AES_RAW_KEY_HEX_STRING ${BOOT_ENCRYPT_IMAGE_EMBEDDED_RAW_KEY})
751+
string(REGEX REPLACE "(..)" "0x\\1, " BOOT_AES_RAW_KEY_HEX_ARRAY "${BOOT_AES_RAW_KEY_HEX_STRING}")
752+
753+
# The tamplate references BOOT_AES_RAW_KEY_HEX_ARRAY where it expects the array to be substituted.
754+
set(OUTPUT_BOOT_AES_RAW_KEY_SRC ${ZEPHYR_BINARY_DIR}/mcuboot_generated/builtin_aes_key_provider.c)
755+
configure_file(templates/single_builtin_aes_key_provider.c.template ${OUTPUT_BOOT_AES_RAW_KEY_SRC} @ONLY)
756+
757+
# Add generated source file to build
758+
zephyr_library_sources(${OUTPUT_BOOT_AES_RAW_KEY_SRC})
759+
else()
760+
message(FATAL_ERROR "Unsupported embedded key configuration")
761+
endif()
762+
endif()

boot/zephyr/Kconfig

Lines changed: 64 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ config BOOT_ED25519_PSA_DEPENDENCIES
9494

9595
if BOOT_ENCRYPT_IMAGE
9696

97+
if !BOOT_ENCRYPT_IMAGE_WITH_EMBEDDED_KEY
98+
9799
config BOOT_X25519_PSA_DEPENDENCIES
98100
bool
99101
select PSA_WANT_ALG_ECDH
@@ -111,6 +113,8 @@ config BOOT_X25519_PSA_DEPENDENCIES
111113
to use with it; the others are used for shared key decryption
112114
and derivation.
113115

116+
endif # !BOOT_ENCRYPT_IMAGE_WITH_EMBEDDED_KEY
117+
114118
endif # BOOT_ENCRYPT_IMAGE
115119

116120
config BOOT_ECDSA_PSA_DEPENDENCIES
@@ -359,7 +363,7 @@ config BOOT_ED25519_PSA
359363
select BOOT_IMG_HASH_ALG_SHA256_ALLOW
360364
select BOOT_IMG_HASH_ALG_SHA512_ALLOW
361365
select BOOT_ED25519_PSA_DEPENDENCIES
362-
select BOOT_X25519_PSA_DEPENDENCIES if BOOT_ENCRYPT_IMAGE
366+
select BOOT_X25519_PSA_DEPENDENCIES if BOOT_ENCRYPT_IMAGE_WITH_SHARED_KEY
363367

364368
endchoice
365369

@@ -595,7 +599,8 @@ config BOOT_BOOTSTRAP
595599

596600
config BOOT_SWAP_SAVE_ENCTLV
597601
bool "Save encrypted key TLVs instead of plaintext keys in swap metadata"
598-
depends on BOOT_ENCRYPT_IMAGE
602+
depends on BOOT_ENCRYPT_IMAGE_WITH_SHARED_KEY
603+
depends on !BOOT_ENCRYPT_IMAGE_WITH_EMBEDDED_KEY
599604
help
600605
If y, instead of saving the encrypted image keys in plaintext in the
601606
swap resume metadata, save the encrypted image TLVs. This should be used
@@ -653,12 +658,66 @@ config BOOT_ENCRYPTION_SUPPORT
653658
help
654659
Hidden option used to check if image encryption is supported.
655660

656-
config BOOT_ENCRYPT_IMAGE
657-
bool "Support for encrypted image updates"
658-
depends on BOOT_ENCRYPTION_SUPPORT
661+
config BOOT_ENCRYPT_IMAGE_WITH_EMBEDDED_KEY
662+
bool "Use key that is already on board with MCUboot"
663+
depends on BOOT_ENCRYPT_IMAGE
664+
help
665+
The key is supposed to be either compiled in or on board.
666+
User is responsible for providing boot_enc_take_key
667+
function that will be able to retrieve the key.
668+
669+
if BOOT_ENCRYPT_IMAGE_WITH_EMBEDDED_KEY
670+
671+
choice BOOT_ENCRYPT_IMAGE_EMBEDDED_KEY_PROVIDER
672+
prompt "Embedded AES key provider"
673+
default BOOT_ENCRYPT_IMAGE_GENERATE_BASIC_KEY_PROVIDER
674+
675+
config BOOT_ENCRYPT_IMAGE_GENERATE_BASIC_KEY_PROVIDER
676+
bool "Generate basic boot_enc_take_key"
677+
depends on BOOT_ENCRYPT_IMAGE_WITH_EMBEDDED_KEY
678+
help
679+
Basic implementation of boot_enc_take_key will be implemented,
680+
that will have single key built in, used for all images and
681+
slots.
682+
683+
config BOOT_ENCRYPT_IMAGE_USE_CUSTOM_KEY_PROVIDER
684+
bool "User provides source code for key provider"
685+
686+
endchoice # BOOT_ENCRYPT_IMAGE_EMBEDDED_KEY_PROVIDER
687+
688+
config BOOT_ENCRYPT_IMAGE_EMBEDDED_RAW_KEY
689+
string "Hexadecimal string representing AES key"
690+
depends on BOOT_ENCRYPT_IMAGE_GENERATE_BASIC_KEY_PROVIDER
691+
help
692+
AES key in form of hexadecimal string that will be used to
693+
generate boot_enc_take_key function, returning the key for
694+
decryption and encryption of image.
695+
The key character length should be the double of expected
696+
AES key length in bytes.
697+
698+
config BOOT_ENCRYPT_IMAGE_EMBEDDED_CUSTOM_KEY_PROVIDER_DIR
699+
string "Path to AES key provider, boot_enc_take_key, implementation"
700+
depends on BOOT_ENCRYPT_IMAGE_USE_CUSTOM_KEY_PROVIDER
701+
default "templates/custom_boot_enc_take_key"
702+
help
703+
Use templates/custom_boot_enc_take_key as a template.
704+
705+
endif # BOOT_ENCRYPT_IMAGE_WITH_EMBEDDED_KEY
706+
707+
config BOOT_ENCRYPT_IMAGE_WITH_SHARED_KEY
708+
bool
709+
default y if !BOOT_ENCRYPT_IMAGE_WITH_EMBEDDED_KEY
710+
depends on BOOT_ENCRYPT_IMAGE
659711
select BOOT_ENCRYPT_RSA if BOOT_SIGNATURE_TYPE_RSA
660712
select BOOT_ENCRYPT_EC256 if BOOT_SIGNATURE_TYPE_ECDSA_P256
661713
select BOOT_ENCRYPT_X25519 if BOOT_SIGNATURE_TYPE_ED25519
714+
help
715+
Hidden option for default behaviour where AES encryption key
716+
is derived from Public Key Cryptography key exchange.
717+
718+
config BOOT_ENCRYPT_IMAGE
719+
bool "Support for encrypted image updates"
720+
depends on BOOT_ENCRYPTION_SUPPORT
662721
depends on !SINGLE_APPLICATION_SLOT || MCUBOOT_SERIAL
663722
help
664723
If y, images in the secondary slot can be encrypted and are decrypted

boot/zephyr/include/mcuboot_config/mcuboot_config.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,11 @@
151151
#define MCUBOOT_USE_TLV_ALLOW_LIST 1
152152
#endif
153153

154+
#ifdef CONFIG_BOOT_ENCRYPT_IMAGE_WITH_EMBEDDED_KEY
155+
#define MCUBOOT_ENC_IMAGES
156+
#define MCUBOOT_BUILTIN_ENC_KEY
157+
#endif
158+
154159
#ifdef CONFIG_BOOT_ENCRYPT_RSA
155160
#define MCUBOOT_ENC_IMAGES
156161
#define MCUBOOT_ENCRYPT_RSA
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#
2+
# Copyright (c) 2025 Nordic Semiconductor ASA
3+
#
4+
# SPDX-License-Identifier: Apache-2.0
5+
#
6+
7+
zephyr_library_sources(
8+
boot_take_enc_key.c
9+
)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
This is template for custom AES key provider.
2+
3+
The template can be used as a starter for your own implementation.
4+
To use the template, copy it somewhere where you want to continue
5+
development of the provider and then use following Kconfig options,
6+
for MCUboot, to include it into your build:
7+
CONFIG_BOOT_ENCRYPT_IMAGE_USE_CUSTOM_KEY_PROVIDER=y
8+
CONFIG_BOOT_ENCRYPT_IMAGE_EMBEDDED_CUSTOM_KEY_PROVIDER_DIR=<dir>
9+
10+
where <dir> is absolute path or path relative to the MCUboot source
11+
code dir.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
*
4+
* Copyright (c) 2025 Nordic Semiconductor ASA
5+
*
6+
*/
7+
8+
#include <stddef.h>
9+
#include <stdbool.h>
10+
#include <inttypes.h>
11+
#include <stdlib.h>
12+
#include <string.h>
13+
/* Logging */
14+
#include "bootutil/bootutil_log.h"
15+
16+
#include "mcuboot_config/mcuboot_config.h"
17+
18+
BOOT_LOG_MODULE_DECLARE(mcuboot_ekp);
19+
20+
int boot_take_enc_key(uint8_t *key, int image, int slot)
21+
{
22+
#error The key processing is missing here
23+
/* Provide your key selection logic here */
24+
25+
return 0;
26+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
*
4+
* Copyright (c) 2025 Nordic Semiconductor ASA
5+
*
6+
*/
7+
8+
#include <stddef.h>
9+
#include <stdbool.h>
10+
#include <inttypes.h>
11+
#include <stdlib.h>
12+
#include <string.h>
13+
14+
#include "mcuboot_config/mcuboot_config.h"
15+
#include "bootutil/enc_key.h"
16+
17+
int boot_take_enc_key(uint8_t *key, int image, int slot)
18+
{
19+
const unsigned char array[] = {
20+
@BOOT_AES_RAW_KEY_HEX_ARRAY@
21+
};
22+
23+
memcpy(key, array, sizeof(array));
24+
25+
return 0;
26+
}

0 commit comments

Comments
 (0)