diff --git a/core/include/crypto/crypto.h b/core/include/crypto/crypto.h index 98ebf0275c7..20c2674c929 100644 --- a/core/include/crypto/crypto.h +++ b/core/include/crypto/crypto.h @@ -175,6 +175,7 @@ struct x25519_keypair { struct ed25519_keypair { uint8_t *priv; uint8_t *pub; + uint32_t curve; }; /* diff --git a/core/tee/tee_svc_cryp.c b/core/tee/tee_svc_cryp.c index 4a4ee5f0101..1da13c73cb9 100644 --- a/core/tee/tee_svc_cryp.c +++ b/core/tee/tee_svc_cryp.c @@ -473,6 +473,13 @@ const struct tee_cryp_obj_type_attrs tee_cryp_obj_ed25519_keypair_attrs[] = { .ops_index = ATTR_OPS_INDEX_25519, RAW_DATA(struct ed25519_keypair, pub) }, + + { + .attr_id = TEE_ATTR_ECC_CURVE, + .flags = TEE_TYPE_ATTR_SIZE_INDICATOR | TEE_TYPE_ATTR_GEN_KEY_REQ, + .ops_index = ATTR_OPS_INDEX_VALUE, + RAW_DATA(struct ed25519_keypair, curve) + }, }; struct tee_cryp_obj_type_props { @@ -1765,6 +1772,7 @@ static TEE_Result get_ec_key_size(uint32_t curve, size_t *key_size) *key_size = 521; break; case TEE_ECC_CURVE_SM2: + case TEE_ECC_CURVE_25519: *key_size = 256; break; default: diff --git a/ta/pkcs11/include/pkcs11_ta.h b/ta/pkcs11/include/pkcs11_ta.h index 887c3dbec4f..1372f0d42f6 100644 --- a/ta/pkcs11/include/pkcs11_ta.h +++ b/ta/pkcs11/include/pkcs11_ta.h @@ -1169,6 +1169,7 @@ enum pkcs11_key_type { PKCS11_CKK_DSA = 0x001, PKCS11_CKK_DH = 0x002, PKCS11_CKK_EC = 0x003, + PKCS11_CKK_EDDSA = 0x004, PKCS11_CKK_GENERIC_SECRET = 0x010, PKCS11_CKK_AES = 0x01f, PKCS11_CKK_MD5_HMAC = 0x027, @@ -1177,6 +1178,7 @@ enum pkcs11_key_type { PKCS11_CKK_SHA384_HMAC = 0x02c, PKCS11_CKK_SHA512_HMAC = 0x02d, PKCS11_CKK_SHA224_HMAC = 0x02e, + PKCS11_CKK_EC_EDWARDS = 0x040, /* Vendor extension: reserved for undefined ID (~0U) */ PKCS11_CKK_UNDEFINED_ID = PKCS11_UNDEFINED_ID, }; @@ -1250,6 +1252,8 @@ enum pkcs11_mechanism_id { PKCS11_CKM_ECDSA_SHA384 = 0x01045, PKCS11_CKM_ECDSA_SHA512 = 0x01046, PKCS11_CKM_ECDH1_DERIVE = 0x01050, + PKCS11_CKM_EC_EDWARDS_KEY_PAIR_GEN = 0x01055, + PKCS11_CKM_EDDSA = 0x01057, PKCS11_CKM_AES_KEY_GEN = 0x01080, PKCS11_CKM_AES_ECB = 0x01081, PKCS11_CKM_AES_CBC = 0x01082, diff --git a/ta/pkcs11/src/pkcs11_attributes.c b/ta/pkcs11/src/pkcs11_attributes.c index aad20fae28c..a6b451f23b2 100644 --- a/ta/pkcs11/src/pkcs11_attributes.c +++ b/ta/pkcs11/src/pkcs11_attributes.c @@ -470,6 +470,12 @@ static const uint32_t ec_private_key_opt_or_null[] = { PKCS11_CKA_VALUE, }; +static const uint32_t eddsa_private_key_opt_or_null[] = { + PKCS11_CKA_EC_PARAMS, + PKCS11_CKA_VALUE, + PKCS11_CKA_EC_POINT, +}; + static enum pkcs11_rc create_storage_attributes(struct obj_attrs **out, struct obj_attrs *temp) { @@ -767,6 +773,7 @@ static enum pkcs11_rc create_pub_key_attributes(struct obj_attrs **out, } break; case PKCS11_CKK_EC: + case PKCS11_CKK_EC_EDWARDS: mandated = ec_public_key_mandated; oon = ec_public_key_opt_or_null; mandated_count = ARRAY_SIZE(ec_public_key_mandated); @@ -829,6 +836,12 @@ static enum pkcs11_rc create_priv_key_attributes(struct obj_attrs **out, mandated_count = ARRAY_SIZE(ec_private_key_mandated); oon_count = ARRAY_SIZE(ec_private_key_opt_or_null); break; + case PKCS11_CKK_EC_EDWARDS: + mandated = ec_private_key_mandated; + oon = eddsa_private_key_opt_or_null; + mandated_count = ARRAY_SIZE(ec_private_key_mandated); + oon_count = ARRAY_SIZE(eddsa_private_key_opt_or_null); + break; default: EMSG("Invalid key type %#"PRIx32"/%s", get_key_type(*out), id2str_key_type(get_key_type(*out))); @@ -978,6 +991,10 @@ create_attributes_from_template(struct obj_attrs **out, void *template, */ if (function == PKCS11_FUNCTION_GENERATE_PAIR) { switch (mecha) { + case PKCS11_CKM_EC_EDWARDS_KEY_PAIR_GEN: + class = template_class; + type = PKCS11_CKK_EDDSA; + break; case PKCS11_CKM_EC_KEY_PAIR_GEN: class = template_class; type = PKCS11_CKK_EC; @@ -1055,6 +1072,14 @@ create_attributes_from_template(struct obj_attrs **out, void *template, goto out; } break; + case PKCS11_CKM_EC_EDWARDS_KEY_PAIR_GEN: + if ((get_class(temp) != PKCS11_CKO_PUBLIC_KEY && + get_class(temp) != PKCS11_CKO_PRIVATE_KEY) || + get_key_type(temp) != PKCS11_CKK_EC_EDWARDS) { + rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; + goto out; + } + break; case PKCS11_CKM_RSA_PKCS_KEY_PAIR_GEN: if ((get_class(temp) != PKCS11_CKO_PUBLIC_KEY && get_class(temp) != PKCS11_CKO_PRIVATE_KEY) || @@ -1382,6 +1407,7 @@ enum pkcs11_rc check_created_attrs_against_processing(uint32_t proc_id, break; case PKCS11_CKM_GENERIC_SECRET_KEY_GEN: case PKCS11_CKM_AES_KEY_GEN: + case PKCS11_CKM_EC_EDWARDS_KEY_PAIR_GEN: case PKCS11_CKM_EC_KEY_PAIR_GEN: case PKCS11_CKM_RSA_PKCS_KEY_PAIR_GEN: assert(check_attr_bval(proc_id, head, PKCS11_CKA_LOCAL, true)); @@ -1398,6 +1424,9 @@ enum pkcs11_rc check_created_attrs_against_processing(uint32_t proc_id, case PKCS11_CKM_AES_KEY_GEN: assert(get_key_type(head) == PKCS11_CKK_AES); break; + case PKCS11_CKM_EC_EDWARDS_KEY_PAIR_GEN: + assert(get_key_type(head) == PKCS11_CKK_EC_EDWARDS); + break; case PKCS11_CKM_EC_KEY_PAIR_GEN: assert(get_key_type(head) == PKCS11_CKK_EC); break; @@ -1448,6 +1477,9 @@ static void get_key_min_max_sizes(enum pkcs11_key_type key_type, case PKCS11_CKK_EC: mechanism = PKCS11_CKM_EC_KEY_PAIR_GEN; break; + case PKCS11_CKK_EDDSA: + mechanism = PKCS11_CKM_EC_EDWARDS_KEY_PAIR_GEN; + break; case PKCS11_CKK_RSA: mechanism = PKCS11_CKM_RSA_PKCS_KEY_PAIR_GEN; break; @@ -1539,6 +1571,7 @@ enum pkcs11_rc check_created_attrs(struct obj_attrs *key1, key_length = ROUNDUP(key_length, 8) / 8; break; case PKCS11_CKK_EC: + case PKCS11_CKK_EC_EDWARDS: break; default: return PKCS11_CKR_TEMPLATE_INCONSISTENT; @@ -1548,6 +1581,7 @@ enum pkcs11_rc check_created_attrs(struct obj_attrs *key1, switch (get_key_type(private)) { case PKCS11_CKK_RSA: case PKCS11_CKK_EC: + case PKCS11_CKK_EC_EDWARDS: break; default: return PKCS11_CKR_TEMPLATE_INCONSISTENT; @@ -1560,6 +1594,7 @@ enum pkcs11_rc check_created_attrs(struct obj_attrs *key1, */ switch (get_key_type(key1)) { case PKCS11_CKK_EC: + case PKCS11_CKK_EC_EDWARDS: return PKCS11_CKR_OK; default: break; @@ -1742,6 +1777,22 @@ check_parent_attrs_against_processing(enum pkcs11_mechanism_id proc_id, } break; + case PKCS11_CKM_EDDSA: + if (key_type != PKCS11_CKK_EC_EDWARDS) { + EMSG("Invalid key %s for mechanism %s", + id2str_type(key_type, key_class), + id2str_proc(proc_id)); + return PKCS11_CKR_KEY_TYPE_INCONSISTENT; + } + if (key_class != PKCS11_CKO_PUBLIC_KEY && + key_class != PKCS11_CKO_PRIVATE_KEY) { + EMSG("Invalid key class for mechanism %s", + id2str_proc(proc_id)); + + return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; + } + break; + case PKCS11_CKM_ECDSA: case PKCS11_CKM_ECDSA_SHA1: case PKCS11_CKM_ECDSA_SHA224: diff --git a/ta/pkcs11/src/pkcs11_helpers.c b/ta/pkcs11/src/pkcs11_helpers.c index d2139645bf6..f3653fe31c7 100644 --- a/ta/pkcs11/src/pkcs11_helpers.c +++ b/ta/pkcs11/src/pkcs11_helpers.c @@ -336,6 +336,8 @@ static const struct any_id __maybe_unused string_key_type[] = { PKCS11_ID(PKCS11_CKK_SHA384_HMAC), PKCS11_ID(PKCS11_CKK_SHA512_HMAC), PKCS11_ID(PKCS11_CKK_EC), + PKCS11_ID(PKCS11_CKK_EC_EDWARDS), + PKCS11_ID(PKCS11_CKK_EDDSA), PKCS11_ID(PKCS11_CKK_RSA), PKCS11_ID(PKCS11_CKK_UNDEFINED_ID) }; @@ -495,6 +497,7 @@ bool key_type_is_asymm_key(uint32_t id) switch (key_type) { case PKCS11_CKK_EC: + case PKCS11_CKK_EC_EDWARDS: case PKCS11_CKK_RSA: return true; default: diff --git a/ta/pkcs11/src/processing.c b/ta/pkcs11/src/processing.c index 08374513e2d..6ad6a08ddb7 100644 --- a/ta/pkcs11/src/processing.c +++ b/ta/pkcs11/src/processing.c @@ -146,6 +146,7 @@ size_t get_object_key_bit_size(struct pkcs11_object *obj) return a_size * 8; case PKCS11_CKK_EC: + case PKCS11_CKK_EC_EDWARDS: if (get_attribute_ptr(attrs, PKCS11_CKA_EC_PARAMS, &a_ptr, &a_size) || !a_ptr) return 0; @@ -503,6 +504,9 @@ enum pkcs11_rc entry_generate_key_pair(struct pkcs11_client *client, /* Generate key pair */ switch (proc_params->id) { + case PKCS11_CKM_EC_EDWARDS_KEY_PAIR_GEN: + rc = generate_eddsa_keys(proc_params, &pub_head, &priv_head); + break; case PKCS11_CKM_EC_KEY_PAIR_GEN: rc = generate_ec_keys(proc_params, &pub_head, &priv_head); break; diff --git a/ta/pkcs11/src/processing.h b/ta/pkcs11/src/processing.h index 306d2c96e20..943514f79a6 100644 --- a/ta/pkcs11/src/processing.h +++ b/ta/pkcs11/src/processing.h @@ -45,6 +45,19 @@ struct rsa_oaep_processing_ctx { uint8_t source_data[]; }; +/** + * EDDSA processing context + * + * @flag: Prehash flag + * @ctx_len: Length of the context data + * @ctx: Context data + */ +struct eddsa_processing_ctx { + uint32_t flag; + uint32_t ctx_len; + uint8_t ctx[]; +}; + /* * Entry points from PKCS11 TA invocation commands */ @@ -152,6 +165,10 @@ enum pkcs11_rc load_tee_ec_key_attrs(TEE_Attribute **tee_attrs, size_t *tee_count, struct pkcs11_object *obj); +enum pkcs11_rc load_tee_eddsa_key_attrs(TEE_Attribute **tee_attrs, + size_t *tee_count, + struct pkcs11_object *obj); + size_t ec_params2tee_keysize(void *attr, size_t size); uint32_t ec_params2tee_curve(void *attr, size_t size); @@ -164,6 +181,10 @@ enum pkcs11_rc generate_ec_keys(struct pkcs11_attribute_head *proc_params, struct obj_attrs **pub_head, struct obj_attrs **priv_head); +enum pkcs11_rc generate_eddsa_keys(struct pkcs11_attribute_head *proc_params, + struct obj_attrs **pub_head, + struct obj_attrs **priv_head); + size_t ecdsa_get_input_max_byte_size(TEE_OperationHandle op); /* @@ -187,6 +208,10 @@ enum pkcs11_rc pkcs2tee_proc_params_rsa_oaep(struct active_processing *proc, struct pkcs11_attribute_head *proc_params); +enum pkcs11_rc +pkcs2tee_proc_params_eddsa(struct active_processing *proc, + struct pkcs11_attribute_head *proc_params); + enum pkcs11_rc pkcs2tee_algo_rsa_oaep(uint32_t *tee_id, uint32_t *tee_hash_id, struct pkcs11_attribute_head *params); diff --git a/ta/pkcs11/src/processing_asymm.c b/ta/pkcs11/src/processing_asymm.c index 6c7e140dbfc..d4bb6ff8465 100644 --- a/ta/pkcs11/src/processing_asymm.c +++ b/ta/pkcs11/src/processing_asymm.c @@ -34,6 +34,7 @@ bool processing_is_tee_asymm(uint32_t proc_id) case PKCS11_CKM_SHA384_RSA_PKCS_PSS: case PKCS11_CKM_SHA512_RSA_PKCS_PSS: /* EC flavors */ + case PKCS11_CKM_EDDSA: case PKCS11_CKM_ECDSA: case PKCS11_CKM_ECDH1_DERIVE: case PKCS11_CKM_ECDSA_SHA1: @@ -92,6 +93,7 @@ pkcs2tee_algorithm(uint32_t *tee_id, uint32_t *tee_hash_id, { PKCS11_CKM_ECDSA_SHA384, 1, TEE_ALG_SHA384 }, { PKCS11_CKM_ECDSA_SHA512, 1, TEE_ALG_SHA512 }, { PKCS11_CKM_ECDH1_DERIVE, 1, 0 }, + { PKCS11_CKM_EDDSA, TEE_ALG_ED25519, 0 }, }; size_t n = 0; enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; @@ -184,6 +186,12 @@ static enum pkcs11_rc pkcs2tee_key_type(uint32_t *tee_type, else *tee_type = TEE_TYPE_RSA_PUBLIC_KEY; break; + case PKCS11_CKK_EC_EDWARDS: + if (class == PKCS11_CKO_PRIVATE_KEY) + *tee_type = TEE_TYPE_ED25519_KEYPAIR; + else + *tee_type = TEE_TYPE_ED25519_PUBLIC_KEY; + break; default: TEE_Panic(type); break; @@ -315,6 +323,10 @@ static enum pkcs11_rc load_tee_key(struct pkcs11_session *session, case PKCS11_CKK_EC: rc = load_tee_ec_key_attrs(&tee_attrs, &tee_attrs_count, obj); break; + case PKCS11_CKK_EC_EDWARDS: + rc = load_tee_eddsa_key_attrs(&tee_attrs, &tee_attrs_count, + obj); + break; default: break; } @@ -381,6 +393,9 @@ init_tee_operation(struct pkcs11_session *session, case PKCS11_CKM_RSA_PKCS_OAEP: rc = pkcs2tee_proc_params_rsa_oaep(proc, proc_params); break; + case PKCS11_CKM_EDDSA: + rc = pkcs2tee_proc_params_eddsa(proc, proc_params); + break; default: break; } @@ -438,6 +453,7 @@ enum pkcs11_rc step_asymm_operation(struct pkcs11_session *session, struct active_processing *proc = session->processing; struct rsa_oaep_processing_ctx *rsa_oaep_ctx = NULL; struct rsa_pss_processing_ctx *rsa_pss_ctx = NULL; + struct eddsa_processing_ctx *eddsa_ctx = NULL; size_t sz = 0; if (TEE_PARAM_TYPE_GET(ptypes, 1) == TEE_PARAM_TYPE_MEMREF_INPUT) { @@ -492,6 +508,29 @@ enum pkcs11_rc step_asymm_operation(struct pkcs11_session *session, rsa_pss_ctx->salt_len, 0); tee_attrs_count++; break; + case PKCS11_CKM_EDDSA: + eddsa_ctx = proc->extra_ctx; + + tee_attrs = TEE_Malloc(2 * sizeof(TEE_Attribute), + TEE_USER_MEM_HINT_NO_FILL_ZERO); + if (!tee_attrs) { + rc = PKCS11_CKR_DEVICE_MEMORY; + goto out; + } + + if (eddsa_ctx->flag) { + TEE_InitValueAttribute(&tee_attrs[tee_attrs_count], + TEE_ATTR_EDDSA_PREHASH, 0, 0); + tee_attrs_count++; + } + + if (eddsa_ctx->ctx_len > 0) { + TEE_InitRefAttribute(&tee_attrs[tee_attrs_count], + TEE_ATTR_EDDSA_CTX, eddsa_ctx->ctx, + eddsa_ctx->ctx_len); + tee_attrs_count++; + } + break; case PKCS11_CKM_RSA_PKCS_OAEP: rsa_oaep_ctx = proc->extra_ctx; @@ -672,6 +711,7 @@ enum pkcs11_rc step_asymm_operation(struct pkcs11_session *session, /* Next perform actual signing operation */ switch (proc->mecha_type) { case PKCS11_CKM_ECDSA: + case PKCS11_CKM_EDDSA: case PKCS11_CKM_RSA_PKCS: case PKCS11_CKM_RSA_PKCS_OAEP: case PKCS11_CKM_RSA_PKCS_PSS: diff --git a/ta/pkcs11/src/processing_ec.c b/ta/pkcs11/src/processing_ec.c index a465a9d2c95..4f60c753a1a 100644 --- a/ta/pkcs11/src/processing_ec.c +++ b/ta/pkcs11/src/processing_ec.c @@ -12,6 +12,7 @@ #include "attributes.h" #include "object.h" +#include "pkcs11_token.h" #include "processing.h" /* @@ -244,6 +245,22 @@ static const uint8_t secp521r1_oid_der[] = { 0x91, 0x38, 0x64, 0x09, 0x02, 0x01, 0x01, }; +/* + * Edwards curves may be specified in two flavours: + * - as a PrintableString 'edwards25519' or 'edwards448' + * - as an OID, DER encoded ASN.1 Object + */ + +static const uint8_t ed25519_name_der[] = { + 0x13, 0x0c, 'e', 'd', 'w', 'a', 'r', 'd', 's', + '2', '5', '5', '1', '9', +}; + +static const uint8_t ed25519_oid_der[] = { + 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xda, + 0x47, 0x0f, 0x01, +}; + struct supported_ecc_curve { const uint8_t *oid_der; size_t oid_size; @@ -273,6 +290,7 @@ static const struct supported_ecc_curve ec_curve_param[] = { ECC_CURVE(TEE_ECC_CURVE_NIST_P256, 256, prime256v1), ECC_CURVE(TEE_ECC_CURVE_NIST_P384, 384, secp384r1), ECC_CURVE(TEE_ECC_CURVE_NIST_P521, 521, secp521r1), + ECC_CURVE(TEE_ECC_CURVE_25519, 256, ed25519), }; static const struct supported_ecc_curve *get_curve(void *attr, size_t size) @@ -624,6 +642,193 @@ enum pkcs11_rc generate_ec_keys(struct pkcs11_attribute_head *proc_params, return rc; } +enum pkcs11_rc load_tee_eddsa_key_attrs(TEE_Attribute **tee_attrs, + size_t *tee_count, + struct pkcs11_object *obj) +{ + TEE_Attribute *attrs = NULL; + size_t count = 0; + enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; + + assert(get_key_type(obj->attributes) == PKCS11_CKK_EC_EDWARDS); + + switch (get_class(obj->attributes)) { + case PKCS11_CKO_PUBLIC_KEY: + attrs = TEE_Malloc(sizeof(TEE_Attribute), + TEE_USER_MEM_HINT_NO_FILL_ZERO); + if (!attrs) + return PKCS11_CKR_DEVICE_MEMORY; + + if (pkcs2tee_load_attr(&attrs[count], + TEE_ATTR_ED25519_PUBLIC_VALUE, + obj, PKCS11_CKA_EC_POINT)) + count++; + + if (count == 1) + rc = PKCS11_CKR_OK; + + break; + + case PKCS11_CKO_PRIVATE_KEY: + attrs = TEE_Malloc(2 * sizeof(TEE_Attribute), + TEE_USER_MEM_HINT_NO_FILL_ZERO); + if (!attrs) + return PKCS11_CKR_DEVICE_MEMORY; + + if (pkcs2tee_load_attr(&attrs[count], + TEE_ATTR_ED25519_PRIVATE_VALUE, + obj, PKCS11_CKA_VALUE)) + count++; + + if (pkcs2tee_load_attr(&attrs[count], + TEE_ATTR_ED25519_PUBLIC_VALUE, + obj, PKCS11_CKA_EC_POINT)) + count++; + + if (count == 2) + rc = PKCS11_CKR_OK; + + break; + + default: + assert(0); + break; + } + + if (rc == PKCS11_CKR_OK) { + *tee_attrs = attrs; + *tee_count = count; + } else { + TEE_Free(attrs); + } + + return rc; +} + +enum pkcs11_rc generate_eddsa_keys(struct pkcs11_attribute_head *proc_params, + struct obj_attrs **pub_head, + struct obj_attrs **priv_head) +{ + enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; + void *a_ptr = NULL; + uint32_t a_size = 0; + uint32_t tee_size = 0; + uint32_t tee_curve = 0; + TEE_ObjectHandle tee_obj = TEE_HANDLE_NULL; + TEE_Attribute tee_key_attr[1] = { }; + TEE_Result res = TEE_ERROR_GENERIC; + + if (!proc_params || !*pub_head || !*priv_head) + return PKCS11_CKR_TEMPLATE_INCONSISTENT; + + if (remove_empty_attribute(pub_head, PKCS11_CKA_EC_POINT) || + remove_empty_attribute(priv_head, PKCS11_CKA_VALUE) || + remove_empty_attribute(priv_head, PKCS11_CKA_EC_PARAMS)) { + EMSG("Unexpected attribute(s) found"); + trace_attributes("public-key", *pub_head); + trace_attributes("private-key", *priv_head); + return PKCS11_CKR_TEMPLATE_INCONSISTENT; + } + + if (get_attribute_ptr(*pub_head, PKCS11_CKA_EC_PARAMS, + &a_ptr, &a_size) || !a_ptr) { + EMSG("No EC_PARAMS attribute found in public key"); + return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID; + } + + tee_size = ec_params2tee_keysize(a_ptr, a_size); + if (!tee_size) + return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID; + + tee_curve = ec_params2tee_curve(a_ptr, a_size); + + TEE_InitValueAttribute(tee_key_attr, TEE_ATTR_ECC_CURVE, tee_curve, 1); + + res = TEE_AllocateTransientObject(TEE_TYPE_ED25519_KEYPAIR, tee_size, + &tee_obj); + if (res) { + EMSG("Transient alloc failed with %#"PRIx32, res); + return tee2pkcs_error(res); + } + + res = TEE_RestrictObjectUsage1(tee_obj, TEE_USAGE_EXTRACTABLE); + if (res) { + rc = tee2pkcs_error(res); + goto out; + } + + res = TEE_GenerateKey(tee_obj, tee_size, tee_key_attr, 1); + if (res) { + rc = tee2pkcs_error(res); + goto out; + } + + /* Private key needs the same EC_PARAMS as used by the public key */ + rc = add_attribute(priv_head, PKCS11_CKA_EC_PARAMS, a_ptr, a_size); + if (rc) + goto out; + + rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_VALUE, + tee_obj, TEE_ATTR_ED25519_PRIVATE_VALUE); + if (rc) + goto out; + + rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_EC_POINT, + tee_obj, TEE_ATTR_ED25519_PUBLIC_VALUE); + if (rc) + goto out; + + rc = tee2pkcs_add_attribute(pub_head, PKCS11_CKA_EC_POINT, + tee_obj, TEE_ATTR_ED25519_PUBLIC_VALUE); + +out: + if (tee_obj != TEE_HANDLE_NULL) + TEE_CloseObject(tee_obj); + + return rc; +} + +enum pkcs11_rc +pkcs2tee_proc_params_eddsa(struct active_processing *proc, + struct pkcs11_attribute_head *proc_params) +{ + enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; + uint32_t ctx_len = 0; + uint32_t flag = 0; + void *ctx_data = NULL; + struct serialargs args = { }; + struct eddsa_processing_ctx *ctx = NULL; + + serialargs_init(&args, proc_params->data, proc_params->size); + + rc = serialargs_get_u32(&args, &flag); + if (rc) + return rc; + + rc = serialargs_get_u32(&args, &ctx_len); + if (rc) + return rc; + + rc = serialargs_get_ptr(&args, &ctx_data, ctx_len); + if (rc) + return rc; + + if (serialargs_remaining_bytes(&args)) + return PKCS11_CKR_ARGUMENTS_BAD; + + proc->extra_ctx = TEE_Malloc(sizeof(*ctx) + ctx_len, + TEE_USER_MEM_HINT_NO_FILL_ZERO); + if (!proc->extra_ctx) + return PKCS11_CKR_DEVICE_MEMORY; + + ctx = proc->extra_ctx; + ctx->ctx_len = ctx_len; + ctx->flag = flag; + TEE_MemMove(ctx->ctx, ctx_data, ctx_len); + + return PKCS11_CKR_OK; +} + size_t ecdsa_get_input_max_byte_size(TEE_OperationHandle op) { TEE_OperationInfo info = { }; diff --git a/ta/pkcs11/src/token_capabilities.c b/ta/pkcs11/src/token_capabilities.c index 0ab473978f4..195c7f60d13 100644 --- a/ta/pkcs11/src/token_capabilities.c +++ b/ta/pkcs11/src/token_capabilities.c @@ -118,6 +118,10 @@ static const struct pkcs11_mechachism_modes pkcs11_modes[] = { MECHANISM(PKCS11_CKM_ECDSA_SHA256, CKFM_AUTH_NO_RECOVER, ANY_PART), MECHANISM(PKCS11_CKM_ECDSA_SHA384, CKFM_AUTH_NO_RECOVER, ANY_PART), MECHANISM(PKCS11_CKM_ECDSA_SHA512, CKFM_AUTH_NO_RECOVER, ANY_PART), + /* EDDSA */ + MECHANISM(PKCS11_CKM_EC_EDWARDS_KEY_PAIR_GEN, + PKCS11_CKFM_GENERATE_KEY_PAIR, ANY_PART), + MECHANISM(PKCS11_CKM_EDDSA, CKFM_AUTH_NO_RECOVER, ANY_PART), /* RSA */ MECHANISM(PKCS11_CKM_RSA_PKCS_KEY_PAIR_GEN, PKCS11_CKFM_GENERATE_KEY_PAIR, ANY_PART), @@ -253,12 +257,15 @@ const struct pkcs11_mechachism_modes token_mechanism[] = { TA_MECHANISM(PKCS11_CKM_SHA512_HMAC_GENERAL, CKFM_AUTH_NO_RECOVER), TA_MECHANISM(PKCS11_CKM_EC_KEY_PAIR_GEN, PKCS11_CKFM_GENERATE_KEY_PAIR), + TA_MECHANISM(PKCS11_CKM_EC_EDWARDS_KEY_PAIR_GEN, + PKCS11_CKFM_GENERATE_KEY_PAIR), TA_MECHANISM(PKCS11_CKM_ECDSA, CKFM_AUTH_NO_RECOVER), TA_MECHANISM(PKCS11_CKM_ECDSA_SHA1, CKFM_AUTH_NO_RECOVER), TA_MECHANISM(PKCS11_CKM_ECDSA_SHA224, CKFM_AUTH_NO_RECOVER), TA_MECHANISM(PKCS11_CKM_ECDSA_SHA256, CKFM_AUTH_NO_RECOVER), TA_MECHANISM(PKCS11_CKM_ECDSA_SHA384, CKFM_AUTH_NO_RECOVER), TA_MECHANISM(PKCS11_CKM_ECDSA_SHA512, CKFM_AUTH_NO_RECOVER), + TA_MECHANISM(PKCS11_CKM_EDDSA, CKFM_AUTH_NO_RECOVER), TA_MECHANISM(PKCS11_CKM_RSA_PKCS_KEY_PAIR_GEN, PKCS11_CKFM_GENERATE_KEY_PAIR), TA_MECHANISM(PKCS11_CKM_RSA_PKCS, CKFM_CIPHER | CKFM_AUTH_NO_RECOVER), @@ -393,6 +400,11 @@ void pkcs11_mechanism_supported_key_sizes(uint32_t proc_id, *min_key_size = 160; /* in bits */ *max_key_size = 521; /* in bits */ break; + case PKCS11_CKM_EC_EDWARDS_KEY_PAIR_GEN: + case PKCS11_CKM_EDDSA: + *min_key_size = 256; /* in bits */ + *max_key_size = 448; /* in bits */ + break; case PKCS11_CKM_RSA_PKCS_KEY_PAIR_GEN: case PKCS11_CKM_RSA_PKCS: case PKCS11_CKM_MD5_RSA_PKCS: @@ -426,8 +438,10 @@ void mechanism_supported_key_sizes_bytes(uint32_t proc_id, switch (proc_id) { case PKCS11_CKM_GENERIC_SECRET_KEY_GEN: + case PKCS11_CKM_EC_EDWARDS_KEY_PAIR_GEN: case PKCS11_CKM_EC_KEY_PAIR_GEN: case PKCS11_CKM_ECDSA: + case PKCS11_CKM_EDDSA: case PKCS11_CKM_ECDSA_SHA1: case PKCS11_CKM_ECDSA_SHA224: case PKCS11_CKM_ECDSA_SHA256: