New configure option --disable-endian-check.
[libgcrypt.git] / cipher / sha256.c
1 /* sha256.c - SHA256 hash function
2  *      Copyright (C) 2003, 2006 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     SHA224: 23097d22 3405d822 8642a477 bda255b3 2aadbce4 bda0b3f7 e36c9da7
26     SHA256: ba7816bf 8f01cfea 414140de 5dae2223 b00361a3 96177a9c b410ff61 f20015ad
27
28     "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
29     SHA224: 75388b16 512776cc 5dba5da1 fd890150 b0c6455c b4f58b19 52522525
30     SHA256: 248d6a61 d20638b8 e5c02693 0c3e6039 a33ce459 64ff2167 f6ecedd4 19db06c1
31  
32     "a" one million times
33     SHA224: 20794655 980c91d8 bbb4c1ea 97618a4b f03f4258 1948b2ee 4ee7ad67
34     SHA256: cdc76e5c 9914fb92 81a1c7e2 84d73e67 f1809a48 a497200e 046d39cc c7112cd0
35
36  */
37
38
39 #include <config.h>
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
43
44 #include "g10lib.h"
45 #include "memory.h"
46 #include "bithelp.h"
47 #include "cipher.h"
48
49 typedef struct {
50   u32  h0,h1,h2,h3,h4,h5,h6,h7;
51   u32  nblocks;
52   byte buf[64];
53   int  count;
54 } SHA256_CONTEXT;
55
56
57 static void
58 sha256_init (void *context)
59 {
60   SHA256_CONTEXT *hd = context;
61
62   hd->h0 = 0x6a09e667;
63   hd->h1 = 0xbb67ae85;
64   hd->h2 = 0x3c6ef372;
65   hd->h3 = 0xa54ff53a;
66   hd->h4 = 0x510e527f;
67   hd->h5 = 0x9b05688c;
68   hd->h6 = 0x1f83d9ab;
69   hd->h7 = 0x5be0cd19;
70
71   hd->nblocks = 0;
72   hd->count = 0;
73 }
74
75
76 static void
77 sha224_init (void *context)
78 {
79   SHA256_CONTEXT *hd = context;
80
81   hd->h0 = 0xc1059ed8;
82   hd->h1 = 0x367cd507;
83   hd->h2 = 0x3070dd17;
84   hd->h3 = 0xf70e5939;
85   hd->h4 = 0xffc00b31;
86   hd->h5 = 0x68581511;
87   hd->h6 = 0x64f98fa7;
88   hd->h7 = 0xbefa4fa4;
89
90   hd->nblocks = 0;
91   hd->count = 0;
92 }
93
94
95 /*
96   Transform the message X which consists of 16 32-bit-words. See FIPS
97   180-2 for details.  */
98 #define Cho(x,y,z) (z ^ (x & (y ^ z)))      /* (4.2) same as SHA-1's F1 */
99 #define Maj(x,y,z) ((x & y) | (z & (x|y)))  /* (4.3) same as SHA-1's F3 */
100 #define Sum0(x) (ror ((x), 2) ^ ror ((x), 13) ^ ror ((x), 22))  /* (4.4) */
101 #define Sum1(x) (ror ((x), 6) ^ ror ((x), 11) ^ ror ((x), 25))  /* (4.5) */
102 #define S0(x) (ror ((x), 7) ^ ror ((x), 18) ^ ((x) >> 3))       /* (4.6) */
103 #define S1(x) (ror ((x), 17) ^ ror ((x), 19) ^ ((x) >> 10))     /* (4.7) */
104 #define R(a,b,c,d,e,f,g,h,k,w) do                                 \
105           {                                                       \
106             t1 = (h) + Sum1((e)) + Cho((e),(f),(g)) + (k) + (w);  \
107             t2 = Sum0((a)) + Maj((a),(b),(c));                    \
108             h = g;                                                \
109             g = f;                                                \
110             f = e;                                                \
111             e = d + t1;                                           \
112             d = c;                                                \
113             c = b;                                                \
114             b = a;                                                \
115             a = t1 + t2;                                          \
116           } while (0)
117  
118 static void
119 transform (SHA256_CONTEXT *hd, byte *data)
120 {
121   static const u32 K[64] = {
122     0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
123     0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
124     0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
125     0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 
126     0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
127     0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
128     0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
129     0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
130     0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
131     0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
132     0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
133     0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
134     0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
135     0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
136     0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
137     0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
138   };
139
140   u32 a,b,c,d,e,f,g,h,t1,t2;
141   u32 x[16];
142   u32 w[64];
143   int i;
144   
145   a = hd->h0;
146   b = hd->h1;
147   c = hd->h2;
148   d = hd->h3;
149   e = hd->h4;
150   f = hd->h5;
151   g = hd->h6;
152   h = hd->h7;
153   
154 #ifdef WORDS_BIGENDIAN
155   memcpy (x, data, 64);
156 #else
157   { 
158     byte *p2;
159   
160     for (i=0, p2=(byte*)x; i < 16; i++, p2 += 4 ) 
161       {
162         p2[3] = *data++;
163         p2[2] = *data++;
164         p2[1] = *data++;
165         p2[0] = *data++;
166       }
167   }
168 #endif
169
170   for (i=0; i < 16; i++)
171     w[i] = x[i];
172   for (; i < 64; i++)
173     w[i] = S1(w[i-2]) + w[i-7] + S0(w[i-15]) + w[i-16];
174
175   for (i=0; i < 64; i++)
176     R(a,b,c,d,e,f,g,h,K[i],w[i]);
177
178   hd->h0 += a;
179   hd->h1 += b;
180   hd->h2 += c;
181   hd->h3 += d;
182   hd->h4 += e;
183   hd->h5 += f;
184   hd->h6 += g;
185   hd->h7 += h;
186 }
187 #undef Cho
188 #undef Maj
189 #undef Sum0
190 #undef Sum1
191 #undef S0
192 #undef S1
193 #undef R
194
195
196 /* Update the message digest with the contents of INBUF with length
197   INLEN.  */
198 static void
199 sha256_write (void *context, byte *inbuf, size_t inlen)
200 {
201   SHA256_CONTEXT *hd = context;
202
203   if (hd->count == 64)
204     { /* flush the buffer */
205       transform (hd, hd->buf);
206       _gcry_burn_stack (74*4+32);
207       hd->count = 0;
208       hd->nblocks++;
209     }
210   if (!inbuf)
211     return;
212   if (hd->count)
213     {
214       for (; inlen && hd->count < 64; inlen--)
215         hd->buf[hd->count++] = *inbuf++;
216       sha256_write (hd, NULL, 0);
217       if (!inlen)
218         return;
219     }
220
221   while (inlen >= 64)
222     {
223       transform (hd, inbuf);
224       hd->count = 0;
225       hd->nblocks++;
226       inlen -= 64;
227       inbuf += 64;
228     }
229   _gcry_burn_stack (74*4+32);
230   for (; inlen && hd->count < 64; inlen--)
231     hd->buf[hd->count++] = *inbuf++;
232 }
233
234
235 /*
236    The routine finally terminates the computation and returns the
237    digest.  The handle is prepared for a new cycle, but adding bytes
238    to the handle will the destroy the returned buffer.  Returns: 32
239    bytes with the message the digest.  */
240 static void
241 sha256_final(void *context)
242 {
243   SHA256_CONTEXT *hd = context;
244   u32 t, msb, lsb;
245   byte *p;
246   
247   sha256_write (hd, NULL, 0); /* flush */;
248
249   t = hd->nblocks;
250   /* multiply by 64 to make a byte count */
251   lsb = t << 6;
252   msb = t >> 26;
253   /* add the count */
254   t = lsb;
255   if ((lsb += hd->count) < t)
256     msb++;
257   /* multiply by 8 to make a bit count */
258   t = lsb;
259   lsb <<= 3;
260   msb <<= 3;
261   msb |= t >> 29;
262
263   if (hd->count < 56)
264     { /* enough room */
265       hd->buf[hd->count++] = 0x80; /* pad */
266       while (hd->count < 56)
267         hd->buf[hd->count++] = 0;  /* pad */
268     }
269   else
270     { /* need one extra block */
271       hd->buf[hd->count++] = 0x80; /* pad character */
272       while (hd->count < 64)
273         hd->buf[hd->count++] = 0;
274       sha256_write (hd, NULL, 0);  /* flush */;
275       memset (hd->buf, 0, 56 ); /* fill next block with zeroes */
276     }
277   /* append the 64 bit count */
278   hd->buf[56] = msb >> 24;
279   hd->buf[57] = msb >> 16;
280   hd->buf[58] = msb >>  8;
281   hd->buf[59] = msb;
282   hd->buf[60] = lsb >> 24;
283   hd->buf[61] = lsb >> 16;
284   hd->buf[62] = lsb >>  8;
285   hd->buf[63] = lsb;
286   transform (hd, hd->buf);
287   _gcry_burn_stack (74*4+32);
288
289   p = hd->buf;
290 #ifdef WORDS_BIGENDIAN
291 #define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
292 #else /* little endian */
293 #define X(a) do { *p++ = hd->h##a >> 24; *p++ = hd->h##a >> 16;  \
294                   *p++ = hd->h##a >> 8; *p++ = hd->h##a; } while(0)
295 #endif
296   X(0);
297   X(1);
298   X(2);
299   X(3);
300   X(4);
301   X(5);
302   X(6);
303   X(7);
304 #undef X
305 }
306
307 static byte *
308 sha256_read (void *context)
309 {
310   SHA256_CONTEXT *hd = context;
311
312   return hd->buf;
313 }
314
315 static byte asn224[19] = /* Object ID is 2.16.840.1.101.3.4.2.4 */
316   { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48,
317     0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04,
318     0x20
319   };
320
321 static gcry_md_oid_spec_t oid_spec_sha224[] =
322   {
323     /* From RFC3874, Section 4 */
324     { "2.16.840.1.101.3.4.2.4" }, 
325     { NULL },
326   };
327
328 static byte asn256[19] = /* Object ID is  2.16.840.1.101.3.4.2.1 */
329   { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
330     0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
331     0x00, 0x04, 0x20 };
332
333 static gcry_md_oid_spec_t oid_spec_sha256[] =
334   {
335     /* According to the OpenPGG draft rfc2440-bis06 */
336     { "2.16.840.1.101.3.4.2.1" }, 
337     /* PKCS#1 sha256WithRSAEncryption */
338     { "1.2.840.113549.1.1.11" },
339
340     { NULL },
341   };
342
343 gcry_md_spec_t _gcry_digest_spec_sha224 =
344   {
345     "SHA224", asn224, DIM (asn224), oid_spec_sha224, 28,
346     sha224_init, sha256_write, sha256_final, sha256_read,
347     sizeof (SHA256_CONTEXT)
348   };
349
350 gcry_md_spec_t _gcry_digest_spec_sha256 =
351   {
352     "SHA256", asn256, DIM (asn256), oid_spec_sha256, 32,
353     sha256_init, sha256_write, sha256_final, sha256_read,
354     sizeof (SHA256_CONTEXT)
355   };