From: Zhushuai Yin <yinzhushuai@huawei.com> uadk_engine will support some algorithms in the OpenSSL 3.0 scenario. Currently, the framework has adapted to some of these algorithms. However, when executing the SM3 algorithm, an error related to SM2 is reported. This is because OpenSSL 3.0 has removed SM2 from the engine scenario in methmods, causing the failure. A fix is needed. At the same time, the differences in the pkey_ctx structure between the two OpenSSL versions were resolved, enabling the engine to support the x25519 and x448 algorithms on OpenSSL 3.0. Signed-off-by: Zhushuai Yin <yinzhushuai@huawei.com> --- src/uadk_ecx.c | 152 +++++++++++++++++++++++++++++++++++++++++++++++- src/uadk_pkey.c | 2 + 2 files changed, 151 insertions(+), 3 deletions(-) diff --git a/src/uadk_ecx.c b/src/uadk_ecx.c index 20a0f77..c9cc6c0 100644 --- a/src/uadk_ecx.c +++ b/src/uadk_ecx.c @@ -35,11 +35,157 @@ #define UADK_E_SUCCESS 1 #define UADK_E_FAIL 0 +#if OPENSSL_VERSION_NUMBER >= 0x30000000 +enum ECX_KEY_TYPE { + ECX_KEY_TYPE_X25519, + ECX_KEY_TYPE_X448, + ECX_KEY_TYPE_ED25519, + ECX_KEY_TYPE_ED448 +}; + +struct ecx_key { + OSSL_LIB_CTX *libctx; + char *propq; + unsigned int haspubkey:1; + unsigned char pubkey[ECX_MAX_KEYLEN]; + unsigned char *privkey; + size_t keylen; + enum ECX_KEY_TYPE type; + int references; + CRYPTO_RWLOCK *lock; +}; + +struct evp_pkey_ctx_st { + /* Actual operation */ + int operation; + + /* + * Library context, property query, keytype and keymgmt associated with + * this context + */ + OSSL_LIB_CTX *libctx; + char *propquery; + const char *keytype; + /* If |pkey| below is set, this field is always a reference to its keymgmt */ + EVP_KEYMGMT *keymgmt; + + union { + struct { + void *genctx; + } keymgmt; + + struct { + EVP_KEYEXCH *exchange; + /* + * Opaque ctx returned from a providers exchange algorithm + * implementation OSSL_FUNC_keyexch_newctx() + */ + void *algctx; + } kex; + + struct { + EVP_SIGNATURE *signature; + /* + * Opaque ctx returned from a providers signature algorithm + * implementation OSSL_FUNC_signature_newctx() + */ + void *algctx; + } sig; + + struct { + EVP_ASYM_CIPHER *cipher; + /* + * Opaque ctx returned from a providers asymmetric cipher algorithm + * implementation OSSL_FUNC_asym_cipher_newctx() + */ + void *algctx; + } ciph; + struct { + EVP_KEM *kem; + /* + * Opaque ctx returned from a providers KEM algorithm + * implementation OSSL_FUNC_kem_newctx() + */ + void *algctx; + } encap; + } op; + + /* + * Cached parameters. Inits of operations that depend on these should + * call evp_pkey_ctx_use_delayed_data() when the operation has been set + * up properly. + */ + struct { + /* Distinguishing Identifier, ISO/IEC 15946-3, FIPS 196 */ + char *dist_id_name; /* The name used with EVP_PKEY_CTX_ctrl_str() */ + void *dist_id; /* The distinguishing ID itself */ + size_t dist_id_len; /* The length of the distinguishing ID */ + + /* Indicators of what has been set. Keep them together! */ + unsigned int dist_id_set : 1; + } cached_parameters; + + /* Application specific data, usually used by the callback */ + void *app_data; + /* Keygen callback */ + EVP_PKEY_gen_cb *pkey_gencb; + /* implementation specific keygen data */ + int *keygen_info; + int keygen_info_count; + + /* Legacy fields below */ + + /* EVP_PKEY identity */ + int legacy_keytype; + /* Method associated with this operation */ + const EVP_PKEY_METHOD *pmeth; + /* Engine that implements this method or NULL if builtin */ + ENGINE *engine; + /* Key: may be NULL */ + EVP_PKEY *pkey; + /* Peer key for key agreement, may be NULL */ + EVP_PKEY *peerkey; + /* Algorithm specific data */ + void *data; + /* Indicator if digest_custom needs to be called */ + unsigned int flag_call_digest_custom:1; + /* + * Used to support taking custody of memory in the case of a provider being + * used with the deprecated EVP_PKEY_CTX_set_rsa_keygen_pubexp() API. This + * member should NOT be used for any other purpose and should be removed + * when said deprecated API is excised completely. + */ + BIGNUM *rsa_pubexp; +}; +#else struct ecx_key { unsigned char pubkey[ECX_MAX_KEYLEN]; unsigned char *privkey; }; +struct evp_pkey_ctx_st { + /* Method associated with this operation */ + const EVP_PKEY_METHOD *pmeth; + /* Engine that implements this method or NULL if builtin */ + ENGINE *engine; + /* Key: may be NULL */ + EVP_PKEY *pkey; + /* Peer key for key agreement, may be NULL */ + EVP_PKEY *peerkey; + /* Actual operation */ + int operation; + /* Algorithm specific data */ + void *data; + /* Application specific data */ + void *app_data; + /* Keygen callback */ + EVP_PKEY_gen_cb *pkey_gencb; + /* implementation specific keygen data */ + int *keygen_info; + int keygen_info_count; +}; +#endif + struct ecx_ctx { handle_t sess; __u32 key_size; @@ -151,12 +297,12 @@ static int x448_init(EVP_PKEY_CTX *ctx) static int ecx_get_nid(EVP_PKEY_CTX *ctx) { - const EVP_PKEY_METHOD **pmeth_from_ctx; + const EVP_PKEY_METHOD *pmeth_from_ctx; int nid; - pmeth_from_ctx = (const EVP_PKEY_METHOD **)ctx; + pmeth_from_ctx = (const EVP_PKEY_METHOD *)(ctx->pmeth); - EVP_PKEY_meth_get0_info(&nid, NULL, *pmeth_from_ctx); + EVP_PKEY_meth_get0_info(&nid, NULL, pmeth_from_ctx); if (nid != EVP_PKEY_X25519 && nid != EVP_PKEY_X448) return UADK_E_FAIL; diff --git a/src/uadk_pkey.c b/src/uadk_pkey.c index 94a74d9..fb45ccc 100644 --- a/src/uadk_pkey.c +++ b/src/uadk_pkey.c @@ -34,7 +34,9 @@ static int g_ecc_support_state[ECC_TYPE]; static int pkey_nids[] = { EVP_PKEY_EC, +#if OPENSSL_VERSION_NUMBER < 0x30000000 EVP_PKEY_SM2, +#endif EVP_PKEY_X25519, EVP_PKEY_X448 }; -- 2.43.0