From c1e75c6c27ea54dec9e31223af49e33aa0d38490 Mon Sep 17 00:00:00 2001 From: Kai Ye 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 --- 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