test(tftf): test PAuth in Realm

- Enable PAuth in Realm RL1 by default.
- Check if PAuth keys are accessible in Realm RL1.
- Check if Realm PAuth keys are preserved across RMM entry/exit.
- Check if NS PAuth keys are preserved across RMM entry/exit.
- Generate PAuth fault by cloberring LR.

Signed-off-by: Shruti Gupta <shruti.gupta@arm.com>
Change-Id: I85d8e03ec604c96117555e7aa866453cb2745cfe
diff --git a/fwu/ns_bl2u/ns_bl2u.mk b/fwu/ns_bl2u/ns_bl2u.mk
index 0864313..7225d01 100644
--- a/fwu/ns_bl2u/ns_bl2u.mk
+++ b/fwu/ns_bl2u/ns_bl2u.mk
@@ -16,6 +16,7 @@
 	-Iinclude/common/${ARCH}			\
 	-Iinclude/lib					\
 	-Iinclude/lib/${ARCH}				\
+	-Iinclude/lib/extensions			\
 	-Iinclude/lib/utils				\
 	-Iinclude/lib/xlat_tables			\
 	-Iinclude/plat/common				\
diff --git a/include/lib/extensions/pauth.h b/include/lib/extensions/pauth.h
index d072f5c..c8d577f 100644
--- a/include/lib/extensions/pauth.h
+++ b/include/lib/extensions/pauth.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,6 +7,7 @@
 #ifndef PAUTH_H
 #define PAUTH_H
 
+#include <stdbool.h>
 #include <stdint.h>
 
 #ifdef __aarch64__
@@ -18,6 +19,22 @@
 
 /* Disable ARMv8.3-PAuth */
 void pauth_disable(void);
+
+/*
+ * Fill Pauth Keys and template with random values if keys werenot initialized earlier,
+ * Else Copy PAuth key registers to template.
+ */
+void pauth_test_lib_fill_regs_and_template(void);
+
+/* Read and Compare PAuth registers with provided template values. */
+bool pauth_test_lib_compare_template(void);
+
+/* Read and Store PAuth registers in template. */
+void pauth_test_lib_read_keys(void);
+
+/* Test PAuth instructions. */
+void pauth_test_lib_test_intrs(void);
+
 #endif	/* __aarch64__ */
 
 #endif /* PAUTH_H */
diff --git a/include/runtime_services/host_realm_managment/host_shared_data.h b/include/runtime_services/host_realm_managment/host_shared_data.h
index 98ab287..821a62f 100644
--- a/include/runtime_services/host_realm_managment/host_shared_data.h
+++ b/include/runtime_services/host_realm_managment/host_shared_data.h
@@ -55,7 +55,10 @@
 	REALM_SVE_ID_REGISTERS,
 	REALM_SVE_PROBE_VL,
 	REALM_SVE_OPS,
