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