test(realm): test realm pauth state is preserved
Modify Pauth lib to work for multiple CPU
Test if Realm pauth state is preserved for all RECs
on context switch to RMM/NS.
Change-Id: Ibb393b415bab27066289b560be49e02d0c8f58ba
Signed-off-by: Shruti Gupta <shruti.gupta@arm.com>
diff --git a/include/lib/extensions/pauth.h b/include/lib/extensions/pauth.h
index c8d577f..8816e18 100644
--- a/include/lib/extensions/pauth.h
+++ b/include/lib/extensions/pauth.h
@@ -11,6 +11,11 @@
#include <stdint.h>
#ifdef __aarch64__
+/* Number of ARMv8.3-PAuth keys */
+#define NUM_KEYS 5U
+
+static const char * const key_name[] = {"IA", "IB", "DA", "DB", "GA"};
+
/* Initialize 128-bit ARMv8.3-PAuth key */
uint128_t init_apkey(void);
@@ -24,13 +29,13 @@
* 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);
+void pauth_test_lib_fill_regs_and_template(uint128_t *pauth_keys_arr);
/* Read and Compare PAuth registers with provided template values. */
-bool pauth_test_lib_compare_template(void);
+bool pauth_test_lib_compare_template(uint128_t *pauth_keys_before, uint128_t *pauth_keys_after);
/* Read and Store PAuth registers in template. */
-void pauth_test_lib_read_keys(void);
+void pauth_test_lib_read_keys(uint128_t *pauth_keys_arr);
/* Test PAuth instructions. */
void pauth_test_lib_test_intrs(void);
diff --git a/lib/extensions/pauth/aarch64/pauth.c b/lib/extensions/pauth/aarch64/pauth.c
index 90e16d5..9608b97 100644
--- a/lib/extensions/pauth/aarch64/pauth.c
+++ b/lib/extensions/pauth/aarch64/pauth.c
@@ -11,14 +11,6 @@
#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
* 128-bit key from sp, x30 and cntpct_el0 values.
@@ -49,11 +41,11 @@
return false;
}
-bool pauth_test_lib_compare_template(void)
+bool pauth_test_lib_compare_template(uint128_t *pauth_keys_before, uint128_t *pauth_keys_after)
{
bool result = true;
- pauth_test_lib_read_keys();
+ pauth_test_lib_read_keys(pauth_keys_after);
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 "
@@ -73,7 +65,7 @@
* 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)
+void pauth_test_lib_fill_regs_and_template(uint128_t *pauth_keys_before)
{
uint128_t plat_key;
@@ -146,30 +138,30 @@
/*
* Read ARMv8.3-PAuth keys and store them in
- * <pauth_keys_after> buffer
+ * <pauth_keys_arr> buffer
*/
-void pauth_test_lib_read_keys(void)
+void pauth_test_lib_read_keys(uint128_t *pauth_keys_arr)
{
- (void)memset(pauth_keys_after, 0, NUM_KEYS * sizeof(uint128_t));
+ (void)memset(pauth_keys_arr, 0, NUM_KEYS * sizeof(uint128_t));
/* Read APIAKey_EL1 */
- pauth_keys_after[0] = read_apiakeylo_el1() |
+ pauth_keys_arr[0] = read_apiakeylo_el1() |
((uint128_t)(read_apiakeyhi_el1()) << 64U);
/* Read APIBKey_EL1 */
- pauth_keys_after[1] = read_apibkeylo_el1() |
+ pauth_keys_arr[1] = read_apibkeylo_el1() |
((uint128_t)(read_apibkeyhi_el1()) << 64U);
/* Read APDAKey_EL1 */
- pauth_keys_after[2] = read_apdakeylo_el1() |
+ pauth_keys_arr[2] = read_apdakeylo_el1() |
((uint128_t)(read_apdakeyhi_el1()) << 64U);
/* Read APDBKey_EL1 */
- pauth_keys_after[3] = read_apdbkeylo_el1() |
+ pauth_keys_arr[3] = read_apdbkeylo_el1() |
((uint128_t)(read_apdbkeyhi_el1()) << 64U);
/* Read APGAKey_EL1 */
- pauth_keys_after[4] = read_apgakeylo_el1() |
+ pauth_keys_arr[4] = read_apgakeylo_el1() |
((uint128_t)(read_apgakeyhi_el1()) << 64U);
}
diff --git a/realm/realm_pauth.c b/realm/realm_pauth.c
index cf3bec3..31b26e7 100644
--- a/realm/realm_pauth.c
+++ b/realm/realm_pauth.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -7,12 +7,15 @@
#include <stdio.h>
#include <arch_features.h>
+#include <assert.h>
#include <debug.h>
#include <pauth.h>
#include <realm_rsi.h>
#include <sync.h>
-static volatile bool set_cmd_done;
+static volatile bool set_cmd_done[MAX_REC_COUNT];
+static uint128_t pauth_keys_before[MAX_REC_COUNT][NUM_KEYS];
+static uint128_t pauth_keys_after[MAX_REC_COUNT][NUM_KEYS];
static bool exception_handler(void)
{
@@ -68,19 +71,28 @@
*/
bool test_realm_pauth_set_cmd(void)
{
+ unsigned int rec = read_mpidr_el1() & MPID_MASK;
+
if (!is_armv8_3_pauth_present()) {
return false;
}
+ assert(rec < MAX_REC_COUNT);
pauth_test_lib_test_intrs();
- pauth_test_lib_fill_regs_and_template();
- set_cmd_done = true;
+ pauth_test_lib_fill_regs_and_template(pauth_keys_before[rec]);
+ set_cmd_done[rec] = true;
return true;
}
bool test_realm_pauth_check_cmd(void)
{
- if (!is_armv8_3_pauth_present() || !set_cmd_done) {
+ unsigned int rec = read_mpidr_el1() & MPID_MASK;
+ bool ret;
+
+ assert(rec < MAX_REC_COUNT);
+ if (!is_armv8_3_pauth_present() || !set_cmd_done[rec]) {
return false;
}
- return pauth_test_lib_compare_template();
+ ret = pauth_test_lib_compare_template(pauth_keys_before[rec], pauth_keys_after[rec]);
+ realm_printf("Pauth key comparison ret=%d\n", ret);
+ return ret;
}
diff --git a/tftf/tests/extensions/pauth/test_pauth.c b/tftf/tests/extensions/pauth/test_pauth.c
index b29e5d0..ada2f1d 100644
--- a/tftf/tests/extensions/pauth/test_pauth.c
+++ b/tftf/tests/extensions/pauth/test_pauth.c
@@ -13,6 +13,11 @@
#include <tsp.h>
#include <string.h>
+#ifdef __aarch64__
+static uint128_t pauth_keys_before[NUM_KEYS];
+static uint128_t pauth_keys_after[NUM_KEYS];
+#endif
+
/*
* 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
@@ -23,7 +28,7 @@
SKIP_TEST_IF_AARCH32();
#ifdef __aarch64__
SKIP_TEST_IF_PAUTH_NOT_SUPPORTED();
- pauth_test_lib_read_keys();
+ pauth_test_lib_read_keys(pauth_keys_before);
return TEST_RESULT_SUCCESS;
#endif /* __aarch64__ */
}
@@ -37,11 +42,11 @@
SKIP_TEST_IF_AARCH32();
#ifdef __aarch64__
SKIP_TEST_IF_PAUTH_NOT_SUPPORTED();
- pauth_test_lib_read_keys();
+ pauth_test_lib_read_keys(pauth_keys_before);
tftf_get_psci_version();
- return pauth_test_lib_compare_template();
+ return pauth_test_lib_compare_template(pauth_keys_before, pauth_keys_after);
#endif /* __aarch64__ */
}
@@ -84,7 +89,7 @@
SKIP_TEST_IF_PAUTH_NOT_SUPPORTED();
SKIP_TEST_IF_TSP_NOT_PRESENT();
- pauth_test_lib_fill_regs_and_template();
+ pauth_test_lib_fill_regs_and_template(pauth_keys_before);
/* Standard SMC to ADD two numbers */
tsp_svc_params.fid = TSP_STD_FID(TSP_ADD);
@@ -106,6 +111,6 @@
return TEST_RESULT_FAIL;
}
- return pauth_test_lib_compare_template();
+ return pauth_test_lib_compare_template(pauth_keys_before, pauth_keys_after);
#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 175dc04..7cb0d5b 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
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -25,6 +25,11 @@
extern const char *rmi_exit[];
+#if ENABLE_PAUTH
+static uint128_t pauth_keys_before[NUM_KEYS];
+static uint128_t pauth_keys_after[NUM_KEYS];
+#endif
+
/*
* @Test_Aim@ Test realm payload creation, execution and destruction iteratively
*/
@@ -97,7 +102,8 @@
}
/*
- * @Test_Aim@ Test PAuth in realm
+ * @Test_Aim@ Create realm with multiple rec
+ * Test PAuth registers are preserved for each rec
*/
test_result_t host_realm_enable_pauth(void)
{
@@ -105,16 +111,17 @@
return TEST_RESULT_SKIPPED;
#else
bool ret1, ret2;
- u_register_t rec_flag[1] = {RMI_RUNNABLE};
+ u_register_t rec_flag[MAX_REC_COUNT] = {RMI_RUNNABLE, RMI_RUNNABLE, RMI_RUNNABLE,
+ RMI_RUNNABLE, RMI_RUNNABLE, RMI_RUNNABLE, RMI_RUNNABLE, RMI_RUNNABLE,};
struct realm realm;
SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
- pauth_test_lib_fill_regs_and_template();
+ pauth_test_lib_fill_regs_and_template(pauth_keys_before);
if (!host_create_activate_realm_payload(&realm, (u_register_t)REALM_IMAGE_BASE,
(u_register_t)PAGE_POOL_BASE,
(u_register_t)PAGE_POOL_MAX_SIZE,
- 0UL, rec_flag, 1U)) {
+ 0UL, rec_flag, MAX_REC_COUNT)) {
return TEST_RESULT_FAIL;
}
@@ -123,24 +130,33 @@
return TEST_RESULT_FAIL;
}
- ret1 = host_enter_realm_execute(&realm, REALM_PAUTH_SET_CMD, RMI_EXIT_HOST_CALL, 0U);
+ for (unsigned int i = 0U; i < MAX_REC_COUNT; i++) {
+ ret1 = host_enter_realm_execute(&realm, REALM_PAUTH_SET_CMD,
+ RMI_EXIT_HOST_CALL, i);
- if (ret1) {
+ if (!ret1) {
+ ERROR("Pauth set cmd failed\n");
+ break;
+ }
/* Re-enter Realm to compare PAuth registers. */
ret1 = host_enter_realm_execute(&realm, REALM_PAUTH_CHECK_CMD,
- RMI_EXIT_HOST_CALL, 0U);
+ RMI_EXIT_HOST_CALL, i);
+ if (!ret1) {
+ ERROR("Pauth check cmd failed\n");
+ break;
+ }
}
ret2 = host_destroy_realm(&realm);
- if (!ret1) {
+ if (!ret1 || !ret2) {
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()) {
+ if (!pauth_test_lib_compare_template(pauth_keys_before, pauth_keys_after)) {
ERROR("%s(): NS PAuth keys not preserved\n",
__func__);
return TEST_RESULT_FAIL;