From 06ea7275b3a630bc962f625bb0b16f8a74b1db1f Mon Sep 17 00:00:00 2001 From: Gaurav Aggarwal Date: Wed, 4 Aug 2021 15:00:47 -0700 Subject: [PATCH] Implement secure stack sealing as per ARM's recommendation Signed-off-by: Gaurav Aggarwal --- .../ARMv8M/secure/context/secure_context.c | 24 +++++++++++++++---- portable/GCC/ARM_CM23/secure/secure_context.c | 24 +++++++++++++++---- portable/GCC/ARM_CM33/secure/secure_context.c | 24 +++++++++++++++---- portable/IAR/ARM_CM23/secure/secure_context.c | 24 +++++++++++++++---- portable/IAR/ARM_CM33/secure/secure_context.c | 24 +++++++++++++++---- 5 files changed, 95 insertions(+), 25 deletions(-) diff --git a/portable/ARMv8M/secure/context/secure_context.c b/portable/ARMv8M/secure/context/secure_context.c index a51d1c17c..b1d5503cb 100644 --- a/portable/ARMv8M/secure/context/secure_context.c +++ b/portable/ARMv8M/secure/context/secure_context.c @@ -51,6 +51,16 @@ */ #define securecontextCONTROL_VALUE_UNPRIVILEGED 0x03 +/** + * @brief Size of stack seal values in bytes. + */ +#define securecontextSTACK_SEAL_SIZE 8 + +/** + * @brief Stack seal value as recommended by ARM. + */ +#define securecontextSTACK_SEAL_VALUE 0xFEF5EDA5 + /** * @brief Maximum number of secure contexts. */ @@ -204,18 +214,22 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) if( ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS ) { /* Allocate the stack space. */ - pucStackMemory = pvPortMalloc( ulSecureStackSize ); + pucStackMemory = pvPortMalloc( ulSecureStackSize + securecontextSTACK_SEAL_SIZE ); if( pucStackMemory != NULL ) { /* Since stack grows down, the starting point will be the last * location. Note that this location is next to the last - * allocated byte because the hardware decrements the stack - * pointer before writing i.e. if stack pointer is 0x2, a push - * operation will decrement the stack pointer to 0x1 and then - * write at 0x1. */ + * allocated byte for stack (excluding the space for seal values) + * because the hardware decrements the stack pointer before + * writing i.e. if stack pointer is 0x2, a push operation will + * decrement the stack pointer to 0x1 and then write at 0x1. */ xSecureContexts[ ulSecureContextIndex ].pucStackStart = pucStackMemory + ulSecureStackSize; + /* Seal the created secure process stack. */ + *( uint32_t * )( pucStackMemory + ulSecureStackSize ) = securecontextSTACK_SEAL_VALUE; + *( uint32_t * )( pucStackMemory + ulSecureStackSize + 4 ) = securecontextSTACK_SEAL_VALUE; + /* The stack cannot go beyond this location. This value is * programmed in the PSPLIM register on context switch.*/ xSecureContexts[ ulSecureContextIndex ].pucStackLimit = pucStackMemory; diff --git a/portable/GCC/ARM_CM23/secure/secure_context.c b/portable/GCC/ARM_CM23/secure/secure_context.c index a51d1c17c..b1d5503cb 100644 --- a/portable/GCC/ARM_CM23/secure/secure_context.c +++ b/portable/GCC/ARM_CM23/secure/secure_context.c @@ -51,6 +51,16 @@ */ #define securecontextCONTROL_VALUE_UNPRIVILEGED 0x03 +/** + * @brief Size of stack seal values in bytes. + */ +#define securecontextSTACK_SEAL_SIZE 8 + +/** + * @brief Stack seal value as recommended by ARM. + */ +#define securecontextSTACK_SEAL_VALUE 0xFEF5EDA5 + /** * @brief Maximum number of secure contexts. */ @@ -204,18 +214,22 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) if( ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS ) { /* Allocate the stack space. */ - pucStackMemory = pvPortMalloc( ulSecureStackSize ); + pucStackMemory = pvPortMalloc( ulSecureStackSize + securecontextSTACK_SEAL_SIZE ); if( pucStackMemory != NULL ) { /* Since stack grows down, the starting point will be the last * location. Note that this location is next to the last - * allocated byte because the hardware decrements the stack - * pointer before writing i.e. if stack pointer is 0x2, a push - * operation will decrement the stack pointer to 0x1 and then - * write at 0x1. */ + * allocated byte for stack (excluding the space for seal values) + * because the hardware decrements the stack pointer before + * writing i.e. if stack pointer is 0x2, a push operation will + * decrement the stack pointer to 0x1 and then write at 0x1. */ xSecureContexts[ ulSecureContextIndex ].pucStackStart = pucStackMemory + ulSecureStackSize; + /* Seal the created secure process stack. */ + *( uint32_t * )( pucStackMemory + ulSecureStackSize ) = securecontextSTACK_SEAL_VALUE; + *( uint32_t * )( pucStackMemory + ulSecureStackSize + 4 ) = securecontextSTACK_SEAL_VALUE; + /* The stack cannot go beyond this location. This value is * programmed in the PSPLIM register on context switch.*/ xSecureContexts[ ulSecureContextIndex ].pucStackLimit = pucStackMemory; diff --git a/portable/GCC/ARM_CM33/secure/secure_context.c b/portable/GCC/ARM_CM33/secure/secure_context.c index a51d1c17c..b1d5503cb 100644 --- a/portable/GCC/ARM_CM33/secure/secure_context.c +++ b/portable/GCC/ARM_CM33/secure/secure_context.c @@ -51,6 +51,16 @@ */ #define securecontextCONTROL_VALUE_UNPRIVILEGED 0x03 +/** + * @brief Size of stack seal values in bytes. + */ +#define securecontextSTACK_SEAL_SIZE 8 + +/** + * @brief Stack seal value as recommended by ARM. + */ +#define securecontextSTACK_SEAL_VALUE 0xFEF5EDA5 + /** * @brief Maximum number of secure contexts. */ @@ -204,18 +214,22 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) if( ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS ) { /* Allocate the stack space. */ - pucStackMemory = pvPortMalloc( ulSecureStackSize ); + pucStackMemory = pvPortMalloc( ulSecureStackSize + securecontextSTACK_SEAL_SIZE ); if( pucStackMemory != NULL ) { /* Since stack grows down, the starting point will be the last * location. Note that this location is next to the last - * allocated byte because the hardware decrements the stack - * pointer before writing i.e. if stack pointer is 0x2, a push - * operation will decrement the stack pointer to 0x1 and then - * write at 0x1. */ + * allocated byte for stack (excluding the space for seal values) + * because the hardware decrements the stack pointer before + * writing i.e. if stack pointer is 0x2, a push operation will + * decrement the stack pointer to 0x1 and then write at 0x1. */ xSecureContexts[ ulSecureContextIndex ].pucStackStart = pucStackMemory + ulSecureStackSize; + /* Seal the created secure process stack. */ + *( uint32_t * )( pucStackMemory + ulSecureStackSize ) = securecontextSTACK_SEAL_VALUE; + *( uint32_t * )( pucStackMemory + ulSecureStackSize + 4 ) = securecontextSTACK_SEAL_VALUE; + /* The stack cannot go beyond this location. This value is * programmed in the PSPLIM register on context switch.*/ xSecureContexts[ ulSecureContextIndex ].pucStackLimit = pucStackMemory; diff --git a/portable/IAR/ARM_CM23/secure/secure_context.c b/portable/IAR/ARM_CM23/secure/secure_context.c index a51d1c17c..b1d5503cb 100644 --- a/portable/IAR/ARM_CM23/secure/secure_context.c +++ b/portable/IAR/ARM_CM23/secure/secure_context.c @@ -51,6 +51,16 @@ */ #define securecontextCONTROL_VALUE_UNPRIVILEGED 0x03 +/** + * @brief Size of stack seal values in bytes. + */ +#define securecontextSTACK_SEAL_SIZE 8 + +/** + * @brief Stack seal value as recommended by ARM. + */ +#define securecontextSTACK_SEAL_VALUE 0xFEF5EDA5 + /** * @brief Maximum number of secure contexts. */ @@ -204,18 +214,22 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) if( ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS ) { /* Allocate the stack space. */ - pucStackMemory = pvPortMalloc( ulSecureStackSize ); + pucStackMemory = pvPortMalloc( ulSecureStackSize + securecontextSTACK_SEAL_SIZE ); if( pucStackMemory != NULL ) { /* Since stack grows down, the starting point will be the last * location. Note that this location is next to the last - * allocated byte because the hardware decrements the stack - * pointer before writing i.e. if stack pointer is 0x2, a push - * operation will decrement the stack pointer to 0x1 and then - * write at 0x1. */ + * allocated byte for stack (excluding the space for seal values) + * because the hardware decrements the stack pointer before + * writing i.e. if stack pointer is 0x2, a push operation will + * decrement the stack pointer to 0x1 and then write at 0x1. */ xSecureContexts[ ulSecureContextIndex ].pucStackStart = pucStackMemory + ulSecureStackSize; + /* Seal the created secure process stack. */ + *( uint32_t * )( pucStackMemory + ulSecureStackSize ) = securecontextSTACK_SEAL_VALUE; + *( uint32_t * )( pucStackMemory + ulSecureStackSize + 4 ) = securecontextSTACK_SEAL_VALUE; + /* The stack cannot go beyond this location. This value is * programmed in the PSPLIM register on context switch.*/ xSecureContexts[ ulSecureContextIndex ].pucStackLimit = pucStackMemory; diff --git a/portable/IAR/ARM_CM33/secure/secure_context.c b/portable/IAR/ARM_CM33/secure/secure_context.c index a51d1c17c..b1d5503cb 100644 --- a/portable/IAR/ARM_CM33/secure/secure_context.c +++ b/portable/IAR/ARM_CM33/secure/secure_context.c @@ -51,6 +51,16 @@ */ #define securecontextCONTROL_VALUE_UNPRIVILEGED 0x03 +/** + * @brief Size of stack seal values in bytes. + */ +#define securecontextSTACK_SEAL_SIZE 8 + +/** + * @brief Stack seal value as recommended by ARM. + */ +#define securecontextSTACK_SEAL_VALUE 0xFEF5EDA5 + /** * @brief Maximum number of secure contexts. */ @@ -204,18 +214,22 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) if( ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS ) { /* Allocate the stack space. */ - pucStackMemory = pvPortMalloc( ulSecureStackSize ); + pucStackMemory = pvPortMalloc( ulSecureStackSize + securecontextSTACK_SEAL_SIZE ); if( pucStackMemory != NULL ) { /* Since stack grows down, the starting point will be the last * location. Note that this location is next to the last - * allocated byte because the hardware decrements the stack - * pointer before writing i.e. if stack pointer is 0x2, a push - * operation will decrement the stack pointer to 0x1 and then - * write at 0x1. */ + * allocated byte for stack (excluding the space for seal values) + * because the hardware decrements the stack pointer before + * writing i.e. if stack pointer is 0x2, a push operation will + * decrement the stack pointer to 0x1 and then write at 0x1. */ xSecureContexts[ ulSecureContextIndex ].pucStackStart = pucStackMemory + ulSecureStackSize; + /* Seal the created secure process stack. */ + *( uint32_t * )( pucStackMemory + ulSecureStackSize ) = securecontextSTACK_SEAL_VALUE; + *( uint32_t * )( pucStackMemory + ulSecureStackSize + 4 ) = securecontextSTACK_SEAL_VALUE; + /* The stack cannot go beyond this location. This value is * programmed in the PSPLIM register on context switch.*/ xSecureContexts[ ulSecureContextIndex ].pucStackLimit = pucStackMemory;