summaryrefslogtreecommitdiff
path: root/crypto
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2023-11-28 14:52:57 +0800
committerHerbert Xu <herbert@gondor.apana.org.au>2023-12-08 11:59:46 +0800
commit47309ea1359115125d9cab17a279c8df72b47235 (patch)
tree08c92a0855dd0b24b6129286c15c149fffeff7eb /crypto
parent662ea18d089ba6fa02859fbd64f2aa78d88c6648 (diff)
crypto: arc4 - Add internal state
The arc4 algorithm has always had internal state. It's been buggy from day one in that the state has been stored in the shared tfm object. That means two users sharing the same tfm will end up affecting each other's output, or worse, they may end up with the same output. Fix this by declaring an internal state and storing the state there instead of within the tfm context. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto')
-rw-r--r--crypto/arc4.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/crypto/arc4.c b/crypto/arc4.c
index 2150f94e7d03..1a4825c97c5a 100644
--- a/crypto/arc4.c
+++ b/crypto/arc4.c
@@ -14,6 +14,8 @@
#include <linux/module.h>
#include <linux/sched.h>
+#define ARC4_ALIGN __alignof__(struct arc4_ctx)
+
static int crypto_arc4_setkey(struct crypto_lskcipher *tfm, const u8 *in_key,
unsigned int key_len)
{
@@ -23,10 +25,15 @@ static int crypto_arc4_setkey(struct crypto_lskcipher *tfm, const u8 *in_key,
}
static int crypto_arc4_crypt(struct crypto_lskcipher *tfm, const u8 *src,
- u8 *dst, unsigned nbytes, u8 *iv, u32 flags)
+ u8 *dst, unsigned nbytes, u8 *siv, u32 flags)
{
struct arc4_ctx *ctx = crypto_lskcipher_ctx(tfm);
+ if (!(flags & CRYPTO_LSKCIPHER_FLAG_CONT))
+ memcpy(siv, ctx, sizeof(*ctx));
+
+ ctx = (struct arc4_ctx *)siv;
+
arc4_crypt(ctx, dst, src, nbytes);
return 0;
}
@@ -45,9 +52,11 @@ static struct lskcipher_alg arc4_alg = {
.co.base.cra_priority = 100,
.co.base.cra_blocksize = ARC4_BLOCK_SIZE,
.co.base.cra_ctxsize = sizeof(struct arc4_ctx),
+ .co.base.cra_alignmask = ARC4_ALIGN - 1,
.co.base.cra_module = THIS_MODULE,
.co.min_keysize = ARC4_MIN_KEY_SIZE,
.co.max_keysize = ARC4_MAX_KEY_SIZE,
+ .co.statesize = sizeof(struct arc4_ctx),
.setkey = crypto_arc4_setkey,
.encrypt = crypto_arc4_crypt,
.decrypt = crypto_arc4_crypt,