-	REALM_SVE_FILL_REGS
+	REALM_SVE_FILL_REGS,
+	REALM_PAUTH_SET_CMD,
+	REALM_PAUTH_CHECK_CMD,
+	REALM_PAUTH_FAULT
 };
 
 /*
diff --git a/lib/extensions/pauth/aarch64/pauth.c b/lib/extensions/pauth/aarch64/pauth.c
index 03de468..90e16d5 100644
--- a/lib/extensions/pauth/aarch64/pauth.c
+++ b/lib/extensions/pauth/aarch64/pauth.c
@@ -6,7 +6,18 @@
 
 #include <arch_helpers.h>
 #include <cdefs.h>
+#include <stdbool.h>
 #include <stdint.h>
+#include <debug.h>
+#include <pauth.h>
+
+/* Number of ARMv8.3-PAuth keys */
+#define NUM_KEYS        5U
+
+static const char * const key_name[] = {"IA", "IB", "DA", "DB", "GA"};
+
+static uint128_t pauth_keys_before[NUM_KEYS];
+static uint128_t pauth_keys_after[NUM_KEYS];
 
 /*
  * This is only a toy implementation to generate a seemingly random
@@ -24,3 +35,151 @@
 
 	return ((uint128_t)(key_hi) << 64) | key_lo;
 }
+
+/* Check if ARMv8.3-PAuth key is enabled */
+static bool is_pauth_key_enabled(uint64_t key_bit)
+{
+	unsigned int el = (unsigned int)GET_EL(read_CurrentEl());
+
+	if (el == 1U) {
+		return ((read_sctlr_el1() & key_bit) != 0U);
+	} else if (el == 2U) {
+		return ((read_sctlr_el2() & key_bit) != 0U);
+	}
+	return false;
+}
+
+bool pauth_test_lib_compare_template(void)
+{
+	bool result = true;
+
+	pauth_test_lib_read_keys();
+	for (unsigned int i = 0U; i < NUM_KEYS; ++i) {
+		if (pauth_keys_before[i] != pauth_keys_after[i]) {
+			ERROR("AP%sKey_EL1 read 0x%llx:%llx "
+			"expected 0x%llx:%llx\n", key_name[i],
+			(uint64_t)(pauth_keys_after[i] >> 64U),
+			(uint64_t)(pauth_keys_after[i]),
+			(uint64_t)(pauth_keys_before[i] >> 64U),
+			(uint64_t)(pauth_keys_before[i]));
+
+			result = false;
+		}
+	}
+	return result;
+}
+
+/*
+ * Program or read ARMv8.3-PAuth keys (if already enabled)
+ * and store them in <pauth_keys_before> buffer
+ */
+void pauth_test_lib_fill_regs_and_template(void)
+{
+	uint128_t plat_key;
+
+	(void)memset(pauth_keys_before, 0, NUM_KEYS * sizeof(uint128_t));
+
+	if (is_pauth_key_enabled(SCTLR_EnIA_BIT)) {
+		/* Read APIAKey_EL1 */
+		plat_key = read_apiakeylo_el1() |
+			((uint128_t)(read_apiakeyhi_el1()) << 64U);
+		INFO("EnIA is set\n");
+	} else {
+		/* Program APIAKey_EL1 */
+		plat_key = init_apkey();
+		write_apiakeylo_el1((uint64_t)plat_key);
+		write_apiakeyhi_el1((uint64_t)(plat_key >> 64U));
+	}
+	pauth_keys_before[0] = plat_key;
+
+	if (is_pauth_key_enabled(SCTLR_EnIB_BIT)) {
+		/* Read APIBKey_EL1 */
+		plat_key = read_apibkeylo_el1() |
+			((uint128_t)(read_apibkeyhi_el1()) << 64U);
+		INFO("EnIB is set\n");
+	} else {
+		/* Program APIBKey_EL1 */
+		plat_key = init_apkey();
+		write_apibkeylo_el1((uint64_t)plat_key);
+		write_apibkeyhi_el1((uint64_t)(plat_key >> 64U));
+	}
+	pauth_keys_before[1] = plat_key;
+
+	if (is_pauth_key_enabled(SCTLR_EnDA_BIT)) {
+		/* Read APDAKey_EL1 */
+		plat_key = read_apdakeylo_el1() |
+			((uint128_t)(read_apdakeyhi_el1()) << 64U);
+		INFO("EnDA is set\n");
+	} else {
+		/* Program APDAKey_EL1 */
+		plat_key = init_apkey();
+		write_apdakeylo_el1((uint64_t)plat_key);
+		write_apdakeyhi_el1((uint64_t)(plat_key >> 64U));
+	}
+	pauth_keys_before[2] = plat_key;
+
+	if (is_pauth_key_enabled(SCTLR_EnDB_BIT)) {
+		/* Read APDBKey_EL1 */
+		plat_key = read_apdbkeylo_el1() |
+			((uint128_t)(read_apdbkeyhi_el1()) << 64U);
+		INFO("EnDB is set\n");
+	} else {
+		/* Program APDBKey_EL1 */
+		plat_key = init_apkey();
+		write_apdbkeylo_el1((uint64_t)plat_key);
+		write_apdbkeyhi_el1((uint64_t)(plat_key >> 64U));
+	}
+	pauth_keys_before[3] = plat_key;
+
+	pauth_keys_before[4] = read_apgakeylo_el1() |
+			       ((uint128_t)(read_apgakeyhi_el1()) << 64U);
+	if (pauth_keys_before[4] == 0ULL) {
+		/* Program APGAKey_EL1 */
+		plat_key = init_apkey();
+		write_apgakeylo_el1((uint64_t)plat_key);
+		write_apgakeyhi_el1((uint64_t)(plat_key >> 64U));
+		pauth_keys_before[4] = plat_key;
+	}
+
+	isb();
+}
+
+/*
+ * Read ARMv8.3-PAuth keys and store them in
+ * <pauth_keys_after> buffer
+ */
+void pauth_test_lib_read_keys(void)
+{
+	(void)memset(pauth_keys_after, 0, NUM_KEYS * sizeof(uint128_t));
+
+	/* Read APIAKey_EL1 */
+	pauth_keys_after[0] = read_apiakeylo_el1() |
+		((uint128_t)(read_apiakeyhi_el1()) << 64U);
+
+	/* Read APIBKey_EL1 */
+	pauth_keys_after[1] = read_apibkeylo_el1() |
+		((uint128_t)(read_apibkeyhi_el1()) << 64U);
+
+	/* Read APDAKey_EL1 */
+	pauth_keys_after[2] = read_apdakeylo_el1() |
+		((uint128_t)(read_apdakeyhi_el1()) << 64U);
+
+	/* Read APDBKey_EL1 */
+	pauth_keys_after[3] = read_apdbkeylo_el1() |
+		((uint128_t)(read_apdbkeyhi_el1()) << 64U);
+
+	/* Read APGAKey_EL1 */
+	pauth_keys_after[4] = read_apgakeylo_el1() |
+		((uint128_t)(read_apgakeyhi_el1()) << 64U);
+}
+
+/* Test execution of ARMv8.3-PAuth instructions */
+void pauth_test_lib_test_intrs(void)
+{
+	/* Pointer authentication instructions */
+	__asm__ volatile (
+			"paciasp\n"
+			"autiasp\n"
+			"paciasp\n"
+			"xpaclri");
+}
diff --git a/realm/aarch64/realm_entrypoint.S b/realm/aarch64/realm_entrypoint.S
index 28a37de..e0638f0 100644
--- a/realm/aarch64/realm_entrypoint.S
+++ b/realm/aarch64/realm_entrypoint.S
@@ -49,9 +49,14 @@
 	mov	x1, REALM_MAX_LOAD_IMG_SIZE
 	add	x1, x1, x0
 	bl	fixup_gdt_reloc
