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 <compiler.h> 9 #include <crypto/crypto.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 "mbd_rand.h" 20 21 /* Translate mbedtls result to TEE result */ 22 static TEE_Result get_tee_result(int lmd_res) 23 { 24 switch (lmd_res) { 25 case 0: 26 return TEE_SUCCESS; 27 case MBEDTLS_ERR_ECP_VERIFY_FAILED: 28 return TEE_ERROR_SIGNATURE_INVALID; 29 case MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL: 30 return TEE_ERROR_SHORT_BUFFER; 31 default: 32 return TEE_ERROR_BAD_STATE; 33 } 34 } 35 36 TEE_Result crypto_acipher_alloc_ecc_keypair(struct ecc_keypair *s, 37 size_t key_size_bits) 38 { 39 memset(s, 0, sizeof(*s)); 40 s->d = crypto_bignum_allocate(key_size_bits); 41 if (!s->d) 42 goto err; 43 s->x = crypto_bignum_allocate(key_size_bits); 44 if (!s->x) 45 goto err; 46 s->y = crypto_bignum_allocate(key_size_bits); 47 if (!s->y) 48 goto err; 49 return TEE_SUCCESS; 50 err: 51 crypto_bignum_free(s->d); 52 crypto_bignum_free(s->x); 53 return TEE_ERROR_OUT_OF_MEMORY; 54 } 55 56 TEE_Result crypto_acipher_alloc_ecc_public_key(struct ecc_public_key *s, 57 size_t key_size_bits) 58 { 59 memset(s, 0, sizeof(*s)); 60 s->x = crypto_bignum_allocate(key_size_bits); 61 if (!s->x) 62 goto err; 63 s->y = crypto_bignum_allocate(key_size_bits); 64 if (!s->y) 65 goto err; 66 return TEE_SUCCESS; 67 err: 68 crypto_bignum_free(s->x); 69 return TEE_ERROR_OUT_OF_MEMORY; 70 } 71 72 void crypto_acipher_free_ecc_public_key(struct ecc_public_key *s) 73 { 74 if (!s) 75 return; 76 77 crypto_bignum_free(s->x); 78 crypto_bignum_free(s->y); 79 } 80 81 /* 82 * curve is part of TEE_ECC_CURVE_NIST_P192,... 83 * algo is part of TEE_ALG_ECDSA_P192,..., and 0 if we do not have it 84 */ 85 static TEE_Result ecc_get_keysize(uint32_t curve, uint32_t algo, 86 size_t *key_size_bytes, size_t *key_size_bits) 87 { 88 /* 89 * Note GPv1.1 indicates TEE_ALG_ECDH_NIST_P192_DERIVE_SHARED_SECRET 90 * but defines TEE_ALG_ECDH_P192 91 */ 92 switch (curve) { 93 case TEE_ECC_CURVE_NIST_P192: 94 *key_size_bits = 192; 95 *key_size_bytes = 24; 96 if ((algo != 0) && (algo != TEE_ALG_ECDSA_P192) && 97 (algo != TEE_ALG_ECDH_P192)) 98 return TEE_ERROR_BAD_PARAMETERS; 99 break; 100 case TEE_ECC_CURVE_NIST_P224: 101 *key_size_bits = 224; 102 *key_size_bytes = 28; 103 if ((algo != 0) && (algo != TEE_ALG_ECDSA_P224) && 104 (algo != TEE_ALG_ECDH_P224)) 105 return TEE_ERROR_BAD_PARAMETERS; 106 break; 107 case TEE_ECC_CURVE_NIST_P256: 108 *key_size_bits = 256; 109 *key_size_bytes = 32; 110 if ((algo != 0) && (algo != TEE_ALG_ECDSA_P256) && 111 (algo != TEE_ALG_ECDH_P256)) 112 return TEE_ERROR_BAD_PARAMETERS; 113 break; 114 case TEE_ECC_CURVE_NIST_P384: 115 *key_size_bits = 384; 116 *key_size_bytes = 48; 117 if ((algo != 0) && (algo != TEE_ALG_ECDSA_P384) && 118 (algo != TEE_ALG_ECDH_P384)) 119 return TEE_ERROR_BAD_PARAMETERS; 120 break; 121 case TEE_ECC_CURVE_NIST_P521: 122 *key_size_bits = 521; 123 *key_size_bytes = 66; 124 if ((algo != 0) && (algo != TEE_ALG_ECDSA_P521) && 125 (algo != TEE_ALG_ECDH_P521)) 126 return TEE_ERROR_BAD_PARAMETERS; 127 break; 128 default: 129 *key_size_bits = 0; 130 *key_size_bytes = 0; 131 return TEE_ERROR_NOT_SUPPORTED; 132 } 133 134 return TEE_SUCCESS; 135 } 136 137 /* 138 * Clear some memory that was used to prepare the context 139 */ 140 static void ecc_clear_precomputed(mbedtls_ecp_group *grp) 141 { 142 size_t i = 0; 143 144 if (grp->T) { 145 for (i = 0; i < grp->T_size; i++) 146 mbedtls_ecp_point_free(&grp->T[i]); 147 free(grp->T); 148 } 149 grp->T = NULL; 150 grp->T_size = 0; 151 } 152 153 TEE_Result crypto_acipher_gen_ecc_key(struct ecc_keypair *key, size_t key_size) 154 { 155 TEE_Result res = TEE_SUCCESS; 156 int lmd_res = 0; 157 mbedtls_ecdsa_context ecdsa; 158 size_t key_size_bytes = 0; 159 size_t key_size_bits = 0; 160 161 memset(&ecdsa, 0, sizeof(ecdsa)); 162 163 res = ecc_get_keysize(key->curve, 0, &key_size_bytes, &key_size_bits); 164 if (res != TEE_SUCCESS) 165 return res; 166 167 if (key_size != key_size_bits) 168 return TEE_ERROR_BAD_PARAMETERS; 169 170 mbedtls_ecdsa_init(&ecdsa); 171 172 /* Generate the ECC key */ 173 lmd_res = mbedtls_ecdsa_genkey(&ecdsa, key->curve, mbd_rand, NULL); 174 if (lmd_res != 0) { 175 res = TEE_ERROR_BAD_PARAMETERS; 176 FMSG("mbedtls_ecdsa_genkey failed."); 177 goto exit; 178 } 179 ecc_clear_precomputed(&ecdsa.grp); 180 181 /* check the size of the keys */ 182 if ((mbedtls_mpi_bitlen(&ecdsa.Q.X) > key_size_bits) || 183 (mbedtls_mpi_bitlen(&ecdsa.Q.Y) > key_size_bits) || 184 (mbedtls_mpi_bitlen(&ecdsa.d) > key_size_bits)) { 185 res = TEE_ERROR_BAD_PARAMETERS; 186 FMSG("Check the size of the keys failed."); 187 goto exit; 188 } 189 190 /* check LMD is returning z==1 */ 191 if (mbedtls_mpi_bitlen(&ecdsa.Q.Z) != 1) { 192 res = TEE_ERROR_BAD_PARAMETERS; 193 FMSG("Check LMD failed."); 194 goto exit; 195 } 196 197 /* Copy the key */ 198 crypto_bignum_copy(key->d, (void *)&ecdsa.d); 199 crypto_bignum_copy(key->x, (void *)&ecdsa.Q.X); 200 crypto_bignum_copy(key->y, (void *)&ecdsa.Q.Y); 201 202 res = TEE_SUCCESS; 203 exit: 204 mbedtls_ecdsa_free(&ecdsa); /* Free the temporary key */ 205 return res; 206 } 207 208 TEE_Result crypto_acipher_ecc_sign(uint32_t algo, struct ecc_keypair *key, 209 const uint8_t *msg, size_t msg_len, 210 uint8_t *sig, size_t *sig_len) 211 { 212 TEE_Result res = TEE_SUCCESS; 213 int lmd_res = 0; 214 const mbedtls_pk_info_t *pk_info = NULL; 215 mbedtls_ecdsa_context ecdsa; 216 size_t key_size_bytes = 0; 217 size_t key_size_bits = 0; 218 mbedtls_mpi r; 219 mbedtls_mpi s; 220 221 memset(&ecdsa, 0, sizeof(ecdsa)); 222 memset(&r, 0, sizeof(r)); 223 memset(&s, 0, sizeof(s)); 224 225 if (algo == 0) 226 return TEE_ERROR_BAD_PARAMETERS; 227 228 mbedtls_mpi_init(&r); 229 mbedtls_mpi_init(&s); 230 231 mbedtls_ecdsa_init(&ecdsa); 232 lmd_res = mbedtls_ecp_group_load(&ecdsa.grp, key->curve); 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 TEE_Result crypto_acipher_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 size_t key_size_bytes, key_size_bits = 0; 285 uint8_t one[1] = { 1 }; 286 mbedtls_mpi r; 287 mbedtls_mpi s; 288 289 memset(&ecdsa, 0, sizeof(ecdsa)); 290 memset(&r, 0, sizeof(r)); 291 memset(&s, 0, sizeof(s)); 292 293 if (algo == 0) 294 return TEE_ERROR_BAD_PARAMETERS; 295 296 mbedtls_mpi_init(&r); 297 mbedtls_mpi_init(&s); 298 299 mbedtls_ecdsa_init(&ecdsa); 300 301 lmd_res = mbedtls_ecp_group_load(&ecdsa.grp, key->curve); 302 if (lmd_res != 0) { 303 res = TEE_ERROR_NOT_SUPPORTED; 304 goto out; 305 } 306 307 ecdsa.Q.X = *(mbedtls_mpi *)key->x; 308 ecdsa.Q.Y = *(mbedtls_mpi *)key->y; 309 mbedtls_mpi_read_binary(&ecdsa.Q.Z, one, sizeof(one)); 310 311 res = ecc_get_keysize(key->curve, algo, 312 &key_size_bytes, &key_size_bits); 313 if (res != TEE_SUCCESS) { 314 res = TEE_ERROR_BAD_PARAMETERS; 315 goto out; 316 } 317 318 /* check keysize vs sig_len */ 319 if ((key_size_bytes * 2) != sig_len) { 320 res = TEE_ERROR_BAD_PARAMETERS; 321 goto out; 322 } 323 324 mbedtls_mpi_read_binary(&r, sig, sig_len / 2); 325 mbedtls_mpi_read_binary(&s, sig + sig_len / 2, sig_len / 2); 326 327 lmd_res = mbedtls_ecdsa_verify(&ecdsa.grp, msg, msg_len, &ecdsa.Q, 328 &r, &s); 329 if (lmd_res != 0) { 330 FMSG("mbedtls_ecdsa_verify failed, returned 0x%x", -lmd_res); 331 res = get_tee_result(lmd_res); 332 } 333 out: 334 mbedtls_mpi_free(&r); 335 mbedtls_mpi_free(&s); 336 /* Reset mpi to skip freeing here, those mpis will be freed with key */ 337 mbedtls_mpi_init(&ecdsa.Q.X); 338 mbedtls_mpi_init(&ecdsa.Q.Y); 339 mbedtls_ecdsa_free(&ecdsa); 340 return res; 341 } 342 343 TEE_Result crypto_acipher_ecc_shared_secret(struct ecc_keypair *private_key, 344 struct ecc_public_key *public_key, 345 void *secret, 346 unsigned long *secret_len) 347 { 348 TEE_Result res = TEE_SUCCESS; 349 int lmd_res = 0; 350 uint8_t one[1] = { 1 }; 351 mbedtls_ecdh_context ecdh; 352 size_t out_len = 0; 353 354 memset(&ecdh, 0, sizeof(ecdh)); 355 mbedtls_ecdh_init(&ecdh); 356 lmd_res = mbedtls_ecp_group_load(&ecdh.grp, private_key->curve); 357 if (lmd_res != 0) { 358 res = TEE_ERROR_NOT_SUPPORTED; 359 goto out; 360 } 361 362 ecdh.d = *(mbedtls_mpi *)private_key->d; 363 ecdh.Qp.X = *(mbedtls_mpi *)public_key->x; 364 ecdh.Qp.Y = *(mbedtls_mpi *)public_key->y; 365 mbedtls_mpi_read_binary(&ecdh.Qp.Z, one, sizeof(one)); 366 367 lmd_res = mbedtls_ecdh_calc_secret(&ecdh, &out_len, secret, 368 *secret_len, mbd_rand, NULL); 369 if (lmd_res != 0) { 370 res = get_tee_result(lmd_res); 371 goto out; 372 } 373 *secret_len = out_len; 374 out: 375 /* Reset mpi to skip freeing here, those mpis will be freed with key */ 376 mbedtls_mpi_init(&ecdh.d); 377 mbedtls_mpi_init(&ecdh.Qp.X); 378 mbedtls_mpi_init(&ecdh.Qp.Y); 379 mbedtls_ecdh_free(&ecdh); 380 return res; 381 } 382