diff options
author | Alexei Fedorov <Alexei.Fedorov@arm.com> | 2019-10-03 10:57:53 +0100 |
---|---|---|
committer | Alexei Fedorov <Alexei.Fedorov@arm.com> | 2019-10-04 14:20:21 +0100 |
commit | 719714f1895399e6d64049bed3b03c2597d95402 (patch) | |
tree | eb40c8e9ffd2dae7a99f42a8a72254c6152a85f3 /lib | |
parent | e73248e004d971adb6259000d463c929f756a345 (diff) |
TF-A Tests: Enable PAuth on warm boot path
This patch provides the following features and makes
modifications listed below:
- `plat_init_apiakey()` function is replaced with `init_apkey()`
which returns 128-bit value and uses Generic timer physical counter
value to increase the randomness of the generated key.
The new function can be used for generation of all ARMv8.3-PAuth keys.
- Source file `pauth.c` moved from `plat/common/aarch64`
to `lib/extensions/pauth/aarch64` folder which contains PAuth specific
code.
- Individual APIAKey key generation for each CPU on every warm boot.
- Per-CPU storage of APIAKey added in `tftf_suspend_context` structure.
- APIAKey key is saved/restored in arch context on entry/exit from
suspended state.
- Added `pauth_init_enable()` function which generates, programs
and enables APIAKey in EL1/EL2.
- Changes in documentation related to ARMv8.3-PAuth support.
Signed-off-by: Alexei Fedorov <Alexei.Fedorov@arm.com>
Change-Id: I964b8f964bb541cbb0b2f772cb0b07aed055fe36
Diffstat (limited to 'lib')
-rw-r--r-- | lib/extensions/pauth/aarch64/pauth.c | 26 | ||||
-rw-r--r-- | lib/extensions/pauth/aarch64/pauth_helpers.S | 53 | ||||
-rw-r--r-- | lib/power_management/hotplug/hotplug.c | 13 | ||||
-rw-r--r-- | lib/power_management/suspend/aarch64/asm_tftf_suspend.S | 38 | ||||
-rw-r--r-- | lib/power_management/suspend/suspend_private.h | 12 |
5 files changed, 126 insertions, 16 deletions
diff --git a/lib/extensions/pauth/aarch64/pauth.c b/lib/extensions/pauth/aarch64/pauth.c new file mode 100644 index 0000000..03de468 --- /dev/null +++ b/lib/extensions/pauth/aarch64/pauth.c @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2019, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <arch_helpers.h> +#include <cdefs.h> +#include <stdint.h> + +/* + * This is only a toy implementation to generate a seemingly random + * 128-bit key from sp, x30 and cntpct_el0 values. + */ +uint128_t init_apkey(void) +{ + uint64_t return_addr = (uint64_t)__builtin_return_address(0U); + uint64_t frame_addr = (uint64_t)__builtin_frame_address(0U); + + uint64_t cntpct = read_cntpct_el0(); + + uint64_t key_lo = (return_addr << 13) ^ frame_addr ^ cntpct; + uint64_t key_hi = (frame_addr << 15) ^ return_addr ^ cntpct; + + return ((uint128_t)(key_hi) << 64) | key_lo; +} diff --git a/lib/extensions/pauth/aarch64/pauth_helpers.S b/lib/extensions/pauth/aarch64/pauth_helpers.S new file mode 100644 index 0000000..e15cac9 --- /dev/null +++ b/lib/extensions/pauth/aarch64/pauth_helpers.S @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2019, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <arch.h> +#include <asm_macros.S> + + .global pauth_init_enable + +/* ----------------------------------------------------------- + * Program APIAKey_EL1 key and enable Pointer Authentication + * of instruction addresses in the current translation regime + * for the calling CPU. + * ----------------------------------------------------------- + */ +func pauth_init_enable + stp x29, x30, [sp, #-16]! + + /* Initialize platform key */ + bl init_apkey + + /* + * Program instruction key A used by + * the Trusted Firmware Test Framework + */ + msr APIAKeyLo_EL1, x0 + msr APIAKeyHi_EL1, x1 + + /* Detect Current Exception level */ + mrs x0, CurrentEL + cmp x0, #(MODE_EL1 << MODE_EL_SHIFT) + b.eq enable_el1 + + /* Enable EL2 pointer authentication */ + mrs x0, sctlr_el2 + orr x0, x0, #SCTLR_EnIA_BIT + msr sctlr_el2, x0 + b enable_exit + + /* Enable EL1 pointer authentication */ +enable_el1: + mrs x0, sctlr_el1 + orr x0, x0, #SCTLR_EnIA_BIT + msr sctlr_el1, x0 + +enable_exit: + isb + + ldp x29, x30, [sp], #16 + ret +endfunc pauth_init_enable diff --git a/lib/power_management/hotplug/hotplug.c b/lib/power_management/hotplug/hotplug.c index 37bfc06..76fa287 100644 --- a/lib/power_management/hotplug/hotplug.c +++ b/lib/power_management/hotplug/hotplug.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Arm Limited. All rights reserved. + * Copyright (c) 2018-2019, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -11,6 +11,7 @@ #include <drivers/arm/arm_gic.h> #include <drivers/console.h> #include <irq.h> +#include <pauth.h> #include <platform.h> #include <platform_def.h> #include <power_management.h> @@ -288,6 +289,16 @@ void __dead2 tftf_warm_boot_main(void) { /* Initialise the CPU */ tftf_arch_setup(); + +#if ENABLE_PAUTH + /* + * Program APIAKey_EL1 key and enable ARMv8.3-PAuth here as this + * function doesn't return, and RETAA instuction won't be executed, + * what would cause translation fault otherwise. + */ + pauth_init_enable(); +#endif /* ENABLE_PAUTH */ + arm_gic_setup_local(); /* Enable the SGI used by the timer management framework */ diff --git a/lib/power_management/suspend/aarch64/asm_tftf_suspend.S b/lib/power_management/suspend/aarch64/asm_tftf_suspend.S index 692bade..09950b5 100644 --- a/lib/power_management/suspend/aarch64/asm_tftf_suspend.S +++ b/lib/power_management/suspend/aarch64/asm_tftf_suspend.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Arm Limited. All rights reserved. + * Copyright (c) 2018-2019, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -54,6 +54,11 @@ func __tftf_suspend endfunc __tftf_suspend func __tftf_save_arch_context +#if ENABLE_PAUTH + mrs x1, APIAKeyLo_EL1 + mrs x2, APIAKeyHi_EL1 + stp x1, x2, [x0, #SUSPEND_CTX_APIAKEY_OFFSET] +#endif JUMP_EL1_OR_EL2 x1, 1f, 2f, dead 1: mrs x1, mair_el1 mrs x2, cpacr_el1 @@ -61,9 +66,9 @@ func __tftf_save_arch_context mrs x4, tcr_el1 mrs x5, vbar_el1 mrs x6, sctlr_el1 - stp x1, x2, [x0] - stp x3, x4, [x0, #16] - stp x5, x6, [x0, #32] + stp x1, x2, [x0, #SUSPEND_CTX_MAIR_OFFSET] + stp x3, x4, [x0, #SUSPEND_CTX_TTBR0_OFFSET] + stp x5, x6, [x0, #SUSPEND_CTX_VBAR_OFFSET] ret 2: mrs x1, mair_el2 @@ -72,9 +77,9 @@ func __tftf_save_arch_context mrs x4, tcr_el2 mrs x5, vbar_el2 mrs x6, sctlr_el2 - stp x1, x2, [x0] - stp x3, x4, [x0, #16] - stp x5, x6, [x0, #32] + stp x1, x2, [x0, #SUSPEND_CTX_MAIR_OFFSET] + stp x3, x4, [x0, #SUSPEND_CTX_TTBR0_OFFSET] + stp x5, x6, [x0, #SUSPEND_CTX_VBAR_OFFSET] ret endfunc __tftf_save_arch_context @@ -86,9 +91,9 @@ func __tftf_cpu_resume_ep JUMP_EL1_OR_EL2 x1, 1f, 2f, dead 1: /* Invalidate local tlb entries before turning on MMU */ tlbi vmalle1 - ldp x1, x2, [x0] - ldp x3, x4, [x0, #16] - ldp x5, x6, [x0, #32] + ldp x1, x2, [x0, #SUSPEND_CTX_MAIR_OFFSET] + ldp x3, x4, [x0, #SUSPEND_CTX_TTBR0_OFFSET] + ldp x5, x6, [x0, #SUSPEND_CTX_VBAR_OFFSET] msr mair_el1, x1 msr cpacr_el1, x2 msr ttbr0_el1, x3 @@ -101,13 +106,13 @@ func __tftf_cpu_resume_ep msr sctlr_el1, x6 /* Ensure the MMU enable takes effect immediately */ isb - b restore_callee_regs + b restore_callee_regs /* Invalidate local tlb entries before turning on MMU */ 2: tlbi alle2 - ldp x1, x2, [x0] - ldp x3, x4, [x0, #16] - ldp x5, x6, [x0, #32] + ldp x1, x2, [x0, #SUSPEND_CTX_MAIR_OFFSET] + ldp x3, x4, [x0, #SUSPEND_CTX_TTBR0_OFFSET] + ldp x5, x6, [x0, #SUSPEND_CTX_VBAR_OFFSET] msr mair_el2, x1 msr hcr_el2, x2 msr ttbr0_el2, x3 @@ -122,6 +127,11 @@ func __tftf_cpu_resume_ep isb restore_callee_regs: +#if ENABLE_PAUTH + ldp x1, x2, [x0, #SUSPEND_CTX_APIAKEY_OFFSET] + msr APIAKeyLo_EL1, x1 + msr APIAKeyHi_EL1, x2 +#endif ldr x2, [x0, #SUSPEND_CTX_SP_OFFSET] mov sp, x2 ldr w1, [x0, #SUSPEND_CTX_SAVE_SYSTEM_CTX_OFFSET] diff --git a/lib/power_management/suspend/suspend_private.h b/lib/power_management/suspend/suspend_private.h index b67bbab..bc2f3a6 100644 --- a/lib/power_management/suspend/suspend_private.h +++ b/lib/power_management/suspend/suspend_private.h @@ -9,11 +9,21 @@ /* * Number of system registers we need to save/restore across a CPU suspend: - * MAIR, CPACR_EL1/HCR_EL2, TTBR0, TCR, VBAR and SCTLR. + * MAIR, CPACR_EL1/HCR_EL2, TTBR0, TCR, VBAR, SCTLR, + * APIAKeyLo_EL1 and APIAKeyHi_EL1 (if enabled). */ +#if ENABLE_PAUTH +#define NR_CTX_REGS 8 +#else #define NR_CTX_REGS 6 +#endif /* Offsets of the fields in the context structure. Needed by asm code. */ +#define SUSPEND_CTX_MAIR_OFFSET 0 +#define SUSPEND_CTX_TTBR0_OFFSET 16 +#define SUSPEND_CTX_VBAR_OFFSET 32 +#define SUSPEND_CTX_APIAKEY_OFFSET 48 + #define SUSPEND_CTX_SP_OFFSET (8 * NR_CTX_REGS) #define SUSPEND_CTX_SAVE_SYSTEM_CTX_OFFSET (SUSPEND_CTX_SP_OFFSET + 8) |