122 lines
3.6 KiB
Diff
122 lines
3.6 KiB
Diff
From d99d0e2683c6507304f72905b773623968c0962a Mon Sep 17 00:00:00 2001
|
|
From: Wenkai Lin <linwenkai6@hisilicon.com>
|
|
Date: Fri, 11 Oct 2024 11:29:45 +0800
|
|
Subject: [PATCH 29/39] uadk: fix for cipher update iv
|
|
|
|
The cipher iv is incorrectly updated, as a result, the uadk
|
|
fails to encrypt data. The CFB, OFB, and CTR mode are modified
|
|
according to the algorithm protocol.
|
|
|
|
Signed-off-by: Wenkai Lin <linwenkai6@hisilicon.com>
|
|
Signed-off-by: Qi Tao <taoqi10@huawei.com>
|
|
---
|
|
drv/hisi_sec.c | 40 ++++++++++++++++++++++++++++------------
|
|
wd_cipher.c | 6 ++++++
|
|
2 files changed, 34 insertions(+), 12 deletions(-)
|
|
|
|
diff --git a/drv/hisi_sec.c b/drv/hisi_sec.c
|
|
index 9d69831..bdde39f 100644
|
|
--- a/drv/hisi_sec.c
|
|
+++ b/drv/hisi_sec.c
|
|
@@ -733,11 +733,14 @@ static void ctr_iv_inc(__u8 *counter, __u32 len)
|
|
|
|
static void update_iv(struct wd_cipher_msg *msg)
|
|
{
|
|
+ __u8 i;
|
|
+
|
|
switch (msg->mode) {
|
|
case WD_CIPHER_CBC:
|
|
case WD_CIPHER_CBC_CS1:
|
|
case WD_CIPHER_CBC_CS2:
|
|
case WD_CIPHER_CBC_CS3:
|
|
+ case WD_CIPHER_CFB:
|
|
if (msg->op_type == WD_CIPHER_ENCRYPTION &&
|
|
msg->out_bytes >= msg->iv_bytes)
|
|
memcpy(msg->iv, msg->out + msg->out_bytes -
|
|
@@ -748,14 +751,15 @@ static void update_iv(struct wd_cipher_msg *msg)
|
|
msg->iv_bytes, msg->iv_bytes);
|
|
break;
|
|
case WD_CIPHER_OFB:
|
|
- case WD_CIPHER_CFB:
|
|
- if (msg->out_bytes >= msg->iv_bytes)
|
|
- memcpy(msg->iv, msg->out + msg->out_bytes -
|
|
- msg->iv_bytes, msg->iv_bytes);
|
|
+ if (msg->in_bytes < msg->iv_bytes)
|
|
+ break;
|
|
+ /* The iv_bytes has been checked and it is not greater than AES_BLOCK_SIZE. */
|
|
+ for (i = 0; i < msg->iv_bytes; i++)
|
|
+ msg->iv[i] = *((__u8 *)msg->in + msg->in_bytes - msg->iv_bytes + i) ^
|
|
+ *((__u8 *)msg->out + msg->out_bytes - msg->iv_bytes + i);
|
|
break;
|
|
case WD_CIPHER_CTR:
|
|
- ctr_iv_inc(msg->iv, msg->iv_bytes >>
|
|
- CTR_MODE_LEN_SHIFT);
|
|
+ ctr_iv_inc(msg->iv, msg->in_bytes >> CTR_MODE_LEN_SHIFT);
|
|
break;
|
|
default:
|
|
break;
|
|
@@ -764,8 +768,16 @@ static void update_iv(struct wd_cipher_msg *msg)
|
|
|
|
static void update_iv_sgl(struct wd_cipher_msg *msg)
|
|
{
|
|
+ __u8 out[AES_BLOCK_SIZE] = {0};
|
|
+ __u8 in[AES_BLOCK_SIZE] = {0};
|
|
+ __u8 i;
|
|
+
|
|
switch (msg->mode) {
|
|
case WD_CIPHER_CBC:
|
|
+ case WD_CIPHER_CBC_CS1:
|
|
+ case WD_CIPHER_CBC_CS2:
|
|
+ case WD_CIPHER_CBC_CS3:
|
|
+ case WD_CIPHER_CFB:
|
|
if (msg->op_type == WD_CIPHER_ENCRYPTION &&
|
|
msg->out_bytes >= msg->iv_bytes)
|
|
hisi_qm_sgl_copy(msg->iv, msg->out,
|
|
@@ -780,16 +792,20 @@ static void update_iv_sgl(struct wd_cipher_msg *msg)
|
|
|
|
break;
|
|
case WD_CIPHER_OFB:
|
|
- case WD_CIPHER_CFB:
|
|
- if (msg->out_bytes >= msg->iv_bytes)
|
|
- hisi_qm_sgl_copy(msg->iv, msg->out,
|
|
+ /* The iv_bytes has been checked and it is not greater than AES_BLOCK_SIZE. */
|
|
+ if (msg->in_bytes >= msg->iv_bytes) {
|
|
+ hisi_qm_sgl_copy(in, msg->in,
|
|
+ msg->in_bytes - msg->iv_bytes,
|
|
+ msg->iv_bytes, COPY_SGL_TO_PBUFF);
|
|
+ hisi_qm_sgl_copy(out, msg->out,
|
|
msg->out_bytes - msg->iv_bytes,
|
|
msg->iv_bytes, COPY_SGL_TO_PBUFF);
|
|
-
|
|
+ for (i = 0; i < msg->iv_bytes; i++)
|
|
+ msg->iv[i] = *(in + i) ^ *(out + i);
|
|
+ }
|
|
break;
|
|
case WD_CIPHER_CTR:
|
|
- ctr_iv_inc(msg->iv, msg->iv_bytes >>
|
|
- CTR_MODE_LEN_SHIFT);
|
|
+ ctr_iv_inc(msg->iv, msg->in_bytes >> CTR_MODE_LEN_SHIFT);
|
|
break;
|
|
default:
|
|
break;
|
|
diff --git a/wd_cipher.c b/wd_cipher.c
|
|
index ec6fb15..0e5de25 100644
|
|
--- a/wd_cipher.c
|
|
+++ b/wd_cipher.c
|
|
@@ -646,6 +646,12 @@ static int wd_cipher_check_params(handle_t h_sess,
|
|
return -WD_EINVAL;
|
|
}
|
|
|
|
+ if (unlikely(req->in_bytes != req->out_bytes)) {
|
|
+ WD_ERR("cipher set out_bytes is error, size = %u\n",
|
|
+ req->out_bytes);
|
|
+ return -WD_EINVAL;
|
|
+ }
|
|
+
|
|
ret = cipher_in_len_check(h_sess, req);
|
|
if (unlikely(ret))
|
|
return ret;
|
|
--
|
|
2.25.1
|
|
|