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
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 @@
 {
 	/* 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 @@
 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 @@
 	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 @@
 	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 @@
 	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 @@
 	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 @@
 	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)