* [dpdk-dev] [PATCH] crypto/mvsam: IPSec full offload support
@ 2021-07-01 6:57 danat
2021-07-11 6:55 ` [dpdk-dev] [PATCH v2] " danat
0 siblings, 1 reply; 8+ messages in thread
From: danat @ 2021-07-01 6:57 UTC (permalink / raw)
To: gakhil; +Cc: dev, danat, lironh, michaelsh
From: Michael Shamis <michaelsh@marvell.com>
This patch provides the support for IPSec protocol
offload to the hardware.
Following security operations are added:
- session_create
- session_destroy
- capabilities_get
Signed-off-by: Michael Shamis <michaelsh@marvell.com>
Reviewed-by: Liron Himi <lironh@marvell.com>
Tested-by: Liron Himi <lironh@marvell.com>
---
drivers/crypto/mvsam/meson.build | 2 +-
drivers/crypto/mvsam/mrvl_pmd_private.h | 8 +-
drivers/crypto/mvsam/rte_mrvl_pmd.c | 331 +++++++++++++++++++++---
drivers/crypto/mvsam/rte_mrvl_pmd_ops.c | 176 +++++++++++++
4 files changed, 483 insertions(+), 34 deletions(-)
diff --git a/drivers/crypto/mvsam/meson.build b/drivers/crypto/mvsam/meson.build
index b4c55b5ff..db1787db6 100644
--- a/drivers/crypto/mvsam/meson.build
+++ b/drivers/crypto/mvsam/meson.build
@@ -14,4 +14,4 @@ ext_deps += dep
sources = files('rte_mrvl_pmd.c', 'rte_mrvl_pmd_ops.c')
-deps += ['bus_vdev', 'common_mvep']
+deps += ['bus_vdev', 'common_mvep', 'security']
diff --git a/drivers/crypto/mvsam/mrvl_pmd_private.h b/drivers/crypto/mvsam/mrvl_pmd_private.h
index e575330ef..719d73d82 100644
--- a/drivers/crypto/mvsam/mrvl_pmd_private.h
+++ b/drivers/crypto/mvsam/mrvl_pmd_private.h
@@ -82,11 +82,17 @@ struct mrvl_crypto_src_table {
} __rte_cache_aligned;
/** Set and validate MRVL crypto session parameters */
-extern int
+int
mrvl_crypto_set_session_parameters(struct mrvl_crypto_session *sess,
const struct rte_crypto_sym_xform *xform);
+int
+mrvl_ipsec_set_session_parameters(struct mrvl_crypto_session *sess,
+ struct rte_security_ipsec_xform *ipsec_xform,
+ struct rte_crypto_sym_xform *crypto_xform);
+
/** device specific operations function pointer structure */
extern struct rte_cryptodev_ops *rte_mrvl_crypto_pmd_ops;
+extern struct rte_security_ops *rte_mrvl_security_pmd_ops;
#endif /* _MRVL_PMD_PRIVATE_H_ */
diff --git a/drivers/crypto/mvsam/rte_mrvl_pmd.c b/drivers/crypto/mvsam/rte_mrvl_pmd.c
index bec51c9ff..3d21319e5 100644
--- a/drivers/crypto/mvsam/rte_mrvl_pmd.c
+++ b/drivers/crypto/mvsam/rte_mrvl_pmd.c
@@ -8,6 +8,7 @@
#include <rte_hexdump.h>
#include <rte_cryptodev.h>
#include <rte_cryptodev_pmd.h>
+#include <rte_security_driver.h>
#include <rte_bus_vdev.h>
#include <rte_malloc.h>
#include <rte_cpuflags.h>
@@ -461,6 +462,96 @@ mrvl_crypto_set_session_parameters(struct mrvl_crypto_session *sess,
return 0;
}
+static int
+replay_wsz_to_mask(uint32_t replay_win_sz)
+{
+ int mask = 0;
+
+ switch (replay_win_sz) {
+ case 0:
+ mask = SAM_ANTI_REPLY_MASK_NONE;
+ break;
+ case 32:
+ mask = SAM_ANTI_REPLY_MASK_32B;
+ break;
+ case 64:
+ mask = SAM_ANTI_REPLY_MASK_64B;
+ break;
+ case 128:
+ mask = SAM_ANTI_REPLY_MASK_128B;
+ break;
+ default:
+ MRVL_LOG(ERR, "Invalid antireplay window size");
+ return -EINVAL;
+ }
+
+ return mask;
+}
+
+/**
+ * Parse IPSEC session parameters.
+ *
+ * @param sess Poiner to security session
+ * @param ipsec_xform Pointer to configuration structure IPSEC operations.
+ * @param crypto_xform Pointer to chain for crypto operations.
+ * @returns 0 in case of success, negative value otherwise.
+ */
+int
+mrvl_ipsec_set_session_parameters(struct mrvl_crypto_session *sess,
+ struct rte_security_ipsec_xform *ipsec_xform,
+ struct rte_crypto_sym_xform *crypto_xform)
+{
+ int seq_mask_size;
+
+ /* Filter out spurious/broken requests */
+ if (ipsec_xform == NULL || crypto_xform == NULL)
+ return -EINVAL;
+
+ /* Crypto parameters handling */
+ if (mrvl_crypto_set_session_parameters(sess, crypto_xform))
+ return -EINVAL;
+
+ seq_mask_size = replay_wsz_to_mask(ipsec_xform->replay_win_sz);
+ if (seq_mask_size < 0)
+ return -EINVAL;
+
+ /* IPSEC protocol parameters handling */
+ sess->sam_sess_params.proto = SAM_PROTO_IPSEC;
+ sess->sam_sess_params.u.ipsec.is_esp =
+ (ipsec_xform->proto == RTE_SECURITY_IPSEC_SA_PROTO_ESP) ?
+ 1 : 0;
+ sess->sam_sess_params.u.ipsec.is_ip6 = 0;
+ sess->sam_sess_params.u.ipsec.is_tunnel =
+ (ipsec_xform->mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL) ?
+ 1 : 0;
+ sess->sam_sess_params.u.ipsec.is_esn = ipsec_xform->options.esn;
+ sess->sam_sess_params.u.ipsec.seq_mask_size = seq_mask_size;
+
+ sess->sam_sess_params.u.ipsec.tunnel.u.ipv4.sip =
+ (uint8_t *)(&ipsec_xform->tunnel.ipv4.src_ip.s_addr);
+ sess->sam_sess_params.u.ipsec.tunnel.u.ipv4.dip =
+ (uint8_t *)&(ipsec_xform->tunnel.ipv4.dst_ip.s_addr);
+
+ sess->sam_sess_params.u.ipsec.tunnel.u.ipv4.dscp =
+ ipsec_xform->tunnel.ipv4.dscp;
+ sess->sam_sess_params.u.ipsec.tunnel.u.ipv4.ttl =
+ ipsec_xform->tunnel.ipv4.ttl;
+ sess->sam_sess_params.u.ipsec.tunnel.u.ipv4.df =
+ ipsec_xform->tunnel.ipv4.df;
+ sess->sam_sess_params.u.ipsec.tunnel.copy_dscp =
+ ipsec_xform->options.copy_dscp;
+ sess->sam_sess_params.u.ipsec.tunnel.copy_flabel =
+ ipsec_xform->options.copy_flabel;
+ sess->sam_sess_params.u.ipsec.tunnel.copy_df =
+ ipsec_xform->options.copy_df;
+
+ sess->sam_sess_params.u.ipsec.is_natt = 0;
+ sess->sam_sess_params.u.ipsec.spi = ipsec_xform->spi;
+ sess->sam_sess_params.u.ipsec.seq = 0;
+
+ return 0;
+}
+
/*
*-----------------------------------------------------------------------------
* Process Operations
@@ -480,7 +571,7 @@ mrvl_crypto_set_session_parameters(struct mrvl_crypto_session *sess,
* @param op Pointer to DPDK crypto operation struct [In].
*/
static inline int
-mrvl_request_prepare(struct sam_cio_op_params *request,
+mrvl_request_prepare_crp(struct sam_cio_op_params *request,
struct sam_buf_info *src_bd,
struct sam_buf_info *dst_bd,
struct rte_crypto_op *op)
@@ -499,7 +590,8 @@ mrvl_request_prepare(struct sam_cio_op_params *request,
}
sess = (struct mrvl_crypto_session *)get_sym_session_private_data(
- op->sym->session, cryptodev_driver_id);
+ op->sym->session,
+ cryptodev_driver_id);
if (unlikely(sess == NULL)) {
MRVL_LOG(ERR, "Session was not created for this device!");
return -EINVAL;
@@ -569,7 +661,7 @@ mrvl_request_prepare(struct sam_cio_op_params *request,
request->cipher_len = op->sym->aead.data.length;
request->cipher_offset = op->sym->aead.data.offset;
request->cipher_iv = rte_crypto_op_ctod_offset(op, uint8_t *,
- sess->cipher_iv_offset);
+ sess->cipher_iv_offset);
request->auth_aad = op->sym->aead.aad.data;
request->auth_offset = request->cipher_offset;
@@ -645,6 +737,108 @@ mrvl_request_prepare(struct sam_cio_op_params *request,
return -1;
}
+/**
+ * Prepare a single security protocol request.
+ *
+ * This function basically translates DPDK security request into one
+ * understandable by MUDSK's SAM. If this is a first request in a session,
+ * it starts the session.
+ *
+ * @param request Pointer to pre-allocated && reset request buffer [Out].
+ * @param src_bd Pointer to pre-allocated source descriptor [Out].
+ * @param dst_bd Pointer to pre-allocated destination descriptor [Out].
+ * @param op Pointer to DPDK crypto operation struct [In].
+ */
+static inline int
+mrvl_request_prepare_sec(struct sam_cio_ipsec_params *request,
+ struct sam_buf_info *src_bd,
+ struct sam_buf_info *dst_bd,
+ struct rte_crypto_op *op)
+{
+ struct mrvl_crypto_session *sess;
+ struct rte_mbuf *src_mbuf, *dst_mbuf;
+ uint16_t segments_nb;
+ int i;
+
+ if (unlikely(op->sess_type != RTE_CRYPTO_OP_SECURITY_SESSION)) {
+ MRVL_LOG(ERR, "MRVL SECURITY: sess_type is not SECURITY_SESSION");
+ return -EINVAL;
+ }
+
+ sess = (struct mrvl_crypto_session *)get_sec_session_private_data(
+ op->sym->sec_session);
+ if (unlikely(sess == NULL)) {
+ MRVL_LOG(ERR, "Session was not created for this device! %d",
+ cryptodev_driver_id);
+ return -EINVAL;
+ }
+
+ request->sa = sess->sam_sess;
+ request->cookie = op;
+ src_mbuf = op->sym->m_src;
+ segments_nb = src_mbuf->nb_segs;
+ /* The following conditions must be met:
+ * - Destination buffer is required when segmented source buffer
+ * - Segmented destination buffer is not supported
+ */
+ if ((segments_nb > 1) && (!op->sym->m_dst)) {
+ MRVL_LOG(ERR, "op->sym->m_dst = NULL!");
+ return -1;
+ }
+ /* For non SG case:
+ * If application delivered us null dst buffer, it means it expects
+ * us to deliver the result in src buffer.
+ */
+ dst_mbuf = op->sym->m_dst ? op->sym->m_dst : op->sym->m_src;
+
+ if (!rte_pktmbuf_is_contiguous(dst_mbuf)) {
+ MRVL_LOG(ERR, "Segmented destination buffer not supported!");
+ return -1;
+ }
+
+ request->num_bufs = segments_nb;
+ for (i = 0; i < segments_nb; i++) {
+ /* Empty source. */
+ if (rte_pktmbuf_data_len(src_mbuf) == 0) {
+ /* EIP does not support 0 length buffers. */
+ MRVL_LOG(ERR, "Buffer length == 0 not supported!");
+ return -1;
+ }
+ src_bd[i].vaddr = rte_pktmbuf_mtod(src_mbuf, void *);
+ src_bd[i].paddr = rte_pktmbuf_iova(src_mbuf);
+ src_bd[i].len = rte_pktmbuf_data_len(src_mbuf);
+
+ src_mbuf = src_mbuf->next;
+ }
+ request->src = src_bd;
+
+ /* Empty destination. */
+ if (rte_pktmbuf_data_len(dst_mbuf) == 0) {
+ /* Make dst buffer fit at least source data. */
+ if (rte_pktmbuf_append(dst_mbuf,
+ rte_pktmbuf_data_len(op->sym->m_src)) == NULL) {
+ MRVL_LOG(ERR, "Unable to set big enough dst buffer!");
+ return -1;
+ }
+ }
+
+ request->dst = dst_bd;
+ dst_bd->vaddr = rte_pktmbuf_mtod(dst_mbuf, void *);
+ dst_bd->paddr = rte_pktmbuf_iova(dst_mbuf);
+
+ /*
+ * We can use all available space in dst_mbuf,
+ * not only what's used currently.
+ */
+ dst_bd->len = dst_mbuf->buf_len - rte_pktmbuf_headroom(dst_mbuf);
+
+
+ request->l3_offset = 0;
+ request->pkt_size = rte_pktmbuf_pkt_len(op->sym->m_src);
+
+ return 0;
+}
+
/*
*-----------------------------------------------------------------------------
* PMD Framework handlers
@@ -664,10 +858,15 @@ mrvl_crypto_pmd_enqueue_burst(void *queue_pair, struct rte_crypto_op **ops,
uint16_t nb_ops)
{
uint16_t iter_ops = 0;
- uint16_t to_enq = 0;
+ uint16_t to_enq_crp = 0;
+ uint16_t to_enq_sec = 0;
uint16_t consumed = 0;
int ret;
- struct sam_cio_op_params requests[nb_ops];
+ struct sam_cio_op_params requests_crp[nb_ops];
+ struct sam_cio_ipsec_params requests_sec[nb_ops];
+ uint16_t indx_map_crp[nb_ops];
+ uint16_t indx_map_sec[nb_ops];
+
/*
* SAM does not store bd pointers, so on-stack scope will be enough.
*/
@@ -679,53 +878,98 @@ mrvl_crypto_pmd_enqueue_burst(void *queue_pair, struct rte_crypto_op **ops,
return 0;
/* Prepare the burst. */
- memset(&requests, 0, sizeof(requests));
+ memset(&requests_crp, 0, sizeof(requests_crp));
+ memset(&requests_sec, 0, sizeof(requests_sec));
memset(&src_bd, 0, sizeof(src_bd));
/* Iterate through */
for (; iter_ops < nb_ops; ++iter_ops) {
/* store the op id for debug */
- src_bd[iter_ops].iter_ops = iter_ops;
- if (mrvl_request_prepare(&requests[iter_ops],
- src_bd[iter_ops].src_bd,
- &dst_bd[iter_ops],
- ops[iter_ops]) < 0) {
- MRVL_LOG(ERR, "Error while preparing parameters!");
- qp->stats.enqueue_err_count++;
- ops[iter_ops]->status = RTE_CRYPTO_OP_STATUS_ERROR;
-
- /*
- * Number of handled ops is increased
- * (even if the result of handling is error).
- */
- ++consumed;
- break;
+ if (ops[iter_ops]->sess_type == RTE_CRYPTO_OP_WITH_SESSION) {
+ src_bd[iter_ops].iter_ops = to_enq_crp;
+ indx_map_crp[to_enq_crp] = iter_ops;
+
+ if (mrvl_request_prepare_crp(&requests_crp[to_enq_crp],
+ src_bd[iter_ops].src_bd,
+ &dst_bd[iter_ops],
+ ops[iter_ops]) < 0) {
+ MRVL_LOG(ERR,
+ "Error while preparing parameters!");
+ qp->stats.enqueue_err_count++;
+ ops[iter_ops]->status =
+ RTE_CRYPTO_OP_STATUS_ERROR;
+ /*
+ * Number of handled ops is increased
+ * (even if the result of handling is error).
+ */
+ ++consumed;
+
+ break;
+ }
+ /* Increase the number of ops to enqueue. */
+ ++to_enq_crp;
+ } else {
+ src_bd[iter_ops].iter_ops = to_enq_sec;
+ indx_map_sec[to_enq_sec] = iter_ops;
+ if (mrvl_request_prepare_sec(&requests_sec[to_enq_sec],
+ src_bd[iter_ops].src_bd,
+ &dst_bd[iter_ops],
+ ops[iter_ops]) < 0) {
+ MRVL_LOG(ERR,
+ "Error while preparing parameters!");
+ qp->stats.enqueue_err_count++;
+ ops[iter_ops]->status =
+ RTE_CRYPTO_OP_STATUS_ERROR;
+ /*
+ * Number of handled ops is increased
+ * (even if the result of handling is error).
+ */
+ ++consumed;
+
+ break;
+ }
+ /* Increase the number of ops to enqueue. */
+ ++to_enq_sec;
}
ops[iter_ops]->status =
RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
- /* Increase the number of ops to enqueue. */
- ++to_enq;
} /* for (; iter_ops < nb_ops;... */
- if (to_enq > 0) {
+ if (to_enq_crp > 0) {
/* Send the burst */
- ret = sam_cio_enq(qp->cio, requests, &to_enq);
- consumed += to_enq;
+ ret = sam_cio_enq(qp->cio, requests_crp, &to_enq_crp);
+ consumed += to_enq_crp;
if (ret < 0) {
/*
* Trust SAM that in this case returned value will be at
* some point correct (now it is returned unmodified).
*/
- qp->stats.enqueue_err_count += to_enq;
- for (iter_ops = 0; iter_ops < to_enq; ++iter_ops)
- ops[iter_ops]->status =
+ qp->stats.enqueue_err_count += to_enq_crp;
+ for (int iter = 0; iter < to_enq_crp; ++iter)
+ ops[indx_map_crp[iter]]->status =
+ RTE_CRYPTO_OP_STATUS_ERROR;
+ }
+ }
+
+ if (to_enq_sec > 0) {
+ /* Send the burst */
+ ret = sam_cio_enq_ipsec(qp->cio, requests_sec, &to_enq_sec);
+ consumed += to_enq_sec;
+ if (ret < 0) {
+ /*
+ * Trust SAM that in this case returned value will be at
+ * some point correct (now it is returned unmodified).
+ */
+ qp->stats.enqueue_err_count += to_enq_sec;
+ for (int iter = 0; iter < to_enq_crp; ++iter)
+ ops[indx_map_sec[iter]]->status =
RTE_CRYPTO_OP_STATUS_ERROR;
}
}
- qp->stats.enqueued_count += to_enq;
+ qp->stats.enqueued_count += to_enq_sec + to_enq_crp;
return consumed;
}
@@ -747,6 +991,7 @@ mrvl_crypto_pmd_dequeue_burst(void *queue_pair,
struct sam_cio *cio = qp->cio;
struct sam_cio_op_result results[nb_ops];
uint16_t i;
+ struct rte_mbuf *dst;
ret = sam_cio_deq(cio, results, &nb_ops);
if (ret < 0) {
@@ -766,6 +1011,16 @@ mrvl_crypto_pmd_dequeue_burst(void *queue_pair,
switch (results[i].status) {
case SAM_CIO_OK:
ops[i]->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
+ if (ops[i]->sess_type ==
+ RTE_CRYPTO_OP_SECURITY_SESSION) {
+
+ if (ops[i]->sym->m_dst)
+ dst = ops[i]->sym->m_dst;
+ else
+ dst = ops[i]->sym->m_src;
+ dst->pkt_len = results[i].out_len;
+ dst->data_len = results[i].out_len;
+ }
break;
case SAM_CIO_ERR_ICV:
MRVL_LOG(DEBUG, "CIO returned SAM_CIO_ERR_ICV.");
@@ -799,6 +1054,7 @@ cryptodev_mrvl_crypto_create(const char *name,
struct rte_cryptodev *dev;
struct mrvl_crypto_private *internals;
struct sam_init_params sam_params;
+ struct rte_security_ctx *security_instance;
int ret = -EINVAL;
dev = rte_cryptodev_pmd_create(name, &vdev->device,
@@ -819,7 +1075,8 @@ cryptodev_mrvl_crypto_create(const char *name,
RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING |
RTE_CRYPTODEV_FF_HW_ACCELERATED |
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;
internals = dev->data->dev_private;
@@ -832,7 +1089,17 @@ cryptodev_mrvl_crypto_create(const char *name,
sam_params.max_num_sessions = internals->max_nb_sessions;
- /* sam_set_debug_flags(3); */
+ /* Initialize security_ctx only for primary process*/
+ security_instance = rte_malloc("rte_security_instances_ops",
+ sizeof(struct rte_security_ctx), 0);
+ if (security_instance == NULL)
+ return -ENOMEM;
+ security_instance->device = (void *)dev;
+ security_instance->ops = rte_mrvl_security_pmd_ops;
+ security_instance->sess_cnt = 0;
+ dev->security_ctx = security_instance;
+
+ /*sam_set_debug_flags(3);*/
ret = sam_init(&sam_params);
if (ret)
diff --git a/drivers/crypto/mvsam/rte_mrvl_pmd_ops.c b/drivers/crypto/mvsam/rte_mrvl_pmd_ops.c
index c61bdca36..e4dfda7fa 100644
--- a/drivers/crypto/mvsam/rte_mrvl_pmd_ops.c
+++ b/drivers/crypto/mvsam/rte_mrvl_pmd_ops.c
@@ -9,6 +9,7 @@
#include <rte_common.h>
#include <rte_malloc.h>
#include <rte_cryptodev_pmd.h>
+#include <rte_security_driver.h>
#include "mrvl_pmd_private.h"
@@ -823,3 +824,178 @@ static struct rte_cryptodev_ops mrvl_crypto_pmd_ops = {
};
struct rte_cryptodev_ops *rte_mrvl_crypto_pmd_ops = &mrvl_crypto_pmd_ops;
+
+/* IPSEC full offloading */
+
+/** Configure the session from a crypto xform chain (PMD ops callback).
+ *
+ * @param dev Pointer to the device structure.
+ * @param conf Pointer to the security session configuration structure.
+ * @param sess Pointer to the empty session structure.
+ * @param mempool Pointer to memory pool.
+ * @returns 0 upon success, negative value otherwise.
+ */
+static int
+mrvl_crypto_pmd_security_session_create(__rte_unused void *dev,
+ struct rte_security_session_conf *conf,
+ struct rte_security_session *sess,
+ struct rte_mempool *mempool)
+{
+ struct mrvl_crypto_session *mrvl_sess;
+ void *sess_private_data;
+ int ret;
+
+ if (sess == NULL) {
+ MRVL_LOG(ERR, "Invalid session struct.");
+ return -EINVAL;
+ }
+
+ if (rte_mempool_get(mempool, &sess_private_data)) {
+ MRVL_LOG(ERR, "Couldn't get object from session mempool.");
+ return -ENOMEM;
+ }
+
+ switch (conf->protocol) {
+ case RTE_SECURITY_PROTOCOL_IPSEC:
+ mrvl_sess = (struct mrvl_crypto_session *)sess_private_data;
+
+ struct rte_security_ipsec_xform *ipsec_xform = &conf->ipsec;
+ struct rte_crypto_sym_xform *crypto_xform = conf->crypto_xform;
+
+ ret = mrvl_ipsec_set_session_parameters(mrvl_sess,
+ ipsec_xform,
+ crypto_xform);
+ if (ret != 0) {
+ MRVL_LOG(ERR, "Failed to configure session parameters.");
+
+ /* Return session to mempool */
+ rte_mempool_put(mempool, sess_private_data);
+ return ret;
+ }
+
+ if (mrvl_sess->sam_sess_params.cipher_mode == SAM_CIPHER_GCM) {
+ /* Nonce is must for all counter modes */
+ mrvl_sess->sam_sess_params.cipher_iv =
+ (uint8_t *)&(conf->ipsec.salt);
+ }
+
+ ret = sam_session_create(&mrvl_sess->sam_sess_params,
+ &mrvl_sess->sam_sess);
+ if (ret < 0) {
+ MRVL_LOG(ERR, "PMD: failed to create IPSEC session.");
+ /* Return session to mempool */
+ rte_mempool_put(mempool, sess_private_data);
+ return ret;
+ }
+ break;
+ case RTE_SECURITY_PROTOCOL_MACSEC:
+ return -ENOTSUP;
+ default:
+ return -EINVAL;
+ }
+
+ set_sec_session_private_data(sess, sess_private_data);
+
+ return ret;
+}
+
+/** Clear the memory of session so it doesn't leave key material behind */
+static int
+mrvl_crypto_pmd_security_session_destroy(void *dev __rte_unused,
+ struct rte_security_session *sess)
+{
+ void *sess_priv = get_sec_session_private_data(sess);
+
+ /* Zero out the whole structure */
+ if (sess_priv) {
+ struct mrvl_crypto_session *mrvl_sess =
+ (struct mrvl_crypto_session *)sess_priv;
+ struct rte_mempool *sess_mp = rte_mempool_from_obj(sess_priv);
+
+ if (mrvl_sess->sam_sess &&
+ sam_session_destroy(mrvl_sess->sam_sess) < 0) {
+ MRVL_LOG(ERR, "Error while destroying session!");
+ }
+
+ rte_free(mrvl_sess->sam_sess_params.cipher_key);
+ rte_free(mrvl_sess->sam_sess_params.auth_key);
+ rte_free(mrvl_sess->sam_sess_params.cipher_iv);
+ memset(sess, 0, sizeof(struct rte_security_session));
+ set_sec_session_private_data(sess, NULL);
+ rte_mempool_put(sess_mp, sess_priv);
+ }
+ return 0;
+}
+
+static const
+struct rte_security_capability mrvl_crypto_pmd_sec_security_cap[] = {
+ { /* IPsec Lookaside Protocol offload ESP Tunnel Egress */
+ .action = RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL,
+ .protocol = RTE_SECURITY_PROTOCOL_IPSEC,
+ .ipsec = {
+ .proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP,
+ .mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL,
+ .direction = RTE_SECURITY_IPSEC_SA_DIR_EGRESS,
+ .options = { 0 },
+ .replay_win_sz_max = 128
+ },
+ .crypto_capabilities = mrvl_crypto_pmd_capabilities
+ },
+ { /* IPsec Lookaside Protocol offload ESP Tunnel Ingress */
+ .action = RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL,
+ .protocol = RTE_SECURITY_PROTOCOL_IPSEC,
+ .ipsec = {
+ .proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP,
+ .mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL,
+ .direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS,
+ .options = { 0 },
+ .replay_win_sz_max = 128
+ },
+ .crypto_capabilities = mrvl_crypto_pmd_capabilities
+ },
+ { /* IPsec Lookaside Protocol offload ESP Transport Egress */
+ .action = RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL,
+ .protocol = RTE_SECURITY_PROTOCOL_IPSEC,
+ .ipsec = {
+ .proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP,
+ .mode = RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT,
+ .direction = RTE_SECURITY_IPSEC_SA_DIR_EGRESS,
+ .options = { 0 },
+ .replay_win_sz_max = 128
+ },
+ .crypto_capabilities = mrvl_crypto_pmd_capabilities
+ },
+ { /* IPsec Lookaside Protocol offload ESP Transport Ingress */
+ .action = RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL,
+ .protocol = RTE_SECURITY_PROTOCOL_IPSEC,
+ .ipsec = {
+ .proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP,
+ .mode = RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT,
+ .direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS,
+ .options = { 0 },
+ .replay_win_sz_max = 128
+ },
+ .crypto_capabilities = mrvl_crypto_pmd_capabilities
+ },
+ {
+ .action = RTE_SECURITY_ACTION_TYPE_NONE
+ }
+};
+
+static const struct rte_security_capability *
+mrvl_crypto_pmd_security_capabilities_get(void *device __rte_unused)
+{
+ return mrvl_crypto_pmd_sec_security_cap;
+}
+
+struct rte_security_ops mrvl_sec_security_pmd_ops = {
+ .session_create = mrvl_crypto_pmd_security_session_create,
+ .session_update = NULL,
+ .session_stats_get = NULL,
+ .session_destroy = mrvl_crypto_pmd_security_session_destroy,
+ .set_pkt_metadata = NULL,
+ .capabilities_get = mrvl_crypto_pmd_security_capabilities_get
+};
+
+struct rte_security_ops *rte_mrvl_security_pmd_ops = &mrvl_sec_security_pmd_ops;
+
--
2.29.0
^ permalink raw reply [flat|nested] 8+ messages in thread
* [dpdk-dev] [PATCH v2] crypto/mvsam: IPSec full offload support
2021-07-01 6:57 [dpdk-dev] [PATCH] crypto/mvsam: IPSec full offload support danat
@ 2021-07-11 6:55 ` danat
2021-07-20 20:49 ` Akhil Goyal
0 siblings, 1 reply; 8+ messages in thread
From: danat @ 2021-07-11 6:55 UTC (permalink / raw)
To: gakhil; +Cc: dev, danat, lironh, michaelsh
From: Michael Shamis <michaelsh@marvell.com>
This patch provides the support for IPSec protocol
offload to the hardware.
Following security operations are added:
- session_create
- session_destroy
- capabilities_get
Signed-off-by: Michael Shamis <michaelsh@marvell.com>
Reviewed-by: Liron Himi <lironh@marvell.com>
Tested-by: Liron Himi <lironh@marvell.com>
---
drivers/crypto/mvsam/meson.build | 2 +-
drivers/crypto/mvsam/mrvl_pmd_private.h | 8 +-
drivers/crypto/mvsam/rte_mrvl_pmd.c | 333 +++++++++++++++++++++---
drivers/crypto/mvsam/rte_mrvl_pmd_ops.c | 176 +++++++++++++
4 files changed, 484 insertions(+), 35 deletions(-)
diff --git a/drivers/crypto/mvsam/meson.build b/drivers/crypto/mvsam/meson.build
index c0c828fbf..fec167bf2 100644
--- a/drivers/crypto/mvsam/meson.build
+++ b/drivers/crypto/mvsam/meson.build
@@ -14,4 +14,4 @@ ext_deps += dep
sources = files('rte_mrvl_pmd.c', 'rte_mrvl_pmd_ops.c')
-deps += ['bus_vdev', 'common_mvep']
+deps += ['bus_vdev', 'common_mvep', 'security']
diff --git a/drivers/crypto/mvsam/mrvl_pmd_private.h b/drivers/crypto/mvsam/mrvl_pmd_private.h
index e575330ef..719d73d82 100644
--- a/drivers/crypto/mvsam/mrvl_pmd_private.h
+++ b/drivers/crypto/mvsam/mrvl_pmd_private.h
@@ -82,11 +82,17 @@ struct mrvl_crypto_src_table {
} __rte_cache_aligned;
/** Set and validate MRVL crypto session parameters */
-extern int
+int
mrvl_crypto_set_session_parameters(struct mrvl_crypto_session *sess,
const struct rte_crypto_sym_xform *xform);
+int
+mrvl_ipsec_set_session_parameters(struct mrvl_crypto_session *sess,
+ struct rte_security_ipsec_xform *ipsec_xform,
+ struct rte_crypto_sym_xform *crypto_xform);
+
/** device specific operations function pointer structure */
extern struct rte_cryptodev_ops *rte_mrvl_crypto_pmd_ops;
+extern struct rte_security_ops *rte_mrvl_security_pmd_ops;
#endif /* _MRVL_PMD_PRIVATE_H_ */
diff --git a/drivers/crypto/mvsam/rte_mrvl_pmd.c b/drivers/crypto/mvsam/rte_mrvl_pmd.c
index b2cfa710f..c1ccd95fc 100644
--- a/drivers/crypto/mvsam/rte_mrvl_pmd.c
+++ b/drivers/crypto/mvsam/rte_mrvl_pmd.c
@@ -8,6 +8,7 @@
#include <rte_hexdump.h>
#include <rte_cryptodev.h>
#include <rte_cryptodev_pmd.h>
+#include <rte_security_driver.h>
#include <rte_bus_vdev.h>
#include <rte_malloc.h>
#include <rte_cpuflags.h>
@@ -398,7 +399,7 @@ mrvl_crypto_set_aead_session_parameters(struct mrvl_crypto_session *sess,
* Parse crypto transform chain and setup session parameters.
*
* @param dev Pointer to crypto device
- * @param sess Poiner to crypto session
+ * @param sess Pointer to crypto session
* @param xform Pointer to configuration structure chain for crypto operations.
* @returns 0 in case of success, negative value otherwise.
*/
@@ -461,6 +462,96 @@ mrvl_crypto_set_session_parameters(struct mrvl_crypto_session *sess,
return 0;
}
+static int
+replay_wsz_to_mask(uint32_t replay_win_sz)
+{
+ int mask = 0;
+
+ switch (replay_win_sz) {
+ case 0:
+ mask = SAM_ANTI_REPLY_MASK_NONE;
+ break;
+ case 32:
+ mask = SAM_ANTI_REPLY_MASK_32B;
+ break;
+ case 64:
+ mask = SAM_ANTI_REPLY_MASK_64B;
+ break;
+ case 128:
+ mask = SAM_ANTI_REPLY_MASK_128B;
+ break;
+ default:
+ MRVL_LOG(ERR, "Invalid antireplay window size");
+ return -EINVAL;
+ }
+
+ return mask;
+}
+
+/**
+ * Parse IPSEC session parameters.
+ *
+ * @param sess Pointer to security session
+ * @param ipsec_xform Pointer to configuration structure IPSEC operations.
+ * @param crypto_xform Pointer to chain for crypto operations.
+ * @returns 0 in case of success, negative value otherwise.
+ */
+int
+mrvl_ipsec_set_session_parameters(struct mrvl_crypto_session *sess,
+ struct rte_security_ipsec_xform *ipsec_xform,
+ struct rte_crypto_sym_xform *crypto_xform)
+{
+ int seq_mask_size;
+
+ /* Filter out spurious/broken requests */
+ if (ipsec_xform == NULL || crypto_xform == NULL)
+ return -EINVAL;
+
+ /* Crypto parameters handling */
+ if (mrvl_crypto_set_session_parameters(sess, crypto_xform))
+ return -EINVAL;
+
+ seq_mask_size = replay_wsz_to_mask(ipsec_xform->replay_win_sz);
+ if (seq_mask_size < 0)
+ return -EINVAL;
+
+ /* IPSEC protocol parameters handling */
+ sess->sam_sess_params.proto = SAM_PROTO_IPSEC;
+ sess->sam_sess_params.u.ipsec.is_esp =
+ (ipsec_xform->proto == RTE_SECURITY_IPSEC_SA_PROTO_ESP) ?
+ 1 : 0;
+ sess->sam_sess_params.u.ipsec.is_ip6 = 0;
+ sess->sam_sess_params.u.ipsec.is_tunnel =
+ (ipsec_xform->mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL) ?
+ 1 : 0;
+ sess->sam_sess_params.u.ipsec.is_esn = ipsec_xform->options.esn;
+ sess->sam_sess_params.u.ipsec.seq_mask_size = seq_mask_size;
+
+ sess->sam_sess_params.u.ipsec.tunnel.u.ipv4.sip =
+ (uint8_t *)(&ipsec_xform->tunnel.ipv4.src_ip.s_addr);
+ sess->sam_sess_params.u.ipsec.tunnel.u.ipv4.dip =
+ (uint8_t *)&(ipsec_xform->tunnel.ipv4.dst_ip.s_addr);
+
+ sess->sam_sess_params.u.ipsec.tunnel.u.ipv4.dscp =
+ ipsec_xform->tunnel.ipv4.dscp;
+ sess->sam_sess_params.u.ipsec.tunnel.u.ipv4.ttl =
+ ipsec_xform->tunnel.ipv4.ttl;
+ sess->sam_sess_params.u.ipsec.tunnel.u.ipv4.df =
+ ipsec_xform->tunnel.ipv4.df;
+ sess->sam_sess_params.u.ipsec.tunnel.copy_dscp =
+ ipsec_xform->options.copy_dscp;
+ sess->sam_sess_params.u.ipsec.tunnel.copy_flabel =
+ ipsec_xform->options.copy_flabel;
+ sess->sam_sess_params.u.ipsec.tunnel.copy_df =
+ ipsec_xform->options.copy_df;
+
+ sess->sam_sess_params.u.ipsec.is_natt = 0;
+ sess->sam_sess_params.u.ipsec.spi = ipsec_xform->spi;
+ sess->sam_sess_params.u.ipsec.seq = 0;
+
+ return 0;
+}
+
/*
*-----------------------------------------------------------------------------
* Process Operations
@@ -480,7 +571,7 @@ mrvl_crypto_set_session_parameters(struct mrvl_crypto_session *sess,
* @param op Pointer to DPDK crypto operation struct [In].
*/
static inline int
-mrvl_request_prepare(struct sam_cio_op_params *request,
+mrvl_request_prepare_crp(struct sam_cio_op_params *request,
struct sam_buf_info *src_bd,
struct sam_buf_info *dst_bd,
struct rte_crypto_op *op)
@@ -499,7 +590,8 @@ mrvl_request_prepare(struct sam_cio_op_params *request,
}
sess = (struct mrvl_crypto_session *)get_sym_session_private_data(
- op->sym->session, cryptodev_driver_id);
+ op->sym->session,
+ cryptodev_driver_id);
if (unlikely(sess == NULL)) {
MRVL_LOG(ERR, "Session was not created for this device!");
return -EINVAL;
@@ -569,7 +661,7 @@ mrvl_request_prepare(struct sam_cio_op_params *request,
request->cipher_len = op->sym->aead.data.length;
request->cipher_offset = op->sym->aead.data.offset;
request->cipher_iv = rte_crypto_op_ctod_offset(op, uint8_t *,
- sess->cipher_iv_offset);
+ sess->cipher_iv_offset);
request->auth_aad = op->sym->aead.aad.data;
request->auth_offset = request->cipher_offset;
@@ -645,6 +737,108 @@ mrvl_request_prepare(struct sam_cio_op_params *request,
return -1;
}
+/**
+ * Prepare a single security protocol request.
+ *
+ * This function basically translates DPDK security request into one
+ * understandable by MUDSK's SAM. If this is a first request in a session,
+ * it starts the session.
+ *
+ * @param request Pointer to pre-allocated && reset request buffer [Out].
+ * @param src_bd Pointer to pre-allocated source descriptor [Out].
+ * @param dst_bd Pointer to pre-allocated destination descriptor [Out].
+ * @param op Pointer to DPDK crypto operation struct [In].
+ */
+static inline int
+mrvl_request_prepare_sec(struct sam_cio_ipsec_params *request,
+ struct sam_buf_info *src_bd,
+ struct sam_buf_info *dst_bd,
+ struct rte_crypto_op *op)
+{
+ struct mrvl_crypto_session *sess;
+ struct rte_mbuf *src_mbuf, *dst_mbuf;
+ uint16_t segments_nb;
+ int i;
+
+ if (unlikely(op->sess_type != RTE_CRYPTO_OP_SECURITY_SESSION)) {
+ MRVL_LOG(ERR, "MRVL SECURITY: sess_type is not SECURITY_SESSION");
+ return -EINVAL;
+ }
+
+ sess = (struct mrvl_crypto_session *)get_sec_session_private_data(
+ op->sym->sec_session);
+ if (unlikely(sess == NULL)) {
+ MRVL_LOG(ERR, "Session was not created for this device! %d",
+ cryptodev_driver_id);
+ return -EINVAL;
+ }
+
+ request->sa = sess->sam_sess;
+ request->cookie = op;
+ src_mbuf = op->sym->m_src;
+ segments_nb = src_mbuf->nb_segs;
+ /* The following conditions must be met:
+ * - Destination buffer is required when segmented source buffer
+ * - Segmented destination buffer is not supported
+ */
+ if ((segments_nb > 1) && (!op->sym->m_dst)) {
+ MRVL_LOG(ERR, "op->sym->m_dst = NULL!");
+ return -1;
+ }
+ /* For non SG case:
+ * If application delivered us null dst buffer, it means it expects
+ * us to deliver the result in src buffer.
+ */
+ dst_mbuf = op->sym->m_dst ? op->sym->m_dst : op->sym->m_src;
+
+ if (!rte_pktmbuf_is_contiguous(dst_mbuf)) {
+ MRVL_LOG(ERR, "Segmented destination buffer not supported!");
+ return -1;
+ }
+
+ request->num_bufs = segments_nb;
+ for (i = 0; i < segments_nb; i++) {
+ /* Empty source. */
+ if (rte_pktmbuf_data_len(src_mbuf) == 0) {
+ /* EIP does not support 0 length buffers. */
+ MRVL_LOG(ERR, "Buffer length == 0 not supported!");
+ return -1;
+ }
+ src_bd[i].vaddr = rte_pktmbuf_mtod(src_mbuf, void *);
+ src_bd[i].paddr = rte_pktmbuf_iova(src_mbuf);
+ src_bd[i].len = rte_pktmbuf_data_len(src_mbuf);
+
+ src_mbuf = src_mbuf->next;
+ }
+ request->src = src_bd;
+
+ /* Empty destination. */
+ if (rte_pktmbuf_data_len(dst_mbuf) == 0) {
+ /* Make dst buffer fit at least source data. */
+ if (rte_pktmbuf_append(dst_mbuf,
+ rte_pktmbuf_data_len(op->sym->m_src)) == NULL) {
+ MRVL_LOG(ERR, "Unable to set big enough dst buffer!");
+ return -1;
+ }
+ }
+
+ request->dst = dst_bd;
+ dst_bd->vaddr = rte_pktmbuf_mtod(dst_mbuf, void *);
+ dst_bd->paddr = rte_pktmbuf_iova(dst_mbuf);
+
+ /*
+ * We can use all available space in dst_mbuf,
+ * not only what's used currently.
+ */
+ dst_bd->len = dst_mbuf->buf_len - rte_pktmbuf_headroom(dst_mbuf);
+
+
+ request->l3_offset = 0;
+ request->pkt_size = rte_pktmbuf_pkt_len(op->sym->m_src);
+
+ return 0;
+}
+
/*
*-----------------------------------------------------------------------------
* PMD Framework handlers
@@ -664,10 +858,15 @@ mrvl_crypto_pmd_enqueue_burst(void *queue_pair, struct rte_crypto_op **ops,
uint16_t nb_ops)
{
uint16_t iter_ops = 0;
- uint16_t to_enq = 0;
+ uint16_t to_enq_crp = 0;
+ uint16_t to_enq_sec = 0;
uint16_t consumed = 0;
int ret;
- struct sam_cio_op_params requests[nb_ops];
+ struct sam_cio_op_params requests_crp[nb_ops];
+ struct sam_cio_ipsec_params requests_sec[nb_ops];
+ uint16_t indx_map_crp[nb_ops];
+ uint16_t indx_map_sec[nb_ops];
+
/*
* SAM does not store bd pointers, so on-stack scope will be enough.
*/
@@ -679,53 +878,98 @@ mrvl_crypto_pmd_enqueue_burst(void *queue_pair, struct rte_crypto_op **ops,
return 0;
/* Prepare the burst. */
- memset(&requests, 0, sizeof(requests));
+ memset(&requests_crp, 0, sizeof(requests_crp));
+ memset(&requests_sec, 0, sizeof(requests_sec));
memset(&src_bd, 0, sizeof(src_bd));
/* Iterate through */
for (; iter_ops < nb_ops; ++iter_ops) {
/* store the op id for debug */
- src_bd[iter_ops].iter_ops = iter_ops;
- if (mrvl_request_prepare(&requests[iter_ops],
- src_bd[iter_ops].src_bd,
- &dst_bd[iter_ops],
- ops[iter_ops]) < 0) {
- MRVL_LOG(ERR, "Error while preparing parameters!");
- qp->stats.enqueue_err_count++;
- ops[iter_ops]->status = RTE_CRYPTO_OP_STATUS_ERROR;
-
- /*
- * Number of handled ops is increased
- * (even if the result of handling is error).
- */
- ++consumed;
- break;
+ if (ops[iter_ops]->sess_type == RTE_CRYPTO_OP_WITH_SESSION) {
+ src_bd[iter_ops].iter_ops = to_enq_crp;
+ indx_map_crp[to_enq_crp] = iter_ops;
+
+ if (mrvl_request_prepare_crp(&requests_crp[to_enq_crp],
+ src_bd[iter_ops].src_bd,
+ &dst_bd[iter_ops],
+ ops[iter_ops]) < 0) {
+ MRVL_LOG(ERR,
+ "Error while preparing parameters!");
+ qp->stats.enqueue_err_count++;
+ ops[iter_ops]->status =
+ RTE_CRYPTO_OP_STATUS_ERROR;
+ /*
+ * Number of handled ops is increased
+ * (even if the result of handling is error).
+ */
+ ++consumed;
+
+ break;
+ }
+ /* Increase the number of ops to enqueue. */
+ ++to_enq_crp;
+ } else {
+ src_bd[iter_ops].iter_ops = to_enq_sec;
+ indx_map_sec[to_enq_sec] = iter_ops;
+ if (mrvl_request_prepare_sec(&requests_sec[to_enq_sec],
+ src_bd[iter_ops].src_bd,
+ &dst_bd[iter_ops],
+ ops[iter_ops]) < 0) {
+ MRVL_LOG(ERR,
+ "Error while preparing parameters!");
+ qp->stats.enqueue_err_count++;
+ ops[iter_ops]->status =
+ RTE_CRYPTO_OP_STATUS_ERROR;
+ /*
+ * Number of handled ops is increased
+ * (even if the result of handling is error).
+ */
+ ++consumed;
+
+ break;
+ }
+ /* Increase the number of ops to enqueue. */
+ ++to_enq_sec;
}
ops[iter_ops]->status =
RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
- /* Increase the number of ops to enqueue. */
- ++to_enq;
} /* for (; iter_ops < nb_ops;... */
- if (to_enq > 0) {
+ if (to_enq_crp > 0) {
/* Send the burst */
- ret = sam_cio_enq(qp->cio, requests, &to_enq);
- consumed += to_enq;
+ ret = sam_cio_enq(qp->cio, requests_crp, &to_enq_crp);
+ consumed += to_enq_crp;
if (ret < 0) {
/*
* Trust SAM that in this case returned value will be at
* some point correct (now it is returned unmodified).
*/
- qp->stats.enqueue_err_count += to_enq;
- for (iter_ops = 0; iter_ops < to_enq; ++iter_ops)
- ops[iter_ops]->status =
+ qp->stats.enqueue_err_count += to_enq_crp;
+ for (int iter = 0; iter < to_enq_crp; ++iter)
+ ops[indx_map_crp[iter]]->status =
+ RTE_CRYPTO_OP_STATUS_ERROR;
+ }
+ }
+
+ if (to_enq_sec > 0) {
+ /* Send the burst */
+ ret = sam_cio_enq_ipsec(qp->cio, requests_sec, &to_enq_sec);
+ consumed += to_enq_sec;
+ if (ret < 0) {
+ /*
+ * Trust SAM that in this case returned value will be at
+ * some point correct (now it is returned unmodified).
+ */
+ qp->stats.enqueue_err_count += to_enq_sec;
+ for (int iter = 0; iter < to_enq_crp; ++iter)
+ ops[indx_map_sec[iter]]->status =
RTE_CRYPTO_OP_STATUS_ERROR;
}
}
- qp->stats.enqueued_count += to_enq;
+ qp->stats.enqueued_count += to_enq_sec + to_enq_crp;
return consumed;
}
@@ -747,6 +991,7 @@ mrvl_crypto_pmd_dequeue_burst(void *queue_pair,
struct sam_cio *cio = qp->cio;
struct sam_cio_op_result results[nb_ops];
uint16_t i;
+ struct rte_mbuf *dst;
ret = sam_cio_deq(cio, results, &nb_ops);
if (ret < 0) {
@@ -766,6 +1011,16 @@ mrvl_crypto_pmd_dequeue_burst(void *queue_pair,
switch (results[i].status) {
case SAM_CIO_OK:
ops[i]->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
+ if (ops[i]->sess_type ==
+ RTE_CRYPTO_OP_SECURITY_SESSION) {
+
+ if (ops[i]->sym->m_dst)
+ dst = ops[i]->sym->m_dst;
+ else
+ dst = ops[i]->sym->m_src;
+ dst->pkt_len = results[i].out_len;
+ dst->data_len = results[i].out_len;
+ }
break;
case SAM_CIO_ERR_ICV:
MRVL_LOG(DEBUG, "CIO returned SAM_CIO_ERR_ICV.");
@@ -799,6 +1054,7 @@ cryptodev_mrvl_crypto_create(const char *name,
struct rte_cryptodev *dev;
struct mrvl_crypto_private *internals;
struct sam_init_params sam_params;
+ struct rte_security_ctx *security_instance;
int ret = -EINVAL;
dev = rte_cryptodev_pmd_create(name, &vdev->device,
@@ -819,7 +1075,8 @@ cryptodev_mrvl_crypto_create(const char *name,
RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING |
RTE_CRYPTODEV_FF_HW_ACCELERATED |
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;
internals = dev->data->dev_private;
@@ -832,7 +1089,17 @@ cryptodev_mrvl_crypto_create(const char *name,
sam_params.max_num_sessions = internals->max_nb_sessions;
- /* sam_set_debug_flags(3); */
+ /* Initialize security_ctx only for primary process*/
+ security_instance = rte_malloc("rte_security_instances_ops",
+ sizeof(struct rte_security_ctx), 0);
+ if (security_instance == NULL)
+ return -ENOMEM;
+ security_instance->device = (void *)dev;
+ security_instance->ops = rte_mrvl_security_pmd_ops;
+ security_instance->sess_cnt = 0;
+ dev->security_ctx = security_instance;
+
+ /*sam_set_debug_flags(3);*/
ret = sam_init(&sam_params);
if (ret)
diff --git a/drivers/crypto/mvsam/rte_mrvl_pmd_ops.c b/drivers/crypto/mvsam/rte_mrvl_pmd_ops.c
index c61bdca36..e4dfda7fa 100644
--- a/drivers/crypto/mvsam/rte_mrvl_pmd_ops.c
+++ b/drivers/crypto/mvsam/rte_mrvl_pmd_ops.c
@@ -9,6 +9,7 @@
#include <rte_common.h>
#include <rte_malloc.h>
#include <rte_cryptodev_pmd.h>
+#include <rte_security_driver.h>
#include "mrvl_pmd_private.h"
@@ -823,3 +824,178 @@ static struct rte_cryptodev_ops mrvl_crypto_pmd_ops = {
};
struct rte_cryptodev_ops *rte_mrvl_crypto_pmd_ops = &mrvl_crypto_pmd_ops;
+
+/* IPSEC full offloading */
+
+/** Configure the session from a crypto xform chain (PMD ops callback).
+ *
+ * @param dev Pointer to the device structure.
+ * @param conf Pointer to the security session configuration structure.
+ * @param sess Pointer to the empty session structure.
+ * @param mempool Pointer to memory pool.
+ * @returns 0 upon success, negative value otherwise.
+ */
+static int
+mrvl_crypto_pmd_security_session_create(__rte_unused void *dev,
+ struct rte_security_session_conf *conf,
+ struct rte_security_session *sess,
+ struct rte_mempool *mempool)
+{
+ struct mrvl_crypto_session *mrvl_sess;
+ void *sess_private_data;
+ int ret;
+
+ if (sess == NULL) {
+ MRVL_LOG(ERR, "Invalid session struct.");
+ return -EINVAL;
+ }
+
+ if (rte_mempool_get(mempool, &sess_private_data)) {
+ MRVL_LOG(ERR, "Couldn't get object from session mempool.");
+ return -ENOMEM;
+ }
+
+ switch (conf->protocol) {
+ case RTE_SECURITY_PROTOCOL_IPSEC:
+ mrvl_sess = (struct mrvl_crypto_session *)sess_private_data;
+
+ struct rte_security_ipsec_xform *ipsec_xform = &conf->ipsec;
+ struct rte_crypto_sym_xform *crypto_xform = conf->crypto_xform;
+
+ ret = mrvl_ipsec_set_session_parameters(mrvl_sess,
+ ipsec_xform,
+ crypto_xform);
+ if (ret != 0) {
+ MRVL_LOG(ERR, "Failed to configure session parameters.");
+
+ /* Return session to mempool */
+ rte_mempool_put(mempool, sess_private_data);
+ return ret;
+ }
+
+ if (mrvl_sess->sam_sess_params.cipher_mode == SAM_CIPHER_GCM) {
+ /* Nonce is must for all counter modes */
+ mrvl_sess->sam_sess_params.cipher_iv =
+ (uint8_t *)&(conf->ipsec.salt);
+ }
+
+ ret = sam_session_create(&mrvl_sess->sam_sess_params,
+ &mrvl_sess->sam_sess);
+ if (ret < 0) {
+ MRVL_LOG(ERR, "PMD: failed to create IPSEC session.");
+ /* Return session to mempool */
+ rte_mempool_put(mempool, sess_private_data);
+ return ret;
+ }
+ break;
+ case RTE_SECURITY_PROTOCOL_MACSEC:
+ return -ENOTSUP;
+ default:
+ return -EINVAL;
+ }
+
+ set_sec_session_private_data(sess, sess_private_data);
+
+ return ret;
+}
+
+/** Clear the memory of session so it doesn't leave key material behind */
+static int
+mrvl_crypto_pmd_security_session_destroy(void *dev __rte_unused,
+ struct rte_security_session *sess)
+{
+ void *sess_priv = get_sec_session_private_data(sess);
+
+ /* Zero out the whole structure */
+ if (sess_priv) {
+ struct mrvl_crypto_session *mrvl_sess =
+ (struct mrvl_crypto_session *)sess_priv;
+ struct rte_mempool *sess_mp = rte_mempool_from_obj(sess_priv);
+
+ if (mrvl_sess->sam_sess &&
+ sam_session_destroy(mrvl_sess->sam_sess) < 0) {
+ MRVL_LOG(ERR, "Error while destroying session!");
+ }
+
+ rte_free(mrvl_sess->sam_sess_params.cipher_key);
+ rte_free(mrvl_sess->sam_sess_params.auth_key);
+ rte_free(mrvl_sess->sam_sess_params.cipher_iv);
+ memset(sess, 0, sizeof(struct rte_security_session));
+ set_sec_session_private_data(sess, NULL);
+ rte_mempool_put(sess_mp, sess_priv);
+ }
+ return 0;
+}
+
+static const
+struct rte_security_capability mrvl_crypto_pmd_sec_security_cap[] = {
+ { /* IPsec Lookaside Protocol offload ESP Tunnel Egress */
+ .action = RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL,
+ .protocol = RTE_SECURITY_PROTOCOL_IPSEC,
+ .ipsec = {
+ .proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP,
+ .mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL,
+ .direction = RTE_SECURITY_IPSEC_SA_DIR_EGRESS,
+ .options = { 0 },
+ .replay_win_sz_max = 128
+ },
+ .crypto_capabilities = mrvl_crypto_pmd_capabilities
+ },
+ { /* IPsec Lookaside Protocol offload ESP Tunnel Ingress */
+ .action = RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL,
+ .protocol = RTE_SECURITY_PROTOCOL_IPSEC,
+ .ipsec = {
+ .proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP,
+ .mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL,
+ .direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS,
+ .options = { 0 },
+ .replay_win_sz_max = 128
+ },
+ .crypto_capabilities = mrvl_crypto_pmd_capabilities
+ },
+ { /* IPsec Lookaside Protocol offload ESP Transport Egress */
+ .action = RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL,
+ .protocol = RTE_SECURITY_PROTOCOL_IPSEC,
+ .ipsec = {
+ .proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP,
+ .mode = RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT,
+ .direction = RTE_SECURITY_IPSEC_SA_DIR_EGRESS,
+ .options = { 0 },
+ .replay_win_sz_max = 128
+ },
+ .crypto_capabilities = mrvl_crypto_pmd_capabilities
+ },
+ { /* IPsec Lookaside Protocol offload ESP Transport Ingress */
+ .action = RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL,
+ .protocol = RTE_SECURITY_PROTOCOL_IPSEC,
+ .ipsec = {
+ .proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP,
+ .mode = RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT,
+ .direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS,
+ .options = { 0 },
+ .replay_win_sz_max = 128
+ },
+ .crypto_capabilities = mrvl_crypto_pmd_capabilities
+ },
+ {
+ .action = RTE_SECURITY_ACTION_TYPE_NONE
+ }
+};
+
+static const struct rte_security_capability *
+mrvl_crypto_pmd_security_capabilities_get(void *device __rte_unused)
+{
+ return mrvl_crypto_pmd_sec_security_cap;
+}
+
+struct rte_security_ops mrvl_sec_security_pmd_ops = {
+ .session_create = mrvl_crypto_pmd_security_session_create,
+ .session_update = NULL,
+ .session_stats_get = NULL,
+ .session_destroy = mrvl_crypto_pmd_security_session_destroy,
+ .set_pkt_metadata = NULL,
+ .capabilities_get = mrvl_crypto_pmd_security_capabilities_get
+};
+
+struct rte_security_ops *rte_mrvl_security_pmd_ops = &mrvl_sec_security_pmd_ops;
+
--
2.17.1
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [dpdk-dev] [PATCH v2] crypto/mvsam: IPSec full offload support
2021-07-11 6:55 ` [dpdk-dev] [PATCH v2] " danat
@ 2021-07-20 20:49 ` Akhil Goyal
2021-07-21 12:48 ` Thomas Monjalon
0 siblings, 1 reply; 8+ messages in thread
From: Akhil Goyal @ 2021-07-20 20:49 UTC (permalink / raw)
To: Dana Vardi; +Cc: dev, Dana Vardi, Liron Himi, Michael Shamis
> From: Michael Shamis <michaelsh@marvell.com>
>
> This patch provides the support for IPSec protocol
> offload to the hardware.
> Following security operations are added:
> - session_create
> - session_destroy
> - capabilities_get
>
> Signed-off-by: Michael Shamis <michaelsh@marvell.com>
> Reviewed-by: Liron Himi <lironh@marvell.com>
> Tested-by: Liron Himi <lironh@marvell.com>
> ---
Applied to dpdk-next-crypto
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [dpdk-dev] [PATCH v2] crypto/mvsam: IPSec full offload support
2021-07-20 20:49 ` Akhil Goyal
@ 2021-07-21 12:48 ` Thomas Monjalon
2021-07-21 13:01 ` [dpdk-dev] [EXT] " Akhil Goyal
0 siblings, 1 reply; 8+ messages in thread
From: Thomas Monjalon @ 2021-07-21 12:48 UTC (permalink / raw)
To: Liron Himi, Michael Shamis, Akhil Goyal; +Cc: Dana Vardi, dev, dev, Dana Vardi
The correct wording is "IPsec"
and it is flagged by devtools/check-git-log.sh
20/07/2021 22:49, Akhil Goyal:
> > From: Michael Shamis <michaelsh@marvell.com>
> >
> > This patch provides the support for IPSec protocol
> > offload to the hardware.
> > Following security operations are added:
> > - session_create
> > - session_destroy
> > - capabilities_get
> >
> > Signed-off-by: Michael Shamis <michaelsh@marvell.com>
> > Reviewed-by: Liron Himi <lironh@marvell.com>
> > Tested-by: Liron Himi <lironh@marvell.com>
> > ---
> Applied to dpdk-next-crypto
A checkpatch warning was ignored:
Warning in drivers/crypto/mvsam/rte_mrvl_pmd.c:
Declaring a variable inside for()
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [dpdk-dev] [EXT] Re: [PATCH v2] crypto/mvsam: IPSec full offload support
2021-07-21 12:48 ` Thomas Monjalon
@ 2021-07-21 13:01 ` Akhil Goyal
2021-07-21 13:14 ` Akhil Goyal
0 siblings, 1 reply; 8+ messages in thread
From: Akhil Goyal @ 2021-07-21 13:01 UTC (permalink / raw)
To: Thomas Monjalon, Liron Himi, Michael Shamis
Cc: Dana Vardi, dev, dev, Dana Vardi
> The correct wording is "IPsec"
> and it is flagged by devtools/check-git-log.sh
>
Ahh my bad! Missed to run that on last patch.
> 20/07/2021 22:49, Akhil Goyal:
> > > From: Michael Shamis <michaelsh@marvell.com>
> > >
> > > This patch provides the support for IPSec protocol
> > > offload to the hardware.
> > > Following security operations are added:
> > > - session_create
> > > - session_destroy
> > > - capabilities_get
> > >
> > > Signed-off-by: Michael Shamis <michaelsh@marvell.com>
> > > Reviewed-by: Liron Himi <lironh@marvell.com>
> > > Tested-by: Liron Himi <lironh@marvell.com>
> > > ---
> > Applied to dpdk-next-crypto
>
> A checkpatch warning was ignored:
>
> Warning in drivers/crypto/mvsam/rte_mrvl_pmd.c:
> Declaring a variable inside for()
>
Will be fixing in next few minutes.
Thanks for highlighting
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [dpdk-dev] [EXT] Re: [PATCH v2] crypto/mvsam: IPSec full offload support
2021-07-21 13:01 ` [dpdk-dev] [EXT] " Akhil Goyal
@ 2021-07-21 13:14 ` Akhil Goyal
2021-07-21 13:54 ` Thomas Monjalon
0 siblings, 1 reply; 8+ messages in thread
From: Akhil Goyal @ 2021-07-21 13:14 UTC (permalink / raw)
To: Thomas Monjalon, Liron Himi, Michael Shamis, Dana Vardi
Cc: dev, dev, Dana Vardi
>
> > The correct wording is "IPsec"
> > and it is flagged by devtools/check-git-log.sh
> >
>
> Ahh my bad! Missed to run that on last patch.
>
> > 20/07/2021 22:49, Akhil Goyal:
> > > > From: Michael Shamis <michaelsh@marvell.com>
> > > >
> > > > This patch provides the support for IPSec protocol
> > > > offload to the hardware.
> > > > Following security operations are added:
> > > > - session_create
> > > > - session_destroy
> > > > - capabilities_get
> > > >
> > > > Signed-off-by: Michael Shamis <michaelsh@marvell.com>
> > > > Reviewed-by: Liron Himi <lironh@marvell.com>
> > > > Tested-by: Liron Himi <lironh@marvell.com>
> > > > ---
> > > Applied to dpdk-next-crypto
> >
> > A checkpatch warning was ignored:
> >
> > Warning in drivers/crypto/mvsam/rte_mrvl_pmd.c:
> > Declaring a variable inside for()
> >
> Will be fixing in next few minutes.
> Thanks for highlighting
It is fixed now.
Documentation update was also missing. It is also added.
@Dana Vardi, @Michael Shamis: please ensure to update documentation
Along with patch.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [dpdk-dev] [EXT] Re: [PATCH v2] crypto/mvsam: IPSec full offload support
2021-07-21 13:14 ` Akhil Goyal
@ 2021-07-21 13:54 ` Thomas Monjalon
2021-07-22 7:40 ` Akhil Goyal
0 siblings, 1 reply; 8+ messages in thread
From: Thomas Monjalon @ 2021-07-21 13:54 UTC (permalink / raw)
To: Akhil Goyal; +Cc: Liron Himi, Michael Shamis, dev, Dana Vardi
21/07/2021 15:14, Akhil Goyal:
> > > A checkpatch warning was ignored:
> > >
> > > Warning in drivers/crypto/mvsam/rte_mrvl_pmd.c:
> > > Declaring a variable inside for()
> > >
> > Will be fixing in next few minutes.
> > Thanks for highlighting
>
> It is fixed now.
> Documentation update was also missing. It is also added.
Thanks
> @Dana Vardi, @Michael Shamis: please ensure to update documentation
> Along with patch.
You should implement checks for crypto doc in devtools/check-doc-vs-code.sh
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2021-07-22 7:40 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-01 6:57 [dpdk-dev] [PATCH] crypto/mvsam: IPSec full offload support danat
2021-07-11 6:55 ` [dpdk-dev] [PATCH v2] " danat
2021-07-20 20:49 ` Akhil Goyal
2021-07-21 12:48 ` Thomas Monjalon
2021-07-21 13:01 ` [dpdk-dev] [EXT] " Akhil Goyal
2021-07-21 13:14 ` Akhil Goyal
2021-07-21 13:54 ` Thomas Monjalon
2021-07-22 7:40 ` 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).