Commit 4bede34c authored by Nagadheeraj, Rottela's avatar Nagadheeraj, Rottela Committed by Herbert Xu

crypto: cavium/nitrox - crypto request format changes

nitrox_skcipher_crypt() will do the necessary formatting/ordering of
input and output sglists based on the algorithm requirements.
It will also accommodate the mandatory output buffers required for
NITROX hardware like Output request headers (ORH) and Completion headers.
Signed-off-by: default avatarNagadheeraj Rottela <rottela.nagadheeraj@cavium.com>
Reviewed-by: default avatarSrikanth Jampala <Jampala.Srikanth@cavium.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent 180def6c
......@@ -155,13 +155,109 @@ static int nitrox_aes_setkey(struct crypto_skcipher *cipher, const u8 *key,
return nitrox_skcipher_setkey(cipher, aes_keylen, key, keylen);
}
static int alloc_src_sglist(struct skcipher_request *skreq, int ivsize)
{
struct nitrox_kcrypt_request *nkreq = skcipher_request_ctx(skreq);
int nents = sg_nents(skreq->src) + 1;
struct se_crypto_request *creq = &nkreq->creq;
char *iv;
struct scatterlist *sg;
/* Allocate buffer to hold IV and input scatterlist array */
nkreq->src = alloc_req_buf(nents, ivsize, creq->gfp);
if (!nkreq->src)
return -ENOMEM;
/* copy iv */
iv = nkreq->src;
memcpy(iv, skreq->iv, ivsize);
sg = (struct scatterlist *)(iv + ivsize);
creq->src = sg;
sg_init_table(sg, nents);
/* Input format:
* +----+----------------+
* | IV | SRC sg entries |
* +----+----------------+
*/
/* IV */
sg = create_single_sg(sg, iv, ivsize);
/* SRC entries */
create_multi_sg(sg, skreq->src);
return 0;
}
static int alloc_dst_sglist(struct skcipher_request *skreq, int ivsize)
{
struct nitrox_kcrypt_request *nkreq = skcipher_request_ctx(skreq);
int nents = sg_nents(skreq->dst) + 3;
int extralen = ORH_HLEN + COMP_HLEN;
struct se_crypto_request *creq = &nkreq->creq;
struct scatterlist *sg;
char *iv = nkreq->src;
/* Allocate buffer to hold ORH, COMPLETION and output scatterlist
* array
*/
nkreq->dst = alloc_req_buf(nents, extralen, creq->gfp);
if (!nkreq->dst)
return -ENOMEM;
creq->orh = (u64 *)(nkreq->dst);
set_orh_value(creq->orh);
creq->comp = (u64 *)(nkreq->dst + ORH_HLEN);
set_comp_value(creq->comp);
sg = (struct scatterlist *)(nkreq->dst + ORH_HLEN + COMP_HLEN);
creq->dst = sg;
sg_init_table(sg, nents);
/* Output format:
* +-----+----+----------------+-----------------+
* | ORH | IV | DST sg entries | COMPLETION Bytes|
* +-----+----+----------------+-----------------+
*/
/* ORH */
sg = create_single_sg(sg, creq->orh, ORH_HLEN);
/* IV */
sg = create_single_sg(sg, iv, ivsize);
/* DST entries */
sg = create_multi_sg(sg, skreq->dst);
/* COMPLETION Bytes */
create_single_sg(sg, creq->comp, COMP_HLEN);
return 0;
}
static void free_src_sglist(struct skcipher_request *skreq)
{
struct nitrox_kcrypt_request *nkreq = skcipher_request_ctx(skreq);
kfree(nkreq->src);
}
static void free_dst_sglist(struct skcipher_request *skreq)
{
struct nitrox_kcrypt_request *nkreq = skcipher_request_ctx(skreq);
kfree(nkreq->dst);
}
static void nitrox_skcipher_callback(struct skcipher_request *skreq,
int err)
{
free_src_sglist(skreq);
free_dst_sglist(skreq);
if (err) {
pr_err_ratelimited("request failed status 0x%0x\n", err);
err = -EINVAL;
}
skcipher_request_complete(skreq, err);
}
......@@ -172,6 +268,7 @@ static int nitrox_skcipher_crypt(struct skcipher_request *skreq, bool enc)
struct nitrox_kcrypt_request *nkreq = skcipher_request_ctx(skreq);
int ivsize = crypto_skcipher_ivsize(cipher);
struct se_crypto_request *creq;
int ret;
creq = &nkreq->creq;
creq->flags = skreq->base.flags;
......@@ -192,11 +289,15 @@ static int nitrox_skcipher_crypt(struct skcipher_request *skreq, bool enc)
creq->ctx_handle = nctx->u.ctx_handle;
creq->ctrl.s.ctxl = sizeof(struct flexi_crypto_context);
/* copy the iv */
memcpy(creq->iv, skreq->iv, ivsize);
creq->ivsize = ivsize;
creq->src = skreq->src;
creq->dst = skreq->dst;
ret = alloc_src_sglist(skreq, ivsize);
if (ret)
return ret;
ret = alloc_dst_sglist(skreq, ivsize);
if (ret) {
free_src_sglist(skreq);
return ret;
}
nkreq->nctx = nctx;
nkreq->skreq = skreq;
......
......@@ -7,6 +7,8 @@
#include "nitrox_dev.h"
#define PENDING_SIG 0xFFFFFFFFFFFFFFFFUL
/**
* struct gphdr - General purpose Header
* @param0: first parameter.
......@@ -46,13 +48,6 @@ union se_req_ctrl {
} s;
};
struct nitrox_sglist {
u16 len;
u16 raz0;
u32 raz1;
dma_addr_t dma;
};
#define MAX_IV_LEN 16
/**
......@@ -62,8 +57,10 @@ struct nitrox_sglist {
* @ctx_handle: Crypto context handle.
* @gph: GP Header
* @ctrl: Request Information.
* @in: Input sglist
* @out: Output sglist
* @orh: ORH address
* @comp: completion address
* @src: Input sglist
* @dst: Output sglist
*/
struct se_crypto_request {
u8 opcode;
......@@ -73,9 +70,8 @@ struct se_crypto_request {
struct gphdr gph;
union se_req_ctrl ctrl;
u8 iv[MAX_IV_LEN];
u16 ivsize;
u64 *orh;
u64 *comp;
struct scatterlist *src;
struct scatterlist *dst;
......@@ -200,6 +196,8 @@ struct nitrox_kcrypt_request {
struct se_crypto_request creq;
struct nitrox_crypto_ctx *nctx;
struct skcipher_request *skreq;
u8 *src;
u8 *dst;
};
/**
......@@ -376,26 +374,19 @@ struct nitrox_sgcomp {
/*
* strutct nitrox_sgtable - SG list information
* @map_cnt: Number of buffers mapped
* @nr_comp: Number of sglist components
* @sgmap_cnt: Number of buffers mapped
* @total_bytes: Total bytes in sglist.
* @len: Total sglist components length.
* @dma: DMA address of sglist component.
* @dir: DMA direction.
* @buf: crypto request buffer.
* @sglist: SG list of input/output buffers.
* @sgcomp_len: Total sglist components length.
* @sgcomp_dma: DMA address of sglist component.
* @sg: crypto request buffer.
* @sgcomp: sglist component for NITROX.
*/
struct nitrox_sgtable {
u8 map_bufs_cnt;
u8 nr_sgcomp;
u8 sgmap_cnt;
u16 total_bytes;
u32 len;
dma_addr_t dma;
enum dma_data_direction dir;
struct scatterlist *buf;
struct nitrox_sglist *sglist;
u32 sgcomp_len;
dma_addr_t sgcomp_dma;
struct scatterlist *sg;
struct nitrox_sgcomp *sgcomp;
};
......@@ -405,10 +396,8 @@ struct nitrox_sgtable {
#define COMP_HLEN 8
struct resp_hdr {
u64 orh;
dma_addr_t orh_dma;
u64 completion;
dma_addr_t completion_dma;
u64 *orh;
u64 *completion;
};
typedef void (*completion_t)(struct skcipher_request *skreq, int err);
......@@ -434,7 +423,6 @@ struct nitrox_softreq {
u32 flags;
gfp_t gfp;
atomic_t status;
bool inplace;
struct nitrox_device *ndev;
struct nitrox_cmdq *cmdq;
......@@ -450,4 +438,46 @@ struct nitrox_softreq {
struct skcipher_request *skreq;
};
static inline void *alloc_req_buf(int nents, int extralen, gfp_t gfp)
{
size_t size;
size = sizeof(struct scatterlist) * nents;
size += extralen;
return kzalloc(size, gfp);
}
static inline struct scatterlist *create_single_sg(struct scatterlist *sg,
void *buf, int buflen)
{
sg_set_buf(sg, buf, buflen);
sg++;
return sg;
}
static inline struct scatterlist *create_multi_sg(struct scatterlist *to_sg,
struct scatterlist *from_sg)
{
struct scatterlist *sg;
int i;
for_each_sg(from_sg, sg, sg_nents(from_sg), i) {
sg_set_buf(to_sg, sg_virt(sg), sg->length);
to_sg++;
}
return to_sg;
}
static inline void set_orh_value(u64 *orh)
{
WRITE_ONCE(*orh, PENDING_SIG);
}
static inline void set_comp_value(u64 *comp)
{
WRITE_ONCE(*comp, PENDING_SIG);
}
#endif /* __NITROX_REQ_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment