Skip to content

Commit

Permalink
cortex-m85: Add non-MPU PACBTI example
Browse files Browse the repository at this point in the history
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 <Ahmed.Ismail@arm.com>
  • Loading branch information
AhmedIsmail02 committed Oct 22, 2024
1 parent 9e061d1 commit 0fa7217
Show file tree
Hide file tree
Showing 21 changed files with 1,942 additions and 0 deletions.
119 changes: 119 additions & 0 deletions CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/CMSIS/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# Copyright 2023-2024 Arm Limited and/or its affiliates
# <open-source-office@arm.com>
# 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 $<$<STREQUAL:${CMAKE_C_COMPILER_ID},ARMClang>:-mbranch-protection=standard>)
target_compile_options(arm-corstone-platform-bsp PUBLIC $<$<STREQUAL:${CMAKE_C_COMPILER_ID},IAR>:$<$<COMPILE_LANGUAGE:C,CXX>:--branch_protection=bti+pac-ret>>)
target_compile_definitions(arm-corstone-platform-bsp
PUBLIC
ARM_V_8_1_M_PACBTI_CONFIG=ARM_V_8_1_M_PACBTI_CONFIG_STANDARD
)
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
)
target_compile_definitions(arm-corstone-platform-bsp
PUBLIC
ARM_V_8_1_M_PACBTI_CONFIG=ARM_V_8_1_M_PACBTI_CONFIG_PACRET_LEAF_BTI
)
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 $<$<STREQUAL:${CMAKE_C_COMPILER_ID},ARMClang>:-mbranch-protection=pac-ret>)
target_compile_options(arm-corstone-platform-bsp PUBLIC $<$<STREQUAL:${CMAKE_C_COMPILER_ID},IAR>:$<$<COMPILE_LANGUAGE:C,CXX>:--branch_protection=pac-ret>>)
target_compile_definitions(arm-corstone-platform-bsp
PUBLIC
ARM_V_8_1_M_PACBTI_CONFIG=ARM_V_8_1_M_PACBTI_CONFIG_PACRET
)
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
)
target_compile_definitions(arm-corstone-platform-bsp
PUBLIC
ARM_V_8_1_M_PACBTI_CONFIG=ARM_V_8_1_M_PACBTI_CONFIG_PACRET_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 $<$<STREQUAL:${CMAKE_C_COMPILER_ID},ARMClang>:-mbranch-protection=bti>)
target_compile_options(arm-corstone-platform-bsp PUBLIC $<$<STREQUAL:${CMAKE_C_COMPILER_ID},IAR>:$<$<COMPILE_LANGUAGE:C,CXX>:--branch_protection=bti>>)
target_compile_definitions(arm-corstone-platform-bsp
PUBLIC
ARM_V_8_1_M_PACBTI_CONFIG=ARM_V_8_1_M_PACBTI_CONFIG_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()
target_compile_definitions(arm-corstone-platform-bsp
PUBLIC
ARM_V_8_1_M_PACBTI_CONFIG=ARM_V_8_1_M_PACBTI_CONFIG_NONE
)
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
)
228 changes: 228 additions & 0 deletions CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/CMSIS/common/bsp_serial.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
/* Copyright 2017-2024 Arm Limited and/or its affiliates
* <open-source-office@arm.com>
* SPDX-License-Identifier: Apache-2.0
*/

#include <stdio.h>
#include <string.h>
#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 <rt_sys.h>

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 <rt_sys.h>: `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 <rt_sys.h>: `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;
}
}
22 changes: 22 additions & 0 deletions CORTEX_M85_PACBTI_FVP_ARMCLANG_IAR/CMSIS/common/bsp_serial.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/* Copyright 2017-2024 Arm Limited and/or its affiliates
* <open-source-office@arm.com>
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef __SERIAL_H__
#define __SERIAL_H__


#include <stddef.h>

/**
* \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__ */
Original file line number Diff line number Diff line change
@@ -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

/* <q> USART (Universal synchronous - asynchronous receiver transmitter) [Driver_USART0] */
/* <i> Configuration settings for Driver_USART0 in component ::Drivers:USART */
#define RTE_USART0 1

#endif /* __RTE_COMPONENTS_H */
Loading

0 comments on commit 0fa7217

Please sign in to comment.