Skip to content

Commit daae031

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 <[email protected]>
1 parent 206c01a commit daae031

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
@@ -391,57 +391,59 @@ if(NOT CONFIG_BOOT_SIGNATURE_KEY_FILE STREQUAL "")
391391
endif()
392392

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

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

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

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

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