On 2023/2/16 21:32, fanghao (A) wrote:
在 2023/2/11 15:19, Weili Qian 写道:
After adding the ecc module of the init2 interface, combine it dynamically load the initialization part, transform HiSilicon HPRE driven, and implemented using the dynamic loading function Connection between driver and algorithm layer.
Signed-off-by: Weili Qian qianweili@huawei.com
drv/hisi_hpre.c | 124 ++++++++++++++++++++------- include/drv/wd_ecc_drv.h | 27 ------ wd_ecc.c | 181 +++++++++++++++++++++++++-------------- 3 files changed, 209 insertions(+), 123 deletions(-)
diff --git a/drv/hisi_hpre.c b/drv/hisi_hpre.c index d8b212d..a08e5e6 100644 --- a/drv/hisi_hpre.c +++ b/drv/hisi_hpre.c @@ -32,6 +32,7 @@ #define SM2_PONIT_SIZE 64 #define MAX_HASH_LENS BITS_TO_BYTES(521) #define HW_PLAINTEXT_BYTES_MAX BITS_TO_BYTES(4096) +#define HPRE_CTX_Q_NUM_DEF 1 #define CRT_PARAMS_SZ(key_size) ((5 * (key_size)) >> 1) #define CRT_GEN_PARAMS_SZ(key_size) ((7 * (key_size)) >> 1) @@ -459,37 +460,26 @@ static int rsa_prepare_iot(struct wd_rsa_msg *msg, return ret; } -static int hpre_init(struct wd_ctx_config_internal *config, void *priv, const char *alg_name) +static int hpre_init_qm_priv(struct wd_ctx_config_internal *config,
struct hisi_hpre_ctx *hpre_ctx,
{struct hisi_qm_priv *qm_priv)
- struct hisi_hpre_ctx *hpre_ctx = (struct hisi_hpre_ctx *)priv;
- struct hisi_qm_priv qm_priv; handle_t h_ctx, h_qp; int i, j;
- if (!config->ctx_num) {
WD_ERR("invalid: hpre init config ctx num is 0!\n");
return -WD_EINVAL;
- }
memcpy(&hpre_ctx->config, config, sizeof(*config)); /* allocate qp for each context */
- qm_priv.sqe_size = sizeof(struct hisi_hpre_sqe);
- /* DH/RSA: qm sqc_type = 0, ECC: qm sqc_type = 1; */
- if (!strcmp(alg_name, "ecc"))
qm_priv.op_type = HPRE_HW_V3_ECC_ALG_TYPE;
- else
qm_priv.op_type = HPRE_HW_V2_ALG_TYPE;
- qm_priv->sqe_size = sizeof(struct hisi_hpre_sqe); for (i = 0; i < config->ctx_num; i++) { h_ctx = config->ctxs[i].ctx;
qm_priv.qp_mode = config->ctxs[i].ctx_mode;
qm_priv->qp_mode = config->ctxs[i].ctx_mode; /* Setting the epoll en to 0 for ASYNC ctx */
qm_priv.epoll_en = (qm_priv.qp_mode == CTX_MODE_SYNC) ?
qm_priv->epoll_en = (qm_priv->qp_mode == CTX_MODE_SYNC) ? config->epoll_en : 0;
qm_priv.idx = i;
h_qp = hisi_qm_alloc_qp(&qm_priv, h_ctx);
qm_priv->idx = i;
h_qp = hisi_qm_alloc_qp(qm_priv, h_ctx); if (!h_qp) { WD_ERR("failed to alloc qp!\n"); goto out;
@@ -506,6 +496,45 @@ out: return -WD_EINVAL; } +static int hpre_rsa_dh_init(struct wd_ctx_config_internal *config, void *priv, const char *alg_name) +{
- struct hisi_hpre_ctx *hpre_ctx = (struct hisi_hpre_ctx *)priv;
- struct hisi_qm_priv qm_priv;
- int ret;
- if (!config->ctx_num) {
WD_ERR("invalid: hpre rsa/dh init config ctx num is 0!\n");
return -WD_EINVAL;
- }
- qm_priv.op_type = HPRE_HW_V2_ALG_TYPE;
- ret = hpre_init_qm_priv(config, hpre_ctx, &qm_priv);
- if (ret)
return ret;
- return 0;
+}
+static int hpre_ecc_init(void *conf, void *priv) +{
- struct wd_ctx_config_internal *config = (struct wd_ctx_config_internal *)conf;
- struct hisi_hpre_ctx *hpre_ctx = (struct hisi_hpre_ctx *)priv;
- struct hisi_qm_priv qm_priv;
- int ret;
- if (!config->ctx_num) {
WD_ERR("invalid: hpre ecc init config ctx num is 0!\n");
return -WD_EINVAL;
- }
- qm_priv.op_type = HPRE_HW_V2_ALG_TYPE;
- ret = hpre_init_qm_priv(config, hpre_ctx, &qm_priv);
- if (ret)
return ret;
- return 0;
+}
- static void hpre_exit(void *priv) { struct hisi_hpre_ctx *hpre_ctx = (struct hisi_hpre_ctx *)priv;
@@ -624,7 +653,7 @@ static struct wd_rsa_driver rsa_hisi_hpre = { .drv_name = "hisi_hpre", .alg_name = "rsa", .drv_ctx_size = sizeof(struct hisi_hpre_ctx),
- .init = hpre_init,
- .init = hpre_rsa_dh_init, .exit = hpre_exit, .send = rsa_send, .recv = rsa_recv,
@@ -777,7 +806,7 @@ static struct wd_dh_driver dh_hisi_hpre = { .drv_name = "hisi_hpre", .alg_name = "dh", .drv_ctx_size = sizeof(struct hisi_hpre_ctx),
- .init = hpre_init,
- .init = hpre_rsa_dh_init, .exit = hpre_exit, .send = dh_send, .recv = dh_recv,
@@ -2427,16 +2456,51 @@ static int ecc_recv(handle_t ctx, void *ecc_msg) return ecc_sqe_parse((struct hisi_qp *)h_qp, msg, &hw_msg); } -static struct wd_ecc_driver ecc_hisi_hpre = {
- .drv_name = "hisi_hpre",
- .alg_name = "ecc",
- .drv_ctx_size = sizeof(struct hisi_hpre_ctx),
- .init = hpre_init,
- .exit = hpre_exit,
- .send = ecc_send,
- .recv = ecc_recv,
+#define GEN_HPRE_ALG_DRIVER(hpre_alg_name) \ +{\
- .drv_name = "hisi_hpre",\
- .alg_name = hpre_alg_name,\
- .priority = UADK_ALG_HW,\
- .priv_size = sizeof(struct hisi_hpre_ctx),\
- .queue_num = HPRE_CTX_Q_NUM_DEF,\
- .op_type_num = 1,\
- .fallback = 0,\
- .init = hpre_ecc_init,\
- .exit = hpre_exit,\
- .send = ecc_send,\
- .recv = ecc_recv,\
+}
+static struct wd_alg_driver hpre_alg_driver[] = {
- GEN_HPRE_ALG_DRIVER("sm2"),
- GEN_HPRE_ALG_DRIVER("ecdh"),
- GEN_HPRE_ALG_DRIVER("ecdsa"),
- GEN_HPRE_ALG_DRIVER("x25519"),
- GEN_HPRE_ALG_DRIVER("x448"), }; +static void __attribute__((constructor)) hisi_hpre_probe(void)
+{
- int alg_num = ARRAY_SIZE(hpre_alg_driver);
- int i, ret;
- WD_INFO("Info: register HPRE alg drivers!\n");
- for (i = 0; i < alg_num; i++) {
ret = wd_alg_driver_register(&hpre_alg_driver[i]);
if (ret)
WD_ERR("failed to register HPRE %s driver!\n", hpre_alg_driver[i].alg_name);
- }
+}
+static void __attribute__((destructor)) hisi_hpre_remove(void) +{
- int alg_num = ARRAY_SIZE(hpre_alg_driver);
- int i;
- for (i = 0; i < alg_num; i++)
wd_alg_driver_unregister(&hpre_alg_driver[i]);
+}
- WD_RSA_SET_DRIVER(rsa_hisi_hpre); WD_DH_SET_DRIVER(dh_hisi_hpre);
-WD_ECC_SET_DRIVER(ecc_hisi_hpre); diff --git a/include/drv/wd_ecc_drv.h b/include/drv/wd_ecc_drv.h index 4d27ccb..f5805cd 100644 --- a/include/drv/wd_ecc_drv.h +++ b/include/drv/wd_ecc_drv.h @@ -175,35 +175,8 @@ struct wd_ecc_out { char data[]; }; -struct wd_ecc_driver {
- const char *drv_name;
- const char *alg_name;
- __u32 drv_ctx_size;
- int (*init)(struct wd_ctx_config_internal *config, void *priv,
const char *alg_name);
- void (*exit)(void *priv);
- int (*send)(handle_t sess, void *ecc_msg);
- int (*recv)(handle_t sess, void *ecc_msg);
-};
-void wd_ecc_set_driver(struct wd_ecc_driver *drv); -struct wd_ecc_driver *wd_ecc_get_driver(void); struct wd_ecc_msg *wd_ecc_get_msg(__u32 idx, __u32 tag); -#ifdef WD_STATIC_DRV -#define WD_ECC_SET_DRIVER(drv) \ -struct wd_ecc_driver *wd_ecc_get_driver(void) \ -{ \
- return &drv; \
-} -#else -#define WD_ECC_SET_DRIVER(drv) \ -static void __attribute__((constructor)) set_driver_ecc(void) \ -{ \
- wd_ecc_set_driver(&(drv)); \
-} -#endif
- #ifdef __cplusplus } #endif
diff --git a/wd_ecc.c b/wd_ecc.c index 4cad1e4..57954e0 100644 --- a/wd_ecc.c +++ b/wd_ecc.c @@ -66,26 +66,16 @@ static struct wd_ecc_setting { enum wd_status status; struct wd_ctx_config_internal config; struct wd_sched sched;
- void *sched_ctx;
- const struct wd_ecc_driver *driver;
- struct wd_async_msg_pool pool;
- struct wd_alg_driver *driver; void *priv; void *dlhandle;
- struct wd_async_msg_pool pool;
- void *dlh_list; } wd_ecc_setting; struct wd_env_config wd_ecc_env_config; static struct wd_init_attrs wd_ecc_init_attrs; -static struct wd_ctx_nums wd_ecc_ctx_num[] = {
- {1, 1}, {}
-};
-static struct wd_ctx_params wd_ecc_ctx_params = {
- .op_type_num = 1,
- .ctx_set_num = wd_ecc_ctx_num,
- .bmp = NULL,
-};
- static const struct wd_ecc_curve_list curve_list[] = { /* parameter 3 is key width */ { WD_X25519, "x25519", 256, X25519_256_PARAM },
@@ -109,36 +99,50 @@ static const struct curve_param_desc curve_pram_list[] = { { ECC_CURVE_G, offsetof(struct wd_ecc_prikey, g), offsetof(struct wd_ecc_pubkey, g) } }; -#ifdef WD_STATIC_DRV -static void wd_ecc_set_static_drv(void) +static void wd_ecc_close_driver(void) {
- wd_ecc_setting.driver = wd_ecc_get_driver();
- if (!wd_ecc_setting.driver)
WD_ERR("failed to get ecc driver!\n");
-} -#else -static void __attribute__((constructor)) wd_ecc_open_driver(void) -{
- wd_ecc_setting.dlhandle = dlopen("libhisi_hpre.so", RTLD_NOW); if (!wd_ecc_setting.dlhandle)
WD_ERR("failed to open libhisi_hpre.so, %s\n", dlerror());
-}
-static void __attribute__((destructor)) wd_ecc_close_driver(void)return;
-{
- if (wd_ecc_setting.dlhandle)
dlclose(wd_ecc_setting.dlhandle);
- wd_release_drv(wd_ecc_setting.driver);
- dlclose(wd_ecc_setting.dlhandle);
- wd_ecc_setting.dlhandle = NULL; }
-#endif -void wd_ecc_set_driver(struct wd_ecc_driver *drv) +static int wd_ecc_open_driver(void) {
- if (!drv) {
WD_ERR("invalid: ecc drv is NULL!\n");
return;
- struct wd_alg_driver *driver = NULL;
- char lib_path[PATH_STR_SIZE];
- const char *alg_name = "sm2";
- int ret;
- /*
* Compatible with the normal acquisition of device
* drivers in the init interface
*/
- if (wd_ecc_setting.dlh_list)
return 0;
- ret = wd_get_lib_file_path("libhisi_hpre.so", lib_path, false);
Can not to specify a specific vendor so?
wd_<alg>_init only supports libhisi_hpre.so, wd_<alg>_init2 can support different .so.
- if (ret)
return ret;
- wd_ecc_setting.dlhandle = dlopen(lib_path, RTLD_NOW);
- if (!wd_ecc_setting.dlhandle) {
WD_ERR("failed to open libhisi_hpre.so, %s!\n", dlerror());
return -WD_EINVAL; }
- wd_ecc_setting.driver = drv;
- driver = wd_request_drv(alg_name, false);
- if (!driver) {
wd_ecc_close_driver();
WD_ERR("failed to get %s driver support\n", alg_name);
return -WD_EINVAL;
- }
- wd_ecc_setting.driver = driver;
- return 0; } static void wd_ecc_clear_status(void)
@@ -148,7 +152,6 @@ static void wd_ecc_clear_status(void) static int wd_ecc_common_init(struct wd_ctx_config *config, struct wd_sched *sched) {
- void *priv; int ret; ret = wd_set_epoll_en("WD_ECC_EPOLL_EN",
@@ -164,10 +167,6 @@ static int wd_ecc_common_init(struct wd_ctx_config *config, struct wd_sched *sch if (ret < 0) goto out_clear_ctx_config; -#ifdef WD_STATIC_DRV
- wd_ecc_set_static_drv();
-#endif
/* fix me: sadly find we allocate async pool for every ctx */ ret = wd_init_async_request_pool(&wd_ecc_setting.pool, config->ctx_num, WD_POOL_MAX_ENTRIES,
@@ -175,26 +174,14 @@ static int wd_ecc_common_init(struct wd_ctx_config *config, struct wd_sched *sch if (ret < 0) goto out_clear_sched;
- /* initialize ctx related resources in specific driver */
- priv = calloc(1, wd_ecc_setting.driver->drv_ctx_size);
- if (!priv) {
ret = -WD_ENOMEM;
- ret = wd_alg_init_driver(&wd_ecc_setting.config,
wd_ecc_setting.driver,
&wd_ecc_setting.priv);
- if (ret) goto out_clear_pool;
- }
- wd_ecc_setting.priv = priv;
- ret = wd_ecc_setting.driver->init(&wd_ecc_setting.config, priv,
wd_ecc_setting.driver->alg_name);
- if (ret < 0) {
WD_ERR("failed to init ecc driver, ret = %d!\n", ret);
goto out_free_priv;
- } return 0; -out_free_priv:
- free(priv);
- wd_ecc_setting.priv = NULL; out_clear_pool: wd_uninit_async_request_pool(&wd_ecc_setting.pool); out_clear_sched:
@@ -211,17 +198,14 @@ static void wd_ecc_common_uninit(void) return; }
- /* driver uninit */
- wd_ecc_setting.driver->exit(wd_ecc_setting.priv);
- free(wd_ecc_setting.priv);
- wd_ecc_setting.priv = NULL;
/* uninit async request pool */ wd_uninit_async_request_pool(&wd_ecc_setting.pool); /* unset config, sched, driver */ wd_clear_sched(&wd_ecc_setting.sched);
- wd_clear_ctx_config(&wd_ecc_setting.config);
- wd_alg_uninit_driver(&wd_ecc_setting.config,
wd_ecc_setting.driver,
} int wd_ecc_init(struct wd_ctx_config *config, struct wd_sched *sched)&wd_ecc_setting.priv);
@@ -239,14 +223,20 @@ int wd_ecc_init(struct wd_ctx_config *config, struct wd_sched *sched) if (ret) goto out_clear_init;
- ret = wd_ecc_common_init(config, sched);
- ret = wd_ecc_open_driver(); if (ret) goto out_clear_init;
- ret = wd_ecc_common_init(config, sched);
- if (ret)
goto out_close_driver;
+out_close_driver:wd_alg_set_init(&wd_ecc_setting.status); return 0;
- wd_ecc_close_driver(); out_clear_init: wd_alg_clear_init(&wd_ecc_setting.status); return ret;
@@ -255,11 +245,14 @@ out_clear_init: void wd_ecc_uninit(void) { wd_ecc_common_uninit();
- wd_ecc_close_driver(); wd_alg_clear_init(&wd_ecc_setting.status); } int wd_ecc_init2_(char *alg, __u32 sched_type, int task_type, struct wd_ctx_params *ctx_params) {
- struct wd_ctx_nums ecc_ctx_num[WD_EC_OP_MAX] = {0};
- struct wd_ctx_params ecc_ctx_params = {0}; bool flag; int ret; @@ -275,19 +268,66 @@ int wd_ecc_init2_(char *alg, __u32 sched_type, int task_type, struct wd_ctx_para goto out_clear_init; }
- /*
* Driver lib file path could set by env param.
* than open tham by wd_dlopen_drv()
* default dir in the /root/lib/xxx.so and then dlopen
*/
- wd_ecc_setting.dlh_list = wd_dlopen_drv(NULL);
- if (!wd_ecc_setting.dlh_list) {
WD_ERR("failed to open driver lib files!\n");
ret = -WD_EINVAL;
goto out_clear_init;
- }
+res_retry:
- memset(&wd_ecc_setting.config, 0, sizeof(struct wd_ctx_config_internal));
- /* Get alg driver and dev name */
- wd_ecc_setting.driver = wd_alg_drv_bind(task_type, alg);
- if (!wd_ecc_setting.driver) {
WD_ERR("failed to bind a valid driver!\n");
ret = -WD_EINVAL;
goto out_dlopen;
- }
- ret = wd_ctx_param_init(&ecc_ctx_params, ctx_params,
ecc_ctx_num, wd_ecc_setting.driver,
WD_EC_OP_MAX);
- if (ret) {
if (ret == -WD_EAGAIN) {
wd_disable_drv(wd_ecc_setting.driver);
wd_alg_drv_unbind(wd_ecc_setting.driver);
goto res_retry;
}
goto out_driver;
- }
wd_ecc_init_attrs.alg = alg; wd_ecc_init_attrs.sched_type = sched_type;
- wd_ecc_init_attrs.ctx_params = ctx_params ? ctx_params : &wd_ecc_ctx_params;
- wd_ecc_init_attrs.driver = wd_ecc_setting.driver;
- wd_ecc_init_attrs.ctx_params = &ecc_ctx_params; wd_ecc_init_attrs.alg_init = wd_ecc_common_init; wd_ecc_init_attrs.alg_poll_ctx = wd_ecc_poll_ctx; ret = wd_alg_attrs_init(&wd_ecc_init_attrs);
- if (ret)
goto out_clear_init;
- if (ret) {
if (ret == -WD_ENODEV) {
wd_disable_drv(wd_ecc_setting.driver);
wd_alg_drv_unbind(wd_ecc_setting.driver);
goto res_retry;
}
WD_ERR("failed to init alg attrs!\n");
goto out_driver;
- } wd_alg_set_init(&wd_ecc_setting.status); return 0; +out_driver:
- wd_alg_drv_unbind(wd_ecc_setting.driver);
+out_dlopen:
- wd_dlclose_drv(wd_ecc_setting.dlh_list); out_clear_init: wd_alg_clear_init(&wd_ecc_setting.status); return ret;
@@ -297,6 +337,9 @@ void wd_ecc_uninit2(void) { wd_ecc_common_uninit(); wd_alg_attrs_uninit(&wd_ecc_init_attrs);
- wd_alg_drv_unbind(wd_ecc_setting.driver);
- wd_dlclose_drv(wd_ecc_setting.dlh_list);
- wd_ecc_setting.dlh_list = NULL; wd_alg_clear_init(&wd_ecc_setting.status); } @@ -1098,6 +1141,12 @@ handle_t wd_ecc_alloc_sess(struct wd_ecc_sess_setup *setup) if (setup_param_check(setup)) return (handle_t)0;
- ret = wd_drv_alg_support(setup->alg, wd_ecc_setting.driver);
- if (!ret) {
WD_ERR("failed to support this algorithm: %s!\n", setup->alg);
return (handle_t)0;
- }
sess = calloc(1, sizeof(struct wd_ecc_sess)); if (!sess) return (handle_t)0;
.