From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by dpdk.org (Postfix) with ESMTP id B09105A35 for ; Tue, 15 Sep 2015 18:27:49 +0200 (CEST) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga103.fm.intel.com with ESMTP; 15 Sep 2015 09:27:48 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.17,536,1437462000"; d="scan'208";a="805698454" Received: from unknown (HELO localhost.ir.intel.com) ([163.33.213.150]) by fmsmga002.fm.intel.com with ESMTP; 15 Sep 2015 09:27:46 -0700 From: Declan Doherty To: dev@dpdk.org Date: Tue, 15 Sep 2015 17:36:13 +0100 Message-Id: <1442334973-31247-1-git-send-email-declan.doherty@intel.com> X-Mailer: git-send-email 2.4.3 In-Reply-To: <20150820190733.GA22871@hmsreliant.think-freely.org> References: <20150820190733.GA22871@hmsreliant.think-freely.org> Subject: [dpdk-dev] [PATCH] cryptodev: changes to crypto operation APIs to support non prescriptive chaining of crypto transforms in a crypto operation. app/test: updates to cryptodev unit tests to support new xform chaining APIs. aesni_mb_pmd: updates to device to support API changes X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 15 Sep 2015 16:27:51 -0000 Proposed changes to cryptodev API for comment based on Neil's comments on the initial RFC. I have included the updates to the cryptodev unit test suite and the AESNI multi buffer PMD for illustrative purposes, I will include the changes for the QAT in a V1 patchset if the proposes changes to the API are acceptable. Signed-off-by: Declan Doherty --- app/test/test_cryptodev.c | 276 +++++++++++++++------ drivers/crypto/aesni_mb/aesni_mb_ops.h | 2 +- drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c | 188 +++++++++----- drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c | 10 +- drivers/crypto/aesni_mb/rte_aesni_mb_pmd_private.h | 28 ++- lib/librte_cryptodev/rte_crypto.h | 141 ++++++++--- lib/librte_cryptodev/rte_cryptodev.c | 54 ++-- lib/librte_cryptodev/rte_cryptodev.h | 26 +- lib/librte_cryptodev/rte_cryptodev_pmd.h | 10 +- 9 files changed, 506 insertions(+), 229 deletions(-) diff --git a/app/test/test_cryptodev.c b/app/test/test_cryptodev.c index 68cc0bf..93b7e0a 100644 --- a/app/test/test_cryptodev.c +++ b/app/test/test_cryptodev.c @@ -62,6 +62,8 @@ #define DIGEST_BYTE_LENGTH_SHA1 (BYTE_LENGTH(160)) #define DIGEST_BYTE_LENGTH_SHA256 (BYTE_LENGTH(256)) #define DIGEST_BYTE_LENGTH_SHA512 (BYTE_LENGTH(512)) +#define DIGEST_BYTE_LENGTH_AES_XCBC (BYTE_LENGTH(96)) +#define AES_XCBC_MAC_KEY_SZ (16) #define TRUNCATED_DIGEST_BYTE_LENGTH_SHA1 (12) #define TRUNCATED_DIGEST_BYTE_LENGTH_SHA256 (16) @@ -75,13 +77,13 @@ struct crypto_testsuite_params { struct rte_cryptodev_config conf; struct rte_cryptodev_qp_conf qp_conf; - uint8_t valid_devs[RTE_MAX_CRYPTODEVS]; + uint8_t valid_devs[RTE_CRYPTO_MAX_DEVS]; uint8_t valid_dev_count; }; struct crypto_unittest_params { - struct rte_crypto_cipher_params cipher_params; - struct rte_crypto_hash_params hash_params; + struct rte_crypto_xform cipher_xform; + struct rte_crypto_xform auth_xform; struct rte_cryptodev_session *sess; @@ -92,6 +94,17 @@ struct crypto_unittest_params { uint8_t *digest; }; +/* + * Forward declarations. + */ +static int +test_AES_CBC_HMAC_SHA512_decrypt_create_session_params(struct crypto_unittest_params *ut_params); + +static int +test_AES_CBC_HMAC_SHA512_decrypt_perform(struct rte_cryptodev_session *sess, + struct crypto_unittest_params *ut_params, + struct crypto_testsuite_params *ts_param); + static struct rte_mbuf * setup_test_string(struct rte_mempool *mpool, const char *string, size_t len, uint8_t blocksize) @@ -184,7 +197,7 @@ testsuite_setup(void) } ts_params->crypto_op_pool = rte_crypto_op_pool_create("CRYPTO_OP_POOL", - NUM_MBUFS, MBUF_CACHE_SIZE, rte_socket_id()); + NUM_MBUFS, MBUF_CACHE_SIZE, 2, rte_socket_id()); if (ts_params->crypto_op_pool == NULL) { RTE_LOG(ERR, USER1, "Can't create CRYPTO_OP_POOL\n"); return TEST_FAILED; @@ -436,6 +449,11 @@ static const uint8_t catch_22_quote_2_512_bytes_AES_CBC_ciphertext[] = { 0X95, 0XBB, 0X26, 0X74, 0X69, 0X12, 0X7F, 0XF1, 0XBB, 0XFF, 0XAE, 0XB5, 0X99, 0X6E, 0XCB, 0X0C }; +static const uint8_t catch_22_quote_2_512_bytes_AES_CBC_HMAC_SHA1_digest[] = { + 0x9a, 0X4f, 0X88, 0X1b, 0Xb6, 0X8f, 0Xd8, 0X60, + 0X42, 0X1a, 0X7d, 0X3d, 0Xf5, 0X82, 0X80, 0Xf1, + 0X18, 0X8c, 0X1d, 0X32 }; + static int test_AES_CBC_HMAC_SHA1_encrypt_digest(void) @@ -452,22 +470,28 @@ test_AES_CBC_HMAC_SHA1_encrypt_digest(void) TEST_ASSERT_NOT_NULL(ut_params->digest, "no room to append digest"); /* Setup Cipher Parameters */ - ut_params->cipher_params.algo = RTE_CRYPTO_SYM_CIPHER_AES_CBC; - ut_params->cipher_params.op = RTE_CRYPTO_SYM_CIPHER_OP_ENCRYPT; - ut_params->cipher_params.key.data = aes_cbc_key; - ut_params->cipher_params.key.length = CIPHER_KEY_LENGTH_AES_CBC; + ut_params->cipher_xform.type = RTE_CRYPTO_XFORM_CIPHER; + ut_params->cipher_xform.next = &ut_params->auth_xform; + + ut_params->cipher_xform.cipher.algo = RTE_CRYPTO_SYM_CIPHER_AES_CBC; + ut_params->cipher_xform.cipher.op = RTE_CRYPTO_SYM_CIPHER_OP_ENCRYPT; + ut_params->cipher_xform.cipher.key.data = aes_cbc_key; + ut_params->cipher_xform.cipher.key.length = CIPHER_KEY_LENGTH_AES_CBC; /* Setup HMAC Parameters */ - ut_params->hash_params.op = RTE_CRYPTO_SYM_HASH_OP_DIGEST_GENERATE; - ut_params->hash_params.algo = RTE_CRYPTO_SYM_HASH_SHA1_HMAC; - ut_params->hash_params.auth_key.length = HMAC_KEY_LENGTH_SHA1; - ut_params->hash_params.auth_key.data = hmac_sha1_key; - ut_params->hash_params.digest_length = DIGEST_BYTE_LENGTH_SHA1; + + ut_params->auth_xform.type = RTE_CRYPTO_XFORM_AUTH; + ut_params->auth_xform.next = NULL; + + ut_params->auth_xform.auth.op = RTE_CRYPTO_SYM_HASH_OP_DIGEST_GENERATE; + ut_params->auth_xform.auth.algo = RTE_CRYPTO_SYM_HASH_SHA1_HMAC; + ut_params->auth_xform.auth.key.length = HMAC_KEY_LENGTH_SHA1; + ut_params->auth_xform.auth.key.data = hmac_sha1_key; + ut_params->auth_xform.auth.digest_length = DIGEST_BYTE_LENGTH_SHA1; /* Create Crypto session*/ ut_params->sess = rte_cryptodev_session_create(ts_params->valid_devs[0], - &ut_params->cipher_params, &ut_params->hash_params, - RTE_CRYPTO_SYM_OPCHAIN_CIPHER_HASH); + &ut_params->cipher_xform); TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed"); /* Generate Crypto op data structure */ @@ -522,6 +546,88 @@ test_AES_CBC_HMAC_SHA1_encrypt_digest(void) return TEST_SUCCESS; } + +static int +test_AES_CBC_HMAC_SHA1_encrypt_digest_sessionless(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct crypto_unittest_params *ut_params = &unittest_params; + + /* Generate test mbuf data and space for digest */ + ut_params->ibuf = setup_test_string(ts_params->mbuf_pool, catch_22_quote, + QUOTE_512_BYTES, 0); + + ut_params->digest = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf, + DIGEST_BYTE_LENGTH_SHA1); + TEST_ASSERT_NOT_NULL(ut_params->digest, "no room to append digest"); + + /* Generate Crypto op data structure */ + ut_params->op = rte_crypto_op_alloc_sessionless(ts_params->crypto_op_pool, 2); + TEST_ASSERT_NOT_NULL(ut_params->op, "Failed to allocate crypto_op"); + + /* Set crypto operation data parameters */ + ut_params->op->xform->type = RTE_CRYPTO_XFORM_CIPHER; + + /* cipher parameters */ + ut_params->op->xform->cipher.op = RTE_CRYPTO_SYM_CIPHER_OP_ENCRYPT; + ut_params->op->xform->cipher.algo = RTE_CRYPTO_SYM_CIPHER_AES_CBC; + ut_params->op->xform->cipher.key.data = aes_cbc_key; + ut_params->op->xform->cipher.key.length = CIPHER_KEY_LENGTH_AES_CBC; + + /* hash parameters */ + ut_params->op->xform->next->type = RTE_CRYPTO_XFORM_AUTH; + + ut_params->op->xform->next->auth.op = RTE_CRYPTO_SYM_HASH_OP_DIGEST_GENERATE; + ut_params->op->xform->next->auth.algo = RTE_CRYPTO_SYM_HASH_SHA1_HMAC; + ut_params->op->xform->next->auth.key.length = HMAC_KEY_LENGTH_SHA1; + ut_params->op->xform->next->auth.key.data = hmac_sha1_key; + ut_params->op->xform->next->auth.digest_length = DIGEST_BYTE_LENGTH_SHA1; + + ut_params->op->digest.data = ut_params->digest; + ut_params->op->digest.phys_addr = rte_pktmbuf_mtophys_offset(ut_params->ibuf, + QUOTE_512_BYTES); + ut_params->op->digest.length = DIGEST_BYTE_LENGTH_SHA1; + + ut_params->op->iv.data = (uint8_t *)rte_pktmbuf_prepend(ut_params->ibuf, + CIPHER_IV_LENGTH_AES_CBC); + ut_params->op->iv.phys_addr = rte_pktmbuf_mtophys(ut_params->ibuf); + ut_params->op->iv.length = CIPHER_IV_LENGTH_AES_CBC; + + rte_memcpy(ut_params->op->iv.data, aes_cbc_iv, CIPHER_IV_LENGTH_AES_CBC); + + ut_params->op->data.to_cipher.offset = CIPHER_IV_LENGTH_AES_CBC; + ut_params->op->data.to_cipher.length = QUOTE_512_BYTES; + ut_params->op->data.to_hash.offset = CIPHER_IV_LENGTH_AES_CBC; + ut_params->op->data.to_hash.length = QUOTE_512_BYTES; + + rte_pktmbuf_attach_crypto_op(ut_params->ibuf, ut_params->op); + + /* Process crypto operation */ + ut_params->obuf = process_crypto_request(ts_params->valid_devs[0], + ut_params->ibuf); + TEST_ASSERT_NOT_NULL(ut_params->obuf, "failed to retrieve obuf"); + + /* Validate obuf */ + TEST_ASSERT_BUFFERS_ARE_EQUAL( + rte_pktmbuf_mtod(ut_params->obuf, uint8_t *) + + CIPHER_IV_LENGTH_AES_CBC, + catch_22_quote_2_512_bytes_AES_CBC_ciphertext, + QUOTE_512_BYTES, + "Ciphertext data not as expected"); + + TEST_ASSERT_BUFFERS_ARE_EQUAL( + rte_pktmbuf_mtod(ut_params->obuf, uint8_t *) + + CIPHER_IV_LENGTH_AES_CBC + QUOTE_512_BYTES, + catch_22_quote_2_512_bytes_AES_CBC_HMAC_SHA1_digest, + gbl_cryptodev_type == RTE_CRYPTODEV_AESNI_MB_PMD ? + TRUNCATED_DIGEST_BYTE_LENGTH_SHA1 : + DIGEST_BYTE_LENGTH_SHA1, + "Generated digest data not as expected"); + + free_testsuite_mbufs(); + return TEST_SUCCESS; +} + static int test_AES_CBC_HMAC_SHA1_decrypt_digest_verify(void) { @@ -542,22 +648,27 @@ test_AES_CBC_HMAC_SHA1_decrypt_digest_verify(void) DIGEST_BYTE_LENGTH_SHA1); /* Setup Cipher Parameters */ - ut_params->cipher_params.algo = RTE_CRYPTO_SYM_CIPHER_AES_CBC; - ut_params->cipher_params.op = RTE_CRYPTO_SYM_CIPHER_OP_DECRYPT; - ut_params->cipher_params.key.data = aes_cbc_key; - ut_params->cipher_params.key.length = CIPHER_KEY_LENGTH_AES_CBC; + ut_params->cipher_xform.type = RTE_CRYPTO_XFORM_CIPHER; + ut_params->cipher_xform.next = NULL; + + ut_params->cipher_xform.cipher.algo = RTE_CRYPTO_SYM_CIPHER_AES_CBC; + ut_params->cipher_xform.cipher.op = RTE_CRYPTO_SYM_CIPHER_OP_DECRYPT; + ut_params->cipher_xform.cipher.key.data = aes_cbc_key; + ut_params->cipher_xform.cipher.key.length = CIPHER_KEY_LENGTH_AES_CBC; /* Setup HMAC Parameters */ - ut_params->hash_params.op = RTE_CRYPTO_SYM_HASH_OP_DIGEST_VERIFY; - ut_params->hash_params.algo = RTE_CRYPTO_SYM_HASH_SHA1_HMAC; - ut_params->hash_params.auth_key.length = HMAC_KEY_LENGTH_SHA1; - ut_params->hash_params.auth_key.data = hmac_sha1_key; - ut_params->hash_params.digest_length = DIGEST_BYTE_LENGTH_SHA1; + ut_params->auth_xform.type = RTE_CRYPTO_XFORM_AUTH; + ut_params->auth_xform.next = &ut_params->cipher_xform; + + ut_params->auth_xform.auth.op = RTE_CRYPTO_SYM_HASH_OP_DIGEST_VERIFY; + ut_params->auth_xform.auth.algo = RTE_CRYPTO_SYM_HASH_SHA1_HMAC; + ut_params->auth_xform.auth.key.length = HMAC_KEY_LENGTH_SHA1; + ut_params->auth_xform.auth.key.data = hmac_sha1_key; + ut_params->auth_xform.auth.digest_length = DIGEST_BYTE_LENGTH_SHA1; /* Create Crypto session*/ ut_params->sess = rte_cryptodev_session_create(ts_params->valid_devs[0], - &ut_params->cipher_params, &ut_params->hash_params, - RTE_CRYPTO_SYM_OPCHAIN_HASH_CIPHER); + &ut_params->auth_xform); TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed"); /* Generate Crypto op data structure */ @@ -641,22 +752,27 @@ test_AES_CBC_HMAC_SHA256_encrypt_digest(void) TEST_ASSERT_NOT_NULL(ut_params->digest, "no room to append digest"); /* Setup Cipher Parameters */ - ut_params->cipher_params.algo = RTE_CRYPTO_SYM_CIPHER_AES_CBC; - ut_params->cipher_params.op = RTE_CRYPTO_SYM_CIPHER_OP_ENCRYPT; - ut_params->cipher_params.key.data = aes_cbc_key; - ut_params->cipher_params.key.length = CIPHER_KEY_LENGTH_AES_CBC; + ut_params->cipher_xform.type = RTE_CRYPTO_XFORM_CIPHER; + ut_params->cipher_xform.next = &ut_params->auth_xform; + + ut_params->cipher_xform.cipher.algo = RTE_CRYPTO_SYM_CIPHER_AES_CBC; + ut_params->cipher_xform.cipher.op = RTE_CRYPTO_SYM_CIPHER_OP_ENCRYPT; + ut_params->cipher_xform.cipher.key.data = aes_cbc_key; + ut_params->cipher_xform.cipher.key.length = CIPHER_KEY_LENGTH_AES_CBC; /* Setup HMAC Parameters */ - ut_params->hash_params.op = RTE_CRYPTO_SYM_HASH_OP_DIGEST_GENERATE; - ut_params->hash_params.algo = RTE_CRYPTO_SYM_HASH_SHA256_HMAC; - ut_params->hash_params.auth_key.length = HMAC_KEY_LENGTH_SHA256; - ut_params->hash_params.auth_key.data = hmac_sha256_key; - ut_params->hash_params.digest_length = DIGEST_BYTE_LENGTH_SHA256; + ut_params->auth_xform.type = RTE_CRYPTO_XFORM_AUTH; + ut_params->auth_xform.next = NULL; + + ut_params->auth_xform.auth.op = RTE_CRYPTO_SYM_HASH_OP_DIGEST_GENERATE; + ut_params->auth_xform.auth.algo = RTE_CRYPTO_SYM_HASH_SHA256_HMAC; + ut_params->auth_xform.auth.key.length = HMAC_KEY_LENGTH_SHA256; + ut_params->auth_xform.auth.key.data = hmac_sha256_key; + ut_params->auth_xform.auth.digest_length = DIGEST_BYTE_LENGTH_SHA256; /* Create Crypto session*/ ut_params->sess = rte_cryptodev_session_create(ts_params->valid_devs[0], - &ut_params->cipher_params, &ut_params->hash_params, - RTE_CRYPTO_SYM_OPCHAIN_CIPHER_HASH); + &ut_params->cipher_xform); TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed"); /* Generate Crypto op data structure */ @@ -731,22 +847,27 @@ test_AES_CBC_HMAC_SHA256_decrypt_digest_verify(void) DIGEST_BYTE_LENGTH_SHA256); /* Setup Cipher Parameters */ - ut_params->cipher_params.algo = RTE_CRYPTO_SYM_CIPHER_AES_CBC; - ut_params->cipher_params.op = RTE_CRYPTO_SYM_CIPHER_OP_DECRYPT; - ut_params->cipher_params.key.data = aes_cbc_key; - ut_params->cipher_params.key.length = CIPHER_KEY_LENGTH_AES_CBC; + ut_params->cipher_xform.type = RTE_CRYPTO_XFORM_CIPHER; + ut_params->cipher_xform.next = NULL; + + ut_params->cipher_xform.cipher.algo = RTE_CRYPTO_SYM_CIPHER_AES_CBC; + ut_params->cipher_xform.cipher.op = RTE_CRYPTO_SYM_CIPHER_OP_DECRYPT; + ut_params->cipher_xform.cipher.key.data = aes_cbc_key; + ut_params->cipher_xform.cipher.key.length = CIPHER_KEY_LENGTH_AES_CBC; /* Setup HMAC Parameters */ - ut_params->hash_params.op = RTE_CRYPTO_SYM_HASH_OP_DIGEST_VERIFY; - ut_params->hash_params.algo = RTE_CRYPTO_SYM_HASH_SHA256_HMAC; - ut_params->hash_params.auth_key.data = hmac_sha256_key; - ut_params->hash_params.auth_key.length = HMAC_KEY_LENGTH_SHA256; - ut_params->hash_params.digest_length = DIGEST_BYTE_LENGTH_SHA256; + ut_params->auth_xform.type = RTE_CRYPTO_XFORM_AUTH; + ut_params->auth_xform.next = &ut_params->cipher_xform; + + ut_params->auth_xform.auth.op = RTE_CRYPTO_SYM_HASH_OP_DIGEST_VERIFY; + ut_params->auth_xform.auth.algo = RTE_CRYPTO_SYM_HASH_SHA256_HMAC; + ut_params->auth_xform.auth.key.data = hmac_sha256_key; + ut_params->auth_xform.auth.key.length = HMAC_KEY_LENGTH_SHA256; + ut_params->auth_xform.auth.digest_length = DIGEST_BYTE_LENGTH_SHA256; /* Create Crypto session*/ ut_params->sess = rte_cryptodev_session_create(ts_params->valid_devs[0], - &ut_params->cipher_params, &ut_params->hash_params, - RTE_CRYPTO_SYM_OPCHAIN_HASH_CIPHER); + &ut_params->auth_xform); TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed"); /* Generate Crypto op data structure */ @@ -837,22 +958,27 @@ test_AES_CBC_HMAC_SHA512_encrypt_digest(void) TEST_ASSERT_NOT_NULL(ut_params->digest, "no room to append digest"); /* Setup Cipher Parameters */ - ut_params->cipher_params.algo = RTE_CRYPTO_SYM_CIPHER_AES_CBC; - ut_params->cipher_params.op = RTE_CRYPTO_SYM_CIPHER_OP_ENCRYPT; - ut_params->cipher_params.key.data = aes_cbc_key; - ut_params->cipher_params.key.length = CIPHER_KEY_LENGTH_AES_CBC; + ut_params->cipher_xform.type = RTE_CRYPTO_XFORM_CIPHER; + ut_params->cipher_xform.next = &ut_params->auth_xform; + + ut_params->cipher_xform.cipher.algo = RTE_CRYPTO_SYM_CIPHER_AES_CBC; + ut_params->cipher_xform.cipher.op = RTE_CRYPTO_SYM_CIPHER_OP_ENCRYPT; + ut_params->cipher_xform.cipher.key.data = aes_cbc_key; + ut_params->cipher_xform.cipher.key.length = CIPHER_KEY_LENGTH_AES_CBC; /* Setup HMAC Parameters */ - ut_params->hash_params.op = RTE_CRYPTO_SYM_HASH_OP_DIGEST_GENERATE; - ut_params->hash_params.algo = RTE_CRYPTO_SYM_HASH_SHA512_HMAC; - ut_params->hash_params.auth_key.length = HMAC_KEY_LENGTH_SHA512; - ut_params->hash_params.auth_key.data = hmac_sha512_key; - ut_params->hash_params.digest_length = DIGEST_BYTE_LENGTH_SHA512; + ut_params->auth_xform.type = RTE_CRYPTO_XFORM_AUTH; + ut_params->auth_xform.next = NULL; + + ut_params->auth_xform.auth.op = RTE_CRYPTO_SYM_HASH_OP_DIGEST_GENERATE; + ut_params->auth_xform.auth.algo = RTE_CRYPTO_SYM_HASH_SHA512_HMAC; + ut_params->auth_xform.auth.key.length = HMAC_KEY_LENGTH_SHA512; + ut_params->auth_xform.auth.key.data = hmac_sha512_key; + ut_params->auth_xform.auth.digest_length = DIGEST_BYTE_LENGTH_SHA512; /* Create Crypto session*/ ut_params->sess = rte_cryptodev_session_create(ts_params->valid_devs[0], - &ut_params->cipher_params, &ut_params->hash_params, - RTE_CRYPTO_SYM_OPCHAIN_CIPHER_HASH); + &ut_params->cipher_xform); TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed"); @@ -931,8 +1057,7 @@ test_AES_CBC_HMAC_SHA512_decrypt_digest_verify(void) /* Create Crypto session*/ ut_params->sess = rte_cryptodev_session_create(ts_params->valid_devs[0], - &ut_params->cipher_params, &ut_params->hash_params, - RTE_CRYPTO_SYM_OPCHAIN_HASH_CIPHER); + &ut_params->auth_xform); TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed"); return test_AES_CBC_HMAC_SHA512_decrypt_perform(ut_params->sess, @@ -944,17 +1069,23 @@ test_AES_CBC_HMAC_SHA512_decrypt_create_session_params(struct crypto_unittest_pa { /* Setup Cipher Parameters */ - ut_params->cipher_params.algo = RTE_CRYPTO_SYM_CIPHER_AES_CBC; - ut_params->cipher_params.op = RTE_CRYPTO_SYM_CIPHER_OP_DECRYPT; - ut_params->cipher_params.key.data = aes_cbc_key; - ut_params->cipher_params.key.length = CIPHER_KEY_LENGTH_AES_CBC; + ut_params->cipher_xform.type = RTE_CRYPTO_XFORM_CIPHER; + ut_params->cipher_xform.next = NULL; + + ut_params->cipher_xform.cipher.algo = RTE_CRYPTO_SYM_CIPHER_AES_CBC; + ut_params->cipher_xform.cipher.op = RTE_CRYPTO_SYM_CIPHER_OP_DECRYPT; + ut_params->cipher_xform.cipher.key.data = aes_cbc_key; + ut_params->cipher_xform.cipher.key.length = CIPHER_KEY_LENGTH_AES_CBC; /* Setup HMAC Parameters */ - ut_params->hash_params.op = RTE_CRYPTO_SYM_HASH_OP_DIGEST_VERIFY; - ut_params->hash_params.algo = RTE_CRYPTO_SYM_HASH_SHA512_HMAC; - ut_params->hash_params.auth_key.data = hmac_sha512_key; - ut_params->hash_params.auth_key.length = HMAC_KEY_LENGTH_SHA512; - ut_params->hash_params.digest_length = DIGEST_BYTE_LENGTH_SHA512; + ut_params->auth_xform.type = RTE_CRYPTO_XFORM_AUTH; + ut_params->auth_xform.next = &ut_params->cipher_xform; + + ut_params->auth_xform.auth.op = RTE_CRYPTO_SYM_HASH_OP_DIGEST_VERIFY; + ut_params->auth_xform.auth.algo = RTE_CRYPTO_SYM_HASH_SHA512_HMAC; + ut_params->auth_xform.auth.key.data = hmac_sha512_key; + ut_params->auth_xform.auth.key.length = HMAC_KEY_LENGTH_SHA512; + ut_params->auth_xform.auth.digest_length = DIGEST_BYTE_LENGTH_SHA512; return TEST_SUCCESS; } @@ -1047,6 +1178,11 @@ static struct unit_test_suite cryptodev_testsuite = { TEST_CASE_ST(ut_setup, ut_teardown, test_AES_CBC_HMAC_SHA512_encrypt_digest), TEST_CASE_ST(ut_setup, ut_teardown, test_AES_CBC_HMAC_SHA512_decrypt_digest_verify), + TEST_CASE_ST(ut_setup, ut_teardown, test_AES_CBC_HMAC_AES_XCBC_encrypt_digest), + TEST_CASE_ST(ut_setup, ut_teardown, test_AES_CBC_HMAC_AES_XCBC_decrypt_digest_verify), + + TEST_CASE_ST(ut_setup, ut_teardown, test_AES_CBC_HMAC_SHA1_encrypt_digest_sessionless), + TEST_CASES_END() /**< NULL terminate unit test array */ } }; diff --git a/drivers/crypto/aesni_mb/aesni_mb_ops.h b/drivers/crypto/aesni_mb/aesni_mb_ops.h index ab96990..1188278 100644 --- a/drivers/crypto/aesni_mb/aesni_mb_ops.h +++ b/drivers/crypto/aesni_mb/aesni_mb_ops.h @@ -59,7 +59,7 @@ typedef void (*aes_keyexp_128_t)(void *key, void *enc_exp_keys, void *dec_exp_ke typedef void (*aes_keyexp_192_t)(void *key, void *enc_exp_keys, void *dec_exp_keys); typedef void (*aes_keyexp_256_t)(void *key, void *enc_exp_keys, void *dec_exp_keys); -typedef void (*aes_xcbc_expand_key_t)(void *key, void *k1_exp, void *k2, void *k3); +typedef void (*aes_xcbc_expand_key_t)(void *key, void *exp_k1, void *k2, void *k3); typedef void (*aesni_gcm_t)(gcm_data *my_ctx_data, u8 *out, const u8 *in, u64 plaintext_len, u8 *iv, const u8 *aad, u64 aad_len, diff --git a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c index 65a3731..506754e 100644 --- a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c +++ b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c @@ -104,31 +104,101 @@ calculate_auth_precomputes(hash_one_block_t one_block_hash, memset(opad_buf, 0, blocksize); } -int -aesni_mb_set_session_parameters(const struct aesni_mb_ops *mb_ops, +static int +aesni_mb_get_chain_order(const struct rte_crypto_xform *xform) +{ + /* multi-buffer only supports HASH_CIPHER or CIPHER_HASH chained + * operations, all other options are invalid, so we must have exactly + * 2 xform structs chained together */ + if (xform->next == NULL || xform->next->next != NULL) + return -1; + + if (xform->type == RTE_CRYPTO_XFORM_AUTH && + xform->next->type == RTE_CRYPTO_XFORM_CIPHER) + return HASH_CIPHER; + + if (xform->type == RTE_CRYPTO_XFORM_CIPHER && + xform->next->type == RTE_CRYPTO_XFORM_AUTH) + return CIPHER_HASH; + + return -1; +} + +static int +aesni_mb_set_session_auth_parameters(const struct aesni_mb_ops *mb_ops, struct aesni_mb_session *sess, - struct rte_crypto_cipher_params *cipher_params, - struct rte_crypto_hash_params *auth_params, - enum rte_crypto_operation_chain op_chain) + const struct rte_crypto_xform *xform) { - aes_keyexp_t aes_keyexp_fn; hash_one_block_t hash_oneblock_fn; - /* Select Crypto operation - hash then cipher / cipher then hash */ - switch (op_chain) { - case RTE_CRYPTO_SYM_OPCHAIN_HASH_CIPHER: - sess->chain_order = HASH_CIPHER; + if (xform->type != RTE_CRYPTO_XFORM_AUTH) { + MB_LOG_ERR("Crypto xform struct not of type auth"); + return -1; + } + + /* Set Authentication Parameters */ + if (xform->auth.algo == RTE_CRYPTO_SYM_HASH_AES_XCBC_MAC) { + sess->auth.algo = AES_XCBC; + (*mb_ops->aux.keyexp.aes_xcbc)(xform->auth.key.data, + sess->auth.xcbc.k1_expanded, + sess->auth.xcbc.k2, sess->auth.xcbc.k3); + return 0; + } + + switch (xform->auth.algo) { + case RTE_CRYPTO_SYM_HASH_MD5_HMAC: + sess->auth.algo = MD5; + hash_oneblock_fn = mb_ops->aux.one_block.md5; break; - case RTE_CRYPTO_SYM_OPCHAIN_CIPHER_HASH: - sess->chain_order = CIPHER_HASH; + case RTE_CRYPTO_SYM_HASH_SHA1_HMAC: + sess->auth.algo = SHA1; + hash_oneblock_fn = mb_ops->aux.one_block.sha1; + break; + case RTE_CRYPTO_SYM_HASH_SHA224_HMAC: + sess->auth.algo = SHA_224; + hash_oneblock_fn = mb_ops->aux.one_block.sha224; + break; + case RTE_CRYPTO_SYM_HASH_SHA256_HMAC: + sess->auth.algo = SHA_256; + hash_oneblock_fn = mb_ops->aux.one_block.sha256; + break; + case RTE_CRYPTO_SYM_HASH_SHA384_HMAC: + sess->auth.algo = SHA_384; + hash_oneblock_fn = mb_ops->aux.one_block.sha384; + break; + case RTE_CRYPTO_SYM_HASH_SHA512_HMAC: + sess->auth.algo = SHA_512; + hash_oneblock_fn = mb_ops->aux.one_block.sha512; break; default: - printf("unsupported operation chain order parameter"); + MB_LOG_ERR("Unsupported authentication algorithm selection"); + return -1; + } + + /* Calculate Authentication precomputes */ + calculate_auth_precomputes(hash_oneblock_fn, + sess->auth.pads.inner, sess->auth.pads.outer, + xform->auth.key.data, + xform->auth.key.length, + get_auth_algo_blocksize(sess->auth.algo)); + + return 0; +} + +static int +aesni_mb_set_session_cipher_parameters(const struct aesni_mb_ops *mb_ops, + struct aesni_mb_session *sess, + const struct rte_crypto_xform *xform) +{ + aes_keyexp_t aes_keyexp_fn; + + if (xform->type != RTE_CRYPTO_XFORM_CIPHER) { + MB_LOG_ERR("Crypto xform struct not of type cipher"); return -1; } /* Select cipher direction */ - switch (cipher_params->op) { + switch (xform->cipher.op) { case RTE_CRYPTO_SYM_CIPHER_OP_ENCRYPT: sess->cipher.direction = ENCRYPT; break; @@ -136,22 +206,22 @@ aesni_mb_set_session_parameters(const struct aesni_mb_ops *mb_ops, sess->cipher.direction = DECRYPT; break; default: - printf("unsupported cipher operation parameter"); + MB_LOG_ERR("Unsupported cipher operation parameter"); return -1; } /* Select cipher mode */ - switch (cipher_params->algo) { + switch (xform->cipher.algo) { case RTE_CRYPTO_SYM_CIPHER_AES_CBC: sess->cipher.mode = CBC; break; default: - printf("unsupported cipher mode parameter"); + MB_LOG_ERR("Unsupported cipher mode parameter"); return -1; } /* Check key length and choose key expansion function */ - switch (cipher_params->key.length) { + switch (xform->cipher.key.length) { case AES_128_BYTES: sess->cipher.key_length_in_bytes = AES_128_BYTES; aes_keyexp_fn = mb_ops->aux.keyexp.aes128; @@ -165,53 +235,53 @@ aesni_mb_set_session_parameters(const struct aesni_mb_ops *mb_ops, aes_keyexp_fn = mb_ops->aux.keyexp.aes256; break; default: - printf("unsupported cipher key length"); + MB_LOG_ERR("Unsupported cipher key length"); return -1; } /* Expanded cipher keys */ - (*aes_keyexp_fn)(cipher_params->key.data, + (*aes_keyexp_fn)(xform->cipher.key.data, sess->cipher.expanded_aes_keys.encode, sess->cipher.expanded_aes_keys.decode); - /* Set Authentication Parameters */ - switch (auth_params->algo) { - case RTE_CRYPTO_SYM_HASH_MD5_HMAC: - sess->auth.algo = MD5; - hash_oneblock_fn = mb_ops->aux.one_block.md5; - break; - case RTE_CRYPTO_SYM_HASH_SHA1_HMAC: - sess->auth.algo = SHA1; - hash_oneblock_fn = mb_ops->aux.one_block.sha1; - break; - case RTE_CRYPTO_SYM_HASH_SHA224_HMAC: - sess->auth.algo = SHA_224; - hash_oneblock_fn = mb_ops->aux.one_block.sha224; - break; - case RTE_CRYPTO_SYM_HASH_SHA256_HMAC: - sess->auth.algo = SHA_256; - hash_oneblock_fn = mb_ops->aux.one_block.sha256; - break; - case RTE_CRYPTO_SYM_HASH_SHA384_HMAC: - sess->auth.algo = SHA_384; - hash_oneblock_fn = mb_ops->aux.one_block.sha384; + return 0; +} + + +int +aesni_mb_set_session_parameters(const struct aesni_mb_ops *mb_ops, + struct aesni_mb_session *sess, + const struct rte_crypto_xform *xform) +{ + const struct rte_crypto_xform *auth_xform = NULL; + const struct rte_crypto_xform *cipher_xform = NULL; + + /* Select Crypto operation - hash then cipher / cipher then hash */ + switch (aesni_mb_get_chain_order(xform)) { + case HASH_CIPHER: + sess->chain_order = HASH_CIPHER; + auth_xform = xform; + cipher_xform = xform->next; break; - case RTE_CRYPTO_SYM_HASH_SHA512_HMAC: - sess->auth.algo = SHA_512; - hash_oneblock_fn = mb_ops->aux.one_block.sha512; + case CIPHER_HASH: + sess->chain_order = CIPHER_HASH; + auth_xform = xform->next; + cipher_xform = xform; break; default: - printf("unsupported authentication algorithm selection"); + MB_LOG_ERR("Unsupported operation chain order parameter"); return -1; } - /* Calculate Authentication precomputes */ - calculate_auth_precomputes(hash_oneblock_fn, - sess->auth.pads.inner, sess->auth.pads.outer, - auth_params->auth_key.data, - auth_params->auth_key.length, - get_auth_algo_blocksize(sess->auth.algo)); + if (aesni_mb_set_session_auth_parameters(mb_ops, sess, auth_xform)) { + MB_LOG_ERR("Invalid/unsupported authentication parameters"); + return -1; + } + if (aesni_mb_set_session_cipher_parameters(mb_ops, sess, cipher_xform)) { + MB_LOG_ERR("Invalid/unsupported cipher parameters"); + return -1; + } return 0; } @@ -239,9 +309,7 @@ process_crypto_op(struct aesni_mb_qp *qp, JOB_AES_HMAC *job, struct rte_mbuf *m) return NULL; if (unlikely(aesni_mb_set_session_parameters(qp->mb_ops, - sess, &c_op->op_params.cipher, - &c_op->op_params.hash, - c_op->op_params.opchain) != 0)) + sess, c_op->xform) != 0)) return NULL; } else { sess = (struct aesni_mb_session *)c_op->session; @@ -250,7 +318,6 @@ process_crypto_op(struct aesni_mb_qp *qp, JOB_AES_HMAC *job, struct rte_mbuf *m) /* Set crypto operation */ job->chain_order = sess->chain_order; - /* Set cipher parameters */ job->cipher_direction = sess->cipher.direction; job->cipher_mode = sess->cipher.mode; @@ -262,9 +329,14 @@ process_crypto_op(struct aesni_mb_qp *qp, JOB_AES_HMAC *job, struct rte_mbuf *m) /* Set authentication parameters */ job->hash_alg = sess->auth.algo; - job->hashed_auth_key_xor_ipad = sess->auth.pads.inner; - job->hashed_auth_key_xor_opad = sess->auth.pads.outer; - + if (job->hash_alg == AES_XCBC) { + job->_k1_expanded = sess->auth.xcbc.k1_expanded; + job->_k2 = sess->auth.xcbc.k2; + job->_k3 = sess->auth.xcbc.k3; + } else { + job->hashed_auth_key_xor_ipad = sess->auth.pads.inner; + job->hashed_auth_key_xor_opad = sess->auth.pads.outer; + } /* Mutable crypto operation parameters */ diff --git a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c index fb57e7b..d9cdd5b 100644 --- a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c +++ b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c @@ -286,9 +286,7 @@ aesni_mb_pmd_session_mempool_create(struct rte_cryptodev *dev, static struct rte_cryptodev_session * aesni_mb_pmd_create_session(struct rte_cryptodev *dev, - struct rte_crypto_cipher_params *cipher_setup_data, - struct rte_crypto_hash_params *hash_setup_data, - enum rte_crypto_operation_chain op_chain) + struct rte_crypto_xform *xform) { struct aesni_mb_private *internals = dev->data->dev_private; struct aesni_mb_session *sess = @@ -299,9 +297,9 @@ aesni_mb_pmd_create_session(struct rte_cryptodev *dev, return NULL; } - if (aesni_mb_set_session_parameters( - &job_ops[internals->vector_mode], sess, - cipher_setup_data, hash_setup_data, op_chain) != 0) { + if (aesni_mb_set_session_parameters(&job_ops[internals->vector_mode], + sess, xform) != 0) { + MB_LOG_ERR("failed configure session parameters"); aesni_mb_free_session(internals->sess_mp, sess); } diff --git a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_private.h b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_private.h index c5c4a86..abfec16 100644 --- a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_private.h +++ b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_private.h @@ -178,13 +178,21 @@ struct aesni_mb_session { struct { JOB_HASH_ALG algo; /** Authentication Algorithm */ - - struct { - uint8_t inner[128] __rte_align(16); /**< inner pad */ - uint8_t outer[128] __rte_align(16); /**< outer pad */ - } pads; - /** HMAC Authentication pads - allocating space for the maximum - * pad size supported which is 128 bytes for SHA512 */ + union { + struct { + uint8_t inner[128] __rte_align(16); /**< inner pad */ + uint8_t outer[128] __rte_align(16); /**< outer pad */ + } pads; + /** HMAC Authentication pads - allocating space for the maximum + * pad size supported which is 128 bytes for SHA512 */ + + struct { + uint32_t k1_expanded[44] __rte_align(16); /* k1 (expanded key). */ + uint8_t k2[16] __rte_align(16); /* k2. */ + uint8_t k3[16] __rte_align(16); /* k3. */ + } xcbc; + /** Expanded XCBC authentication keys */ + }; uint8_t digest[64] __rte_align(16); } auth; /**< Authentication Parameters */ @@ -212,10 +220,10 @@ aesni_mb_free_session(struct rte_mempool *mempool, extern int aesni_mb_set_session_parameters(const struct aesni_mb_ops *mb_ops, struct aesni_mb_session *sess, - struct rte_crypto_cipher_params *cparams, - struct rte_crypto_hash_params *aparams, - enum rte_crypto_operation_chain op_chain); + const struct rte_crypto_xform *xform); + +/** device specific operations function pointer structure */ extern struct rte_cryptodev_ops *rte_aesni_mb_pmd_ops; diff --git a/lib/librte_cryptodev/rte_crypto.h b/lib/librte_cryptodev/rte_crypto.h index b776609..2160003 100644 --- a/lib/librte_cryptodev/rte_crypto.h +++ b/lib/librte_cryptodev/rte_crypto.h @@ -121,8 +121,8 @@ enum rte_crypto_cipher_algorithm { RTE_CRYPTO_SYM_CIPHER_AES_F8, /**< AES algorithm in F8 mode */ RTE_CRYPTO_SYM_CIPHER_AES_GCM, - /**< AES algorithm in CGM mode. When this cipher algorithm is used the - * *RTE_CRYPTO_SYM_CIPHER_AES_GCM* element of the + /**< AES algorithm in GCM mode. When this cipher algorithm is used the + * *RTE_CRYPTO_SYM_HASH_AES_GCM* element of the * *rte_crypto_hash_algorithm* enum MUST be used to set up the related * *rte_crypto_hash_setup_data* structure in the session context or in * the op_params of the crypto operation structure in the case of a @@ -164,7 +164,7 @@ struct rte_crypto_key { * This structure contains data relating to Cipher (Encryption and Decryption) * use to create a session. */ -struct rte_crypto_cipher_params { +struct rte_crypto_cipher_xform { enum rte_crypto_cipher_operation op; /**< This parameter determines if the cipher operation is an encrypt or * a decrypt operation. For the RC4 algorithm and the F8/CTR modes, @@ -203,8 +203,8 @@ struct rte_crypto_cipher_params { **/ }; -/** Symmetric Hash / Authentication Algorithms */ -enum rte_crypto_hash_algorithm { +/** Symmetric Authentication / Hash Algorithms */ +enum rte_crypto_auth_algorithm { RTE_CRYPTO_SYM_HASH_NONE = 0, /**< No hash algorithm. */ @@ -276,27 +276,24 @@ enum rte_crypto_hash_algorithm { /**< ZUC algorithm in EIA3 mode */ }; -/** Symmetric Hash Operations */ -enum rte_crypto_hash_operation { +/** Symmetric Authentication / Hash Operations */ +enum rte_crypto_auth_operation { RTE_CRYPTO_SYM_HASH_OP_DIGEST_VERIFY, /**< Verify digest */ RTE_CRYPTO_SYM_HASH_OP_DIGEST_GENERATE /**< Generate digest */ }; /** - * Hash Setup Data. + * Authentication / Hash transform data. * - * This structure contains data relating to a hash session. The fields hash_algorithm, hash_mode and digest_result_len are common to all - * three hash modes and MUST be set for each mode. - * - *****************************************************************************/ -struct rte_crypto_hash_params { - enum rte_crypto_hash_operation op; - /* hash operation type */ - enum rte_crypto_hash_algorithm algo; - /* hashing algorithm selection */ - - struct rte_crypto_key auth_key; - /**< Authentication key data. + * This structure contains data relating to an authentication/hash crypto + * transforms. The fields op, algo and digest_length are common to all + * authentication transforms and MUST be set. + */ +struct rte_crypto_auth_xform { + enum rte_crypto_auth_operation op; /**< Authentication operation type */ + enum rte_crypto_auth_algorithm algo; /**< Authentication algorithm selection */ + + struct rte_crypto_key key; /**< Authentication key data. * The authentication key length MUST be less than or equal to the * block size of the algorithm. It is the callers responsibility to * ensure that the key length is compliant with the standard being used @@ -346,9 +343,36 @@ struct rte_crypto_hash_params { }; /** + * Defines the crypto transforms available + */ +enum rte_crypto_xform_type { + RTE_CRYPTO_XFORM_NOT_SPECIFIED = 0, + RTE_CRYPTO_XFORM_AUTH, + RTE_CRYPTO_XFORM_CIPHER +}; + +/** + * Crypto transform structure. + * + * This is used to specify the crypto transforms required, multiple transforms + * can be chained together to specify a chain transforms such as authentication + * then cipher, or cipher then authentication. Each transform structure can + * hold a single transform, the type field is used to specify which transform + * is contained within the union */ +struct rte_crypto_xform { + struct rte_crypto_xform *next; /**< next xform in chain */ + + enum rte_crypto_xform_type type; /**< xform type */ + union { + struct rte_crypto_auth_xform auth; /**< Authentication / hash xform */ + struct rte_crypto_cipher_xform cipher; /**< Cipher xform */ + }; +}; + +/** * Crypto operation session type. This is used to specify whether a crypto * operation has session structure attached for immutable parameters or if all - * operation information is include in the operation data structure op_params. + * operation information is included in the operation data structure. */ enum rte_crypto_op_sess_type { RTE_CRYPTO_OP_WITH_SESSION, /**< Session based crypto operation */ @@ -370,11 +394,7 @@ struct rte_crypto_op_data { union { struct rte_cryptodev_session *session; /**< Handle for the initialised session context */ - struct { - struct rte_crypto_cipher_params cipher; - struct rte_crypto_hash_params hash; - enum rte_crypto_operation_chain opchain; - } op_params; + struct rte_crypto_xform *xform; /**< Session-less API crypto operation parameters */ }; @@ -570,6 +590,20 @@ struct rte_crypto_op_data { struct rte_mempool *pool; /**< mempool used to allocate crypto op */ }; + +/** + * Crypto Operation Pool Private Data Structure + */ +struct crypto_op_pool_private { + unsigned max_nb_xforms; +}; + + +extern struct rte_mempool * +rte_crypto_op_pool_create(const char *name, unsigned nb_ops, + unsigned cache_size, unsigned nb_xforms, int socket_id); + + /** * Reset the fields of a packet mbuf to their default values. * @@ -579,9 +613,8 @@ struct rte_crypto_op_data { * The packet mbuf to be resetted. */ static inline void -rte_crypto_op_reset(struct rte_crypto_op_data *op) +__rte_crypto_op_reset(struct rte_crypto_op_data *op) { - op->type = RTE_CRYPTO_OP_SESSIONLESS; } @@ -597,13 +630,10 @@ __rte_crypto_op_raw_alloc(struct rte_mempool *mp) } /** - * Create an crypto operation structure which is used to define the crypto - * operation processing which is to be done on a packet. + * Allocate a crypto operation structure from an crypto pool which is used + * to define the crypto operation processing which is to be done on a packet. * - * @param dev_id Device identifier - * @param m_src Source mbuf of data for processing. - * @param m_dst Destination mbuf for processed data. Can be NULL - * if crypto operation is done in place. + * @param mp crypto operation pool */ static inline struct rte_crypto_op_data * rte_crypto_op_alloc(struct rte_mempool *mp) @@ -611,7 +641,41 @@ rte_crypto_op_alloc(struct rte_mempool *mp) struct rte_crypto_op_data *op; if ((op = __rte_crypto_op_raw_alloc(mp)) != NULL) - rte_crypto_op_reset(op); + __rte_crypto_op_reset(op); + return op; +} + +/** + * Allocate a sessionless crypto operation structure from an crypto pool which is used + * to define the crypto operation processing which is to be done on a packet. The number of + * xforms supported is calculated from the mempools private data is used to check whether + * enough extra data has been allocated for each xform requested after the operation structure + * + * @param mp crypto operation pool + * @param nb_xforms number of crypto transforms to be used in operation + */ +static inline struct rte_crypto_op_data * +rte_crypto_op_alloc_sessionless(struct rte_mempool *mp, unsigned nb_xforms) +{ + struct rte_crypto_op_data *op = NULL; + struct rte_crypto_xform *xform = NULL; + struct crypto_op_pool_private *priv_data = + (struct crypto_op_pool_private *) + rte_mempool_get_priv(mp); + + if (nb_xforms > priv_data->max_nb_xforms && nb_xforms > 0) + return op; + + if ((op = __rte_crypto_op_raw_alloc(mp)) != NULL) { + __rte_crypto_op_reset(op); + + xform = op->xform = (struct rte_crypto_xform *)(op + 1); + + do { + xform->type = RTE_CRYPTO_XFORM_NOT_SPECIFIED; + xform = xform->next = --nb_xforms > 0 ? xform + 1 : NULL; + } while (xform); + } return op; } @@ -629,10 +693,9 @@ rte_crypto_op_free(struct rte_crypto_op_data *op) } } -extern struct rte_mempool * -rte_crypto_op_pool_create(const char *name, unsigned n, unsigned cache_size, - int socket_id); - +/** + * Attach a session to a crypto operation + */ static inline void rte_crypto_op_attach_session(struct rte_crypto_op_data *op, struct rte_cryptodev_session *sess) diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c index a1797ce..7f2e5d1 100644 --- a/lib/librte_cryptodev/rte_cryptodev.c +++ b/lib/librte_cryptodev/rte_cryptodev.c @@ -101,13 +101,13 @@ } \ } while (0) -struct rte_cryptodev rte_crypto_devices[RTE_MAX_CRYPTODEVS]; +struct rte_cryptodev rte_crypto_devices[RTE_CRYPTO_MAX_DEVS]; static struct rte_cryptodev_global cryptodev_globals = { .devs = &rte_crypto_devices[0], .data = NULL, .nb_devs = 0, - .max_devs = RTE_MAX_CRYPTODEVS + .max_devs = RTE_CRYPTO_MAX_DEVS }; struct rte_cryptodev_global *rte_cryptodev_globals = &cryptodev_globals; @@ -164,11 +164,11 @@ rte_cryptodev_find_free_device_index(void) { uint8_t dev_id; - for (dev_id = 0; dev_id < RTE_MAX_CRYPTODEVS; dev_id++) { + for (dev_id = 0; dev_id < RTE_CRYPTO_MAX_DEVS; dev_id++) { if (rte_crypto_devices[dev_id].attached == RTE_CRYPTODEV_DETACHED) return dev_id; } - return RTE_MAX_CRYPTODEVS; + return RTE_CRYPTO_MAX_DEVS; } struct rte_cryptodev * @@ -178,7 +178,7 @@ rte_cryptodev_pmd_allocate(const char *name, enum pmd_type type, int socket_id) struct rte_cryptodev *cryptodev; dev_id = rte_cryptodev_find_free_device_index(); - if (dev_id == RTE_MAX_CRYPTODEVS) { + if (dev_id == RTE_CRYPTO_MAX_DEVS) { CDEV_LOG_ERR("Reached maximum number of crypto devices"); return NULL; } @@ -868,9 +868,7 @@ rte_cryptodev_pmd_callback_process(struct rte_cryptodev *dev, struct rte_cryptodev_session * rte_cryptodev_session_create(uint8_t dev_id, - struct rte_crypto_cipher_params *cipher_setup_data, - struct rte_crypto_hash_params *hash_setup_data, - enum rte_crypto_operation_chain op_chain) + struct rte_crypto_xform *xform) { struct rte_cryptodev *dev; @@ -879,10 +877,10 @@ rte_cryptodev_session_create(uint8_t dev_id, return NULL; } - dev = &rte_crypto_devices[dev_id]; + dev = &rte_crypto_devices[dev_id]; - return dev->dev_ops->session_create(dev, cipher_setup_data, - hash_setup_data, op_chain); + FUNC_PTR_OR_ERR_RET(*dev->dev_ops->session_create, NULL); + return dev->dev_ops->session_create(dev, xform); } void @@ -896,9 +894,10 @@ rte_cryptodev_session_free(uint8_t dev_id, return; } - dev = &rte_crypto_devices[dev_id]; + dev = &rte_crypto_devices[dev_id]; - dev->dev_ops->session_destroy(dev, session); + FUNC_PTR_OR_RET(*dev->dev_ops->session_destroy); + dev->dev_ops->session_destroy(dev, session); } @@ -922,15 +921,24 @@ rte_crypto_op_pool_init(__rte_unused struct rte_mempool *mp, } struct rte_mempool * -rte_crypto_op_pool_create(const char *name, unsigned n, unsigned cache_size, - int socket_id) +rte_crypto_op_pool_create(const char *name, unsigned size, + unsigned cache_size, unsigned nb_xforms, int socket_id) { + struct crypto_op_pool_private *priv_data = NULL; + + unsigned elt_size = sizeof(struct rte_crypto_op_data) + + (sizeof(struct rte_crypto_xform) * nb_xforms); + /* lookup mempool in case already allocated */ struct rte_mempool *mp = rte_mempool_lookup(name); if (mp != NULL) { - if (mp->elt_size != sizeof(struct rte_crypto_op_data) || + priv_data = (struct crypto_op_pool_private *) + rte_mempool_get_priv(mp); + + if (priv_data->max_nb_xforms < nb_xforms || + mp->elt_size != elt_size || mp->cache_size < cache_size || - mp->size < n) { + mp->size < size) { mp = NULL; CDEV_LOG_ERR("%s mempool already exists with " "incompatible initialisation parameters", @@ -941,11 +949,12 @@ rte_crypto_op_pool_create(const char *name, unsigned n, unsigned cache_size, return mp; } - mp = rte_mempool_create(name, /* mempool name */ - n, /* number of elements*/ - sizeof(struct rte_crypto_op_data),/* element size*/ + mp = rte_mempool_create( + name, /* mempool name */ + size, /* number of elements*/ + elt_size, /* element size*/ cache_size, /* Cache size*/ - 0, /* private data size */ + sizeof(struct crypto_op_pool_private), /* private data size */ rte_crypto_op_pool_init, /* pool initialisation constructor */ NULL, /* pool initialisation constructor argument */ rte_crypto_op_init, /* obj constructor */ @@ -958,6 +967,9 @@ rte_crypto_op_pool_create(const char *name, unsigned n, unsigned cache_size, return NULL; } + priv_data = (struct crypto_op_pool_private *)rte_mempool_get_priv(mp); + + priv_data->max_nb_xforms = nb_xforms; CDEV_LOG_DEBUG("%s mempool created!", name); return mp; diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h index d7694ad..d2d34f2 100644 --- a/lib/librte_cryptodev/rte_cryptodev.h +++ b/lib/librte_cryptodev/rte_cryptodev.h @@ -501,31 +501,23 @@ rte_cryptodev_enqueue_burst(uint8_t dev_id, uint16_t qp_id, * parameters of symmetric cryptographic operation. * To perform the operation the rte_cryptodev_enqueue_burst function is * used. Each mbuf should contain a reference to the session - * pointer returned from this function. - * Memory to contain the session information is allocated by the - * implementation. - * An upper limit on the number of session that many be created is - * defined by a build configuration constant. + * pointer returned from this function contained within it's crypto_op if a + * session-based operation is being provisioned. Memory to contain the session + * information is allocated from within mempool managed by the cryptodev. + * * The rte_cryptodev_session_free must be called to free allocated - * memory when the session information is no longer needed. + * memory when the session is no longer required. * - * @param dev_id The device identifier. - * @param cipher_setup_data The parameters associated with the - * cipher operation. This may be NULL. - * @param hash_setup_data The parameters associated with the hash - * operation. This may be NULL. - * @param op_chain Specifies the crypto operation chaining, - * cipher and/or hash and the order in - * which they are performed. + * @param dev_id The device identifier. + * @param xform Crypto transform chain. + * * @return * Pointer to the created session or NULL */ extern struct rte_cryptodev_session * rte_cryptodev_session_create(uint8_t dev_id, - struct rte_crypto_cipher_params *cipher_setup_data, - struct rte_crypto_hash_params *hash_setup_data, - enum rte_crypto_operation_chain op_chain); + struct rte_crypto_xform *xform); /** diff --git a/lib/librte_cryptodev/rte_cryptodev_pmd.h b/lib/librte_cryptodev/rte_cryptodev_pmd.h index e6fdd1c..aa2f6c4 100644 --- a/lib/librte_cryptodev/rte_cryptodev_pmd.h +++ b/lib/librte_cryptodev/rte_cryptodev_pmd.h @@ -453,10 +453,8 @@ typedef int (*cryptodev_create_session_pool_t)( /** * Create a Crypto session on a device. * - * @param dev Crypto device pointer - * @param cipher_setup_data Cipher operation parameters - * @param hash_setup_data Hash operation parameters - * @param op_chain Operation chaining + * @param dev Crypto device pointer + * @param xform Single or chain of crypto xforms * * @return * - Returns cryptodev session structure on success. @@ -464,9 +462,7 @@ typedef int (*cryptodev_create_session_pool_t)( * */ typedef struct rte_cryptodev_session * (*cryptodev_create_session_t)( struct rte_cryptodev *dev, - struct rte_crypto_cipher_params *cipher_setup_data, - struct rte_crypto_hash_params *hash_setup_data, - enum rte_crypto_operation_chain op_chain); + struct rte_crypto_xform *xform); /** * Free Crypto session. -- 2.4.3