crypto: mxs-dcp - fix scatterlist linearization for hash
commit5.4-rM2-2.2.x-imx-squashedfa03481b6e
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>
parent
248414f505
commit
433868b19c
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue