From patchwork Fri Sep 6 13:13:22 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fan Zhang X-Patchwork-Id: 58864 X-Patchwork-Delegate: gakhil@marvell.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id BC8801F388; Fri, 6 Sep 2019 15:13:41 +0200 (CEST) Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by dpdk.org (Postfix) with ESMTP id 6E4821F379 for ; Fri, 6 Sep 2019 15:13:38 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga106.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 06 Sep 2019 06:13:37 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,473,1559545200"; d="scan'208";a="213140721" Received: from silpixa00398673.ir.intel.com (HELO silpixa00398673.ger.corp.intel.com) ([10.237.223.136]) by fmsmga002.fm.intel.com with ESMTP; 06 Sep 2019 06:13:36 -0700 From: Fan Zhang To: dev@dpdk.org Cc: konstantin.ananyev@intel.com, declan.doherty@intel.com, akhil.goyal@nxp.com, Fan Zhang Date: Fri, 6 Sep 2019 14:13:22 +0100 Message-Id: <20190906131330.40185-3-roy.fan.zhang@intel.com> X-Mailer: git-send-email 2.14.5 In-Reply-To: <20190906131330.40185-1-roy.fan.zhang@intel.com> References: <20190903154046.55992-1-roy.fan.zhang@intel.com> <20190906131330.40185-1-roy.fan.zhang@intel.com> Subject: [dpdk-dev] [PATCH 02/10] crypto/aesni_gcm: add rte_security handler 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: , Errors-To: dev-bounces@dpdk.org Sender: "dev" This patch add rte_security support support to AESNI-GCM PMD. The PMD now initialize security context instance, create/delete PMD specific security sessions, and process crypto workloads in synchronous mode with scatter-gather list buffer supported. Signed-off-by: Fan Zhang --- drivers/crypto/aesni_gcm/aesni_gcm_pmd.c | 91 ++++++++++++++++++++++- drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c | 95 ++++++++++++++++++++++++ drivers/crypto/aesni_gcm/aesni_gcm_pmd_private.h | 23 ++++++ 3 files changed, 208 insertions(+), 1 deletion(-) diff --git a/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c b/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c index 1006a5c4d..0a346eddd 100644 --- a/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c +++ b/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -174,6 +175,56 @@ aesni_gcm_get_session(struct aesni_gcm_qp *qp, struct rte_crypto_op *op) return sess; } +static __rte_always_inline int +process_gcm_security_sgl_buf(struct aesni_gcm_security_session *sess, + struct rte_security_vec *buf, uint8_t *iv, + uint8_t *aad, uint8_t *digest) +{ + struct aesni_gcm_session *session = &sess->sess; + uint8_t *tag; + uint32_t i; + + sess->init(&session->gdata_key, &sess->gdata_ctx, iv, aad, + (uint64_t)session->aad_length); + + for (i = 0; i < buf->num; i++) { + struct iovec *vec = &buf->vec[i]; + + sess->update(&session->gdata_key, &sess->gdata_ctx, + vec->iov_base, vec->iov_base, vec->iov_len); + } + + switch (session->op) { + case AESNI_GCM_OP_AUTHENTICATED_ENCRYPTION: + if (session->req_digest_length != session->gen_digest_length) + tag = sess->temp_digest; + else + tag = digest; + + sess->finalize(&session->gdata_key, &sess->gdata_ctx, tag, + session->gen_digest_length); + + if (session->req_digest_length != session->gen_digest_length) + memcpy(digest, sess->temp_digest, + session->req_digest_length); + break; + + case AESNI_GCM_OP_AUTHENTICATED_DECRYPTION: + tag = sess->temp_digest; + + sess->finalize(&session->gdata_key, &sess->gdata_ctx, tag, + session->gen_digest_length); + + if (memcmp(tag, digest, session->req_digest_length) != 0) + return -1; + break; + default: + return -1; + } + + return 0; +} + /** * Process a crypto operation, calling * the GCM API from the multi buffer library. @@ -488,8 +539,10 @@ aesni_gcm_create(const char *name, { struct rte_cryptodev *dev; struct aesni_gcm_private *internals; + struct rte_security_ctx *sec_ctx; enum aesni_gcm_vector_mode vector_mode; MB_MGR *mb_mgr; + char sec_name[RTE_DEV_NAME_MAX_LEN]; /* Check CPU for support for AES instruction set */ if (!rte_cpu_get_flag_enabled(RTE_CPUFLAG_AES)) { @@ -524,7 +577,8 @@ aesni_gcm_create(const char *name, RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING | RTE_CRYPTODEV_FF_CPU_AESNI | RTE_CRYPTODEV_FF_OOP_SGL_IN_LB_OUT | - RTE_CRYPTODEV_FF_OOP_LB_IN_LB_OUT; + RTE_CRYPTODEV_FF_OOP_LB_IN_LB_OUT | + RTE_CRYPTODEV_FF_SECURITY; mb_mgr = alloc_mb_mgr(0); if (mb_mgr == NULL) @@ -587,6 +641,21 @@ aesni_gcm_create(const char *name, internals->max_nb_queue_pairs = init_params->max_nb_queue_pairs; + /* setup security operations */ + snprintf(sec_name, sizeof(sec_name) - 1, "aes_gcm_sec_%u", + dev->driver_id); + sec_ctx = rte_zmalloc_socket(sec_name, + sizeof(struct rte_security_ctx), + RTE_CACHE_LINE_SIZE, init_params->socket_id); + if (sec_ctx == NULL) { + AESNI_GCM_LOG(ERR, "memory allocation failed\n"); + goto error_exit; + } + + sec_ctx->device = (void *)dev; + sec_ctx->ops = rte_aesni_gcm_pmd_security_ops; + dev->security_ctx = sec_ctx; + #if IMB_VERSION_NUM >= IMB_VERSION(0, 50, 0) AESNI_GCM_LOG(INFO, "IPSec Multi-buffer library version used: %s\n", imb_get_version_str()); @@ -641,6 +710,8 @@ aesni_gcm_remove(struct rte_vdev_device *vdev) if (cryptodev == NULL) return -ENODEV; + rte_free(cryptodev->security_ctx); + internals = cryptodev->data->dev_private; free_mb_mgr(internals->mb_mgr); @@ -648,6 +719,24 @@ aesni_gcm_remove(struct rte_vdev_device *vdev) return rte_cryptodev_pmd_destroy(cryptodev); } +void +aesni_gcm_sec_crypto_process_bulk(struct rte_security_session *sess, + struct rte_security_vec buf[], void *iv[], void *aad[], + void *digest[], int status[], uint32_t num) +{ + struct aesni_gcm_security_session *session = + get_sec_session_private_data(sess); + uint32_t i; + + if (unlikely(!session)) + return; + + for (i = 0; i < num; i++) + status[i] = process_gcm_security_sgl_buf(session, &buf[i], + (uint8_t *)iv[i], (uint8_t *)aad[i], + (uint8_t *)digest[i]); +} + static struct rte_vdev_driver aesni_gcm_pmd_drv = { .probe = aesni_gcm_probe, .remove = aesni_gcm_remove diff --git a/drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c b/drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c index 2f66c7c58..cc71dbd60 100644 --- a/drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c +++ b/drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c @@ -7,6 +7,7 @@ #include #include #include +#include #include "aesni_gcm_pmd_private.h" @@ -316,6 +317,85 @@ aesni_gcm_pmd_sym_session_clear(struct rte_cryptodev *dev, } } +static int +aesni_gcm_security_session_create(void *dev, + struct rte_security_session_conf *conf, + struct rte_security_session *sess, + struct rte_mempool *mempool) +{ + struct rte_cryptodev *cdev = dev; + struct aesni_gcm_private *internals = cdev->data->dev_private; + struct aesni_gcm_security_session *sess_priv; + int ret; + + if (!conf->crypto_xform) { + AESNI_GCM_LOG(ERR, "Invalid security session conf"); + return -EINVAL; + } + + if (conf->crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) { + AESNI_GCM_LOG(ERR, "GMAC is not supported in security session"); + return -EINVAL; + } + + + if (rte_mempool_get(mempool, (void **)(&sess_priv))) { + AESNI_GCM_LOG(ERR, + "Couldn't get object from session mempool"); + return -ENOMEM; + } + + ret = aesni_gcm_set_session_parameters(internals->ops, + &sess_priv->sess, conf->crypto_xform); + if (ret != 0) { + AESNI_GCM_LOG(ERR, "Failed configure session parameters"); + + /* Return session to mempool */ + rte_mempool_put(mempool, (void *)sess_priv); + return ret; + } + + sess_priv->pre = internals->ops[sess_priv->sess.key].pre; + sess_priv->init = internals->ops[sess_priv->sess.key].init; + if (sess_priv->sess.op == AESNI_GCM_OP_AUTHENTICATED_ENCRYPTION) { + sess_priv->update = + internals->ops[sess_priv->sess.key].update_enc; + sess_priv->finalize = + internals->ops[sess_priv->sess.key].finalize_enc; + } else { + sess_priv->update = + internals->ops[sess_priv->sess.key].update_dec; + sess_priv->finalize = + internals->ops[sess_priv->sess.key].finalize_dec; + } + + sess->sess_private_data = sess_priv; + + return 0; +} + +static int +aesni_gcm_security_session_destroy(void *dev __rte_unused, + struct rte_security_session *sess) +{ + void *sess_priv = get_sec_session_private_data(sess); + + if (sess_priv) { + struct rte_mempool *sess_mp = rte_mempool_from_obj(sess_priv); + + memset(sess, 0, sizeof(struct aesni_gcm_security_session)); + set_sec_session_private_data(sess, NULL); + rte_mempool_put(sess_mp, sess_priv); + } + return 0; +} + +static unsigned int +aesni_gcm_sec_session_get_size(__rte_unused void *device) +{ + return sizeof(struct aesni_gcm_security_session); +} + struct rte_cryptodev_ops aesni_gcm_pmd_ops = { .dev_configure = aesni_gcm_pmd_config, .dev_start = aesni_gcm_pmd_start, @@ -336,4 +416,19 @@ struct rte_cryptodev_ops aesni_gcm_pmd_ops = { .sym_session_clear = aesni_gcm_pmd_sym_session_clear }; +static struct rte_security_ops aesni_gcm_security_ops = { + .session_create = aesni_gcm_security_session_create, + .session_get_size = aesni_gcm_sec_session_get_size, + .session_update = NULL, + .session_stats_get = NULL, + .session_destroy = aesni_gcm_security_session_destroy, + .set_pkt_metadata = NULL, + .capabilities_get = NULL, + .process_cpu_crypto_bulk = + aesni_gcm_sec_crypto_process_bulk, +}; + struct rte_cryptodev_ops *rte_aesni_gcm_pmd_ops = &aesni_gcm_pmd_ops; + +struct rte_security_ops *rte_aesni_gcm_pmd_security_ops = + &aesni_gcm_security_ops; diff --git a/drivers/crypto/aesni_gcm/aesni_gcm_pmd_private.h b/drivers/crypto/aesni_gcm/aesni_gcm_pmd_private.h index 56b29e013..8e490b6ce 100644 --- a/drivers/crypto/aesni_gcm/aesni_gcm_pmd_private.h +++ b/drivers/crypto/aesni_gcm/aesni_gcm_pmd_private.h @@ -114,5 +114,28 @@ aesni_gcm_set_session_parameters(const struct aesni_gcm_ops *ops, * Device specific operations function pointer structure */ extern struct rte_cryptodev_ops *rte_aesni_gcm_pmd_ops; +/** + * Security session structure. + */ +struct aesni_gcm_security_session { + /** Temp digest for decryption */ + uint8_t temp_digest[DIGEST_LENGTH_MAX]; + /** GCM operations */ + aesni_gcm_pre_t pre; + aesni_gcm_init_t init; + aesni_gcm_update_t update; + aesni_gcm_finalize_t finalize; + /** AESNI-GCM session */ + struct aesni_gcm_session sess; + /** AESNI-GCM context */ + struct gcm_context_data gdata_ctx; +}; + +extern void +aesni_gcm_sec_crypto_process_bulk(struct rte_security_session *sess, + struct rte_security_vec buf[], void *iv[], void *aad[], + void *digest[], int status[], uint32_t num); + +extern struct rte_security_ops *rte_aesni_gcm_pmd_security_ops; #endif /* _RTE_AESNI_GCM_PMD_PRIVATE_H_ */