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 <drvcrypt.h>
8 #include <drvcrypt_acipher.h>
9 #include <crypto/crypto_impl.h>
10 #include <initcall.h>
11 #include <ipi.h>
12 #include <kernel/panic.h>
13 #include <mm/core_memprot.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_ECDSA_KAT_NIST_P384 0
21 #define XSECURE_ECDSA_KAT_NIST_P521 2
22
23 /* Software based ECDSA operations */
24 static const struct crypto_ecc_keypair_ops *pair_ops;
25 static const struct crypto_ecc_public_ops *pub_ops;
26
27 enum versal_ecc_err {
28 KAT_KEY_NOTVALID_ERROR = 0xC0,
29 KAT_FAILED_ERROR,
30 NON_SUPPORTED_CURVE,
31 KEY_ZERO,
32 KEY_WRONG_ORDER,
33 KEY_NOT_ON_CURVE,
34 BAD_SIGN,
35 GEN_SIGN_INCORRECT_HASH_LEN,
36 VER_SIGN_INCORRECT_HASH_LEN,
37 GEN_SIGN_BAD_RAND_NUM,
38 GEN_KEY_ERR,
39 INVALID_PARAM,
40 VER_SIGN_R_ZERO,
41 VER_SIGN_S_ZERO,
42 VER_SIGN_R_ORDER_ERROR,
43 VER_SIGN_S_ORDER_ERROR,
44 KAT_INVLD_CRV_ERROR,
45 };
46
47 #define VERSAL_ECC_ERROR(m) { .error = (m), .name = TO_STR(m) }
48
versal_ecc_error(uint8_t err)49 static const char *versal_ecc_error(uint8_t err)
50 {
51 struct {
52 enum versal_ecc_err error;
53 const char *name;
54 } elist[] = {
55 VERSAL_ECC_ERROR(KAT_KEY_NOTVALID_ERROR),
56 VERSAL_ECC_ERROR(KAT_FAILED_ERROR),
57 VERSAL_ECC_ERROR(NON_SUPPORTED_CURVE),
58 VERSAL_ECC_ERROR(KEY_ZERO),
59 VERSAL_ECC_ERROR(KEY_WRONG_ORDER),
60 VERSAL_ECC_ERROR(KEY_NOT_ON_CURVE),
61 VERSAL_ECC_ERROR(BAD_SIGN),
62 VERSAL_ECC_ERROR(GEN_SIGN_INCORRECT_HASH_LEN),
63 VERSAL_ECC_ERROR(VER_SIGN_INCORRECT_HASH_LEN),
64 VERSAL_ECC_ERROR(GEN_SIGN_BAD_RAND_NUM),
65 VERSAL_ECC_ERROR(GEN_KEY_ERR),
66 VERSAL_ECC_ERROR(INVALID_PARAM),
67 VERSAL_ECC_ERROR(VER_SIGN_R_ZERO),
68 VERSAL_ECC_ERROR(VER_SIGN_S_ZERO),
69 VERSAL_ECC_ERROR(VER_SIGN_R_ORDER_ERROR),
70 VERSAL_ECC_ERROR(VER_SIGN_S_ORDER_ERROR),
71 VERSAL_ECC_ERROR(KAT_INVLD_CRV_ERROR),
72 };
73
74 if (err <= KAT_INVLD_CRV_ERROR && err >= KAT_KEY_NOTVALID_ERROR) {
75 if (elist[err - KAT_KEY_NOTVALID_ERROR].name)
76 return elist[err - KAT_KEY_NOTVALID_ERROR].name;
77
78 return "Invalid";
79 }
80
81 return "Unknown";
82 }
83
ecc_get_key_size(uint32_t curve,size_t * bytes,size_t * bits)84 static TEE_Result ecc_get_key_size(uint32_t curve, size_t *bytes, size_t *bits)
85 {
86 switch (curve) {
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_SHA384)
135 len = TEE_SHA384_HASH_SIZE;
136 else if (algo == TEE_ALG_ECDSA_SHA512)
137 len = TEE_SHA512_HASH_SIZE + 2;
138 else
139 return TEE_ERROR_NOT_SUPPORTED;
140
141 /* Swap the hash/message and pad if necessary */
142 memcpy_swp(swp, msg, msg_len);
143 return versal_mbox_alloc(len, swp, p);
144 }
145
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)146 static TEE_Result verify(uint32_t algo, struct ecc_public_key *key,
147 const uint8_t *msg, size_t msg_len,
148 const uint8_t *sig, size_t sig_len)
149 {
150 TEE_Result ret = TEE_SUCCESS;
151 struct versal_ecc_verify_param *cmd = NULL;
152 struct versal_cmd_args arg = { };
153 struct versal_mbox_mem x = { };
154 struct versal_mbox_mem s = { };
155 struct versal_mbox_mem p = { };
156 struct versal_mbox_mem cmd_buf = { };
157 uint32_t err = 0;
158 size_t bytes = 0;
159 size_t bits = 0;
160
161 if (sig_len % 2)
162 return TEE_ERROR_SIGNATURE_INVALID;
163
164 ret = ecc_get_key_size(key->curve, &bytes, &bits);
165 if (ret != TEE_SUCCESS) {
166 if (ret != TEE_ERROR_NOT_SUPPORTED)
167 return ret;
168
169 /* Fallback to software */
170 return pub_ops->verify(algo, key, msg, msg_len, sig, sig_len);
171 }
172
173 ret = ecc_prepare_msg(algo, msg, msg_len, &p);
174 if (ret)
175 return ret;
176
177 versal_mbox_alloc(bytes * 2, NULL, &x);
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 versal_mbox_alloc(sig_len, NULL, &s);
194 /* Swap the {R,S} components */
195 memcpy_swp(s.buf, sig, sig_len / 2);
196 memcpy_swp((uint8_t *)s.buf + sig_len / 2, sig + sig_len / 2,
197 sig_len / 2);
198 versal_mbox_alloc(sizeof(*cmd), NULL, &cmd_buf);
199
200 cmd = cmd_buf.buf;
201 cmd->signature_addr = virt_to_phys(s.buf);
202 cmd->pub_key_addr = virt_to_phys(x.buf);
203 cmd->hash_addr = virt_to_phys(p.buf);
204 cmd->hash_len = p.len;
205 cmd->curve = key->curve;
206
207 arg.ibuf[0].mem = cmd_buf;
208 arg.ibuf[1].mem = p;
209 arg.ibuf[1].only_cache = true;
210 arg.ibuf[2].mem = x;
211 arg.ibuf[3].mem = s;
212
213 if (versal_crypto_request(VERSAL_ELLIPTIC_VERIFY_SIGN, &arg, &err)) {
214 EMSG("Versal ECC: %s", versal_ecc_error(err));
215 ret = TEE_ERROR_GENERIC;
216 }
217 out:
218 free(p.buf);
219 free(x.buf);
220 free(s.buf);
221 free(cmd);
222
223 return ret;
224 }
225
sign(uint32_t algo,struct ecc_keypair * key,const uint8_t * msg,size_t msg_len,uint8_t * sig,size_t * sig_len)226 static TEE_Result sign(uint32_t algo, struct ecc_keypair *key,
227 const uint8_t *msg, size_t msg_len,
228 uint8_t *sig, size_t *sig_len)
229 {
230 struct versal_ecc_sign_param *cmd = NULL;
231 struct versal_mbox_mem cmd_buf = { };
232 struct ecc_keypair ephemeral = { };
233 struct versal_cmd_args arg = { };
234 struct versal_mbox_mem p = { };
235 struct versal_mbox_mem k = { };
236 struct versal_mbox_mem d = { };
237 struct versal_mbox_mem s = { };
238 TEE_Result ret = TEE_SUCCESS;
239 uint32_t err = 0;
240 size_t bytes = 0;
241 size_t bits = 0;
242
243 ret = ecc_get_key_size(key->curve, &bytes, &bits);
244 if (ret != TEE_SUCCESS) {
245 if (ret != TEE_ERROR_NOT_SUPPORTED)
246 return ret;
247
248 /* Fallback to software */
249 return pair_ops->sign(algo, key, msg, msg_len, sig, sig_len);
250 }
251
252 /* Hash and update the length */
253 ret = ecc_prepare_msg(algo, msg, msg_len, &p);
254 if (ret)
255 return ret;
256
257 /* Ephemeral private key */
258 ret = drvcrypt_asym_alloc_ecc_keypair(&ephemeral,
259 TEE_TYPE_ECDSA_KEYPAIR, bits);
260 if (ret) {
261 EMSG("Versal, can't allocate the ephemeral key");
262 return ret;
263 }
264
265 ephemeral.curve = key->curve;
266 ret = crypto_acipher_gen_ecc_key(&ephemeral, bits);
267 if (ret) {
268 EMSG("Versal, can't generate the ephemeral key");
269 return ret;
270 }
271
272 versal_mbox_alloc(bytes, NULL, &k);
273 crypto_bignum_bn2bin_eswap(key->curve, ephemeral.d, k.buf);
274 crypto_bignum_free(&ephemeral.d);
275 crypto_bignum_free(&ephemeral.x);
276 crypto_bignum_free(&ephemeral.y);
277
278 /* Private key*/
279 versal_mbox_alloc(bytes, NULL, &d);
280 crypto_bignum_bn2bin_eswap(key->curve, key->d, d.buf);
281
282 /* Signature */
283 versal_mbox_alloc(*sig_len, NULL, &s);
284
285 /* IPI command */
286 versal_mbox_alloc(sizeof(*cmd), NULL, &cmd_buf);
287
288 cmd = cmd_buf.buf;
289 cmd->priv_key_addr = virt_to_phys(d.buf);
290 cmd->epriv_key_addr = virt_to_phys(k.buf);
291 cmd->hash_addr = virt_to_phys(p.buf);
292 cmd->hash_len = p.len;
293 cmd->curve = key->curve;
294
295 arg.ibuf[0].mem = cmd_buf;
296 arg.ibuf[1].mem = s;
297 arg.ibuf[2].mem = k;
298 arg.ibuf[3].mem = d;
299 arg.ibuf[4].mem = p;
300
301 if (versal_crypto_request(VERSAL_ELLIPTIC_GENERATE_SIGN, &arg, &err)) {
302 EMSG("Versal ECC: %s", versal_ecc_error(err));
303 ret = TEE_ERROR_GENERIC;
304 goto out;
305 }
306
307 *sig_len = 2 * bytes;
308
309 /* Swap the {R,S} components */
310 memcpy_swp(sig, s.buf, *sig_len / 2);
311 memcpy_swp(sig + *sig_len / 2, (uint8_t *)s.buf + *sig_len / 2,
312 *sig_len / 2);
313 out:
314 free(cmd);
315 free(k.buf);
316 free(p.buf);
317 free(s.buf);
318 free(d.buf);
319
320 return ret;
321 }
322
shared_secret(struct ecc_keypair * private_key,struct ecc_public_key * public_key,void * secret,size_t * secret_len)323 static TEE_Result shared_secret(struct ecc_keypair *private_key,
324 struct ecc_public_key *public_key,
325 void *secret, size_t *secret_len)
326 {
327 return pair_ops->shared_secret(private_key, public_key,
328 secret, secret_len);
329 }
330
do_shared_secret(struct drvcrypt_secret_data * sdata)331 static TEE_Result do_shared_secret(struct drvcrypt_secret_data *sdata)
332 {
333 return shared_secret(sdata->key_priv,
334 sdata->key_pub,
335 sdata->secret.data,
336 &sdata->secret.length);
337 }
338
do_sign(struct drvcrypt_sign_data * sdata)339 static TEE_Result do_sign(struct drvcrypt_sign_data *sdata)
340 {
341 return sign(sdata->algo,
342 sdata->key,
343 sdata->message.data,
344 sdata->message.length,
345 sdata->signature.data,
346 &sdata->signature.length);
347 }
348
do_verify(struct drvcrypt_sign_data * sdata)349 static TEE_Result do_verify(struct drvcrypt_sign_data *sdata)
350 {
351 return verify(sdata->algo,
352 sdata->key,
353 sdata->message.data,
354 sdata->message.length,
355 sdata->signature.data,
356 sdata->signature.length);
357 }
358
do_gen_keypair(struct ecc_keypair * s,size_t size_bits)359 static TEE_Result do_gen_keypair(struct ecc_keypair *s, size_t size_bits)
360 {
361 /*
362 * Versal requires little endian so need to memcpy_swp on Versal IP ops.
363 * We chose not to do it here because some tests might be using
364 * their own keys
365 */
366 return pair_ops->generate(s, size_bits);
367 }
368
do_alloc_keypair(struct ecc_keypair * s,uint32_t type,size_t size_bits)369 static TEE_Result do_alloc_keypair(struct ecc_keypair *s,
370 uint32_t type, size_t size_bits)
371 {
372 TEE_Result ret = TEE_SUCCESS;
373
374 /* This driver only supports ECDH/ECDSA */
375 if (type != TEE_TYPE_ECDSA_KEYPAIR &&
376 type != TEE_TYPE_ECDH_KEYPAIR)
377 return TEE_ERROR_NOT_IMPLEMENTED;
378
379 ret = crypto_asym_alloc_ecc_keypair(s, TEE_TYPE_ECDSA_KEYPAIR,
380 size_bits);
381 if (ret)
382 return TEE_ERROR_NOT_IMPLEMENTED;
383
384 /*
385 * Ignore the software operations, the crypto API will populate
386 * this interface.
387 */
388 s->ops = NULL;
389
390 return TEE_SUCCESS;
391 }
392
do_alloc_publickey(struct ecc_public_key * s,uint32_t type,size_t size_bits)393 static TEE_Result do_alloc_publickey(struct ecc_public_key *s,
394 uint32_t type, size_t size_bits)
395 {
396 TEE_Result ret = TEE_SUCCESS;
397
398 /* This driver only supports ECDH/ECDSA */
399 if (type != TEE_TYPE_ECDSA_PUBLIC_KEY &&
400 type != TEE_TYPE_ECDH_PUBLIC_KEY)
401 return TEE_ERROR_NOT_IMPLEMENTED;
402
403 ret = crypto_asym_alloc_ecc_public_key(s, TEE_TYPE_ECDSA_PUBLIC_KEY,
404 size_bits);
405 if (ret)
406 return TEE_ERROR_NOT_IMPLEMENTED;
407
408 /*
409 * Ignore the software operations, the crypto API will populate
410 * this interface.
411 */
412 s->ops = NULL;
413
414 return TEE_SUCCESS;
415 }
416
do_free_publickey(struct ecc_public_key * s)417 static void do_free_publickey(struct ecc_public_key *s)
418 {
419 return pub_ops->free(s);
420 }
421
422 static struct drvcrypt_ecc driver_ecc = {
423 .shared_secret = do_shared_secret,
424 .alloc_publickey = do_alloc_publickey,
425 .free_publickey = do_free_publickey,
426 .alloc_keypair = do_alloc_keypair,
427 .gen_keypair = do_gen_keypair,
428 .verify = do_verify,
429 .sign = do_sign,
430 };
431
ecc_init(void)432 static TEE_Result ecc_init(void)
433 {
434 struct versal_cmd_args arg = { };
435 uint32_t err = 0;
436
437 arg.data[arg.dlen++] = XSECURE_ECDSA_KAT_NIST_P384;
438 if (versal_crypto_request(VERSAL_ELLIPTIC_KAT, &arg, &err)) {
439 EMSG("Versal KAG NIST_P384: %s", versal_ecc_error(err));
440 return TEE_ERROR_GENERIC;
441 }
442
443 /* Clean previous request */
444 arg.dlen = 0;
445
446 arg.data[arg.dlen++] = XSECURE_ECDSA_KAT_NIST_P521;
447 if (versal_crypto_request(VERSAL_ELLIPTIC_KAT, &arg, &err)) {
448 EMSG("Versal KAG NIST_P521 %s", versal_ecc_error(err));
449 return TEE_ERROR_GENERIC;
450 }
451
452 pair_ops = crypto_asym_get_ecc_keypair_ops(TEE_TYPE_ECDSA_KEYPAIR);
453 if (!pair_ops)
454 return TEE_ERROR_GENERIC;
455
456 pub_ops = crypto_asym_get_ecc_public_ops(TEE_TYPE_ECDSA_PUBLIC_KEY);
457 if (!pub_ops)
458 return TEE_ERROR_GENERIC;
459
460 /* This driver supports both ECDH and ECDSA */
461 assert((pub_ops ==
462 crypto_asym_get_ecc_public_ops(TEE_TYPE_ECDH_PUBLIC_KEY)) &&
463 (pair_ops ==
464 crypto_asym_get_ecc_keypair_ops(TEE_TYPE_ECDH_KEYPAIR)));
465
466 return drvcrypt_register_ecc(&driver_ecc);
467 }
468
469 driver_init(ecc_init);
470