xref: /linux/lib/crypto/arc4.c (revision a1ff5a7d78a036d6c2178ee5acd6ba4946243800)
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