+#if ENABLE_PAUTH
+	bl	pauth_init_enable
+#endif
 
+loop:
 	/* And jump to the C entrypoint. */
-	b	realm_payload_main
+	bl	realm_payload_main
+	b	loop
 endfunc realm_entrypoint
 
 /* Initialize architectural state. */
diff --git a/realm/include/realm_tests.h b/realm/include/realm_tests.h
index 61d4493..4bd260c 100644
--- a/realm/include/realm_tests.h
+++ b/realm/include/realm_tests.h
@@ -12,6 +12,9 @@
 bool test_pmuv3_event_works_realm(void);
 bool test_pmuv3_rmm_preserves(void);
 bool test_pmuv3_overflow_interrupt(void);
+bool test_realm_pauth_set_cmd(void);
+bool test_realm_pauth_check_cmd(void);
+bool test_realm_pauth_fault(void);
 bool test_realm_sve_rdvl(void);
 bool test_realm_sve_read_id_registers(void);
 bool test_realm_sve_probe_vl(void);
diff --git a/realm/realm.mk b/realm/realm.mk
index 047dff8..77499d0 100644
--- a/realm/realm.mk
+++ b/realm/realm.mk
@@ -28,6 +28,7 @@
 	aarch64/realm_exceptions.S					\
 	realm_debug.c							\
 	realm_interrupt.c						\
+	realm_pauth.c							\
 	realm_payload_main.c						\
 	realm_pmuv3.c							\
 	realm_rsi.c							\
@@ -52,6 +53,12 @@
 
 REALM_LINKERFILE:=	realm/realm.ld.S
 
+# ARMv8.3 Pointer Authentication support files
+REALM_SOURCES +=	lib/extensions/pauth/aarch64/pauth.c            \
+			lib/extensions/pauth/aarch64/pauth_helpers.S
+
+REALM_INCLUDES +=	-Iinclude/lib/extensions
+
 REALM_DEFINES:=
 $(eval $(call add_define,REALM_DEFINES,ARM_ARCH_MAJOR))
 $(eval $(call add_define,REALM_DEFINES,ARM_ARCH_MINOR))
