X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fcrypto%2Fmvsam%2Frte_mrvl_pmd_ops.c;h=3064b1f136fe1d35ade85c440a79463fbf60194b;hb=f99316271ceaefd1d632f1664101eeeb26218f4a;hp=d253b8fba17067dbbcac220a9263a1718108194d;hpb=a84226fc055f9948a31fead49d06b9712d6ce864;p=dpdk.git diff --git a/drivers/crypto/mvsam/rte_mrvl_pmd_ops.c b/drivers/crypto/mvsam/rte_mrvl_pmd_ops.c index d253b8fba1..3064b1f136 100644 --- a/drivers/crypto/mvsam/rte_mrvl_pmd_ops.c +++ b/drivers/crypto/mvsam/rte_mrvl_pmd_ops.c @@ -8,9 +8,10 @@ #include #include -#include +#include +#include -#include "rte_mrvl_pmd_private.h" +#include "mrvl_pmd_private.h" /** * Capabilities list to be used in reporting to DPDK. @@ -111,7 +112,7 @@ static const struct rte_cryptodev_capabilities .increment = 1 }, .digest_size = { - .min = 28, + .min = 12, .max = 28, .increment = 0 }, @@ -232,7 +233,7 @@ static const struct rte_cryptodev_capabilities }, .digest_size = { .min = 12, - .max = 48, + .max = 64, .increment = 4 }, }, } @@ -252,7 +253,7 @@ static const struct rte_cryptodev_capabilities }, .digest_size = { .min = 12, - .max = 48, + .max = 64, .increment = 0 }, }, } @@ -298,6 +299,26 @@ static const struct rte_cryptodev_capabilities }, } }, } }, + { /* AES ECB */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER, + {.cipher = { + .algo = RTE_CRYPTO_CIPHER_AES_ECB, + .block_size = 16, + .key_size = { + .min = 16, + .max = 32, + .increment = 8 + }, + .iv_size = { + .min = 0, + .max = 0, + .increment = 0 + } + }, } + }, } + }, { /* AES GCM */ .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, {.sym = { @@ -316,9 +337,9 @@ static const struct rte_cryptodev_capabilities .increment = 0 }, .aad_size = { - .min = 8, - .max = 12, - .increment = 4 + .min = 0, + .max = 64, + .increment = 1 }, .iv_size = { .min = 12, @@ -393,6 +414,71 @@ static const struct rte_cryptodev_capabilities }, } }, } }, + { /* 3DES ECB */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER, + {.cipher = { + .algo = RTE_CRYPTO_CIPHER_3DES_ECB, + .block_size = 8, + .key_size = { + .min = 24, + .max = 24, + .increment = 0 + }, + .iv_size = { + .min = 0, + .max = 0, + .increment = 0 + } + }, } + }, } + }, + { /* NULL (AUTH) */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, + {.auth = { + .algo = RTE_CRYPTO_AUTH_NULL, + .block_size = 1, + .key_size = { + .min = 0, + .max = 0, + .increment = 0 + }, + .digest_size = { + .min = 0, + .max = 0, + .increment = 0 + }, + .iv_size = { + .min = 0, + .max = 0, + .increment = 0 + } + }, }, + }, }, + }, + { /* NULL (CIPHER) */ + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, + {.sym = { + .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER, + {.cipher = { + .algo = RTE_CRYPTO_CIPHER_NULL, + .block_size = 1, + .key_size = { + .min = 0, + .max = 0, + .increment = 0 + }, + .iv_size = { + .min = 0, + .max = 0, + .increment = 0 + } + }, }, + }, } + }, RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST() }; @@ -548,7 +634,7 @@ mrvl_crypto_pmd_close(struct rte_cryptodev *dev) 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]; @@ -572,11 +658,16 @@ mrvl_crypto_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id, */ 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 @@ -588,10 +679,17 @@ mrvl_crypto_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id, * 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); @@ -605,7 +703,8 @@ mrvl_crypto_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id, 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; @@ -616,17 +715,6 @@ mrvl_crypto_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id, 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]. @@ -641,7 +729,7 @@ mrvl_crypto_pmd_sym_session_get_size(__rte_unused struct rte_cryptodev *dev) /** 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. */ @@ -656,7 +744,7 @@ mrvl_crypto_pmd_sym_session_configure(__rte_unused struct rte_cryptodev *dev, int ret; if (sess == NULL) { - MRVL_CRYPTO_LOG_ERR("Invalid session struct."); + MRVL_LOG(ERR, "Invalid session struct!"); return -EINVAL; } @@ -665,9 +753,11 @@ mrvl_crypto_pmd_sym_session_configure(__rte_unused struct rte_cryptodev *dev, 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); @@ -679,10 +769,16 @@ mrvl_crypto_pmd_sym_session_configure(__rte_unused struct rte_cryptodev *dev, 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 */ + if (mrvl_sess->sam_sess_params.cipher_key != NULL) + free(mrvl_sess->sam_sess_params.cipher_key); + if (mrvl_sess->sam_sess_params.auth_key != NULL) + free(mrvl_sess->sam_sess_params.auth_key); + return 0; } @@ -707,10 +803,10 @@ mrvl_crypto_pmd_sym_session_clear(struct rte_cryptodev *dev, 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); @@ -733,7 +829,6 @@ static struct rte_cryptodev_ops mrvl_crypto_pmd_ops = { .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, @@ -741,3 +836,177 @@ 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;