This commit adds ZUC EEA3 cipher capability to Intel(R) QuickAssist
Technology driver

Signed-off-by: Arek Kusztal <arkadiuszx.kusz...@intel.com>
---
 doc/guides/cryptodevs/qat.rst                    |  2 +
 drivers/crypto/qat/qat_adf/qat_algs.h            | 11 ++-
 drivers/crypto/qat/qat_adf/qat_algs_build_desc.c | 97 ++++++++++++++++++++----
 drivers/crypto/qat/qat_crypto.c                  | 34 ++++++++-
 4 files changed, 125 insertions(+), 19 deletions(-)

diff --git a/doc/guides/cryptodevs/qat.rst b/doc/guides/cryptodevs/qat.rst
index 9ecd19b..79b9c9d 100644
--- a/doc/guides/cryptodevs/qat.rst
+++ b/doc/guides/cryptodevs/qat.rst
@@ -55,6 +55,7 @@ Cipher algorithms:
 * ``RTE_CRYPTO_CIPHER_NULL``
 * ``RTE_CRYPTO_CIPHER_KASUMI_F8``
 * ``RTE_CRYPTO_CIPHER_DES_CBC``
+* ``RTE_CRYPTO_CIPHER_ZUC_EEA3``
 
 Hash algorithms:
 
@@ -79,6 +80,7 @@ Limitations
 * SNOW 3G (UEA2) and KASUMI (F8) supported only if cipher length, cipher 
offset fields are byte-aligned.
 * SNOW 3G (UIA2) and KASUMI (F9) supported only if hash length, hash offset 
fields are byte-aligned.
 * No BSD support as BSD QAT kernel driver not available.
+* ZUC EEA3 is not supported by dh895xcc devices
 
 
 Installation
diff --git a/drivers/crypto/qat/qat_adf/qat_algs.h 
b/drivers/crypto/qat/qat_adf/qat_algs.h
index b9e3fd6..37f64d4 100644
--- a/drivers/crypto/qat/qat_adf/qat_algs.h
+++ b/drivers/crypto/qat/qat_adf/qat_algs.h
@@ -80,6 +80,14 @@ struct qat_alg_buf {
        uint64_t addr;
 } __rte_packed;
 
+enum qat_crypto_proto_flag {
+       QAT_CRYPTO_PROTO_FLAG_NONE = 0,
+       QAT_CRYPTO_PROTO_FLAG_CCM = 1,
+       QAT_CRYPTO_PROTO_FLAG_GCM = 2,
+       QAT_CRYPTO_PROTO_FLAG_SNOW3G = 3,
+       QAT_CRYPTO_PROTO_FLAG_ZUC = 4
+};
+
 /*
  * Maximum number of SGL entries
  */
