first commit for TSIP cryp only support

-rsa 2048 verification
 -sha256
pull/328/head
Hideki Miyazaki 2023-06-23 12:38:36 +09:00 committed by Daniele Lacamera
parent f11ae239f9
commit c93a5fa185
14 changed files with 612 additions and 69 deletions

View File

@ -0,0 +1,375 @@
## wolfBoot for Renesas RX72N with TSIP
## 1. Overview
This example demonstrates simple secure firmware update by wolfBoot and uses Renesas TSIP. A sample application v1 is
securely updated to v2. Both versions behave the same except displaying its version of v1 or v2.
They are compiled by e2Studio and running on the target board.
In this demo, you may download two versions of application binary file by Renesas Flash Programmer.
You can download and excute wolfBoot by e2Studio debugger. Use a USB connection between PC and the
board for the debugger and flash programmer. It is only available RSA with Renesas TSIP now.
## 2. Components and Tools
|Item|Name/Version|Note|
|:--|:--|:--|
|Board|RX72N/Envision Kit||
|MCU|Renesas RX72N|R5F572NNxFB|
|IDE|e2studio 2022-07|Download from Renesas site|
|Compiler|CCRX v3.04.00||
|FIT Module||Download from Renesas site|
|Flash Writer|Renesas Flash Programmer v3|Download from Renesas site|
|Key tools|keygen and sign|Included in wolfBoot|
|rx-elf-objcopy|GCC for Renesas RX 8.3.0.202202-GNURX-ELF|Included in GCC for Renesas RX|
FIT Module
|Module|Version|Note|
|:--|:--|:--|
|r_bsp|v7.20|#define BSP_CFG_USTACK_BYTES (0x2000)|
||key size uses rsa-3072, please sets to (0x3000)|
|r_flash_rx|v4.90||
|r_tsip_rx|v1.18.J|Library or Source Version. Please contact Renesas to get source code version.|
Flash Allocation(TSIP Library version use):
```
+---------------------------+------------------------+-----+
| B |H| |H| | |
| o |e| Primary |e| Update |Swap |
| o |a| Partition |a| Partition |Sect |
| t |d| |d| | |
+---------------------------+------------------------+-----+
0xffc00000: wolfBoot
0xffc70000: Primary partition (Header)
0xffc70200: Primary partition (Application image) /* When it uses IMAGE_HEADER_SIZE 512, e.g. RSA2048, RSA3072 */
0xffe20000: Update partition (Header)
0xffe20200: Update partition (Application image)
0xfffd0000: Swap sector
```
Note : Depending on IMAGE_HEADER_SIZE, it needs to change the address of Power Reset vector by Linker section.
Application default is set to 0xffc70200. It means that you need to change it when you use 256 IMAGE_HEADER_SIZE.
Flash Allocation(TSIP source code version use):
```
+---------------------------+------------------------+-----+
| B |H| |H| | |
| o |e| Primary |e| Update |Swap |
| o |a| Partition |a| Partition |Sect |
| t |d| |d| | |
+---------------------------+------------------------+-----+
0xffc00000: wolfBoot
0xffc10000: Primary partition (Header)
0xffc10200: Primary partition (Application image) /* When it uses IMAGE_HEADER_SIZE 512, e.g. RSA2048, RSA3072 */
0xffdf0000: Update partition (Header)
0xffdf0200: Update partition (Application image)
0xfffd0000: Swap sector
```
Note : By enabling `WOLFBOOT_RENESAS_TSIP_SRCVERSION`, this example uses the allocation above.
## 3. How to build and use
It has key tools running under the host environment such as Linux, Windows or MacOS.
For comiling the tools, follow the instruction described in the user manual.
It demonstrates simple secure firmware update by wolfBoot. A sample application v1 is
cerurely updated to v2. Both versions behave the same except displaying its version of v1 or v2.
They are compiled by e2Studio and running on the target board.
In this demo, you may download two versions of application binary file by Renesas Flash Programmer.
You can download and excute wolfBoot by e2Studio debugger. Use a USB connection between PC and the
board for the debugger and flash programmer.
### 3-1 Key generation
```
$ cd <wolfBoot>
$ make keytools RENESAS_KEY=2
$ export PATH:$PATH:<wolfBoot>/tools/keytools
$ keygen --rsa2048 -g ./pri-rsa2048.der
Keytype: RSA2048
Gen ./pri-rsa2048.der
Generating key (type: RSA2048)
RSA public key len: 294 bytes
Associated key file: ./pri-rsa2048.der
Key type : RSA2048
Public key slot: 0
Done.
```
This generates a pair of private and public keys with -g option. The private key is stored
in the specified file. The public key is stored in a key store as a C source code
in "src/keystore.c" soo that it can be compiled and linked with wolfBoot.
If you have an existing key pair, you can use -i option to import the pablic
key to the store.
### 3-2 Compile wolfBoot
Open project under IDE/Renesas/e2studio/RX72N/wolfBoot with e2Studio, and build the project.
Project properties are preset for the demo.
```
Smart Configurator
Flash Driver: r_flash_rx
Include Paths
../../include : <wolfBoot>/IDE/Renesas/e2studio/RX72N/include
../../../../../../include : <wolfBoot>/include
../../../../../../lib/wolfssl/ : <wolfBoot>/lib/wolfssl
Pre-Include
../../include/user_settings.h : <wolfBoot>/IDE/Renesas/e2studio/RX72N/include/user_settigs.h
../../include/target.h : <wolfBoot>/IDE/Renesas/e2studio/RX72N/include/target.h
```
To enable TSIP use, it needs commenting out `WOLFBOOT_RENESAS_TSIP`.
To enable TSIP Source code version, please comment out `WOLFBOOT_RENESAS_TSIP_SRCVERSION`.
`WOLFBOOT_PARTION_INFO` and `PRINTF_ENABLED` are for debug information about partitions.
Eliminate them for operational use.
When you use TSIP source code version, taking the following two steps optimize TSIP driver size.
* Set unnecessary ciphers to "No using XXXX" by Smart Configuration. Only select
* Check "Deletes variables/functions that are not referenced)" Liker optimization option, [Project]->[Properties]->[C/C++ Build]->[Settings]->[Linker]->[Optimization]
### 3-3 Compile the sample application
Open project under IDE/Renesas/e2studio/RX72N/app_RenesasRx01 with e2Studio, and build the project.
Project properties are preset for the demo.
```
Smart Configurator
Flash Driver: r_flash_rx
TSIP Driver: r_tsip_rx
Include Paths
../../include : <wolfBoot>/IDE/Renesas/e2studio/RX72N/include
../../../../../../include : <wolfBoot>/include
Pre-Include
../../include/user_settings.h : <wolfBoot>/IDE/Renesas/e2studio/RX72N/include/user_settigs.h
../../include/target.h : <wolfBoot>/IDE/Renesas/e2studio/RX72N/include/target.h
Code Origin and entry point (PResetPRG) is "0xffc70200" (See Section Viewer of Linker Section).
Code Origin and entry point (PResetPRG) is "0xffc10200" (TSIP source code version and optimization steps above are done.)
You would need updating section settings depending on either TSIP version use.
```
app_RenesasRx01.x in ELF is gnerated under HardwareDebug. You can derive bair binary file
(app_RenesasRx01.bin) by rx-elf-objcopy.exe command as follows. -R are for eliminate unnecessary
secrions.
```
$ rx-elf-objcopy.exe -O binary\
-R '$ADDR_C_FE7F5D00' -R '$ADDR_C_FE7F5D10' -R '$ADDR_C_FE7F5D20' -R '$ADDR_C_FE7F5D30'\
-R '$ADDR_C_FE7F5D40' -R '$ADDR_C_FE7F5D48' -R '$ADDR_C_FE7F5D50' -R '$ADDR_C_FE7F5D64'\
-R '$ADDR_C_FE7F5D70' -R EXCEPTVECT -R RESETVECT app_RenesasRx01.x app_RenesasRx01.bin
```
### 3-3 Generate Encrypted Key for TSIP
TSIP requires to have a encrypted public key for sign verification to generate its own Renesas TSIP Key.
This example supports RSA2048.
You can generate a RSA key pair by wolfBoot "keygen" command along with Renesas Security Key Management Tool "skmt".
"skmt" command creates the encrypted Renesas key, generating Motorola hex file for writing it to flash memory and also generates a c header and source file for an application program with TSIP.
This example uses a encrypted RSA key which is installed into Flash memory in advance.
To generate a RSA key for sign and verify, you can follow the following commands:
```
$ export PATH:$PATH:<wolfBoot>/tools/keytools
$ export PATH:$PATH:<skmt>
$ cd <wolfBoot>
$ keygen --rsa2048 -g ./rsa-pri2048.der
$ openssl rsa -in rsa-pri2048.der -pubout -out rsa-pub2058.pem
```
Generate a c header and source file from PEM file :
```
$ skmt.exe /genkey /ufpk file=./sample.key /wufpk file=./sample.key_enc.key -key file=./pub-rsa2048.pem -mcu RX-TSIP -keytype RSA-2048-public /output key_data.c /filetype csource /keyname rsa2048_pub
```
Copy a generated c header file, which is `key_data.h` to `<wolfBoot>/IDE/Renesas/e2studio/RX72N/wolfBoot/key_data` folder
Generate Motorola hex file to write it to flash memory from PEM file :
```
$ skmt.exe /genkey /ufpk file=./sample.key /wufpk file=./sample.key_enc.key -key file=./pub-rsa2048.pem -mcu RX-TSIP -keytype RSA-2048-public /output rsa_pub2048.mot /filetype "mot" /address "FFFF0000"
```
The generated `mot` key is written to `0xFFFF0000` address. The flash memory address is set by macro, which is `RENESAS_TSIP_INSTALLEDKEY_ADDR` in `user_settings.h`
After generating "mot" format key, you can download it to flash data area by using Renesas flash programmer.
Please refer Renesas Manual to generate sample.key, sample.key_enc.key and to use `skmt` command in detail.
### 3-4 Generate Signature for app V1
The `sign` command under tools/keytools generates a signature for the binary with a specified version.
It generates a file containing a partition header and application image. The partition header
includes the generated signature and other control fields. Output file name is made up from
the input file name and version like app_RenesasRx01_v1.0_signed.bin.
```
$ sign --ras2048enc app_RenesasRx01.bin ../../../../../pri-rsa2048.der 1.0
sign app_RenesasRx01.bin for version 1
wolfBoot KeyTools (Compiled C version)
wolfBoot version 10F0000
Update type: Firmware
Input image: app_RenesasRx01.bin
Selected cipher: RSA2048ENC
Selected hash : SHA256
Public key: ./pri-rsa2048.der
Output image: app_RenesasRx01_v1.0_signed.bin
Target partition id : 1
Calculating SHA256 digest...
Signing the digest...
Output image(s) successfully created.
```
### 3-6 Download the app V1
You can convert the binary file to hex format and download it to the board by Flash Programmer.
The partition starts at "0xffc70000"(TSIP library version) or "0xffc10000"(TSIP source code version).
```
For TSIP Library version
$ rx-elf-objcopy.exe -I binary -O srec --change-addresses=0xffc70000 app_RenesasRx01_v1.0_signed.bin app_RenesasRx01_v1.0_signed.hex
or
For TSIP Source version
$ rx-elf-objcopy.exe -I binary -O srec --change-addresses=0xffc10000 app_RenesasRx01_v1.0_signed.bin app_RenesasRx01_v1.0_signed.hex
```
### 3-7 Execute inital boot
Now, you can download and start wolfBoot program by e2Studio debugger.
After starting the program, you can see the partition information as follows.
If the boot program succeeds integrity and authenticity check, it initiate the
application V1.
```
| -------------------------------------------------------------------------------- |
| Renesas RX w/ TSIP(LIB) User Application in BOOT partition started by wolfBoot |
| -------------------------------------------------------------------------------- |
=== Boot Partition[ffc70000] ===
Magic: WOLF
Version: 01
Status: ff
Tail Mgc: <20><><EFBFBD><EFBFBD>
=== Update Partition[ffe20000] ===
Magic: WOLF
Version: 02
Status: ff
Tail Mgc: <20><><EFBFBD><EFBFBD>
Current Firmware Version: 1
Hit any key to call wolfBoot_success the firmware.
```
After hitting any key, the application calls wolfBoot_success() to set boot partition
state and wait for any key again.
If you re-start the boot program at this moment,
after checking the integrity and authenticity, it jumps to the application.
You can see the state is Success("00").
```
=== Boot Partition[ffc70000] ===
Magic: WOLF
Version: 01
Status: 00
Tail Mgc: BOOT
=== Update Partition[ffe20000] ===
Magic: WOLF
Version: 02
Status: ff
Tail Mgc: <20><><EFBFBD><EFBFBD>
Hit any key to update the firmware.
```
### 3-8 Generate Signed app V2 and download it
Similar to V1, you can signe and generate a binary of V2. The update partition starts at "0xffdf0000".
You can download it by the flash programmer.
```
For TSIP Library version
$ sign --ras2048 app_RenesasRx01.bin ../../../../../pri-rsa2048.der 2.0
$ rx-elf-objcopy.exe -I binary -O srec --change-addresses=0xffe20000 app_RenesasRx01_v2.0_signed.bin app_RenesasRx01_v2.0_signed.hex
or
For TSIP Source version
$ rx-elf-objcopy.exe -I binary -O srec --change-addresses=0xffdf0000 app_RenesasRx01_v2.0_signed.bin app_RenesasRx01_v2.0_signed.hex
```
### 3-9 Re-boot and secure update to V2
Now the image is downloaded but note that the partition status is not changed yet.
When it is re-boot, it checks integrity and authenticity of V1 and initiate V1 as in
step 6.
```
| -------------------------------------------------------------------------------- |
| Renesas RX w/ TSIP(LIB) User Application in BOOT partition started by wolfBoot |
| -------------------------------------------------------------------------------- |
Current Firmware Version: 1
Hit any key to update the firmware.
Firmware Update is triggered
```
After you see the message, hit any key so that the application calls
wolfBoot_update_trigger() whcih changes the partition status and triggers
updating the firmware.
Since this is just a trigger, the application can continue the process.
In the demo application it outputs a message "Firmware Update is triggered" and enters
a infinite loop of nop.
Now you can reboot it by start wolfBoot by e2studio debugger. The boot
program checks integrity and authenticity of V2 now, swap the partition
safely and initiates V2. You will see following message after the partition
information.
```
| -------------------------------------------------------------------------------- |
| Renesas RX w/ TSIP(LIB) User Application in BOOT partition started by wolfBoot |
| -------------------------------------------------------------------------------- |
=== Boot Partition[ffc70000] ===
Magic: WOLF
Version: 02
Status: 10
Tail Mgc: BOOT
=== Update Partition[ffe20000] ===
Magic: <20><><EFBFBD><EFBFBD>
Version: 00
Status: ff
Tail Mgc: <20><><EFBFBD><EFBFBD>
Current Firmware Version: 2
```
Note That application behavior is almost identical but the Version is "2" this time.

