* [dpdk-dev v4] crypto/qat: use intel-ipsec-mb for partial hash & aes [not found] <http://patches.dpdk.org/project/dpdk/patch/20220525165218.10926-1-kai.ji@intel.com/> @ 2022-05-26 10:47 ` Kai Ji 2022-05-26 13:43 ` [EXT] " Akhil Goyal 2022-05-27 8:55 ` [dpdk-dev v5] " Kai Ji 0 siblings, 2 replies; 9+ messages in thread From: Kai Ji @ 2022-05-26 10:47 UTC (permalink / raw) To: dev; +Cc: roy.fan.zhang, bruce.richardson, gakhil, Kai Ji Since openssl 3.0 now deprecates the low level API QAT required to perform partial hash & aes operation when creating the session. This patch add in qat_ipsec_mb_lib driver parameter to allow QAT PMD to switch APIs between openssl and intel ipsec-mb library. Signed-off-by: Kai Ji <kai.ji@intel.com> Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com> --- doc/guides/cryptodevs/qat.rst | 13 + drivers/common/qat/meson.build | 7 + drivers/common/qat/qat_device.c | 1 + drivers/common/qat/qat_device.h | 1 + drivers/crypto/qat/qat_sym.c | 3 + drivers/crypto/qat/qat_sym_session.c | 503 ++++++++++++++++++++++++--- 6 files changed, 485 insertions(+), 43 deletions(-) diff --git a/doc/guides/cryptodevs/qat.rst b/doc/guides/cryptodevs/qat.rst index 785e041324..d92409b77e 100644 --- a/doc/guides/cryptodevs/qat.rst +++ b/doc/guides/cryptodevs/qat.rst @@ -287,6 +287,19 @@ by comma. When the same parameter is used more than once first occurrence of the is used. Maximum threshold that can be set is 32. +Running QAT PMD with Intel IPSEC MB library for symmetric precomputes function +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The QAT PMD use Openssl library for partial hash calculation in symmetirc precomputes function by +default, the following parameter is allow QAT PMD switch over to multi-buffer job API if Intel +IPSEC MB library installed on system. + +- qat_ipsec_mb_lib + +To use this feature the user must set the parameter on process start as a device additional parameter:: + + -a 03:01.1,qat_ipsec_mb_lib=1 + Device and driver naming ~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/drivers/common/qat/meson.build b/drivers/common/qat/meson.build index b7027f3164..b1ae7b4292 100644 --- a/drivers/common/qat/meson.build +++ b/drivers/common/qat/meson.build @@ -35,6 +35,13 @@ if qat_crypto and not libcrypto.found() 'missing dependency, libcrypto') endif +IMB_required_ver = '1.2.0' +libipsecmb = cc.find_library('IPSec_MB', required: false) +if libipsecmb.found() + ext_deps += libipsecmb + dpdk_conf.set('RTE_QAT_LIBIPSECMB', true) +endif + # The driver should not build if both compression and crypto are disabled #FIXME common code depends on compression files so check only compress! if not qat_compress # and not qat_crypto diff --git a/drivers/common/qat/qat_device.c b/drivers/common/qat/qat_device.c index 6824d97050..db4b087d2b 100644 --- a/drivers/common/qat/qat_device.c +++ b/drivers/common/qat/qat_device.c @@ -364,6 +364,7 @@ static int qat_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, struct qat_pci_device *qat_pci_dev; struct qat_dev_hw_spec_funcs *ops_hw; struct qat_dev_cmd_param qat_dev_cmd_param[] = { + { QAT_IPSEC_MB_LIB, 0 }, { SYM_ENQ_THRESHOLD_NAME, 0 }, { ASYM_ENQ_THRESHOLD_NAME, 0 }, { COMP_ENQ_THRESHOLD_NAME, 0 }, diff --git a/drivers/common/qat/qat_device.h b/drivers/common/qat/qat_device.h index 85fae7b7c7..e1a32a7e87 100644 --- a/drivers/common/qat/qat_device.h +++ b/drivers/common/qat/qat_device.h @@ -16,6 +16,7 @@ #define QAT_DEV_NAME_MAX_LEN 64 +#define QAT_IPSEC_MB_LIB "qat_ipsec_mb_lib" #define SYM_ENQ_THRESHOLD_NAME "qat_sym_enq_threshold" #define ASYM_ENQ_THRESHOLD_NAME "qat_asym_enq_threshold" #define COMP_ENQ_THRESHOLD_NAME "qat_comp_enq_threshold" diff --git a/drivers/crypto/qat/qat_sym.c b/drivers/crypto/qat/qat_sym.c index ca8c9a8124..3477cd89ad 100644 --- a/drivers/crypto/qat/qat_sym.c +++ b/drivers/crypto/qat/qat_sym.c @@ -15,6 +15,7 @@ #include "qat_qp.h" uint8_t qat_sym_driver_id; +int qat_ipsec_mb_lib; struct qat_crypto_gen_dev_ops qat_sym_gen_dev_ops[QAT_N_GENS]; @@ -307,6 +308,8 @@ qat_sym_dev_create(struct qat_pci_device *qat_pci_dev, if (!strcmp(qat_dev_cmd_param[i].name, SYM_ENQ_THRESHOLD_NAME)) internals->min_enq_burst_threshold = qat_dev_cmd_param[i].val; + if (!strcmp(qat_dev_cmd_param[i].name, QAT_IPSEC_MB_LIB)) + qat_ipsec_mb_lib = qat_dev_cmd_param[i].val; i++; } diff --git a/drivers/crypto/qat/qat_sym_session.c b/drivers/crypto/qat/qat_sym_session.c index 9d6a19c0be..69a97948f5 100644 --- a/drivers/crypto/qat/qat_sym_session.c +++ b/drivers/crypto/qat/qat_sym_session.c @@ -7,6 +7,10 @@ #include <openssl/md5.h> /* Needed to calculate pre-compute values */ #include <openssl/evp.h> /* Needed for bpi runt block processing */ +#ifdef RTE_QAT_LIBIPSECMB +#include <intel-ipsec-mb.h> +#endif + #include <rte_memcpy.h> #include <rte_common.h> #include <rte_spinlock.h> @@ -22,6 +26,12 @@ #include "qat_sym_session.h" #include "qat_sym.h" +#if (OPENSSL_VERSION_NUMBER >= 0x30000000L) +#include <openssl/provider.h> +#endif + +extern int qat_ipsec_mb_lib; + /* SHA1 - 20 bytes - Initialiser state can be found in FIPS stds 180-2 */ static const uint8_t sha1InitialState[] = { 0x67, 0x45, 0x23, 0x01, 0xef, 0xcd, 0xab, 0x89, 0x98, 0xba, @@ -470,6 +480,21 @@ qat_sym_session_configure(struct rte_cryptodev *dev, return -ENOMEM; } +#if (OPENSSL_VERSION_NUMBER >= 0x30000000L) + OSSL_PROVIDER * legacy; + OSSL_PROVIDER *deflt; + + /* Load Multiple providers into the default (NULL) library context */ + legacy = OSSL_PROVIDER_load(NULL, "legacy"); + if (legacy == NULL) + return -EINVAL; + + deflt = OSSL_PROVIDER_load(NULL, "default"); + if (deflt == NULL) { + OSSL_PROVIDER_unload(legacy); + return -EINVAL; + } +#endif ret = qat_sym_session_set_parameters(dev, xform, sess_private_data); if (ret != 0) { QAT_LOG(ERR, @@ -483,6 +508,10 @@ qat_sym_session_configure(struct rte_cryptodev *dev, set_sym_session_private_data(sess, dev->driver_id, sess_private_data); +# if (OPENSSL_VERSION_NUMBER >= 0x30000000L) + OSSL_PROVIDER_unload(legacy); + OSSL_PROVIDER_unload(deflt); +# endif return 0; } @@ -1057,6 +1086,293 @@ static int qat_hash_get_block_size(enum icp_qat_hw_auth_algo qat_hash_alg) return -EFAULT; } +#define HMAC_IPAD_VALUE 0x36 +#define HMAC_OPAD_VALUE 0x5c +#define HASH_XCBC_PRECOMP_KEY_NUM 3 + +static const uint8_t AES_CMAC_SEED[ICP_QAT_HW_AES_128_KEY_SZ]; + +#ifdef RTE_QAT_LIBIPSECMB +static int aes_ipsecmb_job(uint8_t *in, uint8_t *out, IMB_MGR *m, + const uint8_t *key, uint16_t auth_keylen) +{ + int err; + struct IMB_JOB *job; + DECLARE_ALIGNED(uint32_t expkey[4*15], 16); + DECLARE_ALIGNED(uint32_t dust[4*15], 16); + + if (auth_keylen == ICP_QAT_HW_AES_128_KEY_SZ) + IMB_AES_KEYEXP_128(m, key, expkey, dust); + else if (auth_keylen == ICP_QAT_HW_AES_192_KEY_SZ) + IMB_AES_KEYEXP_192(m, key, expkey, dust); + else if (auth_keylen == ICP_QAT_HW_AES_256_KEY_SZ) + IMB_AES_KEYEXP_256(m, key, expkey, dust); + else + return -EFAULT; + + job = IMB_GET_NEXT_JOB(m); + + job->src = in; + job->dst = out; + job->enc_keys = expkey; + job->key_len_in_bytes = auth_keylen; + job->msg_len_to_cipher_in_bytes = 16; + job->iv_len_in_bytes = 0; + job->cipher_direction = IMB_DIR_ENCRYPT; + job->cipher_mode = IMB_CIPHER_ECB; + job->hash_alg = IMB_AUTH_NULL; + + while (IMB_FLUSH_JOB(m) != NULL) + ; + + job = IMB_SUBMIT_JOB(m); + if (job) { + if (job->status == IMB_STATUS_COMPLETED) + return 0; + } + + err = imb_get_errno(m); + if (err) + QAT_LOG(ERR, "Error: %s!\n", imb_get_strerror(err)); + + return -EFAULT; +} + +static int +partial_hash_compute_ipsec_mb(enum icp_qat_hw_auth_algo hash_alg, + uint8_t *data_in, uint8_t *data_out, IMB_MGR *m) +{ + int digest_size; + uint8_t digest[qat_hash_get_digest_size( + ICP_QAT_HW_AUTH_ALGO_DELIMITER)]; + uint32_t *hash_state_out_be32; + uint64_t *hash_state_out_be64; + int i; + + /* Initialize to avoid gcc warning */ + memset(digest, 0, sizeof(digest)); + + digest_size = qat_hash_get_digest_size(hash_alg); + if (digest_size <= 0) + return -EFAULT; + + hash_state_out_be32 = (uint32_t *)data_out; + hash_state_out_be64 = (uint64_t *)data_out; + + switch (hash_alg) { + case ICP_QAT_HW_AUTH_ALGO_SHA1: + IMB_SHA1_ONE_BLOCK(m, data_in, digest); + for (i = 0; i < digest_size >> 2; i++, hash_state_out_be32++) + *hash_state_out_be32 = + rte_bswap32(*(((uint32_t *)digest)+i)); + break; + case ICP_QAT_HW_AUTH_ALGO_SHA224: + IMB_SHA224_ONE_BLOCK(m, data_in, digest); + for (i = 0; i < digest_size >> 2; i++, hash_state_out_be32++) + *hash_state_out_be32 = + rte_bswap32(*(((uint32_t *)digest)+i)); + break; + case ICP_QAT_HW_AUTH_ALGO_SHA256: + IMB_SHA256_ONE_BLOCK(m, data_in, digest); + for (i = 0; i < digest_size >> 2; i++, hash_state_out_be32++) + *hash_state_out_be32 = + rte_bswap32(*(((uint32_t *)digest)+i)); + break; + case ICP_QAT_HW_AUTH_ALGO_SHA384: + IMB_SHA384_ONE_BLOCK(m, data_in, digest); + for (i = 0; i < digest_size >> 3; i++, hash_state_out_be64++) + *hash_state_out_be64 = + rte_bswap64(*(((uint64_t *)digest)+i)); + break; + case ICP_QAT_HW_AUTH_ALGO_SHA512: + IMB_SHA512_ONE_BLOCK(m, data_in, digest); + for (i = 0; i < digest_size >> 3; i++, hash_state_out_be64++) + *hash_state_out_be64 = + rte_bswap64(*(((uint64_t *)digest)+i)); + break; + case ICP_QAT_HW_AUTH_ALGO_MD5: + IMB_MD5_ONE_BLOCK(m, data_in, data_out); + break; + default: + QAT_LOG(ERR, "invalid hash alg %u", hash_alg); + return -EFAULT; + } + + return 0; +} + +static int qat_sym_do_precomputes_ipsec_mb(enum icp_qat_hw_auth_algo hash_alg, + const uint8_t *auth_key, + uint16_t auth_keylen, + uint8_t *p_state_buf, + uint16_t *p_state_len, + uint8_t aes_cmac) +{ + int block_size; + uint8_t ipad[qat_hash_get_block_size(ICP_QAT_HW_AUTH_ALGO_DELIMITER)]; + uint8_t opad[qat_hash_get_block_size(ICP_QAT_HW_AUTH_ALGO_DELIMITER)]; + int i, ret = 0; + + IMB_MGR *m; + m = alloc_mb_mgr(0); + if (m == NULL) + return -ENOMEM; + + init_mb_mgr_auto(m, NULL); + + if (hash_alg == ICP_QAT_HW_AUTH_ALGO_AES_XCBC_MAC) { + + /* CMAC */ + if (aes_cmac) { + uint8_t *in = NULL; + uint8_t k0[ICP_QAT_HW_AES_128_KEY_SZ]; + uint8_t *k1, *k2; + + auth_keylen = ICP_QAT_HW_AES_128_KEY_SZ; + + in = rte_zmalloc("AES CMAC K1", + ICP_QAT_HW_AES_128_KEY_SZ, 16); + + if (in == NULL) { + QAT_LOG(ERR, "Failed to alloc memory"); + return -ENOMEM; + } + + rte_memcpy(in, AES_CMAC_SEED, + ICP_QAT_HW_AES_128_KEY_SZ); + rte_memcpy(p_state_buf, auth_key, auth_keylen); + + DECLARE_ALIGNED(uint32_t expkey[4*15], 16); + DECLARE_ALIGNED(uint32_t dust[4*15], 16); + IMB_AES_KEYEXP_128(m, p_state_buf, expkey, dust); + k1 = p_state_buf + ICP_QAT_HW_AES_XCBC_MAC_STATE1_SZ; + k2 = k1 + ICP_QAT_HW_AES_XCBC_MAC_STATE1_SZ; + + IMB_AES_CMAC_SUBKEY_GEN_128(m, expkey, k1, k2); + memset(k0, 0, ICP_QAT_HW_AES_128_KEY_SZ); + *p_state_len = ICP_QAT_HW_AES_XCBC_MAC_STATE2_SZ; + rte_free(in); + free_mb_mgr(m); + return 0; + } + + static uint8_t qat_aes_xcbc_key_seed[ + ICP_QAT_HW_AES_XCBC_MAC_STATE2_SZ] = { + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + }; + + uint8_t *in = NULL; + uint8_t *out = p_state_buf; + int x; + + in = rte_zmalloc("working mem for key", + ICP_QAT_HW_AES_XCBC_MAC_STATE2_SZ, 16); + if (in == NULL) { + QAT_LOG(ERR, "Failed to alloc memory"); + return -ENOMEM; + } + + rte_memcpy(in, qat_aes_xcbc_key_seed, + ICP_QAT_HW_AES_XCBC_MAC_STATE2_SZ); + for (x = 0; x < HASH_XCBC_PRECOMP_KEY_NUM; x++) { + if (aes_ipsecmb_job(in, out, m, auth_key, auth_keylen)) { + rte_free(in - + (x * ICP_QAT_HW_AES_XCBC_MAC_KEY_SZ)); + memset(out - + (x * ICP_QAT_HW_AES_XCBC_MAC_KEY_SZ), + 0, ICP_QAT_HW_AES_XCBC_MAC_STATE2_SZ); + return -EFAULT; + } + + in += ICP_QAT_HW_AES_XCBC_MAC_KEY_SZ; + out += ICP_QAT_HW_AES_XCBC_MAC_KEY_SZ; + } + *p_state_len = ICP_QAT_HW_AES_XCBC_MAC_STATE2_SZ; + rte_free(in - x*ICP_QAT_HW_AES_XCBC_MAC_KEY_SZ); + free_mb_mgr(m); + return 0; + + } else if ((hash_alg == ICP_QAT_HW_AUTH_ALGO_GALOIS_128) || + (hash_alg == ICP_QAT_HW_AUTH_ALGO_GALOIS_64)) { + uint8_t *in = NULL; + uint8_t *out = p_state_buf; + + memset(p_state_buf, 0, ICP_QAT_HW_GALOIS_H_SZ + + ICP_QAT_HW_GALOIS_LEN_A_SZ + + ICP_QAT_HW_GALOIS_E_CTR0_SZ); + in = rte_zmalloc("working mem for key", + ICP_QAT_HW_GALOIS_H_SZ, 16); + if (in == NULL) { + QAT_LOG(ERR, "Failed to alloc memory"); + return -ENOMEM; + } + + memset(in, 0, ICP_QAT_HW_GALOIS_H_SZ); + if (aes_ipsecmb_job(in, out, m, auth_key, auth_keylen)) + return -EFAULT; + + *p_state_len = ICP_QAT_HW_GALOIS_H_SZ + + ICP_QAT_HW_GALOIS_LEN_A_SZ + + ICP_QAT_HW_GALOIS_E_CTR0_SZ; + rte_free(in); + free_mb_mgr(m); + return 0; + } + + block_size = qat_hash_get_block_size(hash_alg); + if (block_size < 0) + return block_size; + /* init ipad and opad from key and xor with fixed values */ + memset(ipad, 0, block_size); + memset(opad, 0, block_size); + + if (auth_keylen > (unsigned int)block_size) { + QAT_LOG(ERR, "invalid keylen %u", auth_keylen); + free_mb_mgr(m); + return -EFAULT; + } + rte_memcpy(ipad, auth_key, auth_keylen); + rte_memcpy(opad, auth_key, auth_keylen); + + for (i = 0; i < block_size; i++) { + uint8_t *ipad_ptr = ipad + i; + uint8_t *opad_ptr = opad + i; + *ipad_ptr ^= HMAC_IPAD_VALUE; + *opad_ptr ^= HMAC_OPAD_VALUE; + } + + /* do partial hash of ipad and copy to state1 */ + if (partial_hash_compute_ipsec_mb(hash_alg, ipad, p_state_buf, m)) { + QAT_LOG(ERR, "ipad precompute failed"); + ret = -EFAULT; + goto out; + } + + /* + * State len is a multiple of 8, so may be larger than the digest. + * Put the partial hash of opad state_len bytes after state1 + */ + *p_state_len = qat_hash_get_state1_size(hash_alg); + if (partial_hash_compute_ipsec_mb(hash_alg, opad, + p_state_buf + *p_state_len, m)) { + QAT_LOG(ERR, "opad precompute failed"); + ret = -EFAULT; + goto out; + } + +out: + /* don't leave data lying around */ + memset(ipad, 0, block_size); + memset(opad, 0, block_size); + free_mb_mgr(m); + return ret; +} +#endif static int partial_hash_sha1(uint8_t *data_in, uint8_t *data_out) { SHA_CTX ctx; @@ -1124,6 +1440,20 @@ static int partial_hash_md5(uint8_t *data_in, uint8_t *data_out) return 0; } +static void aes_cmac_key_derive(uint8_t *base, uint8_t *derived) +{ + int i; + + derived[0] = base[0] << 1; + for (i = 1; i < ICP_QAT_HW_AES_BLK_SZ ; i++) { + derived[i] = base[i] << 1; + derived[i - 1] |= base[i] >> 7; + } + + if (base[0] & 0x80) + derived[ICP_QAT_HW_AES_BLK_SZ - 1] ^= QAT_AES_CMAC_CONST_RB; +} + static int partial_hash_compute(enum icp_qat_hw_auth_algo hash_alg, uint8_t *data_in, uint8_t *data_out) @@ -1192,25 +1522,6 @@ partial_hash_compute(enum icp_qat_hw_auth_algo hash_alg, return 0; } -#define HMAC_IPAD_VALUE 0x36 -#define HMAC_OPAD_VALUE 0x5c -#define HASH_XCBC_PRECOMP_KEY_NUM 3 - -static const uint8_t AES_CMAC_SEED[ICP_QAT_HW_AES_128_KEY_SZ]; - -static void aes_cmac_key_derive(uint8_t *base, uint8_t *derived) -{ - int i; - - derived[0] = base[0] << 1; - for (i = 1; i < ICP_QAT_HW_AES_BLK_SZ ; i++) { - derived[i] = base[i] << 1; - derived[i - 1] |= base[i] >> 7; - } - - if (base[0] & 0x80) - derived[ICP_QAT_HW_AES_BLK_SZ - 1] ^= QAT_AES_CMAC_CONST_RB; -} static int qat_sym_do_precomputes(enum icp_qat_hw_auth_algo hash_alg, const uint8_t *auth_key, @@ -1695,6 +2006,7 @@ int qat_sym_cd_auth_set(struct qat_sym_session *cdesc, uint32_t *aad_len = NULL; uint32_t wordIndex = 0; uint32_t *pTempKey; + int ret = 0; if (cdesc->qat_cmd == ICP_QAT_FW_LA_CMD_AUTH) { ICP_QAT_FW_COMN_CURR_ID_SET(hash_cd_ctrl, @@ -1766,9 +2078,22 @@ int qat_sym_cd_auth_set(struct qat_sym_session *cdesc, break; } /* SHA-1 HMAC */ - if (qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA1, authkey, - authkeylen, cdesc->cd_cur_ptr, &state1_size, - cdesc->aes_cmac)) { + if (qat_ipsec_mb_lib) { +#ifdef RTE_QAT_LIBIPSECMB + ret = qat_sym_do_precomputes_ipsec_mb(ICP_QAT_HW_AUTH_ALGO_SHA1, + authkey, authkeylen, cdesc->cd_cur_ptr, &state1_size, + cdesc->aes_cmac); +#else + QAT_LOG(ERR, "Intel IPSEC-MB LIB missing ?"); + return -EFAULT; +#endif + } else { + ret = qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA1, authkey, + authkeylen, cdesc->cd_cur_ptr, &state1_size, + cdesc->aes_cmac); + } + + if (ret) { QAT_LOG(ERR, "(SHA)precompute failed"); return -EFAULT; } @@ -1784,9 +2109,22 @@ int qat_sym_cd_auth_set(struct qat_sym_session *cdesc, break; } /* SHA-224 HMAC */ - if (qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA224, authkey, - authkeylen, cdesc->cd_cur_ptr, &state1_size, - cdesc->aes_cmac)) { + if (qat_ipsec_mb_lib) { +#ifdef RTE_QAT_LIBIPSECMB + ret = qat_sym_do_precomputes_ipsec_mb(ICP_QAT_HW_AUTH_ALGO_SHA224, + authkey, authkeylen, cdesc->cd_cur_ptr, &state1_size, + cdesc->aes_cmac); +#else + QAT_LOG(ERR, "Intel IPSEC-MB LIB missing ?"); + return -EFAULT; +#endif + } else { + ret = qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA224, authkey, + authkeylen, cdesc->cd_cur_ptr, &state1_size, + cdesc->aes_cmac); + } + + if (ret) { QAT_LOG(ERR, "(SHA)precompute failed"); return -EFAULT; } @@ -1802,9 +2140,22 @@ int qat_sym_cd_auth_set(struct qat_sym_session *cdesc, break; } /* SHA-256 HMAC */ - if (qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA256, authkey, - authkeylen, cdesc->cd_cur_ptr, &state1_size, - cdesc->aes_cmac)) { + if (qat_ipsec_mb_lib) { +#ifdef RTE_QAT_LIBIPSECMB + ret = qat_sym_do_precomputes_ipsec_mb(ICP_QAT_HW_AUTH_ALGO_SHA256, + authkey, authkeylen, cdesc->cd_cur_ptr, &state1_size, + cdesc->aes_cmac); +#else + QAT_LOG(ERR, "Intel IPSEC-MB LIB missing ?"); + return -EFAULT; +#endif + } else { + ret = qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA256, authkey, + authkeylen, cdesc->cd_cur_ptr, &state1_size, + cdesc->aes_cmac); + } + + if (ret) { QAT_LOG(ERR, "(SHA)precompute failed"); return -EFAULT; } @@ -1820,9 +2171,22 @@ int qat_sym_cd_auth_set(struct qat_sym_session *cdesc, break; } /* SHA-384 HMAC */ - if (qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA384, authkey, - authkeylen, cdesc->cd_cur_ptr, &state1_size, - cdesc->aes_cmac)) { + if (qat_ipsec_mb_lib) { +#ifdef RTE_QAT_LIBIPSECMB + ret = qat_sym_do_precomputes_ipsec_mb(ICP_QAT_HW_AUTH_ALGO_SHA384, + authkey, authkeylen, cdesc->cd_cur_ptr, &state1_size, + cdesc->aes_cmac); +#else + QAT_LOG(ERR, "Intel IPSEC-MB LIB missing ?"); + return -EFAULT; +#endif + } else { + ret = qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA384, authkey, + authkeylen, cdesc->cd_cur_ptr, &state1_size, + cdesc->aes_cmac); + } + + if (ret) { QAT_LOG(ERR, "(SHA)precompute failed"); return -EFAULT; } @@ -1838,9 +2202,22 @@ int qat_sym_cd_auth_set(struct qat_sym_session *cdesc, break; } /* SHA-512 HMAC */ - if (qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA512, authkey, - authkeylen, cdesc->cd_cur_ptr, &state1_size, - cdesc->aes_cmac)) { + if (qat_ipsec_mb_lib) { +#ifdef RTE_QAT_LIBIPSECMB + ret = qat_sym_do_precomputes_ipsec_mb(ICP_QAT_HW_AUTH_ALGO_SHA512, + authkey, authkeylen, cdesc->cd_cur_ptr, &state1_size, + cdesc->aes_cmac); +#else + QAT_LOG(ERR, "Intel IPSEC-MB LIB missing ?"); + return -EFAULT; +#endif + } else { + ret = qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA512, authkey, + authkeylen, cdesc->cd_cur_ptr, &state1_size, + cdesc->aes_cmac); + } + + if (ret) { QAT_LOG(ERR, "(SHA)precompute failed"); return -EFAULT; } @@ -1851,9 +2228,23 @@ int qat_sym_cd_auth_set(struct qat_sym_session *cdesc, if (cdesc->aes_cmac) memset(cdesc->cd_cur_ptr, 0, state1_size); - if (qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_AES_XCBC_MAC, - authkey, authkeylen, cdesc->cd_cur_ptr + state1_size, - &state2_size, cdesc->aes_cmac)) { + if (qat_ipsec_mb_lib) { +#ifdef RTE_QAT_LIBIPSECMB + ret = qat_sym_do_precomputes_ipsec_mb( + ICP_QAT_HW_AUTH_ALGO_AES_XCBC_MAC, + authkey, authkeylen, cdesc->cd_cur_ptr + state1_size, + &state2_size, cdesc->aes_cmac); +#else + QAT_LOG(ERR, "Intel IPSEC-MB LIB missing ?"); + return -EFAULT; +#endif + } else { + ret = qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_AES_XCBC_MAC, + authkey, authkeylen, cdesc->cd_cur_ptr + state1_size, + &state2_size, cdesc->aes_cmac); + } + + if (ret) { cdesc->aes_cmac ? QAT_LOG(ERR, "(CMAC)precompute failed") : QAT_LOG(ERR, @@ -1865,9 +2256,22 @@ int qat_sym_cd_auth_set(struct qat_sym_session *cdesc, case ICP_QAT_HW_AUTH_ALGO_GALOIS_64: cdesc->qat_proto_flag = QAT_CRYPTO_PROTO_FLAG_GCM; state1_size = ICP_QAT_HW_GALOIS_128_STATE1_SZ; - if (qat_sym_do_precomputes(cdesc->qat_hash_alg, authkey, - authkeylen, cdesc->cd_cur_ptr + state1_size, - &state2_size, cdesc->aes_cmac)) { + if (qat_ipsec_mb_lib) { +#ifdef RTE_QAT_LIBIPSECMB + ret = qat_sym_do_precomputes_ipsec_mb(cdesc->qat_hash_alg, authkey, + authkeylen, cdesc->cd_cur_ptr + state1_size, + &state2_size, cdesc->aes_cmac); +#else + QAT_LOG(ERR, "Intel IPSEC-MB LIB missing ?"); + return -EFAULT; +#endif + } else { + ret = qat_sym_do_precomputes(cdesc->qat_hash_alg, authkey, + authkeylen, cdesc->cd_cur_ptr + state1_size, + &state2_size, cdesc->aes_cmac); + } + + if (ret) { QAT_LOG(ERR, "(GCM)precompute failed"); return -EFAULT; } @@ -1923,9 +2327,22 @@ int qat_sym_cd_auth_set(struct qat_sym_session *cdesc, break; case ICP_QAT_HW_AUTH_ALGO_MD5: - if (qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_MD5, authkey, - authkeylen, cdesc->cd_cur_ptr, &state1_size, - cdesc->aes_cmac)) { + if (qat_ipsec_mb_lib) { +#ifdef RTE_QAT_LIBIPSECMB + ret = qat_sym_do_precomputes_ipsec_mb(ICP_QAT_HW_AUTH_ALGO_MD5, + authkey, authkeylen, cdesc->cd_cur_ptr, &state1_size, + cdesc->aes_cmac); +#else + QAT_LOG(ERR, "Intel IPSEC-MB LIB missing"); + return -EFAULT; +#endif + } else { + ret = qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_MD5, authkey, + authkeylen, cdesc->cd_cur_ptr, &state1_size, + cdesc->aes_cmac); + } + + if (ret) { QAT_LOG(ERR, "(MD5)precompute failed"); return -EFAULT; } -- 2.17.1 ^ permalink raw reply [flat|nested] 9+ messages in thread
* RE: [EXT] [dpdk-dev v4] crypto/qat: use intel-ipsec-mb for partial hash & aes 2022-05-26 10:47 ` [dpdk-dev v4] crypto/qat: use intel-ipsec-mb for partial hash & aes Kai Ji @ 2022-05-26 13:43 ` Akhil Goyal 2022-05-26 13:43 ` Akhil Goyal 2022-05-27 8:55 ` [dpdk-dev v5] " Kai Ji 1 sibling, 1 reply; 9+ messages in thread From: Akhil Goyal @ 2022-05-26 13:43 UTC (permalink / raw) To: Kai Ji, dev; +Cc: roy.fan.zhang, bruce.richardson > Since openssl 3.0 now deprecates the low level API QAT required to > perform partial hash & aes operation when creating the session. This > patch add in qat_ipsec_mb_lib driver parameter to allow QAT PMD to > switch APIs between openssl and intel ipsec-mb library. > > Signed-off-by: Kai Ji <kai.ji@intel.com> > Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com> > --- Changelog missing And compilation is also broken. Please fix. ^ permalink raw reply [flat|nested] 9+ messages in thread
* RE: [EXT] [dpdk-dev v4] crypto/qat: use intel-ipsec-mb for partial hash & aes 2022-05-26 13:43 ` [EXT] " Akhil Goyal @ 2022-05-26 13:43 ` Akhil Goyal 0 siblings, 0 replies; 9+ messages in thread From: Akhil Goyal @ 2022-05-26 13:43 UTC (permalink / raw) To: Kai Ji, dev; +Cc: roy.fan.zhang, bruce.richardson > > > Since openssl 3.0 now deprecates the low level API QAT required to > > perform partial hash & aes operation when creating the session. This > > patch add in qat_ipsec_mb_lib driver parameter to allow QAT PMD to > > switch APIs between openssl and intel ipsec-mb library. > > > > Signed-off-by: Kai Ji <kai.ji@intel.com> > > Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com> > > --- > Changelog missing > > And compilation is also broken. Please fix. http://mails.dpdk.org/archives/test-report/2022-May/284090.html ^ permalink raw reply [flat|nested] 9+ messages in thread
* [dpdk-dev v5] crypto/qat: use intel-ipsec-mb for partial hash & aes 2022-05-26 10:47 ` [dpdk-dev v4] crypto/qat: use intel-ipsec-mb for partial hash & aes Kai Ji 2022-05-26 13:43 ` [EXT] " Akhil Goyal @ 2022-05-27 8:55 ` Kai Ji 2022-05-27 12:26 ` Zhang, Roy Fan 2022-05-30 10:21 ` [dpdk-dev v6] " Kai Ji 1 sibling, 2 replies; 9+ messages in thread From: Kai Ji @ 2022-05-27 8:55 UTC (permalink / raw) To: dev; +Cc: roy.fan.zhang, bruce.richardson, gakhil, Kai Ji Since openssl 3.0 now deprecates the low level API QAT required to perform partial hash & aes operation when creating the session. This patch add in qat_ipsec_mb_lib driver parameter to allow QAT PMD to switch APIs between openssl and intel ipsec-mb library. Signed-off-by: Kai Ji <kai.ji@intel.com> Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com> v5: - fix of Intel IPSEC-MB lib version check v4: - fix of memory leak in IMB_MGR v3: - Add in qat_ipsec_mb_lib driver parameter v2: - Add AES ECB job function for precompute --- doc/guides/cryptodevs/qat.rst | 13 + drivers/common/qat/meson.build | 13 + drivers/common/qat/qat_device.c | 1 + drivers/common/qat/qat_device.h | 1 + drivers/crypto/qat/qat_sym.c | 3 + drivers/crypto/qat/qat_sym_session.c | 503 ++++++++++++++++++++++++--- 6 files changed, 491 insertions(+), 43 deletions(-) diff --git a/doc/guides/cryptodevs/qat.rst b/doc/guides/cryptodevs/qat.rst index 785e041324..d92409b77e 100644 --- a/doc/guides/cryptodevs/qat.rst +++ b/doc/guides/cryptodevs/qat.rst @@ -287,6 +287,19 @@ by comma. When the same parameter is used more than once first occurrence of the is used. Maximum threshold that can be set is 32. +Running QAT PMD with Intel IPSEC MB library for symmetric precomputes function +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The QAT PMD use Openssl library for partial hash calculation in symmetirc precomputes function by +default, the following parameter is allow QAT PMD switch over to multi-buffer job API if Intel +IPSEC MB library installed on system. + +- qat_ipsec_mb_lib + +To use this feature the user must set the parameter on process start as a device additional parameter:: + + -a 03:01.1,qat_ipsec_mb_lib=1 + Device and driver naming ~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/drivers/common/qat/meson.build b/drivers/common/qat/meson.build index b7027f3164..245c0fbe61 100644 --- a/drivers/common/qat/meson.build +++ b/drivers/common/qat/meson.build @@ -35,6 +35,19 @@ if qat_crypto and not libcrypto.found() 'missing dependency, libcrypto') endif +IMB_required_ver = '1.2.0' +libipsecmb = cc.find_library('IPSec_MB', required: false) +if libipsecmb.found() + # version comes with quotes, so we split based on " and take the middle + imb_ver = cc.get_define('IMB_VERSION_STR', + prefix : '#include<intel-ipsec-mb.h>').split('"')[1] + + if (imb_ver.version_compare('>=' + IMB_required_ver)) + ext_deps += libipsecmb + dpdk_conf.set('RTE_QAT_LIBIPSECMB', true) + endif +endif + # The driver should not build if both compression and crypto are disabled #FIXME common code depends on compression files so check only compress! if not qat_compress # and not qat_crypto diff --git a/drivers/common/qat/qat_device.c b/drivers/common/qat/qat_device.c index 6824d97050..db4b087d2b 100644 --- a/drivers/common/qat/qat_device.c +++ b/drivers/common/qat/qat_device.c @@ -364,6 +364,7 @@ static int qat_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, struct qat_pci_device *qat_pci_dev; struct qat_dev_hw_spec_funcs *ops_hw; struct qat_dev_cmd_param qat_dev_cmd_param[] = { + { QAT_IPSEC_MB_LIB, 0 }, { SYM_ENQ_THRESHOLD_NAME, 0 }, { ASYM_ENQ_THRESHOLD_NAME, 0 }, { COMP_ENQ_THRESHOLD_NAME, 0 }, diff --git a/drivers/common/qat/qat_device.h b/drivers/common/qat/qat_device.h index 85fae7b7c7..e1a32a7e87 100644 --- a/drivers/common/qat/qat_device.h +++ b/drivers/common/qat/qat_device.h @@ -16,6 +16,7 @@ #define QAT_DEV_NAME_MAX_LEN 64 +#define QAT_IPSEC_MB_LIB "qat_ipsec_mb_lib" #define SYM_ENQ_THRESHOLD_NAME "qat_sym_enq_threshold" #define ASYM_ENQ_THRESHOLD_NAME "qat_asym_enq_threshold" #define COMP_ENQ_THRESHOLD_NAME "qat_comp_enq_threshold" diff --git a/drivers/crypto/qat/qat_sym.c b/drivers/crypto/qat/qat_sym.c index ca8c9a8124..3477cd89ad 100644 --- a/drivers/crypto/qat/qat_sym.c +++ b/drivers/crypto/qat/qat_sym.c @@ -15,6 +15,7 @@ #include "qat_qp.h" uint8_t qat_sym_driver_id; +int qat_ipsec_mb_lib; struct qat_crypto_gen_dev_ops qat_sym_gen_dev_ops[QAT_N_GENS]; @@ -307,6 +308,8 @@ qat_sym_dev_create(struct qat_pci_device *qat_pci_dev, if (!strcmp(qat_dev_cmd_param[i].name, SYM_ENQ_THRESHOLD_NAME)) internals->min_enq_burst_threshold = qat_dev_cmd_param[i].val; + if (!strcmp(qat_dev_cmd_param[i].name, QAT_IPSEC_MB_LIB)) + qat_ipsec_mb_lib = qat_dev_cmd_param[i].val; i++; } diff --git a/drivers/crypto/qat/qat_sym_session.c b/drivers/crypto/qat/qat_sym_session.c index 9d6a19c0be..69a97948f5 100644 --- a/drivers/crypto/qat/qat_sym_session.c +++ b/drivers/crypto/qat/qat_sym_session.c @@ -7,6 +7,10 @@ #include <openssl/md5.h> /* Needed to calculate pre-compute values */ #include <openssl/evp.h> /* Needed for bpi runt block processing */ +#ifdef RTE_QAT_LIBIPSECMB +#include <intel-ipsec-mb.h> +#endif + #include <rte_memcpy.h> #include <rte_common.h> #include <rte_spinlock.h> @@ -22,6 +26,12 @@ #include "qat_sym_session.h" #include "qat_sym.h" +#if (OPENSSL_VERSION_NUMBER >= 0x30000000L) +#include <openssl/provider.h> +#endif + +extern int qat_ipsec_mb_lib; + /* SHA1 - 20 bytes - Initialiser state can be found in FIPS stds 180-2 */ static const uint8_t sha1InitialState[] = { 0x67, 0x45, 0x23, 0x01, 0xef, 0xcd, 0xab, 0x89, 0x98, 0xba, @@ -470,6 +480,21 @@ qat_sym_session_configure(struct rte_cryptodev *dev, return -ENOMEM; } +#if (OPENSSL_VERSION_NUMBER >= 0x30000000L) + OSSL_PROVIDER * legacy; + OSSL_PROVIDER *deflt; + + /* Load Multiple providers into the default (NULL) library context */ + legacy = OSSL_PROVIDER_load(NULL, "legacy"); + if (legacy == NULL) + return -EINVAL; + + deflt = OSSL_PROVIDER_load(NULL, "default"); + if (deflt == NULL) { + OSSL_PROVIDER_unload(legacy); + return -EINVAL; + } +#endif ret = qat_sym_session_set_parameters(dev, xform, sess_private_data); if (ret != 0) { QAT_LOG(ERR, @@ -483,6 +508,10 @@ qat_sym_session_configure(struct rte_cryptodev *dev, set_sym_session_private_data(sess, dev->driver_id, sess_private_data); +# if (OPENSSL_VERSION_NUMBER >= 0x30000000L) + OSSL_PROVIDER_unload(legacy); + OSSL_PROVIDER_unload(deflt); +# endif return 0; } @@ -1057,6 +1086,293 @@ static int qat_hash_get_block_size(enum icp_qat_hw_auth_algo qat_hash_alg) return -EFAULT; } +#define HMAC_IPAD_VALUE 0x36 +#define HMAC_OPAD_VALUE 0x5c +#define HASH_XCBC_PRECOMP_KEY_NUM 3 + +static const uint8_t AES_CMAC_SEED[ICP_QAT_HW_AES_128_KEY_SZ]; + +#ifdef RTE_QAT_LIBIPSECMB +static int aes_ipsecmb_job(uint8_t *in, uint8_t *out, IMB_MGR *m, + const uint8_t *key, uint16_t auth_keylen) +{ + int err; + struct IMB_JOB *job; + DECLARE_ALIGNED(uint32_t expkey[4*15], 16); + DECLARE_ALIGNED(uint32_t dust[4*15], 16); + + if (auth_keylen == ICP_QAT_HW_AES_128_KEY_SZ) + IMB_AES_KEYEXP_128(m, key, expkey, dust); + else if (auth_keylen == ICP_QAT_HW_AES_192_KEY_SZ) + IMB_AES_KEYEXP_192(m, key, expkey, dust); + else if (auth_keylen == ICP_QAT_HW_AES_256_KEY_SZ) + IMB_AES_KEYEXP_256(m, key, expkey, dust); + else + return -EFAULT; + + job = IMB_GET_NEXT_JOB(m); + + job->src = in; + job->dst = out; + job->enc_keys = expkey; + job->key_len_in_bytes = auth_keylen; + job->msg_len_to_cipher_in_bytes = 16; + job->iv_len_in_bytes = 0; + job->cipher_direction = IMB_DIR_ENCRYPT; + job->cipher_mode = IMB_CIPHER_ECB; + job->hash_alg = IMB_AUTH_NULL; + + while (IMB_FLUSH_JOB(m) != NULL) + ; + + job = IMB_SUBMIT_JOB(m); + if (job) { + if (job->status == IMB_STATUS_COMPLETED) + return 0; + } + + err = imb_get_errno(m); + if (err) + QAT_LOG(ERR, "Error: %s!\n", imb_get_strerror(err)); + + return -EFAULT; +} + +static int +partial_hash_compute_ipsec_mb(enum icp_qat_hw_auth_algo hash_alg, + uint8_t *data_in, uint8_t *data_out, IMB_MGR *m) +{ + int digest_size; + uint8_t digest[qat_hash_get_digest_size( + ICP_QAT_HW_AUTH_ALGO_DELIMITER)]; + uint32_t *hash_state_out_be32; + uint64_t *hash_state_out_be64; + int i; + + /* Initialize to avoid gcc warning */ + memset(digest, 0, sizeof(digest)); + + digest_size = qat_hash_get_digest_size(hash_alg); + if (digest_size <= 0) + return -EFAULT; + + hash_state_out_be32 = (uint32_t *)data_out; + hash_state_out_be64 = (uint64_t *)data_out; + + switch (hash_alg) { + case ICP_QAT_HW_AUTH_ALGO_SHA1: + IMB_SHA1_ONE_BLOCK(m, data_in, digest); + for (i = 0; i < digest_size >> 2; i++, hash_state_out_be32++) + *hash_state_out_be32 = + rte_bswap32(*(((uint32_t *)digest)+i)); + break; + case ICP_QAT_HW_AUTH_ALGO_SHA224: + IMB_SHA224_ONE_BLOCK(m, data_in, digest); + for (i = 0; i < digest_size >> 2; i++, hash_state_out_be32++) + *hash_state_out_be32 = + rte_bswap32(*(((uint32_t *)digest)+i)); + break; + case ICP_QAT_HW_AUTH_ALGO_SHA256: + IMB_SHA256_ONE_BLOCK(m, data_in, digest); + for (i = 0; i < digest_size >> 2; i++, hash_state_out_be32++) + *hash_state_out_be32 = + rte_bswap32(*(((uint32_t *)digest)+i)); + break; + case ICP_QAT_HW_AUTH_ALGO_SHA384: + IMB_SHA384_ONE_BLOCK(m, data_in, digest); + for (i = 0; i < digest_size >> 3; i++, hash_state_out_be64++) + *hash_state_out_be64 = + rte_bswap64(*(((uint64_t *)digest)+i)); + break; + case ICP_QAT_HW_AUTH_ALGO_SHA512: + IMB_SHA512_ONE_BLOCK(m, data_in, digest); + for (i = 0; i < digest_size >> 3; i++, hash_state_out_be64++) + *hash_state_out_be64 = + rte_bswap64(*(((uint64_t *)digest)+i)); + break; + case ICP_QAT_HW_AUTH_ALGO_MD5: + IMB_MD5_ONE_BLOCK(m, data_in, data_out); + break; + default: + QAT_LOG(ERR, "invalid hash alg %u", hash_alg); + return -EFAULT; + } + + return 0; +} + +static int qat_sym_do_precomputes_ipsec_mb(enum icp_qat_hw_auth_algo hash_alg, + const uint8_t *auth_key, + uint16_t auth_keylen, + uint8_t *p_state_buf, + uint16_t *p_state_len, + uint8_t aes_cmac) +{ + int block_size; + uint8_t ipad[qat_hash_get_block_size(ICP_QAT_HW_AUTH_ALGO_DELIMITER)]; + uint8_t opad[qat_hash_get_block_size(ICP_QAT_HW_AUTH_ALGO_DELIMITER)]; + int i, ret = 0; + + IMB_MGR *m; + m = alloc_mb_mgr(0); + if (m == NULL) + return -ENOMEM; + + init_mb_mgr_auto(m, NULL); + + if (hash_alg == ICP_QAT_HW_AUTH_ALGO_AES_XCBC_MAC) { + + /* CMAC */ + if (aes_cmac) { + uint8_t *in = NULL; + uint8_t k0[ICP_QAT_HW_AES_128_KEY_SZ]; + uint8_t *k1, *k2; + + auth_keylen = ICP_QAT_HW_AES_128_KEY_SZ; + + in = rte_zmalloc("AES CMAC K1", + ICP_QAT_HW_AES_128_KEY_SZ, 16); + + if (in == NULL) { + QAT_LOG(ERR, "Failed to alloc memory"); + return -ENOMEM; + } + + rte_memcpy(in, AES_CMAC_SEED, + ICP_QAT_HW_AES_128_KEY_SZ); + rte_memcpy(p_state_buf, auth_key, auth_keylen); + + DECLARE_ALIGNED(uint32_t expkey[4*15], 16); + DECLARE_ALIGNED(uint32_t dust[4*15], 16); + IMB_AES_KEYEXP_128(m, p_state_buf, expkey, dust); + k1 = p_state_buf + ICP_QAT_HW_AES_XCBC_MAC_STATE1_SZ; + k2 = k1 + ICP_QAT_HW_AES_XCBC_MAC_STATE1_SZ; + + IMB_AES_CMAC_SUBKEY_GEN_128(m, expkey, k1, k2); + memset(k0, 0, ICP_QAT_HW_AES_128_KEY_SZ); + *p_state_len = ICP_QAT_HW_AES_XCBC_MAC_STATE2_SZ; + rte_free(in); + free_mb_mgr(m); + return 0; + } + + static uint8_t qat_aes_xcbc_key_seed[ + ICP_QAT_HW_AES_XCBC_MAC_STATE2_SZ] = { + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + }; + + uint8_t *in = NULL; + uint8_t *out = p_state_buf; + int x; + + in = rte_zmalloc("working mem for key", + ICP_QAT_HW_AES_XCBC_MAC_STATE2_SZ, 16); + if (in == NULL) { + QAT_LOG(ERR, "Failed to alloc memory"); + return -ENOMEM; + } + + rte_memcpy(in, qat_aes_xcbc_key_seed, + ICP_QAT_HW_AES_XCBC_MAC_STATE2_SZ); + for (x = 0; x < HASH_XCBC_PRECOMP_KEY_NUM; x++) { + if (aes_ipsecmb_job(in, out, m, auth_key, auth_keylen)) { + rte_free(in - + (x * ICP_QAT_HW_AES_XCBC_MAC_KEY_SZ)); + memset(out - + (x * ICP_QAT_HW_AES_XCBC_MAC_KEY_SZ), + 0, ICP_QAT_HW_AES_XCBC_MAC_STATE2_SZ); + return -EFAULT; + } + + in += ICP_QAT_HW_AES_XCBC_MAC_KEY_SZ; + out += ICP_QAT_HW_AES_XCBC_MAC_KEY_SZ; + } + *p_state_len = ICP_QAT_HW_AES_XCBC_MAC_STATE2_SZ; + rte_free(in - x*ICP_QAT_HW_AES_XCBC_MAC_KEY_SZ); + free_mb_mgr(m); + return 0; + + } else if ((hash_alg == ICP_QAT_HW_AUTH_ALGO_GALOIS_128) || + (hash_alg == ICP_QAT_HW_AUTH_ALGO_GALOIS_64)) { + uint8_t *in = NULL; + uint8_t *out = p_state_buf; + + memset(p_state_buf, 0, ICP_QAT_HW_GALOIS_H_SZ + + ICP_QAT_HW_GALOIS_LEN_A_SZ + + ICP_QAT_HW_GALOIS_E_CTR0_SZ); + in = rte_zmalloc("working mem for key", + ICP_QAT_HW_GALOIS_H_SZ, 16); + if (in == NULL) { + QAT_LOG(ERR, "Failed to alloc memory"); + return -ENOMEM; + } + + memset(in, 0, ICP_QAT_HW_GALOIS_H_SZ); + if (aes_ipsecmb_job(in, out, m, auth_key, auth_keylen)) + return -EFAULT; + + *p_state_len = ICP_QAT_HW_GALOIS_H_SZ + + ICP_QAT_HW_GALOIS_LEN_A_SZ + + ICP_QAT_HW_GALOIS_E_CTR0_SZ; + rte_free(in); + free_mb_mgr(m); + return 0; + } + + block_size = qat_hash_get_block_size(hash_alg); + if (block_size < 0) + return block_size; + /* init ipad and opad from key and xor with fixed values */ + memset(ipad, 0, block_size); + memset(opad, 0, block_size); + + if (auth_keylen > (unsigned int)block_size) { + QAT_LOG(ERR, "invalid keylen %u", auth_keylen); + free_mb_mgr(m); + return -EFAULT; + } + rte_memcpy(ipad, auth_key, auth_keylen); + rte_memcpy(opad, auth_key, auth_keylen); + + for (i = 0; i < block_size; i++) { + uint8_t *ipad_ptr = ipad + i; + uint8_t *opad_ptr = opad + i; + *ipad_ptr ^= HMAC_IPAD_VALUE; + *opad_ptr ^= HMAC_OPAD_VALUE; + } + + /* do partial hash of ipad and copy to state1 */ + if (partial_hash_compute_ipsec_mb(hash_alg, ipad, p_state_buf, m)) { + QAT_LOG(ERR, "ipad precompute failed"); + ret = -EFAULT; + goto out; + } + + /* + * State len is a multiple of 8, so may be larger than the digest. + * Put the partial hash of opad state_len bytes after state1 + */ + *p_state_len = qat_hash_get_state1_size(hash_alg); + if (partial_hash_compute_ipsec_mb(hash_alg, opad, + p_state_buf + *p_state_len, m)) { + QAT_LOG(ERR, "opad precompute failed"); + ret = -EFAULT; + goto out; + } + +out: + /* don't leave data lying around */ + memset(ipad, 0, block_size); + memset(opad, 0, block_size); + free_mb_mgr(m); + return ret; +} +#endif static int partial_hash_sha1(uint8_t *data_in, uint8_t *data_out) { SHA_CTX ctx; @@ -1124,6 +1440,20 @@ static int partial_hash_md5(uint8_t *data_in, uint8_t *data_out) return 0; } +static void aes_cmac_key_derive(uint8_t *base, uint8_t *derived) +{ + int i; + + derived[0] = base[0] << 1; + for (i = 1; i < ICP_QAT_HW_AES_BLK_SZ ; i++) { + derived[i] = base[i] << 1; + derived[i - 1] |= base[i] >> 7; + } + + if (base[0] & 0x80) + derived[ICP_QAT_HW_AES_BLK_SZ - 1] ^= QAT_AES_CMAC_CONST_RB; +} + static int partial_hash_compute(enum icp_qat_hw_auth_algo hash_alg, uint8_t *data_in, uint8_t *data_out) @@ -1192,25 +1522,6 @@ partial_hash_compute(enum icp_qat_hw_auth_algo hash_alg, return 0; } -#define HMAC_IPAD_VALUE 0x36 -#define HMAC_OPAD_VALUE 0x5c -#define HASH_XCBC_PRECOMP_KEY_NUM 3 - -static const uint8_t AES_CMAC_SEED[ICP_QAT_HW_AES_128_KEY_SZ]; - -static void aes_cmac_key_derive(uint8_t *base, uint8_t *derived) -{ - int i; - - derived[0] = base[0] << 1; - for (i = 1; i < ICP_QAT_HW_AES_BLK_SZ ; i++) { - derived[i] = base[i] << 1; - derived[i - 1] |= base[i] >> 7; - } - - if (base[0] & 0x80) - derived[ICP_QAT_HW_AES_BLK_SZ - 1] ^= QAT_AES_CMAC_CONST_RB; -} static int qat_sym_do_precomputes(enum icp_qat_hw_auth_algo hash_alg, const uint8_t *auth_key, @@ -1695,6 +2006,7 @@ int qat_sym_cd_auth_set(struct qat_sym_session *cdesc, uint32_t *aad_len = NULL; uint32_t wordIndex = 0; uint32_t *pTempKey; + int ret = 0; if (cdesc->qat_cmd == ICP_QAT_FW_LA_CMD_AUTH) { ICP_QAT_FW_COMN_CURR_ID_SET(hash_cd_ctrl, @@ -1766,9 +2078,22 @@ int qat_sym_cd_auth_set(struct qat_sym_session *cdesc, break; } /* SHA-1 HMAC */ - if (qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA1, authkey, - authkeylen, cdesc->cd_cur_ptr, &state1_size, - cdesc->aes_cmac)) { + if (qat_ipsec_mb_lib) { +#ifdef RTE_QAT_LIBIPSECMB + ret = qat_sym_do_precomputes_ipsec_mb(ICP_QAT_HW_AUTH_ALGO_SHA1, + authkey, authkeylen, cdesc->cd_cur_ptr, &state1_size, + cdesc->aes_cmac); +#else + QAT_LOG(ERR, "Intel IPSEC-MB LIB missing ?"); + return -EFAULT; +#endif + } else { + ret = qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA1, authkey, + authkeylen, cdesc->cd_cur_ptr, &state1_size, + cdesc->aes_cmac); + } + + if (ret) { QAT_LOG(ERR, "(SHA)precompute failed"); return -EFAULT; } @@ -1784,9 +2109,22 @@ int qat_sym_cd_auth_set(struct qat_sym_session *cdesc, break; } /* SHA-224 HMAC */ - if (qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA224, authkey, - authkeylen, cdesc->cd_cur_ptr, &state1_size, - cdesc->aes_cmac)) { + if (qat_ipsec_mb_lib) { +#ifdef RTE_QAT_LIBIPSECMB + ret = qat_sym_do_precomputes_ipsec_mb(ICP_QAT_HW_AUTH_ALGO_SHA224, + authkey, authkeylen, cdesc->cd_cur_ptr, &state1_size, + cdesc->aes_cmac); +#else + QAT_LOG(ERR, "Intel IPSEC-MB LIB missing ?"); + return -EFAULT; +#endif + } else { + ret = qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA224, authkey, + authkeylen, cdesc->cd_cur_ptr, &state1_size, + cdesc->aes_cmac); + } + + if (ret) { QAT_LOG(ERR, "(SHA)precompute failed"); return -EFAULT; } @@ -1802,9 +2140,22 @@ int qat_sym_cd_auth_set(struct qat_sym_session *cdesc, break; } /* SHA-256 HMAC */ - if (qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA256, authkey, - authkeylen, cdesc->cd_cur_ptr, &state1_size, - cdesc->aes_cmac)) { + if (qat_ipsec_mb_lib) { +#ifdef RTE_QAT_LIBIPSECMB + ret = qat_sym_do_precomputes_ipsec_mb(ICP_QAT_HW_AUTH_ALGO_SHA256, + authkey, authkeylen, cdesc->cd_cur_ptr, &state1_size, + cdesc->aes_cmac); +#else + QAT_LOG(ERR, "Intel IPSEC-MB LIB missing ?"); + return -EFAULT; +#endif + } else { + ret = qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA256, authkey, + authkeylen, cdesc->cd_cur_ptr, &state1_size, + cdesc->aes_cmac); + } + + if (ret) { QAT_LOG(ERR, "(SHA)precompute failed"); return -EFAULT; } @@ -1820,9 +2171,22 @@ int qat_sym_cd_auth_set(struct qat_sym_session *cdesc, break; } /* SHA-384 HMAC */ - if (qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA384, authkey, - authkeylen, cdesc->cd_cur_ptr, &state1_size, - cdesc->aes_cmac)) { + if (qat_ipsec_mb_lib) { +#ifdef RTE_QAT_LIBIPSECMB + ret = qat_sym_do_precomputes_ipsec_mb(ICP_QAT_HW_AUTH_ALGO_SHA384, + authkey, authkeylen, cdesc->cd_cur_ptr, &state1_size, + cdesc->aes_cmac); +#else + QAT_LOG(ERR, "Intel IPSEC-MB LIB missing ?"); + return -EFAULT; +#endif + } else { + ret = qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA384, authkey, + authkeylen, cdesc->cd_cur_ptr, &state1_size, + cdesc->aes_cmac); + } + + if (ret) { QAT_LOG(ERR, "(SHA)precompute failed"); return -EFAULT; } @@ -1838,9 +2202,22 @@ int qat_sym_cd_auth_set(struct qat_sym_session *cdesc, break; } /* SHA-512 HMAC */ - if (qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA512, authkey, - authkeylen, cdesc->cd_cur_ptr, &state1_size, - cdesc->aes_cmac)) { + if (qat_ipsec_mb_lib) { +#ifdef RTE_QAT_LIBIPSECMB + ret = qat_sym_do_precomputes_ipsec_mb(ICP_QAT_HW_AUTH_ALGO_SHA512, + authkey, authkeylen, cdesc->cd_cur_ptr, &state1_size, + cdesc->aes_cmac); +#else + QAT_LOG(ERR, "Intel IPSEC-MB LIB missing ?"); + return -EFAULT; +#endif + } else { + ret = qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA512, authkey, + authkeylen, cdesc->cd_cur_ptr, &state1_size, + cdesc->aes_cmac); + } + + if (ret) { QAT_LOG(ERR, "(SHA)precompute failed"); return -EFAULT; } @@ -1851,9 +2228,23 @@ int qat_sym_cd_auth_set(struct qat_sym_session *cdesc, if (cdesc->aes_cmac) memset(cdesc->cd_cur_ptr, 0, state1_size); - if (qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_AES_XCBC_MAC, - authkey, authkeylen, cdesc->cd_cur_ptr + state1_size, - &state2_size, cdesc->aes_cmac)) { + if (qat_ipsec_mb_lib) { +#ifdef RTE_QAT_LIBIPSECMB + ret = qat_sym_do_precomputes_ipsec_mb( + ICP_QAT_HW_AUTH_ALGO_AES_XCBC_MAC, + authkey, authkeylen, cdesc->cd_cur_ptr + state1_size, + &state2_size, cdesc->aes_cmac); +#else + QAT_LOG(ERR, "Intel IPSEC-MB LIB missing ?"); + return -EFAULT; +#endif + } else { + ret = qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_AES_XCBC_MAC, + authkey, authkeylen, cdesc->cd_cur_ptr + state1_size, + &state2_size, cdesc->aes_cmac); + } + + if (ret) { cdesc->aes_cmac ? QAT_LOG(ERR, "(CMAC)precompute failed") : QAT_LOG(ERR, @@ -1865,9 +2256,22 @@ int qat_sym_cd_auth_set(struct qat_sym_session *cdesc, case ICP_QAT_HW_AUTH_ALGO_GALOIS_64: cdesc->qat_proto_flag = QAT_CRYPTO_PROTO_FLAG_GCM; state1_size = ICP_QAT_HW_GALOIS_128_STATE1_SZ; - if (qat_sym_do_precomputes(cdesc->qat_hash_alg, authkey, - authkeylen, cdesc->cd_cur_ptr + state1_size, - &state2_size, cdesc->aes_cmac)) { + if (qat_ipsec_mb_lib) { +#ifdef RTE_QAT_LIBIPSECMB + ret = qat_sym_do_precomputes_ipsec_mb(cdesc->qat_hash_alg, authkey, + authkeylen, cdesc->cd_cur_ptr + state1_size, + &state2_size, cdesc->aes_cmac); +#else + QAT_LOG(ERR, "Intel IPSEC-MB LIB missing ?"); + return -EFAULT; +#endif + } else { + ret = qat_sym_do_precomputes(cdesc->qat_hash_alg, authkey, + authkeylen, cdesc->cd_cur_ptr + state1_size, + &state2_size, cdesc->aes_cmac); + } + + if (ret) { QAT_LOG(ERR, "(GCM)precompute failed"); return -EFAULT; } @@ -1923,9 +2327,22 @@ int qat_sym_cd_auth_set(struct qat_sym_session *cdesc, break; case ICP_QAT_HW_AUTH_ALGO_MD5: - if (qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_MD5, authkey, - authkeylen, cdesc->cd_cur_ptr, &state1_size, - cdesc->aes_cmac)) { + if (qat_ipsec_mb_lib) { +#ifdef RTE_QAT_LIBIPSECMB + ret = qat_sym_do_precomputes_ipsec_mb(ICP_QAT_HW_AUTH_ALGO_MD5, + authkey, authkeylen, cdesc->cd_cur_ptr, &state1_size, + cdesc->aes_cmac); +#else + QAT_LOG(ERR, "Intel IPSEC-MB LIB missing"); + return -EFAULT; +#endif + } else { + ret = qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_MD5, authkey, + authkeylen, cdesc->cd_cur_ptr, &state1_size, + cdesc->aes_cmac); + } + + if (ret) { QAT_LOG(ERR, "(MD5)precompute failed"); return -EFAULT; } -- 2.17.1 ^ permalink raw reply [flat|nested] 9+ messages in thread
* RE: [dpdk-dev v5] crypto/qat: use intel-ipsec-mb for partial hash & aes 2022-05-27 8:55 ` [dpdk-dev v5] " Kai Ji @ 2022-05-27 12:26 ` Zhang, Roy Fan 2022-05-30 10:21 ` [dpdk-dev v6] " Kai Ji 1 sibling, 0 replies; 9+ messages in thread From: Zhang, Roy Fan @ 2022-05-27 12:26 UTC (permalink / raw) To: Ji, Kai, dev; +Cc: Richardson, Bruce, gakhil > -----Original Message----- > From: Ji, Kai <kai.ji@intel.com> > Sent: Friday, May 27, 2022 9:55 AM > To: dev@dpdk.org > Cc: Zhang, Roy Fan <roy.fan.zhang@intel.com>; Richardson, Bruce > <bruce.richardson@intel.com>; gakhil@marvell.com; Ji, Kai <kai.ji@intel.com> > Subject: [dpdk-dev v5] crypto/qat: use intel-ipsec-mb for partial hash & aes > > Since openssl 3.0 now deprecates the low level API QAT required to > perform partial hash & aes operation when creating the session. This > patch add in qat_ipsec_mb_lib driver parameter to allow QAT PMD to > switch APIs between openssl and intel ipsec-mb library. > > Signed-off-by: Kai Ji <kai.ji@intel.com> > Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com> > [FAN: please keep the change log below the "---" line so it won't be captured by git and keep it in the commit log forever] > v5: > - fix of Intel IPSEC-MB lib version check > > v4: > - fix of memory leak in IMB_MGR > > v3: > - Add in qat_ipsec_mb_lib driver parameter > > v2: > - Add AES ECB job function for precompute > > --- > doc/guides/cryptodevs/qat.rst | 13 + > drivers/common/qat/meson.build | 13 + > drivers/common/qat/qat_device.c | 1 + > drivers/common/qat/qat_device.h | 1 + > drivers/crypto/qat/qat_sym.c | 3 + > drivers/crypto/qat/qat_sym_session.c | 503 > ++++++++++++++++++++++++--- > 6 files changed, 491 insertions(+), 43 deletions(-) > > diff --git a/doc/guides/cryptodevs/qat.rst b/doc/guides/cryptodevs/qat.rst > index 785e041324..d92409b77e 100644 > --- a/doc/guides/cryptodevs/qat.rst > +++ b/doc/guides/cryptodevs/qat.rst > @@ -287,6 +287,19 @@ by comma. When the same parameter is used more > than once first occurrence of the > is used. > Maximum threshold that can be set is 32. > > +Running QAT PMD with Intel IPSEC MB library for symmetric precomputes > function > +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ~~~~~~~~~~~~~~~~~~~~~ > + > +The QAT PMD use Openssl library for partial hash calculation in symmetirc > precomputes function by > +default, the following parameter is allow QAT PMD switch over to multi- > buffer job API if Intel > +IPSEC MB library installed on system. > + > +- qat_ipsec_mb_lib > + > +To use this feature the user must set the parameter on process start as a > device additional parameter:: > + > + -a 03:01.1,qat_ipsec_mb_lib=1 > + > > Device and driver naming > ~~~~~~~~~~~~~~~~~~~~~~~~ > diff --git a/drivers/common/qat/meson.build > b/drivers/common/qat/meson.build > index b7027f3164..245c0fbe61 100644 > --- a/drivers/common/qat/meson.build > +++ b/drivers/common/qat/meson.build > @@ -35,6 +35,19 @@ if qat_crypto and not libcrypto.found() > 'missing dependency, libcrypto') > endif > > +IMB_required_ver = '1.2.0' > +libipsecmb = cc.find_library('IPSec_MB', required: false) > +if libipsecmb.found() > + # version comes with quotes, so we split based on " and take the middle > + imb_ver = cc.get_define('IMB_VERSION_STR', > + prefix : '#include<intel-ipsec-mb.h>').split('"')[1] > + > + if (imb_ver.version_compare('>=' + IMB_required_ver)) > + ext_deps += libipsecmb > + dpdk_conf.set('RTE_QAT_LIBIPSECMB', true) > + endif > +endif > + > # The driver should not build if both compression and crypto are disabled > #FIXME common code depends on compression files so check only > compress! > if not qat_compress # and not qat_crypto > diff --git a/drivers/common/qat/qat_device.c > b/drivers/common/qat/qat_device.c > index 6824d97050..db4b087d2b 100644 > --- a/drivers/common/qat/qat_device.c > +++ b/drivers/common/qat/qat_device.c > @@ -364,6 +364,7 @@ static int qat_pci_probe(struct rte_pci_driver > *pci_drv __rte_unused, > struct qat_pci_device *qat_pci_dev; > struct qat_dev_hw_spec_funcs *ops_hw; > struct qat_dev_cmd_param qat_dev_cmd_param[] = { > + { QAT_IPSEC_MB_LIB, 0 }, > { SYM_ENQ_THRESHOLD_NAME, 0 }, > { ASYM_ENQ_THRESHOLD_NAME, 0 }, > { COMP_ENQ_THRESHOLD_NAME, 0 }, > diff --git a/drivers/common/qat/qat_device.h > b/drivers/common/qat/qat_device.h > index 85fae7b7c7..e1a32a7e87 100644 > --- a/drivers/common/qat/qat_device.h > +++ b/drivers/common/qat/qat_device.h > @@ -16,6 +16,7 @@ > > #define QAT_DEV_NAME_MAX_LEN 64 > > +#define QAT_IPSEC_MB_LIB "qat_ipsec_mb_lib" > #define SYM_ENQ_THRESHOLD_NAME "qat_sym_enq_threshold" > #define ASYM_ENQ_THRESHOLD_NAME "qat_asym_enq_threshold" > #define COMP_ENQ_THRESHOLD_NAME "qat_comp_enq_threshold" > diff --git a/drivers/crypto/qat/qat_sym.c b/drivers/crypto/qat/qat_sym.c > index ca8c9a8124..3477cd89ad 100644 > --- a/drivers/crypto/qat/qat_sym.c > +++ b/drivers/crypto/qat/qat_sym.c > @@ -15,6 +15,7 @@ > #include "qat_qp.h" > > uint8_t qat_sym_driver_id; > +int qat_ipsec_mb_lib; > > struct qat_crypto_gen_dev_ops qat_sym_gen_dev_ops[QAT_N_GENS]; > > @@ -307,6 +308,8 @@ qat_sym_dev_create(struct qat_pci_device > *qat_pci_dev, > if (!strcmp(qat_dev_cmd_param[i].name, > SYM_ENQ_THRESHOLD_NAME)) > internals->min_enq_burst_threshold = > qat_dev_cmd_param[i].val; > + if (!strcmp(qat_dev_cmd_param[i].name, > QAT_IPSEC_MB_LIB)) > + qat_ipsec_mb_lib = qat_dev_cmd_param[i].val; > i++; > } > > diff --git a/drivers/crypto/qat/qat_sym_session.c > b/drivers/crypto/qat/qat_sym_session.c > index 9d6a19c0be..69a97948f5 100644 > --- a/drivers/crypto/qat/qat_sym_session.c > +++ b/drivers/crypto/qat/qat_sym_session.c > @@ -7,6 +7,10 @@ > #include <openssl/md5.h> /* Needed to calculate pre-compute values > */ > #include <openssl/evp.h> /* Needed for bpi runt block processing */ > > +#ifdef RTE_QAT_LIBIPSECMB > +#include <intel-ipsec-mb.h> > +#endif > + > #include <rte_memcpy.h> > #include <rte_common.h> > #include <rte_spinlock.h> > @@ -22,6 +26,12 @@ > #include "qat_sym_session.h" > #include "qat_sym.h" > > +#if (OPENSSL_VERSION_NUMBER >= 0x30000000L) > +#include <openssl/provider.h> > +#endif > + > +extern int qat_ipsec_mb_lib; > + > /* SHA1 - 20 bytes - Initialiser state can be found in FIPS stds 180-2 */ > static const uint8_t sha1InitialState[] = { > 0x67, 0x45, 0x23, 0x01, 0xef, 0xcd, 0xab, 0x89, 0x98, 0xba, > @@ -470,6 +480,21 @@ qat_sym_session_configure(struct rte_cryptodev > *dev, > return -ENOMEM; > } > > +#if (OPENSSL_VERSION_NUMBER >= 0x30000000L) > + OSSL_PROVIDER * legacy; > + OSSL_PROVIDER *deflt; > + > + /* Load Multiple providers into the default (NULL) library context */ > + legacy = OSSL_PROVIDER_load(NULL, "legacy"); > + if (legacy == NULL) > + return -EINVAL; > + > + deflt = OSSL_PROVIDER_load(NULL, "default"); > + if (deflt == NULL) { > + OSSL_PROVIDER_unload(legacy); > + return -EINVAL; > + } > +#endif > ret = qat_sym_session_set_parameters(dev, xform, > sess_private_data); > if (ret != 0) { > QAT_LOG(ERR, > @@ -483,6 +508,10 @@ qat_sym_session_configure(struct rte_cryptodev > *dev, > set_sym_session_private_data(sess, dev->driver_id, > sess_private_data); > > +# if (OPENSSL_VERSION_NUMBER >= 0x30000000L) > + OSSL_PROVIDER_unload(legacy); > + OSSL_PROVIDER_unload(deflt); > +# endif > return 0; > } > > @@ -1057,6 +1086,293 @@ static int qat_hash_get_block_size(enum > icp_qat_hw_auth_algo qat_hash_alg) > return -EFAULT; > } > > +#define HMAC_IPAD_VALUE 0x36 > +#define HMAC_OPAD_VALUE 0x5c > +#define HASH_XCBC_PRECOMP_KEY_NUM 3 > + > +static const uint8_t AES_CMAC_SEED[ICP_QAT_HW_AES_128_KEY_SZ]; > + > +#ifdef RTE_QAT_LIBIPSECMB > +static int aes_ipsecmb_job(uint8_t *in, uint8_t *out, IMB_MGR *m, > + const uint8_t *key, uint16_t auth_keylen) > +{ > + int err; > + struct IMB_JOB *job; > + DECLARE_ALIGNED(uint32_t expkey[4*15], 16); > + DECLARE_ALIGNED(uint32_t dust[4*15], 16); > + > + if (auth_keylen == ICP_QAT_HW_AES_128_KEY_SZ) > + IMB_AES_KEYEXP_128(m, key, expkey, dust); > + else if (auth_keylen == ICP_QAT_HW_AES_192_KEY_SZ) > + IMB_AES_KEYEXP_192(m, key, expkey, dust); > + else if (auth_keylen == ICP_QAT_HW_AES_256_KEY_SZ) > + IMB_AES_KEYEXP_256(m, key, expkey, dust); > + else > + return -EFAULT; > + > + job = IMB_GET_NEXT_JOB(m); > + > + job->src = in; > + job->dst = out; > + job->enc_keys = expkey; > + job->key_len_in_bytes = auth_keylen; > + job->msg_len_to_cipher_in_bytes = 16; > + job->iv_len_in_bytes = 0; > + job->cipher_direction = IMB_DIR_ENCRYPT; > + job->cipher_mode = IMB_CIPHER_ECB; > + job->hash_alg = IMB_AUTH_NULL; > + > + while (IMB_FLUSH_JOB(m) != NULL) > + ; > + > + job = IMB_SUBMIT_JOB(m); > + if (job) { > + if (job->status == IMB_STATUS_COMPLETED) > + return 0; > + } > + > + err = imb_get_errno(m); > + if (err) > + QAT_LOG(ERR, "Error: %s!\n", imb_get_strerror(err)); > + > + return -EFAULT; > +} > + > +static int > +partial_hash_compute_ipsec_mb(enum icp_qat_hw_auth_algo hash_alg, > + uint8_t *data_in, uint8_t *data_out, IMB_MGR *m) > +{ > + int digest_size; > + uint8_t digest[qat_hash_get_digest_size( > + ICP_QAT_HW_AUTH_ALGO_DELIMITER)]; > + uint32_t *hash_state_out_be32; > + uint64_t *hash_state_out_be64; > + int i; > + > + /* Initialize to avoid gcc warning */ > + memset(digest, 0, sizeof(digest)); > + > + digest_size = qat_hash_get_digest_size(hash_alg); > + if (digest_size <= 0) > + return -EFAULT; > + > + hash_state_out_be32 = (uint32_t *)data_out; > + hash_state_out_be64 = (uint64_t *)data_out; > + > + switch (hash_alg) { > + case ICP_QAT_HW_AUTH_ALGO_SHA1: > + IMB_SHA1_ONE_BLOCK(m, data_in, digest); > + for (i = 0; i < digest_size >> 2; i++, hash_state_out_be32++) > + *hash_state_out_be32 = > + rte_bswap32(*(((uint32_t *)digest)+i)); > + break; > + case ICP_QAT_HW_AUTH_ALGO_SHA224: > + IMB_SHA224_ONE_BLOCK(m, data_in, digest); > + for (i = 0; i < digest_size >> 2; i++, hash_state_out_be32++) > + *hash_state_out_be32 = > + rte_bswap32(*(((uint32_t *)digest)+i)); > + break; > + case ICP_QAT_HW_AUTH_ALGO_SHA256: > + IMB_SHA256_ONE_BLOCK(m, data_in, digest); > + for (i = 0; i < digest_size >> 2; i++, hash_state_out_be32++) > + *hash_state_out_be32 = > + rte_bswap32(*(((uint32_t *)digest)+i)); > + break; > + case ICP_QAT_HW_AUTH_ALGO_SHA384: > + IMB_SHA384_ONE_BLOCK(m, data_in, digest); > + for (i = 0; i < digest_size >> 3; i++, hash_state_out_be64++) > + *hash_state_out_be64 = > + rte_bswap64(*(((uint64_t *)digest)+i)); > + break; > + case ICP_QAT_HW_AUTH_ALGO_SHA512: > + IMB_SHA512_ONE_BLOCK(m, data_in, digest); > + for (i = 0; i < digest_size >> 3; i++, hash_state_out_be64++) > + *hash_state_out_be64 = > + rte_bswap64(*(((uint64_t *)digest)+i)); > + break; > + case ICP_QAT_HW_AUTH_ALGO_MD5: > + IMB_MD5_ONE_BLOCK(m, data_in, data_out); > + break; > + default: > + QAT_LOG(ERR, "invalid hash alg %u", hash_alg); > + return -EFAULT; > + } > + > + return 0; > +} > + > +static int qat_sym_do_precomputes_ipsec_mb(enum > icp_qat_hw_auth_algo hash_alg, > + const uint8_t *auth_key, > + uint16_t auth_keylen, > + uint8_t *p_state_buf, > + uint16_t *p_state_len, > + uint8_t aes_cmac) > +{ > + int block_size; > + uint8_t > ipad[qat_hash_get_block_size(ICP_QAT_HW_AUTH_ALGO_DELIMITER)]; > + uint8_t > opad[qat_hash_get_block_size(ICP_QAT_HW_AUTH_ALGO_DELIMITER)]; > + int i, ret = 0; > + > + IMB_MGR *m; > + m = alloc_mb_mgr(0); > + if (m == NULL) > + return -ENOMEM; > + > + init_mb_mgr_auto(m, NULL); > + > + if (hash_alg == ICP_QAT_HW_AUTH_ALGO_AES_XCBC_MAC) { > + > + /* CMAC */ > + if (aes_cmac) { > + uint8_t *in = NULL; > + uint8_t k0[ICP_QAT_HW_AES_128_KEY_SZ]; > + uint8_t *k1, *k2; > + > + auth_keylen = ICP_QAT_HW_AES_128_KEY_SZ; > + > + in = rte_zmalloc("AES CMAC K1", > + ICP_QAT_HW_AES_128_KEY_SZ, 16); [FAN: other than "in" is allocated and copied 16 bytes of seed, I don't see it is used anywhere other than freed later. Any reason we need it?] > + > + if (in == NULL) { > + QAT_LOG(ERR, "Failed to alloc memory"); > + return -ENOMEM; > + } > + > + rte_memcpy(in, AES_CMAC_SEED, > + ICP_QAT_HW_AES_128_KEY_SZ); > + rte_memcpy(p_state_buf, auth_key, auth_keylen); > + > + DECLARE_ALIGNED(uint32_t expkey[4*15], 16); > + DECLARE_ALIGNED(uint32_t dust[4*15], 16); > + IMB_AES_KEYEXP_128(m, p_state_buf, expkey, > dust); > + k1 = p_state_buf + > ICP_QAT_HW_AES_XCBC_MAC_STATE1_SZ; > + k2 = k1 + ICP_QAT_HW_AES_XCBC_MAC_STATE1_SZ; > + > + IMB_AES_CMAC_SUBKEY_GEN_128(m, expkey, k1, > k2); > + memset(k0, 0, ICP_QAT_HW_AES_128_KEY_SZ); > + *p_state_len = > ICP_QAT_HW_AES_XCBC_MAC_STATE2_SZ; [FAN: if we initialize block_size as 0, we can simply set ret = 0 and jump to out here] > + rte_free(in); > + free_mb_mgr(m); > + return 0; > + } > + > + static uint8_t qat_aes_xcbc_key_seed[ > + ICP_QAT_HW_AES_XCBC_MAC_STATE2_SZ] > = { > + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, > + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, > + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, > + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, > + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, > + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, > + }; > + > + uint8_t *in = NULL; > + uint8_t *out = p_state_buf; > + int x; > + > + in = rte_zmalloc("working mem for key", > + ICP_QAT_HW_AES_XCBC_MAC_STATE2_SZ, > 16); > + if (in == NULL) { > + QAT_LOG(ERR, "Failed to alloc memory"); > + return -ENOMEM; > + } > + > + rte_memcpy(in, qat_aes_xcbc_key_seed, > + ICP_QAT_HW_AES_XCBC_MAC_STATE2_SZ); > + for (x = 0; x < HASH_XCBC_PRECOMP_KEY_NUM; x++) { > + if (aes_ipsecmb_job(in, out, m, auth_key, > auth_keylen)) { > + rte_free(in - > + (x * > ICP_QAT_HW_AES_XCBC_MAC_KEY_SZ)); > + memset(out - > + (x * > ICP_QAT_HW_AES_XCBC_MAC_KEY_SZ), > + 0, > ICP_QAT_HW_AES_XCBC_MAC_STATE2_SZ); > + return -EFAULT; > + } > + > + in += ICP_QAT_HW_AES_XCBC_MAC_KEY_SZ; > + out += ICP_QAT_HW_AES_XCBC_MAC_KEY_SZ; > + } > + *p_state_len = ICP_QAT_HW_AES_XCBC_MAC_STATE2_SZ; > + rte_free(in - x*ICP_QAT_HW_AES_XCBC_MAC_KEY_SZ); > + free_mb_mgr(m); > + return 0; > + > + } else if ((hash_alg == ICP_QAT_HW_AUTH_ALGO_GALOIS_128) || > + (hash_alg == ICP_QAT_HW_AUTH_ALGO_GALOIS_64)) { > + uint8_t *in = NULL; > + uint8_t *out = p_state_buf; [FAN: doesn't feel we have to allocate "in" at all, why can't we declare in as an array?] > + > + memset(p_state_buf, 0, ICP_QAT_HW_GALOIS_H_SZ + > + ICP_QAT_HW_GALOIS_LEN_A_SZ + > + ICP_QAT_HW_GALOIS_E_CTR0_SZ); > + in = rte_zmalloc("working mem for key", > + ICP_QAT_HW_GALOIS_H_SZ, 16); > + if (in == NULL) { > + QAT_LOG(ERR, "Failed to alloc memory"); > + return -ENOMEM; > + } > + > + memset(in, 0, ICP_QAT_HW_GALOIS_H_SZ); > + if (aes_ipsecmb_job(in, out, m, auth_key, auth_keylen)) > + return -EFAULT; > + > + *p_state_len = ICP_QAT_HW_GALOIS_H_SZ + > + ICP_QAT_HW_GALOIS_LEN_A_SZ + > + ICP_QAT_HW_GALOIS_E_CTR0_SZ; > + rte_free(in); [FAN: if we initialize block_size as 0, we can simply set ret = 0 and jump to out here] > + free_mb_mgr(m); > + return 0; > + } > + > + block_size = qat_hash_get_block_size(hash_alg); > + if (block_size < 0) > + return block_size; > + /* init ipad and opad from key and xor with fixed values */ > + memset(ipad, 0, block_size); > + memset(opad, 0, block_size); > + > + if (auth_keylen > (unsigned int)block_size) { > + QAT_LOG(ERR, "invalid keylen %u", auth_keylen); > + free_mb_mgr(m); > + return -EFAULT; > + } > + rte_memcpy(ipad, auth_key, auth_keylen); > + rte_memcpy(opad, auth_key, auth_keylen); > + > + for (i = 0; i < block_size; i++) { > + uint8_t *ipad_ptr = ipad + i; > + uint8_t *opad_ptr = opad + i; > + *ipad_ptr ^= HMAC_IPAD_VALUE; > + *opad_ptr ^= HMAC_OPAD_VALUE; > + } > + > + /* do partial hash of ipad and copy to state1 */ > + if (partial_hash_compute_ipsec_mb(hash_alg, ipad, p_state_buf, m)) > { > + QAT_LOG(ERR, "ipad precompute failed"); > + ret = -EFAULT; > + goto out; > + } > + > + /* > + * State len is a multiple of 8, so may be larger than the digest. > + * Put the partial hash of opad state_len bytes after state1 > + */ > + *p_state_len = qat_hash_get_state1_size(hash_alg); > + if (partial_hash_compute_ipsec_mb(hash_alg, opad, > + p_state_buf + *p_state_len, m)) { > + QAT_LOG(ERR, "opad precompute failed"); > + ret = -EFAULT; > + goto out; > + } > + > +out: > + /* don't leave data lying around */ > + memset(ipad, 0, block_size); > + memset(opad, 0, block_size); > + free_mb_mgr(m); > + return ret; > +} > +#endif > static int partial_hash_sha1(uint8_t *data_in, uint8_t *data_out) > { > SHA_CTX ctx; > @@ -1124,6 +1440,20 @@ static int partial_hash_md5(uint8_t *data_in, > uint8_t *data_out) > return 0; > } > > +static void aes_cmac_key_derive(uint8_t *base, uint8_t *derived) > +{ > + int i; > + > + derived[0] = base[0] << 1; > + for (i = 1; i < ICP_QAT_HW_AES_BLK_SZ ; i++) { > + derived[i] = base[i] << 1; > + derived[i - 1] |= base[i] >> 7; > + } > + > + if (base[0] & 0x80) > + derived[ICP_QAT_HW_AES_BLK_SZ - 1] ^= > QAT_AES_CMAC_CONST_RB; > +} > + > static int > partial_hash_compute(enum icp_qat_hw_auth_algo hash_alg, > uint8_t *data_in, uint8_t *data_out) > @@ -1192,25 +1522,6 @@ partial_hash_compute(enum > icp_qat_hw_auth_algo hash_alg, > > return 0; > } > -#define HMAC_IPAD_VALUE 0x36 > -#define HMAC_OPAD_VALUE 0x5c > -#define HASH_XCBC_PRECOMP_KEY_NUM 3 > - > -static const uint8_t AES_CMAC_SEED[ICP_QAT_HW_AES_128_KEY_SZ]; > - > -static void aes_cmac_key_derive(uint8_t *base, uint8_t *derived) > -{ > - int i; > - > - derived[0] = base[0] << 1; > - for (i = 1; i < ICP_QAT_HW_AES_BLK_SZ ; i++) { > - derived[i] = base[i] << 1; > - derived[i - 1] |= base[i] >> 7; > - } > - > - if (base[0] & 0x80) > - derived[ICP_QAT_HW_AES_BLK_SZ - 1] ^= > QAT_AES_CMAC_CONST_RB; > -} > > static int qat_sym_do_precomputes(enum icp_qat_hw_auth_algo hash_alg, > const uint8_t *auth_key, > @@ -1695,6 +2006,7 @@ int qat_sym_cd_auth_set(struct qat_sym_session > *cdesc, > uint32_t *aad_len = NULL; > uint32_t wordIndex = 0; > uint32_t *pTempKey; > + int ret = 0; > > if (cdesc->qat_cmd == ICP_QAT_FW_LA_CMD_AUTH) { > ICP_QAT_FW_COMN_CURR_ID_SET(hash_cd_ctrl, > @@ -1766,9 +2078,22 @@ int qat_sym_cd_auth_set(struct qat_sym_session > *cdesc, > break; > } > /* SHA-1 HMAC */ > - if > (qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA1, authkey, > - authkeylen, cdesc->cd_cur_ptr, &state1_size, > - cdesc->aes_cmac)) { > + if (qat_ipsec_mb_lib) { > +#ifdef RTE_QAT_LIBIPSECMB > + ret = > qat_sym_do_precomputes_ipsec_mb(ICP_QAT_HW_AUTH_ALGO_SHA1, > + authkey, authkeylen, cdesc->cd_cur_ptr, > &state1_size, > + cdesc->aes_cmac); > +#else > + QAT_LOG(ERR, "Intel IPSEC-MB LIB missing ?"); > + return -EFAULT; > +#endif > + } else { > + ret = > qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA1, authkey, > + authkeylen, cdesc->cd_cur_ptr, &state1_size, > + cdesc->aes_cmac); > + } > + > + if (ret) { > QAT_LOG(ERR, "(SHA)precompute failed"); > return -EFAULT; > } > @@ -1784,9 +2109,22 @@ int qat_sym_cd_auth_set(struct qat_sym_session > *cdesc, > break; > } > /* SHA-224 HMAC */ > - if > (qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA224, authkey, > - authkeylen, cdesc->cd_cur_ptr, &state1_size, > - cdesc->aes_cmac)) { > + if (qat_ipsec_mb_lib) { > +#ifdef RTE_QAT_LIBIPSECMB > + ret = > qat_sym_do_precomputes_ipsec_mb(ICP_QAT_HW_AUTH_ALGO_SHA224, > + authkey, authkeylen, cdesc->cd_cur_ptr, > &state1_size, > + cdesc->aes_cmac); > +#else > + QAT_LOG(ERR, "Intel IPSEC-MB LIB missing ?"); > + return -EFAULT; > +#endif > + } else { > + ret = > qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA224, authkey, > + authkeylen, cdesc->cd_cur_ptr, &state1_size, > + cdesc->aes_cmac); > + } > + > + if (ret) { > QAT_LOG(ERR, "(SHA)precompute failed"); > return -EFAULT; > } > @@ -1802,9 +2140,22 @@ int qat_sym_cd_auth_set(struct qat_sym_session > *cdesc, > break; > } > /* SHA-256 HMAC */ > - if > (qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA256, authkey, > - authkeylen, cdesc->cd_cur_ptr, &state1_size, > - cdesc->aes_cmac)) { > + if (qat_ipsec_mb_lib) { > +#ifdef RTE_QAT_LIBIPSECMB > + ret = > qat_sym_do_precomputes_ipsec_mb(ICP_QAT_HW_AUTH_ALGO_SHA256, > + authkey, authkeylen, cdesc->cd_cur_ptr, > &state1_size, > + cdesc->aes_cmac); > +#else > + QAT_LOG(ERR, "Intel IPSEC-MB LIB missing ?"); > + return -EFAULT; > +#endif > + } else { > + ret = > qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA256, authkey, > + authkeylen, cdesc->cd_cur_ptr, &state1_size, > + cdesc->aes_cmac); > + } > + > + if (ret) { > QAT_LOG(ERR, "(SHA)precompute failed"); > return -EFAULT; > } > @@ -1820,9 +2171,22 @@ int qat_sym_cd_auth_set(struct qat_sym_session > *cdesc, > break; > } > /* SHA-384 HMAC */ > - if > (qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA384, authkey, > - authkeylen, cdesc->cd_cur_ptr, &state1_size, > - cdesc->aes_cmac)) { > + if (qat_ipsec_mb_lib) { > +#ifdef RTE_QAT_LIBIPSECMB > + ret = > qat_sym_do_precomputes_ipsec_mb(ICP_QAT_HW_AUTH_ALGO_SHA384, > + authkey, authkeylen, cdesc->cd_cur_ptr, > &state1_size, > + cdesc->aes_cmac); > +#else > + QAT_LOG(ERR, "Intel IPSEC-MB LIB missing ?"); > + return -EFAULT; > +#endif > + } else { > + ret = > qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA384, authkey, > + authkeylen, cdesc->cd_cur_ptr, &state1_size, > + cdesc->aes_cmac); > + } > + > + if (ret) { > QAT_LOG(ERR, "(SHA)precompute failed"); > return -EFAULT; > } > @@ -1838,9 +2202,22 @@ int qat_sym_cd_auth_set(struct qat_sym_session > *cdesc, > break; > } > /* SHA-512 HMAC */ > - if > (qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA512, authkey, > - authkeylen, cdesc->cd_cur_ptr, &state1_size, > - cdesc->aes_cmac)) { > + if (qat_ipsec_mb_lib) { > +#ifdef RTE_QAT_LIBIPSECMB > + ret = > qat_sym_do_precomputes_ipsec_mb(ICP_QAT_HW_AUTH_ALGO_SHA512, > + authkey, authkeylen, cdesc->cd_cur_ptr, > &state1_size, > + cdesc->aes_cmac); > +#else > + QAT_LOG(ERR, "Intel IPSEC-MB LIB missing ?"); > + return -EFAULT; > +#endif > + } else { > + ret = > qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA512, authkey, > + authkeylen, cdesc->cd_cur_ptr, &state1_size, > + cdesc->aes_cmac); > + } > + > + if (ret) { > QAT_LOG(ERR, "(SHA)precompute failed"); > return -EFAULT; > } > @@ -1851,9 +2228,23 @@ int qat_sym_cd_auth_set(struct qat_sym_session > *cdesc, > > if (cdesc->aes_cmac) > memset(cdesc->cd_cur_ptr, 0, state1_size); > - if > (qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_AES_XCBC_MAC, > - authkey, authkeylen, cdesc->cd_cur_ptr + > state1_size, > - &state2_size, cdesc->aes_cmac)) { > + if (qat_ipsec_mb_lib) { > +#ifdef RTE_QAT_LIBIPSECMB > + ret = qat_sym_do_precomputes_ipsec_mb( > + > ICP_QAT_HW_AUTH_ALGO_AES_XCBC_MAC, > + authkey, authkeylen, cdesc->cd_cur_ptr + > state1_size, > + &state2_size, cdesc->aes_cmac); > +#else > + QAT_LOG(ERR, "Intel IPSEC-MB LIB missing ?"); > + return -EFAULT; > +#endif > + } else { > + ret = > qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_AES_XCBC_MAC, > + authkey, authkeylen, cdesc->cd_cur_ptr + > state1_size, > + &state2_size, cdesc->aes_cmac); > + } > + > + if (ret) { > cdesc->aes_cmac ? QAT_LOG(ERR, > "(CMAC)precompute failed") > : QAT_LOG(ERR, > @@ -1865,9 +2256,22 @@ int qat_sym_cd_auth_set(struct qat_sym_session > *cdesc, > case ICP_QAT_HW_AUTH_ALGO_GALOIS_64: > cdesc->qat_proto_flag = QAT_CRYPTO_PROTO_FLAG_GCM; > state1_size = ICP_QAT_HW_GALOIS_128_STATE1_SZ; > - if (qat_sym_do_precomputes(cdesc->qat_hash_alg, authkey, > - authkeylen, cdesc->cd_cur_ptr + state1_size, > - &state2_size, cdesc->aes_cmac)) { > + if (qat_ipsec_mb_lib) { > +#ifdef RTE_QAT_LIBIPSECMB > + ret = qat_sym_do_precomputes_ipsec_mb(cdesc- > >qat_hash_alg, authkey, > + authkeylen, cdesc->cd_cur_ptr + state1_size, > + &state2_size, cdesc->aes_cmac); > +#else > + QAT_LOG(ERR, "Intel IPSEC-MB LIB missing ?"); > + return -EFAULT; > +#endif > + } else { > + ret = qat_sym_do_precomputes(cdesc- > >qat_hash_alg, authkey, > + authkeylen, cdesc->cd_cur_ptr + state1_size, > + &state2_size, cdesc->aes_cmac); > + } > + > + if (ret) { > QAT_LOG(ERR, "(GCM)precompute failed"); > return -EFAULT; > } > @@ -1923,9 +2327,22 @@ int qat_sym_cd_auth_set(struct qat_sym_session > *cdesc, > > break; > case ICP_QAT_HW_AUTH_ALGO_MD5: > - if > (qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_MD5, authkey, > - authkeylen, cdesc->cd_cur_ptr, &state1_size, > - cdesc->aes_cmac)) { > + if (qat_ipsec_mb_lib) { > +#ifdef RTE_QAT_LIBIPSECMB > + ret = > qat_sym_do_precomputes_ipsec_mb(ICP_QAT_HW_AUTH_ALGO_MD5, > + authkey, authkeylen, cdesc->cd_cur_ptr, > &state1_size, > + cdesc->aes_cmac); > +#else > + QAT_LOG(ERR, "Intel IPSEC-MB LIB missing"); > + return -EFAULT; > +#endif > + } else { > + ret = > qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_MD5, authkey, > + authkeylen, cdesc->cd_cur_ptr, &state1_size, > + cdesc->aes_cmac); > + } > + > + if (ret) { > QAT_LOG(ERR, "(MD5)precompute failed"); > return -EFAULT; > } > -- > 2.17.1 ^ permalink raw reply [flat|nested] 9+ messages in thread
* [dpdk-dev v6] crypto/qat: use intel-ipsec-mb for partial hash & aes 2022-05-27 8:55 ` [dpdk-dev v5] " Kai Ji 2022-05-27 12:26 ` Zhang, Roy Fan @ 2022-05-30 10:21 ` Kai Ji 2022-06-13 17:02 ` [dpdk-dev v7] " Kai Ji 1 sibling, 1 reply; 9+ messages in thread From: Kai Ji @ 2022-05-30 10:21 UTC (permalink / raw) To: dev; +Cc: roy.fan.zhang, bruce.richardson, gakhil, Kai Ji Since openssl 3.0 now deprecates the low level API QAT required to perform partial hash & aes operation when creating the session. This patch add in qat_ipsec_mb_lib driver parameter to allow QAT PMD to switch APIs between openssl and intel ipsec-mb library. Signed-off-by: Kai Ji <kai.ji@intel.com> Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com> --- v6: - code review comments resolution v5: - fix of Intel IPSEC-MB lib version check v4: - fix of memory leak in IMB_MGR v3: - Add in qat_ipsec_mb_lib driver parameter v2: - Add AES ECB job function for precompute --- doc/guides/cryptodevs/qat.rst | 13 + drivers/common/qat/meson.build | 13 + drivers/common/qat/qat_device.c | 1 + drivers/common/qat/qat_device.h | 1 + drivers/crypto/qat/qat_sym.c | 3 + drivers/crypto/qat/qat_sym_session.c | 468 ++++++++++++++++++++++++--- 6 files changed, 456 insertions(+), 43 deletions(-) diff --git a/doc/guides/cryptodevs/qat.rst b/doc/guides/cryptodevs/qat.rst index 785e041324..d92409b77e 100644 --- a/doc/guides/cryptodevs/qat.rst +++ b/doc/guides/cryptodevs/qat.rst @@ -287,6 +287,19 @@ by comma. When the same parameter is used more than once first occurrence of the is used. Maximum threshold that can be set is 32. +Running QAT PMD with Intel IPSEC MB library for symmetric precomputes function +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The QAT PMD use Openssl library for partial hash calculation in symmetirc precomputes function by +default, the following parameter is allow QAT PMD switch over to multi-buffer job API if Intel +IPSEC MB library installed on system. + +- qat_ipsec_mb_lib + +To use this feature the user must set the parameter on process start as a device additional parameter:: + + -a 03:01.1,qat_ipsec_mb_lib=1 + Device and driver naming ~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/drivers/common/qat/meson.build b/drivers/common/qat/meson.build index b7027f3164..245c0fbe61 100644 --- a/drivers/common/qat/meson.build +++ b/drivers/common/qat/meson.build @@ -35,6 +35,19 @@ if qat_crypto and not libcrypto.found() 'missing dependency, libcrypto') endif +IMB_required_ver = '1.2.0' +libipsecmb = cc.find_library('IPSec_MB', required: false) +if libipsecmb.found() + # version comes with quotes, so we split based on " and take the middle + imb_ver = cc.get_define('IMB_VERSION_STR', + prefix : '#include<intel-ipsec-mb.h>').split('"')[1] + + if (imb_ver.version_compare('>=' + IMB_required_ver)) + ext_deps += libipsecmb + dpdk_conf.set('RTE_QAT_LIBIPSECMB', true) + endif +endif + # The driver should not build if both compression and crypto are disabled #FIXME common code depends on compression files so check only compress! if not qat_compress # and not qat_crypto diff --git a/drivers/common/qat/qat_device.c b/drivers/common/qat/qat_device.c index 6824d97050..db4b087d2b 100644 --- a/drivers/common/qat/qat_device.c +++ b/drivers/common/qat/qat_device.c @@ -364,6 +364,7 @@ static int qat_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, struct qat_pci_device *qat_pci_dev; struct qat_dev_hw_spec_funcs *ops_hw; struct qat_dev_cmd_param qat_dev_cmd_param[] = { + { QAT_IPSEC_MB_LIB, 0 }, { SYM_ENQ_THRESHOLD_NAME, 0 }, { ASYM_ENQ_THRESHOLD_NAME, 0 }, { COMP_ENQ_THRESHOLD_NAME, 0 }, diff --git a/drivers/common/qat/qat_device.h b/drivers/common/qat/qat_device.h index 85fae7b7c7..e1a32a7e87 100644 --- a/drivers/common/qat/qat_device.h +++ b/drivers/common/qat/qat_device.h @@ -16,6 +16,7 @@ #define QAT_DEV_NAME_MAX_LEN 64 +#define QAT_IPSEC_MB_LIB "qat_ipsec_mb_lib" #define SYM_ENQ_THRESHOLD_NAME "qat_sym_enq_threshold" #define ASYM_ENQ_THRESHOLD_NAME "qat_asym_enq_threshold" #define COMP_ENQ_THRESHOLD_NAME "qat_comp_enq_threshold" diff --git a/drivers/crypto/qat/qat_sym.c b/drivers/crypto/qat/qat_sym.c index ca8c9a8124..3477cd89ad 100644 --- a/drivers/crypto/qat/qat_sym.c +++ b/drivers/crypto/qat/qat_sym.c @@ -15,6 +15,7 @@ #include "qat_qp.h" uint8_t qat_sym_driver_id; +int qat_ipsec_mb_lib; struct qat_crypto_gen_dev_ops qat_sym_gen_dev_ops[QAT_N_GENS]; @@ -307,6 +308,8 @@ qat_sym_dev_create(struct qat_pci_device *qat_pci_dev, if (!strcmp(qat_dev_cmd_param[i].name, SYM_ENQ_THRESHOLD_NAME)) internals->min_enq_burst_threshold = qat_dev_cmd_param[i].val; + if (!strcmp(qat_dev_cmd_param[i].name, QAT_IPSEC_MB_LIB)) + qat_ipsec_mb_lib = qat_dev_cmd_param[i].val; i++; } diff --git a/drivers/crypto/qat/qat_sym_session.c b/drivers/crypto/qat/qat_sym_session.c index 9d6a19c0be..960c387ca2 100644 --- a/drivers/crypto/qat/qat_sym_session.c +++ b/drivers/crypto/qat/qat_sym_session.c @@ -7,6 +7,10 @@ #include <openssl/md5.h> /* Needed to calculate pre-compute values */ #include <openssl/evp.h> /* Needed for bpi runt block processing */ +#ifdef RTE_QAT_LIBIPSECMB +#include <intel-ipsec-mb.h> +#endif + #include <rte_memcpy.h> #include <rte_common.h> #include <rte_spinlock.h> @@ -22,6 +26,12 @@ #include "qat_sym_session.h" #include "qat_sym.h" +#if (OPENSSL_VERSION_NUMBER >= 0x30000000L) +#include <openssl/provider.h> +#endif + +extern int qat_ipsec_mb_lib; + /* SHA1 - 20 bytes - Initialiser state can be found in FIPS stds 180-2 */ static const uint8_t sha1InitialState[] = { 0x67, 0x45, 0x23, 0x01, 0xef, 0xcd, 0xab, 0x89, 0x98, 0xba, @@ -470,6 +480,21 @@ qat_sym_session_configure(struct rte_cryptodev *dev, return -ENOMEM; } +#if (OPENSSL_VERSION_NUMBER >= 0x30000000L) + OSSL_PROVIDER * legacy; + OSSL_PROVIDER *deflt; + + /* Load Multiple providers into the default (NULL) library context */ + legacy = OSSL_PROVIDER_load(NULL, "legacy"); + if (legacy == NULL) + return -EINVAL; + + deflt = OSSL_PROVIDER_load(NULL, "default"); + if (deflt == NULL) { + OSSL_PROVIDER_unload(legacy); + return -EINVAL; + } +#endif ret = qat_sym_session_set_parameters(dev, xform, sess_private_data); if (ret != 0) { QAT_LOG(ERR, @@ -483,6 +508,10 @@ qat_sym_session_configure(struct rte_cryptodev *dev, set_sym_session_private_data(sess, dev->driver_id, sess_private_data); +# if (OPENSSL_VERSION_NUMBER >= 0x30000000L) + OSSL_PROVIDER_unload(legacy); + OSSL_PROVIDER_unload(deflt); +# endif return 0; } @@ -1057,6 +1086,258 @@ static int qat_hash_get_block_size(enum icp_qat_hw_auth_algo qat_hash_alg) return -EFAULT; } +#define HMAC_IPAD_VALUE 0x36 +#define HMAC_OPAD_VALUE 0x5c +#define HASH_XCBC_PRECOMP_KEY_NUM 3 + +static const uint8_t AES_CMAC_SEED[ICP_QAT_HW_AES_128_KEY_SZ]; + +#ifdef RTE_QAT_LIBIPSECMB +static int aes_ipsecmb_job(uint8_t *in, uint8_t *out, IMB_MGR *m, + const uint8_t *key, uint16_t auth_keylen) +{ + int err; + struct IMB_JOB *job; + DECLARE_ALIGNED(uint32_t expkey[4*15], 16); + DECLARE_ALIGNED(uint32_t dust[4*15], 16); + + if (auth_keylen == ICP_QAT_HW_AES_128_KEY_SZ) + IMB_AES_KEYEXP_128(m, key, expkey, dust); + else if (auth_keylen == ICP_QAT_HW_AES_192_KEY_SZ) + IMB_AES_KEYEXP_192(m, key, expkey, dust); + else if (auth_keylen == ICP_QAT_HW_AES_256_KEY_SZ) + IMB_AES_KEYEXP_256(m, key, expkey, dust); + else + return -EFAULT; + + job = IMB_GET_NEXT_JOB(m); + + job->src = in; + job->dst = out; + job->enc_keys = expkey; + job->key_len_in_bytes = auth_keylen; + job->msg_len_to_cipher_in_bytes = 16; + job->iv_len_in_bytes = 0; + job->cipher_direction = IMB_DIR_ENCRYPT; + job->cipher_mode = IMB_CIPHER_ECB; + job->hash_alg = IMB_AUTH_NULL; + + while (IMB_FLUSH_JOB(m) != NULL) + ; + + job = IMB_SUBMIT_JOB(m); + if (job) { + if (job->status == IMB_STATUS_COMPLETED) + return 0; + } + + err = imb_get_errno(m); + if (err) + QAT_LOG(ERR, "Error: %s!\n", imb_get_strerror(err)); + + return -EFAULT; +} + +static int +partial_hash_compute_ipsec_mb(enum icp_qat_hw_auth_algo hash_alg, + uint8_t *data_in, uint8_t *data_out, IMB_MGR *m) +{ + int digest_size; + uint8_t digest[qat_hash_get_digest_size( + ICP_QAT_HW_AUTH_ALGO_DELIMITER)]; + uint32_t *hash_state_out_be32; + uint64_t *hash_state_out_be64; + int i; + + /* Initialize to avoid gcc warning */ + memset(digest, 0, sizeof(digest)); + + digest_size = qat_hash_get_digest_size(hash_alg); + if (digest_size <= 0) + return -EFAULT; + + hash_state_out_be32 = (uint32_t *)data_out; + hash_state_out_be64 = (uint64_t *)data_out; + + switch (hash_alg) { + case ICP_QAT_HW_AUTH_ALGO_SHA1: + IMB_SHA1_ONE_BLOCK(m, data_in, digest); + for (i = 0; i < digest_size >> 2; i++, hash_state_out_be32++) + *hash_state_out_be32 = + rte_bswap32(*(((uint32_t *)digest)+i)); + break; + case ICP_QAT_HW_AUTH_ALGO_SHA224: + IMB_SHA224_ONE_BLOCK(m, data_in, digest); + for (i = 0; i < digest_size >> 2; i++, hash_state_out_be32++) + *hash_state_out_be32 = + rte_bswap32(*(((uint32_t *)digest)+i)); + break; + case ICP_QAT_HW_AUTH_ALGO_SHA256: + IMB_SHA256_ONE_BLOCK(m, data_in, digest); + for (i = 0; i < digest_size >> 2; i++, hash_state_out_be32++) + *hash_state_out_be32 = + rte_bswap32(*(((uint32_t *)digest)+i)); + break; + case ICP_QAT_HW_AUTH_ALGO_SHA384: + IMB_SHA384_ONE_BLOCK(m, data_in, digest); + for (i = 0; i < digest_size >> 3; i++, hash_state_out_be64++) + *hash_state_out_be64 = + rte_bswap64(*(((uint64_t *)digest)+i)); + break; + case ICP_QAT_HW_AUTH_ALGO_SHA512: + IMB_SHA512_ONE_BLOCK(m, data_in, digest); + for (i = 0; i < digest_size >> 3; i++, hash_state_out_be64++) + *hash_state_out_be64 = + rte_bswap64(*(((uint64_t *)digest)+i)); + break; + case ICP_QAT_HW_AUTH_ALGO_MD5: + IMB_MD5_ONE_BLOCK(m, data_in, data_out); + break; + default: + QAT_LOG(ERR, "invalid hash alg %u", hash_alg); + return -EFAULT; + } + + return 0; +} + +static int qat_sym_do_precomputes_ipsec_mb(enum icp_qat_hw_auth_algo hash_alg, + const uint8_t *auth_key, + uint16_t auth_keylen, + uint8_t *p_state_buf, + uint16_t *p_state_len, + uint8_t aes_cmac) +{ + int block_size = 0; + uint8_t ipad[qat_hash_get_block_size(ICP_QAT_HW_AUTH_ALGO_DELIMITER)]; + uint8_t opad[qat_hash_get_block_size(ICP_QAT_HW_AUTH_ALGO_DELIMITER)]; + int i, ret = 0; + uint8_t in[ICP_QAT_HW_AES_XCBC_MAC_STATE2_SZ]; + + IMB_MGR *m; + m = alloc_mb_mgr(0); + if (m == NULL) + return -ENOMEM; + + init_mb_mgr_auto(m, NULL); + memset(in, 0, ICP_QAT_HW_AES_XCBC_MAC_STATE2_SZ); + if (hash_alg == ICP_QAT_HW_AUTH_ALGO_AES_XCBC_MAC) { + + /* CMAC */ + if (aes_cmac) { + uint8_t *k1, *k2; + auth_keylen = ICP_QAT_HW_AES_128_KEY_SZ; + rte_memcpy(p_state_buf, auth_key, auth_keylen); + + DECLARE_ALIGNED(uint32_t expkey[4*15], 16); + DECLARE_ALIGNED(uint32_t dust[4*15], 16); + IMB_AES_KEYEXP_128(m, p_state_buf, expkey, dust); + k1 = p_state_buf + ICP_QAT_HW_AES_XCBC_MAC_STATE1_SZ; + k2 = k1 + ICP_QAT_HW_AES_XCBC_MAC_STATE1_SZ; + + IMB_AES_CMAC_SUBKEY_GEN_128(m, expkey, k1, k2); + *p_state_len = ICP_QAT_HW_AES_XCBC_MAC_STATE2_SZ; + goto out; + } + + static uint8_t qat_aes_xcbc_key_seed[ + ICP_QAT_HW_AES_XCBC_MAC_STATE2_SZ] = { + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + }; + + uint8_t *input = in; + uint8_t *out = p_state_buf; + rte_memcpy(input, qat_aes_xcbc_key_seed, + ICP_QAT_HW_AES_XCBC_MAC_STATE2_SZ); + for (i = 0; i < HASH_XCBC_PRECOMP_KEY_NUM; i++) { + if (aes_ipsecmb_job(input, out, m, auth_key, auth_keylen)) { + memset(input - + (i * ICP_QAT_HW_AES_XCBC_MAC_KEY_SZ), + 0, ICP_QAT_HW_AES_XCBC_MAC_STATE2_SZ); + ret = -EFAULT; + goto out; + } + + input += ICP_QAT_HW_AES_XCBC_MAC_KEY_SZ; + out += ICP_QAT_HW_AES_XCBC_MAC_KEY_SZ; + } + *p_state_len = ICP_QAT_HW_AES_XCBC_MAC_STATE2_SZ; + goto out; + + } else if ((hash_alg == ICP_QAT_HW_AUTH_ALGO_GALOIS_128) || + (hash_alg == ICP_QAT_HW_AUTH_ALGO_GALOIS_64)) { + uint8_t *out = p_state_buf; + + memset(p_state_buf, 0, ICP_QAT_HW_GALOIS_H_SZ + + ICP_QAT_HW_GALOIS_LEN_A_SZ + + ICP_QAT_HW_GALOIS_E_CTR0_SZ); + if (aes_ipsecmb_job(in, out, m, auth_key, auth_keylen)) { + ret = -EFAULT; + goto out; + } + + *p_state_len = ICP_QAT_HW_GALOIS_H_SZ + + ICP_QAT_HW_GALOIS_LEN_A_SZ + + ICP_QAT_HW_GALOIS_E_CTR0_SZ; + goto out; + } + + block_size = qat_hash_get_block_size(hash_alg); + if (block_size < 0) { + free_mb_mgr(m); + return block_size; + } + + if (auth_keylen > (unsigned int)block_size) { + QAT_LOG(ERR, "invalid keylen %u", auth_keylen); + ret = -EFAULT; + goto out; + } + /* init ipad and opad from key and xor with fixed values */ + memset(ipad, 0, block_size); + memset(opad, 0, block_size); + rte_memcpy(ipad, auth_key, auth_keylen); + rte_memcpy(opad, auth_key, auth_keylen); + + for (i = 0; i < block_size; i++) { + uint8_t *ipad_ptr = ipad + i; + uint8_t *opad_ptr = opad + i; + *ipad_ptr ^= HMAC_IPAD_VALUE; + *opad_ptr ^= HMAC_OPAD_VALUE; + } + + /* do partial hash of ipad and copy to state1 */ + if (partial_hash_compute_ipsec_mb(hash_alg, ipad, p_state_buf, m)) { + QAT_LOG(ERR, "ipad precompute failed"); + ret = -EFAULT; + goto out; + } + + /* + * State len is a multiple of 8, so may be larger than the digest. + * Put the partial hash of opad state_len bytes after state1 + */ + *p_state_len = qat_hash_get_state1_size(hash_alg); + if (partial_hash_compute_ipsec_mb(hash_alg, opad, + p_state_buf + *p_state_len, m)) { + QAT_LOG(ERR, "opad precompute failed"); + ret = -EFAULT; + goto out; + } + +out: + /* don't leave data lying around */ + memset(ipad, 0, block_size); + memset(opad, 0, block_size); + free_mb_mgr(m); + return ret; +} +#endif static int partial_hash_sha1(uint8_t *data_in, uint8_t *data_out) { SHA_CTX ctx; @@ -1124,6 +1405,20 @@ static int partial_hash_md5(uint8_t *data_in, uint8_t *data_out) return 0; } +static void aes_cmac_key_derive(uint8_t *base, uint8_t *derived) +{ + int i; + + derived[0] = base[0] << 1; + for (i = 1; i < ICP_QAT_HW_AES_BLK_SZ ; i++) { + derived[i] = base[i] << 1; + derived[i - 1] |= base[i] >> 7; + } + + if (base[0] & 0x80) + derived[ICP_QAT_HW_AES_BLK_SZ - 1] ^= QAT_AES_CMAC_CONST_RB; +} + static int partial_hash_compute(enum icp_qat_hw_auth_algo hash_alg, uint8_t *data_in, uint8_t *data_out) @@ -1192,25 +1487,6 @@ partial_hash_compute(enum icp_qat_hw_auth_algo hash_alg, return 0; } -#define HMAC_IPAD_VALUE 0x36 -#define HMAC_OPAD_VALUE 0x5c -#define HASH_XCBC_PRECOMP_KEY_NUM 3 - -static const uint8_t AES_CMAC_SEED[ICP_QAT_HW_AES_128_KEY_SZ]; - -static void aes_cmac_key_derive(uint8_t *base, uint8_t *derived) -{ - int i; - - derived[0] = base[0] << 1; - for (i = 1; i < ICP_QAT_HW_AES_BLK_SZ ; i++) { - derived[i] = base[i] << 1; - derived[i - 1] |= base[i] >> 7; - } - - if (base[0] & 0x80) - derived[ICP_QAT_HW_AES_BLK_SZ - 1] ^= QAT_AES_CMAC_CONST_RB; -} static int qat_sym_do_precomputes(enum icp_qat_hw_auth_algo hash_alg, const uint8_t *auth_key, @@ -1695,6 +1971,7 @@ int qat_sym_cd_auth_set(struct qat_sym_session *cdesc, uint32_t *aad_len = NULL; uint32_t wordIndex = 0; uint32_t *pTempKey; + int ret = 0; if (cdesc->qat_cmd == ICP_QAT_FW_LA_CMD_AUTH) { ICP_QAT_FW_COMN_CURR_ID_SET(hash_cd_ctrl, @@ -1766,9 +2043,22 @@ int qat_sym_cd_auth_set(struct qat_sym_session *cdesc, break; } /* SHA-1 HMAC */ - if (qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA1, authkey, - authkeylen, cdesc->cd_cur_ptr, &state1_size, - cdesc->aes_cmac)) { + if (qat_ipsec_mb_lib) { +#ifdef RTE_QAT_LIBIPSECMB + ret = qat_sym_do_precomputes_ipsec_mb(ICP_QAT_HW_AUTH_ALGO_SHA1, + authkey, authkeylen, cdesc->cd_cur_ptr, &state1_size, + cdesc->aes_cmac); +#else + QAT_LOG(ERR, "Intel IPSEC-MB LIB missing ?"); + return -EFAULT; +#endif + } else { + ret = qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA1, authkey, + authkeylen, cdesc->cd_cur_ptr, &state1_size, + cdesc->aes_cmac); + } + + if (ret) { QAT_LOG(ERR, "(SHA)precompute failed"); return -EFAULT; } @@ -1784,9 +2074,22 @@ int qat_sym_cd_auth_set(struct qat_sym_session *cdesc, break; } /* SHA-224 HMAC */ - if (qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA224, authkey, - authkeylen, cdesc->cd_cur_ptr, &state1_size, - cdesc->aes_cmac)) { + if (qat_ipsec_mb_lib) { +#ifdef RTE_QAT_LIBIPSECMB + ret = qat_sym_do_precomputes_ipsec_mb(ICP_QAT_HW_AUTH_ALGO_SHA224, + authkey, authkeylen, cdesc->cd_cur_ptr, &state1_size, + cdesc->aes_cmac); +#else + QAT_LOG(ERR, "Intel IPSEC-MB LIB missing ?"); + return -EFAULT; +#endif + } else { + ret = qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA224, authkey, + authkeylen, cdesc->cd_cur_ptr, &state1_size, + cdesc->aes_cmac); + } + + if (ret) { QAT_LOG(ERR, "(SHA)precompute failed"); return -EFAULT; } @@ -1802,9 +2105,22 @@ int qat_sym_cd_auth_set(struct qat_sym_session *cdesc, break; } /* SHA-256 HMAC */ - if (qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA256, authkey, - authkeylen, cdesc->cd_cur_ptr, &state1_size, - cdesc->aes_cmac)) { + if (qat_ipsec_mb_lib) { +#ifdef RTE_QAT_LIBIPSECMB + ret = qat_sym_do_precomputes_ipsec_mb(ICP_QAT_HW_AUTH_ALGO_SHA256, + authkey, authkeylen, cdesc->cd_cur_ptr, &state1_size, + cdesc->aes_cmac); +#else + QAT_LOG(ERR, "Intel IPSEC-MB LIB missing ?"); + return -EFAULT; +#endif + } else { + ret = qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA256, authkey, + authkeylen, cdesc->cd_cur_ptr, &state1_size, + cdesc->aes_cmac); + } + + if (ret) { QAT_LOG(ERR, "(SHA)precompute failed"); return -EFAULT; } @@ -1820,9 +2136,22 @@ int qat_sym_cd_auth_set(struct qat_sym_session *cdesc, break; } /* SHA-384 HMAC */ - if (qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA384, authkey, - authkeylen, cdesc->cd_cur_ptr, &state1_size, - cdesc->aes_cmac)) { + if (qat_ipsec_mb_lib) { +#ifdef RTE_QAT_LIBIPSECMB + ret = qat_sym_do_precomputes_ipsec_mb(ICP_QAT_HW_AUTH_ALGO_SHA384, + authkey, authkeylen, cdesc->cd_cur_ptr, &state1_size, + cdesc->aes_cmac); +#else + QAT_LOG(ERR, "Intel IPSEC-MB LIB missing ?"); + return -EFAULT; +#endif + } else { + ret = qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA384, authkey, + authkeylen, cdesc->cd_cur_ptr, &state1_size, + cdesc->aes_cmac); + } + + if (ret) { QAT_LOG(ERR, "(SHA)precompute failed"); return -EFAULT; } @@ -1838,9 +2167,22 @@ int qat_sym_cd_auth_set(struct qat_sym_session *cdesc, break; } /* SHA-512 HMAC */ - if (qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA512, authkey, - authkeylen, cdesc->cd_cur_ptr, &state1_size, - cdesc->aes_cmac)) { + if (qat_ipsec_mb_lib) { +#ifdef RTE_QAT_LIBIPSECMB + ret = qat_sym_do_precomputes_ipsec_mb(ICP_QAT_HW_AUTH_ALGO_SHA512, + authkey, authkeylen, cdesc->cd_cur_ptr, &state1_size, + cdesc->aes_cmac); +#else + QAT_LOG(ERR, "Intel IPSEC-MB LIB missing ?"); + return -EFAULT; +#endif + } else { + ret = qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA512, authkey, + authkeylen, cdesc->cd_cur_ptr, &state1_size, + cdesc->aes_cmac); + } + + if (ret) { QAT_LOG(ERR, "(SHA)precompute failed"); return -EFAULT; } @@ -1851,9 +2193,23 @@ int qat_sym_cd_auth_set(struct qat_sym_session *cdesc, if (cdesc->aes_cmac) memset(cdesc->cd_cur_ptr, 0, state1_size); - if (qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_AES_XCBC_MAC, - authkey, authkeylen, cdesc->cd_cur_ptr + state1_size, - &state2_size, cdesc->aes_cmac)) { + if (qat_ipsec_mb_lib) { +#ifdef RTE_QAT_LIBIPSECMB + ret = qat_sym_do_precomputes_ipsec_mb( + ICP_QAT_HW_AUTH_ALGO_AES_XCBC_MAC, + authkey, authkeylen, cdesc->cd_cur_ptr + state1_size, + &state2_size, cdesc->aes_cmac); +#else + QAT_LOG(ERR, "Intel IPSEC-MB LIB missing ?"); + return -EFAULT; +#endif + } else { + ret = qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_AES_XCBC_MAC, + authkey, authkeylen, cdesc->cd_cur_ptr + state1_size, + &state2_size, cdesc->aes_cmac); + } + + if (ret) { cdesc->aes_cmac ? QAT_LOG(ERR, "(CMAC)precompute failed") : QAT_LOG(ERR, @@ -1865,9 +2221,22 @@ int qat_sym_cd_auth_set(struct qat_sym_session *cdesc, case ICP_QAT_HW_AUTH_ALGO_GALOIS_64: cdesc->qat_proto_flag = QAT_CRYPTO_PROTO_FLAG_GCM; state1_size = ICP_QAT_HW_GALOIS_128_STATE1_SZ; - if (qat_sym_do_precomputes(cdesc->qat_hash_alg, authkey, - authkeylen, cdesc->cd_cur_ptr + state1_size, - &state2_size, cdesc->aes_cmac)) { + if (qat_ipsec_mb_lib) { +#ifdef RTE_QAT_LIBIPSECMB + ret = qat_sym_do_precomputes_ipsec_mb(cdesc->qat_hash_alg, authkey, + authkeylen, cdesc->cd_cur_ptr + state1_size, + &state2_size, cdesc->aes_cmac); +#else + QAT_LOG(ERR, "Intel IPSEC-MB LIB missing ?"); + return -EFAULT; +#endif + } else { + ret = qat_sym_do_precomputes(cdesc->qat_hash_alg, authkey, + authkeylen, cdesc->cd_cur_ptr + state1_size, + &state2_size, cdesc->aes_cmac); + } + + if (ret) { QAT_LOG(ERR, "(GCM)precompute failed"); return -EFAULT; } @@ -1923,9 +2292,22 @@ int qat_sym_cd_auth_set(struct qat_sym_session *cdesc, break; case ICP_QAT_HW_AUTH_ALGO_MD5: - if (qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_MD5, authkey, - authkeylen, cdesc->cd_cur_ptr, &state1_size, - cdesc->aes_cmac)) { + if (qat_ipsec_mb_lib) { +#ifdef RTE_QAT_LIBIPSECMB + ret = qat_sym_do_precomputes_ipsec_mb(ICP_QAT_HW_AUTH_ALGO_MD5, + authkey, authkeylen, cdesc->cd_cur_ptr, &state1_size, + cdesc->aes_cmac); +#else + QAT_LOG(ERR, "Intel IPSEC-MB LIB missing"); + return -EFAULT; +#endif + } else { + ret = qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_MD5, authkey, + authkeylen, cdesc->cd_cur_ptr, &state1_size, + cdesc->aes_cmac); + } + + if (ret) { QAT_LOG(ERR, "(MD5)precompute failed"); return -EFAULT; } -- 2.17.1 ^ permalink raw reply [flat|nested] 9+ messages in thread
* [dpdk-dev v7] crypto/qat: use intel-ipsec-mb for partial hash & aes 2022-05-30 10:21 ` [dpdk-dev v6] " Kai Ji @ 2022-06-13 17:02 ` Kai Ji 2022-06-17 11:26 ` Power, Ciara 0 siblings, 1 reply; 9+ messages in thread From: Kai Ji @ 2022-06-13 17:02 UTC (permalink / raw) To: dev; +Cc: gakhil, Kai Ji, Fan Zhang Since openssl 3.0 now deprecates the low level API QAT required to perform partial hash & aes operation when creating the session. This patch add in qat_ipsec_mb_lib driver parameter to allow QAT PMD to switch APIs between openssl and intel ipsec-mb library. Signed-off-by: Kai Ji <kai.ji@intel.com> Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com> --- v7: - rebase to 22.07 rc1 v6: - code review comments resolution v5: - fix of Intel IPSEC-MB lib version check v4: - fix of memory leak in IMB_MGR v3: - Add in qat_ipsec_mb_lib driver parameter v2: - Add AES ECB job function for precompute --- doc/guides/cryptodevs/qat.rst | 13 + drivers/common/qat/meson.build | 13 + drivers/common/qat/qat_device.c | 1 + drivers/common/qat/qat_device.h | 1 + drivers/crypto/qat/qat_sym.c | 5 +- drivers/crypto/qat/qat_sym_session.c | 468 ++++++++++++++++++++++++--- 6 files changed, 456 insertions(+), 45 deletions(-) diff --git a/doc/guides/cryptodevs/qat.rst b/doc/guides/cryptodevs/qat.rst index 18ad1646a4..613603eed1 100644 --- a/doc/guides/cryptodevs/qat.rst +++ b/doc/guides/cryptodevs/qat.rst @@ -288,6 +288,19 @@ by comma. When the same parameter is used more than once first occurrence of the is used. Maximum threshold that can be set is 32. +Running QAT PMD with Intel IPSEC MB library for symmetric precomputes function +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The QAT PMD use Openssl library for partial hash calculation in symmetirc precomputes function by +default, the following parameter is allow QAT PMD switch over to multi-buffer job API if Intel +IPSEC MB library installed on system. + +- qat_ipsec_mb_lib + +To use this feature the user must set the parameter on process start as a device additional parameter:: + + -a 03:01.1,qat_ipsec_mb_lib=1 + Device and driver naming ~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/drivers/common/qat/meson.build b/drivers/common/qat/meson.build index b7027f3164..245c0fbe61 100644 --- a/drivers/common/qat/meson.build +++ b/drivers/common/qat/meson.build @@ -35,6 +35,19 @@ if qat_crypto and not libcrypto.found() 'missing dependency, libcrypto') endif +IMB_required_ver = '1.2.0' +libipsecmb = cc.find_library('IPSec_MB', required: false) +if libipsecmb.found() + # version comes with quotes, so we split based on " and take the middle + imb_ver = cc.get_define('IMB_VERSION_STR', + prefix : '#include<intel-ipsec-mb.h>').split('"')[1] + + if (imb_ver.version_compare('>=' + IMB_required_ver)) + ext_deps += libipsecmb + dpdk_conf.set('RTE_QAT_LIBIPSECMB', true) + endif +endif + # The driver should not build if both compression and crypto are disabled #FIXME common code depends on compression files so check only compress! if not qat_compress # and not qat_crypto diff --git a/drivers/common/qat/qat_device.c b/drivers/common/qat/qat_device.c index 6824d97050..db4b087d2b 100644 --- a/drivers/common/qat/qat_device.c +++ b/drivers/common/qat/qat_device.c @@ -364,6 +364,7 @@ static int qat_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, struct qat_pci_device *qat_pci_dev; struct qat_dev_hw_spec_funcs *ops_hw; struct qat_dev_cmd_param qat_dev_cmd_param[] = { + { QAT_IPSEC_MB_LIB, 0 }, { SYM_ENQ_THRESHOLD_NAME, 0 }, { ASYM_ENQ_THRESHOLD_NAME, 0 }, { COMP_ENQ_THRESHOLD_NAME, 0 }, diff --git a/drivers/common/qat/qat_device.h b/drivers/common/qat/qat_device.h index 85fae7b7c7..e1a32a7e87 100644 --- a/drivers/common/qat/qat_device.h +++ b/drivers/common/qat/qat_device.h @@ -16,6 +16,7 @@ #define QAT_DEV_NAME_MAX_LEN 64 +#define QAT_IPSEC_MB_LIB "qat_ipsec_mb_lib" #define SYM_ENQ_THRESHOLD_NAME "qat_sym_enq_threshold" #define ASYM_ENQ_THRESHOLD_NAME "qat_asym_enq_threshold" #define COMP_ENQ_THRESHOLD_NAME "qat_comp_enq_threshold" diff --git a/drivers/crypto/qat/qat_sym.c b/drivers/crypto/qat/qat_sym.c index 3a6c9dcc0a..3477cd89ad 100644 --- a/drivers/crypto/qat/qat_sym.c +++ b/drivers/crypto/qat/qat_sym.c @@ -2,8 +2,6 @@ * Copyright(c) 2015-2022 Intel Corporation */ -#define OPENSSL_API_COMPAT 0x10100000L - #include <openssl/evp.h> #include <rte_mempool.h> @@ -17,6 +15,7 @@ #include "qat_qp.h" uint8_t qat_sym_driver_id; +int qat_ipsec_mb_lib; struct qat_crypto_gen_dev_ops qat_sym_gen_dev_ops[QAT_N_GENS]; @@ -309,6 +308,8 @@ qat_sym_dev_create(struct qat_pci_device *qat_pci_dev, if (!strcmp(qat_dev_cmd_param[i].name, SYM_ENQ_THRESHOLD_NAME)) internals->min_enq_burst_threshold = qat_dev_cmd_param[i].val; + if (!strcmp(qat_dev_cmd_param[i].name, QAT_IPSEC_MB_LIB)) + qat_ipsec_mb_lib = qat_dev_cmd_param[i].val; i++; } diff --git a/drivers/crypto/qat/qat_sym_session.c b/drivers/crypto/qat/qat_sym_session.c index 737a180810..30da20ce4d 100644 --- a/drivers/crypto/qat/qat_sym_session.c +++ b/drivers/crypto/qat/qat_sym_session.c @@ -9,6 +9,10 @@ #include <openssl/md5.h> /* Needed to calculate pre-compute values */ #include <openssl/evp.h> /* Needed for bpi runt block processing */ +#ifdef RTE_QAT_LIBIPSECMB +#include <intel-ipsec-mb.h> +#endif + #include <rte_memcpy.h> #include <rte_common.h> #include <rte_spinlock.h> @@ -24,6 +28,12 @@ #include "qat_sym_session.h" #include "qat_sym.h" +#if (OPENSSL_VERSION_NUMBER >= 0x30000000L) +#include <openssl/provider.h> +#endif + +extern int qat_ipsec_mb_lib; + /* SHA1 - 20 bytes - Initialiser state can be found in FIPS stds 180-2 */ static const uint8_t sha1InitialState[] = { 0x67, 0x45, 0x23, 0x01, 0xef, 0xcd, 0xab, 0x89, 0x98, 0xba, @@ -472,6 +482,21 @@ qat_sym_session_configure(struct rte_cryptodev *dev, return -ENOMEM; } +#if (OPENSSL_VERSION_NUMBER >= 0x30000000L) + OSSL_PROVIDER * legacy; + OSSL_PROVIDER *deflt; + + /* Load Multiple providers into the default (NULL) library context */ + legacy = OSSL_PROVIDER_load(NULL, "legacy"); + if (legacy == NULL) + return -EINVAL; + + deflt = OSSL_PROVIDER_load(NULL, "default"); + if (deflt == NULL) { + OSSL_PROVIDER_unload(legacy); + return -EINVAL; + } +#endif ret = qat_sym_session_set_parameters(dev, xform, sess_private_data); if (ret != 0) { QAT_LOG(ERR, @@ -485,6 +510,10 @@ qat_sym_session_configure(struct rte_cryptodev *dev, set_sym_session_private_data(sess, dev->driver_id, sess_private_data); +# if (OPENSSL_VERSION_NUMBER >= 0x30000000L) + OSSL_PROVIDER_unload(legacy); + OSSL_PROVIDER_unload(deflt); +# endif return 0; } @@ -1059,6 +1088,258 @@ static int qat_hash_get_block_size(enum icp_qat_hw_auth_algo qat_hash_alg) return -EFAULT; } +#define HMAC_IPAD_VALUE 0x36 +#define HMAC_OPAD_VALUE 0x5c +#define HASH_XCBC_PRECOMP_KEY_NUM 3 + +static const uint8_t AES_CMAC_SEED[ICP_QAT_HW_AES_128_KEY_SZ]; + +#ifdef RTE_QAT_LIBIPSECMB +static int aes_ipsecmb_job(uint8_t *in, uint8_t *out, IMB_MGR *m, + const uint8_t *key, uint16_t auth_keylen) +{ + int err; + struct IMB_JOB *job; + DECLARE_ALIGNED(uint32_t expkey[4*15], 16); + DECLARE_ALIGNED(uint32_t dust[4*15], 16); + + if (auth_keylen == ICP_QAT_HW_AES_128_KEY_SZ) + IMB_AES_KEYEXP_128(m, key, expkey, dust); + else if (auth_keylen == ICP_QAT_HW_AES_192_KEY_SZ) + IMB_AES_KEYEXP_192(m, key, expkey, dust); + else if (auth_keylen == ICP_QAT_HW_AES_256_KEY_SZ) + IMB_AES_KEYEXP_256(m, key, expkey, dust); + else + return -EFAULT; + + job = IMB_GET_NEXT_JOB(m); + + job->src = in; + job->dst = out; + job->enc_keys = expkey; + job->key_len_in_bytes = auth_keylen; + job->msg_len_to_cipher_in_bytes = 16; + job->iv_len_in_bytes = 0; + job->cipher_direction = IMB_DIR_ENCRYPT; + job->cipher_mode = IMB_CIPHER_ECB; + job->hash_alg = IMB_AUTH_NULL; + + while (IMB_FLUSH_JOB(m) != NULL) + ; + + job = IMB_SUBMIT_JOB(m); + if (job) { + if (job->status == IMB_STATUS_COMPLETED) + return 0; + } + + err = imb_get_errno(m); + if (err) + QAT_LOG(ERR, "Error: %s!\n", imb_get_strerror(err)); + + return -EFAULT; +} + +static int +partial_hash_compute_ipsec_mb(enum icp_qat_hw_auth_algo hash_alg, + uint8_t *data_in, uint8_t *data_out, IMB_MGR *m) +{ + int digest_size; + uint8_t digest[qat_hash_get_digest_size( + ICP_QAT_HW_AUTH_ALGO_DELIMITER)]; + uint32_t *hash_state_out_be32; + uint64_t *hash_state_out_be64; + int i; + + /* Initialize to avoid gcc warning */ + memset(digest, 0, sizeof(digest)); + + digest_size = qat_hash_get_digest_size(hash_alg); + if (digest_size <= 0) + return -EFAULT; + + hash_state_out_be32 = (uint32_t *)data_out; + hash_state_out_be64 = (uint64_t *)data_out; + + switch (hash_alg) { + case ICP_QAT_HW_AUTH_ALGO_SHA1: + IMB_SHA1_ONE_BLOCK(m, data_in, digest); + for (i = 0; i < digest_size >> 2; i++, hash_state_out_be32++) + *hash_state_out_be32 = + rte_bswap32(*(((uint32_t *)digest)+i)); + break; + case ICP_QAT_HW_AUTH_ALGO_SHA224: + IMB_SHA224_ONE_BLOCK(m, data_in, digest); + for (i = 0; i < digest_size >> 2; i++, hash_state_out_be32++) + *hash_state_out_be32 = + rte_bswap32(*(((uint32_t *)digest)+i)); + break; + case ICP_QAT_HW_AUTH_ALGO_SHA256: + IMB_SHA256_ONE_BLOCK(m, data_in, digest); + for (i = 0; i < digest_size >> 2; i++, hash_state_out_be32++) + *hash_state_out_be32 = + rte_bswap32(*(((uint32_t *)digest)+i)); + break; + case ICP_QAT_HW_AUTH_ALGO_SHA384: + IMB_SHA384_ONE_BLOCK(m, data_in, digest); + for (i = 0; i < digest_size >> 3; i++, hash_state_out_be64++) + *hash_state_out_be64 = + rte_bswap64(*(((uint64_t *)digest)+i)); + break; + case ICP_QAT_HW_AUTH_ALGO_SHA512: + IMB_SHA512_ONE_BLOCK(m, data_in, digest); + for (i = 0; i < digest_size >> 3; i++, hash_state_out_be64++) + *hash_state_out_be64 = + rte_bswap64(*(((uint64_t *)digest)+i)); + break; + case ICP_QAT_HW_AUTH_ALGO_MD5: + IMB_MD5_ONE_BLOCK(m, data_in, data_out); + break; + default: + QAT_LOG(ERR, "invalid hash alg %u", hash_alg); + return -EFAULT; + } + + return 0; +} + +static int qat_sym_do_precomputes_ipsec_mb(enum icp_qat_hw_auth_algo hash_alg, + const uint8_t *auth_key, + uint16_t auth_keylen, + uint8_t *p_state_buf, + uint16_t *p_state_len, + uint8_t aes_cmac) +{ + int block_size = 0; + uint8_t ipad[qat_hash_get_block_size(ICP_QAT_HW_AUTH_ALGO_DELIMITER)]; + uint8_t opad[qat_hash_get_block_size(ICP_QAT_HW_AUTH_ALGO_DELIMITER)]; + int i, ret = 0; + uint8_t in[ICP_QAT_HW_AES_XCBC_MAC_STATE2_SZ]; + + IMB_MGR *m; + m = alloc_mb_mgr(0); + if (m == NULL) + return -ENOMEM; + + init_mb_mgr_auto(m, NULL); + memset(in, 0, ICP_QAT_HW_AES_XCBC_MAC_STATE2_SZ); + if (hash_alg == ICP_QAT_HW_AUTH_ALGO_AES_XCBC_MAC) { + + /* CMAC */ + if (aes_cmac) { + uint8_t *k1, *k2; + auth_keylen = ICP_QAT_HW_AES_128_KEY_SZ; + rte_memcpy(p_state_buf, auth_key, auth_keylen); + + DECLARE_ALIGNED(uint32_t expkey[4*15], 16); + DECLARE_ALIGNED(uint32_t dust[4*15], 16); + IMB_AES_KEYEXP_128(m, p_state_buf, expkey, dust); + k1 = p_state_buf + ICP_QAT_HW_AES_XCBC_MAC_STATE1_SZ; + k2 = k1 + ICP_QAT_HW_AES_XCBC_MAC_STATE1_SZ; + + IMB_AES_CMAC_SUBKEY_GEN_128(m, expkey, k1, k2); + *p_state_len = ICP_QAT_HW_AES_XCBC_MAC_STATE2_SZ; + goto out; + } + + static uint8_t qat_aes_xcbc_key_seed[ + ICP_QAT_HW_AES_XCBC_MAC_STATE2_SZ] = { + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + }; + + uint8_t *input = in; + uint8_t *out = p_state_buf; + rte_memcpy(input, qat_aes_xcbc_key_seed, + ICP_QAT_HW_AES_XCBC_MAC_STATE2_SZ); + for (i = 0; i < HASH_XCBC_PRECOMP_KEY_NUM; i++) { + if (aes_ipsecmb_job(input, out, m, auth_key, auth_keylen)) { + memset(input - + (i * ICP_QAT_HW_AES_XCBC_MAC_KEY_SZ), + 0, ICP_QAT_HW_AES_XCBC_MAC_STATE2_SZ); + ret = -EFAULT; + goto out; + } + + input += ICP_QAT_HW_AES_XCBC_MAC_KEY_SZ; + out += ICP_QAT_HW_AES_XCBC_MAC_KEY_SZ; + } + *p_state_len = ICP_QAT_HW_AES_XCBC_MAC_STATE2_SZ; + goto out; + + } else if ((hash_alg == ICP_QAT_HW_AUTH_ALGO_GALOIS_128) || + (hash_alg == ICP_QAT_HW_AUTH_ALGO_GALOIS_64)) { + uint8_t *out = p_state_buf; + + memset(p_state_buf, 0, ICP_QAT_HW_GALOIS_H_SZ + + ICP_QAT_HW_GALOIS_LEN_A_SZ + + ICP_QAT_HW_GALOIS_E_CTR0_SZ); + if (aes_ipsecmb_job(in, out, m, auth_key, auth_keylen)) { + ret = -EFAULT; + goto out; + } + + *p_state_len = ICP_QAT_HW_GALOIS_H_SZ + + ICP_QAT_HW_GALOIS_LEN_A_SZ + + ICP_QAT_HW_GALOIS_E_CTR0_SZ; + goto out; + } + + block_size = qat_hash_get_block_size(hash_alg); + if (block_size < 0) { + free_mb_mgr(m); + return block_size; + } + + if (auth_keylen > (unsigned int)block_size) { + QAT_LOG(ERR, "invalid keylen %u", auth_keylen); + ret = -EFAULT; + goto out; + } + /* init ipad and opad from key and xor with fixed values */ + memset(ipad, 0, block_size); + memset(opad, 0, block_size); + rte_memcpy(ipad, auth_key, auth_keylen); + rte_memcpy(opad, auth_key, auth_keylen); + + for (i = 0; i < block_size; i++) { + uint8_t *ipad_ptr = ipad + i; + uint8_t *opad_ptr = opad + i; + *ipad_ptr ^= HMAC_IPAD_VALUE; + *opad_ptr ^= HMAC_OPAD_VALUE; + } + + /* do partial hash of ipad and copy to state1 */ + if (partial_hash_compute_ipsec_mb(hash_alg, ipad, p_state_buf, m)) { + QAT_LOG(ERR, "ipad precompute failed"); + ret = -EFAULT; + goto out; + } + + /* + * State len is a multiple of 8, so may be larger than the digest. + * Put the partial hash of opad state_len bytes after state1 + */ + *p_state_len = qat_hash_get_state1_size(hash_alg); + if (partial_hash_compute_ipsec_mb(hash_alg, opad, + p_state_buf + *p_state_len, m)) { + QAT_LOG(ERR, "opad precompute failed"); + ret = -EFAULT; + goto out; + } + +out: + /* don't leave data lying around */ + memset(ipad, 0, block_size); + memset(opad, 0, block_size); + free_mb_mgr(m); + return ret; +} +#endif static int partial_hash_sha1(uint8_t *data_in, uint8_t *data_out) { SHA_CTX ctx; @@ -1126,6 +1407,20 @@ static int partial_hash_md5(uint8_t *data_in, uint8_t *data_out) return 0; } +static void aes_cmac_key_derive(uint8_t *base, uint8_t *derived) +{ + int i; + + derived[0] = base[0] << 1; + for (i = 1; i < ICP_QAT_HW_AES_BLK_SZ ; i++) { + derived[i] = base[i] << 1; + derived[i - 1] |= base[i] >> 7; + } + + if (base[0] & 0x80) + derived[ICP_QAT_HW_AES_BLK_SZ - 1] ^= QAT_AES_CMAC_CONST_RB; +} + static int partial_hash_compute(enum icp_qat_hw_auth_algo hash_alg, uint8_t *data_in, uint8_t *data_out) @@ -1194,25 +1489,6 @@ partial_hash_compute(enum icp_qat_hw_auth_algo hash_alg, return 0; } -#define HMAC_IPAD_VALUE 0x36 -#define HMAC_OPAD_VALUE 0x5c -#define HASH_XCBC_PRECOMP_KEY_NUM 3 - -static const uint8_t AES_CMAC_SEED[ICP_QAT_HW_AES_128_KEY_SZ]; - -static void aes_cmac_key_derive(uint8_t *base, uint8_t *derived) -{ - int i; - - derived[0] = base[0] << 1; - for (i = 1; i < ICP_QAT_HW_AES_BLK_SZ ; i++) { - derived[i] = base[i] << 1; - derived[i - 1] |= base[i] >> 7; - } - - if (base[0] & 0x80) - derived[ICP_QAT_HW_AES_BLK_SZ - 1] ^= QAT_AES_CMAC_CONST_RB; -} static int qat_sym_do_precomputes(enum icp_qat_hw_auth_algo hash_alg, const uint8_t *auth_key, @@ -1697,6 +1973,7 @@ int qat_sym_cd_auth_set(struct qat_sym_session *cdesc, uint32_t *aad_len = NULL; uint32_t wordIndex = 0; uint32_t *pTempKey; + int ret = 0; if (cdesc->qat_cmd == ICP_QAT_FW_LA_CMD_AUTH) { ICP_QAT_FW_COMN_CURR_ID_SET(hash_cd_ctrl, @@ -1768,9 +2045,22 @@ int qat_sym_cd_auth_set(struct qat_sym_session *cdesc, break; } /* SHA-1 HMAC */ - if (qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA1, authkey, - authkeylen, cdesc->cd_cur_ptr, &state1_size, - cdesc->aes_cmac)) { + if (qat_ipsec_mb_lib) { +#ifdef RTE_QAT_LIBIPSECMB + ret = qat_sym_do_precomputes_ipsec_mb(ICP_QAT_HW_AUTH_ALGO_SHA1, + authkey, authkeylen, cdesc->cd_cur_ptr, &state1_size, + cdesc->aes_cmac); +#else + QAT_LOG(ERR, "Intel IPSEC-MB LIB missing ?"); + return -EFAULT; +#endif + } else { + ret = qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA1, authkey, + authkeylen, cdesc->cd_cur_ptr, &state1_size, + cdesc->aes_cmac); + } + + if (ret) { QAT_LOG(ERR, "(SHA)precompute failed"); return -EFAULT; } @@ -1786,9 +2076,22 @@ int qat_sym_cd_auth_set(struct qat_sym_session *cdesc, break; } /* SHA-224 HMAC */ - if (qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA224, authkey, - authkeylen, cdesc->cd_cur_ptr, &state1_size, - cdesc->aes_cmac)) { + if (qat_ipsec_mb_lib) { +#ifdef RTE_QAT_LIBIPSECMB + ret = qat_sym_do_precomputes_ipsec_mb(ICP_QAT_HW_AUTH_ALGO_SHA224, + authkey, authkeylen, cdesc->cd_cur_ptr, &state1_size, + cdesc->aes_cmac); +#else + QAT_LOG(ERR, "Intel IPSEC-MB LIB missing ?"); + return -EFAULT; +#endif + } else { + ret = qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA224, authkey, + authkeylen, cdesc->cd_cur_ptr, &state1_size, + cdesc->aes_cmac); + } + + if (ret) { QAT_LOG(ERR, "(SHA)precompute failed"); return -EFAULT; } @@ -1804,9 +2107,22 @@ int qat_sym_cd_auth_set(struct qat_sym_session *cdesc, break; } /* SHA-256 HMAC */ - if (qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA256, authkey, - authkeylen, cdesc->cd_cur_ptr, &state1_size, - cdesc->aes_cmac)) { + if (qat_ipsec_mb_lib) { +#ifdef RTE_QAT_LIBIPSECMB + ret = qat_sym_do_precomputes_ipsec_mb(ICP_QAT_HW_AUTH_ALGO_SHA256, + authkey, authkeylen, cdesc->cd_cur_ptr, &state1_size, + cdesc->aes_cmac); +#else + QAT_LOG(ERR, "Intel IPSEC-MB LIB missing ?"); + return -EFAULT; +#endif + } else { + ret = qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA256, authkey, + authkeylen, cdesc->cd_cur_ptr, &state1_size, + cdesc->aes_cmac); + } + + if (ret) { QAT_LOG(ERR, "(SHA)precompute failed"); return -EFAULT; } @@ -1822,9 +2138,22 @@ int qat_sym_cd_auth_set(struct qat_sym_session *cdesc, break; } /* SHA-384 HMAC */ - if (qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA384, authkey, - authkeylen, cdesc->cd_cur_ptr, &state1_size, - cdesc->aes_cmac)) { + if (qat_ipsec_mb_lib) { +#ifdef RTE_QAT_LIBIPSECMB + ret = qat_sym_do_precomputes_ipsec_mb(ICP_QAT_HW_AUTH_ALGO_SHA384, + authkey, authkeylen, cdesc->cd_cur_ptr, &state1_size, + cdesc->aes_cmac); +#else + QAT_LOG(ERR, "Intel IPSEC-MB LIB missing ?"); + return -EFAULT; +#endif + } else { + ret = qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA384, authkey, + authkeylen, cdesc->cd_cur_ptr, &state1_size, + cdesc->aes_cmac); + } + + if (ret) { QAT_LOG(ERR, "(SHA)precompute failed"); return -EFAULT; } @@ -1840,9 +2169,22 @@ int qat_sym_cd_auth_set(struct qat_sym_session *cdesc, break; } /* SHA-512 HMAC */ - if (qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA512, authkey, - authkeylen, cdesc->cd_cur_ptr, &state1_size, - cdesc->aes_cmac)) { + if (qat_ipsec_mb_lib) { +#ifdef RTE_QAT_LIBIPSECMB + ret = qat_sym_do_precomputes_ipsec_mb(ICP_QAT_HW_AUTH_ALGO_SHA512, + authkey, authkeylen, cdesc->cd_cur_ptr, &state1_size, + cdesc->aes_cmac); +#else + QAT_LOG(ERR, "Intel IPSEC-MB LIB missing ?"); + return -EFAULT; +#endif + } else { + ret = qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_SHA512, authkey, + authkeylen, cdesc->cd_cur_ptr, &state1_size, + cdesc->aes_cmac); + } + + if (ret) { QAT_LOG(ERR, "(SHA)precompute failed"); return -EFAULT; } @@ -1853,9 +2195,23 @@ int qat_sym_cd_auth_set(struct qat_sym_session *cdesc, if (cdesc->aes_cmac) memset(cdesc->cd_cur_ptr, 0, state1_size); - if (qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_AES_XCBC_MAC, - authkey, authkeylen, cdesc->cd_cur_ptr + state1_size, - &state2_size, cdesc->aes_cmac)) { + if (qat_ipsec_mb_lib) { +#ifdef RTE_QAT_LIBIPSECMB + ret = qat_sym_do_precomputes_ipsec_mb( + ICP_QAT_HW_AUTH_ALGO_AES_XCBC_MAC, + authkey, authkeylen, cdesc->cd_cur_ptr + state1_size, + &state2_size, cdesc->aes_cmac); +#else + QAT_LOG(ERR, "Intel IPSEC-MB LIB missing ?"); + return -EFAULT; +#endif + } else { + ret = qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_AES_XCBC_MAC, + authkey, authkeylen, cdesc->cd_cur_ptr + state1_size, + &state2_size, cdesc->aes_cmac); + } + + if (ret) { cdesc->aes_cmac ? QAT_LOG(ERR, "(CMAC)precompute failed") : QAT_LOG(ERR, @@ -1867,9 +2223,22 @@ int qat_sym_cd_auth_set(struct qat_sym_session *cdesc, case ICP_QAT_HW_AUTH_ALGO_GALOIS_64: cdesc->qat_proto_flag = QAT_CRYPTO_PROTO_FLAG_GCM; state1_size = ICP_QAT_HW_GALOIS_128_STATE1_SZ; - if (qat_sym_do_precomputes(cdesc->qat_hash_alg, authkey, - authkeylen, cdesc->cd_cur_ptr + state1_size, - &state2_size, cdesc->aes_cmac)) { + if (qat_ipsec_mb_lib) { +#ifdef RTE_QAT_LIBIPSECMB + ret = qat_sym_do_precomputes_ipsec_mb(cdesc->qat_hash_alg, authkey, + authkeylen, cdesc->cd_cur_ptr + state1_size, + &state2_size, cdesc->aes_cmac); +#else + QAT_LOG(ERR, "Intel IPSEC-MB LIB missing ?"); + return -EFAULT; +#endif + } else { + ret = qat_sym_do_precomputes(cdesc->qat_hash_alg, authkey, + authkeylen, cdesc->cd_cur_ptr + state1_size, + &state2_size, cdesc->aes_cmac); + } + + if (ret) { QAT_LOG(ERR, "(GCM)precompute failed"); return -EFAULT; } @@ -1925,9 +2294,22 @@ int qat_sym_cd_auth_set(struct qat_sym_session *cdesc, break; case ICP_QAT_HW_AUTH_ALGO_MD5: - if (qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_MD5, authkey, - authkeylen, cdesc->cd_cur_ptr, &state1_size, - cdesc->aes_cmac)) { + if (qat_ipsec_mb_lib) { +#ifdef RTE_QAT_LIBIPSECMB + ret = qat_sym_do_precomputes_ipsec_mb(ICP_QAT_HW_AUTH_ALGO_MD5, + authkey, authkeylen, cdesc->cd_cur_ptr, &state1_size, + cdesc->aes_cmac); +#else + QAT_LOG(ERR, "Intel IPSEC-MB LIB missing"); + return -EFAULT; +#endif + } else { + ret = qat_sym_do_precomputes(ICP_QAT_HW_AUTH_ALGO_MD5, authkey, + authkeylen, cdesc->cd_cur_ptr, &state1_size, + cdesc->aes_cmac); + } + + if (ret) { QAT_LOG(ERR, "(MD5)precompute failed"); return -EFAULT; } -- 2.17.1 ^ permalink raw reply [flat|nested] 9+ messages in thread
* RE: [dpdk-dev v7] crypto/qat: use intel-ipsec-mb for partial hash & aes 2022-06-13 17:02 ` [dpdk-dev v7] " Kai Ji @ 2022-06-17 11:26 ` Power, Ciara 2022-06-21 17:45 ` Akhil Goyal 0 siblings, 1 reply; 9+ messages in thread From: Power, Ciara @ 2022-06-17 11:26 UTC (permalink / raw) To: Ji, Kai, dev; +Cc: gakhil, Ji, Kai, Zhang, Roy Fan Hi Kai, > -----Original Message----- > From: Kai Ji <kai.ji@intel.com> > Sent: Monday 13 June 2022 18:03 > To: dev@dpdk.org > Cc: gakhil@marvell.com; Ji, Kai <kai.ji@intel.com>; Zhang, Roy Fan > <roy.fan.zhang@intel.com> > Subject: [dpdk-dev v7] crypto/qat: use intel-ipsec-mb for partial hash & aes > > Since openssl 3.0 now deprecates the low level API QAT required to perform > partial hash & aes operation when creating the session. This patch add in > qat_ipsec_mb_lib driver parameter to allow QAT PMD to switch APIs > between openssl and intel ipsec-mb library. > > Signed-off-by: Kai Ji <kai.ji@intel.com> > Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com> > Acked-by: Ciara Power <ciara.power@intel.com> ^ permalink raw reply [flat|nested] 9+ messages in thread
* RE: [dpdk-dev v7] crypto/qat: use intel-ipsec-mb for partial hash & aes 2022-06-17 11:26 ` Power, Ciara @ 2022-06-21 17:45 ` Akhil Goyal 0 siblings, 0 replies; 9+ messages in thread From: Akhil Goyal @ 2022-06-21 17:45 UTC (permalink / raw) To: Power, Ciara, Ji, Kai, dev; +Cc: Ji, Kai, Zhang, Roy Fan > Hi Kai, > > > Since openssl 3.0 now deprecates the low level API QAT required to perform > > partial hash & aes operation when creating the session. This patch add in > > qat_ipsec_mb_lib driver parameter to allow QAT PMD to switch APIs > > between openssl and intel ipsec-mb library. > > > > Signed-off-by: Kai Ji <kai.ji@intel.com> > > Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com> > Acked-by: Ciara Power <ciara.power@intel.com> Applied to dpdk-next-crypto ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2022-06-21 17:45 UTC | newest] Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- [not found] <http://patches.dpdk.org/project/dpdk/patch/20220525165218.10926-1-kai.ji@intel.com/> 2022-05-26 10:47 ` [dpdk-dev v4] crypto/qat: use intel-ipsec-mb for partial hash & aes Kai Ji 2022-05-26 13:43 ` [EXT] " Akhil Goyal 2022-05-26 13:43 ` Akhil Goyal 2022-05-27 8:55 ` [dpdk-dev v5] " Kai Ji 2022-05-27 12:26 ` Zhang, Roy Fan 2022-05-30 10:21 ` [dpdk-dev v6] " Kai Ji 2022-06-13 17:02 ` [dpdk-dev v7] " Kai Ji 2022-06-17 11:26 ` Power, Ciara 2022-06-21 17:45 ` Akhil Goyal
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).