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