crypto/bcmfs: add crypto HW module

Add crypto h/w module to process crypto op. Crypto op is processed via
sym_engine module before submitting the crypto request to HW queues.

Signed-off-by: Vikas Gupta <vikas.gupta@broadcom.com>
Signed-off-by: Raveendra Padasalagi <raveendra.padasalagi@broadcom.com>
Reviewed-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
Acked-by: Akhil Goyal <akhil.goyal@nxp.com>
This commit is contained in:
Vikas Gupta 2020-10-07 22:48:59 +05:30 committed by Akhil Goyal
parent 4ed19f0db5
commit 492a19a046
6 changed files with 1628 additions and 1 deletions

View File

@ -0,0 +1,289 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2020 Broadcom
* All rights reserved.
*/
#include <stdbool.h>
#include <rte_byteorder.h>
#include <rte_crypto_sym.h>
#include <rte_cryptodev.h>
#include <rte_mbuf.h>
#include <rte_mempool.h>
#include "bcmfs_sym_defs.h"
#include "bcmfs_sym_engine.h"
#include "bcmfs_sym_req.h"
#include "bcmfs_sym_session.h"
/** Process cipher operation */
static int
process_crypto_cipher_op(struct rte_crypto_op *op,
struct rte_mbuf *mbuf_src,
struct rte_mbuf *mbuf_dst,
struct bcmfs_sym_session *sess,
struct bcmfs_sym_request *req)
{
int rc = 0;
struct fsattr src, dst, iv, key;
struct rte_crypto_sym_op *sym_op = op->sym;
fsattr_sz(&src) = sym_op->cipher.data.length;
fsattr_sz(&dst) = sym_op->cipher.data.length;
fsattr_va(&src) = rte_pktmbuf_mtod_offset
(mbuf_src,
uint8_t *,
op->sym->cipher.data.offset);
fsattr_va(&dst) = rte_pktmbuf_mtod_offset
(mbuf_dst,
uint8_t *,
op->sym->cipher.data.offset);
fsattr_pa(&src) = rte_pktmbuf_iova(mbuf_src);
fsattr_pa(&dst) = rte_pktmbuf_iova(mbuf_dst);
fsattr_va(&iv) = rte_crypto_op_ctod_offset(op,
uint8_t *,
sess->cipher.iv.offset);
fsattr_sz(&iv) = sess->cipher.iv.length;
fsattr_va(&key) = sess->cipher.key.data;
fsattr_pa(&key) = 0;
fsattr_sz(&key) = sess->cipher.key.length;
rc = bcmfs_crypto_build_cipher_req(req, sess->cipher.algo,
sess->cipher.op, &src,
&dst, &key, &iv);
if (rc)
op->status = RTE_CRYPTO_OP_STATUS_ERROR;
return rc;
}
/** Process auth operation */
static int
process_crypto_auth_op(struct rte_crypto_op *op,
struct rte_mbuf *mbuf_src,
struct bcmfs_sym_session *sess,
struct bcmfs_sym_request *req)
{
int rc = 0;
struct fsattr src, dst, mac, key, iv;
fsattr_sz(&src) = op->sym->auth.data.length;
fsattr_va(&src) = rte_pktmbuf_mtod_offset(mbuf_src,
uint8_t *,
op->sym->auth.data.offset);
fsattr_pa(&src) = rte_pktmbuf_iova(mbuf_src);
if (!sess->auth.op) {
fsattr_va(&mac) = op->sym->auth.digest.data;
fsattr_pa(&mac) = op->sym->auth.digest.phys_addr;
fsattr_sz(&mac) = sess->auth.digest_length;
} else {
fsattr_va(&dst) = op->sym->auth.digest.data;
fsattr_pa(&dst) = op->sym->auth.digest.phys_addr;
fsattr_sz(&dst) = sess->auth.digest_length;
}
fsattr_va(&key) = sess->auth.key.data;
fsattr_pa(&key) = 0;
fsattr_sz(&key) = sess->auth.key.length;
/* AES-GMAC uses AES-GCM-128 authenticator */
if (sess->auth.algo == RTE_CRYPTO_AUTH_AES_GMAC) {
fsattr_va(&iv) = rte_crypto_op_ctod_offset(op,
uint8_t *,
sess->auth.iv.offset);
fsattr_pa(&iv) = 0;
fsattr_sz(&iv) = sess->auth.iv.length;
} else {
fsattr_va(&iv) = NULL;
fsattr_sz(&iv) = 0;
}
rc = bcmfs_crypto_build_auth_req(req, sess->auth.algo,
sess->auth.op,
&src,
(sess->auth.op) ? (&dst) : NULL,
(sess->auth.op) ? NULL : (&mac),
&key, &iv);
if (rc)
op->status = RTE_CRYPTO_OP_STATUS_ERROR;
return rc;
}
/** Process combined/chained mode operation */
static int
process_crypto_combined_op(struct rte_crypto_op *op,
struct rte_mbuf *mbuf_src,
struct rte_mbuf *mbuf_dst,
struct bcmfs_sym_session *sess,
struct bcmfs_sym_request *req)
{
int rc = 0, aad_size = 0;
struct fsattr src, dst, iv;
struct rte_crypto_sym_op *sym_op = op->sym;
struct fsattr cipher_key, aad, mac, auth_key;
fsattr_sz(&src) = sym_op->cipher.data.length;
fsattr_sz(&dst) = sym_op->cipher.data.length;
fsattr_va(&src) = rte_pktmbuf_mtod_offset
(mbuf_src,
uint8_t *,
sym_op->cipher.data.offset);
fsattr_va(&dst) = rte_pktmbuf_mtod_offset
(mbuf_dst,
uint8_t *,
sym_op->cipher.data.offset);
fsattr_pa(&src) = rte_pktmbuf_iova_offset(mbuf_src,
sym_op->cipher.data.offset);
fsattr_pa(&dst) = rte_pktmbuf_iova_offset(mbuf_dst,
sym_op->cipher.data.offset);
fsattr_va(&iv) = rte_crypto_op_ctod_offset(op,
uint8_t *,
sess->cipher.iv.offset);
fsattr_pa(&iv) = 0;
fsattr_sz(&iv) = sess->cipher.iv.length;
fsattr_va(&cipher_key) = sess->cipher.key.data;
fsattr_pa(&cipher_key) = 0;
fsattr_sz(&cipher_key) = sess->cipher.key.length;
fsattr_va(&auth_key) = sess->auth.key.data;
fsattr_pa(&auth_key) = 0;
fsattr_sz(&auth_key) = sess->auth.key.length;
fsattr_va(&mac) = op->sym->auth.digest.data;
fsattr_pa(&mac) = op->sym->auth.digest.phys_addr;
fsattr_sz(&mac) = sess->auth.digest_length;
aad_size = sym_op->auth.data.length - sym_op->cipher.data.length;
if (aad_size > 0) {
fsattr_sz(&aad) = aad_size;
fsattr_va(&aad) = rte_pktmbuf_mtod_offset
(mbuf_src,
uint8_t *,
sym_op->auth.data.offset);
fsattr_pa(&aad) = rte_pktmbuf_iova_offset(mbuf_src,
sym_op->auth.data.offset);
}
rc = bcmfs_crypto_build_chain_request(req, sess->cipher.algo,
sess->cipher.op,
sess->auth.algo,
sess->auth.op,
&src, &dst, &cipher_key,
&auth_key, &iv,
(aad_size > 0) ? (&aad) : NULL,
&mac, sess->cipher_first);
if (rc)
op->status = RTE_CRYPTO_OP_STATUS_ERROR;
return rc;
}
/** Process AEAD operation */
static int
process_crypto_aead_op(struct rte_crypto_op *op,
struct rte_mbuf *mbuf_src,
struct rte_mbuf *mbuf_dst,
struct bcmfs_sym_session *sess,
struct bcmfs_sym_request *req)
{
int rc = 0;
struct fsattr src, dst, iv;
struct rte_crypto_sym_op *sym_op = op->sym;
struct fsattr key, aad, mac;
fsattr_sz(&src) = sym_op->aead.data.length;
fsattr_sz(&dst) = sym_op->aead.data.length;
fsattr_va(&src) = rte_pktmbuf_mtod_offset(mbuf_src,
uint8_t *,
sym_op->aead.data.offset);
fsattr_va(&dst) = rte_pktmbuf_mtod_offset(mbuf_dst,
uint8_t *,
sym_op->aead.data.offset);
fsattr_pa(&src) = rte_pktmbuf_iova_offset(mbuf_src,
sym_op->aead.data.offset);
fsattr_pa(&dst) = rte_pktmbuf_iova_offset(mbuf_dst,
sym_op->aead.data.offset);
fsattr_va(&iv) = rte_crypto_op_ctod_offset(op,
uint8_t *,
sess->aead.iv.offset);
fsattr_pa(&iv) = 0;
fsattr_sz(&iv) = sess->aead.iv.length;
fsattr_va(&key) = sess->aead.key.data;
fsattr_pa(&key) = 0;
fsattr_sz(&key) = sess->aead.key.length;
fsattr_va(&mac) = op->sym->aead.digest.data;
fsattr_pa(&mac) = op->sym->aead.digest.phys_addr;
fsattr_sz(&mac) = sess->aead.digest_length;
fsattr_va(&aad) = op->sym->aead.aad.data;
fsattr_pa(&aad) = op->sym->aead.aad.phys_addr;
fsattr_sz(&aad) = sess->aead.aad_length;
rc = bcmfs_crypto_build_aead_request(req, sess->aead.algo,
sess->aead.op, &src, &dst,
&key, &iv, &aad, &mac);
if (rc)
op->status = RTE_CRYPTO_OP_STATUS_ERROR;
return rc;
}
/** Process crypto operation for mbuf */
int
bcmfs_process_sym_crypto_op(struct rte_crypto_op *op,
struct bcmfs_sym_session *sess,
struct bcmfs_sym_request *req)
{
struct rte_mbuf *msrc, *mdst;
int rc = 0;
msrc = op->sym->m_src;
mdst = op->sym->m_dst ? op->sym->m_dst : op->sym->m_src;
op->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
switch (sess->chain_order) {
case BCMFS_SYM_CHAIN_ONLY_CIPHER:
rc = process_crypto_cipher_op(op, msrc, mdst, sess, req);
break;
case BCMFS_SYM_CHAIN_ONLY_AUTH:
rc = process_crypto_auth_op(op, msrc, sess, req);
break;
case BCMFS_SYM_CHAIN_CIPHER_AUTH:
case BCMFS_SYM_CHAIN_AUTH_CIPHER:
rc = process_crypto_combined_op(op, msrc, mdst, sess, req);
break;
case BCMFS_SYM_CHAIN_AEAD:
rc = process_crypto_aead_op(op, msrc, mdst, sess, req);
break;
default:
op->status = RTE_CRYPTO_OP_STATUS_ERROR;
break;
}
return rc;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,115 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2020 Broadcom
* All rights reserved.
*/
#ifndef _BCMFS_SYM_ENGINE_H_
#define _BCMFS_SYM_ENGINE_H_
#include <rte_crypto_sym.h>
#include "bcmfs_dev_msg.h"
#include "bcmfs_sym_defs.h"
#include "bcmfs_sym_req.h"
/* structure to hold element's arrtibutes */
struct fsattr {
void *va;
uint64_t pa;
uint64_t sz;
};
#define fsattr_va(__ptr) ((__ptr)->va)
#define fsattr_pa(__ptr) ((__ptr)->pa)
#define fsattr_sz(__ptr) ((__ptr)->sz)
/*
* Macros for Crypto h/w constraints
*/
#define BCMFS_CRYPTO_AES_BLOCK_SIZE 16
#define BCMFS_CRYPTO_AES_MIN_KEY_SIZE 16
#define BCMFS_CRYPTO_AES_MAX_KEY_SIZE 32
#define BCMFS_CRYPTO_DES_BLOCK_SIZE 8
#define BCMFS_CRYPTO_DES_KEY_SIZE 8
#define BCMFS_CRYPTO_3DES_BLOCK_SIZE 8
#define BCMFS_CRYPTO_3DES_KEY_SIZE (3 * 8)
#define BCMFS_CRYPTO_MD5_DIGEST_SIZE 16
#define BCMFS_CRYPTO_MD5_BLOCK_SIZE 64
#define BCMFS_CRYPTO_SHA1_DIGEST_SIZE 20
#define BCMFS_CRYPTO_SHA1_BLOCK_SIZE 64
#define BCMFS_CRYPTO_SHA224_DIGEST_SIZE 28
#define BCMFS_CRYPTO_SHA224_BLOCK_SIZE 64
#define BCMFS_CRYPTO_SHA256_DIGEST_SIZE 32
#define BCMFS_CRYPTO_SHA256_BLOCK_SIZE 64
#define BCMFS_CRYPTO_SHA384_DIGEST_SIZE 48
#define BCMFS_CRYPTO_SHA384_BLOCK_SIZE 128
#define BCMFS_CRYPTO_SHA512_DIGEST_SIZE 64
#define BCMFS_CRYPTO_SHA512_BLOCK_SIZE 128
#define BCMFS_CRYPTO_SHA3_224_DIGEST_SIZE (224 / 8)
#define BCMFS_CRYPTO_SHA3_224_BLOCK_SIZE (200 - 2 * \
BCMFS_CRYPTO_SHA3_224_DIGEST_SIZE)
#define BCMFS_CRYPTO_SHA3_256_DIGEST_SIZE (256 / 8)
#define BCMFS_CRYPTO_SHA3_256_BLOCK_SIZE (200 - 2 * \
BCMFS_CRYPTO_SHA3_256_DIGEST_SIZE)
#define BCMFS_CRYPTO_SHA3_384_DIGEST_SIZE (384 / 8)
#define BCMFS_CRYPTO_SHA3_384_BLOCK_SIZE (200 - 2 * \
BCMFS_CRYPTO_SHA3_384_DIGEST_SIZE)
#define BCMFS_CRYPTO_SHA3_512_DIGEST_SIZE (512 / 8)
#define BCMFS_CRYPTO_SHA3_512_BLOCK_SIZE (200 - 2 * \
BCMFS_CRYPTO_SHA3_512_DIGEST_SIZE)
enum bcmfs_crypto_aes_cipher_key {
BCMFS_CRYPTO_AES128 = 16,
BCMFS_CRYPTO_AES192 = 24,
BCMFS_CRYPTO_AES256 = 32,
};
int
bcmfs_crypto_build_cipher_req(struct bcmfs_sym_request *req,
enum rte_crypto_cipher_algorithm c_algo,
enum rte_crypto_cipher_operation cop,
struct fsattr *src, struct fsattr *dst,
struct fsattr *key, struct fsattr *iv);
int
bcmfs_crypto_build_auth_req(struct bcmfs_sym_request *req,
enum rte_crypto_auth_algorithm a_algo,
enum rte_crypto_auth_operation aop,
struct fsattr *src, struct fsattr *dst,
struct fsattr *mac, struct fsattr *key,
struct fsattr *iv);
int
bcmfs_crypto_build_chain_request(struct bcmfs_sym_request *req,
enum rte_crypto_cipher_algorithm c_algo,
enum rte_crypto_cipher_operation cop,
enum rte_crypto_auth_algorithm a_algo,
enum rte_crypto_auth_operation aop,
struct fsattr *src, struct fsattr *dst,
struct fsattr *cipher_key,
struct fsattr *auth_key,
struct fsattr *iv, struct fsattr *aad,
struct fsattr *digest, bool cipher_first);
int
bcmfs_crypto_build_aead_request(struct bcmfs_sym_request *req,
enum rte_crypto_aead_algorithm ae_algo,
enum rte_crypto_aead_operation aeop,
struct fsattr *src, struct fsattr *dst,
struct fsattr *key, struct fsattr *iv,
struct fsattr *aad, struct fsattr *digest);
#endif /* _BCMFS_SYM_ENGINE_H_ */

