From 033158cfe7bdcebb2f7c18103a576e6813d1c705 Mon Sep 17 00:00:00 2001 From: Ahmed Ismail Date: Fri, 27 Sep 2024 11:56:46 +0100 Subject: [PATCH] cortex-m85: Add non-MPU PACBTI example This example demonstrates how the new Pointer Authentication and Branch Target Identification (PACBTI)security feature can be used on Cortex-M85 processor. The example is based on Corstone-315 Ecosystem Fixed Virtual Platform (Arm Cortex-M85 CPU and Ethos-U65 NPU). The example consists of two main tasks (prvPacTask , and prvBtiTask). The prvPacTask , and prvBtiTask tasks job is to trigger the UsageFault exception by mimicking ROP (Return Oriented Programming), JOP (Jump Oriented Programming) security exploit attacks. The example is compatible with Arm Compiler For Embedded toolchain and IAR toolchain for Arm. The support for GNU toolchain is not yet enabled due to known issues. Signed-off-by: Ahmed Ismail --- .../CMSIS/CMakeLists.txt | 95 +++++ .../CMSIS/common/bsp_serial.c | 228 ++++++++++++ .../CMSIS/common/bsp_serial.h | 22 ++ .../corstone315/include/RTE_Components.h | 26 ++ .../CMSIS/corstone315/include/device_cfg.h | 276 +++++++++++++++ .../CMakeLists.txt | 100 ++++++ CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/README.md | 169 +++++++++ .../armclang.sct | 47 +++ .../armclang_toolchain.cmake | 15 + .../config/FreeRTOSConfig.h | 190 ++++++++++ .../config/project_config.h | 86 +++++ .../iar_arm.icf | 32 ++ .../iar_toolchain.cmake | 42 +++ CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/main.c | 325 ++++++++++++++++++ CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/run.sh | 7 + .../trusted_firmware-m/CMakeLists.txt | 11 + .../integration/CMakeLists.txt | 40 +++ .../integration/cmake/BuildTfm.cmake | 81 +++++ .../integration/cmake/ConvertElfToBin.cmake | 37 ++ .../integration/cmake/MergeTfmImages.cmake | 40 +++ .../integration/cmake/SignTfmImage.cmake | 44 +++ 21 files changed, 1913 insertions(+) create mode 100644 CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/CMSIS/CMakeLists.txt create mode 100644 CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/CMSIS/common/bsp_serial.c create mode 100644 CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/CMSIS/common/bsp_serial.h create mode 100644 CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/CMSIS/corstone315/include/RTE_Components.h create mode 100644 CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/CMSIS/corstone315/include/device_cfg.h create mode 100644 CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/CMakeLists.txt create mode 100644 CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/README.md create mode 100644 CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/armclang.sct create mode 100644 CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/armclang_toolchain.cmake create mode 100644 CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/config/FreeRTOSConfig.h create mode 100644 CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/config/project_config.h create mode 100644 CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/iar_arm.icf create mode 100644 CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/iar_toolchain.cmake create mode 100644 CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/main.c create mode 100755 CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/run.sh create mode 100644 CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/trusted_firmware-m/CMakeLists.txt create mode 100644 CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/trusted_firmware-m/integration/CMakeLists.txt create mode 100644 CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/trusted_firmware-m/integration/cmake/BuildTfm.cmake create mode 100644 CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/trusted_firmware-m/integration/cmake/ConvertElfToBin.cmake create mode 100644 CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/trusted_firmware-m/integration/cmake/MergeTfmImages.cmake create mode 100644 CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/trusted_firmware-m/integration/cmake/SignTfmImage.cmake diff --git a/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/CMSIS/CMakeLists.txt b/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/CMSIS/CMakeLists.txt new file mode 100644 index 0000000..0fe40c2 --- /dev/null +++ b/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/CMSIS/CMakeLists.txt @@ -0,0 +1,95 @@ +# Copyright 2023-2024 Arm Limited and/or its affiliates +# +# SPDX-License-Identifier: Apache-2.0 + +set(arm_corstone_platform_bsp_SOURCE_DIR + ${CMAKE_CURRENT_LIST_DIR}/../../Demos_Dependencies/arm_corstone_platform_bsp + CACHE INTERNAL + "Path to Arm Corstone-3xx Platform CMSIS-Driver Based Board Support Package source code" +) + +set(ARM_CORSTONE_BSP_TARGET_PLATFORM "corstone315" CACHE STRING "") + +add_subdirectory(${arm_corstone_platform_bsp_SOURCE_DIR} build) + +if(FREERTOS_ARM_V_8_1_M_PACBTI_CONFIG STREQUAL "ARM_V_8_1_M_PACBTI_CONFIG_STANDARD") + target_compile_options(arm-corstone-platform-bsp PUBLIC $<$:-mbranch-protection=standard>) + target_compile_options(arm-corstone-platform-bsp PUBLIC $<$:$<$:--branch_protection=bti+pac-ret>>) +elseif(FREERTOS_ARM_V_8_1_M_PACBTI_CONFIG STREQUAL "ARM_V_8_1_M_PACBTI_CONFIG_PACRET_LEAF_BTI") + if(${CMAKE_C_COMPILER_ID} STREQUAL "ARMClang") + target_compile_options(arm-corstone-platform-bsp + PUBLIC + -mbranch-protection=bti+pac-ret+leaf + ) + elseif(${CMAKE_C_COMPILER_ID} STREQUAL "IAR") + message(FATAL_ERROR "ARM_V_8_1_M_PACBTI_CONFIG_PACRET_LEAF_BTI PACBTI option is not supported on IAR Compiler.") + endif() +elseif(FREERTOS_ARM_V_8_1_M_PACBTI_CONFIG STREQUAL "ARM_V_8_1_M_PACBTI_CONFIG_PACRET") + target_compile_options(arm-corstone-platform-bsp PUBLIC $<$:-mbranch-protection=pac-ret>) + target_compile_options(arm-corstone-platform-bsp PUBLIC $<$:$<$:--branch_protection=pac-ret>>) +elseif(FREERTOS_ARM_V_8_1_M_PACBTI_CONFIG STREQUAL "ARM_V_8_1_M_PACBTI_CONFIG_PACRET_LEAF") + if(${CMAKE_C_COMPILER_ID} STREQUAL "ARMClang") + target_compile_options(arm-corstone-platform-bsp + PUBLIC + -mbranch-protection=pac-ret+leaf + ) + elseif(${CMAKE_C_COMPILER_ID} STREQUAL "IAR") + message(FATAL_ERROR "ARM_V_8_1_M_PACBTI_CONFIG_PACRET_LEAF PACBTI option is not supported on IAR Compiler.") + endif() +elseif(FREERTOS_ARM_V_8_1_M_PACBTI_CONFIG STREQUAL "ARM_V_8_1_M_PACBTI_CONFIG_BTI") + target_compile_options(arm-corstone-platform-bsp PUBLIC $<$:-mbranch-protection=bti>) + target_compile_options(arm-corstone-platform-bsp PUBLIC $<$:$<$:--branch_protection=bti>>) +elseif(FREERTOS_ARM_V_8_1_M_PACBTI_CONFIG STREQUAL "ARM_V_8_1_M_PACBTI_CONFIG_NONE") + if(${CMAKE_C_COMPILER_ID} STREQUAL "ARMClang") + target_compile_options(arm-corstone-platform-bsp + PUBLIC + -mbranch-protection=none + ) + endif() +else() + message(FATAL_ERROR "Invalid FREERTOS_ARM_V_8_1_M_PACBTI_CONFIG option chosen, the supported configurations are + ARM_V_8_1_M_PACBTI_CONFIG_STANDARD, + ARM_V_8_1_M_PACBTI_CONFIG_PACRET_LEAF_BTI, + ARM_V_8_1_M_PACBTI_CONFIG_PACRET, + ARM_V_8_1_M_PACBTI_CONFIG_PACRET_LEAF, + ARM_V_8_1_M_PACBTI_CONFIG_BTI, + ARM_V_8_1_M_PACBTI_CONFIG_NONE + ") +endif() + +target_compile_definitions(arm-corstone-platform-bsp + INTERFACE + __DOMAIN_NS=1 +) + +set(BL1_IMAGE_LOAD_ADDRESS 0x11000000 CACHE STRING "Bootload stage 1 image loading address") +set(BL2_IMAGE_LOAD_ADDRESS 0x12031400 CACHE STRING "Bootload image loading address") +set(S_IMAGE_LOAD_ADDRESS 0x38000000 CACHE STRING "Secure TF-M firmware loading address") +set(NS_IMAGE_LOAD_ADDRESS 0x28040000 CACHE STRING "Non-secure user application loading address") +set(S_CM_PROVISIONING_BUNDLE_LOAD_ADDRESS 0x12024000 CACHE STRING "Secure CM provisioning bundle loading address") +set(S_DM_PROVISIONING_BUNDLE_LOAD_ADDRESS 0x1202aa00 CACHE STRING "Secure DM provisioning bundle loading address") + +target_include_directories(arm-corstone-platform-bsp + PUBLIC + ${CMAKE_CURRENT_LIST_DIR}/corstone315/include +) + +# BSP serial library + +add_library(cmsis_bsp STATIC) + +target_sources(cmsis_bsp + PRIVATE + common/bsp_serial.c +) + +target_include_directories(cmsis_bsp + PUBLIC + common +) + +target_link_libraries(cmsis_bsp + PUBLIC + arm-corstone-platform-bsp + freertos_kernel +) diff --git a/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/CMSIS/common/bsp_serial.c b/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/CMSIS/common/bsp_serial.c new file mode 100644 index 0000000..8e76e1f --- /dev/null +++ b/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/CMSIS/common/bsp_serial.c @@ -0,0 +1,228 @@ +/* Copyright 2017-2024 Arm Limited and/or its affiliates + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "device_cfg.h" +#include "Driver_USART.h" +#include "bsp_serial.h" + +#include "FreeRTOS.h" +#include "semphr.h" + +#define STDIN_FILENO 0 +#define STDOUT_FILENO 1 +#define STDERR_FILENO 2 + +typedef enum +{ + WRITE_ERROR_SEND_FAIL = -3, + WRITE_ERROR_SYNC_FAILED = -2, + WRITE_ERROR_INVALID_ARGS = -1, + WRITE_ERROR_NONE = 0 +} WriteError_t; + +typedef struct +{ + WriteError_t error; + unsigned int charsWritten; +} WriteResult_t; + +extern ARM_DRIVER_USART Driver_USART0; + +static SemaphoreHandle_t xLoggingMutex = NULL; + +static bool prvValidFdHandle( int fd ); +static void prvWriteChars( int fd, + const unsigned char * str, + unsigned int len, + WriteResult_t * result ); + +void bsp_serial_init( void ) +{ + Driver_USART0.Initialize( NULL ); + Driver_USART0.PowerControl( ARM_POWER_FULL ); + Driver_USART0.Control( ARM_USART_MODE_ASYNCHRONOUS, DEFAULT_UART_BAUDRATE ); + Driver_USART0.Control( ARM_USART_CONTROL_TX, 1 ); + Driver_USART0.Control( ARM_USART_CONTROL_RX, 1 ); + + if( xLoggingMutex == NULL ) + { + xLoggingMutex = xSemaphoreCreateMutex(); + configASSERT( xLoggingMutex ); + } +} + +void bsp_serial_print( char * str ) +{ + ( void ) Driver_USART0.Send( str, strlen( str ) ); + + while( Driver_USART0.GetTxCount() != strlen( str ) ) + { + } +} + +#if defined( __ARMCOMPILER_VERSION ) + +/* Retarget armclang, which requires all IO system calls to be overridden together. */ + + #include + + FILEHANDLE _sys_open( const char * name, + int openmode ) + { + if( name == NULL ) + { + return -1; + } + + /* By default, the Arm Compiler uses the special file path ":tt" for stdin, */ + /* stdout and stderr and distinguishes between them using openmode. For details, */ + /* see https://github.com/ARM-software/abi-aa/blob/2022Q1/semihosting/semihosting.rst#sys-open-0x01 */ + if( strcmp( name, ":tt" ) == 0 ) + { + if( openmode & OPEN_W ) + { + return STDOUT_FILENO; + } + + if( openmode & OPEN_A ) + { + return STDERR_FILENO; + } + + return STDIN_FILENO; + } + + return -1; + } + + int _sys_close( FILEHANDLE fh ) + { + /* Not implemented */ + ( void ) fh; + return -1; + } + + int _sys_write( FILEHANDLE fd, + const unsigned char * str, + unsigned int len, + int mode ) + { + /* From : `mode` exists for historical reasons and must be ignored. */ + ( void ) mode; + + WriteResult_t result = { .error = WRITE_ERROR_NONE, .charsWritten = 0 }; + prvWriteChars( ( int ) fd, str, len, &result ); + + if( ( result.error == WRITE_ERROR_NONE ) && ( result.charsWritten == len ) ) + { + return 0; + } + else if( result.error == WRITE_ERROR_SEND_FAIL ) + { + return len - result.charsWritten; + } + else + { + return ( int ) result.error; + } + } + + int _sys_read( FILEHANDLE fd, + unsigned char * str, + unsigned int len, + int mode ) + { + /* From : `mode' exists for historical reasons and must be ignored. */ + ( void ) mode; + + /* Not implemented */ + ( void ) str; + ( void ) len; + return -1; + } + + int _sys_istty( FILEHANDLE fh ) + { + /* Not implemented */ + ( void ) fh; + return 0; + } + + long _sys_flen( FILEHANDLE fh ) + { + /* Not implemented */ + ( void ) fh; + return -1; + } + + int _sys_seek( FILEHANDLE fh, + long offset ) + { + /* Not implemented */ + ( void ) fh; + ( void ) offset; + return -1; + } + +#else /* !defined(__ARMCOMPILER_VERSION) */ + +/* Redirects gcc printf to UART0 */ + int _write( int fd, + char * str, + int len ) + { + WriteResult_t result = { .error = WRITE_ERROR_NONE, .charsWritten = 0 }; + + prvWriteChars( fd, str, len, &result ); + + return ( ( result.error == WRITE_ERROR_NONE ) && ( result.charsWritten == len ) ) ? result.charsWritten : -1; + } + +#endif /* if defined( __ARMCOMPILER_VERSION ) */ + +static bool prvValidFdHandle( int fd ) +{ + return ( bool ) ( ( fd == STDOUT_FILENO ) || ( fd == STDERR_FILENO ) ); +} + +static void prvWriteChars( int fd, + const unsigned char * str, + unsigned int len, + WriteResult_t * result ) +{ + result->charsWritten = 0; + + if( prvValidFdHandle( fd ) == false ) + { + result->error = WRITE_ERROR_INVALID_ARGS; + return; + } + + if( xSemaphoreTake( xLoggingMutex, portMAX_DELAY ) != pdTRUE ) + { + result->error = WRITE_ERROR_SYNC_FAILED; + return; + } + + bool allCharsWritten = ( bool ) ( Driver_USART0.Send( str, len ) == ARM_DRIVER_OK ); + + while( Driver_USART0.GetTxCount() != len ) + { + } + + ( void ) xSemaphoreGive( xLoggingMutex ); + + if( allCharsWritten == true ) + { + result->charsWritten = len; + result->error = WRITE_ERROR_NONE; + } + else + { + result->error = WRITE_ERROR_SEND_FAIL; + } +} diff --git a/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/CMSIS/common/bsp_serial.h b/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/CMSIS/common/bsp_serial.h new file mode 100644 index 0000000..7a3d9fa --- /dev/null +++ b/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/CMSIS/common/bsp_serial.h @@ -0,0 +1,22 @@ +/* Copyright 2017-2024 Arm Limited and/or its affiliates + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __SERIAL_H__ +#define __SERIAL_H__ + + +#include + +/** + * \brief Initializes default UART device + */ +void bsp_serial_init( void ); + +/** + * \brief Prints a string through the default UART device + */ +void bsp_serial_print( char * str ); + +#endif /* __SERIAL_H__ */ diff --git a/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/CMSIS/corstone315/include/RTE_Components.h b/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/CMSIS/corstone315/include/RTE_Components.h new file mode 100644 index 0000000..ec5ab0e --- /dev/null +++ b/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/CMSIS/corstone315/include/RTE_Components.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2019-2024, Arm Limited. All rights reserved. + * + * 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. + */ + +/*-------- <<< Use Configuration Wizard in Context Menu >>> -------------------- */ + +#ifndef __RTE_COMPONENTS_H +#define __RTE_COMPONENTS_H + +/* USART (Universal synchronous - asynchronous receiver transmitter) [Driver_USART0] */ +/* Configuration settings for Driver_USART0 in component ::Drivers:USART */ +#define RTE_USART0 1 + +#endif /* __RTE_COMPONENTS_H */ diff --git a/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/CMSIS/corstone315/include/device_cfg.h b/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/CMSIS/corstone315/include/device_cfg.h new file mode 100644 index 0000000..be28a66 --- /dev/null +++ b/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/CMSIS/corstone315/include/device_cfg.h @@ -0,0 +1,276 @@ +/* + * Copyright (c) 2020-2024 Arm Limited. All rights reserved. + * + * 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. + */ + +#ifndef __DEVICE_CFG_H__ +#define __DEVICE_CFG_H__ + +#include "RTE_Components.h" + +/** + * \file device_cfg.h + * \brief Configuration file native driver re-targeting + * + * \details This file can be used to add native driver specific macro + * definitions to select which peripherals are available in the build. + * + * This is a default device configuration file with all peripherals enabled. + */ + +/* Secure only peripheral configuration */ + +/* ARM MPS3 IO SCC */ +#ifdef RTE_MPS3_IO + #define MPS3_IO_NS + #define MPS3_IO_DEV MPS3_IO_DEV_NS +#endif + +/* I2C_SBCon */ +#ifdef RTE_I2C0 + #define I2C0_SBCON_S + #define I2C0_SBCON_DEV I2C0_SBCON_DEV_S +#endif +#ifdef RTE_I2C1 + #define I2C1_SBCON_S + #define I2C1_SBCON_DEV I2C1_SBCON_DEV_S +#endif +#ifdef RTE_I2C2 + #define I2C2_SBCON_S + #define I2C2_SBCON_DEV I2C2_SBCON_DEV_S +#endif + +/* I2S */ +#ifdef RTE_I2S + #define MPS3_I2S_S + #define MPS3_I2S_DEV MPS3_I2S_DEV_S +#endif + +/* ARM UART Controller CMSDK */ +#ifdef RTE_USART0 + #define UART0_CMSDK_NS + #define UART0_CMSDK_DEV UART0_CMSDK_DEV_NS +#endif +#ifdef RTE_USART1 + #define UART1_CMSDK_S + #define UART1_CMSDK_DEV UART1_CMSDK_DEV_S +#endif +#ifdef RTE_USART2 + #define UART2_CMSDK_S + #define UART2_CMSDK_DEV UART2_CMSDK_DEV_S +#endif +#ifdef RTE_USART3 + #define UART3_CMSDK_S + #define UART3_CMSDK_DEV UART3_CMSDK_DEV_S +#endif +#ifdef RTE_USART4 + #define UART4_CMSDK_S + #define UART4_CMSDK_DEV UART4_CMSDK_DEV_S +#endif +#ifdef RTE_USART5 + #define UART5_CMSDK_S + #define UART5_CMSDK_DEV UART5_CMSDK_DEV_S +#endif + +#define DEFAULT_UART_BAUDRATE 115200U + +/* To be used as CODE and DATA sram */ +#ifdef RTE_ISRAM0_MPC + #define MPC_ISRAM0_S + #define MPC_ISRAM0_DEV MPC_ISRAM0_DEV_S +#endif + +#ifdef RTE_ISRAM1_MPC + #define MPC_ISRAM1_S + #define MPC_ISRAM1_DEV MPC_ISRAM0_DEV_S +#endif + +#ifdef RTE_SRAM_MPC + #define MPC_SRAM_S + #define MPC_SRAM_DEV MPC_SRAM_DEV_S +#endif + +#ifdef RTE_QSPI_MPC + #define MPC_QSPI_S + #define MPC_QSPI_DEV MPC_QSPI_DEV_S +#endif + +/** System Counter Armv8-M */ +#ifdef RTE_SYSCOUNTER + #define SYSCOUNTER_CNTRL_ARMV8_M_S + #define SYSCOUNTER_CNTRL_ARMV8_M_DEV SYSCOUNTER_CNTRL_ARMV8_M_DEV_S + + #define SYSCOUNTER_READ_ARMV8_M_S + #define SYSCOUNTER_READ_ARMV8_M_DEV SYSCOUNTER_READ_ARMV8_M_DEV_S + +/** + * Arbitrary scaling values for test purposes + */ + #define SYSCOUNTER_ARMV8_M_DEFAULT_SCALE0_INT 1u + #define SYSCOUNTER_ARMV8_M_DEFAULT_SCALE0_FRACT 0u + #define SYSCOUNTER_ARMV8_M_DEFAULT_SCALE1_INT 1u + #define SYSCOUNTER_ARMV8_M_DEFAULT_SCALE1_FRACT 0u +#endif /* ifdef RTE_SYSCOUNTER */ + +/* System timer */ +#ifdef RTE_TIMEOUT + #define SYSTIMER0_ARMV8_M_S + #define SYSTIMER0_ARMV8_M_DEV SYSTIMER0_ARMV8_M_DEV_S + #define SYSTIMER1_ARMV8_M_S + #define SYSTIMER1_ARMV8_M_DEV SYSTIMER1_ARMV8_M_DEV_S + #define SYSTIMER2_ARMV8_M_S + #define SYSTIMER2_ARMV8_M_DEV SYSTIMER2_ARMV8_M_DEV_S + #define SYSTIMER3_ARMV8_M_S + #define SYSTIMER3_ARMV8_M_DEV SYSTIMER3_ARMV8_M_DEV_S + + #define SYSTIMER0_ARMV8M_DEFAULT_FREQ_HZ ( 32000000ul ) + #define SYSTIMER1_ARMV8M_DEFAULT_FREQ_HZ ( 32000000ul ) + #define SYSTIMER2_ARMV8M_DEFAULT_FREQ_HZ ( 32000000ul ) + #define SYSTIMER3_ARMV8M_DEFAULT_FREQ_HZ ( 32000000ul ) +#endif /* ifdef RTE_TIMEOUT */ + +/* CMSDK GPIO driver structures */ +#ifdef RTE_GPIO + #define GPIO0_CMSDK_S + #define GPIO0_CMSDK_DEV GPIO0_CMSDK_DEV_S + #define GPIO1_CMSDK_S + #define GPIO1_CMSDK_DEV GPIO1_CMSDK_DEV_S + #define GPIO2_CMSDK_S + #define GPIO2_CMSDK_DEV GPIO2_CMSDK_DEV_S + #define GPIO3_CMSDK_S + #define GPIO3_CMSDK_DEV GPIO3_CMSDK_DEV_S +#endif + +/* System Watchdogs */ +#ifdef RTE_WATCHDOG + #define SYSWDOG_ARMV8_M_S + #define SYSWDOG_ARMV8_M_DEV SYSWDOG_ARMV8_M_DEV_S +#endif + +/* ARM MPC SIE 315 driver structures */ +#ifdef RTE_VM0_MPC + #define MPC_VM0_S + #define MPC_VM0_DEV MPC_VM0_DEV_S +#endif +#ifdef RTE_VM1_MPC + #define MPC_VM1_S + #define MPC_VM1_DEV MPC_VM1_DEV_S +#endif +#ifdef RTE_SSRAM2_MPC + #define MPC_SSRAM2_S + #define MPC_SSRAM2_DEV MPC_SSRAM2_DEV_S +#endif +#ifdef RTE_SSRAM3_MPC + #define MPC_SSRAM3_S + #define MPC_SSRAM3_DEV MPC_SSRAM3_DEV_S +#endif + +/* ARM PPC driver structures */ +#ifdef RTE_MAIN0_PPC_CORSTONE315 + #define PPC_CORSTONE315_MAIN0_S + #define PPC_CORSTONE315_MAIN0_DEV PPC_CORSTONE315_MAIN0_DEV_S +#endif +#ifdef RTE_MAIN_EXP0_PPC_CORSTONE315 + #define PPC_CORSTONE315_MAIN_EXP0_S + #define PPC_CORSTONE315_MAIN_EXP0_DEV PPC_CORSTONE315_MAIN_EXP0_DEV_S +#endif +#ifdef RTE_MAIN_EXP1_PPC_CORSTONE315 + #define PPC_CORSTONE315_MAIN_EXP1_S + #define PPC_CORSTONE315_MAIN_EXP1_DEV PPC_CORSTONE315_MAIN_EXP1_DEV_S +#endif +#ifdef RTE_MAIN_EXP2_PPC_CORSTONE315 + #define PPC_CORSTONE315_MAIN_EXP2_S + #define PPC_CORSTONE315_MAIN_EXP2_DEV PPC_CORSTONE315_MAIN_EXP2_DEV_S +#endif +#ifdef RTE_MAIN_EXP3_PPC_CORSTONE315 + #define PPC_CORSTONE315_MAIN_EXP3_S + #define PPC_CORSTONE315_MAIN_EXP3_DEV PPC_CORSTONE315_MAIN_EXP3_DEV_S +#endif +#ifdef RTE_PERIPH0_PPC_CORSTONE315 + #define PPC_CORSTONE315_PERIPH0_S + #define PPC_CORSTONE315_PERIPH0_DEV PPC_CORSTONE315_PERIPH0_DEV_S +#endif +#ifdef RTE_PERIPH1_PPC_CORSTONE315 + #define PPC_CORSTONE315_PERIPH1_S + #define PPC_CORSTONE315_PERIPH1_DEV PPC_CORSTONE315_PERIPH1_DEV_S +#endif +#ifdef RTE_PERIPH_EXP0_PPC_CORSTONE315 + #define PPC_CORSTONE315_PERIPH_EXP0_S + #define PPC_CORSTONE315_PERIPH_EXP0_DEV PPC_CORSTONE315_PERIPH_EXP0_DEV_S +#endif +#ifdef RTE_PERIPH_EXP1_PPC_CORSTONE315 + #define PPC_CORSTONE315_PERIPH_EXP1_S + #define PPC_CORSTONE315_PERIPH_EXP1_DEV PPC_CORSTONE315_PERIPH_EXP1_DEV_S +#endif +#ifdef RTE_PERIPH_EXP2_PPC_CORSTONE315 + #define PPC_CORSTONE315_PERIPH_EXP2_S + #define PPC_CORSTONE315_PERIPH_EXP2_DEV PPC_CORSTONE315_PERIPH_EXP2_DEV_S +#endif +#ifdef RTE_PERIPH_EXP3_PPC_CORSTONE315 + #define PPC_CORSTONE315_PERIPH_EXP3_S + #define PPC_CORSTONE315_PERIPH_EXP3_DEV PPC_CORSTONE315_PERIPH_EXP3_DEV_S +#endif + +/* DMA350 */ +#ifdef RTE_DMA350 + #define DMA350_DMA0_S + #define DMA350_DMA0_DEV DMA350_DMA0_DEV_S + + #define DMA350_CH0_S + #define DMA350_DMA0_CH0_S + #define DMA350_CH1_S + #define DMA350_DMA0_CH1_S +#endif + +/* Key Management Unit */ +#ifdef RTE_KMU + #define KMU_S + #define KMU_DEV KMU_DEV_S +#endif + +/* Lifecycle Manager */ +#ifdef RTE_LCM + #define LCM_S + #define LCM_DEV LCM_DEV_S +#endif + +/* Security Alarm Manager */ +#ifdef RTE_SAM + #define SAM_S + #define SAM_DEV SAM_DEV_S +#endif + +/* HDLCD Video */ +#ifdef RTE_HDLCD + #define HDLCD_NS + #define HDLCD_DEV HDLCD_DEV_NS +#endif + +/* ARM SPI PL022 */ +/* Invalid device stubs are not defined */ +#define DEFAULT_SPI_SPEED_HZ 4000000U /* 4MHz */ +#ifdef RTE_SPI0 + #define SPI0_PL022_S + #define SPI0_PL022_DEV SPI0_PL022_DEV_S +#endif +#ifdef RTE_SPI1 + #define SPI1_PL022_S + #define SPI1_PL022_DEV SPI1_PL022_DEV_S +#endif +#ifdef RTE_SPI2 + #define SPI2_PL022_S + #define SPI2_PL022_DEV SPI2_PL022_DEV_S +#endif + +#endif /* __DEVICE_CFG_H__ */ diff --git a/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/CMakeLists.txt b/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/CMakeLists.txt new file mode 100644 index 0000000..9d2a244 --- /dev/null +++ b/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/CMakeLists.txt @@ -0,0 +1,100 @@ +# Copyright 2023-2024 Arm Limited and/or its affiliates +# +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.15) + +project( + pacbti-example + VERSION 0.1 + LANGUAGES C ASM) + +set (CMAKE_BUILD_TYPE Release) + +set(CMAKE_EXECUTABLE_SUFFIX ".axf") + +get_filename_component(FREERTOS_DIR_PATH ${CMAKE_CURRENT_LIST_DIR}/../../../.. REALPATH) +message(DEBUG "FREERTOS_DIR_PATH is ${FREERTOS_DIR_PATH}") + +set(KERNEL_DIR_PATH ${FREERTOS_DIR_PATH}/Source) +set(DEMO_COMMON_PATH ${FREERTOS_DIR_PATH}/Demo/Common) +message(DEBUG "KERNEL_DIR_PATH is ${KERNEL_DIR_PATH}") +message(DEBUG "DEMO_COMMON_PATH is ${DEMO_COMMON_PATH}") + +set(FREERTOS_ARM_V_8_1_M_PACBTI_CONFIG "ARM_V_8_1_M_PACBTI_CONFIG_STANDARD" CACHE STRING "" FORCE) +set(TFM_PACBTI_CONFIGURATION "BRANCH_PROTECTION_STANDARD" CACHE STRING "" FORCE) + +# Select the native compile PORT +if(${CMAKE_C_COMPILER_ID} STREQUAL "ARMClang") + set(FREERTOS_PORT "GCC_ARM_CM85_TFM" CACHE STRING "" FORCE) +elseif(${CMAKE_C_COMPILER_ID} STREQUAL "IAR") + set(FREERTOS_PORT "IAR_ARM_CM85_TFM" CACHE STRING "" FORCE) +else() + message(FATAL_ERROR "Unsupported compiler: ${CMAKE_C_COMPILER_ID}") +endif() + +set(FREERTOS_HEAP "4" CACHE STRING "" FORCE) + +add_subdirectory(CMSIS) + +add_library(freertos_config INTERFACE) + +target_include_directories(freertos_config SYSTEM + INTERFACE + config +) + +target_link_libraries(freertos_config + INTERFACE + tfm-ns-interface +) + +add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../../../../Source freertos_kernel) + +add_subdirectory(trusted_firmware-m) + +add_executable(cortex_m85_pacbti_fvp_example) + +# Trusted Firmware-M must be built before the application, because +# the application depends on the NS interface and the BL2 signing scripts, +# both of which are generated as parts of the Trusted Firmware-M build process. +add_dependencies(cortex_m85_pacbti_fvp_example trusted_firmware-m-build) + +target_sources(cortex_m85_pacbti_fvp_example + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/main.c +) + +target_include_directories(cortex_m85_pacbti_fvp_example + PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR} +) + +if(${CMAKE_C_COMPILER_ID} STREQUAL "IAR") + target_link_options(cortex_m85_pacbti_fvp_example + PRIVATE + --config ${CMAKE_CURRENT_SOURCE_DIR}/iar_arm.icf + ) +elseif(${CMAKE_C_COMPILER_ID} STREQUAL "ARMClang") + target_link_options(cortex_m85_pacbti_fvp_example + PRIVATE + --scatter=${CMAKE_CURRENT_SOURCE_DIR}/armclang.sct + --map + ) +endif() + +target_link_libraries(cortex_m85_pacbti_fvp_example + freertos_kernel + tfm-ns-interface + cmsis_bsp +) + +list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/trusted_firmware-m/integration/cmake) +include(MergeTfmImages) +include(SignTfmImage) + +# The non-secure application image should be padded while being signed +# Hence, passing "TRUE" as the input parameter to the pad option of sign function. +tf_m_sign_image(cortex_m85_pacbti_fvp_example cortex_m85_pacbti_fvp_example_signed 0.0.1 TRUE) + +tf_m_merge_images(cortex_m85_pacbti_fvp_example) diff --git a/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/README.md b/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/README.md new file mode 100644 index 0000000..24e5234 --- /dev/null +++ b/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/README.md @@ -0,0 +1,169 @@ +# PACBTI example on Armv8.1-M Cortex-M85 Fixed Virtual Platform + +# Introduction + +The Armv8.1-M architecture extension introduced **Pointer Authentication** and **Branch Target Identification (PACBTI)** to harden the security against Return-Oriented Programming (ROP) and Jump-Oriented Programming (JOP) security exploit attacks. In return-oriented programming, instructions before a function return are used build gadgets in the executable code region. Similarly, in jump-oriented programming, instructions before function calls or switch-case statements (indirect jumping) are used to build gadgets in the executable code region. Please refer to the [document](https://developer.arm.com/documentation/102433/0200/Stack-smashing-and-execution-permissions) to find out more about stack smashing, return-oriented programming and jump-oriented programming. The [blog](https://community.arm.com/arm-community-blogs/b/architectures-and-processors-blog/posts/armv8-1-m-pointer-authentication-and-branch-target-identification-extension) talks in depth about Armv8.1-M PACBTI. + +This example demonstrates how the new **Pointer Authentication** and **Branch Target Identification (PACBTI)** security feature introduced in Armv8.1-M architecture extension can be used on Cortex-M85 processor to harden the security. It encompasses [TrustedFirmware-M](https://www.trustedfirmware.org/projects/tf-m/) running on the secure side of the Armv8.1-M processor, and the FreeRTOS-Kernel along with the application's tasks running on the non-secure side of the Armv8.1-M processor. The example is based on Corstone-315 Ecosystem Fixed Virtual Platform (Arm Cortex-M85 CPU and Ethos-U65 NPU). Follow the [link](https://www.arm.com/products/development-tools/simulation/fixed-virtual-platforms) to learn more about Arm fixed virtual platforms. + +Please refer to the Security related enhancements section in the [Introduction to Armv8.1-M architecture white paper document](https://www.arm.com/resources/white-paper/intro-armv8-1-m-architecture) for more information. + +# Prerequisites + +## Downloading and installing Corstone-315 Ecosystem Fixed Virtual Platform + +Follow the instructions on the [page](https://developer.arm.com/downloads/-/arm-ecosystem-fvps) to download Corstone-315 Ecosystem FVP based on your operating system. Ensure that requirements mentioned in the [page](https://developer.arm.com/documentation/100966/1126/Getting-Started-with-Fixed-Virtual-Platforms/Requirements-for-FVPs?lang=en) are met. + +Then, follow these instructions to install the Corstone-315 Ecosystem FVP +```bash +cd FVP_Corstone_SSE_315_11.xx_yy_64 + +./FVP_Corstone_SSE-315.sh + +Do you want to proceed with the installation? [default: yes] +Yes. + +Do you agree to the above terms and conditions? +Yes. + +Where would you like to install to? [default: /home//FVP_Corstone_SSE-315] +Press Enter for the default installation location or specify the absolute path for the required location. + +Installation completed successfully +``` + +Add the path to `FVP_Corstone_SSE-315` executable to the environment variable `PATH` (if the default installation location was used, the executable path would be something like `/home//FVP_Corstone_SSE-315/models/64__GCC-9.3/`). + +Execute the following command to ensure that the Fixed Virtual Platform for Corstone-315 was installed successfully +```bash +FVP_Corstone_SSE-315 --version + +Fast Models [11.xx.yy (month day year)] +Copyright 2000-2024 ARM Limited. +All Rights Reserved. +``` + +## Build tools + +* [CMake](https://cmake.org/download/) + * The PACBTI example uses `CMake` as the build system. +* [Arm Compiler for Embedded Toolchain](https://developer.arm.com/Tools%20and%20Software/Arm%20Compiler%20for%20Embedded) + * To use Arm Compiler For Embedded Toolchain, login is required for the download, and you will need a license in order to +run the toolchain once installed. + +# Supported toolchains + +The example is supported and tested on the following toolchains: + + * Arm Compiler for Embedded v6.21 (armclang). + * IAR toolchain for Arm v9.60.2 (IARARM). + +# Configuration + +The FreeRTOS-Kernel provides a CMake variable `FREERTOS_ARM_V_8_1_M_PACBTI_CONFIG` to configure the Armv8.1-M PACBTI security feature. The following values are supported: + +`ARM_V_8_1_M_PACBTI_CONFIG_STANDARD`: PACBTI Security Feature Standard Configuration (PAC enabled without leaf functions support, and BTI enabled ). + +`ARM_V_8_1_M_PACBTI_CONFIG_PACRET_LEAF_BTI`: PACBTI Security Feature Standard + Leaf Configuration (PAC with leaf functions support, and BTI enabled). + +`ARM_V_8_1_M_PACBTI_CONFIG_PACRET`: PACBTI Security Feature with only PAC enabled. + +`ARM_V_8_1_M_PACBTI_CONFIG_PACRET_LEAF`: PACBTI Security Feature with PAC and PAC for leaf functions support enabled. + +`ARM_V_8_1_M_PACBTI_CONFIG_BTI`: PACBTI Security Feature with only BTI enabled. + +`ARM_V_8_1_M_PACBTI_CONFIG_NONE`: PACBTI Security Feature disabled. + +It is recommend to set the intended value of `FREERTOS_ARM_V_8_1_M_PACBTI_CONFIG` in the example's top level `CMakeLists.txt`. In this example, `FREERTOS_ARM_V_8_1_M_PACBTI_CONFIG` is set to `ARM_V_8_1_M_PACBTI_CONFIG_STANDARD`, to enable both PAC and BTI, to harden the security against **ROP (Return Oriented Programming)** and **JOP (Jump Oriented Programming)** security exploits. + +All the CMake targets defined to construct the example shall have the respective compiler options and definitions based on the configured value of the `FREERTOS_ARM_V_8_1_M_PACBTI_CONFIG` variable. This is handled as part of `CMSIS/CMakeLists.txt` where the respective compiler options and definitions are added for the `arm-corstone-platform-bsp` target which is later linked to the example's target (i.e `cortex_m85_pacbti_fvp_example`). These options and defnitions are added for the `arm-corstone-platform-bsp` target, rather than being directly added for the example's target, to avoid duplicating the compiler options and definitions handling code for multiple targets. + +# Implementation + +The example consists of two main tasks (**prvPacTask** and **prvBtiTask**). The **prvPacTask** and **prvBtiTask** tasks' job is to trigger the **UsageFault** exception by violating PAC and BTI rules. + +## Pointer Authentication Test + +The **prvPacTask** FreeRTOS task would call one of the application's functions (`prvCorruptLR`) which will change the stacked **Link Register (LR)** value before validating the Pointer Authentication Code at the end of the called function, this will lead to failure of **aut (authentication instruction)** resulting in **UsageFault** exception being triggered. The exception handler is designed in a way to recover gracefully by checking if the exception was triggered intentionally. After this, the task is killed. + +## Branch Target Identification Test + +The **prvBtiTask** FreeRTOS task will attempt to jump to the middle of one of the application's functions (`prvHandleUsageFault`) where this will result in **UsageFault** exception being triggered as the address jumped to is not a **BTI clearing** instruction. The exception handler is designed in a way to recover gracefully by checking if the exception was triggered intentionally. After this, the task is killed. + +## Building and running examples + +First, run the following command to clone FreeRTOS repository: + +```bash +git clone https://github.com/FreeRTOS/FreeRTOS.git --recurse-submodules +``` + +Run the following commands to build the PACBTI example: + +```bash +cd FreeRTOS/FreeRTOS/Demo/ThirdParty/Partner-Supported-Demos/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR +rm -rf build && cmake -B build --toolchain=_toolchain.cmake . && cmake --build build +``` + +### Running the example + +Execute the following script to run the PACBTI example: +```bash +./run.sh +``` + +### Expected output + +```bash +$ ./run.sh +telnetterminal0: Listening for serial connection on port 5000 +telnetterminal2: Listening for serial connection on port 5001 +telnetterminal1: Listening for serial connection on port 5002 +telnetterminal5: Listening for serial connection on port 5003 +WARNING: ISAR5.PACBTI parameter is deprecated, use parameter CFGPACBTI +WARNING: ISAR5.PACBTI parameter is deprecated, use parameter CFGPACBTI + + Ethos-U rev 136b7d75 --- Apr 12 2023 13:44:01 + (C) COPYRIGHT 2019-2023 Arm Limited + ALL RIGHTS RESERVED + + +Info: Corstone_SSE_315_Main: Loading MaliC55Model + +Info: Corstone_SSE_315_Main: MaliC55Model build info: +*** +Version: C55-F5M9R1 +Git id: unknown +Host OS: Linux-3.10.0-693.21.1.el7.x86_64 x86_64 +Compiler: GNU 9.3.0 /arm/eda/tools/dsystool/gcc/9.3.0/1/linux_3.10-redhat_10.7-x86_64/gcc-4.8.5-SYSTEM/bin/c++ +Build tool: /usr/bin/gmake (+ CMake 3.14.3) +Build type: Release +BUILD_SHARED_LIBS: OFF +FAST_CPU_MODE: ON +Build timestamp: Sep 15 2023 12:39:08 +RTL Version: r0p0-00eac0 +Copyright (C) 2023 Arm Limited or its affiliates. All rights reserved. +*** +[INF] Starting bootloader +[INF] PSA Crypto init done, sig_type: EC-P256, using builtin keys +[INF] Image index: 1, Swap type: none +[INF] Image index: 0, Swap type: none +[INF] Bootloader chainload address offset: 0x0 +[INF] Image version: v2.1.0 +[INF] Jumping to the first image slot +Booting TF-M v2.1.0+deda2ede3 +[Sec Thread] Secure image initializing! +PSA Framework version is: 257 + +Attempting to corrupt Link Register (LR). + +Usage Fault Exception triggered due to incorrect computed PAC, was recovered gracefully. + +Attempting to perform an indirect jump to middle of prvHandleUsageFault function. + +Usage Fault Exception triggered due to middle of function jump, was recovered gracefully. + +PAC and BTI tasks have successfully executed, deleting tasks. +^C +Stopping simulation... +``` diff --git a/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/armclang.sct b/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/armclang.sct new file mode 100644 index 0000000..b013872 --- /dev/null +++ b/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/armclang.sct @@ -0,0 +1,47 @@ +#! armclang --target=arm-arm-none-eabi -march=armv8.1-m.main+mve.fp+fp.dp -E -x c +/* + * Copyright (c) 2021-2024 Arm Limited. All rights reserved. + * + * 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. + */ + +#define FLASH_NS_PARTITION_SIZE 0x340000 +#define FLASH_S_PARTITION_SIZE 0x40000 +#define ROM_START 0x28000000 +#define BL2_HEADER_SIZE 0x400 +#define BL2_TRAILER_SIZE 0xC00 +#define ISRAM0_BASE_ADDRESS 0x21000000 +#define ISRAM1_OFFSET 0x00200000 +#define ISRAM1_SIZE 0x00200000 +#define STACK_SIZE 0x00001000 +#define HEAP_SIZE 0x000C0000 + + +LOAD_REGION_0 (ROM_START + ((((0) + (FLASH_S_PARTITION_SIZE)) + BL2_HEADER_SIZE))) +{ + flash (ROM_START + ((((0) + (FLASH_S_PARTITION_SIZE)) + BL2_HEADER_SIZE))) (((FLASH_NS_PARTITION_SIZE) - BL2_HEADER_SIZE - BL2_TRAILER_SIZE)) { + *.o (RESET +First) + * (+RO) + } + + data.bin (ISRAM0_BASE_ADDRESS + ((ISRAM1_OFFSET))) (ISRAM1_SIZE) { + * (+ZI +RW) + } + + + ARM_LIB_STACK +0 ALIGN 32 EMPTY (STACK_SIZE) { + } + + ARM_LIB_HEAP +0 ALIGN 8 EMPTY (HEAP_SIZE) { + } +} diff --git a/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/armclang_toolchain.cmake b/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/armclang_toolchain.cmake new file mode 100644 index 0000000..2851345 --- /dev/null +++ b/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/armclang_toolchain.cmake @@ -0,0 +1,15 @@ +# Copyright 2023-2024 Arm Limited and/or its affiliates +# +# SPDX-License-Identifier: MIT + +set(CMAKE_SYSTEM_NAME Generic) +set(CMAKE_SYSTEM_PROCESSOR cortex-m85) + +set(CMAKE_C_COMPILER armclang) +set(CMAKE_CXX_COMPILER armclang) +set(CMAKE_ASM_COMPILER armclang) + +set(CMAKE_C_STANDARD 11) + +set(CMAKE_C_FLAGS "-march=armv8.1-m.main+pacbti+fp.dp+mve.fp -mfloat-abi=hard -mthumb -fdata-sections") +set(CMAKE_ASM_FLAGS "-march=armv8.1-m.main+pacbti+fp.dp+mve.fp+ -mfloat-abi=hard -mthumb -masm=auto --target=arm-arm-none-eabi") diff --git a/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/config/FreeRTOSConfig.h b/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/config/FreeRTOSConfig.h new file mode 100644 index 0000000..42a4b63 --- /dev/null +++ b/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/config/FreeRTOSConfig.h @@ -0,0 +1,190 @@ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/****************************************************************************** +* See http://www.freertos.org/a00110.html for an explanation of the +* definitions contained in this file. +******************************************************************************/ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- +* Application specific definitions. +* +* These definitions should be adjusted for your particular hardware and +* application requirements. +* +* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE +* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. +* https://www.FreeRTOS.org/a00110.html +*----------------------------------------------------------*/ + +/* Ensure definitions are only used by the compiler, and not by the assembler. */ +#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) + extern uint32_t SystemCoreClock; + void vAssertCalled( const char * pcFile, unsigned long ulLine ); +#endif + +/* See https://freertos.org/a00110.html#configPROTECTED_KERNEL_OBJECT_POOL_SIZE for details. */ +#define configPROTECTED_KERNEL_OBJECT_POOL_SIZE 150 +/* See https://freertos.org/a00110.html#configSYSTEM_CALL_STACK_SIZE for details. */ +#define configSYSTEM_CALL_STACK_SIZE 128 + +/* Cortex M33 port configuration. */ +#define configENABLE_MPU 0 +#define configENABLE_FPU 1 +#define configENABLE_TRUSTZONE 0 +#define configENABLE_MVE 0 + +/* This part has 16 MPU regions. */ +#define configTOTAL_MPU_REGIONS 8 + +/* Run FreeRTOS on the secure side and never jump to the non-secure side. */ +#define configRUN_FREERTOS_SECURE_ONLY 0 + +/* Constants related to the behaviour or the scheduler. */ +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#define configUSE_PREEMPTION 1 +#define configUSE_TIME_SLICING 1 +#define configMAX_PRIORITIES ( 10 ) +#define configIDLE_SHOULD_YIELD 1 +#define configTICK_TYPE_WIDTH_IN_BITS TICK_TYPE_WIDTH_32_BITS + +/* Constants that describe the hardware and memory usage. */ +#define configCPU_CLOCK_HZ SystemCoreClock +#define configMINIMAL_STACK_SIZE ( ( uint16_t ) 512 ) +#define configMAX_TASK_NAME_LEN ( 12 ) +#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 512 * 1024 ) ) + +/* Constants that build features in or out. */ +#define configUSE_MUTEXES 1 +#define configUSE_TICKLESS_IDLE 0 +#define configUSE_APPLICATION_TASK_TAG 0 +#define configUSE_NEWLIB_REENTRANT 0 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_QUEUE_SETS 0 +#define configUSE_TASK_NOTIFICATIONS 1 +#define configUSE_TRACE_FACILITY 1 +#define configNUM_TX_DESCRIPTORS 15 +#define configSTREAM_BUFFER_TRIGGER_LEVEL_TEST_MARGIN 2 + +/* Constants that define which hook (callback) functions should be used. */ +#define configUSE_IDLE_HOOK 1 +#define configUSE_TICK_HOOK 1 +#define configUSE_MALLOC_FAILED_HOOK 1 + +/* Constants provided for debugging and optimisation assistance. */ +#define configCHECK_FOR_STACK_OVERFLOW 2 +#define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled( __FILE__, __LINE__ ); +#define configQUEUE_REGISTRY_SIZE 20 + +/* Software timer definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) +#define configTIMER_QUEUE_LENGTH 20 +#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 ) + +/* Set the following definitions to 1 to include the API function, or zero + * to exclude the API function. NOTE: Setting an INCLUDE_ parameter to 0 is + * only necessary if the linker does not automatically remove functions that are + * not referenced anyway. */ +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 1 +#define INCLUDE_uxTaskGetStackHighWaterMark2 1 +#define INCLUDE_xTaskGetIdleTaskHandle 1 +#define INCLUDE_eTaskGetState 1 +#define INCLUDE_xTaskResumeFromISR 1 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_xTaskGetSchedulerState 1 +#define INCLUDE_xSemaphoreGetMutexHolder 1 +#define INCLUDE_xTimerPendFunctionCall 1 +#define INCLUDE_xTimerGetTimerDaemonTaskHandle 1 +#define INCLUDE_xTaskGetHandle 1 +#define INCLUDE_xTaskAbortDelay 1 + +/* This demo makes use of one or more example stats formatting functions. These + * format the raw data provided by the uxTaskGetSystemState() function in to + * human readable ASCII form. See the notes in the implementation of vTaskList() + * within FreeRTOS/Source/tasks.c for limitations. */ +#define configUSE_STATS_FORMATTING_FUNCTIONS 1 + +/* Dimensions a buffer that can be used by the FreeRTOS+CLI command interpreter. + * See the FreeRTOS+CLI documentation for more information: + * https://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_CLI/ */ +#define configCOMMAND_INT_MAX_OUTPUT_SIZE 2048 + +/* Interrupt priority configuration follows...................... */ + +/* Use the system definition, if there is one. */ +#ifdef __NVIC_PRIO_BITS + #define configPRIO_BITS __NVIC_PRIO_BITS +#else + #define configPRIO_BITS 3 /* 8 priority levels. */ +#endif + +/* The lowest interrupt priority that can be used in a call to a "set priority" + * function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0x07 + +/* The highest interrupt priority that can be used by any interrupt service + * routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT + * CALL INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A + * HIGHER PRIORITY THAN THIS! (higher priorities are lower numeric values). */ +#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5 + +/* Interrupt priorities used by the kernel port layer itself. These are generic +* to all Cortex-M ports, and do not rely on any particular library functions. */ +#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << ( 8 - configPRIO_BITS ) ) + +/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! + * See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ +#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << ( 8 - configPRIO_BITS ) ) + +/* Constants related to the generation of run time stats. */ +#define configGENERATE_RUN_TIME_STATS 0 +#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() +#define portGET_RUN_TIME_COUNTER_VALUE() 0 + +/* Adjust configTICK_RATE_HZ and pdMS_TO_TICKS to simulate a tick per ms on a fast model */ +#define configTICK_RATE_HZ ( ( TickType_t ) 100 ) +#define pdMS_TO_TICKS( xTimeInMs ) ( ( TickType_t ) xTimeInMs ) + + +/* Enable dynamic allocation. */ +#define configSUPPORT_STATIC_ALLOCATION 0 +#define configSUPPORT_DYNAMIC_ALLOCATION 1 + +#endif /* FREERTOS_CONFIG_H */ diff --git a/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/config/project_config.h b/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/config/project_config.h new file mode 100644 index 0000000..7f45431 --- /dev/null +++ b/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/config/project_config.h @@ -0,0 +1,86 @@ +/* Copyright 2023-2024 Arm Limited and/or its affiliates + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#define PLATFORM_SERVICE_INPUT_BUFFER_SIZE 64 + +#define PLATFORM_SERVICE_OUTPUT_BUFFER_SIZE 64 + +#define PLATFORM_SP_STACK_SIZE 0x500 + +#define PLATFORM_NV_COUNTER_MODULE_DISABLED 0 + +#define CRYPTO_ENGINE_BUF_SIZE 0x8000 + +#define CRYPTO_CONC_OPER_NUM 8 + +#define CRYPTO_RNG_MODULE_ENABLED 1 + +#define CRYPTO_KEY_MODULE_ENABLED 1 + +#define CRYPTO_AEAD_MODULE_ENABLED 1 + +#define CRYPTO_MAC_MODULE_ENABLED 1 + +#define CRYPTO_HASH_MODULE_ENABLED 1 + +#define CRYPTO_CIPHER_MODULE_ENABLED 1 + +#define CRYPTO_ASYM_SIGN_MODULE_ENABLED 1 + +#define CRYPTO_ASYM_ENCRYPT_MODULE_ENABLED 1 + +#define CRYPTO_KEY_DERIVATION_MODULE_ENABLED 1 + +#define CRYPTO_IOVEC_BUFFER_SIZE 5120 + +#define CRYPTO_NV_SEED 1 + +#define CRYPTO_SINGLE_PART_FUNCS_DISABLED 0 + +#define CRYPTO_STACK_SIZE 0x1B00 + +#define TFM_FWU_BUF_SIZE PSA_FWU_MAX_WRITE_SIZE + +#define FWU_STACK_SIZE 0x600 + +#define ATTEST_INCLUDE_OPTIONAL_CLAIMS 1 + +#define ATTEST_INCLUDE_COSE_KEY_ID 0 + +#define ATTEST_STACK_SIZE 0x700 + +#define ATTEST_TOKEN_PROFILE_PSA_IOT_1 1 + +#define ITS_CREATE_FLASH_LAYOUT 1 + +#define ITS_RAM_FS 0 + +#define ITS_VALIDATE_METADATA_FROM_FLASH 1 + +#define ITS_MAX_ASSET_SIZE 1300 + +#define ITS_BUF_SIZE ITS_MAX_ASSET_SIZE + +#define ITS_NUM_ASSETS 10 + +#define ITS_STACK_SIZE 0x720 + +#define PS_CREATE_FLASH_LAYOUT 1 + +#define PS_RAM_FS 0 + +#define PS_ROLLBACK_PROTECTION 1 + +#define PS_VALIDATE_METADATA_FROM_FLASH 1 + +#define PS_MAX_ASSET_SIZE 2048 + +#define PS_NUM_ASSETS 10 + +#define PS_STACK_SIZE 0x700 + +#define CONFIG_TFM_CONN_HANDLE_MAX_NUM 8 + +#define CONFIG_TFM_DOORBELL_API 0 diff --git a/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/iar_arm.icf b/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/iar_arm.icf new file mode 100644 index 0000000..a2007af --- /dev/null +++ b/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/iar_arm.icf @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2009-2024 Arm Limited. All rights reserved. + * + * 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 + * + * 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. + */ + +define region ROM_region = mem:[from 0x28040400 size 0x0033F000]; +define region RAM_region = mem:[from 0x21200000 size 0x00200000]; + +define block CSTACK with alignment = 8, size = 0x00001000 { }; +define block HEAP with alignment = 8, size = 0x00080000 { }; + +do not initialize { section .noinit }; + +place at start of ROM_region { readonly section .intvec }; +place in ROM_region { readonly }; + +initialize by copy { readwrite }; + +place in RAM_region { readwrite, block CSTACK, block HEAP }; diff --git a/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/iar_toolchain.cmake b/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/iar_toolchain.cmake new file mode 100644 index 0000000..95be588 --- /dev/null +++ b/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/iar_toolchain.cmake @@ -0,0 +1,42 @@ +# Copyright 2023-2024 Arm Limited and/or its affiliates +# +# SPDX-License-Identifier: MIT + +set(CMAKE_SYSTEM_NAME Generic) +set(CMAKE_SYSTEM_PROCESSOR cortex-m85) + +set(CMAKE_ASM_COMPILER iasmarm) +set(CMAKE_C_COMPILER iccarm) +set(CMAKE_CXX_COMPILER iccarm) + +set(CMAKE_C_STANDARD 11) + +set(CMAKE_C_FLAGS_INIT "--cpu ${CMAKE_SYSTEM_PROCESSOR}") +set(CMAKE_ASM_FLAGS_INIT "--cpu ${CMAKE_SYSTEM_PROCESSOR}") +set(CMAKE_C_LINK_FLAGS "--cpu ${CMAKE_SYSTEM_PROCESSOR}") +set(CMAKE_ASM_LINK_FLAGS "--cpu ${CMAKE_SYSTEM_PROCESSOR}") + +set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS_INIT}) +set(CMAKE_ASM_FLAGS ${CMAKE_ASM_FLAGS_INIT}) + +add_compile_options( + $<$:-e> + $<$:--dlib_config=full> + $<$:--silent> + $<$:-DNO_TYPEOF> + $<$:-D_NO_DEFINITIONS_IN_HEADER_FILES> + $<$:--diag_suppress=Pe546,Pe940,Pa082,Pa084> + $<$:--no_path_in_file_macros> + $<$:--fpu=FPv5_D16> +) + +add_link_options( + --silent + --semihosting + --redirect __write=__write_buffered + --diag_suppress=lp005,Lp023 +) + +add_compile_definitions( + __ARM_ARCH_8_1M_MAIN__=1 +) diff --git a/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/main.c b/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/main.c new file mode 100644 index 0000000..3dcae60 --- /dev/null +++ b/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/main.c @@ -0,0 +1,325 @@ +/* Copyright 2023-2024 Arm Limited and/or its affiliates + * + * SPDX-License-Identifier: MIT + */ + +#include +#include + +/* Kernel includes. */ +#include "FreeRTOS.h" +#include "task.h" + +#include "bsp_serial.h" + +#include "tfm_ns_interface.h" + +#define UFSR_REG ( *( ( volatile uint16_t * ) 0xe000ed2a ) ) +#define UFSR_INVSTATE_BIT_POS ( 1U ) + +extern uint32_t tfm_ns_interface_init( void ); + +static volatile uint8_t ucPacBtiFaultTracker = 0; +TaskHandle_t xPacTaskHandle = NULL; +TaskHandle_t xBtiTaskHandle = NULL; +void ( *pxCheckExceptionFunctionPtr )( void ) = NULL; + +portDONT_DISCARD static void prvHandleUsageFault( uint32_t * pulFaultStackAddress ); + +void vAssertCalled( const char * pcFile, + unsigned long ulLine ) +{ + printf( "ASSERT failed! file %s:%lu, \r\n", pcFile, ulLine ); + + taskENTER_CRITICAL(); + { + volatile unsigned long looping = 0; + + /* Use the debugger to set ul to a non-zero value in order to step out + * of this function to determine why it was called. */ + while( looping == 0LU ) + { + portNOP(); + } + } + taskEXIT_CRITICAL(); +} + +portDONT_DISCARD __attribute__ ((noinline)) static void prvCorruptLR( void ) +{ + __asm volatile + ( + " pac r12, lr, sp \n" + " stmdb sp!, {r12, lr} \n" + " mov r1, #0 \n" + " str r1, [sp, #4] \n" + " ldmia.w sp!, {r12, lr} \n" + " aut r12, lr, sp \n" + " bx lr \n" + ); +} + +static void prvPacTaskCheckException( void ) +{ + configASSERT( ucPacBtiFaultTracker == 0 ); + printf("\r\nUsage Fault Exception triggered due to incorrect computed PAC, was recovered gracefully.\r\n"); + vTaskDelete( xPacTaskHandle ); +} + +static void prvBtiTaskCheckException( void ) +{ + configASSERT( ucPacBtiFaultTracker == 0 ); + printf("\r\nUsage Fault Exception triggered due to middle of function jump, was recovered gracefully.\r\n"); + printf("\r\nPAC and BTI tasks have successfully executed, deleting tasks.\r\n"); + vTaskDelete( xBtiTaskHandle ); +} + +static void prvPacTask( void * arg ) +{ + /* Prevent the compiler warning about the unused parameter. */ + ( void ) arg; + + printf( "PSA Framework version is: %d\n", psa_framework_version() ); + #if( configENABLE_PAC == 1 ) + /* Assign the address of prvPacTaskCheckException function to the pxCheckExceptionFunctionPtr function pointer. + */ + pxCheckExceptionFunctionPtr = prvPacTaskCheckException; + + /* This task performs the following sequence: + * + * 1. Setting ucPacBtiFaultTracker variable to 1 informs the Usage Fault + * Exception Handler that this is an expected fault. Where in this case, the handler + * recovers from the expected fault gracefully by jumping to the next statement + * to be executed after the faulty piece of code. + * + * 2. Call the prvCorruptLR() function which corrupts the Link Register (LR) + * resulting in a Usage Fault Exception being triggered as the `aut` authentication instruction + * will fail to validate the computed pointer authentication code against the one generated + * at the entry of the function as the Link Register is corrupted. + * + * 3. As part of the Usage Fault Exception handler, the program counter is changed to jump to the + * prvPacTaskCheckException function which in turns ensure that the LR corruption did generate a Usage + * Fault exception by checking if the fault handler did clear the ucPacBtiFaultTracker variable, and + * then kills the task. + */ + ucPacBtiFaultTracker = 1; + printf("\r\nAttempting to corrupt Link Register (LR).\r\n"); + prvCorruptLR(); + #else + printf("\r\nPAC is not enabled. Hence, deleteing the prvPacTask.\r\n"); + vTaskDelete( xPacTaskHandle ); + #endif /* configENABLE_PAC */ +} + +static void prvBtiTask( void * arg ) +{ + /* Prevent the compiler warning about the unused parameter. */ + ( void ) arg; + + #if( configENABLE_BTI == 1 ) + /* Assign the address of prvBtiTaskCheckException function to the pxCheckExceptionFunctionPtr function + * pointer. + */ + pxCheckExceptionFunctionPtr = prvBtiTaskCheckException; + + /* This task performs the following sequence: + * + * 1. Setting ucPacBtiFaultTracker variable to 1 informs the Usage Fault + * Exception Handler that this is an expected fault. Where in this case, the handler + * recovers from the expected fault gracefully by jumping to the next statement + * to be executed after the faulty piece of code. + * + * 2. Load the starting address of `prvHandleUsageFault` function, increment the address by `4` + * to jump to the middle of the function resulting in a Usage Fault Exception being triggered + * as the address jumped to is not a BTI clearing instruction `bti`. + * + * 3. As part of the Usage Fault Exception handler, the program counter is changed to jump to the + * prvBtiTaskCheckException function which in turns ensure that the jump to the middle of the function + * did generate a Usage Fault exception by checking if the fault handler did clear the + * ucPacBtiFaultTracker variable, and then kills the task. + */ + + ucPacBtiFaultTracker = 1; + printf("\r\nAttempting to perform an indirect jump to middle of prvHandleUsageFault function.\r\n"); + __asm volatile + ( + " ldr r1, =prvHandleUsageFault \n" + " add r1, #4 \n" + " bx r1 \n" + ); + #else + printf("\r\nBTI is not enabled. Hence, deleteing the prvBtiTask.\r\n"); + vTaskDelete( xBtiTaskHandle ); + #endif /* configENABLE_BTI */ +} + +int main() +{ + bsp_serial_init(); + + uint32_t ret = tfm_ns_interface_init(); + + if( ret != 0 ) + { + printf( "tfm_ns_interface_init() failed: %u\r\n", ret ); + return EXIT_FAILURE; + } + + if(xTaskCreate( prvPacTask, + NULL, + configMINIMAL_STACK_SIZE, + NULL, + ( tskIDLE_PRIORITY + 2 ), + &xPacTaskHandle ) == pdFAIL ) + { + return EXIT_FAILURE; + } + + if(xTaskCreate( prvBtiTask, + NULL, + configMINIMAL_STACK_SIZE, + NULL, + ( tskIDLE_PRIORITY + 1 ), + &xBtiTaskHandle ) == pdFAIL ) + { + return EXIT_FAILURE; + } + + vTaskStartScheduler(); + + /* If all is well, the scheduler will now be running, and the following + * line will never be reached. If the following line does execute, then + * there was insufficient FreeRTOS heap memory available for the idle and/or + * timer tasks to be created. See the memory management section on the + * FreeRTOS web site for more details. NOTE: This demo uses static allocation + * for the idle and timer tasks so this line should never execute. */ + for( ; ; ) + { + } +} + +/** + * Dummy implementation of the callback function vApplicationStackOverflowHook(). + */ +#if ( configCHECK_FOR_STACK_OVERFLOW > 0 ) + void vApplicationStackOverflowHook( TaskHandle_t xTask, + char * pcTaskName ) + { + ( void ) xTask; + ( void ) pcTaskName; + + /* Assert when stack overflow is enabled but no application defined function exists */ + configASSERT( 0 ); + } +#endif + +/*---------------------------------------------------------------------------*/ +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + +/* + * vApplicationGetIdleTaskMemory gets called when configSUPPORT_STATIC_ALLOCATION + * equals to 1 and is required for static memory allocation support. + */ + void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer, + StackType_t ** ppxIdleTaskStackBuffer, + uint32_t * pulIdleTaskStackSize ) + { + /* Idle task control block and stack */ + static StaticTask_t Idle_TCB; + static StackType_t Idle_Stack[ configMINIMAL_STACK_SIZE ]; + + *ppxIdleTaskTCBBuffer = &Idle_TCB; + *ppxIdleTaskStackBuffer = &Idle_Stack[ 0 ]; + *pulIdleTaskStackSize = ( uint32_t ) configMINIMAL_STACK_SIZE; + } + +/* + * vApplicationGetTimerTaskMemory gets called when configSUPPORT_STATIC_ALLOCATION + * equals to 1 and is required for static memory allocation support. + */ + void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer, + StackType_t ** ppxTimerTaskStackBuffer, + uint32_t * pulTimerTaskStackSize ) + { + /* Timer task control block and stack */ + static StaticTask_t Timer_TCB; + static StackType_t Timer_Stack[ configTIMER_TASK_STACK_DEPTH ]; + + *ppxTimerTaskTCBBuffer = &Timer_TCB; + *ppxTimerTaskStackBuffer = &Timer_Stack[ 0 ]; + *pulTimerTaskStackSize = ( uint32_t ) configTIMER_TASK_STACK_DEPTH; + } +#endif /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ + +void vApplicationTickHook( void ) +{ + /* Provide a stub for this function. */ +} + +void vApplicationIdleHook( void ) +{ + const TickType_t xKitHitCheckPeriod = pdMS_TO_TICKS( 1000UL ); + static TickType_t xTimeNow, xLastTimeCheck = 0; + + if( ( xTimeNow - xLastTimeCheck ) > xKitHitCheckPeriod ) + { + xLastTimeCheck = xTimeNow; + } + + /* Exit. Just a stub. */ +} + +void vApplicationMallocFailedHook( void ) +{ + /* Provide a stub for this function. */ +} + +portDONT_DISCARD static void prvHandleUsageFault( uint32_t * pulFaultStackAddress ) +{ + volatile uint16_t ulUfsrReg; + + /* Read the UFSR (Usage Fault Status Register) register value. */ + ulUfsrReg = UFSR_REG; + + /* Is this Hard Fault triggered due to an invalid state? */ + if( ulUfsrReg >> UFSR_INVSTATE_BIT_POS == 1) + { + /* Is this an expected fault? */ + if( ucPacBtiFaultTracker == 1 ) + { + /* Mark the fault as handled. */ + ucPacBtiFaultTracker = 0; + + /* Save the new program counter (recovery address) on the stack. */ + pulFaultStackAddress[ 6 ] = ( uint32_t ) pxCheckExceptionFunctionPtr; + } + else + { + /* This is an unexpected fault - loop forever. */ + for( ; ; ) + { + } + } + } + else + { + /* This fault is not due to an invalid state - loop forever. */ + for( ; ; ) + { + } + } +} + +void UsageFault_Handler( void ) __attribute__((naked)); +void UsageFault_Handler( void ) +{ + __asm volatile + ( + " tst lr, #4 \n" + " ite eq \n" + " mrseq r0, msp \n" + " mrsne r0, psp \n" + " ldr r2, =prvHandleUsageFault \n" + " bx r2 \n" + ); +} diff --git a/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/run.sh b/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/run.sh new file mode 100755 index 0000000..de803e0 --- /dev/null +++ b/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/run.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +# Copyright 2024 Arm Limited and/or its affiliates +# +# SPDX-License-Identifier: MIT + +FVP_Corstone_SSE-315 -a ./build/cortex_m85_pacbti_fvp_example_merged.elf -C mps4_board.visualisation.disable-visualisation=1 -C core_clk.mul=200000000 -C mps4_board.hostbridge.userNetworking=1 -C mps4_board.telnetterminal0.start_telnet=0 -C mps4_board.uart0.out_file="-" -C mps4_board.uart0.unbuffered_output=1 -C vis_hdlcd.disable_visualisation=1 --stat -C mps4_board.subsystem.cpu0.CFGPACBTI=1 -C mps4_board.subsystem.cpu0.ID_ISAR5.PACBTI=1 -C mps4_board.subsystem.cpu0.semihosting-enable=1 diff --git a/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/trusted_firmware-m/CMakeLists.txt b/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/trusted_firmware-m/CMakeLists.txt new file mode 100644 index 0000000..9deacf2 --- /dev/null +++ b/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/trusted_firmware-m/CMakeLists.txt @@ -0,0 +1,11 @@ +# Copyright 2023-2024, Arm Limited and/or its affiliates +# +# SPDX-License-Identifier: MIT + +set(trusted_firmware-m_SOURCE_DIR + ${CMAKE_CURRENT_LIST_DIR}/../../Demos_Dependencies/trusted_firmware-m/ + CACHE INTERNAL + "Path to Trusted Firmware-M source code" +) + +add_subdirectory(integration) diff --git a/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/trusted_firmware-m/integration/CMakeLists.txt b/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/trusted_firmware-m/integration/CMakeLists.txt new file mode 100644 index 0000000..e881d3b --- /dev/null +++ b/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/trusted_firmware-m/integration/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright 2021-2024, Arm Limited and/or its affiliates +# +# SPDX-License-Identifier: MIT + +project(tfm-ns-interface) + +list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/cmake) + +include(BuildTfm) + +# TF-M NS interface for the non-secure side + +add_library(tfm-ns-interface ${tfm_ns_interface_generated}) +add_dependencies(tfm-ns-interface trusted_firmware-m-build) + +target_include_directories(tfm-ns-interface + PUBLIC + ${BINARY_DIR}/api_ns/interface/include + ${BINARY_DIR}/api_ns/platform/include +) + +target_link_libraries(tfm-ns-interface + PRIVATE + ${s_veneers_generated} + tfm-ns-interface-mbedtls-config +) + +target_compile_definitions(tfm-ns-interface + PUBLIC + BL2 + MCUBOOT_IMAGE_NUMBER=2 +) + +add_library(tfm-ns-interface-mbedtls-config INTERFACE) + +target_compile_definitions(tfm-ns-interface-mbedtls-config + INTERFACE + MBEDTLS_CONFIG_FILE="${trusted_firmware-m_SOURCE_DIR}/lib/ext/mbedcrypto/mbedcrypto_config/tfm_mbedcrypto_config_client.h" + MBEDTLS_PSA_CRYPTO_CONFIG_FILE="${trusted_firmware-m_SOURCE_DIR}/lib/ext/mbedcrypto/mbedcrypto_config/crypto_config_default.h" +) diff --git a/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/trusted_firmware-m/integration/cmake/BuildTfm.cmake b/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/trusted_firmware-m/integration/cmake/BuildTfm.cmake new file mode 100644 index 0000000..e0a4e67 --- /dev/null +++ b/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/trusted_firmware-m/integration/cmake/BuildTfm.cmake @@ -0,0 +1,81 @@ +# Copyright 2021-2024 Arm Limited and/or its affiliates +# +# SPDX-License-Identifier: MIT + +# Files generated by TF-M build must be listed as BUILD_BYPRODUCTS +# to inform CMake that they don't exist before build starts. Include +# paths do not need to be listed. +# is a placeholder keyword in ExternalProject_Add. + +set(tfm_ns_interface_generated + /api_ns/interface/src/tfm_tz_psa_ns_api.c + /api_ns/interface/src/tfm_ps_api.c + /api_ns/interface/src/tfm_its_api.c + /api_ns/interface/src/tfm_crypto_api.c + /api_ns/interface/src/tfm_attest_api.c + /api_ns/interface/src/tfm_platform_api.c + /api_ns/interface/src/os_wrapper/tfm_ns_interface_rtos.c +) + +set(s_veneers_generated + /api_ns/interface/lib/s_veneers.o +) + +include(ExternalProject) + +if(CMAKE_C_COMPILER_ID STREQUAL "ARMClang") + set(tfm_toolchain_file "toolchain_ARMCLANG.cmake") +elseif(CMAKE_C_COMPILER_ID STREQUAL "IAR") + set(tfm_toolchain_file "toolchain_IARARM.cmake") +else() + message(FATAL_ERROR "Unsupported compiler: ${CMAKE_C_COMPILER_ID}") +endif() + +ExternalProject_Add( + trusted_firmware-m-build + + DOWNLOAD_COMMAND "" + SOURCE_DIR ${trusted_firmware-m_SOURCE_DIR} + + USES_TERMINAL_CONFIGURE ON + USES_TERMINAL_BUILD ON + + BUILD_ALWAYS ON + + CMAKE_ARGS + -DTFM_TOOLCHAIN_FILE=/${tfm_toolchain_file} + -DCMAKE_BUILD_TYPE=Release + -DCONFIG_TFM_ENABLE_CP10CP11=ON + -DMCUBOOT_GENERATE_SIGNING_KEYPAIR=ON + -DMCUBOOT_LOG_LEVEL=INFO + -DMCUBOOT_SIGNATURE_KEY_LEN=3072 + -DNS=ON + -DPLATFORM_DEFAULT_PROVISIONING=OFF + -DPLATFORM_DEFAULT_UART_STDOUT=ON + -DTFM_DUMMY_PROVISIONING=OFF + -DTFM_EXCEPTION_INFO_DUMP=ON + -DTFM_PARTITION_CRYPTO=ON + -DTFM_PARTITION_INITIAL_ATTESTATION=ON + -DTFM_PARTITION_INTERNAL_TRUSTED_STORAGE=ON + -DTFM_PARTITION_PLATFORM=ON + -DTFM_PARTITION_PROTECTED_STORAGE=ON + -DTFM_SPM_LOG_LEVEL=TFM_SPM_LOG_LEVEL_INFO + -DTFM_PLATFORM=arm/mps4/corstone315 + -DFLASH_S_PARTITION_SIZE=0x40000 + -DFLASH_NS_PARTITION_SIZE=0x340000 + -DPROJECT_CONFIG_HEADER_FILE=${CMAKE_CURRENT_LIST_DIR}/../../../config/project_config.h + -DCONFIG_TFM_BRANCH_PROTECTION_FEAT=${TFM_PACBTI_CONFIGURATION} + + PATCH_COMMAND + ${TFM_PATCH_COMMAND} + + BUILD_BYPRODUCTS + ${tfm_ns_interface_generated} + ${s_veneers_generated} +) + +# The path ${BINARY_DIR} is available after ExternalProject_Add. +# Convert to allow projects to use those files. +ExternalProject_Get_Property(trusted_firmware-m-build BINARY_DIR) +list(TRANSFORM tfm_ns_interface_generated REPLACE "" "${BINARY_DIR}") +list(TRANSFORM s_veneers_generated REPLACE "" "${BINARY_DIR}") diff --git a/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/trusted_firmware-m/integration/cmake/ConvertElfToBin.cmake b/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/trusted_firmware-m/integration/cmake/ConvertElfToBin.cmake new file mode 100644 index 0000000..68b3da6 --- /dev/null +++ b/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/trusted_firmware-m/integration/cmake/ConvertElfToBin.cmake @@ -0,0 +1,37 @@ +# Copyright 2021-2024 Arm Limited and/or its affiliates +# +# SPDX-License-Identifier: MIT + +function(target_axf_to_bin target output_binary_name) + set(SECTORS_BIN_DIR ${CMAKE_BINARY_DIR}/application_sectors CACHE INTERNAL "Output sectors binaries directory") + file(MAKE_DIRECTORY ${SECTORS_BIN_DIR}) + if(CMAKE_C_COMPILER_ID STREQUAL "IAR") + find_program(objcopy NAMES arm-none-eabi-objcopy objcopy REQUIRED) + set(elf_to_bin + ${objcopy} -O binary + $ + ${SECTORS_BIN_DIR}/${output_binary_name}.bin + ) + elseif(CMAKE_C_COMPILER_ID STREQUAL "ARMClang") + find_program(fromelf NAMES fromelf REQUIRED) + set(elf_to_bin + ${fromelf} --bin + --output ${SECTORS_BIN_DIR}/${output_binary_name}.bin + $ + ) + else() + message(FATAL_ERROR "Unsupported compiler: ${CMAKE_C_COMPILER_ID}") + endif() + add_custom_command( + TARGET + ${target} + POST_BUILD + DEPENDS + $ + COMMAND + ${elf_to_bin} + COMMAND + ${CMAKE_COMMAND} -E echo "-- built: $/${output_binary_name}.bin" + VERBATIM + ) +endfunction() diff --git a/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/trusted_firmware-m/integration/cmake/MergeTfmImages.cmake b/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/trusted_firmware-m/integration/cmake/MergeTfmImages.cmake new file mode 100644 index 0000000..4ce9990 --- /dev/null +++ b/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/trusted_firmware-m/integration/cmake/MergeTfmImages.cmake @@ -0,0 +1,40 @@ +# Copyright 2023-2024, Arm Limited and/or its affiliates +# +# SPDX-License-Identifier: MIT + +include(ExternalProject) + +ExternalProject_Get_Property(trusted_firmware-m-build BINARY_DIR) + +# To merge the bootloader image, TF-M secure image, non-secure user application image, +# and provsioning bundle images into one image, their addresses are +# needed. As the addresses are defined in their respective linker scripts, there is no +# simple way to programmatically get them, so they need to be specified by the user project. +# Order: , , , . + +function(tf_m_merge_images target) + find_program(srec_cat NAMES srec_cat REQUIRED) + find_program(objcopy NAMES arm-none-eabi-objcopy objcopy REQUIRED) + add_custom_command( + TARGET + ${target} + POST_BUILD + DEPENDS + $/${target}_signed.bin + COMMAND + ${srec_cat} ${BINARY_DIR}/api_ns/bin/bl1_1.bin -Binary -offset ${BL1_IMAGE_LOAD_ADDRESS} + ${BINARY_DIR}/api_ns/bin/cm_provisioning_bundle.bin -Binary -offset ${S_CM_PROVISIONING_BUNDLE_LOAD_ADDRESS} + ${BINARY_DIR}/api_ns/bin/dm_provisioning_bundle.bin -Binary -offset ${S_DM_PROVISIONING_BUNDLE_LOAD_ADDRESS} + ${BINARY_DIR}/api_ns/bin/bl2_signed.bin -Binary -offset ${BL2_IMAGE_LOAD_ADDRESS} + ${BINARY_DIR}/api_ns/bin/tfm_s_signed.bin -Binary -offset ${S_IMAGE_LOAD_ADDRESS} + $/${target}_signed.bin -Binary -offset ${NS_IMAGE_LOAD_ADDRESS} + -o $/${target}_merged.hex + COMMAND + ${objcopy} -I ihex -O elf32-little + $/${target}_merged.hex + $/${target}_merged.elf + COMMAND + ${CMAKE_COMMAND} -E echo "-- merged: $/${target}_merged.elf" + VERBATIM + ) +endfunction() diff --git a/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/trusted_firmware-m/integration/cmake/SignTfmImage.cmake b/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/trusted_firmware-m/integration/cmake/SignTfmImage.cmake new file mode 100644 index 0000000..64eff82 --- /dev/null +++ b/CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/trusted_firmware-m/integration/cmake/SignTfmImage.cmake @@ -0,0 +1,44 @@ +# Copyright 2023-2024 Arm Limited and/or its affiliates +# +# SPDX-License-Identifier: MIT + +include(ConvertElfToBin) +include(ExternalProject) + +ExternalProject_Get_Property(trusted_firmware-m-build BINARY_DIR) + +function(tf_m_sign_image target signed_target_name version pad) + if(${pad}) + set(pad_option "--pad") + else() + set(pad_option "") + endif() + + target_axf_to_bin( + ${target} + "flash" + ) + + add_custom_command( + TARGET + ${target} + POST_BUILD + DEPENDS + $/${target}.bin + COMMAND + # Sign the non-secure (application) image for TF-M bootloader (BL2) + python3 ${BINARY_DIR}/api_ns/image_signing/scripts/wrapper/wrapper.py + -v ${version} + --layout ${BINARY_DIR}/api_ns/image_signing/layout_files/signing_layout_ns.o + -k ${BINARY_DIR}/api_ns/image_signing/keys/image_ns_signing_private_key.pem + --public-key-format full + --align 1 --pad-header ${pad_option} -H 0x400 -s auto + --measured-boot-record + --confirm + ${SECTORS_BIN_DIR}/flash.bin + $/${signed_target_name}.bin + COMMAND + ${CMAKE_COMMAND} -E echo "-- signed: $/${signed_target_name}.bin" + VERBATIM + ) +endfunction()