From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 11F80A2EFC for ; Wed, 18 Sep 2019 12:24:47 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id DB5831C211; Wed, 18 Sep 2019 12:24:45 +0200 (CEST) Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by dpdk.org (Postfix) with ESMTP id 55D081C1A2 for ; Wed, 18 Sep 2019 12:24:44 +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 fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 18 Sep 2019 03:24:43 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,520,1559545200"; d="scan'208";a="216896383" Received: from irsmsx109.ger.corp.intel.com ([163.33.3.23]) by fmsmga002.fm.intel.com with ESMTP; 18 Sep 2019 03:24:42 -0700 Received: from irsmsx105.ger.corp.intel.com ([169.254.7.164]) by IRSMSX109.ger.corp.intel.com ([169.254.13.29]) with mapi id 14.03.0439.000; Wed, 18 Sep 2019 11:24:41 +0100 From: "Ananyev, Konstantin" To: "Zhang, Roy Fan" , "dev@dpdk.org" CC: "Doherty, Declan" , "akhil.goyal@nxp.com" Thread-Topic: [PATCH 02/10] crypto/aesni_gcm: add rte_security handler Thread-Index: AQHVZLTq340bLnIF8EiBmDrleuXwuacxSsEg Date: Wed, 18 Sep 2019 10:24:40 +0000 Message-ID: <2601191342CEEE43887BDE71AB9772580191966D30@irsmsx105.ger.corp.intel.com> References: <20190903154046.55992-1-roy.fan.zhang@intel.com> <20190906131330.40185-1-roy.fan.zhang@intel.com> <20190906131330.40185-3-roy.fan.zhang@intel.com> In-Reply-To: <20190906131330.40185-3-roy.fan.zhang@intel.com> Accept-Language: en-IE, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-titus-metadata-40: eyJDYXRlZ29yeUxhYmVscyI6IiIsIk1ldGFkYXRhIjp7Im5zIjoiaHR0cDpcL1wvd3d3LnRpdHVzLmNvbVwvbnNcL0ludGVsMyIsImlkIjoiOTE4NjViMTctZDQ4NC00NTMzLWFmMmEtMmE5MDFhZTY1MzY1IiwicHJvcHMiOlt7Im4iOiJDVFBDbGFzc2lmaWNhdGlvbiIsInZhbHMiOlt7InZhbHVlIjoiQ1RQX05UIn1dfV19LCJTdWJqZWN0TGFiZWxzIjpbXSwiVE1DVmVyc2lvbiI6IjE3LjEwLjE4MDQuNDkiLCJUcnVzdGVkTGFiZWxIYXNoIjoiemkxMkkzRDBXT01KTGtWOEMySzRNTjBIa3EwdzA5VUtnNHpQQjJ6RnBINExLVTllbVdwQ0YyN044TUVtaG1UcSJ9 x-ctpclassification: CTP_NT dlp-product: dlpe-windows dlp-version: 11.2.0.6 dlp-reaction: no-action x-originating-ip: [163.33.239.180] Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Subject: Re: [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" Hi Fan, >=20 > 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.Hi=20 >=20 > 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(-) >=20 > diff --git a/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c b/drivers/crypto/ae= sni_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, struc= t rte_crypto_op *op) > return sess; > } >=20 > +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 =3D &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 =3D 0; i < buf->num; i++) { > + struct iovec *vec =3D &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 !=3D session->gen_digest_length) > + tag =3D sess->temp_digest; > + else > + tag =3D digest; > + > + sess->finalize(&session->gdata_key, &sess->gdata_ctx, tag, > + session->gen_digest_length); > + > + if (session->req_digest_length !=3D session->gen_digest_length) > + memcpy(digest, sess->temp_digest, > + session->req_digest_length); > + break; Wonder can we move all these cases and ifs into session_create() time - so instead of one process() function with a lot of branches, we'll have several process functions with minimal/none branches. I think it should help us to save extra cycles. > + > + case AESNI_GCM_OP_AUTHENTICATED_DECRYPTION: > + tag =3D sess->temp_digest; > + > + sess->finalize(&session->gdata_key, &sess->gdata_ctx, tag, > + session->gen_digest_length); > + > + if (memcmp(tag, digest, session->req_digest_length) !=3D 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]; >=20 > /* 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; >=20 > mb_mgr =3D alloc_mb_mgr(0); > if (mb_mgr =3D=3D NULL) > @@ -587,6 +641,21 @@ aesni_gcm_create(const char *name, >=20 > internals->max_nb_queue_pairs =3D init_params->max_nb_queue_pairs; >=20 > + /* setup security operations */ > + snprintf(sec_name, sizeof(sec_name) - 1, "aes_gcm_sec_%u", > + dev->driver_id); > + sec_ctx =3D rte_zmalloc_socket(sec_name, > + sizeof(struct rte_security_ctx), > + RTE_CACHE_LINE_SIZE, init_params->socket_id); > + if (sec_ctx =3D=3D NULL) { > + AESNI_GCM_LOG(ERR, "memory allocation failed\n"); > + goto error_exit; > + } > + > + sec_ctx->device =3D (void *)dev; > + sec_ctx->ops =3D rte_aesni_gcm_pmd_security_ops; > + dev->security_ctx =3D sec_ctx; > + > #if IMB_VERSION_NUM >=3D 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 =3D=3D NULL) > return -ENODEV; >=20 > + rte_free(cryptodev->security_ctx); > + > internals =3D cryptodev->data->dev_private; >=20 > free_mb_mgr(internals->mb_mgr); > @@ -648,6 +719,24 @@ aesni_gcm_remove(struct rte_vdev_device *vdev) > return rte_cryptodev_pmd_destroy(cryptodev); > } >=20 > +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 =3D > + get_sec_session_private_data(sess); > + uint32_t i; > + > + if (unlikely(!session)) > + return; I think you can't just return here, you need to set all status[] entries to some -errno value. > + > + for (i =3D 0; i < num; i++) > + status[i] =3D 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 =3D { > .probe =3D aesni_gcm_probe, > .remove =3D aesni_gcm_remove > diff --git a/drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c b/drivers/crypt= o/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 >=20 > #include "aesni_gcm_pmd_private.h" >=20 > @@ -316,6 +317,85 @@ aesni_gcm_pmd_sym_session_clear(struct rte_cryptodev= *dev, > } > } >=20 > +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 =3D dev; > + struct aesni_gcm_private *internals =3D 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 =3D=3D 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 =3D aesni_gcm_set_session_parameters(internals->ops, > + &sess_priv->sess, conf->crypto_xform); > + if (ret !=3D 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 =3D internals->ops[sess_priv->sess.key].pre; > + sess_priv->init =3D internals->ops[sess_priv->sess.key].init; > + if (sess_priv->sess.op =3D=3D AESNI_GCM_OP_AUTHENTICATED_ENCRYPTION) { > + sess_priv->update =3D > + internals->ops[sess_priv->sess.key].update_enc; > + sess_priv->finalize =3D > + internals->ops[sess_priv->sess.key].finalize_enc; > + } else { > + sess_priv->update =3D > + internals->ops[sess_priv->sess.key].update_dec; > + sess_priv->finalize =3D > + internals->ops[sess_priv->sess.key].finalize_dec; > + } > + > + sess->sess_private_data =3D sess_priv; > + > + return 0; > +} > + > +static int > +aesni_gcm_security_session_destroy(void *dev __rte_unused, > + struct rte_security_session *sess) > +{ > + void *sess_priv =3D get_sec_session_private_data(sess); > + > + if (sess_priv) { > + struct rte_mempool *sess_mp =3D 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 =3D { > .dev_configure =3D aesni_gcm_pmd_config, > .dev_start =3D aesni_gcm_pmd_start, > @@ -336,4 +416,19 @@ struct rte_cryptodev_ops aesni_gcm_pmd_ops =3D { > .sym_session_clear =3D aesni_gcm_pmd_sym_session_clear > }; >=20 > +static struct rte_security_ops aesni_gcm_security_ops =3D { > + .session_create =3D aesni_gcm_security_session_create, > + .session_get_size =3D aesni_gcm_sec_session_get_size, > + .session_update =3D NULL, > + .session_stats_get =3D NULL, > + .session_destroy =3D aesni_gcm_security_session_destroy, > + .set_pkt_metadata =3D NULL, > + .capabilities_get =3D NULL, > + .process_cpu_crypto_bulk =3D > + aesni_gcm_sec_crypto_process_bulk, > +}; > + > struct rte_cryptodev_ops *rte_aesni_gcm_pmd_ops =3D &aesni_gcm_pmd_ops; > + > +struct rte_security_ops *rte_aesni_gcm_pmd_security_ops =3D > + &aesni_gcm_security_ops; > diff --git a/drivers/crypto/aesni_gcm/aesni_gcm_pmd_private.h b/drivers/c= rypto/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; >=20 > +/** > + * 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; >=20 > #endif /* _RTE_AESNI_GCM_PMD_PRIVATE_H_ */ > -- > 2.14.5