@@ -143,7 +151,7 @@ int qat_alg_aead_session_create_content_desc_auth(struct 
qat_session *cdesc,
                                                unsigned int operation);
 
 void qat_alg_init_common_hdr(struct icp_qat_fw_comn_req_hdr *header,
-                                               uint16_t proto);
+                                               enum qat_crypto_proto_flag 
proto_flags);
 
 void qat_alg_ablkcipher_init_enc(struct qat_alg_ablkcipher_cd *cd,
                                        int alg, const uint8_t *key,
@@ -158,4 +166,5 @@ int qat_alg_validate_snow3g_key(int key_len, enum 
icp_qat_hw_cipher_algo *alg);
 int qat_alg_validate_kasumi_key(int key_len, enum icp_qat_hw_cipher_algo *alg);
 int qat_alg_validate_3des_key(int key_len, enum icp_qat_hw_cipher_algo *alg);
 int qat_alg_validate_des_key(int key_len, enum icp_qat_hw_cipher_algo *alg);
+int qat_alg_validate_zuc_key(int key_len, enum icp_qat_hw_cipher_algo *alg);
 #endif
diff --git a/drivers/crypto/qat/qat_adf/qat_algs_build_desc.c 
b/drivers/crypto/qat/qat_adf/qat_algs_build_desc.c
index fbeef0a..3831d19 100644
--- a/drivers/crypto/qat/qat_adf/qat_algs_build_desc.c
+++ b/drivers/crypto/qat/qat_adf/qat_algs_build_desc.c
@@ -422,7 +422,7 @@ static int qat_alg_do_precomputes(enum icp_qat_hw_auth_algo 
hash_alg,
 }
 
 void qat_alg_init_common_hdr(struct icp_qat_fw_comn_req_hdr *header,
-               uint16_t proto)
+               enum qat_crypto_proto_flag proto_flags)
 {
        PMD_INIT_FUNC_TRACE();
        header->hdr_flags =
@@ -435,14 +435,60 @@ void qat_alg_init_common_hdr(struct 
icp_qat_fw_comn_req_hdr *header,
                                  ICP_QAT_FW_LA_PARTIAL_NONE);
        ICP_QAT_FW_LA_CIPH_IV_FLD_FLAG_SET(header->serv_specif_flags,
                                           ICP_QAT_FW_CIPH_IV_16BYTE_DATA);
-       ICP_QAT_FW_LA_PROTO_SET(header->serv_specif_flags,
-                               proto);
+
+       switch (proto_flags)            {
+       case QAT_CRYPTO_PROTO_FLAG_NONE:
+               ICP_QAT_FW_LA_PROTO_SET(header->serv_specif_flags,
+                                       ICP_QAT_FW_LA_NO_PROTO);
+               break;
+       case QAT_CRYPTO_PROTO_FLAG_CCM:
+               ICP_QAT_FW_LA_PROTO_SET(header->serv_specif_flags,
+                                       ICP_QAT_FW_LA_CCM_PROTO);
+               break;
+       case QAT_CRYPTO_PROTO_FLAG_GCM:
+               ICP_QAT_FW_LA_PROTO_SET(header->serv_specif_flags,
+                                       ICP_QAT_FW_LA_GCM_PROTO);
+               break;
+       case QAT_CRYPTO_PROTO_FLAG_SNOW3G:
+               ICP_QAT_FW_LA_PROTO_SET(header->serv_specif_flags,
+                                       ICP_QAT_FW_LA_SNOW_3G_PROTO);
+               break;
+       case QAT_CRYPTO_PROTO_FLAG_ZUC:
+               ICP_QAT_FW_LA_ZUC_3G_PROTO_FLAG_SET(header->serv_specif_flags,
+                       ICP_QAT_FW_LA_ZUC_3G_PROTO);
+               break;
+       }
+
        ICP_QAT_FW_LA_UPDATE_STATE_SET(header->serv_specif_flags,
                                           ICP_QAT_FW_LA_NO_UPDATE_STATE);
        ICP_QAT_FW_LA_DIGEST_IN_BUFFER_SET(header->serv_specif_flags,
                                        ICP_QAT_FW_LA_NO_DIGEST_IN_BUFFER);
 }
 
+/*
+ *     Snow3G and ZUC should never use this function
+ *     and set its protocol flag in both cipher and auth part of content
+ *     descriptor building function
+ */
+static enum qat_crypto_proto_flag
+qat_get_crypto_proto_flag(uint16_t flags)
+{
+       int proto = ICP_QAT_FW_LA_PROTO_GET(flags);
+       enum qat_crypto_proto_flag qat_proto_flag =
+                       QAT_CRYPTO_PROTO_FLAG_NONE;
+
+       switch (proto) {
+       case ICP_QAT_FW_LA_GCM_PROTO:
+               qat_proto_flag = QAT_CRYPTO_PROTO_FLAG_GCM;
+               break;
+       case ICP_QAT_FW_LA_CCM_PROTO:
+               qat_proto_flag = QAT_CRYPTO_PROTO_FLAG_CCM;
+               break;
+       }
+
+       return qat_proto_flag;
+}
+
 int qat_alg_aead_session_create_content_desc_cipher(struct qat_session *cdesc,
                                                uint8_t *cipherkey,
                                                uint32_t cipherkeylen)