diff --git a/realm/realm_pauth.c b/realm/realm_pauth.c
new file mode 100644
index 0000000..0a5a022
--- /dev/null
+++ b/realm/realm_pauth.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <stdio.h>
+#include <arch_features.h>
+#include <debug.h>
+#include <pauth.h>
+#include <realm_rsi.h>
+#include <sync.h>
+
+static volatile bool set_cmd_done;
+
+static bool exception_handler(void)
+{
+	u_register_t lr = read_elr_el1();
+
+	/* Disable PAuth to avoid further PAuth faults. */
+	pauth_disable();
+
+	/* Check for PAuth exception. */
+	/* Note- PAuth decode instruction clobbers PAC Fields[63:56] in case of error. */
+	if (lr & (0xFFULL << 56U)) {
+		rsi_exit_to_host(HOST_CALL_EXIT_SUCCESS_CMD);
+	}
+
+	rsi_exit_to_host(HOST_CALL_EXIT_FAILED_CMD);
+
+	/* Does not return. */
+	return false;
+}
+
+void dummy_func(void)
+{
+	realm_printf("Realm: shouldn't reach here.\n");
+	rsi_exit_to_host(HOST_CALL_EXIT_FAILED_CMD);
+}
+
+bool test_realm_pauth_fault(void)
+{
+	u_register_t ptr = (u_register_t)dummy_func;
+
+	if (!is_armv8_3_pauth_present()) {
+		return false;
+	}
+
+	register_custom_sync_exception_handler(exception_handler);
+	realm_printf("Realm: overwrite LR to generate fault.\n");
+	__asm__("mov	x17, x30;	"
+		"mov	x30, %0;	"	/* overwite LR. */
+		"isb;			"
+		"autiasp;		"
+		"ret;			"	/* fault on return.  */
+		:
+		: "r"(ptr));
+
+	/* Does not return. */
+	return false;
+}
+
+/*
+ * TF-A is expected to allow access to key registers from lower EL's,
+ * reading the keys excercises this, on failure this will trap to
+ * EL3 and crash.
+ */
+bool test_realm_pauth_set_cmd(void)
+{
+	if (!is_armv8_3_pauth_present()) {
+		return false;
+	}
+	pauth_test_lib_test_intrs();
+	pauth_test_lib_fill_regs_and_template();
+	set_cmd_done = true;
+	return true;
+}
+
+bool test_realm_pauth_check_cmd(void)
+{
+	if (!is_armv8_3_pauth_present() || !set_cmd_done) {
+		return false;
+	}
+	return pauth_test_lib_compare_template();
+}
diff --git a/realm/realm_payload_main.c b/realm/realm_payload_main.c
index d99037a..e867546 100644
--- a/realm/realm_payload_main.c
+++ b/realm/realm_payload_main.c
@@ -7,10 +7,12 @@
 
 #include <stdio.h>
 
+#include <arch_features.h>
 #include <debug.h>
 #include <fpu.h>
 #include <host_realm_helper.h>
 #include <host_shared_data.h>
+#include <pauth.h>
 #include "realm_def.h"
 #include <realm_rsi.h>
 #include <realm_tests.h>
@@ -62,7 +64,6 @@
 	bool test_succeed = false;
 
 	realm_set_shared_structure((host_shared_data_t *)rsi_get_ns_buffer());
