Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
869f15b
Improvements for portability using older gcc 4.8.2. Make sure wolfboo…
dgarske May 8, 2025
9804b08
Fix to force alignment on the flash header copy (hdr_cpy). Caused iss…
dgarske May 14, 2025
a63d2a1
Fix for Renesas TSIP key types. Fix for Renesas RX .keystore location…
dgarske Jun 2, 2025
22d021f
Gramar fix `partitions` -> `partition`.
dgarske Jun 5, 2025
35582b1
Added Renesas RX TSIP encrypted updates support using AES CTR. Requir…
dgarske Jun 9, 2025
06eac35
Cleanup includes.
dgarske Jun 9, 2025
eed01dc
Portability fixes with include < vs ". Added `NO_SWAP_EXT` to allow s…
dgarske Jun 11, 2025
7246f8b
Fix logic on `ext_flash_check_read` return code (it is supposed to re…
dgarske Jun 11, 2025
f00a9c7
Fix RX TSIP IV nonce. Adjust location of XALIGNED in declarations.
dgarske Jun 11, 2025
bfe4428
Make sure keySize is set for RX crypto callback.
dgarske Jun 11, 2025
861252f
Cleanup the AES CTR IV.
dgarske Jun 11, 2025
80c32d6
Fix for Renesas RX TSIP AES CTR to make sure the wolfCrypt_Init() is …
dgarske Jun 12, 2025
a81d622
Cleanup duplicate code in `aes_init`.
dgarske Jun 12, 2025
43d7bdf
Added TSIP support to the set_key, get_key and erase_key API's. Finis…
dgarske Jun 13, 2025
55e2930
Fix for `NO_SWAP_EXT=1` with encryption enabled. Peer review fixes.
dgarske Jun 13, 2025
581d1c7
Peer review fixes (thank you Copilot).
dgarske Jun 13, 2025
0ba9004
Disabled `wolfBoot_swap_and_final_erase` with `CUSTOM_PARTITION_TRAIL…
dgarske Jun 13, 2025
bc1c6c4
Don't use XALIGNED_STACK on static.
dgarske Jun 16, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion arch.mk
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
48 changes: 45 additions & 3 deletions docs/Renesas.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -34,12 +34,13 @@ 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

```sh
# Build keytools for Renesas RX (TSIP)
# Use RENESAS_KEY=2 for TSIP
$ make keytools RENESAS_KEY=2
```

Expand Down Expand Up @@ -163,12 +164,53 @@ Output image(s) successfully created.

Download files to flash using Renesas flash programmer.

## RX TSIP AES Encryption (optional)

#### RX TSIP Benchmarks
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

| Hardware | Clock | Algorithm | RX TSIP | Debug | Release (-Os) | Release (-O2) |
| -------- | ------ | ----------------- | -------- | -------- | ------------- | ------------- |
| RX72N | 240MHz | ECDSA Verify P384 | 17.26 ms | 1570 ms | 441 ms | 313 ms |
| 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
4 changes: 2 additions & 2 deletions docs/Targets.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
57 changes: 37 additions & 20 deletions hal/renesas-ra.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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
}

Expand Down
81 changes: 50 additions & 31 deletions hal/renesas-rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -367,38 +367,23 @@ 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;
/* This structure is generated using Renesas Security Key Management Tool
* See docs/Renesas.md */
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 */
Expand All @@ -407,19 +392,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:
Expand All @@ -430,7 +415,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) */
Expand All @@ -447,7 +432,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 */
Expand All @@ -456,9 +441,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)
Expand Down
Loading