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
187 smemclr(&s, sizeof(s));
\r
191 * Thin abstraction for things where hashes are pluggable.
\r
194 static void *sha256_init(void)
\r
198 s = snew(SHA256_State);
\r
203 static void sha256_bytes(void *handle, void *p, int len)
\r
205 SHA256_State *s = handle;
\r
207 SHA256_Bytes(s, p, len);
\r
210 static void sha256_final(void *handle, unsigned char *output)
\r
212 SHA256_State *s = handle;
\r
214 SHA256_Final(s, output);
\r
215 smemclr(s, sizeof(*s));
\r
219 const struct ssh_hash ssh_sha256 = {
\r
220 sha256_init, sha256_bytes, sha256_final, 32, "SHA-256"
\r
223 /* ----------------------------------------------------------------------
\r
224 * The above is the SHA-256 algorithm itself. Now we implement the
\r
225 * HMAC wrapper on it.
\r
228 static void *sha256_make_context(void)
\r
230 return snewn(3, SHA256_State);
\r
233 static void sha256_free_context(void *handle)
\r
235 smemclr(handle, 3 * sizeof(SHA256_State));
\r
239 static void sha256_key_internal(void *handle, unsigned char *key, int len)
\r
241 SHA256_State *keys = (SHA256_State *)handle;
\r
242 unsigned char foo[64];
\r
245 memset(foo, 0x36, 64);
\r
246 for (i = 0; i < len && i < 64; i++)
\r
248 SHA256_Init(&keys[0]);
\r
249 SHA256_Bytes(&keys[0], foo, 64);
\r
251 memset(foo, 0x5C, 64);
\r
252 for (i = 0; i < len && i < 64; i++)
\r
254 SHA256_Init(&keys[1]);
\r
255 SHA256_Bytes(&keys[1], foo, 64);
\r
257 smemclr(foo, 64); /* burn the evidence */
\r
260 static void sha256_key(void *handle, unsigned char *key)
\r
262 sha256_key_internal(handle, key, 32);
\r
265 static void hmacsha256_start(void *handle)
\r
267 SHA256_State *keys = (SHA256_State *)handle;
\r
269 keys[2] = keys[0]; /* structure copy */
\r
272 static void hmacsha256_bytes(void *handle, unsigned char const *blk, int len)
\r
274 SHA256_State *keys = (SHA256_State *)handle;
\r
275 SHA256_Bytes(&keys[2], (void *)blk, len);
\r
278 static void hmacsha256_genresult(void *handle, unsigned char *hmac)
\r
280 SHA256_State *keys = (SHA256_State *)handle;
\r
282 unsigned char intermediate[32];
\r
284 s = keys[2]; /* structure copy */
\r
285 SHA256_Final(&s, intermediate);
\r
286 s = keys[1]; /* structure copy */
\r
287 SHA256_Bytes(&s, intermediate, 32);
\r
288 SHA256_Final(&s, hmac);
\r
291 static void sha256_do_hmac(void *handle, unsigned char *blk, int len,
\r
292 unsigned long seq, unsigned char *hmac)
\r
294 unsigned char seqbuf[4];
\r
296 PUT_32BIT_MSB_FIRST(seqbuf, seq);
\r
297 hmacsha256_start(handle);
\r
298 hmacsha256_bytes(handle, seqbuf, 4);
\r
299 hmacsha256_bytes(handle, blk, len);
\r
300 hmacsha256_genresult(handle, hmac);
\r
303 static void sha256_generate(void *handle, unsigned char *blk, int len,
\r
306 sha256_do_hmac(handle, blk, len, seq, blk + len);
\r
309 static int hmacsha256_verresult(void *handle, unsigned char const *hmac)
\r
311 unsigned char correct[32];
\r
312 hmacsha256_genresult(handle, correct);
\r
313 return smemeq(correct, hmac, 32);
\r
316 static int sha256_verify(void *handle, unsigned char *blk, int len,
\r
319 unsigned char correct[32];
\r
320 sha256_do_hmac(handle, blk, len, seq, correct);
\r
321 return smemeq(correct, blk + len, 32);
\r
324 const struct ssh_mac ssh_hmac_sha256 = {
\r
325 sha256_make_context, sha256_free_context, sha256_key,
\r
326 sha256_generate, sha256_verify,
\r
327 hmacsha256_start, hmacsha256_bytes,
\r
328 hmacsha256_genresult, hmacsha256_verresult,
\r
337 #include <stdlib.h>
\r
338 #include <assert.h>
\r
341 unsigned char digest[32];
\r
345 const char *teststring;
\r
346 unsigned char digest[32];
\r
349 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
\r
350 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
\r
351 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
\r
352 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad,
\r
354 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", {
\r
355 0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8,
\r
356 0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39,
\r
357 0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67,
\r
358 0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1,
\r
364 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++) {
\r
365 SHA256_Simple(tests[i].teststring,
\r
366 strlen(tests[i].teststring), digest);
\r
367 for (j = 0; j < 32; j++) {
\r
368 if (digest[j] != tests[i].digest[j]) {
\r
370 "\"%s\" digest byte %d should be 0x%02x, is 0x%02x\n",
\r
371 tests[i].teststring, j, tests[i].digest[j], digest[j]);
\r
377 printf("%d errors\n", errors);
\r