244 lines
6.6 KiB
Diff
244 lines
6.6 KiB
Diff
From 5d48e854f755213bb145032dfa6b18583a5ced4e Mon Sep 17 00:00:00 2001
|
|
From: Zhiqi Song <songzhiqi1@huawei.com>
|
|
Date: Tue, 19 Sep 2023 15:49:10 +0800
|
|
Subject: [PATCH 29/38] uadk/v1/cipher: support aes-cbc cts mode
|
|
|
|
Support AES-CBC CTS(ciphertext stealing) mode in v1,
|
|
including CBC-CS1, CBC-CS2, CBC-CS3.
|
|
|
|
Signed-off-by: Zhiqi Song <songzhiqi1@huawei.com>
|
|
---
|
|
v1/drv/hisi_sec_udrv.c | 100 ++++++++++++++++++++++++++++++++++++++---
|
|
v1/drv/hisi_sec_udrv.h | 6 +++
|
|
v1/wd_cipher.c | 3 ++
|
|
v1/wd_cipher.h | 4 ++
|
|
4 files changed, 106 insertions(+), 7 deletions(-)
|
|
|
|
diff --git a/v1/drv/hisi_sec_udrv.c b/v1/drv/hisi_sec_udrv.c
|
|
index 1dd9f37..832d6a3 100644
|
|
--- a/v1/drv/hisi_sec_udrv.c
|
|
+++ b/v1/drv/hisi_sec_udrv.c
|
|
@@ -179,6 +179,18 @@ static int fill_cipher_bd2_mode(struct wcrypto_cipher_msg *msg,
|
|
case WCRYPTO_CIPHER_XTS:
|
|
sqe->type2.c_mode = C_MODE_XTS;
|
|
break;
|
|
+ case WCRYPTO_CIPHER_CBC_CS1:
|
|
+ sqe->type2.c_mode = C_MODE_CBC_CS;
|
|
+ sqe->type2.c_width = C_WIDTH_CS1;
|
|
+ break;
|
|
+ case WCRYPTO_CIPHER_CBC_CS2:
|
|
+ sqe->type2.c_mode = C_MODE_CBC_CS;
|
|
+ sqe->type2.c_width = C_WIDTH_CS2;
|
|
+ break;
|
|
+ case WCRYPTO_CIPHER_CBC_CS3:
|
|
+ sqe->type2.c_mode = C_MODE_CBC_CS;
|
|
+ sqe->type2.c_width = C_WIDTH_CS3;
|
|
+ break;
|
|
default:
|
|
WD_ERR("Invalid cipher alg type!\n");
|
|
ret = -WD_EINVAL;
|
|
@@ -253,6 +265,9 @@ static void update_iv(struct wcrypto_cipher_msg *msg)
|
|
{
|
|
switch (msg->mode) {
|
|
case WCRYPTO_CIPHER_CBC:
|
|
+ case WCRYPTO_CIPHER_CBC_CS1:
|
|
+ case WCRYPTO_CIPHER_CBC_CS2:
|
|
+ case WCRYPTO_CIPHER_CBC_CS3:
|
|
if (msg->op_type == WCRYPTO_CIPHER_ENCRYPTION &&
|
|
msg->out_bytes >= msg->iv_bytes)
|
|
update_iv_from_res(msg->iv, msg->out,
|
|
@@ -360,6 +375,18 @@ static int fill_cipher_bd1_mode(struct wcrypto_cipher_msg *msg,
|
|
case WCRYPTO_CIPHER_XTS:
|
|
sqe->type1.c_mode = C_MODE_XTS;
|
|
break;
|
|
+ case WCRYPTO_CIPHER_CBC_CS1:
|
|
+ sqe->type1.c_mode = C_MODE_CBC_CS;
|
|
+ sqe->type1.c_width = C_WIDTH_CS1;
|
|
+ break;
|
|
+ case WCRYPTO_CIPHER_CBC_CS2:
|
|
+ sqe->type1.c_mode = C_MODE_CBC_CS;
|
|
+ sqe->type1.c_width = C_WIDTH_CS2;
|
|
+ break;
|
|
+ case WCRYPTO_CIPHER_CBC_CS3:
|
|
+ sqe->type1.c_mode = C_MODE_CBC_CS;
|
|
+ sqe->type1.c_width = C_WIDTH_CS3;
|
|
+ break;
|
|
default:
|
|
WD_ERR("Invalid cipher alg type for bd1\n");
|
|
return -WD_EINVAL;
|
|
@@ -587,8 +614,32 @@ map_in_error:
|
|
return ret;
|
|
}
|
|
|
|
+static int aes_sm4_param_check(struct wcrypto_cipher_msg *msg)
|
|
+{
|
|
+ if (msg->alg == WCRYPTO_CIPHER_AES &&
|
|
+ msg->in_bytes <= CBC_AES_BLOCK_SIZE &&
|
|
+ (msg->mode == WCRYPTO_CIPHER_CBC_CS1 ||
|
|
+ msg->mode == WCRYPTO_CIPHER_CBC_CS2 ||
|
|
+ msg->mode == WCRYPTO_CIPHER_CBC_CS3)) {
|
|
+ WD_ERR("failed to check input bytes of AES CTS, size = %u\n",
|
|
+ msg->in_bytes);
|
|
+ return -WD_EINVAL;
|
|
+ }
|
|
+
|
|
+ if ((msg->in_bytes & (CBC_AES_BLOCK_SIZE - 1)) &&
|
|
+ (msg->mode == WCRYPTO_CIPHER_CBC ||
|
|
+ msg->mode == WCRYPTO_CIPHER_ECB)) {
|
|
+ WD_ERR("input AES or SM4 cipher parameter is error!\n");
|
|
+ return -WD_EINVAL;
|
|
+ }
|
|
+
|
|
+ return WD_SUCCESS;
|
|
+}
|
|
+
|
|
static int cipher_param_check(struct wcrypto_cipher_msg *msg)
|
|
{
|
|
+ int ret;
|
|
+
|
|
if (unlikely(msg->in_bytes > MAX_CIPHER_LENGTH ||
|
|
!msg->in_bytes)) {
|
|
WD_ERR("input cipher len is too large!\n");
|
|
@@ -616,10 +667,9 @@ static int cipher_param_check(struct wcrypto_cipher_msg *msg)
|
|
}
|
|
|
|
if (msg->alg == WCRYPTO_CIPHER_AES || msg->alg == WCRYPTO_CIPHER_SM4) {
|
|
- if (unlikely(msg->in_bytes & (CBC_AES_BLOCK_SIZE - 1))) {
|
|
- WD_ERR("input AES or SM4 cipher parameter is error!\n");
|
|
- return -WD_EINVAL;
|
|
- }
|
|
+ ret = aes_sm4_param_check(msg);
|
|
+ if (ret)
|
|
+ return ret;
|
|
}
|
|
|
|
return WD_SUCCESS;
|
|
@@ -793,6 +843,18 @@ static int fill_cipher_bd3_mode(struct wcrypto_cipher_msg *msg,
|
|
case WCRYPTO_CIPHER_CFB:
|
|
sqe->c_mode = C_MODE_CFB;
|
|
break;
|
|
+ case WCRYPTO_CIPHER_CBC_CS1:
|
|
+ sqe->c_mode = C_MODE_CBC_CS;
|
|
+ sqe->c_width = C_WIDTH_CS1;
|
|
+ break;
|
|
+ case WCRYPTO_CIPHER_CBC_CS2:
|
|
+ sqe->c_mode = C_MODE_CBC_CS;
|
|
+ sqe->c_width = C_WIDTH_CS2;
|
|
+ break;
|
|
+ case WCRYPTO_CIPHER_CBC_CS3:
|
|
+ sqe->c_mode = C_MODE_CBC_CS;
|
|
+ sqe->c_width = C_WIDTH_CS3;
|
|
+ break;
|
|
default:
|
|
WD_ERR("Invalid cipher alg type!\n");
|
|
ret = -WD_EINVAL;
|
|
@@ -843,7 +905,7 @@ static int fill_cipher_bd3(struct wd_queue *q, struct hisi_sec_bd3_sqe *sqe,
|
|
return ret;
|
|
}
|
|
|
|
-static int sm4_aes_mode_check(int mode)
|
|
+static int sm4_mode_check(int mode)
|
|
{
|
|
switch (mode) {
|
|
case WCRYPTO_CIPHER_ECB:
|
|
@@ -860,6 +922,26 @@ static int sm4_aes_mode_check(int mode)
|
|
}
|
|
}
|
|
|
|
+static int aes_mode_check(int mode)
|
|
+{
|
|
+ switch (mode) {
|
|
+ case WCRYPTO_CIPHER_ECB:
|
|
+ case WCRYPTO_CIPHER_CBC:
|
|
+ case WCRYPTO_CIPHER_OFB:
|
|
+ case WCRYPTO_CIPHER_CFB:
|
|
+ case WCRYPTO_CIPHER_CTR:
|
|
+ case WCRYPTO_CIPHER_XTS:
|
|
+ case WCRYPTO_CIPHER_CCM:
|
|
+ case WCRYPTO_CIPHER_GCM:
|
|
+ case WCRYPTO_CIPHER_CBC_CS1:
|
|
+ case WCRYPTO_CIPHER_CBC_CS2:
|
|
+ case WCRYPTO_CIPHER_CBC_CS3:
|
|
+ return WD_SUCCESS;
|
|
+ default:
|
|
+ return -WD_EINVAL;
|
|
+ }
|
|
+}
|
|
+
|
|
static int triple_des_mode_check(int mode)
|
|
{
|
|
switch (mode) {
|
|
@@ -878,8 +960,10 @@ static int cipher_comb_param_check(struct wcrypto_cipher_msg *msg)
|
|
|
|
switch (msg->alg) {
|
|
case WCRYPTO_CIPHER_SM4:
|
|
+ ret = sm4_mode_check(msg->mode);
|
|
+ break;
|
|
case WCRYPTO_CIPHER_AES:
|
|
- ret = sm4_aes_mode_check(msg->mode);
|
|
+ ret = aes_mode_check(msg->mode);
|
|
break;
|
|
case WCRYPTO_CIPHER_DES:
|
|
case WCRYPTO_CIPHER_3DES:
|
|
@@ -2228,8 +2312,10 @@ static int aead_comb_param_check(struct wcrypto_aead_msg *msg)
|
|
|
|
switch (msg->calg) {
|
|
case WCRYPTO_CIPHER_SM4:
|
|
+ ret = sm4_mode_check(msg->cmode);
|
|
+ break;
|
|
case WCRYPTO_CIPHER_AES:
|
|
- ret = sm4_aes_mode_check(msg->cmode);
|
|
+ ret = aes_mode_check(msg->cmode);
|
|
break;
|
|
default:
|
|
return -WD_EINVAL;
|
|
diff --git a/v1/drv/hisi_sec_udrv.h b/v1/drv/hisi_sec_udrv.h
|
|
index af96a76..9db4af8 100644
|
|
--- a/v1/drv/hisi_sec_udrv.h
|
|
+++ b/v1/drv/hisi_sec_udrv.h
|
|
@@ -461,6 +461,12 @@ enum C_MODE {
|
|
C_MODE_CBC_CS = 0x9
|
|
};
|
|
|
|
+enum SEC_C_WIDTH {
|
|
+ C_WIDTH_CS1 = 0x1,
|
|
+ C_WIDTH_CS2 = 0x2,
|
|
+ C_WIDTH_CS3 = 0x3,
|
|
+};
|
|
+
|
|
enum CKEY_LEN {
|
|
CKEY_LEN_128_BIT = 0x0,
|
|
CKEY_LEN_192_BIT = 0x1,
|
|
diff --git a/v1/wd_cipher.c b/v1/wd_cipher.c
|
|
index 6c0ef69..1b50089 100644
|
|
--- a/v1/wd_cipher.c
|
|
+++ b/v1/wd_cipher.c
|
|
@@ -83,6 +83,9 @@ static __u32 get_iv_block_size(int alg, int mode)
|
|
|
|
switch (mode) {
|
|
case WCRYPTO_CIPHER_CBC:
|
|
+ case WCRYPTO_CIPHER_CBC_CS1:
|
|
+ case WCRYPTO_CIPHER_CBC_CS2:
|
|
+ case WCRYPTO_CIPHER_CBC_CS3:
|
|
case WCRYPTO_CIPHER_OFB:
|
|
if (alg == WCRYPTO_CIPHER_3DES ||
|
|
alg == WCRYPTO_CIPHER_DES)
|
|
diff --git a/v1/wd_cipher.h b/v1/wd_cipher.h
|
|
index 591a590..dafd8a4 100644
|
|
--- a/v1/wd_cipher.h
|
|
+++ b/v1/wd_cipher.h
|
|
@@ -47,6 +47,10 @@ enum wcrypto_cipher_mode {
|
|
WCRYPTO_CIPHER_CFB,
|
|
WCRYPTO_CIPHER_CCM,
|
|
WCRYPTO_CIPHER_GCM,
|
|
+ WCRYPTO_CIPHER_CBC_CS1,
|
|
+ WCRYPTO_CIPHER_CBC_CS2,
|
|
+ WCRYPTO_CIPHER_CBC_CS3,
|
|
+ WCRYPTO_CIPHER_MODE_MAX,
|
|
};
|
|
|
|
/**
|
|
--
|
|
2.25.1
|
|
|