Support sm4-xts GB standard.
Signed-off-by: Weili Qian qianweili@huawei.com --- v1/drv/hisi_sec_udrv.c | 11 ++++++++--- v1/wd_cipher.c | 3 ++- v1/wd_cipher.h | 5 +++++ 3 files changed, 15 insertions(+), 4 deletions(-)
diff --git a/v1/drv/hisi_sec_udrv.c b/v1/drv/hisi_sec_udrv.c index 1249cb6..9866c10 100644 --- a/v1/drv/hisi_sec_udrv.c +++ b/v1/drv/hisi_sec_udrv.c @@ -37,6 +37,7 @@
#define SEC_HW_TASK_DONE 1 #define SEC_HW_ICV_ERR 0x2 +#define SEC_SM4_XTS_GB_V3 0x1 #define SQE_BYTES_NUMS 128 #define CTR_MODE_LEN_SHIFT 4 #define WORD_BYTES 4 @@ -699,7 +700,7 @@ static int cipher_param_check(struct wcrypto_cipher_msg *msg) msg->mode == WCRYPTO_CIPHER_CTR) return WD_SUCCESS;
- if (msg->mode == WCRYPTO_CIPHER_XTS) { + if (msg->mode == WCRYPTO_CIPHER_XTS || msg->mode == WCRYPTO_CIPHER_XTS_GB) { if (unlikely(msg->in_bytes < CBC_AES_BLOCK_SIZE)) { WD_ERR("input cipher length is too small!\n"); return -WD_EINVAL; @@ -893,6 +894,10 @@ static int fill_cipher_bd3_mode(struct wcrypto_cipher_msg *msg, case WCRYPTO_CIPHER_XTS: sqe->c_mode = C_MODE_XTS; break; + case WCRYPTO_CIPHER_XTS_GB: + sqe->c_mode = C_MODE_XTS; + sqe->ctr_counter_mode = SEC_SM4_XTS_GB_V3; + break; case WCRYPTO_CIPHER_CFB: sqe->c_mode = C_MODE_CFB; break; @@ -910,8 +915,7 @@ static int fill_cipher_bd3_mode(struct wcrypto_cipher_msg *msg, break; default: WD_ERR("Invalid cipher alg type!\n"); - ret = -WD_EINVAL; - break; + return -WD_EINVAL; }
return ret; @@ -967,6 +971,7 @@ static int sm4_mode_check(int mode) case WCRYPTO_CIPHER_CFB: case WCRYPTO_CIPHER_CTR: case WCRYPTO_CIPHER_XTS: + case WCRYPTO_CIPHER_XTS_GB: case WCRYPTO_CIPHER_CCM: case WCRYPTO_CIPHER_GCM: return WD_SUCCESS; diff --git a/v1/wd_cipher.c b/v1/wd_cipher.c index 624adb0..3e6fb3d 100644 --- a/v1/wd_cipher.c +++ b/v1/wd_cipher.c @@ -92,6 +92,7 @@ static __u32 get_iv_block_size(int alg, int mode) iv_block_size = CBC_3DES_BLOCK_SIZE; break; case WCRYPTO_CIPHER_XTS: + case WCRYPTO_CIPHER_XTS_GB: case WCRYPTO_CIPHER_CFB: case WCRYPTO_CIPHER_CTR: break; @@ -273,7 +274,7 @@ static int cipher_key_len_check(struct wcrypto_cipher_ctx_setup *setup, __u16 key_len = length; int ret = WD_SUCCESS;
- if (setup->mode == WCRYPTO_CIPHER_XTS) { + if (setup->mode == WCRYPTO_CIPHER_XTS || setup->mode == WCRYPTO_CIPHER_XTS_GB) { if (length & XTS_MODE_KEY_LEN_MASK) { WD_ERR("invalid: unsupported XTS key length, length = %u!\n", length); return -WD_EINVAL; diff --git a/v1/wd_cipher.h b/v1/wd_cipher.h index dafd8a4..29f3ebe 100644 --- a/v1/wd_cipher.h +++ b/v1/wd_cipher.h @@ -38,6 +38,10 @@ enum wcrypto_cipher_alg { WCRYPTO_CIPHER_3DES, };
+/** + * WCRYPTO_CIPHER_XTS for xts specified by IEEE Std 1619-2007. + * WCRYPTO_CIPHER_XTS_GB for xts specified by GB/T 17964-2021. + */ enum wcrypto_cipher_mode { WCRYPTO_CIPHER_ECB, WCRYPTO_CIPHER_CBC, @@ -50,6 +54,7 @@ enum wcrypto_cipher_mode { WCRYPTO_CIPHER_CBC_CS1, WCRYPTO_CIPHER_CBC_CS2, WCRYPTO_CIPHER_CBC_CS3, + WCRYPTO_CIPHER_XTS_GB, WCRYPTO_CIPHER_MODE_MAX, };