OSDN Git Service

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