Added instructions for STM32H5 demo to `docs/flash-OTP.md`.

pull/455/head
David Garske 2024-07-02 15:57:52 -07:00
parent 11ce50f6c1
commit ace95cc2dc
9 changed files with 184 additions and 30 deletions

View File

@ -251,18 +251,24 @@ jobs:
arch: arm
config-file: ./config/examples/stm32h5-dualbank.config
stm32h5_wolfcrypt_tz:
stm32h5_tz_test:
uses: ./.github/workflows/test-build.yml
with:
arch: arm
config-file: ./config/examples/stm32h5-wolfcrypt-tz.config
config-file: ./config/examples/stm32h5-tz.config
stm32h5_tz_dualbank_otp:
stm32h5_tz_dualbank_otp_test:
uses: ./.github/workflows/test-build.yml
with:
arch: arm
config-file: ./config/examples/stm32h5-tz-dualbank-otp.config
stm32h5_tz_dualbank_otp_lms_test:
uses: ./.github/workflows/test-build.yml
with:
arch: arm
config-file: ./config/examples/stm32h5-tz-dualbank-otp-lms.config
stm32h7_test:
uses: ./.github/workflows/test-build.yml
with:

View File

@ -0,0 +1,37 @@
ARCH?=ARM
TZEN?=1
TARGET?=stm32h5
SIGN?=LMS
HASH?=SHA256
DEBUG?=0
VTOR?=1
CORTEX_M0?=0
CORTEX_M33?=1
NO_ASM?=0
NO_MPU=1
EXT_FLASH?=0
SPI_FLASH?=0
ALLOW_DOWNGRADE?=0
NVM_FLASH_WRITEONCE?=1
WOLFBOOT_VERSION?=1
V?=0
SPMATH?=1
RAM_CODE?=1
DUALBANK_SWAP?=1
WOLFBOOT_PARTITION_SIZE?=0xC0000
WOLFBOOT_SECTOR_SIZE?=0x2000
WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x08040000
WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x8140000
WOLFBOOT_PARTITION_SWAP_ADDRESS?=0xFFFFFFFF
FLAGS_HOME=0
DISABLE_BACKUP=0
FLASH_OTP_KEYSTORE=1
WOLFCRYPT_TZ=1
WOLFCRYPT_TZ_PKCS11=1
ARMORED=1
LMS_LEVELS=2
LMS_HEIGHT=5
LMS_WINTERNITZ=8
IMAGE_SIGNATURE_SIZE=2644
IMAGE_HEADER_SIZE?=8192

View File

@ -16,7 +16,7 @@ NVM_FLASH_WRITEONCE?=1
WOLFBOOT_VERSION?=1
V?=0
SPMATH?=1
RAM_CODE?=0
RAM_CODE?=1
DUALBANK_SWAP?=1
WOLFBOOT_PARTITION_SIZE?=0xC0000
WOLFBOOT_SECTOR_SIZE?=0x2000
@ -28,3 +28,4 @@ DISABLE_BACKUP=0
FLASH_OTP_KEYSTORE=1
WOLFCRYPT_TZ=1
WOLFCRYPT_TZ_PKCS11=1
ARMORED=1

View File

@ -27,7 +27,7 @@ non-secure domain can access wolfCrypt through a standard PKCS11 interface and
use the crypto library with pre-provisioned keys that are never exposed to the
non-secure domain.
### Example using STM32-L552
### Example using STM32L552
- Copy the example configuration for STM32-L5 with support for wolfCrypt in
TrustZone-M and PKCS11 interface: `cp config/examples/stm32l5-wolfcrypt-tz.config .config`
@ -117,9 +117,10 @@ STM32_Programmer_CLI -c port=swd -d test-app/image_v1_signed.bin 0x08040000
### Example using STM32H563
- Copy the example configuration for STM32-L5 with support for wolfCrypt in
TrustZone-M and PKCS11 interface: `cp config/examples/stm32l5-wolfcrypt-tz.config .config`
- Copy one of the example configurations for STM32H5 with support for TrustZone and PKCS11 to `.config`:
`cp config/examples/stm32h5-tz.config .config`
`cp config/examples/stm32h5-tz-dualbank-otp.config .config` (with Dual Bank)
`cp config/examples/stm32h5-tz-dualbank-otp-lms.config .config` (with Dual Bank and PQ LMS)
- Run `make`. `wolfboot.elf` and the test applications are built as separate
objects. The application is signed and stored as `test-app/image_v1_signed.bin`.

View File

