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