]> asedeno.scripts.mit.edu Git - PuTTY.git/blob - sshsha.c
Rename ssh_md5 and ssh_sha1 to ssh_hmac_md5 and ssh_hmac_sha1 respectively.
[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  * The above is the SHA-1 algorithm itself. Now we implement the
193  * HMAC wrapper on it.
194  */
195
196 static void *sha1_make_context(void)
197 {
198     return snewn(2, SHA_State);
199 }
200
201 static void sha1_free_context(void *handle)
202 {
203     sfree(handle);
204 }
205
206 static void sha1_key_internal(void *handle, unsigned char *key, int len)
207 {
208     SHA_State *keys = (SHA_State *)handle;
209     unsigned char foo[64];
210     int i;
211
212     memset(foo, 0x36, 64);
213     for (i = 0; i < len && i < 64; i++)
214         foo[i] ^= key[i];
215     SHA_Init(&keys[0]);
216     SHA_Bytes(&keys[0], foo, 64);
217
218     memset(foo, 0x5C, 64);
219     for (i = 0; i < len && i < 64; i++)
220         foo[i] ^= key[i];
221     SHA_Init(&keys[1]);
222     SHA_Bytes(&keys[1], foo, 64);
223
224     memset(foo, 0, 64);                /* burn the evidence */
225 }
226
227 static void sha1_key(void *handle, unsigned char *key)
228 {
229     sha1_key_internal(handle, key, 20);
230 }
231
232 static void sha1_key_buggy(void *handle, unsigned char *key)
233 {
234     sha1_key_internal(handle, key, 16);
235 }
236
237 static void sha1_do_hmac(void *handle, unsigned char *blk, int len,
238                          unsigned long seq, unsigned char *hmac)
239 {
240     SHA_State *keys = (SHA_State *)handle;
241     SHA_State s;
242     unsigned char intermediate[20];
243
244     intermediate[0] = (unsigned char) ((seq >> 24) & 0xFF);
245     intermediate[1] = (unsigned char) ((seq >> 16) & 0xFF);
246     intermediate[2] = (unsigned char) ((seq >> 8) & 0xFF);
247     intermediate[3] = (unsigned char) ((seq) & 0xFF);
248
249     s = keys[0];                       /* structure copy */
250     SHA_Bytes(&s, intermediate, 4);
251     SHA_Bytes(&s, blk, len);
252     SHA_Final(&s, intermediate);
253     s = keys[1];                       /* structure copy */
254     SHA_Bytes(&s, intermediate, 20);
255     SHA_Final(&s, hmac);
256 }
257
258 static void sha1_generate(void *handle, unsigned char *blk, int len,
259                           unsigned long seq)
260 {
261     sha1_do_hmac(handle, blk, len, seq, blk + len);
262 }
263
264 static int sha1_verify(void *handle, unsigned char *blk, int len,
265                        unsigned long seq)
266 {
267     unsigned char correct[20];
268     sha1_do_hmac(handle, blk, len, seq, correct);
269     return !memcmp(correct, blk + len, 20);
270 }
271
272 void hmac_sha1_simple(void *key, int keylen, void *data, int datalen,
273                       unsigned char *output) {
274     SHA_State states[2];
275     unsigned char intermediate[20];
276
277     sha1_key_internal(states, key, keylen);
278     SHA_Bytes(&states[0], data, datalen);
279     SHA_Final(&states[0], intermediate);
280
281     SHA_Bytes(&states[1], intermediate, 20);
282     SHA_Final(&states[1], output);
283 }
284
285 const struct ssh_mac ssh_hmac_sha1 = {
286     sha1_make_context, sha1_free_context, sha1_key,
287     sha1_generate, sha1_verify,
288     "hmac-sha1",
289     20,
290     "HMAC-SHA1"
291 };
292
293 const struct ssh_mac ssh_hmac_sha1_buggy = {
294     sha1_make_context, sha1_free_context, sha1_key_buggy,
295     sha1_generate, sha1_verify,
296     "hmac-sha1",
297     20,
298     "bug-compatible HMAC-SHA1"
299 };