1 #include <stdarg.h> /* FIXME */
2 #include <windows.h> /* FIXME */
3 #include "putty.h" /* FIXME */
6 * SHA1 hash algorithm. Used in SSH2 as a MAC, and the transform is
7 * also used as a `stirring' function for the PuTTY random number
8 * pool. Implemented directly from the specification by Simon
14 typedef unsigned int uint32
;
16 /* ----------------------------------------------------------------------
17 * Core SHA algorithm: processes 16-word blocks into a message digest.
20 #define rol(x,y) ( ((x) << (y)) | (((uint32)x) >> (32-y)) )
22 void SHA_Core_Init(uint32 h
[5]) {
30 void SHATransform(word32
*digest
, word32
*block
) {
35 for (t
= 0; t
< 16; t
++)
38 for (t
= 16; t
< 80; t
++) {
39 word32 tmp
= w
[t
-3] ^ w
[t
-8] ^ w
[t
-14] ^ w
[t
-16];
49 for (t
= 0; t
< 20; t
++) {
50 word32 tmp
= rol(a
, 5) + ( (b
&c
) | (d
&~b
) ) + e
+ w
[t
] + 0x5a827999;
51 e
= d
; d
= c
; c
= rol(b
, 30); b
= a
; a
= tmp
;
53 for (t
= 20; t
< 40; t
++) {
54 word32 tmp
= rol(a
, 5) + (b
^c
^d
) + e
+ w
[t
] + 0x6ed9eba1;
55 e
= d
; d
= c
; c
= rol(b
, 30); b
= a
; a
= tmp
;
57 for (t
= 40; t
< 60; t
++) {
58 word32 tmp
= rol(a
, 5) + ( (b
&c
) | (b
&d
) | (c
&d
) ) + e
+ w
[t
] + 0x8f1bbcdc;
59 e
= d
; d
= c
; c
= rol(b
, 30); b
= a
; a
= tmp
;
61 for (t
= 60; t
< 80; t
++) {
62 word32 tmp
= rol(a
, 5) + (b
^c
^d
) + e
+ w
[t
] + 0xca62c1d6;
63 e
= d
; d
= c
; c
= rol(b
, 30); b
= a
; a
= tmp
;
73 /* ----------------------------------------------------------------------
74 * Outer SHA algorithm: take an arbitrary length byte string,
75 * convert it into 16-word blocks with the prescribed padding at
76 * the end, and pass those blocks to the core SHA algorithm.
79 void SHA_Init(SHA_State
*s
) {
82 s
->lenhi
= s
->lenlo
= 0;
85 void SHA_Bytes(SHA_State
*s
, void *p
, int len
) {
86 unsigned char *q
= (unsigned char *)p
;
92 * Update the length field.
95 s
->lenhi
+= (s
->lenlo
< lenw
);
97 if (s
->blkused
&& s
->blkused
+len
< 64) {
99 * Trivial case: just add to the block.
101 memcpy(s
->block
+ s
->blkused
, q
, len
);
105 * We must complete and process at least one block.
107 while (s
->blkused
+ len
>= 64) {
108 memcpy(s
->block
+ s
->blkused
, q
, 64 - s
->blkused
);
109 q
+= 64 - s
->blkused
;
110 len
-= 64 - s
->blkused
;
111 /* Now process the block. Gather bytes big-endian into words */
112 for (i
= 0; i
< 16; i
++) {
114 ( ((uint32
)s
->block
[i
*4+0]) << 24 ) |
115 ( ((uint32
)s
->block
[i
*4+1]) << 16 ) |
116 ( ((uint32
)s
->block
[i
*4+2]) << 8 ) |
117 ( ((uint32
)s
->block
[i
*4+3]) << 0 );
119 SHATransform(s
->h
, wordblock
);
122 memcpy(s
->block
, q
, len
);
127 void SHA_Final(SHA_State
*s
, unsigned char *output
) {
133 if (s
->blkused
>= 56)
134 pad
= 56 + 64 - s
->blkused
;
136 pad
= 56 - s
->blkused
;
138 lenhi
= (s
->lenhi
<< 3) | (s
->lenlo
>> (32-3));
139 lenlo
= (s
->lenlo
<< 3);
143 SHA_Bytes(s
, &c
, pad
);
145 c
[0] = (lenhi
>> 24) & 0xFF;
146 c
[1] = (lenhi
>> 16) & 0xFF;
147 c
[2] = (lenhi
>> 8) & 0xFF;
148 c
[3] = (lenhi
>> 0) & 0xFF;
149 c
[4] = (lenlo
>> 24) & 0xFF;
150 c
[5] = (lenlo
>> 16) & 0xFF;
151 c
[6] = (lenlo
>> 8) & 0xFF;
152 c
[7] = (lenlo
>> 0) & 0xFF;
156 for (i
= 0; i
< 5; i
++) {
157 output
[i
*4 ] = (s
->h
[i
] >> 24) & 0xFF;
158 output
[i
*4+1] = (s
->h
[i
] >> 16) & 0xFF;
159 output
[i
*4+2] = (s
->h
[i
] >> 8) & 0xFF;
160 output
[i
*4+3] = (s
->h
[i
] ) & 0xFF;
164 void SHA_Simple(void *p
, int len
, unsigned char *output
) {
168 SHA_Bytes(&s
, p
, len
);
169 SHA_Final(&s
, output
);
172 /* ----------------------------------------------------------------------
173 * The above is the SHA-1 algorithm itself. Now we implement the
174 * HMAC wrapper on it.
177 static SHA_State sha1_cs_mac_s1
, sha1_cs_mac_s2
;
178 static SHA_State sha1_sc_mac_s1
, sha1_sc_mac_s2
;
180 static void sha1_key(SHA_State
*s1
, SHA_State
*s2
,
181 unsigned char *key
, int len
) {
182 unsigned char foo
[64];
185 debug(("Key supplied is:\r\n"));
186 for (j
=0; j
<len
; j
++) debug((" %02X", key
[j
]));
190 memset(foo
, 0x36, 64);
191 for (i
= 0; i
< len
&& i
< 64; i
++)
194 SHA_Bytes(s1
, foo
, 64);
196 memset(foo
, 0x5C, 64);
197 for (i
= 0; i
< len
&& i
< 64; i
++)
200 SHA_Bytes(s2
, foo
, 64);
202 memset(foo
, 0, 64); /* burn the evidence */
205 static void sha1_cskey(unsigned char *key
) {
206 sha1_key(&sha1_cs_mac_s1
, &sha1_cs_mac_s2
, key
, 20);
209 static void sha1_sckey(unsigned char *key
) {
210 sha1_key(&sha1_sc_mac_s1
, &sha1_sc_mac_s2
, key
, 20);
213 static void sha1_do_hmac(SHA_State
*s1
, SHA_State
*s2
,
214 unsigned char *blk
, int len
, unsigned long seq
,
215 unsigned char *hmac
) {
217 unsigned char intermediate
[20];
219 intermediate
[0] = (unsigned char)((seq
>> 24) & 0xFF);
220 intermediate
[1] = (unsigned char)((seq
>> 16) & 0xFF);
221 intermediate
[2] = (unsigned char)((seq
>> 8) & 0xFF);
222 intermediate
[3] = (unsigned char)((seq
) & 0xFF);
224 s
= *s1
; /* structure copy */
225 SHA_Bytes(&s
, intermediate
, 4);
226 SHA_Bytes(&s
, blk
, len
);
227 SHA_Final(&s
, intermediate
);
228 s
= *s2
; /* structure copy */
229 SHA_Bytes(&s
, intermediate
, 20);
233 static void sha1_generate(unsigned char *blk
, int len
, unsigned long seq
) {
235 debug(("Gen HMAC on block len=%d seq=%d:\r\n", len
, seq
));
236 for (i
=0; i
<len
; i
++) debug((" %02X", blk
[i
]));
239 sha1_do_hmac(&sha1_cs_mac_s1
, &sha1_cs_mac_s2
, blk
, len
, seq
, blk
+len
);
241 debug(("We compute HMAC as:\r\n"));
242 for (i
=0; i
<20; i
++) debug((" %02X", blk
[len
+i
]));
247 static int sha1_verify(unsigned char *blk
, int len
, unsigned long seq
) {
248 unsigned char correct
[20];
250 debug(("HMAC on block len=%d seq=%d:\r\n", len
, seq
));
251 for (i
=0; i
<len
; i
++) debug((" %02X", blk
[i
]));
254 sha1_do_hmac(&sha1_sc_mac_s1
, &sha1_sc_mac_s2
, blk
, len
, seq
, correct
);
256 debug(("We compute HMAC as:\r\n"));
257 for (i
=0; i
<20; i
++) debug((" %02X", correct
[i
]));
260 return !memcmp(correct
, blk
+len
, 20);
263 struct ssh_mac ssh_sha1
= {
264 sha1_cskey
, sha1_sckey
,