diff --git a/portable/ARMv8M/non_secure/port.c b/portable/ARMv8M/non_secure/port.c index 5492c367a6f..0a40a853474 100644 --- a/portable/ARMv8M/non_secure/port.c +++ b/portable/ARMv8M/non_secure/port.c @@ -41,6 +41,11 @@ #include "mpu_wrappers.h" #include "mpu_syscall_numbers.h" +#if ( configENABLE_PAC == 1 ) + #include + #include +#endif /* configENABLE_PAC */ + /* Portasm includes. */ #include "portasm.h" @@ -1582,6 +1587,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = pulTaskPacKey[i]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1681,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pxTopOfStack--; + *pxTopOfStack = pulTaskPacKey[i]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -2245,5 +2274,22 @@ BaseType_t xPortIsInsideInterrupt( void ) return ulControl; } + #if ( configENABLE_PAC == 1 ) + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ) + { + static BaseType_t isSeeded = pdFALSE; + if ( isSeeded == pdFALSE ) + { + srand(time(NULL)); + isSeeded = pdTRUE; + } + + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pulTaskPacKey[i] = rand(); + } + } + #endif /* configENABLE_PAC */ + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portasm.c b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portasm.c index f7d3bb18109..a0075a79835 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portasm.c +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portasm.c @@ -99,6 +99,15 @@ " ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/ " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r2!, {r3-r6} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r4 \n" + " msr PAC_KEY_P_2, r5 \n" + " msr PAC_KEY_P_3, r6 \n" + " clrm {r3-r6} \n" + #endif /* configENABLE_PAC */ + " \n" " restore_special_regs_first_task: \n" " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ " msr psp, r3 \n" @@ -131,6 +140,14 @@ " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r3, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r3] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ + #if ( configENABLE_PAC == 1 ) + " ldmia r0!, {r1-r4} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r1 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r2 \n" + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_0, r4 \n" + " clrm {r1-r4} \n" + #endif /* configENABLE_PAC */ " \n" " ldm r0!, {r1-r3} \n" /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ " ldr r4, =xSecureContext \n" @@ -300,6 +317,14 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " mrs r4, psplim \n" /* r4 = PSPLIM. */ " mrs r5, control \n" /* r5 = CONTROL. */ " stmia r2!, {r0, r3-r5, lr} \n" /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + #if ( configENABLE_PAC == 1 ) + " mrs r3, PAC_KEY_P_0 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r4, PAC_KEY_P_1 \n" + " mrs r5, PAC_KEY_P_2 \n" + " mrs r6, PAC_KEY_P_3 \n" + " stmia r2!, {r3-r6} \n" /* Store the task's dedicated PAC key on the task's context. */ + " clrm {r3-r6} \n" + #endif /* configENABLE_PAC */ " str r2, [r1] \n" /* Save the location from where the context should be restored as the first member of TCB. */ " \n" " select_next_task: \n" @@ -357,6 +382,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/ " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r2!, {r3-r6} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r4 \n" + " msr PAC_KEY_P_2, r5 \n" + " msr PAC_KEY_P_3, r6 \n" + " clrm {r3-r6} \n" + #endif /* configENABLE_PAC */ + " \n" " restore_special_regs: \n" " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ " msr psp, r3 \n" @@ -434,6 +468,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " mrs r1, psplim \n" /* r1 = PSPLIM. */ " mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ " stmdb r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ + " \n" + #if ( configENABLE_PAC == 1 ) + " mrs r3, PAC_KEY_P_3 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r4, PAC_KEY_P_2 \n" + " mrs r5, PAC_KEY_P_1 \n" + " mrs r6, PAC_KEY_P_0 \n" + " stmdb r2!, {r3-r6} \n" /* Store the task's dedicated PAC key on the stack. */ + " clrm {r3-r6} \n" + #endif /* configENABLE_PAC */ " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ " str r2, [r1] \n" /* Save the new top of stack in TCB. */ @@ -451,6 +494,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ " ldr r2, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmia r2!, {r3-r6} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_1, r5 \n" + " msr PAC_KEY_P_0, r6 \n" + " clrm {r3-r6} \n" + #endif /* configENABLE_PAC */ + " \n" " ldmia r2!, {r0, r1, r4} \n" /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ " msr psplim, r1 \n" /* Restore the PSPLIM register value for the task. */ " mov lr, r4 \n" /* LR = r4. */ diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/portasm.c b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/portasm.c index 7cdff70050d..e0b49ddd64d 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/portasm.c +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/portasm.c @@ -99,6 +99,15 @@ " ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/ " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r1!, {r2-r5} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_3, r5 \n" + " clrm {r2-r5} \n" + #endif /* configENABLE_PAC */ + " \n" " restore_special_regs_first_task: \n" " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ " msr psp, r2 \n" @@ -129,6 +138,15 @@ " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r1] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ + #if ( configENABLE_PAC == 1 ) + " ldmia r0!, {r1-r4} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r1 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r2 \n" + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_0, r4 \n" + " clrm {r1-r4} \n" + #endif /* configENABLE_PAC */ + " \n" " \n" " ldm r0!, {r1-r2} \n" /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ " msr psplim, r1 \n" /* Set this task's PSPLIM value. */ @@ -279,6 +297,14 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " mrs r3, psplim \n" /* r3 = PSPLIM. */ " mrs r4, control \n" /* r4 = CONTROL. */ " stmia r1!, {r2-r4, lr} \n" /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + #if ( configENABLE_PAC == 1 ) + " mrs r2, PAC_KEY_P_0 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r3, PAC_KEY_P_1 \n" + " mrs r4, PAC_KEY_P_2 \n" + " mrs r5, PAC_KEY_P_3 \n" + " stmia r1!, {r2-r5} \n" /* Store the task's dedicated PAC key on the task's context. */ + " clrm {r2-r5} \n" + #endif /* configENABLE_PAC */ " str r1, [r0] \n" /* Save the location from where the context should be restored as the first member of TCB. */ " \n" " select_next_task: \n" @@ -336,6 +362,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/ " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r1!, {r2-r5} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_3, r5 \n" + " clrm {r2-r5} \n" + #endif /* configENABLE_PAC */ + " \n" " restore_special_regs: \n" " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ " msr psp, r2 \n" @@ -381,6 +416,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ " stmdb r0!, {r2-r11} \n" /* Store on the stack - PSPLIM, LR and registers that are not automatically saved. */ " \n" + #if ( configENABLE_PAC == 1 ) + " mrs r1, PAC_KEY_P_3 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r2, PAC_KEY_P_2 \n" + " mrs r3, PAC_KEY_P_1 \n" + " mrs r4, PAC_KEY_P_0 \n" + " stmdb r0!, {r1-r4} \n" /* Store the task's dedicated PAC key on the stack. */ + " clrm {r1-r4} \n" + #endif /* configENABLE_PAC */ + " \n" " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " str r0, [r1] \n" /* Save the new top of stack in TCB. */ @@ -397,6 +441,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmia r0!, {r2-r5} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r3 \n" + " msr PAC_KEY_P_1, r4 \n" + " msr PAC_KEY_P_0, r5 \n" + " clrm {r2-r5} \n" + #endif /* configENABLE_PAC */ + " \n" " ldmia r0!, {r2-r11} \n" /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ " \n" #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) diff --git a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33/portasm.s b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33/portasm.s index c77fd39403b..508694f5d00 100644 --- a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33/portasm.s +++ b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33/portasm.s @@ -27,12 +27,13 @@ * https://github.com/FreeRTOS * */ -/* Including FreeRTOSConfig.h here will cause build errors if the header file -contains code not understood by the assembler - for example the 'extern' keyword. -To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so +/* Including FreeRTOSConfig.h and portasm.h here will cause build errors if the +header file contains code not understood by the assembler - for example the 'extern' +keyword. To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so the code is included in C files but excluded by the preprocessor in assembly files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ #include "FreeRTOSConfig.h" +#include "portasm.h" /* System call numbers includes. */ #include "mpu_syscall_numbers.h" @@ -150,6 +151,14 @@ vRestoreContextOfFirstTask: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* r1 = pxCurrentTCB.*/ ldr r2, [r1] /* r2 = Location of saved context in TCB. */ + #if ( configENABLE_PAC == 1 ) + ldmdb r2!, {r3-r6} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r4 + msr PAC_KEY_P_2, r5 + msr PAC_KEY_P_3, r6 + clrm {r3-r6} + #endif /* configENABLE_PAC */ restore_special_regs_first_task: ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ @@ -176,6 +185,14 @@ vRestoreContextOfFirstTask: ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r3, [r2] /* Read pxCurrentTCB. */ ldr r0, [r3] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ + #if ( configENABLE_PAC == 1 ) + ldmia r0!, {r1-r4} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r1 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r2 + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_0, r4 + clrm {r1-r4} + #endif /* configENABLE_PAC */ ldm r0!, {r1-r3} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ ldr r4, =xSecureContext @@ -271,6 +288,14 @@ PendSV_Handler: mrs r4, psplim /* r4 = PSPLIM. */ mrs r5, control /* r5 = CONTROL. */ stmia r2!, {r0, r3-r5, lr} /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + #if ( configENABLE_PAC == 1 ) + mrs r3, PAC_KEY_P_0 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r4, PAC_KEY_P_1 + mrs r5, PAC_KEY_P_2 + mrs r6, PAC_KEY_P_3 + stmia r2!, {r3-r6} /* Store the task's dedicated PAC key on the task's context. */ + clrm {r3-r6} + #endif /* configENABLE_PAC */ str r2, [r1] /* Save the location from where the context should be restored as the first member of TCB. */ select_next_task: @@ -327,6 +352,14 @@ PendSV_Handler: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* r1 = pxCurrentTCB.*/ ldr r2, [r1] /* r2 = Location of saved context in TCB. */ + #if ( configENABLE_PAC == 1 ) + ldmdb r2!, {r3-r6} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r4 + msr PAC_KEY_P_2, r5 + msr PAC_KEY_P_3, r6 + clrm {r3-r6} + #endif /* configENABLE_PAC */ restore_special_regs: ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ @@ -396,6 +429,15 @@ PendSV_Handler: mrs r1, psplim /* r1 = PSPLIM. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ stmdb r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ + + #if ( configENABLE_PAC == 1 ) + mrs r3, PAC_KEY_P_3 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r4, PAC_KEY_P_2 + mrs r5, PAC_KEY_P_1 + mrs r6, PAC_KEY_P_0 + stmdb r2!, {r3-r6} /* Store the task's dedicated PAC key on the stack. */ + clrm {r3-r6} + #endif /* configENABLE_PAC */ ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ str r2, [r1] /* Save the new top of stack in TCB. */ @@ -412,7 +454,14 @@ PendSV_Handler: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ ldr r2, [r1] /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ - + #if ( configENABLE_PAC == 1 ) + ldmia r2!, {r3-r6} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_1, r5 + msr PAC_KEY_P_0, r6 + clrm {r3-r6} + #endif /* configENABLE_PAC */ ldmia r2!, {r0, r1, r4} /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ msr psplim, r1 /* Restore the PSPLIM register value for the task. */ mov lr, r4 /* LR = r4. */ diff --git a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33_NTZ/portasm.s b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33_NTZ/portasm.s index 9d6c6a7ef9a..ebe7f2b9dea 100644 --- a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33_NTZ/portasm.s +++ b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33_NTZ/portasm.s @@ -27,12 +27,13 @@ * https://github.com/FreeRTOS * */ -/* Including FreeRTOSConfig.h here will cause build errors if the header file -contains code not understood by the assembler - for example the 'extern' keyword. -To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so +/* Including FreeRTOSConfig.h and portasm.h here will cause build errors if the +header file contains code not understood by the assembler - for example the 'extern' +keyword. To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so the code is included in C files but excluded by the preprocessor in assembly files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ #include "FreeRTOSConfig.h" +#include "portasm.h" /* System call numbers includes. */ #include "mpu_syscall_numbers.h" @@ -140,6 +141,14 @@ vRestoreContextOfFirstTask: ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r0, [r2] /* r0 = pxCurrentTCB.*/ ldr r1, [r0] /* r1 = Location of saved context in TCB. */ + #if ( configENABLE_PAC == 1 ) + ldmdb r1!, {r2-r5} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r2 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_3, r5 + clrm {r2-r5} + #endif /* configENABLE_PAC */ restore_special_regs_first_task: ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ @@ -165,6 +174,15 @@ vRestoreContextOfFirstTask: ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ + #if ( configENABLE_PAC == 1 ) + ldmia r0!, {r1-r4} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r1 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r2 + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_0, r4 + clrm {r1-r4} + #endif /* configENABLE_PAC */ + ldm r0!, {r1-r2} /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ msr psplim, r1 /* Set this task's PSPLIM value. */ mrs r1, control /* Obtain current control register value. */ @@ -242,6 +260,16 @@ PendSV_Handler: mrs r3, psplim /* r3 = PSPLIM. */ mrs r4, control /* r4 = CONTROL. */ stmia r1!, {r2-r4, lr} /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + + #if ( configENABLE_PAC == 1 ) + mrs r2, PAC_KEY_P_0 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r3, PAC_KEY_P_1 + mrs r4, PAC_KEY_P_2 + mrs r5, PAC_KEY_P_3 + stmia r1!, {r2-r5} /* Store the task's dedicated PAC key on the task's context. */ + clrm {r2-r5} + #endif /* configENABLE_PAC */ + str r1, [r0] /* Save the location from where the context should be restored as the first member of TCB. */ select_next_task: @@ -299,6 +327,15 @@ PendSV_Handler: ldr r0, [r2] /* r0 = pxCurrentTCB.*/ ldr r1, [r0] /* r1 = Location of saved context in TCB. */ + #if ( configENABLE_PAC == 1 ) + ldmdb r1!, {r2-r5} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r2 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_3, r5 + clrm {r2-r5} + #endif /* configENABLE_PAC */ + restore_special_regs: ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ msr psp, r2 @@ -335,6 +372,15 @@ PendSV_Handler: mov r3, lr /* r3 = LR/EXC_RETURN. */ stmdb r0!, {r2-r11} /* Store on the stack - PSPLIM, LR and registers that are not automatically. */ + #if ( configENABLE_PAC == 1 ) + mrs r1, PAC_KEY_P_3 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r2, PAC_KEY_P_2 + mrs r3, PAC_KEY_P_1 + mrs r4, PAC_KEY_P_0 + stmdb r0!, {r1-r4} /* Store the task's dedicated PAC key on the stack. */ + clrm {r1-r4} + #endif /* configENABLE_PAC */ + ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r2] /* Read pxCurrentTCB. */ str r0, [r1] /* Save the new top of stack in TCB. */ @@ -351,6 +397,15 @@ PendSV_Handler: ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ + #if ( configENABLE_PAC == 1 ) + ldmia r0!, {r2-r5} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r2 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r3 + msr PAC_KEY_P_1, r4 + msr PAC_KEY_P_0, r5 + clrm {r2-r5} + #endif /* configENABLE_PAC */ + ldmia r0!, {r2-r11} /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) diff --git a/portable/ARMv8M/non_secure/portmacrocommon.h b/portable/ARMv8M/non_secure/portmacrocommon.h index 8a8dc7d6ae3..d8ef5b17925 100644 --- a/portable/ARMv8M/non_secure/portmacrocommon.h +++ b/portable/ARMv8M/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,20 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + /** + * @brief Generates 128-bit task's random PAC key. + * + * The implementation in this file is weak to allow application writers to + * provide their own Random Number Generator implementation for PAC keys randomisation. + * + * @param pulTaskPacKey Pointer to task's PAC key array to be assigned an 128-bit random number. + */ + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + + #define portPAC_KEY_SIZE_BYTES 16 +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -223,63 +239,114 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) +/* +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><-----------><----> +* 16 16 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 70 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) /* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><----> +* 16 16 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) /* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | | | PC, xPSR | EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><-----------><----> +* 16 16 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 69 + + #else + +/* +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | | | PC, xPSR | EXC_RETURN | | +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><----> +* 16 16 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 53 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) /* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ +* +----------+-----------------+------------------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +----------+-----------------+------------------------------+------------+-----+ +* +* <---------><----------------><------------------------------><-----------><----> +* 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + +/* +* +----------+-----------------+------------------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | +* +----------+-----------------+------------------------------+-----+ +* +* <---------><----------------><------------------------------><----> +* 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + +/* +* +----------+-----------------+----------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | PC, xPSR | EXC_RETURN | | | +* +----------+-----------------+----------------------+------------+-----+ +* +* <---------><----------------><----------------------><-----------><----> +* 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ /* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ +* +----------+-----------------+----------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | PC, xPSR | EXC_RETURN | | +* +----------+-----------------+----------------------+-----+ +* +* <---------><----------------><----------------------><----> +* 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ diff --git a/portable/GCC/ARM_CM23/non_secure/port.c b/portable/GCC/ARM_CM23/non_secure/port.c index 5492c367a6f..0a40a853474 100644 --- a/portable/GCC/ARM_CM23/non_secure/port.c +++ b/portable/GCC/ARM_CM23/non_secure/port.c @@ -41,6 +41,11 @@ #include "mpu_wrappers.h" #include "mpu_syscall_numbers.h" +#if ( configENABLE_PAC == 1 ) + #include + #include +#endif /* configENABLE_PAC */ + /* Portasm includes. */ #include "portasm.h" @@ -1582,6 +1587,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = pulTaskPacKey[i]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1681,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pxTopOfStack--; + *pxTopOfStack = pulTaskPacKey[i]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -2245,5 +2274,22 @@ BaseType_t xPortIsInsideInterrupt( void ) return ulControl; } + #if ( configENABLE_PAC == 1 ) + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ) + { + static BaseType_t isSeeded = pdFALSE; + if ( isSeeded == pdFALSE ) + { + srand(time(NULL)); + isSeeded = pdTRUE; + } + + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pulTaskPacKey[i] = rand(); + } + } + #endif /* configENABLE_PAC */ + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM23/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM23/non_secure/portmacrocommon.h index 8a8dc7d6ae3..d8ef5b17925 100644 --- a/portable/GCC/ARM_CM23/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM23/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,20 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + /** + * @brief Generates 128-bit task's random PAC key. + * + * The implementation in this file is weak to allow application writers to + * provide their own Random Number Generator implementation for PAC keys randomisation. + * + * @param pulTaskPacKey Pointer to task's PAC key array to be assigned an 128-bit random number. + */ + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + + #define portPAC_KEY_SIZE_BYTES 16 +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -223,63 +239,114 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) +/* +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><-----------><----> +* 16 16 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 70 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) /* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><----> +* 16 16 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) /* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | | | PC, xPSR | EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><-----------><----> +* 16 16 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 69 + + #else + +/* +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | | | PC, xPSR | EXC_RETURN | | +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><----> +* 16 16 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 53 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) /* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ +* +----------+-----------------+------------------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +----------+-----------------+------------------------------+------------+-----+ +* +* <---------><----------------><------------------------------><-----------><----> +* 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + +/* +* +----------+-----------------+------------------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | +* +----------+-----------------+------------------------------+-----+ +* +* <---------><----------------><------------------------------><----> +* 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + +/* +* +----------+-----------------+----------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | PC, xPSR | EXC_RETURN | | | +* +----------+-----------------+----------------------+------------+-----+ +* +* <---------><----------------><----------------------><-----------><----> +* 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ /* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ +* +----------+-----------------+----------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | PC, xPSR | EXC_RETURN | | +* +----------+-----------------+----------------------+-----+ +* +* <---------><----------------><----------------------><----> +* 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ diff --git a/portable/GCC/ARM_CM23_NTZ/non_secure/port.c b/portable/GCC/ARM_CM23_NTZ/non_secure/port.c index 5492c367a6f..0a40a853474 100644 --- a/portable/GCC/ARM_CM23_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_CM23_NTZ/non_secure/port.c @@ -41,6 +41,11 @@ #include "mpu_wrappers.h" #include "mpu_syscall_numbers.h" +#if ( configENABLE_PAC == 1 ) + #include + #include +#endif /* configENABLE_PAC */ + /* Portasm includes. */ #include "portasm.h" @@ -1582,6 +1587,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = pulTaskPacKey[i]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1681,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pxTopOfStack--; + *pxTopOfStack = pulTaskPacKey[i]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -2245,5 +2274,22 @@ BaseType_t xPortIsInsideInterrupt( void ) return ulControl; } + #if ( configENABLE_PAC == 1 ) + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ) + { + static BaseType_t isSeeded = pdFALSE; + if ( isSeeded == pdFALSE ) + { + srand(time(NULL)); + isSeeded = pdTRUE; + } + + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pulTaskPacKey[i] = rand(); + } + } + #endif /* configENABLE_PAC */ + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM23_NTZ/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM23_NTZ/non_secure/portmacrocommon.h index 8a8dc7d6ae3..d8ef5b17925 100644 --- a/portable/GCC/ARM_CM23_NTZ/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM23_NTZ/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,20 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + /** + * @brief Generates 128-bit task's random PAC key. + * + * The implementation in this file is weak to allow application writers to + * provide their own Random Number Generator implementation for PAC keys randomisation. + * + * @param pulTaskPacKey Pointer to task's PAC key array to be assigned an 128-bit random number. + */ + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + + #define portPAC_KEY_SIZE_BYTES 16 +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -223,63 +239,114 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) +/* +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><-----------><----> +* 16 16 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 70 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) /* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><----> +* 16 16 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) /* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | | | PC, xPSR | EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><-----------><----> +* 16 16 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 69 + + #else + +/* +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | | | PC, xPSR | EXC_RETURN | | +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><----> +* 16 16 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 53 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) /* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ +* +----------+-----------------+------------------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +----------+-----------------+------------------------------+------------+-----+ +* +* <---------><----------------><------------------------------><-----------><----> +* 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + +/* +* +----------+-----------------+------------------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | +* +----------+-----------------+------------------------------+-----+ +* +* <---------><----------------><------------------------------><----> +* 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + +/* +* +----------+-----------------+----------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | PC, xPSR | EXC_RETURN | | | +* +----------+-----------------+----------------------+------------+-----+ +* +* <---------><----------------><----------------------><-----------><----> +* 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ /* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ +* +----------+-----------------+----------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | PC, xPSR | EXC_RETURN | | +* +----------+-----------------+----------------------+-----+ +* +* <---------><----------------><----------------------><----> +* 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ diff --git a/portable/GCC/ARM_CM33/non_secure/port.c b/portable/GCC/ARM_CM33/non_secure/port.c index 5492c367a6f..0a40a853474 100644 --- a/portable/GCC/ARM_CM33/non_secure/port.c +++ b/portable/GCC/ARM_CM33/non_secure/port.c @@ -41,6 +41,11 @@ #include "mpu_wrappers.h" #include "mpu_syscall_numbers.h" +#if ( configENABLE_PAC == 1 ) + #include + #include +#endif /* configENABLE_PAC */ + /* Portasm includes. */ #include "portasm.h" @@ -1582,6 +1587,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = pulTaskPacKey[i]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1681,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pxTopOfStack--; + *pxTopOfStack = pulTaskPacKey[i]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -2245,5 +2274,22 @@ BaseType_t xPortIsInsideInterrupt( void ) return ulControl; } + #if ( configENABLE_PAC == 1 ) + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ) + { + static BaseType_t isSeeded = pdFALSE; + if ( isSeeded == pdFALSE ) + { + srand(time(NULL)); + isSeeded = pdTRUE; + } + + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pulTaskPacKey[i] = rand(); + } + } + #endif /* configENABLE_PAC */ + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM33/non_secure/portasm.c b/portable/GCC/ARM_CM33/non_secure/portasm.c index f7d3bb18109..a0075a79835 100644 --- a/portable/GCC/ARM_CM33/non_secure/portasm.c +++ b/portable/GCC/ARM_CM33/non_secure/portasm.c @@ -99,6 +99,15 @@ " ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/ " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r2!, {r3-r6} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r4 \n" + " msr PAC_KEY_P_2, r5 \n" + " msr PAC_KEY_P_3, r6 \n" + " clrm {r3-r6} \n" + #endif /* configENABLE_PAC */ + " \n" " restore_special_regs_first_task: \n" " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ " msr psp, r3 \n" @@ -131,6 +140,14 @@ " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r3, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r3] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ + #if ( configENABLE_PAC == 1 ) + " ldmia r0!, {r1-r4} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r1 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r2 \n" + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_0, r4 \n" + " clrm {r1-r4} \n" + #endif /* configENABLE_PAC */ " \n" " ldm r0!, {r1-r3} \n" /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ " ldr r4, =xSecureContext \n" @@ -300,6 +317,14 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " mrs r4, psplim \n" /* r4 = PSPLIM. */ " mrs r5, control \n" /* r5 = CONTROL. */ " stmia r2!, {r0, r3-r5, lr} \n" /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + #if ( configENABLE_PAC == 1 ) + " mrs r3, PAC_KEY_P_0 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r4, PAC_KEY_P_1 \n" + " mrs r5, PAC_KEY_P_2 \n" + " mrs r6, PAC_KEY_P_3 \n" + " stmia r2!, {r3-r6} \n" /* Store the task's dedicated PAC key on the task's context. */ + " clrm {r3-r6} \n" + #endif /* configENABLE_PAC */ " str r2, [r1] \n" /* Save the location from where the context should be restored as the first member of TCB. */ " \n" " select_next_task: \n" @@ -357,6 +382,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/ " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r2!, {r3-r6} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r4 \n" + " msr PAC_KEY_P_2, r5 \n" + " msr PAC_KEY_P_3, r6 \n" + " clrm {r3-r6} \n" + #endif /* configENABLE_PAC */ + " \n" " restore_special_regs: \n" " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ " msr psp, r3 \n" @@ -434,6 +468,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " mrs r1, psplim \n" /* r1 = PSPLIM. */ " mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ " stmdb r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ + " \n" + #if ( configENABLE_PAC == 1 ) + " mrs r3, PAC_KEY_P_3 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r4, PAC_KEY_P_2 \n" + " mrs r5, PAC_KEY_P_1 \n" + " mrs r6, PAC_KEY_P_0 \n" + " stmdb r2!, {r3-r6} \n" /* Store the task's dedicated PAC key on the stack. */ + " clrm {r3-r6} \n" + #endif /* configENABLE_PAC */ " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ " str r2, [r1] \n" /* Save the new top of stack in TCB. */ @@ -451,6 +494,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ " ldr r2, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmia r2!, {r3-r6} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_1, r5 \n" + " msr PAC_KEY_P_0, r6 \n" + " clrm {r3-r6} \n" + #endif /* configENABLE_PAC */ + " \n" " ldmia r2!, {r0, r1, r4} \n" /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ " msr psplim, r1 \n" /* Restore the PSPLIM register value for the task. */ " mov lr, r4 \n" /* LR = r4. */ diff --git a/portable/GCC/ARM_CM33/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM33/non_secure/portmacrocommon.h index 8a8dc7d6ae3..d8ef5b17925 100644 --- a/portable/GCC/ARM_CM33/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM33/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,20 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + /** + * @brief Generates 128-bit task's random PAC key. + * + * The implementation in this file is weak to allow application writers to + * provide their own Random Number Generator implementation for PAC keys randomisation. + * + * @param pulTaskPacKey Pointer to task's PAC key array to be assigned an 128-bit random number. + */ + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + + #define portPAC_KEY_SIZE_BYTES 16 +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -223,63 +239,114 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) +/* +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><-----------><----> +* 16 16 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 70 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) /* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><----> +* 16 16 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) /* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | | | PC, xPSR | EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><-----------><----> +* 16 16 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 69 + + #else + +/* +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | | | PC, xPSR | EXC_RETURN | | +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><----> +* 16 16 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 53 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) /* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ +* +----------+-----------------+------------------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +----------+-----------------+------------------------------+------------+-----+ +* +* <---------><----------------><------------------------------><-----------><----> +* 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + +/* +* +----------+-----------------+------------------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | +* +----------+-----------------+------------------------------+-----+ +* +* <---------><----------------><------------------------------><----> +* 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + +/* +* +----------+-----------------+----------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | PC, xPSR | EXC_RETURN | | | +* +----------+-----------------+----------------------+------------+-----+ +* +* <---------><----------------><----------------------><-----------><----> +* 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ /* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ +* +----------+-----------------+----------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | PC, xPSR | EXC_RETURN | | +* +----------+-----------------+----------------------+-----+ +* +* <---------><----------------><----------------------><----> +* 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ diff --git a/portable/GCC/ARM_CM33_NTZ/non_secure/port.c b/portable/GCC/ARM_CM33_NTZ/non_secure/port.c index 5492c367a6f..0a40a853474 100644 --- a/portable/GCC/ARM_CM33_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_CM33_NTZ/non_secure/port.c @@ -41,6 +41,11 @@ #include "mpu_wrappers.h" #include "mpu_syscall_numbers.h" +#if ( configENABLE_PAC == 1 ) + #include + #include +#endif /* configENABLE_PAC */ + /* Portasm includes. */ #include "portasm.h" @@ -1582,6 +1587,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = pulTaskPacKey[i]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1681,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pxTopOfStack--; + *pxTopOfStack = pulTaskPacKey[i]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -2245,5 +2274,22 @@ BaseType_t xPortIsInsideInterrupt( void ) return ulControl; } + #if ( configENABLE_PAC == 1 ) + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ) + { + static BaseType_t isSeeded = pdFALSE; + if ( isSeeded == pdFALSE ) + { + srand(time(NULL)); + isSeeded = pdTRUE; + } + + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pulTaskPacKey[i] = rand(); + } + } + #endif /* configENABLE_PAC */ + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM33_NTZ/non_secure/portasm.c b/portable/GCC/ARM_CM33_NTZ/non_secure/portasm.c index 7cdff70050d..e0b49ddd64d 100644 --- a/portable/GCC/ARM_CM33_NTZ/non_secure/portasm.c +++ b/portable/GCC/ARM_CM33_NTZ/non_secure/portasm.c @@ -99,6 +99,15 @@ " ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/ " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r1!, {r2-r5} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_3, r5 \n" + " clrm {r2-r5} \n" + #endif /* configENABLE_PAC */ + " \n" " restore_special_regs_first_task: \n" " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ " msr psp, r2 \n" @@ -129,6 +138,15 @@ " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r1] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ + #if ( configENABLE_PAC == 1 ) + " ldmia r0!, {r1-r4} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r1 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r2 \n" + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_0, r4 \n" + " clrm {r1-r4} \n" + #endif /* configENABLE_PAC */ + " \n" " \n" " ldm r0!, {r1-r2} \n" /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ " msr psplim, r1 \n" /* Set this task's PSPLIM value. */ @@ -279,6 +297,14 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " mrs r3, psplim \n" /* r3 = PSPLIM. */ " mrs r4, control \n" /* r4 = CONTROL. */ " stmia r1!, {r2-r4, lr} \n" /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + #if ( configENABLE_PAC == 1 ) + " mrs r2, PAC_KEY_P_0 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r3, PAC_KEY_P_1 \n" + " mrs r4, PAC_KEY_P_2 \n" + " mrs r5, PAC_KEY_P_3 \n" + " stmia r1!, {r2-r5} \n" /* Store the task's dedicated PAC key on the task's context. */ + " clrm {r2-r5} \n" + #endif /* configENABLE_PAC */ " str r1, [r0] \n" /* Save the location from where the context should be restored as the first member of TCB. */ " \n" " select_next_task: \n" @@ -336,6 +362,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/ " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r1!, {r2-r5} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_3, r5 \n" + " clrm {r2-r5} \n" + #endif /* configENABLE_PAC */ + " \n" " restore_special_regs: \n" " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ " msr psp, r2 \n" @@ -381,6 +416,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ " stmdb r0!, {r2-r11} \n" /* Store on the stack - PSPLIM, LR and registers that are not automatically saved. */ " \n" + #if ( configENABLE_PAC == 1 ) + " mrs r1, PAC_KEY_P_3 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r2, PAC_KEY_P_2 \n" + " mrs r3, PAC_KEY_P_1 \n" + " mrs r4, PAC_KEY_P_0 \n" + " stmdb r0!, {r1-r4} \n" /* Store the task's dedicated PAC key on the stack. */ + " clrm {r1-r4} \n" + #endif /* configENABLE_PAC */ + " \n" " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " str r0, [r1] \n" /* Save the new top of stack in TCB. */ @@ -397,6 +441,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmia r0!, {r2-r5} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r3 \n" + " msr PAC_KEY_P_1, r4 \n" + " msr PAC_KEY_P_0, r5 \n" + " clrm {r2-r5} \n" + #endif /* configENABLE_PAC */ + " \n" " ldmia r0!, {r2-r11} \n" /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ " \n" #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) diff --git a/portable/GCC/ARM_CM33_NTZ/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM33_NTZ/non_secure/portmacrocommon.h index 8a8dc7d6ae3..d8ef5b17925 100644 --- a/portable/GCC/ARM_CM33_NTZ/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM33_NTZ/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,20 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + /** + * @brief Generates 128-bit task's random PAC key. + * + * The implementation in this file is weak to allow application writers to + * provide their own Random Number Generator implementation for PAC keys randomisation. + * + * @param pulTaskPacKey Pointer to task's PAC key array to be assigned an 128-bit random number. + */ + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + + #define portPAC_KEY_SIZE_BYTES 16 +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -223,63 +239,114 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) +/* +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><-----------><----> +* 16 16 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 70 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) /* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><----> +* 16 16 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) /* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | | | PC, xPSR | EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><-----------><----> +* 16 16 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 69 + + #else + +/* +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | | | PC, xPSR | EXC_RETURN | | +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><----> +* 16 16 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 53 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) /* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ +* +----------+-----------------+------------------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +----------+-----------------+------------------------------+------------+-----+ +* +* <---------><----------------><------------------------------><-----------><----> +* 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + +/* +* +----------+-----------------+------------------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | +* +----------+-----------------+------------------------------+-----+ +* +* <---------><----------------><------------------------------><----> +* 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + +/* +* +----------+-----------------+----------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | PC, xPSR | EXC_RETURN | | | +* +----------+-----------------+----------------------+------------+-----+ +* +* <---------><----------------><----------------------><-----------><----> +* 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ /* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ +* +----------+-----------------+----------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | PC, xPSR | EXC_RETURN | | +* +----------+-----------------+----------------------+-----+ +* +* <---------><----------------><----------------------><----> +* 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ diff --git a/portable/GCC/ARM_CM35P/non_secure/port.c b/portable/GCC/ARM_CM35P/non_secure/port.c index 5492c367a6f..0a40a853474 100644 --- a/portable/GCC/ARM_CM35P/non_secure/port.c +++ b/portable/GCC/ARM_CM35P/non_secure/port.c @@ -41,6 +41,11 @@ #include "mpu_wrappers.h" #include "mpu_syscall_numbers.h" +#if ( configENABLE_PAC == 1 ) + #include + #include +#endif /* configENABLE_PAC */ + /* Portasm includes. */ #include "portasm.h" @@ -1582,6 +1587,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = pulTaskPacKey[i]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1681,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pxTopOfStack--; + *pxTopOfStack = pulTaskPacKey[i]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -2245,5 +2274,22 @@ BaseType_t xPortIsInsideInterrupt( void ) return ulControl; } + #if ( configENABLE_PAC == 1 ) + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ) + { + static BaseType_t isSeeded = pdFALSE; + if ( isSeeded == pdFALSE ) + { + srand(time(NULL)); + isSeeded = pdTRUE; + } + + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pulTaskPacKey[i] = rand(); + } + } + #endif /* configENABLE_PAC */ + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM35P/non_secure/portasm.c b/portable/GCC/ARM_CM35P/non_secure/portasm.c index f7d3bb18109..a0075a79835 100644 --- a/portable/GCC/ARM_CM35P/non_secure/portasm.c +++ b/portable/GCC/ARM_CM35P/non_secure/portasm.c @@ -99,6 +99,15 @@ " ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/ " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r2!, {r3-r6} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r4 \n" + " msr PAC_KEY_P_2, r5 \n" + " msr PAC_KEY_P_3, r6 \n" + " clrm {r3-r6} \n" + #endif /* configENABLE_PAC */ + " \n" " restore_special_regs_first_task: \n" " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ " msr psp, r3 \n" @@ -131,6 +140,14 @@ " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r3, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r3] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ + #if ( configENABLE_PAC == 1 ) + " ldmia r0!, {r1-r4} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r1 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r2 \n" + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_0, r4 \n" + " clrm {r1-r4} \n" + #endif /* configENABLE_PAC */ " \n" " ldm r0!, {r1-r3} \n" /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ " ldr r4, =xSecureContext \n" @@ -300,6 +317,14 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " mrs r4, psplim \n" /* r4 = PSPLIM. */ " mrs r5, control \n" /* r5 = CONTROL. */ " stmia r2!, {r0, r3-r5, lr} \n" /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + #if ( configENABLE_PAC == 1 ) + " mrs r3, PAC_KEY_P_0 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r4, PAC_KEY_P_1 \n" + " mrs r5, PAC_KEY_P_2 \n" + " mrs r6, PAC_KEY_P_3 \n" + " stmia r2!, {r3-r6} \n" /* Store the task's dedicated PAC key on the task's context. */ + " clrm {r3-r6} \n" + #endif /* configENABLE_PAC */ " str r2, [r1] \n" /* Save the location from where the context should be restored as the first member of TCB. */ " \n" " select_next_task: \n" @@ -357,6 +382,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/ " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r2!, {r3-r6} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r4 \n" + " msr PAC_KEY_P_2, r5 \n" + " msr PAC_KEY_P_3, r6 \n" + " clrm {r3-r6} \n" + #endif /* configENABLE_PAC */ + " \n" " restore_special_regs: \n" " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ " msr psp, r3 \n" @@ -434,6 +468,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " mrs r1, psplim \n" /* r1 = PSPLIM. */ " mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ " stmdb r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ + " \n" + #if ( configENABLE_PAC == 1 ) + " mrs r3, PAC_KEY_P_3 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r4, PAC_KEY_P_2 \n" + " mrs r5, PAC_KEY_P_1 \n" + " mrs r6, PAC_KEY_P_0 \n" + " stmdb r2!, {r3-r6} \n" /* Store the task's dedicated PAC key on the stack. */ + " clrm {r3-r6} \n" + #endif /* configENABLE_PAC */ " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ " str r2, [r1] \n" /* Save the new top of stack in TCB. */ @@ -451,6 +494,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ " ldr r2, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmia r2!, {r3-r6} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_1, r5 \n" + " msr PAC_KEY_P_0, r6 \n" + " clrm {r3-r6} \n" + #endif /* configENABLE_PAC */ + " \n" " ldmia r2!, {r0, r1, r4} \n" /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ " msr psplim, r1 \n" /* Restore the PSPLIM register value for the task. */ " mov lr, r4 \n" /* LR = r4. */ diff --git a/portable/GCC/ARM_CM35P/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM35P/non_secure/portmacrocommon.h index 8a8dc7d6ae3..d8ef5b17925 100644 --- a/portable/GCC/ARM_CM35P/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM35P/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,20 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + /** + * @brief Generates 128-bit task's random PAC key. + * + * The implementation in this file is weak to allow application writers to + * provide their own Random Number Generator implementation for PAC keys randomisation. + * + * @param pulTaskPacKey Pointer to task's PAC key array to be assigned an 128-bit random number. + */ + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + + #define portPAC_KEY_SIZE_BYTES 16 +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -223,63 +239,114 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) +/* +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><-----------><----> +* 16 16 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 70 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) /* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><----> +* 16 16 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) /* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | | | PC, xPSR | EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><-----------><----> +* 16 16 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 69 + + #else + +/* +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | | | PC, xPSR | EXC_RETURN | | +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><----> +* 16 16 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 53 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) /* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ +* +----------+-----------------+------------------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +----------+-----------------+------------------------------+------------+-----+ +* +* <---------><----------------><------------------------------><-----------><----> +* 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + +/* +* +----------+-----------------+------------------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | +* +----------+-----------------+------------------------------+-----+ +* +* <---------><----------------><------------------------------><----> +* 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + +/* +* +----------+-----------------+----------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | PC, xPSR | EXC_RETURN | | | +* +----------+-----------------+----------------------+------------+-----+ +* +* <---------><----------------><----------------------><-----------><----> +* 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ /* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ +* +----------+-----------------+----------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | PC, xPSR | EXC_RETURN | | +* +----------+-----------------+----------------------+-----+ +* +* <---------><----------------><----------------------><----> +* 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ diff --git a/portable/GCC/ARM_CM35P_NTZ/non_secure/port.c b/portable/GCC/ARM_CM35P_NTZ/non_secure/port.c index 5492c367a6f..0a40a853474 100644 --- a/portable/GCC/ARM_CM35P_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_CM35P_NTZ/non_secure/port.c @@ -41,6 +41,11 @@ #include "mpu_wrappers.h" #include "mpu_syscall_numbers.h" +#if ( configENABLE_PAC == 1 ) + #include + #include +#endif /* configENABLE_PAC */ + /* Portasm includes. */ #include "portasm.h" @@ -1582,6 +1587,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = pulTaskPacKey[i]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1681,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pxTopOfStack--; + *pxTopOfStack = pulTaskPacKey[i]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -2245,5 +2274,22 @@ BaseType_t xPortIsInsideInterrupt( void ) return ulControl; } + #if ( configENABLE_PAC == 1 ) + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ) + { + static BaseType_t isSeeded = pdFALSE; + if ( isSeeded == pdFALSE ) + { + srand(time(NULL)); + isSeeded = pdTRUE; + } + + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pulTaskPacKey[i] = rand(); + } + } + #endif /* configENABLE_PAC */ + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM35P_NTZ/non_secure/portasm.c b/portable/GCC/ARM_CM35P_NTZ/non_secure/portasm.c index 7cdff70050d..e0b49ddd64d 100644 --- a/portable/GCC/ARM_CM35P_NTZ/non_secure/portasm.c +++ b/portable/GCC/ARM_CM35P_NTZ/non_secure/portasm.c @@ -99,6 +99,15 @@ " ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/ " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r1!, {r2-r5} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_3, r5 \n" + " clrm {r2-r5} \n" + #endif /* configENABLE_PAC */ + " \n" " restore_special_regs_first_task: \n" " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ " msr psp, r2 \n" @@ -129,6 +138,15 @@ " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r1] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ + #if ( configENABLE_PAC == 1 ) + " ldmia r0!, {r1-r4} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r1 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r2 \n" + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_0, r4 \n" + " clrm {r1-r4} \n" + #endif /* configENABLE_PAC */ + " \n" " \n" " ldm r0!, {r1-r2} \n" /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ " msr psplim, r1 \n" /* Set this task's PSPLIM value. */ @@ -279,6 +297,14 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " mrs r3, psplim \n" /* r3 = PSPLIM. */ " mrs r4, control \n" /* r4 = CONTROL. */ " stmia r1!, {r2-r4, lr} \n" /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + #if ( configENABLE_PAC == 1 ) + " mrs r2, PAC_KEY_P_0 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r3, PAC_KEY_P_1 \n" + " mrs r4, PAC_KEY_P_2 \n" + " mrs r5, PAC_KEY_P_3 \n" + " stmia r1!, {r2-r5} \n" /* Store the task's dedicated PAC key on the task's context. */ + " clrm {r2-r5} \n" + #endif /* configENABLE_PAC */ " str r1, [r0] \n" /* Save the location from where the context should be restored as the first member of TCB. */ " \n" " select_next_task: \n" @@ -336,6 +362,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/ " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r1!, {r2-r5} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_3, r5 \n" + " clrm {r2-r5} \n" + #endif /* configENABLE_PAC */ + " \n" " restore_special_regs: \n" " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ " msr psp, r2 \n" @@ -381,6 +416,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ " stmdb r0!, {r2-r11} \n" /* Store on the stack - PSPLIM, LR and registers that are not automatically saved. */ " \n" + #if ( configENABLE_PAC == 1 ) + " mrs r1, PAC_KEY_P_3 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r2, PAC_KEY_P_2 \n" + " mrs r3, PAC_KEY_P_1 \n" + " mrs r4, PAC_KEY_P_0 \n" + " stmdb r0!, {r1-r4} \n" /* Store the task's dedicated PAC key on the stack. */ + " clrm {r1-r4} \n" + #endif /* configENABLE_PAC */ + " \n" " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " str r0, [r1] \n" /* Save the new top of stack in TCB. */ @@ -397,6 +441,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmia r0!, {r2-r5} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r3 \n" + " msr PAC_KEY_P_1, r4 \n" + " msr PAC_KEY_P_0, r5 \n" + " clrm {r2-r5} \n" + #endif /* configENABLE_PAC */ + " \n" " ldmia r0!, {r2-r11} \n" /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ " \n" #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) diff --git a/portable/GCC/ARM_CM35P_NTZ/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM35P_NTZ/non_secure/portmacrocommon.h index 8a8dc7d6ae3..d8ef5b17925 100644 --- a/portable/GCC/ARM_CM35P_NTZ/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM35P_NTZ/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,20 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + /** + * @brief Generates 128-bit task's random PAC key. + * + * The implementation in this file is weak to allow application writers to + * provide their own Random Number Generator implementation for PAC keys randomisation. + * + * @param pulTaskPacKey Pointer to task's PAC key array to be assigned an 128-bit random number. + */ + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + + #define portPAC_KEY_SIZE_BYTES 16 +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -223,63 +239,114 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) +/* +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><-----------><----> +* 16 16 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 70 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) /* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><----> +* 16 16 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) /* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | | | PC, xPSR | EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><-----------><----> +* 16 16 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 69 + + #else + +/* +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | | | PC, xPSR | EXC_RETURN | | +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><----> +* 16 16 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 53 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) /* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ +* +----------+-----------------+------------------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +----------+-----------------+------------------------------+------------+-----+ +* +* <---------><----------------><------------------------------><-----------><----> +* 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + +/* +* +----------+-----------------+------------------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | +* +----------+-----------------+------------------------------+-----+ +* +* <---------><----------------><------------------------------><----> +* 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + +/* +* +----------+-----------------+----------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | PC, xPSR | EXC_RETURN | | | +* +----------+-----------------+----------------------+------------+-----+ +* +* <---------><----------------><----------------------><-----------><----> +* 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ /* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ +* +----------+-----------------+----------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | PC, xPSR | EXC_RETURN | | +* +----------+-----------------+----------------------+-----+ +* +* <---------><----------------><----------------------><----> +* 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ diff --git a/portable/GCC/ARM_CM55/non_secure/port.c b/portable/GCC/ARM_CM55/non_secure/port.c index 5492c367a6f..0a40a853474 100644 --- a/portable/GCC/ARM_CM55/non_secure/port.c +++ b/portable/GCC/ARM_CM55/non_secure/port.c @@ -41,6 +41,11 @@ #include "mpu_wrappers.h" #include "mpu_syscall_numbers.h" +#if ( configENABLE_PAC == 1 ) + #include + #include +#endif /* configENABLE_PAC */ + /* Portasm includes. */ #include "portasm.h" @@ -1582,6 +1587,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = pulTaskPacKey[i]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1681,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pxTopOfStack--; + *pxTopOfStack = pulTaskPacKey[i]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -2245,5 +2274,22 @@ BaseType_t xPortIsInsideInterrupt( void ) return ulControl; } + #if ( configENABLE_PAC == 1 ) + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ) + { + static BaseType_t isSeeded = pdFALSE; + if ( isSeeded == pdFALSE ) + { + srand(time(NULL)); + isSeeded = pdTRUE; + } + + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pulTaskPacKey[i] = rand(); + } + } + #endif /* configENABLE_PAC */ + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM55/non_secure/portasm.c b/portable/GCC/ARM_CM55/non_secure/portasm.c index f7d3bb18109..a0075a79835 100644 --- a/portable/GCC/ARM_CM55/non_secure/portasm.c +++ b/portable/GCC/ARM_CM55/non_secure/portasm.c @@ -99,6 +99,15 @@ " ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/ " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r2!, {r3-r6} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r4 \n" + " msr PAC_KEY_P_2, r5 \n" + " msr PAC_KEY_P_3, r6 \n" + " clrm {r3-r6} \n" + #endif /* configENABLE_PAC */ + " \n" " restore_special_regs_first_task: \n" " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ " msr psp, r3 \n" @@ -131,6 +140,14 @@ " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r3, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r3] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ + #if ( configENABLE_PAC == 1 ) + " ldmia r0!, {r1-r4} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r1 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r2 \n" + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_0, r4 \n" + " clrm {r1-r4} \n" + #endif /* configENABLE_PAC */ " \n" " ldm r0!, {r1-r3} \n" /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ " ldr r4, =xSecureContext \n" @@ -300,6 +317,14 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " mrs r4, psplim \n" /* r4 = PSPLIM. */ " mrs r5, control \n" /* r5 = CONTROL. */ " stmia r2!, {r0, r3-r5, lr} \n" /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + #if ( configENABLE_PAC == 1 ) + " mrs r3, PAC_KEY_P_0 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r4, PAC_KEY_P_1 \n" + " mrs r5, PAC_KEY_P_2 \n" + " mrs r6, PAC_KEY_P_3 \n" + " stmia r2!, {r3-r6} \n" /* Store the task's dedicated PAC key on the task's context. */ + " clrm {r3-r6} \n" + #endif /* configENABLE_PAC */ " str r2, [r1] \n" /* Save the location from where the context should be restored as the first member of TCB. */ " \n" " select_next_task: \n" @@ -357,6 +382,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/ " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r2!, {r3-r6} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r4 \n" + " msr PAC_KEY_P_2, r5 \n" + " msr PAC_KEY_P_3, r6 \n" + " clrm {r3-r6} \n" + #endif /* configENABLE_PAC */ + " \n" " restore_special_regs: \n" " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ " msr psp, r3 \n" @@ -434,6 +468,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " mrs r1, psplim \n" /* r1 = PSPLIM. */ " mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ " stmdb r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ + " \n" + #if ( configENABLE_PAC == 1 ) + " mrs r3, PAC_KEY_P_3 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r4, PAC_KEY_P_2 \n" + " mrs r5, PAC_KEY_P_1 \n" + " mrs r6, PAC_KEY_P_0 \n" + " stmdb r2!, {r3-r6} \n" /* Store the task's dedicated PAC key on the stack. */ + " clrm {r3-r6} \n" + #endif /* configENABLE_PAC */ " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ " str r2, [r1] \n" /* Save the new top of stack in TCB. */ @@ -451,6 +494,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ " ldr r2, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmia r2!, {r3-r6} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_1, r5 \n" + " msr PAC_KEY_P_0, r6 \n" + " clrm {r3-r6} \n" + #endif /* configENABLE_PAC */ + " \n" " ldmia r2!, {r0, r1, r4} \n" /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ " msr psplim, r1 \n" /* Restore the PSPLIM register value for the task. */ " mov lr, r4 \n" /* LR = r4. */ diff --git a/portable/GCC/ARM_CM55/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM55/non_secure/portmacrocommon.h index 8a8dc7d6ae3..d8ef5b17925 100644 --- a/portable/GCC/ARM_CM55/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM55/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,20 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + /** + * @brief Generates 128-bit task's random PAC key. + * + * The implementation in this file is weak to allow application writers to + * provide their own Random Number Generator implementation for PAC keys randomisation. + * + * @param pulTaskPacKey Pointer to task's PAC key array to be assigned an 128-bit random number. + */ + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + + #define portPAC_KEY_SIZE_BYTES 16 +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -223,63 +239,114 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) +/* +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><-----------><----> +* 16 16 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 70 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) /* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><----> +* 16 16 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) /* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | | | PC, xPSR | EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><-----------><----> +* 16 16 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 69 + + #else + +/* +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | | | PC, xPSR | EXC_RETURN | | +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><----> +* 16 16 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 53 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) /* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ +* +----------+-----------------+------------------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +----------+-----------------+------------------------------+------------+-----+ +* +* <---------><----------------><------------------------------><-----------><----> +* 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + +/* +* +----------+-----------------+------------------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | +* +----------+-----------------+------------------------------+-----+ +* +* <---------><----------------><------------------------------><----> +* 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + +/* +* +----------+-----------------+----------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | PC, xPSR | EXC_RETURN | | | +* +----------+-----------------+----------------------+------------+-----+ +* +* <---------><----------------><----------------------><-----------><----> +* 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ /* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ +* +----------+-----------------+----------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | PC, xPSR | EXC_RETURN | | +* +----------+-----------------+----------------------+-----+ +* +* <---------><----------------><----------------------><----> +* 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ diff --git a/portable/GCC/ARM_CM55_NTZ/non_secure/port.c b/portable/GCC/ARM_CM55_NTZ/non_secure/port.c index 5492c367a6f..0a40a853474 100644 --- a/portable/GCC/ARM_CM55_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_CM55_NTZ/non_secure/port.c @@ -41,6 +41,11 @@ #include "mpu_wrappers.h" #include "mpu_syscall_numbers.h" +#if ( configENABLE_PAC == 1 ) + #include + #include +#endif /* configENABLE_PAC */ + /* Portasm includes. */ #include "portasm.h" @@ -1582,6 +1587,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = pulTaskPacKey[i]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1681,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pxTopOfStack--; + *pxTopOfStack = pulTaskPacKey[i]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -2245,5 +2274,22 @@ BaseType_t xPortIsInsideInterrupt( void ) return ulControl; } + #if ( configENABLE_PAC == 1 ) + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ) + { + static BaseType_t isSeeded = pdFALSE; + if ( isSeeded == pdFALSE ) + { + srand(time(NULL)); + isSeeded = pdTRUE; + } + + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pulTaskPacKey[i] = rand(); + } + } + #endif /* configENABLE_PAC */ + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM55_NTZ/non_secure/portasm.c b/portable/GCC/ARM_CM55_NTZ/non_secure/portasm.c index 7cdff70050d..e0b49ddd64d 100644 --- a/portable/GCC/ARM_CM55_NTZ/non_secure/portasm.c +++ b/portable/GCC/ARM_CM55_NTZ/non_secure/portasm.c @@ -99,6 +99,15 @@ " ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/ " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r1!, {r2-r5} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_3, r5 \n" + " clrm {r2-r5} \n" + #endif /* configENABLE_PAC */ + " \n" " restore_special_regs_first_task: \n" " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ " msr psp, r2 \n" @@ -129,6 +138,15 @@ " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r1] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ + #if ( configENABLE_PAC == 1 ) + " ldmia r0!, {r1-r4} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r1 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r2 \n" + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_0, r4 \n" + " clrm {r1-r4} \n" + #endif /* configENABLE_PAC */ + " \n" " \n" " ldm r0!, {r1-r2} \n" /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ " msr psplim, r1 \n" /* Set this task's PSPLIM value. */ @@ -279,6 +297,14 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " mrs r3, psplim \n" /* r3 = PSPLIM. */ " mrs r4, control \n" /* r4 = CONTROL. */ " stmia r1!, {r2-r4, lr} \n" /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + #if ( configENABLE_PAC == 1 ) + " mrs r2, PAC_KEY_P_0 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r3, PAC_KEY_P_1 \n" + " mrs r4, PAC_KEY_P_2 \n" + " mrs r5, PAC_KEY_P_3 \n" + " stmia r1!, {r2-r5} \n" /* Store the task's dedicated PAC key on the task's context. */ + " clrm {r2-r5} \n" + #endif /* configENABLE_PAC */ " str r1, [r0] \n" /* Save the location from where the context should be restored as the first member of TCB. */ " \n" " select_next_task: \n" @@ -336,6 +362,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/ " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r1!, {r2-r5} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_3, r5 \n" + " clrm {r2-r5} \n" + #endif /* configENABLE_PAC */ + " \n" " restore_special_regs: \n" " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ " msr psp, r2 \n" @@ -381,6 +416,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ " stmdb r0!, {r2-r11} \n" /* Store on the stack - PSPLIM, LR and registers that are not automatically saved. */ " \n" + #if ( configENABLE_PAC == 1 ) + " mrs r1, PAC_KEY_P_3 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r2, PAC_KEY_P_2 \n" + " mrs r3, PAC_KEY_P_1 \n" + " mrs r4, PAC_KEY_P_0 \n" + " stmdb r0!, {r1-r4} \n" /* Store the task's dedicated PAC key on the stack. */ + " clrm {r1-r4} \n" + #endif /* configENABLE_PAC */ + " \n" " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " str r0, [r1] \n" /* Save the new top of stack in TCB. */ @@ -397,6 +441,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmia r0!, {r2-r5} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r3 \n" + " msr PAC_KEY_P_1, r4 \n" + " msr PAC_KEY_P_0, r5 \n" + " clrm {r2-r5} \n" + #endif /* configENABLE_PAC */ + " \n" " ldmia r0!, {r2-r11} \n" /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ " \n" #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) diff --git a/portable/GCC/ARM_CM55_NTZ/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM55_NTZ/non_secure/portmacrocommon.h index 8a8dc7d6ae3..d8ef5b17925 100644 --- a/portable/GCC/ARM_CM55_NTZ/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM55_NTZ/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,20 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + /** + * @brief Generates 128-bit task's random PAC key. + * + * The implementation in this file is weak to allow application writers to + * provide their own Random Number Generator implementation for PAC keys randomisation. + * + * @param pulTaskPacKey Pointer to task's PAC key array to be assigned an 128-bit random number. + */ + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + + #define portPAC_KEY_SIZE_BYTES 16 +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -223,63 +239,114 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) +/* +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><-----------><----> +* 16 16 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 70 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) /* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><----> +* 16 16 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) /* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | | | PC, xPSR | EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><-----------><----> +* 16 16 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 69 + + #else + +/* +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | | | PC, xPSR | EXC_RETURN | | +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><----> +* 16 16 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 53 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) /* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ +* +----------+-----------------+------------------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +----------+-----------------+------------------------------+------------+-----+ +* +* <---------><----------------><------------------------------><-----------><----> +* 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + +/* +* +----------+-----------------+------------------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | +* +----------+-----------------+------------------------------+-----+ +* +* <---------><----------------><------------------------------><----> +* 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + +/* +* +----------+-----------------+----------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | PC, xPSR | EXC_RETURN | | | +* +----------+-----------------+----------------------+------------+-----+ +* +* <---------><----------------><----------------------><-----------><----> +* 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ /* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ +* +----------+-----------------+----------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | PC, xPSR | EXC_RETURN | | +* +----------+-----------------+----------------------+-----+ +* +* <---------><----------------><----------------------><----> +* 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ diff --git a/portable/GCC/ARM_CM85/non_secure/port.c b/portable/GCC/ARM_CM85/non_secure/port.c index 5492c367a6f..0a40a853474 100644 --- a/portable/GCC/ARM_CM85/non_secure/port.c +++ b/portable/GCC/ARM_CM85/non_secure/port.c @@ -41,6 +41,11 @@ #include "mpu_wrappers.h" #include "mpu_syscall_numbers.h" +#if ( configENABLE_PAC == 1 ) + #include + #include +#endif /* configENABLE_PAC */ + /* Portasm includes. */ #include "portasm.h" @@ -1582,6 +1587,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = pulTaskPacKey[i]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1681,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pxTopOfStack--; + *pxTopOfStack = pulTaskPacKey[i]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -2245,5 +2274,22 @@ BaseType_t xPortIsInsideInterrupt( void ) return ulControl; } + #if ( configENABLE_PAC == 1 ) + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ) + { + static BaseType_t isSeeded = pdFALSE; + if ( isSeeded == pdFALSE ) + { + srand(time(NULL)); + isSeeded = pdTRUE; + } + + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pulTaskPacKey[i] = rand(); + } + } + #endif /* configENABLE_PAC */ + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM85/non_secure/portasm.c b/portable/GCC/ARM_CM85/non_secure/portasm.c index f7d3bb18109..a0075a79835 100644 --- a/portable/GCC/ARM_CM85/non_secure/portasm.c +++ b/portable/GCC/ARM_CM85/non_secure/portasm.c @@ -99,6 +99,15 @@ " ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/ " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r2!, {r3-r6} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r4 \n" + " msr PAC_KEY_P_2, r5 \n" + " msr PAC_KEY_P_3, r6 \n" + " clrm {r3-r6} \n" + #endif /* configENABLE_PAC */ + " \n" " restore_special_regs_first_task: \n" " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ " msr psp, r3 \n" @@ -131,6 +140,14 @@ " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r3, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r3] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ + #if ( configENABLE_PAC == 1 ) + " ldmia r0!, {r1-r4} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r1 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r2 \n" + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_0, r4 \n" + " clrm {r1-r4} \n" + #endif /* configENABLE_PAC */ " \n" " ldm r0!, {r1-r3} \n" /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ " ldr r4, =xSecureContext \n" @@ -300,6 +317,14 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " mrs r4, psplim \n" /* r4 = PSPLIM. */ " mrs r5, control \n" /* r5 = CONTROL. */ " stmia r2!, {r0, r3-r5, lr} \n" /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + #if ( configENABLE_PAC == 1 ) + " mrs r3, PAC_KEY_P_0 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r4, PAC_KEY_P_1 \n" + " mrs r5, PAC_KEY_P_2 \n" + " mrs r6, PAC_KEY_P_3 \n" + " stmia r2!, {r3-r6} \n" /* Store the task's dedicated PAC key on the task's context. */ + " clrm {r3-r6} \n" + #endif /* configENABLE_PAC */ " str r2, [r1] \n" /* Save the location from where the context should be restored as the first member of TCB. */ " \n" " select_next_task: \n" @@ -357,6 +382,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/ " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r2!, {r3-r6} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r4 \n" + " msr PAC_KEY_P_2, r5 \n" + " msr PAC_KEY_P_3, r6 \n" + " clrm {r3-r6} \n" + #endif /* configENABLE_PAC */ + " \n" " restore_special_regs: \n" " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ " msr psp, r3 \n" @@ -434,6 +468,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " mrs r1, psplim \n" /* r1 = PSPLIM. */ " mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ " stmdb r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ + " \n" + #if ( configENABLE_PAC == 1 ) + " mrs r3, PAC_KEY_P_3 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r4, PAC_KEY_P_2 \n" + " mrs r5, PAC_KEY_P_1 \n" + " mrs r6, PAC_KEY_P_0 \n" + " stmdb r2!, {r3-r6} \n" /* Store the task's dedicated PAC key on the stack. */ + " clrm {r3-r6} \n" + #endif /* configENABLE_PAC */ " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ " str r2, [r1] \n" /* Save the new top of stack in TCB. */ @@ -451,6 +494,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ " ldr r2, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmia r2!, {r3-r6} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_1, r5 \n" + " msr PAC_KEY_P_0, r6 \n" + " clrm {r3-r6} \n" + #endif /* configENABLE_PAC */ + " \n" " ldmia r2!, {r0, r1, r4} \n" /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ " msr psplim, r1 \n" /* Restore the PSPLIM register value for the task. */ " mov lr, r4 \n" /* LR = r4. */ diff --git a/portable/GCC/ARM_CM85/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM85/non_secure/portmacrocommon.h index 8a8dc7d6ae3..d8ef5b17925 100644 --- a/portable/GCC/ARM_CM85/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM85/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,20 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + /** + * @brief Generates 128-bit task's random PAC key. + * + * The implementation in this file is weak to allow application writers to + * provide their own Random Number Generator implementation for PAC keys randomisation. + * + * @param pulTaskPacKey Pointer to task's PAC key array to be assigned an 128-bit random number. + */ + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + + #define portPAC_KEY_SIZE_BYTES 16 +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -223,63 +239,114 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) +/* +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><-----------><----> +* 16 16 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 70 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) /* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><----> +* 16 16 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) /* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | | | PC, xPSR | EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><-----------><----> +* 16 16 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 69 + + #else + +/* +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | | | PC, xPSR | EXC_RETURN | | +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><----> +* 16 16 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 53 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) /* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ +* +----------+-----------------+------------------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +----------+-----------------+------------------------------+------------+-----+ +* +* <---------><----------------><------------------------------><-----------><----> +* 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + +/* +* +----------+-----------------+------------------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | +* +----------+-----------------+------------------------------+-----+ +* +* <---------><----------------><------------------------------><----> +* 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + +/* +* +----------+-----------------+----------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | PC, xPSR | EXC_RETURN | | | +* +----------+-----------------+----------------------+------------+-----+ +* +* <---------><----------------><----------------------><-----------><----> +* 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ /* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ +* +----------+-----------------+----------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | PC, xPSR | EXC_RETURN | | +* +----------+-----------------+----------------------+-----+ +* +* <---------><----------------><----------------------><----> +* 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ diff --git a/portable/GCC/ARM_CM85_NTZ/non_secure/port.c b/portable/GCC/ARM_CM85_NTZ/non_secure/port.c index 5492c367a6f..0a40a853474 100644 --- a/portable/GCC/ARM_CM85_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_CM85_NTZ/non_secure/port.c @@ -41,6 +41,11 @@ #include "mpu_wrappers.h" #include "mpu_syscall_numbers.h" +#if ( configENABLE_PAC == 1 ) + #include + #include +#endif /* configENABLE_PAC */ + /* Portasm includes. */ #include "portasm.h" @@ -1582,6 +1587,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = pulTaskPacKey[i]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1681,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pxTopOfStack--; + *pxTopOfStack = pulTaskPacKey[i]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -2245,5 +2274,22 @@ BaseType_t xPortIsInsideInterrupt( void ) return ulControl; } + #if ( configENABLE_PAC == 1 ) + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ) + { + static BaseType_t isSeeded = pdFALSE; + if ( isSeeded == pdFALSE ) + { + srand(time(NULL)); + isSeeded = pdTRUE; + } + + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pulTaskPacKey[i] = rand(); + } + } + #endif /* configENABLE_PAC */ + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM85_NTZ/non_secure/portasm.c b/portable/GCC/ARM_CM85_NTZ/non_secure/portasm.c index 7cdff70050d..e0b49ddd64d 100644 --- a/portable/GCC/ARM_CM85_NTZ/non_secure/portasm.c +++ b/portable/GCC/ARM_CM85_NTZ/non_secure/portasm.c @@ -99,6 +99,15 @@ " ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/ " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r1!, {r2-r5} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_3, r5 \n" + " clrm {r2-r5} \n" + #endif /* configENABLE_PAC */ + " \n" " restore_special_regs_first_task: \n" " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ " msr psp, r2 \n" @@ -129,6 +138,15 @@ " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r1] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ + #if ( configENABLE_PAC == 1 ) + " ldmia r0!, {r1-r4} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r1 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r2 \n" + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_0, r4 \n" + " clrm {r1-r4} \n" + #endif /* configENABLE_PAC */ + " \n" " \n" " ldm r0!, {r1-r2} \n" /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ " msr psplim, r1 \n" /* Set this task's PSPLIM value. */ @@ -279,6 +297,14 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " mrs r3, psplim \n" /* r3 = PSPLIM. */ " mrs r4, control \n" /* r4 = CONTROL. */ " stmia r1!, {r2-r4, lr} \n" /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + #if ( configENABLE_PAC == 1 ) + " mrs r2, PAC_KEY_P_0 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r3, PAC_KEY_P_1 \n" + " mrs r4, PAC_KEY_P_2 \n" + " mrs r5, PAC_KEY_P_3 \n" + " stmia r1!, {r2-r5} \n" /* Store the task's dedicated PAC key on the task's context. */ + " clrm {r2-r5} \n" + #endif /* configENABLE_PAC */ " str r1, [r0] \n" /* Save the location from where the context should be restored as the first member of TCB. */ " \n" " select_next_task: \n" @@ -336,6 +362,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/ " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r1!, {r2-r5} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_3, r5 \n" + " clrm {r2-r5} \n" + #endif /* configENABLE_PAC */ + " \n" " restore_special_regs: \n" " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ " msr psp, r2 \n" @@ -381,6 +416,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ " stmdb r0!, {r2-r11} \n" /* Store on the stack - PSPLIM, LR and registers that are not automatically saved. */ " \n" + #if ( configENABLE_PAC == 1 ) + " mrs r1, PAC_KEY_P_3 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r2, PAC_KEY_P_2 \n" + " mrs r3, PAC_KEY_P_1 \n" + " mrs r4, PAC_KEY_P_0 \n" + " stmdb r0!, {r1-r4} \n" /* Store the task's dedicated PAC key on the stack. */ + " clrm {r1-r4} \n" + #endif /* configENABLE_PAC */ + " \n" " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " str r0, [r1] \n" /* Save the new top of stack in TCB. */ @@ -397,6 +441,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmia r0!, {r2-r5} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r3 \n" + " msr PAC_KEY_P_1, r4 \n" + " msr PAC_KEY_P_0, r5 \n" + " clrm {r2-r5} \n" + #endif /* configENABLE_PAC */ + " \n" " ldmia r0!, {r2-r11} \n" /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ " \n" #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) diff --git a/portable/GCC/ARM_CM85_NTZ/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM85_NTZ/non_secure/portmacrocommon.h index 8a8dc7d6ae3..d8ef5b17925 100644 --- a/portable/GCC/ARM_CM85_NTZ/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM85_NTZ/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,20 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + /** + * @brief Generates 128-bit task's random PAC key. + * + * The implementation in this file is weak to allow application writers to + * provide their own Random Number Generator implementation for PAC keys randomisation. + * + * @param pulTaskPacKey Pointer to task's PAC key array to be assigned an 128-bit random number. + */ + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + + #define portPAC_KEY_SIZE_BYTES 16 +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -223,63 +239,114 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) +/* +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><-----------><----> +* 16 16 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 70 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) /* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><----> +* 16 16 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) /* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | | | PC, xPSR | EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><-----------><----> +* 16 16 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 69 + + #else + +/* +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | | | PC, xPSR | EXC_RETURN | | +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><----> +* 16 16 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 53 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) /* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ +* +----------+-----------------+------------------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +----------+-----------------+------------------------------+------------+-----+ +* +* <---------><----------------><------------------------------><-----------><----> +* 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + +/* +* +----------+-----------------+------------------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | +* +----------+-----------------+------------------------------+-----+ +* +* <---------><----------------><------------------------------><----> +* 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + +/* +* +----------+-----------------+----------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | PC, xPSR | EXC_RETURN | | | +* +----------+-----------------+----------------------+------------+-----+ +* +* <---------><----------------><----------------------><-----------><----> +* 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ /* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ +* +----------+-----------------+----------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | PC, xPSR | EXC_RETURN | | +* +----------+-----------------+----------------------+-----+ +* +* <---------><----------------><----------------------><----> +* 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ diff --git a/portable/IAR/ARM_CM23/non_secure/port.c b/portable/IAR/ARM_CM23/non_secure/port.c index 5492c367a6f..0a40a853474 100644 --- a/portable/IAR/ARM_CM23/non_secure/port.c +++ b/portable/IAR/ARM_CM23/non_secure/port.c @@ -41,6 +41,11 @@ #include "mpu_wrappers.h" #include "mpu_syscall_numbers.h" +#if ( configENABLE_PAC == 1 ) + #include + #include +#endif /* configENABLE_PAC */ + /* Portasm includes. */ #include "portasm.h" @@ -1582,6 +1587,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = pulTaskPacKey[i]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1681,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pxTopOfStack--; + *pxTopOfStack = pulTaskPacKey[i]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -2245,5 +2274,22 @@ BaseType_t xPortIsInsideInterrupt( void ) return ulControl; } + #if ( configENABLE_PAC == 1 ) + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ) + { + static BaseType_t isSeeded = pdFALSE; + if ( isSeeded == pdFALSE ) + { + srand(time(NULL)); + isSeeded = pdTRUE; + } + + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pulTaskPacKey[i] = rand(); + } + } + #endif /* configENABLE_PAC */ + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM23/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM23/non_secure/portmacrocommon.h index 8a8dc7d6ae3..d8ef5b17925 100644 --- a/portable/IAR/ARM_CM23/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM23/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,20 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + /** + * @brief Generates 128-bit task's random PAC key. + * + * The implementation in this file is weak to allow application writers to + * provide their own Random Number Generator implementation for PAC keys randomisation. + * + * @param pulTaskPacKey Pointer to task's PAC key array to be assigned an 128-bit random number. + */ + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + + #define portPAC_KEY_SIZE_BYTES 16 +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -223,63 +239,114 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) +/* +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><-----------><----> +* 16 16 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 70 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) /* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><----> +* 16 16 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) /* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | | | PC, xPSR | EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><-----------><----> +* 16 16 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 69 + + #else + +/* +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | | | PC, xPSR | EXC_RETURN | | +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><----> +* 16 16 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 53 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) /* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ +* +----------+-----------------+------------------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +----------+-----------------+------------------------------+------------+-----+ +* +* <---------><----------------><------------------------------><-----------><----> +* 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + +/* +* +----------+-----------------+------------------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | +* +----------+-----------------+------------------------------+-----+ +* +* <---------><----------------><------------------------------><----> +* 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + +/* +* +----------+-----------------+----------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | PC, xPSR | EXC_RETURN | | | +* +----------+-----------------+----------------------+------------+-----+ +* +* <---------><----------------><----------------------><-----------><----> +* 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ /* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ +* +----------+-----------------+----------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | PC, xPSR | EXC_RETURN | | +* +----------+-----------------+----------------------+-----+ +* +* <---------><----------------><----------------------><----> +* 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ diff --git a/portable/IAR/ARM_CM23_NTZ/non_secure/port.c b/portable/IAR/ARM_CM23_NTZ/non_secure/port.c index 5492c367a6f..0a40a853474 100644 --- a/portable/IAR/ARM_CM23_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_CM23_NTZ/non_secure/port.c @@ -41,6 +41,11 @@ #include "mpu_wrappers.h" #include "mpu_syscall_numbers.h" +#if ( configENABLE_PAC == 1 ) + #include + #include +#endif /* configENABLE_PAC */ + /* Portasm includes. */ #include "portasm.h" @@ -1582,6 +1587,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = pulTaskPacKey[i]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1681,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pxTopOfStack--; + *pxTopOfStack = pulTaskPacKey[i]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -2245,5 +2274,22 @@ BaseType_t xPortIsInsideInterrupt( void ) return ulControl; } + #if ( configENABLE_PAC == 1 ) + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ) + { + static BaseType_t isSeeded = pdFALSE; + if ( isSeeded == pdFALSE ) + { + srand(time(NULL)); + isSeeded = pdTRUE; + } + + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pulTaskPacKey[i] = rand(); + } + } + #endif /* configENABLE_PAC */ + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM23_NTZ/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM23_NTZ/non_secure/portmacrocommon.h index 8a8dc7d6ae3..d8ef5b17925 100644 --- a/portable/IAR/ARM_CM23_NTZ/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM23_NTZ/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,20 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + /** + * @brief Generates 128-bit task's random PAC key. + * + * The implementation in this file is weak to allow application writers to + * provide their own Random Number Generator implementation for PAC keys randomisation. + * + * @param pulTaskPacKey Pointer to task's PAC key array to be assigned an 128-bit random number. + */ + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + + #define portPAC_KEY_SIZE_BYTES 16 +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -223,63 +239,114 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) +/* +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><-----------><----> +* 16 16 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 70 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) /* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><----> +* 16 16 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) /* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | | | PC, xPSR | EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><-----------><----> +* 16 16 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 69 + + #else + +/* +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | | | PC, xPSR | EXC_RETURN | | +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><----> +* 16 16 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 53 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) /* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ +* +----------+-----------------+------------------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +----------+-----------------+------------------------------+------------+-----+ +* +* <---------><----------------><------------------------------><-----------><----> +* 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + +/* +* +----------+-----------------+------------------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | +* +----------+-----------------+------------------------------+-----+ +* +* <---------><----------------><------------------------------><----> +* 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + +/* +* +----------+-----------------+----------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | PC, xPSR | EXC_RETURN | | | +* +----------+-----------------+----------------------+------------+-----+ +* +* <---------><----------------><----------------------><-----------><----> +* 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ /* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ +* +----------+-----------------+----------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | PC, xPSR | EXC_RETURN | | +* +----------+-----------------+----------------------+-----+ +* +* <---------><----------------><----------------------><----> +* 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ diff --git a/portable/IAR/ARM_CM33/non_secure/port.c b/portable/IAR/ARM_CM33/non_secure/port.c index 5492c367a6f..0a40a853474 100644 --- a/portable/IAR/ARM_CM33/non_secure/port.c +++ b/portable/IAR/ARM_CM33/non_secure/port.c @@ -41,6 +41,11 @@ #include "mpu_wrappers.h" #include "mpu_syscall_numbers.h" +#if ( configENABLE_PAC == 1 ) + #include + #include +#endif /* configENABLE_PAC */ + /* Portasm includes. */ #include "portasm.h" @@ -1582,6 +1587,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = pulTaskPacKey[i]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1681,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pxTopOfStack--; + *pxTopOfStack = pulTaskPacKey[i]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -2245,5 +2274,22 @@ BaseType_t xPortIsInsideInterrupt( void ) return ulControl; } + #if ( configENABLE_PAC == 1 ) + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ) + { + static BaseType_t isSeeded = pdFALSE; + if ( isSeeded == pdFALSE ) + { + srand(time(NULL)); + isSeeded = pdTRUE; + } + + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pulTaskPacKey[i] = rand(); + } + } + #endif /* configENABLE_PAC */ + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM33/non_secure/portasm.s b/portable/IAR/ARM_CM33/non_secure/portasm.s index c77fd39403b..508694f5d00 100644 --- a/portable/IAR/ARM_CM33/non_secure/portasm.s +++ b/portable/IAR/ARM_CM33/non_secure/portasm.s @@ -27,12 +27,13 @@ * https://github.com/FreeRTOS * */ -/* Including FreeRTOSConfig.h here will cause build errors if the header file -contains code not understood by the assembler - for example the 'extern' keyword. -To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so +/* Including FreeRTOSConfig.h and portasm.h here will cause build errors if the +header file contains code not understood by the assembler - for example the 'extern' +keyword. To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so the code is included in C files but excluded by the preprocessor in assembly files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ #include "FreeRTOSConfig.h" +#include "portasm.h" /* System call numbers includes. */ #include "mpu_syscall_numbers.h" @@ -150,6 +151,14 @@ vRestoreContextOfFirstTask: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* r1 = pxCurrentTCB.*/ ldr r2, [r1] /* r2 = Location of saved context in TCB. */ + #if ( configENABLE_PAC == 1 ) + ldmdb r2!, {r3-r6} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r4 + msr PAC_KEY_P_2, r5 + msr PAC_KEY_P_3, r6 + clrm {r3-r6} + #endif /* configENABLE_PAC */ restore_special_regs_first_task: ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ @@ -176,6 +185,14 @@ vRestoreContextOfFirstTask: ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r3, [r2] /* Read pxCurrentTCB. */ ldr r0, [r3] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ + #if ( configENABLE_PAC == 1 ) + ldmia r0!, {r1-r4} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r1 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r2 + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_0, r4 + clrm {r1-r4} + #endif /* configENABLE_PAC */ ldm r0!, {r1-r3} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ ldr r4, =xSecureContext @@ -271,6 +288,14 @@ PendSV_Handler: mrs r4, psplim /* r4 = PSPLIM. */ mrs r5, control /* r5 = CONTROL. */ stmia r2!, {r0, r3-r5, lr} /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + #if ( configENABLE_PAC == 1 ) + mrs r3, PAC_KEY_P_0 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r4, PAC_KEY_P_1 + mrs r5, PAC_KEY_P_2 + mrs r6, PAC_KEY_P_3 + stmia r2!, {r3-r6} /* Store the task's dedicated PAC key on the task's context. */ + clrm {r3-r6} + #endif /* configENABLE_PAC */ str r2, [r1] /* Save the location from where the context should be restored as the first member of TCB. */ select_next_task: @@ -327,6 +352,14 @@ PendSV_Handler: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* r1 = pxCurrentTCB.*/ ldr r2, [r1] /* r2 = Location of saved context in TCB. */ + #if ( configENABLE_PAC == 1 ) + ldmdb r2!, {r3-r6} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r4 + msr PAC_KEY_P_2, r5 + msr PAC_KEY_P_3, r6 + clrm {r3-r6} + #endif /* configENABLE_PAC */ restore_special_regs: ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ @@ -396,6 +429,15 @@ PendSV_Handler: mrs r1, psplim /* r1 = PSPLIM. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ stmdb r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ + + #if ( configENABLE_PAC == 1 ) + mrs r3, PAC_KEY_P_3 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r4, PAC_KEY_P_2 + mrs r5, PAC_KEY_P_1 + mrs r6, PAC_KEY_P_0 + stmdb r2!, {r3-r6} /* Store the task's dedicated PAC key on the stack. */ + clrm {r3-r6} + #endif /* configENABLE_PAC */ ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ str r2, [r1] /* Save the new top of stack in TCB. */ @@ -412,7 +454,14 @@ PendSV_Handler: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ ldr r2, [r1] /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ - + #if ( configENABLE_PAC == 1 ) + ldmia r2!, {r3-r6} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_1, r5 + msr PAC_KEY_P_0, r6 + clrm {r3-r6} + #endif /* configENABLE_PAC */ ldmia r2!, {r0, r1, r4} /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ msr psplim, r1 /* Restore the PSPLIM register value for the task. */ mov lr, r4 /* LR = r4. */ diff --git a/portable/IAR/ARM_CM33/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM33/non_secure/portmacrocommon.h index 8a8dc7d6ae3..d8ef5b17925 100644 --- a/portable/IAR/ARM_CM33/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM33/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,20 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + /** + * @brief Generates 128-bit task's random PAC key. + * + * The implementation in this file is weak to allow application writers to + * provide their own Random Number Generator implementation for PAC keys randomisation. + * + * @param pulTaskPacKey Pointer to task's PAC key array to be assigned an 128-bit random number. + */ + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + + #define portPAC_KEY_SIZE_BYTES 16 +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -223,63 +239,114 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) +/* +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><-----------><----> +* 16 16 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 70 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) /* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><----> +* 16 16 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) /* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | | | PC, xPSR | EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><-----------><----> +* 16 16 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 69 + + #else + +/* +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | | | PC, xPSR | EXC_RETURN | | +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><----> +* 16 16 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 53 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) /* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ +* +----------+-----------------+------------------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +----------+-----------------+------------------------------+------------+-----+ +* +* <---------><----------------><------------------------------><-----------><----> +* 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + +/* +* +----------+-----------------+------------------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | +* +----------+-----------------+------------------------------+-----+ +* +* <---------><----------------><------------------------------><----> +* 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + +/* +* +----------+-----------------+----------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | PC, xPSR | EXC_RETURN | | | +* +----------+-----------------+----------------------+------------+-----+ +* +* <---------><----------------><----------------------><-----------><----> +* 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ /* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ +* +----------+-----------------+----------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | PC, xPSR | EXC_RETURN | | +* +----------+-----------------+----------------------+-----+ +* +* <---------><----------------><----------------------><----> +* 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ diff --git a/portable/IAR/ARM_CM33_NTZ/non_secure/port.c b/portable/IAR/ARM_CM33_NTZ/non_secure/port.c index 5492c367a6f..0a40a853474 100644 --- a/portable/IAR/ARM_CM33_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_CM33_NTZ/non_secure/port.c @@ -41,6 +41,11 @@ #include "mpu_wrappers.h" #include "mpu_syscall_numbers.h" +#if ( configENABLE_PAC == 1 ) + #include + #include +#endif /* configENABLE_PAC */ + /* Portasm includes. */ #include "portasm.h" @@ -1582,6 +1587,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = pulTaskPacKey[i]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1681,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pxTopOfStack--; + *pxTopOfStack = pulTaskPacKey[i]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -2245,5 +2274,22 @@ BaseType_t xPortIsInsideInterrupt( void ) return ulControl; } + #if ( configENABLE_PAC == 1 ) + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ) + { + static BaseType_t isSeeded = pdFALSE; + if ( isSeeded == pdFALSE ) + { + srand(time(NULL)); + isSeeded = pdTRUE; + } + + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pulTaskPacKey[i] = rand(); + } + } + #endif /* configENABLE_PAC */ + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM33_NTZ/non_secure/portasm.s b/portable/IAR/ARM_CM33_NTZ/non_secure/portasm.s index 9d6c6a7ef9a..ebe7f2b9dea 100644 --- a/portable/IAR/ARM_CM33_NTZ/non_secure/portasm.s +++ b/portable/IAR/ARM_CM33_NTZ/non_secure/portasm.s @@ -27,12 +27,13 @@ * https://github.com/FreeRTOS * */ -/* Including FreeRTOSConfig.h here will cause build errors if the header file -contains code not understood by the assembler - for example the 'extern' keyword. -To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so +/* Including FreeRTOSConfig.h and portasm.h here will cause build errors if the +header file contains code not understood by the assembler - for example the 'extern' +keyword. To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so the code is included in C files but excluded by the preprocessor in assembly files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ #include "FreeRTOSConfig.h" +#include "portasm.h" /* System call numbers includes. */ #include "mpu_syscall_numbers.h" @@ -140,6 +141,14 @@ vRestoreContextOfFirstTask: ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r0, [r2] /* r0 = pxCurrentTCB.*/ ldr r1, [r0] /* r1 = Location of saved context in TCB. */ + #if ( configENABLE_PAC == 1 ) + ldmdb r1!, {r2-r5} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r2 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_3, r5 + clrm {r2-r5} + #endif /* configENABLE_PAC */ restore_special_regs_first_task: ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ @@ -165,6 +174,15 @@ vRestoreContextOfFirstTask: ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ + #if ( configENABLE_PAC == 1 ) + ldmia r0!, {r1-r4} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r1 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r2 + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_0, r4 + clrm {r1-r4} + #endif /* configENABLE_PAC */ + ldm r0!, {r1-r2} /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ msr psplim, r1 /* Set this task's PSPLIM value. */ mrs r1, control /* Obtain current control register value. */ @@ -242,6 +260,16 @@ PendSV_Handler: mrs r3, psplim /* r3 = PSPLIM. */ mrs r4, control /* r4 = CONTROL. */ stmia r1!, {r2-r4, lr} /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + + #if ( configENABLE_PAC == 1 ) + mrs r2, PAC_KEY_P_0 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r3, PAC_KEY_P_1 + mrs r4, PAC_KEY_P_2 + mrs r5, PAC_KEY_P_3 + stmia r1!, {r2-r5} /* Store the task's dedicated PAC key on the task's context. */ + clrm {r2-r5} + #endif /* configENABLE_PAC */ + str r1, [r0] /* Save the location from where the context should be restored as the first member of TCB. */ select_next_task: @@ -299,6 +327,15 @@ PendSV_Handler: ldr r0, [r2] /* r0 = pxCurrentTCB.*/ ldr r1, [r0] /* r1 = Location of saved context in TCB. */ + #if ( configENABLE_PAC == 1 ) + ldmdb r1!, {r2-r5} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r2 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_3, r5 + clrm {r2-r5} + #endif /* configENABLE_PAC */ + restore_special_regs: ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ msr psp, r2 @@ -335,6 +372,15 @@ PendSV_Handler: mov r3, lr /* r3 = LR/EXC_RETURN. */ stmdb r0!, {r2-r11} /* Store on the stack - PSPLIM, LR and registers that are not automatically. */ + #if ( configENABLE_PAC == 1 ) + mrs r1, PAC_KEY_P_3 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r2, PAC_KEY_P_2 + mrs r3, PAC_KEY_P_1 + mrs r4, PAC_KEY_P_0 + stmdb r0!, {r1-r4} /* Store the task's dedicated PAC key on the stack. */ + clrm {r1-r4} + #endif /* configENABLE_PAC */ + ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r2] /* Read pxCurrentTCB. */ str r0, [r1] /* Save the new top of stack in TCB. */ @@ -351,6 +397,15 @@ PendSV_Handler: ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ + #if ( configENABLE_PAC == 1 ) + ldmia r0!, {r2-r5} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r2 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r3 + msr PAC_KEY_P_1, r4 + msr PAC_KEY_P_0, r5 + clrm {r2-r5} + #endif /* configENABLE_PAC */ + ldmia r0!, {r2-r11} /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) diff --git a/portable/IAR/ARM_CM33_NTZ/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM33_NTZ/non_secure/portmacrocommon.h index 8a8dc7d6ae3..d8ef5b17925 100644 --- a/portable/IAR/ARM_CM33_NTZ/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM33_NTZ/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,20 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + /** + * @brief Generates 128-bit task's random PAC key. + * + * The implementation in this file is weak to allow application writers to + * provide their own Random Number Generator implementation for PAC keys randomisation. + * + * @param pulTaskPacKey Pointer to task's PAC key array to be assigned an 128-bit random number. + */ + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + + #define portPAC_KEY_SIZE_BYTES 16 +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -223,63 +239,114 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) +/* +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><-----------><----> +* 16 16 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 70 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) /* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><----> +* 16 16 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) /* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | | | PC, xPSR | EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><-----------><----> +* 16 16 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 69 + + #else + +/* +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | | | PC, xPSR | EXC_RETURN | | +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><----> +* 16 16 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 53 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) /* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ +* +----------+-----------------+------------------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +----------+-----------------+------------------------------+------------+-----+ +* +* <---------><----------------><------------------------------><-----------><----> +* 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + +/* +* +----------+-----------------+------------------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | +* +----------+-----------------+------------------------------+-----+ +* +* <---------><----------------><------------------------------><----> +* 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + +/* +* +----------+-----------------+----------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | PC, xPSR | EXC_RETURN | | | +* +----------+-----------------+----------------------+------------+-----+ +* +* <---------><----------------><----------------------><-----------><----> +* 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ /* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ +* +----------+-----------------+----------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | PC, xPSR | EXC_RETURN | | +* +----------+-----------------+----------------------+-----+ +* +* <---------><----------------><----------------------><----> +* 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ diff --git a/portable/IAR/ARM_CM35P/non_secure/port.c b/portable/IAR/ARM_CM35P/non_secure/port.c index 5492c367a6f..0a40a853474 100644 --- a/portable/IAR/ARM_CM35P/non_secure/port.c +++ b/portable/IAR/ARM_CM35P/non_secure/port.c @@ -41,6 +41,11 @@ #include "mpu_wrappers.h" #include "mpu_syscall_numbers.h" +#if ( configENABLE_PAC == 1 ) + #include + #include +#endif /* configENABLE_PAC */ + /* Portasm includes. */ #include "portasm.h" @@ -1582,6 +1587,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = pulTaskPacKey[i]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1681,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pxTopOfStack--; + *pxTopOfStack = pulTaskPacKey[i]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -2245,5 +2274,22 @@ BaseType_t xPortIsInsideInterrupt( void ) return ulControl; } + #if ( configENABLE_PAC == 1 ) + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ) + { + static BaseType_t isSeeded = pdFALSE; + if ( isSeeded == pdFALSE ) + { + srand(time(NULL)); + isSeeded = pdTRUE; + } + + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pulTaskPacKey[i] = rand(); + } + } + #endif /* configENABLE_PAC */ + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM35P/non_secure/portasm.s b/portable/IAR/ARM_CM35P/non_secure/portasm.s index c77fd39403b..508694f5d00 100644 --- a/portable/IAR/ARM_CM35P/non_secure/portasm.s +++ b/portable/IAR/ARM_CM35P/non_secure/portasm.s @@ -27,12 +27,13 @@ * https://github.com/FreeRTOS * */ -/* Including FreeRTOSConfig.h here will cause build errors if the header file -contains code not understood by the assembler - for example the 'extern' keyword. -To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so +/* Including FreeRTOSConfig.h and portasm.h here will cause build errors if the +header file contains code not understood by the assembler - for example the 'extern' +keyword. To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so the code is included in C files but excluded by the preprocessor in assembly files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ #include "FreeRTOSConfig.h" +#include "portasm.h" /* System call numbers includes. */ #include "mpu_syscall_numbers.h" @@ -150,6 +151,14 @@ vRestoreContextOfFirstTask: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* r1 = pxCurrentTCB.*/ ldr r2, [r1] /* r2 = Location of saved context in TCB. */ + #if ( configENABLE_PAC == 1 ) + ldmdb r2!, {r3-r6} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r4 + msr PAC_KEY_P_2, r5 + msr PAC_KEY_P_3, r6 + clrm {r3-r6} + #endif /* configENABLE_PAC */ restore_special_regs_first_task: ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ @@ -176,6 +185,14 @@ vRestoreContextOfFirstTask: ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r3, [r2] /* Read pxCurrentTCB. */ ldr r0, [r3] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ + #if ( configENABLE_PAC == 1 ) + ldmia r0!, {r1-r4} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r1 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r2 + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_0, r4 + clrm {r1-r4} + #endif /* configENABLE_PAC */ ldm r0!, {r1-r3} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ ldr r4, =xSecureContext @@ -271,6 +288,14 @@ PendSV_Handler: mrs r4, psplim /* r4 = PSPLIM. */ mrs r5, control /* r5 = CONTROL. */ stmia r2!, {r0, r3-r5, lr} /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + #if ( configENABLE_PAC == 1 ) + mrs r3, PAC_KEY_P_0 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r4, PAC_KEY_P_1 + mrs r5, PAC_KEY_P_2 + mrs r6, PAC_KEY_P_3 + stmia r2!, {r3-r6} /* Store the task's dedicated PAC key on the task's context. */ + clrm {r3-r6} + #endif /* configENABLE_PAC */ str r2, [r1] /* Save the location from where the context should be restored as the first member of TCB. */ select_next_task: @@ -327,6 +352,14 @@ PendSV_Handler: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* r1 = pxCurrentTCB.*/ ldr r2, [r1] /* r2 = Location of saved context in TCB. */ + #if ( configENABLE_PAC == 1 ) + ldmdb r2!, {r3-r6} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r4 + msr PAC_KEY_P_2, r5 + msr PAC_KEY_P_3, r6 + clrm {r3-r6} + #endif /* configENABLE_PAC */ restore_special_regs: ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ @@ -396,6 +429,15 @@ PendSV_Handler: mrs r1, psplim /* r1 = PSPLIM. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ stmdb r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ + + #if ( configENABLE_PAC == 1 ) + mrs r3, PAC_KEY_P_3 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r4, PAC_KEY_P_2 + mrs r5, PAC_KEY_P_1 + mrs r6, PAC_KEY_P_0 + stmdb r2!, {r3-r6} /* Store the task's dedicated PAC key on the stack. */ + clrm {r3-r6} + #endif /* configENABLE_PAC */ ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ str r2, [r1] /* Save the new top of stack in TCB. */ @@ -412,7 +454,14 @@ PendSV_Handler: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ ldr r2, [r1] /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ - + #if ( configENABLE_PAC == 1 ) + ldmia r2!, {r3-r6} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_1, r5 + msr PAC_KEY_P_0, r6 + clrm {r3-r6} + #endif /* configENABLE_PAC */ ldmia r2!, {r0, r1, r4} /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ msr psplim, r1 /* Restore the PSPLIM register value for the task. */ mov lr, r4 /* LR = r4. */ diff --git a/portable/IAR/ARM_CM35P/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM35P/non_secure/portmacrocommon.h index 8a8dc7d6ae3..d8ef5b17925 100644 --- a/portable/IAR/ARM_CM35P/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM35P/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,20 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + /** + * @brief Generates 128-bit task's random PAC key. + * + * The implementation in this file is weak to allow application writers to + * provide their own Random Number Generator implementation for PAC keys randomisation. + * + * @param pulTaskPacKey Pointer to task's PAC key array to be assigned an 128-bit random number. + */ + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + + #define portPAC_KEY_SIZE_BYTES 16 +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -223,63 +239,114 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) +/* +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><-----------><----> +* 16 16 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 70 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) /* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><----> +* 16 16 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) /* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | | | PC, xPSR | EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><-----------><----> +* 16 16 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 69 + + #else + +/* +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | | | PC, xPSR | EXC_RETURN | | +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><----> +* 16 16 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 53 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) /* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ +* +----------+-----------------+------------------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +----------+-----------------+------------------------------+------------+-----+ +* +* <---------><----------------><------------------------------><-----------><----> +* 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + +/* +* +----------+-----------------+------------------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | +* +----------+-----------------+------------------------------+-----+ +* +* <---------><----------------><------------------------------><----> +* 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + +/* +* +----------+-----------------+----------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | PC, xPSR | EXC_RETURN | | | +* +----------+-----------------+----------------------+------------+-----+ +* +* <---------><----------------><----------------------><-----------><----> +* 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ /* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ +* +----------+-----------------+----------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | PC, xPSR | EXC_RETURN | | +* +----------+-----------------+----------------------+-----+ +* +* <---------><----------------><----------------------><----> +* 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ diff --git a/portable/IAR/ARM_CM35P_NTZ/non_secure/port.c b/portable/IAR/ARM_CM35P_NTZ/non_secure/port.c index 5492c367a6f..0a40a853474 100644 --- a/portable/IAR/ARM_CM35P_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_CM35P_NTZ/non_secure/port.c @@ -41,6 +41,11 @@ #include "mpu_wrappers.h" #include "mpu_syscall_numbers.h" +#if ( configENABLE_PAC == 1 ) + #include + #include +#endif /* configENABLE_PAC */ + /* Portasm includes. */ #include "portasm.h" @@ -1582,6 +1587,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = pulTaskPacKey[i]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1681,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pxTopOfStack--; + *pxTopOfStack = pulTaskPacKey[i]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -2245,5 +2274,22 @@ BaseType_t xPortIsInsideInterrupt( void ) return ulControl; } + #if ( configENABLE_PAC == 1 ) + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ) + { + static BaseType_t isSeeded = pdFALSE; + if ( isSeeded == pdFALSE ) + { + srand(time(NULL)); + isSeeded = pdTRUE; + } + + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pulTaskPacKey[i] = rand(); + } + } + #endif /* configENABLE_PAC */ + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM35P_NTZ/non_secure/portasm.s b/portable/IAR/ARM_CM35P_NTZ/non_secure/portasm.s index 9d6c6a7ef9a..ebe7f2b9dea 100644 --- a/portable/IAR/ARM_CM35P_NTZ/non_secure/portasm.s +++ b/portable/IAR/ARM_CM35P_NTZ/non_secure/portasm.s @@ -27,12 +27,13 @@ * https://github.com/FreeRTOS * */ -/* Including FreeRTOSConfig.h here will cause build errors if the header file -contains code not understood by the assembler - for example the 'extern' keyword. -To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so +/* Including FreeRTOSConfig.h and portasm.h here will cause build errors if the +header file contains code not understood by the assembler - for example the 'extern' +keyword. To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so the code is included in C files but excluded by the preprocessor in assembly files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ #include "FreeRTOSConfig.h" +#include "portasm.h" /* System call numbers includes. */ #include "mpu_syscall_numbers.h" @@ -140,6 +141,14 @@ vRestoreContextOfFirstTask: ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r0, [r2] /* r0 = pxCurrentTCB.*/ ldr r1, [r0] /* r1 = Location of saved context in TCB. */ + #if ( configENABLE_PAC == 1 ) + ldmdb r1!, {r2-r5} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r2 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_3, r5 + clrm {r2-r5} + #endif /* configENABLE_PAC */ restore_special_regs_first_task: ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ @@ -165,6 +174,15 @@ vRestoreContextOfFirstTask: ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ + #if ( configENABLE_PAC == 1 ) + ldmia r0!, {r1-r4} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r1 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r2 + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_0, r4 + clrm {r1-r4} + #endif /* configENABLE_PAC */ + ldm r0!, {r1-r2} /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ msr psplim, r1 /* Set this task's PSPLIM value. */ mrs r1, control /* Obtain current control register value. */ @@ -242,6 +260,16 @@ PendSV_Handler: mrs r3, psplim /* r3 = PSPLIM. */ mrs r4, control /* r4 = CONTROL. */ stmia r1!, {r2-r4, lr} /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + + #if ( configENABLE_PAC == 1 ) + mrs r2, PAC_KEY_P_0 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r3, PAC_KEY_P_1 + mrs r4, PAC_KEY_P_2 + mrs r5, PAC_KEY_P_3 + stmia r1!, {r2-r5} /* Store the task's dedicated PAC key on the task's context. */ + clrm {r2-r5} + #endif /* configENABLE_PAC */ + str r1, [r0] /* Save the location from where the context should be restored as the first member of TCB. */ select_next_task: @@ -299,6 +327,15 @@ PendSV_Handler: ldr r0, [r2] /* r0 = pxCurrentTCB.*/ ldr r1, [r0] /* r1 = Location of saved context in TCB. */ + #if ( configENABLE_PAC == 1 ) + ldmdb r1!, {r2-r5} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r2 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_3, r5 + clrm {r2-r5} + #endif /* configENABLE_PAC */ + restore_special_regs: ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ msr psp, r2 @@ -335,6 +372,15 @@ PendSV_Handler: mov r3, lr /* r3 = LR/EXC_RETURN. */ stmdb r0!, {r2-r11} /* Store on the stack - PSPLIM, LR and registers that are not automatically. */ + #if ( configENABLE_PAC == 1 ) + mrs r1, PAC_KEY_P_3 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r2, PAC_KEY_P_2 + mrs r3, PAC_KEY_P_1 + mrs r4, PAC_KEY_P_0 + stmdb r0!, {r1-r4} /* Store the task's dedicated PAC key on the stack. */ + clrm {r1-r4} + #endif /* configENABLE_PAC */ + ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r2] /* Read pxCurrentTCB. */ str r0, [r1] /* Save the new top of stack in TCB. */ @@ -351,6 +397,15 @@ PendSV_Handler: ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ + #if ( configENABLE_PAC == 1 ) + ldmia r0!, {r2-r5} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r2 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r3 + msr PAC_KEY_P_1, r4 + msr PAC_KEY_P_0, r5 + clrm {r2-r5} + #endif /* configENABLE_PAC */ + ldmia r0!, {r2-r11} /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) diff --git a/portable/IAR/ARM_CM35P_NTZ/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM35P_NTZ/non_secure/portmacrocommon.h index 8a8dc7d6ae3..d8ef5b17925 100644 --- a/portable/IAR/ARM_CM35P_NTZ/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM35P_NTZ/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,20 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + /** + * @brief Generates 128-bit task's random PAC key. + * + * The implementation in this file is weak to allow application writers to + * provide their own Random Number Generator implementation for PAC keys randomisation. + * + * @param pulTaskPacKey Pointer to task's PAC key array to be assigned an 128-bit random number. + */ + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + + #define portPAC_KEY_SIZE_BYTES 16 +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -223,63 +239,114 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) +/* +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><-----------><----> +* 16 16 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 70 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) /* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><----> +* 16 16 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) /* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | | | PC, xPSR | EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><-----------><----> +* 16 16 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 69 + + #else + +/* +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | | | PC, xPSR | EXC_RETURN | | +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><----> +* 16 16 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 53 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) /* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ +* +----------+-----------------+------------------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +----------+-----------------+------------------------------+------------+-----+ +* +* <---------><----------------><------------------------------><-----------><----> +* 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + +/* +* +----------+-----------------+------------------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | +* +----------+-----------------+------------------------------+-----+ +* +* <---------><----------------><------------------------------><----> +* 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + +/* +* +----------+-----------------+----------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | PC, xPSR | EXC_RETURN | | | +* +----------+-----------------+----------------------+------------+-----+ +* +* <---------><----------------><----------------------><-----------><----> +* 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ /* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ +* +----------+-----------------+----------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | PC, xPSR | EXC_RETURN | | +* +----------+-----------------+----------------------+-----+ +* +* <---------><----------------><----------------------><----> +* 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ diff --git a/portable/IAR/ARM_CM55/non_secure/port.c b/portable/IAR/ARM_CM55/non_secure/port.c index 5492c367a6f..0a40a853474 100644 --- a/portable/IAR/ARM_CM55/non_secure/port.c +++ b/portable/IAR/ARM_CM55/non_secure/port.c @@ -41,6 +41,11 @@ #include "mpu_wrappers.h" #include "mpu_syscall_numbers.h" +#if ( configENABLE_PAC == 1 ) + #include + #include +#endif /* configENABLE_PAC */ + /* Portasm includes. */ #include "portasm.h" @@ -1582,6 +1587,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = pulTaskPacKey[i]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1681,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pxTopOfStack--; + *pxTopOfStack = pulTaskPacKey[i]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -2245,5 +2274,22 @@ BaseType_t xPortIsInsideInterrupt( void ) return ulControl; } + #if ( configENABLE_PAC == 1 ) + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ) + { + static BaseType_t isSeeded = pdFALSE; + if ( isSeeded == pdFALSE ) + { + srand(time(NULL)); + isSeeded = pdTRUE; + } + + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pulTaskPacKey[i] = rand(); + } + } + #endif /* configENABLE_PAC */ + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM55/non_secure/portasm.s b/portable/IAR/ARM_CM55/non_secure/portasm.s index c77fd39403b..508694f5d00 100644 --- a/portable/IAR/ARM_CM55/non_secure/portasm.s +++ b/portable/IAR/ARM_CM55/non_secure/portasm.s @@ -27,12 +27,13 @@ * https://github.com/FreeRTOS * */ -/* Including FreeRTOSConfig.h here will cause build errors if the header file -contains code not understood by the assembler - for example the 'extern' keyword. -To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so +/* Including FreeRTOSConfig.h and portasm.h here will cause build errors if the +header file contains code not understood by the assembler - for example the 'extern' +keyword. To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so the code is included in C files but excluded by the preprocessor in assembly files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ #include "FreeRTOSConfig.h" +#include "portasm.h" /* System call numbers includes. */ #include "mpu_syscall_numbers.h" @@ -150,6 +151,14 @@ vRestoreContextOfFirstTask: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* r1 = pxCurrentTCB.*/ ldr r2, [r1] /* r2 = Location of saved context in TCB. */ + #if ( configENABLE_PAC == 1 ) + ldmdb r2!, {r3-r6} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r4 + msr PAC_KEY_P_2, r5 + msr PAC_KEY_P_3, r6 + clrm {r3-r6} + #endif /* configENABLE_PAC */ restore_special_regs_first_task: ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ @@ -176,6 +185,14 @@ vRestoreContextOfFirstTask: ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r3, [r2] /* Read pxCurrentTCB. */ ldr r0, [r3] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ + #if ( configENABLE_PAC == 1 ) + ldmia r0!, {r1-r4} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r1 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r2 + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_0, r4 + clrm {r1-r4} + #endif /* configENABLE_PAC */ ldm r0!, {r1-r3} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ ldr r4, =xSecureContext @@ -271,6 +288,14 @@ PendSV_Handler: mrs r4, psplim /* r4 = PSPLIM. */ mrs r5, control /* r5 = CONTROL. */ stmia r2!, {r0, r3-r5, lr} /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + #if ( configENABLE_PAC == 1 ) + mrs r3, PAC_KEY_P_0 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r4, PAC_KEY_P_1 + mrs r5, PAC_KEY_P_2 + mrs r6, PAC_KEY_P_3 + stmia r2!, {r3-r6} /* Store the task's dedicated PAC key on the task's context. */ + clrm {r3-r6} + #endif /* configENABLE_PAC */ str r2, [r1] /* Save the location from where the context should be restored as the first member of TCB. */ select_next_task: @@ -327,6 +352,14 @@ PendSV_Handler: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* r1 = pxCurrentTCB.*/ ldr r2, [r1] /* r2 = Location of saved context in TCB. */ + #if ( configENABLE_PAC == 1 ) + ldmdb r2!, {r3-r6} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r4 + msr PAC_KEY_P_2, r5 + msr PAC_KEY_P_3, r6 + clrm {r3-r6} + #endif /* configENABLE_PAC */ restore_special_regs: ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ @@ -396,6 +429,15 @@ PendSV_Handler: mrs r1, psplim /* r1 = PSPLIM. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ stmdb r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ + + #if ( configENABLE_PAC == 1 ) + mrs r3, PAC_KEY_P_3 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r4, PAC_KEY_P_2 + mrs r5, PAC_KEY_P_1 + mrs r6, PAC_KEY_P_0 + stmdb r2!, {r3-r6} /* Store the task's dedicated PAC key on the stack. */ + clrm {r3-r6} + #endif /* configENABLE_PAC */ ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ str r2, [r1] /* Save the new top of stack in TCB. */ @@ -412,7 +454,14 @@ PendSV_Handler: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ ldr r2, [r1] /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ - + #if ( configENABLE_PAC == 1 ) + ldmia r2!, {r3-r6} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_1, r5 + msr PAC_KEY_P_0, r6 + clrm {r3-r6} + #endif /* configENABLE_PAC */ ldmia r2!, {r0, r1, r4} /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ msr psplim, r1 /* Restore the PSPLIM register value for the task. */ mov lr, r4 /* LR = r4. */ diff --git a/portable/IAR/ARM_CM55/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM55/non_secure/portmacrocommon.h index 8a8dc7d6ae3..d8ef5b17925 100644 --- a/portable/IAR/ARM_CM55/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM55/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,20 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + /** + * @brief Generates 128-bit task's random PAC key. + * + * The implementation in this file is weak to allow application writers to + * provide their own Random Number Generator implementation for PAC keys randomisation. + * + * @param pulTaskPacKey Pointer to task's PAC key array to be assigned an 128-bit random number. + */ + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + + #define portPAC_KEY_SIZE_BYTES 16 +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -223,63 +239,114 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) +/* +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><-----------><----> +* 16 16 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 70 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) /* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><----> +* 16 16 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) /* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | | | PC, xPSR | EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><-----------><----> +* 16 16 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 69 + + #else + +/* +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | | | PC, xPSR | EXC_RETURN | | +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><----> +* 16 16 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 53 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) /* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ +* +----------+-----------------+------------------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +----------+-----------------+------------------------------+------------+-----+ +* +* <---------><----------------><------------------------------><-----------><----> +* 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + +/* +* +----------+-----------------+------------------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | +* +----------+-----------------+------------------------------+-----+ +* +* <---------><----------------><------------------------------><----> +* 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + +/* +* +----------+-----------------+----------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | PC, xPSR | EXC_RETURN | | | +* +----------+-----------------+----------------------+------------+-----+ +* +* <---------><----------------><----------------------><-----------><----> +* 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ /* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ +* +----------+-----------------+----------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | PC, xPSR | EXC_RETURN | | +* +----------+-----------------+----------------------+-----+ +* +* <---------><----------------><----------------------><----> +* 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ diff --git a/portable/IAR/ARM_CM55_NTZ/non_secure/port.c b/portable/IAR/ARM_CM55_NTZ/non_secure/port.c index 5492c367a6f..0a40a853474 100644 --- a/portable/IAR/ARM_CM55_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_CM55_NTZ/non_secure/port.c @@ -41,6 +41,11 @@ #include "mpu_wrappers.h" #include "mpu_syscall_numbers.h" +#if ( configENABLE_PAC == 1 ) + #include + #include +#endif /* configENABLE_PAC */ + /* Portasm includes. */ #include "portasm.h" @@ -1582,6 +1587,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = pulTaskPacKey[i]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1681,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pxTopOfStack--; + *pxTopOfStack = pulTaskPacKey[i]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -2245,5 +2274,22 @@ BaseType_t xPortIsInsideInterrupt( void ) return ulControl; } + #if ( configENABLE_PAC == 1 ) + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ) + { + static BaseType_t isSeeded = pdFALSE; + if ( isSeeded == pdFALSE ) + { + srand(time(NULL)); + isSeeded = pdTRUE; + } + + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pulTaskPacKey[i] = rand(); + } + } + #endif /* configENABLE_PAC */ + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM55_NTZ/non_secure/portasm.s b/portable/IAR/ARM_CM55_NTZ/non_secure/portasm.s index 9d6c6a7ef9a..ebe7f2b9dea 100644 --- a/portable/IAR/ARM_CM55_NTZ/non_secure/portasm.s +++ b/portable/IAR/ARM_CM55_NTZ/non_secure/portasm.s @@ -27,12 +27,13 @@ * https://github.com/FreeRTOS * */ -/* Including FreeRTOSConfig.h here will cause build errors if the header file -contains code not understood by the assembler - for example the 'extern' keyword. -To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so +/* Including FreeRTOSConfig.h and portasm.h here will cause build errors if the +header file contains code not understood by the assembler - for example the 'extern' +keyword. To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so the code is included in C files but excluded by the preprocessor in assembly files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ #include "FreeRTOSConfig.h" +#include "portasm.h" /* System call numbers includes. */ #include "mpu_syscall_numbers.h" @@ -140,6 +141,14 @@ vRestoreContextOfFirstTask: ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r0, [r2] /* r0 = pxCurrentTCB.*/ ldr r1, [r0] /* r1 = Location of saved context in TCB. */ + #if ( configENABLE_PAC == 1 ) + ldmdb r1!, {r2-r5} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r2 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_3, r5 + clrm {r2-r5} + #endif /* configENABLE_PAC */ restore_special_regs_first_task: ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ @@ -165,6 +174,15 @@ vRestoreContextOfFirstTask: ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ + #if ( configENABLE_PAC == 1 ) + ldmia r0!, {r1-r4} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r1 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r2 + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_0, r4 + clrm {r1-r4} + #endif /* configENABLE_PAC */ + ldm r0!, {r1-r2} /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ msr psplim, r1 /* Set this task's PSPLIM value. */ mrs r1, control /* Obtain current control register value. */ @@ -242,6 +260,16 @@ PendSV_Handler: mrs r3, psplim /* r3 = PSPLIM. */ mrs r4, control /* r4 = CONTROL. */ stmia r1!, {r2-r4, lr} /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + + #if ( configENABLE_PAC == 1 ) + mrs r2, PAC_KEY_P_0 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r3, PAC_KEY_P_1 + mrs r4, PAC_KEY_P_2 + mrs r5, PAC_KEY_P_3 + stmia r1!, {r2-r5} /* Store the task's dedicated PAC key on the task's context. */ + clrm {r2-r5} + #endif /* configENABLE_PAC */ + str r1, [r0] /* Save the location from where the context should be restored as the first member of TCB. */ select_next_task: @@ -299,6 +327,15 @@ PendSV_Handler: ldr r0, [r2] /* r0 = pxCurrentTCB.*/ ldr r1, [r0] /* r1 = Location of saved context in TCB. */ + #if ( configENABLE_PAC == 1 ) + ldmdb r1!, {r2-r5} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r2 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_3, r5 + clrm {r2-r5} + #endif /* configENABLE_PAC */ + restore_special_regs: ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ msr psp, r2 @@ -335,6 +372,15 @@ PendSV_Handler: mov r3, lr /* r3 = LR/EXC_RETURN. */ stmdb r0!, {r2-r11} /* Store on the stack - PSPLIM, LR and registers that are not automatically. */ + #if ( configENABLE_PAC == 1 ) + mrs r1, PAC_KEY_P_3 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r2, PAC_KEY_P_2 + mrs r3, PAC_KEY_P_1 + mrs r4, PAC_KEY_P_0 + stmdb r0!, {r1-r4} /* Store the task's dedicated PAC key on the stack. */ + clrm {r1-r4} + #endif /* configENABLE_PAC */ + ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r2] /* Read pxCurrentTCB. */ str r0, [r1] /* Save the new top of stack in TCB. */ @@ -351,6 +397,15 @@ PendSV_Handler: ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ + #if ( configENABLE_PAC == 1 ) + ldmia r0!, {r2-r5} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r2 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r3 + msr PAC_KEY_P_1, r4 + msr PAC_KEY_P_0, r5 + clrm {r2-r5} + #endif /* configENABLE_PAC */ + ldmia r0!, {r2-r11} /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) diff --git a/portable/IAR/ARM_CM55_NTZ/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM55_NTZ/non_secure/portmacrocommon.h index 8a8dc7d6ae3..d8ef5b17925 100644 --- a/portable/IAR/ARM_CM55_NTZ/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM55_NTZ/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,20 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + /** + * @brief Generates 128-bit task's random PAC key. + * + * The implementation in this file is weak to allow application writers to + * provide their own Random Number Generator implementation for PAC keys randomisation. + * + * @param pulTaskPacKey Pointer to task's PAC key array to be assigned an 128-bit random number. + */ + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + + #define portPAC_KEY_SIZE_BYTES 16 +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -223,63 +239,114 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) +/* +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><-----------><----> +* 16 16 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 70 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) /* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><----> +* 16 16 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) /* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | | | PC, xPSR | EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><-----------><----> +* 16 16 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 69 + + #else + +/* +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | | | PC, xPSR | EXC_RETURN | | +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><----> +* 16 16 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 53 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) /* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ +* +----------+-----------------+------------------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +----------+-----------------+------------------------------+------------+-----+ +* +* <---------><----------------><------------------------------><-----------><----> +* 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + +/* +* +----------+-----------------+------------------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | +* +----------+-----------------+------------------------------+-----+ +* +* <---------><----------------><------------------------------><----> +* 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + +/* +* +----------+-----------------+----------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | PC, xPSR | EXC_RETURN | | | +* +----------+-----------------+----------------------+------------+-----+ +* +* <---------><----------------><----------------------><-----------><----> +* 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ /* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ +* +----------+-----------------+----------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | PC, xPSR | EXC_RETURN | | +* +----------+-----------------+----------------------+-----+ +* +* <---------><----------------><----------------------><----> +* 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ diff --git a/portable/IAR/ARM_CM85/non_secure/port.c b/portable/IAR/ARM_CM85/non_secure/port.c index 5492c367a6f..0a40a853474 100644 --- a/portable/IAR/ARM_CM85/non_secure/port.c +++ b/portable/IAR/ARM_CM85/non_secure/port.c @@ -41,6 +41,11 @@ #include "mpu_wrappers.h" #include "mpu_syscall_numbers.h" +#if ( configENABLE_PAC == 1 ) + #include + #include +#endif /* configENABLE_PAC */ + /* Portasm includes. */ #include "portasm.h" @@ -1582,6 +1587,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = pulTaskPacKey[i]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1681,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pxTopOfStack--; + *pxTopOfStack = pulTaskPacKey[i]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -2245,5 +2274,22 @@ BaseType_t xPortIsInsideInterrupt( void ) return ulControl; } + #if ( configENABLE_PAC == 1 ) + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ) + { + static BaseType_t isSeeded = pdFALSE; + if ( isSeeded == pdFALSE ) + { + srand(time(NULL)); + isSeeded = pdTRUE; + } + + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pulTaskPacKey[i] = rand(); + } + } + #endif /* configENABLE_PAC */ + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM85/non_secure/portasm.s b/portable/IAR/ARM_CM85/non_secure/portasm.s index c77fd39403b..508694f5d00 100644 --- a/portable/IAR/ARM_CM85/non_secure/portasm.s +++ b/portable/IAR/ARM_CM85/non_secure/portasm.s @@ -27,12 +27,13 @@ * https://github.com/FreeRTOS * */ -/* Including FreeRTOSConfig.h here will cause build errors if the header file -contains code not understood by the assembler - for example the 'extern' keyword. -To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so +/* Including FreeRTOSConfig.h and portasm.h here will cause build errors if the +header file contains code not understood by the assembler - for example the 'extern' +keyword. To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so the code is included in C files but excluded by the preprocessor in assembly files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ #include "FreeRTOSConfig.h" +#include "portasm.h" /* System call numbers includes. */ #include "mpu_syscall_numbers.h" @@ -150,6 +151,14 @@ vRestoreContextOfFirstTask: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* r1 = pxCurrentTCB.*/ ldr r2, [r1] /* r2 = Location of saved context in TCB. */ + #if ( configENABLE_PAC == 1 ) + ldmdb r2!, {r3-r6} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r4 + msr PAC_KEY_P_2, r5 + msr PAC_KEY_P_3, r6 + clrm {r3-r6} + #endif /* configENABLE_PAC */ restore_special_regs_first_task: ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ @@ -176,6 +185,14 @@ vRestoreContextOfFirstTask: ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r3, [r2] /* Read pxCurrentTCB. */ ldr r0, [r3] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ + #if ( configENABLE_PAC == 1 ) + ldmia r0!, {r1-r4} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r1 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r2 + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_0, r4 + clrm {r1-r4} + #endif /* configENABLE_PAC */ ldm r0!, {r1-r3} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ ldr r4, =xSecureContext @@ -271,6 +288,14 @@ PendSV_Handler: mrs r4, psplim /* r4 = PSPLIM. */ mrs r5, control /* r5 = CONTROL. */ stmia r2!, {r0, r3-r5, lr} /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + #if ( configENABLE_PAC == 1 ) + mrs r3, PAC_KEY_P_0 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r4, PAC_KEY_P_1 + mrs r5, PAC_KEY_P_2 + mrs r6, PAC_KEY_P_3 + stmia r2!, {r3-r6} /* Store the task's dedicated PAC key on the task's context. */ + clrm {r3-r6} + #endif /* configENABLE_PAC */ str r2, [r1] /* Save the location from where the context should be restored as the first member of TCB. */ select_next_task: @@ -327,6 +352,14 @@ PendSV_Handler: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* r1 = pxCurrentTCB.*/ ldr r2, [r1] /* r2 = Location of saved context in TCB. */ + #if ( configENABLE_PAC == 1 ) + ldmdb r2!, {r3-r6} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r4 + msr PAC_KEY_P_2, r5 + msr PAC_KEY_P_3, r6 + clrm {r3-r6} + #endif /* configENABLE_PAC */ restore_special_regs: ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ @@ -396,6 +429,15 @@ PendSV_Handler: mrs r1, psplim /* r1 = PSPLIM. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ stmdb r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ + + #if ( configENABLE_PAC == 1 ) + mrs r3, PAC_KEY_P_3 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r4, PAC_KEY_P_2 + mrs r5, PAC_KEY_P_1 + mrs r6, PAC_KEY_P_0 + stmdb r2!, {r3-r6} /* Store the task's dedicated PAC key on the stack. */ + clrm {r3-r6} + #endif /* configENABLE_PAC */ ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ str r2, [r1] /* Save the new top of stack in TCB. */ @@ -412,7 +454,14 @@ PendSV_Handler: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ ldr r2, [r1] /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ - + #if ( configENABLE_PAC == 1 ) + ldmia r2!, {r3-r6} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_1, r5 + msr PAC_KEY_P_0, r6 + clrm {r3-r6} + #endif /* configENABLE_PAC */ ldmia r2!, {r0, r1, r4} /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ msr psplim, r1 /* Restore the PSPLIM register value for the task. */ mov lr, r4 /* LR = r4. */ diff --git a/portable/IAR/ARM_CM85/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM85/non_secure/portmacrocommon.h index 8a8dc7d6ae3..d8ef5b17925 100644 --- a/portable/IAR/ARM_CM85/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM85/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,20 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + /** + * @brief Generates 128-bit task's random PAC key. + * + * The implementation in this file is weak to allow application writers to + * provide their own Random Number Generator implementation for PAC keys randomisation. + * + * @param pulTaskPacKey Pointer to task's PAC key array to be assigned an 128-bit random number. + */ + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + + #define portPAC_KEY_SIZE_BYTES 16 +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -223,63 +239,114 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) +/* +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><-----------><----> +* 16 16 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 70 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) /* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><----> +* 16 16 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) /* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | | | PC, xPSR | EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><-----------><----> +* 16 16 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 69 + + #else + +/* +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | | | PC, xPSR | EXC_RETURN | | +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><----> +* 16 16 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 53 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) /* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ +* +----------+-----------------+------------------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +----------+-----------------+------------------------------+------------+-----+ +* +* <---------><----------------><------------------------------><-----------><----> +* 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + +/* +* +----------+-----------------+------------------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | +* +----------+-----------------+------------------------------+-----+ +* +* <---------><----------------><------------------------------><----> +* 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + +/* +* +----------+-----------------+----------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | PC, xPSR | EXC_RETURN | | | +* +----------+-----------------+----------------------+------------+-----+ +* +* <---------><----------------><----------------------><-----------><----> +* 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ /* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ +* +----------+-----------------+----------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | PC, xPSR | EXC_RETURN | | +* +----------+-----------------+----------------------+-----+ +* +* <---------><----------------><----------------------><----> +* 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ diff --git a/portable/IAR/ARM_CM85_NTZ/non_secure/port.c b/portable/IAR/ARM_CM85_NTZ/non_secure/port.c index 5492c367a6f..0a40a853474 100644 --- a/portable/IAR/ARM_CM85_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_CM85_NTZ/non_secure/port.c @@ -41,6 +41,11 @@ #include "mpu_wrappers.h" #include "mpu_syscall_numbers.h" +#if ( configENABLE_PAC == 1 ) + #include + #include +#endif /* configENABLE_PAC */ + /* Portasm includes. */ #include "portasm.h" @@ -1582,6 +1587,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = pulTaskPacKey[i]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1681,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pxTopOfStack--; + *pxTopOfStack = pulTaskPacKey[i]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -2245,5 +2274,22 @@ BaseType_t xPortIsInsideInterrupt( void ) return ulControl; } + #if ( configENABLE_PAC == 1 ) + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ) + { + static BaseType_t isSeeded = pdFALSE; + if ( isSeeded == pdFALSE ) + { + srand(time(NULL)); + isSeeded = pdTRUE; + } + + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pulTaskPacKey[i] = rand(); + } + } + #endif /* configENABLE_PAC */ + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM85_NTZ/non_secure/portasm.s b/portable/IAR/ARM_CM85_NTZ/non_secure/portasm.s index 9d6c6a7ef9a..ebe7f2b9dea 100644 --- a/portable/IAR/ARM_CM85_NTZ/non_secure/portasm.s +++ b/portable/IAR/ARM_CM85_NTZ/non_secure/portasm.s @@ -27,12 +27,13 @@ * https://github.com/FreeRTOS * */ -/* Including FreeRTOSConfig.h here will cause build errors if the header file -contains code not understood by the assembler - for example the 'extern' keyword. -To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so +/* Including FreeRTOSConfig.h and portasm.h here will cause build errors if the +header file contains code not understood by the assembler - for example the 'extern' +keyword. To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so the code is included in C files but excluded by the preprocessor in assembly files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ #include "FreeRTOSConfig.h" +#include "portasm.h" /* System call numbers includes. */ #include "mpu_syscall_numbers.h" @@ -140,6 +141,14 @@ vRestoreContextOfFirstTask: ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r0, [r2] /* r0 = pxCurrentTCB.*/ ldr r1, [r0] /* r1 = Location of saved context in TCB. */ + #if ( configENABLE_PAC == 1 ) + ldmdb r1!, {r2-r5} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r2 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_3, r5 + clrm {r2-r5} + #endif /* configENABLE_PAC */ restore_special_regs_first_task: ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ @@ -165,6 +174,15 @@ vRestoreContextOfFirstTask: ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ + #if ( configENABLE_PAC == 1 ) + ldmia r0!, {r1-r4} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r1 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r2 + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_0, r4 + clrm {r1-r4} + #endif /* configENABLE_PAC */ + ldm r0!, {r1-r2} /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ msr psplim, r1 /* Set this task's PSPLIM value. */ mrs r1, control /* Obtain current control register value. */ @@ -242,6 +260,16 @@ PendSV_Handler: mrs r3, psplim /* r3 = PSPLIM. */ mrs r4, control /* r4 = CONTROL. */ stmia r1!, {r2-r4, lr} /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + + #if ( configENABLE_PAC == 1 ) + mrs r2, PAC_KEY_P_0 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r3, PAC_KEY_P_1 + mrs r4, PAC_KEY_P_2 + mrs r5, PAC_KEY_P_3 + stmia r1!, {r2-r5} /* Store the task's dedicated PAC key on the task's context. */ + clrm {r2-r5} + #endif /* configENABLE_PAC */ + str r1, [r0] /* Save the location from where the context should be restored as the first member of TCB. */ select_next_task: @@ -299,6 +327,15 @@ PendSV_Handler: ldr r0, [r2] /* r0 = pxCurrentTCB.*/ ldr r1, [r0] /* r1 = Location of saved context in TCB. */ + #if ( configENABLE_PAC == 1 ) + ldmdb r1!, {r2-r5} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r2 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_3, r5 + clrm {r2-r5} + #endif /* configENABLE_PAC */ + restore_special_regs: ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ msr psp, r2 @@ -335,6 +372,15 @@ PendSV_Handler: mov r3, lr /* r3 = LR/EXC_RETURN. */ stmdb r0!, {r2-r11} /* Store on the stack - PSPLIM, LR and registers that are not automatically. */ + #if ( configENABLE_PAC == 1 ) + mrs r1, PAC_KEY_P_3 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r2, PAC_KEY_P_2 + mrs r3, PAC_KEY_P_1 + mrs r4, PAC_KEY_P_0 + stmdb r0!, {r1-r4} /* Store the task's dedicated PAC key on the stack. */ + clrm {r1-r4} + #endif /* configENABLE_PAC */ + ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r2] /* Read pxCurrentTCB. */ str r0, [r1] /* Save the new top of stack in TCB. */ @@ -351,6 +397,15 @@ PendSV_Handler: ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ + #if ( configENABLE_PAC == 1 ) + ldmia r0!, {r2-r5} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r2 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r3 + msr PAC_KEY_P_1, r4 + msr PAC_KEY_P_0, r5 + clrm {r2-r5} + #endif /* configENABLE_PAC */ + ldmia r0!, {r2-r11} /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) diff --git a/portable/IAR/ARM_CM85_NTZ/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM85_NTZ/non_secure/portmacrocommon.h index 8a8dc7d6ae3..d8ef5b17925 100644 --- a/portable/IAR/ARM_CM85_NTZ/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM85_NTZ/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,20 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + /** + * @brief Generates 128-bit task's random PAC key. + * + * The implementation in this file is weak to allow application writers to + * provide their own Random Number Generator implementation for PAC keys randomisation. + * + * @param pulTaskPacKey Pointer to task's PAC key array to be assigned an 128-bit random number. + */ + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + + #define portPAC_KEY_SIZE_BYTES 16 +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -223,63 +239,114 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) +/* +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><-----------><----> +* 16 16 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 70 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) /* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><----> +* 16 16 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) /* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | | | PC, xPSR | EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><-----------><----> +* 16 16 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 69 + + #else + +/* +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | | | PC, xPSR | EXC_RETURN | | +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><----> +* 16 16 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 53 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) /* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ +* +----------+-----------------+------------------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +----------+-----------------+------------------------------+------------+-----+ +* +* <---------><----------------><------------------------------><-----------><----> +* 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + +/* +* +----------+-----------------+------------------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | +* +----------+-----------------+------------------------------+-----+ +* +* <---------><----------------><------------------------------><----> +* 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + +/* +* +----------+-----------------+----------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | PC, xPSR | EXC_RETURN | | | +* +----------+-----------------+----------------------+------------+-----+ +* +* <---------><----------------><----------------------><-----------><----> +* 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ /* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ +* +----------+-----------------+----------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | PC, xPSR | EXC_RETURN | | +* +----------+-----------------+----------------------+-----+ +* +* <---------><----------------><----------------------><----> +* 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */