mirror of
https://github.com/torvalds/linux.git
synced 2026-11-06 21:58:01 +01:00
crypto: lskcipher - preserve state across unaligned chunks
crypto_lskcipher_crypt_unaligned() splits a request into page-sized
chunks but never sets CRYPTO_LSKCIPHER_FLAG_CONT, so a stateful algorithm
restarts from its keyed state at every page boundary. It also marks every
chunk CRYPTO_LSKCIPHER_FLAG_FINAL, which is wrong but harmless: chunks are
trimmed to a multiple of the chunk size, so the trailing partial block that
FINAL guards against is caught after the loop instead.
ARC4 is the only lskcipher with internal state, and cbc, the other
in-tree user of the direct API, never passes more than one block, so
this went unnoticed. bpf_crypto_crypt() however hands
__bpf_dynptr_data() to crypto_lskcipher_encrypt() unchecked, leaving
both alignment and length to the BPF program. An 8192-byte ARC4 request
offset by one byte comes back with its second page identical to its
first: the keystream is reused.
Set FINAL only on the last chunk and CONT after the first, mirroring the
progression used by crypto_lskcipher_crypt_sg().
Fixes: 0ae4dcc1eb ("crypto: skcipher - Add internal state support")
Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
parent
347c5e29a5
commit
ba871255f7
|
|
@ -75,6 +75,7 @@ static int crypto_lskcipher_crypt_unaligned(
|
|||
unsigned ivsize = crypto_lskcipher_ivsize(tfm);
|
||||
unsigned bs = crypto_lskcipher_blocksize(tfm);
|
||||
unsigned cs = crypto_lskcipher_chunksize(tfm);
|
||||
u32 flags = 0;
|
||||
int err;
|
||||
u8 *tiv;
|
||||
u8 *p;
|
||||
|
|
@ -98,13 +99,16 @@ static int crypto_lskcipher_crypt_unaligned(
|
|||
|
||||
if (chunk > cs)
|
||||
chunk &= ~(cs - 1);
|
||||
if (chunk == len)
|
||||
flags |= CRYPTO_LSKCIPHER_FLAG_FINAL;
|
||||
|
||||
memcpy(p, src, chunk);
|
||||
err = crypt(tfm, p, p, chunk, tiv, CRYPTO_LSKCIPHER_FLAG_FINAL);
|
||||
err = crypt(tfm, p, p, chunk, tiv, flags);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
memcpy(dst, p, chunk);
|
||||
flags |= CRYPTO_LSKCIPHER_FLAG_CONT;
|
||||
src += chunk;
|
||||
dst += chunk;
|
||||
len -= chunk;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user