blob: 9608b97d9e7d498f98ddcffb1ddfd39cac25028b [file] [log] [blame]
Alexei Fedorov719714f2019-10-03 10:57:53 +01001/*
2 * Copyright (c) 2019, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <arch_helpers.h>
8#include <cdefs.h>
Shruti Gupta9d0cfe82023-04-17 10:57:26 +01009#include <stdbool.h>
Alexei Fedorov719714f2019-10-03 10:57:53 +010010#include <stdint.h>
Shruti Gupta9d0cfe82023-04-17 10:57:26 +010011#include <debug.h>
12#include <pauth.h>
13
Alexei Fedorov719714f2019-10-03 10:57:53 +010014/*
15 * This is only a toy implementation to generate a seemingly random
16 * 128-bit key from sp, x30 and cntpct_el0 values.
17 */
18uint128_t init_apkey(void)
19{
20 uint64_t return_addr = (uint64_t)__builtin_return_address(0U);
21 uint64_t frame_addr = (uint64_t)__builtin_frame_address(0U);
22
23 uint64_t cntpct = read_cntpct_el0();
24
25 uint64_t key_lo = (return_addr << 13) ^ frame_addr ^ cntpct;
26 uint64_t key_hi = (frame_addr << 15) ^ return_addr ^ cntpct;
27
28 return ((uint128_t)(key_hi) << 64) | key_lo;
29}
Shruti Gupta9d0cfe82023-04-17 10:57:26 +010030
31/* Check if ARMv8.3-PAuth key is enabled */
32static bool is_pauth_key_enabled(uint64_t key_bit)
33{
34 unsigned int el = (unsigned int)GET_EL(read_CurrentEl());
35
36 if (el == 1U) {
37 return ((read_sctlr_el1() & key_bit) != 0U);
38 } else if (el == 2U) {
39 return ((read_sctlr_el2() & key_bit) != 0U);
40 }
41 return false;
42}
43
Shruti Gupta21a30ed2024-01-13 23:07:43 +000044bool pauth_test_lib_compare_template(uint128_t *pauth_keys_before, uint128_t *pauth_keys_after)
Shruti Gupta9d0cfe82023-04-17 10:57:26 +010045{
46 bool result = true;
47
Shruti Gupta21a30ed2024-01-13 23:07:43 +000048 pauth_test_lib_read_keys(pauth_keys_after);
Shruti Gupta9d0cfe82023-04-17 10:57:26 +010049 for (unsigned int i = 0U; i < NUM_KEYS; ++i) {
50 if (pauth_keys_before[i] != pauth_keys_after[i]) {
51 ERROR("AP%sKey_EL1 read 0x%llx:%llx "
52 "expected 0x%llx:%llx\n", key_name[i],
53 (uint64_t)(pauth_keys_after[i] >> 64U),
54 (uint64_t)(pauth_keys_after[i]),
55 (uint64_t)(pauth_keys_before[i] >> 64U),
56 (uint64_t)(pauth_keys_before[i]));
57
58 result = false;
59 }
60 }
61 return result;
62}
63
64/*
65 * Program or read ARMv8.3-PAuth keys (if already enabled)
66 * and store them in <pauth_keys_before> buffer
67 */
Shruti Gupta21a30ed2024-01-13 23:07:43 +000068void pauth_test_lib_fill_regs_and_template(uint128_t *pauth_keys_before)
Shruti Gupta9d0cfe82023-04-17 10:57:26 +010069{
70 uint128_t plat_key;
71
72 (void)memset(pauth_keys_before, 0, NUM_KEYS * sizeof(uint128_t));
73
74 if (is_pauth_key_enabled(SCTLR_EnIA_BIT)) {
75 /* Read APIAKey_EL1 */
76 plat_key = read_apiakeylo_el1() |
77 ((uint128_t)(read_apiakeyhi_el1()) << 64U);
78 INFO("EnIA is set\n");
79 } else {
80 /* Program APIAKey_EL1 */
81 plat_key = init_apkey();
82 write_apiakeylo_el1((uint64_t)plat_key);
83 write_apiakeyhi_el1((uint64_t)(plat_key >> 64U));
84 }
85 pauth_keys_before[0] = plat_key;
86
87 if (is_pauth_key_enabled(SCTLR_EnIB_BIT)) {
88 /* Read APIBKey_EL1 */
89 plat_key = read_apibkeylo_el1() |
90 ((uint128_t)(read_apibkeyhi_el1()) << 64U);
91 INFO("EnIB is set\n");
92 } else {
93 /* Program APIBKey_EL1 */
94 plat_key = init_apkey();
95 write_apibkeylo_el1((uint64_t)plat_key);
96 write_apibkeyhi_el1((uint64_t)(plat_key >> 64U));
97 }
98 pauth_keys_before[1] = plat_key;
99
100 if (is_pauth_key_enabled(SCTLR_EnDA_BIT)) {
101 /* Read APDAKey_EL1 */
102 plat_key = read_apdakeylo_el1() |
103 ((uint128_t)(read_apdakeyhi_el1()) << 64U);
104 INFO("EnDA is set\n");
105 } else {
106 /* Program APDAKey_EL1 */
107 plat_key = init_apkey();
108 write_apdakeylo_el1((uint64_t)plat_key);
109 write_apdakeyhi_el1((uint64_t)(plat_key >> 64U));
110 }
111 pauth_keys_before[2] = plat_key;
112
113 if (is_pauth_key_enabled(SCTLR_EnDB_BIT)) {
114 /* Read APDBKey_EL1 */
115 plat_key = read_apdbkeylo_el1() |
116 ((uint128_t)(read_apdbkeyhi_el1()) << 64U);
117 INFO("EnDB is set\n");
118 } else {
119 /* Program APDBKey_EL1 */
120 plat_key = init_apkey();
121 write_apdbkeylo_el1((uint64_t)plat_key);
122 write_apdbkeyhi_el1((uint64_t)(plat_key >> 64U));
123 }
124 pauth_keys_before[3] = plat_key;
125
126 pauth_keys_before[4] = read_apgakeylo_el1() |
127 ((uint128_t)(read_apgakeyhi_el1()) << 64U);
128 if (pauth_keys_before[4] == 0ULL) {
129 /* Program APGAKey_EL1 */
130 plat_key = init_apkey();
131 write_apgakeylo_el1((uint64_t)plat_key);
132 write_apgakeyhi_el1((uint64_t)(plat_key >> 64U));
133 pauth_keys_before[4] = plat_key;
134 }
135
136 isb();
137}
138
139/*
140 * Read ARMv8.3-PAuth keys and store them in
Shruti Gupta21a30ed2024-01-13 23:07:43 +0000141 * <pauth_keys_arr> buffer
Shruti Gupta9d0cfe82023-04-17 10:57:26 +0100142 */
Shruti Gupta21a30ed2024-01-13 23:07:43 +0000143void pauth_test_lib_read_keys(uint128_t *pauth_keys_arr)
Shruti Gupta9d0cfe82023-04-17 10:57:26 +0100144{
Shruti Gupta21a30ed2024-01-13 23:07:43 +0000145 (void)memset(pauth_keys_arr, 0, NUM_KEYS * sizeof(uint128_t));
Shruti Gupta9d0cfe82023-04-17 10:57:26 +0100146
147 /* Read APIAKey_EL1 */
Shruti Gupta21a30ed2024-01-13 23:07:43 +0000148 pauth_keys_arr[0] = read_apiakeylo_el1() |
Shruti Gupta9d0cfe82023-04-17 10:57:26 +0100149 ((uint128_t)(read_apiakeyhi_el1()) << 64U);
150
151 /* Read APIBKey_EL1 */
Shruti Gupta21a30ed2024-01-13 23:07:43 +0000152 pauth_keys_arr[1] = read_apibkeylo_el1() |
Shruti Gupta9d0cfe82023-04-17 10:57:26 +0100153 ((uint128_t)(read_apibkeyhi_el1()) << 64U);
154
155 /* Read APDAKey_EL1 */
Shruti Gupta21a30ed2024-01-13 23:07:43 +0000156 pauth_keys_arr[2] = read_apdakeylo_el1() |
Shruti Gupta9d0cfe82023-04-17 10:57:26 +0100157 ((uint128_t)(read_apdakeyhi_el1()) << 64U);
158
159 /* Read APDBKey_EL1 */
Shruti Gupta21a30ed2024-01-13 23:07:43 +0000160 pauth_keys_arr[3] = read_apdbkeylo_el1() |
Shruti Gupta9d0cfe82023-04-17 10:57:26 +0100161 ((uint128_t)(read_apdbkeyhi_el1()) << 64U);
162
163 /* Read APGAKey_EL1 */
Shruti Gupta21a30ed2024-01-13 23:07:43 +0000164 pauth_keys_arr[4] = read_apgakeylo_el1() |
Shruti Gupta9d0cfe82023-04-17 10:57:26 +0100165 ((uint128_t)(read_apgakeyhi_el1()) << 64U);
166}
167
168/* Test execution of ARMv8.3-PAuth instructions */
169void pauth_test_lib_test_intrs(void)
170{
171 /* Pointer authentication instructions */
172 __asm__ volatile (
173 "paciasp\n"
174 "autiasp\n"
175 "paciasp\n"
176 "xpaclri");
177}