arc4.c 1.2 KB

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