16644e2f0SJens Wiklander // SPDX-License-Identifier: BSD-2-Clause 26644e2f0SJens Wiklander /* 36644e2f0SJens Wiklander * Copyright (c) 2014-2019, Linaro Limited 46644e2f0SJens Wiklander */ 56644e2f0SJens Wiklander 61fa655fcSCedric Neveux #include <config.h> 7b56ad90eSCedric Neveux #include <crypto/crypto_impl.h> 86644e2f0SJens Wiklander #include <stdlib.h> 96644e2f0SJens Wiklander #include <string.h> 106644e2f0SJens Wiklander #include <tee_api_types.h> 116644e2f0SJens Wiklander #include <trace.h> 126644e2f0SJens Wiklander #include <utee_defines.h> 136644e2f0SJens Wiklander 146644e2f0SJens Wiklander #include "acipher_helpers.h" 156644e2f0SJens Wiklander 16b56ad90eSCedric Neveux static void _ltc_ecc_free_public_key(struct ecc_public_key *s) 176644e2f0SJens Wiklander { 186644e2f0SJens Wiklander if (!s) 196644e2f0SJens Wiklander return; 206644e2f0SJens Wiklander 216644e2f0SJens Wiklander crypto_bignum_free(s->x); 226644e2f0SJens Wiklander crypto_bignum_free(s->y); 236644e2f0SJens Wiklander } 246644e2f0SJens Wiklander 256644e2f0SJens Wiklander /* 265a913ee7SJerome Forissier * For a given TEE @curve, return key size and LTC curve name. Also check that 275a913ee7SJerome Forissier * @algo is compatible with this curve. 285a913ee7SJerome Forissier * @curve: TEE_ECC_CURVE_NIST_P192, ... 295a913ee7SJerome Forissier * @algo: TEE_ALG_ECDSA_P192, ... 306644e2f0SJens Wiklander */ 315a913ee7SJerome Forissier static TEE_Result ecc_get_curve_info(uint32_t curve, uint32_t algo, 325a913ee7SJerome Forissier size_t *key_size_bytes, 335a913ee7SJerome Forissier size_t *key_size_bits, 345a913ee7SJerome Forissier const char **curve_name) 356644e2f0SJens Wiklander { 365a913ee7SJerome Forissier size_t size_bytes = 0; 375a913ee7SJerome Forissier size_t size_bits = 0; 385a913ee7SJerome Forissier const char *name = NULL; 395a913ee7SJerome Forissier 406644e2f0SJens Wiklander /* 416644e2f0SJens Wiklander * Excerpt of libtomcrypt documentation: 426644e2f0SJens Wiklander * ecc_make_key(... key_size ...): The keysize is the size of the 436644e2f0SJens Wiklander * modulus in bytes desired. Currently directly supported values 446644e2f0SJens Wiklander * are 12, 16, 20, 24, 28, 32, 48, and 65 bytes which correspond 456644e2f0SJens Wiklander * to key sizes of 112, 128, 160, 192, 224, 256, 384, and 521 bits 466644e2f0SJens Wiklander * respectively. 476644e2f0SJens Wiklander */ 486644e2f0SJens Wiklander 496644e2f0SJens Wiklander /* 506644e2f0SJens Wiklander * Note GPv1.1 indicates TEE_ALG_ECDH_NIST_P192_DERIVE_SHARED_SECRET 516644e2f0SJens Wiklander * but defines TEE_ALG_ECDH_P192 526644e2f0SJens Wiklander */ 536644e2f0SJens Wiklander 546644e2f0SJens Wiklander switch (curve) { 556644e2f0SJens Wiklander case TEE_ECC_CURVE_NIST_P192: 565a913ee7SJerome Forissier size_bits = 192; 575a913ee7SJerome Forissier size_bytes = 24; 585a913ee7SJerome Forissier name = "NISTP192"; 596644e2f0SJens Wiklander if ((algo != 0) && (algo != TEE_ALG_ECDSA_P192) && 606644e2f0SJens Wiklander (algo != TEE_ALG_ECDH_P192)) 616644e2f0SJens Wiklander return TEE_ERROR_BAD_PARAMETERS; 626644e2f0SJens Wiklander break; 636644e2f0SJens Wiklander case TEE_ECC_CURVE_NIST_P224: 645a913ee7SJerome Forissier size_bits = 224; 655a913ee7SJerome Forissier size_bytes = 28; 665a913ee7SJerome Forissier name = "NISTP224"; 676644e2f0SJens Wiklander if ((algo != 0) && (algo != TEE_ALG_ECDSA_P224) && 686644e2f0SJens Wiklander (algo != TEE_ALG_ECDH_P224)) 696644e2f0SJens Wiklander return TEE_ERROR_BAD_PARAMETERS; 706644e2f0SJens Wiklander break; 716644e2f0SJens Wiklander case TEE_ECC_CURVE_NIST_P256: 725a913ee7SJerome Forissier size_bits = 256; 735a913ee7SJerome Forissier size_bytes = 32; 745a913ee7SJerome Forissier name = "NISTP256"; 756644e2f0SJens Wiklander if ((algo != 0) && (algo != TEE_ALG_ECDSA_P256) && 766644e2f0SJens Wiklander (algo != TEE_ALG_ECDH_P256)) 776644e2f0SJens Wiklander return TEE_ERROR_BAD_PARAMETERS; 786644e2f0SJens Wiklander break; 796644e2f0SJens Wiklander case TEE_ECC_CURVE_NIST_P384: 805a913ee7SJerome Forissier size_bits = 384; 815a913ee7SJerome Forissier size_bytes = 48; 825a913ee7SJerome Forissier name = "NISTP384"; 836644e2f0SJens Wiklander if ((algo != 0) && (algo != TEE_ALG_ECDSA_P384) && 846644e2f0SJens Wiklander (algo != TEE_ALG_ECDH_P384)) 856644e2f0SJens Wiklander return TEE_ERROR_BAD_PARAMETERS; 866644e2f0SJens Wiklander break; 876644e2f0SJens Wiklander case TEE_ECC_CURVE_NIST_P521: 885a913ee7SJerome Forissier size_bits = 521; 895a913ee7SJerome Forissier size_bytes = 66; 905a913ee7SJerome Forissier name = "NISTP521"; 916644e2f0SJens Wiklander if ((algo != 0) && (algo != TEE_ALG_ECDSA_P521) && 926644e2f0SJens Wiklander (algo != TEE_ALG_ECDH_P521)) 936644e2f0SJens Wiklander return TEE_ERROR_BAD_PARAMETERS; 946644e2f0SJens Wiklander break; 9591fc6bd8SJerome Forissier case TEE_ECC_CURVE_SM2: 9691fc6bd8SJerome Forissier size_bits = 256; 9791fc6bd8SJerome Forissier size_bytes = 32; 9891fc6bd8SJerome Forissier name = "SM2"; 990f151943SJerome Forissier if ((algo != 0) && (algo != TEE_ALG_SM2_PKE) && 1005b385b3fSJerome Forissier (algo != TEE_ALG_SM2_DSA_SM3) && 1015b385b3fSJerome Forissier (algo != TEE_ALG_SM2_KEP)) 10291fc6bd8SJerome Forissier return TEE_ERROR_BAD_PARAMETERS; 10391fc6bd8SJerome Forissier break; 1046644e2f0SJens Wiklander default: 1056644e2f0SJens Wiklander return TEE_ERROR_NOT_SUPPORTED; 1066644e2f0SJens Wiklander } 1076644e2f0SJens Wiklander 1085a913ee7SJerome Forissier if (key_size_bytes) 1095a913ee7SJerome Forissier *key_size_bytes = size_bytes; 1105a913ee7SJerome Forissier if (key_size_bits) 1115a913ee7SJerome Forissier *key_size_bits = size_bits; 1125a913ee7SJerome Forissier if (curve_name) 1135a913ee7SJerome Forissier *curve_name = name; 1146644e2f0SJens Wiklander return TEE_SUCCESS; 1156644e2f0SJens Wiklander } 1166644e2f0SJens Wiklander 117ecf9194dSJerome Forissier /* Note: this function clears the key before setting the curve */ 118ecf9194dSJerome Forissier static TEE_Result ecc_set_curve_from_name(ecc_key *ltc_key, 119ecf9194dSJerome Forissier const char *curve_name) 120ecf9194dSJerome Forissier { 121ecf9194dSJerome Forissier const ltc_ecc_curve *curve = NULL; 122ecf9194dSJerome Forissier int ltc_res = 0; 123ecf9194dSJerome Forissier 124ecf9194dSJerome Forissier ltc_res = ecc_find_curve(curve_name, &curve); 125ecf9194dSJerome Forissier if (ltc_res != CRYPT_OK) 126ecf9194dSJerome Forissier return TEE_ERROR_NOT_SUPPORTED; 127ecf9194dSJerome Forissier 128ecf9194dSJerome Forissier ltc_res = ecc_set_curve(curve, ltc_key); 129ecf9194dSJerome Forissier if (ltc_res != CRYPT_OK) 130ecf9194dSJerome Forissier return TEE_ERROR_GENERIC; 131ecf9194dSJerome Forissier 132ecf9194dSJerome Forissier return TEE_SUCCESS; 133ecf9194dSJerome Forissier } 134ecf9194dSJerome Forissier 135b56ad90eSCedric Neveux static TEE_Result _ltc_ecc_generate_keypair(struct ecc_keypair *key, 136b56ad90eSCedric Neveux size_t key_size) 1376644e2f0SJens Wiklander { 1386644e2f0SJens Wiklander TEE_Result res; 1396644e2f0SJens Wiklander ecc_key ltc_tmp_key; 1406644e2f0SJens Wiklander int ltc_res; 1416644e2f0SJens Wiklander size_t key_size_bytes = 0; 1426644e2f0SJens Wiklander size_t key_size_bits = 0; 143ecf9194dSJerome Forissier const char *name = NULL; 1446644e2f0SJens Wiklander 1455a913ee7SJerome Forissier res = ecc_get_curve_info(key->curve, 0, &key_size_bytes, &key_size_bits, 146ecf9194dSJerome Forissier &name); 1476644e2f0SJens Wiklander if (res != TEE_SUCCESS) 1486644e2f0SJens Wiklander return res; 1496644e2f0SJens Wiklander 15021282baeSJerome Forissier if (key_size != key_size_bits) 15121282baeSJerome Forissier return TEE_ERROR_BAD_PARAMETERS; 15221282baeSJerome Forissier 153ecf9194dSJerome Forissier res = ecc_set_curve_from_name(<c_tmp_key, name); 154ecf9194dSJerome Forissier if (res) 155ecf9194dSJerome Forissier return res; 156ecf9194dSJerome Forissier 1576644e2f0SJens Wiklander /* Generate the ECC key */ 158ecf9194dSJerome Forissier ltc_res = ecc_generate_key(NULL, find_prng("prng_crypto"), 159ecf9194dSJerome Forissier <c_tmp_key); 1606644e2f0SJens Wiklander if (ltc_res != CRYPT_OK) 1616644e2f0SJens Wiklander return TEE_ERROR_BAD_PARAMETERS; 1626644e2f0SJens Wiklander 1636644e2f0SJens Wiklander /* check the size of the keys */ 1646644e2f0SJens Wiklander if (((size_t)mp_count_bits(ltc_tmp_key.pubkey.x) > key_size_bits) || 1656644e2f0SJens Wiklander ((size_t)mp_count_bits(ltc_tmp_key.pubkey.y) > key_size_bits) || 1666644e2f0SJens Wiklander ((size_t)mp_count_bits(ltc_tmp_key.k) > key_size_bits)) { 1676644e2f0SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS; 1686644e2f0SJens Wiklander goto exit; 1696644e2f0SJens Wiklander } 1706644e2f0SJens Wiklander 1716644e2f0SJens Wiklander /* check LTC is returning z==1 */ 1726644e2f0SJens Wiklander if (mp_count_bits(ltc_tmp_key.pubkey.z) != 1) { 1736644e2f0SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS; 1746644e2f0SJens Wiklander goto exit; 1756644e2f0SJens Wiklander } 1766644e2f0SJens Wiklander 1776644e2f0SJens Wiklander /* Copy the key */ 1786644e2f0SJens Wiklander ltc_mp.copy(ltc_tmp_key.k, key->d); 1796644e2f0SJens Wiklander ltc_mp.copy(ltc_tmp_key.pubkey.x, key->x); 1806644e2f0SJens Wiklander ltc_mp.copy(ltc_tmp_key.pubkey.y, key->y); 1816644e2f0SJens Wiklander 1826644e2f0SJens Wiklander res = TEE_SUCCESS; 1836644e2f0SJens Wiklander 1846644e2f0SJens Wiklander exit: 1856644e2f0SJens Wiklander ecc_free(<c_tmp_key); /* Free the temporary key */ 1866644e2f0SJens Wiklander return res; 1876644e2f0SJens Wiklander } 1886644e2f0SJens Wiklander 1896644e2f0SJens Wiklander /* 1906644e2f0SJens Wiklander * Given a keypair "key", populate the Libtomcrypt private key "ltc_key" 1916644e2f0SJens Wiklander * It also returns the key size, in bytes 1926644e2f0SJens Wiklander */ 193c0691130SJerome Forissier TEE_Result ecc_populate_ltc_private_key(ecc_key *ltc_key, 1946644e2f0SJens Wiklander struct ecc_keypair *key, 195c0691130SJerome Forissier uint32_t algo, size_t *key_size_bytes) 1966644e2f0SJens Wiklander { 1975a913ee7SJerome Forissier TEE_Result res = TEE_ERROR_GENERIC; 1985a913ee7SJerome Forissier const char *name = NULL; 1996644e2f0SJens Wiklander 2005a913ee7SJerome Forissier res = ecc_get_curve_info(key->curve, algo, key_size_bytes, NULL, &name); 2015a913ee7SJerome Forissier if (res) 2026644e2f0SJens Wiklander return res; 2036644e2f0SJens Wiklander 2045a913ee7SJerome Forissier memset(ltc_key, 0, sizeof(*ltc_key)); 2055a913ee7SJerome Forissier 2065a913ee7SJerome Forissier res = ecc_set_curve_from_name(ltc_key, name); 2075a913ee7SJerome Forissier if (res) 2085a913ee7SJerome Forissier return res; 2095a913ee7SJerome Forissier 2105a913ee7SJerome Forissier ltc_key->type = PK_PRIVATE; 2115a913ee7SJerome Forissier mp_copy(key->d, ltc_key->k); 2127ecec894SJerome Forissier mp_copy(key->x, ltc_key->pubkey.x); 2137ecec894SJerome Forissier mp_copy(key->y, ltc_key->pubkey.y); 2147ecec894SJerome Forissier mp_set_int(ltc_key->pubkey.z, 1); 2155a913ee7SJerome Forissier 2165a913ee7SJerome Forissier return TEE_SUCCESS; 2176644e2f0SJens Wiklander } 2186644e2f0SJens Wiklander 2196644e2f0SJens Wiklander /* 2206644e2f0SJens Wiklander * Given a public "key", populate the Libtomcrypt public key "ltc_key" 2216644e2f0SJens Wiklander * It also returns the key size, in bytes 2226644e2f0SJens Wiklander */ 223c0691130SJerome Forissier TEE_Result ecc_populate_ltc_public_key(ecc_key *ltc_key, 2246644e2f0SJens Wiklander struct ecc_public_key *key, 225c0691130SJerome Forissier uint32_t algo, size_t *key_size_bytes) 2266644e2f0SJens Wiklander { 2275a913ee7SJerome Forissier TEE_Result res = TEE_ERROR_GENERIC; 2285a913ee7SJerome Forissier const char *name = NULL; 2296644e2f0SJens Wiklander uint8_t one[1] = { 1 }; 2306644e2f0SJens Wiklander 2315a913ee7SJerome Forissier res = ecc_get_curve_info(key->curve, algo, key_size_bytes, NULL, &name); 2325a913ee7SJerome Forissier if (res) 2336644e2f0SJens Wiklander return res; 2346644e2f0SJens Wiklander 2355a913ee7SJerome Forissier memset(ltc_key, 0, sizeof(*ltc_key)); 2365a913ee7SJerome Forissier 2375a913ee7SJerome Forissier res = ecc_set_curve_from_name(ltc_key, name); 2385a913ee7SJerome Forissier if (res) 2395a913ee7SJerome Forissier return res; 2405a913ee7SJerome Forissier 2415a913ee7SJerome Forissier ltc_key->type = PK_PUBLIC; 2425a913ee7SJerome Forissier 2435a913ee7SJerome Forissier mp_copy(key->x, ltc_key->pubkey.x); 2445a913ee7SJerome Forissier mp_copy(key->y, ltc_key->pubkey.y); 2455a913ee7SJerome Forissier mp_read_unsigned_bin(ltc_key->pubkey.z, one, sizeof(one)); 2465a913ee7SJerome Forissier 2475a913ee7SJerome Forissier return TEE_SUCCESS; 2486644e2f0SJens Wiklander } 2496644e2f0SJens Wiklander 250b56ad90eSCedric Neveux static TEE_Result _ltc_ecc_sign(uint32_t algo, struct ecc_keypair *key, 2516644e2f0SJens Wiklander const uint8_t *msg, size_t msg_len, 2526644e2f0SJens Wiklander uint8_t *sig, size_t *sig_len) 2536644e2f0SJens Wiklander { 2545a913ee7SJerome Forissier TEE_Result res = TEE_ERROR_GENERIC; 2555a913ee7SJerome Forissier int ltc_res = 0; 2565a913ee7SJerome Forissier size_t key_size_bytes = 0; 2575a913ee7SJerome Forissier ecc_key ltc_key = { }; 2585a913ee7SJerome Forissier unsigned long ltc_sig_len = 0; 2596644e2f0SJens Wiklander 2605a913ee7SJerome Forissier if (algo == 0) 2615a913ee7SJerome Forissier return TEE_ERROR_BAD_PARAMETERS; 2626644e2f0SJens Wiklander 2636644e2f0SJens Wiklander res = ecc_populate_ltc_private_key(<c_key, key, algo, 2646644e2f0SJens Wiklander &key_size_bytes); 2656644e2f0SJens Wiklander if (res != TEE_SUCCESS) 2665a913ee7SJerome Forissier return res; 2676644e2f0SJens Wiklander 2686644e2f0SJens Wiklander if (*sig_len < 2 * key_size_bytes) { 2696644e2f0SJens Wiklander *sig_len = 2 * key_size_bytes; 2706644e2f0SJens Wiklander res = TEE_ERROR_SHORT_BUFFER; 2715a913ee7SJerome Forissier goto out; 2726644e2f0SJens Wiklander } 2736644e2f0SJens Wiklander 2745a913ee7SJerome Forissier ltc_sig_len = *sig_len; 2755a913ee7SJerome Forissier ltc_res = ecc_sign_hash_rfc7518(msg, msg_len, sig, <c_sig_len, 2761f3b1115SJens Wiklander NULL, find_prng("prng_crypto"), <c_key); 2776644e2f0SJens Wiklander if (ltc_res == CRYPT_OK) { 2786644e2f0SJens Wiklander res = TEE_SUCCESS; 2796644e2f0SJens Wiklander } else { 2806644e2f0SJens Wiklander res = TEE_ERROR_GENERIC; 2816644e2f0SJens Wiklander } 2825a913ee7SJerome Forissier *sig_len = ltc_sig_len; 2836644e2f0SJens Wiklander 2845a913ee7SJerome Forissier out: 2855a913ee7SJerome Forissier ecc_free(<c_key); 2866644e2f0SJens Wiklander return res; 2876644e2f0SJens Wiklander } 2886644e2f0SJens Wiklander 289b56ad90eSCedric Neveux static TEE_Result _ltc_ecc_verify(uint32_t algo, struct ecc_public_key *key, 2906644e2f0SJens Wiklander const uint8_t *msg, size_t msg_len, 2916644e2f0SJens Wiklander const uint8_t *sig, size_t sig_len) 2926644e2f0SJens Wiklander { 2935a913ee7SJerome Forissier TEE_Result res = TEE_ERROR_GENERIC; 2945a913ee7SJerome Forissier int ltc_stat = 0; 2955a913ee7SJerome Forissier int ltc_res = 0; 2965a913ee7SJerome Forissier size_t key_size_bytes = 0; 2975a913ee7SJerome Forissier ecc_key ltc_key = { }; 2986644e2f0SJens Wiklander 2996644e2f0SJens Wiklander if (algo == 0) 3006644e2f0SJens Wiklander return TEE_ERROR_BAD_PARAMETERS; 3016644e2f0SJens Wiklander 3025a913ee7SJerome Forissier res = ecc_populate_ltc_public_key(<c_key, key, algo, &key_size_bytes); 3036644e2f0SJens Wiklander if (res != TEE_SUCCESS) 3046644e2f0SJens Wiklander goto out; 3056644e2f0SJens Wiklander 3066644e2f0SJens Wiklander /* check keysize vs sig_len */ 3076644e2f0SJens Wiklander if ((key_size_bytes * 2) != sig_len) { 3086644e2f0SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS; 3096644e2f0SJens Wiklander goto out; 3106644e2f0SJens Wiklander } 3116644e2f0SJens Wiklander 3125a913ee7SJerome Forissier ltc_res = ecc_verify_hash_rfc7518(sig, sig_len, msg, msg_len, <c_stat, 3135a913ee7SJerome Forissier <c_key); 3146644e2f0SJens Wiklander res = convert_ltc_verify_status(ltc_res, ltc_stat); 3156644e2f0SJens Wiklander out: 3165a913ee7SJerome Forissier ecc_free(<c_key); 3176644e2f0SJens Wiklander return res; 3186644e2f0SJens Wiklander } 3196644e2f0SJens Wiklander 320b56ad90eSCedric Neveux static TEE_Result _ltc_ecc_shared_secret(struct ecc_keypair *private_key, 3216644e2f0SJens Wiklander struct ecc_public_key *public_key, 3226644e2f0SJens Wiklander void *secret, 3236644e2f0SJens Wiklander unsigned long *secret_len) 3246644e2f0SJens Wiklander { 3255a913ee7SJerome Forissier TEE_Result res = TEE_ERROR_GENERIC; 3265a913ee7SJerome Forissier int ltc_res = 0; 3275a913ee7SJerome Forissier ecc_key ltc_private_key = { }; 3285a913ee7SJerome Forissier ecc_key ltc_public_key = { }; 3295a913ee7SJerome Forissier size_t key_size_bytes = 0; 3306644e2f0SJens Wiklander 3316644e2f0SJens Wiklander /* Check the curves are the same */ 3326644e2f0SJens Wiklander if (private_key->curve != public_key->curve) 3336644e2f0SJens Wiklander return TEE_ERROR_BAD_PARAMETERS; 3346644e2f0SJens Wiklander 3356644e2f0SJens Wiklander res = ecc_populate_ltc_private_key(<c_private_key, private_key, 3366644e2f0SJens Wiklander 0, &key_size_bytes); 3376644e2f0SJens Wiklander if (res != TEE_SUCCESS) 3386644e2f0SJens Wiklander goto out; 3395a913ee7SJerome Forissier res = ecc_populate_ltc_public_key(<c_public_key, public_key, 3406644e2f0SJens Wiklander 0, &key_size_bytes); 3416644e2f0SJens Wiklander if (res != TEE_SUCCESS) 3426644e2f0SJens Wiklander goto out; 3436644e2f0SJens Wiklander 3446644e2f0SJens Wiklander ltc_res = ecc_shared_secret(<c_private_key, <c_public_key, 3456644e2f0SJens Wiklander secret, secret_len); 3466644e2f0SJens Wiklander if (ltc_res == CRYPT_OK) 3476644e2f0SJens Wiklander res = TEE_SUCCESS; 3486644e2f0SJens Wiklander else 3496644e2f0SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS; 3506644e2f0SJens Wiklander 3516644e2f0SJens Wiklander out: 3525a913ee7SJerome Forissier ecc_free(<c_private_key); 3535a913ee7SJerome Forissier ecc_free(<c_public_key); 3546644e2f0SJens Wiklander return res; 3556644e2f0SJens Wiklander } 356b56ad90eSCedric Neveux 357b56ad90eSCedric Neveux static const struct crypto_ecc_keypair_ops ecc_keypair_ops = { 35855b5758dSJerome Forissier .generate = _ltc_ecc_generate_keypair, 35955b5758dSJerome Forissier .sign = _ltc_ecc_sign, 36055b5758dSJerome Forissier .shared_secret = _ltc_ecc_shared_secret, 361b56ad90eSCedric Neveux }; 362b56ad90eSCedric Neveux 363b56ad90eSCedric Neveux static const struct crypto_ecc_public_ops ecc_public_key_ops = { 36455b5758dSJerome Forissier .free = _ltc_ecc_free_public_key, 36555b5758dSJerome Forissier .verify = _ltc_ecc_verify, 366b56ad90eSCedric Neveux }; 367b56ad90eSCedric Neveux 3681fa655fcSCedric Neveux static const struct crypto_ecc_keypair_ops sm2_dsa_keypair_ops = { 36955b5758dSJerome Forissier .generate = _ltc_ecc_generate_keypair, 37055b5758dSJerome Forissier .sign = sm2_ltc_dsa_sign, 3711fa655fcSCedric Neveux }; 3721fa655fcSCedric Neveux 3731fa655fcSCedric Neveux static const struct crypto_ecc_public_ops sm2_dsa_public_key_ops = { 37455b5758dSJerome Forissier .free = _ltc_ecc_free_public_key, 37555b5758dSJerome Forissier .verify = sm2_ltc_dsa_verify, 3761fa655fcSCedric Neveux }; 3771fa655fcSCedric Neveux 3781fa655fcSCedric Neveux static const struct crypto_ecc_keypair_ops sm2_pke_keypair_ops = { 37955b5758dSJerome Forissier .generate = _ltc_ecc_generate_keypair, 38055b5758dSJerome Forissier .decrypt = sm2_ltc_pke_decrypt, 3811fa655fcSCedric Neveux }; 3821fa655fcSCedric Neveux 3831fa655fcSCedric Neveux static const struct crypto_ecc_public_ops sm2_pke_public_key_ops = { 38455b5758dSJerome Forissier .free = _ltc_ecc_free_public_key, 38555b5758dSJerome Forissier .encrypt = sm2_ltc_pke_encrypt, 3861fa655fcSCedric Neveux }; 3871fa655fcSCedric Neveux 3881fa655fcSCedric Neveux static const struct crypto_ecc_keypair_ops sm2_kep_keypair_ops = { 38955b5758dSJerome Forissier .generate = _ltc_ecc_generate_keypair, 3901fa655fcSCedric Neveux }; 3911fa655fcSCedric Neveux 3921fa655fcSCedric Neveux static const struct crypto_ecc_public_ops sm2_kep_public_key_ops = { 39355b5758dSJerome Forissier .free = _ltc_ecc_free_public_key, 3941fa655fcSCedric Neveux }; 3951fa655fcSCedric Neveux 396*e7971844SJorge Ramirez-Ortiz const struct crypto_ecc_keypair_ops * 397*e7971844SJorge Ramirez-Ortiz crypto_asym_get_ecc_keypair_ops( uint32_t key_type) 398*e7971844SJorge Ramirez-Ortiz { 399*e7971844SJorge Ramirez-Ortiz switch (key_type) { 400*e7971844SJorge Ramirez-Ortiz case TEE_TYPE_ECDSA_KEYPAIR: 401*e7971844SJorge Ramirez-Ortiz case TEE_TYPE_ECDH_KEYPAIR: 402*e7971844SJorge Ramirez-Ortiz return &ecc_keypair_ops; 403*e7971844SJorge Ramirez-Ortiz case TEE_TYPE_SM2_DSA_KEYPAIR: 404*e7971844SJorge Ramirez-Ortiz if (!IS_ENABLED(_CFG_CORE_LTC_SM2_DSA)) 405*e7971844SJorge Ramirez-Ortiz return NULL; 406*e7971844SJorge Ramirez-Ortiz return &sm2_dsa_keypair_ops; 407*e7971844SJorge Ramirez-Ortiz case TEE_TYPE_SM2_PKE_KEYPAIR: 408*e7971844SJorge Ramirez-Ortiz if (!IS_ENABLED(_CFG_CORE_LTC_SM2_PKE)) 409*e7971844SJorge Ramirez-Ortiz return NULL; 410*e7971844SJorge Ramirez-Ortiz return &sm2_pke_keypair_ops; 411*e7971844SJorge Ramirez-Ortiz case TEE_TYPE_SM2_KEP_KEYPAIR: 412*e7971844SJorge Ramirez-Ortiz if (!IS_ENABLED(_CFG_CORE_LTC_SM2_KEP)) 413*e7971844SJorge Ramirez-Ortiz return NULL; 414*e7971844SJorge Ramirez-Ortiz return &sm2_kep_keypair_ops; 415*e7971844SJorge Ramirez-Ortiz default: 416*e7971844SJorge Ramirez-Ortiz return NULL; 417*e7971844SJorge Ramirez-Ortiz } 418*e7971844SJorge Ramirez-Ortiz } 419*e7971844SJorge Ramirez-Ortiz 420b56ad90eSCedric Neveux TEE_Result crypto_asym_alloc_ecc_keypair(struct ecc_keypair *s, 4211fa655fcSCedric Neveux uint32_t key_type, 422b56ad90eSCedric Neveux size_t key_size_bits __unused) 423b56ad90eSCedric Neveux { 424b56ad90eSCedric Neveux memset(s, 0, sizeof(*s)); 4251fa655fcSCedric Neveux 4261fa655fcSCedric Neveux switch (key_type) { 4271fa655fcSCedric Neveux case TEE_TYPE_ECDSA_KEYPAIR: 4281fa655fcSCedric Neveux case TEE_TYPE_ECDH_KEYPAIR: 4291fa655fcSCedric Neveux s->ops = &ecc_keypair_ops; 4301fa655fcSCedric Neveux break; 4311fa655fcSCedric Neveux case TEE_TYPE_SM2_DSA_KEYPAIR: 4321fa655fcSCedric Neveux if (!IS_ENABLED(_CFG_CORE_LTC_SM2_DSA)) 4331fa655fcSCedric Neveux return TEE_ERROR_NOT_IMPLEMENTED; 4341fa655fcSCedric Neveux 4353002cbb0SJerome Forissier s->curve = TEE_ECC_CURVE_SM2; 4361fa655fcSCedric Neveux s->ops = &sm2_dsa_keypair_ops; 4371fa655fcSCedric Neveux break; 4381fa655fcSCedric Neveux case TEE_TYPE_SM2_PKE_KEYPAIR: 4391fa655fcSCedric Neveux if (!IS_ENABLED(_CFG_CORE_LTC_SM2_PKE)) 4401fa655fcSCedric Neveux return TEE_ERROR_NOT_IMPLEMENTED; 4411fa655fcSCedric Neveux 4423002cbb0SJerome Forissier s->curve = TEE_ECC_CURVE_SM2; 4431fa655fcSCedric Neveux s->ops = &sm2_pke_keypair_ops; 4441fa655fcSCedric Neveux break; 4451fa655fcSCedric Neveux case TEE_TYPE_SM2_KEP_KEYPAIR: 4461fa655fcSCedric Neveux if (!IS_ENABLED(_CFG_CORE_LTC_SM2_KEP)) 4471fa655fcSCedric Neveux return TEE_ERROR_NOT_IMPLEMENTED; 4481fa655fcSCedric Neveux 4493002cbb0SJerome Forissier s->curve = TEE_ECC_CURVE_SM2; 4501fa655fcSCedric Neveux s->ops = &sm2_kep_keypair_ops; 4511fa655fcSCedric Neveux break; 4521fa655fcSCedric Neveux default: 4531fa655fcSCedric Neveux return TEE_ERROR_NOT_IMPLEMENTED; 4541fa655fcSCedric Neveux } 4551fa655fcSCedric Neveux 456b56ad90eSCedric Neveux if (!bn_alloc_max(&s->d)) 457b56ad90eSCedric Neveux goto err; 458b56ad90eSCedric Neveux if (!bn_alloc_max(&s->x)) 459b56ad90eSCedric Neveux goto err; 460b56ad90eSCedric Neveux if (!bn_alloc_max(&s->y)) 461b56ad90eSCedric Neveux goto err; 462b56ad90eSCedric Neveux 463b56ad90eSCedric Neveux return TEE_SUCCESS; 4641fa655fcSCedric Neveux 465b56ad90eSCedric Neveux err: 4661fa655fcSCedric Neveux s->ops = NULL; 4671fa655fcSCedric Neveux 468b56ad90eSCedric Neveux crypto_bignum_free(s->d); 469b56ad90eSCedric Neveux crypto_bignum_free(s->x); 4701fa655fcSCedric Neveux 471b56ad90eSCedric Neveux return TEE_ERROR_OUT_OF_MEMORY; 472b56ad90eSCedric Neveux } 473b56ad90eSCedric Neveux 474*e7971844SJorge Ramirez-Ortiz const struct crypto_ecc_public_ops* 475*e7971844SJorge Ramirez-Ortiz crypto_asym_get_ecc_public_ops(uint32_t key_type) 476*e7971844SJorge Ramirez-Ortiz { 477*e7971844SJorge Ramirez-Ortiz switch (key_type) { 478*e7971844SJorge Ramirez-Ortiz case TEE_TYPE_ECDSA_PUBLIC_KEY: 479*e7971844SJorge Ramirez-Ortiz case TEE_TYPE_ECDH_PUBLIC_KEY: 480*e7971844SJorge Ramirez-Ortiz return &ecc_public_key_ops; 481*e7971844SJorge Ramirez-Ortiz case TEE_TYPE_SM2_DSA_PUBLIC_KEY: 482*e7971844SJorge Ramirez-Ortiz if (!IS_ENABLED(_CFG_CORE_LTC_SM2_DSA)) 483*e7971844SJorge Ramirez-Ortiz return NULL; 484*e7971844SJorge Ramirez-Ortiz return &sm2_dsa_public_key_ops; 485*e7971844SJorge Ramirez-Ortiz case TEE_TYPE_SM2_PKE_PUBLIC_KEY: 486*e7971844SJorge Ramirez-Ortiz if (!IS_ENABLED(_CFG_CORE_LTC_SM2_PKE)) 487*e7971844SJorge Ramirez-Ortiz return NULL; 488*e7971844SJorge Ramirez-Ortiz return &sm2_pke_public_key_ops; 489*e7971844SJorge Ramirez-Ortiz case TEE_TYPE_SM2_KEP_PUBLIC_KEY: 490*e7971844SJorge Ramirez-Ortiz if (!IS_ENABLED(_CFG_CORE_LTC_SM2_KEP)) 491*e7971844SJorge Ramirez-Ortiz return NULL; 492*e7971844SJorge Ramirez-Ortiz return &sm2_kep_public_key_ops; 493*e7971844SJorge Ramirez-Ortiz default: 494*e7971844SJorge Ramirez-Ortiz return NULL; 495*e7971844SJorge Ramirez-Ortiz } 496*e7971844SJorge Ramirez-Ortiz } 497*e7971844SJorge Ramirez-Ortiz 498b56ad90eSCedric Neveux TEE_Result crypto_asym_alloc_ecc_public_key(struct ecc_public_key *s, 4991fa655fcSCedric Neveux uint32_t key_type, 500b56ad90eSCedric Neveux size_t key_size_bits __unused) 501b56ad90eSCedric Neveux { 502b56ad90eSCedric Neveux memset(s, 0, sizeof(*s)); 5031fa655fcSCedric Neveux 5041fa655fcSCedric Neveux switch (key_type) { 5051fa655fcSCedric Neveux case TEE_TYPE_ECDSA_PUBLIC_KEY: 5061fa655fcSCedric Neveux case TEE_TYPE_ECDH_PUBLIC_KEY: 5071fa655fcSCedric Neveux s->ops = &ecc_public_key_ops; 5081fa655fcSCedric Neveux break; 5091fa655fcSCedric Neveux case TEE_TYPE_SM2_DSA_PUBLIC_KEY: 5101fa655fcSCedric Neveux if (!IS_ENABLED(_CFG_CORE_LTC_SM2_DSA)) 5111fa655fcSCedric Neveux return TEE_ERROR_NOT_IMPLEMENTED; 5121fa655fcSCedric Neveux 5133002cbb0SJerome Forissier s->curve = TEE_ECC_CURVE_SM2; 5141fa655fcSCedric Neveux s->ops = &sm2_dsa_public_key_ops; 5151fa655fcSCedric Neveux break; 5161fa655fcSCedric Neveux case TEE_TYPE_SM2_PKE_PUBLIC_KEY: 5171fa655fcSCedric Neveux if (!IS_ENABLED(_CFG_CORE_LTC_SM2_PKE)) 5181fa655fcSCedric Neveux return TEE_ERROR_NOT_IMPLEMENTED; 5191fa655fcSCedric Neveux 5203002cbb0SJerome Forissier s->curve = TEE_ECC_CURVE_SM2; 5211fa655fcSCedric Neveux s->ops = &sm2_pke_public_key_ops; 5221fa655fcSCedric Neveux break; 5231fa655fcSCedric Neveux case TEE_TYPE_SM2_KEP_PUBLIC_KEY: 5241fa655fcSCedric Neveux if (!IS_ENABLED(_CFG_CORE_LTC_SM2_KEP)) 5251fa655fcSCedric Neveux return TEE_ERROR_NOT_IMPLEMENTED; 5261fa655fcSCedric Neveux 5273002cbb0SJerome Forissier s->curve = TEE_ECC_CURVE_SM2; 5281fa655fcSCedric Neveux s->ops = &sm2_kep_public_key_ops; 5291fa655fcSCedric Neveux break; 5301fa655fcSCedric Neveux default: 5311fa655fcSCedric Neveux return TEE_ERROR_NOT_IMPLEMENTED; 5321fa655fcSCedric Neveux } 5331fa655fcSCedric Neveux 534b56ad90eSCedric Neveux if (!bn_alloc_max(&s->x)) 535b56ad90eSCedric Neveux goto err; 536b56ad90eSCedric Neveux if (!bn_alloc_max(&s->y)) 537b56ad90eSCedric Neveux goto err; 538b56ad90eSCedric Neveux 539b56ad90eSCedric Neveux return TEE_SUCCESS; 5401fa655fcSCedric Neveux 541b56ad90eSCedric Neveux err: 5421fa655fcSCedric Neveux s->ops = NULL; 5431fa655fcSCedric Neveux 544b56ad90eSCedric Neveux crypto_bignum_free(s->x); 5451fa655fcSCedric Neveux 546b56ad90eSCedric Neveux return TEE_ERROR_OUT_OF_MEMORY; 547b56ad90eSCedric Neveux } 548