View File

@ -51,6 +51,7 @@
<option id="com.renesas.cdt.managedbuild.renesas.ccrx.compiler.option.fpu.126437015" name="浮動小数点演算命令を使用する (-fpu/-nofpu)" superClass="com.renesas.cdt.managedbuild.renesas.ccrx.compiler.option.fpu" useByScannerDiscovery="false" value="com.renesas.cdt.managedbuild.renesas.ccrx.compiler.option.fpu.yes" valueType="enumerated"/>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.renesas.cdt.managedbuild.renesas.ccrx.compiler.option.include.2039443943" name="インクルード・ファイルを検索するフォルダ (-include)" superClass="com.renesas.cdt.managedbuild.renesas.ccrx.compiler.option.include" useByScannerDiscovery="false" valueType="includePath">
<listOptionValue builtIn="false" value="../../include"/>
<listOptionValue builtIn="false" value="../../../../../../lib/wolfssl"/>
<listOptionValue builtIn="false" value="../../../../../../include"/>
<listOptionValue builtIn="false" value="${TCINSTALL}/include"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src/smc_gen/general}&quot;"/>
@ -81,7 +82,9 @@
<listOptionValue builtIn="false" value="../../include/user_settings.h"/>
<listOptionValue builtIn="false" value="../../include/target.h"/>
</option>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="true" id="com.renesas.cdt.managedbuild.renesas.ccrx.compiler.option.define.1700820161" name="プリプロセッサ・マクロの定義 (-define)" superClass="com.renesas.cdt.managedbuild.renesas.ccrx.compiler.option.define" useByScannerDiscovery="false" valueType="definedSymbols"/>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.renesas.cdt.managedbuild.renesas.ccrx.compiler.option.define.1700820161" name="プリプロセッサ・マクロの定義 (-define)" superClass="com.renesas.cdt.managedbuild.renesas.ccrx.compiler.option.define" useByScannerDiscovery="false" valueType="definedSymbols">
<listOptionValue builtIn="false" value="WOLFBOOT_RENESAS_APP"/>
</option>
<option id="com.renesas.cdt.managedbuild.renesas.ccrx.compiler.option.optimize.467816924" name="最適化レベル (-optimize)" superClass="com.renesas.cdt.managedbuild.renesas.ccrx.compiler.option.optimize" useByScannerDiscovery="false" value="com.renesas.cdt.managedbuild.renesas.ccrx.compiler.option.optimize.level2" valueType="enumerated"/>
<inputType id="com.renesas.cdt.managedbuild.renesas.ccrx.compiler.gcc.inputType.234428537" name="Compiler Input C" superClass="com.renesas.cdt.managedbuild.renesas.ccrx.compiler.gcc.inputType"/>
<inputType id="com.renesas.cdt.managedbuild.renesas.ccrx.compiler.gpp.inputType.1840988365" name="Compiler Input CPP" superClass="com.renesas.cdt.managedbuild.renesas.ccrx.compiler.gpp.inputType"/>
@ -120,7 +123,7 @@
<listOptionValue builtIn="false" value="D_8=R_8"/>
<listOptionValue builtIn="false" value="PFRAM=RPFRAM"/>
</option>
<option id="com.renesas.cdt.managedbuild.renesas.ccrx.linker.option.linkerSection.1211806072" name="セクション (-start)" superClass="com.renesas.cdt.managedbuild.renesas.ccrx.linker.option.linkerSection" useByScannerDiscovery="false" value="SU,SI,B_1,R_1,B_2,R_2,B,R,B_8,R_8,RPFRAM,RPFRAM2/04,PResetPRG,C_1,C_2,C,C_8,C$*,D*,W*,L,P,PFRAM,PFRAM2/0FFC10200,EXCEPTVECT/0FFFFFF80,RESETVECT/0FFFFFFFC" valueType="string"/>
<option id="com.renesas.cdt.managedbuild.renesas.ccrx.linker.option.linkerSection.1211806072" name="セクション (-start)" superClass="com.renesas.cdt.managedbuild.renesas.ccrx.linker.option.linkerSection" useByScannerDiscovery="false" value="SU,SI,B_1,R_1,B_2,R_2,B,R,B_8,R_8,RPFRAM,RPFRAM2/04,PResetPRG,C_1,C_2,C,C_8,C$*,D*,W*,L,P,PFRAM,PFRAM2/0FFC70200,EXCEPTVECT/0FFFFFF80,RESETVECT/0FFFFFFFC" valueType="string"/>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.renesas.cdt.managedbuild.renesas.ccrx.linker.option.userBefore.1217567016" name="追加するオプション(すべての指定オプションの前に追加)" superClass="com.renesas.cdt.managedbuild.renesas.ccrx.linker.option.userBefore" useByScannerDiscovery="false" valueType="stringList">
<listOptionValue builtIn="false" value=""/>
</option>

