From: Herbert Xu herbert@gondor.apana.org.au
stable inclusion from stable-v5.10.210 commit cd51e26a3b89706beec64f2d8296cfb1c34e0c79 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I9Q9DK CVE: CVE-2023-52669
--------------------------------
commit d07f951903fa9922c375b8ab1ce81b18a0034e3b upstream.
When processing the last block, the s390 ctr code will always read a whole block, even if there isn't a whole block of data left. Fix this by using the actual length left and copy it into a buffer first for processing.
Fixes: 0200f3ecc196 ("crypto: s390 - add System z hardware support for CTR mode") Cc: stable@vger.kernel.org Reported-by: Guangwu Zhang guazhang@redhat.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Reviewd-by: Harald Freudenberger freude@de.ibm.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Conflicts: arch/s390/crypto/aes_s390.c arch/s390/crypto/paes_s390.c [Yongqiang: adapt for pointer of blkcipher_walk] Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com --- arch/s390/crypto/aes_s390.c | 5 +++-- arch/s390/crypto/paes_s390.c | 4 +++- 2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/arch/s390/crypto/aes_s390.c b/arch/s390/crypto/aes_s390.c index 2bc189187ed4..7e16cb5b5cc7 100644 --- a/arch/s390/crypto/aes_s390.c +++ b/arch/s390/crypto/aes_s390.c @@ -727,8 +727,9 @@ static int ctr_aes_crypt(struct blkcipher_desc *desc, unsigned long modifier, * final block may be < AES_BLOCK_SIZE, copy only nbytes */ if (nbytes) { - cpacf_kmctr(sctx->fc | modifier, sctx->key, - buf, walk->src.virt.addr, + memset(buf, 0, AES_BLOCK_SIZE); + memcpy(buf, walk->src.virt.addr, nbytes); + cpacf_kmctr(sctx->fc | modifier, sctx->key, buf, buf, AES_BLOCK_SIZE, walk->iv); memcpy(walk->dst.virt.addr, buf, nbytes); crypto_inc(walk->iv, AES_BLOCK_SIZE); diff --git a/arch/s390/crypto/paes_s390.c b/arch/s390/crypto/paes_s390.c index ab9a0ebecc19..7a8bba99867c 100644 --- a/arch/s390/crypto/paes_s390.c +++ b/arch/s390/crypto/paes_s390.c @@ -483,10 +483,12 @@ static int ctr_paes_crypt(struct blkcipher_desc *desc, unsigned long modifier, * final block may be < AES_BLOCK_SIZE, copy only nbytes */ if (nbytes) { + memset(buf, 0, AES_BLOCK_SIZE); + memcpy(buf, walk->src.virt.addr, nbytes); while (1) { if (cpacf_kmctr(ctx->fc | modifier, ctx->pk.protkey, buf, - walk->src.virt.addr, AES_BLOCK_SIZE, + buf, AES_BLOCK_SIZE, walk->iv) == AES_BLOCK_SIZE) break; if (__ctr_paes_set_key(ctx) != 0)