@@ -455,8 +501,9 @@ int qat_alg_aead_session_create_content_desc_cipher(struct 
qat_session *cdesc,
        struct icp_qat_fw_cipher_cd_ctrl_hdr *cipher_cd_ctrl = ptr;
        struct icp_qat_fw_auth_cd_ctrl_hdr *hash_cd_ctrl = ptr;
        enum icp_qat_hw_cipher_convert key_convert;
+       enum qat_crypto_proto_flag qat_proto_flag =
+               QAT_CRYPTO_PROTO_FLAG_NONE;
        uint32_t total_key_size;
-       uint16_t proto = ICP_QAT_FW_LA_NO_PROTO;        /* no CCM/GCM/SNOW 3G */
        uint16_t cipher_offset, cd_size;
        uint32_t wordIndex  = 0;
        uint32_t *temp_key = NULL;
@@ -496,7 +543,8 @@ int qat_alg_aead_session_create_content_desc_cipher(struct 
qat_session *cdesc,
                 */
                cdesc->qat_dir = ICP_QAT_HW_CIPHER_ENCRYPT;
                key_convert = ICP_QAT_HW_CIPHER_NO_CONVERT;
-       } else if (cdesc->qat_cipher_alg == ICP_QAT_HW_CIPHER_ALGO_SNOW_3G_UEA2)
+       } else if (cdesc->qat_cipher_alg == ICP_QAT_HW_CIPHER_ALGO_SNOW_3G_UEA2
+               || cdesc->qat_cipher_alg == 
ICP_QAT_HW_CIPHER_ALGO_ZUC_3G_128_EEA3)
                key_convert = ICP_QAT_HW_CIPHER_KEY_CONVERT;
        else if (cdesc->qat_dir == ICP_QAT_HW_CIPHER_ENCRYPT)
                key_convert = ICP_QAT_HW_CIPHER_NO_CONVERT;
