Add ARMv8.3 pointer authentication support

ARMv8.3-PAuth adds functionality that supports address authentication of
the contents of a register before that register is used as the target of
an indirect branch, or as a load.

This feature is supported only in AArch64 state.

This feature is mandatory in ARMv8.3 implementations.

This patch adds the functionality needed for platforms to provide
authentication keys for the TF-A Test Framework, and a new option
(ENABLE_PAUTH) to enable pointer authentication in the framework itself.
This option is disabled by default.

Pointer authentication support has been added to FVP.

Change-Id: Id2d5c978deb68ae60107879f1c3d0b231cba9f42
Signed-off-by: Antonio Nino Diaz <antonio.ninodiaz@arm.com>
diff --git a/tftf/framework/main.c b/tftf/framework/main.c
index 67f565d..e84e450 100644
--- a/tftf/framework/main.c
+++ b/tftf/framework/main.c
@@ -1,10 +1,11 @@
 /*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <arch_helpers.h>
+#include <arch_features.h>
 #include <assert.h>
 #include <debug.h>
 #include <drivers/arm/arm_gic.h>
@@ -518,6 +519,30 @@
 #endif
 
 	tftf_arch_setup();
+
+	/*
+	 * Enable pointer authentication. tftf_cold_boot_main() never returns,
+	 * so it is safe to do it here. If this function was to return, the
+	 * authentication would fail then.
+	 */
+#if ENABLE_PAUTH
+	assert(is_armv8_3_pauth_apa_api_present());
+
+	uint64_t *apiakey = plat_init_apiakey();
+
+	write_apiakeylo_el1(apiakey[0]);
+	write_apiakeyhi_el1(apiakey[1]);
+
+	if (IS_IN_EL2()) {
+		write_sctlr_el2(read_sctlr_el2() | SCTLR_EnIA_BIT);
+	} else {
+		assert(IS_IN_EL1());
+		write_sctlr_el1(read_sctlr_el1() | SCTLR_EnIA_BIT);
+	}
+
+	isb();
+#endif /* ENABLE_PAUTH */
+
 	tftf_platform_setup();
 	tftf_init_topology();