Commit fa03481b authored by Rosioru Dragos's avatar Rosioru Dragos Committed by Herbert Xu
Browse files

crypto: mxs-dcp - fix scatterlist linearization for hash



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>
parent 5fbab10d
Loading
Loading
Loading
Loading
+28 −30
Original line number Diff line number Diff line
@@ -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
@@ -611,35 +612,33 @@ 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 {
	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);
		scatterwalk_map_and_copy(in_buf + actx->fill, src, oft, clen,
					 0);

		len -= clen;
			src_buf += clen;
		oft += clen;
		actx->fill += clen;

		/*
@@ -653,7 +652,6 @@ static int dcp_sha_req_to_buf(struct crypto_async_request *arq)
			actx->fill = 0;
			rctx->init = 0;
		}
		} while (len);
	}

	if (fin) {