View File

@ -71,10 +71,19 @@ void main(void)
{
uint8_t firmware_version = 0;
#if !defined(WOLFBOOT_RENESAS_TSIP)
printf("| ------------------------------------------------------------------- |\n");
printf("| Renesas RX User Application in BOOT partition started by wolfBoot |\n");
printf("| ------------------------------------------------------------------- |\n\n");
#elif defined(WOLFBOOT_RENESAS_TSIP_SRCVERSION)
printf("| ------------------------------------------------------------------------------- |\n");
printf("| Renesas RX w/ TSIP(SRC) User Application in BOOT partition started by wolfBoot |\n");
printf("| ------------------------------------------------------------------------------- |\n\n");
#else
printf("| ------------------------------------------------------------------------------- |\n");
printf("| Renesas RX w/ TSIP(LIB) User Application in BOOT partition started by wolfBoot |\n");
printf("| ------------------------------------------------------------------------------- |\n\n");
#endif
hal_init();
@ -86,8 +95,8 @@ void main(void)
printf("\nCurrent Firmware Version: %d\n", firmware_version);
if (firmware_version >= 1) {
if (firmware_version == 1) {
printf("Hit any key to call wolfBoot_success the firmware.\n");
if (firmware_version == 1) {
printf("Hit any key to call wolfBoot_success the firmware.\n");
getchar();
wolfBoot_success();
@ -98,7 +107,7 @@ void main(void)
wolfBoot_update_trigger();
printf("Firmware Update is triggered\n");
}
}
} else {
printf("Invalid Firmware Version\n");
goto busy_idle;

View File

@ -36,7 +36,7 @@
#if defined(WOLFBOOT_RENESAS_TSIP)
#define WOLFBOOT_BOOT_SIZE 0x50000
#define WOLFBOOT_BOOT_SIZE 0x70000
#define WOLFBOOT_RX_EXCVECT 0x10000
#define WOLFBOOT_SECTOR_SIZE 0x20000
@ -67,7 +67,7 @@
#define WOLFBOOT_PARTITION_SWAP_ADDRESS 0x0
#else
#define WOLFBOOT_BOOT_SIZE 0x10000
#define WOLFBOOT_BOOT_SIZE 0x20000
#define WOLFBOOT_RX_EXCVECT 0x10000
#define WOLFBOOT_SECTOR_SIZE 0x20000

View File

@ -26,10 +26,20 @@
#ifndef H_USER_SETTINGS_
#define H_USER_SETTINGS_
/* For TSIP use, please enable the following line. */
#define WOLFBOOT_RENESAS_TSIP
#ifdef WOLFBOOT_RENESAS_TSIP
#define WOLFSSL_RENESAS_TSIP_SIGNATURE // Current version support only RSA2048
#define WOLFSSL_NO_SW_MATH
#define WOLFBOOT_SIGN_RSA2048
# define WOLFSSL_RENESAS_TSIP
# define WOLFSSL_RENESAS_TSIP_VER 117
# define WOLFSSL_RENESAS_TSIP_CRYPT
# define WOLFSSL_RENESAS_TSIP_CRYPTONLY
# define WOLFSSL_NO_SW_MATH
# define WOLFBOOT_SIGN_RSA2048
# define WOLFBOOT_SMALL_STACK
# define WOLF_CRYPTO_CB
# define RENESAS_TSIP_INSTALLEDKEY_ADDR 0xFFFF0000
# define RENESAS_DEVID 7890
#else
#define WOLFBOOT_SIGN_RSA2048
/* #define WOLFBOOT_SIGN_RSA3072 */

View File

@ -64,6 +64,7 @@
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src/smc_gen/r_flash_rx/src/flash_type_3}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src/smc_gen/r_flash_rx/src/flash_type_4}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src/smc_gen/r_flash_rx/src/targets}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src/smc_gen/r_tsip_rx}&quot;"/>
</option>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.renesas.cdt.managedbuild.renesas.ccrx.compiler.option.userBefore.869068341" name="追加するオプション(すべての指定オプションの前に追加)" superClass="com.renesas.cdt.managedbuild.renesas.ccrx.compiler.option.userBefore" useByScannerDiscovery="false" valueType="stringList">
<listOptionValue builtIn="false" value=""/>
@ -106,6 +107,7 @@
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src/smc_gen/r_flash_rx/src/flash_type_3}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src/smc_gen/r_flash_rx/src/flash_type_4}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src/smc_gen/r_flash_rx/src/targets}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src/smc_gen/r_tsip_rx}&quot;"/>
</option>
<inputType id="com.renesas.cdt.managedbuild.renesas.ccrx.assembler.inputType.718646193" name="Assembler InputType" superClass="com.renesas.cdt.managedbuild.renesas.ccrx.assembler.inputType"/>
</tool>
@ -117,7 +119,7 @@
<listOptionValue builtIn="false" value="D_8=R_8"/>
<listOptionValue builtIn="false" value="PFRAM=RPFRAM"/>
</option>
<option id="com.renesas.cdt.managedbuild.renesas.ccrx.linker.option.linkerSection.910319832" name="セクション (-start)" superClass="com.renesas.cdt.managedbuild.renesas.ccrx.linker.option.linkerSection" useByScannerDiscovery="false" value="SI,B_1,R_1,B_2,R_2,B,R,B_8,R_8,RPFRAM/04,PResetPRG,C_1,C_2,C,C_8,C$*,D*,W*,L,P,PFRAM/0FFC00000,EXCEPTVECT/0FFFFFF80,RESETVECT/0FFFFFFFC" valueType="string"/>
<option id="com.renesas.cdt.managedbuild.renesas.ccrx.linker.option.linkerSection.910319832" name="セクション (-start)" superClass="com.renesas.cdt.managedbuild.renesas.ccrx.linker.option.linkerSection" useByScannerDiscovery="false" value="SI,B_1,R_1,B_2,R_2,B,R,B_8,R_8,RPFRAM/04,PResetPRG,C_1,C_2,C,C_8,C$*,D*,W*,L,P,PFRAM/0FFC00000,EXCEPTVECT/0FFFFFF80,RESETVECT/0FFFFFFFC,C_FIRMWARE_UPDATE_CONTROL_BLOCK,C_FIRMWARE_UPDATE_CONTROL_BLOCK_MIRROR/00100000" valueType="string"/>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.renesas.cdt.managedbuild.renesas.ccrx.linker.option.userBefore.1608946238" name="追加するオプション(すべての指定オプションの前に追加)" superClass="com.renesas.cdt.managedbuild.renesas.ccrx.linker.option.userBefore" useByScannerDiscovery="false" valueType="stringList">
<listOptionValue builtIn="false" value=""/>
</option>
@ -130,7 +132,9 @@
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.renesas.cdt.managedbuild.renesas.ccrx.linker.option.noneLinkageOrderList.747513762" name="(リンク順序のリスト) (-input/-library/-binary)" superClass="com.renesas.cdt.managedbuild.renesas.ccrx.linker.option.noneLinkageOrderList" useByScannerDiscovery="false" valueType="stringList">
<listOptionValue builtIn="false" value="&quot;.\wolfBoot.lib&quot;"/>
</option>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="true" id="com.renesas.cdt.managedbuild.renesas.ccrx.linker.option.inputFile.1228050498" name="リンクするリロケータブル・ファイル、ライブラリ・ファイルおよびバイナリ・ファイル (-input/-library/-binary)" superClass="com.renesas.cdt.managedbuild.renesas.ccrx.linker.option.inputFile" useByScannerDiscovery="false" valueType="stringList"/>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.renesas.cdt.managedbuild.renesas.ccrx.linker.option.inputFile.1228050498" name="リンクするリロケータブル・ファイル、ライブラリ・ファイルおよびバイナリ・ファイル (-input/-library/-binary)" superClass="com.renesas.cdt.managedbuild.renesas.ccrx.linker.option.inputFile" useByScannerDiscovery="false" valueType="stringList">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src/smc_gen/r_tsip_rx/lib/ccrx/r_tsip_rx72m_rx72n_rx66n_little.lib}&quot;"/>
</option>
</tool>
<tool id="com.renesas.cdt.managedbuild.renesas.ccrx.base.librarian.824424223" name="Library Generator" superClass="com.renesas.cdt.managedbuild.renesas.ccrx.base.librarian">
<option id="com.renesas.cdt.managedbuild.renesas.ccrx.librarian.option.fpu.1603488290" name="浮動小数点演算命令を使用する (-fpu/-nofpu)" superClass="com.renesas.cdt.managedbuild.renesas.ccrx.librarian.option.fpu" useByScannerDiscovery="false" value="com.renesas.cdt.managedbuild.renesas.ccrx.librarian.option.fpu.yes" valueType="enumerated"/>

