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) 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 /* Generate the ECC key */ 163 ltc_res = ecc_make_key(NULL, find_prng("prng_crypto"), 164 key_size_bytes, <c_tmp_key); 165 if (ltc_res != CRYPT_OK) 166 return TEE_ERROR_BAD_PARAMETERS; 167 168 /* check the size of the keys */ 169 if (((size_t)mp_count_bits(ltc_tmp_key.pubkey.x) > key_size_bits) || 170 ((size_t)mp_count_bits(ltc_tmp_key.pubkey.y) > key_size_bits) || 171 ((size_t)mp_count_bits(ltc_tmp_key.k) > key_size_bits)) { 172 res = TEE_ERROR_BAD_PARAMETERS; 173 goto exit; 174 } 175 176 /* check LTC is returning z==1 */ 177 if (mp_count_bits(ltc_tmp_key.pubkey.z) != 1) { 178 res = TEE_ERROR_BAD_PARAMETERS; 179 goto exit; 180 } 181 182 /* Copy the key */ 183 ltc_mp.copy(ltc_tmp_key.k, key->d); 184 ltc_mp.copy(ltc_tmp_key.pubkey.x, key->x); 185 ltc_mp.copy(ltc_tmp_key.pubkey.y, key->y); 186 187 res = TEE_SUCCESS; 188 189 exit: 190 ecc_free(<c_tmp_key); /* Free the temporary key */ 191 return res; 192 } 193 194 /* Note: this function clears the key before setting the curve */ 195 static TEE_Result ecc_set_curve_from_name(ecc_key *ltc_key, 196 const char *curve_name) 197 { 198 const ltc_ecc_curve *curve = NULL; 199 int ltc_res = 0; 200 201 ltc_res = ecc_find_curve(curve_name, &curve); 202 if (ltc_res != CRYPT_OK) 203 return TEE_ERROR_NOT_SUPPORTED; 204 205 ltc_res = ecc_set_curve(curve, ltc_key); 206 if (ltc_res != CRYPT_OK) 207 return TEE_ERROR_GENERIC; 208 209 return TEE_SUCCESS; 210 } 211 212 /* 213 * Given a keypair "key", populate the Libtomcrypt private key "ltc_key" 214 * It also returns the key size, in bytes 215 */ 216 TEE_Result ecc_populate_ltc_private_key(ecc_key *ltc_key, 217 struct ecc_keypair *key, 218 uint32_t algo, size_t *key_size_bytes) 219 { 220 TEE_Result res = TEE_ERROR_GENERIC; 221 const char *name = NULL; 222 223 res = ecc_get_curve_info(key->curve, algo, key_size_bytes, NULL, &name); 224 if (res) 225 return res; 226 227 memset(ltc_key, 0, sizeof(*ltc_key)); 228 229 res = ecc_set_curve_from_name(ltc_key, name); 230 if (res) 231 return res; 232 233 ltc_key->type = PK_PRIVATE; 234 mp_copy(key->d, ltc_key->k); 235 mp_copy(key->x, ltc_key->pubkey.x); 236 mp_copy(key->y, ltc_key->pubkey.y); 237 mp_set_int(ltc_key->pubkey.z, 1); 238 239 return TEE_SUCCESS; 240 } 241 242 /* 243 * Given a public "key", populate the Libtomcrypt public key "ltc_key" 244 * It also returns the key size, in bytes 245 */ 246 TEE_Result ecc_populate_ltc_public_key(ecc_key *ltc_key, 247 struct ecc_public_key *key, 248 uint32_t algo, size_t *key_size_bytes) 249 { 250 TEE_Result res = TEE_ERROR_GENERIC; 251 const char *name = NULL; 252 uint8_t one[1] = { 1 }; 253 254 res = ecc_get_curve_info(key->curve, algo, key_size_bytes, NULL, &name); 255 if (res) 256 return res; 257 258 memset(ltc_key, 0, sizeof(*ltc_key)); 259 260 res = ecc_set_curve_from_name(ltc_key, name); 261 if (res) 262 return res; 263 264 ltc_key->type = PK_PUBLIC; 265 266 mp_copy(key->x, ltc_key->pubkey.x); 267 mp_copy(key->y, ltc_key->pubkey.y); 268 mp_read_unsigned_bin(ltc_key->pubkey.z, one, sizeof(one)); 269 270 return TEE_SUCCESS; 271 } 272 273 TEE_Result crypto_acipher_ecc_sign(uint32_t algo, struct ecc_keypair *key, 274 const uint8_t *msg, size_t msg_len, 275 uint8_t *sig, size_t *sig_len) 276 { 277 TEE_Result res = TEE_ERROR_GENERIC; 278 int ltc_res = 0; 279 size_t key_size_bytes = 0; 280 ecc_key ltc_key = { }; 281 unsigned long ltc_sig_len = 0; 282 283 if (algo == 0) 284 return TEE_ERROR_BAD_PARAMETERS; 285 286 res = ecc_populate_ltc_private_key(<c_key, key, algo, 287 &key_size_bytes); 288 if (res != TEE_SUCCESS) 289 return res; 290 291 if (*sig_len < 2 * key_size_bytes) { 292 *sig_len = 2 * key_size_bytes; 293 res = TEE_ERROR_SHORT_BUFFER; 294 goto out; 295 } 296 297 ltc_sig_len = *sig_len; 298 ltc_res = ecc_sign_hash_rfc7518(msg, msg_len, sig, <c_sig_len, 299 NULL, find_prng("prng_crypto"), <c_key); 300 if (ltc_res == CRYPT_OK) { 301 res = TEE_SUCCESS; 302 } else { 303 res = TEE_ERROR_GENERIC; 304 } 305 *sig_len = ltc_sig_len; 306 307 out: 308 ecc_free(<c_key); 309 return res; 310 } 311 312 TEE_Result crypto_acipher_ecc_verify(uint32_t algo, struct ecc_public_key *key, 313 const uint8_t *msg, size_t msg_len, 314 const uint8_t *sig, size_t sig_len) 315 { 316 TEE_Result res = TEE_ERROR_GENERIC; 317 int ltc_stat = 0; 318 int ltc_res = 0; 319 size_t key_size_bytes = 0; 320 ecc_key ltc_key = { }; 321 322 if (algo == 0) 323 return TEE_ERROR_BAD_PARAMETERS; 324 325 res = ecc_populate_ltc_public_key(<c_key, key, algo, &key_size_bytes); 326 if (res != TEE_SUCCESS) 327 goto out; 328 329 /* check keysize vs sig_len */ 330 if ((key_size_bytes * 2) != sig_len) { 331 res = TEE_ERROR_BAD_PARAMETERS; 332 goto out; 333 } 334 335 ltc_res = ecc_verify_hash_rfc7518(sig, sig_len, msg, msg_len, <c_stat, 336 <c_key); 337 res = convert_ltc_verify_status(ltc_res, ltc_stat); 338 out: 339 ecc_free(<c_key); 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_ERROR_GENERIC; 349 int ltc_res = 0; 350 ecc_key ltc_private_key = { }; 351 ecc_key ltc_public_key = { }; 352 size_t key_size_bytes = 0; 353 354 /* Check the curves are the same */ 355 if (private_key->curve != public_key->curve) 356 return TEE_ERROR_BAD_PARAMETERS; 357 358 res = ecc_populate_ltc_private_key(<c_private_key, private_key, 359 0, &key_size_bytes); 360 if (res != TEE_SUCCESS) 361 goto out; 362 res = ecc_populate_ltc_public_key(<c_public_key, public_key, 363 0, &key_size_bytes); 364 if (res != TEE_SUCCESS) 365 goto out; 366 367 ltc_res = ecc_shared_secret(<c_private_key, <c_public_key, 368 secret, secret_len); 369 if (ltc_res == CRYPT_OK) 370 res = TEE_SUCCESS; 371 else 372 res = TEE_ERROR_BAD_PARAMETERS; 373 374 out: 375 ecc_free(<c_private_key); 376 ecc_free(<c_public_key); 377 return res; 378 } 379