Merge pull request #14972 from OpenNuvoton/nuvoton_m2354_tfm_psa_fwu

M2354: Support PSA Firmware Update
pull/14993/head
Jaeden Amero 2021-08-11 13:57:57 +01:00 committed by GitHub
commit 4125fd0786
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 673 additions and 197 deletions

View File

@ -8,15 +8,28 @@ target_link_libraries(mbed-m2354-tfm
${CMAKE_CURRENT_SOURCE_DIR}/s_veneers.o
)
mbed_post_build_nuvoton_tfm_sign_image_tgt(
NU_M2354
${CMAKE_CURRENT_SOURCE_DIR}
nuvoton_m2354-root-rsa-3072.pem
)
# Must align with TF-M import assets
set(bl2 true)
set(mcuboot_image_number 1)
set(mcuboot_image_number 2)
set(region_defs_h_path "${CMAKE_CURRENT_SOURCE_DIR}/partition/region_defs.h")
set(update_stage_sdh true)
set(update_stage_flash false)
if(mcuboot_image_number EQUAL 2)
mbed_post_build_nuvoton_tfm_sign_image(
NU_M2354
${CMAKE_CURRENT_SOURCE_DIR}
nuvoton_m2354-root-rsa-3072.pem
nuvoton_m2354-root-rsa-3072_1.pem
)
else()
mbed_post_build_nuvoton_tfm_sign_image(
NU_M2354
${CMAKE_CURRENT_SOURCE_DIR}
nuvoton_m2354-root-rsa-3072.pem
NOTFOUND
)
endif()
target_compile_definitions(mbed-m2354-tfm
INTERFACE
@ -24,4 +37,6 @@ target_compile_definitions(mbed-m2354-tfm
NU_TFM_S_MCUBOOT_IMAGE_NUMBER=${mcuboot_image_number}
# TODO: Fix escape sequence in NU_TFM_S_REGION_DEFS_H_PATH
#NU_TFM_S_REGION_DEFS_H_PATH=\"${region_defs_h_path}\"
NU_TFM_S_UPDATE_STAGE_SDH=$<IF:$<BOOL:${update_stage_sdh}>,1,0>
NU_TFM_S_UPDATE_STAGE_FLASH=$<IF:$<BOOL:${update_stage_flash}>,1,0>
)

View File

@ -1,16 +1,16 @@
# Rebuild TF-M and integrate with Mbed on M2354
# Rebuild TF-M and integrate with Mbed for M2354
This document guides how to rebuild TF-M and integrate with Mbed on M2354.
This document guides how to rebuild TF-M and integrate with Mbed for M2354.
### Downloading TF-M source
The M2354 port in TF-M must patch to enable TF-M integration with Mbed.
For TF-M 1.3/Mbed integration on M2354, the [mainstream TF-M](https://git.trustedfirmware.org/TF-M/trusted-firmware-m.git) is patched as follows:
For TF-M 1.3/Mbed integration for M2354, the [mainstream TF-M](https://git.trustedfirmware.org/TF-M/trusted-firmware-m.git) is patched as follows:
- Apply Mbed-enabled patch to `nuvoton/m2354` TF-M target.
Run the following command to fetch and switch to the intended version:
```sh
git clone https://github.com/OpenNuvoton/trusted-firmware-m -b nuvoton_mbed_m2354_tfm-1.3
```
$ git clone https://github.com/OpenNuvoton/trusted-firmware-m -b nuvoton_mbed_m2354_tfm-1.3
```
## Customizing TF-M
@ -36,6 +36,7 @@ In TF-M, by default, the M2354 hardware is partitioned as follows:
- **PDMA1**: Configured to nonsecure for Mbed asynchronous transfer.
- **CRYPTO**: Configured to secure. Inaccessible to Mbed.
- **TRNG**: Hardwired to secure. Accessible to Mbed indirectly through PSA Cryptography API.
- **SDH**: Configured to secure to enable PSA Firmware Update. Inaccessible to Mbed.
### Defining Flash for TF-M/Mbed
@ -75,14 +76,22 @@ To define memory spec of SRAM for TF-M/Mbed, search/change the line:
Navigate [TF-M](https://www.trustedfirmware.org/projects/tf-m/).
Then go through **DOCS****Getting Started Guides****Software requirements** for TF-M build environment setup.
**NOTE**: **GNU Arm Embedded Toolchain 9 2020-q2-update** and earlier built code **FAILS** to run with `-Os`. Avoid these toolchain versions. Check [their bug report](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95646).
**NOTE**: **GNU Arm Embedded Toolchain 10-2020-q4-major** built code **FAILS** to run. Avoid this toolchain version. Check [its bug report](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99157).
### Compile
### Default relevant build configurations
To compile TF-M on M2354, run:
- Enabled BL2 (MCUboot)
- Enabled multiple image boot
- Enabled SDH (SD card) as update staging area for PSA Firmware Update
```sh
cmake -S . \
### Compiling
To compile TF-M for M2354, run:
```
$ cmake -S . \
-B cmake_build \
-DTFM_PLATFORM=nuvoton/m2354 \
-DTFM_TOOLCHAIN_FILE=toolchain_GNUARM.cmake \
@ -93,8 +102,8 @@ cmake -S . \
Then:
```sh
cmake --build cmake_build -- install
```
$ cmake --build cmake_build -- install
```
## Integrating with Mbed
@ -111,21 +120,41 @@ The following TF-M exported stuffs must update into Mbed:
- partition/: Flash layout for image signing and concatenating in post-build process
**NOTE**: On import, `signing_layout_s_ns.o` is renamed to `signing_layout_preprocessed.h` for the following reasons:
- Post-build script checks file name with `_s`/`_ns` to resolve `sw_type` as `SPE`/`NSPE` respectively.
To recognize as `NSPE_SPE`, don't use `_s_ns`/`_ns_s` file name to avoid mis-recognized.
- Use `.h` instead of `.c` as file extension name.
This is to enable custom TF-M build where the locatioin of this directory can change elsewhere.
In Greentea build process, `.c` file isn't but`.h` file is copied into `BUILD` directory, so that post-build script can still access the file.
**NOTE**: On import, `signing_layout_*.o` are renamed to `signing_layout_*.h`.
This is to use `.h` instead of `.c`/`.o` as file extension name and avoid adding into compile/link list.
**NOTE**: On import for single image boot, `signing_layout_s_ns.o` is renamed to `signing_layout_preprocessed.h`.
Post-build script checks file name with `_s`/`_ns` to resolve `sw_type` as `SPE`/`NSPE` respectively.
To recognize as `NSPE_SPE`, don't use `_s_ns`/`_ns_s` file name to avoid mis-recognized.
- [signing_key/](signing_key/nuvoton_m2354-root-rsa-3072.md)
Below summarizes the copy paths from TF-M into Mbed:
Below summarize the copy paths from TF-M into Mbed:
- trusted-firmware-m/cmake_build/bin/bl2.bin → bl2.bin
- trusted-firmware-m/cmake_build/install/export/tfm/lib/s_veneers.o → s_veneers.o
- trusted-firmware-m/cmake_build/bin/tfm_s.bin → tfm_s.bin
- trusted-firmware-m/cmake_build/install/outputs/NUVOTON/M2354/bl2.bin → bl2.bin
- trusted-firmware-m/cmake_build/install/outputs/NUVOTON/M2354/tfm_s.bin → tfm_s.bin
- trusted-firmware-m/cmake_build/install/interface/lib/s_veneers.o → s_veneers.o
- trusted-firmware-m/platform/ext/target/nuvoton/m2354/partition/flash_layout.h → partition/flash_layout.h
- trusted-firmware-m/platform/ext/target/nuvoton/m2354/partition/region_defs.h → partition/region_defs.h
- trusted-firmware-m/cmake_build/bl2/ext/mcuboot/CMakeFiles/signing_layout_s.dir/signing_layout_s_ns.o → partition/signing_layout_preprocessed.h
- trusted-firmware-m/bl2/ext/mcuboot/root-RSA-3072.pem → signing_key/nuvoton_m2354-root-rsa-3072.pem
- trusted-firmware-m/cmake_build/install/image_signing/layout_files/signing_layout_s.o → partition/signing_layout_s_preprocessed.h
- trusted-firmware-m/cmake_build/install/image_signing/layout_files/signing_layout_ns.o → partition/signing_layout_ns_preprocessed.h
- trusted-firmware-m/cmake_build/install/image_signing/keys/root-RSA-3072.pem → signing_key/nuvoton_m2354-root-rsa-3072.pem
- trusted-firmware-m/cmake_build/install/image_signing/keys/root-RSA-3072_1.pem → signing_key/nuvoton_m2354-root-rsa-3072_1.pem
**NOTE**: `trusted-firmware-m/cmake_build/install/image_signing/keys/root-RSA-3072.pem` can be missing due to TF-M build tool issue.
Try to get it from `trusted-firmware-m/bl2/ext/mcuboot/root-RSA-3072.pem` instead if it is just the original source.
## PSA Firmware Update
### Requirement
- SD card: Used for update staging area according to above TF-M build configurations.
### Update binary files
After finishing Mbed build, you will find the following files under build directory.
They are to write to update staging area through PSA Firmware Update API for firmware upgrade.
- `tfm_s_update.bin`: TF-M secure binary file for update separately when multiple image boot is enabled
- `<application>_update.bin`: Mbed non-secure binary file for update separately when multiple image boot is enabled or
combined TF-M secure+Mbed non-secure binary file for update together when single image boot is enabled

View File

@ -1,5 +1,4 @@
/*
* @copyright SPDX-License-Identifier: Apache-2.0
* Copyright (c) 2017-2020 Arm Limited. All rights reserved.
* Copyright (c) 2020 Nuvoton Technology Corp. All rights reserved.
*
@ -21,15 +20,42 @@
/* Flash layout on M2354 with BL2 (single image boot):
*
* 0x0000_0000 BL2 - MCUBoot (64KB)
* 0x0001_0000 Protected Storage Area (32 KB)
* 0x0000_8000 Internal Trusted Storage Area (28 KB)
* 0x0000_F000 NV counters area (4 KB)
* 0x0002_0000 Primary image area (320KB):
* 0x0002_0000 Secure image primary
* 0x0007_0000 Non-secure image primary
* 0x0010_0000 Scratch area (4KB)
* Internal Flash:
* 0x0000_0000 BL2 - MCUBoot (48KB)
* 0x0000_C000 Protected Storage Area (56 KB)
* 0x0001_A000 Internal Trusted Storage Area (20 KB)
* 0x0001_F000 NV counters area (4 KB)
* 0x0002_0000 Primary image area (896KB):
* 0x0002_0000 Secure image primary (320KB)
* 0x0007_0000 Non-secure image primary (576KB)
* 0x0010_0000 Secondary image area (2KB):
* 0x0010_0000 Secure image secondary (320KB) (Dummy)
* 0x0015_0000 Non-secure image secondary (576KB) (Dummy)
* 0x001E_0000 Scratch area (4KB) (Dummy)
*
* SDH Flash:
* 0x0000_0000 Secondary image area (896KB)
* 0x0000_0000 Secure image secondary (320KB)
* 0x0005_0000 Non-secure image secondary (576KB)
* 0x0020_0000 Scratch area (4 KB)
*
* Flash layout on M2354 with BL2 (multiple image boot):
*
* Internal Flash:
* 0x0000_0000 BL2 - MCUBoot (48KB)
* 0x0000_C000 Protected Storage Area (56 KB)
* 0x0001_A000 Internal Trusted Storage Area (20 KB)
* 0x0001_F000 NV counters area (4 KB)
* 0x0002_0000 Secure image primary slot (320KB)
* 0x0007_0000 Non-secure image primary slot (576KB)
* 0x0010_0000 Secure image secondary slot (320KB) (Dummy)
* 0x0015_0000 Non-secure image secondary slot (576KB) (Dummy)
* 0x001E_0000 Scratch area (4KB) (Dummy)
*
* SDH Flash:
* 0x0000_0000 Secure image secondary slot (320KB)
* 0x0010_0000 Non-secure image secondary slot (576KB)
* 0x0020_0000 Scratch area (2 KB)
*/
/* This header file is included from linker scatter file as well, where only a
@ -40,8 +66,13 @@
*/
/* Size of a Secure and of a Non-secure image */
#define FLASH_S_PARTITION_SIZE (0x50000) /* S partition : 192+64+64 KB */
#define FLASH_NS_PARTITION_SIZE (0x90000) /* NS partition: 768-64-64 KB */
#if !NU_UPDATE_STAGE_FLASH
#define FLASH_S_PARTITION_SIZE (0x50000) /* S partition : 320 KB */
#define FLASH_NS_PARTITION_SIZE (0x90000) /* NS partition: 576 KB */
#else
#define FLASH_S_PARTITION_SIZE (0x46000) /* S partition : 280 KB */
#define FLASH_NS_PARTITION_SIZE (0x28000) /* NS partition: 160 KB */
#endif
#define FLASH_MAX_PARTITION_SIZE ((FLASH_S_PARTITION_SIZE > \
FLASH_NS_PARTITION_SIZE) ? \
FLASH_S_PARTITION_SIZE : \
@ -50,34 +81,56 @@
/* Sector size of the flash hardware; same as FLASH0_SECTOR_SIZE */
#define FLASH_AREA_IMAGE_SECTOR_SIZE (0x800) /* 2 KB */
/* Same as FLASH0_SIZE */
#define FLASH_TOTAL_SIZE (0x00100000) /* 512 KB */
#define FLASH_TOTAL_SIZE (0x00100000) /* 1024 KB */
/* Flash layout info for BL2 bootloader */
/* Same as FLASH0_BASE_S */
#define FLASH_BASE_ADDRESS (0x00000000)
#if NU_UPDATE_STAGE_SDH
#define SDH_FLASH_DEVICE_ID (FLASH_DEVICE_ID + 1)
#define SDH_FLASH_DEV_NAME Driver_SDH_FLASH0
#define SDH_FLASH_BASE_ADDRESS (0x00000000)
#endif
/* Offset and size definitions of the flash partitions that are handled by the
* bootloader. The image swapping is done between IMAGE_PRIMARY and
* IMAGE_SECONDARY, SCRATCH is used as a temporary storage during image
* swapping.
*/
#define FLASH_AREA_BL2_OFFSET (0x0)
#define FLASH_AREA_BL2_SIZE (0x10000) /* 64 KB */
#define FLASH_AREA_BL2_SIZE (0xC000) /* 48 KB */
#if !defined(MCUBOOT_IMAGE_NUMBER) || (MCUBOOT_IMAGE_NUMBER == 1)
/* Secure + Non-secure image primary slot */
#define FLASH_AREA_0_ID (1)
#define FLASH_AREA_0_OFFSET (FLASH_AREA_BL2_OFFSET + FLASH_AREA_BL2_SIZE + 0x10000) /* 0x10000 */
#define FLASH_AREA_0_SIZE (FLASH_S_PARTITION_SIZE + FLASH_NS_PARTITION_SIZE) /* 480 KB */
#define FLASH_AREA_0_OFFSET (FLASH_AREA_BL2_OFFSET + FLASH_AREA_BL2_SIZE + 0x14000) /* Reserved for storage */
#define FLASH_AREA_0_SIZE (FLASH_S_PARTITION_SIZE + FLASH_NS_PARTITION_SIZE)
/* Secure + Non-secure secondary slot */
#if NU_UPDATE_STAGE_SDH
#define FLASH_AREA_2_ID (FLASH_AREA_0_ID + 1)
#define FLASH_AREA_2_OFFSET (0x100000)
#define FLASH_AREA_2_SIZE (0x800)
#define FLASH_AREA_2_OFFSET (0x0)
#define FLASH_AREA_2_SIZE (FLASH_S_PARTITION_SIZE + FLASH_NS_PARTITION_SIZE)
#define FLASH_DEVICE_ID_2 SDH_FLASH_DEVICE_ID
#define FLASH_DEV_NAME_2 SDH_FLASH_DEV_NAME
#else
#define FLASH_AREA_2_ID (FLASH_AREA_0_ID + 1)
#define FLASH_AREA_2_OFFSET (FLASH_AREA_0_OFFSET + FLASH_AREA_0_SIZE)
#define FLASH_AREA_2_SIZE (FLASH_S_PARTITION_SIZE + FLASH_NS_PARTITION_SIZE)
#endif
/* Scratch area */
#if NU_UPDATE_STAGE_SDH
#define FLASH_AREA_SCRATCH_ID (FLASH_AREA_2_ID + 1)
#define FLASH_AREA_SCRATCH_OFFSET (0x100800)
#define FLASH_AREA_SCRATCH_SIZE (0x800)
#define FLASH_AREA_SCRATCH_OFFSET (0x200000)
#define FLASH_AREA_SCRATCH_SIZE (0x1000)
#define FLASH_DEVICE_ID_SCRATCH SDH_FLASH_DEVICE_ID
#define FLASH_DEV_NAME_SCRATCH SDH_FLASH_DEV_NAME
#else
#define FLASH_AREA_SCRATCH_ID (FLASH_AREA_2_ID + 1)
#define FLASH_AREA_SCRATCH_OFFSET (FLASH_AREA_2_OFFSET + FLASH_AREA_2_SIZE)
#define FLASH_AREA_SCRATCH_SIZE (0x1000)
#endif
/* The maximum number of status entries supported by the bootloader. */
#define MCUBOOT_STATUS_MAX_ENTRIES ((FLASH_S_PARTITION_SIZE + \
@ -88,24 +141,79 @@
#define MCUBOOT_MAX_IMG_SECTORS ((FLASH_S_PARTITION_SIZE + \
FLASH_NS_PARTITION_SIZE) / \
FLASH_AREA_IMAGE_SECTOR_SIZE)
#elif (MCUBOOT_IMAGE_NUMBER == 2)
/* Secure image primary slot */
#define FLASH_AREA_0_ID (1)
#define FLASH_AREA_0_OFFSET (FLASH_AREA_BL2_OFFSET + FLASH_AREA_BL2_SIZE + 0x14000) /* Reserved for storage */
#define FLASH_AREA_0_SIZE (FLASH_S_PARTITION_SIZE)
/* Non-secure image primary slot */
#define FLASH_AREA_1_ID (FLASH_AREA_0_ID + 1)
#define FLASH_AREA_1_OFFSET (FLASH_AREA_0_OFFSET + FLASH_AREA_0_SIZE)
#define FLASH_AREA_1_SIZE (FLASH_NS_PARTITION_SIZE)
/* Secure image secondary slot */
#if NU_UPDATE_STAGE_SDH
#define FLASH_AREA_2_ID (FLASH_AREA_1_ID + 1)
#define FLASH_AREA_2_OFFSET (0x0)
#define FLASH_AREA_2_SIZE (FLASH_S_PARTITION_SIZE)
#define FLASH_DEVICE_ID_2 SDH_FLASH_DEVICE_ID
#define FLASH_DEV_NAME_2 SDH_FLASH_DEV_NAME
#else
#error "Only MCUBOOT_IMAGE_NUMBER 1 are supported!"
#define FLASH_AREA_2_ID (FLASH_AREA_1_ID + 1)
#define FLASH_AREA_2_OFFSET (FLASH_AREA_1_OFFSET + FLASH_AREA_1_SIZE)
#define FLASH_AREA_2_SIZE (FLASH_S_PARTITION_SIZE)
#endif
/* Non-secure image secondary slot */
#if NU_UPDATE_STAGE_SDH
#define FLASH_AREA_3_ID (FLASH_AREA_2_ID + 1)
#define FLASH_AREA_3_OFFSET (0x100000)
#define FLASH_AREA_3_SIZE (FLASH_NS_PARTITION_SIZE)
#define FLASH_DEVICE_ID_3 SDH_FLASH_DEVICE_ID
#define FLASH_DEV_NAME_3 SDH_FLASH_DEV_NAME
#else
#define FLASH_AREA_3_ID (FLASH_AREA_2_ID + 1)
#define FLASH_AREA_3_OFFSET (FLASH_AREA_2_OFFSET + FLASH_AREA_2_SIZE)
#define FLASH_AREA_3_SIZE (FLASH_NS_PARTITION_SIZE)
#endif
/* Scratch area */
#if NU_UPDATE_STAGE_SDH
#define FLASH_AREA_SCRATCH_ID (FLASH_AREA_3_ID + 1)
#define FLASH_AREA_SCRATCH_OFFSET (0x200000)
#define FLASH_AREA_SCRATCH_SIZE (0x1000)
#define FLASH_DEVICE_ID_SCRATCH SDH_FLASH_DEVICE_ID
#define FLASH_DEV_NAME_SCRATCH SDH_FLASH_DEV_NAME
#else
#define FLASH_AREA_SCRATCH_ID (FLASH_AREA_3_ID + 1)
#define FLASH_AREA_SCRATCH_OFFSET (FLASH_AREA_3_OFFSET + FLASH_AREA_3_SIZE)
#define FLASH_AREA_SCRATCH_SIZE (0x1000)
#endif
/* The maximum number of status entries supported by the bootloader. */
#define MCUBOOT_STATUS_MAX_ENTRIES (FLASH_MAX_PARTITION_SIZE / \
FLASH_AREA_SCRATCH_SIZE)
/* Maximum number of image sectors supported by the bootloader. */
#define MCUBOOT_MAX_IMG_SECTORS (FLASH_MAX_PARTITION_SIZE / \
FLASH_AREA_IMAGE_SECTOR_SIZE)
#else /* MCUBOOT_IMAGE_NUMBER > 2 */
#error "Only MCUBOOT_IMAGE_NUMBER 1 and 2 are supported!"
#endif /* MCUBOOT_IMAGE_NUMBER */
/* Protected Storage (PS) Service definitions */
#define FLASH_PS_AREA_OFFSET (0x10000)
#define FLASH_PS_AREA_SIZE (0x8000)
#define FLASH_PS_AREA_OFFSET (FLASH_AREA_BL2_OFFSET + FLASH_AREA_BL2_SIZE)
#define FLASH_PS_AREA_SIZE (0xE000)
/* Internal Trusted Storage (ITS) Service definitions */
#define FLASH_ITS_AREA_OFFSET (FLASH_PS_AREA_OFFSET + \
FLASH_PS_AREA_SIZE)
#define FLASH_ITS_AREA_SIZE (0x7000)
#define FLASH_ITS_AREA_SIZE (0x5000)
/* NV Counters definitions */
#define FLASH_NV_COUNTERS_AREA_OFFSET (FLASH_ITS_AREA_OFFSET + \
FLASH_ITS_AREA_SIZE)
#define FLASH_NV_COUNTERS_AREA_SIZE (FLASH_AREA_IMAGE_SECTOR_SIZE)
#define FLASH_NV_COUNTERS_AREA_SIZE (0x1000)
/* Offset and size definition in flash area used by assemble.py */
#define SECURE_IMAGE_OFFSET (0x0)