View File

@ -119,6 +119,11 @@
<type>1</type>
<locationURI>PARENT-5-PROJECT_LOC/lib/wolfssl/wolfcrypt/src/asn.c</locationURI>
</link>
<link>
<name>src/wolfcrypt/cryptocb.c</name>
<type>1</type>
<locationURI>PARENT-5-PROJECT_LOC/lib/wolfssl/wolfcrypt/src/cryptocb.c</locationURI>
</link>
<link>
<name>src/wolfcrypt/ecc.c</name>
<type>1</type>
@ -209,5 +214,30 @@
<type>1</type>
<locationURI>PARENT-5-PROJECT_LOC/lib/wolfssl/wolfcrypt/src/tfm.c</locationURI>
</link>
<link>
<name>src/wolfcrypt/wc_port.c</name>
<type>1</type>
<locationURI>PARENT-5-PROJECT_LOC/lib/wolfssl/wolfcrypt/src/wc_port.c</locationURI>
</link>
<link>
<name>src/wolfcrypt/port/renesas_common.c</name>
<type>1</type>
<locationURI>PARENT-5-PROJECT_LOC/lib/wolfssl/wolfcrypt/src/port/Renesas/renesas_common.c</locationURI>
</link>
<link>
<name>src/wolfcrypt/port/renesas_tsip_rsa.c</name>
<type>1</type>
<locationURI>PARENT-5-PROJECT_LOC/lib/wolfssl/wolfcrypt/src/port/Renesas/renesas_tsip_rsa.c</locationURI>
</link>
<link>
<name>src/wolfcrypt/port/renesas_tsip_sha.c</name>
<type>1</type>
<locationURI>PARENT-5-PROJECT_LOC/lib/wolfssl/wolfcrypt/src/port/Renesas/renesas_tsip_sha.c</locationURI>
</link>
<link>
<name>src/wolfcrypt/port/renesas_tsip_util.c</name>
<type>1</type>
<locationURI>PARENT-5-PROJECT_LOC/lib/wolfssl/wolfcrypt/src/port/Renesas/renesas_tsip_util.c</locationURI>
</link>
</linkedResources>
</projectDescription>

