Skip to content

Commit c0c7885

Browse files
committed
Add support of xip encryption mode for swap
Signed-off-by: INFINEON\DovhalA <artem.dovhal@infineon.com>
1 parent d045415 commit c0c7885

33 files changed

Lines changed: 2885 additions & 91 deletions

.github/workflows/sim.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ jobs:
4444
- "sig-rsa validate-primary-slot ram-load multiimage"
4545
- "sig-rsa validate-primary-slot direct-xip multiimage"
4646
- "sig-ecdsa hw-rollback-protection multiimage"
47+
- "enc-xip-ec256,enc-xip-ec256 swap-move,enc-xip-ec256 swap-offset"
48+
- "sig-ecdsa enc-xip-ec256 validate-primary-slot,enc-xip-ec256 overwrite-only"
4749
- "sig-ecdsa-psa,sig-ecdsa-psa sig-p384,sig-ecdsa-psa swap-move bootstrap max-align-16"
4850
- "sig-ecdsa-psa enc-ec256 max-align-16, sig-ecdsa-psa enc-ec256 swap-offset validate-primary-slot max-align-16"
4951
- "ram-load enc-aes256-kw multiimage"

boot/boot_serial/src/boot_serial.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,7 @@ bs_list(struct boot_loader_state *state, char *buf, int len)
352352
{
353353
BOOT_HOOK_CALL_FIH(boot_image_check_hook,
354354
FIH_BOOT_HOOK_REGULAR,
355-
fih_rc, image_index, slot);
355+
fih_rc, NULL, image_index, slot);
356356
if (FIH_EQ(fih_rc, FIH_BOOT_HOOK_REGULAR))
357357
{
358358
#if defined(MCUBOOT_ENC_IMAGES)
@@ -574,7 +574,7 @@ bs_set(struct boot_loader_state *state, char *buf, int len)
574574

575575
BOOT_HOOK_CALL_FIH(boot_image_check_hook,
576576
FIH_BOOT_HOOK_REGULAR,
577-
fih_rc, image_index, slot);
577+
fih_rc, NULL, image_index, slot);
578578
if (FIH_EQ(fih_rc, FIH_BOOT_HOOK_REGULAR))
579579
{
580580
#ifdef MCUBOOT_ENC_IMAGES

boot/bootutil/include/bootutil/boot_hooks.h

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,14 +127,29 @@ int boot_read_image_header_hook(int img_index, int slot,
127127
* This Hook may be used to overide image validation procedure or doing
128128
* a custom action before.
129129
*
130+
* @param state boot loader state (may be NULL when called outside
131+
* the normal boot flow, e.g. serial recovery)
130132
* @param img_index the index of the image pair
131133
* @param slot slot number
132-
*
134+
*
133135
* @retval FIH_SUCCESS: image is valid, skip direct validation
134136
* FIH_FAILURE: image is invalid, skip direct validation
135137
* FIH_BOOT_HOOK_REGULAR: follow the normal execution path.
136138
*/
137-
fih_ret boot_image_check_hook(int img_index, int slot);
139+
fih_ret boot_image_check_hook(struct boot_loader_state *state,
140+
int img_index, int slot);
141+
142+
#if defined(MCUBOOT_ENC_IMAGES_XIP)
143+
/** Hook for populating XIP encryption key/IV in boot response.
144+
*
145+
* Called after fill_rsp() to copy the image's encryption key and IV
146+
* into boot_rsp for post-boot hardware crypto region setup.
147+
*
148+
* @param img_index the index of the current image
149+
* @param rsp the boot response struct to populate
150+
*/
151+
void boot_xip_populate_rsp(int img_index, struct boot_rsp *rsp);
152+
#endif
138153

139154
/** Hook for implement image update
140155
*

boot/bootutil/include/bootutil/bootutil.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@ struct boot_rsp {
5959
*/
6060
uint8_t br_flash_dev_id;
6161
uint32_t br_image_off;
62+
#if defined(MCUBOOT_ENC_IMAGES_XIP)
63+
/** AES-128 key for post-boot XIP hardware crypto setup. */
64+
uint32_t br_xip_key[4];
65+
/** IV/nonce for post-boot XIP hardware crypto setup. */
66+
uint32_t br_xip_iv[4];
67+
#endif
6268
};
6369

6470
/* This is not actually used by mcuboot's code but can be used by apps

boot/bootutil/include/bootutil/caps.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ uint32_t bootutil_get_caps(void);
5454
#define BOOTUTIL_CAP_HW_ROLLBACK_PROT (1<<18)
5555
#define BOOTUTIL_CAP_ECDSA_P384 (1<<19)
5656
#define BOOTUTIL_CAP_SWAP_USING_OFFSET (1<<20)
57+
#define BOOTUTIL_CAP_ENC_XIP_EC256 (1<<21)
5758

5859
/*
5960
* Query the number of images this bootloader is configured for. This

boot/bootutil/src/bootutil_loader.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ boot_check_header_valid(struct boot_loader_state *state, int slot)
9999
return false;
100100
}
101101

102-
#if !defined(MCUBOOT_ENC_IMAGES)
102+
#if !defined(MCUBOOT_ENC_IMAGES) && !defined(MCUBOOT_ENC_IMAGES_XIP)
103103
if (IS_ENCRYPTED(hdr)) {
104104
return false;
105105
}

boot/bootutil/src/bootutil_priv.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,12 @@ _Static_assert(sizeof(boot_img_magic) == BOOT_MAGIC_SZ, "Invalid size for image
197197
#endif /* MCUBOOT_DIRECT_XIP && MCUBOOT_ENC_IMAGES */
198198
#endif /* MCUBOOT_DIRECT_XIP || MCUBOOT_RAM_LOAD */
199199

200+
#if defined(MCUBOOT_ENC_IMAGES) && defined(MCUBOOT_ENC_IMAGES_XIP)
201+
#error "MCUBOOT_ENC_IMAGES and MCUBOOT_ENC_IMAGES_XIP are mutually exclusive. " \
202+
"XIP encryption keeps images encrypted in both slots and does not use " \
203+
"the standard encrypt/decrypt-during-swap mechanism."
204+
#endif
205+
200206
#define BOOT_LOG_IMAGE_INFO(slot, hdr) \
201207
BOOT_LOG_INF("%-9s slot: version=%u.%u.%u+%u", \
202208
((slot) == BOOT_SLOT_PRIMARY) ? "Primary" : "Secondary", \

boot/bootutil/src/caps.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ uint32_t bootutil_get_caps(void)
8383
#if defined(MCUBOOT_HW_ROLLBACK_PROT)
8484
res |= BOOTUTIL_CAP_HW_ROLLBACK_PROT;
8585
#endif
86+
#if defined(MCUBOOT_ENC_IMAGES_XIP)
87+
res |= BOOTUTIL_CAP_ENC_XIP_EC256;
88+
#endif
8689

8790
return res;
8891
}

boot/bootutil/src/loader.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@
5555
#include "bootutil/enc_key.h"
5656
#endif
5757

58+
#if defined(MCUBOOT_ENC_IMAGES_XIP)
59+
#include "xip_enc/xip_enc.h"
60+
#endif
61+
5862
#if !defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD)
5963
#include <os/os_malloc.h>
6064
#endif
@@ -636,7 +640,7 @@ boot_validate_slot(struct boot_loader_state *state, int slot,
636640
fih_rc = FIH_FAILURE;
637641
} else {
638642
BOOT_HOOK_CALL_FIH(boot_image_check_hook, FIH_BOOT_HOOK_REGULAR,
639-
fih_rc, BOOT_CURR_IMG(state), slot);
643+
fih_rc, state, BOOT_CURR_IMG(state), slot);
640644
if (FIH_EQ(fih_rc, FIH_BOOT_HOOK_REGULAR)) {
641645
FIH_CALL(boot_check_image, fih_rc, state, bs, slot);
642646
}
@@ -1970,6 +1974,11 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp)
19701974

