Merge tag 'x86_urgent_for_v5.14' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.git] / lib / crypto / arc4.c
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
13 int 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 }
35 EXPORT_SYMBOL(arc4_setkey);
36
37 void 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 }
72 EXPORT_SYMBOL(arc4_crypt);
73
74 MODULE_LICENSE("GPL");