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/export.h>
12 #include <linux/module.h>
13
arc4_setkey(struct arc4_ctx * ctx,const u8 * in_key,unsigned int key_len)14 int arc4_setkey(struct arc4_ctx *ctx, const u8 *in_key, unsigned int key_len)
15 {
16 int i, j = 0, k = 0;
17
18 ctx->x = 1;
19 ctx->y = 0;
20
21 for (i = 0; i < 256; i++)
22 ctx->S[i] = i;
23
24 for (i = 0; i < 256; i++) {
25 u32 a = ctx->S[i];
26
27 j = (j + in_key[k] + a) & 0xff;
28 ctx->S[i] = ctx->S[j];
29 ctx->S[j] = a;
30 if (++k >= key_len)
31 k = 0;
32 }
33
34 return 0;
35 }
36 EXPORT_SYMBOL(arc4_setkey);
37
arc4_crypt(struct arc4_ctx * ctx,u8 * out,const u8 * in,unsigned int len)38 void arc4_crypt(struct arc4_ctx *ctx, u8 *out, const u8 *in, unsigned int len)
39 {
40 u32 *const S = ctx->S;
41 u32 x, y, a, b;
42 u32 ty, ta, tb;
43
44 if (len == 0)
45 return;
46
47 x = ctx->x;
48 y = ctx->y;
49
50 a = S[x];
51 y = (y + a) & 0xff;
52 b = S[y];
53
54 do {
55 S[y] = a;
56 a = (a + b) & 0xff;
57 S[x] = b;
58 x = (x + 1) & 0xff;
59 ta = S[x];
60 ty = (y + ta) & 0xff;
61 tb = S[ty];
62 *out++ = *in++ ^ S[a];
63 if (--len == 0)
64 break;
65 y = ty;
66 a = ta;
67 b = tb;
68 } while (true);
69
70 ctx->x = x;
71 ctx->y = y;
72 }
73 EXPORT_SYMBOL(arc4_crypt);
74
75 MODULE_DESCRIPTION("ARC4 Cipher Algorithm");
76 MODULE_LICENSE("GPL");
77