View File

@ -1,5 +1,4 @@
/*
* @copyright SPDX-License-Identifier: Apache-2.0
* Copyright (c) 2017-2020 Arm Limited. All rights reserved.
* Copyright (c) 2020 Nuvoton Technology Corp. All rights reserved.
*
@ -98,7 +97,7 @@
#define S_CODE_LIMIT (S_CODE_START + S_CODE_SIZE - 1)
#define S_DATA_START (S_RAM_ALIAS(0x0))
#define S_DATA_SIZE (80 * 1024)
#define S_DATA_SIZE (96 * 1024)
#define S_DATA_LIMIT (S_DATA_START + S_DATA_SIZE - 1)
/* CMSE Veneers region */

View File

@ -21,5 +21,5 @@ enum image_attributes {
RE_SECURE_IMAGE_MAX_SIZE = (0x50000),
RE_NON_SECURE_IMAGE_OFFSET = ((0x0) + (0x50000)),
RE_NON_SECURE_IMAGE_MAX_SIZE = (0x90000),
RE_SIGN_BIN_SIZE = ((0x50000) + (0x90000)),
RE_SIGN_BIN_SIZE = ((0x90000)),
};

View File

@ -0,0 +1,25 @@
/*
* Copyright (c) 2020 Arm Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
enum image_attributes {
RE_SECURE_IMAGE_OFFSET = (0x0),
RE_SECURE_IMAGE_MAX_SIZE = (0x50000),
RE_NON_SECURE_IMAGE_OFFSET = ((0x0) + (0x50000)),
RE_NON_SECURE_IMAGE_MAX_SIZE = (0x90000),
RE_SIGN_BIN_SIZE = ((0x50000)),
};

View File

@ -2,7 +2,7 @@
A default RSA key pair is given to the Nuvoton M2354 target.
Public key was pre-compiled to `targets/TARGET_NUVOTON/TARGET_M2354/TARGET_TFM/TARGET_NU_M2354/COMPONENT_TFM_S_FW/bl2.bin` and private key is in `nuvoton_m2354-root-rsa-3072.pem` for Secure image and Non-Secure image together.
Public key was pre-compiled to `targets/TARGET_NUVOTON/TARGET_M2354/TARGET_TFM/TARGET_NU_M2354/COMPONENT_TFM_S_FW/bl2.bin` and private key is in `nuvoton_m2354-root-rsa-3072.pem` for Secure image and `nuvoton_m2354-root-rsa-3072_1.pem` for Non-Secure image.
DO NOT use them in production code, they are exclusively for testing!

View File

@ -0,0 +1,39 @@
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----

View File

@ -39,11 +39,19 @@
* If not, NU_TFM_S_BL2 and friends must update manually. */
#ifndef NU_TFM_S_BL2
#define NU_TFM_S_BL2 1
#define NU_TFM_S_BL2 1
#endif
#ifndef NU_TFM_S_MCUBOOT_IMAGE_NUMBER
#define NU_TFM_S_MCUBOOT_IMAGE_NUMBER 1
#define NU_TFM_S_MCUBOOT_IMAGE_NUMBER 2
#endif
#ifndef NU_TFM_S_UPDATE_STAGE_SDH
#define NU_TFM_S_UPDATE_STAGE_SDH 1
#endif
#ifndef NU_TFM_S_UPDATE_STAGE_FLASH
#define NU_TFM_S_UPDATE_STAGE_FLASH 0
#endif
#ifndef NU_TFM_S_REGION_DEFS_H_PATH
@ -57,10 +65,14 @@
#endif
#define MCUBOOT_IMAGE_NUMBER NU_TFM_S_MCUBOOT_IMAGE_NUMBER
#include NU_TFM_S_REGION_DEFS_H_PATH
#define NU_UPDATE_STAGE_SDH NU_TFM_S_UPDATE_STAGE_SDH
#define NU_UPDATE_STAGE_FLASH NU_TFM_S_UPDATE_STAGE_FLASH
/* Avoid polluting name space, esp. BL2 */
#undef BL2
#undef MCUBOOT_IMAGE_NUMBER
#undef NU_UPDATE_STAGE_SDH
#undef NU_UPDATE_STAGE_FLASH
/* Resolve MBED_ROM_START and friends
*

View File

@ -36,10 +36,10 @@ define symbol MBED_ROM_START_ORIDE = 0x10070400;
define symbol MBED_ROM_SIZE_ORIDE = 0x8F400;
/* Resolve non-secure RAM start */
define symbol MBED_RAM_START_ORIDE = 0x30014000;
define symbol MBED_RAM_START_ORIDE = 0x30018000;
/* Resolve non-secure RAM size */
define symbol MBED_RAM_SIZE_ORIDE = 0x2C000;
define symbol MBED_RAM_SIZE_ORIDE = 0x28000;
/* Mbed build tool passes just APPLICATION_xxx macros to C/C++ files and just
* MBED_APP_xxx macros to linker files even though they mean the same thing.

View File

@ -23,12 +23,12 @@ import subprocess
import shutil
import argparse
from intelhex import IntelHex
from datetime import datetime
SCRIPT_DIR = dirname(abspath(__file__))
MBED_OS_ROOT = abspath(path_join(SCRIPT_DIR, os.pardir, os.pardir, os.pardir))
def tfm_sign_image_tgt(tfm_import_path, signing_key, non_secure_bin):
def tfm_sign_image(tfm_import_path, signing_key, signing_key_1, non_secure_bin):
SECURE_ROOT = abspath(tfm_import_path)
secure_bin = path_join(SECURE_ROOT, 'tfm_s.bin')
@ -45,13 +45,8 @@ def tfm_sign_image_tgt(tfm_import_path, signing_key, non_secure_bin):
flash_layout = path_join(SECURE_ROOT, 'partition', 'flash_layout.h')
bl2_bin = path_join(SECURE_ROOT, 'bl2.bin')
image_macros_s_ns = path_join(SECURE_ROOT, 'partition', 'signing_layout_preprocessed.h')
s_bin_basename = splitext(basename(secure_bin))[0]
ns_bin_basename = splitext(basename(non_secure_bin))[0]
concatenated_bin = abspath(path_join(tempdir, 'tfm_' + ns_bin_basename + ".bin"))
signed_bin = abspath(path_join(tempdir, 'tfm_' + ns_bin_basename + '_signed' + ".bin"))
signed_nopad_bin = abspath(path_join(tempdir, 'tfm_' + ns_bin_basename + '_signed_nopad' + ".bin"))
assert os.path.isfile(image_macros_s_ns)
signing_key = path_join(SECURE_ROOT, 'signing_key', signing_key)
assert os.path.isfile(signing_key)
@ -59,41 +54,29 @@ def tfm_sign_image_tgt(tfm_import_path, signing_key, non_secure_bin):
# Find Python 3 command name across platforms
python3_cmd = "python3" if shutil.which("python3") is not None else "python"
#1. Concatenate secure TFM and non-secure mbed binaries
cmd = [
python3_cmd,
path_join(MBED_OS_ROOT, "tools", "psa", "tfm", "bin_utils", "assemble.py"),
"--layout",
image_macros_s_ns,
"-s",
secure_bin,
"-n",
non_secure_bin,
"-o",
concatenated_bin,
]
img_ver_major = 1
img_ver_minor = 3
img_ver_revision = 0
img_ver_build = 0
retcode = run_cmd(cmd, MBED_OS_ROOT)
if retcode:
raise Exception("Unable to concatenate " + "TF-M Secure/Mbed Non-secure" +
" binaries, Error code: " + str(retcode))
return
#2.1 Run wrapper to sign the concatenated binary with padding ("--pad"), so upgradeable by mcuboot
cmd = [
# wrapper.py command template
cmd_wrapper = [
python3_cmd,
path_join(MBED_OS_ROOT, "tools", "psa","tfm", "bin_utils", "wrapper.py"),
path_join(MBED_OS_ROOT, "tools", "psa", "tfm", "bin_utils", "wrapper.py"),
"-v",
'1.2.0',
"{}.{}.{}+{}".format(img_ver_major, img_ver_minor, img_ver_revision, img_ver_build),
"-k",
signing_key,
"SIGNING_KEY_PATH",
"--layout",
image_macros_s_ns,
"IMAGE_MACRO_PATH",
"--public-key-format",
'full',
"--align",
'1',
"--pad",
# Reasons for removing padding and boot magic option "--pad":
# 1. PSA FWU API psa_fwu_install() will be responsible for writing boot magic to enable upgradeable.
# 2. The image size gets smaller instead of slot size.
#"--pad",
"--pad-header",
"-H",
'0x400',
@ -101,35 +84,142 @@ def tfm_sign_image_tgt(tfm_import_path, signing_key, non_secure_bin):
"-s",
'auto',
"-d",
'(0,0.0.0+0)',
concatenated_bin,
signed_bin,
'(IMAGE_ID,MAJOR.MINOR.REVISION+BUILD)',
"RAW_BIN_PATH",
"SIGNED_BIN_PATH",
]
pos_wrapper_signing_key = cmd_wrapper.index("-k") + 1
pos_wrapper_layout = cmd_wrapper.index("--layout") + 1
pos_wrapper_dependency = cmd_wrapper.index("-d") + 1
pos_wrapper_raw_bin = len(cmd_wrapper) - 2
pos_wrapper_signed_bin = len(cmd_wrapper) - 1
retcode = run_cmd(cmd, MBED_OS_ROOT)
if retcode:
raise Exception("Unable to sign " + "concatenated" +
# assemble.py command template
cmd_assemble = [
python3_cmd,
path_join(MBED_OS_ROOT, "tools", "psa", "tfm", "bin_utils", "assemble.py"),
"--layout",
"IMAGE_MACRO_PATH",
"-s",
"SECURE_BIN_PATH",
"-n",
"NONSECURE_BIN_PATH",
"-o",
"CONCATENATED_BIN_PATH",
]
pos_assemble_layout = cmd_assemble.index("--layout") + 1
pos_assemble_secure_bin = cmd_assemble.index("-s") + 1
pos_assemble_nonsecure_bin = cmd_assemble.index("-n") + 1
pos_assemble_concat_bin = cmd_assemble.index("-o") + 1
# If second signing key is passed down, go signing separately; otherwise, go signing together.
if signing_key_1 is not None:
signing_key_1 = path_join(SECURE_ROOT, 'signing_key', signing_key_1)
assert os.path.isfile(signing_key_1)
image_macros_s = path_join(SECURE_ROOT, 'partition', 'signing_layout_s_preprocessed.h')
image_macros_ns = path_join(SECURE_ROOT, 'partition', 'signing_layout_ns_preprocessed.h')
assert os.path.isfile(image_macros_s)
assert os.path.isfile(image_macros_ns)
s_signed_bin = abspath(path_join(tempdir, 'tfm_s_signed' + '.bin'))
ns_signed_bin = abspath(path_join(tempdir, 'tfm_' + ns_bin_basename + '_signed' + '.bin'))
signed_concat_bin = abspath(path_join(tempdir, 'tfm_s_signed_' + ns_bin_basename + '_signed_concat' + '.bin'))
s_update_bin = abspath(path_join(build_dir, s_bin_basename + '_update' + '.bin'))
ns_update_bin = abspath(path_join(build_dir, ns_bin_basename + '_update' + '.bin'))
#1. Run wrapper to sign the secure TF-M binary
cmd_wrapper[pos_wrapper_signing_key] = signing_key
cmd_wrapper[pos_wrapper_layout] = image_macros_s
cmd_wrapper[pos_wrapper_dependency] = '(1,0.0.0+0)' # Minimum version of non-secure image required for upgrading to the secure image
cmd_wrapper[pos_wrapper_raw_bin] = secure_bin
cmd_wrapper[pos_wrapper_signed_bin] = s_signed_bin
retcode = run_cmd(cmd_wrapper, MBED_OS_ROOT)
if retcode:
raise Exception("Unable to sign " + "TF-M Secure" +
" binary, Error code: " + str(retcode))
return
return
#2.2. Re-run above but without padding ("--pad"), so non-upgradeable by mcuboot
cmd.remove("--pad")
cmd.pop()
cmd.append(signed_nopad_bin)
#2. Run wrapper to sign the non-secure mbed binary
cmd_wrapper[pos_wrapper_signing_key] = signing_key_1
cmd_wrapper[pos_wrapper_layout] = image_macros_ns
cmd_wrapper[pos_wrapper_dependency] = '(0,0.0.0+0)' # Minimum version of secure image required for upgrading to the non-secure image
cmd_wrapper[pos_wrapper_raw_bin] = non_secure_bin
cmd_wrapper[pos_wrapper_signed_bin] = ns_signed_bin
retcode = run_cmd(cmd, MBED_OS_ROOT)
if retcode:
raise Exception("Unable to sign " + "concatenated" +
retcode = run_cmd(cmd_wrapper, MBED_OS_ROOT)
if retcode:
raise Exception("Unable to sign " + "TF-M Secure" +
" binary, Error code: " + str(retcode))
return
return
#3. Concatenate mcuboot and signed binary and overwrite mbed built bin/hex file
flash_area_0_offset = find_flash_area_0_offset(flash_layout)
out_ih = IntelHex()
out_ih.loadbin(bl2_bin)
out_ih.loadbin(signed_nopad_bin, flash_area_0_offset)
out_ih.tofile(splitext(non_secure_bin)[0] + ".hex", 'hex')
out_ih.tobinfile(non_secure_bin)
#3. Concatenate signed secure TF-M binary and signed non-secure mbed binary
cmd_assemble[pos_assemble_layout] = image_macros_s
cmd_assemble[pos_assemble_secure_bin] = s_signed_bin
cmd_assemble[pos_assemble_nonsecure_bin] = ns_signed_bin
cmd_assemble[pos_assemble_concat_bin] = signed_concat_bin
retcode = run_cmd(cmd_assemble, MBED_OS_ROOT)
if retcode:
raise Exception("Unable to concatenate " + "Secure TF-M (signed)/Non-secure Mbed (signed)" +
" binaries, Error code: " + str(retcode))
return
#4. Concatenate MCUboot and concatenated signed secure TF-M binary/signed non-secure mbed binary
flash_area_0_offset = find_flash_area_0_offset(flash_layout)
out_ih = IntelHex()
out_ih.loadbin(bl2_bin)
out_ih.loadbin(signed_concat_bin, flash_area_0_offset)
out_ih.tofile(splitext(non_secure_bin)[0] + ".hex", 'hex')
out_ih.tobinfile(non_secure_bin)
# Generate firmware update file for PSA Firmware Update
shutil.copy(s_signed_bin, s_update_bin)
shutil.copy(ns_signed_bin, ns_update_bin)
else:
image_macros_s_ns = path_join(SECURE_ROOT, 'partition', 'signing_layout_preprocessed.h')
assert os.path.isfile(image_macros_s_ns)
concat_bin = abspath(path_join(tempdir, 'tfm_s_' + ns_bin_basename + ".bin"))
concat_signed_bin = abspath(path_join(tempdir, 'tfm_s_' + ns_bin_basename + '_signed' + ".bin"))
update_bin = abspath(path_join(build_dir, ns_bin_basename + '_update' + '.bin'))
#1. Concatenate secure TFM and non-secure mbed binaries
cmd_assemble[pos_assemble_layout] = image_macros_s_ns
cmd_assemble[pos_assemble_secure_bin] = secure_bin
cmd_assemble[pos_assemble_nonsecure_bin] = non_secure_bin
cmd_assemble[pos_assemble_concat_bin] = concat_bin
retcode = run_cmd(cmd_assemble, MBED_OS_ROOT)
if retcode:
raise Exception("Unable to concatenate " + "Secure TF-M/Non-secure Mbed" +
" binaries, Error code: " + str(retcode))
return
#2. Run wrapper to sign the concatenated binary
cmd_wrapper[pos_wrapper_signing_key] = signing_key
cmd_wrapper[pos_wrapper_layout] = image_macros_s_ns
cmd_wrapper[pos_wrapper_dependency] = '(1,0.0.0+0)' # No effect for single image boot
cmd_wrapper[pos_wrapper_raw_bin] = concat_bin
cmd_wrapper[pos_wrapper_signed_bin] = concat_signed_bin
retcode = run_cmd(cmd_wrapper, MBED_OS_ROOT)
if retcode:
raise Exception("Unable to sign " + "concatenated" +
" binary, Error code: " + str(retcode))
return
#3. Concatenate MCUboot and signed binary
flash_area_0_offset = find_flash_area_0_offset(flash_layout)
out_ih = IntelHex()
out_ih.loadbin(bl2_bin)
out_ih.loadbin(concat_signed_bin, flash_area_0_offset)
out_ih.tofile(splitext(non_secure_bin)[0] + ".hex", 'hex')
out_ih.tobinfile(non_secure_bin)
# Generate firmware update file for PSA Firmware Update
shutil.copy(concat_signed_bin, update_bin)
def find_flash_area_0_offset(configFile):
# Compiled regular expressions
@ -208,33 +298,39 @@ def parse_args():
subparsers = parser.add_subparsers(description="The action to perform")
parser_tfm_sign_image_tgt = subparsers.add_parser(
"tfm_sign_image_tgt",
help="Sign secure and non-secure images together"
parser_tfm_sign_image = subparsers.add_parser(
"tfm_sign_image",
help="Sign secure and non-secure images"
)
parser_tfm_sign_image_tgt.add_argument(
parser_tfm_sign_image.add_argument(
"--tfm-import-path",
help="Path containing the TF-M bootloader, layouts and signing keys",
required=True
)
parser_tfm_sign_image_tgt.add_argument(
parser_tfm_sign_image.add_argument(
"--signing_key",
help="File name of key for signing secure binary or secure/non-secure binaries together",
required=True
)
parser_tfm_sign_image_tgt.add_argument(
parser_tfm_sign_image.add_argument(
"--signing_key_1",
help="File name of key for signing non-secure binary",
required=False
)
parser_tfm_sign_image.add_argument(
"--non-secure-bin",
help="Path to the non-secure binary",
required=True
)
parser_tfm_sign_image_tgt.set_defaults(func=tfm_sign_image_tgt)
parser_tfm_sign_image.set_defaults(func=tfm_sign_image)
return parser.parse_args()
if __name__ == "__main__":
args = parse_args()
args.func(args.tfm_import_path, args.signing_key, args.non_secure_bin)
args.func(args.tfm_import_path, args.signing_key, args.signing_key_1, args.non_secure_bin)

View File

@ -6,27 +6,46 @@ include(mbed_set_post_build)
#
# Sign TF-M secure and non-secure images and combine them with the bootloader
#
macro(mbed_post_build_nuvoton_tfm_sign_image_tgt
macro(mbed_post_build_nuvoton_tfm_sign_image
nuvoton_target
tfm_import_path
signing_key
signing_key_1
)
if("${nuvoton_target}" STREQUAL "${MBED_TARGET}")
function(mbed_post_build_function target)
find_package(Python3)
add_custom_command(
TARGET
${target}
POST_BUILD
COMMAND
${Python3_EXECUTABLE}
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/NUVOTON.py
tfm_sign_image_tgt
--tfm-import-path ${tfm_import_path}
--signing_key ${signing_key}
--non-secure-bin $<TARGET_FILE_DIR:${target}>/$<TARGET_FILE_BASE_NAME:${target}>.bin
)
# NOTE: Macro arguments are not variables and cannot pass to if(<condition>).
set(signing_key_1_ ${signing_key_1})
if(signing_key_1_)
add_custom_command(
TARGET
${target}
POST_BUILD
COMMAND
${Python3_EXECUTABLE}
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/NUVOTON.py
tfm_sign_image
--tfm-import-path ${tfm_import_path}
--signing_key ${signing_key}
--signing_key_1 ${signing_key_1}
--non-secure-bin $<TARGET_FILE_DIR:${target}>/$<TARGET_FILE_BASE_NAME:${target}>.bin
)
else()
add_custom_command(
TARGET
${target}
POST_BUILD
COMMAND
${Python3_EXECUTABLE}
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/NUVOTON.py
tfm_sign_image
--tfm-import-path ${tfm_import_path}
--signing_key ${signing_key}
--non-secure-bin $<TARGET_FILE_DIR:${target}>/$<TARGET_FILE_BASE_NAME:${target}>.bin
)
endif()
endfunction()
endif()
endmacro()

View File

@ -7107,7 +7107,7 @@
]
],
"bootloader_supported": true,
"forced_reset_timeout": 3
"forced_reset_timeout": 5
},
"NU_M2354": {
"inherits": [

View File

@ -22,9 +22,12 @@ import re
import subprocess
import shutil
from intelhex import IntelHex
from datetime import datetime
SCRIPT_DIR = dirname(abspath(__file__))
MBED_OS_ROOT = abspath(path_join(SCRIPT_DIR, os.pardir, os.pardir))
SECURE_ROOT = path_join(MBED_OS_ROOT, 'targets', 'TARGET_NUVOTON', 'TARGET_M2354', 'TARGET_TFM', 'TARGET_NU_M2354', 'COMPONENT_TFM_S_FW')
def m2354_tfm_bin(t_self, non_secure_image, secure_bin):
@ -34,8 +37,6 @@ def m2354_tfm_bin(t_self, non_secure_image, secure_bin):
secure_bin = abspath(secure_bin)
non_secure_image = abspath(non_secure_image)
SECURE_ROOT = abspath(dirname(secure_bin))
build_dir = dirname(non_secure_image)
tempdir = path_join(build_dir, 'temp')
if not isdir(tempdir):
@ -44,11 +45,8 @@ def m2354_tfm_bin(t_self, non_secure_image, secure_bin):
flash_layout = path_join(SECURE_ROOT, 'partition', 'flash_layout.h')
bl2_bin = path_join(SECURE_ROOT, 'bl2.bin')
image_macros_s_ns = path_join(SECURE_ROOT, 'partition', 'signing_layout_preprocessed.h')
s_bin_basename = splitext(basename(secure_bin))[0]
ns_bin_basename, output_ext = splitext(basename(non_secure_image))
concatenated_bin = abspath(path_join(tempdir, 'tfm_' + ns_bin_basename + ".bin"))
signed_bin = abspath(path_join(tempdir, 'tfm_' + ns_bin_basename + '_signed' + ".bin"))
signed_nopad_bin = abspath(path_join(tempdir, 'tfm_' + ns_bin_basename + '_signed_nopad' + ".bin"))
# Convert NS image to BIN format if it is HEX
if output_ext == ".hex":
@ -58,49 +56,35 @@ def m2354_tfm_bin(t_self, non_secure_image, secure_bin):
else:
non_secure_bin = non_secure_image
assert os.path.isfile(image_macros_s_ns)
signing_key = path_join(SCRIPT_DIR, 'nuvoton_m2354-root-rsa-3072.pem')
assert os.path.isfile(signing_key)
# Find Python 3 command name across platforms
python3_cmd = "python3" if shutil.which("python3") is not None else "python"
#1. Concatenate secure TFM and non-secure mbed binaries
cmd = [
python3_cmd,
path_join(MBED_OS_ROOT, "tools", "psa","tfm", "bin_utils","assemble.py"),
"--layout",
image_macros_s_ns,
"-s",
secure_bin,
"-n",
non_secure_bin,
"-o",
concatenated_bin,
]
img_ver_major = 1
img_ver_minor = 3
img_ver_revision = 0
img_ver_build = 0
retcode = run_cmd(cmd, MBED_OS_ROOT)
if retcode:
raise Exception("Unable to concatenate " + "TF-M Secure/Mbed Non-secure" +
" binaries, Error code: " + str(retcode))
return
#2.1 Run wrapper to sign the concatenated binary with padding ("--pad"), so upgradeable by mcuboot
cmd = [
# wrapper.py command template
cmd_wrapper = [
python3_cmd,
path_join(MBED_OS_ROOT, "tools", "psa", "tfm", "bin_utils", "wrapper.py"),
"-v",
'1.2.0',
"{}.{}.{}+{}".format(img_ver_major, img_ver_minor, img_ver_revision, img_ver_build),
"-k",
signing_key,
"SIGNING_KEY_PATH",
"--layout",
image_macros_s_ns,
"IMAGE_MACRO_PATH",
"--public-key-format",
'full',
"--align",
'1',
"--pad",
# Reasons for removing padding and boot magic option "--pad":
# 1. PSA FWU API psa_fwu_install() will be responsible for writing boot magic to enable upgradeable.
# 2. The image size gets smaller instead of slot size.
#"--pad",
"--pad-header",
"-H",
'0x400',
@ -108,34 +92,145 @@ def m2354_tfm_bin(t_self, non_secure_image, secure_bin):
"-s",
'auto',
"-d",
'(0,0.0.0+0)',
concatenated_bin,
signed_bin,
'(IMAGE_ID,MAJOR.MINOR.REVISION+BUILD)',
"RAW_BIN_PATH",
"SIGNED_BIN_PATH",
]
pos_wrapper_signing_key = cmd_wrapper.index("-k") + 1
pos_wrapper_layout = cmd_wrapper.index("--layout") + 1
pos_wrapper_dependency = cmd_wrapper.index("-d") + 1
pos_wrapper_raw_bin = len(cmd_wrapper) - 2
pos_wrapper_signed_bin = len(cmd_wrapper) - 1
retcode = run_cmd(cmd, MBED_OS_ROOT)
if retcode:
raise Exception("Unable to sign " + "concatenated" +
# assemble.py command template
cmd_assemble = [
python3_cmd,
path_join(MBED_OS_ROOT, "tools", "psa", "tfm", "bin_utils", "assemble.py"),
"--layout",
"IMAGE_MACRO_PATH",
"-s",
"SECURE_BIN_PATH",
"-n",
"NONSECURE_BIN_PATH",
"-o",
"CONCATENATED_BIN_PATH",
]
pos_assemble_layout = cmd_assemble.index("--layout") + 1
pos_assemble_secure_bin = cmd_assemble.index("-s") + 1
pos_assemble_nonsecure_bin = cmd_assemble.index("-n") + 1
pos_assemble_concat_bin = cmd_assemble.index("-o") + 1
# If second signing key is passed down, go signing separately; otherwise, go signing together.
if os.path.isfile(path_join(SECURE_ROOT, 'partition', 'signing_layout_ns_preprocessed.h')):
signing_key_1 = 'nuvoton_m2354-root-rsa-3072_1.pem'
else:
signing_key_1 = None
if signing_key_1 is not None:
signing_key_1 = path_join(SCRIPT_DIR, signing_key_1)
assert os.path.isfile(signing_key_1)
image_macros_s = path_join(SECURE_ROOT, 'partition', 'signing_layout_s_preprocessed.h')
image_macros_ns = path_join(SECURE_ROOT, 'partition', 'signing_layout_ns_preprocessed.h')
assert os.path.isfile(image_macros_s)
assert os.path.isfile(image_macros_ns)
s_signed_bin = abspath(path_join(tempdir, 'tfm_s_signed' + '.bin'))
ns_signed_bin = abspath(path_join(tempdir, 'tfm_' + ns_bin_basename + '_signed' + '.bin'))
signed_concat_bin = abspath(path_join(tempdir, 'tfm_s_signed_' + ns_bin_basename + '_signed_concat' + '.bin'))
s_update_bin = abspath(path_join(build_dir, s_bin_basename + '_update' + '.bin'))
ns_update_bin = abspath(path_join(build_dir, ns_bin_basename + '_update' + '.bin'))
#1. Run wrapper to sign the secure TF-M binary
cmd_wrapper[pos_wrapper_signing_key] = signing_key
cmd_wrapper[pos_wrapper_layout] = image_macros_s
cmd_wrapper[pos_wrapper_dependency] = '(1,0.0.0+0)' # Minimum version of non-secure image required for upgrading to the secure image
cmd_wrapper[pos_wrapper_raw_bin] = secure_bin
cmd_wrapper[pos_wrapper_signed_bin] = s_signed_bin
retcode = run_cmd(cmd_wrapper, MBED_OS_ROOT)
if retcode:
raise Exception("Unable to sign " + "TF-M Secure" +
" binary, Error code: " + str(retcode))
return
return
#2.2. Re-run above but without padding ("--pad"), so non-upgradeable by mcuboot
cmd.remove("--pad")
cmd.pop()
cmd.append(signed_nopad_bin)
#2. Run wrapper to sign the non-secure mbed binary
cmd_wrapper[pos_wrapper_signing_key] = signing_key_1
cmd_wrapper[pos_wrapper_layout] = image_macros_ns
cmd_wrapper[pos_wrapper_dependency] = '(0,0.0.0+0)' # Minimum version of secure image required for upgrading to the non-secure image
cmd_wrapper[pos_wrapper_raw_bin] = non_secure_bin
cmd_wrapper[pos_wrapper_signed_bin] = ns_signed_bin
retcode = run_cmd(cmd, MBED_OS_ROOT)
if retcode:
raise Exception("Unable to sign " + "concatenated" +
retcode = run_cmd(cmd_wrapper, MBED_OS_ROOT)
if retcode:
raise Exception("Unable to sign " + "TF-M Secure" +
" binary, Error code: " + str(retcode))
return
return
#3. Concatenate mcuboot and signed binary and overwrite mbed built bin/hex file
flash_area_0_offset = find_flash_area_0_offset(flash_layout)
out_ih = IntelHex()
out_ih.loadbin(bl2_bin)
out_ih.loadbin(signed_nopad_bin, flash_area_0_offset)
out_ih.tofile(non_secure_image, 'hex' if output_ext == ".hex" else "bin")
#3. Concatenate signed secure TF-M binary and signed non-secure mbed binary
cmd_assemble[pos_assemble_layout] = image_macros_s
cmd_assemble[pos_assemble_secure_bin] = s_signed_bin
cmd_assemble[pos_assemble_nonsecure_bin] = ns_signed_bin
cmd_assemble[pos_assemble_concat_bin] = signed_concat_bin
retcode = run_cmd(cmd_assemble, MBED_OS_ROOT)
if retcode:
raise Exception("Unable to concatenate " + "Secure TF-M (signed)/Non-secure Mbed (signed)" +
" binaries, Error code: " + str(retcode))
return
#4. Concatenate MCUboot and concatenated signed secure TF-M binary/signed non-secure mbed binary
flash_area_0_offset = find_flash_area_0_offset(flash_layout)
out_ih = IntelHex()
out_ih.loadbin(bl2_bin)
out_ih.loadbin(signed_concat_bin, flash_area_0_offset)
out_ih.tofile(non_secure_image, 'hex' if output_ext == ".hex" else "bin")
# Generate firmware update file for PSA Firmware Update
shutil.copy(s_signed_bin, s_update_bin)
shutil.copy(ns_signed_bin, ns_update_bin)
else:
image_macros_s_ns = path_join(SECURE_ROOT, 'partition', 'signing_layout_preprocessed.h')
assert os.path.isfile(image_macros_s_ns)
concat_bin = abspath(path_join(tempdir, 'tfm_s_' + ns_bin_basename + ".bin"))
concat_signed_bin = abspath(path_join(tempdir, 'tfm_s_' + ns_bin_basename + '_signed' + ".bin"))
update_bin = abspath(path_join(build_dir, ns_bin_basename + '_update' + '.bin'))
#1. Concatenate secure TFM and non-secure mbed binaries
cmd_assemble[pos_assemble_layout] = image_macros_s_ns
cmd_assemble[pos_assemble_secure_bin] = secure_bin
cmd_assemble[pos_assemble_nonsecure_bin] = non_secure_bin
cmd_assemble[pos_assemble_concat_bin] = concat_bin
retcode = run_cmd(cmd_assemble, MBED_OS_ROOT)
if retcode:
raise Exception("Unable to concatenate " + "Secure TF-M/Non-secure Mbed" +
" binaries, Error code: " + str(retcode))
return
#2. Run wrapper to sign the concatenated binary
cmd_wrapper[pos_wrapper_signing_key] = signing_key
cmd_wrapper[pos_wrapper_layout] = image_macros_s_ns
cmd_wrapper[pos_wrapper_dependency] = '(1,0.0.0+0)' # No effect for single image boot
cmd_wrapper[pos_wrapper_raw_bin] = concat_bin
cmd_wrapper[pos_wrapper_signed_bin] = concat_signed_bin
retcode = run_cmd(cmd_wrapper, MBED_OS_ROOT)
if retcode:
raise Exception("Unable to sign " + "concatenated" +
" binary, Error code: " + str(retcode))
return
#3. Concatenate MCUboot and signed binary
flash_area_0_offset = find_flash_area_0_offset(flash_layout)
out_ih = IntelHex()
out_ih.loadbin(bl2_bin)
out_ih.loadbin(concat_signed_bin, flash_area_0_offset)
out_ih.tofile(non_secure_image, 'hex' if output_ext == ".hex" else "bin")
# Generate firmware update file for PSA Firmware Update
shutil.copy(concat_signed_bin, update_bin)
def find_flash_area_0_offset(configFile):
# Compiled regular expressions

View File

@ -2,7 +2,7 @@
A default RSA key pair is given to the Nuvoton M2354 target.
Public key was pre-compiled to `targets/TARGET_NUVOTON/TARGET_M2354/TARGET_TFM/TARGET_NU_M2354/COMPONENT_TFM_S_FW/bl2.bin` and private key is in `nuvoton_m2354-root-rsa-3072.pem` for Secure image and Non-Secure image together.
Public key was pre-compiled to `targets/TARGET_NUVOTON/TARGET_M2354/TARGET_TFM/TARGET_NU_M2354/COMPONENT_TFM_S_FW/bl2.bin` and private key is in `nuvoton_m2354-root-rsa-3072.pem` for Secure image and `nuvoton_m2354-root-rsa-3072_1.pem` for Non-Secure image.
DO NOT use them in production code, they are exclusively for testing!

View File

@ -0,0 +1,39 @@
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----