Fixed SHA-224 DER template.
[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, const unsigned char *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, const void *inbuf_arg, size_t inlen)
200 {
201   const unsigned char *inbuf = inbuf_arg;
202   SHA256_CONTEXT *hd = context;
203
204   if (hd->count == 64)
205     { /* flush the buffer */
206       transform (hd, hd->buf);
207       _gcry_burn_stack (74*4+32);
208       hd->count = 0;
209       hd->nblocks++;
210     }
211   if (!inbuf)
212     return;
213   if (hd->count)
214     {
215       for (; inlen && hd->count < 64; inlen--)
216         hd->buf[hd->count++] = *inbuf++;
217       sha256_write (hd, NULL, 0);
218       if (!inlen)
219         return;
220     }
221
222   while (inlen >= 64)
223     {
224       transform (hd, inbuf);
225       hd->count = 0;
226       hd->nblocks++;
227       inlen -= 64;
228       inbuf += 64;
229     }
230   _gcry_burn_stack (74*4+32);
231   for (; inlen && hd->count < 64; inlen--)
232     hd->buf[hd->count++] = *inbuf++;
233 }
234
235
236 /*
237    The routine finally terminates the computation and returns the
238    digest.  The handle is prepared for a new cycle, but adding bytes
239    to the handle will the destroy the returned buffer.  Returns: 32
240    bytes with the message the digest.  */
241 static void
242 sha256_final(void *context)
243 {
244   SHA256_CONTEXT *hd = context;
245   u32 t, msb, lsb;
246   byte *p;
247   
248   sha256_write (hd, NULL, 0); /* flush */;
249
250   t = hd->nblocks;
251   /* multiply by 64 to make a byte count */
252   lsb = t << 6;
253   msb = t >> 26;
254   /* add the count */
255   t = lsb;
256   if ((lsb += hd->count) < t)
257     msb++;
258   /* multiply by 8 to make a bit count */
259   t = lsb;
260   lsb <<= 3;
261   msb <<= 3;
262   msb |= t >> 29;
263
264   if (hd->count < 56)
265     { /* enough room */
266       hd->buf[hd->count++] = 0x80; /* pad */
267       while (hd->count < 56)
268         hd->buf[hd->count++] = 0;  /* pad */
269     }
270   else
271     { /* need one extra block */
272       hd->buf[hd->count++] = 0x80; /* pad character */
273       while (hd->count < 64)
274         hd->buf[hd->count++] = 0;
275       sha256_write (hd, NULL, 0);  /* flush */;
276       memset (hd->buf, 0, 56 ); /* fill next block with zeroes */
277     }
278   /* append the 64 bit count */
279   hd->buf[56] = msb >> 24;
280   hd->buf[57] = msb >> 16;
281   hd->buf[58] = msb >>  8;
282   hd->buf[59] = msb;
283   hd->buf[60] = lsb >> 24;
284   hd->buf[61] = lsb >> 16;
285   hd->buf[62] = lsb >>  8;
286   hd->buf[63] = lsb;
287   transform (hd, hd->buf);
288   _gcry_burn_stack (74*4+32);
289
290   p = hd->buf;
291 #ifdef WORDS_BIGENDIAN
292 #define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
293 #else /* little endian */
294 #define X(a) do { *p++ = hd->h##a >> 24; *p++ = hd->h##a >> 16;  \
295                   *p++ = hd->h##a >> 8; *p++ = hd->h##a; } while(0)
296 #endif
297   X(0);
298   X(1);
299   X(2);
300   X(3);
301   X(4);
302   X(5);
303   X(6);
304   X(7);
305 #undef X
306 }
307
308 static byte *
309 sha256_read (void *context)
310 {
311   SHA256_CONTEXT *hd = context;
312
313   return hd->buf;
314 }
315
316 static byte asn224[19] = /* Object ID is 2.16.840.1.101.3.4.2.4 */
317   { 0x30, 0x2D, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48,
318     0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04,
319     0x1C
320   };
321
322 static gcry_md_oid_spec_t oid_spec_sha224[] =
323   {
324     /* From RFC3874, Section 4 */
325     { "2.16.840.1.101.3.4.2.4" }, 
326     { NULL },
327   };
328
329 static byte asn256[19] = /* Object ID is  2.16.840.1.101.3.4.2.1 */
330   { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
331     0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
332     0x00, 0x04, 0x20 };
333
334 static gcry_md_oid_spec_t oid_spec_sha256[] =
335   {
336     /* According to the OpenPGG draft rfc2440-bis06 */
337     { "2.16.840.1.101.3.4.2.1" }, 
338     /* PKCS#1 sha256WithRSAEncryption */
339     { "1.2.840.113549.1.1.11" },
340
341     { NULL },
342   };
343
344 gcry_md_spec_t _gcry_digest_spec_sha224 =
345   {
346     "SHA224", asn224, DIM (asn224), oid_spec_sha224, 28,
347     sha224_init, sha256_write, sha256_final, sha256_read,
348     sizeof (SHA256_CONTEXT)
349   };
350
351 gcry_md_spec_t _gcry_digest_spec_sha256 =
352   {
353     "SHA256", asn256, DIM (asn256), oid_spec_sha256, 32,
354     sha256_init, sha256_write, sha256_final, sha256_read,
355     sizeof (SHA256_CONTEXT)
356   };