libwd/0030-uadk-v1-cipher-support-user-self-defined-data-functi.patch
2023-09-28 09:15:32 +08:00

327 lines
10 KiB
Diff

From 998b7f678edf910281e07539de2a9f0399ddc2ac Mon Sep 17 00:00:00 2001
From: Zhiqi Song <songzhiqi1@huawei.com>
Date: Sat, 23 Sep 2023 18:32:02 +0800
Subject: [PATCH 30/38] uadk/v1/cipher: support user self-defined data
functions
Support user self-defined data for calculation. This means
user do not need to use reserved memory provided by uadk-v1
driver and make the data to be parsed and processed by the
uadk-v1 driver. Through this new feature, users can configure
the custom data according to 'struct wd_sec_udata', and pass
it to the 'priv' member of 'struct wcrypto_cipher_op_data',
enabling hardware deal with the user custom data directly.
Note that if users want to set key through custom data, the
uadk-v1 api wcrypto_set_cipher_key(), which used to set the
key, should not be used any more. Users should set the key with
'struct wd_sec_udata' type and pass it to 'priv' member.
Signed-off-by: Zhiqi Song <songzhiqi1@huawei.com>
---
v1/drv/hisi_sec_udrv.c | 153 ++++++++++++++++++++++++++++++++++-------
v1/wd_cipher.c | 4 +-
2 files changed, 130 insertions(+), 27 deletions(-)
diff --git a/v1/drv/hisi_sec_udrv.c b/v1/drv/hisi_sec_udrv.c
index 832d6a3..2931bb4 100644
--- a/v1/drv/hisi_sec_udrv.c
+++ b/v1/drv/hisi_sec_udrv.c
@@ -395,7 +395,7 @@ static int fill_cipher_bd1_mode(struct wcrypto_cipher_msg *msg,
return WD_SUCCESS;
}
-static void fill_cipher_bd1_udata(struct hisi_sec_sqe *sqe,
+static void fill_cipher_bd1_dif(struct hisi_sec_sqe *sqe,
struct wd_sec_udata *udata)
{
sqe->type1.gran_num = udata->gran_num;
@@ -418,6 +418,28 @@ static void fill_cipher_bd1_udata(struct hisi_sec_sqe *sqe,
sqe->type1.lba_h = udata->dif.lba >> QM_HADDR_SHIFT;
}
+static void fill_cipher_bd1_udata_addr(struct wcrypto_cipher_msg *msg,
+ struct hisi_sec_sqe *sqe)
+{
+ uintptr_t phy;
+
+ /* For user self-defined scene, iova = pa */
+ phy = (uintptr_t)msg->in;
+ sqe->type1.data_src_addr_l = (__u32)(phy & QM_L32BITS_MASK);
+ sqe->type1.data_src_addr_h = HI_U32(phy);
+ phy = (uintptr_t)msg->out;
+ sqe->type1.data_dst_addr_l = (__u32)(phy & QM_L32BITS_MASK);
+ sqe->type1.data_dst_addr_h = HI_U32(phy);
+ phy = (uintptr_t)msg->key;
+ sqe->type1.c_key_addr_l = (__u32)(phy & QM_L32BITS_MASK);
+ sqe->type1.c_key_addr_h = HI_U32(phy);
+ if (msg->iv_bytes) {
+ phy = (uintptr_t)msg->iv;
+ sqe->type1.c_ivin_addr_l = (__u32)(phy & QM_L32BITS_MASK);
+ sqe->type1.c_ivin_addr_h = HI_U32(phy);
+ }
+}
+
static int map_addr(struct wd_queue *q, __u8 *key, __u16 len,
__u32 *addr_l, __u32 *addr_h, __u8 data_fmt)
{
@@ -500,8 +522,8 @@ map_key_error:
static int fill_cipher_bd1(struct wd_queue *q, struct hisi_sec_sqe *sqe,
struct wcrypto_cipher_msg *msg, struct wcrypto_cipher_tag *tag)
{
- int ret;
struct wd_sec_udata *udata = tag->priv;
+ int ret;
sqe->type = BD_TYPE1;
sqe->scene = SCENE_STORAGE;
@@ -519,11 +541,16 @@ static int fill_cipher_bd1(struct wd_queue *q, struct hisi_sec_sqe *sqe,
if (ret != WD_SUCCESS)
return ret;
- fill_cipher_bd1_udata(sqe, udata);
-
- ret = fill_cipher_bd1_addr(q, msg, sqe);
- if (ret != WD_SUCCESS)
- return ret;
+ if (udata) {
+ /* User self-defined data with DIF scence */
+ fill_cipher_bd1_dif(sqe, udata);
+ fill_cipher_bd1_udata_addr(msg, sqe);
+ } else {
+ /* Reserved for non user self-defined data scence */
+ ret = fill_cipher_bd1_addr(q, msg, sqe);
+ if (ret != WD_SUCCESS)
+ return ret;
+ }
sqe->type1.tag = tag->wcrypto_tag.ctx_id;
@@ -636,6 +663,27 @@ static int aes_sm4_param_check(struct wcrypto_cipher_msg *msg)
return WD_SUCCESS;
}
+static void fill_cipher_bd2_udata_addr(struct wcrypto_cipher_msg *msg,
+ struct hisi_sec_sqe *sqe)
+{
+ uintptr_t phy;
+
+ phy = (uintptr_t)msg->in;
+ sqe->type2.data_src_addr_l = (__u32)(phy & QM_L32BITS_MASK);
+ sqe->type2.data_src_addr_h = HI_U32(phy);
+ phy = (uintptr_t)msg->out;
+ sqe->type2.data_dst_addr_l = (__u32)(phy & QM_L32BITS_MASK);
+ sqe->type2.data_dst_addr_h = HI_U32(phy);
+ phy = (uintptr_t)msg->key;
+ sqe->type2.c_key_addr_l = (__u32)(phy & QM_L32BITS_MASK);
+ sqe->type2.c_key_addr_h = HI_U32(phy);
+ if (msg->iv_bytes) {
+ phy = (uintptr_t)msg->iv;
+ sqe->type2.c_ivin_addr_l = (__u32)(phy & QM_L32BITS_MASK);
+ sqe->type2.c_ivin_addr_h = HI_U32(phy);
+ }
+}
+
static int cipher_param_check(struct wcrypto_cipher_msg *msg)
{
int ret;
@@ -705,9 +753,14 @@ static int fill_cipher_bd2(struct wd_queue *q, struct hisi_sec_sqe *sqe,
return ret;
}
- ret = fill_cipher_bd2_addr(q, msg, sqe);
- if (ret != WD_SUCCESS)
- return ret;
+ if (tag->priv) {
+ /* User self-defined data process */
+ fill_cipher_bd2_udata_addr(msg, sqe);
+ } else {
+ ret = fill_cipher_bd2_addr(q, msg, sqe);
+ if (ret != WD_SUCCESS)
+ return ret;
+ }
if (tag)
sqe->type2.tag = tag->wcrypto_tag.ctx_id;
@@ -978,10 +1031,11 @@ static int cipher_comb_param_check(struct wcrypto_cipher_msg *msg)
int qm_fill_cipher_sqe(void *message, struct qm_queue_info *info, __u16 i)
{
- struct hisi_sec_sqe *sqe;
struct wcrypto_cipher_msg *msg = message;
- struct wd_queue *q = info->q;
struct wcrypto_cipher_tag *tag = (void *)(uintptr_t)msg->usr_data;
+ struct wd_sec_udata *udata = tag->priv;
+ struct wd_queue *q = info->q;
+ struct hisi_sec_sqe *sqe;
uintptr_t temp;
int ret;
@@ -994,10 +1048,13 @@ int qm_fill_cipher_sqe(void *message, struct qm_queue_info *info, __u16 i)
temp = (uintptr_t)info->sq_base + i * info->sqe_size;
sqe = (struct hisi_sec_sqe *)temp;
-
memset(sqe, 0, sizeof(struct hisi_sec_sqe));
- if (tag->priv)
+ /**
+ * For user self-defined data with DIF scence, will fill BD1.
+ * Other scences will fill BD2 by default, including no DIF scence.
+ */
+ if (udata && udata->gran_num != 0)
ret = fill_cipher_bd1(q, sqe, msg, tag);
else
ret = fill_cipher_bd2(q, sqe, msg, tag);
@@ -1015,10 +1072,12 @@ int qm_fill_cipher_sqe(void *message, struct qm_queue_info *info, __u16 i)
int qm_fill_cipher_bd3_sqe(void *message, struct qm_queue_info *info, __u16 i)
{
- struct hisi_sec_bd3_sqe *sqe3;
struct wcrypto_cipher_msg *msg = message;
- struct wd_queue *q = info->q;
struct wcrypto_cipher_tag *tag = (void *)(uintptr_t)msg->usr_data;
+ struct wd_sec_udata *udata = tag->priv;
+ struct wd_queue *q = info->q;
+ struct hisi_sec_bd3_sqe *sqe3;
+ struct hisi_sec_sqe *sqe;
uintptr_t temp;
int ret;
@@ -1030,18 +1089,35 @@ int qm_fill_cipher_bd3_sqe(void *message, struct qm_queue_info *info, __u16 i)
}
temp = (uintptr_t)info->sq_base + i * info->sqe_size;
- sqe3 = (struct hisi_sec_bd3_sqe *)temp;
- memset(sqe3, 0, sizeof(struct hisi_sec_bd3_sqe));
+ /*
+ * For user self-defined data with DIF scence, will fill BD1.
+ * For user self-defined data without DIF scence, will fill BD2.
+ * For non user self-defined data scence, will fill BD3.
+ */
+ if (udata) {
+ sqe = (struct hisi_sec_sqe *)temp;
+ memset(sqe, 0, sizeof(struct hisi_sec_sqe));
+ if (udata->gran_num != 0)
+ ret = fill_cipher_bd1(q, sqe, msg, tag);
+ else
+ ret = fill_cipher_bd2(q, sqe, msg, tag);
+ } else {
+ sqe3 = (struct hisi_sec_bd3_sqe *)temp;
+ memset(sqe3, 0, sizeof(struct hisi_sec_bd3_sqe));
+ ret = fill_cipher_bd3(q, sqe3, msg, tag);
+ }
- ret = fill_cipher_bd3(q, sqe3, msg, tag);
if (ret != WD_SUCCESS)
return ret;
info->req_cache[i] = msg;
#ifdef DEBUG_LOG
- sec_dump_bd((unsigned char *)sqe3, SQE_BYTES_NUMS);
+ if (udata)
+ sec_dump_bd((unsigned char *)sqe, SQE_BYTES_NUMS);
+ else
+ sec_dump_bd((unsigned char *)sqe3, SQE_BYTES_NUMS);
#endif
return ret;
@@ -1686,6 +1762,7 @@ static void cipher_ofb_data_handle(struct wcrypto_cipher_msg *msg)
static void parse_cipher_bd2(struct wd_queue *q, struct hisi_sec_sqe *sqe,
struct wcrypto_cipher_msg *cipher_msg)
{
+ struct wcrypto_cipher_tag *tag;
__u64 dma_addr;
if (sqe->type2.done != SEC_HW_TASK_DONE || sqe->type2.error_type) {
@@ -1695,6 +1772,11 @@ static void parse_cipher_bd2(struct wd_queue *q, struct hisi_sec_sqe *sqe,
} else
cipher_msg->result = WD_SUCCESS;
+ /* In user self-define data case, may not need addr map, just return */
+ tag = (void *)(uintptr_t)cipher_msg->usr_data;
+ if (tag->priv)
+ return;
+
dma_addr = DMA_ADDR(sqe->type2.data_src_addr_h,
sqe->type2.data_src_addr_l);
drv_iova_unmap(q, cipher_msg->in, (void *)(uintptr_t)dma_addr,
@@ -1790,25 +1872,44 @@ int qm_parse_cipher_bd3_sqe(void *msg, const struct qm_queue_info *info,
__u16 i, __u16 usr)
{
struct wcrypto_cipher_msg *cipher_msg = info->req_cache[i];
- struct hisi_sec_bd3_sqe *sqe = msg;
+ struct hisi_sec_bd3_sqe *sqe3 = msg;
struct wd_queue *q = info->q;
+ struct hisi_sec_sqe *sqe;
if (unlikely(!cipher_msg)) {
WD_ERR("info->req_cache is null at index:%hu\n", i);
return 0;
}
- if (likely(sqe->type == BD_TYPE3)) {
- if (unlikely(usr && sqe->tag_l != usr))
+ switch (sqe3->type) {
+ case BD_TYPE3:
+ if (unlikely(usr && sqe3->tag_l != usr))
return 0;
- parse_cipher_bd3(q, sqe, cipher_msg);
- } else {
+ parse_cipher_bd3(q, sqe3, cipher_msg);
+ break;
+ case BD_TYPE2:
+ sqe = (struct hisi_sec_sqe *)sqe3;
+ if (usr && sqe->type2.tag != usr)
+ return 0;
+ parse_cipher_bd2(q, sqe, cipher_msg);
+ break;
+ case BD_TYPE1:
+ sqe = (struct hisi_sec_sqe *)sqe3;
+ if (usr && sqe->type1.tag != usr)
+ return 0;
+ parse_cipher_bd1(q, sqe, cipher_msg);
+ break;
+ default:
WD_ERR("SEC BD Type error\n");
cipher_msg->result = WD_IN_EPARA;
+ break;
}
#ifdef DEBUG_LOG
- sec_dump_bd((unsigned char *)sqe, SQE_BYTES_NUMS);
+ if (sqe3->type == BD_TYPE3)
+ sec_dump_bd((unsigned char *)sqe3, SQE_BYTES_NUMS);
+ else
+ sec_dump_bd((unsigned char *)sqe, SQE_BYTES_NUMS);
#endif
return 1;
diff --git a/v1/wd_cipher.c b/v1/wd_cipher.c
index 1b50089..624adb0 100644
--- a/v1/wd_cipher.c
+++ b/v1/wd_cipher.c
@@ -69,7 +69,7 @@ static void del_ctx_key(struct wcrypto_cipher_ctx *ctx)
if (ctx->key) {
if (ctx->setup.data_fmt == WD_FLAT_BUF)
memset(ctx->key, 0, MAX_CIPHER_KEY_SIZE);
- else if (ctx->setup.data_fmt == WD_SGL_BUF)
+ else if (ctx->setup.data_fmt == WD_SGL_BUF && ctx->key_bytes)
wd_sgl_cp_from_pbuf(ctx->key, 0, tmp, MAX_CIPHER_KEY_SIZE);
}
@@ -361,6 +361,8 @@ static int cipher_requests_init(struct wcrypto_cipher_msg **req,
req[i]->in_bytes = op[i]->in_bytes;
req[i]->out = op[i]->out;
req[i]->out_bytes = op[i]->out_bytes;
+
+ /* In user self-define data case, need update key from udata */
udata = op[i]->priv;
if (udata && udata->key) {
req[i]->key = udata->key;
--
2.25.1