From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by dpdk.org (Postfix) with ESMTP id B7BBBFEB for ; Tue, 14 Aug 2018 11:00:57 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 14 Aug 2018 02:00:56 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.53,237,1531810800"; d="scan'208";a="253923685" Received: from silpixa00399466.ir.intel.com (HELO silpixa00399466.ger.corp.intel.com) ([10.237.223.220]) by fmsmga005.fm.intel.com with ESMTP; 14 Aug 2018 02:00:54 -0700 From: Pablo de Lara To: declan.doherty@intel.com Cc: dev@dpdk.org, Pablo de Lara Date: Tue, 14 Aug 2018 01:54:30 +0100 Message-Id: <20180814005430.5770-1-pablo.de.lara.guarch@intel.com> X-Mailer: git-send-email 2.17.1 Subject: [dpdk-dev] [PATCH] crypto/aesni_gcm: support all truncated digest sizes X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 14 Aug 2018 09:00:58 -0000 The full digest size of GCM/GMAC algorithms is 16 bytes. However, it is sometimes truncated to a smaller size (such as in IPSec). This commit allows a user to generate a digest of any size up to the full size. Signed-off-by: Pablo de Lara --- drivers/crypto/aesni_gcm/aesni_gcm_pmd.c | 79 +++++++++++++------ drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c | 8 +- .../crypto/aesni_gcm/aesni_gcm_pmd_private.h | 6 +- 3 files changed, 65 insertions(+), 28 deletions(-) diff --git a/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c b/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c index 752e0cd6a..9b4d1f630 100644 --- a/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c +++ b/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c @@ -23,7 +23,6 @@ aesni_gcm_set_session_parameters(const struct aesni_gcm_ops *gcm_ops, { const struct rte_crypto_sym_xform *auth_xform; const struct rte_crypto_sym_xform *aead_xform; - uint16_t digest_length; uint8_t key_length; uint8_t *key; @@ -47,7 +46,7 @@ aesni_gcm_set_session_parameters(const struct aesni_gcm_ops *gcm_ops, key_length = auth_xform->auth.key.length; key = auth_xform->auth.key.data; - digest_length = auth_xform->auth.digest_length; + sess->req_digest_length = auth_xform->auth.digest_length; /* AES-GCM */ } else if (xform->type == RTE_CRYPTO_SYM_XFORM_AEAD) { @@ -73,7 +72,7 @@ aesni_gcm_set_session_parameters(const struct aesni_gcm_ops *gcm_ops, key = aead_xform->aead.key.data; sess->aad_length = aead_xform->aead.aad_length; - digest_length = aead_xform->aead.digest_length; + sess->req_digest_length = aead_xform->aead.digest_length; } else { AESNI_GCM_LOG(ERR, "Wrong xform type, has to be AEAD or authentication"); return -ENOTSUP; @@ -106,13 +105,28 @@ aesni_gcm_set_session_parameters(const struct aesni_gcm_ops *gcm_ops, gcm_ops[sess->key].precomp(key, &sess->gdata_key); /* Digest check */ - if (digest_length != 16 && - digest_length != 12 && - digest_length != 8) { + if (sess->req_digest_length > 16) { AESNI_GCM_LOG(ERR, "Invalid digest length"); return -EINVAL; } - sess->digest_length = digest_length; + /* + * Multi-buffer lib supports digest sizes from 4 to 16 bytes + * in version 0.50 and sizes of 8, 12 and 16 bytes, + * in version 0.49. + * If size requested is different, generate the full digest + * (16 bytes) in a temporary location and then memcpy + * the requested number of bytes. + */ +#if IMB_VERSION_NUM >= IMB_VERSION(0, 50, 0) + if (sess->req_digest_length < 4) +#else + if (sess->req_digest_length != 16 && + sess->req_digest_length != 12 && + sess->req_digest_length != 8) +#endif + sess->gen_digest_length = 16; + else + sess->gen_digest_length = sess->req_digest_length; return 0; } @@ -180,6 +194,7 @@ process_gcm_crypto_op(struct aesni_gcm_qp *qp, struct rte_crypto_op *op, struct rte_mbuf *m_src = sym_op->m_src; uint32_t offset, data_offset, data_length; uint32_t part_len, total_len, data_len; + uint8_t *tag; if (session->op == AESNI_GCM_OP_AUTHENTICATED_ENCRYPTION || session->op == AESNI_GCM_OP_AUTHENTICATED_DECRYPTION) { @@ -263,13 +278,16 @@ process_gcm_crypto_op(struct aesni_gcm_qp *qp, struct rte_crypto_op *op, total_len -= part_len; } + if (session->req_digest_length != session->gen_digest_length) + tag = qp->temp_digest; + else + tag = sym_op->aead.digest.data; + qp->ops[session->key].finalize(&session->gdata_key, &qp->gdata_ctx, - sym_op->aead.digest.data, - (uint64_t)session->digest_length); + tag, + session->gen_digest_length); } else if (session->op == AESNI_GCM_OP_AUTHENTICATED_DECRYPTION) { - uint8_t *auth_tag = qp->temp_digest; - qp->ops[session->key].init(&session->gdata_key, &qp->gdata_ctx, iv_ptr, @@ -298,33 +316,41 @@ process_gcm_crypto_op(struct aesni_gcm_qp *qp, struct rte_crypto_op *op, total_len -= part_len; } + tag = qp->temp_digest; qp->ops[session->key].finalize(&session->gdata_key, &qp->gdata_ctx, - auth_tag, - (uint64_t)session->digest_length); + tag, + session->gen_digest_length); } else if (session->op == AESNI_GMAC_OP_GENERATE) { qp->ops[session->key].init(&session->gdata_key, &qp->gdata_ctx, iv_ptr, src, (uint64_t)data_length); + if (session->req_digest_length != session->gen_digest_length) + tag = qp->temp_digest; + else + tag = sym_op->auth.digest.data; qp->ops[session->key].finalize(&session->gdata_key, &qp->gdata_ctx, - sym_op->auth.digest.data, - (uint64_t)session->digest_length); + tag, + session->gen_digest_length); } else { /* AESNI_GMAC_OP_VERIFY */ - uint8_t *auth_tag = qp->temp_digest; - qp->ops[session->key].init(&session->gdata_key, &qp->gdata_ctx, iv_ptr, src, (uint64_t)data_length); + /* + * Generate always 16 bytes and later compare only + * the bytes passed. + */ + tag = qp->temp_digest; qp->ops[session->key].finalize(&session->gdata_key, &qp->gdata_ctx, - auth_tag, - (uint64_t)session->digest_length); + tag, + session->gen_digest_length); } return 0; @@ -361,13 +387,22 @@ post_process_gcm_crypto_op(struct aesni_gcm_qp *qp, #ifdef RTE_LIBRTE_PMD_AESNI_GCM_DEBUG rte_hexdump(stdout, "auth tag (orig):", - digest, session->digest_length); + digest, session->req_digest_length); rte_hexdump(stdout, "auth tag (calc):", - tag, session->digest_length); + tag, session->req_digest_length); #endif - if (memcmp(tag, digest, session->digest_length) != 0) + if (memcmp(tag, digest, session->req_digest_length) != 0) op->status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED; + } else { + if (session->req_digest_length != session->gen_digest_length) { + if (session->op == AESNI_GCM_OP_AUTHENTICATED_ENCRYPTION) + memcpy(op->sym->aead.digest.data, qp->temp_digest, + session->req_digest_length); + else + memcpy(op->sym->auth.digest.data, qp->temp_digest, + session->req_digest_length); + } } } diff --git a/drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c b/drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c index b6b4dd028..c343a393f 100644 --- a/drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c +++ b/drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c @@ -24,9 +24,9 @@ static const struct rte_cryptodev_capabilities aesni_gcm_pmd_capabilities[] = { .increment = 8 }, .digest_size = { - .min = 8, + .min = 1, .max = 16, - .increment = 4 + .increment = 1 }, .iv_size = { .min = 12, @@ -49,9 +49,9 @@ static const struct rte_cryptodev_capabilities aesni_gcm_pmd_capabilities[] = { .increment = 8 }, .digest_size = { - .min = 8, + .min = 1, .max = 16, - .increment = 4 + .increment = 1 }, .aad_size = { .min = 0, diff --git a/drivers/crypto/aesni_gcm/aesni_gcm_pmd_private.h b/drivers/crypto/aesni_gcm/aesni_gcm_pmd_private.h index c13a12a57..92b041354 100644 --- a/drivers/crypto/aesni_gcm/aesni_gcm_pmd_private.h +++ b/drivers/crypto/aesni_gcm/aesni_gcm_pmd_private.h @@ -76,8 +76,10 @@ struct aesni_gcm_session { /**< IV parameters */ uint16_t aad_length; /**< AAD length */ - uint16_t digest_length; - /**< Digest length */ + uint16_t req_digest_length; + /**< Requested digest length */ + uint16_t gen_digest_length; + /**< Generated digest length */ enum aesni_gcm_operation op; /**< GCM operation type */ enum aesni_gcm_key key; -- 2.17.1