Mostly indendation changes. Completed the Manifest.
[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 "bithelp.h"
44 #include "cipher.h"
45
46 typedef struct {
47   u32  h0,h1,h2,h3,h4,h5,h6,h7;
48   u32  nblocks;
49   byte buf[64];
50   int  count;
51 } SHA256_CONTEXT;
52
53
54 static void
55 sha256_init (void *context)
56 {
57   SHA256_CONTEXT *hd = context;
58
59   hd->h0 = 0x6a09e667;
60   hd->h1 = 0xbb67ae85;
61   hd->h2 = 0x3c6ef372;
62   hd->h3 = 0xa54ff53a;
63   hd->h4 = 0x510e527f;
64   hd->h5 = 0x9b05688c;
65   hd->h6 = 0x1f83d9ab;
66   hd->h7 = 0x5be0cd19;
67
68   hd->nblocks = 0;
69   hd->count = 0;
70 }
71
72
73 /*
74   Transform the message X which consists of 16 32-bit-words. See FIPS
75   180-2 for details.  */
76 #define Cho(x,y,z) (z ^ (x & (y ^ z)))      /* (4.2) same as SHA-1's F1 */
77 #define Maj(x,y,z) ((x & y) | (z & (x|y)))  /* (4.3) same as SHA-1's F3 */
78 #define Sum0(x) (ror ((x), 2) ^ ror ((x), 13) ^ ror ((x), 22))  /* (4.4) */
79 #define Sum1(x) (ror ((x), 6) ^ ror ((x), 11) ^ ror ((x), 25))  /* (4.5) */
80 #define S0(x) (ror ((x), 7) ^ ror ((x), 18) ^ ((x) >> 3))       /* (4.6) */
81 #define S1(x) (ror ((x), 17) ^ ror ((x), 19) ^ ((x) >> 10))     /* (4.7) */
82 #define R(a,b,c,d,e,f,g,h,k,w) do                                 \
83           {                                                       \
84             t1 = (h) + Sum1((e)) + Cho((e),(f),(g)) + (k) + (w);  \
85             t2 = Sum0((a)) + Maj((a),(b),(c));                    \
86             h = g;                                                \
87             g = f;                                                \
88             f = e;                                                \
89             e = d + t1;                                           \
90             d = c;                                                \
91             c = b;                                                \
92             b = a;                                                \
93             a = t1 + t2;                                          \
94           } while (0)
95  
96 static void
97 transform (SHA256_CONTEXT *hd, byte *data)
98 {
99   static const u32 K[64] = {
100     0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
101     0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
102     0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
103     0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 
104     0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
105     0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
106     0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
107     0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
108     0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
109     0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
110     0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
111     0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
112     0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
113     0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
114     0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
115     0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
116   };
117
118   u32 a,b,c,d,e,f,g,h,t1,t2;
119   u32 x[16];
120   u32 w[64];
121   int i;
122   
123   a = hd->h0;
124   b = hd->h1;
125   c = hd->h2;
126   d = hd->h3;
127   e = hd->h4;
128   f = hd->h5;
129   g = hd->h6;
130   h = hd->h7;
131   
132 #ifdef WORDS_BIGENDIAN
133   memcpy (x, data, 64);
134 #else
135   { 
136     byte *p2;
137   
138     for (i=0, p2=(byte*)x; i < 16; i++, p2 += 4 ) 
139       {
140         p2[3] = *data++;
141         p2[2] = *data++;
142         p2[1] = *data++;
143         p2[0] = *data++;
144       }
145   }
146 #endif
147
148   for (i=0; i < 16; i++)
149     w[i] = x[i];
150   for (; i < 64; i++)
151     w[i] = S1(w[i-2]) + w[i-7] + S0(w[i-15]) + w[i-16];
152
153   for (i=0; i < 64; i++)
154     R(a,b,c,d,e,f,g,h,K[i],w[i]);
155
156   hd->h0 += a;
157   hd->h1 += b;
158   hd->h2 += c;
159   hd->h3 += d;
160   hd->h4 += e;
161   hd->h5 += f;
162   hd->h6 += g;
163   hd->h7 += h;
164 }
165 #undef Cho
166 #undef Maj
167 #undef Sum0
168 #undef Sum1
169 #undef S0
170 #undef S1
171 #undef R
172
173
174 /* Update the message digest with the contents of INBUF with length
175   INLEN.  */
176 static void
177 sha256_write (void *context, byte *inbuf, size_t inlen)
178 {
179   SHA256_CONTEXT *hd = context;
180
181   if (hd->count == 64)
182     { /* flush the buffer */
183       transform (hd, hd->buf);
184       _gcry_burn_stack (74*4+32);
185       hd->count = 0;
186       hd->nblocks++;
187     }
188   if (!inbuf)
189     return;
190   if (hd->count)
191     {
192       for (; inlen && hd->count < 64; inlen--)
193         hd->buf[hd->count++] = *inbuf++;
194       sha256_write (hd, NULL, 0);
195       if (!inlen)
196         return;
197     }
198
199   while (inlen >= 64)
200     {
201       transform (hd, inbuf);
202       hd->count = 0;
203       hd->nblocks++;
204       inlen -= 64;
205       inbuf += 64;
206     }
207   _gcry_burn_stack (74*4+32);
208   for (; inlen && hd->count < 64; inlen--)
209     hd->buf[hd->count++] = *inbuf++;
210 }
211
212
213 /*
214    The routine finally terminates the computation and returns the
215    digest.  The handle is prepared for a new cycle, but adding bytes
216    to the handle will the destroy the returned buffer.  Returns: 32
217    bytes with the message the digest.  */
218 static void
219 sha256_final(void *context)
220 {
221   SHA256_CONTEXT *hd = context;
222   u32 t, msb, lsb;
223   byte *p;
224   
225   sha256_write (hd, NULL, 0); /* flush */;
226
227   t = hd->nblocks;
228   /* multiply by 64 to make a byte count */
229   lsb = t << 6;
230   msb = t >> 26;
231   /* add the count */
232   t = lsb;
233   if ((lsb += hd->count) < t)
234     msb++;
235   /* multiply by 8 to make a bit count */
236   t = lsb;
237   lsb <<= 3;
238   msb <<= 3;
239   msb |= t >> 29;
240
241   if (hd->count < 56)
242     { /* enough room */
243       hd->buf[hd->count++] = 0x80; /* pad */
244       while (hd->count < 56)
245         hd->buf[hd->count++] = 0;  /* pad */
246     }
247   else
248     { /* need one extra block */
249       hd->buf[hd->count++] = 0x80; /* pad character */
250       while (hd->count < 64)
251         hd->buf[hd->count++] = 0;
252       sha256_write (hd, NULL, 0);  /* flush */;
253       memset (hd->buf, 0, 56 ); /* fill next block with zeroes */
254     }
255   /* append the 64 bit count */
256   hd->buf[56] = msb >> 24;
257   hd->buf[57] = msb >> 16;
258   hd->buf[58] = msb >>  8;
259   hd->buf[59] = msb;
260   hd->buf[60] = lsb >> 24;
261   hd->buf[61] = lsb >> 16;
262   hd->buf[62] = lsb >>  8;
263   hd->buf[63] = lsb;
264   transform (hd, hd->buf);
265   _gcry_burn_stack (74*4+32);
266
267   p = hd->buf;
268 #ifdef WORDS_BIGENDIAN
269 #define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
270 #else /* little endian */
271 #define X(a) do { *p++ = hd->h##a >> 24; *p++ = hd->h##a >> 16;  \
272                   *p++ = hd->h##a >> 8; *p++ = hd->h##a; } while(0)
273 #endif
274   X(0);
275   X(1);
276   X(2);
277   X(3);
278   X(4);
279   X(5);
280   X(6);
281   X(7);
282 #undef X
283 }
284
285 static byte *
286 sha256_read (void *context)
287 {
288   SHA256_CONTEXT *hd = context;
289
290   return hd->buf;
291 }
292
293 static byte asn[19] = /* Object ID is  2.16.840.1.101.3.4.2.1 */
294   { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
295     0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
296     0x00, 0x04, 0x20 };
297
298 static gcry_md_oid_spec_t oid_spec_sha256[] =
299   {
300     /* According to the OpenPGG draft rfc2440-bis06 */
301     { "2.16.840.1.101.3.4.2.1" }, 
302     { NULL },
303   };
304
305 gcry_md_spec_t _gcry_digest_spec_sha256 =
306   {
307     "SHA256", asn, DIM (asn), oid_spec_sha256, 32,
308     sha256_init, sha256_write, sha256_final, sha256_read,
309     sizeof (SHA256_CONTEXT)
310   };