View File

@ -706,7 +706,7 @@
<gridItem id="BSP_CFG_USER_STACK_ENABLE" selectedIndex="0"/>
<gridItem id="BSP_CFG_USTACK_BYTES" selectedIndex="0x1000"/>
<gridItem id="BSP_CFG_ISTACK_BYTES" selectedIndex="0x2000"/>
<gridItem id="BSP_CFG_HEAP_BYTES" selectedIndex="0x400"/>
<gridItem id="BSP_CFG_HEAP_BYTES" selectedIndex="0xf000"/>
<gridItem id="BSP_CFG_IO_LIB_ENABLE" selectedIndex="1"/>
<gridItem id="BSP_CFG_USER_CHARGET_ENABLED" selectedIndex="0"/>
<gridItem id="BSP_CFG_USER_CHARGET_FUNCTION" selectedIndex="my_sw_charget_function"/>
@ -775,6 +775,11 @@
<source description="Components supporting Firmware Integration Technology" display="Firmware Integration Technology" id="com.renesas.smc.tools.swcomponent.fit.source"/>
<source description="Components supporting Firmware Integration Technology" display="Firmware Integration Technology" id="com.renesas.smc.tools.swcomponent.fit.source"/>
</configuration>
<configuration inuse="true" name="r_tsip_rx">
<component description="依存モジュール: r_bsp バージョン 7.30&#10;Support functions: AES, GCM, CCM, CMAC, SHA, MD5, Triple-DES, ARC4, RSA, ECC, Random number generate, Key management, secure boot/secure firmware update.&#10;The &quot;.l&quot; in version number means library version." detailDescription="TSIP(Trusted Secure IP) driver." display="r_tsip_rx" id="r_tsip_rx1.18.l" version="1.18.l"/>
<source description="Components supporting Firmware Integration Technology" display="Firmware Integration Technology" id="com.renesas.smc.tools.swcomponent.fit.source"/>
<source description="Components supporting Firmware Integration Technology" display="Firmware Integration Technology" id="com.renesas.smc.tools.swcomponent.fit.source"/>
</configuration>
</tool>
<tool id="System">
<section id="ocd">

