1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2014-2019, Linaro Limited 4 */ 5 6 #include <crypto/crypto_impl.h> 7 #include <stdlib.h> 8 #include <string.h> 9 #include <tee_api_types.h> 10 #include <trace.h> 11 #include <utee_defines.h> 12 13 #include "acipher_helpers.h" 14 15 static void _ltc_ecc_free_public_key(struct ecc_public_key *s) 16 { 17 if (!s) 18 return; 19 20 crypto_bignum_free(s->x); 21 crypto_bignum_free(s->y); 22 } 23 24 /* 25 * For a given TEE @curve, return key size and LTC curve name. Also check that 26 * @algo is compatible with this curve. 27 * @curve: TEE_ECC_CURVE_NIST_P192, ... 28 * @algo: TEE_ALG_ECDSA_P192, ... 29 */ 30 static TEE_Result ecc_get_curve_info(uint32_t curve, uint32_t algo, 31 size_t *key_size_bytes, 32 size_t *key_size_bits, 33 const char **curve_name) 34 { 35 size_t size_bytes = 0; 36 size_t size_bits = 0; 37 const char *name = NULL; 38 39 /* 40 * Excerpt of libtomcrypt documentation: 41 * ecc_make_key(... key_size ...): The keysize is the size of the 42 * modulus in bytes desired. Currently directly supported values 43 * are 12, 16, 20, 24, 28, 32, 48, and 65 bytes which correspond 44 * to key sizes of 112, 128, 160, 192, 224, 256, 384, and 521 bits 45 * respectively. 46 */ 47 48 /* 49 * Note GPv1.1 indicates TEE_ALG_ECDH_NIST_P192_DERIVE_SHARED_SECRET 50 * but defines TEE_ALG_ECDH_P192 51 */ 52 53 switch (curve) { 54 case TEE_ECC_CURVE_NIST_P192: 55 size_bits = 192; 56 size_bytes = 24; 57 name = "NISTP192"; 58 if ((algo != 0) && (algo != TEE_ALG_ECDSA_P192) && 59 (algo != TEE_ALG_ECDH_P192)) 60 return TEE_ERROR_BAD_PARAMETERS; 61 break; 62 case TEE_ECC_CURVE_NIST_P224: 63 size_bits = 224; 64 size_bytes = 28; 65 name = "NISTP224"; 66 if ((algo != 0) && (algo != TEE_ALG_ECDSA_P224) && 67 (algo != TEE_ALG_ECDH_P224)) 68 return TEE_ERROR_BAD_PARAMETERS; 69 break; 70 case TEE_ECC_CURVE_NIST_P256: 71 size_bits = 256; 72 size_bytes = 32; 73 name = "NISTP256"; 74 if ((algo != 0) && (algo != TEE_ALG_ECDSA_P256) && 75 (algo != TEE_ALG_ECDH_P256)) 76 return TEE_ERROR_BAD_PARAMETERS; 77 break; 78 case TEE_ECC_CURVE_NIST_P384: 79 size_bits = 384; 80 size_bytes = 48; 81 name = "NISTP384"; 82 if ((algo != 0) && (algo != TEE_ALG_ECDSA_P384) && 83 (algo != TEE_ALG_ECDH_P384)) 84 return TEE_ERROR_BAD_PARAMETERS; 85 break; 86 case TEE_ECC_CURVE_NIST_P521: 87 size_bits = 521; 88 size_bytes = 66; 89 name = "NISTP521"; 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 size_bits = 256; 96 size_bytes = 32; 97 name = "SM2"; 98 if ((algo != 0) && (algo != TEE_ALG_SM2_PKE) && 99 (algo != TEE_ALG_SM2_DSA_SM3) && 100 (algo != TEE_ALG_SM2_KEP)) 101 return TEE_ERROR_BAD_PARAMETERS; 102 break; 103 default: 104 return TEE_ERROR_NOT_SUPPORTED; 105 } 106 107 if (key_size_bytes) 108 *key_size_bytes = size_bytes; 109 if (key_size_bits) 110 *key_size_bits = size_bits; 111 if (curve_name) 112 *curve_name = name; 113 return TEE_SUCCESS; 114 } 115 116 static TEE_Result _ltc_ecc_generate_keypair(struct ecc_keypair *key, 117 size_t key_size) 118 { 119 TEE_Result res; 120 ecc_key ltc_tmp_key; 121 int ltc_res; 122 size_t key_size_bytes = 0; 123 size_t key_size_bits = 0; 124 125 res = ecc_get_curve_info(key->curve, 0, &key_size_bytes, &key_size_bits, 126 NULL); 127 if (res != TEE_SUCCESS) 128 return res; 129 130 if (key_size != key_size_bits) 131 return TEE_ERROR_BAD_PARAMETERS; 132 133 /* Generate the ECC key */ 134 ltc_res = ecc_make_key(NULL, find_prng("prng_crypto"), 135 key_size_bytes, <c_tmp_key); 136 if (ltc_res != CRYPT_OK) 137 return TEE_ERROR_BAD_PARAMETERS; 138 139 /* check the size of the keys */ 140 if (((size_t)mp_count_bits(ltc_tmp_key.pubkey.x) > key_size_bits) || 141 ((size_t)mp_count_bits(ltc_tmp_key.pubkey.y) > key_size_bits) || 142 ((size_t)mp_count_bits(ltc_tmp_key.k) > key_size_bits)) { 143 res = TEE_ERROR_BAD_PARAMETERS; 144 goto exit; 145 } 146 147 /* check LTC is returning z==1 */ 148 if (mp_count_bits(ltc_tmp_key.pubkey.z) != 1) { 149 res = TEE_ERROR_BAD_PARAMETERS; 150 goto exit; 151 } 152 153 /* Copy the key */ 154 ltc_mp.copy(ltc_tmp_key.k, key->d); 155 ltc_mp.copy(ltc_tmp_key.pubkey.x, key->x); 156 ltc_mp.copy(ltc_tmp_key.pubkey.y, key->y); 157 158 res = TEE_SUCCESS; 159 160 exit: 161 ecc_free(<c_tmp_key); /* Free the temporary key */ 162 return res; 163 } 164 165 /* Note: this function clears the key before setting the curve */ 166 static TEE_Result ecc_set_curve_from_name(ecc_key *ltc_key, 167 const char *curve_name) 168 { 169 const ltc_ecc_curve *curve = NULL; 170 int ltc_res = 0; 171 172 ltc_res = ecc_find_curve(curve_name, &curve); 173 if (ltc_res != CRYPT_OK) 174 return TEE_ERROR_NOT_SUPPORTED; 175 176 ltc_res = ecc_set_curve(curve, ltc_key); 177 if (ltc_res != CRYPT_OK) 178 return TEE_ERROR_GENERIC; 179 180 return TEE_SUCCESS; 181 } 182 183 /* 184 * Given a keypair "key", populate the Libtomcrypt private key "ltc_key" 185 * It also returns the key size, in bytes 186 */ 187 TEE_Result ecc_populate_ltc_private_key(ecc_key *ltc_key, 188 struct ecc_keypair *key, 189 uint32_t algo, size_t *key_size_bytes) 190 { 191 TEE_Result res = TEE_ERROR_GENERIC; 192 const char *name = NULL; 193 194 res = ecc_get_curve_info(key->curve, algo, key_size_bytes, NULL, &name); 195 if (res) 196 return res; 197 198 memset(ltc_key, 0, sizeof(*ltc_key)); 199 200 res = ecc_set_curve_from_name(ltc_key, name); 201 if (res) 202 return res; 203 204 ltc_key->type = PK_PRIVATE; 205 mp_copy(key->d, ltc_key->k); 206 mp_copy(key->x, ltc_key->pubkey.x); 207 mp_copy(key->y, ltc_key->pubkey.y); 208 mp_set_int(ltc_key->pubkey.z, 1); 209 210 return TEE_SUCCESS; 211 } 212 213 /* 214 * Given a public "key", populate the Libtomcrypt public key "ltc_key" 215 * It also returns the key size, in bytes 216 */ 217 TEE_Result ecc_populate_ltc_public_key(ecc_key *ltc_key, 218 struct ecc_public_key *key, 219 uint32_t algo, size_t *key_size_bytes) 220 { 221 TEE_Result res = TEE_ERROR_GENERIC; 222 const char *name = NULL; 223 uint8_t one[1] = { 1 }; 224 225 res = ecc_get_curve_info(key->curve, algo, key_size_bytes, NULL, &name); 226 if (res) 227 return res; 228 229 memset(ltc_key, 0, sizeof(*ltc_key)); 230 231 res = ecc_set_curve_from_name(ltc_key, name); 232 if (res) 233 return res; 234 235 ltc_key->type = PK_PUBLIC; 236 237 mp_copy(key->x, ltc_key->pubkey.x); 238 mp_copy(key->y, ltc_key->pubkey.y); 239 mp_read_unsigned_bin(ltc_key->pubkey.z, one, sizeof(one)); 240 241 return TEE_SUCCESS; 242 } 243 244 static TEE_Result _ltc_ecc_sign(uint32_t algo, struct ecc_keypair *key, 245 const uint8_t *msg, size_t msg_len, 246 uint8_t *sig, size_t *sig_len) 247 { 248 TEE_Result res = TEE_ERROR_GENERIC; 249 int ltc_res = 0; 250 size_t key_size_bytes = 0; 251 ecc_key ltc_key = { }; 252 unsigned long ltc_sig_len = 0; 253 254 if (algo == 0) 255 return TEE_ERROR_BAD_PARAMETERS; 256 257 res = ecc_populate_ltc_private_key(<c_key, key, algo, 258 &key_size_bytes); 259 if (res != TEE_SUCCESS) 260 return res; 261 262 if (*sig_len < 2 * key_size_bytes) { 263 *sig_len = 2 * key_size_bytes; 264 res = TEE_ERROR_SHORT_BUFFER; 265 goto out; 266 } 267 268 ltc_sig_len = *sig_len; 269 ltc_res = ecc_sign_hash_rfc7518(msg, msg_len, sig, <c_sig_len, 270 NULL, find_prng("prng_crypto"), <c_key); 271 if (ltc_res == CRYPT_OK) { 272 res = TEE_SUCCESS; 273 } else { 274 res = TEE_ERROR_GENERIC; 275 } 276 *sig_len = ltc_sig_len; 277 278 out: 279 ecc_free(<c_key); 280 return res; 281 } 282 283 static TEE_Result _ltc_ecc_verify(uint32_t algo, struct ecc_public_key *key, 284 const uint8_t *msg, size_t msg_len, 285 const uint8_t *sig, size_t sig_len) 286 { 287 TEE_Result res = TEE_ERROR_GENERIC; 288 int ltc_stat = 0; 289 int ltc_res = 0; 290 size_t key_size_bytes = 0; 291 ecc_key ltc_key = { }; 292 293 if (algo == 0) 294 return TEE_ERROR_BAD_PARAMETERS; 295 296 res = ecc_populate_ltc_public_key(<c_key, key, algo, &key_size_bytes); 297 if (res != TEE_SUCCESS) 298 goto out; 299 300 /* check keysize vs sig_len */ 301 if ((key_size_bytes * 2) != sig_len) { 302 res = TEE_ERROR_BAD_PARAMETERS; 303 goto out; 304 } 305 306 ltc_res = ecc_verify_hash_rfc7518(sig, sig_len, msg, msg_len, <c_stat, 307 <c_key); 308 res = convert_ltc_verify_status(ltc_res, ltc_stat); 309 out: 310 ecc_free(<c_key); 311 return res; 312 } 313 314 static TEE_Result _ltc_ecc_shared_secret(struct ecc_keypair *private_key, 315 struct ecc_public_key *public_key, 316 void *secret, 317 unsigned long *secret_len) 318 { 319 TEE_Result res = TEE_ERROR_GENERIC; 320 int ltc_res = 0; 321 ecc_key ltc_private_key = { }; 322 ecc_key ltc_public_key = { }; 323 size_t key_size_bytes = 0; 324 325 /* Check the curves are the same */ 326 if (private_key->curve != public_key->curve) 327 return TEE_ERROR_BAD_PARAMETERS; 328 329 res = ecc_populate_ltc_private_key(<c_private_key, private_key, 330 0, &key_size_bytes); 331 if (res != TEE_SUCCESS) 332 goto out; 333 res = ecc_populate_ltc_public_key(<c_public_key, public_key, 334 0, &key_size_bytes); 335 if (res != TEE_SUCCESS) 336 goto out; 337 338 ltc_res = ecc_shared_secret(<c_private_key, <c_public_key, 339 secret, secret_len); 340 if (ltc_res == CRYPT_OK) 341 res = TEE_SUCCESS; 342 else 343 res = TEE_ERROR_BAD_PARAMETERS; 344 345 out: 346 ecc_free(<c_private_key); 347 ecc_free(<c_public_key); 348 return res; 349 } 350 351 static const struct crypto_ecc_keypair_ops ecc_keypair_ops = { 352 .generate = &_ltc_ecc_generate_keypair, 353 .sign = &_ltc_ecc_sign, 354 .shared_secret = &_ltc_ecc_shared_secret, 355 }; 356 357 static const struct crypto_ecc_public_ops ecc_public_key_ops = { 358 .free = &_ltc_ecc_free_public_key, 359 .verify = &_ltc_ecc_verify, 360 }; 361 362 TEE_Result crypto_asym_alloc_ecc_keypair(struct ecc_keypair *s, 363 uint32_t key_type __unused, 364 size_t key_size_bits __unused) 365 { 366 memset(s, 0, sizeof(*s)); 367 if (!bn_alloc_max(&s->d)) 368 goto err; 369 if (!bn_alloc_max(&s->x)) 370 goto err; 371 if (!bn_alloc_max(&s->y)) 372 goto err; 373 374 s->ops = &ecc_keypair_ops; 375 376 return TEE_SUCCESS; 377 err: 378 crypto_bignum_free(s->d); 379 crypto_bignum_free(s->x); 380 crypto_bignum_free(s->y); 381 return TEE_ERROR_OUT_OF_MEMORY; 382 } 383 384 TEE_Result crypto_asym_alloc_ecc_public_key(struct ecc_public_key *s, 385 uint32_t key_type __unused, 386 size_t key_size_bits __unused) 387 { 388 memset(s, 0, sizeof(*s)); 389 if (!bn_alloc_max(&s->x)) 390 goto err; 391 if (!bn_alloc_max(&s->y)) 392 goto err; 393 394 s->ops = &ecc_public_key_ops; 395 396 return TEE_SUCCESS; 397 err: 398 crypto_bignum_free(s->x); 399 crypto_bignum_free(s->y); 400 return TEE_ERROR_OUT_OF_MEMORY; 401 } 402