1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright 2022 Foundries.io Ltd.
4 * Jorge Ramirez-Ortiz <jorge@foundries.io>
5 */
6
7 #include <assert.h>
8 #include <drivers/versal_mbox.h>
9 #include <drivers/versal_nvm.h>
10 #include <drivers/versal_puf.h>
11 #include <drivers/versal_sha3_384.h>
12 #include <io.h>
13 #include <kernel/panic.h>
14 #include <kernel/tee_common_otp.h>
15 #include <mm/core_memprot.h>
16 #include <string_ext.h>
17 #include <tee/tee_cryp_utl.h>
18 #include <trace.h>
19 #include <utee_defines.h>
20
21 static struct {
22 uint8_t key[HW_UNIQUE_KEY_LENGTH];
23 bool ready;
24 } huk;
25
26 #define MODULE_SHIFT 8
27 #define MODULE_ID 5
28 #define API_ID(__x) ((MODULE_ID << MODULE_SHIFT) | (__x))
29
30 #define VERSAL_AES_KEY_SIZE_256 2
31 #define VERSAL_AES_GCM_ENCRYPT 0
32
33 enum versal_aes_key_src {
34 VERSAL_AES_BBRAM_KEY = 0,
35 VERSAL_AES_BBRAM_RED_KEY,
36 VERSAL_AES_BH_KEY,
37 VERSAL_AES_BH_RED_KEY,
38 VERSAL_AES_EFUSE_KEY,
39 VERSAL_AES_EFUSE_RED_KEY,
40 VERSAL_AES_EFUSE_USER_KEY_0,
41 VERSAL_AES_EFUSE_USER_KEY_1,
42 VERSAL_AES_EFUSE_USER_RED_KEY_0,
43 VERSAL_AES_EFUSE_USER_RED_KEY_1,
44 VERSAL_AES_KUP_KEY,
45 VERSAL_AES_PUF_KEY,
46 VERSAL_AES_USER_KEY_0,
47 VERSAL_AES_USER_KEY_1,
48 VERSAL_AES_USER_KEY_2,
49 VERSAL_AES_USER_KEY_3,
50 VERSAL_AES_USER_KEY_4,
51 VERSAL_AES_USER_KEY_5,
52 VERSAL_AES_USER_KEY_6,
53 VERSAL_AES_USER_KEY_7,
54 VERSAL_AES_EXPANDED_KEYS,
55 VERSAL_AES_ALL_KEYS,
56 };
57
58 enum versal_crypto_api {
59 VERSAL_AES_INIT = 96U,
60 VERSAL_AES_OP_INIT,
61 VERSAL_AES_UPDATE_AAD,
62 VERSAL_AES_ENCRYPT_UPDATE,
63 VERSAL_AES_ENCRYPT_FINAL,
64 VERSAL_AES_DECRYPT_UPDATE,
65 VERSAL_AES_DECRYPT_FINAL,
66 VERSAL_AES_KEY_ZERO,
67 VERSAL_AES_WRITE_KEY,
68 VERSAL_AES_LOCK_USER_KEY,
69 VERSAL_AES_KEK_DECRYPT,
70 VERSAL_AES_SET_DPA_CM,
71 VERSAL_AES_DECRYPT_KAT,
72 VERSAL_AES_DECRYPT_CM_KAT,
73 };
74
75 struct versal_aes_input_param {
76 uint64_t input_addr;
77 uint32_t input_len;
78 uint32_t is_last;
79 };
80
81 struct versal_aes_init {
82 uint64_t iv_addr;
83 uint32_t operation;
84 uint32_t key_src;
85 uint32_t key_len;
86 };
87
88 /*
89 * The PLM is little endian. When programming the keys in uint32_t the driver
90 * will BE swap the values.
91 *
92 * This way the test key below corresponds to the byte array 0xf8, 0x78, 0xb8,
93 * 0x38, 0xd8, 0x58, 0x98, 0x18, 0xe8, 0x68, ....
94 *
95 * NOTICE: This hardcoded value in DEVEL_KEY could have just been zeroes as done
96 * in the weak implementation found in otp_stubs.c.
97 */
98 #define DEVEL_KEY { \
99 0xf878b838, 0xd8589818, 0xe868a828, 0xc8488808, \
100 0xf070b030, 0xd0509010, 0xe060a020, 0xc0408000, \
101 }
102
103 #define AAD { \
104 0x67, 0xe2, 0x1c, 0xf3, 0xcb, 0x29, 0xe0, 0xdc, 0xbc, 0x4d, \
105 0x8b, 0x1d, 0x0c, 0xc5, 0x33, 0x4b, \
106 }
107
108 #define NONCE { \
109 0xd2, 0x45, 0x0e, 0x07, 0xea, 0x5d, 0xe0, 0x42, 0x6c, 0x0f, \
110 0xa1, 0x33, \
111 }
112
versal_persistent_key(enum versal_aes_key_src src,bool * secure)113 static bool versal_persistent_key(enum versal_aes_key_src src, bool *secure)
114 {
115 struct versal_efuse_puf_sec_ctrl_bits puf_ctrl = { };
116 struct versal_efuse_sec_ctrl_bits ctrl = { };
117 struct versal_puf_data puf_data = { };
118 struct versal_puf_cfg cfg = {
119 .global_var_filter = VERSAL_PUF_GLBL_VAR_FLTR_OPTION,
120 .read_option = VERSAL_PUF_READ_FROM_EFUSE_CACHE,
121 .puf_operation = VERSAL_PUF_REGEN_ON_DEMAND,
122 .shutter_value = VERSAL_PUF_SHUTTER_VALUE,
123 .reg_mode = VERSAL_PUF_SYNDROME_MODE_4K,
124 };
125
126 switch (src) {
127 case VERSAL_AES_EFUSE_USER_KEY_0:
128 if (versal_efuse_read_sec_ctrl(&ctrl))
129 panic();
130
131 *secure = ctrl.user_key0_wr_lk;
132 return true;
133
134 case VERSAL_AES_EFUSE_USER_KEY_1:
135 if (versal_efuse_read_sec_ctrl(&ctrl))
136 panic();
137
138 *secure = ctrl.user_key1_wr_lk;
139 return true;
140
141 case VERSAL_AES_PUF_KEY:
142 if (versal_efuse_read_puf_sec_ctrl(&puf_ctrl))
143 panic();
144
145 if (versal_puf_regenerate(&puf_data, &cfg))
146 panic();
147
148 *secure = puf_ctrl.puf_syn_lk;
149 return true;
150
151 case VERSAL_AES_USER_KEY_0:
152 *secure = false;
153 return false;
154
155 default:
156 EMSG("Trying to use an invalid key for the HUK");
157 panic();
158 }
159
160 return false;
161 }
162
163 /* Encrypt using an AES-GCM key selectable with CFG_VERSAL_HUK_KEY */
aes_gcm_encrypt(uint8_t * src,size_t src_len,uint8_t * dst,size_t dst_len)164 static TEE_Result aes_gcm_encrypt(uint8_t *src, size_t src_len,
165 uint8_t *dst, size_t dst_len)
166 {
167 struct versal_aes_input_param *input = NULL;
168 struct versal_aes_init *init = NULL;
169 struct versal_mbox_mem input_cmd = { };
170 struct versal_mbox_mem init_buf = { };
171 struct versal_mbox_mem p = { };
172 struct versal_mbox_mem q = { };
173 uint32_t key_data[8] = DEVEL_KEY;
174 uint8_t nce_data[12] = NONCE;
175 uint8_t aad_data[16] = AAD;
176 size_t nce_len = sizeof(nce_data);
177 size_t key_len = sizeof(key_data);
178 size_t aad_len = sizeof(aad_data);
179 TEE_Result ret = TEE_SUCCESS;
180 struct versal_ipi_cmd cmd = { };
181 bool secure = false;
182 size_t i = 0;
183 uint32_t key_id = CFG_VERSAL_HUK_KEY;
184
185 if (key_id > VERSAL_AES_ALL_KEYS)
186 return TEE_ERROR_BAD_PARAMETERS;
187
188 cmd.data[0] = API_ID(VERSAL_AES_INIT);
189 if (versal_mbox_notify(&cmd, NULL, NULL)) {
190 EMSG("AES_INIT error");
191 return TEE_ERROR_GENERIC;
192 }
193
194 if (!versal_persistent_key(key_id, &secure)) {
195 for (i = 0; i < ARRAY_SIZE(key_data); i++)
196 key_data[i] = TEE_U32_BSWAP(key_data[i]);
197
198 versal_mbox_alloc(key_len, key_data, &p);
199 cmd.data[0] = API_ID(VERSAL_AES_WRITE_KEY);
200 cmd.data[1] = VERSAL_AES_KEY_SIZE_256;
201 cmd.data[2] = key_id;
202 reg_pair_from_64(virt_to_phys(p.buf),
203 &cmd.data[4], &cmd.data[3]);
204 cmd.ibuf[0].mem = p;
205 if (versal_mbox_notify(&cmd, NULL, NULL)) {
206 EMSG("AES_WRITE_KEY error");
207 ret = TEE_ERROR_GENERIC;
208 }
209 free(p.buf);
210 memset(&cmd, 0, sizeof(cmd));
211 if (ret)
212 return ret;
213 }
214
215 /* Trace indication that it is safe to generate a RPMB key */
216 IMSG("Using %s HUK", secure ? "Production" : "Development");
217
218 versal_mbox_alloc(sizeof(*init), NULL, &init_buf);
219 versal_mbox_alloc(nce_len, nce_data, &p);
220 init = init_buf.buf;
221 init->operation = VERSAL_AES_GCM_ENCRYPT;
222 init->key_len = VERSAL_AES_KEY_SIZE_256;
223 init->iv_addr = virt_to_phys(p.buf);
224 init->key_src = key_id;
225 cmd.data[0] = API_ID(VERSAL_AES_OP_INIT);
226 reg_pair_from_64(virt_to_phys(init), &cmd.data[2], &cmd.data[1]);
227 cmd.ibuf[0].mem = init_buf;
228 cmd.ibuf[1].mem = p;
229 if (versal_mbox_notify(&cmd, NULL, NULL)) {
230 EMSG("AES_OP_INIT error");
231 ret = TEE_ERROR_GENERIC;
232 }
233 free(init);
234 free(p.buf);
235 memset(&cmd, 0, sizeof(cmd));
236 if (ret)
237 return ret;
238
239 versal_mbox_alloc(aad_len, aad_data, &p);
240 cmd.data[0] = API_ID(VERSAL_AES_UPDATE_AAD);
241 reg_pair_from_64(virt_to_phys(p.buf), &cmd.data[2], &cmd.data[1]);
242 if (p.len % 16)
243 cmd.data[3] = p.alloc_len;
244 else
245 cmd.data[3] = p.len;
246 cmd.ibuf[0].mem = p;
247 if (versal_mbox_notify(&cmd, NULL, NULL)) {
248 EMSG("AES_UPDATE_AAD error");
249 ret = TEE_ERROR_GENERIC;
250 }
251 free(p.buf);
252 memset(&cmd, 0, sizeof(cmd));
253 if (ret)
254 return ret;
255
256 versal_mbox_alloc(sizeof(*input), NULL, &input_cmd);
257 versal_mbox_alloc(src_len, src, &p);
258 versal_mbox_alloc(dst_len, NULL, &q);
259 input = input_cmd.buf;
260 input->input_addr = virt_to_phys(p.buf);
261 input->input_len = p.len;
262 input->is_last = true;
263 cmd.data[0] = API_ID(VERSAL_AES_ENCRYPT_UPDATE);
264 reg_pair_from_64(virt_to_phys(input), &cmd.data[2], &cmd.data[1]);
265 reg_pair_from_64(virt_to_phys(q.buf), &cmd.data[4], &cmd.data[3]);
266 cmd.ibuf[0].mem = input_cmd;
267 cmd.ibuf[1].mem = p;
268 cmd.ibuf[2].mem = q;
269 if (versal_mbox_notify(&cmd, NULL, NULL)) {
270 EMSG("AES_UPDATE_PAYLOAD error");
271 ret = TEE_ERROR_GENERIC;
272 }
273 memcpy(dst, q.buf, dst_len);
274 free(input);
275 free(p.buf);
276 free(q.buf);
277 memset(&cmd, 0, sizeof(cmd));
278 if (ret)
279 return ret;
280
281 versal_mbox_alloc(16, NULL, &p);
282 cmd.data[0] = API_ID(VERSAL_AES_ENCRYPT_FINAL);
283 reg_pair_from_64(virt_to_phys(p.buf), &cmd.data[2], &cmd.data[1]);
284 if (versal_mbox_notify(&cmd, NULL, NULL)) {
285 EMSG("AES_ENCRYPT_FINAL error");
286 ret = TEE_ERROR_GENERIC;
287 }
288 free(p.buf);
289 memzero_explicit(&cmd, sizeof(cmd));
290
291 return ret;
292 }
293
tee_otp_get_hw_unique_key(struct tee_hw_unique_key * hwkey)294 TEE_Result tee_otp_get_hw_unique_key(struct tee_hw_unique_key *hwkey)
295 {
296 uint32_t dna[EFUSE_DNA_LEN / sizeof(uint32_t)] = { };
297 uint8_t enc_data[64] = { };
298 uint8_t sha[48] = { };
299 TEE_Result ret = TEE_SUCCESS;
300
301 if (huk.ready)
302 goto out;
303
304 if (versal_efuse_read_dna(dna, sizeof(dna)))
305 return TEE_ERROR_GENERIC;
306
307 if (versal_sha3_384((uint8_t *)dna, sizeof(dna), sha, sizeof(sha))) {
308 ret = TEE_ERROR_GENERIC;
309 goto cleanup;
310 }
311
312 if (aes_gcm_encrypt(sha, sizeof(sha), enc_data, sizeof(enc_data))) {
313 ret = TEE_ERROR_GENERIC;
314 goto cleanup;
315 }
316
317 if (tee_hash_createdigest(TEE_ALG_SHA256, enc_data, sizeof(enc_data),
318 huk.key, sizeof(huk.key))) {
319 ret = TEE_ERROR_GENERIC;
320 goto cleanup;
321 }
322
323 cleanup:
324 memzero_explicit(enc_data, sizeof(enc_data));
325 memzero_explicit(dna, sizeof(dna));
326 memzero_explicit(sha, sizeof(sha));
327
328 if (ret)
329 return ret;
330
331 huk.ready = true;
332 out:
333 memcpy(hwkey->data, huk.key, HW_UNIQUE_KEY_LENGTH);
334 return TEE_SUCCESS;
335 }
336