rc4.c 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. /* LibTomCrypt, modular cryptographic library -- Tom St Denis
  2. *
  3. * LibTomCrypt is a library that provides various cryptographic
  4. * algorithms in a highly modular and flexible manner.
  5. *
  6. * The library is free for all purposes without any express
  7. * guarantee it works.
  8. *
  9. * Tom St Denis, [email protected], http://libtomcrypt.org
  10. */
  11. #include "mycrypt.h"
  12. #ifdef RC4
  13. const struct _prng_descriptor rc4_desc =
  14. {
  15. "rc4",
  16. &rc4_start,
  17. &rc4_add_entropy,
  18. &rc4_ready,
  19. &rc4_read
  20. };
  21. int rc4_start(prng_state *prng)
  22. {
  23. _ARGCHK(prng != NULL);
  24. /* set keysize to zero */
  25. prng->rc4.x = 0;
  26. return CRYPT_OK;
  27. }
  28. int rc4_add_entropy(const unsigned char *buf, unsigned long len, prng_state *prng)
  29. {
  30. _ARGCHK(buf != NULL);
  31. _ARGCHK(prng != NULL);
  32. if (prng->rc4.x + len > 256) {
  33. return CRYPT_INVALID_KEYSIZE;
  34. }
  35. while (len--) {
  36. prng->rc4.buf[prng->rc4.x++] = *buf++;
  37. }
  38. return CRYPT_OK;
  39. }
  40. int rc4_ready(prng_state *prng)
  41. {
  42. unsigned char key[256], tmp;
  43. int keylen, x, y;
  44. _ARGCHK(prng != NULL);
  45. /* extract the key */
  46. XMEMCPY(key, prng->rc4.buf, 256);
  47. keylen = prng->rc4.x;
  48. /* make RC4 perm and shuffle */
  49. for (x = 0; x < 256; x++) {
  50. prng->rc4.buf[x] = x;
  51. }
  52. for (x = y = 0; x < 256; x++) {
  53. y = (y + prng->rc4.buf[x] + key[x % keylen]) & 255;
  54. tmp = prng->rc4.buf[x]; prng->rc4.buf[x] = prng->rc4.buf[y]; prng->rc4.buf[y] = tmp;
  55. }
  56. prng->rc4.x = x;
  57. prng->rc4.y = y;
  58. #ifdef CLEAN_STACK
  59. zeromem(key, sizeof(key));
  60. #endif
  61. return CRYPT_OK;
  62. }
  63. unsigned long rc4_read(unsigned char *buf, unsigned long len, prng_state *prng)
  64. {
  65. int x, y;
  66. unsigned char *s, tmp;
  67. unsigned long n;
  68. _ARGCHK(buf != NULL);
  69. _ARGCHK(prng != NULL);
  70. n = len;
  71. x = prng->rc4.x;
  72. y = prng->rc4.y;
  73. s = prng->rc4.buf;
  74. while (len--) {
  75. x = (x + 1) & 255;
  76. y = (y + s[x]) & 255;
  77. tmp = s[x]; s[x] = s[y]; s[y] = tmp;
  78. tmp = (s[x] + s[y]) & 255;
  79. *buf++ ^= s[tmp];
  80. }
  81. prng->rc4.x = x;
  82. prng->rc4.y = y;
  83. return n;
  84. }
  85. #endif