From 18a7d0e4661360a2b3781e904920e4dc8d4b2437 Mon Sep 17 00:00:00 2001 From: Horia Geanta Date: Tue, 25 Mar 2014 18:05:38 +0200 Subject: crypto: caam/qi - fix aead sglen for case 'dst != src' Commit bbf9c8934ba2bfd5fd809562f945deaf5a565898 (crypto: caam - fix aead sglen for case 'dst != src') fixed an oops that showed up when not encrypting in-place. This patch does the same thing, but for caam/qi. Change-Id: If898604e04c41a443b6e1673e924673d50530a4d Signed-off-by: Horia Geanta Reviewed-on: http://git.am.freescale.net:8181/10384 Reviewed-by: Cristian Stoica Reviewed-by: Mircea Pop Reviewed-by: Alexandru Porosanu Tested-by: Review Code-CDREVIEW Reviewed-by: Jose Rivera diff --git a/drivers/crypto/caam/caamalg_qi.c b/drivers/crypto/caam/caamalg_qi.c index e43a286..1dba0c2 100644 --- a/drivers/crypto/caam/caamalg_qi.c +++ b/drivers/crypto/caam/caamalg_qi.c @@ -585,7 +585,7 @@ static inline void aead_done(struct caam_drv_req *drv_req, u32 status) * allocate and map the aead extended descriptor */ static struct aead_edesc *aead_edesc_alloc(struct aead_request *req, - bool *all_contig_ptr) + bool *all_contig_ptr, bool encrypt) { struct crypto_aead *aead = crypto_aead_reqtfm(req); struct caam_ctx *ctx = crypto_aead_ctx(aead); @@ -599,16 +599,26 @@ static struct aead_edesc *aead_edesc_alloc(struct aead_request *req, bool all_contig = true; bool assoc_chained = false, src_chained = false, dst_chained = false; int ivsize = crypto_aead_ivsize(aead); + unsigned int authsize = ctx->authsize; int qm_sg_index, qm_sg_ents = 0, qm_sg_bytes; struct qm_sg_entry *sg_table, *fd_sgt; struct caam_drv_req *drv_req; assoc_nents = sg_count(req->assoc, req->assoclen, &assoc_chained); - src_nents = sg_count(req->src, req->cryptlen, &src_chained); - if (unlikely(req->dst != req->src)) - dst_nents = sg_count(req->dst, req->cryptlen, &dst_chained); + if (unlikely(req->dst != req->src)) { + src_nents = sg_count(req->src, req->cryptlen, &src_chained); + dst_nents = sg_count(req->dst, + req->cryptlen + + (encrypt ? authsize : (-authsize)), + &dst_chained); + } else { + src_nents = sg_count(req->src, + req->cryptlen + + (encrypt ? authsize : 0), + &src_chained); + } sgc = dma_map_sg_chained(qidev, req->assoc, assoc_nents ? : 1, DMA_BIDIRECTIONAL, assoc_chained); @@ -777,10 +787,8 @@ static int aead_encrypt(struct aead_request *req) if (unlikely(caam_drv_ctx_busy(drv_ctx))) return -EAGAIN; - req->cryptlen += ctx->authsize; - /* allocate extended descriptor */ - edesc = aead_edesc_alloc(req, &all_contig); + edesc = aead_edesc_alloc(req, &all_contig, true); if (IS_ERR(edesc)) return PTR_ERR(edesc); @@ -788,9 +796,8 @@ static int aead_encrypt(struct aead_request *req) drv_req = &edesc->drv_req; drv_req->app_ctx = req; drv_req->cbk = aead_done; - drv_req->fd_sgt[0].length = req->cryptlen; - drv_req->fd_sgt[1].length = req->assoclen + ivsize + - req->cryptlen - ctx->authsize; + drv_req->fd_sgt[0].length = req->cryptlen + ctx->authsize; + drv_req->fd_sgt[1].length = req->assoclen + ivsize + req->cryptlen; drv_req->drv_ctx = drv_ctx; ret = caam_qi_enqueue(qidev, drv_req); @@ -824,7 +831,7 @@ static int aead_decrypt(struct aead_request *req) return -EAGAIN; /* allocate extended descriptor */ - edesc = aead_edesc_alloc(req, &all_contig); + edesc = aead_edesc_alloc(req, &all_contig, false); if (IS_ERR(edesc)) return PTR_ERR(edesc); @@ -875,7 +882,8 @@ static struct aead_edesc *aead_giv_edesc_alloc(struct aead_givcrypt_request src_nents = sg_count(req->src, req->cryptlen, &src_chained); if (unlikely(req->dst != req->src)) - dst_nents = sg_count(req->dst, req->cryptlen, &dst_chained); + dst_nents = sg_count(req->dst, req->cryptlen + ctx->authsize, + &dst_chained); sgc = dma_map_sg_chained(qidev, req->assoc, assoc_nents ? : 1, DMA_BIDIRECTIONAL, assoc_chained); @@ -1013,8 +1021,6 @@ static int aead_givencrypt(struct aead_givcrypt_request *areq) if (unlikely(caam_drv_ctx_busy(drv_ctx))) return -EAGAIN; - req->cryptlen += ctx->authsize; - /* allocate extended descriptor */ edesc = aead_giv_edesc_alloc(areq, &contig); if (IS_ERR(edesc)) @@ -1023,9 +1029,8 @@ static int aead_givencrypt(struct aead_givcrypt_request *areq) drv_req = &edesc->drv_req; drv_req->app_ctx = req; drv_req->cbk = aead_done; - drv_req->fd_sgt[0].length = ivsize + req->cryptlen; - drv_req->fd_sgt[1].length = req->assoclen + ivsize + - req->cryptlen - ctx->authsize; + drv_req->fd_sgt[0].length = ivsize + req->cryptlen + ctx->authsize; + drv_req->fd_sgt[1].length = req->assoclen + ivsize + req->cryptlen; drv_req->drv_ctx = drv_ctx; ret = caam_qi_enqueue(qidev, drv_req); -- cgit v0.10.2