-
 	if (realm_get_shared_structure() != NULL) {
 		uint8_t cmd = realm_shared_data_get_realm_cmd();
 
@@ -71,6 +72,15 @@
 			realm_sleep_cmd();
 			test_succeed = true;
 			break;
+		case REALM_PAUTH_SET_CMD:
+			test_succeed = test_realm_pauth_set_cmd();
+			break;
+		case REALM_PAUTH_CHECK_CMD:
+			test_succeed = test_realm_pauth_check_cmd();
+			break;
+		case REALM_PAUTH_FAULT:
+			test_succeed = test_realm_pauth_fault();
+			break;
 		case REALM_GET_RSI_VERSION:
 			realm_get_rsi_version();
 			test_succeed = true;
diff --git a/tftf/tests/extensions/pauth/test_pauth.c b/tftf/tests/extensions/pauth/test_pauth.c
index b7434a8..b29e5d0 100644
--- a/tftf/tests/extensions/pauth/test_pauth.c
+++ b/tftf/tests/extensions/pauth/test_pauth.c
@@ -13,157 +13,6 @@
 #include <tsp.h>
 #include <string.h>
 
-#ifdef __aarch64__
-
-/* Number of ARMv8.3-PAuth keys */
-#define NUM_KEYS	5
-
-static const char * const key_name[] = {"IA", "IB", "DA", "DB", "GA"};
-
-static uint128_t pauth_keys_before[NUM_KEYS];
-static uint128_t pauth_keys_after[NUM_KEYS];
-
-/* Check if ARMv8.3-PAuth key is enabled */
-static bool is_pauth_key_enabled(uint64_t key_bit)
-{
-	return (IS_IN_EL2() ?
-		((read_sctlr_el2() & key_bit) != 0U) :
-		((read_sctlr_el1() & key_bit) != 0U));
-}
-
-static test_result_t compare_pauth_keys(void)
-{
-	test_result_t result = TEST_RESULT_SUCCESS;
-
-	for (unsigned int i = 0; i < NUM_KEYS; ++i) {
-		if (pauth_keys_before[i] != pauth_keys_after[i]) {
-			ERROR("AP%sKey_EL1 read 0x%llx:%llx "
-			"expected 0x%llx:%llx\n", key_name[i],
-			(uint64_t)(pauth_keys_after[i] >> 64),
-			(uint64_t)(pauth_keys_after[i]),
-			(uint64_t)(pauth_keys_before[i] >> 64),
-			(uint64_t)(pauth_keys_before[i]));
-
-			result = TEST_RESULT_FAIL;
-		}
-	}
-	return result;
-}
-
-/*
- * Program or read ARMv8.3-PAuth keys (if already enabled)
- * and store them in <pauth_keys_before> buffer
- */
-static void set_store_pauth_keys(void)
-{
-	uint128_t plat_key;
-
-	memset(pauth_keys_before, 0, NUM_KEYS * sizeof(uint128_t));
-
-	if (is_armv8_3_pauth_apa_api_apa3_present()) {
-		if (is_pauth_key_enabled(SCTLR_EnIA_BIT)) {
-			/* Read APIAKey_EL1 */
-			plat_key = read_apiakeylo_el1() |
-				((uint128_t)(read_apiakeyhi_el1()) << 64);
-			INFO("EnIA is set\n");
-		} else {
-			/* Program APIAKey_EL1 */
-			plat_key = init_apkey();
-			write_apiakeylo_el1((uint64_t)plat_key);
-			write_apiakeyhi_el1((uint64_t)(plat_key >> 64));
-		}
-		pauth_keys_before[0] = plat_key;
-
-		if (is_pauth_key_enabled(SCTLR_EnIB_BIT)) {
-			/* Read APIBKey_EL1 */
-			plat_key = read_apibkeylo_el1() |
-				((uint128_t)(read_apibkeyhi_el1()) << 64);
-			INFO("EnIB is set\n");
-		} else {
-			/* Program APIBKey_EL1 */
-			plat_key = init_apkey();
-			write_apibkeylo_el1((uint64_t)plat_key);
-			write_apibkeyhi_el1((uint64_t)(plat_key >> 64));
-		}
-		pauth_keys_before[1] = plat_key;
-
-		if (is_pauth_key_enabled(SCTLR_EnDA_BIT)) {
-			/* Read APDAKey_EL1 */
-			plat_key = read_apdakeylo_el1() |
-				((uint128_t)(read_apdakeyhi_el1()) << 64);
-			INFO("EnDA is set\n");
-		} else {
-			/* Program APDAKey_EL1 */
-			plat_key = init_apkey();
-			write_apdakeylo_el1((uint64_t)plat_key);
-			write_apdakeyhi_el1((uint64_t)(plat_key >> 64));
-		}
-		pauth_keys_before[2] = plat_key;
-
-		if (is_pauth_key_enabled(SCTLR_EnDB_BIT)) {
-			/* Read APDBKey_EL1 */
-			plat_key = read_apdbkeylo_el1() |
-				((uint128_t)(read_apdbkeyhi_el1()) << 64);
-			INFO("EnDB is set\n");
-		} else {
-			/* Program APDBKey_EL1 */
-			plat_key = init_apkey();
-			write_apdbkeylo_el1((uint64_t)plat_key);
-			write_apdbkeyhi_el1((uint64_t)(plat_key >> 64));
-		}
-		pauth_keys_before[3] = plat_key;
-	}
-
-	/*
-	 * It is safe to assume that Generic Pointer authentication code key
-	 * APGAKey_EL1 can be re-programmed, as this key is not set in
-	 * TF-A Test suite and PACGA instruction is not used.
-	 */
-	if (is_armv8_3_pauth_gpa_gpi_gpa3_present()) {
-		/* Program APGAKey_EL1 */
-		plat_key = init_apkey();
-		write_apgakeylo_el1((uint64_t)plat_key);
-		write_apgakeyhi_el1((uint64_t)(plat_key >> 64));
-		pauth_keys_before[4] = plat_key;
-	}
-
-	isb();
-}
-
-/*
- * Read ARMv8.3-PAuth keys and store them in
- * <pauth_keys_after> buffer
- */
-static void read_pauth_keys(void)
-{
-	memset(pauth_keys_after, 0, NUM_KEYS * sizeof(uint128_t));
-
-	if (is_armv8_3_pauth_apa_api_apa3_present()) {
-		/* Read APIAKey_EL1 */
-		pauth_keys_after[0] = read_apiakeylo_el1() |
-			((uint128_t)(read_apiakeyhi_el1()) << 64);
-
-		/* Read APIBKey_EL1 */
-		pauth_keys_after[1] = read_apibkeylo_el1() |
-			((uint128_t)(read_apibkeyhi_el1()) << 64);
-
-		/* Read APDAKey_EL1 */
-		pauth_keys_after[2] = read_apdakeylo_el1() |
-			((uint128_t)(read_apdakeyhi_el1()) << 64);
-
-		/* Read APDBKey_EL1 */
-		pauth_keys_after[3] = read_apdbkeylo_el1() |
-			((uint128_t)(read_apdbkeyhi_el1()) << 64);
-	}
-
-	if (is_armv8_3_pauth_gpa_gpi_gpa3_present()) {
-		/* Read APGAKey_EL1 */
-		pauth_keys_after[4] = read_apgakeylo_el1() |
-			((uint128_t)(read_apgakeyhi_el1()) << 64);
-	}
-}
-#endif	/* __aarch64__ */
-
 /*
  * TF-A is expected to allow access to key registers from lower EL's,
  * reading the keys excercises this, on failure this will trap to
@@ -174,7 +23,7 @@
 	SKIP_TEST_IF_AARCH32();
 #ifdef __aarch64__
 	SKIP_TEST_IF_PAUTH_NOT_SUPPORTED();
-	read_pauth_keys();
+	pauth_test_lib_read_keys();
 	return TEST_RESULT_SUCCESS;
 #endif	/* __aarch64__ */
 }
