arch: arm: add per thread unique PAC key support
Add a config option to set unique PAC keys per thread and make sure to retain them during context switch. Signed-off-by: Sudan Landge <sudan.landge@arm.com>
This commit is contained in:
committed by
Henrik Brix Andersen
parent
8e5f828fef
commit
09cc777daa
@@ -2,6 +2,7 @@
|
||||
* Copyright (c) 2013-2014 Wind River Systems, Inc.
|
||||
* Copyright (c) 2017-2019 Nordic Semiconductor ASA.
|
||||
* Copyright (c) 2020 Stephanos Ioannidis <root@stephanos.io>
|
||||
* Copyright 2025 Arm Limited and/or its affiliates <open-source-office@arm.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -313,6 +314,18 @@ SECTION_FUNC(TEXT, z_arm_pendsv)
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARM_PAC_PER_THREAD
|
||||
/* Read thread's dedicated PAC key and write them in the privileged PAC key registers.
|
||||
*/
|
||||
add r0, r2, #_thread_offset_to_pac_keys
|
||||
ldmia r0!, {r3-r6}
|
||||
msr PAC_KEY_P_0, r3
|
||||
msr PAC_KEY_P_1, r4
|
||||
msr PAC_KEY_P_2, r5
|
||||
msr PAC_KEY_P_3, r6
|
||||
clrm {r3-r6}
|
||||
#endif /* CONFIG_ARM_PAC_PER_THREAD */
|
||||
|
||||
/* load callee-saved + psp from thread */
|
||||
add r0, r2, #_thread_offset_to_callee_saved
|
||||
ldmia r0, {r4-r11, ip}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014 Wind River Systems, Inc.
|
||||
* Copyright (c) 2021 Lexmark International, Inc.
|
||||
* Copyright (c) 2023 Arm Limited
|
||||
* Copyright (c) 2023, 2025 Arm Limited and/or its affiliates <open-source-office@arm.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <zephyr/sys/barrier.h>
|
||||
#include <stdbool.h>
|
||||
#include <cmsis_core.h>
|
||||
#include <zephyr/random/random.h>
|
||||
|
||||
#if (MPU_GUARD_ALIGN_AND_SIZE_FLOAT > MPU_GUARD_ALIGN_AND_SIZE)
|
||||
#define FP_GUARD_EXTRA_SIZE (MPU_GUARD_ALIGN_AND_SIZE_FLOAT - MPU_GUARD_ALIGN_AND_SIZE)
|
||||
@@ -121,6 +122,12 @@ void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack, char *sta
|
||||
#if defined(CONFIG_USERSPACE)
|
||||
thread->arch.priv_stack_start = 0;
|
||||
#endif
|
||||
#endif
|
||||
#ifdef CONFIG_ARM_PAC_PER_THREAD
|
||||
/* Generate PAC key and save it in thread context to be set later
|
||||
* when the thread is actually switched in
|
||||
*/
|
||||
sys_csrand_get(&thread->arch.pac_keys, sizeof(struct pac_keys));
|
||||
#endif
|
||||
/*
|
||||
* initial values in all other registers/thread entries are
|
||||
@@ -541,6 +548,9 @@ void arch_switch_to_main_thread(struct k_thread *main_thread, char *stack_ptr,
|
||||
#endif
|
||||
#endif /* CONFIG_BUILTIN_STACK_GUARD */
|
||||
|
||||
#ifdef CONFIG_ARM_PAC_PER_THREAD
|
||||
__set_PAC_KEY_P((uint32_t *)&main_thread->arch.pac_keys);
|
||||
#endif
|
||||
/*
|
||||
* Set PSP to the highest address of the main stack
|
||||
* before enabling interrupts and jumping to main.
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014 Wind River Systems, Inc.
|
||||
* Copyright 2025 Arm Limited and/or its affiliates <open-source-office@arm.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -32,6 +33,10 @@
|
||||
GEN_OFFSET_SYM(_thread_arch_t, basepri);
|
||||
GEN_OFFSET_SYM(_thread_arch_t, swap_return_value);
|
||||
|
||||
#if defined(CONFIG_ARM_PAC_PER_THREAD)
|
||||
GEN_OFFSET_SYM(_thread_arch_t, pac_keys);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_CPU_AARCH32_CORTEX_A) || defined(CONFIG_CPU_AARCH32_CORTEX_R)
|
||||
GEN_OFFSET_SYM(_thread_arch_t, exception_depth);
|
||||
GEN_OFFSET_SYM(_cpu_arch_t, exc_depth);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2019 Carlo Caione <ccaione@baylibre.com>
|
||||
* Copyright 2025 Arm Limited and/or its affiliates <open-source-office@arm.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -59,6 +60,10 @@
|
||||
(___thread_stack_info_t_start_OFFSET + ___thread_t_stack_info_OFFSET)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_ARM_PAC_PER_THREAD)
|
||||
#define _thread_offset_to_pac_keys \
|
||||
(___thread_t_arch_OFFSET + ___thread_arch_t_pac_keys_OFFSET)
|
||||
#endif
|
||||
|
||||
/* end - threads */
|
||||
|
||||
|
||||
@@ -76,6 +76,23 @@ config ARM_MPU
|
||||
of full partitioning the default behavior for the ARMv8-M and ARMv8-R MPU
|
||||
driver.
|
||||
|
||||
config ARM_PAC_PER_THREAD
|
||||
bool "Set cryptographically secure PAC key per thread"
|
||||
depends on ARM_PAC
|
||||
depends on ENTROPY_DEVICE_RANDOM_GENERATOR || TIMER_RANDOM_GENERATOR
|
||||
depends on !USERSPACE
|
||||
help
|
||||
Select this option to generate and use unique keys per thread to generate Pointer
|
||||
Authentication Code.
|
||||
Internally, sys_csrand_get() is used as part of arch_new_thread() to generate
|
||||
cryptographically secure random keys, which are saved in the thread's
|
||||
architecture-specific context. These keys are then loaded into the PAC key registers
|
||||
before switching to the thread during context switches.
|
||||
Applications can chose to have hardware based random keys generator by selecting the right
|
||||
generator from RNG_GENERATOR_CHOICE or by selecting TIMER_RANDOM_GENERATOR for testing
|
||||
with pseudo random keys.
|
||||
Note: GCC version 14.3 or higher is needed to support this option.
|
||||
|
||||
config ARM_PAC
|
||||
bool
|
||||
help
|
||||
|
||||
@@ -459,6 +459,11 @@ automatically selected based on the branch protection option chosen for
|
||||
:kconfig:option:`CONFIG_ARM_PACBTI`. These configuration options enforce PACBTI by enabling
|
||||
corresponding PACBTI bits in CONTROL register and in the FVP.
|
||||
|
||||
To further enhance pointer authentication, Zephyr supports using cryptographically secure,
|
||||
per-thread PAC keys by enabling :kconfig:option:`CONFIG_ARM_PAC_PER_THREAD`.
|
||||
For more details on key generation sources and configuration, refer to the Kconfig help for
|
||||
:kconfig:option:`CONFIG_ARM_PAC_PER_THREAD`.
|
||||
|
||||
**Limitations:**
|
||||
|
||||
- Only builds targeting Armv8.1-M Mainline processors with PACBTI hardware support (e.g.,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Intel Corporation
|
||||
* Copyright 2025 Arm Limited and/or its affiliates <open-source-office@arm.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -60,6 +61,15 @@ struct _preempt_float {
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_ARM_PAC_PER_THREAD)
|
||||
struct pac_keys {
|
||||
uint32_t key_0;
|
||||
uint32_t key_1;
|
||||
uint32_t key_2;
|
||||
uint32_t key_3;
|
||||
};
|
||||
#endif
|
||||
|
||||
struct _thread_arch {
|
||||
|
||||
/* interrupt locking key */
|
||||
@@ -134,6 +144,10 @@ struct _thread_arch {
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_ARM_PAC_PER_THREAD)
|
||||
struct pac_keys pac_keys;
|
||||
#endif
|
||||
};
|
||||
|
||||
#if defined(CONFIG_FPU_SHARING) && defined(CONFIG_MPU_STACK_GUARD)
|
||||
|
||||
@@ -147,4 +147,10 @@ typedef enum {
|
||||
#error "Unknown Cortex-M device"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARM_PAC
|
||||
/* This provides apis to set/get PAC keys */
|
||||
#define __ARM_FEATURE_PAUTH 1
|
||||
#include <m-profile/armv81m_pac.h>
|
||||
#endif
|
||||
|
||||
#endif /* ZEPHYR_MODULES_CMSIS_6_CMSIS_CORE_M_DEFAULTS_H_ */
|
||||
|
||||
Reference in New Issue
Block a user