libwd/0001-uadk-digest-add-stream-mode-for-digest-sync.patch
Yang Shen bd84f97fbf libwd: backport for uadk from 2.3.21 to 2.3.24
Update some patch for uadk from mainline.
To get more infomation, please visit the homepage:
https://github.com/Linaro/uadk

Signed-off-by: Yang Shen <shenyang39@huawei.com>
2022-01-10 08:56:20 +00:00

214 lines
6.6 KiB
Diff

From c1e75c6c27ea54dec9e31223af49e33aa0d38490 Mon Sep 17 00:00:00 2001
From: Kai Ye <yekai13@huawei.com>
Date: Mon, 13 Dec 2021 18:55:32 +0800
Subject: [PATCH 01/28] uadk/digest - add stream mode for digest sync
Support the sec digest steam mode. Using the session to store
the stream BD state, using the iv_bytes to notify the BD state
from message. So one session only supports one stream. User
can use the has_next flag to indicate whether there is any
packet to be input.
Signed-off-by: Kai Ye <yekai13@huawei.com>
---
drv/hisi_sec.c | 50 ++++++++++++++++++++-----------------
include/drv/wd_digest_drv.h | 2 ++
wd_digest.c | 20 ++++++++++++---
3 files changed, 46 insertions(+), 26 deletions(-)
diff --git a/drv/hisi_sec.c b/drv/hisi_sec.c
index e43ded2..2fd23f3 100644
--- a/drv/hisi_sec.c
+++ b/drv/hisi_sec.c
@@ -73,6 +73,8 @@
/* The max BD data length is 16M-512B */
#define MAX_INPUT_DATA_LEN 0xFFFE00
#define MAX_CCM_AAD_LEN 65279
+#define SHA1_ALIGN_SZ 64
+#define SHA512_ALIGN_SZ 128
#define AUTHPAD_OFFSET 2
#define AUTHTYPE_OFFSET 6
@@ -1229,31 +1231,24 @@ static int fill_digest_bd2_alg(struct wd_digest_msg *msg,
static void qm_fill_digest_long_bd(struct wd_digest_msg *msg,
struct hisi_sec_sqe *sqe)
{
- struct wd_digest_tag *digest_tag = (void *)(uintptr_t)msg->usr_data;
__u64 total_bits;
if (msg->has_next && (msg->iv_bytes == 0)) {
/* LONG BD FIRST */
sqe->ai_apd_cs = AI_GEN_INNER;
sqe->ai_apd_cs |= AUTHPAD_NOPAD << AUTHPAD_OFFSET;
- msg->iv_bytes = msg->out_bytes;
} else if (msg->has_next && (msg->iv_bytes != 0)) {
/* LONG BD MIDDLE */
sqe->ai_apd_cs = AI_GEN_IVIN_ADDR;
sqe->ai_apd_cs |= AUTHPAD_NOPAD << AUTHPAD_OFFSET;
sqe->type2.a_ivin_addr = sqe->type2.mac_addr;
- msg->iv_bytes = msg->out_bytes;
} else if (!msg->has_next && (msg->iv_bytes != 0)) {
/* LONG BD END */
sqe->ai_apd_cs = AI_GEN_IVIN_ADDR;
sqe->ai_apd_cs |= AUTHPAD_PAD << AUTHPAD_OFFSET;
sqe->type2.a_ivin_addr = sqe->type2.mac_addr;
- total_bits = digest_tag->long_data_len * BYTE_BITS;
+ total_bits = msg->long_data_len * BYTE_BITS;
sqe->type2.long_a_data_len = total_bits;
- msg->iv_bytes = 0;
- } else {
- /* SHORT BD */
- msg->iv_bytes = 0;
}
}
@@ -1282,21 +1277,37 @@ static void parse_digest_bd2(struct hisi_sec_sqe *sqe, struct wd_digest_msg *rec
#endif
}
-static int digest_len_check(struct wd_digest_msg *msg, enum sec_bd_type type)
+static int digest_long_bd_check(struct wd_digest_msg *msg)
{
- if (type == BD_TYPE2 && msg->in_bytes == 0) {
- WD_ERR("digest bd2 not supports 0 packet!\n");
+ if (msg->alg >= WD_DIGEST_SHA512 && msg->in_bytes % SHA512_ALIGN_SZ)
+ return -WD_EINVAL;
+ else if (msg->in_bytes % SHA1_ALIGN_SZ)
+ return -WD_EINVAL;
+
+ return 0;
+}
+
+static int digest_len_check(struct wd_digest_msg *msg, enum sec_bd_type type)
+{
+ int ret;
+
+ /* End BD not need to check the input zero bytes */
+ if (unlikely(type == BD_TYPE2 && (!msg->has_next && msg->in_bytes == 0))) {
+ WD_ERR("kunpeng 920, digest mode not support 0 size!\n");
return -WD_EINVAL;
}
if (unlikely(msg->in_bytes > MAX_INPUT_DATA_LEN)) {
- WD_ERR("failed to check digest input data length!\n");
+ WD_ERR("input data length is too long, size:%u!\n", msg->in_bytes);
return -WD_EINVAL;
}
- if (unlikely(msg->out_bytes & WORD_ALIGNMENT_MASK)) {
- WD_ERR("failed to check digest out length!\n");
- return -WD_EINVAL;
+ if (msg->has_next) {
+ ret = digest_long_bd_check(msg);
+ if (ret) {
+ WD_ERR("input data isn't aligned, size:%u!\n", msg->in_bytes);
+ return -WD_EINVAL;
+ }
}
return 0;
@@ -1435,31 +1446,24 @@ static int fill_digest_bd3_alg(struct wd_digest_msg *msg,
static void qm_fill_digest_long_bd3(struct wd_digest_msg *msg,
struct hisi_sec_sqe3 *sqe)
{
- struct wd_digest_tag *digest_tag = (void *)(uintptr_t)msg->usr_data;
__u64 total_bits;
if (msg->has_next && (msg->iv_bytes == 0)) {
/* LONG BD FIRST */
sqe->auth_mac_key |= AI_GEN_INNER << SEC_AI_GEN_OFFSET_V3;
sqe->stream_scene.stream_auth_pad = AUTHPAD_NOPAD;
- msg->iv_bytes = msg->out_bytes;
} else if (msg->has_next && (msg->iv_bytes != 0)) {
/* LONG BD MIDDLE */
sqe->auth_mac_key |= AI_GEN_IVIN_ADDR << SEC_AI_GEN_OFFSET_V3;
sqe->stream_scene.stream_auth_pad = AUTHPAD_NOPAD;
sqe->auth_ivin.a_ivin_addr = sqe->mac_addr;
- msg->iv_bytes = msg->out_bytes;
} else if (!msg->has_next && (msg->iv_bytes != 0)) {
/* LONG BD END */
sqe->auth_mac_key |= AI_GEN_IVIN_ADDR << SEC_AI_GEN_OFFSET_V3;
sqe->stream_scene.stream_auth_pad = AUTHPAD_PAD;
sqe->auth_ivin.a_ivin_addr = sqe->mac_addr;
- total_bits = digest_tag->long_data_len * BYTE_BITS;
+ total_bits = msg->long_data_len * BYTE_BITS;
sqe->stream_scene.long_a_data_len = total_bits;
- msg->iv_bytes = 0;
- } else {
- /* SHORT BD */
- msg->iv_bytes = 0;
}
}
diff --git a/include/drv/wd_digest_drv.h b/include/drv/wd_digest_drv.h
index 8ccf291..ac3b028 100644
--- a/include/drv/wd_digest_drv.h
+++ b/include/drv/wd_digest_drv.h
@@ -45,6 +45,8 @@ struct wd_digest_msg {
__u8 *in;
/* output data pointer */
__u8 *out;
+ /* total of data for stream mode */
+ __u64 long_data_len;
};
struct wd_digest_driver {
diff --git a/wd_digest.c b/wd_digest.c
index 22aa98e..c110f7b 100644
--- a/wd_digest.c
+++ b/wd_digest.c
@@ -46,6 +46,10 @@ struct wd_digest_sess {
unsigned char key[MAX_HMAC_KEY_SIZE];
__u32 key_bytes;
void *sched_key;
+ /* Notify the BD state */
+ int state;
+ /* Total of data for stream mode */
+ __u64 long_data_len;
};
struct wd_env_config wd_digest_env_config;
@@ -286,11 +290,19 @@ static void fill_request_msg(struct wd_digest_msg *msg,
msg->in_bytes = req->in_bytes;
msg->out = req->out;
msg->out_bytes = req->out_bytes;
- msg->has_next = req->has_next;
msg->data_fmt = req->data_fmt;
+ msg->has_next = req->has_next;
+ sess->long_data_len += req->in_bytes;
+ msg->long_data_len = sess->long_data_len;
+ /* To store the stream bd state */
+ msg->iv_bytes = sess->state;
+ if (req->has_next == 0) {
+ sess->long_data_len = 0;
+ sess->state = 0;
+ }
}
-static int send_recv_sync(struct wd_ctx_internal *ctx,
+static int send_recv_sync(struct wd_ctx_internal *ctx, struct wd_digest_sess *dsess,
struct wd_digest_msg *msg)
{
__u64 recv_cnt = 0;
@@ -320,6 +332,8 @@ static int send_recv_sync(struct wd_ctx_internal *ctx,
goto out;
}
}
+ if (msg->has_next)
+ dsess->state = msg->out_bytes;
} while (ret < 0);
out:
@@ -353,7 +367,7 @@ int wd_do_digest_sync(handle_t h_sess, struct wd_digest_req *req)
return ret;
ctx = config->ctxs + idx;
- ret = send_recv_sync(ctx, &msg);
+ ret = send_recv_sync(ctx, dsess, &msg);
req->state = msg.result;
return ret;
--
2.31.1