@@ -188,13 +37,11 @@
 	SKIP_TEST_IF_AARCH32();
 #ifdef __aarch64__
 	SKIP_TEST_IF_PAUTH_NOT_SUPPORTED();
-	set_store_pauth_keys();
+	pauth_test_lib_read_keys();
 
 	tftf_get_psci_version();
 
-	read_pauth_keys();
-
-	return compare_pauth_keys();
+	return pauth_test_lib_compare_template();
 #endif	/* __aarch64__ */
 }
 
@@ -220,7 +67,6 @@
 				ARM_ARCH_MAJOR, ARM_ARCH_MINOR);
 	return TEST_RESULT_SKIPPED;
 #endif	/* ARM_ARCH_AT_LEAST(8, 3) */
-
 #endif	/* __aarch64__ */
 }
 
@@ -238,7 +84,7 @@
 	SKIP_TEST_IF_PAUTH_NOT_SUPPORTED();
 	SKIP_TEST_IF_TSP_NOT_PRESENT();
 
-	set_store_pauth_keys();
+	pauth_test_lib_fill_regs_and_template();
 
 	/* Standard SMC to ADD two numbers */
 	tsp_svc_params.fid = TSP_STD_FID(TSP_ADD);
@@ -260,8 +106,6 @@
 		return TEST_RESULT_FAIL;
 	}
 
-	read_pauth_keys();
-
-	return compare_pauth_keys();
+	return pauth_test_lib_compare_template();
 #endif	/* __aarch64__ */
 }
diff --git a/tftf/tests/runtime_services/realm_payload/host_realm_payload_tests.c b/tftf/tests/runtime_services/realm_payload/host_realm_payload_tests.c
index ae62336..43747b1 100644
--- a/tftf/tests/runtime_services/realm_payload/host_realm_payload_tests.c
+++ b/tftf/tests/runtime_services/realm_payload/host_realm_payload_tests.c
@@ -12,6 +12,7 @@
 #include <irq.h>
 #include <drivers/arm/arm_gic.h>
 #include <drivers/arm/gic_v3.h>
