2017-12-19 15:49:01 +00:00
|
|
|
/* SPDX-License-Identifier: BSD-3-Clause
|
2018-06-28 15:59:43 +01:00
|
|
|
* Copyright(c) 2016-2018 Intel Corporation
|
2016-09-29 03:59:47 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <rte_common.h>
|
|
|
|
#include <rte_hexdump.h>
|
|
|
|
#include <rte_cryptodev.h>
|
|
|
|
#include <rte_cryptodev_pmd.h>
|
2017-11-07 06:54:21 +00:00
|
|
|
#include <rte_bus_vdev.h>
|
2016-09-29 03:59:47 +01:00
|
|
|
#include <rte_malloc.h>
|
|
|
|
#include <rte_cpuflags.h>
|
|
|
|
|
|
|
|
#include "rte_zuc_pmd_private.h"
|
2018-04-19 15:55:41 +01:00
|
|
|
#define ZUC_MAX_BURST 4
|
2016-09-29 03:59:47 +01:00
|
|
|
#define BYTE_LEN 8
|
|
|
|
|
2017-06-30 15:34:21 +01:00
|
|
|
static uint8_t cryptodev_driver_id;
|
|
|
|
|
2016-09-29 03:59:47 +01:00
|
|
|
/** Get xform chain order. */
|
|
|
|
static enum zuc_operation
|
|
|
|
zuc_get_mode(const struct rte_crypto_sym_xform *xform)
|
|
|
|
{
|
|
|
|
if (xform == NULL)
|
|
|
|
return ZUC_OP_NOT_SUPPORTED;
|
|
|
|
|
|
|
|
if (xform->next)
|
|
|
|
if (xform->next->next != NULL)
|
|
|
|
return ZUC_OP_NOT_SUPPORTED;
|
|
|
|
|
|
|
|
if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) {
|
|
|
|
if (xform->next == NULL)
|
|
|
|
return ZUC_OP_ONLY_AUTH;
|
|
|
|
else if (xform->next->type == RTE_CRYPTO_SYM_XFORM_CIPHER)
|
|
|
|
return ZUC_OP_AUTH_CIPHER;
|
|
|
|
else
|
|
|
|
return ZUC_OP_NOT_SUPPORTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER) {
|
|
|
|
if (xform->next == NULL)
|
|
|
|
return ZUC_OP_ONLY_CIPHER;
|
|
|
|
else if (xform->next->type == RTE_CRYPTO_SYM_XFORM_AUTH)
|
|
|
|
return ZUC_OP_CIPHER_AUTH;
|
|
|
|
else
|
|
|
|
return ZUC_OP_NOT_SUPPORTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ZUC_OP_NOT_SUPPORTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** Parse crypto xform chain and set private session parameters. */
|
|
|
|
int
|
|
|
|
zuc_set_session_parameters(struct zuc_session *sess,
|
|
|
|
const struct rte_crypto_sym_xform *xform)
|
|
|
|
{
|
|
|
|
const struct rte_crypto_sym_xform *auth_xform = NULL;
|
|
|
|
const struct rte_crypto_sym_xform *cipher_xform = NULL;
|
|
|
|
enum zuc_operation mode;
|
|
|
|
|
|
|
|
/* Select Crypto operation - hash then cipher / cipher then hash */
|
|
|
|
mode = zuc_get_mode(xform);
|
|
|
|
|
|
|
|
switch (mode) {
|
|
|
|
case ZUC_OP_CIPHER_AUTH:
|
|
|
|
auth_xform = xform->next;
|
|
|
|
|
|
|
|
/* Fall-through */
|
|
|
|
case ZUC_OP_ONLY_CIPHER:
|
|
|
|
cipher_xform = xform;
|
|
|
|
break;
|
|
|
|
case ZUC_OP_AUTH_CIPHER:
|
|
|
|
cipher_xform = xform->next;
|
|
|
|
/* Fall-through */
|
|
|
|
case ZUC_OP_ONLY_AUTH:
|
|
|
|
auth_xform = xform;
|
|
|
|
break;
|
|
|
|
case ZUC_OP_NOT_SUPPORTED:
|
|
|
|
default:
|
2018-06-28 15:59:43 +01:00
|
|
|
ZUC_LOG(ERR, "Unsupported operation chain order parameter");
|
2017-07-25 07:16:50 +01:00
|
|
|
return -ENOTSUP;
|
2016-09-29 03:59:47 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (cipher_xform) {
|
|
|
|
/* Only ZUC EEA3 supported */
|
|
|
|
if (cipher_xform->cipher.algo != RTE_CRYPTO_CIPHER_ZUC_EEA3)
|
2017-07-25 07:16:50 +01:00
|
|
|
return -ENOTSUP;
|
2017-07-02 06:41:14 +01:00
|
|
|
|
|
|
|
if (cipher_xform->cipher.iv.length != ZUC_IV_KEY_LENGTH) {
|
2018-06-28 15:59:43 +01:00
|
|
|
ZUC_LOG(ERR, "Wrong IV length");
|
2017-07-02 06:41:14 +01:00
|
|
|
return -EINVAL;
|
|
|
|
}
|
2017-07-02 06:41:16 +01:00
|
|
|
sess->cipher_iv_offset = cipher_xform->cipher.iv.offset;
|
2017-07-02 06:41:14 +01:00
|
|
|
|
2016-09-29 03:59:47 +01:00
|
|
|
/* Copy the key */
|
2017-02-07 22:49:58 +00:00
|
|
|
memcpy(sess->pKey_cipher, cipher_xform->cipher.key.data,
|
|
|
|
ZUC_IV_KEY_LENGTH);
|
2016-09-29 03:59:47 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (auth_xform) {
|
|
|
|
/* Only ZUC EIA3 supported */
|
|
|
|
if (auth_xform->auth.algo != RTE_CRYPTO_AUTH_ZUC_EIA3)
|
2017-07-25 07:16:50 +01:00
|
|
|
return -ENOTSUP;
|
2017-07-02 06:41:18 +01:00
|
|
|
|
|
|
|
if (auth_xform->auth.digest_length != ZUC_DIGEST_LENGTH) {
|
2018-06-28 15:59:43 +01:00
|
|
|
ZUC_LOG(ERR, "Wrong digest length");
|
2017-07-02 06:41:18 +01:00
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
2016-09-29 03:59:47 +01:00
|
|
|
sess->auth_op = auth_xform->auth.op;
|
2017-07-02 06:41:16 +01:00
|
|
|
|
|
|
|
if (auth_xform->auth.iv.length != ZUC_IV_KEY_LENGTH) {
|
2018-06-28 15:59:43 +01:00
|
|
|
ZUC_LOG(ERR, "Wrong IV length");
|
2017-07-02 06:41:16 +01:00
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
sess->auth_iv_offset = auth_xform->auth.iv.offset;
|
|
|
|
|
2016-09-29 03:59:47 +01:00
|
|
|
/* Copy the key */
|
2017-02-07 22:49:58 +00:00
|
|
|
memcpy(sess->pKey_hash, auth_xform->auth.key.data,
|
|
|
|
ZUC_IV_KEY_LENGTH);
|
2016-09-29 03:59:47 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
sess->op = mode;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Get ZUC session. */
|
|
|
|
static struct zuc_session *
|
|
|
|
zuc_get_session(struct zuc_qp *qp, struct rte_crypto_op *op)
|
|
|
|
{
|
2017-07-05 06:26:17 +01:00
|
|
|
struct zuc_session *sess = NULL;
|
2016-09-29 03:59:47 +01:00
|
|
|
|
2017-07-02 06:41:02 +01:00
|
|
|
if (op->sess_type == RTE_CRYPTO_OP_WITH_SESSION) {
|
2017-07-05 06:26:17 +01:00
|
|
|
if (likely(op->sym->session != NULL))
|
2018-07-05 03:08:04 +01:00
|
|
|
sess = (struct zuc_session *)get_sym_session_private_data(
|
2017-07-05 06:26:17 +01:00
|
|
|
op->sym->session,
|
|
|
|
cryptodev_driver_id);
|
|
|
|
} else {
|
|
|
|
void *_sess = NULL;
|
|
|
|
void *_sess_private_data = NULL;
|
|
|
|
|
|
|
|
if (rte_mempool_get(qp->sess_mp, (void **)&_sess))
|
|
|
|
return NULL;
|
2016-09-29 03:59:47 +01:00
|
|
|
|
2019-01-10 14:50:11 +00:00
|
|
|
if (rte_mempool_get(qp->sess_mp_priv,
|
|
|
|
(void **)&_sess_private_data))
|
2016-09-29 03:59:47 +01:00
|
|
|
return NULL;
|
|
|
|
|
2017-07-05 06:26:17 +01:00
|
|
|
sess = (struct zuc_session *)_sess_private_data;
|
2016-09-29 03:59:47 +01:00
|
|
|
|
|
|
|
if (unlikely(zuc_set_session_parameters(sess,
|
2017-07-05 06:26:17 +01:00
|
|
|
op->sym->xform) != 0)) {
|
|
|
|
rte_mempool_put(qp->sess_mp, _sess);
|
2019-01-10 14:50:11 +00:00
|
|
|
rte_mempool_put(qp->sess_mp_priv, _sess_private_data);
|
2017-07-05 06:26:17 +01:00
|
|
|
sess = NULL;
|
|
|
|
}
|
|
|
|
op->sym->session = (struct rte_cryptodev_sym_session *)_sess;
|
2018-07-05 03:08:04 +01:00
|
|
|
set_sym_session_private_data(op->sym->session,
|
|
|
|
cryptodev_driver_id, _sess_private_data);
|
2016-09-29 03:59:47 +01:00
|
|
|
}
|
|
|
|
|
2017-07-05 06:26:17 +01:00
|
|
|
if (unlikely(sess == NULL))
|
|
|
|
op->status = RTE_CRYPTO_OP_STATUS_INVALID_SESSION;
|
|
|
|
|
|
|
|
|
2016-09-29 03:59:47 +01:00
|
|
|
return sess;
|
|
|
|
}
|
|
|
|
|
2018-04-19 15:55:41 +01:00
|
|
|
/** Encrypt/decrypt mbufs. */
|
2016-09-29 03:59:47 +01:00
|
|
|
static uint8_t
|
|
|
|
process_zuc_cipher_op(struct rte_crypto_op **ops,
|
2018-04-19 15:55:41 +01:00
|
|
|
struct zuc_session **sessions,
|
2016-09-29 03:59:47 +01:00
|
|
|
uint8_t num_ops)
|
|
|
|
{
|
|
|
|
unsigned i;
|
|
|
|
uint8_t processed_ops = 0;
|
|
|
|
uint8_t *src[ZUC_MAX_BURST], *dst[ZUC_MAX_BURST];
|
2017-07-02 06:41:13 +01:00
|
|
|
uint8_t *iv[ZUC_MAX_BURST];
|
2016-09-29 03:59:47 +01:00
|
|
|
uint32_t num_bytes[ZUC_MAX_BURST];
|
|
|
|
uint8_t *cipher_keys[ZUC_MAX_BURST];
|
2018-04-19 15:55:41 +01:00
|
|
|
struct zuc_session *sess;
|
2016-09-29 03:59:47 +01:00
|
|
|
|
|
|
|
for (i = 0; i < num_ops; i++) {
|
|
|
|
if (((ops[i]->sym->cipher.data.length % BYTE_LEN) != 0)
|
|
|
|
|| ((ops[i]->sym->cipher.data.offset
|
|
|
|
% BYTE_LEN) != 0)) {
|
|
|
|
ops[i]->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
|
2018-06-28 15:59:43 +01:00
|
|
|
ZUC_LOG(ERR, "Data Length or offset");
|
2016-09-29 03:59:47 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2018-04-19 15:55:41 +01:00
|
|
|
sess = sessions[i];
|
|
|
|
|
2017-01-13 16:23:15 +01:00
|
|
|
#ifdef RTE_LIBRTE_PMD_ZUC_DEBUG
|
|
|
|
if (!rte_pktmbuf_is_contiguous(ops[i]->sym->m_src) ||
|
|
|
|
(ops[i]->sym->m_dst != NULL &&
|
|
|
|
!rte_pktmbuf_is_contiguous(
|
|
|
|
ops[i]->sym->m_dst))) {
|
2018-06-28 15:59:43 +01:00
|
|
|
ZUC_LOG(ERR, "PMD supports only contiguous mbufs, "
|
2017-01-13 16:23:15 +01:00
|
|
|
"op (%p) provides noncontiguous mbuf as "
|
|
|
|
"source/destination buffer.\n", ops[i]);
|
|
|
|
ops[i]->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2016-09-29 03:59:47 +01:00
|
|
|
src[i] = rte_pktmbuf_mtod(ops[i]->sym->m_src, uint8_t *) +
|
|
|
|
(ops[i]->sym->cipher.data.offset >> 3);
|
|
|
|
dst[i] = ops[i]->sym->m_dst ?
|
|
|
|
rte_pktmbuf_mtod(ops[i]->sym->m_dst, uint8_t *) +
|
|
|
|
(ops[i]->sym->cipher.data.offset >> 3) :
|
|
|
|
rte_pktmbuf_mtod(ops[i]->sym->m_src, uint8_t *) +
|
|
|
|
(ops[i]->sym->cipher.data.offset >> 3);
|
2017-07-02 06:41:13 +01:00
|
|
|
iv[i] = rte_crypto_op_ctod_offset(ops[i], uint8_t *,
|
2018-04-19 15:55:41 +01:00
|
|
|
sess->cipher_iv_offset);
|
2016-09-29 03:59:47 +01:00
|
|
|
num_bytes[i] = ops[i]->sym->cipher.data.length >> 3;
|
|
|
|
|
2018-04-19 15:55:41 +01:00
|
|
|
cipher_keys[i] = sess->pKey_cipher;
|
2016-09-29 03:59:47 +01:00
|
|
|
|
|
|
|
processed_ops++;
|
|
|
|
}
|
|
|
|
|
2017-07-02 06:41:13 +01:00
|
|
|
sso_zuc_eea3_n_buffer(cipher_keys, iv, src, dst,
|
2016-09-29 03:59:47 +01:00
|
|
|
num_bytes, processed_ops);
|
|
|
|
|
|
|
|
return processed_ops;
|
|
|
|
}
|
|
|
|
|
2018-04-19 15:55:41 +01:00
|
|
|
/** Generate/verify hash from mbufs. */
|
2016-09-29 03:59:47 +01:00
|
|
|
static int
|
2017-09-05 03:20:05 +01:00
|
|
|
process_zuc_hash_op(struct zuc_qp *qp, struct rte_crypto_op **ops,
|
2018-04-19 15:55:41 +01:00
|
|
|
struct zuc_session **sessions,
|
2016-09-29 03:59:47 +01:00
|
|
|
uint8_t num_ops)
|
|
|
|
{
|
|
|
|
unsigned i;
|
|
|
|
uint8_t processed_ops = 0;
|
|
|
|
uint8_t *src;
|
|
|
|
uint32_t *dst;
|
|
|
|
uint32_t length_in_bits;
|
2017-07-02 06:41:16 +01:00
|
|
|
uint8_t *iv;
|
2018-04-19 15:55:41 +01:00
|
|
|
struct zuc_session *sess;
|
2016-09-29 03:59:47 +01:00
|
|
|
|
|
|
|
for (i = 0; i < num_ops; i++) {
|
|
|
|
/* Data must be byte aligned */
|
|
|
|
if ((ops[i]->sym->auth.data.offset % BYTE_LEN) != 0) {
|
|
|
|
ops[i]->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
|
2018-06-28 15:59:43 +01:00
|
|
|
ZUC_LOG(ERR, "Offset");
|
2016-09-29 03:59:47 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2018-04-19 15:55:41 +01:00
|
|
|
sess = sessions[i];
|
|
|
|
|
2016-09-29 03:59:47 +01:00
|
|
|
length_in_bits = ops[i]->sym->auth.data.length;
|
|
|
|
|
|
|
|
src = rte_pktmbuf_mtod(ops[i]->sym->m_src, uint8_t *) +
|
|
|
|
(ops[i]->sym->auth.data.offset >> 3);
|
2017-07-02 06:41:16 +01:00
|
|
|
iv = rte_crypto_op_ctod_offset(ops[i], uint8_t *,
|
2018-04-19 15:55:41 +01:00
|
|
|
sess->auth_iv_offset);
|
2016-09-29 03:59:47 +01:00
|
|
|
|
2018-04-19 15:55:41 +01:00
|
|
|
if (sess->auth_op == RTE_CRYPTO_AUTH_OP_VERIFY) {
|
2017-09-05 03:20:05 +01:00
|
|
|
dst = (uint32_t *)qp->temp_digest;
|
2016-09-29 03:59:47 +01:00
|
|
|
|
2018-04-19 15:55:41 +01:00
|
|
|
sso_zuc_eia3_1_buffer(sess->pKey_hash,
|
2017-07-02 06:41:16 +01:00
|
|
|
iv, src,
|
2016-09-29 03:59:47 +01:00
|
|
|
length_in_bits, dst);
|
|
|
|
/* Verify digest. */
|
|
|
|
if (memcmp(dst, ops[i]->sym->auth.digest.data,
|
2017-07-02 06:41:18 +01:00
|
|
|
ZUC_DIGEST_LENGTH) != 0)
|
2016-09-29 03:59:47 +01:00
|
|
|
ops[i]->status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED;
|
|
|
|
} else {
|
|
|
|
dst = (uint32_t *)ops[i]->sym->auth.digest.data;
|
|
|
|
|
2018-04-19 15:55:41 +01:00
|
|
|
sso_zuc_eia3_1_buffer(sess->pKey_hash,
|
2017-07-02 06:41:16 +01:00
|
|
|
iv, src,
|
2016-09-29 03:59:47 +01:00
|
|
|
length_in_bits, dst);
|
|
|
|
}
|
|
|
|
processed_ops++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return processed_ops;
|
|
|
|
}
|
|
|
|
|
2018-04-19 15:55:41 +01:00
|
|
|
/** Process a batch of crypto ops which shares the same operation type. */
|
2016-09-29 03:59:47 +01:00
|
|
|
static int
|
2018-04-19 15:55:41 +01:00
|
|
|
process_ops(struct rte_crypto_op **ops, enum zuc_operation op_type,
|
|
|
|
struct zuc_session **sessions,
|
2016-09-29 03:59:47 +01:00
|
|
|
struct zuc_qp *qp, uint8_t num_ops,
|
|
|
|
uint16_t *accumulated_enqueued_ops)
|
|
|
|
{
|
|
|
|
unsigned i;
|
|
|
|
unsigned enqueued_ops, processed_ops;
|
|
|
|
|
2018-04-19 15:55:41 +01:00
|
|
|
switch (op_type) {
|
2016-09-29 03:59:47 +01:00
|
|
|
case ZUC_OP_ONLY_CIPHER:
|
|
|
|
processed_ops = process_zuc_cipher_op(ops,
|
2018-04-19 15:55:41 +01:00
|
|
|
sessions, num_ops);
|
2016-09-29 03:59:47 +01:00
|
|
|
break;
|
|
|
|
case ZUC_OP_ONLY_AUTH:
|
2018-04-19 15:55:41 +01:00
|
|
|
processed_ops = process_zuc_hash_op(qp, ops, sessions,
|
2016-09-29 03:59:47 +01:00
|
|
|
num_ops);
|
|
|
|
break;
|
|
|
|
case ZUC_OP_CIPHER_AUTH:
|
2018-04-19 15:55:41 +01:00
|
|
|
processed_ops = process_zuc_cipher_op(ops, sessions,
|
2016-09-29 03:59:47 +01:00
|
|
|
num_ops);
|
2018-04-19 15:55:41 +01:00
|
|
|
process_zuc_hash_op(qp, ops, sessions, processed_ops);
|
2016-09-29 03:59:47 +01:00
|
|
|
break;
|
|
|
|
case ZUC_OP_AUTH_CIPHER:
|
2018-04-19 15:55:41 +01:00
|
|
|
processed_ops = process_zuc_hash_op(qp, ops, sessions,
|
2016-09-29 03:59:47 +01:00
|
|
|
num_ops);
|
2018-04-19 15:55:41 +01:00
|
|
|
process_zuc_cipher_op(ops, sessions, processed_ops);
|
2016-09-29 03:59:47 +01:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
/* Operation not supported. */
|
|
|
|
processed_ops = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < num_ops; i++) {
|
|
|
|
/*
|
|
|
|
* If there was no error/authentication failure,
|
|
|
|
* change status to successful.
|
|
|
|
*/
|
|
|
|
if (ops[i]->status == RTE_CRYPTO_OP_STATUS_NOT_PROCESSED)
|
|
|
|
ops[i]->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
|
|
|
|
/* Free session if a session-less crypto op. */
|
2017-07-02 06:41:02 +01:00
|
|
|
if (ops[i]->sess_type == RTE_CRYPTO_OP_SESSIONLESS) {
|
2018-04-19 15:55:41 +01:00
|
|
|
memset(sessions[i], 0, sizeof(struct zuc_session));
|
2017-07-05 06:26:17 +01:00
|
|
|
memset(ops[i]->sym->session, 0,
|
2019-01-10 14:50:18 +00:00
|
|
|
rte_cryptodev_sym_get_existing_header_session_size(
|
|
|
|
ops[i]->sym->session));
|
2019-01-10 14:50:11 +00:00
|
|
|
rte_mempool_put(qp->sess_mp_priv, sessions[i]);
|
2016-09-29 03:59:47 +01:00
|
|
|
rte_mempool_put(qp->sess_mp, ops[i]->sym->session);
|
|
|
|
ops[i]->sym->session = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
enqueued_ops = rte_ring_enqueue_burst(qp->processed_ops,
|
2017-03-29 16:21:24 +01:00
|
|
|
(void **)ops, processed_ops, NULL);
|
2016-09-29 03:59:47 +01:00
|
|
|
qp->qp_stats.enqueued_count += enqueued_ops;
|
|
|
|
*accumulated_enqueued_ops += enqueued_ops;
|
|
|
|
|
|
|
|
return enqueued_ops;
|
|
|
|
}
|
|
|
|
|
|
|
|
static uint16_t
|
|
|
|
zuc_pmd_enqueue_burst(void *queue_pair, struct rte_crypto_op **ops,
|
|
|
|
uint16_t nb_ops)
|
|
|
|
{
|
|
|
|
struct rte_crypto_op *c_ops[ZUC_MAX_BURST];
|
|
|
|
struct rte_crypto_op *curr_c_op;
|
|
|
|
|
2018-04-19 15:55:41 +01:00
|
|
|
struct zuc_session *curr_sess;
|
|
|
|
struct zuc_session *sessions[ZUC_MAX_BURST];
|
|
|
|
enum zuc_operation prev_zuc_op = ZUC_OP_NOT_SUPPORTED;
|
|
|
|
enum zuc_operation curr_zuc_op;
|
2016-09-29 03:59:47 +01:00
|
|
|
struct zuc_qp *qp = queue_pair;
|
|
|
|
unsigned i;
|
|
|
|
uint8_t burst_size = 0;
|
|
|
|
uint16_t enqueued_ops = 0;
|
|
|
|
uint8_t processed_ops;
|
|
|
|
|
|
|
|
for (i = 0; i < nb_ops; i++) {
|
|
|
|
curr_c_op = ops[i];
|
|
|
|
|
|
|
|
curr_sess = zuc_get_session(qp, curr_c_op);
|
2018-04-19 15:55:40 +01:00
|
|
|
if (unlikely(curr_sess == NULL)) {
|
2016-09-29 03:59:47 +01:00
|
|
|
curr_c_op->status =
|
|
|
|
RTE_CRYPTO_OP_STATUS_INVALID_SESSION;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2018-04-19 15:55:41 +01:00
|
|
|
curr_zuc_op = curr_sess->op;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Batch ops that share the same operation type
|
|
|
|
* (cipher only, auth only...).
|
|
|
|
*/
|
|
|
|
if (burst_size == 0) {
|
|
|
|
prev_zuc_op = curr_zuc_op;
|
|
|
|
c_ops[0] = curr_c_op;
|
|
|
|
sessions[0] = curr_sess;
|
|
|
|
burst_size++;
|
|
|
|
} else if (curr_zuc_op == prev_zuc_op) {
|
|
|
|
c_ops[burst_size] = curr_c_op;
|
|
|
|
sessions[burst_size] = curr_sess;
|
|
|
|
burst_size++;
|
2016-09-29 03:59:47 +01:00
|
|
|
/*
|
|
|
|
* When there are enough ops to process in a batch,
|
|
|
|
* process them, and start a new batch.
|
|
|
|
*/
|
|
|
|
if (burst_size == ZUC_MAX_BURST) {
|
2018-04-19 15:55:41 +01:00
|
|
|
processed_ops = process_ops(c_ops, curr_zuc_op,
|
|
|
|
sessions, qp, burst_size,
|
|
|
|
&enqueued_ops);
|
2016-09-29 03:59:47 +01:00
|
|
|
if (processed_ops < burst_size) {
|
|
|
|
burst_size = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
burst_size = 0;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/*
|
2018-04-19 15:55:41 +01:00
|
|
|
* Different operation type, process the ops
|
|
|
|
* of the previous type.
|
2016-09-29 03:59:47 +01:00
|
|
|
*/
|
2018-04-19 15:55:41 +01:00
|
|
|
processed_ops = process_ops(c_ops, prev_zuc_op,
|
|
|
|
sessions, qp, burst_size,
|
|
|
|
&enqueued_ops);
|
2016-09-29 03:59:47 +01:00
|
|
|
if (processed_ops < burst_size) {
|
|
|
|
burst_size = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
burst_size = 0;
|
2018-04-19 15:55:41 +01:00
|
|
|
prev_zuc_op = curr_zuc_op;
|
2016-09-29 03:59:47 +01:00
|
|
|
|
2018-04-19 15:55:41 +01:00
|
|
|
c_ops[0] = curr_c_op;
|
|
|
|
sessions[0] = curr_sess;
|
|
|
|
burst_size++;
|
2016-09-29 03:59:47 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (burst_size != 0) {
|
2018-04-19 15:55:41 +01:00
|
|
|
/* Process the crypto ops of the last operation type. */
|
|
|
|
processed_ops = process_ops(c_ops, prev_zuc_op,
|
|
|
|
sessions, qp, burst_size,
|
|
|
|
&enqueued_ops);
|
2016-09-29 03:59:47 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
qp->qp_stats.enqueue_err_count += nb_ops - enqueued_ops;
|
|
|
|
return enqueued_ops;
|
|
|
|
}
|
|
|
|
|
|
|
|
static uint16_t
|
|
|
|
zuc_pmd_dequeue_burst(void *queue_pair,
|
|
|
|
struct rte_crypto_op **c_ops, uint16_t nb_ops)
|
|
|
|
{
|
|
|
|
struct zuc_qp *qp = queue_pair;
|
|
|
|
|
|
|
|
unsigned nb_dequeued;
|
|
|
|
|
|
|
|
nb_dequeued = rte_ring_dequeue_burst(qp->processed_ops,
|
2017-03-29 16:21:25 +01:00
|
|
|
(void **)c_ops, nb_ops, NULL);
|
2016-09-29 03:59:47 +01:00
|
|
|
qp->qp_stats.dequeued_count += nb_dequeued;
|
|
|
|
|
|
|
|
return nb_dequeued;
|
|
|
|
}
|
|
|
|
|
2017-04-11 17:44:13 +02:00
|
|
|
static int cryptodev_zuc_remove(struct rte_vdev_device *vdev);
|
2016-09-29 03:59:47 +01:00
|
|
|
|
|
|
|
static int
|
2017-04-18 15:34:20 +01:00
|
|
|
cryptodev_zuc_create(const char *name,
|
|
|
|
struct rte_vdev_device *vdev,
|
2017-10-25 13:00:35 +01:00
|
|
|
struct rte_cryptodev_pmd_init_params *init_params)
|
2016-09-29 03:59:47 +01:00
|
|
|
{
|
|
|
|
struct rte_cryptodev *dev;
|
|
|
|
struct zuc_private *internals;
|
2017-06-20 16:23:07 +01:00
|
|
|
uint64_t cpu_flags = RTE_CRYPTODEV_FF_CPU_SSE;
|
2016-09-29 03:59:47 +01:00
|
|
|
|
cryptodev: add user defined name for vdev
This patch adds a user defined name initializing parameter to cryptodev
library.
Originally, for software cryptodev PMD, the vdev name parameter is
treated as the driver identifier, and will create an unique name for each
device automatically, which is not necessarily as same as the vdev
parameter.
This patch allows the user to either create a unique name for his software
cryptodev, or by default, let the system creates a unique one. This should
help the user managing the created cryptodevs easily.
Examples:
CLI command fragment 1: --vdev "crypto_aesni_gcm_pmd"
The above command will result in creating a AESNI-GCM PMD with name of
"crypto_aesni_gcm_X", where postfix X is the number assigned by the system,
starting from 0. This fragment can be placed in the same CLI command
multiple times, resulting the postfixs incremented by one for each new
device.
CLI command fragment 2: --vdev "crypto_aesni_gcm_pmd,name=gcm1"
The above command will result in creating a AESNI-GCM PMD with name of
"gcm1". This fragment can be placed in the same CLI command multiple
times, as long as each having a unique name value.
Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
Acked-by: Declan Doherty <declan.doherty@intel.com>
2017-01-16 14:14:54 +00:00
|
|
|
|
2017-10-25 13:00:35 +01:00
|
|
|
dev = rte_cryptodev_pmd_create(name, &vdev->device, init_params);
|
2016-09-29 03:59:47 +01:00
|
|
|
if (dev == NULL) {
|
2018-06-28 15:59:43 +01:00
|
|
|
ZUC_LOG(ERR, "failed to create cryptodev vdev");
|
2016-09-29 03:59:47 +01:00
|
|
|
goto init_error;
|
|
|
|
}
|
|
|
|
|
2017-06-30 15:34:21 +01:00
|
|
|
dev->driver_id = cryptodev_driver_id;
|
2016-09-29 03:59:47 +01:00
|
|
|
dev->dev_ops = rte_zuc_pmd_ops;
|
|
|
|
|
|
|
|
/* Register RX/TX burst functions for data path. */
|
|
|
|
dev->dequeue_burst = zuc_pmd_dequeue_burst;
|
|
|
|
dev->enqueue_burst = zuc_pmd_enqueue_burst;
|
|
|
|
|
|
|
|
dev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO |
|
|
|
|
RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING |
|
|
|
|
cpu_flags;
|
|
|
|
|
|
|
|
internals = dev->data->dev_private;
|
|
|
|
|
|
|
|
internals->max_nb_queue_pairs = init_params->max_nb_queue_pairs;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
init_error:
|
2018-06-28 15:59:43 +01:00
|
|
|
ZUC_LOG(ERR, "driver %s: failed",
|
cryptodev: add user defined name for vdev
This patch adds a user defined name initializing parameter to cryptodev
library.
Originally, for software cryptodev PMD, the vdev name parameter is
treated as the driver identifier, and will create an unique name for each
device automatically, which is not necessarily as same as the vdev
parameter.
This patch allows the user to either create a unique name for his software
cryptodev, or by default, let the system creates a unique one. This should
help the user managing the created cryptodevs easily.
Examples:
CLI command fragment 1: --vdev "crypto_aesni_gcm_pmd"
The above command will result in creating a AESNI-GCM PMD with name of
"crypto_aesni_gcm_X", where postfix X is the number assigned by the system,
starting from 0. This fragment can be placed in the same CLI command
multiple times, resulting the postfixs incremented by one for each new
device.
CLI command fragment 2: --vdev "crypto_aesni_gcm_pmd,name=gcm1"
The above command will result in creating a AESNI-GCM PMD with name of
"gcm1". This fragment can be placed in the same CLI command multiple
times, as long as each having a unique name value.
Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
Acked-by: Declan Doherty <declan.doherty@intel.com>
2017-01-16 14:14:54 +00:00
|
|
|
init_params->name);
|
2016-09-29 03:59:47 +01:00
|
|
|
|
2017-04-11 17:44:13 +02:00
|
|
|
cryptodev_zuc_remove(vdev);
|
2016-09-29 03:59:47 +01:00
|
|
|
return -EFAULT;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2017-04-11 17:44:13 +02:00
|
|
|
cryptodev_zuc_probe(struct rte_vdev_device *vdev)
|
2016-09-29 03:59:47 +01:00
|
|
|
{
|
2017-10-25 13:00:35 +01:00
|
|
|
struct rte_cryptodev_pmd_init_params init_params = {
|
|
|
|
"",
|
|
|
|
sizeof(struct zuc_private),
|
cryptodev: add user defined name for vdev
This patch adds a user defined name initializing parameter to cryptodev
library.
Originally, for software cryptodev PMD, the vdev name parameter is
treated as the driver identifier, and will create an unique name for each
device automatically, which is not necessarily as same as the vdev
parameter.
This patch allows the user to either create a unique name for his software
cryptodev, or by default, let the system creates a unique one. This should
help the user managing the created cryptodevs easily.
Examples:
CLI command fragment 1: --vdev "crypto_aesni_gcm_pmd"
The above command will result in creating a AESNI-GCM PMD with name of
"crypto_aesni_gcm_X", where postfix X is the number assigned by the system,
starting from 0. This fragment can be placed in the same CLI command
multiple times, resulting the postfixs incremented by one for each new
device.
CLI command fragment 2: --vdev "crypto_aesni_gcm_pmd,name=gcm1"
The above command will result in creating a AESNI-GCM PMD with name of
"gcm1". This fragment can be placed in the same CLI command multiple
times, as long as each having a unique name value.
Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
Acked-by: Declan Doherty <declan.doherty@intel.com>
2017-01-16 14:14:54 +00:00
|
|
|
rte_socket_id(),
|
2018-07-05 03:07:58 +01:00
|
|
|
RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS
|
2016-09-29 03:59:47 +01:00
|
|
|
};
|
2017-04-11 17:44:13 +02:00
|
|
|
const char *name;
|
|
|
|
const char *input_args;
|
|
|
|
|
|
|
|
name = rte_vdev_device_name(vdev);
|
2017-04-18 15:34:19 +01:00
|
|
|
if (name == NULL)
|
|
|
|
return -EINVAL;
|
2017-04-11 17:44:13 +02:00
|
|
|
input_args = rte_vdev_device_args(vdev);
|
2016-09-29 03:59:47 +01:00
|
|
|
|
2017-10-25 13:00:35 +01:00
|
|
|
rte_cryptodev_pmd_parse_input_args(&init_params, input_args);
|
2016-09-29 03:59:47 +01:00
|
|
|
|
2017-04-18 15:34:20 +01:00
|
|
|
return cryptodev_zuc_create(name, vdev, &init_params);
|
2016-09-29 03:59:47 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2017-04-11 17:44:13 +02:00
|
|
|
cryptodev_zuc_remove(struct rte_vdev_device *vdev)
|
2016-09-29 03:59:47 +01:00
|
|
|
{
|
2017-10-25 13:00:35 +01:00
|
|
|
|
|
|
|
struct rte_cryptodev *cryptodev;
|
2017-04-11 17:44:13 +02:00
|
|
|
const char *name;
|
|
|
|
|
|
|
|
name = rte_vdev_device_name(vdev);
|
2016-09-29 03:59:47 +01:00
|
|
|
if (name == NULL)
|
|
|
|
return -EINVAL;
|
|
|
|
|
2017-10-25 13:00:35 +01:00
|
|
|
cryptodev = rte_cryptodev_pmd_get_named_dev(name);
|
|
|
|
if (cryptodev == NULL)
|
|
|
|
return -ENODEV;
|
2016-09-29 03:59:47 +01:00
|
|
|
|
2017-10-25 13:00:35 +01:00
|
|
|
return rte_cryptodev_pmd_destroy(cryptodev);
|
2016-09-29 03:59:47 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static struct rte_vdev_driver cryptodev_zuc_pmd_drv = {
|
2016-10-11 02:14:52 +01:00
|
|
|
.probe = cryptodev_zuc_probe,
|
|
|
|
.remove = cryptodev_zuc_remove
|
2016-09-29 03:59:47 +01:00
|
|
|
};
|
|
|
|
|
2017-08-16 03:41:51 +01:00
|
|
|
static struct cryptodev_driver zuc_crypto_drv;
|
|
|
|
|
2016-10-10 11:13:15 +05:30
|
|
|
RTE_PMD_REGISTER_VDEV(CRYPTODEV_NAME_ZUC_PMD, cryptodev_zuc_pmd_drv);
|
|
|
|
RTE_PMD_REGISTER_PARAM_STRING(CRYPTODEV_NAME_ZUC_PMD,
|
2016-09-29 03:59:47 +01:00
|
|
|
"max_nb_queue_pairs=<int> "
|
|
|
|
"socket_id=<int>");
|
2018-03-09 17:44:38 +00:00
|
|
|
RTE_PMD_REGISTER_CRYPTO_DRIVER(zuc_crypto_drv, cryptodev_zuc_pmd_drv.driver,
|
2017-08-16 03:41:51 +01:00
|
|
|
cryptodev_driver_id);
|
2018-06-28 15:59:43 +01:00
|
|
|
|
2018-06-18 14:32:21 +02:00
|
|
|
RTE_INIT(zuc_init_log)
|
2018-06-28 15:59:43 +01:00
|
|
|
{
|
|
|
|
zuc_logtype_driver = rte_log_register("pmd.crypto.zuc");
|
|
|
|
}
|