Commit e367644b authored by Rosioru Dragos's avatar Rosioru Dragos Committed by Greg Kroah-Hartman

crypto: mxs-dcp - fix scatterlist linearization for hash

commit fa03481b upstream.

The incorrect traversal of the scatterlist, during the linearization phase
lead to computing the hash value of the wrong input buffer.
New implementation uses scatterwalk_map_and_copy()
to address this issue.

Cc: <stable@vger.kernel.org>
Fixes: 15b59e7c ("crypto: mxs - Add Freescale MXS DCP driver")
Signed-off-by: default avatarRosioru Dragos <dragos.rosioru@nxp.com>
Reviewed-by: default avatarHoria Geantă <horia.geanta@nxp.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent c7b7daf9
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <crypto/sha.h> #include <crypto/sha.h>
#include <crypto/internal/hash.h> #include <crypto/internal/hash.h>
#include <crypto/internal/skcipher.h> #include <crypto/internal/skcipher.h>
#include <crypto/scatterwalk.h>
#define DCP_MAX_CHANS 4 #define DCP_MAX_CHANS 4
#define DCP_BUF_SZ PAGE_SIZE #define DCP_BUF_SZ PAGE_SIZE
...@@ -621,49 +622,46 @@ static int dcp_sha_req_to_buf(struct crypto_async_request *arq) ...@@ -621,49 +622,46 @@ static int dcp_sha_req_to_buf(struct crypto_async_request *arq)
struct dcp_async_ctx *actx = crypto_ahash_ctx(tfm); struct dcp_async_ctx *actx = crypto_ahash_ctx(tfm);
struct dcp_sha_req_ctx *rctx = ahash_request_ctx(req); struct dcp_sha_req_ctx *rctx = ahash_request_ctx(req);
struct hash_alg_common *halg = crypto_hash_alg_common(tfm); struct hash_alg_common *halg = crypto_hash_alg_common(tfm);
const int nents = sg_nents(req->src);
uint8_t *in_buf = sdcp->coh->sha_in_buf; uint8_t *in_buf = sdcp->coh->sha_in_buf;
uint8_t *out_buf = sdcp->coh->sha_out_buf; uint8_t *out_buf = sdcp->coh->sha_out_buf;
uint8_t *src_buf;
struct scatterlist *src; struct scatterlist *src;
unsigned int i, len, clen; unsigned int i, len, clen, oft = 0;
int ret; int ret;
int fin = rctx->fini; int fin = rctx->fini;
if (fin) if (fin)
rctx->fini = 0; rctx->fini = 0;
for_each_sg(req->src, src, nents, i) { src = req->src;
src_buf = sg_virt(src); len = req->nbytes;
len = sg_dma_len(src);
do {
if (actx->fill + len > DCP_BUF_SZ)
clen = DCP_BUF_SZ - actx->fill;
else
clen = len;
memcpy(in_buf + actx->fill, src_buf, clen);
len -= clen;
src_buf += clen;
actx->fill += clen;
/* while (len) {
* If we filled the buffer and still have some if (actx->fill + len > DCP_BUF_SZ)
* more data, submit the buffer. clen = DCP_BUF_SZ - actx->fill;
*/ else
if (len && actx->fill == DCP_BUF_SZ) { clen = len;
ret = mxs_dcp_run_sha(req);
if (ret) scatterwalk_map_and_copy(in_buf + actx->fill, src, oft, clen,
return ret; 0);
actx->fill = 0;
rctx->init = 0; len -= clen;
} oft += clen;
} while (len); actx->fill += clen;
/*
* If we filled the buffer and still have some
* more data, submit the buffer.
*/
if (len && actx->fill == DCP_BUF_SZ) {
ret = mxs_dcp_run_sha(req);
if (ret)
return ret;
actx->fill = 0;
rctx->init = 0;
}
} }
if (fin) { if (fin) {
......
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