Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mcu/nrf5340: Add scripts to export/import NSC code #3336

Merged
merged 2 commits into from
Nov 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion hw/mcu/nordic/nrf5340/nrf5340.ld
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
*/
ENTRY(Reset_Handler)

NSC_REGION_SIZE = 0x200;

SECTIONS
{
.imghdr (NOLOAD):
Expand Down Expand Up @@ -107,7 +109,6 @@ INCLUDE "link_tables.ld.h"
. = ALIGN(4);
} > FLASH


.net_core_img :
{
PROVIDE(net_core_img_start = .);
Expand All @@ -127,6 +128,15 @@ INCLUDE "link_tables.ld.h"
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
. = ALIGN(4);
} > FLASH

.gnu.sgstubs :
{
FILL(0xffff);
. = (ALIGN(16384) >= . + NSC_REGION_SIZE) ? (ALIGN(16384) - NSC_REGION_SIZE) : (ALIGN(16384) - NSC_REGION_SIZE + 16384);
_start_sg = .;
} > FLASH
PROVIDE(_end_sg = .);

__exidx_end = .;

__etext = .;
Expand Down
24 changes: 24 additions & 0 deletions hw/mcu/nordic/nrf5340/src/hal_system_start.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,26 @@ static const unsigned int periph_gpios[] = { UNMANGLE_MYNEWT_VAL(MYNEWT_VAL(MCU_
#endif

extern uint8_t __StackTop[];
extern uint8_t _start_sg[];
extern uint8_t _end_sg[];

static void
init_nsc(void)
{
int region = (uintptr_t)_start_sg / 0x4000;
uintptr_t region_start = region * 0x4000;
uintptr_t region_limit = region_start + 0x4000;
int nsc_region_size = 32;
int m = 1;
/* Calculate NSC region size by checking _start_sg offset in last 16K region */
while ((uintptr_t)_start_sg < region_limit - nsc_region_size) {
m++;
nsc_region_size <<= 1;
}
assert(m <= 8);
NRF_SPU_S->FLASHNSC[0].REGION = region;
NRF_SPU_S->FLASHNSC[0].SIZE = m;
}

void
hal_system_start(void *img_start)
Expand Down Expand Up @@ -106,6 +126,10 @@ hal_system_start(void *img_start)
NRF_SPU->FLASHREGION[i].PERM &= ~SPU_FLASHREGION_PERM_SECATTR_Msk;
}

if ((uint32_t)_start_sg < (uint32_t)_end_sg) {
init_nsc();
}

/* Mark RAM as non-secure */
for (i = 0; i < 64; ++i) {
NRF_SPU->RAMREGION[i].PERM &= ~SPU_FLASHREGION_PERM_SECATTR_Msk;
Expand Down
90 changes: 90 additions & 0 deletions hw/mcu/nordic/nrf5340/tfm/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<!--
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you 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.
#
-->

# TFM package

# Overview

This package provides way to connect secure code from bootloader with
non-secure code of the application.

Bootloader build with `MCU_APP_SECURE` set to 1 will mark non-bootloader
flash as non-secure and part for the bootloader flash region as
non-secure callable.

When syscfg has `TFM_EXPORT_NSC: 1`, during build of the bootloader, additional library `tfm_s_CMSE_lib.a`
will be created that can be linked to the application code so secure functions ar callable.

Application build as unsecure should specify `TFM_IMPORT_NSC: 1` to mark function as non-secure-callable.
Easy connection between the bootloader and the application is achieved with syscfg value `TFM_SECURE_BOOT_TARGET`
that can point to bootloader target where import library should be generated.

# Examples targets

### 1. Bootloader target

#### targets/nordic_pca10095-boot_sec/pkg.yml
```yaml
pkg.name: "targets/nordic_pca10095-boot_sec"
pkg.type: target
````
#### targets/nordic_pca10095-boot_sec/target.yml
```yaml
target.app: "@mcuboot/boot/mynewt"
target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10095"
````
#### targets/nordic_pca10095-boot_sec/syscfg.yml
```yaml
syscfg.vals:
# Build for non-secure application
# Bootloader is still secure
MCU_APP_SECURE: 0

# Export NSC functions to library
TFM_EXPORT_NSC: 1
````
### 2. Application target

#### targets/nordic_pca10095-btshell/pkg.yml
```yaml
pkg.name: "targets/nordic_pca10095-btshell"
pkg.type: target
````
#### targets/nordic_pca10095-btshell/target.yml
```yaml
target.app: "@apache-mynewt-nimble/apps/btshell"
target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10095"
````
#### targets/nordic_pca10095-btshell/syscfg.yml
```yaml
syscfg.vals:
# Build application as non-secure code
MCU_APP_SECURE: 0
# Enable net core automatically
BSP_NRF5340_NET_ENABLE: 1
# Embed default blehci target inside application image
NRF5340_EMBED_NET_CORE: 1

# Inform that NSC functions should be imported from library
TFM_IMPORT_NSC: 1
# Set booloader target that should produce library with NSC functions
TFM_SECURE_BOOT_TARGET: nordic_pca10095-boot_sec
````
11 changes: 9 additions & 2 deletions hw/mcu/nordic/nrf5340/tfm/pkg.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,19 @@ pkg.cflags.(BOOT_LOADER && TFM_EXPORT_NSC):
pkg.cflags.(!BOOT_LOADER && MCU_APP_SECURE && TFM_EXPORT_NSC):
- -mcmse

pkg.cflags.(!BOOT_LOADER && !MCU_APP_SECURE):
app.cflags.(!BOOT_LOADER && !MCU_APP_SECURE):
- -mcmse

pkg.lflags.(MCU_APP_SECURE && TFM_EXPORT_NSC):
pkg.lflags.TFM_EXPORT_NSC:
- -utfm_uicr_otp_read
- -utfm_uicr_otp_write
- -utfm_gpio_pin_mcu_select
- -utfm_uicr_protect_device
- -utfm_ficr_xosc32mtrim_read
- -Wl,--out-implib=bin/tfm_s_CMSE_lib.o -Wl,--cmse-implib

pkg.post_link_cmds.TFM_EXPORT_NSC:
scripts/create_tfmlib.sh: 100

pkg.pre_link_cmds.TFM_IMPORT_NSC:
scripts/import_tfmlib.sh: 100
30 changes: 30 additions & 0 deletions hw/mcu/nordic/nrf5340/tfm/scripts/create_tfmlib.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/bin/bash

# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you 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.
#

AR=${MYNEWT_AR_PATH}

pushd ${MYNEWT_PROJECT_ROOT}

if [ -f ${MYNEWT_PROJECT_ROOT}/bin/tfm_s_CMSE_lib.o ] ; then
mv ${MYNEWT_PROJECT_ROOT}/bin/tfm_s_CMSE_lib.o ${MYNEWT_PKG_BIN_DIR}/
${AR} rcs ${MYNEWT_BIN_DIR}/tfm_s_CMSE_lib.a ${MYNEWT_PKG_BIN_DIR}/tfm_s_CMSE_lib.o
fi

popd
31 changes: 31 additions & 0 deletions hw/mcu/nordic/nrf5340/tfm/scripts/import_tfmlib.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#!/bin/bash

# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you 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.
#

if [ "${MYNEWT_VAL_TFM_SECURE_BOOT_TARGET}" != "" ] ; then
export IMPORT_LIBRARY=${MYNEWT_PROJECT_ROOT}/bin/targets/${MYNEWT_VAL_TFM_SECURE_BOOT_TARGET}/tfm_s_CMSE_lib.a

pushd ${MYNEWT_PROJECT_ROOT}

if [ -f ${IMPORT_LIBRARY} ] ; then
cp -u ${IMPORT_LIBRARY} ${MYNEWT_BUILD_GENERATED_DIR}/bin/
fi

popd
fi
4 changes: 4 additions & 0 deletions hw/mcu/nordic/nrf5340/tfm/src/tfm.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
#include <nrf_gpio.h>
#include <tfm/tfm.h>

#if MYNEWT_VAL(TFM_EXPORT_NSC) || MYNEWT_VAL(MCU_APP_SECURE) || MYNEWT_VAL(BOOT_LOADER)

int SECURE_CALL
tfm_uicr_otp_read(uint8_t n, uint32_t *ret)
{
Expand Down Expand Up @@ -110,3 +112,5 @@ tfm_ficr_xosc32mtrim_read(uint32_t *xosc32mtrim)

return 0;
}

#endif
11 changes: 11 additions & 0 deletions hw/mcu/nordic/nrf5340/tfm/syscfg.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ syscfg.defs:
If set to 1 secure function will be exported and can be used by
non secure code.
value:
TFM_IMPORT_NSC:
description: >
Application is non-secure and needs to import library generated
from secure code.
value:
TFM_MCU_SEL_GPIO0:
description: >
Bit mask of GPIO0 pins that can be assigned between cores by non secure code.
Expand All @@ -40,3 +45,9 @@ syscfg.defs:
description: >
Maximum address of UICR OTP that can be accessed by non-secure core.
value: 191

TFM_SECURE_BOOT_TARGET:
description: >
Mynewt target that holds TFM secure code that will be used to import
veneers from.
value:
Loading