Skip to content

Commit d28a205

Browse files
authored
Merge pull request #610 from danielinux/fix_reuse_iv_fallback
Refactoring of IV handling to prevent reusing IVs
2 parents 68d28fc + 480f310 commit d28a205

File tree

8 files changed

+280
-56
lines changed

8 files changed

+280
-56
lines changed

include/encrypt.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,5 +69,10 @@ void aes_set_iv(uint8_t *nonce, uint32_t address);
6969
int ext_flash_encrypt_write(uintptr_t address, const uint8_t *data, int len);
7070
int ext_flash_decrypt_read(uintptr_t address, uint8_t *data, int len);
7171

72+
#ifdef EXT_ENCRYPTED
73+
int wolfBoot_enable_fallback_iv(int enable);
74+
void wolfBoot_crypto_set_iv(const uint8_t *nonce, uint32_t iv_counter);
75+
#endif
76+
7277
#endif /* __WOLFBOOT || UNIT_TEST */
7378
#endif /* ENCRYPT_H_INCLUDED */

include/wolfboot/wolfboot.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,7 @@ int wolfBoot_get_partition_state(uint8_t part, uint8_t *st);
381381

382382
#ifdef EXT_ENCRYPTED
383383
/* Encryption support */
384+
384385
#if defined(ENCRYPT_WITH_CHACHA)
385386
#define ENCRYPT_BLOCK_SIZE 64
386387
#define ENCRYPT_KEY_SIZE 32 /* Chacha20 - 256bit */

src/libwolfboot.c

Lines changed: 47 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -62,18 +62,23 @@
6262

6363
#include <stddef.h> /* for size_t */
6464

65-
#if defined(EXT_ENCRYPTED)
65+
#if defined(EXT_ENCRYPTED) && (defined(__WOLFBOOT) || defined(UNIT_TEST))
66+
#include "encrypt.h"
6667
static int encrypt_initialized = 0;
6768

6869
static uint8_t encrypt_iv_nonce[ENCRYPT_NONCE_SIZE] XALIGNED(4);
69-
#if defined(__WOLFBOOT)
70-
#include "encrypt.h"
71-
#elif !defined(XMEMSET)
70+
static uint32_t encrypt_iv_offset = 0;
71+
72+
#define FALLBACK_IV_OFFSET 0x00100000U
73+
#if !defined(XMEMSET)
7274
#include <string.h>
7375
#define XMEMSET memset
7476
#define XMEMCPY memcpy
7577
#define XMEMCMP memcmp
7678
#endif
79+
#if defined(ENCRYPT_WITH_AES128) || defined(ENCRYPT_WITH_AES256)
80+
extern void aes_set_iv(uint8_t *nonce, uint32_t address);
81+
#endif
7782

7883
#if defined (__WOLFBOOT) || defined (UNIT_TEST)
7984
int wolfBoot_initialize_encryption(void)
@@ -1027,7 +1032,7 @@ static int decrypt_header(uint8_t *src)
10271032
uint32_t magic;
10281033
uint32_t len;
10291034
for (i = 0; i < IMAGE_HEADER_SIZE; i+=ENCRYPT_BLOCK_SIZE) {
1030-
crypto_set_iv(encrypt_iv_nonce, i / ENCRYPT_BLOCK_SIZE);
1035+
wolfBoot_crypto_set_iv(encrypt_iv_nonce, i / ENCRYPT_BLOCK_SIZE);
10311036
crypto_decrypt(dec_hdr + i, src + i, ENCRYPT_BLOCK_SIZE);
10321037
}
10331038
magic = *((uint32_t*)(dec_hdr));
@@ -1359,6 +1364,7 @@ int wolfBoot_fallback_is_possible(void)
13591364

13601365
#ifdef EXT_ENCRYPTED
13611366
#include "encrypt.h"
1367+
#include "string.h"
13621368