@@ -508,7 +556,8 @@ int qat_alg_aead_session_create_content_desc_cipher(struct 
qat_session *cdesc,
                        ICP_QAT_HW_SNOW_3G_UEA2_IV_SZ;
                cipher_cd_ctrl->cipher_state_sz =
                        ICP_QAT_HW_SNOW_3G_UEA2_IV_SZ >> 3;
-               proto = ICP_QAT_FW_LA_SNOW_3G_PROTO;
+               qat_proto_flag = QAT_CRYPTO_PROTO_FLAG_SNOW3G;
+
        } else if (cdesc->qat_cipher_alg == ICP_QAT_HW_CIPHER_ALGO_KASUMI) {
                total_key_size = ICP_QAT_HW_KASUMI_F8_KEY_SZ;
                cipher_cd_ctrl->cipher_state_sz = ICP_QAT_HW_KASUMI_BLK_SZ >> 3;
@@ -517,25 +566,30 @@ int 
qat_alg_aead_session_create_content_desc_cipher(struct qat_session *cdesc,
        } else if (cdesc->qat_cipher_alg == ICP_QAT_HW_CIPHER_ALGO_3DES) {
                total_key_size = ICP_QAT_HW_3DES_KEY_SZ;
                cipher_cd_ctrl->cipher_state_sz = ICP_QAT_HW_3DES_BLK_SZ >> 3;
-               proto = ICP_QAT_FW_LA_PROTO_GET(header->serv_specif_flags);
+               qat_proto_flag = 
qat_get_crypto_proto_flag(header->serv_specif_flags);
        } else if (cdesc->qat_cipher_alg == ICP_QAT_HW_CIPHER_ALGO_DES) {
                total_key_size = ICP_QAT_HW_DES_KEY_SZ;
                cipher_cd_ctrl->cipher_state_sz = ICP_QAT_HW_DES_BLK_SZ >> 3;
-               proto = ICP_QAT_FW_LA_PROTO_GET(header->serv_specif_flags);
+               qat_proto_flag = 
qat_get_crypto_proto_flag(header->serv_specif_flags);
+       } else if (cdesc->qat_cipher_alg == 
ICP_QAT_HW_CIPHER_ALGO_ZUC_3G_128_EEA3) {
+               total_key_size = ICP_QAT_HW_ZUC_3G_EEA3_KEY_SZ +
+                       ICP_QAT_HW_ZUC_3G_EEA3_IV_SZ;
+               cipher_cd_ctrl->cipher_state_sz =
+                       ICP_QAT_HW_ZUC_3G_EEA3_IV_SZ >> 3;
+               qat_proto_flag = QAT_CRYPTO_PROTO_FLAG_ZUC;
        } else {
                total_key_size = cipherkeylen;
                cipher_cd_ctrl->cipher_state_sz = ICP_QAT_HW_AES_BLK_SZ >> 3;
-               proto = ICP_QAT_FW_LA_PROTO_GET(header->serv_specif_flags);
+               qat_proto_flag = 
qat_get_crypto_proto_flag(header->serv_specif_flags);
        }
        cipher_cd_ctrl->cipher_key_sz = total_key_size >> 3;
        cipher_offset = cdesc->cd_cur_ptr-((uint8_t *)&cdesc->cd);
        cipher_cd_ctrl->cipher_cfg_offset = cipher_offset >> 3;
 
        header->service_cmd_id = cdesc->qat_cmd;
-       qat_alg_init_common_hdr(header, proto);
+       qat_alg_init_common_hdr(header, qat_proto_flag);
 
        cipher = (struct icp_qat_hw_cipher_algo_blk *)cdesc->cd_cur_ptr;
-
        cipher->cipher_config.val =
            ICP_QAT_HW_CIPHER_CONFIG_BUILD(cdesc->qat_mode,
                                        cdesc->qat_cipher_alg, key_convert,
@@ -596,12 +650,13 @@ int qat_alg_aead_session_create_content_desc_auth(struct 
qat_session *cdesc,
                (struct icp_qat_fw_la_auth_req_params *)
                ((char *)&req_tmpl->serv_specif_rqpars +
                sizeof(struct icp_qat_fw_la_cipher_req_params));
-       uint16_t proto = ICP_QAT_FW_LA_NO_PROTO;        /* no CCM/GCM/SNOW 3G */
        uint16_t state1_size = 0, state2_size = 0;
        uint16_t hash_offset, cd_size;
        uint32_t *aad_len = NULL;
        uint32_t wordIndex  = 0;
        uint32_t *pTempKey;
+       enum qat_crypto_proto_flag qat_proto_flag =
+               QAT_CRYPTO_PROTO_FLAG_NONE;
 
        PMD_INIT_FUNC_TRACE();
 
@@ -714,7 +769,7 @@ int qat_alg_aead_session_create_content_desc_auth(struct 
qat_session *cdesc,
                break;
        case ICP_QAT_HW_AUTH_ALGO_GALOIS_128:
        case ICP_QAT_HW_AUTH_ALGO_GALOIS_64:
-               proto = ICP_QAT_FW_LA_GCM_PROTO;
+               qat_proto_flag = QAT_CRYPTO_PROTO_FLAG_GCM;
                state1_size = ICP_QAT_HW_GALOIS_128_STATE1_SZ;
                if (qat_alg_do_precomputes(cdesc->qat_hash_alg,
                        authkey, authkeylen, cdesc->cd_cur_ptr + state1_size,
@@ -736,7 +791,7 @@ int qat_alg_aead_session_create_content_desc_auth(struct 
qat_session *cdesc,
                *aad_len = rte_bswap32(add_auth_data_length);
                break;
        case ICP_QAT_HW_AUTH_ALGO_SNOW_3G_UIA2:
-               proto = ICP_QAT_FW_LA_SNOW_3G_PROTO;
+               qat_proto_flag = QAT_CRYPTO_PROTO_FLAG_SNOW3G;
                state1_size = qat_hash_get_state1_size(
                                ICP_QAT_HW_AUTH_ALGO_SNOW_3G_UIA2);
                state2_size = ICP_QAT_HW_SNOW_3G_UIA2_STATE2_SZ;
@@ -794,7 +849,7 @@ int qat_alg_aead_session_create_content_desc_auth(struct 
qat_session *cdesc,
        }
 
        /* Request template setup */
-       qat_alg_init_common_hdr(header, proto);
+       qat_alg_init_common_hdr(header, qat_proto_flag);
        header->service_cmd_id = cdesc->qat_cmd;
 
        /* Auth CD config setup */
@@ -886,3 +941,15 @@ int qat_alg_validate_3des_key(int key_len, enum 
icp_qat_hw_cipher_algo *alg)
        }
        return 0;
 }
+
+int qat_alg_validate_zuc_key(int key_len, enum icp_qat_hw_cipher_algo *alg)
+{
+       switch (key_len) {
+       case ICP_QAT_HW_ZUC_3G_EEA3_KEY_SZ:
+               *alg = ICP_QAT_HW_CIPHER_ALGO_ZUC_3G_128_EEA3;
+               break;
+       default:
+               return -EINVAL;
+       }
+       return 0;
+}
diff --git a/drivers/crypto/qat/qat_crypto.c b/drivers/crypto/qat/qat_crypto.c
index 43e1d00..fff51c8 100644
--- a/drivers/crypto/qat/qat_crypto.c
+++ b/drivers/crypto/qat/qat_crypto.c
@@ -516,6 +516,26 @@ static const struct rte_cryptodev_capabilities 
qat_pmd_capabilities[] = {
                        }, }
                }, }
        },
+               {       /* ZUC (EEA3) */
+               .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+               {.sym = {
+                       .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,
+                       {.cipher = {
+                               .algo = RTE_CRYPTO_CIPHER_ZUC_EEA3,
+                               .block_size = 16,
+                               .key_size = {
+                                       .min = 16,
+                                       .max = 16,
+                                       .increment = 0
+                               },
+                               .iv_size = {
+                                       .min = 16,
+                                       .max = 16,
+                                       .increment = 0
+                               }
+                       }, }
+               }, }
+       },
        RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
 };
 
