* basic.c (check_one_md): Kludge to check a one million "a".
[libgcrypt.git] / cipher / sha256.c
1 /* sha256.c - SHA256 hash function
2  *      Copyright (C) 2003 Free Software Foundation, Inc.
3  *
4  * This file is part of Libgcrypt.
5  *
6  * Libgcrypt is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as
8  * published by the Free Software Foundation; either version 2.1 of
9  * the License, or (at your option) any later version.
10  *
11  * Libgcrypt is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21
22 /*  Test vectors:
23     
24     "abc"
25     ba7816bf 8f01cfea 414140de 5dae2223 b00361a3 96177a9c b410ff61 f20015ad
26
27     "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
28     248d6a61 d20638b8 e5c02693 0c3e6039 a33ce459 64ff2167 f6ecedd4 19db06c1
29  
30     "a" one million times
31     cdc76e5c 9914fb92 81a1c7e2 84d73e67 f1809a48 a497200e 046d39cc c7112cd0
32
33  */
34
35
36 #include <config.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <assert.h>
41 #include "g10lib.h"
42 #include "memory.h"
43 #include "dynload.h"
44 #include "bithelp.h"
45
46
47 typedef struct {
48   u32  h0,h1,h2,h3,h4,h5,h6,h7;
49   u32  nblocks;
50   byte buf[64];
51   int  count;
52 } SHA256_CONTEXT;
53
54
55 static void
56 burn_stack (int bytes)
57 {
58     char buf[128];
59     
60     memset (buf, 0, sizeof buf);
61     bytes -= sizeof buf;
62     if (bytes > 0)
63         burn_stack (bytes);
64 }
65
66
67 static void
68 sha256_init (SHA256_CONTEXT *hd)
69 {
70   hd->h0 = 0x6a09e667;
71   hd->h1 = 0xbb67ae85;
72   hd->h2 = 0x3c6ef372;
73   hd->h3 = 0xa54ff53a;
74   hd->h4 = 0x510e527f;
75   hd->h5 = 0x9b05688c;
76   hd->h6 = 0x1f83d9ab;
77   hd->h7 = 0x5be0cd19;
78
79   hd->nblocks = 0;
80   hd->count = 0;
81 }
82
83
84 /*
85   Transform the message X which consists of 16 32-bit-words. See FIPS
86   180-2 for details.  */
87 #define Cho(x,y,z) (z ^ (x & (y ^ z)))      /* (4.2) same as SHA-1's F1 */
88 #define Maj(x,y,z) ((x & y) | (z & (x|y)))  /* (4.3) same as SHA-1's F3 */
89 #define Sum0(x) (ror ((x), 2) ^ ror ((x), 13) ^ ror ((x), 22))  /* (4.4) */
90 #define Sum1(x) (ror ((x), 6) ^ ror ((x), 11) ^ ror ((x), 25))  /* (4.5) */
91 #define S0(x) (ror ((x), 7) ^ ror ((x), 18) ^ ((x) >> 3))       /* (4.6) */
92 #define S1(x) (ror ((x), 17) ^ ror ((x), 19) ^ ((x) >> 10))     /* (4.7) */
93 #define R(a,b,c,d,e,f,g,h,k,w) do                                 \
94           {                                                       \
95             t1 = (h) + Sum1((e)) + Cho((e),(f),(g)) + (k) + (w);  \
96             t2 = Sum0((a)) + Maj((a),(b),(c));                    \
97             h = g;                                                \
98             g = f;                                                \
99             f = e;                                                \
100             e = d + t1;                                           \
101             d = c;                                                \
102             c = b;                                                \
103             b = a;                                                \
104             a = t1 + t2;                                          \
105           } while (0)
106  
107 static void
108 transform (SHA256_CONTEXT *hd, byte *data)
109 {
110   static const u32 K[64] = {
111     0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
112     0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
113     0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
114     0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 
115     0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
116     0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
117     0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
118     0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
119     0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
120     0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
121     0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
122     0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
123     0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
124     0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
125     0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
126     0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
127   };
128
129   u32 a,b,c,d,e,f,g,h,t1,t2;
130   u32 x[16];
131   u32 w[64];
132   int i;
133   
134   a = hd->h0;
135   b = hd->h1;
136   c = hd->h2;
137   d = hd->h3;
138   e = hd->h4;
139   f = hd->h5;
140   g = hd->h6;
141   h = hd->h7;
142   
143 #ifdef BIG_ENDIAN_HOST
144   memcpy (x, data, 64);
145 #else
146   { 
147     byte *p2;
148   
149     for (i=0, p2=(byte*)x; i < 16; i++, p2 += 4 ) 
150       {
151         p2[3] = *data++;
152         p2[2] = *data++;
153         p2[1] = *data++;
154         p2[0] = *data++;
155       }
156   }
157 #endif
158
159   for (i=0; i < 16; i++)
160     w[i] = x[i];
161   for (; i < 64; i++)
162     w[i] = S1(w[i-2]) + w[i-7] + S0(w[i-15]) + w[i-16];
163
164   for (i=0; i < 64; i++)
165     R(a,b,c,d,e,f,g,h,K[i],w[i]);
166
167   hd->h0 += a;
168   hd->h1 += b;
169   hd->h2 += c;
170   hd->h3 += d;
171   hd->h4 += e;
172   hd->h5 += f;
173   hd->h6 += g;
174   hd->h7 += h;
175 }
176 #undef Cho
177 #undef Maj
178 #undef Sum0
179 #undef Sum1
180 #undef S0
181 #undef S1
182 #undef R
183
184
185 /* Update the message digest with the contents of INBUF with length
186   INLEN.  */
187 static void
188 sha256_write (SHA256_CONTEXT *hd, byte *inbuf, size_t inlen)
189 {
190   if (hd->count == 64)
191     { /* flush the buffer */
192       transform (hd, hd->buf);
193       burn_stack (74*4+32);
194       hd->count = 0;
195       hd->nblocks++;
196     }
197   if (!inbuf)
198     return;
199   if (hd->count)
200     {
201       for (; inlen && hd->count < 64; inlen--)
202         hd->buf[hd->count++] = *inbuf++;
203       sha256_write (hd, NULL, 0);
204       if (!inlen)
205         return;
206     }
207
208   while (inlen >= 64)
209     {
210       transform (hd, inbuf);
211       hd->count = 0;
212       hd->nblocks++;
213       inlen -= 64;
214       inbuf += 64;
215     }
216   burn_stack (74*4+32);
217   for (; inlen && hd->count < 64; inlen--)
218     hd->buf[hd->count++] = *inbuf++;
219 }
220
221
222 /*
223    The routine finally terminates the computation and returns the
224    digest.  The handle is prepared for a new cycle, but adding bytes
225    to the handle will the destroy the returned buffer.  Returns: 32
226    bytes with the message the digest.  */
227 static void
228 sha256_final(SHA256_CONTEXT *hd)
229 {
230   u32 t, msb, lsb;
231   byte *p;
232   
233   sha256_write (hd, NULL, 0); /* flush */;
234
235   t = hd->nblocks;
236   /* multiply by 64 to make a byte count */
237   lsb = t << 6;
238   msb = t >> 26;
239   /* add the count */
240   t = lsb;
241   if ((lsb += hd->count) < t)
242     msb++;
243   /* multiply by 8 to make a bit count */
244   t = lsb;
245   lsb <<= 3;
246   msb <<= 3;
247   msb |= t >> 29;
248
249   if (hd->count < 56)
250     { /* enough room */
251       hd->buf[hd->count++] = 0x80; /* pad */
252       while (hd->count < 56)
253         hd->buf[hd->count++] = 0;  /* pad */
254     }
255   else
256     { /* need one extra block */
257       hd->buf[hd->count++] = 0x80; /* pad character */
258       while (hd->count < 64)
259         hd->buf[hd->count++] = 0;
260       sha256_write (hd, NULL, 0);  /* flush */;
261       memset (hd->buf, 0, 56 ); /* fill next block with zeroes */
262     }
263   /* append the 64 bit count */
264   hd->buf[56] = msb >> 24;
265   hd->buf[57] = msb >> 16;
266   hd->buf[58] = msb >>  8;
267   hd->buf[59] = msb;
268   hd->buf[60] = lsb >> 24;
269   hd->buf[61] = lsb >> 16;
270   hd->buf[62] = lsb >>  8;
271   hd->buf[63] = lsb;
272   transform (hd, hd->buf);
273   burn_stack (74*4+32);
274
275   p = hd->buf;
276 #ifdef BIG_ENDIAN_HOST
277 #define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
278 #else /* little endian */
279 #define X(a) do { *p++ = hd->h##a >> 24; *p++ = hd->h##a >> 16;  \
280                   *p++ = hd->h##a >> 8; *p++ = hd->h##a; } while(0)
281 #endif
282   X(0);
283   X(1);
284   X(2);
285   X(3);
286   X(4);
287   X(5);
288   X(6);
289   X(7);
290 #undef X
291 }
292
293 static byte *
294 sha256_read (SHA256_CONTEXT *hd)
295 {
296   return hd->buf;
297 }
298
299 /*
300    Return some information about the algorithm.  We need algo here to
301    distinguish different flavors of the algorithm.  Returns: A pointer
302    to string describing the algorithm or NULL if the ALGO is invalid.  */
303 static const char *
304 sha256_get_info (int algo, size_t *contextsize,
305                  byte **r_asnoid, int *r_asnlen, int *r_mdlen,
306                  void (**r_init)( void *c ),
307                  void (**r_write)( void *c, byte *buf, size_t nbytes ),
308                  void (**r_final)( void *c ),
309                  byte *(**r_read)( void *c )
310                  )
311 {
312   static byte asn[19] = /* Object ID is  2.16.840.1.101.3.4.2.1 */
313   { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
314     0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
315     0x00, 0x04, 0x20 };
316
317   if(algo != 8)
318     return NULL;
319
320   *contextsize = sizeof(SHA256_CONTEXT);
321   *r_asnoid = asn;
322   *r_asnlen = DIM(asn);
323   *r_mdlen = 32;
324   *(void  (**)(SHA256_CONTEXT *))r_init                   = sha256_init;
325   *(void  (**)(SHA256_CONTEXT *, byte*, size_t))r_write = sha256_write;
326   *(void  (**)(SHA256_CONTEXT *))r_final                  = sha256_final;
327   *(byte *(**)(SHA256_CONTEXT *))r_read                   = sha256_read;
328   
329   return "SHA256";
330 }
331
332
333
334 #ifndef IS_MODULE
335 static
336 #endif
337 const char * const gnupgext_version = "SHA256 ($Revision$)";
338
339 static struct {
340     int class;
341     int version;
342     int  value;
343     void (*func)(void);
344 } func_table[] = {
345     { 10, 1, 0, (void(*)(void))sha256_get_info },
346     { 11, 1, 8 },
347 };
348
349
350 #ifndef IS_MODULE
351 static
352 #endif
353 void *
354 gnupgext_enum_func( int what, int *sequence, int *class, int *vers )
355 {
356     void *ret;
357     int i = *sequence;
358
359     do {
360         if( i >= DIM(func_table) || i < 0 ) {
361             return NULL;
362         }
363         *class = func_table[i].class;
364         *vers  = func_table[i].version;
365         switch( *class ) {
366           case 11:
367           case 21:
368           case 31:
369             ret = &func_table[i].value;
370             break;
371           default:
372             ret = func_table[i].func;
373             break;
374         }
375         i++;
376     } while( what && what != *class );
377
378     *sequence = i;
379     return ret;
380 }
381
382
383
384
385 #ifndef IS_MODULE
386 void
387 _gcry_sha256_constructor(void)
388 {
389   _gcry_register_internal_cipher_extension (gnupgext_version,
390                                             gnupgext_enum_func );
391 }
392 #endif