1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright (C) Foundries Ltd. 2022.
4 * Author: Jorge Ramirez <jorge@foundries.io>
5 */
6
7 #include <crypto/crypto_impl.h>
8 #include <drvcrypt.h>
9 #include <drvcrypt_acipher.h>
10 #include <ecc.h>
11 #include <ipi.h>
12 #include <mm/core_memprot.h>
13 #include <kernel/panic.h>
14 #include <string.h>
15 #include <tee/cache.h>
16 #include <tee/tee_cryp_utl.h>
17 #include <util.h>
18
19 /* AMD/Xilinx Versal's Known Answer Tests */
20 #define XSECURE_ECC_PRIME 0
21 #define XSECURE_ECC_BINARY 1
22
23 enum versal_ecc_err {
24 KAT_KEY_NOTVALID_ERROR = 0xC0,
25 KAT_FAILED_ERROR,
26 NON_SUPPORTED_CURVE,
27 KEY_ZERO,
28 KEY_WRONG_ORDER,
29 KEY_NOT_ON_CURVE,
30 BAD_SIGN,
31 GEN_SIGN_INCORRECT_HASH_LEN,
32 VER_SIGN_INCORRECT_HASH_LEN,
33 GEN_SIGN_BAD_RAND_NUM,
34 GEN_KEY_ERR,
35 INVALID_PARAM,
36 VER_SIGN_R_ZERO,
37 VER_SIGN_S_ZERO,
38 VER_SIGN_R_ORDER_ERROR,
39 VER_SIGN_S_ORDER_ERROR,
40 KAT_INVLD_CRV_ERROR,
41 };
42
43 #define VERSAL_ECC_ERROR(m) { .error = (m), .name = TO_STR(m) }
44
versal_ecc_error(uint8_t err)45 static const char *versal_ecc_error(uint8_t err)
46 {
47 struct {
48 enum versal_ecc_err error;
49 const char *name;
50 } elist[] = {
51 VERSAL_ECC_ERROR(KAT_KEY_NOTVALID_ERROR),
52 VERSAL_ECC_ERROR(KAT_FAILED_ERROR),
53 VERSAL_ECC_ERROR(NON_SUPPORTED_CURVE),
54 VERSAL_ECC_ERROR(KEY_ZERO),
55 VERSAL_ECC_ERROR(KEY_WRONG_ORDER),
56 VERSAL_ECC_ERROR(KEY_NOT_ON_CURVE),
57 VERSAL_ECC_ERROR(BAD_SIGN),
58 VERSAL_ECC_ERROR(GEN_SIGN_INCORRECT_HASH_LEN),
59 VERSAL_ECC_ERROR(VER_SIGN_INCORRECT_HASH_LEN),
60 VERSAL_ECC_ERROR(GEN_SIGN_BAD_RAND_NUM),
61 VERSAL_ECC_ERROR(GEN_KEY_ERR),
62 VERSAL_ECC_ERROR(INVALID_PARAM),
63 VERSAL_ECC_ERROR(VER_SIGN_R_ZERO),
64 VERSAL_ECC_ERROR(VER_SIGN_S_ZERO),
65 VERSAL_ECC_ERROR(VER_SIGN_R_ORDER_ERROR),
66 VERSAL_ECC_ERROR(VER_SIGN_S_ORDER_ERROR),
67 VERSAL_ECC_ERROR(KAT_INVLD_CRV_ERROR),
68 };
69
70 if (err <= KAT_INVLD_CRV_ERROR && err >= KAT_KEY_NOTVALID_ERROR) {
71 if (elist[err - KAT_KEY_NOTVALID_ERROR].name)
72 return elist[err - KAT_KEY_NOTVALID_ERROR].name;
73
74 return "Invalid";
75 }
76
77 return "Unknown";
78 }
79
ecc_get_key_size(uint32_t curve,size_t * bytes,size_t * bits)80 static TEE_Result ecc_get_key_size(uint32_t curve, size_t *bytes, size_t *bits)
81 {
82 switch (curve) {
83 case TEE_ECC_CURVE_NIST_P256:
84 *bits = 256;
85 *bytes = 32;
86 break;
87 case TEE_ECC_CURVE_NIST_P384:
88 *bits = 384;
89 *bytes = 48;
90 break;
91 case TEE_ECC_CURVE_NIST_P521:
92 *bits = 521;
93 *bytes = 66;
94 break;
95 default:
96 return TEE_ERROR_NOT_SUPPORTED;
97 }
98
99 return TEE_SUCCESS;
100 }
101
memcpy_swp(uint8_t * to,const uint8_t * from,size_t len)102 static void memcpy_swp(uint8_t *to, const uint8_t *from, size_t len)
103 {
104 size_t i = 0;
105
106 for (i = 0; i < len; i++)
107 to[i] = from[len - 1 - i];
108 }
109
crypto_bignum_bn2bin_eswap(uint32_t curve,struct bignum * from,uint8_t * to)110 static void crypto_bignum_bn2bin_eswap(uint32_t curve,
111 struct bignum *from, uint8_t *to)
112 {
113 uint8_t pad[66] = { 0 };
114 size_t len = crypto_bignum_num_bytes(from);
115 size_t bytes = 0;
116 size_t bits = 0;
117
118 if (ecc_get_key_size(curve, &bytes, &bits))
119 panic();
120
121 crypto_bignum_bn2bin(from, pad + bytes - len);
122 memcpy_swp(to, pad, bytes);
123 }
124
ecc_prepare_msg(uint32_t algo,const uint8_t * msg,size_t msg_len,struct versal_mbox_mem * p)125 static TEE_Result ecc_prepare_msg(uint32_t algo, const uint8_t *msg,
126 size_t msg_len, struct versal_mbox_mem *p)
127 {
128 uint8_t swp[TEE_SHA512_HASH_SIZE + 2] = { 0 };
129 size_t len = 0;
130
131 if (msg_len > TEE_SHA512_HASH_SIZE + 2)
132 return TEE_ERROR_BAD_PARAMETERS;
133
134 if (algo == TEE_ALG_ECDSA_SHA256)
135 len = TEE_SHA256_HASH_SIZE;
136 else if (algo == TEE_ALG_ECDSA_SHA384)
137 len = TEE_SHA384_HASH_SIZE;
138 else if (algo == TEE_ALG_ECDSA_SHA512)
139 len = TEE_SHA512_HASH_SIZE + 2;
140 else
141 return TEE_ERROR_NOT_SUPPORTED;
142
143 /* Swap the hash/message and pad if necessary */
144 memcpy_swp(swp, msg, msg_len);
145 return versal_mbox_alloc(len, swp, p);
146 }
147
versal_ecc_verify(uint32_t algo,struct ecc_public_key * key,const uint8_t * msg,size_t msg_len,const uint8_t * sig,size_t sig_len)148 TEE_Result versal_ecc_verify(uint32_t algo, struct ecc_public_key *key,
149 const uint8_t *msg, size_t msg_len,
150 const uint8_t *sig, size_t sig_len)
151 {
152 TEE_Result ret = TEE_SUCCESS;
153 struct versal_ecc_verify_param *cmd = NULL;
154 struct versal_cmd_args arg = { };
155 struct versal_mbox_mem x = { };
156 struct versal_mbox_mem s = { };
157 struct versal_mbox_mem p = { };
158 struct versal_mbox_mem cmd_buf = { };
159 uint32_t err = 0;
160 size_t bytes = 0;
161 size_t bits = 0;
162
163 if (sig_len % 2)
164 return TEE_ERROR_SIGNATURE_INVALID;
165
166 ret = ecc_get_key_size(key->curve, &bytes, &bits);
167 if (ret)
168 return ret;
169
170 ret = ecc_prepare_msg(algo, msg, msg_len, &p);
171 if (ret)
172 return ret;
173
174 ret = versal_mbox_alloc(bytes * 2, NULL, &x);
175 if (ret)
176 goto out;
177
178 crypto_bignum_bn2bin_eswap(key->curve, key->x, x.buf);
179 crypto_bignum_bn2bin_eswap(key->curve, key->y,
180 (uint8_t *)x.buf + bytes);
181 /* Validate the public key for the curve */
182 arg.data[0] = key->curve;
183 arg.dlen = 1;
184 arg.ibuf[0].mem = x;
185 if (versal_crypto_request(VERSAL_ELLIPTIC_VALIDATE_PUBLIC_KEY,
186 &arg, &err)) {
187 EMSG("Versal ECC: %s", versal_ecc_error(err));
188 ret = TEE_ERROR_GENERIC;
189 goto out;
190 }
191 memset(&arg, 0, sizeof(arg));
192
193 ret = versal_mbox_alloc(sig_len, NULL, &s);
194 if (ret)
195 goto out;
196
197 /* Swap the {R,S} components */
198 memcpy_swp(s.buf, sig, sig_len / 2);
199 memcpy_swp((uint8_t *)s.buf + sig_len / 2, sig + sig_len / 2,
200 sig_len / 2);
201
202 ret = versal_mbox_alloc(sizeof(*cmd), NULL, &cmd_buf);
203 if (ret)
204 goto out;
205
206 cmd = cmd_buf.buf;
207 cmd->signature_addr = virt_to_phys(s.buf);
208 cmd->pub_key_addr = virt_to_phys(x.buf);
209 cmd->hash_addr = virt_to_phys(p.buf);
210 cmd->hash_len = p.len;
211 cmd->curve = key->curve;
212
213 arg.ibuf[0].mem = cmd_buf;
214 arg.ibuf[1].mem = p;
215 arg.ibuf[1].only_cache = true;
216 arg.ibuf[2].mem = x;
217 arg.ibuf[3].mem = s;
218
219 if (versal_crypto_request(VERSAL_ELLIPTIC_VERIFY_SIGN, &arg, &err)) {
220 EMSG("Versal ECC: %s", versal_ecc_error(err));
221 ret = TEE_ERROR_GENERIC;
222 }
223
224 out:
225 versal_mbox_free(&cmd_buf);
226 versal_mbox_free(&s);
227 versal_mbox_free(&x);
228 versal_mbox_free(&p);
229
230 return ret;
231 }
232
versal_ecc_sign(uint32_t algo,struct ecc_keypair * key,const uint8_t * msg,size_t msg_len,uint8_t * sig,size_t * sig_len)233 TEE_Result versal_ecc_sign(uint32_t algo, struct ecc_keypair *key,
234 const uint8_t *msg, size_t msg_len,
235 uint8_t *sig, size_t *sig_len)
236 {
237 struct versal_ecc_sign_param *cmd = NULL;
238 struct versal_mbox_mem cmd_buf = { };
239 struct ecc_keypair ephemeral = { };
240 struct versal_cmd_args arg = { };
241 struct versal_mbox_mem p = { };
242 struct versal_mbox_mem k = { };
243 struct versal_mbox_mem d = { };
244 struct versal_mbox_mem s = { };
245 TEE_Result ret = TEE_SUCCESS;
246 uint32_t err = 0;
247 size_t bytes = 0;
248 size_t bits = 0;
249
250 ret = ecc_get_key_size(key->curve, &bytes, &bits);
251 if (ret)
252 return ret;
253
254 /* Hash and update the length */
255 ret = ecc_prepare_msg(algo, msg, msg_len, &p);
256 if (ret)
257 return ret;
258
259 /* Ephemeral private key */
260 ret = drvcrypt_asym_alloc_ecc_keypair(&ephemeral,
261 TEE_TYPE_ECDSA_KEYPAIR, bits);
262 if (ret) {
263 EMSG("Versal, can't allocate the ephemeral key");
264 goto out;
265 }
266
267 ephemeral.curve = key->curve;
268 ret = crypto_acipher_gen_ecc_key(&ephemeral, bits);
269 if (ret) {
270 EMSG("Versal, can't generate the ephemeral key");
271 goto out;
272 }
273
274 ret = versal_mbox_alloc(bytes, NULL, &k);
275 if (ret)
276 goto out;
277
278 crypto_bignum_bn2bin_eswap(key->curve, ephemeral.d, k.buf);
279
280 /* Private key*/
281 ret = versal_mbox_alloc(bytes, NULL, &d);
282 if (ret)
283 goto out;
284
285 crypto_bignum_bn2bin_eswap(key->curve, key->d, d.buf);
286
287 /* Signature */
288 ret = versal_mbox_alloc(*sig_len, NULL, &s);
289 if (ret)
290 goto out;
291
292 /* IPI command */
293 ret = versal_mbox_alloc(sizeof(*cmd), NULL, &cmd_buf);
294 if (ret)
295 goto out;
296
297 cmd = cmd_buf.buf;
298 cmd->priv_key_addr = virt_to_phys(d.buf);
299 cmd->epriv_key_addr = virt_to_phys(k.buf);
300 cmd->hash_addr = virt_to_phys(p.buf);
301 cmd->hash_len = p.len;
302 cmd->curve = key->curve;
303
304 arg.ibuf[0].mem = cmd_buf;
305 arg.ibuf[1].mem = s;
306 arg.ibuf[2].mem = k;
307 arg.ibuf[3].mem = d;
308 arg.ibuf[4].mem = p;
309
310 if (versal_crypto_request(VERSAL_ELLIPTIC_GENERATE_SIGN, &arg, &err)) {
311 EMSG("Versal ECC: %s", versal_ecc_error(err));
312 ret = TEE_ERROR_GENERIC;
313 goto out;
314 }
315
316 *sig_len = 2 * bytes;
317
318 /* Swap the {R,S} components */
319 memcpy_swp(sig, s.buf, *sig_len / 2);
320 memcpy_swp(sig + *sig_len / 2, (uint8_t *)s.buf + *sig_len / 2,
321 *sig_len / 2);
322
323 out:
324 versal_mbox_free(&cmd_buf);
325 versal_mbox_free(&s);
326 versal_mbox_free(&d);
327 versal_mbox_free(&k);
328
329 crypto_bignum_free(&ephemeral.d);
330 crypto_bignum_free(&ephemeral.x);
331 crypto_bignum_free(&ephemeral.y);
332
333 versal_mbox_free(&p);
334
335 return ret;
336 }
337
versal_ecc_gen_keypair(struct ecc_keypair * s __maybe_unused)338 TEE_Result versal_ecc_gen_keypair(struct ecc_keypair *s __maybe_unused)
339 {
340 return TEE_ERROR_NOT_SUPPORTED;
341 }
342
versal_ecc_kat_test(void)343 TEE_Result versal_ecc_kat_test(void)
344 {
345 struct versal_cmd_args arg = { };
346 uint32_t err = 0;
347
348 arg.data[arg.dlen++] = VERSAL_ELLIPTIC_SIGN_GEN_KAT;
349 arg.data[arg.dlen++] = XSECURE_ECC_PRIME;
350 if (versal_crypto_request(VERSAL_KAT, &arg, &err)) {
351 EMSG("Versal KAT ECC SignGen: %s", versal_ecc_error(err));
352 return TEE_ERROR_GENERIC;
353 }
354
355 /* Clean previous request */
356 arg.dlen = 0;
357
358 arg.data[arg.dlen++] = VERSAL_ELLIPTIC_SIGN_VERIFY_KAT;
359 arg.data[arg.dlen++] = XSECURE_ECC_PRIME;
360 if (versal_crypto_request(VERSAL_KAT, &arg, &err)) {
361 EMSG("Versal KAT ECC SignVerify: %s", versal_ecc_error(err));
362 return TEE_ERROR_GENERIC;
363 }
364
365 return TEE_SUCCESS;
366 }
367
versal_ecc_hw_init(void)368 TEE_Result versal_ecc_hw_init(void)
369 {
370 return TEE_SUCCESS;
371 }
372