19711975
fill_rsp(state, rsp);
19721976

1977+
#if defined(MCUBOOT_ENC_IMAGES_XIP)
1978+
boot_xip_populate_rsp(BOOT_CURR_IMG(state), rsp);
1979+
xip_enc_clear_keys();
1980+
#endif
1981+
19731982
fih_rc = FIH_SUCCESS;
19741983
out:
19751984
/*
@@ -2454,6 +2463,11 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp)
24542463

24552464
fill_rsp(state, rsp);
24562465

2466+
#if defined(MCUBOOT_ENC_IMAGES_XIP)
2467+
boot_xip_populate_rsp(BOOT_CURR_IMG(state), rsp);
2468+
xip_enc_clear_keys();
2469+
#endif
2470+
24572471
close:
24582472
boot_close_all_flash_areas(state);
24592473

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
*
4+
* XIP Multi-Key Encryption Library
5+
* Self-contained library for XIP encryption support in MCUBoot.
6+
* Interfaces with MCUBoot via boot_image_check_hook (existing hook).
7+
*/
8+
#ifndef XIP_ENC_H
9+
#define XIP_ENC_H
10+
11+
#include <stdint.h>
12+
#include <stdbool.h>
13+
#include <string.h>
14+
#include "bootutil/bootutil.h"
15+
#include "bootutil/image.h"
16+
#include "flash_map_backend/flash_map_backend.h"
17+
#include "mcuboot_config/mcuboot_config.h"
18+
19+
#if defined(MCUBOOT_ENC_IMAGES) && defined(MCUBOOT_ENC_IMAGES_XIP)
20+
#error "MCUBOOT_ENC_IMAGES and MCUBOOT_ENC_IMAGES_XIP are mutually exclusive."
21+
#endif
22+
23+
/**
24+
* Secure zeroization -- uses volatile pointer to prevent compiler optimization.
25+
*/
26+
static inline void xip_enc_zeroize(void *p, size_t n)
27+
{
28+
volatile unsigned char *v = (volatile unsigned char *)p;
29+
for (size_t i = 0; i < n; i++) {
30+
v[i] = 0;
31+
}
32+
}
33+
34+
/**
35+
* Constant-time comparison to avoid timing side-channels.
36+
* Returns 0 if equal, non-zero otherwise.
37+
*/
38+
static inline int xip_enc_ct_compare(const uint8_t *a, const uint8_t *b,
39+
size_t size)
40+
{
41+
uint8_t result = 0;
42+
for (size_t i = 0; i < size; i++) {
43+
result |= a[i] ^ b[i];
44+
}
45+
return (int)result;
46+
}
47+
48+
#define XIP_ENC_KEY_SIZE 16u
49+
#define XIP_ENC_IV_SIZE 16u
50+
#define XIP_ENC_MAX_IMAGES 3u
51+
52+
/*
53+
* boot_image_check_hook() is declared in bootutil/boot_hooks.h (upstream).
54+
* The library provides the implementation in xip_enc_validate.c.
55+
* Do NOT redeclare here.
56+
*/
57+
58+
/**
59+
* Called by MCUBoot after fill_rsp() to populate xip_key/xip_iv in boot_rsp.
60+
* Copies key/IV from library-internal storage for the specified image.
61+
*
62+
* @param img_index Image index (passed via BOOT_CURR_IMG from MCUBoot)
63+
* @param rsp Boot response to populate
64+
*/
65+
void boot_xip_populate_rsp(int img_index, struct boot_rsp *rsp);
66+
67+
/**
68+
* Platform-provided: decrypt image payload using SMIF hardware.
69+
* Used during hash computation to decrypt AES-CTR encrypted payload.
70+
*
71+
* @param image_index Current image index
72+
* @param fap Flash area of the image
73+
* @param off Offset within flash area
74+
* @param sz Size of data to decrypt
75+
* @param buf Buffer with data to decrypt (in-place)
76+
*
77+
* @return 0 on success, negative on error
78+
*/
79+
int boot_decrypt_xip(int image_index, const struct flash_area *fap,
80+
uint32_t off, uint32_t sz, uint8_t *buf);
81+
82+
/**
83+
* Store key/IV for an image (called by validation hook after ECIES unwrap).
84+
*/
85+
void xip_enc_store_key(int img_index, const uint8_t *key, const uint8_t *iv);
86+
87+
/**
88+
* Retrieve stored key/IV for an image.
89+
*
90+
* @return 0 on success, -1 if not valid
91+
*/
92+
int xip_enc_get_key(int img_index, uint8_t *key, uint8_t *iv);
93+
94+
/**
95+
* Zeroize all stored keys. Call before launching application.
96+
*/
97+
void xip_enc_clear_keys(void);
98+
99+
/**
100+
* ECIES-P256 key unwrap with extended TLV support.
101+
* Extracts AES key and XIP IV from ECIES envelope.
102+
*
103+
* @param tlv_buf ECIES TLV data read from image
104+
* @param tlv_len Length of TLV data (113 standard, up to 177 extended)
105+
* @param out_key Output: 16-byte AES key
106+
* @param out_iv Output: 16-byte XIP IV
107+
*
108+
* @return 0 on success, negative on error
109+
*/
110+
int xip_enc_ecies_unwrap(const uint8_t *tlv_buf, uint16_t tlv_len,
111+
uint8_t *out_key, uint8_t *out_iv);
112+
113+
#endif /* XIP_ENC_H */

0 commit comments

Comments
 (0)