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