1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright (C) 2018, ARM Limited
4 * Copyright (C) 2019, Linaro Limited
5 */
6
7 #include <assert.h>
8 #include <config.h>
9 #include <crypto/crypto_impl.h>
10 #include <mbedtls/ctr_drbg.h>
11 #include <mbedtls/ecdh.h>
12 #include <mbedtls/ecdsa.h>
13 #include <mbedtls/ecp.h>
14 #include <mbedtls/entropy.h>
15 #include <mbedtls/pk.h>
16 #include <stdlib.h>
17 #include <string.h>
18
19 #include "mbed_helpers.h"
20 #include "sm2-dsa.h"
21 #include "sm2-pke.h"
22
23 /* Translate mbedtls result to TEE result */
get_tee_result(int lmd_res)24 static TEE_Result get_tee_result(int lmd_res)
25 {
26 switch (lmd_res) {
27 case 0:
28 return TEE_SUCCESS;
29 case MBEDTLS_ERR_ECP_VERIFY_FAILED:
30 return TEE_ERROR_SIGNATURE_INVALID;
31 case MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL:
32 return TEE_ERROR_SHORT_BUFFER;
33 default:
34 return TEE_ERROR_BAD_STATE;
35 }
36 }
37
ecc_free_public_key(struct ecc_public_key * s)38 static void ecc_free_public_key(struct ecc_public_key *s)
39 {
40 if (!s)
41 return;
42
43 crypto_bignum_free(&s->x);
44 crypto_bignum_free(&s->y);
45 }
46
ecc_get_keysize(uint32_t curve,uint32_t algo,size_t * key_size_bytes,size_t * key_size_bits)47 static TEE_Result ecc_get_keysize(uint32_t curve, uint32_t algo,
48 size_t *key_size_bytes, size_t *key_size_bits)
49 {
50 switch (curve) {
51 case TEE_ECC_CURVE_NIST_P192:
52 *key_size_bits = 192;
53 *key_size_bytes = 24;
54 break;
55 case TEE_ECC_CURVE_NIST_P224:
56 *key_size_bits = 224;
57 *key_size_bytes = 28;
58 break;
59 case TEE_ECC_CURVE_NIST_P256:
60 *key_size_bits = 256;
61 *key_size_bytes = 32;
62 break;
63 case TEE_ECC_CURVE_NIST_P384:
64 *key_size_bits = 384;
65 *key_size_bytes = 48;
66 break;
67 case TEE_ECC_CURVE_NIST_P521:
68 *key_size_bits = 521;
69 *key_size_bytes = 66;
70 break;
71 case TEE_ECC_CURVE_SM2:
72 *key_size_bits = 256;
73 *key_size_bytes = 32;
74 if (algo != 0 && algo != TEE_ALG_SM2_DSA_SM3 &&
75 algo != TEE_ALG_SM2_KEP && algo != TEE_ALG_SM2_PKE)
76 return TEE_ERROR_BAD_PARAMETERS;
77 break;
78 default:
79 *key_size_bits = 0;
80 *key_size_bytes = 0;
81 return TEE_ERROR_NOT_SUPPORTED;
82 }
83
84 return TEE_SUCCESS;
85 }
86
curve_to_group_id(uint32_t curve)87 static mbedtls_ecp_group_id curve_to_group_id(uint32_t curve)
88 {
89 switch (curve) {
90 case TEE_ECC_CURVE_NIST_P192:
91 return MBEDTLS_ECP_DP_SECP192R1;
92 case TEE_ECC_CURVE_NIST_P224:
93 return MBEDTLS_ECP_DP_SECP224R1;
94 case TEE_ECC_CURVE_NIST_P256:
95 return MBEDTLS_ECP_DP_SECP256R1;
96 case TEE_ECC_CURVE_NIST_P384:
97 return MBEDTLS_ECP_DP_SECP384R1;
98 case TEE_ECC_CURVE_NIST_P521:
99 return MBEDTLS_ECP_DP_SECP521R1;
100 case TEE_ECC_CURVE_SM2:
101 return MBEDTLS_ECP_DP_SM2;
102 default:
103 return MBEDTLS_ECP_DP_NONE;
104 }
105 }
106
ecc_generate_keypair(struct ecc_keypair * key,size_t key_size)107 static TEE_Result ecc_generate_keypair(struct ecc_keypair *key, size_t key_size)
108 {
109 TEE_Result res = TEE_SUCCESS;
110 int lmd_res = 0;
111 mbedtls_ecdsa_context ecdsa;
112 mbedtls_ecp_group_id gid;
113 size_t key_size_bytes = 0;
114 size_t key_size_bits = 0;
115
116 memset(&ecdsa, 0, sizeof(ecdsa));
117 memset(&gid, 0, sizeof(gid));
118
119 res = ecc_get_keysize(key->curve, 0, &key_size_bytes, &key_size_bits);
120 if (res != TEE_SUCCESS)
121 return res;
122
123 if (key_size != key_size_bits)
124 return TEE_ERROR_BAD_PARAMETERS;
125
126 mbedtls_ecdsa_init(&ecdsa);
127
128 /* Generate the ECC key */
129 gid = curve_to_group_id(key->curve);
130 lmd_res = mbedtls_ecdsa_genkey(&ecdsa, gid, mbd_rand, NULL);
131 if (lmd_res != 0) {
132 res = TEE_ERROR_BAD_PARAMETERS;
133 FMSG("mbedtls_ecdsa_genkey failed.");
134 goto exit;
135 }
136
137 /* check the size of the keys */
138 if ((mbedtls_mpi_bitlen(&ecdsa.Q.X) > key_size_bits) ||
139 (mbedtls_mpi_bitlen(&ecdsa.Q.Y) > key_size_bits) ||
140 (mbedtls_mpi_bitlen(&ecdsa.d) > key_size_bits)) {
141 res = TEE_ERROR_BAD_PARAMETERS;
142 FMSG("Check the size of the keys failed.");
143 goto exit;
144 }
145
146 /* check LMD is returning z==1 */
147 if (mbedtls_mpi_bitlen(&ecdsa.Q.Z) != 1) {
148 res = TEE_ERROR_BAD_PARAMETERS;
149 FMSG("Check LMD failed.");
150 goto exit;
151 }
152
153 /* Copy the key */
154 crypto_bignum_copy(key->d, (void *)&ecdsa.d);
155 crypto_bignum_copy(key->x, (void *)&ecdsa.Q.X);
156 crypto_bignum_copy(key->y, (void *)&ecdsa.Q.Y);
157
158 res = TEE_SUCCESS;
159 exit:
160 mbedtls_ecdsa_free(&ecdsa); /* Free the temporary key */
161 return res;
162 }
163
ecc_sign(uint32_t algo,struct ecc_keypair * key,const uint8_t * msg,size_t msg_len,uint8_t * sig,size_t * sig_len)164 static TEE_Result ecc_sign(uint32_t algo, struct ecc_keypair *key,
165 const uint8_t *msg, size_t msg_len, uint8_t *sig,
166 size_t *sig_len)
167 {
168 TEE_Result res = TEE_SUCCESS;
169 int lmd_res = 0;
170 const mbedtls_pk_info_t *pk_info = NULL;
171 mbedtls_ecdsa_context ecdsa;
172 mbedtls_ecp_group_id gid;
173 size_t key_size_bytes = 0;
174 size_t key_size_bits = 0;
175 mbedtls_mpi r;
176 mbedtls_mpi s;
177
178 memset(&ecdsa, 0, sizeof(ecdsa));
179 memset(&gid, 0, sizeof(gid));
180 memset(&r, 0, sizeof(r));
181 memset(&s, 0, sizeof(s));
182
183 if (algo == 0)
184 return TEE_ERROR_BAD_PARAMETERS;
185
186 mbedtls_mpi_init(&r);
187 mbedtls_mpi_init(&s);
188
189 mbedtls_ecdsa_init(&ecdsa);
190
191 gid = curve_to_group_id(key->curve);
192 lmd_res = mbedtls_ecp_group_load(&ecdsa.grp, gid);
193 if (lmd_res != 0) {
194 res = TEE_ERROR_NOT_SUPPORTED;
195 goto out;
196 }
197
198 ecdsa.d = *(mbedtls_mpi *)key->d;
199
200 res = ecc_get_keysize(key->curve, algo, &key_size_bytes,
201 &key_size_bits);
202 if (res != TEE_SUCCESS)
203 goto out;
204
205 if (*sig_len < 2 * key_size_bytes) {
206 *sig_len = 2 * key_size_bytes;
207 res = TEE_ERROR_SHORT_BUFFER;
208 goto out;
209 }
210
211 pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_ECDSA);
212 if (pk_info == NULL) {
213 res = TEE_ERROR_NOT_SUPPORTED;
214 goto out;
215 }
216
217 lmd_res = mbedtls_ecdsa_sign(&ecdsa.grp, &r, &s, &ecdsa.d, msg,
218 msg_len, mbd_rand, NULL);
219 if (lmd_res == 0) {
220 *sig_len = 2 * key_size_bytes;
221 memset(sig, 0, *sig_len);
222 mbedtls_mpi_write_binary(&r, sig + *sig_len / 2 -
223 mbedtls_mpi_size(&r),
224 mbedtls_mpi_size(&r));
225
226 mbedtls_mpi_write_binary(&s, sig + *sig_len -
227 mbedtls_mpi_size(&s),
228 mbedtls_mpi_size(&s));
229 res = TEE_SUCCESS;
230 } else {
231 FMSG("mbedtls_ecdsa_sign failed, returned 0x%x", -lmd_res);
232 res = TEE_ERROR_GENERIC;
233 }
234 out:
235 mbedtls_mpi_free(&r);
236 mbedtls_mpi_free(&s);
237 /* Reset mpi to skip freeing here, those mpis will be freed with key */
238 mbedtls_mpi_init(&ecdsa.d);
239 mbedtls_ecdsa_free(&ecdsa);
240 return res;
241 }
242
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)243 static TEE_Result ecc_verify(uint32_t algo, struct ecc_public_key *key,
244 const uint8_t *msg, size_t msg_len,
245 const uint8_t *sig, size_t sig_len)
246 {
247 TEE_Result res = TEE_SUCCESS;
248 int lmd_res = 0;
249 mbedtls_ecdsa_context ecdsa;
250 mbedtls_ecp_group_id gid;
251 size_t key_size_bytes, key_size_bits = 0;
252 uint8_t one[1] = { 1 };
253 mbedtls_mpi r;
254 mbedtls_mpi s;
255
256 memset(&ecdsa, 0, sizeof(ecdsa));
257 memset(&gid, 0, sizeof(gid));
258 memset(&r, 0, sizeof(r));
259 memset(&s, 0, sizeof(s));
260
261 if (algo == 0)
262 return TEE_ERROR_BAD_PARAMETERS;
263
264 mbedtls_mpi_init(&r);
265 mbedtls_mpi_init(&s);
266
267 mbedtls_ecdsa_init(&ecdsa);
268
269 gid = curve_to_group_id(key->curve);
270 lmd_res = mbedtls_ecp_group_load(&ecdsa.grp, gid);
271 if (lmd_res != 0) {
272 res = TEE_ERROR_NOT_SUPPORTED;
273 goto out;
274 }
275
276 ecdsa.Q.X = *(mbedtls_mpi *)key->x;
277 ecdsa.Q.Y = *(mbedtls_mpi *)key->y;
278 mbedtls_mpi_read_binary(&ecdsa.Q.Z, one, sizeof(one));
279
280 res = ecc_get_keysize(key->curve, algo,
281 &key_size_bytes, &key_size_bits);
282 if (res != TEE_SUCCESS) {
283 res = TEE_ERROR_BAD_PARAMETERS;
284 goto out;
285 }
286
287 /* check keysize vs sig_len */
288 if ((key_size_bytes * 2) != sig_len) {
289 res = TEE_ERROR_BAD_PARAMETERS;
290 goto out;
291 }
292
293 mbedtls_mpi_read_binary(&r, sig, sig_len / 2);
294 mbedtls_mpi_read_binary(&s, sig + sig_len / 2, sig_len / 2);
295
296 lmd_res = mbedtls_ecdsa_verify(&ecdsa.grp, msg, msg_len, &ecdsa.Q,
297 &r, &s);
298 if (lmd_res != 0) {
299 FMSG("mbedtls_ecdsa_verify failed, returned 0x%x", -lmd_res);
300 res = get_tee_result(lmd_res);
301 }
302 out:
303 mbedtls_mpi_free(&r);
304 mbedtls_mpi_free(&s);
305 /* Reset mpi to skip freeing here, those mpis will be freed with key */
306 mbedtls_mpi_init(&ecdsa.Q.X);
307 mbedtls_mpi_init(&ecdsa.Q.Y);
308 mbedtls_ecdsa_free(&ecdsa);
309 return res;
310 }
311
ecc_shared_secret(struct ecc_keypair * private_key,struct ecc_public_key * public_key,void * secret,unsigned long * secret_len)312 static TEE_Result ecc_shared_secret(struct ecc_keypair *private_key,
313 struct ecc_public_key *public_key,
314 void *secret, unsigned long *secret_len)
315 {
316 TEE_Result res = TEE_SUCCESS;
317 int lmd_res = 0;
318 uint8_t one[1] = { 1 };
319 mbedtls_ecdh_context ecdh;
320 mbedtls_ecp_group_id gid;
321 size_t out_len = 0;
322
323 memset(&ecdh, 0, sizeof(ecdh));
324 memset(&gid, 0, sizeof(gid));
325 mbedtls_ecdh_init(&ecdh);
326 gid = curve_to_group_id(private_key->curve);
327 lmd_res = mbedtls_ecdh_setup(&ecdh, gid);
328 if (lmd_res != 0) {
329 res = TEE_ERROR_NOT_SUPPORTED;
330 goto out;
331 }
332
333 assert(ecdh.var == MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0);
334 ecdh.ctx.mbed_ecdh.d = *(mbedtls_mpi *)private_key->d;
335 ecdh.ctx.mbed_ecdh.Qp.X = *(mbedtls_mpi *)public_key->x;
336 ecdh.ctx.mbed_ecdh.Qp.Y = *(mbedtls_mpi *)public_key->y;
337 mbedtls_mpi_read_binary(&ecdh.ctx.mbed_ecdh.Qp.Z, one, sizeof(one));
338
339 lmd_res = mbedtls_ecdh_calc_secret(&ecdh, &out_len, secret,
340 *secret_len, mbd_rand, NULL);
341 if (lmd_res != 0) {
342 res = get_tee_result(lmd_res);
343 goto out;
344 }
345 *secret_len = out_len;
346 out:
347 /* Reset mpi to skip freeing here, those mpis will be freed with key */
348 mbedtls_mpi_init(&ecdh.ctx.mbed_ecdh.d);
349 mbedtls_mpi_init(&ecdh.ctx.mbed_ecdh.Qp.X);
350 mbedtls_mpi_init(&ecdh.ctx.mbed_ecdh.Qp.Y);
351 mbedtls_ecdh_free(&ecdh);
352 return res;
353 }
354
355 static const struct crypto_ecc_keypair_ops ecc_keypair_ops = {
356 .generate = ecc_generate_keypair,
357 .sign = ecc_sign,
358 .shared_secret = ecc_shared_secret,
359 };
360
361 static const struct crypto_ecc_keypair_ops sm2_pke_keypair_ops = {
362 .generate = ecc_generate_keypair,
363 .decrypt = sm2_mbedtls_pke_decrypt,
364 };
365
366 static const struct crypto_ecc_keypair_ops sm2_kep_keypair_ops = {
367 .generate = ecc_generate_keypair,
368 };
369
370 static const struct crypto_ecc_keypair_ops sm2_dsa_keypair_ops = {
371 .generate = ecc_generate_keypair,
372 .sign = sm2_mbedtls_dsa_sign,
373 };
374
375 const struct crypto_ecc_keypair_ops *
crypto_asym_get_ecc_keypair_ops(uint32_t key_type)376 crypto_asym_get_ecc_keypair_ops(uint32_t key_type)
377 {
378 switch (key_type) {
379 case TEE_TYPE_ECDSA_KEYPAIR:
380 case TEE_TYPE_ECDH_KEYPAIR:
381 return &ecc_keypair_ops;
382 case TEE_TYPE_SM2_DSA_KEYPAIR:
383 if (!IS_ENABLED(CFG_CRYPTO_SM2_DSA))
384 return NULL;
385 return &sm2_dsa_keypair_ops;
386 case TEE_TYPE_SM2_PKE_KEYPAIR:
387 if (!IS_ENABLED(CFG_CRYPTO_SM2_PKE))
388 return NULL;
389 return &sm2_pke_keypair_ops;
390 case TEE_TYPE_SM2_KEP_KEYPAIR:
391 if (!IS_ENABLED(CFG_CRYPTO_SM2_KEP))
392 return NULL;
393 return &sm2_kep_keypair_ops;
394 default:
395 return NULL;
396 }
397 }
398
crypto_asym_alloc_ecc_keypair(struct ecc_keypair * s,uint32_t key_type,size_t key_size_bits)399 TEE_Result crypto_asym_alloc_ecc_keypair(struct ecc_keypair *s,
400 uint32_t key_type,
401 size_t key_size_bits)
402 {
403 memset(s, 0, sizeof(*s));
404
405 switch (key_type) {
406 case TEE_TYPE_ECDSA_KEYPAIR:
407 case TEE_TYPE_ECDH_KEYPAIR:
408 s->ops = &ecc_keypair_ops;
409 break;
410 case TEE_TYPE_SM2_DSA_KEYPAIR:
411 if (!IS_ENABLED(CFG_CRYPTO_SM2_DSA))
412 return TEE_ERROR_NOT_IMPLEMENTED;
413
414 s->curve = TEE_ECC_CURVE_SM2;
415 s->ops = &sm2_dsa_keypair_ops;
416 break;
417 case TEE_TYPE_SM2_PKE_KEYPAIR:
418 if (!IS_ENABLED(CFG_CRYPTO_SM2_PKE))
419 return TEE_ERROR_NOT_IMPLEMENTED;
420
421 s->curve = TEE_ECC_CURVE_SM2;
422 s->ops = &sm2_pke_keypair_ops;
423 break;
424 case TEE_TYPE_SM2_KEP_KEYPAIR:
425 if (!IS_ENABLED(CFG_CRYPTO_SM2_KEP))
426 return TEE_ERROR_NOT_IMPLEMENTED;
427
428 s->curve = TEE_ECC_CURVE_SM2;
429 s->ops = &sm2_kep_keypair_ops;
430 break;
431 default:
432 return TEE_ERROR_NOT_IMPLEMENTED;
433 }
434
435 s->d = crypto_bignum_allocate(key_size_bits);
436 if (!s->d)
437 goto err;
438 s->x = crypto_bignum_allocate(key_size_bits);
439 if (!s->x)
440 goto err;
441 s->y = crypto_bignum_allocate(key_size_bits);
442 if (!s->y)
443 goto err;
444
445 return TEE_SUCCESS;
446
447 err:
448 crypto_bignum_free(&s->d);
449 crypto_bignum_free(&s->x);
450
451 return TEE_ERROR_OUT_OF_MEMORY;
452 }
453
454 static const struct crypto_ecc_public_ops ecc_public_key_ops = {
455 .free = ecc_free_public_key,
456 .verify = ecc_verify,
457 };
458
459 static const struct crypto_ecc_public_ops sm2_pke_public_key_ops = {
460 .free = ecc_free_public_key,
461 .encrypt = sm2_mbedtls_pke_encrypt,
462 };
463
464 static const struct crypto_ecc_public_ops sm2_kep_public_key_ops = {
465 .free = ecc_free_public_key,
466 };
467
468 static const struct crypto_ecc_public_ops sm2_dsa_public_key_ops = {
469 .free = ecc_free_public_key,
470 .verify = sm2_mbedtls_dsa_verify,
471 };
472
473 const struct crypto_ecc_public_ops*
crypto_asym_get_ecc_public_ops(uint32_t key_type)474 crypto_asym_get_ecc_public_ops(uint32_t key_type)
475 {
476 switch (key_type) {
477 case TEE_TYPE_ECDSA_PUBLIC_KEY:
478 case TEE_TYPE_ECDH_PUBLIC_KEY:
479 return &ecc_public_key_ops;
480 case TEE_TYPE_SM2_DSA_PUBLIC_KEY:
481 if (!IS_ENABLED(CFG_CRYPTO_SM2_DSA))
482 return NULL;
483
484 return &sm2_dsa_public_key_ops;
485 case TEE_TYPE_SM2_PKE_PUBLIC_KEY:
486 if (!IS_ENABLED(CFG_CRYPTO_SM2_PKE))
487 return NULL;
488
489 return &sm2_pke_public_key_ops;
490 case TEE_TYPE_SM2_KEP_PUBLIC_KEY:
491 if (!IS_ENABLED(CFG_CRYPTO_SM2_KEP))
492 return NULL;
493 return &sm2_kep_public_key_ops;
494 default:
495 return NULL;
496 }
497 }
498
crypto_asym_alloc_ecc_public_key(struct ecc_public_key * s,uint32_t key_type,size_t key_size_bits)499 TEE_Result crypto_asym_alloc_ecc_public_key(struct ecc_public_key *s,
500 uint32_t key_type,
501 size_t key_size_bits)
502 {
503 memset(s, 0, sizeof(*s));
504
505 switch (key_type) {
506 case TEE_TYPE_ECDSA_PUBLIC_KEY:
507 case TEE_TYPE_ECDH_PUBLIC_KEY:
508 s->ops = &ecc_public_key_ops;
509 break;
510 case TEE_TYPE_SM2_DSA_PUBLIC_KEY:
511 if (!IS_ENABLED(CFG_CRYPTO_SM2_DSA))
512 return TEE_ERROR_NOT_IMPLEMENTED;
513
514 s->curve = TEE_ECC_CURVE_SM2;
515 s->ops = &sm2_dsa_public_key_ops;
516 break;
517 case TEE_TYPE_SM2_PKE_PUBLIC_KEY:
518 if (!IS_ENABLED(CFG_CRYPTO_SM2_PKE))
519 return TEE_ERROR_NOT_IMPLEMENTED;
520
521 s->curve = TEE_ECC_CURVE_SM2;
522 s->ops = &sm2_pke_public_key_ops;
523 break;
524 case TEE_TYPE_SM2_KEP_PUBLIC_KEY:
525 if (!IS_ENABLED(CFG_CRYPTO_SM2_KEP))
526 return TEE_ERROR_NOT_IMPLEMENTED;
527
528 s->curve = TEE_ECC_CURVE_SM2;
529 s->ops = &sm2_kep_public_key_ops;
530 break;
531 default:
532 return TEE_ERROR_NOT_IMPLEMENTED;
533 }
534
535 s->x = crypto_bignum_allocate(key_size_bits);
536 if (!s->x)
537 goto err;
538 s->y = crypto_bignum_allocate(key_size_bits);
539 if (!s->y)
540 goto err;
541
542 return TEE_SUCCESS;
543
544 err:
545 crypto_bignum_free(&s->x);
546
547 return TEE_ERROR_OUT_OF_MEMORY;
548 }
549