ssharcf.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. /*
  2. * Arcfour (RC4) implementation for PuTTY.
  3. *
  4. * Coded from Schneier.
  5. */
  6. #include <assert.h>
  7. #include "ssh.h"
  8. typedef struct {
  9. unsigned char i, j, s[256];
  10. } ArcfourContext;
  11. static void arcfour_block(void *handle, unsigned char *blk, int len)
  12. {
  13. ArcfourContext *ctx = (ArcfourContext *)handle;
  14. unsigned k;
  15. unsigned char tmp, i, j, *s;
  16. s = ctx->s;
  17. i = ctx->i; j = ctx->j;
  18. for (k = 0; (int)k < len; k++) {
  19. i = (i + 1) & 0xff;
  20. j = (j + s[i]) & 0xff;
  21. tmp = s[i]; s[i] = s[j]; s[j] = tmp;
  22. blk[k] ^= s[(s[i]+s[j]) & 0xff];
  23. }
  24. ctx->i = i; ctx->j = j;
  25. }
  26. static void arcfour_setkey(ArcfourContext *ctx, unsigned char const *key,
  27. unsigned keybytes)
  28. {
  29. unsigned char tmp, k[256], *s;
  30. unsigned i, j;
  31. s = ctx->s;
  32. assert(keybytes <= 256);
  33. ctx->i = ctx->j = 0;
  34. for (i = 0; i < 256; i++) {
  35. s[i] = i;
  36. k[i] = key[i % keybytes];
  37. }
  38. j = 0;
  39. for (i = 0; i < 256; i++) {
  40. j = (j + s[i] + k[i]) & 0xff;
  41. tmp = s[i]; s[i] = s[j]; s[j] = tmp;
  42. }
  43. }
  44. /* -- Interface with PuTTY -- */
  45. /*
  46. * We don't implement Arcfour in SSH-1 because it's utterly insecure in
  47. * several ways. See CERT Vulnerability Notes VU#25309, VU#665372,
  48. * and VU#565052.
  49. *
  50. * We don't implement the "arcfour" algorithm in SSH-2 because it doesn't
  51. * stir the cipher state before emitting keystream, and hence is likely
  52. * to leak data about the key.
  53. */
  54. static void *arcfour_make_context(void)
  55. {
  56. return snew(ArcfourContext);
  57. }
  58. static void arcfour_free_context(void *handle)
  59. {
  60. sfree(handle);
  61. }
  62. static void arcfour_stir(ArcfourContext *ctx)
  63. {
  64. unsigned char *junk = snewn(1536, unsigned char);
  65. memset(junk, 0, 1536);
  66. arcfour_block(ctx, junk, 1536);
  67. smemclr(junk, 1536);
  68. sfree(junk);
  69. }
  70. static void arcfour128_key(void *handle, unsigned char *key)
  71. {
  72. ArcfourContext *ctx = (ArcfourContext *)handle;
  73. arcfour_setkey(ctx, key, 16);
  74. arcfour_stir(ctx);
  75. }
  76. static void arcfour256_key(void *handle, unsigned char *key)
  77. {
  78. ArcfourContext *ctx = (ArcfourContext *)handle;
  79. arcfour_setkey(ctx, key, 32);
  80. arcfour_stir(ctx);
  81. }
  82. static void arcfour_iv(void *handle, unsigned char *key)
  83. {
  84. }
  85. const struct ssh2_cipher ssh_arcfour128_ssh2 = {
  86. arcfour_make_context, arcfour_free_context, arcfour_iv, arcfour128_key,
  87. arcfour_block, arcfour_block, NULL, NULL,
  88. "arcfour128",
  89. 1, 128, 16, 0, "Arcfour-128",
  90. NULL
  91. };
  92. const struct ssh2_cipher ssh_arcfour256_ssh2 = {
  93. arcfour_make_context, arcfour_free_context, arcfour_iv, arcfour256_key,
  94. arcfour_block, arcfour_block, NULL, NULL,
  95. "arcfour256",
  96. 1, 256, 32, 0, "Arcfour-256",
  97. NULL
  98. };
  99. static const struct ssh2_cipher *const arcfour_list[] = {
  100. &ssh_arcfour256_ssh2,
  101. &ssh_arcfour128_ssh2,
  102. };
  103. const struct ssh2_ciphers ssh2_arcfour = {
  104. sizeof(arcfour_list) / sizeof(*arcfour_list),
  105. arcfour_list
  106. };