blob: b7434a81c1550b5b012131f13916bcb9a6aeb44d [file] [log] [blame]
Joel Hutton8790f022019-03-15 14:47:02 +00001/*
Juan Pablo Condeebd1b692022-06-30 17:47:35 -04002 * Copyright (c) 2019-2022, Arm Limited. All rights reserved.
Joel Hutton8790f022019-03-15 14:47:02 +00003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
Alexei Fedorovfb003382019-10-04 16:13:47 +01007#include <pauth.h>
Joel Hutton8790f022019-03-15 14:47:02 +00008#include <psci.h>
9#include <smccc.h>
10#include <test_helpers.h>
11#include <tftf_lib.h>
12#include <tftf.h>
13#include <tsp.h>
14#include <string.h>
15
Alexei Fedorovfb003382019-10-04 16:13:47 +010016#ifdef __aarch64__
Joel Hutton8790f022019-03-15 14:47:02 +000017
Alexei Fedorovfb003382019-10-04 16:13:47 +010018/* Number of ARMv8.3-PAuth keys */
19#define NUM_KEYS 5
20
21static const char * const key_name[] = {"IA", "IB", "DA", "DB", "GA"};
22
23static uint128_t pauth_keys_before[NUM_KEYS];
24static uint128_t pauth_keys_after[NUM_KEYS];
25
26/* Check if ARMv8.3-PAuth key is enabled */
27static bool is_pauth_key_enabled(uint64_t key_bit)
Joel Hutton8790f022019-03-15 14:47:02 +000028{
Alexei Fedorovfb003382019-10-04 16:13:47 +010029 return (IS_IN_EL2() ?
30 ((read_sctlr_el2() & key_bit) != 0U) :
31 ((read_sctlr_el1() & key_bit) != 0U));
32}
Joel Hutton8790f022019-03-15 14:47:02 +000033
Alexei Fedorovfb003382019-10-04 16:13:47 +010034static test_result_t compare_pauth_keys(void)
35{
36 test_result_t result = TEST_RESULT_SUCCESS;
37
38 for (unsigned int i = 0; i < NUM_KEYS; ++i) {
39 if (pauth_keys_before[i] != pauth_keys_after[i]) {
40 ERROR("AP%sKey_EL1 read 0x%llx:%llx "
41 "expected 0x%llx:%llx\n", key_name[i],
42 (uint64_t)(pauth_keys_after[i] >> 64),
43 (uint64_t)(pauth_keys_after[i]),
44 (uint64_t)(pauth_keys_before[i] >> 64),
45 (uint64_t)(pauth_keys_before[i]));
46
47 result = TEST_RESULT_FAIL;
48 }
49 }
50 return result;
51}
52
53/*
54 * Program or read ARMv8.3-PAuth keys (if already enabled)
55 * and store them in <pauth_keys_before> buffer
56 */
57static void set_store_pauth_keys(void)
58{
59 uint128_t plat_key;
60
61 memset(pauth_keys_before, 0, NUM_KEYS * sizeof(uint128_t));
Joel Hutton8790f022019-03-15 14:47:02 +000062
Juan Pablo Condeebd1b692022-06-30 17:47:35 -040063 if (is_armv8_3_pauth_apa_api_apa3_present()) {
Alexei Fedorovfb003382019-10-04 16:13:47 +010064 if (is_pauth_key_enabled(SCTLR_EnIA_BIT)) {
65 /* Read APIAKey_EL1 */
66 plat_key = read_apiakeylo_el1() |
67 ((uint128_t)(read_apiakeyhi_el1()) << 64);
68 INFO("EnIA is set\n");
69 } else {
70 /* Program APIAKey_EL1 */
71 plat_key = init_apkey();
72 write_apiakeylo_el1((uint64_t)plat_key);
73 write_apiakeyhi_el1((uint64_t)(plat_key >> 64));
74 }
75 pauth_keys_before[0] = plat_key;
Joel Hutton8790f022019-03-15 14:47:02 +000076
Alexei Fedorovfb003382019-10-04 16:13:47 +010077 if (is_pauth_key_enabled(SCTLR_EnIB_BIT)) {
78 /* Read APIBKey_EL1 */
79 plat_key = read_apibkeylo_el1() |
80 ((uint128_t)(read_apibkeyhi_el1()) << 64);
81 INFO("EnIB is set\n");
82 } else {
83 /* Program APIBKey_EL1 */
84 plat_key = init_apkey();
85 write_apibkeylo_el1((uint64_t)plat_key);
86 write_apibkeyhi_el1((uint64_t)(plat_key >> 64));
87 }
88 pauth_keys_before[1] = plat_key;
Joel Hutton8790f022019-03-15 14:47:02 +000089
Alexei Fedorovfb003382019-10-04 16:13:47 +010090 if (is_pauth_key_enabled(SCTLR_EnDA_BIT)) {
91 /* Read APDAKey_EL1 */
92 plat_key = read_apdakeylo_el1() |
93 ((uint128_t)(read_apdakeyhi_el1()) << 64);
94 INFO("EnDA is set\n");
95 } else {
96 /* Program APDAKey_EL1 */
97 plat_key = init_apkey();
98 write_apdakeylo_el1((uint64_t)plat_key);
99 write_apdakeyhi_el1((uint64_t)(plat_key >> 64));
100 }
101 pauth_keys_before[2] = plat_key;
Joel Hutton8790f022019-03-15 14:47:02 +0000102
Alexei Fedorovfb003382019-10-04 16:13:47 +0100103 if (is_pauth_key_enabled(SCTLR_EnDB_BIT)) {
104 /* Read APDBKey_EL1 */
105 plat_key = read_apdbkeylo_el1() |
106 ((uint128_t)(read_apdbkeyhi_el1()) << 64);
107 INFO("EnDB is set\n");
108 } else {
109 /* Program APDBKey_EL1 */
110 plat_key = init_apkey();
111 write_apdbkeylo_el1((uint64_t)plat_key);
112 write_apdbkeyhi_el1((uint64_t)(plat_key >> 64));
113 }
114 pauth_keys_before[3] = plat_key;
115 }
116
117 /*
118 * It is safe to assume that Generic Pointer authentication code key
119 * APGAKey_EL1 can be re-programmed, as this key is not set in
120 * TF-A Test suite and PACGA instruction is not used.
121 */
Juan Pablo Condeebd1b692022-06-30 17:47:35 -0400122 if (is_armv8_3_pauth_gpa_gpi_gpa3_present()) {
Alexei Fedorovfb003382019-10-04 16:13:47 +0100123 /* Program APGAKey_EL1 */
124 plat_key = init_apkey();
125 write_apgakeylo_el1((uint64_t)plat_key);
126 write_apgakeyhi_el1((uint64_t)(plat_key >> 64));
127 pauth_keys_before[4] = plat_key;
128 }
129
130 isb();
131}
132
133/*
134 * Read ARMv8.3-PAuth keys and store them in
135 * <pauth_keys_after> buffer
136 */
137static void read_pauth_keys(void)
138{
139 memset(pauth_keys_after, 0, NUM_KEYS * sizeof(uint128_t));
140
Juan Pablo Condeebd1b692022-06-30 17:47:35 -0400141 if (is_armv8_3_pauth_apa_api_apa3_present()) {
Alexei Fedorovfb003382019-10-04 16:13:47 +0100142 /* Read APIAKey_EL1 */
143 pauth_keys_after[0] = read_apiakeylo_el1() |
144 ((uint128_t)(read_apiakeyhi_el1()) << 64);
145
146 /* Read APIBKey_EL1 */
147 pauth_keys_after[1] = read_apibkeylo_el1() |
148 ((uint128_t)(read_apibkeyhi_el1()) << 64);
149
150 /* Read APDAKey_EL1 */
151 pauth_keys_after[2] = read_apdakeylo_el1() |
152 ((uint128_t)(read_apdakeyhi_el1()) << 64);
153
154 /* Read APDBKey_EL1 */
155 pauth_keys_after[3] = read_apdbkeylo_el1() |
156 ((uint128_t)(read_apdbkeyhi_el1()) << 64);
Joel Hutton8790f022019-03-15 14:47:02 +0000157 }
158
Juan Pablo Condeebd1b692022-06-30 17:47:35 -0400159 if (is_armv8_3_pauth_gpa_gpi_gpa3_present()) {
Alexei Fedorovfb003382019-10-04 16:13:47 +0100160 /* Read APGAKey_EL1 */
161 pauth_keys_after[4] = read_apgakeylo_el1() |
162 ((uint128_t)(read_apgakeyhi_el1()) << 64);
Joel Hutton8790f022019-03-15 14:47:02 +0000163 }
Joel Hutton8790f022019-03-15 14:47:02 +0000164}
Alexei Fedorovfb003382019-10-04 16:13:47 +0100165#endif /* __aarch64__ */
Joel Hutton8790f022019-03-15 14:47:02 +0000166
167/*
168 * TF-A is expected to allow access to key registers from lower EL's,
169 * reading the keys excercises this, on failure this will trap to
170 * EL3 and crash.
171 */
172test_result_t test_pauth_reg_access(void)
173{
174 SKIP_TEST_IF_AARCH32();
Alexei Fedorovfb003382019-10-04 16:13:47 +0100175#ifdef __aarch64__
Joel Hutton8790f022019-03-15 14:47:02 +0000176 SKIP_TEST_IF_PAUTH_NOT_SUPPORTED();
Alexei Fedorovfb003382019-10-04 16:13:47 +0100177 read_pauth_keys();
Joel Hutton8790f022019-03-15 14:47:02 +0000178 return TEST_RESULT_SUCCESS;
Alexei Fedorovfb003382019-10-04 16:13:47 +0100179#endif /* __aarch64__ */
Joel Hutton8790f022019-03-15 14:47:02 +0000180}
181
182/*
Alexei Fedorovfb003382019-10-04 16:13:47 +0100183 * Makes a call to PSCI version, and checks that the EL3 pauth keys are not
Joel Hutton8790f022019-03-15 14:47:02 +0000184 * leaked when it returns
185 */
Joel Hutton8790f022019-03-15 14:47:02 +0000186test_result_t test_pauth_leakage(void)
187{
188 SKIP_TEST_IF_AARCH32();
Alexei Fedorovfb003382019-10-04 16:13:47 +0100189#ifdef __aarch64__
Joel Hutton8790f022019-03-15 14:47:02 +0000190 SKIP_TEST_IF_PAUTH_NOT_SUPPORTED();
Alexei Fedorovfb003382019-10-04 16:13:47 +0100191 set_store_pauth_keys();
Joel Hutton8790f022019-03-15 14:47:02 +0000192
193 tftf_get_psci_version();
194
Alexei Fedorovfb003382019-10-04 16:13:47 +0100195 read_pauth_keys();
Joel Hutton8790f022019-03-15 14:47:02 +0000196
Alexei Fedorovfb003382019-10-04 16:13:47 +0100197 return compare_pauth_keys();
198#endif /* __aarch64__ */
Joel Hutton8790f022019-03-15 14:47:02 +0000199}
200
Alexei Fedorovfb003382019-10-04 16:13:47 +0100201/* Test execution of ARMv8.3-PAuth instructions */
Joel Hutton8790f022019-03-15 14:47:02 +0000202test_result_t test_pauth_instructions(void)
203{
204 SKIP_TEST_IF_AARCH32();
Alexei Fedorovfb003382019-10-04 16:13:47 +0100205#ifdef __aarch64__
Joel Hutton8790f022019-03-15 14:47:02 +0000206 SKIP_TEST_IF_PAUTH_NOT_SUPPORTED();
Alexei Fedorovfb003382019-10-04 16:13:47 +0100207
208#if ARM_ARCH_AT_LEAST(8, 3)
209 /* Pointer authentication instructions */
210 __asm__ volatile (
211 "paciasp\n"
212 "autiasp\n"
213 "paciasp\n"
214 "xpaclri"
215 );
Joel Hutton8790f022019-03-15 14:47:02 +0000216 return TEST_RESULT_SUCCESS;
Alexei Fedorovfb003382019-10-04 16:13:47 +0100217#else
218 tftf_testcase_printf("Pointer Authentication instructions "
219 "are not supported on ARMv%u.%u\n",
220 ARM_ARCH_MAJOR, ARM_ARCH_MINOR);
221 return TEST_RESULT_SKIPPED;
222#endif /* ARM_ARCH_AT_LEAST(8, 3) */
223
224#endif /* __aarch64__ */
Joel Hutton8790f022019-03-15 14:47:02 +0000225}
226
227/*
228 * Makes a call to TSP ADD, and checks that the checks that the Secure World
229 * pauth keys are not leaked
230 */
Joel Hutton8790f022019-03-15 14:47:02 +0000231test_result_t test_pauth_leakage_tsp(void)
232{
233 SKIP_TEST_IF_AARCH32();
Alexei Fedorovfb003382019-10-04 16:13:47 +0100234#ifdef __aarch64__
Joel Hutton8790f022019-03-15 14:47:02 +0000235 smc_args tsp_svc_params;
236 smc_ret_values tsp_result = {0};
Joel Hutton8790f022019-03-15 14:47:02 +0000237
238 SKIP_TEST_IF_PAUTH_NOT_SUPPORTED();
239 SKIP_TEST_IF_TSP_NOT_PRESENT();
240
Alexei Fedorovfb003382019-10-04 16:13:47 +0100241 set_store_pauth_keys();
Joel Hutton8790f022019-03-15 14:47:02 +0000242
243 /* Standard SMC to ADD two numbers */
244 tsp_svc_params.fid = TSP_STD_FID(TSP_ADD);
245 tsp_svc_params.arg1 = 4;
246 tsp_svc_params.arg2 = 6;
247 tsp_result = tftf_smc(&tsp_svc_params);
248
249 /*
250 * Check the result of the addition-TSP_ADD will add
251 * the arguments to themselves and return
252 */
253 if (tsp_result.ret0 != 0 || tsp_result.ret1 != 8 ||
Alexei Fedorovfb003382019-10-04 16:13:47 +0100254 tsp_result.ret2 != 12) {
255 tftf_testcase_printf("TSP add returned wrong result: "
Joel Hutton8790f022019-03-15 14:47:02 +0000256 "got %d %d %d expected: 0 8 12\n",
Alexei Fedorovfb003382019-10-04 16:13:47 +0100257 (unsigned int)tsp_result.ret0,
258 (unsigned int)tsp_result.ret1,
259 (unsigned int)tsp_result.ret2);
Joel Hutton8790f022019-03-15 14:47:02 +0000260 return TEST_RESULT_FAIL;
261 }
Joel Hutton8790f022019-03-15 14:47:02 +0000262
Alexei Fedorovfb003382019-10-04 16:13:47 +0100263 read_pauth_keys();
264
265 return compare_pauth_keys();
266#endif /* __aarch64__ */
Joel Hutton8790f022019-03-15 14:47:02 +0000267}