summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAlexei Fedorov <Alexei.Fedorov@arm.com>2019-10-03 10:57:53 +0100
committerAlexei Fedorov <Alexei.Fedorov@arm.com>2019-10-04 14:20:21 +0100
commit719714f1895399e6d64049bed3b03c2597d95402 (patch)
treeeb40c8e9ffd2dae7a99f42a8a72254c6152a85f3 /lib
parente73248e004d971adb6259000d463c929f756a345 (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.c26
-rw-r--r--lib/extensions/pauth/aarch64/pauth_helpers.S53
-rw-r--r--lib/power_management/hotplug/hotplug.c13
-rw-r--r--lib/power_management/suspend/aarch64/asm_tftf_suspend.S38
-rw-r--r--lib/power_management/suspend/suspend_private.h12
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)