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.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 * curve is part of TEE_ECC_CURVE_NIST_P192,... 60 * algo is part of TEE_ALG_ECDSA_P192,..., and 0 if we do not have it 61 */ 62 static TEE_Result ecc_get_keysize(uint32_t curve, uint32_t algo, 63 size_t *key_size_bytes, size_t *key_size_bits) 64 { 65 /* 66 * Excerpt of libtomcrypt documentation: 67 * ecc_make_key(... key_size ...): The keysize is the size of the 68 * modulus in bytes desired. Currently directly supported values 69 * are 12, 16, 20, 24, 28, 32, 48, and 65 bytes which correspond 70 * to key sizes of 112, 128, 160, 192, 224, 256, 384, and 521 bits 71 * respectively. 72 */ 73 74 /* 75 * Note GPv1.1 indicates TEE_ALG_ECDH_NIST_P192_DERIVE_SHARED_SECRET 76 * but defines TEE_ALG_ECDH_P192 77 */ 78 79 switch (curve) { 80 case TEE_ECC_CURVE_NIST_P192: 81 *key_size_bits = 192; 82 *key_size_bytes = 24; 83 if ((algo != 0) && (algo != TEE_ALG_ECDSA_P192) && 84 (algo != TEE_ALG_ECDH_P192)) 85 return TEE_ERROR_BAD_PARAMETERS; 86 break; 87 case TEE_ECC_CURVE_NIST_P224: 88 *key_size_bits = 224; 89 *key_size_bytes = 28; 90 if ((algo != 0) && (algo != TEE_ALG_ECDSA_P224) && 91 (algo != TEE_ALG_ECDH_P224)) 92 return TEE_ERROR_BAD_PARAMETERS; 93 break; 94 case TEE_ECC_CURVE_NIST_P256: 95 *key_size_bits = 256; 96 *key_size_bytes = 32; 97 if ((algo != 0) && (algo != TEE_ALG_ECDSA_P256) && 98 (algo != TEE_ALG_ECDH_P256)) 99 return TEE_ERROR_BAD_PARAMETERS; 100 break; 101 case TEE_ECC_CURVE_NIST_P384: 102 *key_size_bits = 384; 103 *key_size_bytes = 48; 104 if ((algo != 0) && (algo != TEE_ALG_ECDSA_P384) && 105 (algo != TEE_ALG_ECDH_P384)) 106 return TEE_ERROR_BAD_PARAMETERS; 107 break; 108 case TEE_ECC_CURVE_NIST_P521: 109 *key_size_bits = 521; 110 /* 111 * set 66 instead of 65 wrt to Libtomcrypt documentation as 112 * if it the real key size 113 */ 114 *key_size_bytes = 66; 115 if ((algo != 0) && (algo != TEE_ALG_ECDSA_P521) && 116 (algo != TEE_ALG_ECDH_P521)) 117 return TEE_ERROR_BAD_PARAMETERS; 118 break; 119 default: 120 *key_size_bits = 0; 121 *key_size_bytes = 0; 122 return TEE_ERROR_NOT_SUPPORTED; 123 } 124 125 return TEE_SUCCESS; 126 } 127 128 TEE_Result crypto_acipher_gen_ecc_key(struct ecc_keypair *key) 129 { 130 TEE_Result res; 131 ecc_key ltc_tmp_key; 132 int ltc_res; 133 size_t key_size_bytes = 0; 134 size_t key_size_bits = 0; 135 136 res = ecc_get_keysize(key->curve, 0, &key_size_bytes, &key_size_bits); 137 if (res != TEE_SUCCESS) 138 return res; 139 140 /* Generate the ECC key */ 141 ltc_res = ecc_make_key(NULL, find_prng("prng_crypto"), 142 key_size_bytes, <c_tmp_key); 143 if (ltc_res != CRYPT_OK) 144 return TEE_ERROR_BAD_PARAMETERS; 145 146 /* check the size of the keys */ 147 if (((size_t)mp_count_bits(ltc_tmp_key.pubkey.x) > key_size_bits) || 148 ((size_t)mp_count_bits(ltc_tmp_key.pubkey.y) > key_size_bits) || 149 ((size_t)mp_count_bits(ltc_tmp_key.k) > key_size_bits)) { 150 res = TEE_ERROR_BAD_PARAMETERS; 151 goto exit; 152 } 153 154 /* check LTC is returning z==1 */ 155 if (mp_count_bits(ltc_tmp_key.pubkey.z) != 1) { 156 res = TEE_ERROR_BAD_PARAMETERS; 157 goto exit; 158 } 159 160 /* Copy the key */ 161 ltc_mp.copy(ltc_tmp_key.k, key->d); 162 ltc_mp.copy(ltc_tmp_key.pubkey.x, key->x); 163 ltc_mp.copy(ltc_tmp_key.pubkey.y, key->y); 164 165 res = TEE_SUCCESS; 166 167 exit: 168 ecc_free(<c_tmp_key); /* Free the temporary key */ 169 return res; 170 } 171 172 static TEE_Result ecc_compute_key_idx(ecc_key *ltc_key, size_t keysize) 173 { 174 size_t x; 175 176 for (x = 0; ((int)keysize > ltc_ecc_sets[x].size) && 177 (ltc_ecc_sets[x].size != 0); 178 x++) 179 ; 180 keysize = (size_t)ltc_ecc_sets[x].size; 181 182 if ((keysize > ECC_MAXSIZE) || (ltc_ecc_sets[x].size == 0)) 183 return TEE_ERROR_BAD_PARAMETERS; 184 185 ltc_key->idx = -1; 186 ltc_key->dp = <c_ecc_sets[x]; 187 188 return TEE_SUCCESS; 189 } 190 191 /* 192 * Given a keypair "key", populate the Libtomcrypt private key "ltc_key" 193 * It also returns the key size, in bytes 194 */ 195 static TEE_Result ecc_populate_ltc_private_key(ecc_key *ltc_key, 196 struct ecc_keypair *key, 197 uint32_t algo, 198 size_t *key_size_bytes) 199 { 200 TEE_Result res; 201 size_t key_size_bits; 202 203 memset(ltc_key, 0, sizeof(*ltc_key)); 204 ltc_key->type = PK_PRIVATE; 205 ltc_key->k = key->d; 206 207 /* compute the index of the ecc curve */ 208 res = ecc_get_keysize(key->curve, algo, 209 key_size_bytes, &key_size_bits); 210 if (res != TEE_SUCCESS) 211 return res; 212 213 return ecc_compute_key_idx(ltc_key, *key_size_bytes); 214 } 215 216 /* 217 * Given a public "key", populate the Libtomcrypt public key "ltc_key" 218 * It also returns the key size, in bytes 219 */ 220 static TEE_Result ecc_populate_ltc_public_key(ecc_key *ltc_key, 221 struct ecc_public_key *key, 222 void *key_z, 223 uint32_t algo, 224 size_t *key_size_bytes) 225 { 226 TEE_Result res; 227 size_t key_size_bits; 228 uint8_t one[1] = { 1 }; 229 230 231 memset(ltc_key, 0, sizeof(*ltc_key)); 232 ltc_key->type = PK_PUBLIC; 233 ltc_key->pubkey.x = key->x; 234 ltc_key->pubkey.y = key->y; 235 ltc_key->pubkey.z = key_z; 236 mp_read_unsigned_bin(ltc_key->pubkey.z, one, sizeof(one)); 237 238 /* compute the index of the ecc curve */ 239 res = ecc_get_keysize(key->curve, algo, 240 key_size_bytes, &key_size_bits); 241 if (res != TEE_SUCCESS) 242 return res; 243 244 return ecc_compute_key_idx(ltc_key, *key_size_bytes); 245 } 246 247 TEE_Result crypto_acipher_ecc_sign(uint32_t algo, struct ecc_keypair *key, 248 const uint8_t *msg, size_t msg_len, 249 uint8_t *sig, size_t *sig_len) 250 { 251 TEE_Result res; 252 int ltc_res; 253 void *r, *s; 254 size_t key_size_bytes; 255 ecc_key ltc_key; 256 257 if (algo == 0) { 258 res = TEE_ERROR_BAD_PARAMETERS; 259 goto err; 260 } 261 262 res = ecc_populate_ltc_private_key(<c_key, key, algo, 263 &key_size_bytes); 264 if (res != TEE_SUCCESS) 265 goto err; 266 267 if (*sig_len < 2 * key_size_bytes) { 268 *sig_len = 2 * key_size_bytes; 269 res = TEE_ERROR_SHORT_BUFFER; 270 goto err; 271 } 272 273 ltc_res = mp_init_multi(&r, &s, NULL); 274 if (ltc_res != CRYPT_OK) { 275 res = TEE_ERROR_OUT_OF_MEMORY; 276 goto err; 277 } 278 279 ltc_res = ecc_sign_hash_raw(msg, msg_len, r, s, 280 NULL, find_prng("prng_crypto"), <c_key); 281 282 if (ltc_res == CRYPT_OK) { 283 *sig_len = 2 * key_size_bytes; 284 memset(sig, 0, *sig_len); 285 mp_to_unsigned_bin(r, (uint8_t *)sig + *sig_len/2 - 286 mp_unsigned_bin_size(r)); 287 mp_to_unsigned_bin(s, (uint8_t *)sig + *sig_len - 288 mp_unsigned_bin_size(s)); 289 res = TEE_SUCCESS; 290 } else { 291 res = TEE_ERROR_GENERIC; 292 } 293 294 mp_clear_multi(r, s, NULL); 295 296 err: 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; 305 int ltc_stat; 306 int ltc_res; 307 void *r; 308 void *s; 309 void *key_z; 310 size_t key_size_bytes; 311 ecc_key ltc_key; 312 313 if (algo == 0) 314 return TEE_ERROR_BAD_PARAMETERS; 315 316 ltc_res = mp_init_multi(&key_z, &r, &s, NULL); 317 if (ltc_res != CRYPT_OK) 318 return TEE_ERROR_OUT_OF_MEMORY; 319 320 res = ecc_populate_ltc_public_key(<c_key, key, key_z, algo, 321 &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 mp_read_unsigned_bin(r, (uint8_t *)sig, sig_len/2); 332 mp_read_unsigned_bin(s, (uint8_t *)sig + sig_len/2, sig_len/2); 333 334 ltc_res = ecc_verify_hash_raw(r, s, msg, msg_len, <c_stat, <c_key); 335 res = convert_ltc_verify_status(ltc_res, ltc_stat); 336 out: 337 mp_clear_multi(key_z, r, s, NULL); 338 return res; 339 } 340 341 TEE_Result crypto_acipher_ecc_shared_secret(struct ecc_keypair *private_key, 342 struct ecc_public_key *public_key, 343 void *secret, 344 unsigned long *secret_len) 345 { 346 TEE_Result res; 347 int ltc_res; 348 ecc_key ltc_private_key; 349 ecc_key ltc_public_key; 350 size_t key_size_bytes; 351 void *key_z; 352 353 /* Check the curves are the same */ 354 if (private_key->curve != public_key->curve) 355 return TEE_ERROR_BAD_PARAMETERS; 356 357 ltc_res = mp_init_multi(&key_z, NULL); 358 if (ltc_res != CRYPT_OK) 359 return TEE_ERROR_OUT_OF_MEMORY; 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, key_z, 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 mp_clear_multi(key_z, NULL); 379 return res; 380 } 381