16644e2f0SJens Wiklander // SPDX-License-Identifier: BSD-2-Clause 26644e2f0SJens Wiklander /* 36644e2f0SJens Wiklander * Copyright (c) 2014-2019, Linaro Limited 46644e2f0SJens Wiklander */ 56644e2f0SJens Wiklander 66644e2f0SJens Wiklander #include <crypto/crypto.h> 76644e2f0SJens Wiklander #include <stdlib.h> 86644e2f0SJens Wiklander #include <string.h> 96644e2f0SJens Wiklander #include <tee_api_types.h> 106644e2f0SJens Wiklander #include <tomcrypt.h> 116644e2f0SJens Wiklander #include <trace.h> 126644e2f0SJens Wiklander #include <utee_defines.h> 136644e2f0SJens Wiklander 146644e2f0SJens Wiklander #include "acipher_helpers.h" 156644e2f0SJens Wiklander 166644e2f0SJens Wiklander TEE_Result crypto_acipher_alloc_ecc_keypair(struct ecc_keypair *s, 176644e2f0SJens Wiklander size_t key_size_bits __unused) 186644e2f0SJens Wiklander { 196644e2f0SJens Wiklander memset(s, 0, sizeof(*s)); 206644e2f0SJens Wiklander if (!bn_alloc_max(&s->d)) 216644e2f0SJens Wiklander goto err; 226644e2f0SJens Wiklander if (!bn_alloc_max(&s->x)) 236644e2f0SJens Wiklander goto err; 246644e2f0SJens Wiklander if (!bn_alloc_max(&s->y)) 256644e2f0SJens Wiklander goto err; 266644e2f0SJens Wiklander return TEE_SUCCESS; 276644e2f0SJens Wiklander err: 286644e2f0SJens Wiklander crypto_bignum_free(s->d); 296644e2f0SJens Wiklander crypto_bignum_free(s->x); 306644e2f0SJens Wiklander crypto_bignum_free(s->y); 316644e2f0SJens Wiklander return TEE_ERROR_OUT_OF_MEMORY; 326644e2f0SJens Wiklander } 336644e2f0SJens Wiklander 346644e2f0SJens Wiklander TEE_Result crypto_acipher_alloc_ecc_public_key(struct ecc_public_key *s, 356644e2f0SJens Wiklander size_t key_size_bits __unused) 366644e2f0SJens Wiklander { 376644e2f0SJens Wiklander memset(s, 0, sizeof(*s)); 386644e2f0SJens Wiklander if (!bn_alloc_max(&s->x)) 396644e2f0SJens Wiklander goto err; 406644e2f0SJens Wiklander if (!bn_alloc_max(&s->y)) 416644e2f0SJens Wiklander goto err; 426644e2f0SJens Wiklander return TEE_SUCCESS; 436644e2f0SJens Wiklander err: 446644e2f0SJens Wiklander crypto_bignum_free(s->x); 456644e2f0SJens Wiklander crypto_bignum_free(s->y); 466644e2f0SJens Wiklander return TEE_ERROR_OUT_OF_MEMORY; 476644e2f0SJens Wiklander } 486644e2f0SJens Wiklander 496644e2f0SJens Wiklander void crypto_acipher_free_ecc_public_key(struct ecc_public_key *s) 506644e2f0SJens Wiklander { 516644e2f0SJens Wiklander if (!s) 526644e2f0SJens Wiklander return; 536644e2f0SJens Wiklander 546644e2f0SJens Wiklander crypto_bignum_free(s->x); 556644e2f0SJens Wiklander crypto_bignum_free(s->y); 566644e2f0SJens Wiklander } 576644e2f0SJens Wiklander 586644e2f0SJens Wiklander /* 596644e2f0SJens Wiklander * curve is part of TEE_ECC_CURVE_NIST_P192,... 606644e2f0SJens Wiklander * algo is part of TEE_ALG_ECDSA_P192,..., and 0 if we do not have it 616644e2f0SJens Wiklander */ 626644e2f0SJens Wiklander static TEE_Result ecc_get_keysize(uint32_t curve, uint32_t algo, 636644e2f0SJens Wiklander size_t *key_size_bytes, size_t *key_size_bits) 646644e2f0SJens Wiklander { 656644e2f0SJens Wiklander /* 666644e2f0SJens Wiklander * Excerpt of libtomcrypt documentation: 676644e2f0SJens Wiklander * ecc_make_key(... key_size ...): The keysize is the size of the 686644e2f0SJens Wiklander * modulus in bytes desired. Currently directly supported values 696644e2f0SJens Wiklander * are 12, 16, 20, 24, 28, 32, 48, and 65 bytes which correspond 706644e2f0SJens Wiklander * to key sizes of 112, 128, 160, 192, 224, 256, 384, and 521 bits 716644e2f0SJens Wiklander * respectively. 726644e2f0SJens Wiklander */ 736644e2f0SJens Wiklander 746644e2f0SJens Wiklander /* 756644e2f0SJens Wiklander * Note GPv1.1 indicates TEE_ALG_ECDH_NIST_P192_DERIVE_SHARED_SECRET 766644e2f0SJens Wiklander * but defines TEE_ALG_ECDH_P192 776644e2f0SJens Wiklander */ 786644e2f0SJens Wiklander 796644e2f0SJens Wiklander switch (curve) { 806644e2f0SJens Wiklander case TEE_ECC_CURVE_NIST_P192: 816644e2f0SJens Wiklander *key_size_bits = 192; 826644e2f0SJens Wiklander *key_size_bytes = 24; 836644e2f0SJens Wiklander if ((algo != 0) && (algo != TEE_ALG_ECDSA_P192) && 846644e2f0SJens Wiklander (algo != TEE_ALG_ECDH_P192)) 856644e2f0SJens Wiklander return TEE_ERROR_BAD_PARAMETERS; 866644e2f0SJens Wiklander break; 876644e2f0SJens Wiklander case TEE_ECC_CURVE_NIST_P224: 886644e2f0SJens Wiklander *key_size_bits = 224; 896644e2f0SJens Wiklander *key_size_bytes = 28; 906644e2f0SJens Wiklander if ((algo != 0) && (algo != TEE_ALG_ECDSA_P224) && 916644e2f0SJens Wiklander (algo != TEE_ALG_ECDH_P224)) 926644e2f0SJens Wiklander return TEE_ERROR_BAD_PARAMETERS; 936644e2f0SJens Wiklander break; 946644e2f0SJens Wiklander case TEE_ECC_CURVE_NIST_P256: 956644e2f0SJens Wiklander *key_size_bits = 256; 966644e2f0SJens Wiklander *key_size_bytes = 32; 976644e2f0SJens Wiklander if ((algo != 0) && (algo != TEE_ALG_ECDSA_P256) && 986644e2f0SJens Wiklander (algo != TEE_ALG_ECDH_P256)) 996644e2f0SJens Wiklander return TEE_ERROR_BAD_PARAMETERS; 1006644e2f0SJens Wiklander break; 1016644e2f0SJens Wiklander case TEE_ECC_CURVE_NIST_P384: 1026644e2f0SJens Wiklander *key_size_bits = 384; 1036644e2f0SJens Wiklander *key_size_bytes = 48; 1046644e2f0SJens Wiklander if ((algo != 0) && (algo != TEE_ALG_ECDSA_P384) && 1056644e2f0SJens Wiklander (algo != TEE_ALG_ECDH_P384)) 1066644e2f0SJens Wiklander return TEE_ERROR_BAD_PARAMETERS; 1076644e2f0SJens Wiklander break; 1086644e2f0SJens Wiklander case TEE_ECC_CURVE_NIST_P521: 1096644e2f0SJens Wiklander *key_size_bits = 521; 1106644e2f0SJens Wiklander /* 1116644e2f0SJens Wiklander * set 66 instead of 65 wrt to Libtomcrypt documentation as 1126644e2f0SJens Wiklander * if it the real key size 1136644e2f0SJens Wiklander */ 1146644e2f0SJens Wiklander *key_size_bytes = 66; 1156644e2f0SJens Wiklander if ((algo != 0) && (algo != TEE_ALG_ECDSA_P521) && 1166644e2f0SJens Wiklander (algo != TEE_ALG_ECDH_P521)) 1176644e2f0SJens Wiklander return TEE_ERROR_BAD_PARAMETERS; 1186644e2f0SJens Wiklander break; 1196644e2f0SJens Wiklander default: 1206644e2f0SJens Wiklander *key_size_bits = 0; 1216644e2f0SJens Wiklander *key_size_bytes = 0; 1226644e2f0SJens Wiklander return TEE_ERROR_NOT_SUPPORTED; 1236644e2f0SJens Wiklander } 1246644e2f0SJens Wiklander 1256644e2f0SJens Wiklander return TEE_SUCCESS; 1266644e2f0SJens Wiklander } 1276644e2f0SJens Wiklander 1286644e2f0SJens Wiklander TEE_Result crypto_acipher_gen_ecc_key(struct ecc_keypair *key) 1296644e2f0SJens Wiklander { 1306644e2f0SJens Wiklander TEE_Result res; 1316644e2f0SJens Wiklander ecc_key ltc_tmp_key; 1326644e2f0SJens Wiklander int ltc_res; 1336644e2f0SJens Wiklander size_t key_size_bytes = 0; 1346644e2f0SJens Wiklander size_t key_size_bits = 0; 1356644e2f0SJens Wiklander 1366644e2f0SJens Wiklander res = ecc_get_keysize(key->curve, 0, &key_size_bytes, &key_size_bits); 1376644e2f0SJens Wiklander if (res != TEE_SUCCESS) 1386644e2f0SJens Wiklander return res; 1396644e2f0SJens Wiklander 1406644e2f0SJens Wiklander /* Generate the ECC key */ 141*1f3b1115SJens Wiklander ltc_res = ecc_make_key(NULL, find_prng("prng_crypto"), 1426644e2f0SJens Wiklander key_size_bytes, <c_tmp_key); 1436644e2f0SJens Wiklander if (ltc_res != CRYPT_OK) 1446644e2f0SJens Wiklander return TEE_ERROR_BAD_PARAMETERS; 1456644e2f0SJens Wiklander 1466644e2f0SJens Wiklander /* check the size of the keys */ 1476644e2f0SJens Wiklander if (((size_t)mp_count_bits(ltc_tmp_key.pubkey.x) > key_size_bits) || 1486644e2f0SJens Wiklander ((size_t)mp_count_bits(ltc_tmp_key.pubkey.y) > key_size_bits) || 1496644e2f0SJens Wiklander ((size_t)mp_count_bits(ltc_tmp_key.k) > key_size_bits)) { 1506644e2f0SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS; 1516644e2f0SJens Wiklander goto exit; 1526644e2f0SJens Wiklander } 1536644e2f0SJens Wiklander 1546644e2f0SJens Wiklander /* check LTC is returning z==1 */ 1556644e2f0SJens Wiklander if (mp_count_bits(ltc_tmp_key.pubkey.z) != 1) { 1566644e2f0SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS; 1576644e2f0SJens Wiklander goto exit; 1586644e2f0SJens Wiklander } 1596644e2f0SJens Wiklander 1606644e2f0SJens Wiklander /* Copy the key */ 1616644e2f0SJens Wiklander ltc_mp.copy(ltc_tmp_key.k, key->d); 1626644e2f0SJens Wiklander ltc_mp.copy(ltc_tmp_key.pubkey.x, key->x); 1636644e2f0SJens Wiklander ltc_mp.copy(ltc_tmp_key.pubkey.y, key->y); 1646644e2f0SJens Wiklander 1656644e2f0SJens Wiklander res = TEE_SUCCESS; 1666644e2f0SJens Wiklander 1676644e2f0SJens Wiklander exit: 1686644e2f0SJens Wiklander ecc_free(<c_tmp_key); /* Free the temporary key */ 1696644e2f0SJens Wiklander return res; 1706644e2f0SJens Wiklander } 1716644e2f0SJens Wiklander 1726644e2f0SJens Wiklander static TEE_Result ecc_compute_key_idx(ecc_key *ltc_key, size_t keysize) 1736644e2f0SJens Wiklander { 1746644e2f0SJens Wiklander size_t x; 1756644e2f0SJens Wiklander 1766644e2f0SJens Wiklander for (x = 0; ((int)keysize > ltc_ecc_sets[x].size) && 1776644e2f0SJens Wiklander (ltc_ecc_sets[x].size != 0); 1786644e2f0SJens Wiklander x++) 1796644e2f0SJens Wiklander ; 1806644e2f0SJens Wiklander keysize = (size_t)ltc_ecc_sets[x].size; 1816644e2f0SJens Wiklander 1826644e2f0SJens Wiklander if ((keysize > ECC_MAXSIZE) || (ltc_ecc_sets[x].size == 0)) 1836644e2f0SJens Wiklander return TEE_ERROR_BAD_PARAMETERS; 1846644e2f0SJens Wiklander 1856644e2f0SJens Wiklander ltc_key->idx = -1; 1866644e2f0SJens Wiklander ltc_key->dp = <c_ecc_sets[x]; 1876644e2f0SJens Wiklander 1886644e2f0SJens Wiklander return TEE_SUCCESS; 1896644e2f0SJens Wiklander } 1906644e2f0SJens Wiklander 1916644e2f0SJens Wiklander /* 1926644e2f0SJens Wiklander * Given a keypair "key", populate the Libtomcrypt private key "ltc_key" 1936644e2f0SJens Wiklander * It also returns the key size, in bytes 1946644e2f0SJens Wiklander */ 1956644e2f0SJens Wiklander static TEE_Result ecc_populate_ltc_private_key(ecc_key *ltc_key, 1966644e2f0SJens Wiklander struct ecc_keypair *key, 1976644e2f0SJens Wiklander uint32_t algo, 1986644e2f0SJens Wiklander size_t *key_size_bytes) 1996644e2f0SJens Wiklander { 2006644e2f0SJens Wiklander TEE_Result res; 2016644e2f0SJens Wiklander size_t key_size_bits; 2026644e2f0SJens Wiklander 2036644e2f0SJens Wiklander memset(ltc_key, 0, sizeof(*ltc_key)); 2046644e2f0SJens Wiklander ltc_key->type = PK_PRIVATE; 2056644e2f0SJens Wiklander ltc_key->k = key->d; 2066644e2f0SJens Wiklander 2076644e2f0SJens Wiklander /* compute the index of the ecc curve */ 2086644e2f0SJens Wiklander res = ecc_get_keysize(key->curve, algo, 2096644e2f0SJens Wiklander key_size_bytes, &key_size_bits); 2106644e2f0SJens Wiklander if (res != TEE_SUCCESS) 2116644e2f0SJens Wiklander return res; 2126644e2f0SJens Wiklander 2136644e2f0SJens Wiklander return ecc_compute_key_idx(ltc_key, *key_size_bytes); 2146644e2f0SJens Wiklander } 2156644e2f0SJens Wiklander 2166644e2f0SJens Wiklander /* 2176644e2f0SJens Wiklander * Given a public "key", populate the Libtomcrypt public key "ltc_key" 2186644e2f0SJens Wiklander * It also returns the key size, in bytes 2196644e2f0SJens Wiklander */ 2206644e2f0SJens Wiklander static TEE_Result ecc_populate_ltc_public_key(ecc_key *ltc_key, 2216644e2f0SJens Wiklander struct ecc_public_key *key, 2226644e2f0SJens Wiklander void *key_z, 2236644e2f0SJens Wiklander uint32_t algo, 2246644e2f0SJens Wiklander size_t *key_size_bytes) 2256644e2f0SJens Wiklander { 2266644e2f0SJens Wiklander TEE_Result res; 2276644e2f0SJens Wiklander size_t key_size_bits; 2286644e2f0SJens Wiklander uint8_t one[1] = { 1 }; 2296644e2f0SJens Wiklander 2306644e2f0SJens Wiklander 2316644e2f0SJens Wiklander memset(ltc_key, 0, sizeof(*ltc_key)); 2326644e2f0SJens Wiklander ltc_key->type = PK_PUBLIC; 2336644e2f0SJens Wiklander ltc_key->pubkey.x = key->x; 2346644e2f0SJens Wiklander ltc_key->pubkey.y = key->y; 2356644e2f0SJens Wiklander ltc_key->pubkey.z = key_z; 2366644e2f0SJens Wiklander mp_read_unsigned_bin(ltc_key->pubkey.z, one, sizeof(one)); 2376644e2f0SJens Wiklander 2386644e2f0SJens Wiklander /* compute the index of the ecc curve */ 2396644e2f0SJens Wiklander res = ecc_get_keysize(key->curve, algo, 2406644e2f0SJens Wiklander key_size_bytes, &key_size_bits); 2416644e2f0SJens Wiklander if (res != TEE_SUCCESS) 2426644e2f0SJens Wiklander return res; 2436644e2f0SJens Wiklander 2446644e2f0SJens Wiklander return ecc_compute_key_idx(ltc_key, *key_size_bytes); 2456644e2f0SJens Wiklander } 2466644e2f0SJens Wiklander 2476644e2f0SJens Wiklander TEE_Result crypto_acipher_ecc_sign(uint32_t algo, struct ecc_keypair *key, 2486644e2f0SJens Wiklander const uint8_t *msg, size_t msg_len, 2496644e2f0SJens Wiklander uint8_t *sig, size_t *sig_len) 2506644e2f0SJens Wiklander { 2516644e2f0SJens Wiklander TEE_Result res; 2526644e2f0SJens Wiklander int ltc_res; 2536644e2f0SJens Wiklander void *r, *s; 2546644e2f0SJens Wiklander size_t key_size_bytes; 2556644e2f0SJens Wiklander ecc_key ltc_key; 2566644e2f0SJens Wiklander 2576644e2f0SJens Wiklander if (algo == 0) { 2586644e2f0SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS; 2596644e2f0SJens Wiklander goto err; 2606644e2f0SJens Wiklander } 2616644e2f0SJens Wiklander 2626644e2f0SJens Wiklander res = ecc_populate_ltc_private_key(<c_key, key, algo, 2636644e2f0SJens Wiklander &key_size_bytes); 2646644e2f0SJens Wiklander if (res != TEE_SUCCESS) 2656644e2f0SJens Wiklander goto err; 2666644e2f0SJens Wiklander 2676644e2f0SJens Wiklander if (*sig_len < 2 * key_size_bytes) { 2686644e2f0SJens Wiklander *sig_len = 2 * key_size_bytes; 2696644e2f0SJens Wiklander res = TEE_ERROR_SHORT_BUFFER; 2706644e2f0SJens Wiklander goto err; 2716644e2f0SJens Wiklander } 2726644e2f0SJens Wiklander 2736644e2f0SJens Wiklander ltc_res = mp_init_multi(&r, &s, NULL); 2746644e2f0SJens Wiklander if (ltc_res != CRYPT_OK) { 2756644e2f0SJens Wiklander res = TEE_ERROR_OUT_OF_MEMORY; 2766644e2f0SJens Wiklander goto err; 2776644e2f0SJens Wiklander } 2786644e2f0SJens Wiklander 2796644e2f0SJens Wiklander ltc_res = ecc_sign_hash_raw(msg, msg_len, r, s, 280*1f3b1115SJens Wiklander NULL, find_prng("prng_crypto"), <c_key); 2816644e2f0SJens Wiklander 2826644e2f0SJens Wiklander if (ltc_res == CRYPT_OK) { 2836644e2f0SJens Wiklander *sig_len = 2 * key_size_bytes; 2846644e2f0SJens Wiklander memset(sig, 0, *sig_len); 2856644e2f0SJens Wiklander mp_to_unsigned_bin(r, (uint8_t *)sig + *sig_len/2 - 2866644e2f0SJens Wiklander mp_unsigned_bin_size(r)); 2876644e2f0SJens Wiklander mp_to_unsigned_bin(s, (uint8_t *)sig + *sig_len - 2886644e2f0SJens Wiklander mp_unsigned_bin_size(s)); 2896644e2f0SJens Wiklander res = TEE_SUCCESS; 2906644e2f0SJens Wiklander } else { 2916644e2f0SJens Wiklander res = TEE_ERROR_GENERIC; 2926644e2f0SJens Wiklander } 2936644e2f0SJens Wiklander 2946644e2f0SJens Wiklander mp_clear_multi(r, s, NULL); 2956644e2f0SJens Wiklander 2966644e2f0SJens Wiklander err: 2976644e2f0SJens Wiklander return res; 2986644e2f0SJens Wiklander } 2996644e2f0SJens Wiklander 3006644e2f0SJens Wiklander TEE_Result crypto_acipher_ecc_verify(uint32_t algo, struct ecc_public_key *key, 3016644e2f0SJens Wiklander const uint8_t *msg, size_t msg_len, 3026644e2f0SJens Wiklander const uint8_t *sig, size_t sig_len) 3036644e2f0SJens Wiklander { 3046644e2f0SJens Wiklander TEE_Result res; 3056644e2f0SJens Wiklander int ltc_stat; 3066644e2f0SJens Wiklander int ltc_res; 3076644e2f0SJens Wiklander void *r; 3086644e2f0SJens Wiklander void *s; 3096644e2f0SJens Wiklander void *key_z; 3106644e2f0SJens Wiklander size_t key_size_bytes; 3116644e2f0SJens Wiklander ecc_key ltc_key; 3126644e2f0SJens Wiklander 3136644e2f0SJens Wiklander if (algo == 0) 3146644e2f0SJens Wiklander return TEE_ERROR_BAD_PARAMETERS; 3156644e2f0SJens Wiklander 3166644e2f0SJens Wiklander ltc_res = mp_init_multi(&key_z, &r, &s, NULL); 3176644e2f0SJens Wiklander if (ltc_res != CRYPT_OK) 3186644e2f0SJens Wiklander return TEE_ERROR_OUT_OF_MEMORY; 3196644e2f0SJens Wiklander 3206644e2f0SJens Wiklander res = ecc_populate_ltc_public_key(<c_key, key, key_z, algo, 3216644e2f0SJens Wiklander &key_size_bytes); 3226644e2f0SJens Wiklander if (res != TEE_SUCCESS) 3236644e2f0SJens Wiklander goto out; 3246644e2f0SJens Wiklander 3256644e2f0SJens Wiklander /* check keysize vs sig_len */ 3266644e2f0SJens Wiklander if ((key_size_bytes * 2) != sig_len) { 3276644e2f0SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS; 3286644e2f0SJens Wiklander goto out; 3296644e2f0SJens Wiklander } 3306644e2f0SJens Wiklander 3316644e2f0SJens Wiklander mp_read_unsigned_bin(r, (uint8_t *)sig, sig_len/2); 3326644e2f0SJens Wiklander mp_read_unsigned_bin(s, (uint8_t *)sig + sig_len/2, sig_len/2); 3336644e2f0SJens Wiklander 3346644e2f0SJens Wiklander ltc_res = ecc_verify_hash_raw(r, s, msg, msg_len, <c_stat, <c_key); 3356644e2f0SJens Wiklander res = convert_ltc_verify_status(ltc_res, ltc_stat); 3366644e2f0SJens Wiklander out: 3376644e2f0SJens Wiklander mp_clear_multi(key_z, r, s, NULL); 3386644e2f0SJens Wiklander return res; 3396644e2f0SJens Wiklander } 3406644e2f0SJens Wiklander 3416644e2f0SJens Wiklander TEE_Result crypto_acipher_ecc_shared_secret(struct ecc_keypair *private_key, 3426644e2f0SJens Wiklander struct ecc_public_key *public_key, 3436644e2f0SJens Wiklander void *secret, 3446644e2f0SJens Wiklander unsigned long *secret_len) 3456644e2f0SJens Wiklander { 3466644e2f0SJens Wiklander TEE_Result res; 3476644e2f0SJens Wiklander int ltc_res; 3486644e2f0SJens Wiklander ecc_key ltc_private_key; 3496644e2f0SJens Wiklander ecc_key ltc_public_key; 3506644e2f0SJens Wiklander size_t key_size_bytes; 3516644e2f0SJens Wiklander void *key_z; 3526644e2f0SJens Wiklander 3536644e2f0SJens Wiklander /* Check the curves are the same */ 3546644e2f0SJens Wiklander if (private_key->curve != public_key->curve) 3556644e2f0SJens Wiklander return TEE_ERROR_BAD_PARAMETERS; 3566644e2f0SJens Wiklander 3576644e2f0SJens Wiklander ltc_res = mp_init_multi(&key_z, NULL); 3586644e2f0SJens Wiklander if (ltc_res != CRYPT_OK) 3596644e2f0SJens Wiklander return TEE_ERROR_OUT_OF_MEMORY; 3606644e2f0SJens Wiklander 3616644e2f0SJens Wiklander res = ecc_populate_ltc_private_key(<c_private_key, private_key, 3626644e2f0SJens Wiklander 0, &key_size_bytes); 3636644e2f0SJens Wiklander if (res != TEE_SUCCESS) 3646644e2f0SJens Wiklander goto out; 3656644e2f0SJens Wiklander res = ecc_populate_ltc_public_key(<c_public_key, public_key, key_z, 3666644e2f0SJens Wiklander 0, &key_size_bytes); 3676644e2f0SJens Wiklander if (res != TEE_SUCCESS) 3686644e2f0SJens Wiklander goto out; 3696644e2f0SJens Wiklander 3706644e2f0SJens Wiklander ltc_res = ecc_shared_secret(<c_private_key, <c_public_key, 3716644e2f0SJens Wiklander secret, secret_len); 3726644e2f0SJens Wiklander if (ltc_res == CRYPT_OK) 3736644e2f0SJens Wiklander res = TEE_SUCCESS; 3746644e2f0SJens Wiklander else 3756644e2f0SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS; 3766644e2f0SJens Wiklander 3776644e2f0SJens Wiklander out: 3786644e2f0SJens Wiklander mp_clear_multi(key_z, NULL); 3796644e2f0SJens Wiklander return res; 3806644e2f0SJens Wiklander } 381