@ -884,7 +884,7 @@ The example configuration for this scenario is available in [/config/examples/st
For a full list of all the option bytes tested with this configuration, refer to [STM32-TZ.md](/docs/STM32-TZ.md).
### Scenario 2: Trustzone Enabled, wolfCrypt as secure engine for NS applications
### Scenario 2: TrustZone Enabled, wolfCrypt as secure engine for NS applications
This is similar to Scenario 1, but also includes wolfCrypt in secure mode, and
that can be accessed via PKCS11 interface by non-secure applications.
@ -893,15 +893,17 @@ This option can be enabled with the `WOLFCRYPT_TZ=1` and `WOLFCRYPT_TZ_PKCS11=1`
options in your configuration. This enables a PKCS11 accessible from NS domain via
non-secure callables (NSC).
The example configuration for this scenario is available in [/config/examples/stm32h5-wolfcrypt-tz.config](/config/examples/stm32h5-wolfcrypt-tz.config).
The example configuration for this scenario is available in [/config/examples/stm32h5-tz.config](/config/examples/stm32h5-tz.config).
For more information, see [/docs/STM32-TZ.md](/docs/STM32-TZ.md).
### Scenario 3: DUALBANK mode (Trustzone disabled)
### Scenario 3: DUALBANK mode
The STM32H5 can be configured to use hardware-assisted bank swapping to facilitate the update.
The configuration file to copy into `.config` is `config/examples/stm32h5-dualbank.config`.
For DUALBANK with TrustZone use `stm32h5-tz-dualbank-otp.config`.
DUALBANK configuration (Tested on NUCLEO-STM32H563ZI):
BANK A: 0x08000000 to 0x080FFFFFF (1MB)

View File

@ -1,4 +1,4 @@
## Using One-Time Programmable (OTP) flash area for keystore
# Using One-Time Programmable (OTP) flash area for keystore
Some microcontrollers provide a special area in flash memory that can
only be written once and cannot be erased.
@ -9,7 +9,7 @@ key is a cryptographic key that can be freely distributed and is used to verify
of the firmware update image. By storing the public keys in the OTP area, you can ensure that
they are immutable and cannot be tampered with.
### Compiling wolfBoot to access OTP as keystore
## Compiling wolfBoot to access OTP as keystore
To use the OTP area as a keystore, you need to compile wolfBoot with the `FLASH_OTP_KEYSTORE`
option enabled. This option is disabled by default, which means that the keystore is incorporated into
@ -24,7 +24,7 @@ must be provisioned to the OTP area in a separate step, as described in the next
Depending on the target device, you can either prepare a binary image of the OTP area content, or use `otp-keystore-primer` firmware to directly provision the keys on the target.
### Creating an image of the OTP area content
## Creating an image of the OTP area content
It is possible to create a binary image of the content for the OTP area. The resulting file (otp.bin) can be manually provisioned using any external tool that allows writing to the target OTP area.
@ -39,11 +39,11 @@ And then, to create the image file `otp.bin`:
tools/keytools/otp/otp-keystore-gen
### Directly provisioning the public keys to the OTP area (primer)
## Directly provisioning the public keys to the OTP area (primer)
After enabling the `FLASH_OTP_KEYSTORE` option in your `.config` file, when you compile wolfBoot by running "make",
an additional application called `otp-keystore-primer` is generated under `tools/keytools/otp`. This application is used to
provision the public keys to the OTP area. By flashing this application to the microcontroller, the public keys contained
provision the public keys to the OTP area. By flashing this application to the microcontroller, the public keys contained
in your keystore (previously generated by `keygen`) are written to the OTP area.
The `otp-keystore-primer` application is generated with the public keys embedded in it. The keys are retrieved from the `keystore.c` file,
@ -59,3 +59,120 @@ After generating a new `keystore.c` with the `keygen` application, you can gener
> [!CAUTION]
> ** Be very careful when using the `otp-keystore-primer` application. Use it at your own risk. **
## Examples
### STM32H5 OTP KeyStore
Example for NULCLEO-STM32H563ZI with TrustZone (via PKCS11), DualBank and signing with PQ LMS:
1) Setup the configuration and key tools:
```sh
cp config/examples/stm32h5-tz-dualbank-otp-lms.config .config
make include/target.h
make keytools
```
2) Generate key(s) to write to OTP
- `./examples/keytools/keygen --lms -g 1.key -g 2.key -g 3.key -g 4.key -g 5.key`
3) Backup the generated keys and `src/keystore.c`
- Save to safe place outside of the wolfBoot tree
4) Set the signing key to use
- Copy one of the generated keys to `wolfboot_signing_private_key.der`
- `cp 1.key wolfboot_signing_private_key.der`
5) Setup the option bytes
- User Configuration 2 -> TrustZone Enable (TZEN=0xB4)
- Bank1 - Flash Watermark area (SECWM1_START=0x00, SECWM1_END=0x1F)
- Bank2 - Flash Watermark area (SECWM2_START=0x00, SECWM2_END=0x1F)
6) Build wolfBoot and test application using `make`
7) Flash the OTP keystore primer:
- Flash `./tools/keytools/otp/otp-keystore-primer.bin` to `0x08000000`
8) Disconnect the tool and reboot
- The primer will run and flash keystore.c to OTP.
- Verify you flashed the keystore in OTP
- Read memory from STM32CubeProgrammer at address `0x08FFF000` (should start with ASCII "WOLFBOOT")
9) Mass erase the device
- STM32CubeProgrammer -> Full chip erase
10) Flash wolfBoot and test-app
- Flash `wolfboot.bin` at `0x0C000000`
- Flash `test-app/image_v1_signed.bin` at `0x08040000`
13) Disconnect and reboot, the red LED should turn on.
14) Connect to USB UART on NUCLEO board for console
Explore the command line (run help)
```sh
========================
STM32H5 wolfBoot demo Application
Copyright 2024 wolfSSL Inc
GPL v3
Version : 0x1
========================
cmd> help
help : shows this help message
info : display information about the system and partitions
success : confirm a successful update
pkcs11 : enable and test crypto calls with PKCS11 in secure mode
random : generate a random number
timestamp : print the current timestamp
benchmark : run the wolfCrypt benchmark
test : run the wolfCrypt test
update : update the firmware via XMODEM
reboot : reboot the system
```
15) Test Update
- Sign a new version of the firmware: `./tools/keytools/sign --lms test-app/image.bin wolfboot_signing_private_key.der 2`
- Run "update" command on the shell and wait for xmodem transfer
- Use serial terminal that supports xmodem like "minicom" or "CoolTerm".
* Run `minicom` on `/dev/ttyACM0` and start file transfer using "CTRL+A; S"
* Select xmodem then navigate to the new signed firmware file `test-app/image_v2_signed.bin`
- During the transfer, the yellow LED will flash.
- The green LED is dim because it's sync with the UART RX
- At the end of the transfer, the new image will be in the update partition.
- Reset board to install new firmware and confirm new version number.
Example update output:
```sh
cmd> update
Erasing update partition...Done.
Waiting for XMODEM transfer...
.......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
End of transfer. ret: 0
New firmware version: 0x2
Triggering update...
Update completed successfully.
cmd> reboot
========================
STM32H5 wolfBoot demo Application
Copyright 2024 wolfSSL Inc
GPL v3
Version : 0x2
========================
cmd>
```

