198f06089SFiona Trahe /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0) 2254558c8SKai Ji * Copyright(c) 2015-2022 Intel Corporation 398f06089SFiona Trahe */ 4f9a3d7f6SFiona Trahe 57360749fSHeinrich Schuchardt #define OPENSSL_API_COMPAT 0x10100000L 67360749fSHeinrich Schuchardt 762126a92SCiara Power #ifdef RTE_QAT_OPENSSL 8f9a3d7f6SFiona Trahe #include <openssl/sha.h> /* Needed to calculate pre-compute values */ 9f9a3d7f6SFiona Trahe #include <openssl/aes.h> /* Needed to calculate pre-compute values */ 10f9a3d7f6SFiona Trahe #include <openssl/md5.h> /* Needed to calculate pre-compute values */ 11f9a3d7f6SFiona Trahe #include <openssl/evp.h> /* Needed for bpi runt block processing */ 1262126a92SCiara Power #endif 13f9a3d7f6SFiona Trahe 14ca0ba0e4SBrian Dooley #ifndef RTE_QAT_OPENSSL 15ca0ba0e4SBrian Dooley #ifndef RTE_ARCH_ARM 163227bc71SKai Ji #include <intel-ipsec-mb.h> 173227bc71SKai Ji #endif 180899a87cSRuifeng Wang #endif 193227bc71SKai Ji 2098f06089SFiona Trahe #include <rte_memcpy.h> 2198f06089SFiona Trahe #include <rte_common.h> 2298f06089SFiona Trahe #include <rte_spinlock.h> 2398f06089SFiona Trahe #include <rte_byteorder.h> 2498f06089SFiona Trahe #include <rte_log.h> 2598f06089SFiona Trahe #include <rte_malloc.h> 2698f06089SFiona Trahe #include <rte_crypto_sym.h> 273f3fc330SAkhil Goyal #include <rte_security_driver.h> 28ce7a737cSKevin O'Sullivan #include <rte_ether.h> 2998f06089SFiona Trahe 3098f06089SFiona Trahe #include "qat_logs.h" 3198f06089SFiona Trahe #include "qat_sym_session.h" 32e0a67610SKai Ji #include "qat_sym.h" 3398f06089SFiona Trahe 34ca0ba0e4SBrian Dooley #ifdef RTE_QAT_OPENSSL 353227bc71SKai Ji #if (OPENSSL_VERSION_NUMBER >= 0x30000000L) 363227bc71SKai Ji #include <openssl/provider.h> 3752d59b92SKai Ji 3852d59b92SKai Ji static OSSL_PROVIDER * legacy_lib; 3952d59b92SKai Ji static OSSL_PROVIDER *default_lib; 4052d59b92SKai Ji 4152d59b92SKai Ji /* Some cryptographic algorithms such as MD and DES are now considered legacy 4252d59b92SKai Ji * and not enabled by default in OpenSSL 3.0. Load up lagacy provider as MD5 4352d59b92SKai Ji * DES are needed in QAT pre-computes and secure session creation. 4452d59b92SKai Ji */ 4552d59b92SKai Ji static int ossl_legacy_provider_load(void) 4652d59b92SKai Ji { 4752d59b92SKai Ji /* Load Multiple providers into the default (NULL) library context */ 4852d59b92SKai Ji legacy_lib = OSSL_PROVIDER_load(NULL, "legacy"); 4952d59b92SKai Ji if (legacy_lib == NULL) 5052d59b92SKai Ji return -EINVAL; 5152d59b92SKai Ji 5252d59b92SKai Ji default_lib = OSSL_PROVIDER_load(NULL, "default"); 5352d59b92SKai Ji if (default_lib == NULL) { 5452d59b92SKai Ji OSSL_PROVIDER_unload(legacy_lib); 5552d59b92SKai Ji return -EINVAL; 5652d59b92SKai Ji } 5752d59b92SKai Ji 5852d59b92SKai Ji return 0; 5952d59b92SKai Ji } 6052d59b92SKai Ji 6152d59b92SKai Ji static void ossl_legacy_provider_unload(void) 6252d59b92SKai Ji { 6352d59b92SKai Ji OSSL_PROVIDER_unload(legacy_lib); 6452d59b92SKai Ji OSSL_PROVIDER_unload(default_lib); 6552d59b92SKai Ji } 663227bc71SKai Ji #endif 67ca0ba0e4SBrian Dooley #endif 683227bc71SKai Ji 69ce7a737cSKevin O'Sullivan #define ETH_CRC32_POLYNOMIAL 0x04c11db7 70ce7a737cSKevin O'Sullivan #define ETH_CRC32_INIT_VAL 0xffffffff 71ce7a737cSKevin O'Sullivan #define ETH_CRC32_XOR_OUT 0xffffffff 72ce7a737cSKevin O'Sullivan #define ETH_CRC32_POLYNOMIAL_BE RTE_BE32(ETH_CRC32_POLYNOMIAL) 73ce7a737cSKevin O'Sullivan #define ETH_CRC32_INIT_VAL_BE RTE_BE32(ETH_CRC32_INIT_VAL) 74ce7a737cSKevin O'Sullivan #define ETH_CRC32_XOR_OUT_BE RTE_BE32(ETH_CRC32_XOR_OUT) 75ce7a737cSKevin O'Sullivan 766e21c1a5SAdam Dybkowski /* SHA1 - 20 bytes - Initialiser state can be found in FIPS stds 180-2 */ 776e21c1a5SAdam Dybkowski static const uint8_t sha1InitialState[] = { 786e21c1a5SAdam Dybkowski 0x67, 0x45, 0x23, 0x01, 0xef, 0xcd, 0xab, 0x89, 0x98, 0xba, 796e21c1a5SAdam Dybkowski 0xdc, 0xfe, 0x10, 0x32, 0x54, 0x76, 0xc3, 0xd2, 0xe1, 0xf0}; 806e21c1a5SAdam Dybkowski 816e21c1a5SAdam Dybkowski /* SHA 224 - 32 bytes - Initialiser state can be found in FIPS stds 180-2 */ 826e21c1a5SAdam Dybkowski static const uint8_t sha224InitialState[] = { 836e21c1a5SAdam Dybkowski 0xc1, 0x05, 0x9e, 0xd8, 0x36, 0x7c, 0xd5, 0x07, 0x30, 0x70, 0xdd, 846e21c1a5SAdam Dybkowski 0x17, 0xf7, 0x0e, 0x59, 0x39, 0xff, 0xc0, 0x0b, 0x31, 0x68, 0x58, 856e21c1a5SAdam Dybkowski 0x15, 0x11, 0x64, 0xf9, 0x8f, 0xa7, 0xbe, 0xfa, 0x4f, 0xa4}; 866e21c1a5SAdam Dybkowski 876e21c1a5SAdam Dybkowski /* SHA 256 - 32 bytes - Initialiser state can be found in FIPS stds 180-2 */ 886e21c1a5SAdam Dybkowski static const uint8_t sha256InitialState[] = { 896e21c1a5SAdam Dybkowski 0x6a, 0x09, 0xe6, 0x67, 0xbb, 0x67, 0xae, 0x85, 0x3c, 0x6e, 0xf3, 906e21c1a5SAdam Dybkowski 0x72, 0xa5, 0x4f, 0xf5, 0x3a, 0x51, 0x0e, 0x52, 0x7f, 0x9b, 0x05, 916e21c1a5SAdam Dybkowski 0x68, 0x8c, 0x1f, 0x83, 0xd9, 0xab, 0x5b, 0xe0, 0xcd, 0x19}; 926e21c1a5SAdam Dybkowski 936e21c1a5SAdam Dybkowski /* SHA 384 - 64 bytes - Initialiser state can be found in FIPS stds 180-2 */ 946e21c1a5SAdam Dybkowski static const uint8_t sha384InitialState[] = { 956e21c1a5SAdam Dybkowski 0xcb, 0xbb, 0x9d, 0x5d, 0xc1, 0x05, 0x9e, 0xd8, 0x62, 0x9a, 0x29, 966e21c1a5SAdam Dybkowski 0x2a, 0x36, 0x7c, 0xd5, 0x07, 0x91, 0x59, 0x01, 0x5a, 0x30, 0x70, 976e21c1a5SAdam Dybkowski 0xdd, 0x17, 0x15, 0x2f, 0xec, 0xd8, 0xf7, 0x0e, 0x59, 0x39, 0x67, 986e21c1a5SAdam Dybkowski 0x33, 0x26, 0x67, 0xff, 0xc0, 0x0b, 0x31, 0x8e, 0xb4, 0x4a, 0x87, 996e21c1a5SAdam Dybkowski 0x68, 0x58, 0x15, 0x11, 0xdb, 0x0c, 0x2e, 0x0d, 0x64, 0xf9, 0x8f, 1006e21c1a5SAdam Dybkowski 0xa7, 0x47, 0xb5, 0x48, 0x1d, 0xbe, 0xfa, 0x4f, 0xa4}; 1016e21c1a5SAdam Dybkowski 1026e21c1a5SAdam Dybkowski /* SHA 512 - 64 bytes - Initialiser state can be found in FIPS stds 180-2 */ 1036e21c1a5SAdam Dybkowski static const uint8_t sha512InitialState[] = { 1046e21c1a5SAdam Dybkowski 0x6a, 0x09, 0xe6, 0x67, 0xf3, 0xbc, 0xc9, 0x08, 0xbb, 0x67, 0xae, 1056e21c1a5SAdam Dybkowski 0x85, 0x84, 0xca, 0xa7, 0x3b, 0x3c, 0x6e, 0xf3, 0x72, 0xfe, 0x94, 1066e21c1a5SAdam Dybkowski 0xf8, 0x2b, 0xa5, 0x4f, 0xf5, 0x3a, 0x5f, 0x1d, 0x36, 0xf1, 0x51, 1076e21c1a5SAdam Dybkowski 0x0e, 0x52, 0x7f, 0xad, 0xe6, 0x82, 0xd1, 0x9b, 0x05, 0x68, 0x8c, 1086e21c1a5SAdam Dybkowski 0x2b, 0x3e, 0x6c, 0x1f, 0x1f, 0x83, 0xd9, 0xab, 0xfb, 0x41, 0xbd, 1096e21c1a5SAdam Dybkowski 0x6b, 0x5b, 0xe0, 0xcd, 0x19, 0x13, 0x7e, 0x21, 0x79}; 1106e21c1a5SAdam Dybkowski 11175fd4bbcSArek Kusztal static uint8_t sm3InitialState[] = { 11275fd4bbcSArek Kusztal 0x73, 0x80, 0x16, 0x6f, 0x49, 0x14, 0xb2, 0xb9, 11375fd4bbcSArek Kusztal 0x17, 0x24, 0x42, 0xd7, 0xda, 0x8a, 0x06, 0x00, 11475fd4bbcSArek Kusztal 0xa9, 0x6f, 0x30, 0xbc, 0x16, 0x31, 0x38, 0xaa, 11575fd4bbcSArek Kusztal 0xe3, 0x8d, 0xee, 0x4d, 0xb0, 0xfb, 0x0e, 0x4e 11675fd4bbcSArek Kusztal }; 11775fd4bbcSArek Kusztal 118bfe16f14SArek Kusztal static int 119bfe16f14SArek Kusztal qat_sym_cd_cipher_set(struct qat_sym_session *cd, 120bfe16f14SArek Kusztal const uint8_t *enckey, 121bfe16f14SArek Kusztal uint32_t enckeylen); 122bfe16f14SArek Kusztal 123bfe16f14SArek Kusztal static int 124ce7a737cSKevin O'Sullivan qat_sym_cd_crc_set(struct qat_sym_session *cdesc, 125ce7a737cSKevin O'Sullivan enum qat_device_gen qat_dev_gen); 126ce7a737cSKevin O'Sullivan 127ce7a737cSKevin O'Sullivan static int 128bfe16f14SArek Kusztal qat_sym_cd_auth_set(struct qat_sym_session *cdesc, 129bfe16f14SArek Kusztal const uint8_t *authkey, 130bfe16f14SArek Kusztal uint32_t authkeylen, 131bfe16f14SArek Kusztal uint32_t aad_length, 132bfe16f14SArek Kusztal uint32_t digestsize, 133171c655bSArkadiusz Kusztal unsigned int operation, 134171c655bSArkadiusz Kusztal enum qat_device_gen qat_dev_gen); 135ce7a737cSKevin O'Sullivan 1366618d3b5SArek Kusztal static void 1376618d3b5SArek Kusztal qat_sym_session_init_common_hdr(struct qat_sym_session *session); 1386618d3b5SArek Kusztal 139e2c11053SNishikant Nayak static void 140e2c11053SNishikant Nayak qat_sym_session_init_gen_lce_hdr(struct qat_sym_session *session); 141e2c11053SNishikant Nayak 1426618d3b5SArek Kusztal /* Req/cd init functions */ 1436618d3b5SArek Kusztal 1446618d3b5SArek Kusztal static void 1456618d3b5SArek Kusztal qat_sym_session_finalize(struct qat_sym_session *session) 1466618d3b5SArek Kusztal { 1476618d3b5SArek Kusztal qat_sym_session_init_common_hdr(session); 1486618d3b5SArek Kusztal } 149bfe16f14SArek Kusztal 150ca0ba0e4SBrian Dooley #ifdef RTE_QAT_OPENSSL 15198f06089SFiona Trahe /** Frees a context previously created 15298f06089SFiona Trahe * Depends on openssl libcrypto 15398f06089SFiona Trahe */ 15498f06089SFiona Trahe static void 15598f06089SFiona Trahe bpi_cipher_ctx_free(void *bpi_ctx) 15698f06089SFiona Trahe { 15798f06089SFiona Trahe if (bpi_ctx != NULL) 15898f06089SFiona Trahe EVP_CIPHER_CTX_free((EVP_CIPHER_CTX *)bpi_ctx); 15998f06089SFiona Trahe } 16098f06089SFiona Trahe 161f9a3d7f6SFiona Trahe /** Creates a context in either AES or DES in ECB mode 162f9a3d7f6SFiona Trahe * Depends on openssl libcrypto 163f9a3d7f6SFiona Trahe */ 16498f06089SFiona Trahe static int 16598f06089SFiona Trahe bpi_cipher_ctx_init(enum rte_crypto_cipher_algorithm cryptodev_algo, 16698f06089SFiona Trahe enum rte_crypto_cipher_operation direction __rte_unused, 1672aab3ff3SMairtin o Loingsigh const uint8_t *key, uint16_t key_length, void **ctx) 16898f06089SFiona Trahe { 16998f06089SFiona Trahe const EVP_CIPHER *algo = NULL; 17098f06089SFiona Trahe int ret; 17198f06089SFiona Trahe *ctx = EVP_CIPHER_CTX_new(); 17298f06089SFiona Trahe 17398f06089SFiona Trahe if (*ctx == NULL) { 17498f06089SFiona Trahe ret = -ENOMEM; 17598f06089SFiona Trahe goto ctx_init_err; 17698f06089SFiona Trahe } 17798f06089SFiona Trahe 17898f06089SFiona Trahe if (cryptodev_algo == RTE_CRYPTO_CIPHER_DES_DOCSISBPI) 17998f06089SFiona Trahe algo = EVP_des_ecb(); 18098f06089SFiona Trahe else 1812aab3ff3SMairtin o Loingsigh if (key_length == ICP_QAT_HW_AES_128_KEY_SZ) 18298f06089SFiona Trahe algo = EVP_aes_128_ecb(); 1832aab3ff3SMairtin o Loingsigh else 1842aab3ff3SMairtin o Loingsigh algo = EVP_aes_256_ecb(); 18598f06089SFiona Trahe 18698f06089SFiona Trahe /* IV will be ECB encrypted whether direction is encrypt or decrypt*/ 18798f06089SFiona Trahe if (EVP_EncryptInit_ex(*ctx, algo, NULL, key, 0) != 1) { 18898f06089SFiona Trahe ret = -EINVAL; 18998f06089SFiona Trahe goto ctx_init_err; 19098f06089SFiona Trahe } 19198f06089SFiona Trahe 19298f06089SFiona Trahe return 0; 19398f06089SFiona Trahe 19498f06089SFiona Trahe ctx_init_err: 19503f0e360SRebecca Troy if (*ctx != NULL) { 19698f06089SFiona Trahe EVP_CIPHER_CTX_free(*ctx); 19703f0e360SRebecca Troy *ctx = NULL; 19803f0e360SRebecca Troy } 19998f06089SFiona Trahe return ret; 20098f06089SFiona Trahe } 201ca0ba0e4SBrian Dooley #endif 202ca0ba0e4SBrian Dooley 203ca0ba0e4SBrian Dooley #ifndef RTE_QAT_OPENSSL 204ca0ba0e4SBrian Dooley /** Creates a context in either AES or DES in ECB mode 205ca0ba0e4SBrian Dooley */ 206ca0ba0e4SBrian Dooley static int 207ca0ba0e4SBrian Dooley ipsec_mb_ctx_init(const uint8_t *key, uint16_t key_length, 208ca0ba0e4SBrian Dooley enum rte_crypto_cipher_algorithm cryptodev_algo, 209ca0ba0e4SBrian Dooley uint64_t *expkey, uint32_t *dust, IMB_MGR **m) 210ca0ba0e4SBrian Dooley { 211ca0ba0e4SBrian Dooley int ret; 212ca0ba0e4SBrian Dooley 213ca0ba0e4SBrian Dooley *m = alloc_mb_mgr(0); 214ca0ba0e4SBrian Dooley if (*m == NULL) 215ca0ba0e4SBrian Dooley return -ENOMEM; 216ca0ba0e4SBrian Dooley 217ca0ba0e4SBrian Dooley init_mb_mgr_auto(*m, NULL); 218ca0ba0e4SBrian Dooley 219ca0ba0e4SBrian Dooley if (cryptodev_algo == RTE_CRYPTO_CIPHER_AES_DOCSISBPI) { 220ca0ba0e4SBrian Dooley if (key_length == ICP_QAT_HW_AES_128_KEY_SZ) 221ca0ba0e4SBrian Dooley IMB_AES_KEYEXP_128(*m, key, expkey, dust); 222ca0ba0e4SBrian Dooley else if (key_length == ICP_QAT_HW_AES_256_KEY_SZ) 223ca0ba0e4SBrian Dooley IMB_AES_KEYEXP_256(*m, key, expkey, dust); 224ca0ba0e4SBrian Dooley else { 225ca0ba0e4SBrian Dooley ret = -EFAULT; 226ca0ba0e4SBrian Dooley goto error_out; 227ca0ba0e4SBrian Dooley } 228ca0ba0e4SBrian Dooley } else if (cryptodev_algo == RTE_CRYPTO_CIPHER_DES_DOCSISBPI) { 229ca0ba0e4SBrian Dooley if (key_length == ICP_QAT_HW_DES_KEY_SZ) 230ca0ba0e4SBrian Dooley IMB_DES_KEYSCHED(*m, (uint64_t *)expkey, key); 231ca0ba0e4SBrian Dooley else { 232ca0ba0e4SBrian Dooley ret = -EFAULT; 233ca0ba0e4SBrian Dooley goto error_out; 234ca0ba0e4SBrian Dooley } 235ca0ba0e4SBrian Dooley } 236ca0ba0e4SBrian Dooley return 0; 237ca0ba0e4SBrian Dooley 238ca0ba0e4SBrian Dooley error_out: 239ca0ba0e4SBrian Dooley if (*m) { 240ca0ba0e4SBrian Dooley free_mb_mgr(*m); 241ca0ba0e4SBrian Dooley *m = NULL; 242ca0ba0e4SBrian Dooley } 243ca0ba0e4SBrian Dooley return ret; 244ca0ba0e4SBrian Dooley } 245ca0ba0e4SBrian Dooley #endif 24698f06089SFiona Trahe 24798f06089SFiona Trahe static int 24898f06089SFiona Trahe qat_is_cipher_alg_supported(enum rte_crypto_cipher_algorithm algo, 249f0f369a6SFan Zhang struct qat_cryptodev_private *internals) 25098f06089SFiona Trahe { 25198f06089SFiona Trahe int i = 0; 25298f06089SFiona Trahe const struct rte_cryptodev_capabilities *capability; 25398f06089SFiona Trahe 25498f06089SFiona Trahe while ((capability = &(internals->qat_dev_capabilities[i++]))->op != 25598f06089SFiona Trahe RTE_CRYPTO_OP_TYPE_UNDEFINED) { 25698f06089SFiona Trahe if (capability->op != RTE_CRYPTO_OP_TYPE_SYMMETRIC) 25798f06089SFiona Trahe continue; 25898f06089SFiona Trahe 25998f06089SFiona Trahe if (capability->sym.xform_type != RTE_CRYPTO_SYM_XFORM_CIPHER) 26098f06089SFiona Trahe continue; 26198f06089SFiona Trahe 26298f06089SFiona Trahe if (capability->sym.cipher.algo == algo) 26398f06089SFiona Trahe return 1; 26498f06089SFiona Trahe } 26598f06089SFiona Trahe return 0; 26698f06089SFiona Trahe } 26798f06089SFiona Trahe 26898f06089SFiona Trahe static int 26998f06089SFiona Trahe qat_is_auth_alg_supported(enum rte_crypto_auth_algorithm algo, 270f0f369a6SFan Zhang struct qat_cryptodev_private *internals) 27198f06089SFiona Trahe { 27298f06089SFiona Trahe int i = 0; 27398f06089SFiona Trahe const struct rte_cryptodev_capabilities *capability; 27498f06089SFiona Trahe 27598f06089SFiona Trahe while ((capability = &(internals->qat_dev_capabilities[i++]))->op != 27698f06089SFiona Trahe RTE_CRYPTO_OP_TYPE_UNDEFINED) { 27798f06089SFiona Trahe if (capability->op != RTE_CRYPTO_OP_TYPE_SYMMETRIC) 27898f06089SFiona Trahe continue; 27998f06089SFiona Trahe 28098f06089SFiona Trahe if (capability->sym.xform_type != RTE_CRYPTO_SYM_XFORM_AUTH) 28198f06089SFiona Trahe continue; 28298f06089SFiona Trahe 28398f06089SFiona Trahe if (capability->sym.auth.algo == algo) 28498f06089SFiona Trahe return 1; 28598f06089SFiona Trahe } 28698f06089SFiona Trahe return 0; 28798f06089SFiona Trahe } 28898f06089SFiona Trahe 28998f06089SFiona Trahe void 290bdce2564SAkhil Goyal qat_sym_session_clear(struct rte_cryptodev *dev __rte_unused, 29198f06089SFiona Trahe struct rte_cryptodev_sym_session *sess) 29298f06089SFiona Trahe { 2932a440d6aSAkhil Goyal struct qat_sym_session *s = CRYPTODEV_GET_SYM_SESS_PRIV(sess); 29498f06089SFiona Trahe 295ca0ba0e4SBrian Dooley #ifdef RTE_QAT_OPENSSL 29698f06089SFiona Trahe if (s->bpi_ctx) 29798f06089SFiona Trahe bpi_cipher_ctx_free(s->bpi_ctx); 298ca0ba0e4SBrian Dooley #else 299ca0ba0e4SBrian Dooley if (s->mb_mgr) 300ca0ba0e4SBrian Dooley free_mb_mgr(s->mb_mgr); 301ca0ba0e4SBrian Dooley #endif 30298f06089SFiona Trahe } 30398f06089SFiona Trahe 30498f06089SFiona Trahe static int 30598f06089SFiona Trahe qat_get_cmd_id(const struct rte_crypto_sym_xform *xform) 30698f06089SFiona Trahe { 30798f06089SFiona Trahe /* Cipher Only */ 30898f06089SFiona Trahe if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER && xform->next == NULL) 30998f06089SFiona Trahe return ICP_QAT_FW_LA_CMD_CIPHER; 31098f06089SFiona Trahe 31198f06089SFiona Trahe /* Authentication Only */ 31298f06089SFiona Trahe if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH && xform->next == NULL) 31398f06089SFiona Trahe return ICP_QAT_FW_LA_CMD_AUTH; 31498f06089SFiona Trahe 31598f06089SFiona Trahe /* AEAD */ 31698f06089SFiona Trahe if (xform->type == RTE_CRYPTO_SYM_XFORM_AEAD) { 31798f06089SFiona Trahe /* AES-GCM and AES-CCM works with different direction 31898f06089SFiona Trahe * GCM first encrypts and generate hash where AES-CCM 31998f06089SFiona Trahe * first generate hash and encrypts. Similar relation 32098f06089SFiona Trahe * applies to decryption. 32198f06089SFiona Trahe */ 32298f06089SFiona Trahe if (xform->aead.op == RTE_CRYPTO_AEAD_OP_ENCRYPT) 32398f06089SFiona Trahe if (xform->aead.algo == RTE_CRYPTO_AEAD_AES_GCM) 32498f06089SFiona Trahe return ICP_QAT_FW_LA_CMD_CIPHER_HASH; 32598f06089SFiona Trahe else 32698f06089SFiona Trahe return ICP_QAT_FW_LA_CMD_HASH_CIPHER; 32798f06089SFiona Trahe else 32898f06089SFiona Trahe if (xform->aead.algo == RTE_CRYPTO_AEAD_AES_GCM) 32998f06089SFiona Trahe return ICP_QAT_FW_LA_CMD_HASH_CIPHER; 33098f06089SFiona Trahe else 33198f06089SFiona Trahe return ICP_QAT_FW_LA_CMD_CIPHER_HASH; 33298f06089SFiona Trahe } 33398f06089SFiona Trahe 33498f06089SFiona Trahe if (xform->next == NULL) 33598f06089SFiona Trahe return -1; 33698f06089SFiona Trahe 33798f06089SFiona Trahe /* Cipher then Authenticate */ 33898f06089SFiona Trahe if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER && 33998f06089SFiona Trahe xform->next->type == RTE_CRYPTO_SYM_XFORM_AUTH) 34098f06089SFiona Trahe return ICP_QAT_FW_LA_CMD_CIPHER_HASH; 34198f06089SFiona Trahe 34298f06089SFiona Trahe /* Authenticate then Cipher */ 34398f06089SFiona Trahe if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH && 34498f06089SFiona Trahe xform->next->type == RTE_CRYPTO_SYM_XFORM_CIPHER) 34598f06089SFiona Trahe return ICP_QAT_FW_LA_CMD_HASH_CIPHER; 34698f06089SFiona Trahe 34798f06089SFiona Trahe return -1; 34898f06089SFiona Trahe } 34998f06089SFiona Trahe 35098f06089SFiona Trahe static struct rte_crypto_auth_xform * 35198f06089SFiona Trahe qat_get_auth_xform(struct rte_crypto_sym_xform *xform) 35298f06089SFiona Trahe { 35398f06089SFiona Trahe do { 35498f06089SFiona Trahe if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) 35598f06089SFiona Trahe return &xform->auth; 35698f06089SFiona Trahe 35798f06089SFiona Trahe xform = xform->next; 35898f06089SFiona Trahe } while (xform); 35998f06089SFiona Trahe 36098f06089SFiona Trahe return NULL; 36198f06089SFiona Trahe } 36298f06089SFiona Trahe 36398f06089SFiona Trahe static struct rte_crypto_cipher_xform * 36498f06089SFiona Trahe qat_get_cipher_xform(struct rte_crypto_sym_xform *xform) 36598f06089SFiona Trahe { 36698f06089SFiona Trahe do { 36798f06089SFiona Trahe if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER) 36898f06089SFiona Trahe return &xform->cipher; 36998f06089SFiona Trahe 37098f06089SFiona Trahe xform = xform->next; 37198f06089SFiona Trahe } while (xform); 37298f06089SFiona Trahe 37398f06089SFiona Trahe return NULL; 37498f06089SFiona Trahe } 37598f06089SFiona Trahe 37698f06089SFiona Trahe int 377bba31cffSFiona Trahe qat_sym_session_configure_cipher(struct rte_cryptodev *dev, 37898f06089SFiona Trahe struct rte_crypto_sym_xform *xform, 3796132b718SFiona Trahe struct qat_sym_session *session) 38098f06089SFiona Trahe { 381f0f369a6SFan Zhang struct qat_cryptodev_private *internals = dev->data->dev_private; 38298f06089SFiona Trahe struct rte_crypto_cipher_xform *cipher_xform = NULL; 383d0549291SArek Kusztal enum qat_device_gen qat_dev_gen = 384d0549291SArek Kusztal internals->qat_dev->qat_dev_gen; 3856c868d6eSCiara Power int ret, is_wireless = 0; 3866c868d6eSCiara Power struct icp_qat_fw_la_bulk_req *req_tmpl = &session->fw_req; 3876c868d6eSCiara Power struct icp_qat_fw_comn_req_hdr *header = &req_tmpl->comn_hdr; 38898f06089SFiona Trahe 38998f06089SFiona Trahe /* Get cipher xform from crypto xform chain */ 39098f06089SFiona Trahe cipher_xform = qat_get_cipher_xform(xform); 39198f06089SFiona Trahe 39298f06089SFiona Trahe session->cipher_iv.offset = cipher_xform->iv.offset; 39398f06089SFiona Trahe session->cipher_iv.length = cipher_xform->iv.length; 39498f06089SFiona Trahe 39598f06089SFiona Trahe switch (cipher_xform->algo) { 39698f06089SFiona Trahe case RTE_CRYPTO_CIPHER_AES_CBC: 397bba31cffSFiona Trahe if (qat_sym_validate_aes_key(cipher_xform->key.length, 39898f06089SFiona Trahe &session->qat_cipher_alg) != 0) { 399be24b0d9SFiona Trahe QAT_LOG(ERR, "Invalid AES cipher key size"); 40098f06089SFiona Trahe ret = -EINVAL; 40198f06089SFiona Trahe goto error_out; 40298f06089SFiona Trahe } 40398f06089SFiona Trahe session->qat_mode = ICP_QAT_HW_CIPHER_CBC_MODE; 40498f06089SFiona Trahe break; 40598f06089SFiona Trahe case RTE_CRYPTO_CIPHER_AES_CTR: 406bba31cffSFiona Trahe if (qat_sym_validate_aes_key(cipher_xform->key.length, 40798f06089SFiona Trahe &session->qat_cipher_alg) != 0) { 408be24b0d9SFiona Trahe QAT_LOG(ERR, "Invalid AES cipher key size"); 40998f06089SFiona Trahe ret = -EINVAL; 41098f06089SFiona Trahe goto error_out; 41198f06089SFiona Trahe } 41298f06089SFiona Trahe session->qat_mode = ICP_QAT_HW_CIPHER_CTR_MODE; 4132e98e808SArkadiusz Kusztal if (qat_dev_gen == QAT_GEN4 || qat_dev_gen == QAT_GEN5 || 4142e98e808SArkadiusz Kusztal qat_dev_gen == QAT_VQAT) 415d0549291SArek Kusztal session->is_ucs = 1; 41698f06089SFiona Trahe break; 41798f06089SFiona Trahe case RTE_CRYPTO_CIPHER_SNOW3G_UEA2: 418bba31cffSFiona Trahe if (qat_sym_validate_snow3g_key(cipher_xform->key.length, 41998f06089SFiona Trahe &session->qat_cipher_alg) != 0) { 420be24b0d9SFiona Trahe QAT_LOG(ERR, "Invalid SNOW 3G cipher key size"); 42198f06089SFiona Trahe ret = -EINVAL; 42298f06089SFiona Trahe goto error_out; 42398f06089SFiona Trahe } 42498f06089SFiona Trahe session->qat_mode = ICP_QAT_HW_CIPHER_ECB_MODE; 425b7bd72d8SArkadiusz Kusztal if (internals->qat_dev->options.has_wireless_slice) 4266c868d6eSCiara Power is_wireless = 1; 42798f06089SFiona Trahe break; 42898f06089SFiona Trahe case RTE_CRYPTO_CIPHER_NULL: 42920f1cb1aSFiona Trahe session->qat_cipher_alg = ICP_QAT_HW_CIPHER_ALGO_NULL; 43020f1cb1aSFiona Trahe session->qat_mode = ICP_QAT_HW_CIPHER_CTR_MODE; 43198f06089SFiona Trahe break; 43298f06089SFiona Trahe case RTE_CRYPTO_CIPHER_KASUMI_F8: 433bba31cffSFiona Trahe if (qat_sym_validate_kasumi_key(cipher_xform->key.length, 43498f06089SFiona Trahe &session->qat_cipher_alg) != 0) { 435be24b0d9SFiona Trahe QAT_LOG(ERR, "Invalid KASUMI cipher key size"); 43698f06089SFiona Trahe ret = -EINVAL; 43798f06089SFiona Trahe goto error_out; 43898f06089SFiona Trahe } 43998f06089SFiona Trahe session->qat_mode = ICP_QAT_HW_CIPHER_F8_MODE; 44098f06089SFiona Trahe break; 44198f06089SFiona Trahe case RTE_CRYPTO_CIPHER_3DES_CBC: 442bba31cffSFiona Trahe if (qat_sym_validate_3des_key(cipher_xform->key.length, 44398f06089SFiona Trahe &session->qat_cipher_alg) != 0) { 444be24b0d9SFiona Trahe QAT_LOG(ERR, "Invalid 3DES cipher key size"); 44598f06089SFiona Trahe ret = -EINVAL; 44698f06089SFiona Trahe goto error_out; 44798f06089SFiona Trahe } 44898f06089SFiona Trahe session->qat_mode = ICP_QAT_HW_CIPHER_CBC_MODE; 44998f06089SFiona Trahe break; 45098f06089SFiona Trahe case RTE_CRYPTO_CIPHER_DES_CBC: 451bba31cffSFiona Trahe if (qat_sym_validate_des_key(cipher_xform->key.length, 45298f06089SFiona Trahe &session->qat_cipher_alg) != 0) { 453be24b0d9SFiona Trahe QAT_LOG(ERR, "Invalid DES cipher key size"); 45498f06089SFiona Trahe ret = -EINVAL; 45598f06089SFiona Trahe goto error_out; 45698f06089SFiona Trahe } 45798f06089SFiona Trahe session->qat_mode = ICP_QAT_HW_CIPHER_CBC_MODE; 45898f06089SFiona Trahe break; 45998f06089SFiona Trahe case RTE_CRYPTO_CIPHER_3DES_CTR: 460bba31cffSFiona Trahe if (qat_sym_validate_3des_key(cipher_xform->key.length, 46198f06089SFiona Trahe &session->qat_cipher_alg) != 0) { 462be24b0d9SFiona Trahe QAT_LOG(ERR, "Invalid 3DES cipher key size"); 46398f06089SFiona Trahe ret = -EINVAL; 46498f06089SFiona Trahe goto error_out; 46598f06089SFiona Trahe } 46698f06089SFiona Trahe session->qat_mode = ICP_QAT_HW_CIPHER_CTR_MODE; 46798f06089SFiona Trahe break; 46898f06089SFiona Trahe case RTE_CRYPTO_CIPHER_DES_DOCSISBPI: 469ca0ba0e4SBrian Dooley #ifdef RTE_QAT_OPENSSL 47098f06089SFiona Trahe ret = bpi_cipher_ctx_init( 47198f06089SFiona Trahe cipher_xform->algo, 47298f06089SFiona Trahe cipher_xform->op, 47398f06089SFiona Trahe cipher_xform->key.data, 4742aab3ff3SMairtin o Loingsigh cipher_xform->key.length, 47598f06089SFiona Trahe &session->bpi_ctx); 476ca0ba0e4SBrian Dooley #else 477ca0ba0e4SBrian Dooley session->docsis_key_len = cipher_xform->key.length; 478ca0ba0e4SBrian Dooley ret = ipsec_mb_ctx_init( 479ca0ba0e4SBrian Dooley cipher_xform->key.data, 480ca0ba0e4SBrian Dooley cipher_xform->key.length, 481ca0ba0e4SBrian Dooley cipher_xform->algo, 482ca0ba0e4SBrian Dooley session->expkey, 483ca0ba0e4SBrian Dooley session->dust, 484ca0ba0e4SBrian Dooley &session->mb_mgr); 485ca0ba0e4SBrian Dooley #endif 48698f06089SFiona Trahe if (ret != 0) { 487be24b0d9SFiona Trahe QAT_LOG(ERR, "failed to create DES BPI ctx"); 48898f06089SFiona Trahe goto error_out; 48998f06089SFiona Trahe } 490bba31cffSFiona Trahe if (qat_sym_validate_des_key(cipher_xform->key.length, 49198f06089SFiona Trahe &session->qat_cipher_alg) != 0) { 492be24b0d9SFiona Trahe QAT_LOG(ERR, "Invalid DES cipher key size"); 49398f06089SFiona Trahe ret = -EINVAL; 49498f06089SFiona Trahe goto error_out; 49598f06089SFiona Trahe } 49698f06089SFiona Trahe session->qat_mode = ICP_QAT_HW_CIPHER_CBC_MODE; 49798f06089SFiona Trahe break; 49898f06089SFiona Trahe case RTE_CRYPTO_CIPHER_AES_DOCSISBPI: 499ca0ba0e4SBrian Dooley #ifdef RTE_QAT_OPENSSL 50098f06089SFiona Trahe ret = bpi_cipher_ctx_init( 50198f06089SFiona Trahe cipher_xform->algo, 50298f06089SFiona Trahe cipher_xform->op, 50398f06089SFiona Trahe cipher_xform->key.data, 5042aab3ff3SMairtin o Loingsigh cipher_xform->key.length, 50598f06089SFiona Trahe &session->bpi_ctx); 506ca0ba0e4SBrian Dooley #else 507ca0ba0e4SBrian Dooley session->docsis_key_len = cipher_xform->key.length; 508ca0ba0e4SBrian Dooley ret = ipsec_mb_ctx_init( 509ca0ba0e4SBrian Dooley cipher_xform->key.data, 510ca0ba0e4SBrian Dooley cipher_xform->key.length, 511ca0ba0e4SBrian Dooley cipher_xform->algo, 512ca0ba0e4SBrian Dooley session->expkey, 513ca0ba0e4SBrian Dooley session->dust, 514ca0ba0e4SBrian Dooley &session->mb_mgr); 515ca0ba0e4SBrian Dooley #endif 51698f06089SFiona Trahe if (ret != 0) { 517be24b0d9SFiona Trahe QAT_LOG(ERR, "failed to create AES BPI ctx"); 51898f06089SFiona Trahe goto error_out; 51998f06089SFiona Trahe } 520bba31cffSFiona Trahe if (qat_sym_validate_aes_docsisbpi_key(cipher_xform->key.length, 52198f06089SFiona Trahe &session->qat_cipher_alg) != 0) { 522be24b0d9SFiona Trahe QAT_LOG(ERR, "Invalid AES DOCSISBPI key size"); 52398f06089SFiona Trahe ret = -EINVAL; 52498f06089SFiona Trahe goto error_out; 52598f06089SFiona Trahe } 52698f06089SFiona Trahe session->qat_mode = ICP_QAT_HW_CIPHER_CBC_MODE; 52798f06089SFiona Trahe break; 52898f06089SFiona Trahe case RTE_CRYPTO_CIPHER_ZUC_EEA3: 52998f06089SFiona Trahe if (!qat_is_cipher_alg_supported( 53098f06089SFiona Trahe cipher_xform->algo, internals)) { 531be24b0d9SFiona Trahe QAT_LOG(ERR, "%s not supported on this device", 5327e1e1277SAkhil Goyal rte_cryptodev_get_cipher_algo_string( 5337e1e1277SAkhil Goyal cipher_xform->algo)); 53498f06089SFiona Trahe ret = -ENOTSUP; 53598f06089SFiona Trahe goto error_out; 53698f06089SFiona Trahe } 537bba31cffSFiona Trahe if (qat_sym_validate_zuc_key(cipher_xform->key.length, 53898f06089SFiona Trahe &session->qat_cipher_alg) != 0) { 539be24b0d9SFiona Trahe QAT_LOG(ERR, "Invalid ZUC cipher key size"); 54098f06089SFiona Trahe ret = -EINVAL; 54198f06089SFiona Trahe goto error_out; 54298f06089SFiona Trahe } 54398f06089SFiona Trahe session->qat_mode = ICP_QAT_HW_CIPHER_ECB_MODE; 5446c868d6eSCiara Power if (cipher_xform->key.length == ICP_QAT_HW_ZUC_256_KEY_SZ) 5456c868d6eSCiara Power session->is_zuc256 = 1; 546b7bd72d8SArkadiusz Kusztal if (internals->qat_dev->options.has_wireless_slice) 5476c868d6eSCiara Power is_wireless = 1; 54898f06089SFiona Trahe break; 5497d5ef3bbSDamian Nowak case RTE_CRYPTO_CIPHER_AES_XTS: 5507d5ef3bbSDamian Nowak if ((cipher_xform->key.length/2) == ICP_QAT_HW_AES_192_KEY_SZ) { 5517d5ef3bbSDamian Nowak QAT_LOG(ERR, "AES-XTS-192 not supported"); 5527d5ef3bbSDamian Nowak ret = -EINVAL; 5537d5ef3bbSDamian Nowak goto error_out; 5547d5ef3bbSDamian Nowak } 5557d5ef3bbSDamian Nowak if (qat_sym_validate_aes_key((cipher_xform->key.length/2), 5567d5ef3bbSDamian Nowak &session->qat_cipher_alg) != 0) { 5577d5ef3bbSDamian Nowak QAT_LOG(ERR, "Invalid AES-XTS cipher key size"); 5587d5ef3bbSDamian Nowak ret = -EINVAL; 5597d5ef3bbSDamian Nowak goto error_out; 5607d5ef3bbSDamian Nowak } 5617d5ef3bbSDamian Nowak session->qat_mode = ICP_QAT_HW_CIPHER_XTS_MODE; 5627d5ef3bbSDamian Nowak break; 56392522c84SArek Kusztal case RTE_CRYPTO_CIPHER_SM4_ECB: 56492522c84SArek Kusztal session->qat_cipher_alg = ICP_QAT_HW_CIPHER_ALGO_SM4; 56592522c84SArek Kusztal session->qat_mode = ICP_QAT_HW_CIPHER_ECB_MODE; 56692522c84SArek Kusztal break; 56792522c84SArek Kusztal case RTE_CRYPTO_CIPHER_SM4_CBC: 56892522c84SArek Kusztal session->qat_cipher_alg = ICP_QAT_HW_CIPHER_ALGO_SM4; 56992522c84SArek Kusztal session->qat_mode = ICP_QAT_HW_CIPHER_CBC_MODE; 57092522c84SArek Kusztal break; 57192522c84SArek Kusztal case RTE_CRYPTO_CIPHER_SM4_CTR: 57292522c84SArek Kusztal session->qat_cipher_alg = ICP_QAT_HW_CIPHER_ALGO_SM4; 57392522c84SArek Kusztal session->qat_mode = ICP_QAT_HW_CIPHER_CTR_MODE; 57492522c84SArek Kusztal break; 57598f06089SFiona Trahe case RTE_CRYPTO_CIPHER_3DES_ECB: 57698f06089SFiona Trahe case RTE_CRYPTO_CIPHER_AES_ECB: 57798f06089SFiona Trahe case RTE_CRYPTO_CIPHER_AES_F8: 57898f06089SFiona Trahe case RTE_CRYPTO_CIPHER_ARC4: 579be24b0d9SFiona Trahe QAT_LOG(ERR, "Crypto QAT PMD: Unsupported Cipher alg %u", 58098f06089SFiona Trahe cipher_xform->algo); 58198f06089SFiona Trahe ret = -ENOTSUP; 58298f06089SFiona Trahe goto error_out; 58398f06089SFiona Trahe default: 584*f665790aSDavid Marchand QAT_LOG(ERR, "Crypto: Undefined Cipher specified %u", 58598f06089SFiona Trahe cipher_xform->algo); 58698f06089SFiona Trahe ret = -EINVAL; 58798f06089SFiona Trahe goto error_out; 58898f06089SFiona Trahe } 58998f06089SFiona Trahe 59098f06089SFiona Trahe if (cipher_xform->op == RTE_CRYPTO_CIPHER_OP_ENCRYPT) 59198f06089SFiona Trahe session->qat_dir = ICP_QAT_HW_CIPHER_ENCRYPT; 59298f06089SFiona Trahe else 59398f06089SFiona Trahe session->qat_dir = ICP_QAT_HW_CIPHER_DECRYPT; 59498f06089SFiona Trahe 595bfe16f14SArek Kusztal if (qat_sym_cd_cipher_set(session, 59698f06089SFiona Trahe cipher_xform->key.data, 59798f06089SFiona Trahe cipher_xform->key.length)) { 59898f06089SFiona Trahe ret = -EINVAL; 59998f06089SFiona Trahe goto error_out; 60098f06089SFiona Trahe } 60198f06089SFiona Trahe 6026c868d6eSCiara Power if (is_wireless) { 6036c868d6eSCiara Power /* Set the Use Extended Protocol Flags bit in LW 1 */ 6046c868d6eSCiara Power ICP_QAT_FW_USE_EXTENDED_PROTOCOL_FLAGS_SET( 6056c868d6eSCiara Power header->ext_flags, 6066c868d6eSCiara Power QAT_LA_USE_EXTENDED_PROTOCOL_FLAGS); 6076c868d6eSCiara Power /* Force usage of Wireless Cipher slice */ 6086c868d6eSCiara Power ICP_QAT_FW_USE_WCP_SLICE_SET(header->ext_flags, 6096c868d6eSCiara Power QAT_LA_USE_WCP_SLICE); 6106c868d6eSCiara Power session->is_wireless = 1; 6116c868d6eSCiara Power } 6126c868d6eSCiara Power 61398f06089SFiona Trahe return 0; 61498f06089SFiona Trahe 61598f06089SFiona Trahe error_out: 616ca0ba0e4SBrian Dooley #ifdef RTE_QAT_OPENSSL 61798f06089SFiona Trahe if (session->bpi_ctx) { 61898f06089SFiona Trahe bpi_cipher_ctx_free(session->bpi_ctx); 61998f06089SFiona Trahe session->bpi_ctx = NULL; 62098f06089SFiona Trahe } 621ca0ba0e4SBrian Dooley #else 622ca0ba0e4SBrian Dooley if (session->mb_mgr) { 623ca0ba0e4SBrian Dooley free_mb_mgr(session->mb_mgr); 624ca0ba0e4SBrian Dooley session->mb_mgr = NULL; 625ca0ba0e4SBrian Dooley } 626ca0ba0e4SBrian Dooley 627ca0ba0e4SBrian Dooley #endif 62898f06089SFiona Trahe return ret; 62998f06089SFiona Trahe } 63098f06089SFiona Trahe 63198f06089SFiona Trahe int 632bba31cffSFiona Trahe qat_sym_session_configure(struct rte_cryptodev *dev, 63398f06089SFiona Trahe struct rte_crypto_sym_xform *xform, 634bdce2564SAkhil Goyal struct rte_cryptodev_sym_session *sess) 63598f06089SFiona Trahe { 63698f06089SFiona Trahe int ret; 63798f06089SFiona Trahe 638ca0ba0e4SBrian Dooley #ifdef RTE_QAT_OPENSSL 6393227bc71SKai Ji #if (OPENSSL_VERSION_NUMBER >= 0x30000000L) 6403625d12eSBrian Dooley ossl_legacy_provider_load(); 6413227bc71SKai Ji #endif 642ca0ba0e4SBrian Dooley #endif 643bdce2564SAkhil Goyal ret = qat_sym_session_set_parameters(dev, xform, 6442a440d6aSAkhil Goyal CRYPTODEV_GET_SYM_SESS_PRIV(sess), 6452a440d6aSAkhil Goyal CRYPTODEV_GET_SYM_SESS_PRIV_IOVA(sess)); 64698f06089SFiona Trahe if (ret != 0) { 647be24b0d9SFiona Trahe QAT_LOG(ERR, 64898f06089SFiona Trahe "Crypto QAT PMD: failed to configure session parameters"); 64998f06089SFiona Trahe 65098f06089SFiona Trahe return ret; 65198f06089SFiona Trahe } 65298f06089SFiona Trahe 653ca0ba0e4SBrian Dooley #ifdef RTE_QAT_OPENSSL 6543227bc71SKai Ji # if (OPENSSL_VERSION_NUMBER >= 0x30000000L) 6553625d12eSBrian Dooley ossl_legacy_provider_unload(); 6563227bc71SKai Ji # endif 657ca0ba0e4SBrian Dooley # endif 65898f06089SFiona Trahe return 0; 65998f06089SFiona Trahe } 66098f06089SFiona Trahe 66198f06089SFiona Trahe int 662bba31cffSFiona Trahe qat_sym_session_set_parameters(struct rte_cryptodev *dev, 663bdce2564SAkhil Goyal struct rte_crypto_sym_xform *xform, void *session_private, 664bdce2564SAkhil Goyal rte_iova_t session_paddr) 66598f06089SFiona Trahe { 6666132b718SFiona Trahe struct qat_sym_session *session = session_private; 667f0f369a6SFan Zhang struct qat_cryptodev_private *internals = dev->data->dev_private; 66845fe9ea9SAdam Dybkowski enum qat_device_gen qat_dev_gen = internals->qat_dev->qat_dev_gen; 66998f06089SFiona Trahe int ret; 67098f06089SFiona Trahe int qat_cmd_id; 67198f06089SFiona Trahe 672b9e3ac69SAdam Dybkowski /* Verify the session physical address is known */ 673b9e3ac69SAdam Dybkowski if (session_paddr == 0 || session_paddr == RTE_BAD_IOVA) { 674b9e3ac69SAdam Dybkowski QAT_LOG(ERR, 675b9e3ac69SAdam Dybkowski "Session physical address unknown. Bad memory pool."); 676b9e3ac69SAdam Dybkowski return -EINVAL; 677b9e3ac69SAdam Dybkowski } 678b9e3ac69SAdam Dybkowski 6798f393c4fSArek Kusztal memset(session, 0, sizeof(*session)); 68098f06089SFiona Trahe /* Set context descriptor physical address */ 681b9e3ac69SAdam Dybkowski session->cd_paddr = session_paddr + 6826132b718SFiona Trahe offsetof(struct qat_sym_session, cd); 683171c655bSArkadiusz Kusztal session->prefix_paddr = session_paddr + 684171c655bSArkadiusz Kusztal offsetof(struct qat_sym_session, prefix_state); 68598f06089SFiona Trahe 686254558c8SKai Ji session->dev_id = internals->dev_id; 6876618d3b5SArek Kusztal session->qat_proto_flag = QAT_CRYPTO_PROTO_FLAG_NONE; 688d0549291SArek Kusztal session->is_ucs = 0; 68998f06089SFiona Trahe 69098f06089SFiona Trahe /* Get requested QAT command id */ 69198f06089SFiona Trahe qat_cmd_id = qat_get_cmd_id(xform); 69298f06089SFiona Trahe if (qat_cmd_id < 0 || qat_cmd_id >= ICP_QAT_FW_LA_CMD_DELIMITER) { 693be24b0d9SFiona Trahe QAT_LOG(ERR, "Unsupported xform chain requested"); 69498f06089SFiona Trahe return -ENOTSUP; 69598f06089SFiona Trahe } 69698f06089SFiona Trahe session->qat_cmd = (enum icp_qat_fw_la_cmd_id)qat_cmd_id; 69798f06089SFiona Trahe switch (session->qat_cmd) { 69898f06089SFiona Trahe case ICP_QAT_FW_LA_CMD_CIPHER: 699bba31cffSFiona Trahe ret = qat_sym_session_configure_cipher(dev, xform, session); 70098f06089SFiona Trahe if (ret < 0) 70198f06089SFiona Trahe return ret; 70298f06089SFiona Trahe break; 70398f06089SFiona Trahe case ICP_QAT_FW_LA_CMD_AUTH: 704bba31cffSFiona Trahe ret = qat_sym_session_configure_auth(dev, xform, session); 70598f06089SFiona Trahe if (ret < 0) 70698f06089SFiona Trahe return ret; 70745fe9ea9SAdam Dybkowski session->is_single_pass_gmac = 70845fe9ea9SAdam Dybkowski qat_dev_gen == QAT_GEN3 && 70945fe9ea9SAdam Dybkowski xform->auth.algo == RTE_CRYPTO_AUTH_AES_GMAC && 71045fe9ea9SAdam Dybkowski xform->auth.iv.length == QAT_AES_GCM_SPC_IV_SIZE; 71198f06089SFiona Trahe break; 71298f06089SFiona Trahe case ICP_QAT_FW_LA_CMD_CIPHER_HASH: 71398f06089SFiona Trahe if (xform->type == RTE_CRYPTO_SYM_XFORM_AEAD) { 714aa983f03SAdam Dybkowski ret = qat_sym_session_configure_aead(dev, xform, 71598f06089SFiona Trahe session); 71698f06089SFiona Trahe if (ret < 0) 71798f06089SFiona Trahe return ret; 71898f06089SFiona Trahe } else { 719bba31cffSFiona Trahe ret = qat_sym_session_configure_cipher(dev, 72098f06089SFiona Trahe xform, session); 72198f06089SFiona Trahe if (ret < 0) 72298f06089SFiona Trahe return ret; 723bba31cffSFiona Trahe ret = qat_sym_session_configure_auth(dev, 72498f06089SFiona Trahe xform, session); 72598f06089SFiona Trahe if (ret < 0) 72698f06089SFiona Trahe return ret; 72798f06089SFiona Trahe } 72898f06089SFiona Trahe break; 72998f06089SFiona Trahe case ICP_QAT_FW_LA_CMD_HASH_CIPHER: 73098f06089SFiona Trahe if (xform->type == RTE_CRYPTO_SYM_XFORM_AEAD) { 731aa983f03SAdam Dybkowski ret = qat_sym_session_configure_aead(dev, xform, 73298f06089SFiona Trahe session); 73398f06089SFiona Trahe if (ret < 0) 73498f06089SFiona Trahe return ret; 73598f06089SFiona Trahe } else { 736bba31cffSFiona Trahe ret = qat_sym_session_configure_auth(dev, 73798f06089SFiona Trahe xform, session); 73898f06089SFiona Trahe if (ret < 0) 73998f06089SFiona Trahe return ret; 740bba31cffSFiona Trahe ret = qat_sym_session_configure_cipher(dev, 74198f06089SFiona Trahe xform, session); 74298f06089SFiona Trahe if (ret < 0) 74398f06089SFiona Trahe return ret; 74498f06089SFiona Trahe } 74598f06089SFiona Trahe break; 74698f06089SFiona Trahe case ICP_QAT_FW_LA_CMD_TRNG_GET_RANDOM: 74798f06089SFiona Trahe case ICP_QAT_FW_LA_CMD_TRNG_TEST: 74898f06089SFiona Trahe case ICP_QAT_FW_LA_CMD_SSL3_KEY_DERIVE: 74998f06089SFiona Trahe case ICP_QAT_FW_LA_CMD_TLS_V1_1_KEY_DERIVE: 75098f06089SFiona Trahe case ICP_QAT_FW_LA_CMD_TLS_V1_2_KEY_DERIVE: 75198f06089SFiona Trahe case ICP_QAT_FW_LA_CMD_MGF1: 75298f06089SFiona Trahe case ICP_QAT_FW_LA_CMD_AUTH_PRE_COMP: 75398f06089SFiona Trahe case ICP_QAT_FW_LA_CMD_CIPHER_PRE_COMP: 754ce7a737cSKevin O'Sullivan case ICP_QAT_FW_LA_CMD_CIPHER_CRC: 75598f06089SFiona Trahe case ICP_QAT_FW_LA_CMD_DELIMITER: 756be24b0d9SFiona Trahe QAT_LOG(ERR, "Unsupported Service %u", 75798f06089SFiona Trahe session->qat_cmd); 75898f06089SFiona Trahe return -ENOTSUP; 75998f06089SFiona Trahe default: 760be24b0d9SFiona Trahe QAT_LOG(ERR, "Unsupported Service %u", 76198f06089SFiona Trahe session->qat_cmd); 76298f06089SFiona Trahe return -ENOTSUP; 76398f06089SFiona Trahe } 764e2c11053SNishikant Nayak 765e2c11053SNishikant Nayak if (qat_dev_gen == QAT_GEN_LCE) { 766e2c11053SNishikant Nayak qat_sym_session_init_gen_lce_hdr(session); 767e2c11053SNishikant Nayak return 0; 768e2c11053SNishikant Nayak } 769e2c11053SNishikant Nayak 7706618d3b5SArek Kusztal qat_sym_session_finalize(session); 77198f06089SFiona Trahe 772254558c8SKai Ji return qat_sym_gen_dev_ops[qat_dev_gen].set_session((void *)dev, 773254558c8SKai Ji (void *)session); 77498f06089SFiona Trahe } 77598f06089SFiona Trahe 776ce7a737cSKevin O'Sullivan int 777ce7a737cSKevin O'Sullivan qat_cipher_crc_cap_msg_sess_prepare(struct qat_sym_session *session, 778ce7a737cSKevin O'Sullivan rte_iova_t session_paddr, 779ce7a737cSKevin O'Sullivan const uint8_t *cipherkey, 780ce7a737cSKevin O'Sullivan uint32_t cipherkeylen, 781ce7a737cSKevin O'Sullivan enum qat_device_gen qat_dev_gen) 782ce7a737cSKevin O'Sullivan { 783ce7a737cSKevin O'Sullivan int ret; 784ce7a737cSKevin O'Sullivan 785ce7a737cSKevin O'Sullivan /* Set content descriptor physical address */ 786ce7a737cSKevin O'Sullivan session->cd_paddr = session_paddr + 787ce7a737cSKevin O'Sullivan offsetof(struct qat_sym_session, cd); 788ce7a737cSKevin O'Sullivan 789ce7a737cSKevin O'Sullivan /* Set up some pre-requisite variables */ 790ce7a737cSKevin O'Sullivan session->qat_proto_flag = QAT_CRYPTO_PROTO_FLAG_NONE; 791ce7a737cSKevin O'Sullivan session->is_ucs = 0; 792ce7a737cSKevin O'Sullivan session->qat_cmd = ICP_QAT_FW_LA_CMD_CIPHER_CRC; 793ce7a737cSKevin O'Sullivan session->qat_mode = ICP_QAT_HW_CIPHER_CBC_MODE; 794ce7a737cSKevin O'Sullivan session->qat_cipher_alg = ICP_QAT_HW_CIPHER_ALGO_AES128; 795ce7a737cSKevin O'Sullivan session->qat_dir = ICP_QAT_HW_CIPHER_ENCRYPT; 796ce7a737cSKevin O'Sullivan session->is_auth = 1; 797ce7a737cSKevin O'Sullivan session->qat_hash_alg = ICP_QAT_HW_AUTH_ALGO_NULL; 798ce7a737cSKevin O'Sullivan session->auth_mode = ICP_QAT_HW_AUTH_MODE0; 799ce7a737cSKevin O'Sullivan session->auth_op = ICP_QAT_HW_AUTH_GENERATE; 800ce7a737cSKevin O'Sullivan session->digest_length = RTE_ETHER_CRC_LEN; 801ce7a737cSKevin O'Sullivan 802ce7a737cSKevin O'Sullivan ret = qat_sym_cd_cipher_set(session, cipherkey, cipherkeylen); 803ce7a737cSKevin O'Sullivan if (ret < 0) 804ce7a737cSKevin O'Sullivan return -EINVAL; 805ce7a737cSKevin O'Sullivan 806ce7a737cSKevin O'Sullivan ret = qat_sym_cd_crc_set(session, qat_dev_gen); 807ce7a737cSKevin O'Sullivan if (ret < 0) 808ce7a737cSKevin O'Sullivan return -EINVAL; 809ce7a737cSKevin O'Sullivan 810ce7a737cSKevin O'Sullivan qat_sym_session_finalize(session); 811ce7a737cSKevin O'Sullivan 812ce7a737cSKevin O'Sullivan return 0; 813ce7a737cSKevin O'Sullivan } 814ce7a737cSKevin O'Sullivan 815aa983f03SAdam Dybkowski static int 816faa57df0SArek Kusztal qat_sym_session_handle_single_pass(struct qat_sym_session *session, 8176618d3b5SArek Kusztal const struct rte_crypto_aead_xform *aead_xform) 818aa983f03SAdam Dybkowski { 819aa983f03SAdam Dybkowski session->is_single_pass = 1; 8206618d3b5SArek Kusztal session->is_auth = 1; 821aa983f03SAdam Dybkowski session->qat_cmd = ICP_QAT_FW_LA_CMD_CIPHER; 8226618d3b5SArek Kusztal /* Chacha-Poly is special case that use QAT CTR mode */ 823254558c8SKai Ji if (aead_xform->algo == RTE_CRYPTO_AEAD_AES_GCM) 824aa983f03SAdam Dybkowski session->qat_mode = ICP_QAT_HW_CIPHER_AEAD_MODE; 825254558c8SKai Ji else 826faa57df0SArek Kusztal session->qat_mode = ICP_QAT_HW_CIPHER_CTR_MODE; 827254558c8SKai Ji 828aa983f03SAdam Dybkowski session->cipher_iv.offset = aead_xform->iv.offset; 829aa983f03SAdam Dybkowski session->cipher_iv.length = aead_xform->iv.length; 830aa983f03SAdam Dybkowski session->aad_len = aead_xform->aad_length; 831aa983f03SAdam Dybkowski session->digest_length = aead_xform->digest_length; 8326618d3b5SArek Kusztal 833aa983f03SAdam Dybkowski if (aead_xform->op == RTE_CRYPTO_AEAD_OP_ENCRYPT) { 834aa983f03SAdam Dybkowski session->qat_dir = ICP_QAT_HW_CIPHER_ENCRYPT; 835aa983f03SAdam Dybkowski session->auth_op = ICP_QAT_HW_AUTH_GENERATE; 836aa983f03SAdam Dybkowski } else { 837aa983f03SAdam Dybkowski session->qat_dir = ICP_QAT_HW_CIPHER_DECRYPT; 838aa983f03SAdam Dybkowski session->auth_op = ICP_QAT_HW_AUTH_VERIFY; 839aa983f03SAdam Dybkowski } 840faa57df0SArek Kusztal 841aa983f03SAdam Dybkowski return 0; 842aa983f03SAdam Dybkowski } 843aa983f03SAdam Dybkowski 84498f06089SFiona Trahe int 845bba31cffSFiona Trahe qat_sym_session_configure_auth(struct rte_cryptodev *dev, 84698f06089SFiona Trahe struct rte_crypto_sym_xform *xform, 8476132b718SFiona Trahe struct qat_sym_session *session) 84898f06089SFiona Trahe { 84998f06089SFiona Trahe struct rte_crypto_auth_xform *auth_xform = qat_get_auth_xform(xform); 850f0f369a6SFan Zhang struct qat_cryptodev_private *internals = dev->data->dev_private; 851186b14d6SFan Zhang const uint8_t *key_data = auth_xform->key.data; 8526c868d6eSCiara Power uint16_t key_length = auth_xform->key.length; 853e4beb311SArek Kusztal enum qat_device_gen qat_dev_gen = 854e4beb311SArek Kusztal internals->qat_dev->qat_dev_gen; 8556c868d6eSCiara Power struct icp_qat_fw_la_bulk_req *req_tmpl = &session->fw_req; 8566c868d6eSCiara Power struct icp_qat_fw_comn_req_hdr *header = &req_tmpl->comn_hdr; 8576c868d6eSCiara Power struct icp_qat_fw_cipher_auth_cd_ctrl_hdr *cd_ctrl = 8586c868d6eSCiara Power (struct icp_qat_fw_cipher_auth_cd_ctrl_hdr *) 8596c868d6eSCiara Power session->fw_req.cd_ctrl.content_desc_ctrl_lw; 8606c868d6eSCiara Power uint8_t hash_flag = 0; 8616c868d6eSCiara Power int is_wireless = 0; 86298f06089SFiona Trahe 86345fe9ea9SAdam Dybkowski session->aes_cmac = 0; 86445fe9ea9SAdam Dybkowski session->auth_key_length = auth_xform->key.length; 8652165e2e9SArek Kusztal session->auth_iv.offset = auth_xform->iv.offset; 8662165e2e9SArek Kusztal session->auth_iv.length = auth_xform->iv.length; 8676e21c1a5SAdam Dybkowski session->auth_mode = ICP_QAT_HW_AUTH_MODE1; 8686618d3b5SArek Kusztal session->is_auth = 1; 869e4beb311SArek Kusztal session->digest_length = auth_xform->digest_length; 8702165e2e9SArek Kusztal 87198f06089SFiona Trahe switch (auth_xform->algo) { 87275fd4bbcSArek Kusztal case RTE_CRYPTO_AUTH_SM3: 87375fd4bbcSArek Kusztal session->qat_hash_alg = ICP_QAT_HW_AUTH_ALGO_SM3; 8746291de62SCiara Power session->auth_mode = ICP_QAT_HW_AUTH_MODE0; 87575fd4bbcSArek Kusztal break; 876171c655bSArkadiusz Kusztal case RTE_CRYPTO_AUTH_SM3_HMAC: 877171c655bSArkadiusz Kusztal session->qat_hash_alg = ICP_QAT_HW_AUTH_ALGO_SM3; 878171c655bSArkadiusz Kusztal session->auth_mode = ICP_QAT_HW_AUTH_MODE2; 879171c655bSArkadiusz Kusztal break; 8806e21c1a5SAdam Dybkowski case RTE_CRYPTO_AUTH_SHA1: 8816e21c1a5SAdam Dybkowski session->qat_hash_alg = ICP_QAT_HW_AUTH_ALGO_SHA1; 8826e21c1a5SAdam Dybkowski session->auth_mode = ICP_QAT_HW_AUTH_MODE0; 8836e21c1a5SAdam Dybkowski break; 8846e21c1a5SAdam Dybkowski case RTE_CRYPTO_AUTH_SHA224: 8856e21c1a5SAdam Dybkowski session->qat_hash_alg = ICP_QAT_HW_AUTH_ALGO_SHA224; 8866e21c1a5SAdam Dybkowski session->auth_mode = ICP_QAT_HW_AUTH_MODE0; 8876e21c1a5SAdam Dybkowski break; 8886e21c1a5SAdam Dybkowski case RTE_CRYPTO_AUTH_SHA256: 8896e21c1a5SAdam Dybkowski session->qat_hash_alg = ICP_QAT_HW_AUTH_ALGO_SHA256; 8906e21c1a5SAdam Dybkowski session->auth_mode = ICP_QAT_HW_AUTH_MODE0; 8916e21c1a5SAdam Dybkowski break; 8926e21c1a5SAdam Dybkowski case RTE_CRYPTO_AUTH_SHA384: 8936e21c1a5SAdam Dybkowski session->qat_hash_alg = ICP_QAT_HW_AUTH_ALGO_SHA384; 8946e21c1a5SAdam Dybkowski session->auth_mode = ICP_QAT_HW_AUTH_MODE0; 8956e21c1a5SAdam Dybkowski break; 8966e21c1a5SAdam Dybkowski case RTE_CRYPTO_AUTH_SHA512: 8976e21c1a5SAdam Dybkowski session->qat_hash_alg = ICP_QAT_HW_AUTH_ALGO_SHA512; 8986e21c1a5SAdam Dybkowski session->auth_mode = ICP_QAT_HW_AUTH_MODE0; 8996e21c1a5SAdam Dybkowski break; 9003a80d7fbSCiara Power case RTE_CRYPTO_AUTH_SHA3_224: 9013a80d7fbSCiara Power session->qat_hash_alg = ICP_QAT_HW_AUTH_ALGO_SHA3_224; 9023a80d7fbSCiara Power session->auth_mode = ICP_QAT_HW_AUTH_MODE0; 9033a80d7fbSCiara Power break; 9043a80d7fbSCiara Power case RTE_CRYPTO_AUTH_SHA3_256: 9053a80d7fbSCiara Power session->qat_hash_alg = ICP_QAT_HW_AUTH_ALGO_SHA3_256; 9063a80d7fbSCiara Power session->auth_mode = ICP_QAT_HW_AUTH_MODE0; 9073a80d7fbSCiara Power break; 9083a80d7fbSCiara Power case RTE_CRYPTO_AUTH_SHA3_384: 9093a80d7fbSCiara Power session->qat_hash_alg = ICP_QAT_HW_AUTH_ALGO_SHA3_384; 9103a80d7fbSCiara Power session->auth_mode = ICP_QAT_HW_AUTH_MODE0; 9113a80d7fbSCiara Power break; 9123a80d7fbSCiara Power case RTE_CRYPTO_AUTH_SHA3_512: 9133a80d7fbSCiara Power session->qat_hash_alg = ICP_QAT_HW_AUTH_ALGO_SHA3_512; 9143a80d7fbSCiara Power session->auth_mode = ICP_QAT_HW_AUTH_MODE0; 9153a80d7fbSCiara Power break; 91698f06089SFiona Trahe case RTE_CRYPTO_AUTH_SHA1_HMAC: 91798f06089SFiona Trahe session->qat_hash_alg = ICP_QAT_HW_AUTH_ALGO_SHA1; 91898f06089SFiona Trahe break; 91998f06089SFiona Trahe case RTE_CRYPTO_AUTH_SHA224_HMAC: 92098f06089SFiona Trahe session->qat_hash_alg = ICP_QAT_HW_AUTH_ALGO_SHA224; 92198f06089SFiona Trahe break; 92298f06089SFiona Trahe case RTE_CRYPTO_AUTH_SHA256_HMAC: 92398f06089SFiona Trahe session->qat_hash_alg = ICP_QAT_HW_AUTH_ALGO_SHA256; 92498f06089SFiona Trahe break; 92598f06089SFiona Trahe case RTE_CRYPTO_AUTH_SHA384_HMAC: 92698f06089SFiona Trahe session->qat_hash_alg = ICP_QAT_HW_AUTH_ALGO_SHA384; 92798f06089SFiona Trahe break; 92898f06089SFiona Trahe case RTE_CRYPTO_AUTH_SHA512_HMAC: 92998f06089SFiona Trahe session->qat_hash_alg = ICP_QAT_HW_AUTH_ALGO_SHA512; 93098f06089SFiona Trahe break; 93198f06089SFiona Trahe case RTE_CRYPTO_AUTH_AES_XCBC_MAC: 93298f06089SFiona Trahe session->qat_hash_alg = ICP_QAT_HW_AUTH_ALGO_AES_XCBC_MAC; 93398f06089SFiona Trahe break; 93491c1daa4STomasz Cel case RTE_CRYPTO_AUTH_AES_CMAC: 93591c1daa4STomasz Cel session->aes_cmac = 1; 936b7bd72d8SArkadiusz Kusztal if (!internals->qat_dev->options.has_wireless_slice) { 937210bea96SCiara Power session->qat_hash_alg = ICP_QAT_HW_AUTH_ALGO_AES_XCBC_MAC; 938210bea96SCiara Power break; 939210bea96SCiara Power } 9406c868d6eSCiara Power is_wireless = 1; 9416c868d6eSCiara Power session->is_wireless = 1; 942210bea96SCiara Power switch (key_length) { 943210bea96SCiara Power case ICP_QAT_HW_AES_128_KEY_SZ: 944210bea96SCiara Power session->qat_hash_alg = ICP_QAT_HW_AUTH_ALGO_AES_128_CMAC; 945210bea96SCiara Power break; 946210bea96SCiara Power default: 947210bea96SCiara Power QAT_LOG(ERR, "Invalid key length: %d", key_length); 948210bea96SCiara Power return -ENOTSUP; 9496c868d6eSCiara Power } 95091c1daa4STomasz Cel break; 95198f06089SFiona Trahe case RTE_CRYPTO_AUTH_AES_GMAC: 952bba31cffSFiona Trahe if (qat_sym_validate_aes_key(auth_xform->key.length, 95398f06089SFiona Trahe &session->qat_cipher_alg) != 0) { 954be24b0d9SFiona Trahe QAT_LOG(ERR, "Invalid AES key size"); 95598f06089SFiona Trahe return -EINVAL; 95698f06089SFiona Trahe } 95798f06089SFiona Trahe session->qat_mode = ICP_QAT_HW_CIPHER_CTR_MODE; 95898f06089SFiona Trahe session->qat_hash_alg = ICP_QAT_HW_AUTH_ALGO_GALOIS_128; 9592165e2e9SArek Kusztal if (session->auth_iv.length == 0) 9602165e2e9SArek Kusztal session->auth_iv.length = AES_GCM_J0_LEN; 9616618d3b5SArek Kusztal else 9626618d3b5SArek Kusztal session->is_iv12B = 1; 9632e98e808SArkadiusz Kusztal if (qat_dev_gen == QAT_GEN4 || qat_dev_gen == QAT_GEN5 || 9642e98e808SArkadiusz Kusztal qat_dev_gen == QAT_VQAT) { 965e4beb311SArek Kusztal session->is_cnt_zero = 1; 966e4beb311SArek Kusztal session->is_ucs = 1; 967e4beb311SArek Kusztal } 96898f06089SFiona Trahe break; 96998f06089SFiona Trahe case RTE_CRYPTO_AUTH_SNOW3G_UIA2: 97098f06089SFiona Trahe session->qat_hash_alg = ICP_QAT_HW_AUTH_ALGO_SNOW_3G_UIA2; 971b7bd72d8SArkadiusz Kusztal if (internals->qat_dev->options.has_wireless_slice) { 9726c868d6eSCiara Power is_wireless = 1; 9736c868d6eSCiara Power session->is_wireless = 1; 9746c868d6eSCiara Power hash_flag = 1 << ICP_QAT_FW_AUTH_HDR_FLAG_SNOW3G_UIA2_BITPOS; 9756c868d6eSCiara Power } 97698f06089SFiona Trahe break; 97798f06089SFiona Trahe case RTE_CRYPTO_AUTH_MD5_HMAC: 97898f06089SFiona Trahe session->qat_hash_alg = ICP_QAT_HW_AUTH_ALGO_MD5; 97998f06089SFiona Trahe break; 98098f06089SFiona Trahe case RTE_CRYPTO_AUTH_NULL: 98198f06089SFiona Trahe session->qat_hash_alg = ICP_QAT_HW_AUTH_ALGO_NULL; 98298f06089SFiona Trahe break; 98398f06089SFiona Trahe case RTE_CRYPTO_AUTH_KASUMI_F9: 98498f06089SFiona Trahe session->qat_hash_alg = ICP_QAT_HW_AUTH_ALGO_KASUMI_F9; 98598f06089SFiona Trahe break; 98698f06089SFiona Trahe case RTE_CRYPTO_AUTH_ZUC_EIA3: 98798f06089SFiona Trahe if (!qat_is_auth_alg_supported(auth_xform->algo, internals)) { 988be24b0d9SFiona Trahe QAT_LOG(ERR, "%s not supported on this device", 9897e1e1277SAkhil Goyal rte_cryptodev_get_auth_algo_string(auth_xform->algo)); 99098f06089SFiona Trahe return -ENOTSUP; 99198f06089SFiona Trahe } 9926c868d6eSCiara Power if (key_length == ICP_QAT_HW_ZUC_3G_EEA3_KEY_SZ) 99398f06089SFiona Trahe session->qat_hash_alg = ICP_QAT_HW_AUTH_ALGO_ZUC_3G_128_EIA3; 9946c868d6eSCiara Power else if (key_length == ICP_QAT_HW_ZUC_256_KEY_SZ) { 9956c868d6eSCiara Power switch (auth_xform->digest_length) { 9966c868d6eSCiara Power case 4: 9976c868d6eSCiara Power session->qat_hash_alg = ICP_QAT_HW_AUTH_ALGO_ZUC_256_MAC_32; 9986c868d6eSCiara Power break; 9996c868d6eSCiara Power case 8: 10006c868d6eSCiara Power session->qat_hash_alg = ICP_QAT_HW_AUTH_ALGO_ZUC_256_MAC_64; 10016c868d6eSCiara Power break; 10026c868d6eSCiara Power case 16: 10036c868d6eSCiara Power session->qat_hash_alg = ICP_QAT_HW_AUTH_ALGO_ZUC_256_MAC_128; 10046c868d6eSCiara Power break; 10056c868d6eSCiara Power default: 10066c868d6eSCiara Power QAT_LOG(ERR, "Invalid digest length: %d", 10076c868d6eSCiara Power auth_xform->digest_length); 10086c868d6eSCiara Power return -ENOTSUP; 10096c868d6eSCiara Power } 10106c868d6eSCiara Power session->is_zuc256 = 1; 10116c868d6eSCiara Power } else { 10126c868d6eSCiara Power QAT_LOG(ERR, "Invalid key length: %d", key_length); 10136c868d6eSCiara Power return -ENOTSUP; 10146c868d6eSCiara Power } 1015b7bd72d8SArkadiusz Kusztal if (internals->qat_dev->options.has_wireless_slice) { 10166c868d6eSCiara Power is_wireless = 1; 10176c868d6eSCiara Power session->is_wireless = 1; 10186c868d6eSCiara Power hash_flag = 1 << ICP_QAT_FW_AUTH_HDR_FLAG_ZUC_EIA3_BITPOS; 10196c868d6eSCiara Power } else 10206c868d6eSCiara Power session->auth_mode = ICP_QAT_HW_AUTH_MODE0; 102198f06089SFiona Trahe break; 102298f06089SFiona Trahe case RTE_CRYPTO_AUTH_MD5: 102398f06089SFiona Trahe case RTE_CRYPTO_AUTH_AES_CBC_MAC: 1024be24b0d9SFiona Trahe QAT_LOG(ERR, "Crypto: Unsupported hash alg %u", 102598f06089SFiona Trahe auth_xform->algo); 102698f06089SFiona Trahe return -ENOTSUP; 102798f06089SFiona Trahe default: 1028be24b0d9SFiona Trahe QAT_LOG(ERR, "Crypto: Undefined Hash algo %u specified", 102998f06089SFiona Trahe auth_xform->algo); 103098f06089SFiona Trahe return -EINVAL; 103198f06089SFiona Trahe } 103298f06089SFiona Trahe 103398f06089SFiona Trahe if (auth_xform->algo == RTE_CRYPTO_AUTH_AES_GMAC) { 10346618d3b5SArek Kusztal session->is_gmac = 1; 103598f06089SFiona Trahe if (auth_xform->op == RTE_CRYPTO_AUTH_OP_GENERATE) { 103698f06089SFiona Trahe session->qat_cmd = ICP_QAT_FW_LA_CMD_CIPHER_HASH; 103798f06089SFiona Trahe session->qat_dir = ICP_QAT_HW_CIPHER_ENCRYPT; 103898f06089SFiona Trahe /* 103998f06089SFiona Trahe * It needs to create cipher desc content first, 104098f06089SFiona Trahe * then authentication 104198f06089SFiona Trahe */ 1042bfe16f14SArek Kusztal if (qat_sym_cd_cipher_set(session, 104398f06089SFiona Trahe auth_xform->key.data, 104498f06089SFiona Trahe auth_xform->key.length)) 104598f06089SFiona Trahe return -EINVAL; 104698f06089SFiona Trahe 1047bfe16f14SArek Kusztal if (qat_sym_cd_auth_set(session, 104898f06089SFiona Trahe key_data, 104998f06089SFiona Trahe key_length, 105098f06089SFiona Trahe 0, 105198f06089SFiona Trahe auth_xform->digest_length, 1052171c655bSArkadiusz Kusztal auth_xform->op, 1053171c655bSArkadiusz Kusztal qat_dev_gen)) 105498f06089SFiona Trahe return -EINVAL; 105598f06089SFiona Trahe } else { 105698f06089SFiona Trahe session->qat_cmd = ICP_QAT_FW_LA_CMD_HASH_CIPHER; 105798f06089SFiona Trahe session->qat_dir = ICP_QAT_HW_CIPHER_DECRYPT; 105898f06089SFiona Trahe /* 105998f06089SFiona Trahe * It needs to create authentication desc content first, 106098f06089SFiona Trahe * then cipher 106198f06089SFiona Trahe */ 1062bba31cffSFiona Trahe 1063bfe16f14SArek Kusztal if (qat_sym_cd_auth_set(session, 106498f06089SFiona Trahe key_data, 106598f06089SFiona Trahe key_length, 106698f06089SFiona Trahe 0, 106798f06089SFiona Trahe auth_xform->digest_length, 1068171c655bSArkadiusz Kusztal auth_xform->op, 1069171c655bSArkadiusz Kusztal qat_dev_gen)) 107098f06089SFiona Trahe return -EINVAL; 107198f06089SFiona Trahe 1072bfe16f14SArek Kusztal if (qat_sym_cd_cipher_set(session, 107398f06089SFiona Trahe auth_xform->key.data, 107498f06089SFiona Trahe auth_xform->key.length)) 107598f06089SFiona Trahe return -EINVAL; 107698f06089SFiona Trahe } 107798f06089SFiona Trahe } else { 1078bfe16f14SArek Kusztal if (qat_sym_cd_auth_set(session, 107998f06089SFiona Trahe key_data, 108098f06089SFiona Trahe key_length, 108198f06089SFiona Trahe 0, 108298f06089SFiona Trahe auth_xform->digest_length, 1083171c655bSArkadiusz Kusztal auth_xform->op, 1084171c655bSArkadiusz Kusztal qat_dev_gen)) 108598f06089SFiona Trahe return -EINVAL; 108698f06089SFiona Trahe } 108798f06089SFiona Trahe 10886c868d6eSCiara Power if (is_wireless) { 10896c868d6eSCiara Power if (!session->aes_cmac) { 10906c868d6eSCiara Power /* Set the Use Extended Protocol Flags bit in LW 1 */ 10916c868d6eSCiara Power ICP_QAT_FW_USE_EXTENDED_PROTOCOL_FLAGS_SET( 10926c868d6eSCiara Power header->ext_flags, 10936c868d6eSCiara Power QAT_LA_USE_EXTENDED_PROTOCOL_FLAGS); 10946c868d6eSCiara Power 10956c868d6eSCiara Power /* Set Hash Flags in LW 28 */ 10966c868d6eSCiara Power cd_ctrl->hash_flags |= hash_flag; 10976c868d6eSCiara Power } 10986c868d6eSCiara Power /* Force usage of Wireless Auth slice */ 10996c868d6eSCiara Power ICP_QAT_FW_USE_WAT_SLICE_SET(header->ext_flags, 11006c868d6eSCiara Power QAT_LA_USE_WAT_SLICE); 11016c868d6eSCiara Power } 11026c868d6eSCiara Power 110398f06089SFiona Trahe return 0; 110498f06089SFiona Trahe } 110598f06089SFiona Trahe 110698f06089SFiona Trahe int 1107aa983f03SAdam Dybkowski qat_sym_session_configure_aead(struct rte_cryptodev *dev, 1108aa983f03SAdam Dybkowski struct rte_crypto_sym_xform *xform, 11096132b718SFiona Trahe struct qat_sym_session *session) 111098f06089SFiona Trahe { 111198f06089SFiona Trahe struct rte_crypto_aead_xform *aead_xform = &xform->aead; 111298f06089SFiona Trahe enum rte_crypto_auth_operation crypto_operation; 1113f0f369a6SFan Zhang struct qat_cryptodev_private *internals = 1114faa57df0SArek Kusztal dev->data->dev_private; 1115faa57df0SArek Kusztal enum qat_device_gen qat_dev_gen = 1116faa57df0SArek Kusztal internals->qat_dev->qat_dev_gen; 1117e2c11053SNishikant Nayak if (qat_dev_gen == QAT_GEN_LCE) { 1118e2c11053SNishikant Nayak struct icp_qat_fw_la_bulk_req *req_tmpl = &session->fw_req; 1119e2c11053SNishikant Nayak struct lce_key_buff_desc *key_buff = &req_tmpl->key_buff; 1120e2c11053SNishikant Nayak 1121e2c11053SNishikant Nayak key_buff->keybuff = session->key_paddr; 1122e2c11053SNishikant Nayak } 112398f06089SFiona Trahe 112498f06089SFiona Trahe /* 112598f06089SFiona Trahe * Store AEAD IV parameters as cipher IV, 112698f06089SFiona Trahe * to avoid unnecessary memory usage 112798f06089SFiona Trahe */ 112898f06089SFiona Trahe session->cipher_iv.offset = xform->aead.iv.offset; 112998f06089SFiona Trahe session->cipher_iv.length = xform->aead.iv.length; 113098f06089SFiona Trahe 11316e21c1a5SAdam Dybkowski session->auth_mode = ICP_QAT_HW_AUTH_MODE1; 11326618d3b5SArek Kusztal session->is_auth = 1; 11336618d3b5SArek Kusztal session->digest_length = aead_xform->digest_length; 11346e21c1a5SAdam Dybkowski 1135faa57df0SArek Kusztal session->is_single_pass = 0; 113698f06089SFiona Trahe switch (aead_xform->algo) { 113798f06089SFiona Trahe case RTE_CRYPTO_AEAD_AES_GCM: 1138bba31cffSFiona Trahe if (qat_sym_validate_aes_key(aead_xform->key.length, 113998f06089SFiona Trahe &session->qat_cipher_alg) != 0) { 1140be24b0d9SFiona Trahe QAT_LOG(ERR, "Invalid AES key size"); 114198f06089SFiona Trahe return -EINVAL; 114298f06089SFiona Trahe } 114398f06089SFiona Trahe session->qat_mode = ICP_QAT_HW_CIPHER_CTR_MODE; 1144f5862ae9SThomas Monjalon session->qat_hash_alg = ICP_QAT_HW_AUTH_ALGO_GALOIS_128; 11456618d3b5SArek Kusztal 11462e98e808SArkadiusz Kusztal if (qat_dev_gen == QAT_GEN4 || qat_dev_gen == QAT_GEN5 || 11472e98e808SArkadiusz Kusztal qat_dev_gen == QAT_VQAT) 11486599d093SArek Kusztal session->is_ucs = 1; 11496618d3b5SArek Kusztal if (session->cipher_iv.length == 0) { 11506618d3b5SArek Kusztal session->cipher_iv.length = AES_GCM_J0_LEN; 11516618d3b5SArek Kusztal break; 11526618d3b5SArek Kusztal } 11536618d3b5SArek Kusztal session->is_iv12B = 1; 11543e7a5a12SArek Kusztal if (qat_dev_gen < QAT_GEN3) 11553e7a5a12SArek Kusztal break; 11566618d3b5SArek Kusztal qat_sym_session_handle_single_pass(session, 11576618d3b5SArek Kusztal aead_xform); 115898f06089SFiona Trahe break; 115998f06089SFiona Trahe case RTE_CRYPTO_AEAD_AES_CCM: 1160bba31cffSFiona Trahe if (qat_sym_validate_aes_key(aead_xform->key.length, 116198f06089SFiona Trahe &session->qat_cipher_alg) != 0) { 1162be24b0d9SFiona Trahe QAT_LOG(ERR, "Invalid AES key size"); 116398f06089SFiona Trahe return -EINVAL; 116498f06089SFiona Trahe } 116598f06089SFiona Trahe session->qat_mode = ICP_QAT_HW_CIPHER_CTR_MODE; 116698f06089SFiona Trahe session->qat_hash_alg = ICP_QAT_HW_AUTH_ALGO_AES_CBC_MAC; 11672e98e808SArkadiusz Kusztal if (qat_dev_gen == QAT_GEN4 || qat_dev_gen == QAT_GEN5 || 11682e98e808SArkadiusz Kusztal qat_dev_gen == QAT_VQAT) 11696599d093SArek Kusztal session->is_ucs = 1; 117098f06089SFiona Trahe break; 1171faa57df0SArek Kusztal case RTE_CRYPTO_AEAD_CHACHA20_POLY1305: 1172faa57df0SArek Kusztal if (aead_xform->key.length != ICP_QAT_HW_CHACHAPOLY_KEY_SZ) 1173faa57df0SArek Kusztal return -EINVAL; 11742e98e808SArkadiusz Kusztal if (qat_dev_gen == QAT_GEN4 || qat_dev_gen == QAT_GEN5 || 11752e98e808SArkadiusz Kusztal qat_dev_gen == QAT_VQAT) 1176c2c1ccaeSArek Kusztal session->is_ucs = 1; 1177faa57df0SArek Kusztal session->qat_cipher_alg = 1178faa57df0SArek Kusztal ICP_QAT_HW_CIPHER_ALGO_CHACHA20_POLY1305; 11796618d3b5SArek Kusztal qat_sym_session_handle_single_pass(session, 1180faa57df0SArek Kusztal aead_xform); 11816618d3b5SArek Kusztal break; 118298f06089SFiona Trahe default: 1183*f665790aSDavid Marchand QAT_LOG(ERR, "Crypto: Undefined AEAD specified %u", 118498f06089SFiona Trahe aead_xform->algo); 118598f06089SFiona Trahe return -EINVAL; 118698f06089SFiona Trahe } 118798f06089SFiona Trahe 11886618d3b5SArek Kusztal if (session->is_single_pass) { 1189e2c11053SNishikant Nayak if (qat_dev_gen != QAT_GEN_LCE) { 11906618d3b5SArek Kusztal if (qat_sym_cd_cipher_set(session, 11916618d3b5SArek Kusztal aead_xform->key.data, aead_xform->key.length)) 11926618d3b5SArek Kusztal return -EINVAL; 1193e2c11053SNishikant Nayak } else { 1194e2c11053SNishikant Nayak session->auth_key_length = aead_xform->key.length; 1195e2c11053SNishikant Nayak memcpy(session->key_array, aead_xform->key.data, aead_xform->key.length); 1196e2c11053SNishikant Nayak } 11976618d3b5SArek Kusztal } else if ((aead_xform->op == RTE_CRYPTO_AEAD_OP_ENCRYPT && 119898f06089SFiona Trahe aead_xform->algo == RTE_CRYPTO_AEAD_AES_GCM) || 119998f06089SFiona Trahe (aead_xform->op == RTE_CRYPTO_AEAD_OP_DECRYPT && 120098f06089SFiona Trahe aead_xform->algo == RTE_CRYPTO_AEAD_AES_CCM)) { 120198f06089SFiona Trahe session->qat_dir = ICP_QAT_HW_CIPHER_ENCRYPT; 120298f06089SFiona Trahe /* 120398f06089SFiona Trahe * It needs to create cipher desc content first, 120498f06089SFiona Trahe * then authentication 120598f06089SFiona Trahe */ 120698f06089SFiona Trahe crypto_operation = aead_xform->algo == RTE_CRYPTO_AEAD_AES_GCM ? 120798f06089SFiona Trahe RTE_CRYPTO_AUTH_OP_GENERATE : RTE_CRYPTO_AUTH_OP_VERIFY; 120898f06089SFiona Trahe 1209bfe16f14SArek Kusztal if (qat_sym_cd_cipher_set(session, 121098f06089SFiona Trahe aead_xform->key.data, 121198f06089SFiona Trahe aead_xform->key.length)) 121298f06089SFiona Trahe return -EINVAL; 121398f06089SFiona Trahe 1214bfe16f14SArek Kusztal if (qat_sym_cd_auth_set(session, 121598f06089SFiona Trahe aead_xform->key.data, 121698f06089SFiona Trahe aead_xform->key.length, 121798f06089SFiona Trahe aead_xform->aad_length, 121898f06089SFiona Trahe aead_xform->digest_length, 1219171c655bSArkadiusz Kusztal crypto_operation, 1220171c655bSArkadiusz Kusztal qat_dev_gen)) 122198f06089SFiona Trahe return -EINVAL; 122298f06089SFiona Trahe } else { 122398f06089SFiona Trahe session->qat_dir = ICP_QAT_HW_CIPHER_DECRYPT; 122498f06089SFiona Trahe /* 122598f06089SFiona Trahe * It needs to create authentication desc content first, 122698f06089SFiona Trahe * then cipher 122798f06089SFiona Trahe */ 122898f06089SFiona Trahe 122998f06089SFiona Trahe crypto_operation = aead_xform->algo == RTE_CRYPTO_AEAD_AES_GCM ? 123098f06089SFiona Trahe RTE_CRYPTO_AUTH_OP_VERIFY : RTE_CRYPTO_AUTH_OP_GENERATE; 123198f06089SFiona Trahe 1232bfe16f14SArek Kusztal if (qat_sym_cd_auth_set(session, 123398f06089SFiona Trahe aead_xform->key.data, 123498f06089SFiona Trahe aead_xform->key.length, 123598f06089SFiona Trahe aead_xform->aad_length, 123698f06089SFiona Trahe aead_xform->digest_length, 1237171c655bSArkadiusz Kusztal crypto_operation, 1238171c655bSArkadiusz Kusztal qat_dev_gen)) 123998f06089SFiona Trahe return -EINVAL; 124098f06089SFiona Trahe 1241bfe16f14SArek Kusztal if (qat_sym_cd_cipher_set(session, 124298f06089SFiona Trahe aead_xform->key.data, 124398f06089SFiona Trahe aead_xform->key.length)) 124498f06089SFiona Trahe return -EINVAL; 124598f06089SFiona Trahe } 124698f06089SFiona Trahe 124798f06089SFiona Trahe return 0; 124898f06089SFiona Trahe } 124998f06089SFiona Trahe 1250bba31cffSFiona Trahe unsigned int qat_sym_session_get_private_size( 125198f06089SFiona Trahe struct rte_cryptodev *dev __rte_unused) 125298f06089SFiona Trahe { 12536132b718SFiona Trahe return RTE_ALIGN_CEIL(sizeof(struct qat_sym_session), 8); 125498f06089SFiona Trahe } 125598f06089SFiona Trahe 125698f06089SFiona Trahe /* returns block size in bytes per cipher algo */ 125798f06089SFiona Trahe int qat_cipher_get_block_size(enum icp_qat_hw_cipher_algo qat_cipher_alg) 125898f06089SFiona Trahe { 125998f06089SFiona Trahe switch (qat_cipher_alg) { 126098f06089SFiona Trahe case ICP_QAT_HW_CIPHER_ALGO_DES: 126198f06089SFiona Trahe return ICP_QAT_HW_DES_BLK_SZ; 126298f06089SFiona Trahe case ICP_QAT_HW_CIPHER_ALGO_3DES: 126398f06089SFiona Trahe return ICP_QAT_HW_3DES_BLK_SZ; 126498f06089SFiona Trahe case ICP_QAT_HW_CIPHER_ALGO_AES128: 126598f06089SFiona Trahe case ICP_QAT_HW_CIPHER_ALGO_AES192: 126698f06089SFiona Trahe case ICP_QAT_HW_CIPHER_ALGO_AES256: 126798f06089SFiona Trahe return ICP_QAT_HW_AES_BLK_SZ; 126898f06089SFiona Trahe default: 1269be24b0d9SFiona Trahe QAT_LOG(ERR, "invalid block cipher alg %u", qat_cipher_alg); 127098f06089SFiona Trahe return -EFAULT; 127198f06089SFiona Trahe }; 127298f06089SFiona Trahe return -EFAULT; 127398f06089SFiona Trahe } 127498f06089SFiona Trahe 127598f06089SFiona Trahe /* 127698f06089SFiona Trahe * Returns size in bytes per hash algo for state1 size field in cd_ctrl 127798f06089SFiona Trahe * This is digest size rounded up to nearest quadword 127898f06089SFiona Trahe */ 127998f06089SFiona Trahe static int qat_hash_get_state1_size(enum icp_qat_hw_auth_algo qat_hash_alg) 128098f06089SFiona Trahe { 128198f06089SFiona Trahe switch (qat_hash_alg) { 128298f06089SFiona Trahe case ICP_QAT_HW_AUTH_ALGO_SHA1: 128398f06089SFiona Trahe return QAT_HW_ROUND_UP(ICP_QAT_HW_SHA1_STATE1_SZ, 128498f06089SFiona Trahe QAT_HW_DEFAULT_ALIGNMENT); 128598f06089SFiona Trahe case ICP_QAT_HW_AUTH_ALGO_SHA224: 128698f06089SFiona Trahe return QAT_HW_ROUND_UP(ICP_QAT_HW_SHA224_STATE1_SZ, 128798f06089SFiona Trahe QAT_HW_DEFAULT_ALIGNMENT); 128898f06089SFiona Trahe case ICP_QAT_HW_AUTH_ALGO_SHA256: 128998f06089SFiona Trahe return QAT_HW_ROUND_UP(ICP_QAT_HW_SHA256_STATE1_SZ, 129098f06089SFiona Trahe QAT_HW_DEFAULT_ALIGNMENT); 129198f06089SFiona Trahe case ICP_QAT_HW_AUTH_ALGO_SHA384: 129298f06089SFiona Trahe return QAT_HW_ROUND_UP(ICP_QAT_HW_SHA384_STATE1_SZ, 129398f06089SFiona Trahe QAT_HW_DEFAULT_ALIGNMENT); 129498f06089SFiona Trahe case ICP_QAT_HW_AUTH_ALGO_SHA512: 129598f06089SFiona Trahe return QAT_HW_ROUND_UP(ICP_QAT_HW_SHA512_STATE1_SZ, 129698f06089SFiona Trahe QAT_HW_DEFAULT_ALIGNMENT); 12973a80d7fbSCiara Power case ICP_QAT_HW_AUTH_ALGO_SHA3_224: 12983a80d7fbSCiara Power return QAT_HW_ROUND_UP(ICP_QAT_HW_SHA3_224_STATE1_SZ, 12993a80d7fbSCiara Power QAT_HW_DEFAULT_ALIGNMENT); 13003a80d7fbSCiara Power case ICP_QAT_HW_AUTH_ALGO_SHA3_256: 13013a80d7fbSCiara Power return QAT_HW_ROUND_UP(ICP_QAT_HW_SHA3_256_STATE1_SZ, 13023a80d7fbSCiara Power QAT_HW_DEFAULT_ALIGNMENT); 13033a80d7fbSCiara Power case ICP_QAT_HW_AUTH_ALGO_SHA3_384: 13043a80d7fbSCiara Power return QAT_HW_ROUND_UP(ICP_QAT_HW_SHA3_384_STATE1_SZ, 13053a80d7fbSCiara Power QAT_HW_DEFAULT_ALIGNMENT); 13063a80d7fbSCiara Power case ICP_QAT_HW_AUTH_ALGO_SHA3_512: 13073a80d7fbSCiara Power return QAT_HW_ROUND_UP(ICP_QAT_HW_SHA3_512_STATE1_SZ, 13083a80d7fbSCiara Power QAT_HW_DEFAULT_ALIGNMENT); 130998f06089SFiona Trahe case ICP_QAT_HW_AUTH_ALGO_AES_XCBC_MAC: 131098f06089SFiona Trahe return QAT_HW_ROUND_UP(ICP_QAT_HW_AES_XCBC_MAC_STATE1_SZ, 131198f06089SFiona Trahe QAT_HW_DEFAULT_ALIGNMENT); 131298f06089SFiona Trahe case ICP_QAT_HW_AUTH_ALGO_GALOIS_128: 131398f06089SFiona Trahe case ICP_QAT_HW_AUTH_ALGO_GALOIS_64: 131498f06089SFiona Trahe return QAT_HW_ROUND_UP(ICP_QAT_HW_GALOIS_128_STATE1_SZ, 131598f06089SFiona Trahe QAT_HW_DEFAULT_ALIGNMENT); 131698f06089SFiona Trahe case ICP_QAT_HW_AUTH_ALGO_ZUC_3G_128_EIA3: 131798f06089SFiona Trahe return QAT_HW_ROUND_UP(ICP_QAT_HW_ZUC_3G_EIA3_STATE1_SZ, 131898f06089SFiona Trahe QAT_HW_DEFAULT_ALIGNMENT); 13196c868d6eSCiara Power case ICP_QAT_HW_AUTH_ALGO_ZUC_256_MAC_32: 13206c868d6eSCiara Power return QAT_HW_ROUND_UP(ICP_QAT_HW_ZUC_256_MAC_32_STATE1_SZ, 13216c868d6eSCiara Power QAT_HW_DEFAULT_ALIGNMENT); 13226c868d6eSCiara Power case ICP_QAT_HW_AUTH_ALGO_ZUC_256_MAC_64: 13236c868d6eSCiara Power return QAT_HW_ROUND_UP(ICP_QAT_HW_ZUC_256_MAC_64_STATE1_SZ, 13246c868d6eSCiara Power QAT_HW_DEFAULT_ALIGNMENT); 13256c868d6eSCiara Power case ICP_QAT_HW_AUTH_ALGO_ZUC_256_MAC_128: 13266c868d6eSCiara Power return QAT_HW_ROUND_UP(ICP_QAT_HW_ZUC_256_MAC_128_STATE1_SZ, 13276c868d6eSCiara Power QAT_HW_DEFAULT_ALIGNMENT); 132898f06089SFiona Trahe case ICP_QAT_HW_AUTH_ALGO_SNOW_3G_UIA2: 132998f06089SFiona Trahe return QAT_HW_ROUND_UP(ICP_QAT_HW_SNOW_3G_UIA2_STATE1_SZ, 133098f06089SFiona Trahe QAT_HW_DEFAULT_ALIGNMENT); 133198f06089SFiona Trahe case ICP_QAT_HW_AUTH_ALGO_MD5: 133298f06089SFiona Trahe return QAT_HW_ROUND_UP(ICP_QAT_HW_MD5_STATE1_SZ, 133398f06089SFiona Trahe QAT_HW_DEFAULT_ALIGNMENT); 133498f06089SFiona Trahe case ICP_QAT_HW_AUTH_ALGO_KASUMI_F9: 133598f06089SFiona Trahe return QAT_HW_ROUND_UP(ICP_QAT_HW_KASUMI_F9_STATE1_SZ, 133698f06089SFiona Trahe QAT_HW_DEFAULT_ALIGNMENT); 133798f06089SFiona Trahe case ICP_QAT_HW_AUTH_ALGO_AES_CBC_MAC: 133898f06089SFiona Trahe return QAT_HW_ROUND_UP(ICP_QAT_HW_AES_CBC_MAC_STATE1_SZ, 133998f06089SFiona Trahe QAT_HW_DEFAULT_ALIGNMENT); 134075fd4bbcSArek Kusztal case ICP_QAT_HW_AUTH_ALGO_SM3: 134175fd4bbcSArek Kusztal return QAT_HW_ROUND_UP(ICP_QAT_HW_SM3_STATE1_SZ, 134275fd4bbcSArek Kusztal QAT_HW_DEFAULT_ALIGNMENT); 134398f06089SFiona Trahe case ICP_QAT_HW_AUTH_ALGO_NULL: 134498f06089SFiona Trahe return QAT_HW_ROUND_UP(ICP_QAT_HW_NULL_STATE1_SZ, 134598f06089SFiona Trahe QAT_HW_DEFAULT_ALIGNMENT); 1346210bea96SCiara Power case ICP_QAT_HW_AUTH_ALGO_AES_128_CMAC: 1347210bea96SCiara Power return QAT_HW_ROUND_UP(ICP_QAT_HW_AES_CMAC_STATE1_SZ, 1348210bea96SCiara Power QAT_HW_DEFAULT_ALIGNMENT); 134998f06089SFiona Trahe case ICP_QAT_HW_AUTH_ALGO_DELIMITER: 135098f06089SFiona Trahe /* return maximum state1 size in this case */ 135198f06089SFiona Trahe return QAT_HW_ROUND_UP(ICP_QAT_HW_SHA512_STATE1_SZ, 135298f06089SFiona Trahe QAT_HW_DEFAULT_ALIGNMENT); 135398f06089SFiona Trahe default: 1354be24b0d9SFiona Trahe QAT_LOG(ERR, "invalid hash alg %u", qat_hash_alg); 135598f06089SFiona Trahe return -EFAULT; 135698f06089SFiona Trahe }; 135798f06089SFiona Trahe return -EFAULT; 135898f06089SFiona Trahe } 135998f06089SFiona Trahe 136098f06089SFiona Trahe /* returns digest size in bytes per hash algo */ 136198f06089SFiona Trahe static int qat_hash_get_digest_size(enum icp_qat_hw_auth_algo qat_hash_alg) 136298f06089SFiona Trahe { 136398f06089SFiona Trahe switch (qat_hash_alg) { 136498f06089SFiona Trahe case ICP_QAT_HW_AUTH_ALGO_SHA1: 136598f06089SFiona Trahe return ICP_QAT_HW_SHA1_STATE1_SZ; 136698f06089SFiona Trahe case ICP_QAT_HW_AUTH_ALGO_SHA224: 136798f06089SFiona Trahe return ICP_QAT_HW_SHA224_STATE1_SZ; 136898f06089SFiona Trahe case ICP_QAT_HW_AUTH_ALGO_SHA256: 136998f06089SFiona Trahe return ICP_QAT_HW_SHA256_STATE1_SZ; 137098f06089SFiona Trahe case ICP_QAT_HW_AUTH_ALGO_SHA384: 137198f06089SFiona Trahe return ICP_QAT_HW_SHA384_STATE1_SZ; 137298f06089SFiona Trahe case ICP_QAT_HW_AUTH_ALGO_SHA512: 137398f06089SFiona Trahe return ICP_QAT_HW_SHA512_STATE1_SZ; 13743a80d7fbSCiara Power case ICP_QAT_HW_AUTH_ALGO_SHA3_224: 13753a80d7fbSCiara Power return ICP_QAT_HW_SHA3_224_STATE1_SZ; 13763a80d7fbSCiara Power case ICP_QAT_HW_AUTH_ALGO_SHA3_256: 13773a80d7fbSCiara Power return ICP_QAT_HW_SHA3_256_STATE1_SZ; 13783a80d7fbSCiara Power case ICP_QAT_HW_AUTH_ALGO_SHA3_384: 13793a80d7fbSCiara Power return ICP_QAT_HW_SHA3_384_STATE1_SZ; 13803a80d7fbSCiara Power case ICP_QAT_HW_AUTH_ALGO_SHA3_512: 13813a80d7fbSCiara Power return ICP_QAT_HW_SHA3_512_STATE1_SZ; 138298f06089SFiona Trahe case ICP_QAT_HW_AUTH_ALGO_MD5: 138398f06089SFiona Trahe return ICP_QAT_HW_MD5_STATE1_SZ; 138491c1daa4STomasz Cel case ICP_QAT_HW_AUTH_ALGO_AES_XCBC_MAC: 1385210bea96SCiara Power case ICP_QAT_HW_AUTH_ALGO_AES_128_CMAC: 138691c1daa4STomasz Cel return ICP_QAT_HW_AES_XCBC_MAC_STATE1_SZ; 138798f06089SFiona Trahe case ICP_QAT_HW_AUTH_ALGO_DELIMITER: 138898f06089SFiona Trahe /* return maximum digest size in this case */ 138998f06089SFiona Trahe return ICP_QAT_HW_SHA512_STATE1_SZ; 139098f06089SFiona Trahe default: 1391be24b0d9SFiona Trahe QAT_LOG(ERR, "invalid hash alg %u", qat_hash_alg); 139298f06089SFiona Trahe return -EFAULT; 139398f06089SFiona Trahe }; 139498f06089SFiona Trahe return -EFAULT; 139598f06089SFiona Trahe } 139698f06089SFiona Trahe 139798f06089SFiona Trahe /* returns block size in byes per hash algo */ 139898f06089SFiona Trahe static int qat_hash_get_block_size(enum icp_qat_hw_auth_algo qat_hash_alg) 139998f06089SFiona Trahe { 140098f06089SFiona Trahe switch (qat_hash_alg) { 140198f06089SFiona Trahe case ICP_QAT_HW_AUTH_ALGO_SHA1: 140298f06089SFiona Trahe case ICP_QAT_HW_AUTH_ALGO_SHA224: 140398f06089SFiona Trahe case ICP_QAT_HW_AUTH_ALGO_SHA256: 140462126a92SCiara Power return QAT_SHA_CBLOCK; 140598f06089SFiona Trahe case ICP_QAT_HW_AUTH_ALGO_SHA384: 140698f06089SFiona Trahe case ICP_QAT_HW_AUTH_ALGO_SHA512: 140762126a92SCiara Power return QAT_SHA512_CBLOCK; 140898f06089SFiona Trahe case ICP_QAT_HW_AUTH_ALGO_GALOIS_128: 140998f06089SFiona Trahe return 16; 141091c1daa4STomasz Cel case ICP_QAT_HW_AUTH_ALGO_AES_XCBC_MAC: 141191c1daa4STomasz Cel return ICP_QAT_HW_AES_BLK_SZ; 141298f06089SFiona Trahe case ICP_QAT_HW_AUTH_ALGO_MD5: 141362126a92SCiara Power return QAT_MD5_CBLOCK; 14146c868d6eSCiara Power case ICP_QAT_HW_AUTH_ALGO_ZUC_256_MAC_32: 14156c868d6eSCiara Power case ICP_QAT_HW_AUTH_ALGO_ZUC_256_MAC_64: 14166c868d6eSCiara Power case ICP_QAT_HW_AUTH_ALGO_ZUC_256_MAC_128: 14176c868d6eSCiara Power return ICP_QAT_HW_ZUC_256_BLK_SZ; 141898f06089SFiona Trahe case ICP_QAT_HW_AUTH_ALGO_DELIMITER: 141998f06089SFiona Trahe /* return maximum block size in this case */ 142062126a92SCiara Power return QAT_SHA512_CBLOCK; 1421171c655bSArkadiusz Kusztal case ICP_QAT_HW_AUTH_ALGO_SM3: 1422171c655bSArkadiusz Kusztal return QAT_SM3_BLOCK_SIZE; 142398f06089SFiona Trahe default: 1424be24b0d9SFiona Trahe QAT_LOG(ERR, "invalid hash alg %u", qat_hash_alg); 142598f06089SFiona Trahe return -EFAULT; 142698f06089SFiona Trahe }; 142798f06089SFiona Trahe return -EFAULT; 142898f06089SFiona Trahe } 142998f06089SFiona Trahe 14303227bc71SKai Ji #define HMAC_IPAD_VALUE 0x36 14313227bc71SKai Ji #define HMAC_OPAD_VALUE 0x5c 14323227bc71SKai Ji #define HASH_XCBC_PRECOMP_KEY_NUM 3 14333227bc71SKai Ji 1434ca0ba0e4SBrian Dooley #ifdef RTE_QAT_OPENSSL 1435ca0ba0e4SBrian Dooley static int partial_hash_sha1(uint8_t *data_in, uint8_t *data_out) 1436ca0ba0e4SBrian Dooley { 1437ca0ba0e4SBrian Dooley SHA_CTX ctx; 1438ca0ba0e4SBrian Dooley 1439ca0ba0e4SBrian Dooley if (!SHA1_Init(&ctx)) 1440ca0ba0e4SBrian Dooley return -EFAULT; 1441ca0ba0e4SBrian Dooley SHA1_Transform(&ctx, data_in); 1442ca0ba0e4SBrian Dooley rte_memcpy(data_out, &ctx, SHA_DIGEST_LENGTH); 1443ca0ba0e4SBrian Dooley return 0; 1444ca0ba0e4SBrian Dooley } 1445ca0ba0e4SBrian Dooley 1446ca0ba0e4SBrian Dooley static int partial_hash_sha224(uint8_t *data_in, uint8_t *data_out) 1447ca0ba0e4SBrian Dooley { 1448ca0ba0e4SBrian Dooley SHA256_CTX ctx; 1449ca0ba0e4SBrian Dooley 1450ca0ba0e4SBrian Dooley if (!SHA224_Init(&ctx)) 1451ca0ba0e4SBrian Dooley return -EFAULT; 1452ca0ba0e4SBrian Dooley SHA256_Transform(&ctx, data_in); 1453ca0ba0e4SBrian Dooley rte_memcpy(data_out, &ctx, SHA256_DIGEST_LENGTH); 1454ca0ba0e4SBrian Dooley return 0; 1455ca0ba0e4SBrian Dooley } 1456ca0ba0e4SBrian Dooley 1457ca0ba0e4SBrian Dooley static int partial_hash_sha256(uint8_t *data_in, uint8_t *data_out) 1458ca0ba0e4SBrian Dooley { 1459ca0ba0e4SBrian Dooley SHA256_CTX ctx; 1460ca0ba0e4SBrian Dooley 1461ca0ba0e4SBrian Dooley if (!SHA256_Init(&ctx)) 1462ca0ba0e4SBrian Dooley return -EFAULT; 1463ca0ba0e4SBrian Dooley SHA256_Transform(&ctx, data_in); 1464ca0ba0e4SBrian Dooley rte_memcpy(data_out, &ctx, SHA256_DIGEST_LENGTH); 1465ca0ba0e4SBrian Dooley return 0; 1466ca0ba0e4SBrian Dooley } 1467ca0ba0e4SBrian Dooley 1468ca0ba0e4SBrian Dooley static int partial_hash_sha384(uint8_t *data_in, uint8_t *data_out) 1469ca0ba0e4SBrian Dooley { 1470ca0ba0e4SBrian Dooley SHA512_CTX ctx; 1471ca0ba0e4SBrian Dooley 1472ca0ba0e4SBrian Dooley if (!SHA384_Init(&ctx)) 1473ca0ba0e4SBrian Dooley return -EFAULT; 1474ca0ba0e4SBrian Dooley SHA512_Transform(&ctx, data_in); 1475ca0ba0e4SBrian Dooley rte_memcpy(data_out, &ctx, SHA512_DIGEST_LENGTH); 1476ca0ba0e4SBrian Dooley return 0; 1477ca0ba0e4SBrian Dooley } 1478ca0ba0e4SBrian Dooley 1479ca0ba0e4SBrian Dooley static int partial_hash_sha512(uint8_t *data_in, uint8_t *data_out) 1480ca0ba0e4SBrian Dooley { 1481ca0ba0e4SBrian Dooley SHA512_CTX ctx; 1482ca0ba0e4SBrian Dooley 1483ca0ba0e4SBrian Dooley if (!SHA512_Init(&ctx)) 1484ca0ba0e4SBrian Dooley return -EFAULT; 1485ca0ba0e4SBrian Dooley SHA512_Transform(&ctx, data_in); 1486ca0ba0e4SBrian Dooley rte_memcpy(data_out, &ctx, SHA512_DIGEST_LENGTH); 1487ca0ba0e4SBrian Dooley return 0; 1488ca0ba0e4SBrian Dooley } 1489ca0ba0e4SBrian Dooley 1490ca0ba0e4SBrian Dooley static int partial_hash_md5(uint8_t *data_in, uint8_t *data_out) 1491ca0ba0e4SBrian Dooley { 1492ca0ba0e4SBrian Dooley MD5_CTX ctx; 1493ca0ba0e4SBrian Dooley 1494ca0ba0e4SBrian Dooley if (!MD5_Init(&ctx)) 1495ca0ba0e4SBrian Dooley return -EFAULT; 1496ca0ba0e4SBrian Dooley MD5_Transform(&ctx, data_in); 1497ca0ba0e4SBrian Dooley rte_memcpy(data_out, &ctx, MD5_DIGEST_LENGTH); 1498ca0ba0e4SBrian Dooley 1499ca0ba0e4SBrian Dooley return 0; 1500ca0ba0e4SBrian Dooley } 1501ca0ba0e4SBrian Dooley 1502ca0ba0e4SBrian Dooley static void aes_cmac_key_derive(uint8_t *base, uint8_t *derived) 1503ca0ba0e4SBrian Dooley { 1504ca0ba0e4SBrian Dooley int i; 1505ca0ba0e4SBrian Dooley 1506ca0ba0e4SBrian Dooley derived[0] = base[0] << 1; 1507ca0ba0e4SBrian Dooley for (i = 1; i < ICP_QAT_HW_AES_BLK_SZ ; i++) { 1508ca0ba0e4SBrian Dooley derived[i] = base[i] << 1; 1509ca0ba0e4SBrian Dooley derived[i - 1] |= base[i] >> 7; 1510ca0ba0e4SBrian Dooley } 1511ca0ba0e4SBrian Dooley 1512ca0ba0e4SBrian Dooley if (base[0] & 0x80) 1513ca0ba0e4SBrian Dooley derived[ICP_QAT_HW_AES_BLK_SZ - 1] ^= QAT_AES_CMAC_CONST_RB; 1514ca0ba0e4SBrian Dooley } 1515ca0ba0e4SBrian Dooley 1516ca0ba0e4SBrian Dooley static int 1517ca0ba0e4SBrian Dooley partial_hash_compute(enum icp_qat_hw_auth_algo hash_alg, 1518ca0ba0e4SBrian Dooley uint8_t *data_in, uint8_t *data_out) 1519ca0ba0e4SBrian Dooley { 1520ca0ba0e4SBrian Dooley int digest_size; 1521ca0ba0e4SBrian Dooley uint8_t digest[qat_hash_get_digest_size( 1522ca0ba0e4SBrian Dooley ICP_QAT_HW_AUTH_ALGO_DELIMITER)]; 1523ca0ba0e4SBrian Dooley uint32_t *hash_state_out_be32; 1524ca0ba0e4SBrian Dooley uint64_t *hash_state_out_be64; 1525ca0ba0e4SBrian Dooley int i; 1526ca0ba0e4SBrian Dooley 1527ca0ba0e4SBrian Dooley /* Initialize to avoid gcc warning */ 1528ca0ba0e4SBrian Dooley memset(digest, 0, sizeof(digest)); 1529ca0ba0e4SBrian Dooley 1530ca0ba0e4SBrian Dooley digest_size = qat_hash_get_digest_size(hash_alg); 1531ca0ba0e4SBrian Dooley if (digest_size <= 0) 1532ca0ba0e4SBrian Dooley return -EFAULT; 1533ca0ba0e4SBrian Dooley 1534ca0ba0e4SBrian Dooley hash_state_out_be32 = (uint32_t *)data_out; 1535ca0ba0e4SBrian Dooley hash_state_out_be64 = (uint64_t *)data_out; 1536ca0ba0e4SBrian Dooley 1537ca0ba0e4SBrian Dooley switch (hash_alg) { 1538ca0ba0e4SBrian Dooley case ICP_QAT_HW_AUTH_ALGO_SHA1: 1539ca0ba0e4SBrian Dooley if (partial_hash_sha1(data_in, digest)) 1540ca0ba0e4SBrian Dooley return -EFAULT; 1541ca0ba0e4SBrian Dooley for (i = 0; i < digest_size >> 2; i++, hash_state_out_be32++) 1542ca0ba0e4SBrian Dooley *hash_state_out_be32 = 1543ca0ba0e4SBrian Dooley rte_bswap32(*(((uint32_t *)digest)+i)); 1544ca0ba0e4SBrian Dooley break; 1545ca0ba0e4SBrian Dooley case ICP_QAT_HW_AUTH_ALGO_SHA224: 1546ca0ba0e4SBrian Dooley if (partial_hash_sha224(data_in, digest)) 1547ca0ba0e4SBrian Dooley return -EFAULT; 1548ca0ba0e4SBrian Dooley for (i = 0; i < digest_size >> 2; i++, hash_state_out_be32++) 1549ca0ba0e4SBrian Dooley *hash_state_out_be32 = 1550ca0ba0e4SBrian Dooley rte_bswap32(*(((uint32_t *)digest)+i)); 1551ca0ba0e4SBrian Dooley break; 1552ca0ba0e4SBrian Dooley case ICP_QAT_HW_AUTH_ALGO_SHA256: 1553ca0ba0e4SBrian Dooley if (partial_hash_sha256(data_in, digest)) 1554ca0ba0e4SBrian Dooley return -EFAULT; 1555ca0ba0e4SBrian Dooley for (i = 0; i < digest_size >> 2; i++, hash_state_out_be32++) 1556ca0ba0e4SBrian Dooley *hash_state_out_be32 = 1557ca0ba0e4SBrian Dooley rte_bswap32(*(((uint32_t *)digest)+i)); 1558ca0ba0e4SBrian Dooley break; 1559ca0ba0e4SBrian Dooley case ICP_QAT_HW_AUTH_ALGO_SHA384: 1560ca0ba0e4SBrian Dooley if (partial_hash_sha384(data_in, digest)) 1561ca0ba0e4SBrian Dooley return -EFAULT; 1562ca0ba0e4SBrian Dooley for (i = 0; i < digest_size >> 3; i++, hash_state_out_be64++) 1563ca0ba0e4SBrian Dooley *hash_state_out_be64 = 1564ca0ba0e4SBrian Dooley rte_bswap64(*(((uint64_t *)digest)+i)); 1565ca0ba0e4SBrian Dooley break; 1566ca0ba0e4SBrian Dooley case ICP_QAT_HW_AUTH_ALGO_SHA512: 1567ca0ba0e4SBrian Dooley if (partial_hash_sha512(data_in, digest)) 1568ca0ba0e4SBrian Dooley return -EFAULT; 1569ca0ba0e4SBrian Dooley for (i = 0; i < digest_size >> 3; i++, hash_state_out_be64++) 1570ca0ba0e4SBrian Dooley *hash_state_out_be64 = 1571ca0ba0e4SBrian Dooley rte_bswap64(*(((uint64_t *)digest)+i)); 1572ca0ba0e4SBrian Dooley break; 1573ca0ba0e4SBrian Dooley case ICP_QAT_HW_AUTH_ALGO_MD5: 1574ca0ba0e4SBrian Dooley if (partial_hash_md5(data_in, data_out)) 1575ca0ba0e4SBrian Dooley return -EFAULT; 1576ca0ba0e4SBrian Dooley break; 1577ca0ba0e4SBrian Dooley default: 1578ca0ba0e4SBrian Dooley QAT_LOG(ERR, "invalid hash alg %u", hash_alg); 1579ca0ba0e4SBrian Dooley return -EFAULT; 1580ca0ba0e4SBrian Dooley } 1581ca0ba0e4SBrian Dooley 1582ca0ba0e4SBrian Dooley return 0; 1583ca0ba0e4SBrian Dooley } 1584ca0ba0e4SBrian Dooley 15853227bc71SKai Ji static const uint8_t AES_CMAC_SEED[ICP_QAT_HW_AES_128_KEY_SZ]; 15863227bc71SKai Ji 1587ca0ba0e4SBrian Dooley static int qat_sym_do_precomputes(enum icp_qat_hw_auth_algo hash_alg, 1588ca0ba0e4SBrian Dooley const uint8_t *auth_key, 1589ca0ba0e4SBrian Dooley uint16_t auth_keylen, 1590ca0ba0e4SBrian Dooley uint8_t *p_state_buf, 1591ca0ba0e4SBrian Dooley uint16_t *p_state_len, 1592ca0ba0e4SBrian Dooley uint8_t aes_cmac) 1593ca0ba0e4SBrian Dooley { 1594ca0ba0e4SBrian Dooley int block_size; 1595ca0ba0e4SBrian Dooley uint8_t ipad[qat_hash_get_block_size(ICP_QAT_HW_AUTH_ALGO_DELIMITER)]; 1596ca0ba0e4SBrian Dooley uint8_t opad[qat_hash_get_block_size(ICP_QAT_HW_AUTH_ALGO_DELIMITER)]; 1597ca0ba0e4SBrian Dooley int i; 1598ca0ba0e4SBrian Dooley 1599ca0ba0e4SBrian Dooley if (hash_alg == ICP_QAT_HW_AUTH_ALGO_AES_XCBC_MAC) { 1600ca0ba0e4SBrian Dooley 1601ca0ba0e4SBrian Dooley /* CMAC */ 1602ca0ba0e4SBrian Dooley if (aes_cmac) { 1603ca0ba0e4SBrian Dooley AES_KEY enc_key; 1604ca0ba0e4SBrian Dooley uint8_t *in = NULL; 1605ca0ba0e4SBrian Dooley uint8_t k0[ICP_QAT_HW_AES_128_KEY_SZ]; 1606ca0ba0e4SBrian Dooley uint8_t *k1, *k2; 1607ca0ba0e4SBrian Dooley 1608ca0ba0e4SBrian Dooley auth_keylen = ICP_QAT_HW_AES_128_KEY_SZ; 1609ca0ba0e4SBrian Dooley 1610ca0ba0e4SBrian Dooley in = rte_zmalloc("AES CMAC K1", 1611ca0ba0e4SBrian Dooley ICP_QAT_HW_AES_128_KEY_SZ, 16); 1612ca0ba0e4SBrian Dooley 1613ca0ba0e4SBrian Dooley if (in == NULL) { 1614ca0ba0e4SBrian Dooley QAT_LOG(ERR, "Failed to alloc memory"); 1615ca0ba0e4SBrian Dooley return -ENOMEM; 1616ca0ba0e4SBrian Dooley } 1617ca0ba0e4SBrian Dooley 1618ca0ba0e4SBrian Dooley rte_memcpy(in, AES_CMAC_SEED, 1619ca0ba0e4SBrian Dooley ICP_QAT_HW_AES_128_KEY_SZ); 1620ca0ba0e4SBrian Dooley rte_memcpy(p_state_buf, auth_key, auth_keylen); 1621ca0ba0e4SBrian Dooley 1622ca0ba0e4SBrian Dooley if (AES_set_encrypt_key(auth_key, auth_keylen << 3, 1623ca0ba0e4SBrian Dooley &enc_key) != 0) { 1624ca0ba0e4SBrian Dooley rte_free(in); 1625ca0ba0e4SBrian Dooley return -EFAULT; 1626ca0ba0e4SBrian Dooley } 1627ca0ba0e4SBrian Dooley 1628ca0ba0e4SBrian Dooley AES_encrypt(in, k0, &enc_key); 1629ca0ba0e4SBrian Dooley 1630ca0ba0e4SBrian Dooley k1 = p_state_buf + ICP_QAT_HW_AES_XCBC_MAC_STATE1_SZ; 1631ca0ba0e4SBrian Dooley k2 = k1 + ICP_QAT_HW_AES_XCBC_MAC_STATE1_SZ; 1632ca0ba0e4SBrian Dooley 1633ca0ba0e4SBrian Dooley aes_cmac_key_derive(k0, k1); 1634ca0ba0e4SBrian Dooley aes_cmac_key_derive(k1, k2); 1635ca0ba0e4SBrian Dooley 1636ca0ba0e4SBrian Dooley memset(k0, 0, ICP_QAT_HW_AES_128_KEY_SZ); 1637ca0ba0e4SBrian Dooley *p_state_len = ICP_QAT_HW_AES_XCBC_MAC_STATE2_SZ; 1638ca0ba0e4SBrian Dooley rte_free(in); 1639ca0ba0e4SBrian Dooley goto out; 1640ca0ba0e4SBrian Dooley } else { 1641ca0ba0e4SBrian Dooley static uint8_t qat_aes_xcbc_key_seed[ 1642ca0ba0e4SBrian Dooley ICP_QAT_HW_AES_XCBC_MAC_STATE2_SZ] = { 1643ca0ba0e4SBrian Dooley 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 1644ca0ba0e4SBrian Dooley 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 1645ca0ba0e4SBrian Dooley 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 1646ca0ba0e4SBrian Dooley 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 1647ca0ba0e4SBrian Dooley 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 1648ca0ba0e4SBrian Dooley 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 1649ca0ba0e4SBrian Dooley }; 1650ca0ba0e4SBrian Dooley 1651ca0ba0e4SBrian Dooley uint8_t *in = NULL; 1652ca0ba0e4SBrian Dooley uint8_t *out = p_state_buf; 1653ca0ba0e4SBrian Dooley int x; 1654ca0ba0e4SBrian Dooley AES_KEY enc_key; 1655ca0ba0e4SBrian Dooley 1656ca0ba0e4SBrian Dooley in = rte_zmalloc("working mem for key", 1657ca0ba0e4SBrian Dooley ICP_QAT_HW_AES_XCBC_MAC_STATE2_SZ, 16); 1658ca0ba0e4SBrian Dooley if (in == NULL) { 1659ca0ba0e4SBrian Dooley QAT_LOG(ERR, "Failed to alloc memory"); 1660ca0ba0e4SBrian Dooley return -ENOMEM; 1661ca0ba0e4SBrian Dooley } 1662ca0ba0e4SBrian Dooley 1663ca0ba0e4SBrian Dooley rte_memcpy(in, qat_aes_xcbc_key_seed, 1664ca0ba0e4SBrian Dooley ICP_QAT_HW_AES_XCBC_MAC_STATE2_SZ); 1665ca0ba0e4SBrian Dooley for (x = 0; x < HASH_XCBC_PRECOMP_KEY_NUM; x++) { 1666ca0ba0e4SBrian Dooley if (AES_set_encrypt_key(auth_key, 1667ca0ba0e4SBrian Dooley auth_keylen << 3, 1668ca0ba0e4SBrian Dooley &enc_key) != 0) { 1669ca0ba0e4SBrian Dooley rte_free(in - 1670ca0ba0e4SBrian Dooley (x * ICP_QAT_HW_AES_XCBC_MAC_KEY_SZ)); 1671ca0ba0e4SBrian Dooley memset(out - 1672ca0ba0e4SBrian Dooley (x * ICP_QAT_HW_AES_XCBC_MAC_KEY_SZ), 1673ca0ba0e4SBrian Dooley 0, ICP_QAT_HW_AES_XCBC_MAC_STATE2_SZ); 1674ca0ba0e4SBrian Dooley return -EFAULT; 1675ca0ba0e4SBrian Dooley } 1676ca0ba0e4SBrian Dooley AES_encrypt(in, out, &enc_key); 1677ca0ba0e4SBrian Dooley in += ICP_QAT_HW_AES_XCBC_MAC_KEY_SZ; 1678ca0ba0e4SBrian Dooley out += ICP_QAT_HW_AES_XCBC_MAC_KEY_SZ; 1679ca0ba0e4SBrian Dooley } 1680ca0ba0e4SBrian Dooley *p_state_len = ICP_QAT_HW_AES_XCBC_MAC_STATE2_SZ; 1681ca0ba0e4SBrian Dooley rte_free(in - x*ICP_QAT_HW_AES_XCBC_MAC_KEY_SZ); 1682ca0ba0e4SBrian Dooley goto out; 1683ca0ba0e4SBrian Dooley } 1684ca0ba0e4SBrian Dooley 1685ca0ba0e4SBrian Dooley } else if ((hash_alg == ICP_QAT_HW_AUTH_ALGO_GALOIS_128) || 1686ca0ba0e4SBrian Dooley (hash_alg == ICP_QAT_HW_AUTH_ALGO_GALOIS_64)) { 1687ca0ba0e4SBrian Dooley uint8_t *in = NULL; 1688ca0ba0e4SBrian Dooley uint8_t *out = p_state_buf; 1689ca0ba0e4SBrian Dooley AES_KEY enc_key; 1690ca0ba0e4SBrian Dooley 1691ca0ba0e4SBrian Dooley memset(p_state_buf, 0, ICP_QAT_HW_GALOIS_H_SZ + 1692ca0ba0e4SBrian Dooley ICP_QAT_HW_GALOIS_LEN_A_SZ + 1693ca0ba0e4SBrian Dooley ICP_QAT_HW_GALOIS_E_CTR0_SZ); 1694ca0ba0e4SBrian Dooley in = rte_zmalloc("working mem for key", 1695ca0ba0e4SBrian Dooley ICP_QAT_HW_GALOIS_H_SZ, 16); 1696ca0ba0e4SBrian Dooley if (in == NULL) { 1697ca0ba0e4SBrian Dooley QAT_LOG(ERR, "Failed to alloc memory"); 1698ca0ba0e4SBrian Dooley return -ENOMEM; 1699ca0ba0e4SBrian Dooley } 1700ca0ba0e4SBrian Dooley 1701ca0ba0e4SBrian Dooley memset(in, 0, ICP_QAT_HW_GALOIS_H_SZ); 1702ca0ba0e4SBrian Dooley if (AES_set_encrypt_key(auth_key, auth_keylen << 3, 1703ca0ba0e4SBrian Dooley &enc_key) != 0) { 1704ca0ba0e4SBrian Dooley return -EFAULT; 1705ca0ba0e4SBrian Dooley } 1706ca0ba0e4SBrian Dooley AES_encrypt(in, out, &enc_key); 1707ca0ba0e4SBrian Dooley *p_state_len = ICP_QAT_HW_GALOIS_H_SZ + 1708ca0ba0e4SBrian Dooley ICP_QAT_HW_GALOIS_LEN_A_SZ + 1709ca0ba0e4SBrian Dooley ICP_QAT_HW_GALOIS_E_CTR0_SZ; 1710ca0ba0e4SBrian Dooley rte_free(in); 1711ca0ba0e4SBrian Dooley return 0; 1712ca0ba0e4SBrian Dooley } 1713ca0ba0e4SBrian Dooley 1714ca0ba0e4SBrian Dooley block_size = qat_hash_get_block_size(hash_alg); 1715ca0ba0e4SBrian Dooley if (block_size < 0) 1716ca0ba0e4SBrian Dooley return block_size; 1717ca0ba0e4SBrian Dooley /* init ipad and opad from key and xor with fixed values */ 1718ca0ba0e4SBrian Dooley memset(ipad, 0, block_size); 1719ca0ba0e4SBrian Dooley memset(opad, 0, block_size); 1720ca0ba0e4SBrian Dooley 1721ca0ba0e4SBrian Dooley if (auth_keylen > (unsigned int)block_size) { 1722ca0ba0e4SBrian Dooley QAT_LOG(ERR, "invalid keylen %u", auth_keylen); 1723ca0ba0e4SBrian Dooley return -EFAULT; 1724ca0ba0e4SBrian Dooley } 1725ca0ba0e4SBrian Dooley 1726ca0ba0e4SBrian Dooley RTE_VERIFY(auth_keylen <= sizeof(ipad)); 1727ca0ba0e4SBrian Dooley RTE_VERIFY(auth_keylen <= sizeof(opad)); 1728ca0ba0e4SBrian Dooley 1729ca0ba0e4SBrian Dooley rte_memcpy(ipad, auth_key, auth_keylen); 1730ca0ba0e4SBrian Dooley rte_memcpy(opad, auth_key, auth_keylen); 1731ca0ba0e4SBrian Dooley 1732ca0ba0e4SBrian Dooley for (i = 0; i < block_size; i++) { 1733ca0ba0e4SBrian Dooley uint8_t *ipad_ptr = ipad + i; 1734ca0ba0e4SBrian Dooley uint8_t *opad_ptr = opad + i; 1735ca0ba0e4SBrian Dooley *ipad_ptr ^= HMAC_IPAD_VALUE; 1736ca0ba0e4SBrian Dooley *opad_ptr ^= HMAC_OPAD_VALUE; 1737ca0ba0e4SBrian Dooley } 1738ca0ba0e4SBrian Dooley 1739ca0ba0e4SBrian Dooley /* do partial hash of ipad and copy to state1 */ 1740ca0ba0e4SBrian Dooley if (partial_hash_compute(hash_alg, ipad, p_state_buf)) { 1741ca0ba0e4SBrian Dooley memset(ipad, 0, block_size); 1742ca0ba0e4SBrian Dooley memset(opad, 0, block_size); 1743ca0ba0e4SBrian Dooley QAT_LOG(ERR, "ipad precompute failed"); 1744ca0ba0e4SBrian Dooley return -EFAULT; 1745ca0ba0e4SBrian Dooley } 1746ca0ba0e4SBrian Dooley 1747ca0ba0e4SBrian Dooley /* 1748ca0ba0e4SBrian Dooley * State len is a multiple of 8, so may be larger than the digest. 1749ca0ba0e4SBrian Dooley * Put the partial hash of opad state_len bytes after state1 1750ca0ba0e4SBrian Dooley */ 1751ca0ba0e4SBrian Dooley *p_state_len = qat_hash_get_state1_size(hash_alg); 1752ca0ba0e4SBrian Dooley if (partial_hash_compute(hash_alg, opad, p_state_buf + *p_state_len)) { 1753ca0ba0e4SBrian Dooley memset(ipad, 0, block_size); 1754ca0ba0e4SBrian Dooley memset(opad, 0, block_size); 1755ca0ba0e4SBrian Dooley QAT_LOG(ERR, "opad precompute failed"); 1756ca0ba0e4SBrian Dooley return -EFAULT; 1757ca0ba0e4SBrian Dooley } 1758ca0ba0e4SBrian Dooley 1759ca0ba0e4SBrian Dooley /* don't leave data lying around */ 1760ca0ba0e4SBrian Dooley memset(ipad, 0, block_size); 1761ca0ba0e4SBrian Dooley memset(opad, 0, block_size); 1762ca0ba0e4SBrian Dooley out: 1763ca0ba0e4SBrian Dooley return 0; 1764ca0ba0e4SBrian Dooley } 1765ca0ba0e4SBrian Dooley 1766ca0ba0e4SBrian Dooley #else 1767ca0ba0e4SBrian Dooley 17683227bc71SKai Ji static int aes_ipsecmb_job(uint8_t *in, uint8_t *out, IMB_MGR *m, 17693227bc71SKai Ji const uint8_t *key, uint16_t auth_keylen) 17703227bc71SKai Ji { 17713227bc71SKai Ji int err; 17723227bc71SKai Ji struct IMB_JOB *job; 17733227bc71SKai Ji DECLARE_ALIGNED(uint32_t expkey[4*15], 16); 17743227bc71SKai Ji DECLARE_ALIGNED(uint32_t dust[4*15], 16); 17753227bc71SKai Ji 17763227bc71SKai Ji if (auth_keylen == ICP_QAT_HW_AES_128_KEY_SZ) 17773227bc71SKai Ji IMB_AES_KEYEXP_128(m, key, expkey, dust); 17783227bc71SKai Ji else if (auth_keylen == ICP_QAT_HW_AES_192_KEY_SZ) 17793227bc71SKai Ji IMB_AES_KEYEXP_192(m, key, expkey, dust); 17803227bc71SKai Ji else if (auth_keylen == ICP_QAT_HW_AES_256_KEY_SZ) 17813227bc71SKai Ji IMB_AES_KEYEXP_256(m, key, expkey, dust); 17823227bc71SKai Ji else 17833227bc71SKai Ji return -EFAULT; 17843227bc71SKai Ji 17853227bc71SKai Ji job = IMB_GET_NEXT_JOB(m); 17863227bc71SKai Ji 17873227bc71SKai Ji job->src = in; 17883227bc71SKai Ji job->dst = out; 17893227bc71SKai Ji job->enc_keys = expkey; 17903227bc71SKai Ji job->key_len_in_bytes = auth_keylen; 17913227bc71SKai Ji job->msg_len_to_cipher_in_bytes = 16; 17923227bc71SKai Ji job->iv_len_in_bytes = 0; 17933227bc71SKai Ji job->cipher_direction = IMB_DIR_ENCRYPT; 17943227bc71SKai Ji job->cipher_mode = IMB_CIPHER_ECB; 17953227bc71SKai Ji job->hash_alg = IMB_AUTH_NULL; 17963227bc71SKai Ji 17973227bc71SKai Ji while (IMB_FLUSH_JOB(m) != NULL) 17983227bc71SKai Ji ; 17993227bc71SKai Ji 18003227bc71SKai Ji job = IMB_SUBMIT_JOB(m); 18013227bc71SKai Ji if (job) { 18023227bc71SKai Ji if (job->status == IMB_STATUS_COMPLETED) 18033227bc71SKai Ji return 0; 18043227bc71SKai Ji } 18053227bc71SKai Ji 18063227bc71SKai Ji err = imb_get_errno(m); 18073227bc71SKai Ji if (err) 1808*f665790aSDavid Marchand QAT_LOG(ERR, "Error: %s!", imb_get_strerror(err)); 18093227bc71SKai Ji 18103227bc71SKai Ji return -EFAULT; 18113227bc71SKai Ji } 18123227bc71SKai Ji 18133227bc71SKai Ji static int 18143227bc71SKai Ji partial_hash_compute_ipsec_mb(enum icp_qat_hw_auth_algo hash_alg, 18153227bc71SKai Ji uint8_t *data_in, uint8_t *data_out, IMB_MGR *m) 18163227bc71SKai Ji { 18173227bc71SKai Ji int digest_size; 18183227bc71SKai Ji uint8_t digest[qat_hash_get_digest_size( 18193227bc71SKai Ji ICP_QAT_HW_AUTH_ALGO_DELIMITER)]; 18203227bc71SKai Ji uint32_t *hash_state_out_be32; 18213227bc71SKai Ji uint64_t *hash_state_out_be64; 18223227bc71SKai Ji int i; 18233227bc71SKai Ji 18243227bc71SKai Ji /* Initialize to avoid gcc warning */ 18253227bc71SKai Ji memset(digest, 0, sizeof(digest)); 18263227bc71SKai Ji 18273227bc71SKai Ji digest_size = qat_hash_get_digest_size(hash_alg); 18283227bc71SKai Ji if (digest_size <= 0) 18293227bc71SKai Ji return -EFAULT; 18303227bc71SKai Ji 18313227bc71SKai Ji hash_state_out_be32 = (uint32_t *)data_out; 18323227bc71SKai Ji hash_state_out_be64 = (uint64_t *)data_out; 18333227bc71SKai Ji 18343227bc71SKai Ji switch (hash_alg) { 18353227bc71SKai Ji case ICP_QAT_HW_AUTH_ALGO_SHA1: 18363227bc71SKai Ji IMB_SHA1_ONE_BLOCK(m, data_in, digest); 18373227bc71SKai Ji for (i = 0; i < digest_size >> 2; i++, hash_state_out_be32++) 18383227bc71SKai Ji *hash_state_out_be32 = 18393227bc71SKai Ji rte_bswap32(*(((uint32_t *)digest)+i)); 18403227bc71SKai Ji break; 18413227bc71SKai Ji case ICP_QAT_HW_AUTH_ALGO_SHA224: 18423227bc71SKai Ji IMB_SHA224_ONE_BLOCK(m, data_in, digest); 18433227bc71SKai Ji for (i = 0; i < digest_size >> 2; i++, hash_state_out_be32++) 18443227bc71SKai Ji *hash_state_out_be32 = 18453227bc71SKai Ji rte_bswap32(*(((uint32_t *)digest)+i)); 18463227bc71SKai Ji break; 18473227bc71SKai Ji case ICP_QAT_HW_AUTH_ALGO_SHA256: 18483227bc71SKai Ji IMB_SHA256_ONE_BLOCK(m, data_in, digest); 18493227bc71SKai Ji for (i = 0; i < digest_size >> 2; i++, hash_state_out_be32++) 18503227bc71SKai Ji *hash_state_out_be32 = 18513227bc71SKai Ji rte_bswap32(*(((uint32_t *)digest)+i)); 18523227bc71SKai Ji break; 18533227bc71SKai Ji case ICP_QAT_HW_AUTH_ALGO_SHA384: 18543227bc71SKai Ji IMB_SHA384_ONE_BLOCK(m, data_in, digest); 18553227bc71SKai Ji for (i = 0; i < digest_size >> 3; i++, hash_state_out_be64++) 18563227bc71SKai Ji *hash_state_out_be64 = 18573227bc71SKai Ji rte_bswap64(*(((uint64_t *)digest)+i)); 18583227bc71SKai Ji break; 18593227bc71SKai Ji case ICP_QAT_HW_AUTH_ALGO_SHA512: 18603227bc71SKai Ji IMB_SHA512_ONE_BLOCK(m, data_in, digest); 18613227bc71SKai Ji for (i = 0; i < digest_size >> 3; i++, hash_state_out_be64++) 18623227bc71SKai Ji *hash_state_out_be64 = 18633227bc71SKai Ji rte_bswap64(*(((uint64_t *)digest)+i)); 18643227bc71SKai Ji break; 18653227bc71SKai Ji case ICP_QAT_HW_AUTH_ALGO_MD5: 18663227bc71SKai Ji IMB_MD5_ONE_BLOCK(m, data_in, data_out); 18673227bc71SKai Ji break; 18683227bc71SKai Ji default: 18693227bc71SKai Ji QAT_LOG(ERR, "invalid hash alg %u", hash_alg); 18703227bc71SKai Ji return -EFAULT; 18713227bc71SKai Ji } 18723227bc71SKai Ji 18733227bc71SKai Ji return 0; 18743227bc71SKai Ji } 18753227bc71SKai Ji 18763227bc71SKai Ji static int qat_sym_do_precomputes_ipsec_mb(enum icp_qat_hw_auth_algo hash_alg, 18773227bc71SKai Ji const uint8_t *auth_key, 18783227bc71SKai Ji uint16_t auth_keylen, 18793227bc71SKai Ji uint8_t *p_state_buf, 18803227bc71SKai Ji uint16_t *p_state_len, 18813227bc71SKai Ji uint8_t aes_cmac) 18823227bc71SKai Ji { 18833227bc71SKai Ji int block_size = 0; 18843227bc71SKai Ji uint8_t ipad[qat_hash_get_block_size(ICP_QAT_HW_AUTH_ALGO_DELIMITER)]; 18853227bc71SKai Ji uint8_t opad[qat_hash_get_block_size(ICP_QAT_HW_AUTH_ALGO_DELIMITER)]; 18863227bc71SKai Ji int i, ret = 0; 18873227bc71SKai Ji uint8_t in[ICP_QAT_HW_AES_XCBC_MAC_STATE2_SZ]; 18883227bc71SKai Ji 18893227bc71SKai Ji IMB_MGR *m; 18903227bc71SKai Ji m = alloc_mb_mgr(0); 18913227bc71SKai Ji if (m == NULL) 18923227bc71SKai Ji return -ENOMEM; 18933227bc71SKai Ji 18943227bc71SKai Ji init_mb_mgr_auto(m, NULL); 18953227bc71SKai Ji memset(in, 0, ICP_QAT_HW_AES_XCBC_MAC_STATE2_SZ); 18963227bc71SKai Ji if (hash_alg == ICP_QAT_HW_AUTH_ALGO_AES_XCBC_MAC) { 18973227bc71SKai Ji 18983227bc71SKai Ji /* CMAC */ 18993227bc71SKai Ji if (aes_cmac) { 19003227bc71SKai Ji uint8_t *k1, *k2; 19013227bc71SKai Ji auth_keylen = ICP_QAT_HW_AES_128_KEY_SZ; 19023227bc71SKai Ji rte_memcpy(p_state_buf, auth_key, auth_keylen); 19033227bc71SKai Ji 19043227bc71SKai Ji DECLARE_ALIGNED(uint32_t expkey[4*15], 16); 19053227bc71SKai Ji DECLARE_ALIGNED(uint32_t dust[4*15], 16); 19063227bc71SKai Ji IMB_AES_KEYEXP_128(m, p_state_buf, expkey, dust); 19073227bc71SKai Ji k1 = p_state_buf + ICP_QAT_HW_AES_XCBC_MAC_STATE1_SZ; 19083227bc71SKai Ji k2 = k1 + ICP_QAT_HW_AES_XCBC_MAC_STATE1_SZ; 19093227bc71SKai Ji 19103227bc71SKai Ji IMB_AES_CMAC_SUBKEY_GEN_128(m, expkey, k1, k2); 19113227bc71SKai Ji *p_state_len = ICP_QAT_HW_AES_XCBC_MAC_STATE2_SZ; 19123227bc71SKai Ji goto out; 19133227bc71SKai Ji } 19143227bc71SKai Ji 19153227bc71SKai Ji static uint8_t qat_aes_xcbc_key_seed[ 19163227bc71SKai Ji ICP_QAT_HW_AES_XCBC_MAC_STATE2_SZ] = { 19173227bc71SKai Ji 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 19183227bc71SKai Ji 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 19193227bc71SKai Ji 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 19203227bc71SKai Ji 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 19213227bc71SKai Ji 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 19223227bc71SKai Ji 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 19233227bc71SKai Ji }; 19243227bc71SKai Ji 19253227bc71SKai Ji uint8_t *input = in; 19263227bc71SKai Ji uint8_t *out = p_state_buf; 19273227bc71SKai Ji rte_memcpy(input, qat_aes_xcbc_key_seed, 19283227bc71SKai Ji ICP_QAT_HW_AES_XCBC_MAC_STATE2_SZ); 19293227bc71SKai Ji for (i = 0; i < HASH_XCBC_PRECOMP_KEY_NUM; i++) { 19303227bc71SKai Ji if (aes_ipsecmb_job(input, out, m, auth_key, auth_keylen)) { 19313227bc71SKai Ji memset(input - 19323227bc71SKai Ji (i * ICP_QAT_HW_AES_XCBC_MAC_KEY_SZ), 19333227bc71SKai Ji 0, ICP_QAT_HW_AES_XCBC_MAC_STATE2_SZ); 19343227bc71SKai Ji ret = -EFAULT; 19353227bc71SKai Ji goto out; 19363227bc71SKai Ji } 19373227bc71SKai Ji 19383227bc71SKai Ji input += ICP_QAT_HW_AES_XCBC_MAC_KEY_SZ; 19393227bc71SKai Ji out += ICP_QAT_HW_AES_XCBC_MAC_KEY_SZ; 19403227bc71SKai Ji } 19413227bc71SKai Ji *p_state_len = ICP_QAT_HW_AES_XCBC_MAC_STATE2_SZ; 19423227bc71SKai Ji goto out; 19433227bc71SKai Ji 19443227bc71SKai Ji } else if ((hash_alg == ICP_QAT_HW_AUTH_ALGO_GALOIS_128) || 19453227bc71SKai Ji (hash_alg == ICP_QAT_HW_AUTH_ALGO_GALOIS_64)) { 19463227bc71SKai Ji uint8_t *out = p_state_buf; 19473227bc71SKai Ji 19483227bc71SKai Ji memset(p_state_buf, 0, ICP_QAT_HW_GALOIS_H_SZ + 19493227bc71SKai Ji ICP_QAT_HW_GALOIS_LEN_A_SZ + 19503227bc71SKai Ji ICP_QAT_HW_GALOIS_E_CTR0_SZ); 19513227bc71SKai Ji if (aes_ipsecmb_job(in, out, m, auth_key, auth_keylen)) { 19523227bc71SKai Ji ret = -EFAULT; 19533227bc71SKai Ji goto out; 19543227bc71SKai Ji } 19553227bc71SKai Ji 19563227bc71SKai Ji *p_state_len = ICP_QAT_HW_GALOIS_H_SZ + 19573227bc71SKai Ji ICP_QAT_HW_GALOIS_LEN_A_SZ + 19583227bc71SKai Ji ICP_QAT_HW_GALOIS_E_CTR0_SZ; 19593227bc71SKai Ji goto out; 19603227bc71SKai Ji } 19613227bc71SKai Ji 19623227bc71SKai Ji block_size = qat_hash_get_block_size(hash_alg); 19633227bc71SKai Ji if (block_size < 0) { 19643227bc71SKai Ji free_mb_mgr(m); 19653227bc71SKai Ji return block_size; 19663227bc71SKai Ji } 19673227bc71SKai Ji 19683227bc71SKai Ji if (auth_keylen > (unsigned int)block_size) { 19693227bc71SKai Ji QAT_LOG(ERR, "invalid keylen %u", auth_keylen); 19703227bc71SKai Ji ret = -EFAULT; 19713227bc71SKai Ji goto out; 19723227bc71SKai Ji } 19733227bc71SKai Ji /* init ipad and opad from key and xor with fixed values */ 19743227bc71SKai Ji memset(ipad, 0, block_size); 19753227bc71SKai Ji memset(opad, 0, block_size); 1976ad7d6eeaSDavid Marchand RTE_VERIFY(auth_keylen <= sizeof(ipad)); 1977ad7d6eeaSDavid Marchand RTE_VERIFY(auth_keylen <= sizeof(opad)); 19783227bc71SKai Ji rte_memcpy(ipad, auth_key, auth_keylen); 19793227bc71SKai Ji rte_memcpy(opad, auth_key, auth_keylen); 19803227bc71SKai Ji 19813227bc71SKai Ji for (i = 0; i < block_size; i++) { 19823227bc71SKai Ji uint8_t *ipad_ptr = ipad + i; 19833227bc71SKai Ji uint8_t *opad_ptr = opad + i; 19843227bc71SKai Ji *ipad_ptr ^= HMAC_IPAD_VALUE; 19853227bc71SKai Ji *opad_ptr ^= HMAC_OPAD_VALUE; 19863227bc71SKai Ji } 19873227bc71SKai Ji 19883227bc71SKai Ji /* do partial hash of ipad and copy to state1 */ 19893227bc71SKai Ji if (partial_hash_compute_ipsec_mb(hash_alg, ipad, p_state_buf, m)) { 19903227bc71SKai Ji QAT_LOG(ERR, "ipad precompute failed"); 19913227bc71SKai Ji ret = -EFAULT; 19923227bc71SKai Ji goto out; 19933227bc71SKai Ji } 19943227bc71SKai Ji 19953227bc71SKai Ji /* 19963227bc71SKai Ji * State len is a multiple of 8, so may be larger than the digest. 19973227bc71SKai Ji * Put the partial hash of opad state_len bytes after state1 19983227bc71SKai Ji */ 19993227bc71SKai Ji *p_state_len = qat_hash_get_state1_size(hash_alg); 20003227bc71SKai Ji if (partial_hash_compute_ipsec_mb(hash_alg, opad, 20013227bc71SKai Ji p_state_buf + *p_state_len, m)) { 20023227bc71SKai Ji QAT_LOG(ERR, "opad precompute failed"); 20033227bc71SKai Ji ret = -EFAULT; 20043227bc71SKai Ji goto out; 20053227bc71SKai Ji } 20063227bc71SKai Ji 20073227bc71SKai Ji out: 20083227bc71SKai Ji /* don't leave data lying around */ 20093227bc71SKai Ji memset(ipad, 0, block_size); 20103227bc71SKai Ji memset(opad, 0, block_size); 20113227bc71SKai Ji free_mb_mgr(m); 20123227bc71SKai Ji return ret; 20133227bc71SKai Ji } 20143227bc71SKai Ji #endif 201598f06089SFiona Trahe 2016bba31cffSFiona Trahe static void 20176618d3b5SArek Kusztal qat_sym_session_init_common_hdr(struct qat_sym_session *session) 201898f06089SFiona Trahe { 20196618d3b5SArek Kusztal struct icp_qat_fw_la_bulk_req *req_tmpl = &session->fw_req; 20206618d3b5SArek Kusztal struct icp_qat_fw_comn_req_hdr *header = &req_tmpl->comn_hdr; 20216618d3b5SArek Kusztal enum qat_sym_proto_flag proto_flags = session->qat_proto_flag; 20226618d3b5SArek Kusztal uint32_t slice_flags = session->slice_types; 20236618d3b5SArek Kusztal 202498f06089SFiona Trahe header->hdr_flags = 202598f06089SFiona Trahe ICP_QAT_FW_COMN_HDR_FLAGS_BUILD(ICP_QAT_FW_COMN_REQ_FLAG_SET); 202698f06089SFiona Trahe header->service_type = ICP_QAT_FW_COMN_REQ_CPM_FW_LA; 20276618d3b5SArek Kusztal header->service_cmd_id = session->qat_cmd; 202898f06089SFiona Trahe header->comn_req_flags = 202998f06089SFiona Trahe ICP_QAT_FW_COMN_FLAGS_BUILD(QAT_COMN_CD_FLD_TYPE_64BIT_ADR, 203098f06089SFiona Trahe QAT_COMN_PTR_TYPE_FLAT); 203198f06089SFiona Trahe ICP_QAT_FW_LA_PARTIAL_SET(header->serv_specif_flags, 203298f06089SFiona Trahe ICP_QAT_FW_LA_PARTIAL_NONE); 203398f06089SFiona Trahe ICP_QAT_FW_LA_CIPH_IV_FLD_FLAG_SET(header->serv_specif_flags, 203498f06089SFiona Trahe ICP_QAT_FW_CIPH_IV_16BYTE_DATA); 203598f06089SFiona Trahe 203698f06089SFiona Trahe switch (proto_flags) { 203798f06089SFiona Trahe case QAT_CRYPTO_PROTO_FLAG_NONE: 203898f06089SFiona Trahe ICP_QAT_FW_LA_PROTO_SET(header->serv_specif_flags, 203998f06089SFiona Trahe ICP_QAT_FW_LA_NO_PROTO); 204098f06089SFiona Trahe break; 204198f06089SFiona Trahe case QAT_CRYPTO_PROTO_FLAG_CCM: 204298f06089SFiona Trahe ICP_QAT_FW_LA_PROTO_SET(header->serv_specif_flags, 204398f06089SFiona Trahe ICP_QAT_FW_LA_CCM_PROTO); 204498f06089SFiona Trahe break; 204598f06089SFiona Trahe case QAT_CRYPTO_PROTO_FLAG_GCM: 204698f06089SFiona Trahe ICP_QAT_FW_LA_PROTO_SET(header->serv_specif_flags, 204798f06089SFiona Trahe ICP_QAT_FW_LA_GCM_PROTO); 204898f06089SFiona Trahe break; 204998f06089SFiona Trahe case QAT_CRYPTO_PROTO_FLAG_SNOW3G: 205098f06089SFiona Trahe ICP_QAT_FW_LA_PROTO_SET(header->serv_specif_flags, 205198f06089SFiona Trahe ICP_QAT_FW_LA_SNOW_3G_PROTO); 205298f06089SFiona Trahe break; 205398f06089SFiona Trahe case QAT_CRYPTO_PROTO_FLAG_ZUC: 205498f06089SFiona Trahe ICP_QAT_FW_LA_ZUC_3G_PROTO_FLAG_SET(header->serv_specif_flags, 205598f06089SFiona Trahe ICP_QAT_FW_LA_ZUC_3G_PROTO); 205698f06089SFiona Trahe break; 205798f06089SFiona Trahe } 205898f06089SFiona Trahe 20596618d3b5SArek Kusztal /* More than one of the following flags can be set at once */ 20606618d3b5SArek Kusztal if (QAT_SESSION_IS_SLICE_SET(slice_flags, QAT_CRYPTO_SLICE_SPC)) { 20616618d3b5SArek Kusztal ICP_QAT_FW_LA_SINGLE_PASS_PROTO_FLAG_SET( 20626618d3b5SArek Kusztal header->serv_specif_flags, 20636618d3b5SArek Kusztal ICP_QAT_FW_LA_SINGLE_PASS_PROTO); 20646618d3b5SArek Kusztal } 20656618d3b5SArek Kusztal if (QAT_SESSION_IS_SLICE_SET(slice_flags, QAT_CRYPTO_SLICE_UCS)) { 20666618d3b5SArek Kusztal ICP_QAT_FW_LA_SLICE_TYPE_SET( 20676618d3b5SArek Kusztal header->serv_specif_flags, 20686618d3b5SArek Kusztal ICP_QAT_FW_LA_USE_UCS_SLICE_TYPE); 20696618d3b5SArek Kusztal } 20706618d3b5SArek Kusztal 20716618d3b5SArek Kusztal if (session->is_auth) { 20726618d3b5SArek Kusztal if (session->auth_op == ICP_QAT_HW_AUTH_VERIFY) { 20736618d3b5SArek Kusztal ICP_QAT_FW_LA_RET_AUTH_SET(header->serv_specif_flags, 20746618d3b5SArek Kusztal ICP_QAT_FW_LA_NO_RET_AUTH_RES); 20756618d3b5SArek Kusztal ICP_QAT_FW_LA_CMP_AUTH_SET(header->serv_specif_flags, 20766618d3b5SArek Kusztal ICP_QAT_FW_LA_CMP_AUTH_RES); 20776618d3b5SArek Kusztal } else if (session->auth_op == ICP_QAT_HW_AUTH_GENERATE) { 20786618d3b5SArek Kusztal ICP_QAT_FW_LA_RET_AUTH_SET(header->serv_specif_flags, 20796618d3b5SArek Kusztal ICP_QAT_FW_LA_RET_AUTH_RES); 20806618d3b5SArek Kusztal ICP_QAT_FW_LA_CMP_AUTH_SET(header->serv_specif_flags, 20816618d3b5SArek Kusztal ICP_QAT_FW_LA_NO_CMP_AUTH_RES); 20826618d3b5SArek Kusztal } 20836618d3b5SArek Kusztal } else { 20846618d3b5SArek Kusztal ICP_QAT_FW_LA_RET_AUTH_SET(header->serv_specif_flags, 20856618d3b5SArek Kusztal ICP_QAT_FW_LA_NO_RET_AUTH_RES); 20866618d3b5SArek Kusztal ICP_QAT_FW_LA_CMP_AUTH_SET(header->serv_specif_flags, 20876618d3b5SArek Kusztal ICP_QAT_FW_LA_NO_CMP_AUTH_RES); 20886618d3b5SArek Kusztal } 20896618d3b5SArek Kusztal 20906618d3b5SArek Kusztal if (session->is_iv12B) { 20916618d3b5SArek Kusztal ICP_QAT_FW_LA_GCM_IV_LEN_FLAG_SET( 20926618d3b5SArek Kusztal header->serv_specif_flags, 20936618d3b5SArek Kusztal ICP_QAT_FW_LA_GCM_IV_LEN_12_OCTETS); 20946618d3b5SArek Kusztal } 20956618d3b5SArek Kusztal 209698f06089SFiona Trahe ICP_QAT_FW_LA_UPDATE_STATE_SET(header->serv_specif_flags, 209798f06089SFiona Trahe ICP_QAT_FW_LA_NO_UPDATE_STATE); 209898f06089SFiona Trahe ICP_QAT_FW_LA_DIGEST_IN_BUFFER_SET(header->serv_specif_flags, 209998f06089SFiona Trahe ICP_QAT_FW_LA_NO_DIGEST_IN_BUFFER); 210098f06089SFiona Trahe } 210198f06089SFiona Trahe 2102e2c11053SNishikant Nayak static void 2103e2c11053SNishikant Nayak qat_sym_session_init_gen_lce_hdr(struct qat_sym_session *session) 2104e2c11053SNishikant Nayak { 2105e2c11053SNishikant Nayak struct icp_qat_fw_la_bulk_req *req_tmpl = &session->fw_req; 2106e2c11053SNishikant Nayak struct icp_qat_fw_comn_req_hdr *header = &req_tmpl->comn_hdr; 2107e2c11053SNishikant Nayak 2108e2c11053SNishikant Nayak /* 2109e2c11053SNishikant Nayak * GEN_LCE specifies separate command id for AEAD operations but Cryptodev 2110e2c11053SNishikant Nayak * API processes AEAD operations as Single pass Crypto operations. 2111e2c11053SNishikant Nayak * Hence even for GEN_LCE, Session Algo Command ID is CIPHER. 2112e2c11053SNishikant Nayak * Note, however Session Algo Mode is AEAD. 2113e2c11053SNishikant Nayak */ 2114e2c11053SNishikant Nayak header->service_cmd_id = ICP_QAT_FW_LA_CMD_AEAD; 2115e2c11053SNishikant Nayak header->service_type = ICP_QAT_FW_COMN_REQ_CPM_FW_LA; 2116e2c11053SNishikant Nayak header->hdr_flags = ICP_QAT_FW_COMN_HDR_FLAGS_BUILD_GEN_LCE(ICP_QAT_FW_COMN_REQ_FLAG_SET, 2117e2c11053SNishikant Nayak ICP_QAT_FW_COMN_GEN_LCE_DESC_LAYOUT); 2118e2c11053SNishikant Nayak header->comn_req_flags = ICP_QAT_FW_COMN_FLAGS_BUILD_GEN_LCE(QAT_COMN_PTR_TYPE_SGL, 2119e2c11053SNishikant Nayak QAT_COMN_KEY_BUFFER_USED); 2120e2c11053SNishikant Nayak 2121e2c11053SNishikant Nayak ICP_QAT_FW_SYM_AEAD_ALGO_SET(header->serv_specif_flags, QAT_LA_CRYPTO_AEAD_AES_GCM_GEN_LCE); 2122e2c11053SNishikant Nayak ICP_QAT_FW_SYM_IV_SIZE_SET(header->serv_specif_flags, ICP_QAT_FW_LA_GCM_IV_LEN_12_OCTETS); 2123e2c11053SNishikant Nayak ICP_QAT_FW_SYM_IV_IN_DESC_FLAG_SET(header->serv_specif_flags, 2124e2c11053SNishikant Nayak ICP_QAT_FW_SYM_IV_IN_DESC_VALID); 2125e2c11053SNishikant Nayak 2126e2c11053SNishikant Nayak if (session->qat_dir == ICP_QAT_HW_CIPHER_DECRYPT) { 2127e2c11053SNishikant Nayak ICP_QAT_FW_SYM_DIR_FLAG_SET(header->serv_specif_flags, ICP_QAT_HW_CIPHER_DECRYPT); 2128e2c11053SNishikant Nayak } else { 2129e2c11053SNishikant Nayak ICP_QAT_FW_SYM_DIR_FLAG_SET(header->serv_specif_flags, ICP_QAT_HW_CIPHER_ENCRYPT); 2130e2c11053SNishikant Nayak } 2131e2c11053SNishikant Nayak } 2132e2c11053SNishikant Nayak 2133bfe16f14SArek Kusztal int qat_sym_cd_cipher_set(struct qat_sym_session *cdesc, 2134186b14d6SFan Zhang const uint8_t *cipherkey, 213598f06089SFiona Trahe uint32_t cipherkeylen) 213698f06089SFiona Trahe { 213798f06089SFiona Trahe struct icp_qat_hw_cipher_algo_blk *cipher; 2138d0549291SArek Kusztal struct icp_qat_hw_cipher_algo_blk20 *cipher20; 213998f06089SFiona Trahe struct icp_qat_fw_la_bulk_req *req_tmpl = &cdesc->fw_req; 214098f06089SFiona Trahe struct icp_qat_fw_comn_req_hdr_cd_pars *cd_pars = &req_tmpl->cd_pars; 214198f06089SFiona Trahe struct icp_qat_fw_comn_req_hdr *header = &req_tmpl->comn_hdr; 214298f06089SFiona Trahe void *ptr = &req_tmpl->cd_ctrl; 214398f06089SFiona Trahe struct icp_qat_fw_cipher_cd_ctrl_hdr *cipher_cd_ctrl = ptr; 214498f06089SFiona Trahe struct icp_qat_fw_auth_cd_ctrl_hdr *hash_cd_ctrl = ptr; 214598f06089SFiona Trahe enum icp_qat_hw_cipher_convert key_convert; 21466618d3b5SArek Kusztal struct icp_qat_fw_la_cipher_20_req_params *req_ucs = 21476618d3b5SArek Kusztal (struct icp_qat_fw_la_cipher_20_req_params *) 21486618d3b5SArek Kusztal &cdesc->fw_req.serv_specif_rqpars; 21496618d3b5SArek Kusztal struct icp_qat_fw_la_cipher_req_params *req_cipher = 21506618d3b5SArek Kusztal (struct icp_qat_fw_la_cipher_req_params *) 21516618d3b5SArek Kusztal &cdesc->fw_req.serv_specif_rqpars; 215298f06089SFiona Trahe uint32_t total_key_size; 215398f06089SFiona Trahe uint16_t cipher_offset, cd_size; 215498f06089SFiona Trahe uint32_t wordIndex = 0; 215598f06089SFiona Trahe uint32_t *temp_key = NULL; 215698f06089SFiona Trahe 215798f06089SFiona Trahe if (cdesc->qat_cmd == ICP_QAT_FW_LA_CMD_CIPHER) { 215898f06089SFiona Trahe cd_pars->u.s.content_desc_addr = cdesc->cd_paddr; 215998f06089SFiona Trahe ICP_QAT_FW_COMN_CURR_ID_SET(cipher_cd_ctrl, 216098f06089SFiona Trahe ICP_QAT_FW_SLICE_CIPHER); 216198f06089SFiona Trahe ICP_QAT_FW_COMN_NEXT_ID_SET(cipher_cd_ctrl, 216298f06089SFiona Trahe ICP_QAT_FW_SLICE_DRAM_WR); 216398f06089SFiona Trahe ICP_QAT_FW_LA_RET_AUTH_SET(header->serv_specif_flags, 216498f06089SFiona Trahe ICP_QAT_FW_LA_NO_RET_AUTH_RES); 216598f06089SFiona Trahe ICP_QAT_FW_LA_CMP_AUTH_SET(header->serv_specif_flags, 216698f06089SFiona Trahe ICP_QAT_FW_LA_NO_CMP_AUTH_RES); 216798f06089SFiona Trahe cdesc->cd_cur_ptr = (uint8_t *)&cdesc->cd; 216898f06089SFiona Trahe } else if (cdesc->qat_cmd == ICP_QAT_FW_LA_CMD_CIPHER_HASH) { 216998f06089SFiona Trahe cd_pars->u.s.content_desc_addr = cdesc->cd_paddr; 217098f06089SFiona Trahe ICP_QAT_FW_COMN_CURR_ID_SET(cipher_cd_ctrl, 217198f06089SFiona Trahe ICP_QAT_FW_SLICE_CIPHER); 217298f06089SFiona Trahe ICP_QAT_FW_COMN_NEXT_ID_SET(cipher_cd_ctrl, 217398f06089SFiona Trahe ICP_QAT_FW_SLICE_AUTH); 217498f06089SFiona Trahe ICP_QAT_FW_COMN_CURR_ID_SET(hash_cd_ctrl, 217598f06089SFiona Trahe ICP_QAT_FW_SLICE_AUTH); 217698f06089SFiona Trahe ICP_QAT_FW_COMN_NEXT_ID_SET(hash_cd_ctrl, 217798f06089SFiona Trahe ICP_QAT_FW_SLICE_DRAM_WR); 217898f06089SFiona Trahe cdesc->cd_cur_ptr = (uint8_t *)&cdesc->cd; 2179ce7a737cSKevin O'Sullivan } else if (cdesc->qat_cmd == ICP_QAT_FW_LA_CMD_CIPHER_CRC) { 2180ce7a737cSKevin O'Sullivan cd_pars->u.s.content_desc_addr = cdesc->cd_paddr; 2181ce7a737cSKevin O'Sullivan cdesc->cd_cur_ptr = (uint8_t *)&cdesc->cd; 218298f06089SFiona Trahe } else if (cdesc->qat_cmd != ICP_QAT_FW_LA_CMD_HASH_CIPHER) { 2183be24b0d9SFiona Trahe QAT_LOG(ERR, "Invalid param, must be a cipher command."); 218498f06089SFiona Trahe return -EFAULT; 218598f06089SFiona Trahe } 218698f06089SFiona Trahe 218798f06089SFiona Trahe if (cdesc->qat_mode == ICP_QAT_HW_CIPHER_CTR_MODE) { 218898f06089SFiona Trahe /* 218998f06089SFiona Trahe * CTR Streaming ciphers are a special case. Decrypt = encrypt 21906618d3b5SArek Kusztal * Overriding default values previously set. 21916618d3b5SArek Kusztal * Chacha20-Poly1305 is special case, CTR but single-pass 21926618d3b5SArek Kusztal * so both direction need to be used. 219398f06089SFiona Trahe */ 219498f06089SFiona Trahe cdesc->qat_dir = ICP_QAT_HW_CIPHER_ENCRYPT; 21956618d3b5SArek Kusztal if (cdesc->qat_cipher_alg == 21966618d3b5SArek Kusztal ICP_QAT_HW_CIPHER_ALGO_CHACHA20_POLY1305 && 21976618d3b5SArek Kusztal cdesc->auth_op == ICP_QAT_HW_AUTH_VERIFY) { 21986618d3b5SArek Kusztal cdesc->qat_dir = ICP_QAT_HW_CIPHER_DECRYPT; 21996618d3b5SArek Kusztal } 220098f06089SFiona Trahe key_convert = ICP_QAT_HW_CIPHER_NO_CONVERT; 220198f06089SFiona Trahe } else if (cdesc->qat_cipher_alg == ICP_QAT_HW_CIPHER_ALGO_SNOW_3G_UEA2 220298f06089SFiona Trahe || cdesc->qat_cipher_alg == 22036c868d6eSCiara Power ICP_QAT_HW_CIPHER_ALGO_ZUC_3G_128_EEA3 22046c868d6eSCiara Power || cdesc->qat_cipher_alg == ICP_QAT_HW_CIPHER_ALGO_ZUC_256) { 220598f06089SFiona Trahe key_convert = ICP_QAT_HW_CIPHER_KEY_CONVERT; 220696ef7febSCiara Power cdesc->qat_dir = ICP_QAT_HW_CIPHER_ENCRYPT; 220796ef7febSCiara Power } else if (cdesc->qat_dir == ICP_QAT_HW_CIPHER_ENCRYPT) 220898f06089SFiona Trahe key_convert = ICP_QAT_HW_CIPHER_NO_CONVERT; 22096618d3b5SArek Kusztal else if (cdesc->qat_mode == ICP_QAT_HW_CIPHER_AEAD_MODE) 22106618d3b5SArek Kusztal key_convert = ICP_QAT_HW_CIPHER_NO_CONVERT; 221198f06089SFiona Trahe else 221298f06089SFiona Trahe key_convert = ICP_QAT_HW_CIPHER_KEY_CONVERT; 221398f06089SFiona Trahe 221498f06089SFiona Trahe if (cdesc->qat_cipher_alg == ICP_QAT_HW_CIPHER_ALGO_SNOW_3G_UEA2) { 221598f06089SFiona Trahe total_key_size = ICP_QAT_HW_SNOW_3G_UEA2_KEY_SZ + 221698f06089SFiona Trahe ICP_QAT_HW_SNOW_3G_UEA2_IV_SZ; 221798f06089SFiona Trahe cipher_cd_ctrl->cipher_state_sz = 221898f06089SFiona Trahe ICP_QAT_HW_SNOW_3G_UEA2_IV_SZ >> 3; 22196618d3b5SArek Kusztal cdesc->qat_proto_flag = QAT_CRYPTO_PROTO_FLAG_SNOW3G; 222098f06089SFiona Trahe 222198f06089SFiona Trahe } else if (cdesc->qat_cipher_alg == ICP_QAT_HW_CIPHER_ALGO_KASUMI) { 222298f06089SFiona Trahe total_key_size = ICP_QAT_HW_KASUMI_F8_KEY_SZ; 222398f06089SFiona Trahe cipher_cd_ctrl->cipher_state_sz = ICP_QAT_HW_KASUMI_BLK_SZ >> 3; 222498f06089SFiona Trahe cipher_cd_ctrl->cipher_padding_sz = 222598f06089SFiona Trahe (2 * ICP_QAT_HW_KASUMI_BLK_SZ) >> 3; 222698f06089SFiona Trahe } else if (cdesc->qat_cipher_alg == ICP_QAT_HW_CIPHER_ALGO_3DES) { 222798f06089SFiona Trahe total_key_size = ICP_QAT_HW_3DES_KEY_SZ; 222898f06089SFiona Trahe cipher_cd_ctrl->cipher_state_sz = ICP_QAT_HW_3DES_BLK_SZ >> 3; 222998f06089SFiona Trahe } else if (cdesc->qat_cipher_alg == ICP_QAT_HW_CIPHER_ALGO_DES) { 223098f06089SFiona Trahe total_key_size = ICP_QAT_HW_DES_KEY_SZ; 223198f06089SFiona Trahe cipher_cd_ctrl->cipher_state_sz = ICP_QAT_HW_DES_BLK_SZ >> 3; 223298f06089SFiona Trahe } else if (cdesc->qat_cipher_alg == 223398f06089SFiona Trahe ICP_QAT_HW_CIPHER_ALGO_ZUC_3G_128_EEA3) { 223498f06089SFiona Trahe total_key_size = ICP_QAT_HW_ZUC_3G_EEA3_KEY_SZ + 223598f06089SFiona Trahe ICP_QAT_HW_ZUC_3G_EEA3_IV_SZ; 223698f06089SFiona Trahe cipher_cd_ctrl->cipher_state_sz = 223798f06089SFiona Trahe ICP_QAT_HW_ZUC_3G_EEA3_IV_SZ >> 3; 22386618d3b5SArek Kusztal cdesc->qat_proto_flag = QAT_CRYPTO_PROTO_FLAG_ZUC; 22396c868d6eSCiara Power } else if (cdesc->qat_cipher_alg == 22406c868d6eSCiara Power ICP_QAT_HW_CIPHER_ALGO_ZUC_256) { 22416c868d6eSCiara Power if (cdesc->cipher_iv.length != 23 && cdesc->cipher_iv.length != 25) { 22426c868d6eSCiara Power QAT_LOG(ERR, "Invalid IV length for ZUC256, must be 23 or 25."); 22436c868d6eSCiara Power return -EINVAL; 22446c868d6eSCiara Power } 22456c868d6eSCiara Power total_key_size = ICP_QAT_HW_ZUC_256_KEY_SZ + 22466c868d6eSCiara Power ICP_QAT_HW_ZUC_256_IV_SZ; 22476c868d6eSCiara Power cipher_cd_ctrl->cipher_state_sz = 22486c868d6eSCiara Power ICP_QAT_HW_ZUC_256_IV_SZ >> 3; 22496c868d6eSCiara Power cdesc->qat_proto_flag = QAT_CRYPTO_PROTO_FLAG_ZUC; 225098f06089SFiona Trahe } else { 225198f06089SFiona Trahe total_key_size = cipherkeylen; 225298f06089SFiona Trahe cipher_cd_ctrl->cipher_state_sz = ICP_QAT_HW_AES_BLK_SZ >> 3; 225398f06089SFiona Trahe } 225498f06089SFiona Trahe cipher_offset = cdesc->cd_cur_ptr-((uint8_t *)&cdesc->cd); 225598f06089SFiona Trahe cipher_cd_ctrl->cipher_cfg_offset = cipher_offset >> 3; 225698f06089SFiona Trahe 225798f06089SFiona Trahe cipher = (struct icp_qat_hw_cipher_algo_blk *)cdesc->cd_cur_ptr; 2258d0549291SArek Kusztal cipher20 = (struct icp_qat_hw_cipher_algo_blk20 *)cdesc->cd_cur_ptr; 225998f06089SFiona Trahe cipher->cipher_config.val = 226098f06089SFiona Trahe ICP_QAT_HW_CIPHER_CONFIG_BUILD(cdesc->qat_mode, 226198f06089SFiona Trahe cdesc->qat_cipher_alg, key_convert, 226298f06089SFiona Trahe cdesc->qat_dir); 226398f06089SFiona Trahe 226498f06089SFiona Trahe if (cdesc->qat_cipher_alg == ICP_QAT_HW_CIPHER_ALGO_KASUMI) { 226598f06089SFiona Trahe temp_key = (uint32_t *)(cdesc->cd_cur_ptr + 226698f06089SFiona Trahe sizeof(struct icp_qat_hw_cipher_config) 226798f06089SFiona Trahe + cipherkeylen); 226898f06089SFiona Trahe memcpy(cipher->key, cipherkey, cipherkeylen); 226998f06089SFiona Trahe memcpy(temp_key, cipherkey, cipherkeylen); 227098f06089SFiona Trahe 227198f06089SFiona Trahe /* XOR Key with KASUMI F8 key modifier at 4 bytes level */ 227298f06089SFiona Trahe for (wordIndex = 0; wordIndex < (cipherkeylen >> 2); 227398f06089SFiona Trahe wordIndex++) 227498f06089SFiona Trahe temp_key[wordIndex] ^= KASUMI_F8_KEY_MODIFIER_4_BYTES; 227598f06089SFiona Trahe 227698f06089SFiona Trahe cdesc->cd_cur_ptr += sizeof(struct icp_qat_hw_cipher_config) + 227798f06089SFiona Trahe cipherkeylen + cipherkeylen; 2278d0549291SArek Kusztal } else if (cdesc->is_ucs) { 2279d0549291SArek Kusztal const uint8_t *final_key = cipherkey; 2280d0549291SArek Kusztal 22816618d3b5SArek Kusztal cdesc->slice_types |= QAT_CRYPTO_SLICE_UCS; 2282d0549291SArek Kusztal total_key_size = RTE_ALIGN_CEIL(cipherkeylen, 2283d0549291SArek Kusztal ICP_QAT_HW_AES_128_KEY_SZ); 2284d0549291SArek Kusztal cipher20->cipher_config.reserved[0] = 0; 2285d0549291SArek Kusztal cipher20->cipher_config.reserved[1] = 0; 2286d0549291SArek Kusztal cipher20->cipher_config.reserved[2] = 0; 2287d0549291SArek Kusztal 2288d0549291SArek Kusztal rte_memcpy(cipher20->key, final_key, cipherkeylen); 2289d0549291SArek Kusztal cdesc->cd_cur_ptr += 2290d0549291SArek Kusztal sizeof(struct icp_qat_hw_ucs_cipher_config) + 2291d0549291SArek Kusztal cipherkeylen; 229298f06089SFiona Trahe } else { 229398f06089SFiona Trahe memcpy(cipher->key, cipherkey, cipherkeylen); 229498f06089SFiona Trahe cdesc->cd_cur_ptr += sizeof(struct icp_qat_hw_cipher_config) + 229598f06089SFiona Trahe cipherkeylen; 229698f06089SFiona Trahe } 229798f06089SFiona Trahe 22986618d3b5SArek Kusztal if (cdesc->is_single_pass) { 22996618d3b5SArek Kusztal QAT_FIELD_SET(cipher->cipher_config.val, 23006618d3b5SArek Kusztal cdesc->digest_length, 23016618d3b5SArek Kusztal QAT_CIPHER_AEAD_HASH_CMP_LEN_BITPOS, 23026618d3b5SArek Kusztal QAT_CIPHER_AEAD_HASH_CMP_LEN_MASK); 23036618d3b5SArek Kusztal /* UCS and SPC 1.8/2.0 share configuration of 2nd config word */ 23046618d3b5SArek Kusztal cdesc->cd.cipher.cipher_config.reserved = 23056618d3b5SArek Kusztal ICP_QAT_HW_CIPHER_CONFIG_BUILD_UPPER( 23066618d3b5SArek Kusztal cdesc->aad_len); 23076618d3b5SArek Kusztal cdesc->slice_types |= QAT_CRYPTO_SLICE_SPC; 23086618d3b5SArek Kusztal } 23096618d3b5SArek Kusztal 231098f06089SFiona Trahe if (total_key_size > cipherkeylen) { 231198f06089SFiona Trahe uint32_t padding_size = total_key_size-cipherkeylen; 231298f06089SFiona Trahe if ((cdesc->qat_cipher_alg == ICP_QAT_HW_CIPHER_ALGO_3DES) 2313e3d99884SFiona Trahe && (cipherkeylen == QAT_3DES_KEY_SZ_OPT2)) { 231498f06089SFiona Trahe /* K3 not provided so use K1 = K3*/ 231598f06089SFiona Trahe memcpy(cdesc->cd_cur_ptr, cipherkey, padding_size); 2316e3d99884SFiona Trahe } else if ((cdesc->qat_cipher_alg == ICP_QAT_HW_CIPHER_ALGO_3DES) 2317e3d99884SFiona Trahe && (cipherkeylen == QAT_3DES_KEY_SZ_OPT3)) { 2318e3d99884SFiona Trahe /* K2 and K3 not provided so use K1 = K2 = K3*/ 2319e3d99884SFiona Trahe memcpy(cdesc->cd_cur_ptr, cipherkey, 2320e3d99884SFiona Trahe cipherkeylen); 2321e3d99884SFiona Trahe memcpy(cdesc->cd_cur_ptr+cipherkeylen, 2322e3d99884SFiona Trahe cipherkey, cipherkeylen); 2323e3d99884SFiona Trahe } else 232498f06089SFiona Trahe memset(cdesc->cd_cur_ptr, 0, padding_size); 2325e3d99884SFiona Trahe 232698f06089SFiona Trahe cdesc->cd_cur_ptr += padding_size; 232798f06089SFiona Trahe } 23286618d3b5SArek Kusztal if (cdesc->is_ucs) { 23296618d3b5SArek Kusztal /* 23306618d3b5SArek Kusztal * These values match in terms of position auth 23316618d3b5SArek Kusztal * slice request fields 23326618d3b5SArek Kusztal */ 23336618d3b5SArek Kusztal req_ucs->spc_auth_res_sz = cdesc->digest_length; 23346618d3b5SArek Kusztal if (!cdesc->is_gmac) { 23356618d3b5SArek Kusztal req_ucs->spc_aad_sz = cdesc->aad_len; 23366618d3b5SArek Kusztal req_ucs->spc_aad_offset = 0; 23376618d3b5SArek Kusztal } 23386618d3b5SArek Kusztal } else if (cdesc->is_single_pass) { 23396618d3b5SArek Kusztal req_cipher->spc_aad_sz = cdesc->aad_len; 23406618d3b5SArek Kusztal req_cipher->spc_auth_res_sz = cdesc->digest_length; 23416618d3b5SArek Kusztal } 234298f06089SFiona Trahe cd_size = cdesc->cd_cur_ptr-(uint8_t *)&cdesc->cd; 234398f06089SFiona Trahe cd_pars->u.s.content_desc_params_sz = RTE_ALIGN_CEIL(cd_size, 8) >> 3; 2344d0549291SArek Kusztal cipher_cd_ctrl->cipher_key_sz = total_key_size >> 3; 234598f06089SFiona Trahe 234698f06089SFiona Trahe return 0; 234798f06089SFiona Trahe } 234898f06089SFiona Trahe 2349bfe16f14SArek Kusztal int qat_sym_cd_auth_set(struct qat_sym_session *cdesc, 2350186b14d6SFan Zhang const uint8_t *authkey, 235198f06089SFiona Trahe uint32_t authkeylen, 235298f06089SFiona Trahe uint32_t aad_length, 235398f06089SFiona Trahe uint32_t digestsize, 2354171c655bSArkadiusz Kusztal unsigned int operation, 2355171c655bSArkadiusz Kusztal enum qat_device_gen qat_dev_gen) 235698f06089SFiona Trahe { 2357171c655bSArkadiusz Kusztal struct icp_qat_hw_auth_setup *hash, *hash_2 = NULL; 235898f06089SFiona Trahe struct icp_qat_hw_cipher_algo_blk *cipherconfig; 235998f06089SFiona Trahe struct icp_qat_fw_la_bulk_req *req_tmpl = &cdesc->fw_req; 236098f06089SFiona Trahe struct icp_qat_fw_comn_req_hdr_cd_pars *cd_pars = &req_tmpl->cd_pars; 236198f06089SFiona Trahe void *ptr = &req_tmpl->cd_ctrl; 236298f06089SFiona Trahe struct icp_qat_fw_cipher_cd_ctrl_hdr *cipher_cd_ctrl = ptr; 236398f06089SFiona Trahe struct icp_qat_fw_auth_cd_ctrl_hdr *hash_cd_ctrl = ptr; 236498f06089SFiona Trahe struct icp_qat_fw_la_auth_req_params *auth_param = 236598f06089SFiona Trahe (struct icp_qat_fw_la_auth_req_params *) 236698f06089SFiona Trahe ((char *)&req_tmpl->serv_specif_rqpars + 2367aa983f03SAdam Dybkowski ICP_QAT_FW_HASH_REQUEST_PARAMETERS_OFFSET); 2368fae347cbSArek Kusztal uint16_t state1_size = 0, state2_size = 0, cd_extra_size = 0; 236998f06089SFiona Trahe uint16_t hash_offset, cd_size; 237098f06089SFiona Trahe uint32_t *aad_len = NULL; 237198f06089SFiona Trahe uint32_t wordIndex = 0; 237298f06089SFiona Trahe uint32_t *pTempKey; 2373171c655bSArkadiusz Kusztal uint8_t *prefix = NULL; 23743227bc71SKai Ji int ret = 0; 237598f06089SFiona Trahe 237698f06089SFiona Trahe if (cdesc->qat_cmd == ICP_QAT_FW_LA_CMD_AUTH) { 237798f06089SFiona Trahe ICP_QAT_FW_COMN_CURR_ID_SET(hash_cd_ctrl, 237898f06089SFiona Trahe ICP_QAT_FW_SLICE_AUTH); 237998f06089SFiona Trahe ICP_QAT_FW_COMN_NEXT_ID_SET(hash_cd_ctrl, 238098f06089SFiona Trahe ICP_QAT_FW_SLICE_DRAM_WR); 238198f06089SFiona Trahe cdesc->cd_cur_ptr = (uint8_t *)&cdesc->cd; 238298f06089SFiona Trahe } else if (cdesc->qat_cmd == ICP_QAT_FW_LA_CMD_HASH_CIPHER) { 238398f06089SFiona Trahe ICP_QAT_FW_COMN_CURR_ID_SET(hash_cd_ctrl, 238498f06089SFiona Trahe ICP_QAT_FW_SLICE_AUTH); 238598f06089SFiona Trahe ICP_QAT_FW_COMN_NEXT_ID_SET(hash_cd_ctrl, 238698f06089SFiona Trahe ICP_QAT_FW_SLICE_CIPHER); 238798f06089SFiona Trahe ICP_QAT_FW_COMN_CURR_ID_SET(cipher_cd_ctrl, 238898f06089SFiona Trahe ICP_QAT_FW_SLICE_CIPHER); 238998f06089SFiona Trahe ICP_QAT_FW_COMN_NEXT_ID_SET(cipher_cd_ctrl, 239098f06089SFiona Trahe ICP_QAT_FW_SLICE_DRAM_WR); 239198f06089SFiona Trahe cdesc->cd_cur_ptr = (uint8_t *)&cdesc->cd; 239298f06089SFiona Trahe } else if (cdesc->qat_cmd != ICP_QAT_FW_LA_CMD_CIPHER_HASH) { 2393be24b0d9SFiona Trahe QAT_LOG(ERR, "Invalid param, must be a hash command."); 239498f06089SFiona Trahe return -EFAULT; 239598f06089SFiona Trahe } 239698f06089SFiona Trahe 23976618d3b5SArek Kusztal if (operation == RTE_CRYPTO_AUTH_OP_VERIFY) 239898f06089SFiona Trahe cdesc->auth_op = ICP_QAT_HW_AUTH_VERIFY; 23996618d3b5SArek Kusztal else 240098f06089SFiona Trahe cdesc->auth_op = ICP_QAT_HW_AUTH_GENERATE; 240198f06089SFiona Trahe 240298f06089SFiona Trahe /* 240398f06089SFiona Trahe * Setup the inner hash config 240498f06089SFiona Trahe */ 240598f06089SFiona Trahe hash_offset = cdesc->cd_cur_ptr-((uint8_t *)&cdesc->cd); 240698f06089SFiona Trahe hash = (struct icp_qat_hw_auth_setup *)cdesc->cd_cur_ptr; 240798f06089SFiona Trahe hash->auth_config.reserved = 0; 24087283c59eSBrian Dooley if (cdesc->qat_hash_alg == ICP_QAT_HW_AUTH_ALGO_NULL) 24097283c59eSBrian Dooley hash->auth_config.config = 24107283c59eSBrian Dooley ICP_QAT_HW_AUTH_CONFIG_BUILD(cdesc->auth_mode, 24117283c59eSBrian Dooley cdesc->qat_hash_alg, 4); 24127283c59eSBrian Dooley else 241398f06089SFiona Trahe hash->auth_config.config = 24146e21c1a5SAdam Dybkowski ICP_QAT_HW_AUTH_CONFIG_BUILD(cdesc->auth_mode, 241598f06089SFiona Trahe cdesc->qat_hash_alg, digestsize); 241698f06089SFiona Trahe 24176e21c1a5SAdam Dybkowski if (cdesc->auth_mode == ICP_QAT_HW_AUTH_MODE0 24186e21c1a5SAdam Dybkowski || cdesc->qat_hash_alg == ICP_QAT_HW_AUTH_ALGO_SNOW_3G_UIA2 241998f06089SFiona Trahe || cdesc->qat_hash_alg == ICP_QAT_HW_AUTH_ALGO_KASUMI_F9 242091c1daa4STomasz Cel || cdesc->qat_hash_alg == ICP_QAT_HW_AUTH_ALGO_ZUC_3G_128_EIA3 24216c868d6eSCiara Power || cdesc->qat_hash_alg == ICP_QAT_HW_AUTH_ALGO_ZUC_256_MAC_32 24226c868d6eSCiara Power || cdesc->qat_hash_alg == ICP_QAT_HW_AUTH_ALGO_ZUC_256_MAC_64 24236c868d6eSCiara Power || cdesc->qat_hash_alg == ICP_QAT_HW_AUTH_ALGO_ZUC_256_MAC_128 242491c1daa4STomasz Cel || cdesc->qat_hash_alg == ICP_QAT_HW_AUTH_ALGO_AES_XCBC_MAC 2425210bea96SCiara Power || cdesc->qat_hash_alg == ICP_QAT_HW_AUTH_ALGO_AES_128_CMAC 2426605eb4d5SArek Kusztal || cdesc->qat_hash_alg == ICP_QAT_HW_AUTH_ALGO_AES_CBC_MAC 24274dc73ff7SArek Kusztal || cdesc->qat_hash_alg == ICP_QAT_HW_AUTH_ALGO_NULL 2428171c655bSArkadiusz Kusztal || cdesc->qat_hash_alg == ICP_QAT_HW_AUTH_ALGO_SM3 2429e4beb311SArek Kusztal || cdesc->is_cnt_zero 243091c1daa4STomasz Cel ) 243198f06089SFiona Trahe hash->auth_counter.counter = 0; 243293685b1fSArek Kusztal else { 243393685b1fSArek Kusztal int block_size = qat_hash_get_block_size(cdesc->qat_hash_alg); 243493685b1fSArek Kusztal 243593685b1fSArek Kusztal if (block_size < 0) 243693685b1fSArek Kusztal return block_size; 243793685b1fSArek Kusztal hash->auth_counter.counter = rte_bswap32(block_size); 243893685b1fSArek Kusztal } 243998f06089SFiona Trahe 2440171c655bSArkadiusz Kusztal hash_cd_ctrl->hash_cfg_offset = hash_offset >> 3; 244198f06089SFiona Trahe cdesc->cd_cur_ptr += sizeof(struct icp_qat_hw_auth_setup); 244298f06089SFiona Trahe switch (cdesc->qat_hash_alg) { 244375fd4bbcSArek Kusztal case ICP_QAT_HW_AUTH_ALGO_SM3: 244475fd4bbcSArek Kusztal rte_memcpy(cdesc->cd_cur_ptr, sm3InitialState, 244575fd4bbcSArek Kusztal sizeof(sm3InitialState)); 244675fd4bbcSArek Kusztal state1_size = qat_hash_get_state1_size( 244775fd4bbcSArek Kusztal cdesc->qat_hash_alg); 244875fd4bbcSArek Kusztal state2_size = ICP_QAT_HW_SM3_STATE2_SZ; 2449171c655bSArkadiusz Kusztal if (cdesc->auth_mode == ICP_QAT_HW_AUTH_MODE0) 2450171c655bSArkadiusz Kusztal break; 2451171c655bSArkadiusz Kusztal hash_2 = (struct icp_qat_hw_auth_setup *)(cdesc->cd_cur_ptr + 2452171c655bSArkadiusz Kusztal state1_size + state2_size); 2453171c655bSArkadiusz Kusztal hash_2->auth_config.config = 2454171c655bSArkadiusz Kusztal ICP_QAT_HW_AUTH_CONFIG_BUILD(ICP_QAT_HW_AUTH_MODE2, 2455171c655bSArkadiusz Kusztal cdesc->qat_hash_alg, digestsize); 2456171c655bSArkadiusz Kusztal rte_memcpy(cdesc->cd_cur_ptr + state1_size + state2_size + 2457171c655bSArkadiusz Kusztal sizeof(*hash_2), sm3InitialState, 2458171c655bSArkadiusz Kusztal sizeof(sm3InitialState)); 2459171c655bSArkadiusz Kusztal hash_cd_ctrl->inner_state1_sz = state1_size; 2460171c655bSArkadiusz Kusztal hash_cd_ctrl->inner_state2_sz = state2_size; 2461171c655bSArkadiusz Kusztal hash_cd_ctrl->inner_state2_offset = 2462171c655bSArkadiusz Kusztal hash_cd_ctrl->hash_cfg_offset + 2463171c655bSArkadiusz Kusztal ((sizeof(struct icp_qat_hw_auth_setup) + 2464171c655bSArkadiusz Kusztal RTE_ALIGN_CEIL(hash_cd_ctrl->inner_state1_sz, 8)) >> 3); 2465171c655bSArkadiusz Kusztal hash_cd_ctrl->outer_config_offset = 2466171c655bSArkadiusz Kusztal hash_cd_ctrl->inner_state2_offset + 2467171c655bSArkadiusz Kusztal ((hash_cd_ctrl->inner_state2_sz) >> 3); 2468171c655bSArkadiusz Kusztal hash_cd_ctrl->outer_state1_sz = state1_size; 2469171c655bSArkadiusz Kusztal hash_cd_ctrl->outer_res_sz = state2_size; 2470171c655bSArkadiusz Kusztal hash_cd_ctrl->outer_prefix_sz = 2471171c655bSArkadiusz Kusztal qat_hash_get_block_size(cdesc->qat_hash_alg); 2472171c655bSArkadiusz Kusztal hash_cd_ctrl->outer_prefix_offset = 2473171c655bSArkadiusz Kusztal qat_hash_get_block_size(cdesc->qat_hash_alg) >> 3; 2474171c655bSArkadiusz Kusztal auth_param->u2.inner_prefix_sz = 2475171c655bSArkadiusz Kusztal qat_hash_get_block_size(cdesc->qat_hash_alg); 2476171c655bSArkadiusz Kusztal auth_param->hash_state_sz = digestsize; 24772e98e808SArkadiusz Kusztal if (qat_dev_gen == QAT_GEN4 || qat_dev_gen == QAT_GEN5 || 24782e98e808SArkadiusz Kusztal qat_dev_gen == QAT_VQAT) { 2479171c655bSArkadiusz Kusztal ICP_QAT_FW_HASH_FLAG_MODE2_SET( 2480171c655bSArkadiusz Kusztal hash_cd_ctrl->hash_flags, 2481171c655bSArkadiusz Kusztal QAT_FW_LA_MODE2); 2482171c655bSArkadiusz Kusztal } else { 2483171c655bSArkadiusz Kusztal hash_cd_ctrl->hash_flags |= 2484171c655bSArkadiusz Kusztal ICP_QAT_FW_AUTH_HDR_FLAG_DO_NESTED; 2485171c655bSArkadiusz Kusztal } 2486171c655bSArkadiusz Kusztal prefix = cdesc->prefix_state; 2487171c655bSArkadiusz Kusztal rte_memcpy(prefix, authkey, authkeylen); 2488171c655bSArkadiusz Kusztal rte_memcpy(prefix + QAT_PREFIX_SIZE, authkey, 2489171c655bSArkadiusz Kusztal authkeylen); 2490171c655bSArkadiusz Kusztal cd_extra_size += sizeof(struct icp_qat_hw_auth_setup) + 2491171c655bSArkadiusz Kusztal state1_size + state2_size; 249275fd4bbcSArek Kusztal break; 249398f06089SFiona Trahe case ICP_QAT_HW_AUTH_ALGO_SHA1: 24946e21c1a5SAdam Dybkowski if (cdesc->auth_mode == ICP_QAT_HW_AUTH_MODE0) { 24956e21c1a5SAdam Dybkowski /* Plain SHA-1 */ 24966e21c1a5SAdam Dybkowski rte_memcpy(cdesc->cd_cur_ptr, sha1InitialState, 24976e21c1a5SAdam Dybkowski sizeof(sha1InitialState)); 24986e21c1a5SAdam Dybkowski state1_size = qat_hash_get_state1_size( 24996e21c1a5SAdam Dybkowski cdesc->qat_hash_alg); 25006e21c1a5SAdam Dybkowski break; 25016e21c1a5SAdam Dybkowski } 25026e21c1a5SAdam Dybkowski /* SHA-1 HMAC */ 2503ca0ba0e4SBrian Dooley #ifdef RTE_QAT_OPENSSL 25043227bc71SKai Ji ret = qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA1, authkey, 250591c1daa4STomasz Cel authkeylen, cdesc->cd_cur_ptr, &state1_size, 25063227bc71SKai Ji cdesc->aes_cmac); 2507ca0ba0e4SBrian Dooley 2508ca0ba0e4SBrian Dooley #else 2509ca0ba0e4SBrian Dooley ret = qat_sym_do_precomputes_ipsec_mb(ICP_QAT_HW_AUTH_ALGO_SHA1, 2510ca0ba0e4SBrian Dooley authkey, authkeylen, cdesc->cd_cur_ptr, &state1_size, 2511ca0ba0e4SBrian Dooley cdesc->aes_cmac); 2512ca0ba0e4SBrian Dooley #endif 25133227bc71SKai Ji 25143227bc71SKai Ji if (ret) { 2515be24b0d9SFiona Trahe QAT_LOG(ERR, "(SHA)precompute failed"); 251698f06089SFiona Trahe return -EFAULT; 251798f06089SFiona Trahe } 251898f06089SFiona Trahe state2_size = RTE_ALIGN_CEIL(ICP_QAT_HW_SHA1_STATE2_SZ, 8); 251998f06089SFiona Trahe break; 252098f06089SFiona Trahe case ICP_QAT_HW_AUTH_ALGO_SHA224: 25216e21c1a5SAdam Dybkowski if (cdesc->auth_mode == ICP_QAT_HW_AUTH_MODE0) { 25226e21c1a5SAdam Dybkowski /* Plain SHA-224 */ 25236e21c1a5SAdam Dybkowski rte_memcpy(cdesc->cd_cur_ptr, sha224InitialState, 25246e21c1a5SAdam Dybkowski sizeof(sha224InitialState)); 25256e21c1a5SAdam Dybkowski state1_size = qat_hash_get_state1_size( 25266e21c1a5SAdam Dybkowski cdesc->qat_hash_alg); 25276e21c1a5SAdam Dybkowski break; 25286e21c1a5SAdam Dybkowski } 25296e21c1a5SAdam Dybkowski /* SHA-224 HMAC */ 2530ca0ba0e4SBrian Dooley #ifdef RTE_QAT_OPENSSL 25313227bc71SKai Ji ret = qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA224, authkey, 253291c1daa4STomasz Cel authkeylen, cdesc->cd_cur_ptr, &state1_size, 25333227bc71SKai Ji cdesc->aes_cmac); 2534ca0ba0e4SBrian Dooley #else 2535ca0ba0e4SBrian Dooley ret = qat_sym_do_precomputes_ipsec_mb(ICP_QAT_HW_AUTH_ALGO_SHA224, 2536ca0ba0e4SBrian Dooley authkey, authkeylen, cdesc->cd_cur_ptr, &state1_size, 2537ca0ba0e4SBrian Dooley cdesc->aes_cmac); 2538ca0ba0e4SBrian Dooley #endif 25393227bc71SKai Ji if (ret) { 2540be24b0d9SFiona Trahe QAT_LOG(ERR, "(SHA)precompute failed"); 254198f06089SFiona Trahe return -EFAULT; 254298f06089SFiona Trahe } 254398f06089SFiona Trahe state2_size = ICP_QAT_HW_SHA224_STATE2_SZ; 254498f06089SFiona Trahe break; 254598f06089SFiona Trahe case ICP_QAT_HW_AUTH_ALGO_SHA256: 25466e21c1a5SAdam Dybkowski if (cdesc->auth_mode == ICP_QAT_HW_AUTH_MODE0) { 25476e21c1a5SAdam Dybkowski /* Plain SHA-256 */ 25486e21c1a5SAdam Dybkowski rte_memcpy(cdesc->cd_cur_ptr, sha256InitialState, 25496e21c1a5SAdam Dybkowski sizeof(sha256InitialState)); 25506e21c1a5SAdam Dybkowski state1_size = qat_hash_get_state1_size( 25516e21c1a5SAdam Dybkowski cdesc->qat_hash_alg); 25526e21c1a5SAdam Dybkowski break; 25536e21c1a5SAdam Dybkowski } 25546e21c1a5SAdam Dybkowski /* SHA-256 HMAC */ 2555ca0ba0e4SBrian Dooley #ifdef RTE_QAT_OPENSSL 25563227bc71SKai Ji ret = qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA256, authkey, 255791c1daa4STomasz Cel authkeylen, cdesc->cd_cur_ptr, &state1_size, 25583227bc71SKai Ji cdesc->aes_cmac); 2559ca0ba0e4SBrian Dooley #else 2560ca0ba0e4SBrian Dooley ret = qat_sym_do_precomputes_ipsec_mb(ICP_QAT_HW_AUTH_ALGO_SHA256, 2561ca0ba0e4SBrian Dooley authkey, authkeylen, cdesc->cd_cur_ptr, &state1_size, 2562ca0ba0e4SBrian Dooley cdesc->aes_cmac); 2563ca0ba0e4SBrian Dooley #endif 25643227bc71SKai Ji if (ret) { 2565be24b0d9SFiona Trahe QAT_LOG(ERR, "(SHA)precompute failed"); 256698f06089SFiona Trahe return -EFAULT; 256798f06089SFiona Trahe } 256898f06089SFiona Trahe state2_size = ICP_QAT_HW_SHA256_STATE2_SZ; 256998f06089SFiona Trahe break; 257098f06089SFiona Trahe case ICP_QAT_HW_AUTH_ALGO_SHA384: 25716e21c1a5SAdam Dybkowski if (cdesc->auth_mode == ICP_QAT_HW_AUTH_MODE0) { 25726e21c1a5SAdam Dybkowski /* Plain SHA-384 */ 25736e21c1a5SAdam Dybkowski rte_memcpy(cdesc->cd_cur_ptr, sha384InitialState, 25746e21c1a5SAdam Dybkowski sizeof(sha384InitialState)); 25756e21c1a5SAdam Dybkowski state1_size = qat_hash_get_state1_size( 25766e21c1a5SAdam Dybkowski cdesc->qat_hash_alg); 25776e21c1a5SAdam Dybkowski break; 25786e21c1a5SAdam Dybkowski } 25796e21c1a5SAdam Dybkowski /* SHA-384 HMAC */ 2580ca0ba0e4SBrian Dooley #ifdef RTE_QAT_OPENSSL 25813227bc71SKai Ji ret = qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA384, authkey, 258291c1daa4STomasz Cel authkeylen, cdesc->cd_cur_ptr, &state1_size, 25833227bc71SKai Ji cdesc->aes_cmac); 2584ca0ba0e4SBrian Dooley #else 2585ca0ba0e4SBrian Dooley ret = qat_sym_do_precomputes_ipsec_mb(ICP_QAT_HW_AUTH_ALGO_SHA384, 2586ca0ba0e4SBrian Dooley authkey, authkeylen, cdesc->cd_cur_ptr, &state1_size, 2587ca0ba0e4SBrian Dooley cdesc->aes_cmac); 2588ca0ba0e4SBrian Dooley #endif 25893227bc71SKai Ji if (ret) { 2590be24b0d9SFiona Trahe QAT_LOG(ERR, "(SHA)precompute failed"); 259198f06089SFiona Trahe return -EFAULT; 259298f06089SFiona Trahe } 259398f06089SFiona Trahe state2_size = ICP_QAT_HW_SHA384_STATE2_SZ; 259498f06089SFiona Trahe break; 259598f06089SFiona Trahe case ICP_QAT_HW_AUTH_ALGO_SHA512: 25966e21c1a5SAdam Dybkowski if (cdesc->auth_mode == ICP_QAT_HW_AUTH_MODE0) { 25976e21c1a5SAdam Dybkowski /* Plain SHA-512 */ 25986e21c1a5SAdam Dybkowski rte_memcpy(cdesc->cd_cur_ptr, sha512InitialState, 25996e21c1a5SAdam Dybkowski sizeof(sha512InitialState)); 26006e21c1a5SAdam Dybkowski state1_size = qat_hash_get_state1_size( 26016e21c1a5SAdam Dybkowski cdesc->qat_hash_alg); 26026e21c1a5SAdam Dybkowski break; 26036e21c1a5SAdam Dybkowski } 26046e21c1a5SAdam Dybkowski /* SHA-512 HMAC */ 2605ca0ba0e4SBrian Dooley #ifdef RTE_QAT_OPENSSL 26063227bc71SKai Ji ret = qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA512, authkey, 260791c1daa4STomasz Cel authkeylen, cdesc->cd_cur_ptr, &state1_size, 26083227bc71SKai Ji cdesc->aes_cmac); 2609ca0ba0e4SBrian Dooley #else 2610ca0ba0e4SBrian Dooley ret = qat_sym_do_precomputes_ipsec_mb(ICP_QAT_HW_AUTH_ALGO_SHA512, 2611ca0ba0e4SBrian Dooley authkey, authkeylen, cdesc->cd_cur_ptr, &state1_size, 2612ca0ba0e4SBrian Dooley cdesc->aes_cmac); 2613ca0ba0e4SBrian Dooley #endif 26143227bc71SKai Ji if (ret) { 2615be24b0d9SFiona Trahe QAT_LOG(ERR, "(SHA)precompute failed"); 261698f06089SFiona Trahe return -EFAULT; 261798f06089SFiona Trahe } 261898f06089SFiona Trahe state2_size = ICP_QAT_HW_SHA512_STATE2_SZ; 261998f06089SFiona Trahe break; 26203a80d7fbSCiara Power case ICP_QAT_HW_AUTH_ALGO_SHA3_224: 26213a80d7fbSCiara Power /* Plain SHA3-224 */ 26223a80d7fbSCiara Power memset(cdesc->cd_cur_ptr, 0, state1_size); 26233a80d7fbSCiara Power state1_size = qat_hash_get_state1_size( 26243a80d7fbSCiara Power cdesc->qat_hash_alg); 26253a80d7fbSCiara Power break; 26263a80d7fbSCiara Power case ICP_QAT_HW_AUTH_ALGO_SHA3_256: 26273a80d7fbSCiara Power /* Plain SHA3-256 */ 26283a80d7fbSCiara Power memset(cdesc->cd_cur_ptr, 0, state1_size); 26293a80d7fbSCiara Power state1_size = qat_hash_get_state1_size( 26303a80d7fbSCiara Power cdesc->qat_hash_alg); 26313a80d7fbSCiara Power break; 26323a80d7fbSCiara Power case ICP_QAT_HW_AUTH_ALGO_SHA3_384: 26333a80d7fbSCiara Power /* Plain SHA3-384 */ 26343a80d7fbSCiara Power memset(cdesc->cd_cur_ptr, 0, state1_size); 26353a80d7fbSCiara Power state1_size = qat_hash_get_state1_size( 26363a80d7fbSCiara Power cdesc->qat_hash_alg); 26373a80d7fbSCiara Power break; 26383a80d7fbSCiara Power case ICP_QAT_HW_AUTH_ALGO_SHA3_512: 26393a80d7fbSCiara Power /* Plain SHA3-512 */ 26403a80d7fbSCiara Power memset(cdesc->cd_cur_ptr, 0, state1_size); 26413a80d7fbSCiara Power state1_size = qat_hash_get_state1_size( 26423a80d7fbSCiara Power cdesc->qat_hash_alg); 26433a80d7fbSCiara Power break; 264498f06089SFiona Trahe case ICP_QAT_HW_AUTH_ALGO_AES_XCBC_MAC: 264598f06089SFiona Trahe state1_size = ICP_QAT_HW_AES_XCBC_MAC_STATE1_SZ; 264691c1daa4STomasz Cel 264791c1daa4STomasz Cel if (cdesc->aes_cmac) 264891c1daa4STomasz Cel memset(cdesc->cd_cur_ptr, 0, state1_size); 2649ca0ba0e4SBrian Dooley #ifdef RTE_QAT_OPENSSL 2650ca0ba0e4SBrian Dooley ret = qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_AES_XCBC_MAC, 2651ca0ba0e4SBrian Dooley authkey, authkeylen, cdesc->cd_cur_ptr + state1_size, 2652ca0ba0e4SBrian Dooley &state2_size, cdesc->aes_cmac); 2653ca0ba0e4SBrian Dooley #else 26543227bc71SKai Ji ret = qat_sym_do_precomputes_ipsec_mb( 26553227bc71SKai Ji ICP_QAT_HW_AUTH_ALGO_AES_XCBC_MAC, 265698f06089SFiona Trahe authkey, authkeylen, cdesc->cd_cur_ptr + state1_size, 26573227bc71SKai Ji &state2_size, cdesc->aes_cmac); 26583227bc71SKai Ji #endif 26593227bc71SKai Ji if (ret) { 2660*f665790aSDavid Marchand QAT_LOG(ERR, "(%s)precompute failed", 2661*f665790aSDavid Marchand cdesc->aes_cmac ? "CMAC" : "XCBC"); 266298f06089SFiona Trahe return -EFAULT; 266398f06089SFiona Trahe } 266498f06089SFiona Trahe break; 2665210bea96SCiara Power case ICP_QAT_HW_AUTH_ALGO_AES_128_CMAC: 2666210bea96SCiara Power state1_size = ICP_QAT_HW_AES_CMAC_STATE1_SZ; 2667210bea96SCiara Power memset(cdesc->cd_cur_ptr, 0, state1_size); 2668210bea96SCiara Power memcpy(cdesc->cd_cur_ptr + state1_size, authkey, authkeylen); 2669210bea96SCiara Power state2_size = ICP_QAT_HW_AES_128_CMAC_STATE2_SZ; 2670210bea96SCiara Power break; 267198f06089SFiona Trahe case ICP_QAT_HW_AUTH_ALGO_GALOIS_128: 267298f06089SFiona Trahe case ICP_QAT_HW_AUTH_ALGO_GALOIS_64: 26736618d3b5SArek Kusztal cdesc->qat_proto_flag = QAT_CRYPTO_PROTO_FLAG_GCM; 267498f06089SFiona Trahe state1_size = ICP_QAT_HW_GALOIS_128_STATE1_SZ; 2675ca0ba0e4SBrian Dooley #ifdef RTE_QAT_OPENSSL 26763227bc71SKai Ji ret = qat_sym_do_precomputes(cdesc->qat_hash_alg, authkey, 26773227bc71SKai Ji authkeylen, cdesc->cd_cur_ptr + state1_size, 26783227bc71SKai Ji &state2_size, cdesc->aes_cmac); 2679ca0ba0e4SBrian Dooley #else 2680ca0ba0e4SBrian Dooley ret = qat_sym_do_precomputes_ipsec_mb(cdesc->qat_hash_alg, authkey, 2681ca0ba0e4SBrian Dooley authkeylen, cdesc->cd_cur_ptr + state1_size, 2682ca0ba0e4SBrian Dooley &state2_size, cdesc->aes_cmac); 2683ca0ba0e4SBrian Dooley #endif 26843227bc71SKai Ji if (ret) { 2685be24b0d9SFiona Trahe QAT_LOG(ERR, "(GCM)precompute failed"); 268698f06089SFiona Trahe return -EFAULT; 268798f06089SFiona Trahe } 268898f06089SFiona Trahe /* 268998f06089SFiona Trahe * Write (the length of AAD) into bytes 16-19 of state2 269098f06089SFiona Trahe * in big-endian format. This field is 8 bytes 269198f06089SFiona Trahe */ 269298f06089SFiona Trahe auth_param->u2.aad_sz = 269398f06089SFiona Trahe RTE_ALIGN_CEIL(aad_length, 16); 269498f06089SFiona Trahe auth_param->hash_state_sz = (auth_param->u2.aad_sz) >> 3; 269598f06089SFiona Trahe 269698f06089SFiona Trahe aad_len = (uint32_t *)(cdesc->cd_cur_ptr + 269798f06089SFiona Trahe ICP_QAT_HW_GALOIS_128_STATE1_SZ + 269898f06089SFiona Trahe ICP_QAT_HW_GALOIS_H_SZ); 269998f06089SFiona Trahe *aad_len = rte_bswap32(aad_length); 270098f06089SFiona Trahe cdesc->aad_len = aad_length; 270198f06089SFiona Trahe break; 270298f06089SFiona Trahe case ICP_QAT_HW_AUTH_ALGO_SNOW_3G_UIA2: 27036c868d6eSCiara Power if (!cdesc->is_wireless) 27046618d3b5SArek Kusztal cdesc->qat_proto_flag = QAT_CRYPTO_PROTO_FLAG_SNOW3G; 270598f06089SFiona Trahe state1_size = qat_hash_get_state1_size( 270698f06089SFiona Trahe ICP_QAT_HW_AUTH_ALGO_SNOW_3G_UIA2); 270798f06089SFiona Trahe state2_size = ICP_QAT_HW_SNOW_3G_UIA2_STATE2_SZ; 270898f06089SFiona Trahe memset(cdesc->cd_cur_ptr, 0, state1_size + state2_size); 270998f06089SFiona Trahe 271098f06089SFiona Trahe cipherconfig = (struct icp_qat_hw_cipher_algo_blk *) 271198f06089SFiona Trahe (cdesc->cd_cur_ptr + state1_size + state2_size); 271298f06089SFiona Trahe cipherconfig->cipher_config.val = 271398f06089SFiona Trahe ICP_QAT_HW_CIPHER_CONFIG_BUILD(ICP_QAT_HW_CIPHER_ECB_MODE, 271498f06089SFiona Trahe ICP_QAT_HW_CIPHER_ALGO_SNOW_3G_UEA2, 271598f06089SFiona Trahe ICP_QAT_HW_CIPHER_KEY_CONVERT, 271698f06089SFiona Trahe ICP_QAT_HW_CIPHER_ENCRYPT); 271798f06089SFiona Trahe memcpy(cipherconfig->key, authkey, authkeylen); 271898f06089SFiona Trahe memset(cipherconfig->key + authkeylen, 271998f06089SFiona Trahe 0, ICP_QAT_HW_SNOW_3G_UEA2_IV_SZ); 2720fae347cbSArek Kusztal cd_extra_size += sizeof(struct icp_qat_hw_cipher_config) + 272198f06089SFiona Trahe authkeylen + ICP_QAT_HW_SNOW_3G_UEA2_IV_SZ; 272298f06089SFiona Trahe auth_param->hash_state_sz = ICP_QAT_HW_SNOW_3G_UEA2_IV_SZ >> 3; 272398f06089SFiona Trahe break; 272498f06089SFiona Trahe case ICP_QAT_HW_AUTH_ALGO_ZUC_3G_128_EIA3: 27256c868d6eSCiara Power if (!cdesc->is_wireless) { 272698f06089SFiona Trahe hash->auth_config.config = 272798f06089SFiona Trahe ICP_QAT_HW_AUTH_CONFIG_BUILD(ICP_QAT_HW_AUTH_MODE0, 272898f06089SFiona Trahe cdesc->qat_hash_alg, digestsize); 27296618d3b5SArek Kusztal cdesc->qat_proto_flag = QAT_CRYPTO_PROTO_FLAG_ZUC; 27306c868d6eSCiara Power } 273198f06089SFiona Trahe state1_size = qat_hash_get_state1_size( 273298f06089SFiona Trahe ICP_QAT_HW_AUTH_ALGO_ZUC_3G_128_EIA3); 273398f06089SFiona Trahe state2_size = ICP_QAT_HW_ZUC_3G_EIA3_STATE2_SZ; 273498f06089SFiona Trahe memset(cdesc->cd_cur_ptr, 0, state1_size + state2_size 273598f06089SFiona Trahe + ICP_QAT_HW_ZUC_3G_EEA3_IV_SZ); 273698f06089SFiona Trahe 273798f06089SFiona Trahe memcpy(cdesc->cd_cur_ptr + state1_size, authkey, authkeylen); 2738fae347cbSArek Kusztal cd_extra_size += ICP_QAT_HW_ZUC_3G_EEA3_IV_SZ; 273998f06089SFiona Trahe auth_param->hash_state_sz = ICP_QAT_HW_ZUC_3G_EEA3_IV_SZ >> 3; 274098f06089SFiona Trahe 274198f06089SFiona Trahe break; 27426c868d6eSCiara Power case ICP_QAT_HW_AUTH_ALGO_ZUC_256_MAC_32: 27436c868d6eSCiara Power case ICP_QAT_HW_AUTH_ALGO_ZUC_256_MAC_64: 27446c868d6eSCiara Power case ICP_QAT_HW_AUTH_ALGO_ZUC_256_MAC_128: 27456c868d6eSCiara Power state1_size = qat_hash_get_state1_size(cdesc->qat_hash_alg); 27466c868d6eSCiara Power state2_size = ICP_QAT_HW_ZUC_256_STATE2_SZ; 27476c868d6eSCiara Power memset(cdesc->cd_cur_ptr, 0, state1_size + state2_size 27486c868d6eSCiara Power + ICP_QAT_HW_ZUC_256_IV_SZ); 27496c868d6eSCiara Power 27506c868d6eSCiara Power memcpy(cdesc->cd_cur_ptr + state1_size, authkey, authkeylen); 27516c868d6eSCiara Power cd_extra_size += ICP_QAT_HW_ZUC_256_IV_SZ; 27526c868d6eSCiara Power auth_param->hash_state_sz = ICP_QAT_HW_ZUC_256_IV_SZ >> 3; 27536c868d6eSCiara Power break; 275498f06089SFiona Trahe case ICP_QAT_HW_AUTH_ALGO_MD5: 2755ca0ba0e4SBrian Dooley #ifdef RTE_QAT_OPENSSL 27563227bc71SKai Ji ret = qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_MD5, authkey, 275791c1daa4STomasz Cel authkeylen, cdesc->cd_cur_ptr, &state1_size, 27583227bc71SKai Ji cdesc->aes_cmac); 2759ca0ba0e4SBrian Dooley #else 2760ca0ba0e4SBrian Dooley ret = qat_sym_do_precomputes_ipsec_mb(ICP_QAT_HW_AUTH_ALGO_MD5, 2761ca0ba0e4SBrian Dooley authkey, authkeylen, cdesc->cd_cur_ptr, &state1_size, 2762ca0ba0e4SBrian Dooley cdesc->aes_cmac); 2763ca0ba0e4SBrian Dooley #endif 27643227bc71SKai Ji if (ret) { 2765be24b0d9SFiona Trahe QAT_LOG(ERR, "(MD5)precompute failed"); 276698f06089SFiona Trahe return -EFAULT; 276798f06089SFiona Trahe } 276898f06089SFiona Trahe state2_size = ICP_QAT_HW_MD5_STATE2_SZ; 276998f06089SFiona Trahe break; 277098f06089SFiona Trahe case ICP_QAT_HW_AUTH_ALGO_NULL: 277198f06089SFiona Trahe state1_size = qat_hash_get_state1_size( 277298f06089SFiona Trahe ICP_QAT_HW_AUTH_ALGO_NULL); 277398f06089SFiona Trahe state2_size = ICP_QAT_HW_NULL_STATE2_SZ; 277498f06089SFiona Trahe break; 277598f06089SFiona Trahe case ICP_QAT_HW_AUTH_ALGO_AES_CBC_MAC: 27766618d3b5SArek Kusztal cdesc->qat_proto_flag = QAT_CRYPTO_PROTO_FLAG_CCM; 277798f06089SFiona Trahe state1_size = qat_hash_get_state1_size( 277898f06089SFiona Trahe ICP_QAT_HW_AUTH_ALGO_AES_CBC_MAC); 277998f06089SFiona Trahe state2_size = ICP_QAT_HW_AES_CBC_MAC_KEY_SZ + 278098f06089SFiona Trahe ICP_QAT_HW_AES_CCM_CBC_E_CTR0_SZ; 278198f06089SFiona Trahe 278298f06089SFiona Trahe if (aad_length > 0) { 278398f06089SFiona Trahe aad_length += ICP_QAT_HW_CCM_AAD_B0_LEN + 278498f06089SFiona Trahe ICP_QAT_HW_CCM_AAD_LEN_INFO; 278598f06089SFiona Trahe auth_param->u2.aad_sz = 278698f06089SFiona Trahe RTE_ALIGN_CEIL(aad_length, 278798f06089SFiona Trahe ICP_QAT_HW_CCM_AAD_ALIGNMENT); 278898f06089SFiona Trahe } else { 278998f06089SFiona Trahe auth_param->u2.aad_sz = ICP_QAT_HW_CCM_AAD_B0_LEN; 279098f06089SFiona Trahe } 279198f06089SFiona Trahe cdesc->aad_len = aad_length; 279298f06089SFiona Trahe hash->auth_counter.counter = 0; 279398f06089SFiona Trahe 279498f06089SFiona Trahe hash_cd_ctrl->outer_prefix_sz = digestsize; 279598f06089SFiona Trahe auth_param->hash_state_sz = digestsize; 279698f06089SFiona Trahe 279798f06089SFiona Trahe memcpy(cdesc->cd_cur_ptr + state1_size, authkey, authkeylen); 279898f06089SFiona Trahe break; 279998f06089SFiona Trahe case ICP_QAT_HW_AUTH_ALGO_KASUMI_F9: 280098f06089SFiona Trahe state1_size = qat_hash_get_state1_size( 280198f06089SFiona Trahe ICP_QAT_HW_AUTH_ALGO_KASUMI_F9); 280298f06089SFiona Trahe state2_size = ICP_QAT_HW_KASUMI_F9_STATE2_SZ; 280398f06089SFiona Trahe memset(cdesc->cd_cur_ptr, 0, state1_size + state2_size); 280498f06089SFiona Trahe pTempKey = (uint32_t *)(cdesc->cd_cur_ptr + state1_size 280598f06089SFiona Trahe + authkeylen); 280698f06089SFiona Trahe /* 280798f06089SFiona Trahe * The Inner Hash Initial State2 block must contain IK 280898f06089SFiona Trahe * (Initialisation Key), followed by IK XOR-ed with KM 280998f06089SFiona Trahe * (Key Modifier): IK||(IK^KM). 281098f06089SFiona Trahe */ 281198f06089SFiona Trahe /* write the auth key */ 281298f06089SFiona Trahe memcpy(cdesc->cd_cur_ptr + state1_size, authkey, authkeylen); 281398f06089SFiona Trahe /* initialise temp key with auth key */ 281498f06089SFiona Trahe memcpy(pTempKey, authkey, authkeylen); 281598f06089SFiona Trahe /* XOR Key with KASUMI F9 key modifier at 4 bytes level */ 281698f06089SFiona Trahe for (wordIndex = 0; wordIndex < (authkeylen >> 2); wordIndex++) 281798f06089SFiona Trahe pTempKey[wordIndex] ^= KASUMI_F9_KEY_MODIFIER_4_BYTES; 281898f06089SFiona Trahe break; 281998f06089SFiona Trahe default: 2820be24b0d9SFiona Trahe QAT_LOG(ERR, "Invalid HASH alg %u", cdesc->qat_hash_alg); 282198f06089SFiona Trahe return -EFAULT; 282298f06089SFiona Trahe } 282398f06089SFiona Trahe 282498f06089SFiona Trahe /* Auth CD config setup */ 2825171c655bSArkadiusz Kusztal hash_cd_ctrl->hash_flags |= ICP_QAT_FW_AUTH_HDR_FLAG_NO_NESTED; 28267283c59eSBrian Dooley hash_cd_ctrl->inner_state1_sz = state1_size; 28277283c59eSBrian Dooley if (cdesc->qat_hash_alg == ICP_QAT_HW_AUTH_ALGO_NULL) { 28287283c59eSBrian Dooley hash_cd_ctrl->inner_res_sz = 4; 28297283c59eSBrian Dooley hash_cd_ctrl->final_sz = 4; 28307283c59eSBrian Dooley auth_param->auth_res_sz = 4; 28317283c59eSBrian Dooley } else { 283298f06089SFiona Trahe hash_cd_ctrl->inner_res_sz = digestsize; 283398f06089SFiona Trahe hash_cd_ctrl->final_sz = digestsize; 283498f06089SFiona Trahe auth_param->auth_res_sz = digestsize; 28357283c59eSBrian Dooley } 283698f06089SFiona Trahe 283798f06089SFiona Trahe hash_cd_ctrl->inner_state2_sz = state2_size; 283898f06089SFiona Trahe hash_cd_ctrl->inner_state2_offset = hash_cd_ctrl->hash_cfg_offset + 283998f06089SFiona Trahe ((sizeof(struct icp_qat_hw_auth_setup) + 284098f06089SFiona Trahe RTE_ALIGN_CEIL(hash_cd_ctrl->inner_state1_sz, 8)) 284198f06089SFiona Trahe >> 3); 2842fae347cbSArek Kusztal cdesc->cd_cur_ptr += state1_size + state2_size + cd_extra_size; 284398f06089SFiona Trahe cd_size = cdesc->cd_cur_ptr-(uint8_t *)&cdesc->cd; 284498f06089SFiona Trahe cd_pars->u.s.content_desc_addr = cdesc->cd_paddr; 284598f06089SFiona Trahe cd_pars->u.s.content_desc_params_sz = RTE_ALIGN_CEIL(cd_size, 8) >> 3; 284698f06089SFiona Trahe return 0; 284798f06089SFiona Trahe } 284898f06089SFiona Trahe 2849bba31cffSFiona Trahe int qat_sym_validate_aes_key(int key_len, enum icp_qat_hw_cipher_algo *alg) 285098f06089SFiona Trahe { 285198f06089SFiona Trahe switch (key_len) { 285298f06089SFiona Trahe case ICP_QAT_HW_AES_128_KEY_SZ: 285398f06089SFiona Trahe *alg = ICP_QAT_HW_CIPHER_ALGO_AES128; 285498f06089SFiona Trahe break; 285598f06089SFiona Trahe case ICP_QAT_HW_AES_192_KEY_SZ: 285698f06089SFiona Trahe *alg = ICP_QAT_HW_CIPHER_ALGO_AES192; 285798f06089SFiona Trahe break; 285898f06089SFiona Trahe case ICP_QAT_HW_AES_256_KEY_SZ: 285998f06089SFiona Trahe *alg = ICP_QAT_HW_CIPHER_ALGO_AES256; 286098f06089SFiona Trahe break; 286198f06089SFiona Trahe default: 286298f06089SFiona Trahe return -EINVAL; 286398f06089SFiona Trahe } 286498f06089SFiona Trahe return 0; 286598f06089SFiona Trahe } 286698f06089SFiona Trahe 2867bba31cffSFiona Trahe int qat_sym_validate_aes_docsisbpi_key(int key_len, 286898f06089SFiona Trahe enum icp_qat_hw_cipher_algo *alg) 286998f06089SFiona Trahe { 287098f06089SFiona Trahe switch (key_len) { 287198f06089SFiona Trahe case ICP_QAT_HW_AES_128_KEY_SZ: 287298f06089SFiona Trahe *alg = ICP_QAT_HW_CIPHER_ALGO_AES128; 287398f06089SFiona Trahe break; 28742aab3ff3SMairtin o Loingsigh case ICP_QAT_HW_AES_256_KEY_SZ: 28752aab3ff3SMairtin o Loingsigh *alg = ICP_QAT_HW_CIPHER_ALGO_AES256; 28762aab3ff3SMairtin o Loingsigh break; 287798f06089SFiona Trahe default: 287898f06089SFiona Trahe return -EINVAL; 287998f06089SFiona Trahe } 288098f06089SFiona Trahe return 0; 288198f06089SFiona Trahe } 288298f06089SFiona Trahe 2883bba31cffSFiona Trahe int qat_sym_validate_snow3g_key(int key_len, enum icp_qat_hw_cipher_algo *alg) 288498f06089SFiona Trahe { 288598f06089SFiona Trahe switch (key_len) { 288698f06089SFiona Trahe case ICP_QAT_HW_SNOW_3G_UEA2_KEY_SZ: 288798f06089SFiona Trahe *alg = ICP_QAT_HW_CIPHER_ALGO_SNOW_3G_UEA2; 288898f06089SFiona Trahe break; 288998f06089SFiona Trahe default: 289098f06089SFiona Trahe return -EINVAL; 289198f06089SFiona Trahe } 289298f06089SFiona Trahe return 0; 289398f06089SFiona Trahe } 289498f06089SFiona Trahe 2895bba31cffSFiona Trahe int qat_sym_validate_kasumi_key(int key_len, enum icp_qat_hw_cipher_algo *alg) 289698f06089SFiona Trahe { 289798f06089SFiona Trahe switch (key_len) { 289898f06089SFiona Trahe case ICP_QAT_HW_KASUMI_KEY_SZ: 289998f06089SFiona Trahe *alg = ICP_QAT_HW_CIPHER_ALGO_KASUMI; 290098f06089SFiona Trahe break; 290198f06089SFiona Trahe default: 290298f06089SFiona Trahe return -EINVAL; 290398f06089SFiona Trahe } 290498f06089SFiona Trahe return 0; 290598f06089SFiona Trahe } 290698f06089SFiona Trahe 2907bba31cffSFiona Trahe int qat_sym_validate_des_key(int key_len, enum icp_qat_hw_cipher_algo *alg) 290898f06089SFiona Trahe { 290998f06089SFiona Trahe switch (key_len) { 291098f06089SFiona Trahe case ICP_QAT_HW_DES_KEY_SZ: 291198f06089SFiona Trahe *alg = ICP_QAT_HW_CIPHER_ALGO_DES; 291298f06089SFiona Trahe break; 291398f06089SFiona Trahe default: 291498f06089SFiona Trahe return -EINVAL; 291598f06089SFiona Trahe } 291698f06089SFiona Trahe return 0; 291798f06089SFiona Trahe } 291898f06089SFiona Trahe 2919bba31cffSFiona Trahe int qat_sym_validate_3des_key(int key_len, enum icp_qat_hw_cipher_algo *alg) 292098f06089SFiona Trahe { 292198f06089SFiona Trahe switch (key_len) { 292298f06089SFiona Trahe case QAT_3DES_KEY_SZ_OPT1: 292398f06089SFiona Trahe case QAT_3DES_KEY_SZ_OPT2: 2924e3d99884SFiona Trahe case QAT_3DES_KEY_SZ_OPT3: 292598f06089SFiona Trahe *alg = ICP_QAT_HW_CIPHER_ALGO_3DES; 292698f06089SFiona Trahe break; 292798f06089SFiona Trahe default: 292898f06089SFiona Trahe return -EINVAL; 292998f06089SFiona Trahe } 293098f06089SFiona Trahe return 0; 293198f06089SFiona Trahe } 293298f06089SFiona Trahe 2933bba31cffSFiona Trahe int qat_sym_validate_zuc_key(int key_len, enum icp_qat_hw_cipher_algo *alg) 293498f06089SFiona Trahe { 293598f06089SFiona Trahe switch (key_len) { 293698f06089SFiona Trahe case ICP_QAT_HW_ZUC_3G_EEA3_KEY_SZ: 293798f06089SFiona Trahe *alg = ICP_QAT_HW_CIPHER_ALGO_ZUC_3G_128_EEA3; 293898f06089SFiona Trahe break; 29396c868d6eSCiara Power case ICP_QAT_HW_ZUC_256_KEY_SZ: 29406c868d6eSCiara Power *alg = ICP_QAT_HW_CIPHER_ALGO_ZUC_256; 29416c868d6eSCiara Power break; 294298f06089SFiona Trahe default: 294398f06089SFiona Trahe return -EINVAL; 294498f06089SFiona Trahe } 294598f06089SFiona Trahe return 0; 294698f06089SFiona Trahe } 29476f0ef237SDavid Coyle 29486f0ef237SDavid Coyle static int 29496f0ef237SDavid Coyle qat_sec_session_check_docsis(struct rte_security_session_conf *conf) 29506f0ef237SDavid Coyle { 29516f0ef237SDavid Coyle struct rte_crypto_sym_xform *crypto_sym = conf->crypto_xform; 29526f0ef237SDavid Coyle struct rte_security_docsis_xform *docsis = &conf->docsis; 29536f0ef237SDavid Coyle 29546f0ef237SDavid Coyle /* CRC generate -> Cipher encrypt */ 29556f0ef237SDavid Coyle if (docsis->direction == RTE_SECURITY_DOCSIS_DOWNLINK) { 29566f0ef237SDavid Coyle 29576f0ef237SDavid Coyle if (crypto_sym != NULL && 29586f0ef237SDavid Coyle crypto_sym->type == RTE_CRYPTO_SYM_XFORM_CIPHER && 29596f0ef237SDavid Coyle crypto_sym->cipher.op == RTE_CRYPTO_CIPHER_OP_ENCRYPT && 29606f0ef237SDavid Coyle crypto_sym->cipher.algo == 29616f0ef237SDavid Coyle RTE_CRYPTO_CIPHER_AES_DOCSISBPI && 29626f0ef237SDavid Coyle (crypto_sym->cipher.key.length == 29636f0ef237SDavid Coyle ICP_QAT_HW_AES_128_KEY_SZ || 29646f0ef237SDavid Coyle crypto_sym->cipher.key.length == 29656f0ef237SDavid Coyle ICP_QAT_HW_AES_256_KEY_SZ) && 29666f0ef237SDavid Coyle crypto_sym->cipher.iv.length == ICP_QAT_HW_AES_BLK_SZ && 29676f0ef237SDavid Coyle crypto_sym->next == NULL) { 29686f0ef237SDavid Coyle return 0; 29696f0ef237SDavid Coyle } 29706f0ef237SDavid Coyle /* Cipher decrypt -> CRC verify */ 29716f0ef237SDavid Coyle } else if (docsis->direction == RTE_SECURITY_DOCSIS_UPLINK) { 29726f0ef237SDavid Coyle 29736f0ef237SDavid Coyle if (crypto_sym != NULL && 29746f0ef237SDavid Coyle crypto_sym->type == RTE_CRYPTO_SYM_XFORM_CIPHER && 29756f0ef237SDavid Coyle crypto_sym->cipher.op == RTE_CRYPTO_CIPHER_OP_DECRYPT && 29766f0ef237SDavid Coyle crypto_sym->cipher.algo == 29776f0ef237SDavid Coyle RTE_CRYPTO_CIPHER_AES_DOCSISBPI && 29786f0ef237SDavid Coyle (crypto_sym->cipher.key.length == 29796f0ef237SDavid Coyle ICP_QAT_HW_AES_128_KEY_SZ || 29806f0ef237SDavid Coyle crypto_sym->cipher.key.length == 29816f0ef237SDavid Coyle ICP_QAT_HW_AES_256_KEY_SZ) && 29826f0ef237SDavid Coyle crypto_sym->cipher.iv.length == ICP_QAT_HW_AES_BLK_SZ && 29836f0ef237SDavid Coyle crypto_sym->next == NULL) { 29846f0ef237SDavid Coyle return 0; 29856f0ef237SDavid Coyle } 29866f0ef237SDavid Coyle } 29876f0ef237SDavid Coyle 29886f0ef237SDavid Coyle return -EINVAL; 29896f0ef237SDavid Coyle } 29906f0ef237SDavid Coyle 29916f0ef237SDavid Coyle static int 2992ce7a737cSKevin O'Sullivan qat_sym_cd_crc_set(struct qat_sym_session *cdesc, 2993ce7a737cSKevin O'Sullivan enum qat_device_gen qat_dev_gen) 2994ce7a737cSKevin O'Sullivan { 2995ce7a737cSKevin O'Sullivan struct icp_qat_hw_gen2_crc_cd *crc_cd_gen2; 2996ce7a737cSKevin O'Sullivan struct icp_qat_hw_gen3_crc_cd *crc_cd_gen3; 2997ce7a737cSKevin O'Sullivan struct icp_qat_hw_gen4_crc_cd *crc_cd_gen4; 2998ce7a737cSKevin O'Sullivan struct icp_qat_fw_la_bulk_req *req_tmpl = &cdesc->fw_req; 2999ce7a737cSKevin O'Sullivan struct icp_qat_fw_comn_req_hdr_cd_pars *cd_pars = &req_tmpl->cd_pars; 3000ce7a737cSKevin O'Sullivan void *ptr = &req_tmpl->cd_ctrl; 3001ce7a737cSKevin O'Sullivan struct icp_qat_fw_auth_cd_ctrl_hdr *crc_cd_ctrl = ptr; 3002ce7a737cSKevin O'Sullivan struct icp_qat_fw_la_auth_req_params *crc_param = 3003ce7a737cSKevin O'Sullivan (struct icp_qat_fw_la_auth_req_params *) 3004ce7a737cSKevin O'Sullivan ((char *)&req_tmpl->serv_specif_rqpars + 3005ce7a737cSKevin O'Sullivan ICP_QAT_FW_HASH_REQUEST_PARAMETERS_OFFSET); 3006ce7a737cSKevin O'Sullivan struct icp_qat_fw_ucs_slice_cipher_config crc_cfg; 3007ce7a737cSKevin O'Sullivan uint16_t crc_cfg_offset, cd_size; 3008ce7a737cSKevin O'Sullivan 3009ce7a737cSKevin O'Sullivan crc_cfg_offset = cdesc->cd_cur_ptr - ((uint8_t *)&cdesc->cd); 3010ce7a737cSKevin O'Sullivan 3011ce7a737cSKevin O'Sullivan switch (qat_dev_gen) { 3012ce7a737cSKevin O'Sullivan case QAT_GEN2: 3013ce7a737cSKevin O'Sullivan crc_cd_gen2 = 3014ce7a737cSKevin O'Sullivan (struct icp_qat_hw_gen2_crc_cd *)cdesc->cd_cur_ptr; 3015ce7a737cSKevin O'Sullivan crc_cd_gen2->flags = 0; 3016ce7a737cSKevin O'Sullivan crc_cd_gen2->initial_crc = 0; 3017ce7a737cSKevin O'Sullivan memset(&crc_cd_gen2->reserved1, 3018ce7a737cSKevin O'Sullivan 0, 3019ce7a737cSKevin O'Sullivan sizeof(crc_cd_gen2->reserved1)); 3020ce7a737cSKevin O'Sullivan memset(&crc_cd_gen2->reserved2, 3021ce7a737cSKevin O'Sullivan 0, 3022ce7a737cSKevin O'Sullivan sizeof(crc_cd_gen2->reserved2)); 3023ce7a737cSKevin O'Sullivan cdesc->cd_cur_ptr += sizeof(struct icp_qat_hw_gen2_crc_cd); 3024ce7a737cSKevin O'Sullivan break; 3025ce7a737cSKevin O'Sullivan case QAT_GEN3: 3026ce7a737cSKevin O'Sullivan crc_cd_gen3 = 3027ce7a737cSKevin O'Sullivan (struct icp_qat_hw_gen3_crc_cd *)cdesc->cd_cur_ptr; 3028ce7a737cSKevin O'Sullivan crc_cd_gen3->flags = ICP_QAT_HW_GEN3_CRC_FLAGS_BUILD(1, 1); 3029ce7a737cSKevin O'Sullivan crc_cd_gen3->polynomial = ETH_CRC32_POLYNOMIAL; 3030ce7a737cSKevin O'Sullivan crc_cd_gen3->initial_crc = ETH_CRC32_INIT_VAL; 3031ce7a737cSKevin O'Sullivan crc_cd_gen3->xor_val = ETH_CRC32_XOR_OUT; 3032ce7a737cSKevin O'Sullivan memset(&crc_cd_gen3->reserved1, 3033ce7a737cSKevin O'Sullivan 0, 3034ce7a737cSKevin O'Sullivan sizeof(crc_cd_gen3->reserved1)); 3035ce7a737cSKevin O'Sullivan memset(&crc_cd_gen3->reserved2, 3036ce7a737cSKevin O'Sullivan 0, 3037ce7a737cSKevin O'Sullivan sizeof(crc_cd_gen3->reserved2)); 3038ce7a737cSKevin O'Sullivan crc_cd_gen3->reserved3 = 0; 3039ce7a737cSKevin O'Sullivan cdesc->cd_cur_ptr += sizeof(struct icp_qat_hw_gen3_crc_cd); 3040ce7a737cSKevin O'Sullivan break; 3041ce7a737cSKevin O'Sullivan case QAT_GEN4: 304259cda512SCiara Power case QAT_GEN5: 3043ce7a737cSKevin O'Sullivan crc_cfg.mode = ICP_QAT_HW_CIPHER_ECB_MODE; 3044ce7a737cSKevin O'Sullivan crc_cfg.algo = ICP_QAT_HW_CIPHER_ALGO_NULL; 3045ce7a737cSKevin O'Sullivan crc_cfg.hash_cmp_val = 0; 3046ce7a737cSKevin O'Sullivan crc_cfg.dir = ICP_QAT_HW_CIPHER_ENCRYPT; 3047ce7a737cSKevin O'Sullivan crc_cfg.associated_data_len_in_bytes = 0; 3048ce7a737cSKevin O'Sullivan crc_cfg.crc_reflect_out = 3049ce7a737cSKevin O'Sullivan ICP_QAT_HW_CIPHER_UCS_REFLECT_OUT_ENABLED; 3050ce7a737cSKevin O'Sullivan crc_cfg.crc_reflect_in = 3051ce7a737cSKevin O'Sullivan ICP_QAT_HW_CIPHER_UCS_REFLECT_IN_ENABLED; 3052ce7a737cSKevin O'Sullivan crc_cfg.crc_encoding = ICP_QAT_HW_CIPHER_UCS_CRC32; 3053ce7a737cSKevin O'Sullivan 3054ce7a737cSKevin O'Sullivan crc_cd_gen4 = 3055ce7a737cSKevin O'Sullivan (struct icp_qat_hw_gen4_crc_cd *)cdesc->cd_cur_ptr; 3056ce7a737cSKevin O'Sullivan crc_cd_gen4->ucs_config[0] = 3057ce7a737cSKevin O'Sullivan ICP_QAT_HW_UCS_CIPHER_GEN4_BUILD_CONFIG_LOWER(crc_cfg); 3058ce7a737cSKevin O'Sullivan crc_cd_gen4->ucs_config[1] = 3059ce7a737cSKevin O'Sullivan ICP_QAT_HW_UCS_CIPHER_GEN4_BUILD_CONFIG_UPPER(crc_cfg); 3060ce7a737cSKevin O'Sullivan crc_cd_gen4->polynomial = ETH_CRC32_POLYNOMIAL_BE; 3061ce7a737cSKevin O'Sullivan crc_cd_gen4->initial_crc = ETH_CRC32_INIT_VAL_BE; 3062ce7a737cSKevin O'Sullivan crc_cd_gen4->xor_val = ETH_CRC32_XOR_OUT_BE; 3063ce7a737cSKevin O'Sullivan crc_cd_gen4->reserved1 = 0; 3064ce7a737cSKevin O'Sullivan crc_cd_gen4->reserved2 = 0; 3065ce7a737cSKevin O'Sullivan crc_cd_gen4->reserved3 = 0; 3066ce7a737cSKevin O'Sullivan cdesc->cd_cur_ptr += sizeof(struct icp_qat_hw_gen4_crc_cd); 3067ce7a737cSKevin O'Sullivan break; 3068ce7a737cSKevin O'Sullivan default: 3069ce7a737cSKevin O'Sullivan return -EINVAL; 3070ce7a737cSKevin O'Sullivan } 3071ce7a737cSKevin O'Sullivan 3072ce7a737cSKevin O'Sullivan crc_cd_ctrl->hash_cfg_offset = crc_cfg_offset >> 3; 3073ce7a737cSKevin O'Sullivan crc_cd_ctrl->hash_flags = ICP_QAT_FW_AUTH_HDR_FLAG_NO_NESTED; 3074ce7a737cSKevin O'Sullivan crc_cd_ctrl->inner_res_sz = cdesc->digest_length; 3075ce7a737cSKevin O'Sullivan crc_cd_ctrl->final_sz = cdesc->digest_length; 3076ce7a737cSKevin O'Sullivan crc_cd_ctrl->inner_state1_sz = 0; 3077ce7a737cSKevin O'Sullivan crc_cd_ctrl->inner_state2_sz = 0; 3078ce7a737cSKevin O'Sullivan crc_cd_ctrl->inner_state2_offset = 0; 3079ce7a737cSKevin O'Sullivan crc_cd_ctrl->outer_prefix_sz = 0; 3080ce7a737cSKevin O'Sullivan crc_cd_ctrl->outer_config_offset = 0; 3081ce7a737cSKevin O'Sullivan crc_cd_ctrl->outer_state1_sz = 0; 3082ce7a737cSKevin O'Sullivan crc_cd_ctrl->outer_res_sz = 0; 3083ce7a737cSKevin O'Sullivan crc_cd_ctrl->outer_prefix_offset = 0; 3084ce7a737cSKevin O'Sullivan 3085ce7a737cSKevin O'Sullivan crc_param->auth_res_sz = cdesc->digest_length; 3086ce7a737cSKevin O'Sullivan crc_param->u2.aad_sz = 0; 3087ce7a737cSKevin O'Sullivan crc_param->hash_state_sz = 0; 3088ce7a737cSKevin O'Sullivan 3089ce7a737cSKevin O'Sullivan cd_size = cdesc->cd_cur_ptr - (uint8_t *)&cdesc->cd; 3090ce7a737cSKevin O'Sullivan cd_pars->u.s.content_desc_addr = cdesc->cd_paddr; 3091ce7a737cSKevin O'Sullivan cd_pars->u.s.content_desc_params_sz = RTE_ALIGN_CEIL(cd_size, 8) >> 3; 3092ce7a737cSKevin O'Sullivan 3093ce7a737cSKevin O'Sullivan return 0; 3094ce7a737cSKevin O'Sullivan } 3095ce7a737cSKevin O'Sullivan 3096ce7a737cSKevin O'Sullivan static int 3097ce7a737cSKevin O'Sullivan qat_sym_session_configure_crc(struct rte_cryptodev *dev, 3098ce7a737cSKevin O'Sullivan const struct rte_crypto_sym_xform *cipher_xform, 3099ce7a737cSKevin O'Sullivan struct qat_sym_session *session) 3100ce7a737cSKevin O'Sullivan { 3101ce7a737cSKevin O'Sullivan struct qat_cryptodev_private *internals = dev->data->dev_private; 3102ce7a737cSKevin O'Sullivan enum qat_device_gen qat_dev_gen = internals->qat_dev->qat_dev_gen; 3103ce7a737cSKevin O'Sullivan int ret; 3104ce7a737cSKevin O'Sullivan 3105ce7a737cSKevin O'Sullivan session->is_auth = 1; 3106ce7a737cSKevin O'Sullivan session->qat_hash_alg = ICP_QAT_HW_AUTH_ALGO_NULL; 3107ce7a737cSKevin O'Sullivan session->auth_mode = ICP_QAT_HW_AUTH_MODE0; 3108ce7a737cSKevin O'Sullivan session->auth_op = cipher_xform->cipher.op == 3109ce7a737cSKevin O'Sullivan RTE_CRYPTO_CIPHER_OP_ENCRYPT ? 3110ce7a737cSKevin O'Sullivan ICP_QAT_HW_AUTH_GENERATE : 3111ce7a737cSKevin O'Sullivan ICP_QAT_HW_AUTH_VERIFY; 3112ce7a737cSKevin O'Sullivan session->digest_length = RTE_ETHER_CRC_LEN; 3113ce7a737cSKevin O'Sullivan 3114ce7a737cSKevin O'Sullivan ret = qat_sym_cd_crc_set(session, qat_dev_gen); 3115ce7a737cSKevin O'Sullivan if (ret < 0) 3116ce7a737cSKevin O'Sullivan return ret; 3117ce7a737cSKevin O'Sullivan 3118ce7a737cSKevin O'Sullivan return 0; 3119ce7a737cSKevin O'Sullivan } 3120ce7a737cSKevin O'Sullivan 3121ce7a737cSKevin O'Sullivan static int 31226f0ef237SDavid Coyle qat_sec_session_set_docsis_parameters(struct rte_cryptodev *dev, 31233f3fc330SAkhil Goyal struct rte_security_session_conf *conf, void *session_private, 31243f3fc330SAkhil Goyal rte_iova_t session_paddr) 31256f0ef237SDavid Coyle { 31266f0ef237SDavid Coyle int ret; 31276f0ef237SDavid Coyle int qat_cmd_id; 3128f7f2e8a9SBrian Dooley struct rte_cryptodev *cdev = (struct rte_cryptodev *)dev; 31296f0ef237SDavid Coyle struct rte_crypto_sym_xform *xform = NULL; 31306f0ef237SDavid Coyle struct qat_sym_session *session = session_private; 3131f7f2e8a9SBrian Dooley struct qat_cryptodev_private *internals = cdev->data->dev_private; 3132f7f2e8a9SBrian Dooley enum qat_device_gen qat_dev_gen = internals->qat_dev->qat_dev_gen; 31336f0ef237SDavid Coyle 31349acadb24SDavid Coyle /* Clear the session */ 31359acadb24SDavid Coyle memset(session, 0, qat_sym_session_get_private_size(dev)); 31369acadb24SDavid Coyle 31376f0ef237SDavid Coyle ret = qat_sec_session_check_docsis(conf); 31386f0ef237SDavid Coyle if (ret) { 31396f0ef237SDavid Coyle QAT_LOG(ERR, "Unsupported DOCSIS security configuration"); 31406f0ef237SDavid Coyle return ret; 31416f0ef237SDavid Coyle } 31426f0ef237SDavid Coyle 31436f0ef237SDavid Coyle xform = conf->crypto_xform; 31446f0ef237SDavid Coyle 31456f0ef237SDavid Coyle /* Verify the session physical address is known */ 31466f0ef237SDavid Coyle if (session_paddr == 0 || session_paddr == RTE_BAD_IOVA) { 31476f0ef237SDavid Coyle QAT_LOG(ERR, 31486f0ef237SDavid Coyle "Session physical address unknown. Bad memory pool."); 31496f0ef237SDavid Coyle return -EINVAL; 31506f0ef237SDavid Coyle } 31516f0ef237SDavid Coyle 31526f0ef237SDavid Coyle /* Set context descriptor physical address */ 31536f0ef237SDavid Coyle session->cd_paddr = session_paddr + 31546f0ef237SDavid Coyle offsetof(struct qat_sym_session, cd); 3155171c655bSArkadiusz Kusztal session->prefix_paddr = session_paddr + 3156171c655bSArkadiusz Kusztal offsetof(struct qat_sym_session, prefix_state); 31576f0ef237SDavid Coyle 31589acadb24SDavid Coyle /* Get requested QAT command id - should be cipher */ 31596f0ef237SDavid Coyle qat_cmd_id = qat_get_cmd_id(xform); 31609acadb24SDavid Coyle if (qat_cmd_id != ICP_QAT_FW_LA_CMD_CIPHER) { 31616f0ef237SDavid Coyle QAT_LOG(ERR, "Unsupported xform chain requested"); 31626f0ef237SDavid Coyle return -ENOTSUP; 3163ce7a737cSKevin O'Sullivan } else if (internals->internal_capabilities 3164ce7a737cSKevin O'Sullivan & QAT_SYM_CAP_CIPHER_CRC) { 3165ce7a737cSKevin O'Sullivan qat_cmd_id = ICP_QAT_FW_LA_CMD_CIPHER_CRC; 31666f0ef237SDavid Coyle } 31676f0ef237SDavid Coyle session->qat_cmd = (enum icp_qat_fw_la_cmd_id)qat_cmd_id; 31689acadb24SDavid Coyle 31696f0ef237SDavid Coyle ret = qat_sym_session_configure_cipher(dev, xform, session); 31706f0ef237SDavid Coyle if (ret < 0) 31716f0ef237SDavid Coyle return ret; 3172ce7a737cSKevin O'Sullivan 3173ce7a737cSKevin O'Sullivan if (qat_cmd_id == ICP_QAT_FW_LA_CMD_CIPHER_CRC) { 3174ce7a737cSKevin O'Sullivan ret = qat_sym_session_configure_crc(dev, xform, session); 3175ce7a737cSKevin O'Sullivan if (ret < 0) 3176ce7a737cSKevin O'Sullivan return ret; 3177ce7a737cSKevin O'Sullivan } 31786618d3b5SArek Kusztal qat_sym_session_finalize(session); 31796f0ef237SDavid Coyle 31803625d12eSBrian Dooley return qat_sym_gen_dev_ops[qat_dev_gen].set_session((void *)cdev, 31813625d12eSBrian Dooley (void *)session); 31826f0ef237SDavid Coyle } 31836f0ef237SDavid Coyle 31846f0ef237SDavid Coyle int 31856f0ef237SDavid Coyle qat_security_session_create(void *dev, 31866f0ef237SDavid Coyle struct rte_security_session_conf *conf, 31873f3fc330SAkhil Goyal struct rte_security_session *sess) 31886f0ef237SDavid Coyle { 31893f3fc330SAkhil Goyal void *sess_private_data = SECURITY_GET_SESS_PRIV(sess); 31906f0ef237SDavid Coyle struct rte_cryptodev *cdev = (struct rte_cryptodev *)dev; 31916f0ef237SDavid Coyle int ret; 31926f0ef237SDavid Coyle 31939acadb24SDavid Coyle if (conf->action_type != RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL || 31949acadb24SDavid Coyle conf->protocol != RTE_SECURITY_PROTOCOL_DOCSIS) { 31959acadb24SDavid Coyle QAT_LOG(ERR, "Invalid security protocol"); 31969acadb24SDavid Coyle return -EINVAL; 31979acadb24SDavid Coyle } 31989acadb24SDavid Coyle 3199ca0ba0e4SBrian Dooley #ifdef RTE_QAT_OPENSSL 320052d59b92SKai Ji #if (OPENSSL_VERSION_NUMBER >= 0x30000000L) 320152d59b92SKai Ji if (ossl_legacy_provider_load()) 320252d59b92SKai Ji return -EINVAL; 320352d59b92SKai Ji #endif 3204ca0ba0e4SBrian Dooley #endif 32056f0ef237SDavid Coyle ret = qat_sec_session_set_docsis_parameters(cdev, conf, 32063f3fc330SAkhil Goyal sess_private_data, SECURITY_GET_SESS_PRIV_IOVA(sess)); 32076f0ef237SDavid Coyle if (ret != 0) { 32086f0ef237SDavid Coyle QAT_LOG(ERR, "Failed to configure session parameters"); 32096f0ef237SDavid Coyle return ret; 32106f0ef237SDavid Coyle } 32116f0ef237SDavid Coyle 3212ca0ba0e4SBrian Dooley #ifdef RTE_QAT_OPENSSL 32133625d12eSBrian Dooley #if (OPENSSL_VERSION_NUMBER >= 0x30000000L) 32143625d12eSBrian Dooley ossl_legacy_provider_unload(); 32153625d12eSBrian Dooley #endif 3216ca0ba0e4SBrian Dooley #endif 3217f7f2e8a9SBrian Dooley return 0; 32186f0ef237SDavid Coyle } 32196f0ef237SDavid Coyle 32206f0ef237SDavid Coyle int 32216f0ef237SDavid Coyle qat_security_session_destroy(void *dev __rte_unused, 32226f0ef237SDavid Coyle struct rte_security_session *sess) 32236f0ef237SDavid Coyle { 32243f3fc330SAkhil Goyal void *sess_priv = SECURITY_GET_SESS_PRIV(sess); 32256f0ef237SDavid Coyle struct qat_sym_session *s = (struct qat_sym_session *)sess_priv; 32266f0ef237SDavid Coyle 32276f0ef237SDavid Coyle if (sess_priv) { 3228ca0ba0e4SBrian Dooley #ifdef RTE_QAT_OPENSSL 32296f0ef237SDavid Coyle if (s->bpi_ctx) 32306f0ef237SDavid Coyle bpi_cipher_ctx_free(s->bpi_ctx); 3231ca0ba0e4SBrian Dooley #else 3232ca0ba0e4SBrian Dooley if (s->mb_mgr) 3233ca0ba0e4SBrian Dooley free_mb_mgr(s->mb_mgr); 3234ca0ba0e4SBrian Dooley #endif 32356f0ef237SDavid Coyle memset(s, 0, qat_sym_session_get_private_size(dev)); 32366f0ef237SDavid Coyle } 323752d59b92SKai Ji 32386f0ef237SDavid Coyle return 0; 32396f0ef237SDavid Coyle } 324066837861SAkhil Goyal 324166837861SAkhil Goyal unsigned int 324266837861SAkhil Goyal qat_security_session_get_size(void *device __rte_unused) 324366837861SAkhil Goyal { 324466837861SAkhil Goyal return sizeof(struct qat_sym_session); 324566837861SAkhil Goyal } 3246