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