TEE_TYPE_DSA_KEYPAIR = 0xA1000031,
TEE_TYPE_DH_KEYPAIR = 0xA1000032,
#ifdef ECC_IMPLEMENTATION
- TEE_TYPE_ECDSA_PUBLIC_KEY = 0xA0000033,
- TEE_TYPE_ECDSA_KEYPAIR = 0xA1000033,
- TEE_TYPE_ECDH_KEYPAIR = 0xA1000034,
+ TEE_TYPE_ECDSA_PUBLIC_KEY = 0xA0000041,
+ TEE_TYPE_ECDSA_KEYPAIR = 0xA1000041,
+ TEE_TYPE_ECDH_PUBLIC_KEY = 0xA0000042,
+ TEE_TYPE_ECDH_KEYPAIR = 0xA1000042,
#endif // ECC_IMPLEMENTATION
TEE_TYPE_GENERIC_SECRET = 0xA0000000,
TEE_TYPE_CERT_ROOT_GSL = 0xA00000A0, // GPD System Loader root Certificate
// more for application certificate?
} TEE_OBJECT_TYPES;
+#ifdef ECC_IMPLEMENTATION
+typedef enum {
+ TEE_ECC_CURVE_NIST_P192 = 0x00000001,
+ TEE_ECC_CURVE_NIST_P224 = 0x00000002,
+ TEE_ECC_CURVE_NIST_P256 = 0x00000003,
+ TEE_ECC_CURVE_NIST_P384 = 0x00000004,
+ TEE_ECC_CURVE_NIST_P521 = 0x00000005
+} TEE_ECC_CURVE;
+#endif // ECC_IMPLEMENTATION
+
/******************************************************************************
* 6.11 Object or Operation Attributes
******************************************************************************/
TEE_ATTR_RSA_PSS_SALT_LENGTH = 0xF0000A30,
#ifdef ECC_IMPLEMENTATION
- TEE_ATTR_ECDSA_PRIME = 0xD0001041,
- TEE_ATTR_ECDSA_COFF_A = 0xD0001141,
- TEE_ATTR_ECDSA_COFF_B = 0xD0001241,
- TEE_ATTR_ECDSA_GENERATOR_X = 0xD0001341,
- TEE_ATTR_ECDSA_GENERATOR_Y = 0xD0001441,
- TEE_ATTR_ECDSA_ORDER = 0xD0001541,
- TEE_ATTR_ECDSA_PUBLIC_VALUE_X = 0xD0002141,
- TEE_ATTR_ECDSA_PUBLIC_VALUE_Y = 0xD0003141,
- TEE_ATTR_ECDSA_PRIVATE_VALUE = 0xC0000241,
+ TEE_ATTR_ECC_PUBLIC_VALUE_X = 0xD0000141,
+ TEE_ATTR_ECC_PUBLIC_VALUE_Y = 0xD0000241,
+ TEE_ATTR_ECC_PRIVATE_VALUE = 0xC0000341,
+ TEE_ATTR_ECC_CURVE = 0xF0000441,
#endif // ECC_IMPLEMENTATION
//Certificate attribute start
crypto_internal_keydata secret; /* TEE_ATTR_SECRET_VALUE */
crypto_internal_keydata rsa_modulus; /* TEE_ATTR_RSA_MODULUS / TEE_ATTR_DSA_BASE */
crypto_internal_keydata rsa_public; /* TEE_ATTR_RSA_PUBLIC_EXPONENT / TEE_ATTR_DSA_PUBLIC_VALUE */
- crypto_internal_keydata rsa_private; /* TEE_ATTR_RSA_PRIVATE_EXPONENT / TEE_ATTR_DSA_PRIVATE_VALUE */
- crypto_internal_keydata rsa_prime1; /* TEE_ATTR_RSA_PRIME1 / TEE_ATTR_DSA_PRIME */
- crypto_internal_keydata rsa_prime2; /* TEE_ATTR_RSA_PRIME2 / TEE_ATTR_DSA_SUBPRIME */
+ crypto_internal_keydata rsa_private; /* TEE_ATTR_RSA_PRIVATE_EXPONENT / TEE_ATTR_DSA_PRIVATE_VALUE */
+ crypto_internal_keydata rsa_prime1; /* TEE_ATTR_RSA_PRIME1 / TEE_ATTR_DSA_PRIME */
+ crypto_internal_keydata rsa_prime2; /* TEE_ATTR_RSA_PRIME2 / TEE_ATTR_DSA_SUBPRIME */
crypto_internal_keydata rsa_exponent1; /* TEE_ATTR_RSA_EXPONENT1 */
crypto_internal_keydata rsa_exponent2; /* TEE_ATTR_RSA_EXPONENT2 */
- crypto_internal_keydata rsa_coefficient; /* TEE_ATTR_RSA_COEFFICIENT */
+ crypto_internal_keydata rsa_coefficient; /* TEE_ATTR_RSA_COEFFICIENT */
+ crypto_internal_keydata ecc_private; /* TEE_ATTR_ECC_PRIVATE_VALUE */
+ crypto_internal_keydata ecc_public_x; /* TEE_ATTR_ECC_PUBLIC_VALUE_X */
+ crypto_internal_keydata ecc_public_y; /* TEE_ATTR_ECC_PUBLIC_VALUE_Y */
+ uint32_t ecc_curve; /* TEE_ATTR_ECC_CURVE */
} crypto_internal_keystruct;
void crypto_internal_set_engine(int set);
void *dst, size_t *dst_len, void *tag, size_t *tag_len);
int ossl_crypto_ae_dec_final(crypto_internal_operation *op, void *src, size_t src_len,
void *dst, size_t *dst_len, void *tag, size_t tag_len);
+int ossl_ecdsa_sign(crypto_internal_keydata priv_key, const void *src, size_t src_len,
+ void *sig, size_t *sig_len);
+int ossl_ecdsa_verify(uint32_t curve, crypto_internal_keydata pub_x, crypto_internal_keydata pub_y,
+ const void *src, size_t src_len, const void *sig, size_t sig_len);
+int curve_to_nid(int curve, int *nid);
#endif // _SSF_CRYPTO_OPENSSL_H_
int crypto_internal_open(crypto_internal_operation *operation)
{
- if (operation->info.algorithm == TEE_ALG_AES_GCM || operation->info.algorithm == TEE_ALG_AES_CTR) {
+ switch(operation->info.algorithm) {
+ case TEE_ALG_AES_GCM:
+ case TEE_ALG_AES_CTR:
+ case TEE_ALG_ECDSA_P160:
+ case TEE_ALG_ECDSA_P192:
+ case TEE_ALG_ECDSA_P224:
+ case TEE_ALG_ECDSA_P256:
+ case TEE_ALG_ECDSA_P384:
+ case TEE_ALG_ECDSA_P521:
+ case TEE_ALG_ECDH_P192:
+ case TEE_ALG_ECDH_P224:
+ case TEE_ALG_ECDH_P256:
+ case TEE_ALG_ECDH_P384:
+ case TEE_ALG_ECDH_P521:
return ossl_crypto_open(operation);
- } else {
+ default:
return sw_crypto_open(operation);
}
}
int crypto_internal_close(crypto_internal_operation *operation)
{
- if (operation->info.algorithm == TEE_ALG_AES_GCM || operation->info.algorithm == TEE_ALG_AES_CTR) {
+ switch(operation->info.algorithm) {
+ case TEE_ALG_AES_GCM:
+ case TEE_ALG_AES_CTR:
+ case TEE_ALG_ECDSA_P160:
+ case TEE_ALG_ECDSA_P192:
+ case TEE_ALG_ECDSA_P224:
+ case TEE_ALG_ECDSA_P256:
+ case TEE_ALG_ECDSA_P384:
+ case TEE_ALG_ECDSA_P521:
+ case TEE_ALG_ECDH_P192:
+ case TEE_ALG_ECDH_P224:
+ case TEE_ALG_ECDH_P256:
+ case TEE_ALG_ECDH_P384:
+ case TEE_ALG_ECDH_P521:
ossl_crypto_close(operation);
return 0;
- } else {
+ default:
return sw_crypto_close(operation);
}
}
crypto_internal_operation *op = (crypto_internal_operation*) operation;
crypto_internal_keystruct key;
TEE_ObjectInfo info;
+ int ret = 0;
if (op->info.operationClass != TEE_OPERATION_ASYMMETRIC_SIGNATURE) {
CRYPTO_PANIC;
(void*) key.rsa_private.buffer, (size_t*) &key.rsa_private.size) != TEE_SUCCESS) {
CRYPTO_PANIC;
}
-
+ break;
+ }
+ case TEE_TYPE_ECDSA_KEYPAIR:
+ case TEE_TYPE_ECDH_KEYPAIR:
+ {
+ bp.PrepareBuffer(maxAttrSize, key.ecc_private);
+ if (TEE_GetObjectBufferAttribute(op->key1, TEE_ATTR_ECC_PRIVATE_VALUE,
+ (void*) key.ecc_private.buffer, (size_t*) &key.ecc_private.size) != TEE_SUCCESS) {
+ CRYPTO_PANIC;
+ }
+ uint32_t a, b;
+ if (TEE_GetObjectValueAttribute(op->key1, TEE_ATTR_ECC_CURVE, &a, &b) != TEE_SUCCESS) {
+ CRYPTO_PANIC;
+ }
+ key.ecc_curve = b;
break;
}
default:
CRYPTO_PANIC;
}
- if (crypto_internal_init(op, &key, NULL, 0)) {
- CRYPTO_PANIC;
+ if (info.objectType == TEE_TYPE_ECDSA_KEYPAIR || info.objectType == TEE_TYPE_ECDH_KEYPAIR) {
+ ret = ossl_ecdsa_sign(key.ecc_private, digest, digestLen, signature, signatureLen);
+ } else {
+ if (crypto_internal_init(op, &key, NULL, 0)) {
+ CRYPTO_PANIC;
+ }
+ ret = crypto_internal_final(op, (unsigned char*)digest, digestLen, (unsigned char*)signature, signatureLen);
}
- int ret = crypto_internal_final(op, (unsigned char*)digest, digestLen, (unsigned char*)signature, signatureLen);
+
switch (ret) {
case 0:
return TEE_SUCCESS;
crypto_internal_keystruct key;
size_t sign_len=signatureLen;
TEE_ObjectInfo info;
+ int ret = 0;
if (op->info.operationClass != TEE_OPERATION_ASYMMETRIC_SIGNATURE) {
CRYPTO_PANIC;
}
break;
}
+ case TEE_TYPE_ECDSA_PUBLIC_KEY:
+ case TEE_TYPE_ECDSA_KEYPAIR:
+ case TEE_TYPE_ECDH_PUBLIC_KEY:
+ case TEE_TYPE_ECDH_KEYPAIR:
+ {
+ bp.PrepareBuffer(maxAttrSize, key.ecc_public_x);
+ bp.PrepareBuffer(maxAttrSize, key.ecc_public_y);
+ if (TEE_GetObjectBufferAttribute(op->key1, TEE_ATTR_ECC_PUBLIC_VALUE_X,
+ (void*) key.ecc_public_x.buffer, (size_t*) &key.ecc_public_x.size) != TEE_SUCCESS) {
+ CRYPTO_PANIC;
+ }
+ if (TEE_GetObjectBufferAttribute(op->key1, TEE_ATTR_ECC_PUBLIC_VALUE_Y,
+ (void*) key.ecc_public_y.buffer, (size_t*) &key.ecc_public_y.size) != TEE_SUCCESS) {
+ CRYPTO_PANIC;
+ }
+ uint32_t a, b;
+ if (TEE_GetObjectValueAttribute(op->key1, TEE_ATTR_ECC_CURVE, &a, &b) != TEE_SUCCESS) {
+ CRYPTO_PANIC;
+ }
+ key.ecc_curve = b;
+ break;
+ }
default:
CRYPTO_PANIC;
}
- if (crypto_internal_init(op, &key, NULL, 0)) {
- CRYPTO_PANIC;
+ if (info.objectType == TEE_TYPE_ECDSA_PUBLIC_KEY || info.objectType == TEE_TYPE_ECDSA_KEYPAIR ||
+ info.objectType == TEE_TYPE_ECDH_PUBLIC_KEY || info.objectType == TEE_TYPE_ECDH_KEYPAIR) {
+ ret = ossl_ecdsa_verify(key.ecc_curve, key.ecc_public_x, key.ecc_public_y,
+ digest, digestLen, signature, signatureLen);
+ } else {
+ if (crypto_internal_init(op, &key, NULL, 0)) {
+ CRYPTO_PANIC;
+ }
+ ret = crypto_internal_final(op, (unsigned char*)digest, digestLen, (unsigned char*)signature, &sign_len);
}
- int ret = crypto_internal_final(op, (unsigned char*)digest, digestLen, (unsigned char*)signature, &sign_len);
+
switch (ret) {
case 0:
return TEE_SUCCESS;
#include "ssf_crypto_openssl.h"
#include <tee_internal_api.h>
#include <openssl/evp.h>
+#include <openssl/ecdsa.h>
+#include <openssl/ecdh.h>
+#include <openssl/bio.h>
+#include <openssl/pem.h>
#include <log.h>
// DO NOT MODIFY BELOW VALUES
return 0;
}
+int ossl_ecdsa_sign(crypto_internal_keydata priv_key,
+ const void *src, size_t src_len,
+ void *sig, size_t *sig_len)
+{
+ EC_KEY* eckey;
+
+ BIO* bio = BIO_new_mem_buf(priv_key.buffer, priv_key.size);
+
+ if ((eckey = d2i_ECPrivateKey_bio(bio, NULL)) == NULL) {
+ LOGE(MODULE_SSF_LIB, "ossl_ecdsa_sign: PEM_read_bio_ECPrivateKey() failed");
+ return -1;
+ }
+
+ if (ECDSA_sign(0, (unsigned char *)src, (int) src_len,
+ (unsigned char *) sig, (unsigned int *)sig_len, eckey) == 0) {
+ LOGE(MODULE_SSF_LIB, "ossl_ecdsa_sign: ECDSA_sign() failed");
+ return -1;
+ }
+
+ return 0;
+}
+
+int ossl_ecdsa_verify(uint32_t curve,
+ crypto_internal_keydata pub_x,
+ crypto_internal_keydata pub_y,
+ const void *src, size_t src_len,
+ const void *sig, size_t sig_len)
+{
+ int nid;
+ EC_KEY* eckey;
+ BIGNUM *x, *y;
+ int ret;
+
+ if (curve_to_nid(curve, &nid) != 0) {
+ LOGE(MODULE_SSF_LIB, "ossl_ecdsa_sign: to_nid() failed");
+ return -2;
+ }
+ eckey = EC_KEY_new_by_curve_name(nid);
+
+ x = BN_bin2bn(pub_x.buffer, pub_x.size, NULL);
+ y = BN_bin2bn(pub_y.buffer, pub_y.size, NULL);
+
+ EC_KEY_set_public_key_affine_coordinates(eckey, x, y);
+ EC_KEY_set_asn1_flag(eckey, OPENSSL_EC_NAMED_CURVE);
+
+ ret = ECDSA_verify(0, (unsigned char *)src, (int) src_len,
+ (unsigned char *) sig, (unsigned int)sig_len, eckey);
+ if (ret == 0) { // Invalid Signature
+ LOGE(MODULE_SSF_LIB, "ossl_ecdsa_verify: ECDSA_verify() failed");
+ return -1;
+ } else if (ret < 0) { // Error
+ LOGE(MODULE_SSF_LIB, "ossl_ecdsa_verify: Error happened in ECDSA_verify()");
+ return -1;
+ }
+
+ return 0;
+}
+
+int curve_to_nid(int curve, int *nid) {
+ switch ((TEE_ECC_CURVE) curve) {
+ case TEE_ECC_CURVE_NIST_P192: {*nid = NID_X9_62_prime192v1; return 0;}
+ case TEE_ECC_CURVE_NIST_P256: {*nid = NID_X9_62_prime256v1; return 0;}
+ case TEE_ECC_CURVE_NIST_P384: {*nid = NID_secp384r1; return 0;}
+ default: return -1;
+ }
+}
\ No newline at end of file
* Include files
*-----------------------------------------------------------------------------*/
#include "ssf_storage.h"
+#include "ssf_crypto_openssl.h"
#include <sys/mman.h>
#include <string.h>
#include <permission.h>
#include <log.h>
+#include <openssl/ecdsa.h>
+#include <openssl/ecdh.h>
+#include <openssl/evp.h>
+#include <openssl/bio.h>
+#include <openssl/pem.h>
/*-----------------------------------------------------------------------------
* MACROS
MSG("\n---------------------------------------------------");
}
+static inline bool isValueAttr(uint32_t attrId)
+{
+ // bit[29] == 1 -> value type attribute, not a buffer attribute.
+ return attrId & TEE_ATTR_FLAG_VALUE;
+}
+
/*-----------------------------------------------------------------------------
* TEE API implementation
*-----------------------------------------------------------------------------*/
}
}
+int to_buffer(BIO *bio, uint8_t **buffer, size_t *size) {
+ uint8_t tmp[1024*4];
+ uint8_t* tmp_buffer;
+ size_t read = 0;
+
+ BIO_seek(bio, 0);
+ read = BIO_read(bio, tmp, sizeof(tmp));
+ if (read >= sizeof(tmp)) { // Too Big Data
+ return -1;
+ }
+ tmp_buffer = (uint8_t*) malloc(read);
+ if(tmp_buffer == NULL) {
+ return -1;
+ }
+ memcpy(tmp_buffer, tmp, read);
+
+ *buffer = tmp_buffer;
+ *size = read;
+ return 0;
+}
+
/////////////////////////////////////////////////////////////////////////////////////////////
// Internal transient Object Operations
/////////////////////////////////////////////////////////////////////////////////////////////
if (maxObjectSize < 256 || maxObjectSize > 2048)
return TEE_ERROR_NOT_SUPPORTED;
break;
+#ifdef ECC_IMPLEMENTATION
+ case TEE_TYPE_ECDSA_PUBLIC_KEY:
+ case TEE_TYPE_ECDSA_KEYPAIR:
+ case TEE_TYPE_ECDH_PUBLIC_KEY:
+ case TEE_TYPE_ECDH_KEYPAIR:
+ // This types of keys will have internal format.
+ // So no size check is required.
+ break;
+#endif // ECC_IMPLEMENTATION
case TEE_TYPE_GENERIC_SECRET:
if (maxObjectSize > 4096 || maxObjectSize % 8)
return TEE_ERROR_NOT_SUPPORTED;
TEE_Attribute* curr_attr = &tr->attr.attr_array[tr->attr.attr_number];
for (i = 0; i < attrCount; i++) {
- if (attrs[i].content.ref.length * 8 > tr->info.maxObjectSize) {
+ if ((!isValueAttr(attrs[i].attributeID))
+ && (attrs[i].content.ref.length * 8 > tr->info.maxObjectSize)) {
TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
TEE_Panic(0);
}
}
}
break;
+ case TEE_TYPE_ECDSA_PUBLIC_KEY:
+ case TEE_TYPE_ECDH_PUBLIC_KEY: {
+ if (tr->attr.attr_number != 3) {
+ TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+ TEE_Panic(0);
+ }
+ break;
+ }
+ case TEE_TYPE_ECDSA_KEYPAIR:
+ case TEE_TYPE_ECDH_KEYPAIR: {
+ if (tr->attr.attr_number != 4) {
+ TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+ TEE_Panic(0);
+ }
+ break;
+ }
default:
return TEE_ERROR_BAD_PARAMETERS;
}
|| ((dest->info.objectType == TEE_TYPE_RSA_PUBLIC_KEY)
&& (src->info.objectType == TEE_TYPE_RSA_KEYPAIR))
|| ((dest->info.objectType == TEE_TYPE_DSA_PUBLIC_KEY)
- && (src->info.objectType == TEE_TYPE_DSA_KEYPAIR)))) {
+ && (src->info.objectType == TEE_TYPE_DSA_KEYPAIR))
+ || ((dest->info.objectType == TEE_TYPE_ECDSA_PUBLIC_KEY)
+ && (src->info.objectType == TEE_TYPE_ECDSA_KEYPAIR))
+ || ((dest->info.objectType == TEE_TYPE_ECDH_PUBLIC_KEY)
+ && (src->info.objectType == TEE_TYPE_ECDH_KEYPAIR)))) {
TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+ TZ_ERROR("dest obj type = %x, src obj type = %x\n", dest->info.objectType , src->info.objectType);
TEE_Panic(0);
}
+
if (src->info.objectSize > dest->info.maxObjectSize) {
- TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+ TZ_ERROR("operation error line = %d,%s, src_obj_size=%d, dest_max_obj_size=%d\n", __LINE__, __func__, src->info.objectSize, dest->info.maxObjectSize);
TEE_Panic(0);
}
dest->info.objectSize = src->info.objectSize;
OsaFree(pubKey);
}
break;
+#ifdef ECC_IMPLEMENTATION
+ case TEE_TYPE_ECDSA_KEYPAIR:
+ case TEE_TYPE_ECDH_KEYPAIR: {
+ size_t key_size = (keySize + 7) / 8;
+ int nid = 0;
+ uint8_t *privKey = NULL, *pubX = NULL, *pubY = NULL;
+ size_t privSize = 0, pubXSize = 0, pubYSize = 0;
+
+ for (i = 0; i < paramCount; i++) {
+ if (params[i].attributeID == TEE_ATTR_ECC_CURVE) {
+ if (curve_to_nid(params[i].content.value.b, &nid) != 0)
+ return TEE_ERROR_BAD_PARAMETERS;
+ check |= 0x01;
+ }
+ }
+ if (check != 0x01) {
+ TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+ TEE_Panic(0);
+ }
+
+ /* Create an Elliptic Curve Key object */
+ EC_KEY *ec_key = EC_KEY_new();
+ EC_GROUP *ec_group = EC_GROUP_new_by_curve_name(nid);
+ EC_KEY_set_group(ec_key, ec_group);
+ if(NULL == ec_group) {
+ TZ_ERROR("EC_GROUP_new_by_curve_name() operation error line = %d,%s\n", __LINE__, __func__);
+ TEE_Panic(0);
+ }
+
+ /* Generate the private and public key */
+ if(1 != EC_KEY_generate_key(ec_key)) {
+ TZ_ERROR("EC_KEY_generate_key() operation error line = %d,%s\n", __LINE__, __func__);
+ TEE_Panic(0);
+ }
+
+ BIO *bio_pri = BIO_new(BIO_s_mem());
+ i2d_ECPrivateKey_bio(bio_pri, ec_key);
+
+ if(to_buffer(bio_pri, &privKey, &privSize) != 0) {
+ TZ_ERROR("failed to convert private key to binary. line = %d,%s\n", __LINE__, __func__);
+ TEE_Panic(0);
+ }
+
+ const EC_POINT *pubkey_pnt = EC_KEY_get0_public_key(ec_key);
+ BIGNUM *x = BN_new();
+ BIGNUM *y = BN_new();
+ if (EC_POINT_get_affine_coordinates_GFp(ec_group, pubkey_pnt, x, y, NULL) != 1) {
+ TZ_ERROR("failed in EC_POINT_get_affine_coordinates_GFp(). line = %d,%s\n", __LINE__, __func__);
+ TEE_Panic(0);
+ }
+ pubX = (uint8_t *) malloc(key_size);
+ pubY = (uint8_t *) malloc(key_size);
+ pubXSize = BN_bn2bin(x, pubX);
+ pubYSize = BN_bn2bin(y, pubY);
+ if (key_size < pubXSize || key_size < pubYSize) {
+ TZ_ERROR("Too small key size. line = %d,%s. key_size=%d, pubXSize=%d, pubYSize=%d\n",
+ __LINE__, __func__, key_size, pubXSize, pubYSize);
+ TEE_Panic(0);
+ }
+
+ TEE_InitValueAttribute(&attrs[0], params[0].attributeID, params[0].content.value.a, params[0].content.value.b);
+ TEE_InitRefAttribute(&attrs[1], TEE_ATTR_ECC_PRIVATE_VALUE, privKey, privSize);
+ TEE_InitRefAttribute(&attrs[2], TEE_ATTR_ECC_PUBLIC_VALUE_X, pubX, pubXSize);
+ TEE_InitRefAttribute(&attrs[3], TEE_ATTR_ECC_PUBLIC_VALUE_Y, pubY, pubYSize);
+ TEE_PopulateTransientObject(object, attrs, 4);
+
+ EC_GROUP_free(ec_group);
+ EC_KEY_free(ec_key);
+ BIO_free(bio_pri);
+ BN_free(x);
+ BN_free(y);
+ free(privKey);
+ free(pubX);
+ free(pubY);
+ }
+ break;
+#endif // ECC_IMPLEMENTATION
}
+ tr->info.handleFlags |= TEE_HANDLE_FLAG_INITIALIZED;
+
return TEE_SUCCESS;
}