+#include <pauth.h>
 #include <test_helpers.h>
 
 #include <host_realm_helper.h>
@@ -57,6 +58,97 @@
 
 	return host_cmp_result();
 }
+
+/*
+ * @Test_Aim@ Test PAuth in realm
+ */
+test_result_t host_realm_enable_pauth(void)
+{
+#if ENABLE_PAUTH == 0
+	return TEST_RESULT_SKIPPED;
+#else
+	bool ret1, ret2;
+
+	SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
+
+	pauth_test_lib_fill_regs_and_template();
+	if (!host_create_realm_payload((u_register_t)REALM_IMAGE_BASE,
+				(u_register_t)PAGE_POOL_BASE,
+				(u_register_t)(PAGE_POOL_MAX_SIZE +
+					NS_REALM_SHARED_MEM_SIZE),
+				(u_register_t)PAGE_POOL_MAX_SIZE,
+				0UL)) {
+		return TEST_RESULT_FAIL;
+	}
+
+	if (!host_create_shared_mem(NS_REALM_SHARED_MEM_BASE,
+				NS_REALM_SHARED_MEM_SIZE)) {
+		return TEST_RESULT_FAIL;
+	}
+
+	ret1 = host_enter_realm_execute(REALM_PAUTH_SET_CMD, NULL, RMI_EXIT_HOST_CALL);
+
+	if (ret1) {
+		/* Re-enter Realm to compare PAuth registers. */
+		ret1 = host_enter_realm_execute(REALM_PAUTH_CHECK_CMD, NULL, RMI_EXIT_HOST_CALL);
+	}
+
+	ret2 = host_destroy_realm();
+
+	if (!ret1) {
+		ERROR("%s(): enter=%d destroy=%d\n",
+				__func__, ret1, ret2);
+		return TEST_RESULT_FAIL;
+	}
+
+	/* Check if PAuth keys are preserved. */
+	if (!pauth_test_lib_compare_template()) {
+		ERROR("%s(): NS PAuth keys not preserved\n",
+				__func__);
+		return TEST_RESULT_FAIL;
+	}
+
+	return host_cmp_result();
+#endif
+}
+
+/*
+ * @Test_Aim@ Test PAuth fault in Realm
+ */
+test_result_t host_realm_pauth_fault(void)
+{
+#if ENABLE_PAUTH == 0
+	return TEST_RESULT_SKIPPED;
+#else
+	bool ret1, ret2;
+
+	SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
+	if (!host_create_realm_payload((u_register_t)REALM_IMAGE_BASE,
+				(u_register_t)PAGE_POOL_BASE,
+				(u_register_t)(PAGE_POOL_MAX_SIZE +
+					NS_REALM_SHARED_MEM_SIZE),
+				(u_register_t)PAGE_POOL_MAX_SIZE,
+				0UL)) {
+		return TEST_RESULT_FAIL;
+	}
+	if (!host_create_shared_mem(NS_REALM_SHARED_MEM_BASE,
+				NS_REALM_SHARED_MEM_SIZE)) {
+		return TEST_RESULT_FAIL;
+	}
+
+	ret1 = host_enter_realm_execute(REALM_PAUTH_FAULT, NULL, RMI_EXIT_HOST_CALL);
+	ret2 = host_destroy_realm();
+
+	if (!ret1) {
+		ERROR("%s(): enter=%d destroy=%d\n",
+				__func__, ret1, ret2);
+		return TEST_RESULT_FAIL;
+	}
+
+	return host_cmp_result();
+#endif
+}
+
 /*
  * This function is called on REC exit due to IRQ.
  * By checking Realm PMU state in RecExit object this finction
diff --git a/tftf/tests/tests-realm-payload.xml b/tftf/tests/tests-realm-payload.xml
index 6569357..8498472 100644
--- a/tftf/tests/tests-realm-payload.xml
+++ b/tftf/tests/tests-realm-payload.xml
@@ -51,5 +51,9 @@
 	  function="host_sve_realm_check_vectors_operations" />
 	  <testcase name="Check if RMM does not leak Realm SVE vector registers"
 	  function="host_sve_realm_check_vectors_leaked" />
+	  <testcase name="Check if PAuth keys are preserved in RL/SE/NS"
+	  function="host_realm_enable_pauth" />
+	  <testcase name="Generate PAuth Fault by overwriting LR"
+	  function="host_realm_pauth_fault" />
   </testsuite>
 </testsuites>