1*6644e2f0SJens Wiklander // SPDX-License-Identifier: BSD-2-Clause 2*6644e2f0SJens Wiklander /* 3*6644e2f0SJens Wiklander * Copyright (c) 2014-2019, Linaro Limited 4*6644e2f0SJens Wiklander */ 5*6644e2f0SJens Wiklander 6*6644e2f0SJens Wiklander #include <crypto/crypto.h> 7*6644e2f0SJens Wiklander #include <stdlib.h> 8*6644e2f0SJens Wiklander #include <string.h> 9*6644e2f0SJens Wiklander #include <tee_api_types.h> 10*6644e2f0SJens Wiklander #include <tomcrypt.h> 11*6644e2f0SJens Wiklander #include <trace.h> 12*6644e2f0SJens Wiklander #include <utee_defines.h> 13*6644e2f0SJens Wiklander 14*6644e2f0SJens Wiklander #include "acipher_helpers.h" 15*6644e2f0SJens Wiklander 16*6644e2f0SJens Wiklander TEE_Result crypto_acipher_alloc_ecc_keypair(struct ecc_keypair *s, 17*6644e2f0SJens Wiklander size_t key_size_bits __unused) 18*6644e2f0SJens Wiklander { 19*6644e2f0SJens Wiklander memset(s, 0, sizeof(*s)); 20*6644e2f0SJens Wiklander if (!bn_alloc_max(&s->d)) 21*6644e2f0SJens Wiklander goto err; 22*6644e2f0SJens Wiklander if (!bn_alloc_max(&s->x)) 23*6644e2f0SJens Wiklander goto err; 24*6644e2f0SJens Wiklander if (!bn_alloc_max(&s->y)) 25*6644e2f0SJens Wiklander goto err; 26*6644e2f0SJens Wiklander return TEE_SUCCESS; 27*6644e2f0SJens Wiklander err: 28*6644e2f0SJens Wiklander crypto_bignum_free(s->d); 29*6644e2f0SJens Wiklander crypto_bignum_free(s->x); 30*6644e2f0SJens Wiklander crypto_bignum_free(s->y); 31*6644e2f0SJens Wiklander return TEE_ERROR_OUT_OF_MEMORY; 32*6644e2f0SJens Wiklander } 33*6644e2f0SJens Wiklander 34*6644e2f0SJens Wiklander TEE_Result crypto_acipher_alloc_ecc_public_key(struct ecc_public_key *s, 35*6644e2f0SJens Wiklander size_t key_size_bits __unused) 36*6644e2f0SJens Wiklander { 37*6644e2f0SJens Wiklander memset(s, 0, sizeof(*s)); 38*6644e2f0SJens Wiklander if (!bn_alloc_max(&s->x)) 39*6644e2f0SJens Wiklander goto err; 40*6644e2f0SJens Wiklander if (!bn_alloc_max(&s->y)) 41*6644e2f0SJens Wiklander goto err; 42*6644e2f0SJens Wiklander return TEE_SUCCESS; 43*6644e2f0SJens Wiklander err: 44*6644e2f0SJens Wiklander crypto_bignum_free(s->x); 45*6644e2f0SJens Wiklander crypto_bignum_free(s->y); 46*6644e2f0SJens Wiklander return TEE_ERROR_OUT_OF_MEMORY; 47*6644e2f0SJens Wiklander } 48*6644e2f0SJens Wiklander 49*6644e2f0SJens Wiklander void crypto_acipher_free_ecc_public_key(struct ecc_public_key *s) 50*6644e2f0SJens Wiklander { 51*6644e2f0SJens Wiklander if (!s) 52*6644e2f0SJens Wiklander return; 53*6644e2f0SJens Wiklander 54*6644e2f0SJens Wiklander crypto_bignum_free(s->x); 55*6644e2f0SJens Wiklander crypto_bignum_free(s->y); 56*6644e2f0SJens Wiklander } 57*6644e2f0SJens Wiklander 58*6644e2f0SJens Wiklander /* 59*6644e2f0SJens Wiklander * curve is part of TEE_ECC_CURVE_NIST_P192,... 60*6644e2f0SJens Wiklander * algo is part of TEE_ALG_ECDSA_P192,..., and 0 if we do not have it 61*6644e2f0SJens Wiklander */ 62*6644e2f0SJens Wiklander static TEE_Result ecc_get_keysize(uint32_t curve, uint32_t algo, 63*6644e2f0SJens Wiklander size_t *key_size_bytes, size_t *key_size_bits) 64*6644e2f0SJens Wiklander { 65*6644e2f0SJens Wiklander /* 66*6644e2f0SJens Wiklander * Excerpt of libtomcrypt documentation: 67*6644e2f0SJens Wiklander * ecc_make_key(... key_size ...): The keysize is the size of the 68*6644e2f0SJens Wiklander * modulus in bytes desired. Currently directly supported values 69*6644e2f0SJens Wiklander * are 12, 16, 20, 24, 28, 32, 48, and 65 bytes which correspond 70*6644e2f0SJens Wiklander * to key sizes of 112, 128, 160, 192, 224, 256, 384, and 521 bits 71*6644e2f0SJens Wiklander * respectively. 72*6644e2f0SJens Wiklander */ 73*6644e2f0SJens Wiklander 74*6644e2f0SJens Wiklander /* 75*6644e2f0SJens Wiklander * Note GPv1.1 indicates TEE_ALG_ECDH_NIST_P192_DERIVE_SHARED_SECRET 76*6644e2f0SJens Wiklander * but defines TEE_ALG_ECDH_P192 77*6644e2f0SJens Wiklander */ 78*6644e2f0SJens Wiklander 79*6644e2f0SJens Wiklander switch (curve) { 80*6644e2f0SJens Wiklander case TEE_ECC_CURVE_NIST_P192: 81*6644e2f0SJens Wiklander *key_size_bits = 192; 82*6644e2f0SJens Wiklander *key_size_bytes = 24; 83*6644e2f0SJens Wiklander if ((algo != 0) && (algo != TEE_ALG_ECDSA_P192) && 84*6644e2f0SJens Wiklander (algo != TEE_ALG_ECDH_P192)) 85*6644e2f0SJens Wiklander return TEE_ERROR_BAD_PARAMETERS; 86*6644e2f0SJens Wiklander break; 87*6644e2f0SJens Wiklander case TEE_ECC_CURVE_NIST_P224: 88*6644e2f0SJens Wiklander *key_size_bits = 224; 89*6644e2f0SJens Wiklander *key_size_bytes = 28; 90*6644e2f0SJens Wiklander if ((algo != 0) && (algo != TEE_ALG_ECDSA_P224) && 91*6644e2f0SJens Wiklander (algo != TEE_ALG_ECDH_P224)) 92*6644e2f0SJens Wiklander return TEE_ERROR_BAD_PARAMETERS; 93*6644e2f0SJens Wiklander break; 94*6644e2f0SJens Wiklander case TEE_ECC_CURVE_NIST_P256: 95*6644e2f0SJens Wiklander *key_size_bits = 256; 96*6644e2f0SJens Wiklander *key_size_bytes = 32; 97*6644e2f0SJens Wiklander if ((algo != 0) && (algo != TEE_ALG_ECDSA_P256) && 98*6644e2f0SJens Wiklander (algo != TEE_ALG_ECDH_P256)) 99*6644e2f0SJens Wiklander return TEE_ERROR_BAD_PARAMETERS; 100*6644e2f0SJens Wiklander break; 101*6644e2f0SJens Wiklander case TEE_ECC_CURVE_NIST_P384: 102*6644e2f0SJens Wiklander *key_size_bits = 384; 103*6644e2f0SJens Wiklander *key_size_bytes = 48; 104*6644e2f0SJens Wiklander if ((algo != 0) && (algo != TEE_ALG_ECDSA_P384) && 105*6644e2f0SJens Wiklander (algo != TEE_ALG_ECDH_P384)) 106*6644e2f0SJens Wiklander return TEE_ERROR_BAD_PARAMETERS; 107*6644e2f0SJens Wiklander break; 108*6644e2f0SJens Wiklander case TEE_ECC_CURVE_NIST_P521: 109*6644e2f0SJens Wiklander *key_size_bits = 521; 110*6644e2f0SJens Wiklander /* 111*6644e2f0SJens Wiklander * set 66 instead of 65 wrt to Libtomcrypt documentation as 112*6644e2f0SJens Wiklander * if it the real key size 113*6644e2f0SJens Wiklander */ 114*6644e2f0SJens Wiklander *key_size_bytes = 66; 115*6644e2f0SJens Wiklander if ((algo != 0) && (algo != TEE_ALG_ECDSA_P521) && 116*6644e2f0SJens Wiklander (algo != TEE_ALG_ECDH_P521)) 117*6644e2f0SJens Wiklander return TEE_ERROR_BAD_PARAMETERS; 118*6644e2f0SJens Wiklander break; 119*6644e2f0SJens Wiklander default: 120*6644e2f0SJens Wiklander *key_size_bits = 0; 121*6644e2f0SJens Wiklander *key_size_bytes = 0; 122*6644e2f0SJens Wiklander return TEE_ERROR_NOT_SUPPORTED; 123*6644e2f0SJens Wiklander } 124*6644e2f0SJens Wiklander 125*6644e2f0SJens Wiklander return TEE_SUCCESS; 126*6644e2f0SJens Wiklander } 127*6644e2f0SJens Wiklander 128*6644e2f0SJens Wiklander TEE_Result crypto_acipher_gen_ecc_key(struct ecc_keypair *key) 129*6644e2f0SJens Wiklander { 130*6644e2f0SJens Wiklander TEE_Result res; 131*6644e2f0SJens Wiklander ecc_key ltc_tmp_key; 132*6644e2f0SJens Wiklander int ltc_res; 133*6644e2f0SJens Wiklander size_t key_size_bytes = 0; 134*6644e2f0SJens Wiklander size_t key_size_bits = 0; 135*6644e2f0SJens Wiklander 136*6644e2f0SJens Wiklander res = ecc_get_keysize(key->curve, 0, &key_size_bytes, &key_size_bits); 137*6644e2f0SJens Wiklander if (res != TEE_SUCCESS) 138*6644e2f0SJens Wiklander return res; 139*6644e2f0SJens Wiklander 140*6644e2f0SJens Wiklander /* Generate the ECC key */ 141*6644e2f0SJens Wiklander ltc_res = ecc_make_key(NULL, find_prng("prng_mpa"), 142*6644e2f0SJens Wiklander key_size_bytes, <c_tmp_key); 143*6644e2f0SJens Wiklander if (ltc_res != CRYPT_OK) 144*6644e2f0SJens Wiklander return TEE_ERROR_BAD_PARAMETERS; 145*6644e2f0SJens Wiklander 146*6644e2f0SJens Wiklander /* check the size of the keys */ 147*6644e2f0SJens Wiklander if (((size_t)mp_count_bits(ltc_tmp_key.pubkey.x) > key_size_bits) || 148*6644e2f0SJens Wiklander ((size_t)mp_count_bits(ltc_tmp_key.pubkey.y) > key_size_bits) || 149*6644e2f0SJens Wiklander ((size_t)mp_count_bits(ltc_tmp_key.k) > key_size_bits)) { 150*6644e2f0SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS; 151*6644e2f0SJens Wiklander goto exit; 152*6644e2f0SJens Wiklander } 153*6644e2f0SJens Wiklander 154*6644e2f0SJens Wiklander /* check LTC is returning z==1 */ 155*6644e2f0SJens Wiklander if (mp_count_bits(ltc_tmp_key.pubkey.z) != 1) { 156*6644e2f0SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS; 157*6644e2f0SJens Wiklander goto exit; 158*6644e2f0SJens Wiklander } 159*6644e2f0SJens Wiklander 160*6644e2f0SJens Wiklander /* Copy the key */ 161*6644e2f0SJens Wiklander ltc_mp.copy(ltc_tmp_key.k, key->d); 162*6644e2f0SJens Wiklander ltc_mp.copy(ltc_tmp_key.pubkey.x, key->x); 163*6644e2f0SJens Wiklander ltc_mp.copy(ltc_tmp_key.pubkey.y, key->y); 164*6644e2f0SJens Wiklander 165*6644e2f0SJens Wiklander res = TEE_SUCCESS; 166*6644e2f0SJens Wiklander 167*6644e2f0SJens Wiklander exit: 168*6644e2f0SJens Wiklander ecc_free(<c_tmp_key); /* Free the temporary key */ 169*6644e2f0SJens Wiklander return res; 170*6644e2f0SJens Wiklander } 171*6644e2f0SJens Wiklander 172*6644e2f0SJens Wiklander static TEE_Result ecc_compute_key_idx(ecc_key *ltc_key, size_t keysize) 173*6644e2f0SJens Wiklander { 174*6644e2f0SJens Wiklander size_t x; 175*6644e2f0SJens Wiklander 176*6644e2f0SJens Wiklander for (x = 0; ((int)keysize > ltc_ecc_sets[x].size) && 177*6644e2f0SJens Wiklander (ltc_ecc_sets[x].size != 0); 178*6644e2f0SJens Wiklander x++) 179*6644e2f0SJens Wiklander ; 180*6644e2f0SJens Wiklander keysize = (size_t)ltc_ecc_sets[x].size; 181*6644e2f0SJens Wiklander 182*6644e2f0SJens Wiklander if ((keysize > ECC_MAXSIZE) || (ltc_ecc_sets[x].size == 0)) 183*6644e2f0SJens Wiklander return TEE_ERROR_BAD_PARAMETERS; 184*6644e2f0SJens Wiklander 185*6644e2f0SJens Wiklander ltc_key->idx = -1; 186*6644e2f0SJens Wiklander ltc_key->dp = <c_ecc_sets[x]; 187*6644e2f0SJens Wiklander 188*6644e2f0SJens Wiklander return TEE_SUCCESS; 189*6644e2f0SJens Wiklander } 190*6644e2f0SJens Wiklander 191*6644e2f0SJens Wiklander /* 192*6644e2f0SJens Wiklander * Given a keypair "key", populate the Libtomcrypt private key "ltc_key" 193*6644e2f0SJens Wiklander * It also returns the key size, in bytes 194*6644e2f0SJens Wiklander */ 195*6644e2f0SJens Wiklander static TEE_Result ecc_populate_ltc_private_key(ecc_key *ltc_key, 196*6644e2f0SJens Wiklander struct ecc_keypair *key, 197*6644e2f0SJens Wiklander uint32_t algo, 198*6644e2f0SJens Wiklander size_t *key_size_bytes) 199*6644e2f0SJens Wiklander { 200*6644e2f0SJens Wiklander TEE_Result res; 201*6644e2f0SJens Wiklander size_t key_size_bits; 202*6644e2f0SJens Wiklander 203*6644e2f0SJens Wiklander memset(ltc_key, 0, sizeof(*ltc_key)); 204*6644e2f0SJens Wiklander ltc_key->type = PK_PRIVATE; 205*6644e2f0SJens Wiklander ltc_key->k = key->d; 206*6644e2f0SJens Wiklander 207*6644e2f0SJens Wiklander /* compute the index of the ecc curve */ 208*6644e2f0SJens Wiklander res = ecc_get_keysize(key->curve, algo, 209*6644e2f0SJens Wiklander key_size_bytes, &key_size_bits); 210*6644e2f0SJens Wiklander if (res != TEE_SUCCESS) 211*6644e2f0SJens Wiklander return res; 212*6644e2f0SJens Wiklander 213*6644e2f0SJens Wiklander return ecc_compute_key_idx(ltc_key, *key_size_bytes); 214*6644e2f0SJens Wiklander } 215*6644e2f0SJens Wiklander 216*6644e2f0SJens Wiklander /* 217*6644e2f0SJens Wiklander * Given a public "key", populate the Libtomcrypt public key "ltc_key" 218*6644e2f0SJens Wiklander * It also returns the key size, in bytes 219*6644e2f0SJens Wiklander */ 220*6644e2f0SJens Wiklander static TEE_Result ecc_populate_ltc_public_key(ecc_key *ltc_key, 221*6644e2f0SJens Wiklander struct ecc_public_key *key, 222*6644e2f0SJens Wiklander void *key_z, 223*6644e2f0SJens Wiklander uint32_t algo, 224*6644e2f0SJens Wiklander size_t *key_size_bytes) 225*6644e2f0SJens Wiklander { 226*6644e2f0SJens Wiklander TEE_Result res; 227*6644e2f0SJens Wiklander size_t key_size_bits; 228*6644e2f0SJens Wiklander uint8_t one[1] = { 1 }; 229*6644e2f0SJens Wiklander 230*6644e2f0SJens Wiklander 231*6644e2f0SJens Wiklander memset(ltc_key, 0, sizeof(*ltc_key)); 232*6644e2f0SJens Wiklander ltc_key->type = PK_PUBLIC; 233*6644e2f0SJens Wiklander ltc_key->pubkey.x = key->x; 234*6644e2f0SJens Wiklander ltc_key->pubkey.y = key->y; 235*6644e2f0SJens Wiklander ltc_key->pubkey.z = key_z; 236*6644e2f0SJens Wiklander mp_read_unsigned_bin(ltc_key->pubkey.z, one, sizeof(one)); 237*6644e2f0SJens Wiklander 238*6644e2f0SJens Wiklander /* compute the index of the ecc curve */ 239*6644e2f0SJens Wiklander res = ecc_get_keysize(key->curve, algo, 240*6644e2f0SJens Wiklander key_size_bytes, &key_size_bits); 241*6644e2f0SJens Wiklander if (res != TEE_SUCCESS) 242*6644e2f0SJens Wiklander return res; 243*6644e2f0SJens Wiklander 244*6644e2f0SJens Wiklander return ecc_compute_key_idx(ltc_key, *key_size_bytes); 245*6644e2f0SJens Wiklander } 246*6644e2f0SJens Wiklander 247*6644e2f0SJens Wiklander TEE_Result crypto_acipher_ecc_sign(uint32_t algo, struct ecc_keypair *key, 248*6644e2f0SJens Wiklander const uint8_t *msg, size_t msg_len, 249*6644e2f0SJens Wiklander uint8_t *sig, size_t *sig_len) 250*6644e2f0SJens Wiklander { 251*6644e2f0SJens Wiklander TEE_Result res; 252*6644e2f0SJens Wiklander int ltc_res; 253*6644e2f0SJens Wiklander void *r, *s; 254*6644e2f0SJens Wiklander size_t key_size_bytes; 255*6644e2f0SJens Wiklander ecc_key ltc_key; 256*6644e2f0SJens Wiklander 257*6644e2f0SJens Wiklander if (algo == 0) { 258*6644e2f0SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS; 259*6644e2f0SJens Wiklander goto err; 260*6644e2f0SJens Wiklander } 261*6644e2f0SJens Wiklander 262*6644e2f0SJens Wiklander res = ecc_populate_ltc_private_key(<c_key, key, algo, 263*6644e2f0SJens Wiklander &key_size_bytes); 264*6644e2f0SJens Wiklander if (res != TEE_SUCCESS) 265*6644e2f0SJens Wiklander goto err; 266*6644e2f0SJens Wiklander 267*6644e2f0SJens Wiklander if (*sig_len < 2 * key_size_bytes) { 268*6644e2f0SJens Wiklander *sig_len = 2 * key_size_bytes; 269*6644e2f0SJens Wiklander res = TEE_ERROR_SHORT_BUFFER; 270*6644e2f0SJens Wiklander goto err; 271*6644e2f0SJens Wiklander } 272*6644e2f0SJens Wiklander 273*6644e2f0SJens Wiklander ltc_res = mp_init_multi(&r, &s, NULL); 274*6644e2f0SJens Wiklander if (ltc_res != CRYPT_OK) { 275*6644e2f0SJens Wiklander res = TEE_ERROR_OUT_OF_MEMORY; 276*6644e2f0SJens Wiklander goto err; 277*6644e2f0SJens Wiklander } 278*6644e2f0SJens Wiklander 279*6644e2f0SJens Wiklander ltc_res = ecc_sign_hash_raw(msg, msg_len, r, s, 280*6644e2f0SJens Wiklander NULL, find_prng("prng_mpa"), <c_key); 281*6644e2f0SJens Wiklander 282*6644e2f0SJens Wiklander if (ltc_res == CRYPT_OK) { 283*6644e2f0SJens Wiklander *sig_len = 2 * key_size_bytes; 284*6644e2f0SJens Wiklander memset(sig, 0, *sig_len); 285*6644e2f0SJens Wiklander mp_to_unsigned_bin(r, (uint8_t *)sig + *sig_len/2 - 286*6644e2f0SJens Wiklander mp_unsigned_bin_size(r)); 287*6644e2f0SJens Wiklander mp_to_unsigned_bin(s, (uint8_t *)sig + *sig_len - 288*6644e2f0SJens Wiklander mp_unsigned_bin_size(s)); 289*6644e2f0SJens Wiklander res = TEE_SUCCESS; 290*6644e2f0SJens Wiklander } else { 291*6644e2f0SJens Wiklander res = TEE_ERROR_GENERIC; 292*6644e2f0SJens Wiklander } 293*6644e2f0SJens Wiklander 294*6644e2f0SJens Wiklander mp_clear_multi(r, s, NULL); 295*6644e2f0SJens Wiklander 296*6644e2f0SJens Wiklander err: 297*6644e2f0SJens Wiklander return res; 298*6644e2f0SJens Wiklander } 299*6644e2f0SJens Wiklander 300*6644e2f0SJens Wiklander TEE_Result crypto_acipher_ecc_verify(uint32_t algo, struct ecc_public_key *key, 301*6644e2f0SJens Wiklander const uint8_t *msg, size_t msg_len, 302*6644e2f0SJens Wiklander const uint8_t *sig, size_t sig_len) 303*6644e2f0SJens Wiklander { 304*6644e2f0SJens Wiklander TEE_Result res; 305*6644e2f0SJens Wiklander int ltc_stat; 306*6644e2f0SJens Wiklander int ltc_res; 307*6644e2f0SJens Wiklander void *r; 308*6644e2f0SJens Wiklander void *s; 309*6644e2f0SJens Wiklander void *key_z; 310*6644e2f0SJens Wiklander size_t key_size_bytes; 311*6644e2f0SJens Wiklander ecc_key ltc_key; 312*6644e2f0SJens Wiklander 313*6644e2f0SJens Wiklander if (algo == 0) 314*6644e2f0SJens Wiklander return TEE_ERROR_BAD_PARAMETERS; 315*6644e2f0SJens Wiklander 316*6644e2f0SJens Wiklander ltc_res = mp_init_multi(&key_z, &r, &s, NULL); 317*6644e2f0SJens Wiklander if (ltc_res != CRYPT_OK) 318*6644e2f0SJens Wiklander return TEE_ERROR_OUT_OF_MEMORY; 319*6644e2f0SJens Wiklander 320*6644e2f0SJens Wiklander res = ecc_populate_ltc_public_key(<c_key, key, key_z, algo, 321*6644e2f0SJens Wiklander &key_size_bytes); 322*6644e2f0SJens Wiklander if (res != TEE_SUCCESS) 323*6644e2f0SJens Wiklander goto out; 324*6644e2f0SJens Wiklander 325*6644e2f0SJens Wiklander /* check keysize vs sig_len */ 326*6644e2f0SJens Wiklander if ((key_size_bytes * 2) != sig_len) { 327*6644e2f0SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS; 328*6644e2f0SJens Wiklander goto out; 329*6644e2f0SJens Wiklander } 330*6644e2f0SJens Wiklander 331*6644e2f0SJens Wiklander mp_read_unsigned_bin(r, (uint8_t *)sig, sig_len/2); 332*6644e2f0SJens Wiklander mp_read_unsigned_bin(s, (uint8_t *)sig + sig_len/2, sig_len/2); 333*6644e2f0SJens Wiklander 334*6644e2f0SJens Wiklander ltc_res = ecc_verify_hash_raw(r, s, msg, msg_len, <c_stat, <c_key); 335*6644e2f0SJens Wiklander res = convert_ltc_verify_status(ltc_res, ltc_stat); 336*6644e2f0SJens Wiklander out: 337*6644e2f0SJens Wiklander mp_clear_multi(key_z, r, s, NULL); 338*6644e2f0SJens Wiklander return res; 339*6644e2f0SJens Wiklander } 340*6644e2f0SJens Wiklander 341*6644e2f0SJens Wiklander TEE_Result crypto_acipher_ecc_shared_secret(struct ecc_keypair *private_key, 342*6644e2f0SJens Wiklander struct ecc_public_key *public_key, 343*6644e2f0SJens Wiklander void *secret, 344*6644e2f0SJens Wiklander unsigned long *secret_len) 345*6644e2f0SJens Wiklander { 346*6644e2f0SJens Wiklander TEE_Result res; 347*6644e2f0SJens Wiklander int ltc_res; 348*6644e2f0SJens Wiklander ecc_key ltc_private_key; 349*6644e2f0SJens Wiklander ecc_key ltc_public_key; 350*6644e2f0SJens Wiklander size_t key_size_bytes; 351*6644e2f0SJens Wiklander void *key_z; 352*6644e2f0SJens Wiklander 353*6644e2f0SJens Wiklander /* Check the curves are the same */ 354*6644e2f0SJens Wiklander if (private_key->curve != public_key->curve) 355*6644e2f0SJens Wiklander return TEE_ERROR_BAD_PARAMETERS; 356*6644e2f0SJens Wiklander 357*6644e2f0SJens Wiklander ltc_res = mp_init_multi(&key_z, NULL); 358*6644e2f0SJens Wiklander if (ltc_res != CRYPT_OK) 359*6644e2f0SJens Wiklander return TEE_ERROR_OUT_OF_MEMORY; 360*6644e2f0SJens Wiklander 361*6644e2f0SJens Wiklander res = ecc_populate_ltc_private_key(<c_private_key, private_key, 362*6644e2f0SJens Wiklander 0, &key_size_bytes); 363*6644e2f0SJens Wiklander if (res != TEE_SUCCESS) 364*6644e2f0SJens Wiklander goto out; 365*6644e2f0SJens Wiklander res = ecc_populate_ltc_public_key(<c_public_key, public_key, key_z, 366*6644e2f0SJens Wiklander 0, &key_size_bytes); 367*6644e2f0SJens Wiklander if (res != TEE_SUCCESS) 368*6644e2f0SJens Wiklander goto out; 369*6644e2f0SJens Wiklander 370*6644e2f0SJens Wiklander ltc_res = ecc_shared_secret(<c_private_key, <c_public_key, 371*6644e2f0SJens Wiklander secret, secret_len); 372*6644e2f0SJens Wiklander if (ltc_res == CRYPT_OK) 373*6644e2f0SJens Wiklander res = TEE_SUCCESS; 374*6644e2f0SJens Wiklander else 375*6644e2f0SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS; 376*6644e2f0SJens Wiklander 377*6644e2f0SJens Wiklander out: 378*6644e2f0SJens Wiklander mp_clear_multi(key_z, NULL); 379*6644e2f0SJens Wiklander return res; 380*6644e2f0SJens Wiklander } 381