From: Wenkai Lin linwenkai6@hisilicon.com
In long hash scene, the first and middle hash task should ensure full mac len out buffer, so we add out_bytes check here. But out_bytes of the last hash task should be actual length.
mac length should also be set for hardware mac check.
Signed-off-by: Wenkai Lin linwenkai6@hisilicon.com --- v1/drv/hisi_sec_udrv.c | 4 ++++ v1/wd_digest.c | 34 ++++++++++++++++++++++++++-------- v1/wd_digest.h | 12 ++++++++++++ 3 files changed, 42 insertions(+), 8 deletions(-)
diff --git a/v1/drv/hisi_sec_udrv.c b/v1/drv/hisi_sec_udrv.c index ecb2ac2..fb6c933 100644 --- a/v1/drv/hisi_sec_udrv.c +++ b/v1/drv/hisi_sec_udrv.c @@ -1178,11 +1178,13 @@ static void qm_fill_digest_long_bd(struct wcrypto_digest_msg *msg,
if (msg->has_next && (msg->iv_bytes == 0)) { /* LONG BD FIRST */ + sqe->type2.mac_len = 0x1; sqe->type2.ai_gen = AI_GEN_INNER; sqe->type2.a_pad = AUTHPAD_NOPAD; msg->iv_bytes = msg->out_bytes; } else if (msg->has_next && (msg->iv_bytes != 0)) { /* LONG BD MIDDLE */ + sqe->type2.mac_len = 0x1; sqe->type2.ai_gen = AI_GEN_IVIN_ADDR; sqe->type2.a_pad = AUTHPAD_NOPAD; sqe->type2.a_ivin_addr_h = sqe->type2.mac_addr_h; @@ -1508,11 +1510,13 @@ static void qm_fill_digest_long_bd3(struct wcrypto_digest_msg *msg, /* iv_bytes is multiplexed as a flag bit to determine whether it is LOGN BD FIRST */ if (msg->has_next && msg->iv_bytes == 0) { /* LONG BD FIRST */ + sqe->mac_len = 0x1; sqe->ai_gen = AI_GEN_INNER; sqe->stream_scene.auth_pad = AUTHPAD_NOPAD; msg->iv_bytes = msg->out_bytes; } else if (msg->has_next && msg->iv_bytes != 0) { /* LONG BD MIDDLE */ + sqe->mac_len = 0x1; sqe->ai_gen = AI_GEN_IVIN_ADDR; sqe->stream_scene.auth_pad = AUTHPAD_NOPAD; sqe->auth_key_iv.a_ivin_addr_h = sqe->mac_addr_h; diff --git a/v1/wd_digest.c b/v1/wd_digest.c index cb0d4d8..5057f49 100644 --- a/v1/wd_digest.c +++ b/v1/wd_digest.c @@ -54,6 +54,14 @@ static __u32 g_digest_mac_len[WCRYPTO_MAX_DIGEST_TYPE] = { WCRYPTO_DIGEST_SHA512_224_LEN, WCRYPTO_DIGEST_SHA512_256_LEN };
+static __u32 g_digest_mac_full_len[WCRYPTO_MAX_DIGEST_TYPE] = { + WCRYPTO_DIGEST_SM3_FULL_LEN, WCRYPTO_DIGEST_MD5_FULL_LEN, + WCRYPTO_DIGEST_SHA1_FULL_LEN, WCRYPTO_DIGEST_SHA256_FULL_LEN, + WCRYPTO_DIGEST_SHA224_FULL_LEN, WCRYPTO_DIGEST_SHA384_FULL_LEN, + WCRYPTO_DIGEST_SHA512_FULL_LEN, WCRYPTO_DIGEST_SHA512_224_FULL_LEN, + WCRYPTO_DIGEST_SHA512_256_FULL_LEN +}; + static void del_ctx_key(struct wcrypto_digest_ctx *ctx) { struct wd_mm_br *br = &(ctx->setup.br); @@ -330,20 +338,30 @@ static int param_check(struct wcrypto_digest_ctx *d_ctx, return -WD_EINVAL; }
- if (unlikely(num != 1 && d_opdata[i]->has_next)) { - WD_ERR("num > 1, wcrypto_burst_digest does not support stream mode!\n"); + if (unlikely(!d_opdata[i]->out_bytes)) { + WD_ERR("invalid: digest mac length is 0.\n"); return -WD_EINVAL; }
- if (unlikely(d_opdata[0]->has_next && d_opdata[0]->in_bytes % d_ctx->align_sz)) { - WD_ERR("digest stream mode must be %u-byte aligned!\n", d_ctx->align_sz); - return -WD_EINVAL; - } - if (d_opdata[i]->out_bytes == 0 || - d_opdata[i]->out_bytes > g_digest_mac_len[alg]) { + if (d_opdata[i]->has_next) { + if (unlikely(num != 1)) { + WD_ERR("num > 1, wcrypto_burst_digest does not support stream mode!\n"); + return -WD_EINVAL; + } + if (unlikely(d_opdata[i]->in_bytes % d_ctx->align_sz)) { + WD_ERR("digest stream mode must be %u-byte aligned!\n", d_ctx->align_sz); + return -WD_EINVAL; + } + if (unlikely(d_opdata[i]->out_bytes < g_digest_mac_full_len[alg])) { + WD_ERR("digest stream mode out buffer space is not enough!\n"); + return -WD_EINVAL; + } + } else { + if (unlikely(d_opdata[i]->out_bytes > g_digest_mac_len[alg])) { WD_ERR("failed to check digest mac length!\n"); return -WD_EINVAL; } + }
if (unlikely(tag && !tag[i])) { WD_ERR("tag[%u] is NULL!\n", i); diff --git a/v1/wd_digest.h b/v1/wd_digest.h index 6ad4c85..8f7ac2e 100644 --- a/v1/wd_digest.h +++ b/v1/wd_digest.h @@ -51,6 +51,18 @@ enum wd_digest_mac_len { WCRYPTO_DIGEST_SHA512_256_LEN = 32 };
+enum wcrypto_digest_mac_full_len { + WCRYPTO_DIGEST_SM3_FULL_LEN = 32, + WCRYPTO_DIGEST_MD5_FULL_LEN = 16, + WCRYPTO_DIGEST_SHA1_FULL_LEN = 20, + WCRYPTO_DIGEST_SHA256_FULL_LEN = 32, + WCRYPTO_DIGEST_SHA224_FULL_LEN = 32, + WCRYPTO_DIGEST_SHA384_FULL_LEN = 64, + WCRYPTO_DIGEST_SHA512_FULL_LEN = 64, + WCRYPTO_DIGEST_SHA512_224_FULL_LEN = 64, + WCRYPTO_DIGEST_SHA512_256_FULL_LEN = 64, +}; + enum wcrypto_digest_mode { WCRYPTO_DIGEST_NORMAL, WCRYPTO_DIGEST_HMAC,