1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Cryptographic API
4 *
5 * ARC4 Cipher Algorithm
6 *
7 * Jon Oberheide <jon@oberheide.org>
8 */
9
10#include <crypto/arc4.h>
11#include <linux/module.h>
12
13int arc4_setkey(struct arc4_ctx *ctx, const u8 *in_key, unsigned int key_len)
14{
15	int i, j = 0, k = 0;
16
17	ctx->x = 1;
18	ctx->y = 0;
19
20	for (i = 0; i < 256; i++)
21		ctx->S[i] = i;
22
23	for (i = 0; i < 256; i++) {
24		u32 a = ctx->S[i];
25
26		j = (j + in_key[k] + a) & 0xff;
27		ctx->S[i] = ctx->S[j];
28		ctx->S[j] = a;
29		if (++k >= key_len)
30			k = 0;
31	}
32
33	return 0;
34}
35EXPORT_SYMBOL(arc4_setkey);
36
37void arc4_crypt(struct arc4_ctx *ctx, u8 *out, const u8 *in, unsigned int len)
38{
39	u32 *const S = ctx->S;
40	u32 x, y, a, b;
41	u32 ty, ta, tb;
42
43	if (len == 0)
44		return;
45
46	x = ctx->x;
47	y = ctx->y;
48
49	a = S[x];
50	y = (y + a) & 0xff;
51	b = S[y];
52
53	do {
54		S[y] = a;
55		a = (a + b) & 0xff;
56		S[x] = b;
57		x = (x + 1) & 0xff;
58		ta = S[x];
59		ty = (y + ta) & 0xff;
60		tb = S[ty];
61		*out++ = *in++ ^ S[a];
62		if (--len == 0)
63			break;
64		y = ty;
65		a = ta;
66		b = tb;
67	} while (true);
68
69	ctx->x = x;
70	ctx->y = y;
71}
72EXPORT_SYMBOL(arc4_crypt);
73
74MODULE_LICENSE("GPL");
75