From a2f229101942e53bd0c325022c98044c6923373a Mon Sep 17 00:00:00 2001 From: Valerii Chubar Date: Fri, 12 Aug 2022 08:37:31 +0000 Subject: [PATCH] core: crypto: add Ed25519 support Put in place Ed25519 core functionality and support it for OP-TEE crypto syscalls. Signed-off-by: Valerii Chubar Signed-off-by: Sergiy Kibrik Reviewed-by: Jerome Forissier --- core/crypto.mk | 8 +- core/tee/tee_svc_cryp.c | 190 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 195 insertions(+), 3 deletions(-) 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/tee/tee_svc_cryp.c b/core/tee/tee_svc_cryp.c index e62af6dd911..72616c61bd2 100644 --- a/core/tee/tee_svc_cryp.c +++ b/core/tee/tee_svc_cryp.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -85,6 +86,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 +449,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 +608,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 +1381,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 +1517,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 +2141,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 +2389,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 +2520,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 +4146,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 +4299,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,