2003-04-17 Moritz Schulte <moritz@g10code.com>
[libgcrypt.git] / cipher / sha512.c
1 /* sha512.c - SHA384 and SHA512 hash functions
2  *      Copyright (C) 2003 Free Software Foundation, Inc.
3  *
4  * Please see below for more legal information!
5  *
6  * This file is part of Libgcrypt.
7  *
8  * Libgcrypt is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser general Public License as
10  * published by the Free Software Foundation; either version 2.1 of
11  * the License, or (at your option) any later version.
12  *
13  * Libgcrypt is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
21  */
22
23
24 /*  Test vectors from FIPS-180-2:
25  *
26  *  "abc"
27  * 384:
28  *  CB00753F 45A35E8B B5A03D69 9AC65007 272C32AB 0EDED163
29  *  1A8B605A 43FF5BED 8086072B A1E7CC23 58BAECA1 34C825A7
30  * 512:
31  *  DDAF35A1 93617ABA CC417349 AE204131 12E6FA4E 89A97EA2 0A9EEEE6 4B55D39A
32  *  2192992A 274FC1A8 36BA3C23 A3FEEBBD 454D4423 643CE80E 2A9AC94F A54CA49F
33  *
34  *  "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"
35  * 384:
36  *  09330C33 F71147E8 3D192FC7 82CD1B47 53111B17 3B3B05D2
37  *  2FA08086 E3B0F712 FCC7C71A 557E2DB9 66C3E9FA 91746039
38  * 512:
39  *  8E959B75 DAE313DA 8CF4F728 14FC143F 8F7779C6 EB9F7FA1 7299AEAD B6889018
40  *  501D289E 4900F7E4 331B99DE C4B5433A C7D329EE B6DD2654 5E96E55B 874BE909
41  *
42  *  "a" x 1000000
43  * 384:
44  *  9D0E1809 716474CB 086E834E 310A4A1C ED149E9C 00F24852
45  *  7972CEC5 704C2A5B 07B8B3DC 38ECC4EB AE97DDD8 7F3D8985
46  * 512:
47  *  E718483D 0CE76964 4E2E42C7 BC15B463 8E1F98B1 3B204428 5632A803 AFA973EB
48  *  DE0FF244 877EA60A 4CB0432C E577C31B EB009C5C 2C49AA2E 4EADB217 AD8CC09B
49  */
50
51
52 #include <config.h>
53 #include <string.h>
54 #include "g10lib.h"
55 #include "bithelp.h"
56 #include "cipher.h"
57
58 typedef struct
59 {
60   u64 h0, h1, h2, h3, h4, h5, h6, h7;
61   u64 nblocks;
62   byte buf[128];
63   int count;
64 } SHA512_CONTEXT;
65
66 void
67 sha512_init (void *context)
68 {
69   SHA512_CONTEXT *hd = (SHA512_CONTEXT *) context;
70
71   hd->h0 = 0x6a09e667f3bcc908;
72   hd->h1 = 0xbb67ae8584caa73b;
73   hd->h2 = 0x3c6ef372fe94f82b;
74   hd->h3 = 0xa54ff53a5f1d36f1;
75   hd->h4 = 0x510e527fade682d1;
76   hd->h5 = 0x9b05688c2b3e6c1f;
77   hd->h6 = 0x1f83d9abfb41bd6b;
78   hd->h7 = 0x5be0cd19137e2179;
79
80   hd->nblocks = 0;
81   hd->count = 0;
82 }
83
84 void
85 sha384_init (void *context)
86 {
87   SHA512_CONTEXT *hd = (SHA512_CONTEXT *) context;
88
89   hd->h0 = 0xcbbb9d5dc1059ed8;
90   hd->h1 = 0x629a292a367cd507;
91   hd->h2 = 0x9159015a3070dd17;
92   hd->h3 = 0x152fecd8f70e5939;
93   hd->h4 = 0x67332667ffc00b31;
94   hd->h5 = 0x8eb44a8768581511;
95   hd->h6 = 0xdb0c2e0d64f98fa7;
96   hd->h7 = 0x47b5481dbefa4fa4;
97
98   hd->nblocks = 0;
99   hd->count = 0;
100 }
101
102
103 /****************
104  * Transform the message W which consists of 16 64-bit-words
105  */
106 static void
107 transform (SHA512_CONTEXT *hd, byte *data)
108 {
109   u64 a, b, c, d, e, f, g, h;
110   u64 w[80];
111   int t;
112   static const u64 k[] =
113     {
114       0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f,
115       0xe9b5dba58189dbbc, 0x3956c25bf348b538, 0x59f111f1b605d019,
116       0x923f82a4af194f9b, 0xab1c5ed5da6d8118, 0xd807aa98a3030242,
117       0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2,
118       0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235,
119       0xc19bf174cf692694, 0xe49b69c19ef14ad2, 0xefbe4786384f25e3,
120       0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65, 0x2de92c6f592b0275,
121       0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5,
122       0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f,
123       0xbf597fc7beef0ee4, 0xc6e00bf33da88fc2, 0xd5a79147930aa725,
124       0x06ca6351e003826f, 0x142929670a0e6e70, 0x27b70a8546d22ffc,
125       0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df,
126       0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6,
127       0x92722c851482353b, 0xa2bfe8a14cf10364, 0xa81a664bbc423001,
128       0xc24b8b70d0f89791, 0xc76c51a30654be30, 0xd192e819d6ef5218,
129       0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8,
130       0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99,
131       0x34b0bcb5e19b48a8, 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb,
132       0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3, 0x748f82ee5defb2fc,
133       0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec,
134       0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915,
135       0xc67178f2e372532b, 0xca273eceea26619c, 0xd186b8c721c0c207,
136       0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, 0x06f067aa72176fba,
137       0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b,
138       0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc,
139       0x431d67c49c100d4c, 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a,
140       0x5fcb6fab3ad6faec, 0x6c44198c4a475817
141     };
142
143   /* get values from the chaining vars */
144   a = hd->h0;
145   b = hd->h1;
146   c = hd->h2;
147   d = hd->h3;
148   e = hd->h4;
149   f = hd->h5;
150   g = hd->h6;
151   h = hd->h7;
152
153 #ifdef BIG_ENDIAN_HOST
154   memcpy (w, data, 128);
155 #else
156   {
157     int i;
158     byte *p2;
159
160     for (i = 0, p2 = (byte *) w; i < 16; i++, p2 += 8)
161       {
162         p2[7] = *data++;
163         p2[6] = *data++;
164         p2[5] = *data++;
165         p2[4] = *data++;
166         p2[3] = *data++;
167         p2[2] = *data++;
168         p2[1] = *data++;
169         p2[0] = *data++;
170       }
171   }
172 #endif
173
174 #define ROTR(x,n) (((x)>>(n)) | ((x)<<(64-(n))))
175 #define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z)))
176 #define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
177 #define Sum0(x) (ROTR((x),28) ^ ROTR((x),34) ^ ROTR((x),39))
178 #define Sum1(x) (ROTR((x),14) ^ ROTR((x),18) ^ ROTR((x),41))
179 #define S0(x) (ROTR((x),1) ^ ROTR((x),8) ^ ((x)>>7))
180 #define S1(x) (ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6))
181
182   for (t = 16; t < 80; t++)
183     w[t] = S1 (w[t - 2]) + w[t - 7] + S0 (w[t - 15]) + w[t - 16];
184
185   for (t = 0; t < 80; t++)
186     {
187       u64 t1, t2;
188
189       t1 = h + Sum1 (e) + Ch (e, f, g) + k[t] + w[t];
190       t2 = Sum0 (a) + Maj (a, b, c);
191       h = g;
192       g = f;
193       f = e;
194       e = d + t1;
195       d = c;
196       c = b;
197       b = a;
198       a = t1 + t2;
199
200       /* printf("t=%d a=%016llX b=%016llX c=%016llX d=%016llX e=%016llX f=%016llX g=%016llX h=%016llX\n",t,a,b,c,d,e,f,g,h); */
201     }
202
203   /* update chaining vars */
204   hd->h0 += a;
205   hd->h1 += b;
206   hd->h2 += c;
207   hd->h3 += d;
208   hd->h4 += e;
209   hd->h5 += f;
210   hd->h6 += g;
211   hd->h7 += h;
212 }
213
214
215 /* Update the message digest with the contents
216  * of INBUF with length INLEN.
217  */
218 static void
219 sha512_write (void *context, byte *inbuf, size_t inlen)
220 {
221   SHA512_CONTEXT *hd = (SHA512_CONTEXT *) context;
222
223   if (hd->count == 128)
224     {                           /* flush the buffer */
225       transform (hd, hd->buf);
226       _gcry_burn_stack (768);
227       hd->count = 0;
228       hd->nblocks++;
229     }
230   if (!inbuf)
231     return;
232   if (hd->count)
233     {
234       for (; inlen && hd->count < 128; inlen--)
235         hd->buf[hd->count++] = *inbuf++;
236       sha512_write (context, NULL, 0);
237       if (!inlen)
238         return;
239     }
240
241   while (inlen >= 128)
242     {
243       transform (hd, inbuf);
244       hd->count = 0;
245       hd->nblocks++;
246       inlen -= 128;
247       inbuf += 128;
248     }
249   _gcry_burn_stack (768);
250   for (; inlen && hd->count < 128; inlen--)
251     hd->buf[hd->count++] = *inbuf++;
252 }
253
254
255 /* The routine final terminates the computation and
256  * returns the digest.
257  * The handle is prepared for a new cycle, but adding bytes to the
258  * handle will the destroy the returned buffer.
259  * Returns: 64 bytes representing the digest.  When used for sha384,
260  * we take the leftmost 48 of those bytes.
261  */
262
263 static void
264 sha512_final (void *context)
265 {
266   SHA512_CONTEXT *hd = (SHA512_CONTEXT *) context;
267   u64 t, msb, lsb;
268   byte *p;
269
270   sha512_write (context, NULL, 0); /* flush */ ;
271
272   t = hd->nblocks;
273   /* multiply by 128 to make a byte count */
274   lsb = t << 7;
275   msb = t >> 57;
276   /* add the count */
277   t = lsb;
278   if ((lsb += hd->count) < t)
279     msb++;
280   /* multiply by 8 to make a bit count */
281   t = lsb;
282   lsb <<= 3;
283   msb <<= 3;
284   msb |= t >> 61;
285
286   if (hd->count < 112)
287     {                           /* enough room */
288       hd->buf[hd->count++] = 0x80;      /* pad */
289       while (hd->count < 112)
290         hd->buf[hd->count++] = 0;       /* pad */
291     }
292   else
293     {                           /* need one extra block */
294       hd->buf[hd->count++] = 0x80;      /* pad character */
295       while (hd->count < 128)
296         hd->buf[hd->count++] = 0;
297       sha512_write (context, NULL, 0); /* flush */ ;
298       memset (hd->buf, 0, 112); /* fill next block with zeroes */
299     }
300   /* append the 128 bit count */
301   hd->buf[112] = msb >> 56;
302   hd->buf[113] = msb >> 48;
303   hd->buf[114] = msb >> 40;
304   hd->buf[115] = msb >> 32;
305   hd->buf[116] = msb >> 24;
306   hd->buf[117] = msb >> 16;
307   hd->buf[118] = msb >> 8;
308   hd->buf[119] = msb;
309
310   hd->buf[120] = lsb >> 56;
311   hd->buf[121] = lsb >> 48;
312   hd->buf[122] = lsb >> 40;
313   hd->buf[123] = lsb >> 32;
314   hd->buf[124] = lsb >> 24;
315   hd->buf[125] = lsb >> 16;
316   hd->buf[126] = lsb >> 8;
317   hd->buf[127] = lsb;
318   transform (hd, hd->buf);
319   _gcry_burn_stack (768);
320
321   p = hd->buf;
322 #ifdef BIG_ENDIAN_HOST
323 #define X(a) do { *(u64*)p = hd->h##a ; p += 8; } while (0)
324 #else /* little endian */
325 #define X(a) do { *p++ = hd->h##a >> 56; *p++ = hd->h##a >> 48;       \
326                   *p++ = hd->h##a >> 40; *p++ = hd->h##a >> 32;       \
327                   *p++ = hd->h##a >> 24; *p++ = hd->h##a >> 16;       \
328                   *p++ = hd->h##a >> 8;  *p++ = hd->h##a; } while (0)
329 #endif
330   X (0);
331   X (1);
332   X (2);
333   X (3);
334   X (4);
335   X (5);
336   /* Note that these last two chunks are included even for SHA384.
337      We just ignore them. */
338   X (6);
339   X (7);
340 #undef X
341 }
342
343 static byte *
344 sha512_read (void *context)
345 {
346   SHA512_CONTEXT *hd = (SHA512_CONTEXT *) context;
347   return hd->buf;
348 }
349
350 static byte sha512_asn[] =      /* Object ID is 2.16.840.1.101.3.4.2.3 */
351 {
352   0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
353   0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05,
354   0x00, 0x04, 0x40
355 };
356
357 GcryDigestSpec digest_spec_sha512 = {
358   "SHA512", GCRY_MD_SHA512, sha512_asn, DIM (sha512_asn), 64,
359   sha512_init, sha512_write, sha512_final, sha512_read,
360   sizeof (SHA512_CONTEXT),
361 };
362
363 static byte sha384_asn[] =      /* Object ID is 2.16.840.1.101.3.4.2.2 */
364 {
365   0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
366   0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05,
367   0x00, 0x04, 0x30
368 };
369
370 GcryDigestSpec digest_spec_sha384 = {
371   "SHA384", GCRY_MD_SHA384, sha384_asn, DIM (sha384_asn), 48,
372   sha384_init, sha512_write, sha512_final, sha512_read,
373   sizeof (SHA512_CONTEXT),
374 };