diff --git a/0039-uadk-cipher-support-sm4-xts-GB-standard.patch b/0039-uadk-cipher-support-sm4-xts-GB-standard.patch new file mode 100644 index 0000000..0ba6f69 --- /dev/null +++ b/0039-uadk-cipher-support-sm4-xts-GB-standard.patch @@ -0,0 +1,125 @@ +From 083fb5b4ad2e4deeea7bc35603b45e834aeac3d8 Mon Sep 17 00:00:00 2001 +From: Weili Qian +Date: Thu, 26 Oct 2023 16:17:42 +0800 +Subject: [PATCH 39/42] uadk/cipher: support sm4-xts GB standard. + +Support sm4-xts GB standard. + +Signed-off-by: Weili Qian +--- + 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( +-- +2.25.1 + diff --git a/0040-uadk-v1-cipher-support-sm4-xts-GB-standard.patch b/0040-uadk-v1-cipher-support-sm4-xts-GB-standard.patch new file mode 100644 index 0000000..675426a --- /dev/null +++ b/0040-uadk-v1-cipher-support-sm4-xts-GB-standard.patch @@ -0,0 +1,111 @@ +From 54119965db820614c5d2032d126ad6b28f8bef5e Mon Sep 17 00:00:00 2001 +From: Weili Qian +Date: Thu, 26 Oct 2023 16:17:48 +0800 +Subject: [PATCH 40/42] uadk/v1/cipher: support sm4-xts GB standard + +Support sm4-xts GB standard. + +Signed-off-by: Weili Qian +--- + 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, + }; + +-- +2.25.1 + diff --git a/0041-uadk-v1-digest-support-new-AES-mode-algs.patch b/0041-uadk-v1-digest-support-new-AES-mode-algs.patch new file mode 100644 index 0000000..3abf6ba --- /dev/null +++ b/0041-uadk-v1-digest-support-new-AES-mode-algs.patch @@ -0,0 +1,458 @@ +From d0499781ec60e553adef8a3275bcf321abd25d77 Mon Sep 17 00:00:00 2001 +From: Weili Qian +Date: Thu, 26 Oct 2023 16:17:53 +0800 +Subject: [PATCH 41/42] uadk/v1/digest: support new AES mode algs + +Supports some new auth algs: +AES-CMAC,AES-GMAC,AES_XCBC_MAC_96,AES-CBC_PRF_128. + +Signed-off-by: Weili Qian +--- + v1/drv/hisi_sec_udrv.c | 135 ++++++++++++++++++++++++++++++----------- + v1/wd_digest.c | 69 +++++++++++++++++++-- + v1/wd_digest.h | 24 ++++++-- + 3 files changed, 182 insertions(+), 46 deletions(-) + +diff --git a/v1/drv/hisi_sec_udrv.c b/v1/drv/hisi_sec_udrv.c +index 9866c10..02a63c2 100644 +--- a/v1/drv/hisi_sec_udrv.c ++++ b/v1/drv/hisi_sec_udrv.c +@@ -54,6 +54,7 @@ + #define CBC_AES_BLOCK_SIZE 16 + #define AEAD_IV_MAX_BYTES 64 + #define MAX_CCM_AAD_LEN 65279 ++#define SEC_GMAC_IV_LEN 16 + + static int g_digest_a_alg[WCRYPTO_MAX_DIGEST_TYPE] = { + A_ALG_SM3, A_ALG_MD5, A_ALG_SHA1, A_ALG_SHA256, A_ALG_SHA224, +@@ -62,7 +63,9 @@ static int g_digest_a_alg[WCRYPTO_MAX_DIGEST_TYPE] = { + static int g_hmac_a_alg[WCRYPTO_MAX_DIGEST_TYPE] = { + A_ALG_HMAC_SM3, A_ALG_HMAC_MD5, A_ALG_HMAC_SHA1, + A_ALG_HMAC_SHA256, A_ALG_HMAC_SHA224, A_ALG_HMAC_SHA384, +- A_ALG_HMAC_SHA512, A_ALG_HMAC_SHA512_224, A_ALG_HMAC_SHA512_256 ++ A_ALG_HMAC_SHA512, A_ALG_HMAC_SHA512_224, A_ALG_HMAC_SHA512_256, ++ A_ALG_AES_XCBC_MAC_96, A_ALG_AES_XCBC_PRF_128, A_ALG_AES_CMAC, ++ A_ALG_AES_GMAC + }; + + static void parse_aead_bd2(struct wd_queue *q, struct hisi_sec_sqe *sqe, +@@ -1128,13 +1131,19 @@ int qm_fill_cipher_bd3_sqe(void *message, struct qm_queue_info *info, __u16 i) + return ret; + } + +-static int digest_param_check(struct wcrypto_digest_msg *msg) ++static int digest_param_check(struct wcrypto_digest_msg *msg, __u8 bd_type) + { + if (unlikely(msg->alg >= WCRYPTO_MAX_DIGEST_TYPE)) { + WD_ERR("invalid digest type!\n"); + return -WD_EINVAL; + } + ++ if (msg->alg >= WCRYPTO_AES_XCBC_MAC_96 && ++ (bd_type == BD_TYPE1 || bd_type == BD_TYPE2)) { ++ WD_ERR("invalid: BD tpye does not support the alg %d!\n", msg->alg); ++ return -WD_EINVAL; ++ } ++ + if (unlikely(msg->in_bytes > MAX_CIPHER_LENGTH)) { + WD_ERR("invalid digest in_bytes!\n"); + return -WD_EINVAL; +@@ -1153,12 +1162,12 @@ static int fill_digest_bd2_alg(struct wcrypto_digest_msg *msg, + { + int ret; + +- ret = digest_param_check(msg); ++ ret = digest_param_check(msg, BD_TYPE2); + if (unlikely(ret)) + return ret; + + if(unlikely(msg->in_bytes == 0)) { +- if ((msg->has_next && !msg->iv_bytes) || (msg->has_next && msg->iv_bytes)) { ++ if (msg->has_next) { + /* Long hash first and middle BD */ + WD_ERR("invalid: digest bd2 not supports 0 packet in first bd and middle bd!\n"); + return -WD_EINVAL; +@@ -1223,7 +1232,7 @@ static int fill_digest_bd1_alg(struct wcrypto_digest_msg *msg, + { + int ret; + +- ret = digest_param_check(msg); ++ ret = digest_param_check(msg, BD_TYPE1); + if (unlikely(ret)) + return ret; + +@@ -1513,12 +1522,29 @@ int qm_fill_digest_sqe(void *message, struct qm_queue_info *info, __u16 i) + return WD_SUCCESS; + } + +-static void qm_fill_digest_long_bd3(struct wcrypto_digest_msg *msg, ++static int qm_fill_digest_long_bd3(struct wcrypto_digest_msg *msg, + struct hisi_sec_bd3_sqe *sqe) + { + struct wcrypto_digest_tag *digest_tag = (void *)(uintptr_t)msg->usr_data; + __u64 total_bits = 0; + ++ if (msg->alg == WCRYPTO_AES_XCBC_MAC_96 || ++ msg->alg == WCRYPTO_AES_XCBC_PRF_128 || ++ msg->alg == WCRYPTO_AES_CMAC || ++ msg->alg == WCRYPTO_AES_GMAC) { ++ if (msg->has_next) { ++ WD_ERR("aes alg %d not supports long hash mode!\n", msg->alg); ++ return -WD_EINVAL; ++ } ++ return WD_SUCCESS; ++ } ++ ++ if (unlikely(msg->has_next && !msg->in_bytes)) { ++ /* Long hash first and middle BD */ ++ WD_ERR("invalid: digest bd3 not supports 0 packet in first bd and middle bd!\n"); ++ return -WD_EINVAL; ++ } ++ + /* iv_bytes is multiplexed as a flag bit to determine whether it is LOGN BD FIRST */ + if (msg->has_next && msg->iv_bytes == 0) { + /* LONG BD FIRST */ +@@ -1548,26 +1574,13 @@ static void qm_fill_digest_long_bd3(struct wcrypto_digest_msg *msg, + /* SHORT BD */ + msg->iv_bytes = 0; + } ++ ++ return WD_SUCCESS; + } + + static int fill_digest_bd3_alg(struct wcrypto_digest_msg *msg, + struct hisi_sec_bd3_sqe *sqe) + { +- int ret; +- +- ret = digest_param_check(msg); +- if (unlikely(ret)) +- return ret; +- +- if (unlikely(msg->in_bytes == 0)) { +- if ((msg->has_next && !msg->iv_bytes) || (msg->has_next && msg->iv_bytes)) { +- /* Long hash first and middle BD */ +- WD_ERR("invalid: digest bd3 not supports 0 packet in first bd and middle bd!\n"); +- return -WD_EINVAL; +- } +- } +- +- sqe->mac_len = msg->out_bytes / WORD_BYTES; + if (msg->mode == WCRYPTO_DIGEST_NORMAL) + sqe->a_alg = g_digest_a_alg[msg->alg]; + else if (msg->mode == WCRYPTO_DIGEST_HMAC) +@@ -1591,8 +1604,7 @@ static int set_hmac_mode_v3(struct wcrypto_digest_msg *msg, + + if (unlikely(msg->key_bytes & WORD_ALIGNMENT_MASK)) { + WD_ERR("Invalid digest key_bytes!\n"); +- ret = -WD_EINVAL; +- return ret; ++ return -WD_EINVAL; + } + sqe->a_key_len = msg->key_bytes / WORD_BYTES; + ret = map_addr(q, msg->key, msg->key_bytes, +@@ -1604,21 +1616,68 @@ static int set_hmac_mode_v3(struct wcrypto_digest_msg *msg, + return ret; + } + +- return 0; ++ if (msg->alg != WCRYPTO_AES_GMAC) ++ return WD_SUCCESS; ++ ++ sqe->ai_gen = AI_GEN_IVIN_ADDR; ++ ret = map_addr(q, msg->iv, SEC_GMAC_IV_LEN, &sqe->auth_key_iv.a_ivin_addr_l, ++ &sqe->auth_key_iv.a_ivin_addr_h, msg->data_fmt); ++ if (unlikely(ret)) { ++ WD_ERR("Get digest bd3 hmac iv dma address fail!\n"); ++ unmap_addr(q, msg->key, msg->key_bytes, sqe->auth_key_iv.a_key_addr_l, ++ sqe->auth_key_iv.a_key_addr_h, msg->data_fmt); ++ return ret; ++ } ++ ++ return WD_SUCCESS; ++} ++ ++static int digest_param_check_v3(struct wcrypto_digest_msg *msg) ++{ ++ int ret; ++ ++ ret = digest_param_check(msg, BD_TYPE3); ++ if (unlikely(ret)) ++ return ret; ++ ++ if (unlikely(!msg->in_bytes && ++ (msg->alg == WCRYPTO_AES_XCBC_MAC_96 || ++ msg->alg == WCRYPTO_AES_XCBC_PRF_128 || ++ msg->alg == WCRYPTO_AES_CMAC))) { ++ WD_ERR("invalid: digest mode %d not supports 0 packet!\n", msg->alg); ++ return -WD_EINVAL; ++ } ++ ++ if (unlikely((msg->alg == WCRYPTO_AES_XCBC_MAC_96 && ++ msg->out_bytes != WCRYPTO_AES_XCBC_MAC_96_LEN) || ++ (msg->alg == WCRYPTO_AES_XCBC_PRF_128 && ++ msg->out_bytes != WCRYPTO_AES_XCBC_PRF_128_LEN))) { ++ WD_ERR("invalid digest out_bytes %u, msg->alg = %d!\n", ++ msg->out_bytes, msg->alg); ++ return -WD_EINVAL; ++ } ++ ++ return WD_SUCCESS; + } + + static int fill_digest_bd3(struct wd_queue *q, struct hisi_sec_bd3_sqe *sqe, + struct wcrypto_digest_msg *msg, struct wcrypto_digest_tag *tag) + { +- int ret = -WD_ENOMEM; + uintptr_t phy; ++ int ret; ++ ++ ret = digest_param_check_v3(msg); ++ if (unlikely(ret)) ++ return ret; + + sqe->type = BD_TYPE3; +- sqe->scene = SCENE_STREAM; ++ if (msg->alg == WCRYPTO_AES_GMAC) ++ sqe->scene = SCENE_IPSEC; ++ else ++ sqe->scene = SCENE_STREAM; + + sqe->auth = AUTH_MAC_CALCULATE; + sqe->a_len = msg->in_bytes; +- + phy = (uintptr_t)drv_iova_map(q, msg->in, msg->in_bytes); + if (unlikely(!phy)) { + WD_ERR("Get message in dma address fail!\n"); +@@ -1634,17 +1693,21 @@ static int fill_digest_bd3(struct wd_queue *q, struct hisi_sec_bd3_sqe *sqe, + WD_ERR("Get digest bd3 message out dma address fail!\n"); + goto map_out_error; + } +- +- ret = set_hmac_mode_v3(msg, sqe, q); +- if (ret) +- goto map_key_error; ++ sqe->mac_len = msg->out_bytes / WORD_BYTES; + + ret = fill_digest_bd3_alg(msg, sqe); + if (ret != WD_SUCCESS) { + WD_ERR("fill_digest_bd3_alg fail!\n"); + goto map_alg_error; + } +- qm_fill_digest_long_bd3(msg, sqe); ++ ++ ret = qm_fill_digest_long_bd3(msg, sqe); ++ if (ret) ++ goto map_alg_error; ++ ++ ret = set_hmac_mode_v3(msg, sqe, q); ++ if (ret) ++ goto map_alg_error; + + if (tag) + sqe->tag_l = tag->wcrypto_tag.ctx_id; +@@ -1652,9 +1715,6 @@ static int fill_digest_bd3(struct wd_queue *q, struct hisi_sec_bd3_sqe *sqe, + return ret; + + map_alg_error: +- unmap_addr(q, msg->key, msg->key_bytes, sqe->auth_key_iv.a_key_addr_l, +- sqe->auth_key_iv.a_key_addr_h, msg->data_fmt); +-map_key_error: + unmap_addr(q, msg->out, msg->out_bytes, sqe->mac_addr_l, + sqe->mac_addr_h, msg->data_fmt); + map_out_error: +@@ -2585,6 +2645,11 @@ static void parse_digest_bd3(struct wd_queue *q, struct hisi_sec_bd3_sqe *sqe, + unmap_addr(q, digest_msg->key, digest_msg->key_bytes, + sqe->auth_key_iv.a_key_addr_l, + sqe->auth_key_iv.a_key_addr_h, digest_msg->data_fmt); ++ ++ if (digest_msg->alg == WCRYPTO_AES_GMAC) ++ unmap_addr(q, digest_msg->iv, SEC_GMAC_IV_LEN, ++ sqe->auth_key_iv.a_ivin_addr_l, ++ sqe->auth_key_iv.a_ivin_addr_h, digest_msg->data_fmt); + } + + int qm_parse_digest_bd3_sqe(void *msg, const struct qm_queue_info *info, +diff --git a/v1/wd_digest.c b/v1/wd_digest.c +index be43c73..f6c8b84 100644 +--- a/v1/wd_digest.c ++++ b/v1/wd_digest.c +@@ -30,6 +30,7 @@ + #define MAX_DIGEST_RETRY_CNT 20000000 + #define SEC_SHA1_ALIGN_SZ 64 + #define SEC_SHA512_ALIGN_SZ 128 ++#define SEC_GMAC_IV_LEN 16 + + struct wcrypto_digest_cookie { + struct wcrypto_digest_tag tag; +@@ -51,7 +52,9 @@ static __u32 g_digest_mac_len[WCRYPTO_MAX_DIGEST_TYPE] = { + WCRYPTO_DIGEST_SM3_LEN, WCRYPTO_DIGEST_MD5_LEN, WCRYPTO_DIGEST_SHA1_LEN, + WCRYPTO_DIGEST_SHA256_LEN, WCRYPTO_DIGEST_SHA224_LEN, + WCRYPTO_DIGEST_SHA384_LEN, WCRYPTO_DIGEST_SHA512_LEN, +- WCRYPTO_DIGEST_SHA512_224_LEN, WCRYPTO_DIGEST_SHA512_256_LEN ++ WCRYPTO_DIGEST_SHA512_224_LEN, WCRYPTO_DIGEST_SHA512_256_LEN, ++ WCRYPTO_AES_XCBC_MAC_96_LEN, WCRYPTO_AES_XCBC_PRF_128_LEN, ++ WCRYPTO_AES_CMAC_LEN, WCRYPTO_AES_GMAC_LEN + }; + + static __u32 g_digest_mac_full_len[WCRYPTO_MAX_DIGEST_TYPE] = { +@@ -103,6 +106,17 @@ static int create_ctx_para_check(struct wd_queue *q, + return -WD_EINVAL; + } + ++ if (setup->alg >= WCRYPTO_MAX_DIGEST_TYPE) { ++ WD_ERR("invalid: the alg %d does not support!\n", setup->alg); ++ return -WD_EINVAL; ++ } ++ ++ if (setup->mode == WCRYPTO_DIGEST_NORMAL && ++ setup->alg >= WCRYPTO_AES_XCBC_MAC_96) { ++ WD_ERR("invalid: the alg %d does not support normal mode!\n", setup->alg); ++ return -WD_EINVAL; ++ } ++ + return WD_SUCCESS; + } + +@@ -246,26 +260,65 @@ static void digest_requests_init(struct wcrypto_digest_msg **req, + req[i]->in_bytes = op[i]->in_bytes; + req[i]->out = op[i]->out; + req[i]->out_bytes = op[i]->out_bytes; ++ req[i]->iv = op[i]->iv; + c->io_bytes += op[i]->in_bytes; + } + } + ++static int digest_hmac_key_check(enum wcrypto_digest_alg alg, __u16 key_len) ++{ ++ switch (alg) { ++ case WCRYPTO_SM3 ... WCRYPTO_SHA224: ++ if (key_len > (MAX_HMAC_KEY_SIZE >> 1)) { ++ WD_ERR("failed to check alg %u key bytes, key_len = %u\n", alg, key_len); ++ return -WD_EINVAL; ++ } ++ break; ++ case WCRYPTO_SHA384 ... WCRYPTO_SHA512_256: ++ break; ++ case WCRYPTO_AES_XCBC_MAC_96: ++ case WCRYPTO_AES_XCBC_PRF_128: ++ case WCRYPTO_AES_CMAC: ++ if (key_len != AES_KEYSIZE_128) { ++ WD_ERR("failed to check alg %u key bytes, key_len = %u\n", alg, key_len); ++ return -WD_EINVAL; ++ } ++ break; ++ case WCRYPTO_AES_GMAC: ++ if (key_len != AES_KEYSIZE_128 && ++ key_len != AES_KEYSIZE_192 && ++ key_len != AES_KEYSIZE_256) { ++ WD_ERR("failed to check alg %u key bytes, key_len = %u\n", alg, key_len); ++ return -WD_EINVAL; ++ } ++ break; ++ default: ++ WD_ERR("failed to check digest key bytes, invalid alg type = %d\n", alg); ++ return -WD_EINVAL; ++ } ++ ++ return WD_SUCCESS; ++} ++ + int wcrypto_set_digest_key(void *ctx, __u8 *key, __u16 key_len) + { + struct wcrypto_digest_ctx *ctxt = ctx; ++ int ret; + + if (!ctx || !key) { + WD_ERR("%s(): input param err!\n", __func__); + return -WD_EINVAL; + } + +- if ((ctxt->setup.alg <= WCRYPTO_SHA224 && key_len > +- MAX_HMAC_KEY_SIZE >> 1) || key_len == 0 || +- key_len > MAX_HMAC_KEY_SIZE) { +- WD_ERR("%s: input key length err!\n", __func__); ++ if (key_len == 0 || key_len > MAX_HMAC_KEY_SIZE) { ++ WD_ERR("%s: input key length err, key_len = %u!\n", __func__, key_len); + return -WD_EINVAL; + } + ++ ret = digest_hmac_key_check(ctxt->setup.alg, key_len); ++ if (ret) ++ return ret; ++ + ctxt->key_bytes = key_len; + + if (ctxt->setup.data_fmt == WD_SGL_BUF) +@@ -361,6 +414,12 @@ static int param_check(struct wcrypto_digest_ctx *d_ctx, + WD_ERR("failed to check digest mac length!\n"); + return -WD_EINVAL; + } ++ if (d_ctx->setup.alg == WCRYPTO_AES_GMAC && ++ d_opdata[i]->iv_bytes != SEC_GMAC_IV_LEN) { ++ WD_ERR("failed to check digest aes_gmac iv length, iv_bytes = %u\n", ++ d_opdata[i]->iv_bytes); ++ return -WD_EINVAL; ++ } + } + + if (unlikely(tag && !tag[i])) { +diff --git a/v1/wd_digest.h b/v1/wd_digest.h +index 8f7ac2e..9667a66 100644 +--- a/v1/wd_digest.h ++++ b/v1/wd_digest.h +@@ -36,6 +36,10 @@ enum wcrypto_digest_alg { + WCRYPTO_SHA512, + WCRYPTO_SHA512_224, + WCRYPTO_SHA512_256, ++ WCRYPTO_AES_XCBC_MAC_96, ++ WCRYPTO_AES_XCBC_PRF_128, ++ WCRYPTO_AES_CMAC, ++ WCRYPTO_AES_GMAC, + WCRYPTO_MAX_DIGEST_TYPE, + }; + +@@ -43,12 +47,16 @@ enum wd_digest_mac_len { + WCRYPTO_DIGEST_SM3_LEN = 32, + WCRYPTO_DIGEST_MD5_LEN = 16, + WCRYPTO_DIGEST_SHA1_LEN = 20, +- WCRYPTO_DIGEST_SHA256_LEN = 32, +- WCRYPTO_DIGEST_SHA224_LEN = 28, +- WCRYPTO_DIGEST_SHA384_LEN = 48, +- WCRYPTO_DIGEST_SHA512_LEN = 64, +- WCRYPTO_DIGEST_SHA512_224_LEN = 28, +- WCRYPTO_DIGEST_SHA512_256_LEN = 32 ++ WCRYPTO_DIGEST_SHA256_LEN = 32, ++ WCRYPTO_DIGEST_SHA224_LEN = 28, ++ WCRYPTO_DIGEST_SHA384_LEN = 48, ++ WCRYPTO_DIGEST_SHA512_LEN = 64, ++ WCRYPTO_DIGEST_SHA512_224_LEN = 28, ++ WCRYPTO_DIGEST_SHA512_256_LEN = 32, ++ WCRYPTO_AES_XCBC_MAC_96_LEN = 12, ++ WCRYPTO_AES_XCBC_PRF_128_LEN = 16, ++ WCRYPTO_AES_CMAC_LEN = 16, ++ WCRYPTO_AES_GMAC_LEN = 16, + }; + + enum wcrypto_digest_mac_full_len { +@@ -93,6 +101,8 @@ struct wcrypto_digest_ctx_setup { + * @priv:reserved data field segment + * @status:I/O operation return status + * @has_next: is there next data block ++ * @iv: initialization verctor data address ++ * @iv_bytes:initialization verctor data size + */ + struct wcrypto_digest_op_data { + void *in; +@@ -102,6 +112,8 @@ struct wcrypto_digest_op_data { + void *priv; + int status; + bool has_next; ++ void *iv; ++ __u32 iv_bytes; + }; + + /* Digest message format of Warpdrive */ +-- +2.25.1 + diff --git a/0042-uadk-v1-fix-long-hash-state-issue.patch b/0042-uadk-v1-fix-long-hash-state-issue.patch new file mode 100644 index 0000000..439c8ff --- /dev/null +++ b/0042-uadk-v1-fix-long-hash-state-issue.patch @@ -0,0 +1,30 @@ +From bd3c4738ff9c6891a206ed7f77e80379ba443f9a Mon Sep 17 00:00:00 2001 +From: Weili Qian +Date: Thu, 26 Oct 2023 16:17:58 +0800 +Subject: [PATCH 42/42] uadk/v1: fix long hash state issue + +'iv_bytes' in msg is used as the packet status in the long hash service. +If initial value is not 0, the long hash calculation may be abnormal. +Therefore, initialize the cookie to 0. + +Signed-off-by: Weili Qian +--- + v1/wd_util.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/v1/wd_util.c b/v1/wd_util.c +index 6b8f944..a1d08b4 100644 +--- a/v1/wd_util.c ++++ b/v1/wd_util.c +@@ -87,7 +87,7 @@ int wd_init_cookie_pool(struct wd_cookie_pool *pool, + { + __u64 total_size = cookies_size * cookies_num; + +- pool->cookies = malloc(total_size + cookies_num); ++ pool->cookies = calloc(1, total_size + cookies_num); + if (!pool->cookies) + return -WD_ENOMEM; + +-- +2.25.1 + diff --git a/warpdrive.spec b/warpdrive.spec index 2365072..3188706 100644 --- a/warpdrive.spec +++ b/warpdrive.spec @@ -1,7 +1,7 @@ Name: libwd Summary: User Space Accelerator Development Kit Version: 2.5.0 -Release: 4 +Release: 5 License: Apache-2.0 Source: %{name}-%{version}.tar.gz Vendor: Huawei Corporation @@ -53,6 +53,10 @@ Patch0035: 0035-uadk-add-out_bytes-check-for-long-hash-scene.patch Patch0036: 0036-uadk-bugfix-for-aead-set-decrypt-mac-for-stream-mode.patch Patch0037: 0037-uadk-fix-for-digest-mac-full-length-check.patch Patch0038: 0038-uadk-sec-optimize-the-function-name-and-implement-fo.patch +Patch0039: 0039-uadk-cipher-support-sm4-xts-GB-standard.patch +Patch0040: 0040-uadk-v1-cipher-support-sm4-xts-GB-standard.patch +Patch0041: 0041-uadk-v1-digest-support-new-AES-mode-algs.patch +Patch0042: 0042-uadk-v1-fix-long-hash-state-issue.patch %description This package contains the User Space Accelerator Library @@ -225,6 +229,9 @@ fi /sbin/ldconfig %changelog +* Tue Oct 31 2023 JiangShui Yang 2.5.0-5 +- libwd: update the source code + * Thu Sep 28 2023 JiangShui Yang 2.5.0-4 - libwd: update the source code