bootutil: allow encryption key TLVs in swap status
Add a new option that when enabled, allows a swap status to store
an encrypted key TLV instead of plain keys. When a new swap operation is
started the encryption keys are saved to the swap status area to allow
for resuming (because it is challenging to find those TLV in the middle
of a swap operation).
Previously those keys were saved in plain text, so it would be easy to
dump them if the images were stored in external flash. With this new
option one can choose to save the TLV instead, which uses more flash
but does not leak secrets. The amount of flash required varies depending
on the size of the TLV, which is 48 for AES-128-KW, 512 for RSA and 240
for ECIES-P256.
Signed-off-by: Fabio Utzig <utzig@apache.org>
diff --git a/boot/bootutil/src/bootutil_misc.c b/boot/bootutil/src/bootutil_misc.c
index a29a27d..ab79b8b 100644
--- a/boot/bootutil/src/bootutil_misc.c
+++ b/boot/bootutil/src/bootutil_misc.c
@@ -161,7 +161,11 @@
boot_status_sz(min_write_sz) +
#ifdef MCUBOOT_ENC_IMAGES
/* encryption keys */
+# if MCUBOOT_SWAP_SAVE_ENCTLV
+ BOOT_ENC_TLV_ALIGN_SIZE * 2 +
+# else
BOOT_ENC_KEY_SIZE * 2 +
+# endif
#endif
/* swap_type + copy_done + image_ok + swap_size */
BOOT_MAX_ALIGN * 4 +
@@ -231,7 +235,12 @@
static inline uint32_t
boot_enc_key_off(const struct flash_area *fap, uint8_t slot)
{
+#if MCUBOOT_SWAP_SAVE_ENCTLV
+ return boot_swap_size_off(fap) - ((slot + 1) *
+ ((((BOOT_ENC_TLV_SIZE - 1) / BOOT_MAX_ALIGN) + 1) * BOOT_MAX_ALIGN));
+#else
return boot_swap_size_off(fap) - ((slot + 1) * BOOT_ENC_KEY_SIZE);
+#endif
}
#endif
@@ -390,16 +399,34 @@
#ifdef MCUBOOT_ENC_IMAGES
int
-boot_read_enc_key(int image_index, uint8_t slot, uint8_t *enckey)
+boot_read_enc_key(int image_index, uint8_t slot, struct boot_status *bs)
{
uint32_t off;
const struct flash_area *fap;
+#if MCUBOOT_SWAP_SAVE_ENCTLV
+ int i;
+#endif
int rc;
rc = boot_find_status(image_index, &fap);
if (rc == 0) {
off = boot_enc_key_off(fap, slot);
- rc = flash_area_read(fap, off, enckey, BOOT_ENC_KEY_SIZE);
+#if MCUBOOT_SWAP_SAVE_ENCTLV
+ rc = flash_area_read(fap, off, bs->enctlv[slot], BOOT_ENC_TLV_ALIGN_SIZE);
+ if (rc == 0) {
+ for (i = 0; i < BOOT_ENC_TLV_ALIGN_SIZE; i++) {
+ if (bs->enctlv[slot][i] != 0xff) {
+ break;
+ }
+ }
+ /* Only try to decrypt non-erased TLV metadata */
+ if (i != BOOT_ENC_TLV_ALIGN_SIZE) {
+ rc = boot_enc_decrypt(bs->enctlv[slot], bs->enckey[slot]);
+ }
+ }
+#else
+ rc = flash_area_read(fap, off, bs->enckey[slot], BOOT_ENC_KEY_SIZE);
+#endif
flash_area_close(fap);
}
@@ -526,7 +553,8 @@
#ifdef MCUBOOT_ENC_IMAGES
int
-boot_write_enc_key(const struct flash_area *fap, uint8_t slot, const uint8_t *enckey)
+boot_write_enc_key(const struct flash_area *fap, uint8_t slot,
+ const struct boot_status *bs)
{
uint32_t off;
int rc;
@@ -535,7 +563,11 @@
BOOT_LOG_DBG("writing enc_key; fa_id=%d off=0x%lx (0x%lx)",
fap->fa_id, (unsigned long)off,
(unsigned long)fap->fa_off + off);
- rc = flash_area_write(fap, off, enckey, BOOT_ENC_KEY_SIZE);
+#if MCUBOOT_SWAP_SAVE_ENCTLV
+ rc = flash_area_write(fap, off, bs->enctlv[slot], BOOT_ENC_TLV_ALIGN_SIZE);
+#else
+ rc = flash_area_write(fap, off, bs->enckey[slot], BOOT_ENC_KEY_SIZE);
+#endif
if (rc != 0) {
return BOOT_EFLASH;
}