rc4.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  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. &rc4_done,
  21. &rc4_export,
  22. &rc4_import
  23. };
  24. int rc4_start(prng_state *prng)
  25. {
  26. _ARGCHK(prng != NULL);
  27. /* set keysize to zero */
  28. prng->rc4.x = 0;
  29. return CRYPT_OK;
  30. }
  31. int rc4_add_entropy(const unsigned char *buf, unsigned long len, prng_state *prng)
  32. {
  33. _ARGCHK(buf != NULL);
  34. _ARGCHK(prng != NULL);
  35. if (prng->rc4.x + len > 256) {
  36. return CRYPT_INVALID_KEYSIZE;
  37. }
  38. while (len--) {
  39. prng->rc4.buf[prng->rc4.x++] = *buf++;
  40. }
  41. return CRYPT_OK;
  42. }
  43. int rc4_ready(prng_state *prng)
  44. {
  45. unsigned char key[256], tmp;
  46. int keylen, x, y;
  47. _ARGCHK(prng != NULL);
  48. /* extract the key */
  49. XMEMCPY(key, prng->rc4.buf, 256);
  50. keylen = prng->rc4.x;
  51. /* make RC4 perm and shuffle */
  52. for (x = 0; x < 256; x++) {
  53. prng->rc4.buf[x] = x;
  54. }
  55. for (x = y = 0; x < 256; x++) {
  56. y = (y + prng->rc4.buf[x] + key[x % keylen]) & 255;
  57. tmp = prng->rc4.buf[x]; prng->rc4.buf[x] = prng->rc4.buf[y]; prng->rc4.buf[y] = tmp;
  58. }
  59. prng->rc4.x = x;
  60. prng->rc4.y = y;
  61. #ifdef CLEAN_STACK
  62. zeromem(key, sizeof(key));
  63. #endif
  64. return CRYPT_OK;
  65. }
  66. unsigned long rc4_read(unsigned char *buf, unsigned long len, prng_state *prng)
  67. {
  68. int x, y;
  69. unsigned char *s, tmp;
  70. unsigned long n;
  71. _ARGCHK(buf != NULL);
  72. _ARGCHK(prng != NULL);
  73. n = len;
  74. x = prng->rc4.x;
  75. y = prng->rc4.y;
  76. s = prng->rc4.buf;
  77. while (len--) {
  78. x = (x + 1) & 255;
  79. y = (y + s[x]) & 255;
  80. tmp = s[x]; s[x] = s[y]; s[y] = tmp;
  81. tmp = (s[x] + s[y]) & 255;
  82. *buf++ = s[tmp];
  83. }
  84. prng->rc4.x = x;
  85. prng->rc4.y = y;
  86. return n;
  87. }
  88. void rc4_done(prng_state *prng)
  89. {
  90. _ARGCHK(prng != NULL);
  91. }
  92. int rc4_export(unsigned char *out, unsigned long *outlen, prng_state *prng)
  93. {
  94. _ARGCHK(outlen != NULL);
  95. *outlen = 0;
  96. return CRYPT_OK;
  97. }
  98. int rc4_import(const unsigned char *in, unsigned long inlen, prng_state *prng)
  99. {
  100. return CRYPT_OK;
  101. }
  102. #endif