View File

@ -11,7 +11,7 @@
if [ $# -ne 4 ];then
echo "Usage: $0 <0 or 1 for TSIP use> WOLFBOOT_DIR RXELF_BIN_DIR <signature method>";
echo "Usage: $0 <0, 1 for TSIP LIB use or 2 for TSIP SRC use> WOLFBOOT_DIR RXELF_BIN_DIR <signature method>";
echo " sig : 0,1 : rsa-2048 (Default)"
echo " 2 : rsa-3072"
echo " 3 : ed25519"
@ -35,6 +35,7 @@ ECC384_SIGN="ecc384"
ECC512_SIGN="ecc521"
SIGN_METHOD=${RSA2048_SIGN}
SIGN_METHOD_EX=""
TSIPUSE=$1
WOLFBOOT_DIR="$2"
@ -45,11 +46,6 @@ RXELF_OBJCPY_BIN="${RXELF_BIN_DIR}/rx-elf-objcopy.exe"
PATH=$PATH:${WOLFBOOT_DIR}/tools/keytools
if [ $TSIPUSE -eq 1 ]; then
VER1_ADDR=0xffc50000
VER2_ADDR=0xffe10000
fi
case $4 in
0) ;;
1) ;;
@ -63,6 +59,25 @@ case $4 in
exit 1 ;;
esac
if [ $TSIPUSE -eq 1 -o $TSIPUSE -eq 2 ]; then
if [ $TSIPUSE -eq 2 ]; then
VER1_ADDR=0xffc10000
VER2_ADDR=0xffdf0000
else
VER1_ADDR=0xffc70000
VER2_ADDR=0xffe20000
fi
# only support rsa2048 now
case $4 in
0) ;;
1) ;;
*) echo "invalid signature mehtod $4. Please specifiy [0-8] for sign."
exit 1 ;;
esac
SIGN_METHOD_EX="enc"
fi
echo "Version 1 app start address : " $VER1_ADDR
echo "Version 2 app start address : " $VER2_ADDR
echo "Signature method : " $SIGN_METHOD
@ -89,11 +104,11 @@ keygen --${SIGN_METHOD} -g ./pri-${SIGN_METHOD}.der
echo
echo sign app_RenesasRx01.bin for version 1
sign --${SIGN_METHOD} app_RenesasRx01.bin ./pri-${SIGN_METHOD}.der 1.0
sign --${SIGN_METHOD}${SIGN_METHOD_EX} app_RenesasRx01.bin ./pri-${SIGN_METHOD}.der 1.0
echo
echo sign app_RenesasRx01.bin for version 2
sign --${SIGN_METHOD} app_RenesasRx01.bin ./pri-${SIGN_METHOD}.der 2.0
sign --${SIGN_METHOD}${SIGN_METHOD_EX} app_RenesasRx01.bin ./pri-${SIGN_METHOD}.der 2.0
echo
echo copy app_RenesasRx01_v1.0/v2.0_signed.bin RXELF_BIN_DIR

View File