View File

@ -132,6 +132,12 @@ static void
spu_req_init(struct bcmfs_sym_request *sr, rte_iova_t iova __rte_unused)
{
memset(sr, 0, sizeof(*sr));
sr->fptr = iova;
sr->cptr = iova + offsetof(struct bcmfs_sym_request, cipher_key);
sr->aptr = iova + offsetof(struct bcmfs_sym_request, auth_key);
sr->iptr = iova + offsetof(struct bcmfs_sym_request, iv);
sr->dptr = iova + offsetof(struct bcmfs_sym_request, digest);
sr->rptr = iova + offsetof(struct bcmfs_sym_request, resp);
}
static void
@ -244,6 +250,7 @@ bcmfs_sym_pmd_enqueue_op_burst(void *queue_pair,
uint16_t nb_ops)
{
int i, j;
int retval;
uint16_t enq = 0;
struct bcmfs_sym_request *sreq;
struct bcmfs_sym_session *sess;
@ -273,6 +280,11 @@ bcmfs_sym_pmd_enqueue_op_burst(void *queue_pair,
/* save context */
qp->infl_msgs[i] = &sreq->msgs;
qp->infl_msgs[i]->ctx = (void *)sreq;
/* pre process the request crypto h/w acceleration */
retval = bcmfs_process_sym_crypto_op(ops[i], sess, sreq);
if (unlikely(retval < 0))
goto enqueue_err;
}
/* Send burst request to hw QP */
enq = bcmfs_enqueue_op_burst(qp, (void **)qp->infl_msgs, i);
@ -289,6 +301,17 @@ bcmfs_sym_pmd_enqueue_op_burst(void *queue_pair,
return enq;
}
static void bcmfs_sym_set_request_status(struct rte_crypto_op *op,
struct bcmfs_sym_request *out)
{
if (*out->resp == BCMFS_SYM_RESPONSE_SUCCESS)
op->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
else if (*out->resp == BCMFS_SYM_RESPONSE_HASH_TAG_ERROR)
op->status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED;
else
op->status = RTE_CRYPTO_OP_STATUS_ERROR;
}
static uint16_t
bcmfs_sym_pmd_dequeue_op_burst(void *queue_pair,
struct rte_crypto_op **ops,
@ -308,6 +331,9 @@ bcmfs_sym_pmd_dequeue_op_burst(void *queue_pair,
for (i = 0; i < deq; i++) {
sreq = (struct bcmfs_sym_request *)qp->infl_msgs[i]->ctx;
/* set the status based on the response from the crypto h/w */
bcmfs_sym_set_request_status(sreq->op, sreq);
ops[pkts++] = sreq->op;
rte_mempool_put(qp->sr_mp, sreq);

View File

@ -6,13 +6,53 @@
#ifndef _BCMFS_SYM_REQ_H_
#define _BCMFS_SYM_REQ_H_
#include <rte_cryptodev.h>
#include "bcmfs_dev_msg.h"
#include "bcmfs_sym_defs.h"
/* Fixed SPU2 Metadata */
struct spu2_fmd {
uint64_t ctrl0;
uint64_t ctrl1;
uint64_t ctrl2;
uint64_t ctrl3;
};
/*
* This structure hold the supportive data required to process a
* rte_crypto_op
*/
struct bcmfs_sym_request {
/* spu2 engine related data */
struct spu2_fmd fmd;
/* cipher key */
uint8_t cipher_key[BCMFS_MAX_KEY_SIZE];
/* auth key */
uint8_t auth_key[BCMFS_MAX_KEY_SIZE];
/* iv key */
uint8_t iv[BCMFS_MAX_IV_SIZE];
/* digest data output from crypto h/w */
uint8_t digest[BCMFS_MAX_DIGEST_SIZE];
/* 2-Bytes response from crypto h/w */
uint8_t resp[2];
/*
* Below are all iovas for above members
* from top
*/
/* iova for fmd */
rte_iova_t fptr;
/* iova for cipher key */
rte_iova_t cptr;
/* iova for auth key */
rte_iova_t aptr;
/* iova for iv key */
rte_iova_t iptr;
/* iova for digest */
rte_iova_t dptr;
/* iova for response */
rte_iova_t rptr;
/* bcmfs qp message for h/w queues to process */
struct bcmfs_qp_message msgs;
/* crypto op */

View File

@ -14,5 +14,7 @@ sources = files(
'hw/bcmfs_rm_common.c',
'bcmfs_sym_pmd.c',
'bcmfs_sym_capabilities.c',
'bcmfs_sym_session.c'
'bcmfs_sym_session.c',
'bcmfs_sym.c',
'bcmfs_sym_engine.c'
)