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