2 * SHA-256 algorithm as described at
\r
4 * http://csrc.nist.gov/cryptval/shs.html
\r
9 /* ----------------------------------------------------------------------
\r
10 * Core SHA256 algorithm: processes 16-word blocks into a message digest.
\r
13 #define ror(x,y) ( ((x) << (32-y)) | (((uint32)(x)) >> (y)) )
\r
14 #define shr(x,y) ( (((uint32)(x)) >> (y)) )
\r
15 #define Ch(x,y,z) ( ((x) & (y)) ^ (~(x) & (z)) )
\r
16 #define Maj(x,y,z) ( ((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)) )
\r
17 #define bigsigma0(x) ( ror((x),2) ^ ror((x),13) ^ ror((x),22) )
\r
18 #define bigsigma1(x) ( ror((x),6) ^ ror((x),11) ^ ror((x),25) )
\r
19 #define smallsigma0(x) ( ror((x),7) ^ ror((x),18) ^ shr((x),3) )
\r
20 #define smallsigma1(x) ( ror((x),17) ^ ror((x),19) ^ shr((x),10) )
\r
22 void SHA256_Core_Init(SHA256_State *s) {
\r
23 s->h[0] = 0x6a09e667;
\r
24 s->h[1] = 0xbb67ae85;
\r
25 s->h[2] = 0x3c6ef372;
\r
26 s->h[3] = 0xa54ff53a;
\r
27 s->h[4] = 0x510e527f;
\r
28 s->h[5] = 0x9b05688c;
\r
29 s->h[6] = 0x1f83d9ab;
\r
30 s->h[7] = 0x5be0cd19;
\r
33 void SHA256_Block(SHA256_State *s, uint32 *block) {
\r
35 uint32 a,b,c,d,e,f,g,h;
\r
36 static const int k[] = {
\r
37 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
\r
38 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
\r
39 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
\r
40 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
\r
41 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
\r
42 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
\r
43 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
\r
44 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
\r
45 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
\r
46 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
\r
47 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
\r
48 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
\r
49 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
\r
50 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
\r
51 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
\r
52 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
\r
57 for (t = 0; t < 16; t++)
\r
60 for (t = 16; t < 64; t++)
\r
61 w[t] = smallsigma1(w[t-2]) + w[t-7] + smallsigma0(w[t-15]) + w[t-16];
\r
63 a = s->h[0]; b = s->h[1]; c = s->h[2]; d = s->h[3];
\r
64 e = s->h[4]; f = s->h[5]; g = s->h[6]; h = s->h[7];
\r
66 for (t = 0; t < 64; t+=8) {
\r
69 #define ROUND(j,a,b,c,d,e,f,g,h) \
\r
70 t1 = h + bigsigma1(e) + Ch(e,f,g) + k[j] + w[j]; \
\r
71 t2 = bigsigma0(a) + Maj(a,b,c); \
\r
72 d = d + t1; h = t1 + t2;
\r
74 ROUND(t+0, a,b,c,d,e,f,g,h);
\r
75 ROUND(t+1, h,a,b,c,d,e,f,g);
\r
76 ROUND(t+2, g,h,a,b,c,d,e,f);
\r
77 ROUND(t+3, f,g,h,a,b,c,d,e);
\r
78 ROUND(t+4, e,f,g,h,a,b,c,d);
\r
79 ROUND(t+5, d,e,f,g,h,a,b,c);
\r
80 ROUND(t+6, c,d,e,f,g,h,a,b);
\r
81 ROUND(t+7, b,c,d,e,f,g,h,a);
\r
84 s->h[0] += a; s->h[1] += b; s->h[2] += c; s->h[3] += d;
\r
85 s->h[4] += e; s->h[5] += f; s->h[6] += g; s->h[7] += h;
\r
88 /* ----------------------------------------------------------------------
\r
89 * Outer SHA256 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 SHA256 algorithm.
\r
96 void SHA256_Init(SHA256_State *s) {
\r
97 SHA256_Core_Init(s);
\r
99 s->lenhi = s->lenlo = 0;
\r
102 void SHA256_Bytes(SHA256_State *s, const void *p, int len) {
\r
103 unsigned char *q = (unsigned char *)p;
\r
104 uint32 wordblock[16];
\r
109 * Update the length field.
\r
112 s->lenhi += (s->lenlo < lenw);
\r
114 if (s->blkused && s->blkused+len < BLKSIZE) {
\r
116 * Trivial case: just add to the block.
\r
118 memcpy(s->block + s->blkused, q, len);
\r
122 * We must complete and process at least one block.
\r
124 while (s->blkused + len >= BLKSIZE) {
\r
125 memcpy(s->block + s->blkused, q, BLKSIZE - s->blkused);
\r
126 q += BLKSIZE - s->blkused;
\r
127 len -= BLKSIZE - s->blkused;
\r
128 /* Now process the block. Gather bytes big-endian into words */
\r
129 for (i = 0; i < 16; 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
136 SHA256_Block(s, wordblock);
\r
139 memcpy(s->block, q, len);
\r
144 void SHA256_Final(SHA256_State *s, unsigned char *digest) {
\r
147 unsigned char c[64];
\r
148 uint32 lenhi, lenlo;
\r
150 if (s->blkused >= 56)
\r
151 pad = 56 + 64 - s->blkused;
\r
153 pad = 56 - s->blkused;
\r
155 lenhi = (s->lenhi << 3) | (s->lenlo >> (32-3));
\r
156 lenlo = (s->lenlo << 3);
\r
160 SHA256_Bytes(s, &c, pad);
\r
162 c[0] = (lenhi >> 24) & 0xFF;
\r
163 c[1] = (lenhi >> 16) & 0xFF;
\r
164 c[2] = (lenhi >> 8) & 0xFF;
\r
165 c[3] = (lenhi >> 0) & 0xFF;
\r
166 c[4] = (lenlo >> 24) & 0xFF;
\r
167 c[5] = (lenlo >> 16) & 0xFF;
\r
168 c[6] = (lenlo >> 8) & 0xFF;
\r
169 c[7] = (lenlo >> 0) & 0xFF;
\r
171 SHA256_Bytes(s, &c, 8);
\r
173 for (i = 0; i < 8; i++) {
\r
174 digest[i*4+0] = (s->h[i] >> 24) & 0xFF;
\r
175 digest[i*4+1] = (s->h[i] >> 16) & 0xFF;
\r
176 digest[i*4+2] = (s->h[i] >> 8) & 0xFF;
\r
177 digest[i*4+3] = (s->h[i] >> 0) & 0xFF;
\r
181 void SHA256_Simple(const void *p, int len, unsigned char *output) {
\r
185 SHA256_Bytes(&s, p, len);
\r
186 SHA256_Final(&s, output);
\r
190 * Thin abstraction for things where hashes are pluggable.
\r
193 static void *sha256_init(void)
\r
197 s = snew(SHA256_State);
\r
202 static void sha256_bytes(void *handle, void *p, int len)
\r
204 SHA256_State *s = handle;
\r
206 SHA256_Bytes(s, p, len);
\r
209 static void sha256_final(void *handle, unsigned char *output)
\r
211 SHA256_State *s = handle;
\r
213 SHA256_Final(s, output);
\r
217 const struct ssh_hash ssh_sha256 = {
\r
218 sha256_init, sha256_bytes, sha256_final, 32, "SHA-256"
\r
221 /* ----------------------------------------------------------------------
\r
222 * The above is the SHA-256 algorithm itself. Now we implement the
\r
223 * HMAC wrapper on it.
\r
226 static void *sha256_make_context(void)
\r
228 return snewn(3, SHA256_State);
\r
231 static void sha256_free_context(void *handle)
\r
236 static void sha256_key_internal(void *handle, unsigned char *key, int len)
\r
238 SHA256_State *keys = (SHA256_State *)handle;
\r
239 unsigned char foo[64];
\r
242 memset(foo, 0x36, 64);
\r
243 for (i = 0; i < len && i < 64; i++)
\r
245 SHA256_Init(&keys[0]);
\r
246 SHA256_Bytes(&keys[0], foo, 64);
\r
248 memset(foo, 0x5C, 64);
\r
249 for (i = 0; i < len && i < 64; i++)
\r
251 SHA256_Init(&keys[1]);
\r
252 SHA256_Bytes(&keys[1], foo, 64);
\r
254 smemclr(foo, 64); /* burn the evidence */
\r
257 static void sha256_key(void *handle, unsigned char *key)
\r
259 sha256_key_internal(handle, key, 32);
\r
262 static void hmacsha256_start(void *handle)
\r
264 SHA256_State *keys = (SHA256_State *)handle;
\r
266 keys[2] = keys[0]; /* structure copy */
\r
269 static void hmacsha256_bytes(void *handle, unsigned char const *blk, int len)
\r
271 SHA256_State *keys = (SHA256_State *)handle;
\r
272 SHA256_Bytes(&keys[2], (void *)blk, len);
\r
275 static void hmacsha256_genresult(void *handle, unsigned char *hmac)
\r
277 SHA256_State *keys = (SHA256_State *)handle;
\r
279 unsigned char intermediate[32];
\r
281 s = keys[2]; /* structure copy */
\r
282 SHA256_Final(&s, intermediate);
\r
283 s = keys[1]; /* structure copy */
\r
284 SHA256_Bytes(&s, intermediate, 32);
\r
285 SHA256_Final(&s, hmac);
\r
288 static void sha256_do_hmac(void *handle, unsigned char *blk, int len,
\r
289 unsigned long seq, unsigned char *hmac)
\r
291 unsigned char seqbuf[4];
\r
293 PUT_32BIT_MSB_FIRST(seqbuf, seq);
\r
294 hmacsha256_start(handle);
\r
295 hmacsha256_bytes(handle, seqbuf, 4);
\r
296 hmacsha256_bytes(handle, blk, len);
\r
297 hmacsha256_genresult(handle, hmac);
\r
300 static void sha256_generate(void *handle, unsigned char *blk, int len,
\r
303 sha256_do_hmac(handle, blk, len, seq, blk + len);
\r
306 static int hmacsha256_verresult(void *handle, unsigned char const *hmac)
\r
308 unsigned char correct[32];
\r
309 hmacsha256_genresult(handle, correct);
\r
310 return !memcmp(correct, hmac, 32);
\r
313 static int sha256_verify(void *handle, unsigned char *blk, int len,
\r
316 unsigned char correct[32];
\r
317 sha256_do_hmac(handle, blk, len, seq, correct);
\r
318 return !memcmp(correct, blk + len, 32);
\r
321 const struct ssh_mac ssh_hmac_sha256 = {
\r
322 sha256_make_context, sha256_free_context, sha256_key,
\r
323 sha256_generate, sha256_verify,
\r
324 hmacsha256_start, hmacsha256_bytes,
\r
325 hmacsha256_genresult, hmacsha256_verresult,
\r
334 #include <stdlib.h>
\r
335 #include <assert.h>
\r
338 unsigned char digest[32];
\r
342 const char *teststring;
\r
343 unsigned char digest[32];
\r
346 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
\r
347 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
\r
348 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
\r
349 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad,
\r
351 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", {
\r
352 0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8,
\r
353 0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39,
\r
354 0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67,
\r
355 0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1,
\r
361 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++) {
\r
362 SHA256_Simple(tests[i].teststring,
\r
363 strlen(tests[i].teststring), digest);
\r
364 for (j = 0; j < 32; j++) {
\r
365 if (digest[j] != tests[i].digest[j]) {
\r
367 "\"%s\" digest byte %d should be 0x%02x, is 0x%02x\n",
\r
368 tests[i].teststring, j, tests[i].digest[j], digest[j]);
\r
374 printf("%d errors\n", errors);
\r