@ -30,13 +30,14 @@
#include "hal.h"
#include "r_flash_rx.h"
#ifdef WOLFBOOT_RENESAS_TSIP
#include "r_tsip_rx_if.h"
#include "key_data.h"
tsip_tls_ca_certification_public_key_index_t g_key_index_1;
tsip_update_key_ring_t g_key_index_2;
#if defined(WOLFBOOT_RENESAS_TSIP) && \
!defined(WOLFBOOT_RENESAS_APP)
# include "wolfssl/wolfcrypt/wc_port.h"
# include "wolfssl/wolfcrypt/port/Renesas/renesas-tsip-crypt.h"
# include "wolfssl/wolfcrypt/port/Renesas/renesas_sync.h"
# include "key_data.h"
# include "wolfssl/wolfcrypt/port/Renesas/renesas_tsip_types.h"
TsipUserCtx pkInfo;
#endif
static inline void hal_panic(void)
@ -47,12 +48,72 @@ static inline void hal_panic(void)
void hal_init(void)
{
#if defined(WOLFBOOT_RENESAS_TSIP) &&\
!defined(WOLFBOOT_RENESAS_APP)
int err;
uint32_t key_type = 0;
int tsip_key_type = -1;
/* retrive installed pubkey data from flash */
struct encrypted_user_key_data *encrypted_user_key_data =
(struct encrypted_user_key_data*)keystore_get_buffer(0);
#endif
if(R_FLASH_Open() != FLASH_SUCCESS)
hal_panic();
#ifdef WOLFBOOT_RENESAS_TSIP
if(R_TSIP_Open(&g_key_index_1, &g_key_index_2)!= TSIP_SUCCESS)
#if defined(WOLFBOOT_RENESAS_TSIP) && \
!defined(WOLFBOOT_RENESAS_APP)
err = wolfCrypt_Init();
if (err != 0) {
printf("ERROR: wolfCrypt_Init %d\n", err);
hal_panic();
}
key_type = keystore_get_key_type(0);
switch(key_type){
case AUTH_KEY_RSA2048:
tsip_key_type = TSIP_RSA2048;
break;
case AUTH_KEY_RSA4096:
tsip_key_type = TSIP_RSA4096;
break;
case AUTH_KEY_ED448:
case AUTH_KEY_ECC384:
case AUTH_KEY_ECC521:
case AUTH_KEY_ED25519:
case AUTH_KEY_ECC256:
case AUTH_KEY_RSA3072:
default:
tsip_key_type = -1;
break;
}
if (tsip_key_type == -1) {
printf("key type (%d) not supported\n", key_type);
hal_panic();
}
/* inform user key */
tsip_inform_user_keys_ex((byte*)&encrypted_user_key_data->wufpk,
(byte*)&encrypted_user_key_data->initial_vector,
(byte*)&encrypted_user_key_data->encrypted_user_key,
0/* dummy */);
/* TSIP specific RSA public key */
if (tsip_use_PublicKey_buffer(&pkInfo,
(const char*)&encrypted_user_key_data->encrypted_user_key,
ENCRYPTED_KEY_BYTE_SIZE,
tsip_key_type) != 0) {
printf("ERROR tsip_use_PublicKey_buffer\n");
hal_panic();
}
/* Init Crypt Callback */
pkInfo.sing_hash_type = sha256_mac;
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();
}
#endif
}
@ -69,7 +130,7 @@ static uint8_t save[MIN_PROG];
int blockWrite(const uint8_t *data, uint32_t addr, int len)
{
for(; len; len-=MIN_PROG, data+=MIN_PROG, addr+=MIN_PROG) {
memcpy(save, data, MIN_PROG); /* for the case "data" ls a flash address */
memcpy(save, data, MIN_PROG); /* for the case "data" ls a flash address */
if(R_FLASH_Write((uint32_t)save, addr, MIN_PROG) != FLASH_SUCCESS)
return -1;
}
@ -100,7 +161,7 @@ int hal_flash_write(uint32_t addr, const uint8_t *data, int len)
if(blockWrite(data, addr, ALIGN_FLASH(len)) < 0)
goto error;
addr += ALIGN_FLASH(len);
data += ALIGN_FLASH(len);
data += ALIGN_FLASH(len);
len -= ALIGN_FLASH(len);
}
@ -130,7 +191,7 @@ int hal_flash_erase(uint32_t address, int len)
!= FLASH_SUCCESS)
return -1;
}
return 0;
return 0;
}
void RAMFUNCTION hal_flash_unlock(void)
@ -163,9 +224,9 @@ void RAMFUNCTION hal_flash_lock(void)
void RAMFUNCTION hal_flash_dualbank_swap(void)
{
flash_cmd_t cmd = FLASH_CMD_SWAPFLAG_TOGGLE;
printf("FLASH_CMD_SWAPFLAG_TOGGLE=%d\n", FLASH_CMD_SWAPFLAG_TOGGLE);
hal_flash_unlock();
flash_cmd_t cmd = FLASH_CMD_SWAPFLAG_TOGGLE;
printf("FLASH_CMD_SWAPFLAG_TOGGLE=%d\n", FLASH_CMD_SWAPFLAG_TOGGLE);
hal_flash_unlock();
if(R_FLASH_Control(cmd, NULL) != FLASH_SUCCESS)
hal_panic();
hal_flash_lock();

View File

@ -35,11 +35,13 @@
*
*/
#if !defined(_RENESAS_RA_)
#pragma inline_asm longJump
static void longJump(const uint32_t *app_offset)
{
jmp r1;
}
#endif
void do_boot(const uint32_t *app_offset)
{

View File

@ -334,8 +334,22 @@ static void wolfBoot_verify_signature(uint8_t key_slot,
word32 in_out = 0;
int res = 0;
#if !defined(WOLFBOOT_RENESAS_SCEPROTECT)
#if defined(WOLFBOOT_RENESAS_SCEPROTECT) ||\
defined(WOLFBOOT_RENESAS_TSIP)
ret = wc_InitRsaKey_ex(&rsa, NULL,
RENESAS_DEVID);
if (ret < 0) {
/* Failed to initialize key */
return;
}
XMEMCPY(output, sig, IMAGE_SIGNATURE_SIZE);
RSA_VERIFY_FN(ret, wc_RsaSSL_Verify, img->sha_hash,
WOLFBOOT_SHA_DIGEST_SIZE, output, IMAGE_SIGNATURE_SIZE, &rsa);
/* SCE SignatureVerify API has verified */
if (ret == 0)
wolfBoot_image_confirm_signature_ok(img);
#else
ret = wc_InitRsaKey(&rsa, NULL);
if (ret < 0) {
/* Failed to initialize key */
@ -352,19 +366,7 @@ static void wolfBoot_verify_signature(uint8_t key_slot,
XMEMCPY(output, sig, IMAGE_SIGNATURE_SIZE);
RSA_VERIFY_FN(ret, wc_RsaSSL_VerifyInline, output, IMAGE_SIGNATURE_SIZE,
&digest_out, &rsa);
#else
ret = wc_InitRsaKey_ex(&rsa, NULL, SCE_ID);
if (ret < 0) {
/* Failed to initialize key */
return;
}
XMEMCPY(output, sig, IMAGE_SIGNATURE_SIZE);
RSA_VERIFY_FN(ret, wc_RsaSSL_Verify, img->sha_hash,
WOLFBOOT_SHA_DIGEST_SIZE, output, IMAGE_SIGNATURE_SIZE, &rsa);
/* SCE SignatureVerify API has verified */
if (ret == 0)
wolfBoot_image_confirm_signature_ok(img);
#endif /* WOLFBOOT_RENESAS_SCEPROTECT_CRYPTONLY */
#endif /* SCE || TSIP */
}
#endif /* WOLFBOOT_TPM */
@ -1005,16 +1007,19 @@ int wolfBoot_verify_authenticity(struct wolfBoot_image *img)
return -1;
pubkey_hint_size = get_header(img, HDR_PUBKEY, &pubkey_hint);
if (pubkey_hint_size == WOLFBOOT_SHA_DIGEST_SIZE) {
#if !defined(WOLFBOOT_RENESAS_SCEPROTECT)
#if defined(WOLFBOOT_RENESAS_SCEPROTECT) ||\
defined(WOLFBOOT_RENESAS_TSIP)
/* SCE wrapped key is installed at
* RENESAS_SCE_INSTALLEDKEY_ADDR
* TSIP encrypted key is installed ad
* RENESAS_TSIP_INSTALLEDKEY_ADDR
*/
key_slot = 0;
#else
key_slot = keyslot_id_by_sha(pubkey_hint);
if (key_slot < 0) {
return -1; /* Key was not found */
}
#else
/* SCE wrapped key is installed at
* RENESAS_SCE_INSTALLEDKEY_ADDR
*/
key_slot = 0;
#endif
} else {
return -1; /* Invalid hash size for public key hint */

View File

@ -30,6 +30,8 @@ CFLAGS+=-DDELTA_UPDATES
ifeq ($(RENESAS_KEY),1)
CFLAGS+=-DWOLFBOOT_RENESAS_SCEPROTECT
else ifeq ($(RENESAS_KEY),2)
CFLAGS+=-DWOLFBOOT_RENESAS_TSIP
endif
# Sources

View File

@ -106,6 +106,9 @@ const char Cfile_Banner[]="/* Keystore file for wolfBoot, automatically generate
" * used by wolfBoot to verify the updates.\n"
" */" \
"\n#include <stdint.h>\n#include \"wolfboot/wolfboot.h\"\n"
#if defined(WOLFBOOT_RENESAS_TSIP)
"#include \"key_data.h\"\n"
#endif
"#ifdef WOLFBOOT_NO_SIGN\n\t#define NUM_PUBKEYS 0\n#else\n\n"
"#if (KEYSTORE_PUBKEY_SIZE != KEYSTORE_PUBKEY_SIZE_%s)\n\t"
"#error Key algorithm mismatch. Remove old keys via 'make distclean'\n"
@ -129,7 +132,25 @@ const char Keystore_API[] =
"{\n"
" return NUM_PUBKEYS;\n"
"}\n\n"
#if !defined(WOLFBOOT_RENESAS_SCEPROTECT)
#if defined(WOLFBOOT_RENESAS_SCEPROTECT)
"uint32_t *keystore_get_buffer(int id)\n"
"{\n"
" return (uint32_t *)RENESAS_SCE_INSTALLEDKEY_ADDR;\n"
"}\n\n"
"int keystore_get_size(int id)\n"
"{\n"
" return (int)260;\n"
"}\n\n"
#elif defined(WOLFBOOT_RENESAS_TSIP)
"uint32_t *keystore_get_buffer(int id)\n"
"{\n"
" return (uint32_t *)RENESAS_TSIP_INSTALLEDKEY_ADDR;\n"
"}\n\n"
"int keystore_get_size(int id)\n"
"{\n"
" return (int)ENCRYPTED_KEY_BYTE_SIZE;\n"
"}\n\n"
#else
"uint8_t *keystore_get_buffer(int id)\n"
"{\n"
" if (id >= keystore_num_pubkeys())\n"
@ -142,15 +163,6 @@ const char Keystore_API[] =
" return -1;\n"
" return (int)PubKeys[id].pubkey_size;\n"
"}\n\n"
#else
"uint32_t *keystore_get_buffer(int id)\n"
"{\n"
" return (uint32_t *)RENESAS_SCE_INSTALLEDKEY_ADDR;\n"
"}\n\n"
"int keystore_get_size(int id)\n"
"{\n"
" return (int)260;\n"
"}\n\n"
#endif
"uint32_t keystore_get_mask(int id)\n"
"{\n"
@ -158,6 +170,11 @@ const char Keystore_API[] =
" return -1;\n"
" return (int)PubKeys[id].part_id_mask;\n"
"}\n\n"
"uint32_t keystore_get_key_type(int id)\n"
"{\n"
" return PubKeys[id].key_type;\n"
"}\n\n"
"#endif /* Keystore public key size check */\n"
"#endif /* WOLFBOOT_NO_SIGN */\n";
@ -450,14 +467,14 @@ static void keygen_ed448(const char *privkey)
#endif
static void key_generate(uint32_t ktype, const char *kfilename)
static void key_gen_check(const char *kfilename)
{
FILE *f;
f = fopen(kfilename, "rb");
if (!force && (f != NULL)) {
char reply[40];
int replySz;
printf("** Warning: key file already exist! Are you sure you want to generate a new key and overwrite the existing key? [Type 'Yes']: ");
printf("** Warning: key file already exist! Are you sure you want to generate a new key and overwrite the existing key? [Type 'Yes']: ");
fflush(stdout);
replySz = scanf("%s", reply);
printf("Reply is [%s]\n", reply);
@ -469,6 +486,10 @@ static void key_generate(uint32_t ktype, const char *kfilename)
unlink(kfilename);
}
}
}
static void key_generate(uint32_t ktype, const char *kfilename)
{
printf("Generating key (type: %s)\n", KName[ktype]);
fflush(stdout);
@ -613,6 +634,7 @@ int main(int argc, char** argv)
force = 1;
}
else if (strcmp(argv[i], "-g") == 0) {
key_gen_check(argv[i + 1]);
i++;
n_pubkeys++;
continue;