diff --git a/core/crypto.mk b/core/crypto.mk index a9f81cbf895..9cead9b71e0 100644 --- a/core/crypto.mk +++ b/core/crypto.mk @@ -47,8 +47,9 @@ CFG_CRYPTO_ECC ?= y CFG_CRYPTO_SM2_PKE ?= y CFG_CRYPTO_SM2_DSA ?= y CFG_CRYPTO_SM2_KEP ?= y -# X25519 is only supported by libtomcrypt +# X25519 and Ed25519 are only supported by libtomcrypt ifeq ($(CFG_CRYPTOLIB_NAME),tomcrypt) +CFG_CRYPTO_ED25519 ?= y CFG_CRYPTO_X25519 ?= y endif @@ -167,7 +168,7 @@ core-ltc-vars += SIZE_OPTIMIZATION core-ltc-vars += SM2_PKE core-ltc-vars += SM2_DSA core-ltc-vars += SM2_KEP -core-ltc-vars += X25519 +core-ltc-vars += ED25519 X25519 # Assigned selected CFG_CRYPTO_xxx as _CFG_CORE_LTC_xxx $(foreach v, $(core-ltc-vars), $(eval _CFG_CORE_LTC_$(v) := $(CFG_CRYPTO_$(v)))) _CFG_CORE_LTC_MPI := $(CFG_CORE_MBEDTLS_MPI) @@ -192,6 +193,7 @@ _CFG_CORE_LTC_XTS := $(CFG_CRYPTO_XTS) _CFG_CORE_LTC_CCM := $(CFG_CRYPTO_CCM) _CFG_CORE_LTC_AES_DESC := $(call cfg-one-enabled, CFG_CRYPTO_XTS CFG_CRYPTO_CCM) $(call force,CFG_CRYPTO_X25519,n,not supported by mbedtls) +$(call force,CFG_CRYPTO_ED25519,n,not supported by mbedtls) endif ############################################################### @@ -232,7 +234,7 @@ _CFG_CORE_LTC_HASH := $(call ltc-one-enabled, MD5 SHA1 SHA224 SHA256 SHA384 \ _CFG_CORE_LTC_MAC := $(call ltc-one-enabled, HMAC CMAC CBC_MAC) _CFG_CORE_LTC_CBC := $(call ltc-one-enabled, CBC CBC_MAC) _CFG_CORE_LTC_ASN1 := $(call ltc-one-enabled, RSA DSA ECC) -_CFG_CORE_LTC_EC25519 := $(call ltc-one-enabled, X25519) +_CFG_CORE_LTC_EC25519 := $(call ltc-one-enabled, ED25519 X25519) ############################################################### # Platform independent crypto-driver configuration diff --git a/core/crypto/crypto.c b/core/crypto/crypto.c index 4a892b4a5e3..fd2a3bf57b0 100644 --- a/core/crypto/crypto.c +++ b/core/crypto/crypto.c @@ -825,6 +825,64 @@ TEE_Result crypto_acipher_x25519_shared_secret(struct x25519_keypair } #endif +#if !defined(CFG_CRYPTO_ED25519) +TEE_Result crypto_acipher_alloc_ed25519_keypair(struct ed25519_keypair *key + __unused, + size_t key_size_bits __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} + +TEE_Result crypto_acipher_gen_ed25519_key(struct ed25519_keypair *key __unused, + size_t key_size __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} + +TEE_Result crypto_acipher_ed25519_sign(struct ed25519_keypair *key __unused, + const uint8_t *msg __unused, + size_t msg_len __unused, + uint8_t *sig __unused, + size_t *sig_len __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} + +TEE_Result crypto_acipher_ed25519_verify(struct ed25519_keypair *key __unused, + const uint8_t *msg __unused, + size_t msg_len __unused, + const uint8_t *sig __unused, + size_t sig_len __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} + +TEE_Result crypto_acipher_ed25519ctx_sign(struct ed25519_keypair *key __unused, + const uint8_t *msg __unused, + size_t msg_len __unused, + uint8_t *sig __unused, + size_t *sig_len __unused, + bool ph_flag __unused, + const uint8_t *ctx __unused, + size_t ctxlen __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} + +TEE_Result crypto_acipher_ed25519ctx_verify(struct ed25519_keypair *key + __unused, + const uint8_t *msg __unused, + size_t msg_len __unused, + const uint8_t *sig __unused, + size_t sig_len __unused, + bool ph_flag __unused, + const uint8_t *ctx __unused, + size_t ctxlen __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} +#endif + __weak void crypto_storage_obj_del(uint8_t *data __unused, size_t len __unused) { } diff --git a/core/include/crypto/crypto.h b/core/include/crypto/crypto.h index 4257bfe548c..98ebf0275c7 100644 --- a/core/include/crypto/crypto.h +++ b/core/include/crypto/crypto.h @@ -172,6 +172,11 @@ struct x25519_keypair { uint8_t *pub; /* Public value */ }; +struct ed25519_keypair { + uint8_t *priv; + uint8_t *pub; +}; + /* * Key allocation functions * Allocate the bignum's inside a key structure. @@ -198,6 +203,8 @@ TEE_Result crypto_acipher_alloc_ecc_keypair(struct ecc_keypair *s, void crypto_acipher_free_ecc_public_key(struct ecc_public_key *s); TEE_Result crypto_acipher_alloc_x25519_keypair(struct x25519_keypair *s, size_t key_size_bits); +TEE_Result crypto_acipher_alloc_ed25519_keypair(struct ed25519_keypair *s, + size_t key_size_bits); /* * Key generation functions @@ -209,6 +216,24 @@ TEE_Result crypto_acipher_gen_dh_key(struct dh_keypair *key, struct bignum *q, TEE_Result crypto_acipher_gen_ecc_key(struct ecc_keypair *key, size_t key_size); TEE_Result crypto_acipher_gen_x25519_key(struct x25519_keypair *key, size_t key_size); +TEE_Result crypto_acipher_gen_ed25519_key(struct ed25519_keypair *key, + size_t key_size); +TEE_Result crypto_acipher_ed25519_sign(struct ed25519_keypair *key, + const uint8_t *msg, size_t msg_len, + uint8_t *sig, size_t *sig_len); +TEE_Result crypto_acipher_ed25519ctx_sign(struct ed25519_keypair *key, + const uint8_t *msg, size_t msg_len, + uint8_t *sig, size_t *sig_len, + bool ph_flag, + const uint8_t *ctx, size_t ctxlen); +TEE_Result crypto_acipher_ed25519_verify(struct ed25519_keypair *key, + const uint8_t *msg, size_t msg_len, + const uint8_t *sig, size_t sig_len); +TEE_Result crypto_acipher_ed25519ctx_verify(struct ed25519_keypair *key, + const uint8_t *msg, size_t msg_len, + const uint8_t *sig, size_t sig_len, + bool ph_flag, + const uint8_t *ctx, size_t ctxlen); TEE_Result crypto_acipher_dh_shared_secret(struct dh_keypair *private_key, struct bignum *public_key, diff --git a/core/lib/libtomcrypt/ed25519.c b/core/lib/libtomcrypt/ed25519.c new file mode 100644 index 00000000000..b85629b869f --- /dev/null +++ b/core/lib/libtomcrypt/ed25519.c @@ -0,0 +1,179 @@ +// SPDX-License-Identifier: BSD-2-Clause +/* + * Copyright (c) 2022, Technology Innovation Institute (TII) + * Copyright (c) 2022, EPAM Systems + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "acipher_helpers.h" + +#define ED25519_KEY_SIZE UL(256) + +TEE_Result crypto_acipher_alloc_ed25519_keypair(struct ed25519_keypair *key, + size_t key_size) +{ + if (!key || key_size != ED25519_KEY_SIZE) + return TEE_ERROR_BAD_PARAMETERS; + + memset(key, 0, sizeof(*key)); + + key->priv = calloc(1, key_size >> 3); + key->pub = calloc(1, key_size >> 3); + + if (!key->priv || !key->pub) { + free(key->priv); + free(key->pub); + return TEE_ERROR_OUT_OF_MEMORY; + } + + return TEE_SUCCESS; +} + +TEE_Result crypto_acipher_gen_ed25519_key(struct ed25519_keypair *key, + size_t key_size) +{ + curve25519_key ltc_tmp_key = { }; + + if (key_size != ED25519_KEY_SIZE) + return TEE_ERROR_BAD_PARAMETERS; + + if (ed25519_make_key(NULL, find_prng("prng_crypto"), + <c_tmp_key) != CRYPT_OK) + return TEE_ERROR_BAD_PARAMETERS; + + assert(key_size >= sizeof(ltc_tmp_key.pub) && + key_size >= sizeof(ltc_tmp_key.priv)); + + memcpy(key->pub, ltc_tmp_key.pub, sizeof(ltc_tmp_key.pub)); + memcpy(key->priv, ltc_tmp_key.priv, sizeof(ltc_tmp_key.priv)); + memzero_explicit(<c_tmp_key, sizeof(ltc_tmp_key)); + + return TEE_SUCCESS; +} + +TEE_Result crypto_acipher_ed25519_sign(struct ed25519_keypair *key, + const uint8_t *msg, size_t msg_len, + uint8_t *sig, size_t *sig_len) +{ + int err; + unsigned long siglen; + curve25519_key private_key = { + .type = PK_PRIVATE, + .algo = LTC_OID_ED25519, + }; + + if (!key) + return TEE_ERROR_BAD_PARAMETERS; + + memcpy(private_key.priv, key->priv, sizeof(private_key.priv)); + memcpy(private_key.pub, key->pub, sizeof(private_key.pub)); + + err = ed25519_sign(msg, msg_len, sig, &siglen, &private_key); + + memzero_explicit(&private_key, sizeof(private_key)); + + if (err != CRYPT_OK) + return TEE_ERROR_BAD_PARAMETERS; + *sig_len = siglen; + return TEE_SUCCESS; +} + +TEE_Result crypto_acipher_ed25519ctx_sign(struct ed25519_keypair *key, + const uint8_t *msg, size_t msg_len, + uint8_t *sig, size_t *sig_len, + bool ph_flag, + const uint8_t *ctx, size_t ctxlen) +{ + int err = CRYPT_ERROR; + unsigned long siglen; + curve25519_key private_key = { + .type = PK_PRIVATE, + .algo = LTC_OID_ED25519, + }; + + if (!key) + return TEE_ERROR_BAD_PARAMETERS; + + memcpy(private_key.priv, key->priv, sizeof(private_key.priv)); + memcpy(private_key.pub, key->pub, sizeof(private_key.pub)); + + if (ph_flag) { + err = ed25519ph_sign(msg, msg_len, sig, &siglen, + ctx, ctxlen, &private_key); + } else { + err = ed25519ctx_sign(msg, msg_len, sig, &siglen, + ctx, ctxlen, &private_key); + } + + memzero_explicit(&private_key, sizeof(private_key)); + + if (err != CRYPT_OK) + return TEE_ERROR_BAD_PARAMETERS; + *sig_len = siglen; + return TEE_SUCCESS; +} + +TEE_Result crypto_acipher_ed25519_verify(struct ed25519_keypair *key, + const uint8_t *msg, size_t msg_len, + const uint8_t *sig, size_t sig_len) +{ + int stat = 0; + curve25519_key public_key = { + .type = PK_PUBLIC, + .algo = LTC_OID_ED25519, + }; + + if (!key) + return TEE_ERROR_BAD_PARAMETERS; + + memcpy(public_key.pub, key->pub, sizeof(public_key.pub)); + + if (ed25519_verify(msg, msg_len, sig, sig_len, &stat, + &public_key) != CRYPT_OK) + return TEE_ERROR_BAD_PARAMETERS; + + if (stat != 1) + return TEE_ERROR_SIGNATURE_INVALID; + + return TEE_SUCCESS; +} + +TEE_Result crypto_acipher_ed25519ctx_verify(struct ed25519_keypair *key, + const uint8_t *msg, size_t msg_len, + const uint8_t *sig, size_t sig_len, + bool ph_flag, + const uint8_t *ctx, size_t ctxlen) +{ + int stat = 0; + curve25519_key public_key = { + .type = PK_PUBLIC, + .algo = LTC_OID_ED25519, + }; + + if (!key) + return TEE_ERROR_BAD_PARAMETERS; + + memcpy(public_key.pub, key->pub, sizeof(public_key.pub)); + + if (ph_flag) { + if (ed25519ph_verify(msg, msg_len, sig, sig_len, ctx, ctxlen, + &stat, &public_key) != CRYPT_OK) + return TEE_ERROR_BAD_PARAMETERS; + } else { + if (ed25519ctx_verify(msg, msg_len, sig, sig_len, ctx, ctxlen, + &stat, &public_key) != CRYPT_OK) + return TEE_ERROR_BAD_PARAMETERS; + } + + if (stat != 1) + return TEE_ERROR_SIGNATURE_INVALID; + + return TEE_SUCCESS; +} diff --git a/core/lib/libtomcrypt/src/pk/ec25519/sub.mk b/core/lib/libtomcrypt/src/pk/ec25519/sub.mk index e3d07c0e04b..5040c391ce0 100644 --- a/core/lib/libtomcrypt/src/pk/ec25519/sub.mk +++ b/core/lib/libtomcrypt/src/pk/ec25519/sub.mk @@ -1,2 +1,3 @@ +srcs-y += ec25519_crypto_ctx.c srcs-y += ec25519_export.c srcs-y += tweetnacl.c diff --git a/core/lib/libtomcrypt/src/pk/ed25519/sub.mk b/core/lib/libtomcrypt/src/pk/ed25519/sub.mk new file mode 100644 index 00000000000..cb2206dabec --- /dev/null +++ b/core/lib/libtomcrypt/src/pk/ed25519/sub.mk @@ -0,0 +1,7 @@ +srcs-y += ed25519_export.c +srcs-y += ed25519_import.c +srcs-y += ed25519_import_pkcs8.c +srcs-y += ed25519_import_x509.c +srcs-y += ed25519_make_key.c +srcs-y += ed25519_sign.c +srcs-y += ed25519_verify.c diff --git a/core/lib/libtomcrypt/src/pk/sub.mk b/core/lib/libtomcrypt/src/pk/sub.mk index 968c63b5368..dca26a50a05 100644 --- a/core/lib/libtomcrypt/src/pk/sub.mk +++ b/core/lib/libtomcrypt/src/pk/sub.mk @@ -7,3 +7,5 @@ subdirs-$(_CFG_CORE_LTC_DH) += dh subdirs-$(_CFG_CORE_LTC_ECC) += ecc subdirs-$(_CFG_CORE_LTC_X25519) += ec25519 subdirs-$(_CFG_CORE_LTC_X25519) += x25519 +subdirs-$(_CFG_CORE_LTC_ED25519) += ec25519 +subdirs-$(_CFG_CORE_LTC_ED25519) += ed25519 diff --git a/core/lib/libtomcrypt/sub.mk b/core/lib/libtomcrypt/sub.mk index b4de4f80bb5..941d4f0119b 100644 --- a/core/lib/libtomcrypt/sub.mk +++ b/core/lib/libtomcrypt/sub.mk @@ -95,6 +95,7 @@ ifeq ($(_CFG_CORE_LTC_ECC),y) cppflags-lib-y += -DLTC_ECC256 cppflags-lib-y += -DLTC_ECC384 cppflags-lib-y += -DLTC_ECC521 + cppflags-lib-y += -DLTC_CURVE25519 # ECC 521 bits is the max supported key size cppflags-lib-y += -DLTC_MAX_ECC=521 @@ -104,6 +105,7 @@ ifneq (,$(filter y,$(_CFG_CORE_LTC_SM2_DSA) $(_CFG_CORE_LTC_SM2_PKE))) endif cppflags-lib-$(_CFG_CORE_LTC_X25519) += -DLTC_CURVE25519 +cppflags-lib-$(_CFG_CORE_LTC_ED25519) += -DLTC_CURVE25519 cppflags-lib-y += -DLTC_NO_PRNGS -DLTC_FORTUNA @@ -134,6 +136,7 @@ srcs-$(_CFG_CORE_LTC_SM2_DSA) += sm2-dsa.c srcs-$(_CFG_CORE_LTC_SM2_PKE) += sm2-pke.c srcs-$(_CFG_CORE_LTC_SM2_KEP) += sm2-kep.c srcs-$(_CFG_CORE_LTC_X25519) += x25519.c +srcs-$(_CFG_CORE_LTC_ED25519) += ed25519.c ifeq ($(_CFG_CORE_LTC_ACIPHER),y) srcs-y += mpi_desc.c endif diff --git a/core/tee/tee_svc_cryp.c b/core/tee/tee_svc_cryp.c index e62af6dd911..4a4ee5f0101 100644 --- a/core/tee/tee_svc_cryp.c +++ b/core/tee/tee_svc_cryp.c @@ -85,6 +85,8 @@ struct tee_cryp_obj_secret { /* Curve25519 key bytes size is always 32 bytes*/ #define KEY_SIZE_BYTES_25519 UL(32) + /* TEE Internal Core API v1.3.1, Table 6-8 */ +#define TEE_ED25519_CTX_MAX_LENGTH 255 struct tee_cryp_obj_type_attrs { uint32_t attr_id; @@ -446,6 +448,33 @@ const struct tee_cryp_obj_type_attrs tee_cryp_obj_x25519_keypair_attrs[] = { }, }; +static +const struct tee_cryp_obj_type_attrs tee_cryp_obj_ed25519_pub_key_attrs[] = { + { + .attr_id = TEE_ATTR_ED25519_PUBLIC_VALUE, + .flags = TEE_TYPE_ATTR_REQUIRED, + .ops_index = ATTR_OPS_INDEX_25519, + RAW_DATA(struct ed25519_keypair, pub) + }, +}; + +static +const struct tee_cryp_obj_type_attrs tee_cryp_obj_ed25519_keypair_attrs[] = { + { + .attr_id = TEE_ATTR_ED25519_PRIVATE_VALUE, + .flags = TEE_TYPE_ATTR_REQUIRED, + .ops_index = ATTR_OPS_INDEX_25519, + RAW_DATA(struct ed25519_keypair, priv) + }, + + { + .attr_id = TEE_ATTR_ED25519_PUBLIC_VALUE, + .flags = TEE_TYPE_ATTR_REQUIRED, + .ops_index = ATTR_OPS_INDEX_25519, + RAW_DATA(struct ed25519_keypair, pub) + }, +}; + struct tee_cryp_obj_type_props { TEE_ObjectType obj_type; uint16_t min_size; /* may not be smaller than this */ @@ -578,6 +607,14 @@ static const struct tee_cryp_obj_type_props tee_cryp_obj_props[] = { PROP(TEE_TYPE_X25519_KEYPAIR, 1, 256, 256, sizeof(struct x25519_keypair), tee_cryp_obj_x25519_keypair_attrs), + + PROP(TEE_TYPE_ED25519_PUBLIC_KEY, 1, 256, 256, + sizeof(struct ed25519_keypair), + tee_cryp_obj_ed25519_pub_key_attrs), + + PROP(TEE_TYPE_ED25519_KEYPAIR, 1, 256, 256, + sizeof(struct ed25519_keypair), + tee_cryp_obj_ed25519_keypair_attrs), }; struct attr_ops { @@ -1343,6 +1380,9 @@ TEE_Result tee_obj_attr_copy_from(struct tee_obj *o, const struct tee_obj *src) } else if (o->info.objectType == TEE_TYPE_SM2_KEP_PUBLIC_KEY) { if (src->info.objectType != TEE_TYPE_SM2_KEP_KEYPAIR) return TEE_ERROR_BAD_PARAMETERS; + } else if (o->info.objectType == TEE_TYPE_ED25519_PUBLIC_KEY) { + if (src->info.objectType != TEE_TYPE_ED25519_KEYPAIR) + return TEE_ERROR_BAD_PARAMETERS; } else { return TEE_ERROR_BAD_PARAMETERS; } @@ -1476,6 +1516,11 @@ TEE_Result tee_obj_set_type(struct tee_obj *o, uint32_t obj_type, res = crypto_acipher_alloc_x25519_keypair(o->attr, max_key_size); break; + case TEE_TYPE_ED25519_KEYPAIR: + case TEE_TYPE_ED25519_PUBLIC_KEY: + res = crypto_acipher_alloc_ed25519_keypair(o->attr, + max_key_size); + break; default: if (obj_type != TEE_TYPE_DATA) { struct tee_cryp_obj_secret *key = o->attr; @@ -2095,6 +2140,125 @@ tee_svc_obj_generate_key_x25519(struct tee_obj *o, return TEE_SUCCESS; } +static TEE_Result +tee_svc_obj_generate_key_ed25519(struct tee_obj *o, + const struct tee_cryp_obj_type_props + *type_props, + uint32_t key_size, + const TEE_Attribute *params, + uint32_t param_count) +{ + TEE_Result res = TEE_ERROR_GENERIC; + struct ed25519_keypair *key = NULL; + + /* Copy the present attributes into the obj before starting */ + res = tee_svc_cryp_obj_populate_type(o, type_props, params, + param_count); + if (res != TEE_SUCCESS) + return res; + + key = o->attr; + + res = crypto_acipher_gen_ed25519_key(key, key_size); + if (res != TEE_SUCCESS) + return res; + + /* Set bits for the generated public and private key */ + set_attribute(o, type_props, TEE_ATTR_ED25519_PRIVATE_VALUE); + set_attribute(o, type_props, TEE_ATTR_ED25519_PUBLIC_VALUE); + return TEE_SUCCESS; +} + +static TEE_Result +tee_svc_obj_ed25519_parse_params(const TEE_Attribute *params, size_t num_params, + bool *ph_flag, const uint8_t **ctx, + size_t *ctx_len) +{ + size_t n = 0; + + *ctx = NULL; + + for (n = 0; n < num_params; n++) { + switch (params[n].attributeID) { + case TEE_ATTR_EDDSA_PREHASH: + *ph_flag = true; + break; + + case TEE_ATTR_EDDSA_CTX: + /* several provided contexts are treated as error */ + if (*ctx) + return TEE_ERROR_BAD_PARAMETERS; + + *ctx_len = params[n].content.ref.length; + if (*ctx_len > TEE_ED25519_CTX_MAX_LENGTH) + return TEE_ERROR_BAD_PARAMETERS; + + if (!*ctx_len) + break; + + *ctx = params[n].content.ref.buffer; + if (!*ctx) + return TEE_ERROR_BAD_PARAMETERS; + break; + + default: + return TEE_ERROR_BAD_PARAMETERS; + } + } + + return TEE_SUCCESS; +} + +static TEE_Result +tee_svc_obj_ed25519_sign(struct ed25519_keypair *key, + const uint8_t *msg, size_t msg_len, + uint8_t *sig, size_t *sig_len, + const TEE_Attribute *params, size_t num_params) +{ + TEE_Result err = TEE_ERROR_GENERIC; + size_t ctx_len = 0; + const uint8_t *ctx = NULL; + bool ph_flag = false; + + err = tee_svc_obj_ed25519_parse_params(params, num_params, &ph_flag, + &ctx, &ctx_len); + if (err != TEE_SUCCESS) + return err; + + if (ph_flag || ctx) { + return crypto_acipher_ed25519ctx_sign(key, msg, msg_len, sig, + sig_len, ph_flag, + ctx, ctx_len); + } + + return crypto_acipher_ed25519_sign(key, msg, msg_len, sig, sig_len); +} + +static TEE_Result +tee_svc_obj_ed25519_verify(struct ed25519_keypair *key, + const uint8_t *msg, size_t msg_len, + const uint8_t *sig, size_t sig_len, + const TEE_Attribute *params, size_t num_params) +{ + TEE_Result err = TEE_ERROR_GENERIC; + size_t ctx_len = 0; + const uint8_t *ctx = NULL; + bool ph_flag = false; + + err = tee_svc_obj_ed25519_parse_params(params, num_params, &ph_flag, + &ctx, &ctx_len); + if (err) + return err; + + if (ph_flag || ctx) { + return crypto_acipher_ed25519ctx_verify(key, msg, msg_len, sig, + sig_len, ph_flag, + ctx, ctx_len); + } + + return crypto_acipher_ed25519_verify(key, msg, msg_len, sig, sig_len); +} + TEE_Result syscall_obj_generate_key(unsigned long obj, unsigned long key_size, const struct utee_attribute *usr_params, unsigned long param_count) @@ -2224,6 +2388,13 @@ TEE_Result syscall_obj_generate_key(unsigned long obj, unsigned long key_size, goto out; break; + case TEE_TYPE_ED25519_KEYPAIR: + res = tee_svc_obj_generate_key_ed25519(o, type_props, key_size, + params, param_count); + if (res != TEE_SUCCESS) + goto out; + break; + default: res = TEE_ERROR_BAD_FORMAT; } @@ -2348,6 +2519,11 @@ static TEE_Result tee_svc_cryp_check_key_type(const struct tee_obj *o, case TEE_MAIN_ALGO_ECDH: req_key_type = TEE_TYPE_ECDH_KEYPAIR; break; + case TEE_MAIN_ALGO_ED25519: + req_key_type = TEE_TYPE_ED25519_KEYPAIR; + if (mode == TEE_MODE_VERIFY) + req_key_type2 = TEE_TYPE_ED25519_PUBLIC_KEY; + break; case TEE_MAIN_ALGO_SM2_PKE: if (mode == TEE_MODE_ENCRYPT) req_key_type = TEE_TYPE_SM2_PKE_PUBLIC_KEY; @@ -3969,6 +4145,13 @@ TEE_Result syscall_asymm_operate(unsigned long state, res = crypto_acipher_dsa_sign(cs->algo, o->attr, src_data, src_len, dst_data, &dlen); break; + + case TEE_ALG_ED25519: + res = tee_svc_obj_ed25519_sign(o->attr, src_data, src_len, + dst_data, &dlen, params, + num_params); + break; + case TEE_ALG_ECDSA_P192: case TEE_ALG_ECDSA_P224: case TEE_ALG_ECDSA_P256: @@ -4115,6 +4298,12 @@ TEE_Result syscall_asymm_verify(unsigned long state, data_len, sig, sig_len); break; + case TEE_MAIN_ALGO_ED25519: + res = tee_svc_obj_ed25519_verify(o->attr, data, + data_len, sig, sig_len, + params, num_params); + break; + case TEE_MAIN_ALGO_ECDSA: case TEE_MAIN_ALGO_SM2_DSA_SM3: res = crypto_acipher_ecc_verify(cs->algo, o->attr, data, diff --git a/lib/libutee/include/tee_api_defines.h b/lib/libutee/include/tee_api_defines.h index c58f1de0a68..7d29fd67e26 100644 --- a/lib/libutee/include/tee_api_defines.h +++ b/lib/libutee/include/tee_api_defines.h @@ -196,6 +196,7 @@ #define TEE_ALG_ECDSA_P256 0x70003041 #define TEE_ALG_ECDSA_P384 0x70004041 #define TEE_ALG_ECDSA_P521 0x70005041 +#define TEE_ALG_ED25519 0x70006043 /* v1.3.1 spec */ #define TEE_ALG_ECDH_P192 0x80001042 #define TEE_ALG_ECDH_P224 0x80002042 #define TEE_ALG_ECDH_P256 0x80003042 @@ -228,6 +229,8 @@ #define TEE_TYPE_ECDSA_KEYPAIR 0xA1000041 #define TEE_TYPE_ECDH_PUBLIC_KEY 0xA0000042 #define TEE_TYPE_ECDH_KEYPAIR 0xA1000042 +#define TEE_TYPE_ED25519_PUBLIC_KEY 0xA0000043 /* v1.3.1 spec */ +#define TEE_TYPE_ED25519_KEYPAIR 0xA1000043 /* v1.3.1 spec */ #define TEE_TYPE_SM2_DSA_PUBLIC_KEY 0xA0000045 #define TEE_TYPE_SM2_DSA_KEYPAIR 0xA1000045 #define TEE_TYPE_SM2_KEP_PUBLIC_KEY 0xA0000046 @@ -275,8 +278,12 @@ #define TEE_ATTR_SM2_KEP_CONFIRMATION_OUT 0xD0000846 #define TEE_ATTR_ECC_EPHEMERAL_PUBLIC_VALUE_X 0xD0000946 /* Missing in 1.2.1 */ #define TEE_ATTR_ECC_EPHEMERAL_PUBLIC_VALUE_Y 0xD0000A46 /* Missing in 1.2.1 */ +#define TEE_ATTR_EDDSA_CTX 0xD0000643 /* v1.3.1 spec */ +#define TEE_ATTR_ED25519_PUBLIC_VALUE 0xD0000743 /* v1.3.1 spec */ +#define TEE_ATTR_ED25519_PRIVATE_VALUE 0xC0000843 /* v1.3.1 spec */ #define TEE_ATTR_X25519_PUBLIC_VALUE 0xD0000944 #define TEE_ATTR_X25519_PRIVATE_VALUE 0xC0000A44 +#define TEE_ATTR_EDDSA_PREHASH 0xF0000004 /* v1.3.1 spec */ #define TEE_ATTR_FLAG_PUBLIC (1 << 28) #define TEE_ATTR_FLAG_VALUE (1 << 29) diff --git a/lib/libutee/include/utee_defines.h b/lib/libutee/include/utee_defines.h index 36a3c792e30..a9106829c57 100644 --- a/lib/libutee/include/utee_defines.h +++ b/lib/libutee/include/utee_defines.h @@ -32,6 +32,7 @@ #define TEE_MAIN_ALGO_DH 0x32 #define TEE_MAIN_ALGO_ECDSA 0x41 #define TEE_MAIN_ALGO_ECDH 0x42 +#define TEE_MAIN_ALGO_ED25519 0x43 #define TEE_MAIN_ALGO_SM2_DSA_SM3 0x45 /* Not in v1.2 spec */ #define TEE_MAIN_ALGO_SM2_KEP 0x46 /* Not in v1.2 spec */ #define TEE_MAIN_ALGO_SM2_PKE 0x47 /* Not in v1.2 spec */ @@ -78,6 +79,8 @@ static inline uint32_t __tee_alg_get_main_alg(uint32_t algo) return TEE_MAIN_ALGO_SM2_KEP; case TEE_ALG_X25519: return TEE_MAIN_ALGO_X25519; + case TEE_ALG_ED25519: + return TEE_MAIN_ALGO_ED25519; default: break; } diff --git a/lib/libutee/tee_api_operations.c b/lib/libutee/tee_api_operations.c index 0a8e4f8cdcf..9bb3e7656cf 100644 --- a/lib/libutee/tee_api_operations.c +++ b/lib/libutee/tee_api_operations.c @@ -105,6 +105,7 @@ TEE_Result TEE_AllocateOperation(TEE_OperationHandle *operation, if (maxKeySize != 521) return TEE_ERROR_NOT_SUPPORTED; break; + case TEE_ALG_ED25519: case TEE_ALG_X25519: if (maxKeySize != 256) return TEE_ERROR_NOT_SUPPORTED; @@ -169,6 +170,7 @@ TEE_Result TEE_AllocateOperation(TEE_OperationHandle *operation, case TEE_ALG_ECDSA_P384: case TEE_ALG_ECDSA_P521: case TEE_ALG_SM2_DSA_SM3: + case TEE_ALG_ED25519: if (mode == TEE_MODE_SIGN) { with_private_key = true; req_key_usage = TEE_USAGE_SIGN; @@ -2075,6 +2077,10 @@ TEE_Result TEE_IsAlgorithmSupported(uint32_t alg, uint32_t element) if (alg == TEE_ALG_X25519 && element == TEE_ECC_CURVE_25519) return TEE_SUCCESS; } + if (IS_ENABLED(CFG_CRYPTO_ED25519)) { + if (alg == TEE_ALG_ED25519 && element == TEE_ECC_CURVE_25519) + return TEE_SUCCESS; + } return TEE_ERROR_NOT_SUPPORTED; check_element_none: