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