OSDN Git Service

TGitCache.exe build success
[tortoisegit/TortoiseGitJp.git] / src / TortoisePlink / SSHSHA.C
1 /*\r
2  * SHA1 hash algorithm. Used in SSH-2 as a MAC, and the transform is\r
3  * also used as a `stirring' function for the PuTTY random number\r
4  * pool. Implemented directly from the specification by Simon\r
5  * Tatham.\r
6  */\r
7 \r
8 #include "ssh.h"\r
9 \r
10 /* ----------------------------------------------------------------------\r
11  * Core SHA algorithm: processes 16-word blocks into a message digest.\r
12  */\r
13 \r
14 #define rol(x,y) ( ((x) << (y)) | (((uint32)x) >> (32-y)) )\r
15 \r
16 static void SHA_Core_Init(uint32 h[5])\r
17 {\r
18     h[0] = 0x67452301;\r
19     h[1] = 0xefcdab89;\r
20     h[2] = 0x98badcfe;\r
21     h[3] = 0x10325476;\r
22     h[4] = 0xc3d2e1f0;\r
23 }\r
24 \r
25 void SHATransform(word32 * digest, word32 * block)\r
26 {\r
27     word32 w[80];\r
28     word32 a, b, c, d, e;\r
29     int t;\r
30 \r
31     for (t = 0; t < 16; t++)\r
32         w[t] = block[t];\r
33 \r
34     for (t = 16; t < 80; t++) {\r
35         word32 tmp = w[t - 3] ^ w[t - 8] ^ w[t - 14] ^ w[t - 16];\r
36         w[t] = rol(tmp, 1);\r
37     }\r
38 \r
39     a = digest[0];\r
40     b = digest[1];\r
41     c = digest[2];\r
42     d = digest[3];\r
43     e = digest[4];\r
44 \r
45     for (t = 0; t < 20; t++) {\r
46         word32 tmp =\r
47             rol(a, 5) + ((b & c) | (d & ~b)) + e + w[t] + 0x5a827999;\r
48         e = d;\r
49         d = c;\r
50         c = rol(b, 30);\r
51         b = a;\r
52         a = tmp;\r
53     }\r
54     for (t = 20; t < 40; t++) {\r
55         word32 tmp = rol(a, 5) + (b ^ c ^ d) + e + w[t] + 0x6ed9eba1;\r
56         e = d;\r
57         d = c;\r
58         c = rol(b, 30);\r
59         b = a;\r
60         a = tmp;\r
61     }\r
62     for (t = 40; t < 60; t++) {\r
63         word32 tmp = rol(a,\r
64                          5) + ((b & c) | (b & d) | (c & d)) + e + w[t] +\r
65             0x8f1bbcdc;\r
66         e = d;\r
67         d = c;\r
68         c = rol(b, 30);\r
69         b = a;\r
70         a = tmp;\r
71     }\r
72     for (t = 60; t < 80; t++) {\r
73         word32 tmp = rol(a, 5) + (b ^ c ^ d) + e + w[t] + 0xca62c1d6;\r
74         e = d;\r
75         d = c;\r
76         c = rol(b, 30);\r
77         b = a;\r
78         a = tmp;\r
79     }\r
80 \r
81     digest[0] += a;\r
82     digest[1] += b;\r
83     digest[2] += c;\r
84     digest[3] += d;\r
85     digest[4] += e;\r
86 }\r
87 \r
88 /* ----------------------------------------------------------------------\r
89  * Outer SHA algorithm: take an arbitrary length byte string,\r
90  * convert it into 16-word blocks with the prescribed padding at\r
91  * the end, and pass those blocks to the core SHA algorithm.\r
92  */\r
93 \r
94 void SHA_Init(SHA_State * s)\r
95 {\r
96     SHA_Core_Init(s->h);\r
97     s->blkused = 0;\r
98     s->lenhi = s->lenlo = 0;\r
99 }\r
100 \r
101 void SHA_Bytes(SHA_State * s, void *p, int len)\r
102 {\r
103     unsigned char *q = (unsigned char *) p;\r
104     uint32 wordblock[16];\r
105     uint32 lenw = len;\r
106     int i;\r
107 \r
108     /*\r
109      * Update the length field.\r
110      */\r
111     s->lenlo += lenw;\r
112     s->lenhi += (s->lenlo < lenw);\r
113 \r
114     if (s->blkused && s->blkused + len < 64) {\r
115         /*\r
116          * Trivial case: just add to the block.\r
117          */\r
118         memcpy(s->block + s->blkused, q, len);\r
119         s->blkused += len;\r
120     } else {\r
121         /*\r
122          * We must complete and process at least one block.\r
123          */\r
124         while (s->blkused + len >= 64) {\r
125             memcpy(s->block + s->blkused, q, 64 - s->blkused);\r
126             q += 64 - s->blkused;\r
127             len -= 64 - s->blkused;\r
128             /* Now process the block. Gather bytes big-endian into words */\r
129             for (i = 0; i < 16; i++) {\r
130                 wordblock[i] =\r
131                     (((uint32) s->block[i * 4 + 0]) << 24) |\r
132                     (((uint32) s->block[i * 4 + 1]) << 16) |\r
133                     (((uint32) s->block[i * 4 + 2]) << 8) |\r
134                     (((uint32) s->block[i * 4 + 3]) << 0);\r
135             }\r
136             SHATransform(s->h, wordblock);\r
137             s->blkused = 0;\r
138         }\r
139         memcpy(s->block, q, len);\r
140         s->blkused = len;\r
141     }\r
142 }\r
143 \r
144 void SHA_Final(SHA_State * s, unsigned char *output)\r
145 {\r
146     int i;\r
147     int pad;\r
148     unsigned char c[64];\r
149     uint32 lenhi, lenlo;\r
150 \r
151     if (s->blkused >= 56)\r
152         pad = 56 + 64 - s->blkused;\r
153     else\r
154         pad = 56 - s->blkused;\r
155 \r
156     lenhi = (s->lenhi << 3) | (s->lenlo >> (32 - 3));\r
157     lenlo = (s->lenlo << 3);\r
158 \r
159     memset(c, 0, pad);\r
160     c[0] = 0x80;\r
161     SHA_Bytes(s, &c, pad);\r
162 \r
163     c[0] = (lenhi >> 24) & 0xFF;\r
164     c[1] = (lenhi >> 16) & 0xFF;\r
165     c[2] = (lenhi >> 8) & 0xFF;\r
166     c[3] = (lenhi >> 0) & 0xFF;\r
167     c[4] = (lenlo >> 24) & 0xFF;\r
168     c[5] = (lenlo >> 16) & 0xFF;\r
169     c[6] = (lenlo >> 8) & 0xFF;\r
170     c[7] = (lenlo >> 0) & 0xFF;\r
171 \r
172     SHA_Bytes(s, &c, 8);\r
173 \r
174     for (i = 0; i < 5; i++) {\r
175         output[i * 4] = (s->h[i] >> 24) & 0xFF;\r
176         output[i * 4 + 1] = (s->h[i] >> 16) & 0xFF;\r
177         output[i * 4 + 2] = (s->h[i] >> 8) & 0xFF;\r
178         output[i * 4 + 3] = (s->h[i]) & 0xFF;\r
179     }\r
180 }\r
181 \r
182 void SHA_Simple(void *p, int len, unsigned char *output)\r
183 {\r
184     SHA_State s;\r
185 \r
186     SHA_Init(&s);\r
187     SHA_Bytes(&s, p, len);\r
188     SHA_Final(&s, output);\r
189 }\r
190 \r
191 /*\r
192  * Thin abstraction for things where hashes are pluggable.\r
193  */\r
194 \r
195 static void *sha1_init(void)\r
196 {\r
197     SHA_State *s;\r
198 \r
199     s = snew(SHA_State);\r
200     SHA_Init(s);\r
201     return s;\r
202 }\r
203 \r
204 static void sha1_bytes(void *handle, void *p, int len)\r
205 {\r
206     SHA_State *s = handle;\r
207 \r
208     SHA_Bytes(s, p, len);\r
209 }\r
210 \r
211 static void sha1_final(void *handle, unsigned char *output)\r
212 {\r
213     SHA_State *s = handle;\r
214 \r
215     SHA_Final(s, output);\r
216     sfree(s);\r
217 }\r
218 \r
219 const struct ssh_hash ssh_sha1 = {\r
220     sha1_init, sha1_bytes, sha1_final, 20, "SHA-1"\r
221 };\r
222 \r
223 /* ----------------------------------------------------------------------\r
224  * The above is the SHA-1 algorithm itself. Now we implement the\r
225  * HMAC wrapper on it.\r
226  */\r
227 \r
228 static void *sha1_make_context(void)\r
229 {\r
230     return snewn(2, SHA_State);\r
231 }\r
232 \r
233 static void sha1_free_context(void *handle)\r
234 {\r
235     sfree(handle);\r
236 }\r
237 \r
238 static void sha1_key_internal(void *handle, unsigned char *key, int len)\r
239 {\r
240     SHA_State *keys = (SHA_State *)handle;\r
241     unsigned char foo[64];\r
242     int i;\r
243 \r
244     memset(foo, 0x36, 64);\r
245     for (i = 0; i < len && i < 64; i++)\r
246         foo[i] ^= key[i];\r
247     SHA_Init(&keys[0]);\r
248     SHA_Bytes(&keys[0], foo, 64);\r
249 \r
250     memset(foo, 0x5C, 64);\r
251     for (i = 0; i < len && i < 64; i++)\r
252         foo[i] ^= key[i];\r
253     SHA_Init(&keys[1]);\r
254     SHA_Bytes(&keys[1], foo, 64);\r
255 \r
256     memset(foo, 0, 64);                /* burn the evidence */\r
257 }\r
258 \r
259 static void sha1_key(void *handle, unsigned char *key)\r
260 {\r
261     sha1_key_internal(handle, key, 20);\r
262 }\r
263 \r
264 static void sha1_key_buggy(void *handle, unsigned char *key)\r
265 {\r
266     sha1_key_internal(handle, key, 16);\r
267 }\r
268 \r
269 static void sha1_do_hmac(void *handle, unsigned char *blk, int len,\r
270                          unsigned long seq, unsigned char *hmac)\r
271 {\r
272     SHA_State *keys = (SHA_State *)handle;\r
273     SHA_State s;\r
274     unsigned char intermediate[20];\r
275 \r
276     intermediate[0] = (unsigned char) ((seq >> 24) & 0xFF);\r
277     intermediate[1] = (unsigned char) ((seq >> 16) & 0xFF);\r
278     intermediate[2] = (unsigned char) ((seq >> 8) & 0xFF);\r
279     intermediate[3] = (unsigned char) ((seq) & 0xFF);\r
280 \r
281     s = keys[0];                       /* structure copy */\r
282     SHA_Bytes(&s, intermediate, 4);\r
283     SHA_Bytes(&s, blk, len);\r
284     SHA_Final(&s, intermediate);\r
285     s = keys[1];                       /* structure copy */\r
286     SHA_Bytes(&s, intermediate, 20);\r
287     SHA_Final(&s, hmac);\r
288 }\r
289 \r
290 static void sha1_generate(void *handle, unsigned char *blk, int len,\r
291                           unsigned long seq)\r
292 {\r
293     sha1_do_hmac(handle, blk, len, seq, blk + len);\r
294 }\r
295 \r
296 static int sha1_verify(void *handle, unsigned char *blk, int len,\r
297                        unsigned long seq)\r
298 {\r
299     unsigned char correct[20];\r
300     sha1_do_hmac(handle, blk, len, seq, correct);\r
301     return !memcmp(correct, blk + len, 20);\r
302 }\r
303 \r
304 static void sha1_96_generate(void *handle, unsigned char *blk, int len,\r
305                              unsigned long seq)\r
306 {\r
307     unsigned char full[20];\r
308     sha1_do_hmac(handle, blk, len, seq, full);\r
309     memcpy(blk + len, full, 12);\r
310 }\r
311 \r
312 static int sha1_96_verify(void *handle, unsigned char *blk, int len,\r
313                        unsigned long seq)\r
314 {\r
315     unsigned char correct[20];\r
316     sha1_do_hmac(handle, blk, len, seq, correct);\r
317     return !memcmp(correct, blk + len, 12);\r
318 }\r
319 \r
320 void hmac_sha1_simple(void *key, int keylen, void *data, int datalen,\r
321                       unsigned char *output) {\r
322     SHA_State states[2];\r
323     unsigned char intermediate[20];\r
324 \r
325     sha1_key_internal(states, key, keylen);\r
326     SHA_Bytes(&states[0], data, datalen);\r
327     SHA_Final(&states[0], intermediate);\r
328 \r
329     SHA_Bytes(&states[1], intermediate, 20);\r
330     SHA_Final(&states[1], output);\r
331 }\r
332 \r
333 const struct ssh_mac ssh_hmac_sha1 = {\r
334     sha1_make_context, sha1_free_context, sha1_key,\r
335     sha1_generate, sha1_verify,\r
336     "hmac-sha1",\r
337     20,\r
338     "HMAC-SHA1"\r
339 };\r
340 \r
341 const struct ssh_mac ssh_hmac_sha1_96 = {\r
342     sha1_make_context, sha1_free_context, sha1_key,\r
343     sha1_96_generate, sha1_96_verify,\r
344     "hmac-sha1-96",\r
345     12,\r
346     "HMAC-SHA1-96"\r
347 };\r
348 \r
349 const struct ssh_mac ssh_hmac_sha1_buggy = {\r
350     sha1_make_context, sha1_free_context, sha1_key_buggy,\r
351     sha1_generate, sha1_verify,\r
352     "hmac-sha1",\r
353     20,\r
354     "bug-compatible HMAC-SHA1"\r
355 };\r
356 \r
357 const struct ssh_mac ssh_hmac_sha1_96_buggy = {\r
358     sha1_make_context, sha1_free_context, sha1_key_buggy,\r
359     sha1_96_generate, sha1_96_verify,\r
360     "hmac-sha1-96",\r
361     12,\r
362     "bug-compatible HMAC-SHA1-96"\r
363 };\r