uadk_engine/0004-uadk_provider-support-ec-keymgmt-hardware-accelerati.patch
Eingesch de8288e8f7 uadk_engine: adding the uadk_provider library
(cherry picked from commit 66c935685ac0a2f1c37fd09e88d24f793a8c24ba)
2024-12-20 15:58:28 +08:00

903 lines
22 KiB
Diff

From f124acb1af235ecd30249f903573175c1ea624a2 Mon Sep 17 00:00:00 2001
From: Weili Qian <qianweili@huawei.com>
Date: Thu, 19 Dec 2024 15:57:57 +0800
Subject: [PATCH 04/10] uadk_provider: support ec keymgmt hardware acceleration
Support ECDH key generation.
Signed-off-by: Weili Qian <qianweili@huawei.com>
Signed-off-by: JiangShui Yang <yangjiangshui@h-partners.com>
---
src/Makefile.am | 3 +-
src/uadk_prov.h | 2 +
src/uadk_prov_ec_kmgmt.c | 746 +++++++++++++++++++++++++++++++++++++++
src/uadk_prov_init.c | 2 +
src/uadk_prov_pkey.c | 26 +-
src/uadk_prov_pkey.h | 9 +
6 files changed, 785 insertions(+), 3 deletions(-)
create mode 100644 src/uadk_prov_ec_kmgmt.c
diff --git a/src/Makefile.am b/src/Makefile.am
index 921305b..b2e2c06 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -65,7 +65,8 @@ uadk_provider_la_SOURCES=uadk_prov_init.c uadk_async.c uadk_utils.c \
uadk_prov_rsa.c uadk_prov_dh.c \
uadk_prov_bio.c uadk_prov_der_writer.c uadk_prov_packet.c \
uadk_prov_pkey.c uadk_prov_sm2.c \
- uadk_prov_ffc.c uadk_prov_aead.c
+ uadk_prov_ffc.c uadk_prov_aead.c \
+ uadk_prov_ec_kmgmt.c
uadk_provider_la_LDFLAGS=-module -version-number $(VERSION)
uadk_provider_la_LIBADD=$(WD_LIBS) -lpthread
diff --git a/src/uadk_prov.h b/src/uadk_prov.h
index e85aff8..9c310b7 100644
--- a/src/uadk_prov.h
+++ b/src/uadk_prov.h
@@ -179,6 +179,8 @@ extern const OSSL_DISPATCH uadk_sm2_keymgmt_functions[FUNC_MAX_NUM];
extern const OSSL_DISPATCH uadk_sm2_signature_functions[FUNC_MAX_NUM];
extern const OSSL_DISPATCH uadk_sm2_asym_cipher_functions[FUNC_MAX_NUM];
+extern const OSSL_DISPATCH uadk_ec_keymgmt_functions[FUNC_MAX_NUM];
+
void uadk_prov_destroy_digest(void);
void uadk_prov_destroy_cipher(void);
void uadk_prov_destroy_aead(void);
diff --git a/src/uadk_prov_ec_kmgmt.c b/src/uadk_prov_ec_kmgmt.c
new file mode 100644
index 0000000..86182bd
--- /dev/null
+++ b/src/uadk_prov_ec_kmgmt.c
@@ -0,0 +1,746 @@
+// SPDX-License-Identifier: Apache-2.0
+/*
+ * Copyright 2024 Huawei Technologies Co.,Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/err.h>
+#include <openssl/bn.h>
+#include <uadk/wd_ecc.h>
+#include "uadk_async.h"
+#include "uadk_prov.h"
+#include "uadk_prov_pkey.h"
+
+#define UADK_PROV_ECC_PADDING 7
+#define UADK_PROV_RAND_MAX_CNT 1000
+#define UADK_EC_DEFAULT_FLAGS 0
+#define UADK_EC_FLAGS_ERROR (-1)
+
+static const OSSL_ITEM check_group_type_nameid_map[] = {
+ {0, OSSL_PKEY_EC_GROUP_CHECK_DEFAULT},
+ {EC_FLAG_CHECK_NAMED_GROUP, OSSL_PKEY_EC_GROUP_CHECK_NAMED},
+ {EC_FLAG_CHECK_NAMED_GROUP_NIST, OSSL_PKEY_EC_GROUP_CHECK_NAMED_NIST},
+};
+
+UADK_PKEY_KEYMGMT_DESCR(ec, EC);
+
+static int ec_param_check(struct ec_gen_ctx *gctx, EC_KEY *ec)
+{
+ const EC_GROUP *group;
+ int type, ret;
+
+ ret = uadk_prov_ecc_genctx_check(gctx, ec);
+ if (!ret) {
+ fprintf(stderr, "failed to check genctx!\n");
+ return ret;
+ }
+
+ group = EC_KEY_get0_group(ec);
+ /* Field GF(2m) is not supported by uadk */
+ type = EC_METHOD_get_field_type(EC_GROUP_method_of(group));
+ if (type != NID_X9_62_prime_field) {
+ fprintf(stderr, "invalid: uadk unsupport Field GF(2m)!\n");
+ return UADK_P_FAIL;
+ }
+
+ return uadk_prov_ecc_bit_check(group);
+}
+
+static int ec_set_public_key(EC_KEY *ec, struct wd_ecc_out *ec_out)
+{
+ int key_size_std, key_size_x, key_size_y;
+ struct wd_ecc_point *pubkey = NULL;
+ int ret = UADK_P_FAIL;
+ const EC_GROUP *group;
+ int x_shift, y_shift;
+ unsigned char *buff;
+ EC_POINT *point;
+ int buff_size;
+
+ wd_ecxdh_get_out_params(ec_out, &pubkey);
+ if (!pubkey) {
+ fprintf(stderr, "failed to get pubkey!\n");
+ return ret;
+ }
+
+ group = EC_KEY_get0_group(ec);
+ point = EC_POINT_new(group);
+ if (!point) {
+ fprintf(stderr, "failed to new ec point!\n");
+ return ret;
+ }
+
+ key_size_std = (unsigned int)(EC_GROUP_get_degree(group) +
+ UADK_PROV_ECC_PADDING) >> TRANS_BITS_BYTES_SHIFT;
+ key_size_x = pubkey->x.dsize;
+ key_size_y = pubkey->y.dsize;
+ if (key_size_x > key_size_std || key_size_y > key_size_std) {
+ fprintf(stderr, "invalid: key size is error!\n");
+ goto free_point;
+ }
+
+ /*
+ * The public key is composed as: tag + point_x + point_y
+ * tag - 1 byte
+ * point_x - [key_size_std] bytes
+ * point_y - [key_size_std] bytes
+ */
+ buff_size = ECC_POINT_SIZE(key_size_std) + 1;
+ x_shift = key_size_std - key_size_x + 1;
+ y_shift = buff_size - key_size_y;
+ buff = (unsigned char *)OPENSSL_zalloc(buff_size);
+ if (!buff) {
+ fprintf(stderr, "failed to alloc buf, buff_size = %d!\n",
+ buff_size);
+ goto free_point;
+ }
+
+ buff[0] = UADK_OCTET_STRING;
+ memcpy(buff + x_shift, pubkey->x.data, key_size_x);
+ memcpy(buff + y_shift, pubkey->y.data, key_size_y);
+
+ ret = EC_POINT_oct2point(group, point, buff, buff_size, NULL);
+ if (!ret) {
+ fprintf(stderr, "failed to do EC_POINT_oct2point!\n");
+ goto free_buf;
+ }
+
+ ret = EC_KEY_set_public_key(ec, point);
+ if (!ret)
+ fprintf(stderr, "failed to do EC_KEY_set_public_key!\n");
+
+free_buf:
+ OPENSSL_free(buff);
+free_point:
+ EC_POINT_free(point);
+
+ return ret;
+}
+
+static handle_t ec_alloc_sess(EC_KEY *ec, struct wd_ecc_out **ec_out)
+{
+ handle_t sess;
+ int ret;
+
+ ret = uadk_prov_keymgmt_get_support_state(KEYMGMT_EC);
+ if (!ret) {
+ fprintf(stderr, "failed to get hardware ecdh keygen support!\n");
+ return ret;
+ }
+
+ ret = uadk_prov_ecc_init("ecdh");
+ if (!ret) {
+ fprintf(stderr, "failed to init ecdh!\n");
+ return ret;
+ }
+
+ sess = uadk_prov_ecc_alloc_sess(ec, "ecdh");
+ if (!sess) {
+ fprintf(stderr, "failed to alloc ec sess!\n");
+ return ret;
+ }
+
+ *ec_out = wd_ecxdh_new_out(sess);
+ if (!(*ec_out)) {
+ fprintf(stderr, "failed to new sign out\n");
+ wd_ecc_free_sess(sess);
+ return UADK_P_FAIL;
+ }
+
+ return sess;
+}
+
+static void ec_free_sess(handle_t sess, struct wd_ecc_out *ec_out)
+{
+ wd_ecc_del_out(sess, ec_out);
+ wd_ecc_free_sess(sess);
+}
+
+static int ec_set_private_key(EC_KEY *ec, BIGNUM *priv_key)
+{
+ BIGNUM *priv_k = priv_key;
+ int ret = UADK_P_FAIL;
+ const EC_GROUP *group;
+ const BIGNUM *order;
+ int cnt = 0;
+
+ if (priv_k)
+ goto set_key;
+
+ priv_k = BN_new();
+ if (!priv_k) {
+ fprintf(stderr, "failed to BN_new priv_k!\n");
+ return UADK_P_FAIL;
+ }
+
+ group = EC_KEY_get0_group(ec);
+ order = EC_GROUP_get0_order(group);
+
+ do {
+ cnt++;
+ if (cnt > UADK_PROV_RAND_MAX_CNT) {
+ fprintf(stderr, "failed to get appropriate prikey, timeout\n");
+ goto free_priv_k;
+ }
+
+ if (!BN_priv_rand_range(priv_k, order)) {
+ fprintf(stderr, "failed to get rand data!\n");
+ goto free_priv_k;
+ }
+ } while (BN_is_zero(priv_k) || BN_is_one(priv_k));
+
+set_key:
+ ret = EC_KEY_set_private_key(ec, priv_k);
+ if (!ret)
+ fprintf(stderr, "failed to set private key!\n");
+
+free_priv_k:
+ if (!priv_key)
+ BN_clear_free(priv_k);
+ return ret;
+}
+
+static int ec_update_private_key(EC_KEY *ec, handle_t sess, BIGNUM *priv_key)
+{
+ int ret;
+
+ ret = ec_set_private_key(ec, priv_key);
+ if (!ret)
+ return ret;
+
+ return uadk_prov_ecc_set_private_key(sess, ec);
+}
+
+static int ec_hw_keygen(EC_KEY *ec, BIGNUM *priv_key)
+{
+ struct wd_ecc_out *ec_out = NULL;
+ struct wd_ecc_req req = {0};
+ handle_t sess;
+ int ret;
+
+ sess = ec_alloc_sess(ec, &ec_out);
+ if (!sess) {
+ fprintf(stderr, "failed to alloc sess!\n");
+ return UADK_P_FAIL;
+ }
+
+ ret = ec_update_private_key(ec, sess, priv_key);
+ if (!ret) {
+ fprintf(stderr, "failed to update private key!\n");
+ goto free_sess;
+ }
+
+ uadk_prov_ecc_fill_req(&req, WD_ECXDH_GEN_KEY, NULL, ec_out);
+ ret = uadk_prov_ecc_crypto(sess, &req, (void *)sess);
+ if (!ret) {
+ fprintf(stderr, "failed to generate key!\n");
+ goto free_sess;
+ }
+
+ ret = ec_set_public_key(ec, ec_out);
+
+free_sess:
+ ec_free_sess(sess, ec_out);
+ return ret;
+}
+
+static int ec_set_cofactor_mode(EC_KEY *ec, int mode)
+{
+ const EC_GROUP *group = EC_KEY_get0_group(ec);
+ const BIGNUM *cofactor;
+ /*
+ * mode can be only 0 for disable, or 1 for enable here.
+ *
+ * This is in contrast with the same parameter on an ECDH EVP_PKEY_CTX that
+ * also supports mode == -1 with the meaning of "reset to the default for
+ * the associated key".
+ */
+ if (mode < COFACTOR_MODE_DISABLED || mode > COFACTOR_MODE_ENABLED)
+ return UADK_P_FAIL;
+
+ cofactor = EC_GROUP_get0_cofactor(group);
+ if (!cofactor)
+ return UADK_P_FAIL;
+
+ /* ECDH cofactor mode has no effect if cofactor is 1 */
+ if (BN_is_one(cofactor))
+ return UADK_P_SUCCESS;
+
+ if (mode == COFACTOR_MODE_ENABLED)
+ EC_KEY_set_flags(ec, EC_FLAG_COFACTOR_ECDH);
+ else
+ EC_KEY_clear_flags(ec, EC_FLAG_COFACTOR_ECDH);
+
+ return UADK_P_SUCCESS;
+}
+
+static int ec_check_group_type_name2id(const char *name)
+{
+ size_t size = OSSL_NELEM(check_group_type_nameid_map);
+ size_t i;
+
+ /* Return the default value if there is no name */
+ if (!name)
+ return UADK_EC_DEFAULT_FLAGS;
+
+ for (i = 0; i < size; i++) {
+ if (!OPENSSL_strcasecmp(name, check_group_type_nameid_map[i].ptr))
+ return check_group_type_nameid_map[i].id;
+ }
+
+ return UADK_EC_FLAGS_ERROR;
+}
+
+static int ec_set_check_group_type(EC_KEY *ec, const char *name)
+{
+ int flags;
+
+ flags = ec_check_group_type_name2id(name);
+ if (flags == UADK_EC_FLAGS_ERROR)
+ return UADK_P_FAIL;
+
+ EC_KEY_clear_flags(ec, EC_FLAG_CHECK_NAMED_GROUP_MASK);
+ EC_KEY_set_flags(ec, flags);
+
+ return UADK_P_SUCCESS;
+}
+
+static void *uadk_keymgmt_ec_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
+{
+ struct ec_gen_ctx *gctx = genctx;
+ EC_KEY *ec;
+ int ret;
+
+ if (!gctx) {
+ fprintf(stderr, "invalid: gctx is NULL to ec gen!\n");
+ return NULL;
+ }
+
+ ec = EC_KEY_new_ex(gctx->libctx, NULL);
+ if (!ec) {
+ fprintf(stderr, "failed to new ec key!\n");
+ return NULL;
+ }
+
+ ret = ec_param_check(genctx, ec);
+ if (!ret) {
+ fprintf(stderr, "failed to check genctx!\n");
+ goto free_ec_key;
+ }
+
+ /* Whether you want it or not, you get a keypair, not just one half */
+ if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
+ ret = ec_hw_keygen(ec, gctx->priv_key);
+ if (!ret) {
+ fprintf(stderr, "failed to gen public key!\n");
+ goto free_ec_key;
+ }
+ }
+
+ if (gctx->ecdh_mode != COFACTOR_MODE_USE_KEY) {
+ ret = ec_set_cofactor_mode(ec, gctx->ecdh_mode);
+ if (!ret)
+ goto free_ec_key;
+ }
+
+ if (gctx->group_check) {
+ ret = ec_set_check_group_type(ec, gctx->group_check);
+ if (!ret)
+ goto free_ec_key;
+ }
+
+ return ec;
+
+free_ec_key:
+ EC_KEY_free(ec);
+ return NULL;
+}
+
+static void uadk_keymgmt_ec_gen_cleanup(void *genctx)
+{
+ struct ec_gen_ctx *gctx = genctx;
+
+ if (!gctx)
+ return;
+
+ EC_GROUP_free(gctx->gen_group);
+ BN_free(gctx->p);
+ BN_free(gctx->a);
+ BN_free(gctx->b);
+ BN_free(gctx->order);
+ BN_free(gctx->cofactor);
+ BN_clear_free(gctx->priv_key);
+ OPENSSL_free(gctx->group_name);
+ OPENSSL_free(gctx->field_type);
+ OPENSSL_free(gctx->pt_format);
+ OPENSSL_free(gctx->encoding);
+ OPENSSL_free(gctx->seed);
+ OPENSSL_free(gctx->gen);
+ OPENSSL_free(gctx);
+}
+
+static void *uadk_keymgmt_ec_gen_init(void *provctx, int selection,
+ const OSSL_PARAM params[])
+{
+ struct ec_gen_ctx *gctx;
+ int ret;
+
+ if (!provctx)
+ return NULL;
+
+ if (!(selection & OSSL_KEYMGMT_SELECT_ALL))
+ return NULL;
+
+ gctx = OPENSSL_zalloc(sizeof(*gctx));
+ if (!gctx)
+ return NULL;
+
+ gctx->libctx = prov_libctx_of(provctx);
+ gctx->selection = selection;
+
+ ret = uadk_keymgmt_ec_gen_set_params(gctx, params);
+ if (!ret) {
+ OPENSSL_free(gctx);
+ return NULL;
+ }
+
+ return gctx;
+}
+
+static int uadk_keymgmt_ec_gen_set_template(void *genctx, void *templ)
+{
+ struct ec_gen_ctx *gctx = genctx;
+ const EC_GROUP *src_group;
+ EC_GROUP *dst_group;
+ EC_KEY *ec = templ;
+
+ if (!gctx || !ec) {
+ fprintf(stderr, "invalid: genctx or templ is NULL!\n");
+ return UADK_P_FAIL;
+ }
+
+ src_group = EC_KEY_get0_group(ec);
+ if (!src_group) {
+ fprintf(stderr, "failed to get source group!\n");
+ return UADK_P_FAIL;
+ }
+
+ dst_group = EC_GROUP_dup(src_group);
+ if (!dst_group) {
+ fprintf(stderr, "failed to copy group!\n");
+ return UADK_P_FAIL;
+ }
+
+ EC_GROUP_free(gctx->gen_group);
+ gctx->gen_group = dst_group;
+
+ return UADK_P_SUCCESS;
+}
+
+static int ec_set_int_param(const char *key, int *val, const OSSL_PARAM params[])
+{
+ const OSSL_PARAM *p;
+
+ p = OSSL_PARAM_locate_const(params, key);
+ if (!p)
+ return UADK_P_SUCCESS;
+
+ return OSSL_PARAM_get_int(p, val);
+}
+
+static int ec_set_utf8_param(const char *key, char **val, const OSSL_PARAM params[])
+{
+ const OSSL_PARAM *p;
+
+ p = OSSL_PARAM_locate_const(params, key);
+ if (!p)
+ return UADK_P_SUCCESS;
+
+ if (p->data_type != OSSL_PARAM_UTF8_STRING)
+ return UADK_P_FAIL;
+
+ OPENSSL_free(*val);
+ *val = OPENSSL_strdup(p->data);
+ if (!(*val))
+ return UADK_P_FAIL;
+
+ return UADK_P_SUCCESS;
+}
+
+static int ec_set_bn_param(const char *key, BIGNUM **val, const OSSL_PARAM params[])
+{
+ const OSSL_PARAM *p;
+
+ p = OSSL_PARAM_locate_const(params, key);
+ if (!p)
+ return UADK_P_SUCCESS;
+
+ if (!(*val))
+ *val = BN_new();
+
+ if (!(*val))
+ return UADK_P_FAIL;
+
+ return OSSL_PARAM_get_BN(p, val);
+}
+
+static int ec_set_octet_param(const char *key, unsigned char **val,
+ size_t *val_len, const OSSL_PARAM params[])
+{
+ const OSSL_PARAM *p;
+
+ p = OSSL_PARAM_locate_const(params, key);
+ if (!p)
+ return UADK_P_SUCCESS;
+
+ if (p->data_type != OSSL_PARAM_OCTET_STRING)
+ return UADK_P_FAIL;
+
+ OPENSSL_free(*val);
+ *val = OPENSSL_memdup(p->data, p->data_size);
+ if (!(*val))
+ return UADK_P_FAIL;
+
+ *val_len = p->data_size;
+
+ return UADK_P_SUCCESS;
+}
+
+static int uadk_keymgmt_ec_gen_set_params(void *genctx, const OSSL_PARAM params[])
+{
+ struct ec_gen_ctx *gctx = genctx;
+ int ret;
+
+ if (!gctx) {
+ fprintf(stderr, "invalid: gctx is NULL to set params!\n");
+ return UADK_P_FAIL;
+ }
+
+ ret = ec_set_int_param(OSSL_PKEY_PARAM_USE_COFACTOR_ECDH, &gctx->ecdh_mode, params);
+ if (!ret)
+ return ret;
+
+ ret = ec_set_utf8_param(OSSL_PKEY_PARAM_GROUP_NAME, &gctx->group_name, params);
+ if (!ret)
+ return ret;
+
+ ret = ec_set_utf8_param(OSSL_PKEY_PARAM_EC_FIELD_TYPE, &gctx->field_type, params);
+ if (!ret)
+ return ret;
+
+ ret = ec_set_utf8_param(OSSL_PKEY_PARAM_EC_ENCODING, &gctx->encoding, params);
+ if (!ret)
+ return ret;
+
+ ret = ec_set_utf8_param(OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT,
+ &gctx->pt_format, params);
+ if (!ret)
+ return ret;
+
+ ret = ec_set_utf8_param(OSSL_PKEY_PARAM_EC_GROUP_CHECK_TYPE,
+ &gctx->group_check, params);
+ if (!ret)
+ return ret;
+
+ ret = ec_set_bn_param(OSSL_PKEY_PARAM_EC_P, &gctx->p, params);
+ if (!ret)
+ return ret;
+
+ ret = ec_set_bn_param(OSSL_PKEY_PARAM_EC_A, &gctx->a, params);
+ if (!ret)
+ return ret;
+
+ ret = ec_set_bn_param(OSSL_PKEY_PARAM_EC_B, &gctx->b, params);
+ if (!ret)
+ return ret;
+
+ ret = ec_set_bn_param(OSSL_PKEY_PARAM_EC_ORDER, &gctx->order, params);
+ if (!ret)
+ return ret;
+
+ ret = ec_set_bn_param(OSSL_PKEY_PARAM_PRIV_KEY, &gctx->priv_key, params);
+ if (!ret)
+ return ret;
+
+ ret = ec_set_bn_param(OSSL_PKEY_PARAM_EC_COFACTOR, &gctx->cofactor, params);
+ if (!ret)
+ return ret;
+
+ ret = ec_set_octet_param(OSSL_PKEY_PARAM_EC_SEED, &gctx->seed,
+ &gctx->seed_len, params);
+ if (!ret)
+ return ret;
+
+ return ec_set_octet_param(OSSL_PKEY_PARAM_EC_GENERATOR,
+ &gctx->gen, &gctx->gen_len, params);
+}
+
+static const OSSL_PARAM *uadk_keymgmt_ec_gen_settable_params(ossl_unused void *genctx,
+ ossl_unused void *provctx)
+{
+ static OSSL_PARAM settable[] = {
+ OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, NULL, 0),
+ OSSL_PARAM_int(OSSL_PKEY_PARAM_USE_COFACTOR_ECDH, NULL),
+ OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_ENCODING, NULL, 0),
+ OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT,
+ NULL, 0),
+ OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_FIELD_TYPE, NULL, 0),
+ OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_P, NULL, 0),
+ OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_A, NULL, 0),
+ OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_B, NULL, 0),
+ OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_GENERATOR, NULL, 0),
+ OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_ORDER, NULL, 0),
+ OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_COFACTOR, NULL, 0),
+ OSSL_PARAM_BN(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0),
+ OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_SEED, NULL, 0),
+ OSSL_PARAM_END
+ };
+
+ return settable;
+}
+
+static void *uadk_keymgmt_ec_new(void *provctx)
+{
+ if (!get_default_ec_keymgmt().new_fun)
+ return NULL;
+
+ return get_default_ec_keymgmt().new_fun(provctx);
+}
+
+static void uadk_keymgmt_ec_free(void *keydata)
+{
+ if (!get_default_ec_keymgmt().free)
+ return;
+
+ return get_default_ec_keymgmt().free(keydata);
+}
+
+static int uadk_keymgmt_ec_get_params(void *key, OSSL_PARAM params[])
+{
+ if (!get_default_ec_keymgmt().get_params)
+ return UADK_P_FAIL;
+
+ return get_default_ec_keymgmt().get_params(key, params);
+}
+
+static const OSSL_PARAM *uadk_keymgmt_ec_gettable_params(void *provctx)
+{
+ if (!get_default_ec_keymgmt().gettable_params)
+ return NULL;
+
+ return get_default_ec_keymgmt().gettable_params(provctx);
+}
+
+static int uadk_keymgmt_ec_set_params(void *key, const OSSL_PARAM params[])
+{
+ if (!get_default_ec_keymgmt().set_params)
+ return UADK_P_FAIL;
+
+ return get_default_ec_keymgmt().set_params(key, params);
+}
+
+static const OSSL_PARAM *uadk_keymgmt_ec_settable_params(void *provctx)
+{
+ if (!get_default_ec_keymgmt().settable_params)
+ return NULL;
+
+ return get_default_ec_keymgmt().settable_params(provctx);
+}
+
+static void *uadk_keymgmt_ec_load(const void *reference, size_t reference_sz)
+{
+ if (!get_default_ec_keymgmt().load)
+ return NULL;
+
+ return get_default_ec_keymgmt().load(reference, reference_sz);
+}
+
+static int uadk_keymgmt_ec_has(const void *keydata, int selection)
+{
+ if (!get_default_ec_keymgmt().has)
+ return UADK_P_FAIL;
+
+ return get_default_ec_keymgmt().has(keydata, selection);
+}
+
+static int uadk_keymgmt_ec_validate(const void *keydata,
+ int selection, int checktype)
+{
+ if (!get_default_ec_keymgmt().validate)
+ return UADK_P_FAIL;
+
+ return get_default_ec_keymgmt().validate(keydata, selection, checktype);
+}
+
+static int uadk_keymgmt_ec_match(const void *keydata1,
+ const void *keydata2, int selection)
+{
+ if (!get_default_ec_keymgmt().match)
+ return UADK_P_FAIL;
+
+ return get_default_ec_keymgmt().match(keydata1, keydata2, selection);
+}
+
+static int uadk_keymgmt_ec_import(void *keydata, int selection,
+ const OSSL_PARAM params[])
+{
+ if (!get_default_ec_keymgmt().import)
+ return UADK_P_FAIL;
+
+ return get_default_ec_keymgmt().import(keydata, selection, params);
+}
+
+static const OSSL_PARAM *uadk_keymgmt_ec_import_types(int selection)
+{
+ if (!get_default_ec_keymgmt().import_types)
+ return NULL;
+
+ return get_default_ec_keymgmt().import_types(selection);
+}
+
+static int uadk_keymgmt_ec_export(void *keydata, int selection,
+ OSSL_CALLBACK *param_cb, void *cbarg)
+{
+ if (!get_default_ec_keymgmt().export_fun)
+ return UADK_P_FAIL;
+
+ return get_default_ec_keymgmt().export_fun(keydata, selection, param_cb, cbarg);
+}
+
+static const OSSL_PARAM *uadk_keymgmt_ec_export_types(int selection)
+{
+ if (!get_default_ec_keymgmt().export_types)
+ return NULL;
+
+ return get_default_ec_keymgmt().export_types(selection);
+}
+
+static void *uadk_keymgmt_ec_dup(const void *keydata_from, int selection)
+{
+ if (!get_default_ec_keymgmt().dup)
+ return NULL;
+
+ return get_default_ec_keymgmt().dup(keydata_from, selection);
+}
+
+static const char *uadk_keymgmt_ec_query_operation_name(int operation_id)
+{
+ if (!get_default_ec_keymgmt().query_operation_name)
+ return NULL;
+
+ return get_default_ec_keymgmt().query_operation_name(operation_id);
+}
diff --git a/src/uadk_prov_init.c b/src/uadk_prov_init.c
index 55202ae..b5d3df5 100644
--- a/src/uadk_prov_init.c
+++ b/src/uadk_prov_init.c
@@ -174,6 +174,8 @@ static const OSSL_ALGORITHM uadk_prov_keymgmt[] = {
{ "DH", UADK_DEFAULT_PROPERTIES, uadk_dh_keymgmt_functions },
{ "SM2", UADK_DEFAULT_PROPERTIES,
uadk_sm2_keymgmt_functions, "uadk SM2 Keymgmt implementation." },
+ { "EC", UADK_DEFAULT_PROPERTIES,
+ uadk_ec_keymgmt_functions, "uadk EC Keymgmt implementation."},
{ NULL, NULL, NULL }
};
diff --git a/src/uadk_prov_pkey.c b/src/uadk_prov_pkey.c
index 6e0612e..170c30b 100644
--- a/src/uadk_prov_pkey.c
+++ b/src/uadk_prov_pkey.c
@@ -628,7 +628,7 @@ int uadk_prov_ecc_genctx_check(struct ec_gen_ctx *gctx, EC_KEY *ec)
return UADK_P_SUCCESS;
}
-static bool uadk_prov_support_algorithm(const char *alg)
+bool uadk_prov_support_algorithm(const char *alg)
{
struct uacce_dev_list *list = wd_get_accel_list(alg);
@@ -642,7 +642,7 @@ static bool uadk_prov_support_algorithm(const char *alg)
void uadk_prov_keymgmt_alg(void)
{
- static const char * const keymgmt_alg[] = {"sm2"};
+ static const char * const keymgmt_alg[] = {"sm2", "ecdh"};
__u32 i, size;
bool sp;
@@ -811,3 +811,25 @@ void uadk_prov_ecc_uninit(void)
}
pthread_mutex_unlock(&ecc_mutex);
}
+
+int uadk_prov_ecc_bit_check(const EC_GROUP *group)
+{
+ int bits = EC_GROUP_order_bits(group);
+
+ switch (bits) {
+ case ECC128BITS:
+ case ECC192BITS:
+ case ECC224BITS:
+ case ECC256BITS:
+ case ECC320BITS:
+ case ECC384BITS:
+ case ECC521BITS:
+ return UADK_P_SUCCESS;
+ default:
+ break;
+ }
+
+ fprintf(stderr, "invalid: unsupport key bits %d!\n", bits);
+
+ return UADK_P_FAIL;
+}
diff --git a/src/uadk_prov_pkey.h b/src/uadk_prov_pkey.h
index c9ddba1..1d4911c 100644
--- a/src/uadk_prov_pkey.h
+++ b/src/uadk_prov_pkey.h
@@ -68,6 +68,7 @@
enum {
KEYMGMT_SM2 = 0x0,
+ KEYMGMT_EC = 0x1,
KEYMGMT_MAX = 0x6
};
@@ -76,6 +77,12 @@ enum {
SIGNATURE_MAX = 0x3
};
+enum {
+ COFACTOR_MODE_USE_KEY = -1,
+ COFACTOR_MODE_DISABLED = 0,
+ COFACTOR_MODE_ENABLED = 1,
+};
+
struct curve_param {
/* Prime */
BIGNUM *p;
@@ -102,6 +109,7 @@ struct ec_gen_ctx {
int selection;
int ecdh_mode;
EC_GROUP *gen_group;
+ BIGNUM *priv_key;
};
typedef struct {
@@ -443,5 +451,6 @@ void uadk_prov_signature_alg(void);
void uadk_prov_asym_cipher_alg(void);
int uadk_prov_asym_cipher_get_support_state(int alg_tag);
int uadk_prov_ecc_init(const char *alg_name);
+int uadk_prov_ecc_bit_check(const EC_GROUP *group);
#endif
--
2.25.1