Support sm4-xts GB standard.
Signed-off-by: Weili Qian qianweili@huawei.com --- drv/hisi_sec.c | 8 +++++++- include/wd_cipher.h | 3 +++ wd_alg.c | 3 +++ wd_cipher.c | 9 +++++---- 4 files changed, 18 insertions(+), 5 deletions(-)
diff --git a/drv/hisi_sec.c b/drv/hisi_sec.c index 507f48b..03e7037 100644 --- a/drv/hisi_sec.c +++ b/drv/hisi_sec.c @@ -45,6 +45,8 @@ #define SEC_CALG_OFFSET_V3 4 #define SEC_AKEY_OFFSET_V3 9 #define SEC_MAC_OFFSET_V3 4 +#define SEC_SM4_XTS_STD_V3 25 +#define SEC_SM4_XTS_GB_V3 0x1 #define SEC_AUTH_ALG_OFFSET_V3 15 #define SEC_SVA_PREFETCH_OFFSET 27 #define SEC_ENABLE_SVA_PREFETCH 0x1 @@ -927,7 +929,7 @@ static int cipher_len_check(struct wd_cipher_msg *msg) msg->mode == WD_CIPHER_CTR) return 0;
- if (msg->mode == WD_CIPHER_XTS) { + if (msg->mode == WD_CIPHER_XTS || msg->mode == WD_CIPHER_XTS_GB) { if (msg->in_bytes < AES_BLOCK_SIZE) { WD_ERR("input cipher length is too small, size = %u\n", msg->in_bytes); @@ -1217,6 +1219,10 @@ static int fill_cipher_bd3_mode(struct wd_cipher_msg *msg, case WD_CIPHER_XTS: c_mode = C_MODE_XTS; break; + case WD_CIPHER_XTS_GB: + c_mode = C_MODE_XTS; + sqe->auth_mac_key |= (__u32)(SEC_SM4_XTS_GB_V3 << SEC_SM4_XTS_STD_V3); + break; case WD_CIPHER_CFB: c_mode = C_MODE_CFB; break; diff --git a/include/wd_cipher.h b/include/wd_cipher.h index 8f043fd..7e63402 100644 --- a/include/wd_cipher.h +++ b/include/wd_cipher.h @@ -50,6 +50,8 @@ enum wd_cipher_alg {
/** * wd_cipher_mode - Algorithm mode of cipher + * WD_CIPHER_XTS for xts specified by IEEE Std 1619-2007. + * WD_CIPHER_XTS_GB for xts specified by GB/T 17964-2021. */ enum wd_cipher_mode { WD_CIPHER_ECB, @@ -63,6 +65,7 @@ enum wd_cipher_mode { WD_CIPHER_CBC_CS3, WD_CIPHER_CCM, WD_CIPHER_GCM, + WD_CIPHER_XTS_GB, WD_CIPHER_MODE_TYPE_MAX, };
diff --git a/wd_alg.c b/wd_alg.c index be38e52..8d88316 100644 --- a/wd_alg.c +++ b/wd_alg.c @@ -213,6 +213,9 @@ bool wd_drv_alg_support(const char *alg_name, struct wd_alg_list *head = &alg_list_head; struct wd_alg_list *pnext = head->next;
+ if (!alg_name) + return false; + while (pnext) { if (!strcmp(alg_name, pnext->alg_name) && !strcmp(drv->drv_name, pnext->drv_name)) { diff --git a/wd_cipher.c b/wd_cipher.c index 2eaa77b..58d34f7 100644 --- a/wd_cipher.c +++ b/wd_cipher.c @@ -46,7 +46,8 @@ static const unsigned char des_weak_keys[DES_WEAK_KEY_NUM][DES_KEY_SIZE] = {
static char *wd_cipher_alg_name[WD_CIPHER_ALG_TYPE_MAX][WD_CIPHER_MODE_TYPE_MAX] = { {"ecb(sm4)", "cbc(sm4)", "ctr(sm4)", "xts(sm4)", "ofb(sm4)", - "cfb(sm4)", "cbc-cs1(sm4)", "cbc-cs2(sm4)", "cbc-cs3(sm4)"}, + "cfb(sm4)", "cbc-cs1(sm4)", "cbc-cs2(sm4)", "cbc-cs3(sm4)", + "", "", "xts(sm4)"}, {"ecb(aes)", "cbc(aes)", "ctr(aes)", "xts(aes)", "ofb(aes)", "cfb(aes)", "cbc-cs1(aes)", "cbc-cs2(aes)", "cbc-cs3(aes)"}, {"ecb(des)", "cbc(des)",}, @@ -145,7 +146,7 @@ static int cipher_key_len_check(struct wd_cipher_sess *sess, __u32 length) __u32 key_len = length; int ret = 0;
- if (sess->mode == WD_CIPHER_XTS) { + if (sess->mode == WD_CIPHER_XTS || sess->mode == WD_CIPHER_XTS_GB) { if (length & XTS_MODE_KEY_LEN_MASK) { WD_ERR("invalid: unsupported XTS key length, length = %u!\n", length); return -WD_EINVAL; @@ -250,13 +251,13 @@ handle_t wd_cipher_alloc_sess(struct wd_cipher_sess_setup *setup) }
sess->alg_name = wd_cipher_alg_name[setup->alg][setup->mode]; - sess->alg = setup->alg; - sess->mode = setup->mode; ret = wd_drv_alg_support(sess->alg_name, wd_cipher_setting.driver); if (!ret) { WD_ERR("failed to support this algorithm: %s!\n", sess->alg_name); goto err_sess; } + sess->alg = setup->alg; + sess->mode = setup->mode;
/* Some simple scheduler don't need scheduling parameters */ sess->sched_key = (void *)wd_cipher_setting.sched.sched_init(