From: Eric Biggers <ebiggers@xxxxxxxxxx> Replace calls to the deprecated function scatterwalk_copychunks() with memcpy_{from,to}_scatterwalk(), or just memcpy_{from,to}_sglist(). Since scatterwalk_copychunks() was incorrectly being called without being followed by scatterwalk_done(), this also fixes a bug where the dcache of the destination page(s) was not being flushed on architectures that need that. Signed-off-by: Eric Biggers <ebiggers@xxxxxxxxxx> --- crypto/keywrap.c | 48 ++++++------------------------------------------ 1 file changed, 6 insertions(+), 42 deletions(-) diff --git a/crypto/keywrap.c b/crypto/keywrap.c index 5ec4f94d46bd..700b7b79a93d 100644 --- a/crypto/keywrap.c +++ b/crypto/keywrap.c @@ -92,37 +92,10 @@ struct crypto_kw_block { #define SEMIBSIZE 8 __be64 A; __be64 R; }; -/* - * Fast forward the SGL to the "end" length minus SEMIBSIZE. - * The start in the SGL defined by the fast-forward is returned with - * the walk variable - */ -static void crypto_kw_scatterlist_ff(struct scatter_walk *walk, - struct scatterlist *sg, - unsigned int end) -{ - unsigned int skip = 0; - - /* The caller should only operate on full SEMIBLOCKs. */ - BUG_ON(end < SEMIBSIZE); - - skip = end - SEMIBSIZE; - while (sg) { - if (sg->length > skip) { - scatterwalk_start(walk, sg); - scatterwalk_advance(walk, skip); - break; - } - - skip -= sg->length; - sg = sg_next(sg); - } -} - static int crypto_kw_decrypt(struct skcipher_request *req) { struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); struct crypto_cipher *cipher = skcipher_cipher_simple(tfm); struct crypto_kw_block block; @@ -148,34 +121,27 @@ static int crypto_kw_decrypt(struct skcipher_request *req) */ src = req->src; dst = req->dst; for (i = 0; i < 6; i++) { - struct scatter_walk src_walk, dst_walk; unsigned int nbytes = req->cryptlen; while (nbytes) { - /* move pointer by nbytes in the SGL */ - crypto_kw_scatterlist_ff(&src_walk, src, nbytes); + nbytes -= SEMIBSIZE; + /* get the source block */ - scatterwalk_copychunks(&block.R, &src_walk, SEMIBSIZE, - false); + memcpy_from_sglist(&block.R, src, nbytes, SEMIBSIZE); /* perform KW operation: modify IV with counter */ block.A ^= cpu_to_be64(t); t--; /* perform KW operation: decrypt block */ crypto_cipher_decrypt_one(cipher, (u8 *)&block, (u8 *)&block); - /* move pointer by nbytes in the SGL */ - crypto_kw_scatterlist_ff(&dst_walk, dst, nbytes); /* Copy block->R into place */ - scatterwalk_copychunks(&block.R, &dst_walk, SEMIBSIZE, - true); - - nbytes -= SEMIBSIZE; + memcpy_to_sglist(dst, nbytes, &block.R, SEMIBSIZE); } /* we now start to operate on the dst SGL only */ src = req->dst; dst = req->dst; @@ -229,23 +195,21 @@ static int crypto_kw_encrypt(struct skcipher_request *req) scatterwalk_start(&src_walk, src); scatterwalk_start(&dst_walk, dst); while (nbytes) { /* get the source block */ - scatterwalk_copychunks(&block.R, &src_walk, SEMIBSIZE, - false); + memcpy_from_scatterwalk(&block.R, &src_walk, SEMIBSIZE); /* perform KW operation: encrypt block */ crypto_cipher_encrypt_one(cipher, (u8 *)&block, (u8 *)&block); /* perform KW operation: modify IV with counter */ block.A ^= cpu_to_be64(t); t++; /* Copy block->R into place */ - scatterwalk_copychunks(&block.R, &dst_walk, SEMIBSIZE, - true); + memcpy_to_scatterwalk(&dst_walk, &block.R, SEMIBSIZE); nbytes -= SEMIBSIZE; } /* we now start to operate on the dst SGL only */ -- 2.47.1