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