@@ -674,13 +694,20 @@ qat_crypto_sym_configure_session_cipher(struct 
rte_cryptodev *dev,
                }
                session->qat_mode = ICP_QAT_HW_CIPHER_CTR_MODE;
                break;
+       case RTE_CRYPTO_CIPHER_ZUC_EEA3:
+               if (qat_alg_validate_zuc_key(cipher_xform->key.length,
+                               &session->qat_cipher_alg) != 0) {
+                       PMD_DRV_LOG(ERR, "Invalid ZUC cipher key size");
+                       goto error_out;
+               }
+               session->qat_mode = ICP_QAT_HW_CIPHER_ECB_MODE;
+               break;
        case RTE_CRYPTO_CIPHER_3DES_ECB:
        case RTE_CRYPTO_CIPHER_AES_ECB:
        case RTE_CRYPTO_CIPHER_AES_CCM:
        case RTE_CRYPTO_CIPHER_AES_F8:
        case RTE_CRYPTO_CIPHER_AES_XTS:
        case RTE_CRYPTO_CIPHER_ARC4:
-       case RTE_CRYPTO_CIPHER_ZUC_EEA3:
                PMD_DRV_LOG(ERR, "Crypto QAT PMD: Unsupported Cipher alg %u",
                                cipher_xform->algo);
                goto error_out;
@@ -1085,14 +1112,15 @@ qat_write_hw_desc_entry(struct rte_crypto_op *op, 
uint8_t *out_msg,
 
                if (ctx->qat_cipher_alg ==
                                         ICP_QAT_HW_CIPHER_ALGO_SNOW_3G_UEA2 ||
-                       ctx->qat_cipher_alg == ICP_QAT_HW_CIPHER_ALGO_KASUMI) {
+                       ctx->qat_cipher_alg == ICP_QAT_HW_CIPHER_ALGO_KASUMI    
||
+                       ctx->qat_cipher_alg == 
ICP_QAT_HW_CIPHER_ALGO_ZUC_3G_128_EEA3) {
 
                        if (unlikely(
                                (cipher_param->cipher_length % BYTE_LENGTH != 0)
                                 || (cipher_param->cipher_offset
                                                        % BYTE_LENGTH != 0))) {
                                PMD_DRV_LOG(ERR,
-                 "SNOW3G/KASUMI in QAT PMD only supports byte aligned values");
+                 "SNOW3G/KASUMI/ZUC in QAT PMD only supports byte aligned 
values");
                                op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
                                return -EINVAL;
                        }
-- 
2.7.4

Reply via email to