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