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