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