blob: 564c56d9fd68abf8ba1757058da5920ead717a31 [file] [log] [blame]
Joel Hutton8790f022019-03-15 14:47:02 +00001/*
2 * Copyright (c) 2019, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <psci.h>
8#include <smccc.h>
9#include <test_helpers.h>
10#include <tftf_lib.h>
11#include <tftf.h>
12#include <tsp.h>
13#include <string.h>
14
15/* The length of the array used to hold the pauth keys */
16#define LENGTH_KEYS 10
17
18#ifndef AARCH32
19static void read_pauth_keys(uint64_t *pauth_keys, unsigned int len)
20{
21 assert(len >= LENGTH_KEYS);
22
23 memset(pauth_keys, 0, len * sizeof(uint64_t));
24
25 if (is_armv8_3_pauth_apa_api_present()) {
26 /* read instruction keys a and b (both 128 bit) */
27 pauth_keys[0] = read_apiakeylo_el1();
28 pauth_keys[1] = read_apiakeyhi_el1();
29
30 pauth_keys[2] = read_apibkeylo_el1();
31 pauth_keys[3] = read_apibkeyhi_el1();
32
33 /* read data keys a and b (both 128 bit) */
34 pauth_keys[4] = read_apdakeylo_el1();
35 pauth_keys[5] = read_apdakeyhi_el1();
36
37 pauth_keys[6] = read_apdbkeylo_el1();
38 pauth_keys[7] = read_apdbkeyhi_el1();
39 }
40
41 if (is_armv8_3_pauth_gpa_gpi_present()) {
42 /* read generic key */
43 pauth_keys[8] = read_apgakeylo_el1();
44 pauth_keys[9] = read_apgakeyhi_el1();
45 }
46
47}
48#endif
49
50/*
51 * TF-A is expected to allow access to key registers from lower EL's,
52 * reading the keys excercises this, on failure this will trap to
53 * EL3 and crash.
54 */
55test_result_t test_pauth_reg_access(void)
56{
57 SKIP_TEST_IF_AARCH32();
58#ifndef AARCH32
59 uint64_t pauth_keys[LENGTH_KEYS];
60 SKIP_TEST_IF_PAUTH_NOT_SUPPORTED();
61 read_pauth_keys(pauth_keys, LENGTH_KEYS);
62 return TEST_RESULT_SUCCESS;
63#endif
64}
65
66/*
67 * Makes a call to psci version, and checks that the EL3 pauth keys are not
68 * leaked when it returns
69 */
John Tsichritzis96e25032019-05-07 10:42:22 +010070#if (__GNUC__ > 7 || (__GNUC__ == 7 && __GNUC_MINOR__ > 0)) && AARCH64
Joel Hutton8790f022019-03-15 14:47:02 +000071__attribute__((target("sign-return-address=all")))
72#endif
73test_result_t test_pauth_leakage(void)
74{
75 SKIP_TEST_IF_AARCH32();
76#ifndef AARCH32
77 uint64_t pauth_keys_before[LENGTH_KEYS];
78 uint64_t pauth_keys_after[LENGTH_KEYS];
79 SKIP_TEST_IF_PAUTH_NOT_SUPPORTED();
80
81 read_pauth_keys(pauth_keys_before, LENGTH_KEYS);
82
83 tftf_get_psci_version();
84
85 read_pauth_keys(pauth_keys_after, LENGTH_KEYS);
86
87 if (memcmp(pauth_keys_before, pauth_keys_after,
88 LENGTH_KEYS * sizeof(uint64_t)) != 0)
89 return TEST_RESULT_FAIL;
90 return TEST_RESULT_SUCCESS;
91#endif
92}
93
94/* Uses the pauth instructions, this checks the enable PAUTH bit has been set */
95test_result_t test_pauth_instructions(void)
96{
97 SKIP_TEST_IF_AARCH32();
98#ifndef AARCH32
99 SKIP_TEST_IF_PAUTH_NOT_SUPPORTED();
100 /*
101 * Pointer authentication instructions (explicit encoding for compilers
102 * that do not recognize these instructions)
103 */
104 /* paciasp */
105 __asm__ volatile (".inst 0xD503233F");
106 /* autiasp */
107 __asm__ volatile (".inst 0xD50323BF");
108 /* paciasp */
109 __asm__ volatile (".inst 0xD503233F");
110 /* xpaclri */
111 __asm__ volatile (".inst 0xD50320FF");
112 return TEST_RESULT_SUCCESS;
113#endif
114}
115
116/*
117 * Makes a call to TSP ADD, and checks that the checks that the Secure World
118 * pauth keys are not leaked
119 */
John Tsichritzis96e25032019-05-07 10:42:22 +0100120#if (__GNUC__ > 7 || (__GNUC__ == 7 && __GNUC_MINOR__ > 0)) && AARCH64
Joel Hutton8790f022019-03-15 14:47:02 +0000121__attribute__((target("sign-return-address=all")))
122#endif
123test_result_t test_pauth_leakage_tsp(void)
124{
125 SKIP_TEST_IF_AARCH32();
126#ifndef AARCH32
127 smc_args tsp_svc_params;
128 smc_ret_values tsp_result = {0};
129 uint64_t pauth_keys_before[LENGTH_KEYS];
130 uint64_t pauth_keys_after[LENGTH_KEYS];
131
132 SKIP_TEST_IF_PAUTH_NOT_SUPPORTED();
133 SKIP_TEST_IF_TSP_NOT_PRESENT();
134
135 read_pauth_keys(pauth_keys_before, LENGTH_KEYS);
136
137 /* Standard SMC to ADD two numbers */
138 tsp_svc_params.fid = TSP_STD_FID(TSP_ADD);
139 tsp_svc_params.arg1 = 4;
140 tsp_svc_params.arg2 = 6;
141 tsp_result = tftf_smc(&tsp_svc_params);
142
143 /*
144 * Check the result of the addition-TSP_ADD will add
145 * the arguments to themselves and return
146 */
147 if (tsp_result.ret0 != 0 || tsp_result.ret1 != 8 ||
148 tsp_result.ret2 != 12) {
149 tftf_testcase_printf("TSP add returned wrong result:"
150 "got %d %d %d expected: 0 8 12\n",
151 (unsigned int)tsp_result.ret0,
152 (unsigned int)tsp_result.ret1,
153 (unsigned int)tsp_result.ret2);
154
155 return TEST_RESULT_FAIL;
156 }
157 read_pauth_keys(pauth_keys_after, LENGTH_KEYS);
158
159 if (memcmp(pauth_keys_before, pauth_keys_after,
160 LENGTH_KEYS * sizeof(uint64_t)) != 0)
161 return TEST_RESULT_FAIL;
162 return TEST_RESULT_SUCCESS;
163#endif
164}