From: Zhiqi Song songzhiqi1@huawei.com
Based on the original implementation, a unified data structure is used. And FFC-related extended functions are added.
Signed-off-by: Zhiqi Song songzhiqi1@huawei.com --- src/uadk_prov.h | 5 +- src/uadk_prov_dh.c | 2609 ++++++++++++++++++++++-------------------- src/uadk_prov_init.c | 1 + src/uadk_prov_pkey.h | 106 ++ 4 files changed, 1508 insertions(+), 1213 deletions(-)
diff --git a/src/uadk_prov.h b/src/uadk_prov.h index 1b8aab9..e0174b0 100644 --- a/src/uadk_prov.h +++ b/src/uadk_prov.h @@ -146,8 +146,8 @@ extern const OSSL_DISPATCH uadk_rsa_signature_functions[FUNC_MAX_NUM]; extern const OSSL_DISPATCH uadk_rsa_keymgmt_functions[FUNC_MAX_NUM]; extern const OSSL_DISPATCH uadk_rsa_asym_cipher_functions[FUNC_MAX_NUM];
-extern const OSSL_DISPATCH uadk_dh_keymgmt_functions[]; -extern const OSSL_DISPATCH uadk_dh_keyexch_functions[]; +extern const OSSL_DISPATCH uadk_dh_keymgmt_functions[FUNC_MAX_NUM]; +extern const OSSL_DISPATCH uadk_dh_keyexch_functions[FUNC_MAX_NUM];
extern const OSSL_DISPATCH uadk_sm2_keymgmt_functions[FUNC_MAX_NUM]; extern const OSSL_DISPATCH uadk_sm2_signature_functions[FUNC_MAX_NUM]; @@ -158,6 +158,7 @@ void uadk_prov_destroy_cipher(void); void uadk_prov_destroy_rsa(void); void uadk_prov_destroy_dh(void); void uadk_prov_sm2_uninit(void); +void uadk_prov_dh_uninit(void);
/* offload small packets to sw */ extern int enable_sw_offload; diff --git a/src/uadk_prov_dh.c b/src/uadk_prov_dh.c index 5d35a6a..57d66f5 100644 --- a/src/uadk_prov_dh.c +++ b/src/uadk_prov_dh.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: Apache-2.0 /* * Copyright 2023-2024 Huawei Technologies Co.,Ltd. All rights reserved. * Copyright 2023-2024 Linaro ltd. @@ -16,97 +17,49 @@ * */ #include <openssl/core_names.h> -#include <openssl/proverr.h> #include <openssl/dh.h> +#include <openssl/kdf.h> +#include <openssl/proverr.h> #include <uadk/wd_dh.h> #include <uadk/wd_sched.h> #include "uadk.h" #include "uadk_async.h" #include "uadk_prov.h" +#include "uadk_prov_ffc.h" +#include "uadk_prov_pkey.h" + +#define DH768BITS 768 +#define DH1024BITS 1024 +#define DH1536BITS 1536 +#define DH2048BITS 2048 +#define DH3072BITS 3072 +#define DH4096BITS 4096 +#define UADK_DH_MAX_MODULE_BIT 4096 +#define DH_GENERATOR_2 2 +#define CHAR_BIT_SIZE 3 +#define DH_PARAMS_CNT 3 +#define CTX_MODE_NUM 2 +#define UN_SET 0 +#define IS_SET 1 +#define CTX_ASYNC 1 +#define CTX_SYNC 0 +#define CTX_NUM 2 +#define UADK_DO_SOFT (-0xE0) +#define UADK_P_INIT_SUCCESS 0 +#define ENV_ENABLED 1 +#define KEY_GEN_BY_PROV 1 +#define KEY_GEN_BY_USR 0 +#define RAND_MAX_CNT 1000 +#define LEN_ZERO 0 +#define DH_MAX_PARAM_LEN 80 +#define IGNORE_Q 1 +#define USE_PAD 1 +#define KDF_PARAM_NUM 5 + +UADK_PKEY_KEYMGMT_DESCR(dh, DH); +UADK_PKEY_KEYEXCH_DESCR(dh, DH);
-#define DH768BITS 768 -#define DH1024BITS 1024 -#define DH1536BITS 1536 -#define DH2048BITS 2048 -#define DH3072BITS 3072 -#define DH4096BITS 4096 -#define UADK_DH_MAX_MODULE_BIT 4096 -#define DH_GENERATOR_2 2 -#define DH_GENERATOR_5 5 -#define CHAR_BIT_SIZE 3 -#define DH_PARAMS_CNT 3 -#define CTX_MODE_NUM 2 -#define UN_SET 0 -#define IS_SET 1 -#define CTX_ASYNC 1 -#define CTX_SYNC 0 -#define CTX_NUM 2 -#define UADK_DO_SOFT (-0xE0) -#define UADK_E_SUCCESS 1 -#define UADK_E_FAIL 0 -#define UADK_E_POLL_SUCCESS 0 -#define UADK_E_POLL_FAIL (-1) -#define UADK_E_INIT_SUCCESS 0 -#define ENV_ENABLED 1 -#define KEY_GEN_BY_ENGINE 1 - -struct evp_keyexch_st { - int name_id; - char *type_name; - const char *description; - OSSL_PROVIDER *prov; - CRYPTO_REF_COUNT refcnt; -# if OPENSSL_VERSION_NUMBER < 0x30200000 - CRYPTO_RWLOCK *lock; -# endif - OSSL_FUNC_keyexch_newctx_fn *newctx; - OSSL_FUNC_keyexch_init_fn *init; - OSSL_FUNC_keyexch_set_peer_fn *set_peer; - OSSL_FUNC_keyexch_derive_fn *derive; - OSSL_FUNC_keyexch_freectx_fn *freectx; - OSSL_FUNC_keyexch_dupctx_fn *dupctx; - OSSL_FUNC_keyexch_set_ctx_params_fn *set_ctx_params; - OSSL_FUNC_keyexch_settable_ctx_params_fn *settable_ctx_params; - OSSL_FUNC_keyexch_get_ctx_params_fn *get_ctx_params; - OSSL_FUNC_keyexch_gettable_ctx_params_fn *gettable_ctx_params; -} /* EVP_KEYEXCH */; - -typedef struct ffc_params_st { - /* Primes */ - BIGNUM *p; - BIGNUM *q; - /* Generator */ - BIGNUM *g; - /* DH X9.42 Optional Subgroup factor j >= 2 where p = j * q + 1 */ - BIGNUM *j; - - /* Required for FIPS186_4 validation of p, q and optionally canonical g */ - unsigned char *seed; - /* If this value is zero the hash size is used as the seed length */ - size_t seedlen; - /* Required for FIPS186_4 validation of p and q */ - int pcounter; - int nid; /* The identity of a named group */ - - /* - * Required for FIPS186_4 generation & validation of canonical g. - * It uses unverifiable g if this value is -1. - */ - int gindex; - int h; /* loop counter for unverifiable g */ - - unsigned int flags; - /* - * The digest to use for generation or validation. If this value is NULL, - * then the digest is chosen using the value of N. - */ - const char *mdname; - const char *mdprops; -#if OPENSSL_VERSION_NUMBER >= 0x30000060 - /* Default key length for known named groups according to RFC7919 */ - int keylength; -#endif -} FFC_PARAMS; +static pthread_mutex_t dh_mutex = PTHREAD_MUTEX_INITIALIZER;
struct dh_st { /* @@ -122,17 +75,18 @@ struct dh_st { BIGNUM *priv_key; /* x */ int flags; BN_MONT_CTX *method_mont_p; - CRYPTO_REF_COUNT references; + int references; #ifndef FIPS_MODULE CRYPTO_EX_DATA ex_data; ENGINE *engine; #endif OSSL_LIB_CTX * libctx; const DH_METHOD *meth; - CRYPTO_RWLOCK *lock; + void *lock;
/* Provider data */ - size_t dirty_cnt; /* If any key material changes, increment this */ + /* If any key material changes, increment this */ + size_t dirty_cnt; }; /* DH */
struct dh_method { @@ -154,27 +108,22 @@ struct dh_method { BN_GENCB *cb); };
-#define FFC_UNVERIFIABLE_GINDEX -1 -#define FFC_PARAM_FLAG_VALIDATE_PQ 0x01 -#define FFC_PARAM_FLAG_VALIDATE_G 0x02 -#define FFC_PARAM_FLAG_VALIDATE_PQG \ - (FFC_PARAM_FLAG_VALIDATE_PQ | FFC_PARAM_FLAG_VALIDATE_G) - struct uadk_dh_sess { handle_t sess; struct wd_dh_sess_setup setup; struct wd_dh_req req; DH *alg; __u16 key_size; - /* key_flag: 0 - key is defined by user, 1 - key is generated by engine */ + /* + * key_flag: 0 - key is defined by user + * 1 - key is generated by provider + */ int key_flag; };
struct dh_res { int pid; -} g_dh_res; - -static pthread_mutex_t dh_mutex = PTHREAD_MUTEX_INITIALIZER; +} g_dh_prov;
/* * This type is only really used to handle some legacy related functionality. @@ -191,33 +140,8 @@ enum kdf_type { PROV_DH_KDF_X9_42_ASN1 };
-/* - * What's passed as an actual key is defined by the KEYMGMT interface. - * We happen to know that our KEYMGMT simply passes DH structures, so - * we use that here too. - */ - typedef struct { OSSL_LIB_CTX *libctx; - DH *dh; - DH *dhpeer; - unsigned int pad : 1; - - /* DH KDF */ - /* KDF (if any) to use for DH */ - enum kdf_type kdf_type; - /* Message digest to use for key derivation */ - EVP_MD *kdf_md; - /* User key material */ - unsigned char *kdf_ukm; - size_t kdf_ukmlen; - /* KDF output length */ - size_t kdf_outlen; - char *kdf_cekalg; -} UADK_PROV_DH_CTX; - -struct dh_gen_ctx { - OSSL_LIB_CTX *libctx;
FFC_PARAMS *ffc_params; int selection; @@ -240,212 +164,247 @@ struct dh_gen_ctx { OSSL_CALLBACK *cb; void *cbarg; int dh_type; -}; +} PROV_DH_KEYMGMT_CTX;
+/* + * What's passed as an actual key is defined by the KEYMGMT interface. + * We happen to know that our KEYMGMT simply passes DH structures, so + * we use that here too. + */ typedef struct { - int id; /* libcrypto internal */ - int name_id; - char *type_name; - const char *description; - OSSL_PROVIDER *prov; - - CRYPTO_REF_COUNT refcnt; -# if OPENSSL_VERSION_NUMBER < 0x30200000 - CRYPTO_RWLOCK *lock; -# endif - - /* Constructor(s), destructor, information */ - OSSL_FUNC_keymgmt_new_fn *new; - OSSL_FUNC_keymgmt_free_fn *free; - OSSL_FUNC_keymgmt_get_params_fn *get_params; - OSSL_FUNC_keymgmt_gettable_params_fn *gettable_params; - OSSL_FUNC_keymgmt_set_params_fn *set_params; - OSSL_FUNC_keymgmt_settable_params_fn *settable_params; - - /* Generation, a complex constructor */ - OSSL_FUNC_keymgmt_gen_init_fn *gen_init; - OSSL_FUNC_keymgmt_gen_set_template_fn *gen_set_template; - OSSL_FUNC_keymgmt_gen_set_params_fn *gen_set_params; - OSSL_FUNC_keymgmt_gen_settable_params_fn *gen_settable_params; - OSSL_FUNC_keymgmt_gen_fn *gen; - OSSL_FUNC_keymgmt_gen_cleanup_fn *gen_cleanup; - OSSL_FUNC_keymgmt_load_fn *load; - - /* Key object checking */ - OSSL_FUNC_keymgmt_query_operation_name_fn *query_operation_name; - OSSL_FUNC_keymgmt_has_fn *has; - OSSL_FUNC_keymgmt_validate_fn *validate; - OSSL_FUNC_keymgmt_match_fn *match; - - /* Import and export routines */ - OSSL_FUNC_keymgmt_import_fn *import; - OSSL_FUNC_keymgmt_import_types_fn *import_types; -# if OPENSSL_VERSION_NUMBER >= 0x30200000 - OSSL_FUNC_keymgmt_import_types_ex_fn *import_types_ex; -# endif - OSSL_FUNC_keymgmt_export_fn *export; - OSSL_FUNC_keymgmt_export_types_fn *export_types; -# if OPENSSL_VERSION_NUMBER >= 0x30200000 - OSSL_FUNC_keymgmt_export_types_ex_fn *export_types_ex; -# endif - OSSL_FUNC_keymgmt_dup_fn *dup; - -} UADK_DH_KEYMGMT; - -static inline int CRYPTO_UP_REF(int *val, int *ret, ossl_unused void *lock) -{ - *ret = __atomic_fetch_add(val, 1, __ATOMIC_RELAXED) + 1; - return 1; -} - -static inline int CRYPTO_DOWN_REF(int *val, int *ret, - ossl_unused void *lock) -{ - *ret = __atomic_fetch_sub(val, 1, __ATOMIC_RELAXED) - 1; - if (*ret == 0) - __atomic_thread_fence(__ATOMIC_ACQUIRE); - return 1; -} - -static FFC_PARAMS *uadk_dh_get0_params(DH *dh) + OSSL_LIB_CTX *libctx; + DH *dh; + DH *dhpeer; + unsigned int pad : 1; + + /* DH KDF */ + /* KDF (if any) to use for DH */ + enum kdf_type kdf_type; + /* Message digest to use for key derivation */ + EVP_MD *kdf_md; + /* User key material */ + unsigned char *kdf_ukm; + size_t kdf_ukmlen; + /* KDF output length */ + size_t kdf_outlen; + char *kdf_cekalg; +} PROV_DH_KEYEXCH_CTX; + +static void *uadk_keymgmt_dh_new(void *provctx) { - return &dh->params; + if (get_default_keymgmt().new_fun == NULL) + return NULL; + + return get_default_keymgmt().new_fun(provctx); }
-static int uadk_DH_size(const DH *dh) +static void uadk_keymgmt_dh_free(void *keydata) { - if (dh->params.p != NULL) - return BN_num_bytes(dh->params.p); - return -1; + if (get_default_keymgmt().free == NULL) + return; + + get_default_keymgmt().free(keydata); }
-static void uadk_DH_get0_key(const DH *dh, const BIGNUM **pub_key, - const BIGNUM **priv_key) +static int uadk_keymgmt_dh_has(const void *keydata, int selection) { - if (pub_key != NULL) - *pub_key = dh->pub_key; - if (priv_key != NULL) - *priv_key = dh->priv_key; + if (get_default_keymgmt().has == NULL) + return UADK_P_FAIL; + + return get_default_keymgmt().has(keydata, selection); }
-static int uadk_DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key) +static int uadk_keymgmt_dh_match(const void *keydata1, const void *keydata2, int selection) { - if (pub_key != NULL) { - BN_clear_free(dh->pub_key); - dh->pub_key = pub_key; - } + if (get_default_keymgmt().match == NULL) + return UADK_P_FAIL;
- if (priv_key != NULL) { - BN_clear_free(dh->priv_key); - dh->priv_key = priv_key; - } + return get_default_keymgmt().match(keydata1, keydata2, selection); +}
- dh->dirty_cnt++; - return 1; +static int uadk_keymgmt_dh_import(void *keydata, int selection, const OSSL_PARAM params[]) +{ + if (get_default_keymgmt().import == NULL) + return UADK_P_FAIL; + + return get_default_keymgmt().import(keydata, selection, params); }
-static FFC_PARAMS *uadk_ossl_dh_get0_params(DH *dh) +static int uadk_keymgmt_dh_export(void *keydata, int selection, OSSL_CALLBACK *cb, void *cb_params) { - return &dh->params; + if (get_default_keymgmt().export_fun == NULL) + return UADK_P_FAIL; + + return get_default_keymgmt().export_fun(keydata, selection, cb, cb_params); }
-static const BIGNUM *uadk_DH_get0_p(const DH *dh) +static const OSSL_PARAM *uadk_keymgmt_dh_import_types(int selection) { - return dh->params.p; + if (get_default_keymgmt().import_types == NULL) + return NULL; + + return get_default_keymgmt().import_types(selection); }
-static int ossl_ffc_params_set_seed(FFC_PARAMS *params, - const unsigned char *seed, size_t seedlen) +static const OSSL_PARAM *uadk_keymgmt_dh_export_types(int selection) { - if (params == NULL) - return 0; + if (get_default_keymgmt().export_types == NULL) + return NULL;
- if (params->seed != NULL) { - if (params->seed == seed) - return 1; - OPENSSL_free(params->seed); - } + return get_default_keymgmt().export_types(selection); +}
- if (seed != NULL && seedlen > 0) { - params->seed = OPENSSL_memdup(seed, seedlen); - if (params->seed == NULL) - return 0; - params->seedlen = seedlen; - } else { - params->seed = NULL; - params->seedlen = 0; - } - return 1; +static ossl_inline int uadk_keymgmt_dh_get_params(void *key, OSSL_PARAM params[]) +{ + if (get_default_keymgmt().get_params == NULL) + return UADK_P_FAIL; + + return get_default_keymgmt().get_params(key, params); }
-static int ffc_bn_cpy(BIGNUM **dst, const BIGNUM *src) +static const OSSL_PARAM *uadk_keymgmt_dh_gettable_params(void *provctx) { - BIGNUM *a; + if (get_default_keymgmt().gettable_params == NULL) + return NULL;
- /* - * If source is read only just copy the pointer, so - * we don't have to reallocate it. - */ - if (src == NULL) - a = NULL; - else if (BN_get_flags(src, BN_FLG_STATIC_DATA) - && !BN_get_flags(src, BN_FLG_MALLOCED)) - a = (BIGNUM *)src; - else { - a = BN_dup(src); - if (a == NULL) - return 0; - } + return get_default_keymgmt().gettable_params(provctx); +} + +static const OSSL_PARAM *uadk_keymgmt_dh_settable_params(void *provctx) +{ + if (get_default_keymgmt().settable_params == NULL) + return NULL;
- BN_clear_free(*dst); - *dst = a; - return 1; + return get_default_keymgmt().settable_params(provctx); }
-static int ossl_ffc_params_copy(FFC_PARAMS *dst, const FFC_PARAMS *src) +static int uadk_keymgmt_dh_set_params(void *key, const OSSL_PARAM params[]) { - if (!ffc_bn_cpy(&dst->p, src->p) - || !ffc_bn_cpy(&dst->g, src->g) - || !ffc_bn_cpy(&dst->q, src->q) - || !ffc_bn_cpy(&dst->j, src->j)) - return 0; + if (get_default_keymgmt().set_params == NULL) + return UADK_P_FAIL;
- OPENSSL_free(dst->seed); - dst->seedlen = src->seedlen; - if (src->seed != NULL) { - dst->seed = OPENSSL_memdup(src->seed, src->seedlen); - if (dst->seed == NULL) - return 0; - } else { - dst->seed = NULL; + return get_default_keymgmt().set_params(key, params); +} + +static int uadk_keymgmt_dh_validate(const void *keydata, int selection, int checktype) +{ + if (get_default_keymgmt().validate == NULL) + return UADK_P_FAIL; + + return get_default_keymgmt().validate(keydata, selection, checktype); +} + +static void *uadk_keymgmt_dh_gen_init(void *provctx, int selection, + const OSSL_PARAM params[]) +{ + if (get_default_keymgmt().gen_init == NULL) + return NULL; + + return get_default_keymgmt().gen_init(provctx, selection, params); +} + +static int uadk_keymgmt_dh_gen_set_template(void *genctx, void *templ) +{ + if (get_default_keymgmt().gen_set_template == NULL) + return UADK_P_FAIL; + + return get_default_keymgmt().gen_set_template(genctx, templ); +} + +static const OSSL_PARAM *uadk_keymgmt_dh_gen_settable_params(ossl_unused void *genctx, + ossl_unused void *provctx) +{ + if (get_default_keymgmt().gen_settable_params == NULL) + return NULL; + + return get_default_keymgmt().gen_settable_params(genctx, provctx); +} + +static int uadk_keymgmt_dh_gen_set_params(void *genctx, + const OSSL_PARAM params[]) +{ + if (get_default_keymgmt().gen_set_params == NULL) + return UADK_P_FAIL; + + return get_default_keymgmt().gen_set_params(genctx, params); +} + +static void uadk_keymgmt_dh_gen_cleanup(void *genctx) +{ + if (get_default_keymgmt().gen_cleanup == NULL) + return; + + get_default_keymgmt().gen_cleanup(genctx); +} + +static void *uadk_keymgmt_dh_load(const void *reference, size_t reference_sz) +{ + if (get_default_keymgmt().load == NULL) + return NULL; + + return get_default_keymgmt().load(reference, reference_sz); +} + +static void *uadk_keymgmt_dh_dup(const void *keydata_from, int selection) +{ + if (get_default_keymgmt().dup == NULL) + return NULL; + + return get_default_keymgmt().dup(keydata_from, selection); +} + +static int uadk_DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key) +{ + if (dh == NULL) { + fprintf(stderr, "invalid: dh is NULL\n"); + return UADK_P_FAIL; + } + + if (pub_key != NULL) { + BN_clear_free(dh->pub_key); + dh->pub_key = pub_key; } - dst->nid = src->nid; - dst->pcounter = src->pcounter; - dst->h = src->h; - dst->gindex = src->gindex; - dst->flags = src->flags; - return 1; + + if (priv_key != NULL) { + BN_clear_free(dh->priv_key); + dh->priv_key = priv_key; + } + + dh->dirty_cnt++; + + return UADK_P_SUCCESS; +} + +static FFC_PARAMS *ossl_dh_get0_params(DH *dh) +{ + if (dh == NULL) + return NULL; + + return &dh->params; +} + +static const BIGNUM *uadk_DH_get0_p(const DH *dh) +{ + if (dh == NULL) + return NULL; + + return dh->params.p; }
static const BIGNUM *uadk_DH_get0_q(const DH *dh) { + if (dh == NULL) + return NULL; + return dh->params.q; }
static long uadk_DH_get_length(const DH *dh) { - return dh->length; -} + if (dh == NULL) + return LEN_ZERO;
-static void ossl_ffc_params_get0_pqg(const FFC_PARAMS *d, const BIGNUM **p, - const BIGNUM **q, const BIGNUM **g) -{ - if (p != NULL) - *p = d->p; - if (q != NULL) - *q = d->q; - if (g != NULL) - *g = d->g; + return dh->length; }
static void uadk_DH_get0_pqg(const DH *dh, const BIGNUM **p, @@ -456,19 +415,31 @@ static void uadk_DH_get0_pqg(const DH *dh, const BIGNUM **p,
static const BIGNUM *uadk_DH_get0_priv_key(const DH *dh) { + if (dh == NULL) + return NULL; + return dh->priv_key; }
static const BIGNUM *uadk_DH_get0_pub_key(const DH *dh) { + if (dh == NULL) + return NULL; + return dh->pub_key; }
static int uadk_DH_bits(const DH *dh) { + int bits = 0; + + if (dh == NULL) + return bits; + if (dh->params.p != NULL) - return BN_num_bits(dh->params.p); - return -1; + bits = BN_num_bits(dh->params.p); + + return bits; }
static void uadk_DH_clear_flags(DH *dh, int flags) @@ -481,85 +452,77 @@ static void uadk_DH_set_flags(DH *dh, int flags) dh->flags |= flags; }
-static int uadk_ffc_params_cmp(const FFC_PARAMS *a, const FFC_PARAMS *b, int ignore_q) -{ - return BN_cmp(a->p, b->p) == 0 && BN_cmp(a->g, b->g) == 0 && - (ignore_q || BN_cmp(a->q, b->q) == 0); /* Note: q may be NULL */ -} - -static int uadk_DH_up_ref(DH *r) -{ - int i; - - if (CRYPTO_UP_REF(&r->references, &i, r->lock) <= 0) - return 0; - - if (i < 2) { - fprintf(stderr, "refcount error.\n"); - return 0; - } - return ((i > 1) ? 1 : 0); -} - -static EVP_KEYEXCH get_default_keyexch(void) -{ - static EVP_KEYEXCH s_keyexch; - static int initilazed; - - if (!initilazed) { - EVP_KEYEXCH *keyexch = - (EVP_KEYEXCH *)EVP_KEYEXCH_fetch(NULL, "DH", "provider=default"); - if (keyexch) { - s_keyexch = *keyexch; - EVP_KEYEXCH_free((EVP_KEYEXCH *)keyexch); - initilazed = 1; - } else { - fprintf(stderr, "EVP_KEYEXCH_fetch from default provider failed"); - } - } - return s_keyexch; -} - -static int dh_generate_new_priv_key(const DH *dh, BIGNUM *new_priv_key) +static int dh_gen_rand_prikey(const DH *dh, BIGNUM *new_prikey) { const BIGNUM *q = uadk_DH_get0_q(dh); - int bits; + int bits, cnt;
if (q) { + cnt = 0; do { - if (!BN_priv_rand_range(new_priv_key, q)) - return UADK_E_FAIL; - } while (BN_is_zero(new_priv_key) || BN_is_one(new_priv_key)); + if (!BN_priv_rand_range(new_prikey, q)) { + fprintf(stderr, "failed to BN_priv_rand_range\n"); + return UADK_P_FAIL; + } + + cnt++; + if (cnt > RAND_MAX_CNT) { + fprintf(stderr, "failed to get appropriate prikey, timeout\n"); + return UADK_P_FAIL; + } + } while (BN_is_zero(new_prikey) || BN_is_one(new_prikey)); } else { bits = uadk_DH_get_length(dh) ? uadk_DH_get_length(dh) : BN_num_bits(uadk_DH_get0_p(dh)) - 1; - if (!BN_priv_rand(new_priv_key, bits, BN_RAND_TOP_ONE, - BN_RAND_BOTTOM_ANY)) - return UADK_E_FAIL; + if (!BN_priv_rand(new_prikey, bits, BN_RAND_TOP_ONE, + BN_RAND_BOTTOM_ANY)) { + fprintf(stderr, "failed to BN_priv_rand\n"); + return UADK_P_FAIL; + } }
- return UADK_E_SUCCESS; + return UADK_P_SUCCESS; }
-static int dh_try_get_priv_key(struct uadk_dh_sess *dh_sess, const DH *dh, BIGNUM **priv_key) +static int uadk_prov_dh_prepare_prikey(struct uadk_dh_sess *dh_sess, const DH *dh, BIGNUM **prikey) { - *priv_key = (BIGNUM *)uadk_DH_get0_priv_key(dh); - if (!(*priv_key)) { - *priv_key = BN_secure_new(); - if (!(*priv_key)) - return UADK_E_FAIL; + *prikey = (BIGNUM *)uadk_DH_get0_priv_key(dh);
- if (!dh_generate_new_priv_key(dh, *priv_key)) - goto err; + if (*prikey == NULL) { + *prikey = BN_secure_new(); + if (*prikey == NULL) { + fprintf(stderr, "failed to do BN_secure_new\n"); + return UADK_P_FAIL; + }
- dh_sess->key_flag = KEY_GEN_BY_ENGINE; + if (dh_gen_rand_prikey(dh, *prikey) == UADK_P_FAIL) { + fprintf(stderr, "failed to generate new private key\n"); + goto free_prikey; + } + + dh_sess->key_flag = KEY_GEN_BY_PROV; + } else { + dh_sess->key_flag = KEY_GEN_BY_USR; }
- return UADK_E_SUCCESS; + return UADK_P_SUCCESS;
-err: - BN_free(*priv_key); - return UADK_E_FAIL; +free_prikey: + /* Free the prikey generated by uadk provider */ + BN_free(*prikey); + *prikey = NULL; + + return UADK_P_FAIL; +} + +static void uadk_prov_dh_free_prikey(struct uadk_dh_sess *dh_sess, BIGNUM *prikey) +{ + if (dh_sess == NULL) + return; + + /* User generated key will be freed by user, not uadk provider */ + if (prikey && dh_sess->key_flag == KEY_GEN_BY_PROV) + BN_free(prikey); }
static void uadk_prov_dh_cb(void *req_t) @@ -569,19 +532,19 @@ static void uadk_prov_dh_cb(void *req_t) struct wd_dh_req *req_origin; struct async_op *op;
- if (!req_new) + if (req_new == NULL) return;
cb_param = req_new->cb_param; - if (!cb_param) + if (cb_param == NULL) return;
req_origin = cb_param->priv; - if (!req_origin) + if (req_origin == NULL) return;
req_origin->status = req_new->status; - if (!req_origin->status) + if (req_origin->status == 0) req_origin->pri_bytes = req_new->pri_bytes;
op = cb_param->op; @@ -592,7 +555,7 @@ static void uadk_prov_dh_cb(void *req_t) } }
-static int uadk_dh_env_poll(void *ctx) +static int uadk_prov_dh_poll(void *ctx) { __u64 rx_cnt = 0; __u32 recv = 0; @@ -605,106 +568,88 @@ static int uadk_dh_env_poll(void *ctx) if (ret < 0 || recv == expt) return ret; rx_cnt++; - } while (rx_cnt < ENGINE_RECV_MAX_CNT); + } while (rx_cnt < PROV_ENV_RECV_MAX_CNT);
fprintf(stderr, "failed to poll msg: timeout!\n");
return -ETIMEDOUT; }
+static void uadk_prov_dh_mutex_infork(void) +{ + /* Release the replication lock of the child process */ + pthread_mutex_unlock(&dh_mutex); +} + static int uadk_prov_dh_init(void) { int ret;
+ pthread_atfork(NULL, NULL, uadk_prov_dh_mutex_infork); pthread_mutex_lock(&dh_mutex); - if (g_dh_res.pid != getpid()) { - ret = wd_dh_init2("dh", 0, 0); - if (unlikely(ret)) + if (g_dh_prov.pid != getpid()) { + ret = wd_dh_init2("dh", SCHED_POLICY_RR, TASK_HW); + if (unlikely(ret)) { + pthread_mutex_unlock(&dh_mutex); return ret; - g_dh_res.pid = getpid(); - async_register_poll_fn(ASYNC_TASK_DH, uadk_dh_env_poll); + } + g_dh_prov.pid = getpid(); + async_register_poll_fn(ASYNC_TASK_DH, uadk_prov_dh_poll); } pthread_mutex_unlock(&dh_mutex);
- return UADK_E_INIT_SUCCESS; + return UADK_P_INIT_SUCCESS; }
-static struct uadk_dh_sess *dh_new_eng_session(DH *dh_alg) +/* Uninit only when the process exits, not uninit when thread exits */ +void uadk_prov_dh_uninit(void) { - struct uadk_dh_sess *dh_sess; - - dh_sess = OPENSSL_malloc(sizeof(struct uadk_dh_sess)); - if (!dh_sess) - return NULL; - - memset(dh_sess, 0, sizeof(struct uadk_dh_sess)); - - dh_sess->alg = dh_alg; - - return dh_sess; + pthread_mutex_lock(&dh_mutex); + if (g_dh_prov.pid == getpid()) { + wd_dh_uninit2(); + g_dh_prov.pid = 0; + } + pthread_mutex_unlock(&dh_mutex); }
-static int dh_init_eng_session(struct uadk_dh_sess *dh_sess, - __u16 bits, bool is_g2) +static struct uadk_dh_sess *uadk_prov_dh_new_session(DH *dh, __u16 bits, bool is_g2) { + struct uadk_dh_sess *dh_sess = OPENSSL_zalloc(sizeof(struct uadk_dh_sess)); __u16 key_size = bits >> CHAR_BIT_SIZE; struct sched_params params = {0};
- if (dh_sess->sess && dh_sess->req.x_p) { - memset(dh_sess->req.x_p, 0, dh_sess->req.pbytes + - dh_sess->req.xbytes); - return UADK_E_SUCCESS; + if (dh_sess == NULL) { + fprintf(stderr, "failed to alloc dh session\n"); + return NULL; }
- if (!dh_sess->sess) { - dh_sess->key_size = key_size; - dh_sess->setup.key_bits = bits; - dh_sess->setup.is_g2 = is_g2; - /* Use the default numa parameters */ - params.numa_id = -1; - dh_sess->setup.sched_param = ¶ms; - dh_sess->sess = wd_dh_alloc_sess(&dh_sess->setup); - if (!dh_sess->sess) - return UADK_E_FAIL; + dh_sess->alg = dh; + dh_sess->key_size = key_size; + dh_sess->setup.key_bits = bits; + dh_sess->setup.is_g2 = is_g2; + /* Use the default numa parameters */ + params.numa_id = -1; + dh_sess->setup.sched_param = ¶ms; + dh_sess->sess = wd_dh_alloc_sess(&dh_sess->setup); + if (dh_sess->sess == (handle_t)0) { + fprintf(stderr, "failed to init dh sess\n"); + OPENSSL_free(dh_sess); + return NULL; }
- return UADK_E_SUCCESS; + return dh_sess; }
-static void dh_free_eng_session(struct uadk_dh_sess *dh_sess) +static void uadk_prov_dh_free_session(struct uadk_dh_sess *dh_sess) { - if (!dh_sess) + if (dh_sess == NULL) return;
if (dh_sess->sess) wd_dh_free_sess(dh_sess->sess);
- if (dh_sess->req.x_p) - OPENSSL_free(dh_sess->req.x_p); - - if (dh_sess->req.pv) - OPENSSL_free(dh_sess->req.pv); - - OPENSSL_free(dh_sess); -} - -static struct uadk_dh_sess *dh_get_eng_session(DH *dh, __u16 bits, - bool is_g2) -{ - struct uadk_dh_sess *dh_sess = dh_new_eng_session(dh); - int ret; - - if (!dh_sess) - return NULL; - - ret = dh_init_eng_session(dh_sess, bits, is_g2); - if (!ret) { - dh_free_eng_session(dh_sess); - return NULL; - } - - return dh_sess; -} + OPENSSL_free(dh_sess); +}
static int check_dh_bit_useful(const __u16 bits) { @@ -714,7 +659,7 @@ static int check_dh_bit_useful(const __u16 bits) * OPENSSL_DH_MAX_MODULUS_BITS, 10000 bits. * OpenSSL speed tool supports 2048/3072/4096/6144/8192 bits. * UADK supports 768/1024/1536/2048/3072/4096 bits. - * UADK-engine will be consistent with UADK. + * UADK-provider will be consistent with UADK. */ switch (bits) { case DH768BITS: @@ -723,17 +668,16 @@ static int check_dh_bit_useful(const __u16 bits) case DH2048BITS: case DH3072BITS: case DH4096BITS: - return UADK_E_SUCCESS; + return UADK_P_SUCCESS; default: break; }
- return UADK_E_FAIL; + return UADK_P_FAIL; }
-static int dh_prepare_data(const BIGNUM *g, DH *dh, - struct uadk_dh_sess **dh_sess, - BIGNUM **priv_key) +static int uadk_prov_dh_prepare_data(const BIGNUM *g, DH *dh, struct uadk_dh_sess **dh_sess, + BIGNUM **prikey) { bool is_g2 = BN_is_word(g, DH_GENERATOR_2); __u16 bits; @@ -744,178 +688,149 @@ static int dh_prepare_data(const BIGNUM *g, DH *dh, * OPENSSL_DH_MAX_MODULUS_BITS, 10000 bits. */ bits = (__u16)uadk_DH_bits(dh); + if (bits == 0) { + fprintf(stderr, "invalid dh bits %u\n", bits); + return UADK_P_FAIL; + } + ret = check_dh_bit_useful(bits); - if (!ret) { - fprintf(stderr, "op size is not supported by uadk engine\n"); - return UADK_E_FAIL; + if (ret == UADK_P_FAIL) { + fprintf(stderr, "invalid: dh%u is not supported by uadk provider\n", bits); + return UADK_P_FAIL; }
- *dh_sess = dh_get_eng_session(dh, bits, is_g2); - if (!(*dh_sess)) { - fprintf(stderr, "failed to get eng ctx\n"); - return UADK_E_FAIL; + *dh_sess = uadk_prov_dh_new_session(dh, bits, is_g2); + if (*dh_sess == NULL) { + fprintf(stderr, "failed to get session\n"); + return UADK_P_FAIL; }
- ret = dh_try_get_priv_key(*dh_sess, dh, priv_key); - if (!ret) { - dh_free_eng_session(*dh_sess); - return UADK_E_FAIL; + ret = uadk_prov_dh_prepare_prikey(*dh_sess, dh, prikey); + if (ret == UADK_P_FAIL) { + fprintf(stderr, "failed to get private key\n"); + uadk_prov_dh_free_session(*dh_sess); }
return ret; }
+static void uadk_prov_dh_free_prepare_data(struct uadk_dh_sess *dh_sess, BIGNUM *prikey) +{ + uadk_prov_dh_free_prikey(dh_sess, prikey); + uadk_prov_dh_free_session(dh_sess); +} + static int dh_set_g(const BIGNUM *g, const __u16 key_size, - unsigned char *ag_bin, struct uadk_dh_sess *dh_sess) + unsigned char *g_bin, struct uadk_dh_sess *dh_sess) { - struct wd_dtb g_dtb; + struct wd_dtb g_dtb = {0}; __u32 gbytes; int ret;
- gbytes = BN_bn2bin(g, ag_bin); - g_dtb.data = (char *)ag_bin; + gbytes = BN_bn2bin(g, g_bin); + g_dtb.data = (char *)g_bin; g_dtb.bsize = key_size; g_dtb.dsize = gbytes;
ret = wd_dh_set_g(dh_sess->sess, &g_dtb); if (ret) { fprintf(stderr, "failed to set dh g\n"); - return UADK_E_FAIL; + return UADK_P_FAIL; }
- return UADK_E_SUCCESS; + return UADK_P_SUCCESS; }
-static int dh_get_pubkey(struct uadk_dh_sess *dh_sess, BIGNUM **pubkey) +static int uadk_prov_dh_get_pubkey(struct uadk_dh_sess *dh_sess, BIGNUM **pubkey) { const unsigned char *pubkey_str;
pubkey_str = (const unsigned char *)dh_sess->req.pri; - if (!pubkey_str) - return UADK_E_FAIL; + if (pubkey_str == NULL) { + fprintf(stderr, "dh_sess->req.pri is NULL\n"); + return UADK_P_FAIL; + }
*pubkey = BN_bin2bn(pubkey_str, dh_sess->req.pri_bytes, *pubkey); - if (!(*pubkey)) - return UADK_E_FAIL; + if (*pubkey == NULL) { + fprintf(stderr, "failed to trans pubkey outs\n"); + return UADK_P_FAIL; + }
- return UADK_E_SUCCESS; + return UADK_P_SUCCESS; }
-static int dh_fill_genkey_req(const BIGNUM *g, const BIGNUM *p, - const BIGNUM *priv_key, - struct uadk_dh_sess *dh_sess) +static int uadk_prov_dh_fill_genkey_req(const BIGNUM *g, const BIGNUM *p, const BIGNUM *prikey, + struct uadk_dh_sess *dh_sess) { + unsigned char *g_bin, *x_bin, *p_bin, *pri_bin; __u16 key_size = dh_sess->key_size; - unsigned char *apriv_key_bin; - unsigned char *ag_bin; - unsigned char *ap_bin; - unsigned char *out_pri; - int ret;
- ag_bin = OPENSSL_malloc(key_size); - if (!ag_bin) - return UADK_E_FAIL; - - /* Malloc a contiguous chunk of memory */ - apriv_key_bin = OPENSSL_malloc(key_size * DH_PARAMS_CNT); - if (!apriv_key_bin) - goto free_ag; + g_bin = OPENSSL_zalloc(key_size); + if (g_bin == NULL) { + fprintf(stderr, "failed to alloc g_bin\n"); + return UADK_P_FAIL; + }
- ap_bin = apriv_key_bin + key_size; - out_pri = ap_bin + key_size; - memset(ag_bin, 0, key_size); - memset(apriv_key_bin, 0, key_size); - memset(ap_bin, 0, key_size); - memset(out_pri, 0, key_size); + /* x is private key, x and p will be treated together in uadk */ + x_bin = OPENSSL_zalloc(key_size * DH_PARAMS_CNT); + if (x_bin == NULL) { + fprintf(stderr, "failed to alloc x_bin\n"); + goto free_g; + } + p_bin = x_bin + key_size; + pri_bin = p_bin + key_size;
/* Construct data block of g */ - ret = dh_set_g(g, key_size, ag_bin, dh_sess); - if (!ret) - goto free_apriv; + if (dh_set_g(g, key_size, g_bin, dh_sess) == UADK_P_FAIL) + goto free_x_p_pri;
- dh_sess->req.xbytes = BN_bn2bin(priv_key, apriv_key_bin); - dh_sess->req.pbytes = BN_bn2bin(p, ap_bin); - dh_sess->req.x_p = (void *)apriv_key_bin; - dh_sess->req.pri = out_pri; + dh_sess->req.xbytes = BN_bn2bin(prikey, x_bin); + dh_sess->req.pbytes = BN_bn2bin(p, p_bin); + dh_sess->req.x_p = (void *)x_bin; + dh_sess->req.pri = pri_bin; dh_sess->req.pri_bytes = key_size; dh_sess->req.op_type = WD_DH_PHASE1;
- OPENSSL_free(ag_bin); + /* Free binary g right away, free other parameters later */ + OPENSSL_free(g_bin);
- return ret; + return UADK_P_SUCCESS; + +free_x_p_pri: + OPENSSL_free(x_bin); +free_g: + OPENSSL_free(g_bin);
-free_apriv: - OPENSSL_free(apriv_key_bin); -free_ag: - OPENSSL_free(ag_bin); - return UADK_E_FAIL; + return UADK_P_FAIL; }
-static int dh_fill_compkey_req(const BIGNUM *g, const BIGNUM *p, - const BIGNUM *priv_key, const BIGNUM *pub_key, - struct uadk_dh_sess *dh_sess) +static void uadk_prov_dh_free_genkey_req(struct uadk_dh_sess *dh_sess) { - __u16 key_size = dh_sess->key_size; - unsigned char *apriv_key_bin; - unsigned char *ap_bin; - unsigned char *ag_bin; - unsigned char *out_pri; - int ret; - - ag_bin = OPENSSL_malloc(key_size); - if (!ag_bin) - return UADK_E_FAIL; - - apriv_key_bin = OPENSSL_malloc(key_size * DH_PARAMS_CNT); - if (!apriv_key_bin) - goto free_ag; - - ap_bin = apriv_key_bin + key_size; - out_pri = ap_bin + key_size; - memset(ag_bin, 0, key_size); - memset(apriv_key_bin, 0, key_size); - memset(ap_bin, 0, key_size); - memset(out_pri, 0, key_size); - - ret = dh_set_g(g, key_size, ag_bin, dh_sess); - if (!ret) - goto free_apriv; - - dh_sess->req.x_p = apriv_key_bin; - dh_sess->req.xbytes = BN_bn2bin(priv_key, apriv_key_bin); - dh_sess->req.pbytes = BN_bn2bin(p, ap_bin); - - dh_sess->req.pv = ag_bin; - dh_sess->req.pvbytes = BN_bn2bin(pub_key, ag_bin); - dh_sess->req.pri = out_pri; - dh_sess->req.pri_bytes = key_size; - dh_sess->req.op_type = WD_DH_PHASE2; - - return ret; + if (dh_sess == NULL) + return;
-free_apriv: - OPENSSL_free(apriv_key_bin); -free_ag: - OPENSSL_free(ag_bin); - return UADK_E_FAIL; + /* Free x_bin, p_bin and pri_bin */ + if (dh_sess->req.x_p) + OPENSSL_free(dh_sess->req.x_p); }
-static int dh_do_crypto(struct uadk_dh_sess *dh_sess) +static int uadk_prov_dh_do_crypto(struct uadk_dh_sess *dh_sess) { struct uadk_e_cb_info cb_param; struct async_op op; - int idx, ret; + int idx, ret, cnt;
ret = async_setup_async_event_notification(&op); - if (!ret) { + if (ret == 0) { printf("failed to setup async event notification.\n"); - return UADK_E_FAIL; + return UADK_P_FAIL; }
- if (!op.job) { + if (op.job == NULL) { ret = wd_do_dh_sync(dh_sess->sess, &dh_sess->req); if (ret) - return UADK_E_FAIL; + return UADK_P_FAIL; } else { cb_param.op = &op; cb_param.priv = &dh_sess->req; @@ -927,12 +842,17 @@ static int dh_do_crypto(struct uadk_dh_sess *dh_sess) goto err;
op.idx = idx; - + cnt = 0; do { ret = wd_do_dh_async(dh_sess->sess, &dh_sess->req); if (ret < 0 && ret != -EBUSY) { - async_free_poll_task(idx, 0); - goto err; + fprintf(stderr, "failed to do dh async\n"); + goto free_poll_task; + } + + if (unlikely(++cnt > PROV_SEND_MAX_CNT)) { + fprintf(stderr, "do dh async operation timeout\n"); + goto free_poll_task; } } while (ret == -EBUSY);
@@ -945,929 +865,1196 @@ static int dh_do_crypto(struct uadk_dh_sess *dh_sess) goto err; }
- return UADK_E_SUCCESS; + return UADK_P_SUCCESS;
+free_poll_task: + async_free_poll_task(idx, 0); err: (void)async_clear_async_event_notification(); - return UADK_E_FAIL; + return UADK_P_FAIL; }
-static int dh_soft_set_pkey(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key) +static int uadk_prov_dh_set_pkey(DH *dh, BIGNUM *pubkey, BIGNUM *prikey) { - const BIGNUM *old_pub = uadk_DH_get0_pub_key(dh); const BIGNUM *old_priv = uadk_DH_get0_priv_key(dh); + const BIGNUM *old_pub = uadk_DH_get0_pub_key(dh); + int ret = UADK_P_SUCCESS;
- if (old_pub != pub_key && old_priv != priv_key) - uadk_DH_set0_key(dh, pub_key, priv_key); - else if (old_pub != pub_key) - uadk_DH_set0_key(dh, pub_key, NULL); - else if (old_priv != priv_key) - uadk_DH_set0_key(dh, NULL, priv_key); + if (old_pub != pubkey && old_priv != prikey) + ret = uadk_DH_set0_key(dh, pubkey, prikey); + else if (old_pub != pubkey) + ret = uadk_DH_set0_key(dh, pubkey, NULL); + else if (old_priv != prikey) + ret = uadk_DH_set0_key(dh, NULL, prikey);
- return UADK_E_SUCCESS; + return ret; }
-static int uadk_dh_generate_key(DH *dh) +static int uadk_prov_dh_generate_key(DH *dh) { struct uadk_dh_sess *dh_sess = NULL; - BIGNUM *priv_key = NULL; - BIGNUM *pub_key = NULL; const BIGNUM *p = NULL; const BIGNUM *g = NULL; - const BIGNUM *q = NULL; + BIGNUM *prikey = NULL; + BIGNUM *pubkey = NULL; int ret;
- if (!dh) - goto exe_soft; + if (dh == NULL) { + fprintf(stderr, "invalid: dh is NULL\n"); + return UADK_P_FAIL; + }
ret = uadk_prov_dh_init(); - if (ret) - goto exe_soft; + if (ret) { + fprintf(stderr, "failed to init dh\n"); + return UADK_P_FAIL; + }
- uadk_DH_get0_pqg(dh, &p, &q, &g); - if (!p || !g || q) - goto exe_soft; + uadk_DH_get0_pqg(dh, &p, NULL, &g); + if (p == NULL || g == NULL) { + fprintf(stderr, "invalid: p or g is NULL\n"); + return UADK_P_FAIL; + }
/* Get session and prepare private key */ - ret = dh_prepare_data(g, dh, &dh_sess, &priv_key); - if (!ret) { - fprintf(stderr, "prepare dh data failed\n"); - goto exe_soft; + ret = uadk_prov_dh_prepare_data(g, dh, &dh_sess, &prikey); + if (ret == UADK_P_FAIL) { + fprintf(stderr, "failed to prepare dh data\n"); + return ret; }
- ret = dh_fill_genkey_req(g, p, priv_key, dh_sess); - if (!ret) { + ret = uadk_prov_dh_fill_genkey_req(g, p, prikey, dh_sess); + if (ret == UADK_P_FAIL) { fprintf(stderr, "failed to fill req\n"); goto free_data; }
- ret = dh_do_crypto(dh_sess); - if (!ret) { + ret = uadk_prov_dh_do_crypto(dh_sess); + if (ret == UADK_P_FAIL) { fprintf(stderr, "failed to generate DH key\n"); - goto free_data; + goto free_req; }
- ret = dh_get_pubkey(dh_sess, &pub_key); - if (!ret) { + ret = uadk_prov_dh_get_pubkey(dh_sess, &pubkey); + if (ret == UADK_P_FAIL) { fprintf(stderr, "failed to get public key\n"); - goto free_data; + goto free_req; }
- ret = dh_soft_set_pkey(dh, pub_key, priv_key); - dh_free_eng_session(dh_sess); + ret = uadk_prov_dh_set_pkey(dh, pubkey, prikey); + if (ret == UADK_P_FAIL) + fprintf(stderr, "failed to set dh pkey\n"); + + uadk_prov_dh_free_genkey_req(dh_sess); + uadk_prov_dh_free_session(dh_sess);
return ret;
+free_req: + uadk_prov_dh_free_genkey_req(dh_sess); free_data: - if (dh_sess->key_flag == KEY_GEN_BY_ENGINE) - BN_free(priv_key); - dh_free_eng_session(dh_sess); -exe_soft: - fprintf(stderr, "switch to execute openssl software calculation.\n"); - return UADK_DO_SOFT; + uadk_prov_dh_free_prepare_data(dh_sess, prikey); + + return UADK_P_FAIL; }
-static int uadk_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, - DH *dh) +static int dh_gencb(int p, int n, BN_GENCB *cb) { - struct uadk_dh_sess *dh_sess = NULL; - BIGNUM *priv_key = NULL; - const BIGNUM *p = NULL; - const BIGNUM *g = NULL; - const BIGNUM *q = NULL; - int ret; + OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END }; + PROV_DH_KEYMGMT_CTX *gctx = BN_GENCB_get_arg(cb);
- if (!dh || !key || !pub_key || !uadk_DH_get0_priv_key(dh)) - goto exe_soft; + params[0] = OSSL_PARAM_construct_int(OSSL_GEN_PARAM_POTENTIAL, &p); + params[1] = OSSL_PARAM_construct_int(OSSL_GEN_PARAM_ITERATION, &n);
- ret = uadk_prov_dh_init(); - if (ret) - goto exe_soft; + return gctx->cb(params, gctx->cbarg); +}
- uadk_DH_get0_pqg(dh, &p, &q, &g); - if (!p || !g) - goto exe_soft; +static int ossl_dh_get_named_group_uid_from_size(int pbits) +{ + int nid;
- ret = dh_prepare_data(g, dh, &dh_sess, &priv_key); - if (!ret) { - fprintf(stderr, "failed to prepare dh data\n"); - goto exe_soft; + /* + * Just choose an approved safe prime group. + * The alternative to this is to generate FIPS186-4 domain parameters i.e. + * return dh_generate_ffc_parameters(ret, prime_len, 0, NULL, cb); + * As the FIPS186-4 generated params are for backwards compatibility, + * the safe prime group should be used as the default. + */ + switch (pbits) { + case DH2048BITS: + nid = NID_ffdhe2048; + break; + case DH3072BITS: + nid = NID_ffdhe3072; + break; + case DH4096BITS: + nid = NID_ffdhe4096; + break; + /* + * Retain the commonly supported part. The different specifications are + * listed in the unsupported prime_len scope: + * 'pbits' 6144 and 8192 are supported by OpenSSL but not supported by uadk, + * 'pbits' 768/1024/1536 are not supported by OpenSSL. + * + */ + default: + return NID_undef; }
- ret = dh_fill_compkey_req(g, p, priv_key, pub_key, dh_sess); - if (!ret) { - fprintf(stderr, "failed to fill req\n"); - goto free_data; - } + return nid; +}
- ret = dh_do_crypto(dh_sess); - if (!ret) { - fprintf(stderr, "failed to generate DH shared key\n"); - goto free_data; - } +static int ossl_dh_generate_ffc_parameters(DH *dh, int type, int pbits, int qbits, + BN_GENCB *cb) +{ + int ret, res;
- memcpy(key, dh_sess->req.pri, dh_sess->req.pri_bytes); - ret = dh_sess->req.pri_bytes; - dh_free_eng_session(dh_sess); + if (type == DH_PARAMGEN_TYPE_FIPS_186_2) + ret = ossl_ffc_params_FIPS186_2_generate(dh->libctx, &dh->params, + FFC_PARAM_TYPE_DH, pbits, qbits, &res, cb); + else + ret = ossl_ffc_params_FIPS186_4_generate(dh->libctx, &dh->params, + FFC_PARAM_TYPE_DH, pbits, qbits, &res, cb); + if (ret > 0) + dh->dirty_cnt++;
return ret; - -free_data: - if (dh_sess->key_flag == KEY_GEN_BY_ENGINE) - BN_free(priv_key); - dh_free_eng_session(dh_sess); -exe_soft: - fprintf(stderr, "switch to execute openssl software calculation.\n"); - return UADK_DO_SOFT; }
-static void uadk_ffc_params_init(FFC_PARAMS *params) +static DH *ossl_dh_new_ex(OSSL_LIB_CTX *libctx) { - memset(params, 0, sizeof(*params)); - params->pcounter = -1; - params->gindex = FFC_UNVERIFIABLE_GINDEX; - params->flags = FFC_PARAM_FLAG_VALIDATE_PQG; + DH *dh = OPENSSL_zalloc(sizeof(*dh)); + + if (dh == NULL) { + fprintf(stderr, "failed to alloc dh\n"); + return NULL; + } + + dh->references = 1; + dh->lock = CRYPTO_THREAD_lock_new(); + if (dh->lock == NULL) { + fprintf(stderr, "failed to new dh thread lock\n"); + OPENSSL_free(dh); + return NULL; + } + + dh->libctx = libctx; + + return dh; }
-static void uadk_ffc_params_cleanup(FFC_PARAMS *params) +static void ossl_dh_free_ex(DH *dh) { - BN_free(params->p); - BN_free(params->q); - BN_free(params->g); - BN_free(params->j); - OPENSSL_free(params->seed); - uadk_ffc_params_init(params); + if (dh) { + CRYPTO_THREAD_lock_free(dh->lock); + OPENSSL_free(dh); + } }
-static void uadk_DH_free(DH *r) +static DH *uadk_prov_dh_gen_params_with_group(PROV_DH_KEYMGMT_CTX *gctx, FFC_PARAMS **ffc) { - int i; - - if (r == NULL) - return; - - CRYPTO_DOWN_REF(&r->references, &i, r->lock); - if (i > 0) - return; + const DH_NAMED_GROUP *group = NULL; + DH *dh = NULL;
- if (i < 0) - fprintf(stderr, "WARN: refcount error.\n"); + /* Select a named group if there is not one already */ + if (gctx->group_nid == NID_undef) { + gctx->group_nid = ossl_dh_get_named_group_uid_from_size(gctx->pbits); + if (gctx->group_nid == NID_undef) { + fprintf(stderr, "failed to get named group uid from size\n"); + return NULL; + } + }
- if (r->meth != NULL && r->meth->finish != NULL) - r->meth->finish(r); + group = ossl_ffc_uid_to_dh_named_group(gctx->group_nid); + if (group) { + dh = ossl_dh_new_ex(gctx->libctx); + if (dh == NULL) { + fprintf(stderr, "failed to get dh from libctx\n"); + return NULL; + }
- CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DH, r, &r->ex_data); + ossl_ffc_named_group_set(&dh->params, group); + dh->params.nid = ossl_ffc_named_group_get_uid(group); + dh->dirty_cnt++; + }
- CRYPTO_THREAD_lock_free(r->lock); + *ffc = ossl_dh_get0_params(dh); + if (*ffc == NULL) { + fprintf(stderr, "failed to gen ffc params\n"); + ossl_dh_free_ex(dh); + return NULL; + }
- uadk_ffc_params_cleanup(&r->params); - BN_clear_free(r->pub_key); - BN_clear_free(r->priv_key); - OPENSSL_free(r); + return dh; }
-static void *uadk_dh_keyexch_newctx(void *provctx) +static DH *uadk_prov_dh_gen_params_ex(PROV_DH_KEYMGMT_CTX *gctx, FFC_PARAMS **ffc) { - UADK_PROV_DH_CTX *pdhctx; + DH *dh = NULL;
- pdhctx = OPENSSL_zalloc(sizeof(UADK_PROV_DH_CTX)); - if (pdhctx == NULL) + /* Use existing params */ + dh = ossl_dh_new_ex(gctx->libctx); + if (dh == NULL) { + fprintf(stderr, "failed to new dh by nid\n"); return NULL; - pdhctx->libctx = prov_libctx_of(provctx); - pdhctx->kdf_type = PROV_DH_KDF_NONE; - return pdhctx; -} + }
-/* The 2 parties must share the same domain parameters */ -static int uadk_dh_keyexch_match_params(DH *priv, DH *peer) -{ - int ret; - FFC_PARAMS *dhparams_priv = uadk_dh_get0_params(priv); - FFC_PARAMS *dhparams_peer = uadk_dh_get0_params(peer); + *ffc = ossl_dh_get0_params(dh); + if (*ffc == NULL) { + fprintf(stderr, "failed to get ffc params\n"); + goto free_dh; + }
- ret = dhparams_priv != NULL && dhparams_peer != NULL && - uadk_ffc_params_cmp(dhparams_priv, dhparams_peer, 1); - if (!ret) - ERR_raise(ERR_LIB_PROV, PROV_R_MISMATCHING_DOMAIN_PARAMETERS); - return ret; -} + /* Copy the template value if one was passed */ + if (gctx->ffc_params != NULL && ossl_ffc_params_copy(*ffc, gctx->ffc_params) == 0) { + fprintf(stderr, "failed to copy params\n"); + goto free_dh; + }
-static int uadk_dh_keyexch_set_peer(void *vpdhctx, void *vdh) -{ - UADK_PROV_DH_CTX *pdhctx = (UADK_PROV_DH_CTX *)vpdhctx; + if (ossl_ffc_params_set_seed(*ffc, gctx->seed, gctx->seedlen) == 0) { + fprintf(stderr, "failed to set seed\n"); + goto free_dh; + }
- if (pdhctx == NULL || vdh == NULL || - !uadk_dh_keyexch_match_params(vdh, pdhctx->dh) || - !uadk_DH_up_ref(vdh)) - return 0; - uadk_DH_free(pdhctx->dhpeer); - pdhctx->dhpeer = vdh; - return 1; + if (gctx->gindex != -1) { + ossl_ffc_params_set_gindex(*ffc, gctx->gindex); + if (gctx->pcounter != -1) + ossl_ffc_params_set_pcounter(*ffc, gctx->pcounter); + } else if (gctx->hindex != 0) { + ossl_ffc_params_set_h(*ffc, gctx->hindex); + } + + if (gctx->mdname) { + if (ossl_ffc_set_digest(*ffc, gctx->mdname, gctx->mdprops) == 0) { + fprintf(stderr, "failed to set digest\n"); + goto free_dh; + } + } + + return dh; + +free_dh: + ossl_dh_free_ex(dh); + + return NULL; }
-static int uadk_dh_plain_derive(void *vpdhctx, unsigned char *secret, - size_t *secretlen, size_t outlen) +static int uadk_prov_dh_gen_params_cb(PROV_DH_KEYMGMT_CTX *gctx, DH *dh, + OSSL_CALLBACK *cb, void *cb_params, BN_GENCB *gencb) { - UADK_PROV_DH_CTX *pdhctx = (UADK_PROV_DH_CTX *)vpdhctx; - const BIGNUM *pub_key = NULL; - size_t dhsize; int ret;
- if (pdhctx->dh == NULL || pdhctx->dhpeer == NULL) { - ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_KEY); - return 0; + if (cb == NULL || cb_params == NULL) { + fprintf(stderr, "invalid: cb function or param is NULL\n"); + return UADK_P_FAIL; }
- dhsize = (size_t)uadk_DH_size(pdhctx->dh); - if (secret == NULL) { - *secretlen = dhsize; - return 1; + gctx->cb = cb; + gctx->cbarg = cb_params; + /* gencb can be NULL */ + gencb = BN_GENCB_new(); + if (gencb != NULL) + BN_GENCB_set(gencb, dh_gencb, gctx); + + if ((gctx->selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) { + /* + * NOTE: The old safe prime generator code is not used in fips mode, + * (i.e internally it ignores the generator and chooses a named + * group based on pbits. + */ + if (gctx->gen_type == DH_PARAMGEN_TYPE_GENERATOR) + ret = DH_generate_parameters_ex(dh, gctx->pbits, + gctx->generator, gencb); + else + ret = ossl_dh_generate_ffc_parameters(dh, gctx->gen_type, + gctx->pbits, gctx->qbits, gencb); + if (ret <= 0) { + fprintf(stderr, "failed to generate ffc parameters\n"); + goto free_cb; + } }
- if (outlen < dhsize) { - ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); - return 0; - } + return UADK_P_SUCCESS;
- uadk_DH_get0_key(pdhctx->dhpeer, &pub_key, NULL); +free_cb: + if (gencb) + BN_GENCB_free(gencb);
- ret = uadk_dh_compute_key(secret, pub_key, pdhctx->dh); - if (ret <= 0) - return ret; + return UADK_P_FAIL; +}
- *secretlen = ret; - return 1; +static void uadk_prov_dh_free_params_cb(BN_GENCB *gencb) +{ + if (gencb) + BN_GENCB_free(gencb); } -static int uadk_dh_keyexch_derive(void *vpdhctx, unsigned char *secret, - size_t *psecretlen, size_t outlen) + +static DH *uadk_prov_dh_gen_params(PROV_DH_KEYMGMT_CTX *gctx, FFC_PARAMS **ffc, + OSSL_CALLBACK *cb, void *cb_params, BN_GENCB *gencb) { - typedef int (*fun_ptr)(void *vpdhctx, unsigned char *secret, - size_t *secretlen, size_t outlen); - UADK_PROV_DH_CTX *pdhctx = (UADK_PROV_DH_CTX *)vpdhctx; - int ret = 0; + DH *dh = NULL; + int ret;
- switch (pdhctx->kdf_type) { - case PROV_DH_KDF_NONE: - ret = uadk_dh_plain_derive(pdhctx, secret, psecretlen, outlen); - if (ret == UADK_DO_SOFT) - goto exec_soft; - default: - break; + /* For parameter generation - If there is a group name just create it */ + if (gctx->gen_type == DH_PARAMGEN_TYPE_GROUP && gctx->ffc_params == NULL) { + dh = uadk_prov_dh_gen_params_with_group(gctx, ffc); + if (dh == NULL || *ffc == NULL) + return NULL; + } else { + dh = uadk_prov_dh_gen_params_ex(gctx, ffc); + if (dh == NULL || *ffc == NULL) + return NULL; + + ret = uadk_prov_dh_gen_params_cb(gctx, dh, cb, cb_params, gencb); + if (ret == UADK_P_FAIL) { + ossl_dh_free_ex(dh); + return NULL; + } } - return ret; - -exec_soft: - fprintf(stderr, "switch to execute openssl software calculation.\n"); - fun_ptr fun = get_default_keyexch().derive; - - if (!fun) - return 0;
- return fun(vpdhctx, secret, psecretlen, outlen); + return dh; }
-static void uadk_dh_keyexch_freectx(void *vpdhctx) +static void uadk_prov_dh_free_params(DH *dh, BN_GENCB *gencb) { - UADK_PROV_DH_CTX *pdhctx = (UADK_PROV_DH_CTX *)vpdhctx; - - OPENSSL_free(pdhctx->kdf_cekalg); - uadk_DH_free(pdhctx->dh); - uadk_DH_free(pdhctx->dhpeer); - EVP_MD_free(pdhctx->kdf_md); - OPENSSL_clear_free(pdhctx->kdf_ukm, pdhctx->kdf_ukmlen); - OPENSSL_free(pdhctx); + /* + * Release DH object that allocated by uadk_prov_dh_gen_params_ex() or + * uadk_prov_dh_gen_params_with_group(). + */ + ossl_dh_free_ex(dh); + uadk_prov_dh_free_params_cb(gencb); }
-static void *uadk_dh_keyexch_dupctx(void *vpdhctx) +static void *uadk_keymgmt_dh_gen(void *genctx, OSSL_CALLBACK *cb, void *cb_params) { - UADK_PROV_DH_CTX *srcctx = (UADK_PROV_DH_CTX *)vpdhctx; - UADK_PROV_DH_CTX *dstctx; + PROV_DH_KEYMGMT_CTX *gctx = (PROV_DH_KEYMGMT_CTX *)genctx; + BN_GENCB *gencb = NULL; + FFC_PARAMS *ffc = NULL; + DH *dh = NULL; + int ret;
- dstctx = OPENSSL_zalloc(sizeof(*srcctx)); - if (dstctx == NULL) + if (gctx == NULL) { + fprintf(stderr, "invalid: keygen ctx is NULL\n"); return NULL; + }
- *dstctx = *srcctx; - dstctx->dh = NULL; - dstctx->dhpeer = NULL; - dstctx->kdf_md = NULL; - dstctx->kdf_ukm = NULL; - dstctx->kdf_cekalg = NULL; + /* + * If a group name is selected then the type is group regardless of what + * the user selected. This overrides rather than errors for backwards + * compatibility. + */ + if (gctx->group_nid != NID_undef) + gctx->gen_type = DH_PARAMGEN_TYPE_GROUP;
- if (srcctx->dh != NULL && !uadk_DH_up_ref(srcctx->dh)) - goto err; - else - dstctx->dh = srcctx->dh; + dh = uadk_prov_dh_gen_params(gctx, &ffc, cb, cb_params, gencb); + if (dh == NULL || ffc == NULL) + return NULL;
- if (srcctx->dhpeer != NULL && !uadk_DH_up_ref(srcctx->dhpeer)) - goto err; - else - dstctx->dhpeer = srcctx->dhpeer; + /* DH key generation */ + if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) { + if (ffc->p == NULL || ffc->g == NULL) { + fprintf(stderr, "invalid: ffc->p or ffc->g is NULL\n"); + goto free_gen_params; + }
- if (srcctx->kdf_md != NULL && !EVP_MD_up_ref(srcctx->kdf_md)) - goto err; - else - dstctx->kdf_md = srcctx->kdf_md; + if (gctx->priv_len > 0) + (void)DH_set_length(dh, (long)gctx->priv_len);
- /* Duplicate UKM data if present */ - if (srcctx->kdf_ukm != NULL && srcctx->kdf_ukmlen > 0) { - dstctx->kdf_ukm = OPENSSL_memdup(srcctx->kdf_ukm, - srcctx->kdf_ukmlen); - if (dstctx->kdf_ukm == NULL) - goto err; - } + ossl_ffc_params_enable_flags(ffc, FFC_PARAM_FLAG_VALIDATE_LEGACY, + gctx->gen_type == DH_PARAMGEN_TYPE_FIPS_186_2);
- if (srcctx->kdf_cekalg != NULL) { - dstctx->kdf_cekalg = OPENSSL_strdup(srcctx->kdf_cekalg); - if (dstctx->kdf_cekalg == NULL) - goto err; + ret = uadk_prov_dh_generate_key(dh); + if (ret == UADK_P_FAIL) { + fprintf(stderr, "failed to do dh generation key\n"); + goto free_gen_params; + } }
- return dstctx; -err: - uadk_dh_keyexch_freectx(dstctx); + uadk_DH_clear_flags(dh, DH_FLAG_TYPE_MASK); + uadk_DH_set_flags(dh, gctx->dh_type); + uadk_prov_dh_free_params_cb(gencb); + + return dh; + +free_gen_params: + uadk_prov_dh_free_params(dh, gencb); return NULL; }
-static int uadk_dh_keyexch_set_ctx_params(void *vpdhctx, - const OSSL_PARAM params[]) +static int uadk_DH_size(const DH *dh) { - UADK_PROV_DH_CTX *pdhctx = (UADK_PROV_DH_CTX *)vpdhctx; - const OSSL_PARAM *p; - unsigned int pad; - char name[80] = {'\0'}; /* should be big enough */ - char *str = NULL; + /* DH object has been checked when the function is called */ + if (dh->params.p != NULL) + return BN_num_bytes(dh->params.p);
- if (pdhctx == NULL) - return 0; - if (params == NULL) - return 1; + /* size zero */ + return 0; +}
- p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_KDF_TYPE); - if (p != NULL) { - str = name; - if (!OSSL_PARAM_get_utf8_string(p, &str, sizeof(name))) - return 0; +static void uadk_DH_get0_key(const DH *dh, const BIGNUM **pubkey, + const BIGNUM **prikey) +{ + /* DH object has been checked when the function is called */ + if (pubkey != NULL) + *pubkey = dh->pub_key;
- if (name[0] == '\0') - pdhctx->kdf_type = PROV_DH_KDF_NONE; - else if (strcmp(name, OSSL_KDF_NAME_X942KDF_ASN1) == 0) - pdhctx->kdf_type = PROV_DH_KDF_X9_42_ASN1; - else - return 0; - } - p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_KDF_DIGEST); - if (p != NULL) { - char mdprops[80] = {'\0'}; /* should be big enough */ + if (prikey != NULL) + *prikey = dh->priv_key; +}
- str = name; - if (!OSSL_PARAM_get_utf8_string(p, &str, sizeof(name))) - return 0; +static void *uadk_keyexch_dh_newctx(void *provctx) +{ + PROV_DH_KEYEXCH_CTX *pdhctx;
- str = mdprops; - p = OSSL_PARAM_locate_const(params, - OSSL_EXCHANGE_PARAM_KDF_DIGEST_PROPS); + pdhctx = OPENSSL_zalloc(sizeof(PROV_DH_KEYEXCH_CTX)); + if (pdhctx == NULL) { + fprintf(stderr, "failed to alloc pdhctx\n"); + return NULL; + }
- if (p != NULL) - if (!OSSL_PARAM_get_utf8_string(p, &str, sizeof(mdprops))) - return 0; + /* The libctx maybe NULL, if libctx is NULL, will use default ctx. */ + pdhctx->libctx = prov_libctx_of(provctx); + pdhctx->kdf_type = PROV_DH_KDF_NONE;
- EVP_MD_free(pdhctx->kdf_md); - pdhctx->kdf_md = EVP_MD_fetch(pdhctx->libctx, name, mdprops); + return pdhctx; +}
- if (pdhctx->kdf_md == NULL) - return 0; - } +static void uadk_keyexch_dh_freectx(void *dhctx) +{ + PROV_DH_KEYEXCH_CTX *pdhctx = (PROV_DH_KEYEXCH_CTX *)dhctx;
- p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_KDF_OUTLEN); - if (p != NULL) { - size_t outlen; + if (pdhctx == NULL) + return;
- if (!OSSL_PARAM_get_size_t(p, &outlen)) - return 0; - pdhctx->kdf_outlen = outlen; + if (pdhctx->kdf_cekalg) { + OPENSSL_free(pdhctx->kdf_cekalg); + pdhctx->kdf_cekalg = NULL; }
- p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_KDF_UKM); - if (p != NULL) { - void *tmp_ukm = NULL; - size_t tmp_ukmlen; + if (pdhctx->dh) { + DH_free(pdhctx->dh); + pdhctx->dh = NULL; + }
- OPENSSL_free(pdhctx->kdf_ukm); - pdhctx->kdf_ukm = NULL; - pdhctx->kdf_ukmlen = 0; - /* ukm is an optional field so it can be NULL */ - if (p->data != NULL && p->data_size != 0) { - if (!OSSL_PARAM_get_octet_string(p, &tmp_ukm, 0, &tmp_ukmlen)) - return 0; - pdhctx->kdf_ukm = tmp_ukm; - pdhctx->kdf_ukmlen = tmp_ukmlen; - } + if (pdhctx->dhpeer) { + DH_free(pdhctx->dhpeer); + pdhctx->dhpeer = NULL; }
- p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_PAD); - if (p != NULL) { - if (!OSSL_PARAM_get_uint(p, &pad)) - return 0; - pdhctx->pad = pad ? 1 : 0; + if (pdhctx->kdf_md) { + EVP_MD_free(pdhctx->kdf_md); + pdhctx->kdf_md = NULL; }
- p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_CEK_ALG); - if (p != NULL) { - str = name; + if (pdhctx->kdf_ukm) { + OPENSSL_clear_free(pdhctx->kdf_ukm, pdhctx->kdf_ukmlen); + pdhctx->kdf_ukm = NULL; + }
+ if (pdhctx->kdf_cekalg) { OPENSSL_free(pdhctx->kdf_cekalg); pdhctx->kdf_cekalg = NULL; - if (p->data != NULL && p->data_size != 0) { - if (!OSSL_PARAM_get_utf8_string(p, &str, sizeof(name))) - return 0; - pdhctx->kdf_cekalg = OPENSSL_strdup(name); - if (pdhctx->kdf_cekalg == NULL) - return 0; - } } - return 1; -}
-static const OSSL_PARAM known_settable_ctx_params[] = { - OSSL_PARAM_int(OSSL_EXCHANGE_PARAM_PAD, NULL), - OSSL_PARAM_utf8_string(OSSL_EXCHANGE_PARAM_KDF_TYPE, NULL, 0), - OSSL_PARAM_utf8_string(OSSL_EXCHANGE_PARAM_KDF_DIGEST, NULL, 0), - OSSL_PARAM_utf8_string(OSSL_EXCHANGE_PARAM_KDF_DIGEST_PROPS, NULL, 0), - OSSL_PARAM_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN, NULL), - OSSL_PARAM_octet_string(OSSL_EXCHANGE_PARAM_KDF_UKM, NULL, 0), - OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_CEK_ALG, NULL, 0), - OSSL_PARAM_END -}; + OPENSSL_free(pdhctx); +}
-static const -OSSL_PARAM *uadk_dh_keyexch_settable_ctx_params(ossl_unused void *vpdhctx, - ossl_unused void *provctx) +static int uadk_keyexch_dh_init(void *dhctx, void *dh, const OSSL_PARAM params[]) { - return known_settable_ctx_params; -} + PROV_DH_KEYEXCH_CTX *pdhctx = (PROV_DH_KEYEXCH_CTX *)dhctx;
-static const OSSL_PARAM known_gettable_ctx_params[] = { - OSSL_PARAM_utf8_string(OSSL_EXCHANGE_PARAM_KDF_TYPE, NULL, 0), - OSSL_PARAM_utf8_string(OSSL_EXCHANGE_PARAM_KDF_DIGEST, NULL, 0), - OSSL_PARAM_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN, NULL), - OSSL_PARAM_DEFN(OSSL_EXCHANGE_PARAM_KDF_UKM, OSSL_PARAM_OCTET_PTR, - NULL, 0), - OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_CEK_ALG, NULL, 0), - OSSL_PARAM_END -}; + if (pdhctx == NULL) { + fprintf(stderr, "invalid: dhctx is NULL\n"); + return UADK_P_FAIL; + }
-static const -OSSL_PARAM *uadk_dh_keyexch_gettable_ctx_params(ossl_unused void *vpdhctx, - ossl_unused void *provctx) + if (dh == NULL || !DH_up_ref(dh)) { + fprintf(stderr, "invalid: dh is NULL\n"); + return UADK_P_FAIL; + } + + pthread_mutex_lock(&dh_mutex); + if (pdhctx->dh) { + DH_free(pdhctx->dh); + pdhctx->dh = NULL; + } + + pdhctx->dh = dh; + pdhctx->kdf_type = PROV_DH_KDF_NONE; + pthread_mutex_unlock(&dh_mutex); + + return uadk_keyexch_dh_set_ctx_params(pdhctx, params); +} + +/* The 2 parties must share the same domain parameters */ +static int uadk_keyexch_dh_match_params(DH *priv, DH *peer) { - return known_gettable_ctx_params; + FFC_PARAMS *dhparams_priv = ossl_dh_get0_params(priv); + FFC_PARAMS *dhparams_peer = ossl_dh_get0_params(peer); + int ret; + + if (dhparams_priv == NULL || dhparams_peer == NULL) { + fprintf(stderr, "failed to get dh params\n"); + return UADK_P_FAIL; + } + + ret = ossl_ffc_params_cmp(dhparams_priv, dhparams_peer, IGNORE_Q); + if (ret == UADK_P_FAIL) + fprintf(stderr, "invalid: domain parameters of both parties do not match\n"); + + return ret; }
-static int uadk_dh_keyexch_get_ctx_params(void *vpdhctx, OSSL_PARAM params[]) +static int uadk_keyexch_dh_set_peer(void *dhctx, void *dh) { - UADK_PROV_DH_CTX *pdhctx = (UADK_PROV_DH_CTX *)vpdhctx; - OSSL_PARAM *p; + PROV_DH_KEYEXCH_CTX *pdhctx = (PROV_DH_KEYEXCH_CTX *)dhctx;
- if (pdhctx == NULL) - return 0; + if (pdhctx == NULL || dh == NULL) { + fprintf(stderr, "invalid: dh ctx or object is NULL\n"); + return UADK_P_FAIL; + }
- p = OSSL_PARAM_locate(params, OSSL_EXCHANGE_PARAM_KDF_TYPE); - if (p != NULL) { - const char *kdf_type = NULL; + if (uadk_keyexch_dh_match_params(dh, pdhctx->dh) == UADK_P_FAIL || + DH_up_ref(dh) == UADK_P_FAIL) { + fprintf(stderr, "failed to match dh params\n"); + return UADK_P_FAIL; + }
- switch (pdhctx->kdf_type) { - case PROV_DH_KDF_NONE: - kdf_type = ""; - break; - case PROV_DH_KDF_X9_42_ASN1: - kdf_type = OSSL_KDF_NAME_X942KDF_ASN1; - break; - default: - return 0; - } + pthread_mutex_lock(&dh_mutex); + if (pdhctx->dhpeer) + DH_free(pdhctx->dhpeer); + pdhctx->dhpeer = dh; + pthread_mutex_unlock(&dh_mutex); + + return UADK_P_SUCCESS; +}
- if (!OSSL_PARAM_set_utf8_string(p, kdf_type)) - return 0; +static int uadk_prov_dh_fill_compkey_req(const BIGNUM *g, const BIGNUM *p, + const BIGNUM *prikey, const BIGNUM *pubkey, + struct uadk_dh_sess *dh_sess) +{ + unsigned char *x_bin, *p_bin, *g_bin, *out_pri; + __u16 key_size = dh_sess->key_size; + + g_bin = OPENSSL_zalloc(key_size); + if (g_bin == NULL) { + fprintf(stderr, "failed to alloc g\n"); + return UADK_P_FAIL; }
- p = OSSL_PARAM_locate(params, OSSL_EXCHANGE_PARAM_KDF_DIGEST); - if (p != NULL && !OSSL_PARAM_set_utf8_string(p, pdhctx->kdf_md == NULL - ? "" - : EVP_MD_get0_name(pdhctx->kdf_md))) - return 0; + /* x is private key, x and p will be treated together in uadk */ + x_bin = OPENSSL_zalloc(key_size * DH_PARAMS_CNT); + if (x_bin == NULL) { + fprintf(stderr, "failed to alloc x_bin\n"); + goto free_g; + }
- p = OSSL_PARAM_locate(params, OSSL_EXCHANGE_PARAM_KDF_OUTLEN); - if (p != NULL && !OSSL_PARAM_set_size_t(p, pdhctx->kdf_outlen)) - return 0; + p_bin = x_bin + key_size; + out_pri = p_bin + key_size;
- p = OSSL_PARAM_locate(params, OSSL_EXCHANGE_PARAM_KDF_UKM); - if (p != NULL && !OSSL_PARAM_set_octet_ptr(p, pdhctx->kdf_ukm, pdhctx->kdf_ukmlen)) - return 0; + /* Construct data block of g */ + if (dh_set_g(g, key_size, g_bin, dh_sess) == UADK_P_FAIL) + goto free_priv;
- p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_CEK_ALG); - if (p != NULL && !OSSL_PARAM_set_utf8_string(p, pdhctx->kdf_cekalg == NULL - ? "" - : pdhctx->kdf_cekalg)) - return 0; + dh_sess->req.x_p = x_bin; + dh_sess->req.xbytes = BN_bn2bin(prikey, x_bin); + dh_sess->req.pbytes = BN_bn2bin(p, p_bin);
- return 1; -} + dh_sess->req.pv = g_bin; + dh_sess->req.pvbytes = BN_bn2bin(pubkey, g_bin); + dh_sess->req.pri = out_pri; + dh_sess->req.pri_bytes = key_size; + dh_sess->req.op_type = WD_DH_PHASE2;
-static int uadk_dh_keyexch_init(void *vpdhctx, void *vdh, const OSSL_PARAM params[]) -{ - UADK_PROV_DH_CTX *pdhctx = (UADK_PROV_DH_CTX *)vpdhctx; + return UADK_P_SUCCESS;
- if (pdhctx == NULL || vdh == NULL || !uadk_DH_up_ref(vdh)) - return 0; - uadk_DH_free(pdhctx->dh); - pdhctx->dh = vdh; - pdhctx->kdf_type = PROV_DH_KDF_NONE; - return uadk_dh_keyexch_set_ctx_params(pdhctx, params); +free_priv: + OPENSSL_free(x_bin); +free_g: + OPENSSL_free(g_bin); + + return UADK_P_FAIL; }
-static UADK_DH_KEYMGMT get_default_keymgmt(void) +static void uadk_prov_dh_free_compkey_req(struct uadk_dh_sess *dh_sess) { - static UADK_DH_KEYMGMT s_keymgmt; - static int initilazed; + if (dh_sess == NULL) + return;
- if (!initilazed) { - UADK_DH_KEYMGMT *keymgmt = - (UADK_DH_KEYMGMT *)EVP_KEYMGMT_fetch(NULL, "DH", "provider=default"); + /* Free x_bin, p_bin and pri_bin */ + if (dh_sess->req.x_p) { + OPENSSL_free(dh_sess->req.x_p); + dh_sess->req.x_p = NULL; + }
- if (keymgmt) { - s_keymgmt = *keymgmt; - EVP_KEYMGMT_free((EVP_KEYMGMT *)keymgmt); - initilazed = 1; - } else { - fprintf(stderr, "WARN: EVP_KEYMGMT_fetch from default provider failed"); - } + /* Free pv */ + if (dh_sess->req.pv) { + OPENSSL_free(dh_sess->req.pv); + dh_sess->req.pv = NULL; } - return s_keymgmt; }
-static void *uadk_dh_keymgmt_newdata(void *provctx) +static int uadk_dh_compute_key(unsigned char *key, const BIGNUM *pubkey, DH *dh) { - typedef void *(*fun_ptr)(void *); - fun_ptr fun = get_default_keymgmt().new; + struct uadk_dh_sess *dh_sess = NULL; + BIGNUM *prikey = NULL; + const BIGNUM *p = NULL; + const BIGNUM *g = NULL; + int ret;
- if (!fun) - return NULL; - return fun(provctx); -} + if (!dh || !key || !pubkey || !uadk_DH_get0_priv_key(dh)) { + fprintf(stderr, "failed to check key params\n"); + return UADK_P_FAIL; + }
-static void uadk_dh_keymgmt_freedata(void *keydata) -{ - typedef void (*fun_ptr)(void *); - fun_ptr fun = get_default_keymgmt().free; + uadk_DH_get0_pqg(dh, &p, NULL, &g); + if (!p || !g) { + fprintf(stderr, "failed to get p/q/g param\n"); + return UADK_P_FAIL; + }
- if (!fun) - return; - fun(keydata); -} + ret = uadk_prov_dh_init(); + if (ret) { + fprintf(stderr, "failed to init\n"); + return UADK_P_FAIL; + }
-static int uadk_dh_keymgmt_has(const void *keydata, int selection) -{ - typedef int (*fun_ptr)(const void *, int); - fun_ptr fun = get_default_keymgmt().has; + ret = uadk_prov_dh_prepare_data(g, dh, &dh_sess, &prikey); + if (ret == UADK_P_FAIL) { + fprintf(stderr, "failed to prepare dh data\n"); + return ret; + }
- if (!fun) - return 0; - return fun(keydata, selection); -} + ret = uadk_prov_dh_fill_compkey_req(g, p, prikey, pubkey, dh_sess); + if (ret == UADK_P_FAIL) { + fprintf(stderr, "failed to fill req\n"); + goto free_data; + }
-static int uadk_dh_keymgmt_match(const void *keydata1, const void *keydata2, int selection) -{ - typedef int (*fun_ptr)(const void *, const void *, int); - fun_ptr fun = get_default_keymgmt().match; + ret = uadk_prov_dh_do_crypto(dh_sess); + if (ret == UADK_P_FAIL) { + fprintf(stderr, "failed to generate DH shared key\n"); + goto free_req; + }
- if (!fun) - return 0; - return fun(keydata1, keydata2, selection); -} + memcpy(key, dh_sess->req.pri, dh_sess->req.pri_bytes); + ret = dh_sess->req.pri_bytes; + uadk_prov_dh_free_compkey_req(dh_sess); + /* key will be used by user, do not free it here */ + uadk_prov_dh_free_session(dh_sess);
-static int uadk_dh_keymgmt_import(void *keydata, int selection, const OSSL_PARAM params[]) -{ - typedef int (*fun_ptr)(void *, int, const OSSL_PARAM *); - fun_ptr fun = get_default_keymgmt().import; + return ret;
- if (!fun) - return 0; - return fun(keydata, selection, params); +free_req: + uadk_prov_dh_free_compkey_req(dh_sess); +free_data: + uadk_prov_dh_free_prepare_data(dh_sess, prikey); + + return ret; }
-static int uadk_dh_keymgmt_export(void *keydata, int selection, OSSL_CALLBACK *param_cb, - void *cbarg) +static int uadk_dh_compute_key_padded(unsigned char *key, const BIGNUM *pub_key, DH *dh) { - typedef int (*fun_ptr)(void *, int, OSSL_CALLBACK *, void *); - fun_ptr fun = get_default_keymgmt().export; + size_t dhsize; + int rv, pad; + + /* rv is constant unless compute_key is external */ + rv = uadk_dh_compute_key(key, pub_key, dh); + if (rv <= 0) + return rv; + + dhsize = BN_num_bytes(dh->params.p); + pad = dhsize - rv; + /* pad is constant (zero) unless compute_key is external */ + if (pad > 0) { + memmove(key + pad, key, rv); + memset(key, 0, pad); + }
- if (!fun) - return 0; - return fun(keydata, selection, param_cb, cbarg); + if (pad < 0) { + fprintf(stderr, "invalid: recv key size(%d) > dhsize(%lu)", rv, dhsize); + return UADK_P_FAIL; + } + + return rv + pad; }
-static const OSSL_PARAM *uadk_dh_keymgmt_import_types(int selection) +static int uadk_prov_dh_plain_derive(PROV_DH_KEYEXCH_CTX *pdhctx, unsigned char *secret, + size_t *secretlen, size_t outlen, unsigned int pad) { - typedef const OSSL_PARAM *(*fun_ptr)(int); - fun_ptr fun = get_default_keymgmt().import_types; + const BIGNUM *pubkey = NULL; + size_t dhsize; + int ret;
- if (!fun) - return NULL; - return fun(selection); -} + /* pdhctx has been checked when the function is called */ + if (pdhctx->dh == NULL) { + fprintf(stderr, "invalid: dh is NULL\n"); + return UADK_P_FAIL; + }
-static const OSSL_PARAM *uadk_dh_keymgmt_export_types(int selection) -{ - typedef const OSSL_PARAM *(*fun_ptr)(int); - fun_ptr fun = get_default_keymgmt().export_types; + dhsize = (size_t)uadk_DH_size(pdhctx->dh); + if (dhsize == 0) { + fprintf(stderr, "invalid: dhszie is zero\n"); + return UADK_P_FAIL; + }
- if (!fun) - return NULL; - return fun(selection); + if (secret == NULL) { + *secretlen = dhsize; + return UADK_P_SUCCESS; + } + + if (outlen < dhsize) { + fprintf(stderr, "invalid: outlen(%lu) < dhsize(%lu)\n", outlen, dhsize); + return UADK_P_FAIL; + } + + if (pdhctx->dhpeer == NULL) { + fprintf(stderr, "invalid: dhpeer is NULL\n"); + return UADK_P_FAIL; + } + + uadk_DH_get0_key(pdhctx->dhpeer, &pubkey, NULL); + + if (pad) + ret = uadk_dh_compute_key_padded(secret, pubkey, pdhctx->dh); + else + ret = uadk_dh_compute_key(secret, pubkey, pdhctx->dh); + if (ret <= 0) { + fprintf(stderr, "failed to do dh compute, pad(%d)\n", pad); + return ret; + } + + *secretlen = ret; + + return UADK_P_SUCCESS; }
-static ossl_inline int uadk_dh_keymgmt_get_params(void *key, OSSL_PARAM params[]) +/* Key derivation function from X9.63/SECG */ +int ossl_dh_kdf_X9_42_asn1(unsigned char *out, PROV_DH_KEYEXCH_CTX *pdhctx, + const unsigned char *z, size_t z_len, + const char *propq) { - typedef int (*fun_ptr)(void *, OSSL_PARAM *); - fun_ptr fun = get_default_keymgmt().get_params; + OSSL_LIB_CTX *libctx = pdhctx->libctx; + const char *cek_alg = pdhctx->kdf_cekalg; + const unsigned char *ukm = pdhctx->kdf_ukm; + OSSL_PARAM params[KDF_PARAM_NUM] = {0}; + size_t outlen = pdhctx->kdf_outlen; + size_t ukmlen = pdhctx->kdf_ukmlen; + const EVP_MD *md = pdhctx->kdf_md; + OSSL_PARAM *p = params; + EVP_KDF_CTX *kctx = NULL; + EVP_KDF *kdf = NULL; + const char *mdname; + int ret = 0;
- if (!fun) + kdf = EVP_KDF_fetch(libctx, OSSL_KDF_NAME_X942KDF_ASN1, propq); + if (kdf == NULL) return 0; - return fun(key, params); -}
-static const OSSL_PARAM *uadk_dh_keymgmt_gettable_params(void *provctx) -{ - typedef const OSSL_PARAM *(*fun_ptr)(void *); - fun_ptr fun = get_default_keymgmt().gettable_params; + kctx = EVP_KDF_CTX_new(kdf); + if (kctx == NULL) + goto end;
- if (!fun) - return NULL; - return fun(provctx); -} + mdname = EVP_MD_get0_name(md); + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, + (char *)mdname, 0); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, + (unsigned char *)z, z_len); + if (ukm != NULL) + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_UKM, + (unsigned char *)ukm, ukmlen);
-static const OSSL_PARAM *uadk_dh_keymgmt_settable_params(void *provctx) -{ - typedef const OSSL_PARAM *(*fun_ptr)(void *); - fun_ptr fun = get_default_keymgmt().settable_params; + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_CEK_ALG, + (char *)cek_alg, 0); + *p = OSSL_PARAM_construct_end(); + ret = EVP_KDF_derive(kctx, out, outlen, params) > 0;
- if (!fun) - return NULL; - return fun(provctx); +end: + EVP_KDF_CTX_free(kctx); + EVP_KDF_free(kdf); + + return ret; }
-static int uadk_dh_keymgmt_set_params(void *key, const OSSL_PARAM params[]) +static int uadk_prov_dh_X9_42_kdf_derive(PROV_DH_KEYEXCH_CTX *pdhctx, unsigned char *secret, + size_t *secretlen, size_t outlen) { - typedef int (*fun_ptr)(void *, const OSSL_PARAM *); - fun_ptr fun = get_default_keymgmt().set_params; + unsigned char *stmp = NULL; + size_t stmplen; + int ret = 0;
- if (!fun) - return 0; - return fun(key, params); + if (secret == NULL) { + *secretlen = pdhctx->kdf_outlen; + return UADK_P_SUCCESS; + } + + if (outlen < pdhctx->kdf_outlen) { + fprintf(stderr, "invalid: outlen(%lu) < kdf_outlen(%lu)\n", + outlen, pdhctx->kdf_outlen); + return UADK_P_FAIL; + } + + if (!uadk_prov_dh_plain_derive(pdhctx, NULL, &stmplen, 0, 1)) + return UADK_P_FAIL; + + stmp = OPENSSL_secure_malloc(stmplen); + if (stmp == NULL) { + fprintf(stderr, "failed to do OPENSSL_secure_malloc\n"); + return UADK_P_FAIL; + } + + if (uadk_prov_dh_plain_derive(pdhctx, stmp, &stmplen, stmplen, USE_PAD) == UADK_P_FAIL) + goto end; + + /* Do KDF stuff */ + if (pdhctx->kdf_type == PROV_DH_KDF_X9_42_ASN1) { + if (ossl_dh_kdf_X9_42_asn1(secret, pdhctx, stmp, stmplen, NULL) == UADK_P_FAIL) { + fprintf(stderr, "failed to do ossl_dh_kdf_X9_42_asn1\n"); + goto end; + } + } + + *secretlen = pdhctx->kdf_outlen; + ret = UADK_P_SUCCESS; + +end: + OPENSSL_secure_clear_free(stmp, stmplen); + + return ret; }
-static int uadk_dh_keymgmt_validate(const void *keydata, int selection, int checktype) +static int uadk_keyexch_dh_derive(void *dhctx, unsigned char *secret, + size_t *psecretlen, size_t outlen) { - typedef int (*fun_ptr)(const void *, int, int); - fun_ptr fun = get_default_keymgmt().validate; + PROV_DH_KEYEXCH_CTX *pdhctx = (PROV_DH_KEYEXCH_CTX *)dhctx; + int ret = UADK_P_FAIL;
- if (!fun) - return 0; - return fun(keydata, selection, checktype); + if (pdhctx == NULL) { + fprintf(stderr, "invalid: pdhctx is NULL\n"); + return UADK_P_FAIL; + } + + switch (pdhctx->kdf_type) { + case PROV_DH_KDF_NONE: + ret = uadk_prov_dh_plain_derive(pdhctx, secret, psecretlen, outlen, pdhctx->pad); + break; + case PROV_DH_KDF_X9_42_ASN1: + ret = uadk_prov_dh_X9_42_kdf_derive(pdhctx, secret, psecretlen, outlen); + default: + fprintf(stderr, "invalid: unsupport kdf type\n"); + break; + } + + return ret; }
-static void *uadk_dh_keymgmt_gen_init(void *provctx, int selection, - const OSSL_PARAM params[]) +static void *uadk_keyexch_dh_dupctx(void *dhctx) { - typedef void *(*fun_ptr)(void *, int, const OSSL_PARAM *); - fun_ptr fun = get_default_keymgmt().gen_init; + PROV_DH_KEYEXCH_CTX *srcctx = (PROV_DH_KEYEXCH_CTX *)dhctx; + PROV_DH_KEYEXCH_CTX *dstctx;
- if (!fun) + if (srcctx == NULL) { + fprintf(stderr, "invalid: src ctx is NULL\n"); return NULL; - return fun(provctx, selection, params); -} + }
-static int uadk_dh_keymgmt_gen_set_template(void *genctx, void *templ) -{ - typedef int (*fun_ptr)(void *, void *); - fun_ptr fun = get_default_keymgmt().gen_set_template; + dstctx = OPENSSL_zalloc(sizeof(*dstctx)); + if (dstctx == NULL) { + fprintf(stderr, "failed to alloc dst ctx\n"); + return NULL; + }
- if (!fun) - return 0; - return fun(genctx, templ); + memcpy(dstctx, srcctx, sizeof(PROV_DH_KEYEXCH_CTX)); + dstctx->dh = NULL; + dstctx->dhpeer = NULL; + dstctx->kdf_md = NULL; + dstctx->kdf_ukm = NULL; + dstctx->kdf_cekalg = NULL; + + if (srcctx->dh && !DH_up_ref(srcctx->dh)) + goto err; + else + dstctx->dh = srcctx->dh; + + if (srcctx->dhpeer && !DH_up_ref(srcctx->dhpeer)) + goto err; + else + dstctx->dhpeer = srcctx->dhpeer; + + if (srcctx->kdf_md && !EVP_MD_up_ref(srcctx->kdf_md)) + goto err; + else + dstctx->kdf_md = srcctx->kdf_md; + + /* Duplicate UKM data if present */ + if (srcctx->kdf_ukm && srcctx->kdf_ukmlen > 0) { + dstctx->kdf_ukm = OPENSSL_memdup(srcctx->kdf_ukm, + srcctx->kdf_ukmlen); + if (dstctx->kdf_ukm == NULL) + goto err; + } + + if (srcctx->kdf_cekalg != NULL) { + dstctx->kdf_cekalg = OPENSSL_strdup(srcctx->kdf_cekalg); + if (dstctx->kdf_cekalg == NULL) + goto err; + } + + return dstctx; + +err: + uadk_keyexch_dh_freectx(dstctx); + + return NULL; }
-static const -OSSL_PARAM *uadk_dh_keymgmt_gen_settable_params(ossl_unused void *genctx, - ossl_unused void *provctx) +static int uadk_prov_dh_locate_kdf_type(PROV_DH_KEYEXCH_CTX *pdhctx, const OSSL_PARAM params[]) { - typedef const OSSL_PARAM *(*fun_ptr)(void *, void *); - fun_ptr fun = get_default_keymgmt().gen_settable_params; + char name[DH_MAX_PARAM_LEN + 1] = {'\0'}; + const OSSL_PARAM *p; + char *str = NULL;
- if (!fun) - return NULL; - return fun(genctx, provctx); + p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_KDF_TYPE); + if (p != NULL) { + str = name; + if (!OSSL_PARAM_get_utf8_string(p, &str, sizeof(name))) + return UADK_P_FAIL; + + if (name[0] == '\0') + pdhctx->kdf_type = PROV_DH_KDF_NONE; + else if (strcmp(name, OSSL_KDF_NAME_X942KDF_ASN1) == 0) + pdhctx->kdf_type = PROV_DH_KDF_X9_42_ASN1; + else + return UADK_P_FAIL; + } + + return UADK_P_SUCCESS; }
-static int uadk_dh_keymgmt_gen_set_params(void *genctx, +static int uadk_prov_dh_locate_kdf_digest(PROV_DH_KEYEXCH_CTX *pdhctx, const OSSL_PARAM params[]) { - typedef int (*fun_ptr)(void *, const OSSL_PARAM *); - fun_ptr fun = get_default_keymgmt().gen_set_params; + char mdprops[DH_MAX_PARAM_LEN + 1] = {'\0'}; + char name[DH_MAX_PARAM_LEN + 1] = {'\0'}; + const OSSL_PARAM *p; + char *str = NULL;
- if (!fun) - return 0; - return fun(genctx, params); + p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_KDF_DIGEST); + if (p != NULL) { + str = name; + if (!OSSL_PARAM_get_utf8_string(p, &str, sizeof(name))) + return UADK_P_FAIL; + + str = mdprops; + p = OSSL_PARAM_locate_const(params, + OSSL_EXCHANGE_PARAM_KDF_DIGEST_PROPS); + if (p != NULL) + if (!OSSL_PARAM_get_utf8_string(p, &str, sizeof(mdprops))) + return UADK_P_FAIL; + + if (pdhctx->kdf_md) + EVP_MD_free(pdhctx->kdf_md); + + pdhctx->kdf_md = EVP_MD_fetch(pdhctx->libctx, name, mdprops); + if (pdhctx->kdf_md == NULL) + return UADK_P_FAIL; + } + + return UADK_P_SUCCESS; }
-static int dh_gencb(int p, int n, BN_GENCB *cb) +static int uadk_prov_dh_locate_kdf_outlen(PROV_DH_KEYEXCH_CTX *pdhctx, + const OSSL_PARAM params[]) { - struct dh_gen_ctx *gctx = BN_GENCB_get_arg(cb); - OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END }; + const OSSL_PARAM *p; + size_t outlen = 0;
- params[0] = OSSL_PARAM_construct_int(OSSL_GEN_PARAM_POTENTIAL, &p); - params[1] = OSSL_PARAM_construct_int(OSSL_GEN_PARAM_ITERATION, &n); + p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_KDF_OUTLEN); + if (p != NULL) { + if (!OSSL_PARAM_get_size_t(p, &outlen)) + return UADK_P_FAIL; + pdhctx->kdf_outlen = outlen; + }
- return gctx->cb(params, gctx->cbarg); + return UADK_P_SUCCESS; }
-static DH *ossl_dh_new_ex(OSSL_LIB_CTX *libctx) +static int uadk_prov_dh_locate_kdf_ukm(PROV_DH_KEYEXCH_CTX *pdhctx, const OSSL_PARAM params[]) { - DH *ret = OPENSSL_zalloc(sizeof(*ret)); + const OSSL_PARAM *p; + void *tmp_ukm = NULL; + size_t tmp_ukmlen;
- if (ret == NULL) { - ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); - return NULL; - } + p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_KDF_UKM); + if (p != NULL) { + if (pdhctx->kdf_ukm) + OPENSSL_free(pdhctx->kdf_ukm); + pdhctx->kdf_ukm = NULL; + pdhctx->kdf_ukmlen = 0;
- ret->references = 1; - ret->lock = CRYPTO_THREAD_lock_new(); - if (ret->lock == NULL) { - ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE); - OPENSSL_free(ret); - return NULL; + /* ukm is an optional field so it can be NULL */ + if (p->data != NULL && p->data_size != 0) { + if (!OSSL_PARAM_get_octet_string(p, &tmp_ukm, 0, &tmp_ukmlen)) + return UADK_P_FAIL; + pdhctx->kdf_ukm = tmp_ukm; + pdhctx->kdf_ukmlen = tmp_ukmlen; + } }
- ret->libctx = libctx; + return UADK_P_SUCCESS; +}
- return ret; +static int uadk_prov_dh_locate_kdf_pad(PROV_DH_KEYEXCH_CTX *pdhctx, const OSSL_PARAM params[]) +{ + const OSSL_PARAM *p; + unsigned int pad = 0; + + p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_PAD); + if (p != NULL) { + if (!OSSL_PARAM_get_uint(p, &pad)) + return UADK_P_FAIL; + pdhctx->pad = pad ? 1 : 0; + } + + return UADK_P_SUCCESS; }
-static void *uadk_dh_keymgmt_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) +static int uadk_keyexch_dh_set_ctx_params(void *dhctx, const OSSL_PARAM params[]) { - typedef void* (*fun_ptr)(void *, OSSL_CALLBACK *, void *); - struct dh_gen_ctx *gctx = genctx; - DH *dh = NULL; - BN_GENCB *gencb = NULL; - FFC_PARAMS *ffc; - fun_ptr fun; - int ret; + PROV_DH_KEYEXCH_CTX *pdhctx = (PROV_DH_KEYEXCH_CTX *)dhctx; + int ret = UADK_P_FAIL;
- if (gctx == NULL) - return NULL; + if (pdhctx == NULL) { + fprintf(stderr, "invalid: dh ctx is NULL\n"); + return ret; + }
- dh = ossl_dh_new_ex(gctx->libctx); - if (dh == NULL) - return NULL; - ffc = uadk_ossl_dh_get0_params(dh); - if (gctx->ffc_params != NULL - && !ossl_ffc_params_copy(ffc, gctx->ffc_params)) - goto exec_soft; - if (!ossl_ffc_params_set_seed(ffc, gctx->seed, gctx->seedlen)) - goto exec_soft; - gctx->cb = osslcb; - gctx->cbarg = cbarg; - gencb = BN_GENCB_new(); - if (gencb != NULL) - BN_GENCB_set(gencb, dh_gencb, genctx); + /* If params is NULL, no need to set */ + if (params == NULL) + return UADK_P_SUCCESS;
+ pthread_mutex_lock(&dh_mutex); + ret = uadk_prov_dh_locate_kdf_type(pdhctx, params); + if (ret == UADK_P_FAIL) { + fprintf(stderr, "failed to locate kdf type\n"); + goto end; + }
- ret = uadk_dh_generate_key(dh); - if (ret == UADK_DO_SOFT) - goto exec_soft; - uadk_DH_clear_flags(dh, DH_FLAG_TYPE_MASK); - uadk_DH_set_flags(dh, gctx->dh_type); - BN_GENCB_free(gencb); - return dh; + ret = uadk_prov_dh_locate_kdf_digest(pdhctx, params); + if (ret == UADK_P_FAIL) { + fprintf(stderr, "failed to locate kdf digest\n"); + goto end; + }
-exec_soft: - if (dh) - uadk_dh_keymgmt_freedata(dh); - if (gencb) - BN_GENCB_free(gencb); - fun = get_default_keymgmt().gen; - if (!fun) - return NULL; - return fun(genctx, osslcb, cbarg); -} + ret = uadk_prov_dh_locate_kdf_outlen(pdhctx, params); + if (ret == UADK_P_FAIL) { + fprintf(stderr, "failed to locate kdf outlen\n"); + goto end; + }
-static void uadk_dh_keymgmt_gen_cleanup(void *genctx) -{ - typedef void (*fun_ptr)(void *); - fun_ptr fun = get_default_keymgmt().gen_cleanup; + ret = uadk_prov_dh_locate_kdf_ukm(pdhctx, params); + if (ret == UADK_P_FAIL) { + fprintf(stderr, "failed to locate kdf ukm\n"); + goto end; + }
- if (!fun) - return; - fun(genctx); + ret = uadk_prov_dh_locate_kdf_pad(pdhctx, params); + if (ret == UADK_P_FAIL) + fprintf(stderr, "failed to locate kdf pad\n"); + +end: + pthread_mutex_unlock(&dh_mutex); + return ret; }
-static void *uadk_dh_keymgmt_load(const void *reference, size_t reference_sz) +static const OSSL_PARAM known_settable_ctx_params[] = { + OSSL_PARAM_int(OSSL_EXCHANGE_PARAM_PAD, NULL), + OSSL_PARAM_utf8_string(OSSL_EXCHANGE_PARAM_KDF_TYPE, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_EXCHANGE_PARAM_KDF_DIGEST, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_EXCHANGE_PARAM_KDF_DIGEST_PROPS, NULL, 0), + OSSL_PARAM_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN, NULL), + OSSL_PARAM_octet_string(OSSL_EXCHANGE_PARAM_KDF_UKM, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_CEK_ALG, NULL, 0), + OSSL_PARAM_END +}; + +static const OSSL_PARAM *uadk_keyexch_dh_settable_ctx_params(ossl_unused void *dhctx, + ossl_unused void *provctx) { - typedef void *(*fun_ptr)(const void *, size_t); - fun_ptr fun = get_default_keymgmt().load; + return known_settable_ctx_params; +}
- if (!fun) - return NULL; - return fun(reference, reference_sz); +static const OSSL_PARAM known_gettable_ctx_params[] = { + OSSL_PARAM_utf8_string(OSSL_EXCHANGE_PARAM_KDF_TYPE, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_EXCHANGE_PARAM_KDF_DIGEST, NULL, 0), + OSSL_PARAM_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN, NULL), + OSSL_PARAM_DEFN(OSSL_EXCHANGE_PARAM_KDF_UKM, OSSL_PARAM_OCTET_PTR, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_CEK_ALG, NULL, 0), + OSSL_PARAM_END +}; + +static const OSSL_PARAM *uadk_keyexch_dh_gettable_ctx_params(ossl_unused void *dhctx, + ossl_unused void *provctx) +{ + return known_gettable_ctx_params; }
-static void *uadk_dh_keymgmt_dup(const void *keydata_from, int selection) +static int uadk_keyexch_dh_get_ctx_params(void *dhctx, OSSL_PARAM params[]) { - typedef void *(*fun_ptr)(const void *, int); - fun_ptr fun = get_default_keymgmt().dup; + PROV_DH_KEYEXCH_CTX *pdhctx = (PROV_DH_KEYEXCH_CTX *)dhctx; + const char *kdf_type = NULL; + OSSL_PARAM *p;
- if (!fun) - return NULL; - return fun(keydata_from, selection); -} - -const OSSL_DISPATCH uadk_dh_keyexch_functions[] = { - {OSSL_FUNC_KEYEXCH_NEWCTX, - (void (*)(void))uadk_dh_keyexch_newctx}, - {OSSL_FUNC_KEYEXCH_INIT, - (void (*)(void))uadk_dh_keyexch_init}, - {OSSL_FUNC_KEYEXCH_DERIVE, - (void (*)(void))uadk_dh_keyexch_derive}, - {OSSL_FUNC_KEYEXCH_SET_PEER, - (void (*)(void))uadk_dh_keyexch_set_peer}, - {OSSL_FUNC_KEYEXCH_FREECTX, - (void (*)(void))uadk_dh_keyexch_freectx}, - {OSSL_FUNC_KEYEXCH_DUPCTX, - (void (*)(void))uadk_dh_keyexch_dupctx}, - {OSSL_FUNC_KEYEXCH_SET_CTX_PARAMS, - (void (*)(void))uadk_dh_keyexch_set_ctx_params}, - {OSSL_FUNC_KEYEXCH_SETTABLE_CTX_PARAMS, - (void (*)(void))uadk_dh_keyexch_settable_ctx_params}, - {OSSL_FUNC_KEYEXCH_GET_CTX_PARAMS, - (void (*)(void))uadk_dh_keyexch_get_ctx_params}, - {OSSL_FUNC_KEYEXCH_GETTABLE_CTX_PARAMS, - (void (*)(void))uadk_dh_keyexch_gettable_ctx_params}, - {0, NULL} -}; + if (pdhctx == NULL) { + fprintf(stderr, "invalid: dh ctx is NULL\n"); + return UADK_P_FAIL; + }
-const OSSL_DISPATCH uadk_dh_keymgmt_functions[] = { - {OSSL_FUNC_KEYMGMT_NEW, - (void (*)(void))uadk_dh_keymgmt_newdata}, - {OSSL_FUNC_KEYMGMT_GEN_INIT, - (void (*)(void))uadk_dh_keymgmt_gen_init}, - {OSSL_FUNC_KEYMGMT_GEN_SET_TEMPLATE, - (void (*)(void))uadk_dh_keymgmt_gen_set_template}, - {OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, - (void (*)(void))uadk_dh_keymgmt_gen_set_params}, - {OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS, - (void (*)(void))uadk_dh_keymgmt_gen_settable_params}, - {OSSL_FUNC_KEYMGMT_GEN, - (void (*)(void))uadk_dh_keymgmt_gen}, - {OSSL_FUNC_KEYMGMT_GEN_CLEANUP, - (void (*)(void))uadk_dh_keymgmt_gen_cleanup}, - {OSSL_FUNC_KEYMGMT_LOAD, - (void (*)(void))uadk_dh_keymgmt_load}, - {OSSL_FUNC_KEYMGMT_FREE, - (void (*)(void))uadk_dh_keymgmt_freedata}, - {OSSL_FUNC_KEYMGMT_GET_PARAMS, - (void (*)(void))uadk_dh_keymgmt_get_params}, - {OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, - (void (*)(void))uadk_dh_keymgmt_gettable_params}, - {OSSL_FUNC_KEYMGMT_SET_PARAMS, - (void (*)(void))uadk_dh_keymgmt_set_params}, - {OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, - (void (*)(void))uadk_dh_keymgmt_settable_params}, - {OSSL_FUNC_KEYMGMT_HAS, - (void (*)(void))uadk_dh_keymgmt_has}, - {OSSL_FUNC_KEYMGMT_MATCH, - (void (*)(void))uadk_dh_keymgmt_match}, - {OSSL_FUNC_KEYMGMT_VALIDATE, - (void (*)(void))uadk_dh_keymgmt_validate}, - {OSSL_FUNC_KEYMGMT_IMPORT, - (void (*)(void))uadk_dh_keymgmt_import}, - {OSSL_FUNC_KEYMGMT_IMPORT_TYPES, - (void (*)(void))uadk_dh_keymgmt_import_types}, - {OSSL_FUNC_KEYMGMT_EXPORT, - (void (*)(void))uadk_dh_keymgmt_export}, - {OSSL_FUNC_KEYMGMT_EXPORT_TYPES, - (void (*)(void))uadk_dh_keymgmt_export_types}, - {OSSL_FUNC_KEYMGMT_DUP, - (void (*)(void))uadk_dh_keymgmt_dup}, - {0, NULL} -}; + p = OSSL_PARAM_locate(params, OSSL_EXCHANGE_PARAM_KDF_TYPE); + if (p != NULL) { + switch (pdhctx->kdf_type) { + case PROV_DH_KDF_NONE: + kdf_type = ""; + break; + case PROV_DH_KDF_X9_42_ASN1: + kdf_type = OSSL_KDF_NAME_X942KDF_ASN1; + break; + default: + fprintf(stderr, "invalid kdf_type\n"); + return UADK_P_FAIL; + }
-void uadk_prov_destroy_dh(void) -{ - pthread_mutex_lock(&dh_mutex); - if (g_dh_res.pid == getpid()) { - wd_dh_uninit2(); - g_dh_res.pid = 0; + if (!OSSL_PARAM_set_utf8_string(p, kdf_type)) { + fprintf(stderr, "failed to set utf8 string for kdf_type\n"); + return UADK_P_FAIL; + } } - pthread_mutex_lock(&dh_mutex); + + p = OSSL_PARAM_locate(params, OSSL_EXCHANGE_PARAM_KDF_DIGEST); + if (p != NULL && !OSSL_PARAM_set_utf8_string(p, pdhctx->kdf_md == NULL + ? "" : EVP_MD_get0_name(pdhctx->kdf_md))) { + fprintf(stderr, "failed to set kdf_md\n"); + return UADK_P_FAIL; + } + + p = OSSL_PARAM_locate(params, OSSL_EXCHANGE_PARAM_KDF_OUTLEN); + if (p != NULL && !OSSL_PARAM_set_size_t(p, pdhctx->kdf_outlen)) { + fprintf(stderr, "failed to set kdf_outlen\n"); + return UADK_P_FAIL; + } + + p = OSSL_PARAM_locate(params, OSSL_EXCHANGE_PARAM_KDF_UKM); + if (p != NULL && !OSSL_PARAM_set_octet_ptr(p, pdhctx->kdf_ukm, pdhctx->kdf_ukmlen)) { + fprintf(stderr, "failed to set kdf_ukm\n"); + return UADK_P_FAIL; + } + + p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_CEK_ALG); + if (p != NULL && !OSSL_PARAM_set_utf8_string(p, pdhctx->kdf_cekalg == NULL + ? "" : pdhctx->kdf_cekalg)) { + fprintf(stderr, "failed to set kdf_cekalg\n"); + return UADK_P_FAIL; + } + + return UADK_P_SUCCESS; } diff --git a/src/uadk_prov_init.c b/src/uadk_prov_init.c index 34027bf..4c2793f 100644 --- a/src/uadk_prov_init.c +++ b/src/uadk_prov_init.c @@ -176,6 +176,7 @@ static void uadk_teardown(void *provctx) uadk_prov_destroy_cipher(); uadk_prov_destroy_rsa(); uadk_prov_sm2_uninit(); + uadk_prov_dh_uninit(); OPENSSL_free(ctx); OSSL_PROVIDER_unload(prov); async_poll_task_free(); diff --git a/src/uadk_prov_pkey.h b/src/uadk_prov_pkey.h index d044597..105d9bb 100644 --- a/src/uadk_prov_pkey.h +++ b/src/uadk_prov_pkey.h @@ -275,6 +275,26 @@ static OSSL_FUNC_signature_get_ctx_md_params_fn uadk_signature_##nm##_get_ctx_md static OSSL_FUNC_signature_gettable_ctx_md_params_fn uadk_signature_##nm##_gettable_ctx_md_params; \ static OSSL_FUNC_signature_set_ctx_md_params_fn uadk_signature_##nm##_set_ctx_md_params; \ static OSSL_FUNC_signature_settable_ctx_md_params_fn uadk_signature_##nm##_settable_ctx_md_params; \ +static UADK_PKEY_SIGNATURE get_default_signature(void) \ +{ \ + static UADK_PKEY_SIGNATURE s_signature; \ + static int initilazed; \ + \ + if (!initilazed) { \ + UADK_PKEY_SIGNATURE *signature = \ + (UADK_PKEY_SIGNATURE *)EVP_SIGNATURE_fetch(NULL, #alg, \ + "provider=default"); \ + \ + if (signature) { \ + s_signature = *signature; \ + EVP_SIGNATURE_free((EVP_SIGNATURE *)signature); \ + initilazed = 1; \ + } else { \ + fprintf(stderr, "failed to EVP_SIGNATURE_fetch default provider\n"); \ + } \ + } \ + return s_signature; \ +} \ const OSSL_DISPATCH uadk_##nm##_signature_functions[] = { \ { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))uadk_signature_##nm##_newctx }, \ { OSSL_FUNC_SIGNATURE_SIGN_INIT, (void (*)(void))uadk_signature_##nm##_sign_init }, \ @@ -347,6 +367,26 @@ static OSSL_FUNC_asym_cipher_get_ctx_params_fn uadk_asym_cipher_##nm##_get_ctx_p static OSSL_FUNC_asym_cipher_gettable_ctx_params_fn uadk_asym_cipher_##nm##_gettable_ctx_params; \ static OSSL_FUNC_asym_cipher_set_ctx_params_fn uadk_asym_cipher_##nm##_set_ctx_params; \ static OSSL_FUNC_asym_cipher_settable_ctx_params_fn uadk_asym_cipher_##nm##_settable_ctx_params; \ +static UADK_PKEY_ASYM_CIPHER get_default_asym_cipher(void) \ +{ \ + static UADK_PKEY_ASYM_CIPHER s_asym_cipher; \ + static int initilazed; \ + \ + if (!initilazed) { \ + UADK_PKEY_ASYM_CIPHER *asym_cipher = \ + (UADK_PKEY_ASYM_CIPHER *)EVP_ASYM_CIPHER_fetch(NULL, #alg, \ + "provider=default"); \ + \ + if (asym_cipher) { \ + s_asym_cipher = *asym_cipher; \ + EVP_ASYM_CIPHER_free((EVP_ASYM_CIPHER *)asym_cipher); \ + initilazed = 1; \ + } else { \ + fprintf(stderr, "failed to EVP_ASYM_CIPHER_fetch default provider\n"); \ + } \ + } \ + return s_asym_cipher; \ +} \ const OSSL_DISPATCH uadk_##nm##_asym_cipher_functions[] = { \ { OSSL_FUNC_ASYM_CIPHER_NEWCTX, (void (*)(void))uadk_asym_cipher_##nm##_newctx }, \ { OSSL_FUNC_ASYM_CIPHER_ENCRYPT_INIT, \ @@ -368,6 +408,72 @@ const OSSL_DISPATCH uadk_##nm##_asym_cipher_functions[] = { \ { 0, NULL } \ } \
+typedef struct { + int name_id; + char *type_name; + const char *description; + OSSL_PROVIDER *prov; + int refcnt; + + OSSL_FUNC_keyexch_newctx_fn *newctx; + OSSL_FUNC_keyexch_init_fn *init; + OSSL_FUNC_keyexch_set_peer_fn *set_peer; + OSSL_FUNC_keyexch_derive_fn *derive; + OSSL_FUNC_keyexch_freectx_fn *freectx; + OSSL_FUNC_keyexch_dupctx_fn *dupctx; + OSSL_FUNC_keyexch_set_ctx_params_fn *set_ctx_params; + OSSL_FUNC_keyexch_settable_ctx_params_fn *settable_ctx_params; + OSSL_FUNC_keyexch_get_ctx_params_fn *get_ctx_params; + OSSL_FUNC_keyexch_gettable_ctx_params_fn *gettable_ctx_params; +} UADK_PKEY_KEYEXCH; + +#define UADK_PKEY_KEYEXCH_DESCR(nm, alg) \ + static OSSL_FUNC_keyexch_newctx_fn uadk_keyexch_##nm##_newctx; \ + static OSSL_FUNC_keyexch_init_fn uadk_keyexch_##nm##_init; \ + static OSSL_FUNC_keyexch_set_peer_fn uadk_keyexch_##nm##_set_peer; \ + static OSSL_FUNC_keyexch_derive_fn uadk_keyexch_##nm##_derive; \ + static OSSL_FUNC_keyexch_freectx_fn uadk_keyexch_##nm##_freectx; \ + static OSSL_FUNC_keyexch_dupctx_fn uadk_keyexch_##nm##_dupctx; \ + static OSSL_FUNC_keyexch_set_ctx_params_fn uadk_keyexch_##nm##_set_ctx_params; \ + static OSSL_FUNC_keyexch_settable_ctx_params_fn uadk_keyexch_##nm##_settable_ctx_params; \ + static OSSL_FUNC_keyexch_get_ctx_params_fn uadk_keyexch_##nm##_get_ctx_params; \ + static OSSL_FUNC_keyexch_gettable_ctx_params_fn uadk_keyexch_##nm##_gettable_ctx_params; \ +static UADK_PKEY_KEYEXCH get_default_keyexch(void) \ +{ \ + UADK_PKEY_KEYEXCH s_keyexch; \ + static int initilazed; \ + \ + if (!initilazed) { \ + UADK_PKEY_KEYEXCH *keyexch = \ + (UADK_PKEY_KEYEXCH *)EVP_KEYEXCH_fetch(NULL, #alg, "provider=default"); \ + if (keyexch) { \ + s_keyexch = *keyexch; \ + EVP_KEYEXCH_free((EVP_KEYEXCH *)keyexch); \ + initilazed = 1; \ + } else { \ + fprintf(stderr, "failed to EVP_KEYEXCH_fetch default provider\n"); \ + } \ + } \ + return s_keyexch; \ +} \ +const OSSL_DISPATCH uadk_##nm##_keyexch_functions[] = { \ + { OSSL_FUNC_KEYEXCH_NEWCTX, (void (*)(void))uadk_keyexch_##nm##_newctx }, \ + { OSSL_FUNC_KEYEXCH_INIT, (void (*)(void))uadk_keyexch_##nm##_init }, \ + { OSSL_FUNC_KEYEXCH_DERIVE, (void (*)(void))uadk_keyexch_##nm##_derive }, \ + { OSSL_FUNC_KEYEXCH_SET_PEER, (void (*)(void))uadk_keyexch_##nm##_set_peer }, \ + { OSSL_FUNC_KEYEXCH_FREECTX, (void (*)(void))uadk_keyexch_##nm##_freectx }, \ + { OSSL_FUNC_KEYEXCH_DUPCTX, (void (*)(void))uadk_keyexch_##nm##_dupctx }, \ + { OSSL_FUNC_KEYEXCH_SET_CTX_PARAMS, \ + (void (*)(void))uadk_keyexch_##nm##_set_ctx_params }, \ + { OSSL_FUNC_KEYEXCH_SETTABLE_CTX_PARAMS, \ + (void (*)(void))uadk_keyexch_##nm##_settable_ctx_params }, \ + {OSSL_FUNC_KEYEXCH_GET_CTX_PARAMS, \ + (void (*)(void))uadk_keyexch_##nm##_get_ctx_params }, \ + { OSSL_FUNC_KEYEXCH_GETTABLE_CTX_PARAMS, \ + (void (*)(void))uadk_keyexch_##nm##_gettable_ctx_params }, \ + { 0, NULL } \ +} \ + handle_t uadk_prov_ecc_alloc_sess(const EC_KEY *eckey, char *alg); int uadk_prov_ecc_crypto(handle_t sess, struct wd_ecc_req *req, void *usr); int uadk_prov_keymgmt_get_support_state(int alg_tag);