View File

@ -279,20 +279,12 @@
#define FLASH_OPT_KEY1 (0x08192A3BU)
#define FLASH_OPT_KEY2 (0x4C5D6E7FU)
#ifndef FLASH_OTP_BASE
/* OTP FLASH AREA */
#define FLASH_OTP_BASE 0x08FFF000
#endif
#ifndef FLASH_OTP_END
#define FLASH_OTP_END 0x08FFF3FF
#endif
#ifndef OTP_SIZE
#define OTP_SIZE 1024
#endif
#ifndef OTP_BLOCKS
#define OTP_BLOCKS 16
#endif
#define OTP_BLOCK_SIZE (OTP_SIZE / OTP_BLOCKS) /* 64 bytes */
/* STM32H7: Due to ECC functionality, it is not possible to write partition/sector
* flags and signature more than once. This flags_cache is used to intercept write operations and

View File

@ -1,4 +1,4 @@
/* otp-keystore-primer.c
/* otp-keystore-gen.c
*
* Command line utility to create a OTP image
*
@ -30,8 +30,6 @@
#include <unistd.h>
#include <errno.h>
#define OTP_SIZE 4096
#include "wolfboot/wolfboot.h"
#include "keystore.h"
#include "otp_keystore.h"
@ -59,7 +57,7 @@ int main(void)
fprintf(stderr, "Error: too few keys (%d), refusing to create %s\n", n_keys, outfile);
exit(1);
}
slot_size = keystore_get_size(0);
slot_size += KEYSTORE_HDR_SIZE;
fprintf(stderr, "Slot size: %d\n", slot_size);
@ -71,7 +69,7 @@ int main(void)
perror("opening output file");
exit(2);
}
/* Write the header to the beginning of the OTP binary file */
if (write(ofd, &hdr, sizeof(hdr)) != sizeof(hdr)) {
fprintf(stderr, "Error writing to %s: %s\n", outfile, strerror(errno));