Support AES-CBC CTS(ciphertext stealing) mode in v1,
including CBC-CS1, CBC-CS2, CBC-CS3.
Signed-off-by: Zhiqi Song <songzhiqi1(a)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 4d5ede5..f9cd8c0 100644
--- a/v1/drv/hisi_sec_udrv.c
+++ b/v1/drv/hisi_sec_udrv.c
@@ -174,6 +174,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;
@@ -248,6 +260,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,
@@ -355,6 +370,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;
@@ -582,8 +609,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");
@@ -611,10 +662,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;
@@ -788,6 +838,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;
@@ -838,7 +900,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:
@@ -855,6 +917,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) {
@@ -873,8 +955,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:
@@ -2125,8 +2209,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 9c0da47..054ab71 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 3d7d140..a53cf8f 100644
--- a/v1/wd_cipher.c
+++ b/v1/wd_cipher.c
@@ -82,6 +82,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.33.0