#include <rte_common.h>
#include <rte_malloc.h>
-#include <rte_cryptodev_pmd.h>
+#include <cryptodev_pmd.h>
+#include <rte_security_driver.h>
-#include "rte_mrvl_pmd_private.h"
+#include "mrvl_pmd_private.h"
/**
* Capabilities list to be used in reporting to DPDK.
.increment = 1
},
.digest_size = {
- .min = 28,
+ .min = 12,
.max = 28,
.increment = 0
},
},
.digest_size = {
.min = 12,
- .max = 48,
+ .max = 64,
.increment = 4
},
}, }
},
.digest_size = {
.min = 12,
- .max = 48,
+ .max = 64,
.increment = 0
},
}, }
.increment = 0
},
.aad_size = {
- .min = 8,
- .max = 12,
- .increment = 4
+ .min = 0,
+ .max = 64,
+ .increment = 1
},
.iv_size = {
.min = 12,
static int
mrvl_crypto_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
const struct rte_cryptodev_qp_conf *qp_conf,
- int socket_id, struct rte_mempool *session_pool)
+ int socket_id)
{
struct mrvl_crypto_qp *qp = NULL;
char match[RTE_CRYPTODEV_NAME_MAX_LEN];
*/
int num = sam_get_num_inst();
if (num == 0) {
- MRVL_CRYPTO_LOG_ERR("No crypto engines detected.\n");
+ MRVL_LOG(ERR, "No crypto engines detected!");
return -1;
}
/*
+ * In case just one engine is enabled mapping will look as
+ * follows:
+ * qp: 0 1 2 3
+ * cio-x:y: cio-0:0, cio-0:1, cio-0:2, cio-0:3
+ *
* In case two crypto engines are enabled qps will
* be evenly spread among them. Even and odd qps will
* be handled by cio-0 and cio-1 respectively. qp-cio mapping
* qp: 4 5 6 7
* cio-x:y: cio-0:2, cio-1:2, cio-0:3, cio-1:3
*
- * In case just one engine is enabled mapping will look as
- * follows:
+ * In case of three crypto engines are enabled qps will
+ * be mapped as following:
+ *
* qp: 0 1 2 3
- * cio-x:y: cio-0:0, cio-0:1, cio-0:2, cio-0:3
+ * cio-x:y: cio-0:0, cio-1:0, cio-2:0, cio-0:1
+ *
+ * qp: 4 5 6 7
+ * cio-x:y: cio-1:1, cio-2:1, cio-0:2, cio-1:2
+ *
+ * qp: 8 9 10 11
+ * cio-x:y: cio-2:2, cio-0:3, cio-1:3, cio-2:3
*/
n = snprintf(match, sizeof(match), "cio-%u:%u",
qp_id % num, qp_id / num);
if (sam_cio_init(&qp->cio_params, &qp->cio) < 0)
break;
- qp->sess_mp = session_pool;
+ qp->sess_mp = qp_conf->mp_session;
+ qp->sess_mp_priv = qp_conf->mp_session_private;
memset(&qp->stats, 0, sizeof(qp->stats));
dev->data->queue_pairs[qp_id] = qp;
return -1;
}
-/** Return the number of allocated queue pairs (PMD ops callback).
- *
- * @param dev Pointer to the device structure.
- * @returns Number of allocated queue pairs.
- */
-static uint32_t
-mrvl_crypto_pmd_qp_count(struct rte_cryptodev *dev)
-{
- return dev->data->nb_queue_pairs;
-}
-
/** Returns the size of the session structure (PMD ops callback).
*
* @param dev Pointer to the device structure [Unused].
/** Configure the session from a crypto xform chain (PMD ops callback).
*
* @param dev Pointer to the device structure.
- * @param xform Pointer to the crytpo configuration structure.
+ * @param xform Pointer to the crypto configuration structure.
* @param sess Pointer to the empty session structure.
* @returns 0 upon success, negative value otherwise.
*/
int ret;
if (sess == NULL) {
- MRVL_CRYPTO_LOG_ERR("Invalid session struct.");
+ MRVL_LOG(ERR, "Invalid session struct!");
return -EINVAL;
}
return -ENOMEM;
}
+ memset(sess_private_data, 0, sizeof(struct mrvl_crypto_session));
+
ret = mrvl_crypto_set_session_parameters(sess_private_data, xform);
if (ret != 0) {
- MRVL_CRYPTO_LOG_ERR("Failed to configure session parameters.");
+ MRVL_LOG(ERR, "Failed to configure session parameters!");
/* Return session to mempool */
rte_mempool_put(mp, sess_private_data);
mrvl_sess = (struct mrvl_crypto_session *)sess_private_data;
if (sam_session_create(&mrvl_sess->sam_sess_params,
&mrvl_sess->sam_sess) < 0) {
- MRVL_CRYPTO_LOG_DBG("Failed to create session!");
+ MRVL_LOG(DEBUG, "Failed to create session!");
return -EIO;
}
+ /* free the keys memory allocated for session creation */
+ free(mrvl_sess->sam_sess_params.cipher_key);
+ free(mrvl_sess->sam_sess_params.auth_key);
+
return 0;
}
if (mrvl_sess->sam_sess &&
sam_session_destroy(mrvl_sess->sam_sess) < 0) {
- MRVL_CRYPTO_LOG_INFO("Error while destroying session!");
+ MRVL_LOG(ERR, "Error while destroying session!");
}
- memset(sess, 0, sizeof(struct mrvl_crypto_session));
+ memset(mrvl_sess, 0, sizeof(struct mrvl_crypto_session));
struct rte_mempool *sess_mp = rte_mempool_from_obj(sess_priv);
set_sym_session_private_data(sess, index, NULL);
rte_mempool_put(sess_mp, sess_priv);
.queue_pair_setup = mrvl_crypto_pmd_qp_setup,
.queue_pair_release = mrvl_crypto_pmd_qp_release,
- .queue_pair_count = mrvl_crypto_pmd_qp_count,
.sym_session_get_size = mrvl_crypto_pmd_sym_session_get_size,
.sym_session_configure = mrvl_crypto_pmd_sym_session_configure,
};
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;