16644e2f0SJens Wiklander // SPDX-License-Identifier: BSD-2-Clause 26644e2f0SJens Wiklander /* 36644e2f0SJens Wiklander * Copyright (c) 2014-2019, Linaro Limited 46644e2f0SJens Wiklander */ 56644e2f0SJens Wiklander 6*b56ad90eSCedric Neveux #include <crypto/crypto_impl.h> 76644e2f0SJens Wiklander #include <stdlib.h> 86644e2f0SJens Wiklander #include <string.h> 96644e2f0SJens Wiklander #include <tee_api_types.h> 106644e2f0SJens Wiklander #include <trace.h> 116644e2f0SJens Wiklander #include <utee_defines.h> 126644e2f0SJens Wiklander 136644e2f0SJens Wiklander #include "acipher_helpers.h" 146644e2f0SJens Wiklander 15*b56ad90eSCedric Neveux static void _ltc_ecc_free_public_key(struct ecc_public_key *s) 166644e2f0SJens Wiklander { 176644e2f0SJens Wiklander if (!s) 186644e2f0SJens Wiklander return; 196644e2f0SJens Wiklander 206644e2f0SJens Wiklander crypto_bignum_free(s->x); 216644e2f0SJens Wiklander crypto_bignum_free(s->y); 226644e2f0SJens Wiklander } 236644e2f0SJens Wiklander 246644e2f0SJens Wiklander /* 255a913ee7SJerome Forissier * For a given TEE @curve, return key size and LTC curve name. Also check that 265a913ee7SJerome Forissier * @algo is compatible with this curve. 275a913ee7SJerome Forissier * @curve: TEE_ECC_CURVE_NIST_P192, ... 285a913ee7SJerome Forissier * @algo: TEE_ALG_ECDSA_P192, ... 296644e2f0SJens Wiklander */ 305a913ee7SJerome Forissier static TEE_Result ecc_get_curve_info(uint32_t curve, uint32_t algo, 315a913ee7SJerome Forissier size_t *key_size_bytes, 325a913ee7SJerome Forissier size_t *key_size_bits, 335a913ee7SJerome Forissier const char **curve_name) 346644e2f0SJens Wiklander { 355a913ee7SJerome Forissier size_t size_bytes = 0; 365a913ee7SJerome Forissier size_t size_bits = 0; 375a913ee7SJerome Forissier const char *name = NULL; 385a913ee7SJerome Forissier 396644e2f0SJens Wiklander /* 406644e2f0SJens Wiklander * Excerpt of libtomcrypt documentation: 416644e2f0SJens Wiklander * ecc_make_key(... key_size ...): The keysize is the size of the 426644e2f0SJens Wiklander * modulus in bytes desired. Currently directly supported values 436644e2f0SJens Wiklander * are 12, 16, 20, 24, 28, 32, 48, and 65 bytes which correspond 446644e2f0SJens Wiklander * to key sizes of 112, 128, 160, 192, 224, 256, 384, and 521 bits 456644e2f0SJens Wiklander * respectively. 466644e2f0SJens Wiklander */ 476644e2f0SJens Wiklander 486644e2f0SJens Wiklander /* 496644e2f0SJens Wiklander * Note GPv1.1 indicates TEE_ALG_ECDH_NIST_P192_DERIVE_SHARED_SECRET 506644e2f0SJens Wiklander * but defines TEE_ALG_ECDH_P192 516644e2f0SJens Wiklander */ 526644e2f0SJens Wiklander 536644e2f0SJens Wiklander switch (curve) { 546644e2f0SJens Wiklander case TEE_ECC_CURVE_NIST_P192: 555a913ee7SJerome Forissier size_bits = 192; 565a913ee7SJerome Forissier size_bytes = 24; 575a913ee7SJerome Forissier name = "NISTP192"; 586644e2f0SJens Wiklander if ((algo != 0) && (algo != TEE_ALG_ECDSA_P192) && 596644e2f0SJens Wiklander (algo != TEE_ALG_ECDH_P192)) 606644e2f0SJens Wiklander return TEE_ERROR_BAD_PARAMETERS; 616644e2f0SJens Wiklander break; 626644e2f0SJens Wiklander case TEE_ECC_CURVE_NIST_P224: 635a913ee7SJerome Forissier size_bits = 224; 645a913ee7SJerome Forissier size_bytes = 28; 655a913ee7SJerome Forissier name = "NISTP224"; 666644e2f0SJens Wiklander if ((algo != 0) && (algo != TEE_ALG_ECDSA_P224) && 676644e2f0SJens Wiklander (algo != TEE_ALG_ECDH_P224)) 686644e2f0SJens Wiklander return TEE_ERROR_BAD_PARAMETERS; 696644e2f0SJens Wiklander break; 706644e2f0SJens Wiklander case TEE_ECC_CURVE_NIST_P256: 715a913ee7SJerome Forissier size_bits = 256; 725a913ee7SJerome Forissier size_bytes = 32; 735a913ee7SJerome Forissier name = "NISTP256"; 746644e2f0SJens Wiklander if ((algo != 0) && (algo != TEE_ALG_ECDSA_P256) && 756644e2f0SJens Wiklander (algo != TEE_ALG_ECDH_P256)) 766644e2f0SJens Wiklander return TEE_ERROR_BAD_PARAMETERS; 776644e2f0SJens Wiklander break; 786644e2f0SJens Wiklander case TEE_ECC_CURVE_NIST_P384: 795a913ee7SJerome Forissier size_bits = 384; 805a913ee7SJerome Forissier size_bytes = 48; 815a913ee7SJerome Forissier name = "NISTP384"; 826644e2f0SJens Wiklander if ((algo != 0) && (algo != TEE_ALG_ECDSA_P384) && 836644e2f0SJens Wiklander (algo != TEE_ALG_ECDH_P384)) 846644e2f0SJens Wiklander return TEE_ERROR_BAD_PARAMETERS; 856644e2f0SJens Wiklander break; 866644e2f0SJens Wiklander case TEE_ECC_CURVE_NIST_P521: 875a913ee7SJerome Forissier size_bits = 521; 885a913ee7SJerome Forissier size_bytes = 66; 895a913ee7SJerome Forissier name = "NISTP521"; 906644e2f0SJens Wiklander if ((algo != 0) && (algo != TEE_ALG_ECDSA_P521) && 916644e2f0SJens Wiklander (algo != TEE_ALG_ECDH_P521)) 926644e2f0SJens Wiklander return TEE_ERROR_BAD_PARAMETERS; 936644e2f0SJens Wiklander break; 9491fc6bd8SJerome Forissier case TEE_ECC_CURVE_SM2: 9591fc6bd8SJerome Forissier size_bits = 256; 9691fc6bd8SJerome Forissier size_bytes = 32; 9791fc6bd8SJerome Forissier name = "SM2"; 980f151943SJerome Forissier if ((algo != 0) && (algo != TEE_ALG_SM2_PKE) && 995b385b3fSJerome Forissier (algo != TEE_ALG_SM2_DSA_SM3) && 1005b385b3fSJerome Forissier (algo != TEE_ALG_SM2_KEP)) 10191fc6bd8SJerome Forissier return TEE_ERROR_BAD_PARAMETERS; 10291fc6bd8SJerome Forissier break; 1036644e2f0SJens Wiklander default: 1046644e2f0SJens Wiklander return TEE_ERROR_NOT_SUPPORTED; 1056644e2f0SJens Wiklander } 1066644e2f0SJens Wiklander 1075a913ee7SJerome Forissier if (key_size_bytes) 1085a913ee7SJerome Forissier *key_size_bytes = size_bytes; 1095a913ee7SJerome Forissier if (key_size_bits) 1105a913ee7SJerome Forissier *key_size_bits = size_bits; 1115a913ee7SJerome Forissier if (curve_name) 1125a913ee7SJerome Forissier *curve_name = name; 1136644e2f0SJens Wiklander return TEE_SUCCESS; 1146644e2f0SJens Wiklander } 1156644e2f0SJens Wiklander 116*b56ad90eSCedric Neveux static TEE_Result _ltc_ecc_generate_keypair(struct ecc_keypair *key, 117*b56ad90eSCedric Neveux size_t key_size) 1186644e2f0SJens Wiklander { 1196644e2f0SJens Wiklander TEE_Result res; 1206644e2f0SJens Wiklander ecc_key ltc_tmp_key; 1216644e2f0SJens Wiklander int ltc_res; 1226644e2f0SJens Wiklander size_t key_size_bytes = 0; 1236644e2f0SJens Wiklander size_t key_size_bits = 0; 1246644e2f0SJens Wiklander 1255a913ee7SJerome Forissier res = ecc_get_curve_info(key->curve, 0, &key_size_bytes, &key_size_bits, 1265a913ee7SJerome Forissier NULL); 1276644e2f0SJens Wiklander if (res != TEE_SUCCESS) 1286644e2f0SJens Wiklander return res; 1296644e2f0SJens Wiklander 13021282baeSJerome Forissier if (key_size != key_size_bits) 13121282baeSJerome Forissier return TEE_ERROR_BAD_PARAMETERS; 13221282baeSJerome Forissier 1336644e2f0SJens Wiklander /* Generate the ECC key */ 1341f3b1115SJens Wiklander ltc_res = ecc_make_key(NULL, find_prng("prng_crypto"), 1356644e2f0SJens Wiklander key_size_bytes, <c_tmp_key); 1366644e2f0SJens Wiklander if (ltc_res != CRYPT_OK) 1376644e2f0SJens Wiklander return TEE_ERROR_BAD_PARAMETERS; 1386644e2f0SJens Wiklander 1396644e2f0SJens Wiklander /* check the size of the keys */ 1406644e2f0SJens Wiklander if (((size_t)mp_count_bits(ltc_tmp_key.pubkey.x) > key_size_bits) || 1416644e2f0SJens Wiklander ((size_t)mp_count_bits(ltc_tmp_key.pubkey.y) > key_size_bits) || 1426644e2f0SJens Wiklander ((size_t)mp_count_bits(ltc_tmp_key.k) > key_size_bits)) { 1436644e2f0SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS; 1446644e2f0SJens Wiklander goto exit; 1456644e2f0SJens Wiklander } 1466644e2f0SJens Wiklander 1476644e2f0SJens Wiklander /* check LTC is returning z==1 */ 1486644e2f0SJens Wiklander if (mp_count_bits(ltc_tmp_key.pubkey.z) != 1) { 1496644e2f0SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS; 1506644e2f0SJens Wiklander goto exit; 1516644e2f0SJens Wiklander } 1526644e2f0SJens Wiklander 1536644e2f0SJens Wiklander /* Copy the key */ 1546644e2f0SJens Wiklander ltc_mp.copy(ltc_tmp_key.k, key->d); 1556644e2f0SJens Wiklander ltc_mp.copy(ltc_tmp_key.pubkey.x, key->x); 1566644e2f0SJens Wiklander ltc_mp.copy(ltc_tmp_key.pubkey.y, key->y); 1576644e2f0SJens Wiklander 1586644e2f0SJens Wiklander res = TEE_SUCCESS; 1596644e2f0SJens Wiklander 1606644e2f0SJens Wiklander exit: 1616644e2f0SJens Wiklander ecc_free(<c_tmp_key); /* Free the temporary key */ 1626644e2f0SJens Wiklander return res; 1636644e2f0SJens Wiklander } 1646644e2f0SJens Wiklander 1655a913ee7SJerome Forissier /* Note: this function clears the key before setting the curve */ 1665a913ee7SJerome Forissier static TEE_Result ecc_set_curve_from_name(ecc_key *ltc_key, 1675a913ee7SJerome Forissier const char *curve_name) 1686644e2f0SJens Wiklander { 1695a913ee7SJerome Forissier const ltc_ecc_curve *curve = NULL; 1705a913ee7SJerome Forissier int ltc_res = 0; 1716644e2f0SJens Wiklander 1725a913ee7SJerome Forissier ltc_res = ecc_find_curve(curve_name, &curve); 1735a913ee7SJerome Forissier if (ltc_res != CRYPT_OK) 1745a913ee7SJerome Forissier return TEE_ERROR_NOT_SUPPORTED; 1756644e2f0SJens Wiklander 1765a913ee7SJerome Forissier ltc_res = ecc_set_curve(curve, ltc_key); 1775a913ee7SJerome Forissier if (ltc_res != CRYPT_OK) 1785a913ee7SJerome Forissier return TEE_ERROR_GENERIC; 1796644e2f0SJens Wiklander 1806644e2f0SJens Wiklander return TEE_SUCCESS; 1816644e2f0SJens Wiklander } 1826644e2f0SJens Wiklander 1836644e2f0SJens Wiklander /* 1846644e2f0SJens Wiklander * Given a keypair "key", populate the Libtomcrypt private key "ltc_key" 1856644e2f0SJens Wiklander * It also returns the key size, in bytes 1866644e2f0SJens Wiklander */ 187c0691130SJerome Forissier TEE_Result ecc_populate_ltc_private_key(ecc_key *ltc_key, 1886644e2f0SJens Wiklander struct ecc_keypair *key, 189c0691130SJerome Forissier uint32_t algo, size_t *key_size_bytes) 1906644e2f0SJens Wiklander { 1915a913ee7SJerome Forissier TEE_Result res = TEE_ERROR_GENERIC; 1925a913ee7SJerome Forissier const char *name = NULL; 1936644e2f0SJens Wiklander 1945a913ee7SJerome Forissier res = ecc_get_curve_info(key->curve, algo, key_size_bytes, NULL, &name); 1955a913ee7SJerome Forissier if (res) 1966644e2f0SJens Wiklander return res; 1976644e2f0SJens Wiklander 1985a913ee7SJerome Forissier memset(ltc_key, 0, sizeof(*ltc_key)); 1995a913ee7SJerome Forissier 2005a913ee7SJerome Forissier res = ecc_set_curve_from_name(ltc_key, name); 2015a913ee7SJerome Forissier if (res) 2025a913ee7SJerome Forissier return res; 2035a913ee7SJerome Forissier 2045a913ee7SJerome Forissier ltc_key->type = PK_PRIVATE; 2055a913ee7SJerome Forissier mp_copy(key->d, ltc_key->k); 2067ecec894SJerome Forissier mp_copy(key->x, ltc_key->pubkey.x); 2077ecec894SJerome Forissier mp_copy(key->y, ltc_key->pubkey.y); 2087ecec894SJerome Forissier mp_set_int(ltc_key->pubkey.z, 1); 2095a913ee7SJerome Forissier 2105a913ee7SJerome Forissier return TEE_SUCCESS; 2116644e2f0SJens Wiklander } 2126644e2f0SJens Wiklander 2136644e2f0SJens Wiklander /* 2146644e2f0SJens Wiklander * Given a public "key", populate the Libtomcrypt public key "ltc_key" 2156644e2f0SJens Wiklander * It also returns the key size, in bytes 2166644e2f0SJens Wiklander */ 217c0691130SJerome Forissier TEE_Result ecc_populate_ltc_public_key(ecc_key *ltc_key, 2186644e2f0SJens Wiklander struct ecc_public_key *key, 219c0691130SJerome Forissier uint32_t algo, size_t *key_size_bytes) 2206644e2f0SJens Wiklander { 2215a913ee7SJerome Forissier TEE_Result res = TEE_ERROR_GENERIC; 2225a913ee7SJerome Forissier const char *name = NULL; 2236644e2f0SJens Wiklander uint8_t one[1] = { 1 }; 2246644e2f0SJens Wiklander 2255a913ee7SJerome Forissier res = ecc_get_curve_info(key->curve, algo, key_size_bytes, NULL, &name); 2265a913ee7SJerome Forissier if (res) 2276644e2f0SJens Wiklander return res; 2286644e2f0SJens Wiklander 2295a913ee7SJerome Forissier memset(ltc_key, 0, sizeof(*ltc_key)); 2305a913ee7SJerome Forissier 2315a913ee7SJerome Forissier res = ecc_set_curve_from_name(ltc_key, name); 2325a913ee7SJerome Forissier if (res) 2335a913ee7SJerome Forissier return res; 2345a913ee7SJerome Forissier 2355a913ee7SJerome Forissier ltc_key->type = PK_PUBLIC; 2365a913ee7SJerome Forissier 2375a913ee7SJerome Forissier mp_copy(key->x, ltc_key->pubkey.x); 2385a913ee7SJerome Forissier mp_copy(key->y, ltc_key->pubkey.y); 2395a913ee7SJerome Forissier mp_read_unsigned_bin(ltc_key->pubkey.z, one, sizeof(one)); 2405a913ee7SJerome Forissier 2415a913ee7SJerome Forissier return TEE_SUCCESS; 2426644e2f0SJens Wiklander } 2436644e2f0SJens Wiklander 244*b56ad90eSCedric Neveux static TEE_Result _ltc_ecc_sign(uint32_t algo, struct ecc_keypair *key, 2456644e2f0SJens Wiklander const uint8_t *msg, size_t msg_len, 2466644e2f0SJens Wiklander uint8_t *sig, size_t *sig_len) 2476644e2f0SJens Wiklander { 2485a913ee7SJerome Forissier TEE_Result res = TEE_ERROR_GENERIC; 2495a913ee7SJerome Forissier int ltc_res = 0; 2505a913ee7SJerome Forissier size_t key_size_bytes = 0; 2515a913ee7SJerome Forissier ecc_key ltc_key = { }; 2525a913ee7SJerome Forissier unsigned long ltc_sig_len = 0; 2536644e2f0SJens Wiklander 2545a913ee7SJerome Forissier if (algo == 0) 2555a913ee7SJerome Forissier return TEE_ERROR_BAD_PARAMETERS; 2566644e2f0SJens Wiklander 2576644e2f0SJens Wiklander res = ecc_populate_ltc_private_key(<c_key, key, algo, 2586644e2f0SJens Wiklander &key_size_bytes); 2596644e2f0SJens Wiklander if (res != TEE_SUCCESS) 2605a913ee7SJerome Forissier return res; 2616644e2f0SJens Wiklander 2626644e2f0SJens Wiklander if (*sig_len < 2 * key_size_bytes) { 2636644e2f0SJens Wiklander *sig_len = 2 * key_size_bytes; 2646644e2f0SJens Wiklander res = TEE_ERROR_SHORT_BUFFER; 2655a913ee7SJerome Forissier goto out; 2666644e2f0SJens Wiklander } 2676644e2f0SJens Wiklander 2685a913ee7SJerome Forissier ltc_sig_len = *sig_len; 2695a913ee7SJerome Forissier ltc_res = ecc_sign_hash_rfc7518(msg, msg_len, sig, <c_sig_len, 2701f3b1115SJens Wiklander NULL, find_prng("prng_crypto"), <c_key); 2716644e2f0SJens Wiklander if (ltc_res == CRYPT_OK) { 2726644e2f0SJens Wiklander res = TEE_SUCCESS; 2736644e2f0SJens Wiklander } else { 2746644e2f0SJens Wiklander res = TEE_ERROR_GENERIC; 2756644e2f0SJens Wiklander } 2765a913ee7SJerome Forissier *sig_len = ltc_sig_len; 2776644e2f0SJens Wiklander 2785a913ee7SJerome Forissier out: 2795a913ee7SJerome Forissier ecc_free(<c_key); 2806644e2f0SJens Wiklander return res; 2816644e2f0SJens Wiklander } 2826644e2f0SJens Wiklander 283*b56ad90eSCedric Neveux static TEE_Result _ltc_ecc_verify(uint32_t algo, struct ecc_public_key *key, 2846644e2f0SJens Wiklander const uint8_t *msg, size_t msg_len, 2856644e2f0SJens Wiklander const uint8_t *sig, size_t sig_len) 2866644e2f0SJens Wiklander { 2875a913ee7SJerome Forissier TEE_Result res = TEE_ERROR_GENERIC; 2885a913ee7SJerome Forissier int ltc_stat = 0; 2895a913ee7SJerome Forissier int ltc_res = 0; 2905a913ee7SJerome Forissier size_t key_size_bytes = 0; 2915a913ee7SJerome Forissier ecc_key ltc_key = { }; 2926644e2f0SJens Wiklander 2936644e2f0SJens Wiklander if (algo == 0) 2946644e2f0SJens Wiklander return TEE_ERROR_BAD_PARAMETERS; 2956644e2f0SJens Wiklander 2965a913ee7SJerome Forissier res = ecc_populate_ltc_public_key(<c_key, key, algo, &key_size_bytes); 2976644e2f0SJens Wiklander if (res != TEE_SUCCESS) 2986644e2f0SJens Wiklander goto out; 2996644e2f0SJens Wiklander 3006644e2f0SJens Wiklander /* check keysize vs sig_len */ 3016644e2f0SJens Wiklander if ((key_size_bytes * 2) != sig_len) { 3026644e2f0SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS; 3036644e2f0SJens Wiklander goto out; 3046644e2f0SJens Wiklander } 3056644e2f0SJens Wiklander 3065a913ee7SJerome Forissier ltc_res = ecc_verify_hash_rfc7518(sig, sig_len, msg, msg_len, <c_stat, 3075a913ee7SJerome Forissier <c_key); 3086644e2f0SJens Wiklander res = convert_ltc_verify_status(ltc_res, ltc_stat); 3096644e2f0SJens Wiklander out: 3105a913ee7SJerome Forissier ecc_free(<c_key); 3116644e2f0SJens Wiklander return res; 3126644e2f0SJens Wiklander } 3136644e2f0SJens Wiklander 314*b56ad90eSCedric Neveux static TEE_Result _ltc_ecc_shared_secret(struct ecc_keypair *private_key, 3156644e2f0SJens Wiklander struct ecc_public_key *public_key, 3166644e2f0SJens Wiklander void *secret, 3176644e2f0SJens Wiklander unsigned long *secret_len) 3186644e2f0SJens Wiklander { 3195a913ee7SJerome Forissier TEE_Result res = TEE_ERROR_GENERIC; 3205a913ee7SJerome Forissier int ltc_res = 0; 3215a913ee7SJerome Forissier ecc_key ltc_private_key = { }; 3225a913ee7SJerome Forissier ecc_key ltc_public_key = { }; 3235a913ee7SJerome Forissier size_t key_size_bytes = 0; 3246644e2f0SJens Wiklander 3256644e2f0SJens Wiklander /* Check the curves are the same */ 3266644e2f0SJens Wiklander if (private_key->curve != public_key->curve) 3276644e2f0SJens Wiklander return TEE_ERROR_BAD_PARAMETERS; 3286644e2f0SJens Wiklander 3296644e2f0SJens Wiklander res = ecc_populate_ltc_private_key(<c_private_key, private_key, 3306644e2f0SJens Wiklander 0, &key_size_bytes); 3316644e2f0SJens Wiklander if (res != TEE_SUCCESS) 3326644e2f0SJens Wiklander goto out; 3335a913ee7SJerome Forissier res = ecc_populate_ltc_public_key(<c_public_key, public_key, 3346644e2f0SJens Wiklander 0, &key_size_bytes); 3356644e2f0SJens Wiklander if (res != TEE_SUCCESS) 3366644e2f0SJens Wiklander goto out; 3376644e2f0SJens Wiklander 3386644e2f0SJens Wiklander ltc_res = ecc_shared_secret(<c_private_key, <c_public_key, 3396644e2f0SJens Wiklander secret, secret_len); 3406644e2f0SJens Wiklander if (ltc_res == CRYPT_OK) 3416644e2f0SJens Wiklander res = TEE_SUCCESS; 3426644e2f0SJens Wiklander else 3436644e2f0SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS; 3446644e2f0SJens Wiklander 3456644e2f0SJens Wiklander out: 3465a913ee7SJerome Forissier ecc_free(<c_private_key); 3475a913ee7SJerome Forissier ecc_free(<c_public_key); 3486644e2f0SJens Wiklander return res; 3496644e2f0SJens Wiklander } 350*b56ad90eSCedric Neveux 351*b56ad90eSCedric Neveux static const struct crypto_ecc_keypair_ops ecc_keypair_ops = { 352*b56ad90eSCedric Neveux .generate = &_ltc_ecc_generate_keypair, 353*b56ad90eSCedric Neveux .sign = &_ltc_ecc_sign, 354*b56ad90eSCedric Neveux .shared_secret = &_ltc_ecc_shared_secret, 355*b56ad90eSCedric Neveux }; 356*b56ad90eSCedric Neveux 357*b56ad90eSCedric Neveux static const struct crypto_ecc_public_ops ecc_public_key_ops = { 358*b56ad90eSCedric Neveux .free = &_ltc_ecc_free_public_key, 359*b56ad90eSCedric Neveux .verify = &_ltc_ecc_verify, 360*b56ad90eSCedric Neveux }; 361*b56ad90eSCedric Neveux 362*b56ad90eSCedric Neveux TEE_Result crypto_asym_alloc_ecc_keypair(struct ecc_keypair *s, 363*b56ad90eSCedric Neveux uint32_t key_type __unused, 364*b56ad90eSCedric Neveux size_t key_size_bits __unused) 365*b56ad90eSCedric Neveux { 366*b56ad90eSCedric Neveux memset(s, 0, sizeof(*s)); 367*b56ad90eSCedric Neveux if (!bn_alloc_max(&s->d)) 368*b56ad90eSCedric Neveux goto err; 369*b56ad90eSCedric Neveux if (!bn_alloc_max(&s->x)) 370*b56ad90eSCedric Neveux goto err; 371*b56ad90eSCedric Neveux if (!bn_alloc_max(&s->y)) 372*b56ad90eSCedric Neveux goto err; 373*b56ad90eSCedric Neveux 374*b56ad90eSCedric Neveux s->ops = &ecc_keypair_ops; 375*b56ad90eSCedric Neveux 376*b56ad90eSCedric Neveux return TEE_SUCCESS; 377*b56ad90eSCedric Neveux err: 378*b56ad90eSCedric Neveux crypto_bignum_free(s->d); 379*b56ad90eSCedric Neveux crypto_bignum_free(s->x); 380*b56ad90eSCedric Neveux crypto_bignum_free(s->y); 381*b56ad90eSCedric Neveux return TEE_ERROR_OUT_OF_MEMORY; 382*b56ad90eSCedric Neveux } 383*b56ad90eSCedric Neveux 384*b56ad90eSCedric Neveux TEE_Result crypto_asym_alloc_ecc_public_key(struct ecc_public_key *s, 385*b56ad90eSCedric Neveux uint32_t key_type __unused, 386*b56ad90eSCedric Neveux size_t key_size_bits __unused) 387*b56ad90eSCedric Neveux { 388*b56ad90eSCedric Neveux memset(s, 0, sizeof(*s)); 389*b56ad90eSCedric Neveux if (!bn_alloc_max(&s->x)) 390*b56ad90eSCedric Neveux goto err; 391*b56ad90eSCedric Neveux if (!bn_alloc_max(&s->y)) 392*b56ad90eSCedric Neveux goto err; 393*b56ad90eSCedric Neveux 394*b56ad90eSCedric Neveux s->ops = &ecc_public_key_ops; 395*b56ad90eSCedric Neveux 396*b56ad90eSCedric Neveux return TEE_SUCCESS; 397*b56ad90eSCedric Neveux err: 398*b56ad90eSCedric Neveux crypto_bignum_free(s->x); 399*b56ad90eSCedric Neveux crypto_bignum_free(s->y); 400*b56ad90eSCedric Neveux return TEE_ERROR_OUT_OF_MEMORY; 401*b56ad90eSCedric Neveux } 402