1
0
Fork 0

crypto: mxs-dcp - fix scatterlist linearization for hash

commit fa03481b6e 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: 15b59e7c37 ("crypto: mxs - Add Freescale MXS DCP driver")
Signed-off-by: Rosioru Dragos <dragos.rosioru@nxp.com>
Reviewed-by: Horia Geantă <horia.geanta@nxp.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
5.4-rM2-2.2.x-imx-squashed
Rosioru Dragos 2020-02-25 17:05:52 +02:00 committed by Greg Kroah-Hartman
parent 248414f505
commit 433868b19c
1 changed files with 26 additions and 28 deletions

View File

@ -20,6 +20,7 @@
#include <crypto/sha.h>
#include <crypto/internal/hash.h>
#include <crypto/internal/skcipher.h>
#include <crypto/scatterwalk.h>
#define DCP_MAX_CHANS 4
#define DCP_BUF_SZ PAGE_SIZE
@ -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_sha_req_ctx *rctx = ahash_request_ctx(req);
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 *out_buf = sdcp->coh->sha_out_buf;
uint8_t *src_buf;
struct scatterlist *src;
unsigned int i, len, clen;
unsigned int i, len, clen, oft = 0;
int ret;
int fin = rctx->fini;
if (fin)
rctx->fini = 0;
for_each_sg(req->src, src, nents, i) {
src_buf = sg_virt(src);
len = sg_dma_len(src);
src = req->src;
len = req->nbytes;
do {
if (actx->fill + len > DCP_BUF_SZ)
clen = DCP_BUF_SZ - actx->fill;
else
clen = len;
while (len) {
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;
scatterwalk_map_and_copy(in_buf + actx->fill, src, oft, clen,
0);
/*
* 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;
}
} while (len);
len -= clen;
oft += clen;
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) {