From dd148be238326a25a57d11cf281dfbdca52a35dd Mon Sep 17 00:00:00 2001 From: loubaihui Date: Sat, 15 Jul 2023 00:34:27 +0800 Subject: [PATCH] crypto: add X448 support Refer to the X25519 algorithm, add the X448 algorithm framework code. Signed-off-by: loubaihui Acked-by: Jerome Forissier Acked-by: Jens Wiklander --- core/crypto.mk | 1 + core/crypto/crypto.c | 25 +++++++ core/include/crypto/crypto.h | 8 +++ core/tee/tee_svc_cryp.c | 107 +++++++++++++++++++++++++++++ lib/libutee/include/utee_defines.h | 3 + 5 files changed, 144 insertions(+) diff --git a/core/crypto.mk b/core/crypto.mk index dbc305a408f..9e2c2be27f8 100644 --- a/core/crypto.mk +++ b/core/crypto.mk @@ -64,6 +64,7 @@ CFG_CRYPTO_SM2_DSA ?= y CFG_CRYPTO_SM2_KEP ?= y CFG_CRYPTO_ED25519 ?= y CFG_CRYPTO_X25519 ?= y +CFG_CRYPTO_X448 ?= y # Authenticated encryption CFG_CRYPTO_CCM ?= y diff --git a/core/crypto/crypto.c b/core/crypto/crypto.c index 5712a2de386..5b16ad47435 100644 --- a/core/crypto/crypto.c +++ b/core/crypto/crypto.c @@ -859,6 +859,31 @@ TEE_Result crypto_acipher_x25519_shared_secret(struct montgomery_keypair } #endif +#if !defined(CFG_CRYPTO_X448) +TEE_Result crypto_acipher_alloc_x448_keypair(struct montgomery_keypair *key + __unused, + size_t key_size_bits __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} + +TEE_Result crypto_acipher_gen_x448_key(struct montgomery_keypair *key __unused, + size_t key_size __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} + +TEE_Result crypto_acipher_x448_shared_secret(struct montgomery_keypair + *private_key __unused, + void *public_key __unused, + void *secret __unused, + unsigned long + *secret_len __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} +#endif + #if !defined(CFG_CRYPTO_ED25519) TEE_Result crypto_acipher_alloc_ed25519_keypair(struct ed25519_keypair *key __unused, diff --git a/core/include/crypto/crypto.h b/core/include/crypto/crypto.h index 2c2fc94c575..d0ee5f38f07 100644 --- a/core/include/crypto/crypto.h +++ b/core/include/crypto/crypto.h @@ -210,6 +210,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 montgomery_keypair *s, size_t key_size_bits); +TEE_Result crypto_acipher_alloc_x448_keypair(struct montgomery_keypair *s, + size_t key_size_bits); TEE_Result crypto_acipher_alloc_ed25519_keypair(struct ed25519_keypair *s, size_t key_size_bits); TEE_Result @@ -226,6 +228,8 @@ 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 montgomery_keypair *key, size_t key_size); +TEE_Result crypto_acipher_gen_x448_key(struct montgomery_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, @@ -300,6 +304,10 @@ TEE_Result crypto_acipher_x25519_shared_secret(struct montgomery_keypair *private_key, void *public_key, void *secret, unsigned long *secret_len); +TEE_Result crypto_acipher_x448_shared_secret(struct montgomery_keypair + *private_key, + void *public_key, void *secret, + unsigned long *secret_len); struct sm2_kep_parms { uint8_t *out; diff --git a/core/tee/tee_svc_cryp.c b/core/tee/tee_svc_cryp.c index 553d771f0b6..9a5a1eab980 100644 --- a/core/tee/tee_svc_cryp.c +++ b/core/tee/tee_svc_cryp.c @@ -82,9 +82,11 @@ struct tee_cryp_obj_secret { #define ATTR_OPS_INDEX_VALUE 2 /* Convert to/from curve25519 attribute depending on direction */ #define ATTR_OPS_INDEX_25519 3 +#define ATTR_OPS_INDEX_448 4 /* Curve25519 key bytes size is always 32 bytes*/ #define KEY_SIZE_BYTES_25519 UL(32) +#define KEY_SIZE_BYTES_448 UL(56) /* TEE Internal Core API v1.3.1, Table 6-8 */ #define TEE_ED25519_CTX_MAX_LENGTH 255 @@ -448,6 +450,23 @@ const struct tee_cryp_obj_type_attrs tee_cryp_obj_x25519_keypair_attrs[] = { }, }; +static +const struct tee_cryp_obj_type_attrs tee_cryp_obj_x448_keypair_attrs[] = { + { + .attr_id = TEE_ATTR_X448_PRIVATE_VALUE, + .flags = TEE_TYPE_ATTR_REQUIRED, + .ops_index = ATTR_OPS_INDEX_448, + RAW_DATA(struct montgomery_keypair, priv) + }, + + { + .attr_id = TEE_ATTR_X448_PUBLIC_VALUE, + .flags = TEE_TYPE_ATTR_REQUIRED, + .ops_index = ATTR_OPS_INDEX_448, + RAW_DATA(struct montgomery_keypair, pub) + }, +}; + static const struct tee_cryp_obj_type_attrs tee_cryp_obj_ed25519_pub_key_attrs[] = { { @@ -638,6 +657,10 @@ static const struct tee_cryp_obj_type_props tee_cryp_obj_props[] = { sizeof(struct montgomery_keypair), tee_cryp_obj_x25519_keypair_attrs), + PROP(TEE_TYPE_X448_KEYPAIR, 1, 448, 448, + sizeof(struct montgomery_keypair), + tee_cryp_obj_x448_keypair_attrs), + PROP(TEE_TYPE_ED25519_PUBLIC_KEY, 1, 256, 256, sizeof(struct ed25519_public_key), tee_cryp_obj_ed25519_pub_key_attrs), @@ -1433,6 +1456,9 @@ TEE_Result tee_obj_attr_copy_from(struct tee_obj *o, const struct tee_obj *src) } else if (o->info.objectType == TEE_TYPE_X25519_PUBLIC_KEY) { if (src->info.objectType != TEE_TYPE_X25519_KEYPAIR) return TEE_ERROR_BAD_PARAMETERS; + } else if (o->info.objectType == TEE_TYPE_X448_PUBLIC_KEY) { + if (src->info.objectType != TEE_TYPE_X448_KEYPAIR) + return TEE_ERROR_BAD_PARAMETERS; } else { return TEE_ERROR_BAD_PARAMETERS; } @@ -1566,6 +1592,10 @@ 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_X448_KEYPAIR: + res = crypto_acipher_alloc_x448_keypair(o->attr, + max_key_size); + break; case TEE_TYPE_ED25519_KEYPAIR: res = crypto_acipher_alloc_ed25519_keypair(o->attr, max_key_size); @@ -2206,6 +2236,32 @@ tee_svc_obj_generate_key_x25519(struct tee_obj *o, return TEE_SUCCESS; } +static TEE_Result +tee_svc_obj_generate_key_x448(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 montgomery_keypair *tee_x448_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; + + tee_x448_key = (struct montgomery_keypair *)o->attr; + res = crypto_acipher_gen_x448_key(tee_x448_key, key_size); + if (res != TEE_SUCCESS) + return res; + + set_attribute(o, type_props, TEE_ATTR_X448_PRIVATE_VALUE); + set_attribute(o, type_props, TEE_ATTR_X448_PUBLIC_VALUE); + + return TEE_SUCCESS; +} + static TEE_Result tee_svc_obj_generate_key_ed25519(struct tee_obj *o, const struct tee_cryp_obj_type_props @@ -2464,6 +2520,12 @@ TEE_Result syscall_obj_generate_key(unsigned long obj, unsigned long key_size, if (res != TEE_SUCCESS) goto out; break; + case TEE_TYPE_X448_KEYPAIR: + res = tee_svc_obj_generate_key_x448(o, type_props, key_size, + params, param_count); + if (res != TEE_SUCCESS) + goto out; + break; case TEE_TYPE_ED25519_KEYPAIR: res = tee_svc_obj_generate_key_ed25519(o, type_props, key_size, @@ -2649,6 +2711,9 @@ static TEE_Result tee_svc_cryp_check_key_type(const struct tee_obj *o, case TEE_MAIN_ALGO_X25519: req_key_type = TEE_TYPE_X25519_KEYPAIR; break; + case TEE_MAIN_ALGO_X448: + req_key_type = TEE_TYPE_X448_KEYPAIR; + break; default: return TEE_ERROR_BAD_PARAMETERS; } @@ -3920,6 +3985,48 @@ TEE_Result syscall_cryp_derive_key(unsigned long state, } } #endif +#if defined(CFG_CRYPTO_X448) + else if (cs->algo == TEE_ALG_X448) { + uint8_t *x448_pub_key = NULL; + uint8_t *pt_secret = NULL; + unsigned long pt_secret_len = 0; + void *bbuf = NULL; + + if (param_count != 1 || + params[0].attributeID != TEE_ATTR_X448_PUBLIC_VALUE) { + res = TEE_ERROR_BAD_PARAMETERS; + goto out; + } + + /* X448 public key size is 56 bytes */ + if (params[0].content.ref.length != KEY_SIZE_BYTES_448) { + res = TEE_ERROR_BAD_PARAMETERS; + goto out; + } + + res = bb_memdup_user(params[0].content.ref.buffer, + params[0].content.ref.length, + &bbuf); + if (res) + goto out; + + /* Set the public key */ + x448_pub_key = bbuf; + + pt_secret = (uint8_t *)(sk + 1); + pt_secret_len = sk->alloc_size; + res = crypto_acipher_x448_shared_secret(ko->attr, + x448_pub_key, + pt_secret, + &pt_secret_len); + + if (res == TEE_SUCCESS) { + sk->key_size = pt_secret_len; + so->info.handleFlags |= TEE_HANDLE_FLAG_INITIALIZED; + set_attribute(so, type_props, TEE_ATTR_SECRET_VALUE); + } + } +#endif else res = TEE_ERROR_NOT_SUPPORTED; diff --git a/lib/libutee/include/utee_defines.h b/lib/libutee/include/utee_defines.h index 564bd23f019..bfbe5933e3a 100644 --- a/lib/libutee/include/utee_defines.h +++ b/lib/libutee/include/utee_defines.h @@ -46,6 +46,7 @@ #define TEE_MAIN_ALGO_X25519 0x44 /* Not in v1.2 spec */ #define TEE_MAIN_ALGO_SHAKE128 0xC3 /* OP-TEE extension */ #define TEE_MAIN_ALGO_SHAKE256 0xC4 /* OP-TEE extension */ +#define TEE_MAIN_ALGO_X448 0xC5 /* OP-TEE extension */ #define TEE_CHAIN_MODE_ECB_NOPAD 0x0 @@ -105,6 +106,8 @@ static inline uint32_t __tee_alg_get_main_alg(uint32_t algo) return TEE_MAIN_ALGO_SHAKE128; case TEE_ALG_SHAKE256: return TEE_MAIN_ALGO_SHAKE256; + case TEE_ALG_X448: + return TEE_MAIN_ALGO_X448; default: break; }