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