From 869f15bf94d07cd5663eb0470a061301c371509d Mon Sep 17 00:00:00 2001 From: David Garske Date: Thu, 8 May 2025 14:54:50 -0700 Subject: [PATCH 01/18] Improvements for portability using older gcc 4.8.2. Make sure wolfboot.h includes the `wolfBoot_verify_*` API's. Fixed issue with parsing headers when `#include` is `# include`. --- docs/Renesas.md | 19 ++++++++++++++++--- include/image.h | 1 - include/user_settings.h | 3 +++ include/wolfboot/wolfboot.h | 24 +++++++++++++++++++++--- src/delta.c | 2 +- 5 files changed, 41 insertions(+), 8 deletions(-) diff --git a/docs/Renesas.md b/docs/Renesas.md index a2e5fd72e9..a5568d33af 100644 --- a/docs/Renesas.md +++ b/docs/Renesas.md @@ -17,7 +17,7 @@ Platforms Supported: All of the Renesas examples support using e2Studio. The Renesas RX parts support using wolfBoot Makefile's with the rx-elf-gcc cross-compiler and example .config files. -### Security Key Management Tool (SKMT) Key Wrapping +## Security Key Management Tool (SKMT) Key Wrapping 1) Setup a Renesas KeyWrap account and do the PGP key exchange. https://dlm.renesas.com/keywrap @@ -34,7 +34,7 @@ Use GPG4Win and the Sign/Encrypt option. Sign with your own GPG key and encrypt It will use the Hidden Root Key (HRK) that both Renesas and the RX TSIP have pre-provisioned from Renesas Factory. Result is `sample.key_enc.key`. Example: `00000001 6CCB9A1C 8AA58883 B1CB02DE 6C37DA60 54FB94E2 06EAE720 4D9CCF4C 6EEB288C` -### RX TSIP +## RX TSIP 1) Build key tools for Renesas @@ -164,7 +164,7 @@ Output image(s) successfully created. Download files to flash using Renesas flash programmer. -#### RX TSIP Benchmarks +### RX TSIP Benchmarks | Hardware | Clock | Algorithm | RX TSIP | Debug | Release (-Os) | Release (-O2) | | -------- | ------ | ----------------- | -------- | -------- | ------------- | ------------- | @@ -172,3 +172,16 @@ Download files to flash using Renesas flash programmer. | RX72N | 240MHz | ECDSA Verify P256 | 2.73 ms | 469 ms | 135 ms | 107 ms | | RX65N | 120MHz | ECDSA Verify P384 | 18.57 ms | 4213 ms | 2179 ms | 1831 ms | | RX65N | 120MHz | ECDSA Verify P256 | 2.95 ms | 1208 ms | 602 ms | 517 ms | + + +## RX Production Protection (recommendations) + +1) Lockdown external serial programmer `SPCC.SPE = 0` +2) Flash Access Window Setting Register (FAW) + * BTFLG: Start-up Area Select FAW.BTFLG (1=FFFF E000h to FFFF FFFFh, 0=FFFF C000h to FFFF DFFFh) + * FSPR - FAW.FSPR Access Window Protection (0=protections enabled) Once changed to 0 cannot be reset. +3) ROM Code Protection Register `ROMCODE.CODE[31:0]` + * 0000 0000h: ROM code protection enabled (ROM code protection 1) + * 0000 0001h: ROM code protection enabled (ROM code protection 2) + * Other than above: ROM code protection disabled +4) Options Trusted Memory (TM) Enable `TMEF.TMEF[2:0] = b000` - prevents reading of blocks 8 and 9 (see 59.17 Trusted Memory) - Location for keys or code that should not be read diff --git a/include/image.h b/include/image.h index 0697ab805a..d2a3049d96 100644 --- a/include/image.h +++ b/include/image.h @@ -833,7 +833,6 @@ int wolfBoot_open_image_external(struct wolfBoot_image* img, uint8_t part, uint8 int wolfBoot_open_image_address(struct wolfBoot_image* img, uint8_t* image); int wolfBoot_verify_integrity(struct wolfBoot_image *img); int wolfBoot_verify_authenticity(struct wolfBoot_image *img); -int wolfBoot_get_partition_state(uint8_t part, uint8_t *st); int wolfBoot_set_partition_state(uint8_t part, uint8_t newst); int wolfBoot_get_update_sector_flag(uint16_t sector, uint8_t *flag); int wolfBoot_set_update_sector_flag(uint16_t sector, uint8_t newflag); diff --git a/include/user_settings.h b/include/user_settings.h index 299bbf3baf..2c7ca4620f 100644 --- a/include/user_settings.h +++ b/include/user_settings.h @@ -37,6 +37,8 @@ #define WOLFSSL_USER_MUTEX /* avoid wc_port.c wc_InitAndAllocMutex */ #define WOLFCRYPT_ONLY #define SIZEOF_LONG_LONG 8 +#define HAVE_EMPTY_AGGREGATES 0 +#define HAVE_ANONYMOUS_INLINE_AGGREGATES 0 /* Stdlib Types */ #define CTYPE_USER /* don't let wolfCrypt types.h include ctype.h */ @@ -533,6 +535,7 @@ extern int tolower(int c); #ifdef WOLFBOOT_ENABLE_WOLFHSM_CLIENT # define WOLF_CRYPTO_CB +# undef HAVE_ANONYMOUS_INLINE_AGGREGATES # define HAVE_ANONYMOUS_INLINE_AGGREGATES 1 # define WOLFSSL_KEY_GEN #endif /* WOLFBOOT_ENABLE_WOLFHSM_CLIENT */ diff --git a/include/wolfboot/wolfboot.h b/include/wolfboot/wolfboot.h index 84aa389d9e..1487bc850e 100644 --- a/include/wolfboot/wolfboot.h +++ b/include/wolfboot/wolfboot.h @@ -163,7 +163,11 @@ extern "C" { /* Hashing configuration */ #if defined(WOLFBOOT_HASH_SHA256) -# include "wolfssl/wolfcrypt/sha256.h" + #include "wolfssl/wolfcrypt/settings.h" + #include "wolfssl/wolfcrypt/visibility.h" + #include "wolfssl/wolfcrypt/wc_port.h" + #include "wolfssl/wolfcrypt/types.h" + #include "wolfssl/wolfcrypt/sha256.h" # ifndef WOLFBOOT_SHA_BLOCK_SIZE # define WOLFBOOT_SHA_BLOCK_SIZE (256) # endif @@ -178,7 +182,11 @@ extern "C" { typedef wc_Sha256 wolfBoot_hash_t; # define HDR_HASH HDR_SHA256 #elif defined(WOLFBOOT_HASH_SHA384) -# include "wolfssl/wolfcrypt/sha512.h" + #include "wolfssl/wolfcrypt/settings.h" + #include "wolfssl/wolfcrypt/visibility.h" + #include "wolfssl/wolfcrypt/wc_port.h" + #include "wolfssl/wolfcrypt/types.h" + #include "wolfssl/wolfcrypt/sha512.h" # ifndef WOLFBOOT_SHA_BLOCK_SIZE # define WOLFBOOT_SHA_BLOCK_SIZE (256) # endif @@ -193,7 +201,11 @@ extern "C" { typedef wc_Sha384 wolfBoot_hash_t; # define HDR_HASH HDR_SHA384 #elif defined(WOLFBOOT_HASH_SHA3_384) -# include "wolfssl/wolfcrypt/sha3.h" + #include "wolfssl/wolfcrypt/settings.h" + #include "wolfssl/wolfcrypt/visibility.h" + #include "wolfssl/wolfcrypt/wc_port.h" + #include "wolfssl/wolfcrypt/types.h" + #include "wolfssl/wolfcrypt/sha3.h" # ifndef WOLFBOOT_SHA_BLOCK_SIZE # define WOLFBOOT_SHA_BLOCK_SIZE (128) # endif @@ -325,6 +337,12 @@ extern "C" { #define FLASH_WORD_ERASED 0x00000000UL #endif +#ifdef __WOLFBOOT + /* include after PART_* are defined */ + /* for wolfBoot_verify_integrity and wolfBoot_verify_authenticity */ + #include "image.h" +#endif + void wolfBoot_update_trigger(void); void wolfBoot_success(void); uint32_t wolfBoot_image_size(uint8_t *image); diff --git a/src/delta.c b/src/delta.c index 83e5ef6db3..f26f06b711 100644 --- a/src/delta.c +++ b/src/delta.c @@ -43,7 +43,7 @@ struct BLOCK_HDR_PACKED block_hdr { #define BLOCK_HDR_SIZE (sizeof (struct block_hdr)) #if defined(EXT_ENCRYPTED) && defined(__WOLFBOOT) -#include "encrypt.h" +#include "image.h" #define ext_flash_check_write ext_flash_encrypt_write #define ext_flash_check_read ext_flash_decrypt_read #elif defined(__WOLFBOOT) From 9804b088e7fb373cd2f91f1c53432fd0918bb974 Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 14 May 2025 15:15:39 -0700 Subject: [PATCH 02/18] Fix to force alignment on the flash header copy (hdr_cpy). Caused issues using wolfBoot as static library on Renesas RX. --- src/image.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/image.c b/src/image.c index e850a85988..a5d568db8b 100644 --- a/src/image.c +++ b/src/image.c @@ -772,7 +772,7 @@ static uint8_t *get_sha_block(struct wolfBoot_image *img, uint32_t offset) } #ifdef EXT_FLASH -static uint8_t hdr_cpy[IMAGE_HEADER_SIZE]; +static uint8_t XALIGNED(4) hdr_cpy[IMAGE_HEADER_SIZE]; static int hdr_cpy_done = 0; /** From a63d2a188a90aa2a8e534c3062cb29b0b7a15332 Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 2 Jun 2025 13:19:10 -0700 Subject: [PATCH 03/18] Fix for Renesas TSIP key types. Fix for Renesas RX .keystore location in linker script. Fix for wolfBoot as library with Renesas to make sure crypto hardware is initialized and setup. Add forced alignment on additional buffers used for flash read/write. --- hal/renesas-ra.c | 57 ++++++++++++++++---------- hal/renesas-rx.c | 79 ++++++++++++++++++++++--------------- hal/renesas-rz.c | 39 ++++++++++++------ include/user_settings.h | 1 + include/wolfboot/wolfboot.h | 2 +- src/image.c | 17 +++++--- tools/keytools/keygen.c | 6 +-- tools/keytools/keygen.py | 2 +- 8 files changed, 129 insertions(+), 74 deletions(-) mode change 100755 => 100644 tools/keytools/keygen.py diff --git a/hal/renesas-ra.c b/hal/renesas-ra.c index 4e90ff867f..ed36e57b5c 100644 --- a/hal/renesas-ra.c +++ b/hal/renesas-ra.c @@ -54,29 +54,19 @@ static inline void hal_panic(void) extern flash_ctrl_t g_flash0_ctrl; extern flash_cfg_t g_flash0_cfg; -void hal_init(void) +#if defined(WOLFBOOT_RENESAS_SCEPROTECT) && !defined(WOLFBOOT_RENESAS_APP) +static int sipInitDone = 0; +int hal_renesas_init(void) { fsp_err_t err; + uint32_t *pubkey; -#if defined(WOLFBOOT_RENESAS_SCEPROTECT) && !defined(WOLFBOOT_RENESAS_APP) - /* retrieve installed pubkey from flash */ - uint32_t *pubkey = keystore_get_buffer(0); -#endif - err = R_FLASH_HP_Close(&g_flash0_ctrl); - err = R_FLASH_HP_Open(&g_flash0_ctrl, &g_flash0_cfg); + if (sipInitDone) + return 0; - if(err != FSP_ERR_ALREADY_OPEN && err != FSP_SUCCESS){ - printf("ERROR: %d\n", err); - hal_panic(); - } + /* retrieve installed pubkey from flash */ + pubkey = keystore_get_buffer(0); - /* Setup Default Block 0 as Startup Setup Block */ - err = R_FLASH_HP_StartUpAreaSelect(&g_flash0_ctrl, FLASH_STARTUP_AREA_BLOCK0, true); - if(err != FSP_SUCCESS){ - printf("ERROR: %d\n", err); - hal_panic(); - } -#if defined(WOLFBOOT_RENESAS_SCEPROTECT) && !defined(WOLFBOOT_RENESAS_APP) err = wolfCrypt_Init(); if (err != 0) { printf("ERROR: wolfCrypt_Init %d\n", err); @@ -93,12 +83,39 @@ void hal_init(void) pkInfo.keyflgs_crypt.bits.rsapub2048_installedkey_set = 1; pkInfo.keyflgs_crypt.bits.message_type = 1; err = wc_CryptoCb_CryptInitRenesasCmn(NULL, &pkInfo); - if (err < 0) { printf("ERROR: wc_CryptoCb_CryptInitRenesasCmn %d\n", err); - hal_panic(); + return err; } + sipInitDone = 1; + return 0; +} +#endif +void hal_init(void) +{ + fsp_err_t err; + + err = R_FLASH_HP_Close(&g_flash0_ctrl); + err = R_FLASH_HP_Open(&g_flash0_ctrl, &g_flash0_cfg); + + if (err != FSP_ERR_ALREADY_OPEN && err != FSP_SUCCESS){ + wolfBoot_printf("ERROR: %d\n", err); + hal_panic(); + } + + /* Setup Default Block 0 as Startup Setup Block */ + err = R_FLASH_HP_StartUpAreaSelect(&g_flash0_ctrl, FLASH_STARTUP_AREA_BLOCK0, true); + if (err != FSP_SUCCESS){ + wolfBoot_printf("ERROR: %d\n", err); + hal_panic(); + } +#if defined(WOLFBOOT_RENESAS_SCEPROTECT) && !defined(WOLFBOOT_RENESAS_APP) + err = hal_renesas_init(); + if (err != 0) { + wolfBoot_printf("ERROR: hal_renesas_init %d\n", err); + hal_panic(); + } #endif } diff --git a/hal/renesas-rx.c b/hal/renesas-rx.c index 0141790388..66527b5f24 100644 --- a/hal/renesas-rx.c +++ b/hal/renesas-rx.c @@ -367,38 +367,21 @@ void hal_clk_init(void) PROTECT_ON(); /* write protect on */ } -void hal_init(void) +#if defined(WOLFBOOT_RENESAS_TSIP) && !defined(WOLFBOOT_RENESAS_APP) +static int sipInitDone = 0; +int hal_renesas_init(void) { -#if defined(WOLFBOOT_RENESAS_TSIP) && \ - !defined(WOLFBOOT_RENESAS_APP) int err; uint32_t key_type = 0; int tsip_key_type = -1; struct enc_pub_key *encrypted_user_key_data; -#endif - -/* For CCRX, mcu_clock_setup() in resetprg.c will set up clocks. */ -#if defined(__GNUC__) - hal_clk_init(); -#endif -#ifdef ENABLE_LED - hal_led_off(); -#endif + if (sipInitDone) + return 0; -#ifdef DEBUG_UART - uart_init(); - uart_write("wolfBoot HAL Init\n", 18); -#endif - - hal_flash_init(); - -#if defined(WOLFBOOT_RENESAS_TSIP) && \ - !defined(WOLFBOOT_RENESAS_APP) err = wolfCrypt_Init(); if (err != 0) { - wolfBoot_printf("ERROR: wolfCrypt_Init %d\n", err); - hal_panic(); + return err; } /* retrive installed pubkey data from flash */ @@ -407,19 +390,19 @@ void hal_init(void) key_type = keystore_get_key_type(0); switch (key_type) { case AUTH_KEY_RSA2048: - tsip_key_type = TSIP_RSA2048; + tsip_key_type = TSIP_KEY_TYPE_RSA2048; break; case AUTH_KEY_RSA3072: - tsip_key_type = TSIP_RSA3072; + tsip_key_type = TSIP_KEY_TYPE_RSA3072; break; case AUTH_KEY_RSA4096: - tsip_key_type = TSIP_RSA4096; + tsip_key_type = TSIP_KEY_TYPE_RSA4096; break; case AUTH_KEY_ECC256: - tsip_key_type = TSIP_ECCP256; + tsip_key_type = TSIP_KEY_TYPE_ECDSAP256; break; case AUTH_KEY_ECC384: - tsip_key_type = TSIP_ECCP384; + tsip_key_type = TSIP_KEY_TYPE_ECDSAP384; break; case AUTH_KEY_ECC521: case AUTH_KEY_ED25519: @@ -430,7 +413,7 @@ void hal_init(void) } if (tsip_key_type == -1) { wolfBoot_printf("key type (%d) not supported\n", key_type); - hal_panic(); + return -1; } /* Load encrypted UFPK (User Factory Programming Key) */ @@ -447,7 +430,7 @@ void hal_init(void) sizeof(encrypted_user_key_data->encrypted_user_key), tsip_key_type) != 0) { wolfBoot_printf("ERROR tsip_use_PublicKey_buffer\n"); - hal_panic(); + return -1; } /* Init Crypt Callback */ @@ -456,9 +439,43 @@ void hal_init(void) err = wc_CryptoCb_CryptInitRenesasCmn(NULL, &pkInfo); if (err < 0) { wolfBoot_printf("ERROR: wc_CryptoCb_CryptInitRenesasCmn %d\n", err); - hal_panic(); + return -1; } + sipInitDone = 1; + return 0; +} #endif /* TSIP */ + + +void hal_init(void) +{ +#if defined(WOLFBOOT_RENESAS_TSIP) && !defined(WOLFBOOT_RENESAS_APP) + int err; +#endif + +/* For CCRX, mcu_clock_setup() in resetprg.c will set up clocks. */ +#if defined(__GNUC__) + hal_clk_init(); +#endif + +#ifdef ENABLE_LED + hal_led_off(); +#endif + +#ifdef DEBUG_UART + uart_init(); + uart_write("wolfBoot HAL Init\n", 18); +#endif + + hal_flash_init(); + +#if defined(WOLFBOOT_RENESAS_TSIP) && !defined(WOLFBOOT_RENESAS_APP) + err = hal_renesas_init(); + if (err != 0) { + wolfBoot_printf("ERROR: hal_renesas_init %d\n", err); + hal_panic(); + } +#endif } void hal_prepare_boot(void) diff --git a/hal/renesas-rz.c b/hal/renesas-rz.c index f4a3124047..d1dc82d810 100644 --- a/hal/renesas-rz.c +++ b/hal/renesas-rz.c @@ -34,7 +34,7 @@ #include "wolfssl/wolfcrypt/wc_port.h" #include "wolfssl/wolfcrypt/port/Renesas/renesas-fspsm-crypt.h" #include "wolfssl/wolfcrypt/port/Renesas/renesas-fspsm-types.h" - + FSPSM_ST pkInfo; uint8_t wrapped_public_key[RSIP_BYTE_SIZE_WRAPPED_KEY_VALUE_RSA_2048_PUBLIC]; rsip_wrapped_key_t *p_wrapped_public_key = (rsip_wrapped_key_t *) wrapped_public_key; @@ -125,20 +125,22 @@ void ext_flash_unlock(void) #endif -void hal_init(void) -{ - #if defined(WOLFBOOT_RENESAS_RSIP) && !defined(WOLFBOOT_RENESAS_APP) - +static int sipInitDone = 0; +int hal_renesas_init(void) +{ fsp_err_t err; int ret; rsa_public_t rsip_pub_key; const size_t key_size = sizeof(rsip_pub_key); - err = wolfCrypt_Init(); - if (err != 0) { - printf("ERROR: wolfCrypt_Init %d\n", err); - hal_panic(); + if (sipInitDone) + reutrn 0; + + ret = wolfCrypt_Init(); + if (ret != 0) { + wolfBoot_printf("ERROR: wolfCrypt_Init %d\n", ret); + return ret; } /* copy the key from ext flash to RAM */ @@ -146,8 +148,8 @@ void hal_init(void) (uint8_t*)RENESAS_RSIP_INSTALLEDKEY_RAM_ADDR, key_size); if (ret != key_size){ wolfBoot_printf("Error reading public key at %lx\n", - RENESAS_RSIP_INSTALLEDKEY_FLASH_ADDR); - hal_panic(); + RENESAS_RSIP_INSTALLEDKEY_FLASH_ADDR); + return -1; } /* import enrypted key */ XMEMCPY(&rsip_pub_key, (const void*)RENESAS_RSIP_INSTALLEDKEY_RAM_ADDR, key_size); @@ -166,12 +168,23 @@ void hal_init(void) pkInfo.keyflgs_crypt.bits.message_type = 1; pkInfo.hash_type = RSIP_HASH_TYPE_SHA256; err = wc_CryptoCb_CryptInitRenesasCmn(NULL, &pkInfo); - if (err < 0) { wolfBoot_printf("ERROR: wc_CryptoCb_CryptInitRenesasCmn %d\n", err); - hal_panic(); + return err; } + sipInitDone = 1; + return 0; +} +#endif +void hal_init(void) +{ +#if defined(WOLFBOOT_RENESAS_RSIP) && !defined(WOLFBOOT_RENESAS_APP) + int err = hal_renesas_init(); + if (err != 0) { + printf("ERROR: hal_renesas_init %d\n", err); + hal_panic(); + } #endif } diff --git a/include/user_settings.h b/include/user_settings.h index 2c7ca4620f..b1c0d524cd 100644 --- a/include/user_settings.h +++ b/include/user_settings.h @@ -501,6 +501,7 @@ extern int tolower(int c); #define WOLF_CRYPTO_CB_ONLY_ECC #define WOLF_CRYPTO_CB_ONLY_RSA #define WOLFSSL_NO_SW_MATH + #define MAX_CRYPTO_DEVID_CALLBACKS 2 #ifdef WOLFBOOT_RENESAS_TSIP #define WOLFSSL_RENESAS_TSIP diff --git a/include/wolfboot/wolfboot.h b/include/wolfboot/wolfboot.h index 1487bc850e..fba0f4d5dc 100644 --- a/include/wolfboot/wolfboot.h +++ b/include/wolfboot/wolfboot.h @@ -207,7 +207,7 @@ extern "C" { #include "wolfssl/wolfcrypt/types.h" #include "wolfssl/wolfcrypt/sha3.h" # ifndef WOLFBOOT_SHA_BLOCK_SIZE -# define WOLFBOOT_SHA_BLOCK_SIZE (128) +# define WOLFBOOT_SHA_BLOCK_SIZE (256) # endif # define WOLFBOOT_SHA_HDR HDR_SHA3_384 # define WOLFBOOT_SHA_DIGEST_SIZE (48) diff --git a/src/image.c b/src/image.c index a5d568db8b..ce8a157733 100644 --- a/src/image.c +++ b/src/image.c @@ -53,7 +53,7 @@ #endif /* Globals */ -static uint8_t digest[WOLFBOOT_SHA_DIGEST_SIZE]; +static uint8_t XALIGNED(4) digest[WOLFBOOT_SHA_DIGEST_SIZE]; /* TPM based verify */ #if defined(WOLFBOOT_TPM) && defined(WOLFBOOT_TPM_VERIFY) @@ -748,7 +748,7 @@ uint16_t wolfBoot_get_header(struct wolfBoot_image *img, uint16_t type, } #ifdef EXT_FLASH -static uint8_t ext_hash_block[WOLFBOOT_SHA_BLOCK_SIZE]; +static uint8_t XALIGNED(4) ext_hash_block[WOLFBOOT_SHA_BLOCK_SIZE]; #endif /** * @brief Get a block of data to be hashed. @@ -1500,7 +1500,7 @@ static int update_hash_flash_fwimg(wolfBoot_hash_t* ctx, { uint32_t current_offset = offset; uint32_t remaining_size = size; - uint8_t read_buf[WOLFBOOT_SHA_BLOCK_SIZE]; /* Use local buffer */ + uint8_t XALIGNED(4) read_buf[WOLFBOOT_SHA_BLOCK_SIZE]; /* Use local buffer */ while (remaining_size > 0) { uint32_t read_size = (remaining_size > WOLFBOOT_SHA_BLOCK_SIZE) @@ -1529,7 +1529,7 @@ static int update_hash_flash_fwimg(wolfBoot_hash_t* ctx, static int update_hash_flash_addr(wolfBoot_hash_t* ctx, uintptr_t addr, uint32_t size, int src_ext) { - uint8_t buffer[WOLFBOOT_SHA_BLOCK_SIZE]; + uint8_t XALIGNED(4) buffer[WOLFBOOT_SHA_BLOCK_SIZE]; uint32_t remaining_size = size; uintptr_t current_addr = addr; @@ -1568,7 +1568,7 @@ int wolfBoot_check_flash_image_elf(uint8_t part, unsigned long* entry_out) size_t ph_size = 0; size_t current_ph_offset = 0; int64_t final_offset = -1; - uint8_t calc_digest[WOLFBOOT_SHA_DIGEST_SIZE]; + uint8_t XALIGNED(4) calc_digest[WOLFBOOT_SHA_DIGEST_SIZE]; uint8_t* exp_digest; int32_t stored_sha_len; int i; @@ -1913,7 +1913,14 @@ int wolfBoot_verify_authenticity(struct wolfBoot_image *img) * TSIP encrypted key is installed at * RENESAS_TSIP_INSTALLEDKEY_ADDR */ + extern int hal_renesas_init(void); + int rc = hal_renesas_init(); + if (rc != 0) { + wolfBoot_printf("hal_renesas_init failed! %d\n", rc); + return rc; + } key_slot = 0; + #elif defined(WOLFBOOT_ENABLE_WOLFHSM_CLIENT) && \ defined(WOLFBOOT_USE_WOLFHSM_PUBKEY_ID) /* Don't care about the key slot, we are using a fixed wolfHSM keyId */ diff --git a/tools/keytools/keygen.c b/tools/keytools/keygen.c index cf72042650..5e54c92518 100644 --- a/tools/keytools/keygen.c +++ b/tools/keytools/keygen.c @@ -168,8 +168,8 @@ const char Cfile_Banner[]= const char Store_hdr[] = "\n" "#if defined(__APPLE__) && defined(__MACH__)\n" "#define KEYSTORE_SECTION __attribute__((section (\"__KEYSTORE,__keystore\")))\n" - "#elif defined(__CCRX__) /* Renesas RX */\n" - "#define KEYSTORE_SECTION\n" + "#elif defined(__CCRX__) || defined(WOLFBOOT_RENESAS_RSIP) || defined(WOLFBOOT_RENESAS_TSIP) || defined(WOLFBOOT_RENESAS_SCEPROTECT)\n" + "#define KEYSTORE_SECTION /* Renesas RX */\n" "#elif defined(TARGET_x86_64_efi)\n" "#define KEYSTORE_SECTION\n" "#else\n" @@ -258,7 +258,7 @@ const char Keystore_API[] = "{\n" " if (id >= keystore_num_pubkeys())\n" " return 0;\n" - " return (int)PubKeys[id].part_id_mask;\n" + " return PubKeys[id].part_id_mask;\n" "}\n" "\n" "uint32_t keystore_get_key_type(int id)\n" diff --git a/tools/keytools/keygen.py b/tools/keytools/keygen.py old mode 100755 new mode 100644 index 8e2b63769e..46c6a0029c --- a/tools/keytools/keygen.py +++ b/tools/keytools/keygen.py @@ -172,7 +172,7 @@ def keystore_add(slot, pub, sz = 0): Keystore_API += "{\n" Keystore_API += " if (id >= keystore_num_pubkeys())\n" Keystore_API += " return -1;\n" -Keystore_API += " return (int)PubKeys[id].part_id_mask;\n" +Keystore_API += " return PubKeys[id].part_id_mask;\n" Keystore_API += "}\n\n" Keystore_API += "#endif /* Keystore public key size check */\n" Keystore_API += "#endif /* WOLFBOOT_NO_SIGN */\n" From 22d021f5ac3c551623ab333e8e4526ac6cfecdcc Mon Sep 17 00:00:00 2001 From: David Garske Date: Thu, 5 Jun 2025 10:08:49 -0700 Subject: [PATCH 04/18] Gramar fix `partitions` -> `partition`. --- docs/Targets.md | 4 ++-- src/update_flash.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/Targets.md b/docs/Targets.md index a8db49c352..2cf3cf44dd 100644 --- a/docs/Targets.md +++ b/docs/Targets.md @@ -2453,7 +2453,7 @@ Boot header magic 0x00000000 invalid at 0x20000128 Copy sector 1 (part 1->2) Copy sector 1 (part 0->1) Copy sector 1 (part 2->0) -Erasing remainder of partitions (235 sectors)... +Erasing remainder of partition (235 sectors)... Boot partition: 0xC000 (sz 4832, ver 0x2, type 0x201) Boot header magic 0x00000000 invalid at 0x20000128 Copy sector 236 (part 0->2) @@ -2495,7 +2495,7 @@ Copy sector 1 (part 2->0) Copy sector 2 (part 1->2) Copy sector 2 (part 0->1) Copy sector 2 (part 2->0) -Erasing remainder of partitions (88 sectors)... +Erasing remainder of partition (88 sectors)... Boot partition: 0x100C000 (sz 4120, ver 0x2, type 0x202) Update partition: 0x100000 (sz 4120, ver 0x1, type 0x201) Copy sector 90 (part 0->2) diff --git a/src/update_flash.c b/src/update_flash.c index a055538f5e..13489757df 100644 --- a/src/update_flash.c +++ b/src/update_flash.c @@ -777,7 +777,7 @@ static int RAMFUNCTION wolfBoot_update(int fallback_allowed) } } - /* Erase remainder of partitions */ + /* Erase remainder of partition */ #if defined(WOLFBOOT_FLASH_MULTI_SECTOR_ERASE) || defined(PRINTF_ENABLED) /* calculate number of remaining bytes */ /* reserve 1 sector for status (2 sectors for NV write once) */ @@ -787,7 +787,7 @@ static int RAMFUNCTION wolfBoot_update(int fallback_allowed) size = WOLFBOOT_PARTITION_SIZE - (sector * sector_size) - sector_size; #endif - wolfBoot_printf("Erasing remainder of partitions (%d sectors)...\n", + wolfBoot_printf("Erasing remainder of partition (%d sectors)...\n", size/sector_size); #endif From 35582b1d059a28b7eb5d1508ef41bea63941076a Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 9 Jun 2025 12:35:00 -0700 Subject: [PATCH 05/18] Added Renesas RX TSIP encrypted updates support using AES CTR. Requires https://github.com/wolfSSL/wolfssl/pull/8854 --- .gitignore | 4 ++-- arch.mk | 3 ++- docs/Renesas.md | 29 ++++++++++++++++++++++++++ hal/renesas-rx.c | 2 ++ include/encrypt.h | 3 +++ include/user_settings.h | 5 +++++ src/libwolfboot.c | 46 +++++++++++++++++++++++++++++++++++++++-- 7 files changed, 87 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index bc8cbf89eb..c17c21bac0 100644 --- a/.gitignore +++ b/.gitignore @@ -61,8 +61,8 @@ src/ecc512_pub_key.c src/rsa2048_pub_key.c src/rsa4096_pub_key.c # Renesas key data files -include/key_data.c -include/key_data.h +include/key_data.* +include/enckey_data.* # keygen binaries tools/keytools/sign diff --git a/arch.mk b/arch.mk index 0ac53ceb8f..4fd1c5372f 100644 --- a/arch.mk +++ b/arch.mk @@ -458,7 +458,8 @@ ifeq ($(ARCH),RENESAS_RX) OBJS+=./lib/wolfssl/wolfcrypt/src/cryptocb.o \ ./lib/wolfssl/wolfcrypt/src/port/Renesas/renesas_common.o \ - ./lib/wolfssl/wolfcrypt/src/port/Renesas/renesas_tsip_util.o + ./lib/wolfssl/wolfcrypt/src/port/Renesas/renesas_tsip_util.o \ + ./lib/wolfssl/wolfcrypt/src/port/Renesas/renesas_tsip_aes.o # RX TSIP uses pre-compiled .a library by default ifneq ($(RX_TSIP_SRC),1) diff --git a/docs/Renesas.md b/docs/Renesas.md index a5568d33af..944eefa0d6 100644 --- a/docs/Renesas.md +++ b/docs/Renesas.md @@ -40,6 +40,7 @@ Result is `sample.key_enc.key`. Example: `00000001 6CCB9A1C 8AA58883 B1CB02DE 6C ```sh # Build keytools for Renesas RX (TSIP) +# Use RENESAS_KEY=2 for TSIP $ make keytools RENESAS_KEY=2 ``` @@ -163,6 +164,34 @@ Output image(s) successfully created. Download files to flash using Renesas flash programmer. +## RX TSIP AES Encryption (optional) + +Create a wrapped AES key for encrypting/decrypting the update + +Example key: `fwenc.key`: e07227e477450b1ca266078e217a3c89cbae827a7bb117ff851bc25300163575 +Note: `.config` must include `ENCRYPT=1` and `ENCRYPT_WITH_AES256=1` + +```sh +$ C:\Renesas\SecurityKeyManagementTool\cli\skmt.exe -genkey -ufpk file=./sample.key -wufpk file=./sample.key_enc.key -key file=./fwenc.key -mcu RX-TSIP -keytype AES-256 -output include/enckey_data.c -filetype csource -keyname wrap_enc_key -iv A8B14B0F5F09D73F31D4777FC0103FB4 +Output File: C:\CPG_Controls\wolfboot\include\enckey_data.h +Output File: C:\CPG_Controls\wolfboot\include\enckey_data.c +UFPK: B94A2B961C75510174F0C967ECFC20B377C7FB256DB627B1BFFADEE05EE98AC4 +W-UFPK: 000000016CCB9A1C8AA58883B1CB02DE6C37DA6054FB94E206EAE7204D9CCF4C6EEB288C +IV: A8B14B0F5F09D73F31D4777FC0103FB4 +Encrypted key: 3C39BE75E9CA5CB9D2D0BBDE111CABC894A2B13F857399B05E7B140518F35D05CD97D8DF20817CEEBA2F207CC90BAF2C + +$ C:\Renesas\SecurityKeyManagementTool\cli\skmt.exe -genkey -ufpk file=./sample.key -wufpk file=./sample.key_enc.key -key file=./fwenc.key -mcu RX-TSIP -keytype AES-256 -output fwenc.srec -filetype "mot" -address FFFF0100 -iv A8B14B0F5F09D73F31D4777FC0103FB4 +Output File: C:\CPG_Controls\wolfboot\fwenc.srec +UFPK: B94A2B961C75510174F0C967ECFC20B377C7FB256DB627B1BFFADEE05EE98AC4 +W-UFPK: 000000016CCB9A1C8AA58883B1CB02DE6C37DA6054FB94E206EAE7204D9CCF4C6EEB288C +IV: A8B14B0F5F09D73F31D4777FC0103FB4 +Encrypted key: 3C39BE75E9CA5CB9D2D0BBDE111CABC894A2B13F857399B05E7B140518F35D05CD97D8DF20817CEEBA2F207CC90BAF2C +``` + +The offset for the wrapped AES key is determined by `RENESAS_TSIP_INSTALLEDENCKEY_ADDR` and defaults to `RENESAS_TSIP_INSTALLEDKEY_ADDR` + 0x100 + +The key needed for the firmware signing tool is the 32 byte AES Key + 16 byte IV. +`echo "e07227e477450b1ca266078e217a3c89cbae827a7bb117ff851bc25300163575A8B14B0F5F09D73F31D4777FC0103FB4" | xxd -r -p - > fwkey.bin` ### RX TSIP Benchmarks diff --git a/hal/renesas-rx.c b/hal/renesas-rx.c index 66527b5f24..0aa939082c 100644 --- a/hal/renesas-rx.c +++ b/hal/renesas-rx.c @@ -374,6 +374,8 @@ int hal_renesas_init(void) int err; uint32_t key_type = 0; int tsip_key_type = -1; + /* This structure is generated using Renesas Security Key Management Tool + * See docs/Renesas.md */ struct enc_pub_key *encrypted_user_key_data; if (sipInitDone) diff --git a/include/encrypt.h b/include/encrypt.h index ce1cb184ef..be7abbfbf6 100644 --- a/include/encrypt.h +++ b/include/encrypt.h @@ -38,6 +38,9 @@ #else #include #endif +#ifdef WOLF_CRYPTO_CB +#include +#endif #include diff --git a/include/user_settings.h b/include/user_settings.h index b1c0d524cd..2f625ef2b2 100644 --- a/include/user_settings.h +++ b/include/user_settings.h @@ -502,6 +502,7 @@ extern int tolower(int c); #define WOLF_CRYPTO_CB_ONLY_RSA #define WOLFSSL_NO_SW_MATH #define MAX_CRYPTO_DEVID_CALLBACKS 2 + #define WOLFSSL_AES_SMALL_TABLES #ifdef WOLFBOOT_RENESAS_TSIP #define WOLFSSL_RENESAS_TSIP @@ -510,6 +511,10 @@ extern int tolower(int c); #define WOLFSSL_RENESAS_TSIP_CRYPTONLY #define NO_WOLFSSL_RENESAS_TSIP_CRYPT_HASH #define RENESAS_TSIP_INSTALLEDKEY_ADDR 0xFFFF0000 + #ifndef RENESAS_TSIP_INSTALLEDENCKEY_ADDR + #define RENESAS_TSIP_INSTALLEDENCKEY_ADDR \ + (RENESAS_TSIP_INSTALLEDKEY_ADDR + 0x100) + #endif #define ENCRYPTED_KEY_BYTE_SIZE ENC_PUB_KEY_SIZE #define RENESAS_DEVID 7890 #endif diff --git a/src/libwolfboot.c b/src/libwolfboot.c index 8b30fc5da3..48e34c4cba 100644 --- a/src/libwolfboot.c +++ b/src/libwolfboot.c @@ -1553,6 +1553,7 @@ int RAMFUNCTION chacha_init(void) #elif defined(ENCRYPT_WITH_AES128) || defined(ENCRYPT_WITH_AES256) Aes aes_dec, aes_enc; + /** * @brief Initialize AES encryption. * @@ -1564,6 +1565,46 @@ Aes aes_dec, aes_enc; */ int aes_init(void) { +#if defined(WOLFBOOT_RENESAS_TSIP) + /* This structure is generated using Renesas Security Key Management Tool + * See docs/Renesas.md */ + #include "enckey_data.h" + int ret; + int devId = RENESAS_DEVID + 1; + wrap_enc_key_t* enc_key =(wrap_enc_key_t*)RENESAS_TSIP_INSTALLEDENCKEY_ADDR; + + XMEMSET(&aes_enc, 0, sizeof(aes_enc)); + XMEMSET(&aes_dec, 0, sizeof(aes_dec)); + wc_AesInit(&aes_enc, NULL, devId); + wc_AesInit(&aes_dec, NULL, devId); + + /* Unwrap key and get key index */ +#if ENCRYPT_KEY_SIZE == 32 + ret = R_TSIP_GenerateAes256KeyIndex(enc_key->wufpk, enc_key->initial_vector, + enc_key->encrypted_user_key, &aes_enc.ctx.tsip_keyIdx); +#else + ret = R_TSIP_GenerateAes128KeyIndex(enc_key->wufpk, enc_key->initial_vector, + enc_key->encrypted_user_key, &aes_enc.ctx.tsip_keyIdx); +#endif + if (ret == TSIP_SUCCESS) { + /* copy to decryption key */ + XMEMCPY(&aes_dec.ctx, &aes_enc.ctx, sizeof(aes_enc.ctx)); + + /* register AES crypto callback */ + extern int wc_tsip_AesCipher(int devIdArg, struct wc_CryptoInfo* info, void* ctx); + wc_CryptoCb_RegisterDevice(devId, wc_tsip_AesCipher, NULL); + + encrypt_initialized = 1; + + /* AES_ENCRYPTION is used for both directions in CTR */ + /* unwrapped key never leaves TSIP and is referenced by tsip_keyIdx */ + wc_AesSetKeyDirect(&aes_enc, enc_key->encrypted_user_key, + ENCRYPT_KEY_SIZE, enc_key->initial_vector, AES_ENCRYPTION); + wc_AesSetKeyDirect(&aes_dec, enc_key->encrypted_user_key, + ENCRYPT_KEY_SIZE, enc_key->initial_vector, AES_ENCRYPTION); + } +#else + #if defined(MMU) || defined(UNIT_TEST) uint8_t *key = ENCRYPT_KEY; #else @@ -1582,8 +1623,8 @@ int aes_init(void) XMEMSET(&aes_enc, 0, sizeof(aes_enc)); XMEMSET(&aes_dec, 0, sizeof(aes_dec)); - wc_AesInit(&aes_enc, NULL, 0); - wc_AesInit(&aes_dec, NULL, 0); + wc_AesInit(&aes_enc, NULL, INVALID_DEVID); + wc_AesInit(&aes_dec, NULL, INVALID_DEVID); /* Check against 'all 0xff' or 'all zero' cases */ XMEMSET(ff, 0xFF, ENCRYPT_KEY_SIZE); @@ -1599,6 +1640,7 @@ int aes_init(void) wc_AesSetKeyDirect(&aes_enc, key, ENCRYPT_KEY_SIZE, iv_buf, AES_ENCRYPTION); wc_AesSetKeyDirect(&aes_dec, key, ENCRYPT_KEY_SIZE, iv_buf, AES_ENCRYPTION); encrypt_initialized = 1; +#endif return 0; } From 06eac35000986e2e0e2a134064dcd89cefddb0ed Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 9 Jun 2025 13:52:16 -0700 Subject: [PATCH 06/18] Cleanup includes. --- include/encrypt.h | 3 +++ src/libwolfboot.c | 10 ++++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/include/encrypt.h b/include/encrypt.h index be7abbfbf6..605c752042 100644 --- a/include/encrypt.h +++ b/include/encrypt.h @@ -41,6 +41,9 @@ #ifdef WOLF_CRYPTO_CB #include #endif +#ifdef WOLFSSL_RENESAS_TSIP +#include +#endif #include diff --git a/src/libwolfboot.c b/src/libwolfboot.c index 48e34c4cba..87ec586cea 100644 --- a/src/libwolfboot.c +++ b/src/libwolfboot.c @@ -1554,6 +1554,12 @@ int RAMFUNCTION chacha_init(void) Aes aes_dec, aes_enc; +#if defined(WOLFBOOT_RENESAS_TSIP) + /* Provides wrap_enc_key_t structure generated using + * Renesas Security Key Management Tool. See docs/Renesas.md */ + #include "enckey_data.h" +#endif + /** * @brief Initialize AES encryption. * @@ -1566,9 +1572,6 @@ Aes aes_dec, aes_enc; int aes_init(void) { #if defined(WOLFBOOT_RENESAS_TSIP) - /* This structure is generated using Renesas Security Key Management Tool - * See docs/Renesas.md */ - #include "enckey_data.h" int ret; int devId = RENESAS_DEVID + 1; wrap_enc_key_t* enc_key =(wrap_enc_key_t*)RENESAS_TSIP_INSTALLEDENCKEY_ADDR; @@ -1591,7 +1594,6 @@ int aes_init(void) XMEMCPY(&aes_dec.ctx, &aes_enc.ctx, sizeof(aes_enc.ctx)); /* register AES crypto callback */ - extern int wc_tsip_AesCipher(int devIdArg, struct wc_CryptoInfo* info, void* ctx); wc_CryptoCb_RegisterDevice(devId, wc_tsip_AesCipher, NULL); encrypt_initialized = 1; From eed01dcb2b687660756dd8e326f5c816ff80bfc9 Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 11 Jun 2025 08:48:18 -0700 Subject: [PATCH 07/18] Portability fixes with include < vs ". Added `NO_SWAP_EXT` to allow support for onboard flash swap sector. Added `WOLFSSL_NO_CT_OPS` for ECDSA verify only. Added `WC_NO_DEFAULT_DEVID` to help with code size reduction. --- include/encrypt.h | 16 +++++----------- include/user_settings.h | 3 ++- include/wolfboot/wolfboot.h | 29 ++++++++++++++++------------- options.mk | 5 ++++- src/libwolfboot.c | 2 ++ 5 files changed, 29 insertions(+), 26 deletions(-) diff --git a/include/encrypt.h b/include/encrypt.h index 605c752042..f0f61e5925 100644 --- a/include/encrypt.h +++ b/include/encrypt.h @@ -27,25 +27,19 @@ #if defined(__WOLFBOOT) || defined(UNIT_TEST) #include -#include -#include +#include "wolfssl/wolfcrypt/settings.h" +#include "wolfssl/wolfcrypt/sha256.h" #include "target.h" #include "wolfboot/wolfboot.h" #ifdef ENCRYPT_WITH_CHACHA -#include + #include "wolfssl/wolfcrypt/chacha.h" #else -#include -#endif -#ifdef WOLF_CRYPTO_CB -#include -#endif -#ifdef WOLFSSL_RENESAS_TSIP -#include + #include "wolfssl/wolfcrypt/aes.h" #endif -#include +#include "wolfssl/wolfcrypt/pwdbased.h" #ifdef ENCRYPT_WITH_CHACHA diff --git a/include/user_settings.h b/include/user_settings.h index 2f625ef2b2..298ee98530 100644 --- a/include/user_settings.h +++ b/include/user_settings.h @@ -113,12 +113,12 @@ extern int tolower(int c); # define FREESCALE_LTC_TFM # endif - /* Some ECC options are disabled to reduce size */ # if !defined(WOLFCRYPT_SECURE_MODE) # if !defined(WOLFBOOT_TPM) # define NO_ECC_SIGN # define NO_ECC_DHE +# define WOLFSSL_NO_CT_OPS /* don't use constant time ops in misc.c */ # if !defined(WOLFBOOT_ENABLE_WOLFHSM_CLIENT) # define NO_ECC_EXPORT # define NO_ECC_KEY_EXPORT @@ -502,6 +502,7 @@ extern int tolower(int c); #define WOLF_CRYPTO_CB_ONLY_RSA #define WOLFSSL_NO_SW_MATH #define MAX_CRYPTO_DEVID_CALLBACKS 2 + #define WC_NO_DEFAULT_DEVID #define WOLFSSL_AES_SMALL_TABLES #ifdef WOLFBOOT_RENESAS_TSIP diff --git a/include/wolfboot/wolfboot.h b/include/wolfboot/wolfboot.h index fba0f4d5dc..ec5b043f0e 100644 --- a/include/wolfboot/wolfboot.h +++ b/include/wolfboot/wolfboot.h @@ -161,12 +161,22 @@ extern "C" { #if defined(__WOLFBOOT) || defined(UNIT_TEST_AUTH) +#include "wolfssl/wolfcrypt/settings.h" +#include "wolfssl/wolfcrypt/visibility.h" +#include "wolfssl/wolfcrypt/wc_port.h" +#include "wolfssl/wolfcrypt/types.h" + +#ifdef WOLFBOOT_RENESAS_TSIP + /* Include these before any algorithm headers */ + #include "mcu/all/r_bsp_common.h" + #include "r_bsp_config.h" + #include "r_tsip_rx_if.h" + #include "wolfssl/wolfcrypt/port/Renesas/renesas_tsip_types.h" +#endif + + /* Hashing configuration */ #if defined(WOLFBOOT_HASH_SHA256) - #include "wolfssl/wolfcrypt/settings.h" - #include "wolfssl/wolfcrypt/visibility.h" - #include "wolfssl/wolfcrypt/wc_port.h" - #include "wolfssl/wolfcrypt/types.h" #include "wolfssl/wolfcrypt/sha256.h" # ifndef WOLFBOOT_SHA_BLOCK_SIZE # define WOLFBOOT_SHA_BLOCK_SIZE (256) @@ -182,10 +192,6 @@ extern "C" { typedef wc_Sha256 wolfBoot_hash_t; # define HDR_HASH HDR_SHA256 #elif defined(WOLFBOOT_HASH_SHA384) - #include "wolfssl/wolfcrypt/settings.h" - #include "wolfssl/wolfcrypt/visibility.h" - #include "wolfssl/wolfcrypt/wc_port.h" - #include "wolfssl/wolfcrypt/types.h" #include "wolfssl/wolfcrypt/sha512.h" # ifndef WOLFBOOT_SHA_BLOCK_SIZE # define WOLFBOOT_SHA_BLOCK_SIZE (256) @@ -201,10 +207,6 @@ extern "C" { typedef wc_Sha384 wolfBoot_hash_t; # define HDR_HASH HDR_SHA384 #elif defined(WOLFBOOT_HASH_SHA3_384) - #include "wolfssl/wolfcrypt/settings.h" - #include "wolfssl/wolfcrypt/visibility.h" - #include "wolfssl/wolfcrypt/wc_port.h" - #include "wolfssl/wolfcrypt/types.h" #include "wolfssl/wolfcrypt/sha3.h" # ifndef WOLFBOOT_SHA_BLOCK_SIZE # define WOLFBOOT_SHA_BLOCK_SIZE (256) @@ -234,7 +236,8 @@ extern "C" { #endif -#if defined(__WOLFBOOT) || defined (__FLASH_OTP_PRIMER) || defined (UNIT_TEST_AUTH) || defined(WOLFBOOT_TPM) +#if defined(__WOLFBOOT) || defined (__FLASH_OTP_PRIMER) || \ + defined (UNIT_TEST_AUTH) || defined(WOLFBOOT_TPM) /* Authentication configuration */ #if defined(WOLFBOOT_NO_SIGN) diff --git a/options.mk b/options.mk index 41dfeff8b2..487080b128 100644 --- a/options.mk +++ b/options.mk @@ -549,7 +549,10 @@ ifeq ($(ENCRYPT),1) endif ifeq ($(EXT_FLASH),1) - CFLAGS+= -D"EXT_FLASH=1" -D"PART_UPDATE_EXT=1" -D"PART_SWAP_EXT=1" + CFLAGS+= -D"EXT_FLASH=1" -D"PART_UPDATE_EXT=1" + ifeq ($(NO_SWAP_EXT),) + CFLAGS+= -D"PART_SWAP_EXT=1" + endif ifeq ($(NO_XIP),1) CFLAGS+=-D"PART_BOOT_EXT=1" endif diff --git a/src/libwolfboot.c b/src/libwolfboot.c index 87ec586cea..5848966080 100644 --- a/src/libwolfboot.c +++ b/src/libwolfboot.c @@ -1555,6 +1555,8 @@ int RAMFUNCTION chacha_init(void) Aes aes_dec, aes_enc; #if defined(WOLFBOOT_RENESAS_TSIP) + #include "wolfssl/wolfcrypt/port/Renesas/renesas-tsip-crypt.h" + /* Provides wrap_enc_key_t structure generated using * Renesas Security Key Management Tool. See docs/Renesas.md */ #include "enckey_data.h" From 7246f8b87c079db88032dee4e836b8d545cd7cd0 Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 11 Jun 2025 10:54:52 -0700 Subject: [PATCH 08/18] Fix logic on `ext_flash_check_read` return code (it is supposed to return size read or decrypted). --- src/image.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/image.c b/src/image.c index ce8a157733..59dea6762a 100644 --- a/src/image.c +++ b/src/image.c @@ -1446,7 +1446,7 @@ static int read_flash_fwimage(struct wolfBoot_image* img, uint32_t offset, #ifdef EXT_FLASH if (PART_IS_EXT(img)) { if (ext_flash_check_read((uintptr_t)img->fw_base + offset, buffer, - size) != 0) { + size) < 0) { wolfBoot_printf( "ERROR: ext_flash_check_read failed at offset %lu, size %u\n", (unsigned long)offset, size); @@ -1474,7 +1474,7 @@ static int read_flash_addr(void* src, void* buffer, uint32_t size, int src_ext) #ifdef EXT_FLASH if (src_ext) { - if (ext_flash_check_read((uintptr_t)src, buffer, size) != 0) { + if (ext_flash_check_read((uintptr_t)src, buffer, size) < 0) { wolfBoot_printf( "ERROR: ext_flash_check_read failed at address %p, size %u\n", src, size); From f00a9c70d5d4d6bb8568c105eff3ea6d37ae1122 Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 11 Jun 2025 13:31:09 -0700 Subject: [PATCH 09/18] Fix RX TSIP IV nonce. Adjust location of XALIGNED in declarations. --- src/image.c | 12 ++++++------ src/libwolfboot.c | 11 ++++++----- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/image.c b/src/image.c index 59dea6762a..21060f9fae 100644 --- a/src/image.c +++ b/src/image.c @@ -53,7 +53,7 @@ #endif /* Globals */ -static uint8_t XALIGNED(4) digest[WOLFBOOT_SHA_DIGEST_SIZE]; +static uint8_t digest[WOLFBOOT_SHA_DIGEST_SIZE] XALIGNED(4); /* TPM based verify */ #if defined(WOLFBOOT_TPM) && defined(WOLFBOOT_TPM_VERIFY) @@ -748,7 +748,7 @@ uint16_t wolfBoot_get_header(struct wolfBoot_image *img, uint16_t type, } #ifdef EXT_FLASH -static uint8_t XALIGNED(4) ext_hash_block[WOLFBOOT_SHA_BLOCK_SIZE]; +static uint8_t ext_hash_block[WOLFBOOT_SHA_BLOCK_SIZE] XALIGNED(4); #endif /** * @brief Get a block of data to be hashed. @@ -772,7 +772,7 @@ static uint8_t *get_sha_block(struct wolfBoot_image *img, uint32_t offset) } #ifdef EXT_FLASH -static uint8_t XALIGNED(4) hdr_cpy[IMAGE_HEADER_SIZE]; +static uint8_t hdr_cpy[IMAGE_HEADER_SIZE] XALIGNED(4); static int hdr_cpy_done = 0; /** @@ -1500,7 +1500,7 @@ static int update_hash_flash_fwimg(wolfBoot_hash_t* ctx, { uint32_t current_offset = offset; uint32_t remaining_size = size; - uint8_t XALIGNED(4) read_buf[WOLFBOOT_SHA_BLOCK_SIZE]; /* Use local buffer */ + uint8_t read_buf[WOLFBOOT_SHA_BLOCK_SIZE] XALIGNED(4); /* Use local buffer*/ while (remaining_size > 0) { uint32_t read_size = (remaining_size > WOLFBOOT_SHA_BLOCK_SIZE) @@ -1529,7 +1529,7 @@ static int update_hash_flash_fwimg(wolfBoot_hash_t* ctx, static int update_hash_flash_addr(wolfBoot_hash_t* ctx, uintptr_t addr, uint32_t size, int src_ext) { - uint8_t XALIGNED(4) buffer[WOLFBOOT_SHA_BLOCK_SIZE]; + uint8_t buffer[WOLFBOOT_SHA_BLOCK_SIZE] XALIGNED(4); uint32_t remaining_size = size; uintptr_t current_addr = addr; @@ -1568,7 +1568,7 @@ int wolfBoot_check_flash_image_elf(uint8_t part, unsigned long* entry_out) size_t ph_size = 0; size_t current_ph_offset = 0; int64_t final_offset = -1; - uint8_t XALIGNED(4) calc_digest[WOLFBOOT_SHA_DIGEST_SIZE]; + uint8_t calc_digest[WOLFBOOT_SHA_DIGEST_SIZE] XALIGNED(4); uint8_t* exp_digest; int32_t stored_sha_len; int i; diff --git a/src/libwolfboot.c b/src/libwolfboot.c index 5848966080..32708ffdba 100644 --- a/src/libwolfboot.c +++ b/src/libwolfboot.c @@ -64,7 +64,7 @@ #if defined(EXT_ENCRYPTED) static int encrypt_initialized = 0; -static uint8_t encrypt_iv_nonce[ENCRYPT_NONCE_SIZE]; +static uint8_t encrypt_iv_nonce[ENCRYPT_NONCE_SIZE] XALIGNED(4); #if defined(__WOLFBOOT) #include "encrypt.h" #elif !defined(XMEMSET) @@ -1598,14 +1598,15 @@ int aes_init(void) /* register AES crypto callback */ wc_CryptoCb_RegisterDevice(devId, wc_tsip_AesCipher, NULL); - encrypt_initialized = 1; - /* AES_ENCRYPTION is used for both directions in CTR */ /* unwrapped key never leaves TSIP and is referenced by tsip_keyIdx */ wc_AesSetKeyDirect(&aes_enc, enc_key->encrypted_user_key, ENCRYPT_KEY_SIZE, enc_key->initial_vector, AES_ENCRYPTION); wc_AesSetKeyDirect(&aes_dec, enc_key->encrypted_user_key, ENCRYPT_KEY_SIZE, enc_key->initial_vector, AES_ENCRYPTION); + + XMEMCPY(encrypt_iv_nonce, enc_key->initial_vector, ENCRYPT_NONCE_SIZE); + encrypt_initialized = 1; } #else @@ -1825,8 +1826,8 @@ int RAMFUNCTION ext_flash_encrypt_write(uintptr_t address, const uint8_t *data, */ int RAMFUNCTION ext_flash_decrypt_read(uintptr_t address, uint8_t *data, int len) { - uint8_t block[ENCRYPT_BLOCK_SIZE]; - uint8_t dec_block[ENCRYPT_BLOCK_SIZE]; + uint8_t block[ENCRYPT_BLOCK_SIZE] XALIGNED(4); + uint8_t dec_block[ENCRYPT_BLOCK_SIZE] XALIGNED(4); uint32_t row_address = address, row_offset, iv_counter = 0; int i; int flash_read_size; From bfe442852d7aa10ff50ccd1825a83619865d9869 Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 11 Jun 2025 14:46:22 -0700 Subject: [PATCH 10/18] Make sure keySize is set for RX crypto callback. --- src/libwolfboot.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libwolfboot.c b/src/libwolfboot.c index 32708ffdba..d49c616c1f 100644 --- a/src/libwolfboot.c +++ b/src/libwolfboot.c @@ -1592,6 +1592,8 @@ int aes_init(void) enc_key->encrypted_user_key, &aes_enc.ctx.tsip_keyIdx); #endif if (ret == TSIP_SUCCESS) { + aes_enc.ctx.keySize = ENCRYPT_KEY_SIZE; + /* copy to decryption key */ XMEMCPY(&aes_dec.ctx, &aes_enc.ctx, sizeof(aes_enc.ctx)); From 861252fa3818c921cb211e877b8f351cb748be80 Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 11 Jun 2025 15:01:21 -0700 Subject: [PATCH 11/18] Cleanup the AES CTR IV. --- include/encrypt.h | 2 +- src/libwolfboot.c | 34 ++++++++++++++++++---------------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/include/encrypt.h b/include/encrypt.h index f0f61e5925..fc85bc3f84 100644 --- a/include/encrypt.h +++ b/include/encrypt.h @@ -65,7 +65,7 @@ int aes_init(void); void aes_set_iv(uint8_t *nonce, uint32_t address); #endif /* ENCRYPT_WITH_CHACHA */ -/* Internal read/write functions (not exported in the libwolfboot API) */ +/* external flash encryption read/write functions */ int ext_flash_encrypt_write(uintptr_t address, const uint8_t *data, int len); int ext_flash_decrypt_read(uintptr_t address, uint8_t *data, int len); diff --git a/src/libwolfboot.c b/src/libwolfboot.c index d49c616c1f..47dcf21e52 100644 --- a/src/libwolfboot.c +++ b/src/libwolfboot.c @@ -1600,13 +1600,14 @@ int aes_init(void) /* register AES crypto callback */ wc_CryptoCb_RegisterDevice(devId, wc_tsip_AesCipher, NULL); - /* AES_ENCRYPTION is used for both directions in CTR */ - /* unwrapped key never leaves TSIP and is referenced by tsip_keyIdx */ + /* AES_ENCRYPTION is used for both directions in CTR + * IV is set later with "wc_AesSetIV" */ wc_AesSetKeyDirect(&aes_enc, enc_key->encrypted_user_key, - ENCRYPT_KEY_SIZE, enc_key->initial_vector, AES_ENCRYPTION); + ENCRYPT_KEY_SIZE, NULL, AES_ENCRYPTION); wc_AesSetKeyDirect(&aes_dec, enc_key->encrypted_user_key, - ENCRYPT_KEY_SIZE, enc_key->initial_vector, AES_ENCRYPTION); + ENCRYPT_KEY_SIZE, NULL, AES_ENCRYPTION); + /* set IV nonce use in aes_set_iv */ XMEMCPY(encrypt_iv_nonce, enc_key->initial_vector, ENCRYPT_NONCE_SIZE); encrypt_initialized = 1; } @@ -1619,7 +1620,6 @@ int aes_init(void) ENCRYPT_TMP_SECRET_OFFSET); #endif uint8_t ff[ENCRYPT_KEY_SIZE]; - uint8_t iv_buf[ENCRYPT_NONCE_SIZE]; uint8_t* stored_nonce; #ifdef NVM_FLASH_WRITEONCE @@ -1641,11 +1641,13 @@ int aes_init(void) if (XMEMCMP(key, ff, ENCRYPT_KEY_SIZE) == 0) return -1; + /* AES_ENCRYPTION is used for both directions in CTR + * IV is set later with "wc_AesSetIV" */ + wc_AesSetKeyDirect(&aes_enc, key, ENCRYPT_KEY_SIZE, NULL, AES_ENCRYPTION); + wc_AesSetKeyDirect(&aes_dec, key, ENCRYPT_KEY_SIZE, NULL, AES_ENCRYPTION); + + /* set IV nonce use in aes_set_iv */ XMEMCPY(encrypt_iv_nonce, stored_nonce, ENCRYPT_NONCE_SIZE); - XMEMCPY(iv_buf, stored_nonce, ENCRYPT_NONCE_SIZE); - /* AES_ENCRYPTION is used for both directions in CTR */ - wc_AesSetKeyDirect(&aes_enc, key, ENCRYPT_KEY_SIZE, iv_buf, AES_ENCRYPTION); - wc_AesSetKeyDirect(&aes_dec, key, ENCRYPT_KEY_SIZE, iv_buf, AES_ENCRYPTION); encrypt_initialized = 1; #endif return 0; @@ -1655,10 +1657,10 @@ int aes_init(void) * @brief Set the AES initialization vector (IV) for CTR mode. * * This function sets the AES initialization vector (IV) for the Counter (CTR) - * mode encryption. It takes a 12-byte nonce and a 32-bit IV counter value to + * mode encryption. It takes a 16-byte nonce and a 32-bit IV counter value to * construct the 16-byte IV used for encryption. * - * @param nonce Pointer to the 12-byte nonce (IV) buffer. + * @param nonce Pointer to the 16-byte nonce (IV) buffer. * @param iv_ctr The IV counter value. * */ @@ -1751,7 +1753,8 @@ int RAMFUNCTION ext_flash_encrypt_write(uintptr_t address, const uint8_t *data, int sz = len, i, step; uint8_t part; uint32_t iv_counter = 0; -#if defined(EXT_ENCRYPTED) && !defined(WOLFBOOT_SMALL_STACK) && !defined(NVM_FLASH_WRITEONCE) +#if defined(EXT_ENCRYPTED) && !defined(WOLFBOOT_SMALL_STACK) && \ + !defined(NVM_FLASH_WRITEONCE) uint8_t ENCRYPT_CACHE[NVM_CACHE_SIZE] XALIGNED_STACK(32); #endif @@ -1863,9 +1866,8 @@ int RAMFUNCTION ext_flash_decrypt_read(uintptr_t address, uint8_t *data, int len crypto_set_iv(encrypt_iv_nonce, iv_counter); break; case PART_SWAP: - { - break; - } + break; + default: return -1; } @@ -1908,7 +1910,7 @@ int RAMFUNCTION ext_flash_decrypt_read(uintptr_t address, uint8_t *data, int len unaligned_trailer_size = read_remaining; if (unaligned_trailer_size > 0) { - uint8_t dec_block[ENCRYPT_BLOCK_SIZE]; + uint8_t dec_block[ENCRYPT_BLOCK_SIZE] XALIGNED(4); if (ext_flash_read(address, block, ENCRYPT_BLOCK_SIZE) != ENCRYPT_BLOCK_SIZE) return -1; From 80c32d62ddcba1deecce91af8cc3e48626f458ca Mon Sep 17 00:00:00 2001 From: David Garske Date: Thu, 12 Jun 2025 09:52:06 -0700 Subject: [PATCH 12/18] Fix for Renesas RX TSIP AES CTR to make sure the wolfCrypt_Init() is called before trying to setup the crypto callback. --- src/libwolfboot.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libwolfboot.c b/src/libwolfboot.c index 47dcf21e52..e69cc88bf3 100644 --- a/src/libwolfboot.c +++ b/src/libwolfboot.c @@ -1578,6 +1578,9 @@ int aes_init(void) int devId = RENESAS_DEVID + 1; wrap_enc_key_t* enc_key =(wrap_enc_key_t*)RENESAS_TSIP_INSTALLEDENCKEY_ADDR; + /* required to properly setup the crypto callback defaults */ + wolfCrypt_Init(); /* has logic to support being called multiple times */ + XMEMSET(&aes_enc, 0, sizeof(aes_enc)); XMEMSET(&aes_dec, 0, sizeof(aes_dec)); wc_AesInit(&aes_enc, NULL, devId); From a81d622eab4dd9a20103edfec180e2414f5d5678 Mon Sep 17 00:00:00 2001 From: David Garske Date: Thu, 12 Jun 2025 13:59:26 -0700 Subject: [PATCH 13/18] Cleanup duplicate code in `aes_init`. --- src/libwolfboot.c | 93 +++++++++++++++++++++-------------------------- 1 file changed, 42 insertions(+), 51 deletions(-) diff --git a/src/libwolfboot.c b/src/libwolfboot.c index e69cc88bf3..bd0f39ace9 100644 --- a/src/libwolfboot.c +++ b/src/libwolfboot.c @@ -1573,68 +1573,37 @@ Aes aes_dec, aes_enc; */ int aes_init(void) { -#if defined(WOLFBOOT_RENESAS_TSIP) - int ret; - int devId = RENESAS_DEVID + 1; - wrap_enc_key_t* enc_key =(wrap_enc_key_t*)RENESAS_TSIP_INSTALLEDENCKEY_ADDR; - - /* required to properly setup the crypto callback defaults */ - wolfCrypt_Init(); /* has logic to support being called multiple times */ - - XMEMSET(&aes_enc, 0, sizeof(aes_enc)); - XMEMSET(&aes_dec, 0, sizeof(aes_dec)); - wc_AesInit(&aes_enc, NULL, devId); - wc_AesInit(&aes_dec, NULL, devId); - - /* Unwrap key and get key index */ -#if ENCRYPT_KEY_SIZE == 32 - ret = R_TSIP_GenerateAes256KeyIndex(enc_key->wufpk, enc_key->initial_vector, - enc_key->encrypted_user_key, &aes_enc.ctx.tsip_keyIdx); -#else - ret = R_TSIP_GenerateAes128KeyIndex(enc_key->wufpk, enc_key->initial_vector, - enc_key->encrypted_user_key, &aes_enc.ctx.tsip_keyIdx); -#endif - if (ret == TSIP_SUCCESS) { - aes_enc.ctx.keySize = ENCRYPT_KEY_SIZE; - - /* copy to decryption key */ - XMEMCPY(&aes_dec.ctx, &aes_enc.ctx, sizeof(aes_enc.ctx)); - - /* register AES crypto callback */ - wc_CryptoCb_RegisterDevice(devId, wc_tsip_AesCipher, NULL); - - /* AES_ENCRYPTION is used for both directions in CTR - * IV is set later with "wc_AesSetIV" */ - wc_AesSetKeyDirect(&aes_enc, enc_key->encrypted_user_key, - ENCRYPT_KEY_SIZE, NULL, AES_ENCRYPTION); - wc_AesSetKeyDirect(&aes_dec, enc_key->encrypted_user_key, - ENCRYPT_KEY_SIZE, NULL, AES_ENCRYPTION); + int devId; + uint8_t *stored_nonce; + uint8_t *key; + uint8_t ff[ENCRYPT_KEY_SIZE]; - /* set IV nonce use in aes_set_iv */ - XMEMCPY(encrypt_iv_nonce, enc_key->initial_vector, ENCRYPT_NONCE_SIZE); - encrypt_initialized = 1; - } +#ifdef WOLFBOOT_RENESAS_TSIP + int ret; + wrap_enc_key_t* enc_key; + devId = RENESAS_DEVID + 1; + enc_key =(wrap_enc_key_t*)RENESAS_TSIP_INSTALLEDENCKEY_ADDR; + key = enc_key->encrypted_user_key; + stored_nonce = enc_key->initial_vector; + wolfCrypt_Init(); /* required to setup the crypto callback defaults */ #else - + devId = INVALID_DEVID; #if defined(MMU) || defined(UNIT_TEST) - uint8_t *key = ENCRYPT_KEY; + key = ENCRYPT_KEY; #else - uint8_t *key = (uint8_t *)(WOLFBOOT_PARTITION_BOOT_ADDRESS + + key = (uint8_t*)(WOLFBOOT_PARTITION_BOOT_ADDRESS + ENCRYPT_TMP_SECRET_OFFSET); #endif - uint8_t ff[ENCRYPT_KEY_SIZE]; - uint8_t* stored_nonce; - #ifdef NVM_FLASH_WRITEONCE key -= WOLFBOOT_SECTOR_SIZE * nvm_select_fresh_sector(PART_BOOT); #endif - stored_nonce = key + ENCRYPT_KEY_SIZE; +#endif XMEMSET(&aes_enc, 0, sizeof(aes_enc)); XMEMSET(&aes_dec, 0, sizeof(aes_dec)); - wc_AesInit(&aes_enc, NULL, INVALID_DEVID); - wc_AesInit(&aes_dec, NULL, INVALID_DEVID); + wc_AesInit(&aes_enc, NULL, devId); + wc_AesInit(&aes_dec, NULL, devId); /* Check against 'all 0xff' or 'all zero' cases */ XMEMSET(ff, 0xFF, ENCRYPT_KEY_SIZE); @@ -1644,15 +1613,37 @@ int aes_init(void) if (XMEMCMP(key, ff, ENCRYPT_KEY_SIZE) == 0) return -1; +#ifdef WOLFBOOT_RENESAS_TSIP + /* Unwrap key and get key index */ +#if ENCRYPT_KEY_SIZE == 32 + ret = R_TSIP_GenerateAes256KeyIndex(enc_key->wufpk, enc_key->initial_vector, + enc_key->encrypted_user_key, &aes_enc.ctx.tsip_keyIdx); +#else + ret = R_TSIP_GenerateAes128KeyIndex(enc_key->wufpk, enc_key->initial_vector, + enc_key->encrypted_user_key, &aes_enc.ctx.tsip_keyIdx); +#endif + if (ret != TSIP_SUCCESS) { + return -1; + } + /* set encryption key size */ + aes_enc.ctx.keySize = ENCRYPT_KEY_SIZE; + + /* copy TSIP ctx to decryption key */ + XMEMCPY(&aes_dec.ctx, &aes_enc.ctx, sizeof(aes_enc.ctx)); + + /* register AES crypto callback */ + wc_CryptoCb_RegisterDevice(devId, wc_tsip_AesCipher, NULL); +#endif /* WOLFBOOT_RENESAS_TSIP */ + /* AES_ENCRYPTION is used for both directions in CTR * IV is set later with "wc_AesSetIV" */ wc_AesSetKeyDirect(&aes_enc, key, ENCRYPT_KEY_SIZE, NULL, AES_ENCRYPTION); wc_AesSetKeyDirect(&aes_dec, key, ENCRYPT_KEY_SIZE, NULL, AES_ENCRYPTION); - /* set IV nonce use in aes_set_iv */ + /* Set global IV nonce used in aes_set_iv */ XMEMCPY(encrypt_iv_nonce, stored_nonce, ENCRYPT_NONCE_SIZE); encrypt_initialized = 1; -#endif + return 0; } From 43d7bdfe9f7025daf9382158b9ddbe55a7b3ba01 Mon Sep 17 00:00:00 2001 From: David Garske Date: Fri, 13 Jun 2025 08:01:08 -0700 Subject: [PATCH 14/18] =?UTF-8?q?Added=20TSIP=20support=20to=20the=20set?= =?UTF-8?q?=5Fkey,=20get=5Fkey=20and=20erase=5Fkey=20API's.=20Finished=20f?= =?UTF-8?q?ull=20encrypted=20update=20testing=20on=20Renesas=20RX=20with?= =?UTF-8?q?=20TSIP.=20Fixed=20issue=20with=20`No=20rule=20to=20make=20targ?= =?UTF-8?q?et=20`NONE=E2=80=99`=20using=20encrypted=20AES.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- options.mk | 4 +--- src/libwolfboot.c | 49 +++++++++++++++++++++++++++++------------------ 2 files changed, 31 insertions(+), 22 deletions(-) diff --git a/options.mk b/options.mk index 487080b128..36b8253ba8 100644 --- a/options.mk +++ b/options.mk @@ -765,9 +765,7 @@ OBJS+=$(SECURE_OBJS) # ifeq ($(RAM_CODE),1) ifeq ($(ENCRYPT),1) - ifneq ($(ENCRYPT_WITH_CHACHA),1) - LSCRIPT_IN=NONE - else + ifeq ($(ENCRYPT_WITH_CHACHA),1) LSCRIPT_IN=hal/$(TARGET)_chacha_ram.ld endif endif diff --git a/src/libwolfboot.c b/src/libwolfboot.c index bd0f39ace9..c7ad8bfadb 100644 --- a/src/libwolfboot.c +++ b/src/libwolfboot.c @@ -1335,6 +1335,14 @@ int wolfBoot_fallback_is_possible(void) #ifdef EXT_ENCRYPTED #include "encrypt.h" +#if defined(WOLFBOOT_RENESAS_TSIP) + #include "wolfssl/wolfcrypt/port/Renesas/renesas-tsip-crypt.h" + + /* Provides wrap_enc_key_t structure generated using + * Renesas Security Key Management Tool. See docs/Renesas.md */ + #include "enckey_data.h" +#endif + #if !defined(EXT_FLASH) && !defined(MMU) #error option EXT_ENCRYPTED requires EXT_FLASH or MMU mode #endif @@ -1357,20 +1365,25 @@ static uint8_t ENCRYPT_KEY[ENCRYPT_KEY_SIZE + ENCRYPT_NONCE_SIZE]; static int RAMFUNCTION hal_set_key(const uint8_t *k, const uint8_t *nonce) { +#ifdef WOLFBOOT_RENESAS_TSIP + /* must be flashed to RENESAS_TSIP_INSTALLEDENCKEY_ADDR */ + (void)k; + (void)nonce; + return 0; +#elif defined(MMU) + XMEMCPY(ENCRYPT_KEY, k, ENCRYPT_KEY_SIZE); + XMEMCPY(ENCRYPT_KEY + ENCRYPT_KEY_SIZE, nonce, ENCRYPT_NONCE_SIZE); + return 0; +#else uintptr_t addr, addr_align, addr_off; int ret = 0; int sel_sec = 0; uint32_t trailer_relative_off = 4; - -#if !defined(WOLFBOOT_SMALL_STACK) && !defined(NVM_FLASH_WRITEONCE) && !defined(WOLFBOOT_ENCRYPT_CACHE) +#if !defined(WOLFBOOT_SMALL_STACK) && !defined(NVM_FLASH_WRITEONCE) && \ + !defined(WOLFBOOT_ENCRYPT_CACHE) uint8_t ENCRYPT_CACHE[NVM_CACHE_SIZE] XALIGNED_STACK(32); #endif -#ifdef MMU - XMEMCPY(ENCRYPT_KEY, k, ENCRYPT_KEY_SIZE); - XMEMCPY(ENCRYPT_KEY + ENCRYPT_KEY_SIZE, nonce, ENCRYPT_NONCE_SIZE); - return 0; -#else addr = ENCRYPT_TMP_SECRET_OFFSET + WOLFBOOT_PARTITION_BOOT_ADDRESS; addr_align = addr & (~(WOLFBOOT_SECTOR_SIZE - 1)); addr_off = addr & (WOLFBOOT_SECTOR_SIZE - 1); @@ -1463,7 +1476,11 @@ int RAMFUNCTION wolfBoot_set_encrypt_key(const uint8_t *key, */ int RAMFUNCTION wolfBoot_get_encrypt_key(uint8_t *k, uint8_t *nonce) { -#if defined(MMU) +#ifdef WOLFBOOT_RENESAS_TSIP + wrap_enc_key_t* enc_key =(wrap_enc_key_t*)RENESAS_TSIP_INSTALLEDENCKEY_ADDR; + XMEMCPY(k, enc_key->encrypted_user_key, ENCRYPT_KEY_SIZE); + XMEMCPY(nonce, enc_key->initial_vector, ENCRYPT_NONCE_SIZE); +#elif defined(MMU) XMEMCPY(k, ENCRYPT_KEY, ENCRYPT_KEY_SIZE); XMEMCPY(nonce, ENCRYPT_KEY + ENCRYPT_KEY_SIZE, ENCRYPT_NONCE_SIZE); #else @@ -1491,7 +1508,9 @@ int RAMFUNCTION wolfBoot_get_encrypt_key(uint8_t *k, uint8_t *nonce) */ int RAMFUNCTION wolfBoot_erase_encrypt_key(void) { -#if defined(MMU) +#ifdef WOLFBOOT_RENESAS_TSIP + /* nothing to erase */ +#elif defined(MMU) ForceZero(ENCRYPT_KEY, ENCRYPT_KEY_SIZE + ENCRYPT_NONCE_SIZE); #else uint8_t ff[ENCRYPT_KEY_SIZE + ENCRYPT_NONCE_SIZE]; @@ -1554,14 +1573,6 @@ int RAMFUNCTION chacha_init(void) Aes aes_dec, aes_enc; -#if defined(WOLFBOOT_RENESAS_TSIP) - #include "wolfssl/wolfcrypt/port/Renesas/renesas-tsip-crypt.h" - - /* Provides wrap_enc_key_t structure generated using - * Renesas Security Key Management Tool. See docs/Renesas.md */ - #include "enckey_data.h" -#endif - /** * @brief Initialize AES encryption. * @@ -1586,7 +1597,7 @@ int aes_init(void) key = enc_key->encrypted_user_key; stored_nonce = enc_key->initial_vector; wolfCrypt_Init(); /* required to setup the crypto callback defaults */ -#else +#else /* non TSIP */ devId = INVALID_DEVID; #if defined(MMU) || defined(UNIT_TEST) key = ENCRYPT_KEY; @@ -1598,7 +1609,7 @@ int aes_init(void) key -= WOLFBOOT_SECTOR_SIZE * nvm_select_fresh_sector(PART_BOOT); #endif stored_nonce = key + ENCRYPT_KEY_SIZE; -#endif +#endif /* WOLFBOOT_RENESAS_TSIP */ XMEMSET(&aes_enc, 0, sizeof(aes_enc)); XMEMSET(&aes_dec, 0, sizeof(aes_dec)); From 55e2930d165d855508efb1aa264e0644e1bfebf0 Mon Sep 17 00:00:00 2001 From: David Garske Date: Fri, 13 Jun 2025 13:17:00 -0700 Subject: [PATCH 15/18] Fix for `NO_SWAP_EXT=1` with encryption enabled. Peer review fixes. --- include/user_settings.h | 6 +++++- src/image.c | 6 +++--- src/libwolfboot.c | 6 +++--- src/update_flash.c | 6 +++--- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/include/user_settings.h b/include/user_settings.h index 298ee98530..61b5cfab80 100644 --- a/include/user_settings.h +++ b/include/user_settings.h @@ -118,7 +118,11 @@ extern int tolower(int c); # if !defined(WOLFBOOT_TPM) # define NO_ECC_SIGN # define NO_ECC_DHE -# define WOLFSSL_NO_CT_OPS /* don't use constant time ops in misc.c */ + /* For Renesas RX do not enable the misc.c constant time code + * due to issue with 64-bit types */ +# if defined(__RX__) +# define WOLFSSL_NO_CT_OPS /* don't use constant time ops in misc.c */ +# endif # if !defined(WOLFBOOT_ENABLE_WOLFHSM_CLIENT) # define NO_ECC_EXPORT # define NO_ECC_KEY_EXPORT diff --git a/src/image.c b/src/image.c index 21060f9fae..45537124a3 100644 --- a/src/image.c +++ b/src/image.c @@ -1500,7 +1500,7 @@ static int update_hash_flash_fwimg(wolfBoot_hash_t* ctx, { uint32_t current_offset = offset; uint32_t remaining_size = size; - uint8_t read_buf[WOLFBOOT_SHA_BLOCK_SIZE] XALIGNED(4); /* Use local buffer*/ + uint8_t read_buf[WOLFBOOT_SHA_BLOCK_SIZE] XALIGNED_STACK(4); /* Use local buffer */ while (remaining_size > 0) { uint32_t read_size = (remaining_size > WOLFBOOT_SHA_BLOCK_SIZE) @@ -1529,7 +1529,7 @@ static int update_hash_flash_fwimg(wolfBoot_hash_t* ctx, static int update_hash_flash_addr(wolfBoot_hash_t* ctx, uintptr_t addr, uint32_t size, int src_ext) { - uint8_t buffer[WOLFBOOT_SHA_BLOCK_SIZE] XALIGNED(4); + uint8_t buffer[WOLFBOOT_SHA_BLOCK_SIZE] XALIGNED_STACK(4); uint32_t remaining_size = size; uintptr_t current_addr = addr; @@ -1568,7 +1568,7 @@ int wolfBoot_check_flash_image_elf(uint8_t part, unsigned long* entry_out) size_t ph_size = 0; size_t current_ph_offset = 0; int64_t final_offset = -1; - uint8_t calc_digest[WOLFBOOT_SHA_DIGEST_SIZE] XALIGNED(4); + uint8_t calc_digest[WOLFBOOT_SHA_DIGEST_SIZE] XALIGNED_STACK(4); uint8_t* exp_digest; int32_t stored_sha_len; int i; diff --git a/src/libwolfboot.c b/src/libwolfboot.c index c7ad8bfadb..01e0870646 100644 --- a/src/libwolfboot.c +++ b/src/libwolfboot.c @@ -1836,8 +1836,8 @@ int RAMFUNCTION ext_flash_encrypt_write(uintptr_t address, const uint8_t *data, */ int RAMFUNCTION ext_flash_decrypt_read(uintptr_t address, uint8_t *data, int len) { - uint8_t block[ENCRYPT_BLOCK_SIZE] XALIGNED(4); - uint8_t dec_block[ENCRYPT_BLOCK_SIZE] XALIGNED(4); + uint8_t block[ENCRYPT_BLOCK_SIZE] XALIGNED_STACK(4); + uint8_t dec_block[ENCRYPT_BLOCK_SIZE] XALIGNED_STACK(4); uint32_t row_address = address, row_offset, iv_counter = 0; int i; int flash_read_size; @@ -1915,7 +1915,7 @@ int RAMFUNCTION ext_flash_decrypt_read(uintptr_t address, uint8_t *data, int len unaligned_trailer_size = read_remaining; if (unaligned_trailer_size > 0) { - uint8_t dec_block[ENCRYPT_BLOCK_SIZE] XALIGNED(4); + uint8_t dec_block[ENCRYPT_BLOCK_SIZE] XALIGNED_STACK(4); if (ext_flash_read(address, block, ENCRYPT_BLOCK_SIZE) != ENCRYPT_BLOCK_SIZE) return -1; diff --git a/src/update_flash.c b/src/update_flash.c index 13489757df..500b2b000c 100644 --- a/src/update_flash.c +++ b/src/update_flash.c @@ -153,7 +153,7 @@ static int RAMFUNCTION wolfBoot_copy_sector(struct wolfBoot_image *src, #ifdef EXT_ENCRYPTED wolfBoot_get_encrypt_key(key, nonce); - if(src->part == PART_SWAP) + if (src->part == PART_SWAP) iv_counter = dst_sector_offset; else iv_counter = src_sector_offset; @@ -172,8 +172,8 @@ static int RAMFUNCTION wolfBoot_copy_sector(struct wolfBoot_image *src, while (pos < WOLFBOOT_SECTOR_SIZE) { if (src_sector_offset + pos < (src->fw_size + IMAGE_HEADER_SIZE + FLASHBUFFER_SIZE)) { - /* bypass decryption, copy encrypted data into swap */ - if (dst->part == PART_SWAP) { + /* bypass decryption, copy encrypted data into swap (and its external) */ + if (dst->part == PART_SWAP && SWAP_EXT) { ext_flash_read((uintptr_t)(src->hdr) + src_sector_offset + pos, (void *)buffer, FLASHBUFFER_SIZE); } else { From 581d1c7f79a8dd6b23d857d4d812a5001fc7271a Mon Sep 17 00:00:00 2001 From: David Garske Date: Fri, 13 Jun 2025 13:32:19 -0700 Subject: [PATCH 16/18] Peer review fixes (thank you Copilot). --- hal/renesas-rz.c | 2 +- include/image.h | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/hal/renesas-rz.c b/hal/renesas-rz.c index d1dc82d810..4ba9089458 100644 --- a/hal/renesas-rz.c +++ b/hal/renesas-rz.c @@ -135,7 +135,7 @@ int hal_renesas_init(void) const size_t key_size = sizeof(rsip_pub_key); if (sipInitDone) - reutrn 0; + return 0; ret = wolfCrypt_Init(); if (ret != 0) { diff --git a/include/image.h b/include/image.h index d2a3049d96..f57993ad92 100644 --- a/include/image.h +++ b/include/image.h @@ -931,6 +931,9 @@ static inline int wb_flash_write_verify_word(struct wolfBoot_image *img, #else +# define SWAP_EXT (0) +# define BOOT_EXT (0) +# define UPDATE_EXT (0) # define PART_IS_EXT(x) (0) # define PARTN_IS_EXT(x) (0) # define wb_flash_erase(im, of, siz) \ From 0ba9004304695bc9d78737b3127b2662ddb1cde0 Mon Sep 17 00:00:00 2001 From: David Garske Date: Fri, 13 Jun 2025 15:57:03 -0700 Subject: [PATCH 17/18] Disabled `wolfBoot_swap_and_final_erase` with `CUSTOM_PARTITION_TRAILER` (not compatible). Added a few more `uint8_t` alignments. --- src/image.c | 2 +- src/update_flash.c | 25 ++++++++++++++++--------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/image.c b/src/image.c index 45537124a3..99daf8a60e 100644 --- a/src/image.c +++ b/src/image.c @@ -1354,7 +1354,7 @@ static int copy_flash_buffered(uintptr_t src_addr, uintptr_t dst_addr, #ifndef BUFFER_DECLARED #define BUFFER_DECLARED - static uint8_t buffer[FLASHBUFFER_SIZE]; + static uint8_t buffer[FLASHBUFFER_SIZE] XALIGNED_STACK(4); #endif #ifdef WOLFBOOT_FLASH_MULTI_SECTOR_ERASE diff --git a/src/update_flash.c b/src/update_flash.c index 500b2b000c..bdbdaae76e 100644 --- a/src/update_flash.c +++ b/src/update_flash.c @@ -50,7 +50,7 @@ static volatile const uint32_t __attribute__((used)) wolfboot_version = WOLFBOOT #ifdef EXT_FLASH # ifndef BUFFER_DECLARED # define BUFFER_DECLARED -static uint8_t buffer[FLASHBUFFER_SIZE]; +static uint8_t buffer[FLASHBUFFER_SIZE] XALIGNED(4); # endif #endif @@ -166,13 +166,13 @@ static int RAMFUNCTION wolfBoot_copy_sector(struct wolfBoot_image *src, if (PART_IS_EXT(src)) { #ifndef BUFFER_DECLARED #define BUFFER_DECLARED - static uint8_t buffer[FLASHBUFFER_SIZE]; + static uint8_t buffer[FLASHBUFFER_SIZE] XALIGNED_STACK(4); #endif wb_flash_erase(dst, dst_sector_offset, WOLFBOOT_SECTOR_SIZE); while (pos < WOLFBOOT_SECTOR_SIZE) { if (src_sector_offset + pos < (src->fw_size + IMAGE_HEADER_SIZE + FLASHBUFFER_SIZE)) { - /* bypass decryption, copy encrypted data into swap (and its external) */ + /* bypass decryption, copy encrypted data into swap if its external */ if (dst->part == PART_SWAP && SWAP_EXT) { ext_flash_read((uintptr_t)(src->hdr) + src_sector_offset + pos, (void *)buffer, FLASHBUFFER_SIZE); @@ -202,7 +202,7 @@ static int RAMFUNCTION wolfBoot_copy_sector(struct wolfBoot_image *src, return pos; } -#ifndef DISABLE_BACKUP +#if !defined(DISABLE_BACKUP) && !defined(CUSTOM_PARTITION_TRAILER) #ifdef EXT_ENCRYPTED # define TRAILER_OFFSET_WORDS \ @@ -214,7 +214,7 @@ static int RAMFUNCTION wolfBoot_copy_sector(struct wolfBoot_image *src, /** * @brief Performs the final swap and erase operations during a secure update, * ensuring that if power is lost during the update, the process can be resumed - * on next boot. + * on next boot. Not supported with CUSTOM_PARTITION_TRAILER * * This function handles the final phase of the three-way swap update process. * It ensures that the update is atomic and power-fail safe by: @@ -341,7 +341,7 @@ static int wolfBoot_swap_and_final_erase(int resume) return 0; } -#endif +#endif /* !DISABLE_BACKUP && !CUSTOM_PARTITION_TRAILER */ #ifdef DELTA_UPDATES @@ -541,9 +541,10 @@ static int wolfBoot_delta_update(struct wolfBoot_image *boot, ext_flash_lock(); #endif hal_flash_lock(); + +#if !defined(DISABLE_BACKUP) && !defined(CUSTOM_PARTITION_TRAILER) /* start re-entrant final erase, return code is only for resumption in * wolfBoot_start */ -#ifndef DISABLE_BACKUP if (ret == 0) { wolfBoot_swap_and_final_erase(0); } @@ -817,9 +818,15 @@ static int RAMFUNCTION wolfBoot_update(int fallback_allowed) ext_flash_lock(); #endif hal_flash_lock(); + +#if !defined(CUSTOM_PARTITION_TRAILER) /* start re-entrant final erase, return code is only for resumption in - * wolfBoot_start*/ + * wolfBoot_start */ wolfBoot_swap_and_final_erase(0); +#else + /* Mark boot partition as TESTING - this tells bootloader to fallback if update fails */ + wolfBoot_set_partition_state(PART_BOOT, IMG_STATE_TESTING); +#endif #else /* DISABLE_BACKUP */ #ifdef WOLFBOOT_ELF_FLASH_SCATTER @@ -1033,7 +1040,7 @@ void RAMFUNCTION wolfBoot_start(void) #endif #endif -#if !defined(DISABLE_BACKUP) +#if !defined(DISABLE_BACKUP) && !defined(CUSTOM_PARTITION_TRAILER) /* resume the final erase in case the power failed before it finished */ resumedFinalErase = wolfBoot_swap_and_final_erase(1); if (resumedFinalErase != 0) From bc1c6c459c7396335365036db1c6fc5c5bfb5263 Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 16 Jun 2025 09:48:50 -0700 Subject: [PATCH 18/18] Don't use XALIGNED_STACK on static. --- src/image.c | 2 +- src/update_flash.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/image.c b/src/image.c index 99daf8a60e..2033cf2876 100644 --- a/src/image.c +++ b/src/image.c @@ -1354,7 +1354,7 @@ static int copy_flash_buffered(uintptr_t src_addr, uintptr_t dst_addr, #ifndef BUFFER_DECLARED #define BUFFER_DECLARED - static uint8_t buffer[FLASHBUFFER_SIZE] XALIGNED_STACK(4); + static uint8_t buffer[FLASHBUFFER_SIZE] XALIGNED(4); #endif #ifdef WOLFBOOT_FLASH_MULTI_SECTOR_ERASE diff --git a/src/update_flash.c b/src/update_flash.c index bdbdaae76e..c1d339014d 100644 --- a/src/update_flash.c +++ b/src/update_flash.c @@ -166,7 +166,7 @@ static int RAMFUNCTION wolfBoot_copy_sector(struct wolfBoot_image *src, if (PART_IS_EXT(src)) { #ifndef BUFFER_DECLARED #define BUFFER_DECLARED - static uint8_t buffer[FLASHBUFFER_SIZE] XALIGNED_STACK(4); + static uint8_t buffer[FLASHBUFFER_SIZE] XALIGNED(4); #endif wb_flash_erase(dst, dst_sector_offset, WOLFBOOT_SECTOR_SIZE); while (pos < WOLFBOOT_SECTOR_SIZE) {