13631369
#if defined(WOLFBOOT_RENESAS_TSIP)
13641370
#include "wolfssl/wolfcrypt/port/Renesas/renesas-tsip-crypt.h"
@@ -1388,6 +1394,39 @@ int wolfBoot_fallback_is_possible(void)
13881394
static uint8_t ENCRYPT_KEY[ENCRYPT_KEY_SIZE + ENCRYPT_NONCE_SIZE];
13891395
#endif
13901396

1397+
#if defined(EXT_ENCRYPTED) && (defined(__WOLFBOOT) || defined(UNIT_TEST))
1398+
int RAMFUNCTION wolfBoot_enable_fallback_iv(int enable)
1399+
{
1400+
int prev = 0;
1401+
if (encrypt_iv_offset != 0)
1402+
prev = 1;
1403+
1404+
if (enable)
1405+
encrypt_iv_offset = FALLBACK_IV_OFFSET;
1406+
else
1407+
encrypt_iv_offset = 0;
1408+
1409+
return prev;
1410+
}
1411+
1412+
void RAMFUNCTION wolfBoot_crypto_set_iv(const uint8_t *nonce, uint32_t iv_counter)
1413+
{
1414+
#if defined(ENCRYPT_WITH_CHACHA)
1415+
crypto_set_iv((uint8_t *)nonce, iv_counter + encrypt_iv_offset);
1416+
#elif defined(ENCRYPT_WITH_AES128) || defined(ENCRYPT_WITH_AES256)
1417+
uint8_t local_nonce[ENCRYPT_NONCE_SIZE];
1418+
XMEMCPY(local_nonce, nonce, ENCRYPT_NONCE_SIZE);
1419+
crypto_set_iv(local_nonce, iv_counter + encrypt_iv_offset);
1420+
#else
1421+
(void)nonce;
1422+
(void)iv_counter;
1423+
#endif
1424+
1425+
/* Fallback IV offset is single-use; clear it once applied. */
1426+
encrypt_iv_offset = 0;
1427+
}
1428+
#endif /* EXT_ENCRYPTED && (__WOLFBOOT || UNIT_TEST) */
1429+
13911430
static int RAMFUNCTION hal_set_key(const uint8_t *k, const uint8_t *nonce)
13921431
{
13931432
#ifdef WOLFBOOT_RENESAS_TSIP
@@ -1808,8 +1847,7 @@ int RAMFUNCTION ext_flash_encrypt_write(uintptr_t address, const uint8_t *data,
18081847
}
18091848
if (wolfBoot_initialize_encryption() < 0)
18101849
return -1;
1811-
1812-
crypto_set_iv(encrypt_iv_nonce, iv_counter);
1850+
wolfBoot_crypto_set_iv(encrypt_iv_nonce, iv_counter);
18131851
break;
18141852
case PART_SWAP:
18151853
/* data is coming from update and is already encrypted */
@@ -1892,7 +1930,7 @@ int RAMFUNCTION ext_flash_decrypt_read(uintptr_t address, uint8_t *data, int len
18921930
return -1;
18931931
}
18941932
}
1895-
crypto_set_iv(encrypt_iv_nonce, iv_counter);
1933+
wolfBoot_crypto_set_iv(encrypt_iv_nonce, iv_counter);
18961934
break;
18971935
case PART_SWAP:
18981936
break;
@@ -1988,7 +2026,7 @@ int wolfBoot_ram_decrypt(uint8_t *src, uint8_t *dst)
19882026

19892027
/* decrypt content */
19902028
while (dst_offset < (len + IMAGE_HEADER_SIZE)) {
1991-
crypto_set_iv(encrypt_iv_nonce, iv_counter);
2029+
wolfBoot_crypto_set_iv(encrypt_iv_nonce, iv_counter);
19922030
crypto_decrypt(dec_block, row_address, ENCRYPT_BLOCK_SIZE);
19932031
XMEMCPY(dst + dst_offset, dec_block, ENCRYPT_BLOCK_SIZE);
19942032
row_address += ENCRYPT_BLOCK_SIZE;
@@ -2035,4 +2073,3 @@ int wolfBoot_nsc_write_update(uint32_t address, const uint8_t *buf, uint32_t len
20352073
}
20362074

20372075
#endif
2038-

0 commit comments

Comments
 (0)