1 /*-
2  * Copyright (c) 2001-2003 Allan Saddi <allan@saddi.com>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY ALLAN SADDI AND HIS CONTRIBUTORS ``AS IS''
15  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL ALLAN SADDI OR HIS CONTRIBUTORS BE
18  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24  * POSSIBILITY OF SUCH DAMAGE.
25  *
26  * $Id: sha512.c 680 2003-07-25 21:58:07Z asaddi $
27  */
28 
29 /*
30  * Define WORDS_BIGENDIAN if compiling on a big-endian architecture.
31  *
32  * Define SHA512_TEST to test the implementation using the NIST's
33  * sample messages. The output should be:
34  *
35  *   ddaf35a193617aba cc417349ae204131 12e6fa4e89a97ea2 0a9eeee64b55d39a
36  *   2192992a274fc1a8 36ba3c23a3feebbd 454d4423643ce80e 2a9ac94fa54ca49f
37  *   8e959b75dae313da 8cf4f72814fc143f 8f7779c6eb9f7fa1 7299aeadb6889018
38  *   501d289e4900f7e4 331b99dec4b5433a c7d329eeb6dd2654 5e96e55b874be909
39  *   e718483d0ce76964 4e2e42c7bc15b463 8e1f98b13b204428 5632a803afa973eb
40  *   de0ff244877ea60a 4cb0432ce577c31b eb009c5c2c49aa2e 4eadb217ad8cc09b
41  */
42 
43 #ifdef HAVE_CONFIG_H
44 #include <config.h>
45 #endif /* HAVE_CONFIG_H */
46 
47 #if HAVE_INTTYPES_H
48 # include <inttypes.h>
49 #else
50 # if HAVE_STDINT_H
51 #  include <stdint.h>
52 # endif
53 #endif
54 
55 #include <string.h>
56 
57 #include "sha512.h"
58 
59 #ifndef lint
60 static const char rcsid[] =
61 	"$Id: sha512.c 680 2003-07-25 21:58:07Z asaddi $";
62 #endif /* !lint */
63 
64 #define ROTL(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
65 #define ROTR(x, n) (((x) >> (n)) | ((x) << (32 - (n))))
66 #define ROTL64(x, n) (((x) << (n)) | ((x) >> (64 - (n))))
67 #define ROTR64(x, n) (((x) >> (n)) | ((x) << (64 - (n))))
68 
69 #define Ch(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
70 #define Maj(x, y, z) (((x) & ((y) | (z))) | ((y) & (z)))
71 #define SIGMA0(x) (ROTR64((x), 28) ^ ROTR64((x), 34) ^ ROTR64((x), 39))
72 #define SIGMA1(x) (ROTR64((x), 14) ^ ROTR64((x), 18) ^ ROTR64((x), 41))
73 #define sigma0(x) (ROTR64((x), 1) ^ ROTR64((x), 8) ^ ((x) >> 7))
74 #define sigma1(x) (ROTR64((x), 19) ^ ROTR64((x), 61) ^ ((x) >> 6))
75 
76 #define DO_ROUND() { \
77   t1 = h + SIGMA1(e) + Ch(e, f, g) + *(Kp++) + *(W++); \
78   t2 = SIGMA0(a) + Maj(a, b, c); \
79   h = g; \
80   g = f; \
81   f = e; \
82   e = d + t1; \
83   d = c; \
84   c = b; \
85   b = a; \
86   a = t1 + t2; \
87 }
88 
89 static const uint64_t K[80] = {
90   0x428a2f98d728ae22LL, 0x7137449123ef65cdLL,
91   0xb5c0fbcfec4d3b2fLL, 0xe9b5dba58189dbbcLL,
92   0x3956c25bf348b538LL, 0x59f111f1b605d019LL,
93   0x923f82a4af194f9bLL, 0xab1c5ed5da6d8118LL,
94   0xd807aa98a3030242LL, 0x12835b0145706fbeLL,
95   0x243185be4ee4b28cLL, 0x550c7dc3d5ffb4e2LL,
96   0x72be5d74f27b896fLL, 0x80deb1fe3b1696b1LL,
97   0x9bdc06a725c71235LL, 0xc19bf174cf692694LL,
98   0xe49b69c19ef14ad2LL, 0xefbe4786384f25e3LL,
99   0x0fc19dc68b8cd5b5LL, 0x240ca1cc77ac9c65LL,
100   0x2de92c6f592b0275LL, 0x4a7484aa6ea6e483LL,
101   0x5cb0a9dcbd41fbd4LL, 0x76f988da831153b5LL,
102   0x983e5152ee66dfabLL, 0xa831c66d2db43210LL,
103   0xb00327c898fb213fLL, 0xbf597fc7beef0ee4LL,
104   0xc6e00bf33da88fc2LL, 0xd5a79147930aa725LL,
105   0x06ca6351e003826fLL, 0x142929670a0e6e70LL,
106   0x27b70a8546d22ffcLL, 0x2e1b21385c26c926LL,
107   0x4d2c6dfc5ac42aedLL, 0x53380d139d95b3dfLL,
108   0x650a73548baf63deLL, 0x766a0abb3c77b2a8LL,
109   0x81c2c92e47edaee6LL, 0x92722c851482353bLL,
110   0xa2bfe8a14cf10364LL, 0xa81a664bbc423001LL,
111   0xc24b8b70d0f89791LL, 0xc76c51a30654be30LL,
112   0xd192e819d6ef5218LL, 0xd69906245565a910LL,
113   0xf40e35855771202aLL, 0x106aa07032bbd1b8LL,
114   0x19a4c116b8d2d0c8LL, 0x1e376c085141ab53LL,
115   0x2748774cdf8eeb99LL, 0x34b0bcb5e19b48a8LL,
116   0x391c0cb3c5c95a63LL, 0x4ed8aa4ae3418acbLL,
117   0x5b9cca4f7763e373LL, 0x682e6ff3d6b2b8a3LL,
118   0x748f82ee5defb2fcLL, 0x78a5636f43172f60LL,
119   0x84c87814a1f0ab72LL, 0x8cc702081a6439ecLL,
120   0x90befffa23631e28LL, 0xa4506cebde82bde9LL,
121   0xbef9a3f7b2c67915LL, 0xc67178f2e372532bLL,
122   0xca273eceea26619cLL, 0xd186b8c721c0c207LL,
123   0xeada7dd6cde0eb1eLL, 0xf57d4f7fee6ed178LL,
124   0x06f067aa72176fbaLL, 0x0a637dc5a2c898a6LL,
125   0x113f9804bef90daeLL, 0x1b710b35131c471bLL,
126   0x28db77f523047d84LL, 0x32caab7b40c72493LL,
127   0x3c9ebe0a15c9bebcLL, 0x431d67c49c100d4cLL,
128   0x4cc5d4becb3e42b6LL, 0x597f299cfc657e2aLL,
129   0x5fcb6fab3ad6faecLL, 0x6c44198c4a475817LL
130 };
131 
132 #ifndef RUNTIME_ENDIAN
133 
134 #ifdef WORDS_BIGENDIAN
135 
136 #define BYTESWAP(x) (x)
137 #define BYTESWAP64(x) (x)
138 
139 #else /* WORDS_BIGENDIAN */
140 
141 #define BYTESWAP(x) ((ROTR((x), 8) & 0xff00ff00L) | \
142 		     (ROTL((x), 8) & 0x00ff00ffL))
143 #define BYTESWAP64(x) _byteswap64(x)
144 
_byteswap64(uint64_t x)145 static inline uint64_t _byteswap64(uint64_t x)
146 {
147   uint32_t a = x >> 32;
148   uint32_t b = (uint32_t) x;
149   return ((uint64_t) BYTESWAP(b) << 32) | (uint64_t) BYTESWAP(a);
150 }
151 
152 #endif /* WORDS_BIGENDIAN */
153 
154 #else /* !RUNTIME_ENDIAN */
155 
156 #define BYTESWAP(x) _byteswap(sc->littleEndian, x)
157 #define BYTESWAP64(x) _byteswap64(sc->littleEndian, x)
158 
159 #define _BYTESWAP(x) ((ROTR((x), 8) & 0xff00ff00L) | \
160 		      (ROTL((x), 8) & 0x00ff00ffL))
161 #define _BYTESWAP64(x) __byteswap64(x)
162 
__byteswap64(uint64_t x)163 static inline uint64_t __byteswap64(uint64_t x)
164 {
165   uint32_t a = x >> 32;
166   uint32_t b = (uint32_t) x;
167   return ((uint64_t) _BYTESWAP(b) << 32) | (uint64_t) _BYTESWAP(a);
168 }
169 
_byteswap(int littleEndian,uint32_t x)170 static inline uint32_t _byteswap(int littleEndian, uint32_t x)
171 {
172   if (!littleEndian)
173     return x;
174   else
175     return _BYTESWAP(x);
176 }
177 
_byteswap64(int littleEndian,uint64_t x)178 static inline uint64_t _byteswap64(int littleEndian, uint64_t x)
179 {
180   if (!littleEndian)
181     return x;
182   else
183     return _BYTESWAP64(x);
184 }
185 
setEndian(int * littleEndianp)186 static inline void setEndian(int *littleEndianp)
187 {
188   union {
189     uint32_t w;
190     uint8_t b[4];
191   } endian;
192 
193   endian.w = 1L;
194   *littleEndianp = endian.b[0] != 0;
195 }
196 
197 #endif /* !RUNTIME_ENDIAN */
198 
199 static const uint8_t padding[128] = {
200   0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
201   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
202   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
203   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
204   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
205   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
206   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
207   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
208   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
209   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
210   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
211   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
212   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
213   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
214   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
215   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
216 };
217 
218 void
SHA512Init(SHA512Context * sc)219 SHA512Init (SHA512Context *sc)
220 {
221 #ifdef RUNTIME_ENDIAN
222   setEndian (&sc->littleEndian);
223 #endif /* RUNTIME_ENDIAN */
224 
225   sc->totalLength[0] = 0LL;
226   sc->totalLength[1] = 0LL;
227   sc->hash[0] = 0x6a09e667f3bcc908LL;
228   sc->hash[1] = 0xbb67ae8584caa73bLL;
229   sc->hash[2] = 0x3c6ef372fe94f82bLL;
230   sc->hash[3] = 0xa54ff53a5f1d36f1LL;
231   sc->hash[4] = 0x510e527fade682d1LL;
232   sc->hash[5] = 0x9b05688c2b3e6c1fLL;
233   sc->hash[6] = 0x1f83d9abfb41bd6bLL;
234   sc->hash[7] = 0x5be0cd19137e2179LL;
235   sc->bufferLength = 0L;
236 }
237 
238 static void
burnStack(int size)239 burnStack (int size)
240 {
241   char buf[128];
242 
243   memset (buf, 0, sizeof (buf));
244   size -= sizeof (buf);
245   if (size > 0)
246     burnStack (size);
247 }
248 
249 static void
SHA512Guts(SHA512Context * sc,const uint64_t * cbuf)250 SHA512Guts (SHA512Context *sc, const uint64_t *cbuf)
251 {
252   uint64_t buf[80];
253   uint64_t *W, *W2, *W7, *W15, *W16;
254   uint64_t a, b, c, d, e, f, g, h;
255   uint64_t t1, t2;
256   const uint64_t *Kp;
257   int i;
258 
259   W = buf;
260 
261   for (i = 15; i >= 0; i--) {
262     *(W++) = BYTESWAP64(*cbuf);
263     cbuf++;
264   }
265 
266   W16 = &buf[0];
267   W15 = &buf[1];
268   W7 = &buf[9];
269   W2 = &buf[14];
270 
271   for (i = 63; i >= 0; i--) {
272     *(W++) = sigma1(*W2) + *(W7++) + sigma0(*W15) + *(W16++);
273     W2++;
274     W15++;
275   }
276 
277   a = sc->hash[0];
278   b = sc->hash[1];
279   c = sc->hash[2];
280   d = sc->hash[3];
281   e = sc->hash[4];
282   f = sc->hash[5];
283   g = sc->hash[6];
284   h = sc->hash[7];
285 
286   Kp = K;
287   W = buf;
288 
289   for (i = 79; i >= 0; i--)
290     DO_ROUND();
291 
292   sc->hash[0] += a;
293   sc->hash[1] += b;
294   sc->hash[2] += c;
295   sc->hash[3] += d;
296   sc->hash[4] += e;
297   sc->hash[5] += f;
298   sc->hash[6] += g;
299   sc->hash[7] += h;
300 }
301 
302 void
SHA512Update(SHA512Context * sc,const void * vdata,uint32_t len)303 SHA512Update (SHA512Context *sc, const void *vdata, uint32_t len)
304 {
305   const uint8_t *data = vdata;
306   uint32_t bufferBytesLeft;
307   uint32_t bytesToCopy;
308   uint64_t carryCheck;
309   int needBurn = 0;
310 
311 #ifdef SHA512_FAST_COPY
312   if (sc->bufferLength) {
313     bufferBytesLeft = 128L - sc->bufferLength;
314 
315     bytesToCopy = bufferBytesLeft;
316     if (bytesToCopy > len)
317       bytesToCopy = len;
318 
319     memcpy (&sc->buffer.bytes[sc->bufferLength], data, bytesToCopy);
320 
321     carryCheck = sc->totalLength[1];
322     sc->totalLength[1] += bytesToCopy * 8L;
323     if (sc->totalLength[1] < carryCheck)
324       sc->totalLength[0]++;
325 
326     sc->bufferLength += bytesToCopy;
327     data += bytesToCopy;
328     len -= bytesToCopy;
329 
330     if (sc->bufferLength == 128L) {
331       SHA512Guts (sc, sc->buffer.words);
332       needBurn = 1;
333       sc->bufferLength = 0L;
334     }
335   }
336 
337   while (len > 127) {
338     carryCheck = sc->totalLength[1];
339     sc->totalLength[1] += 1024L;
340     if (sc->totalLength[1] < carryCheck)
341       sc->totalLength[0]++;
342 
343     SHA512Guts (sc, data);
344     needBurn = 1;
345 
346     data += 128L;
347     len -= 128L;
348   }
349 
350   if (len) {
351     memcpy (&sc->buffer.bytes[sc->bufferLength], data, len);
352 
353     carryCheck = sc->totalLength[1];
354     sc->totalLength[1] += len * 8L;
355     if (sc->totalLength[1] < carryCheck)
356       sc->totalLength[0]++;
357 
358     sc->bufferLength += len;
359   }
360 #else /* SHA512_FAST_COPY */
361   while (len) {
362     bufferBytesLeft = 128L - sc->bufferLength;
363 
364     bytesToCopy = bufferBytesLeft;
365     if (bytesToCopy > len)
366       bytesToCopy = len;
367 
368     memcpy (&sc->buffer.bytes[sc->bufferLength], data, bytesToCopy);
369 
370     carryCheck = sc->totalLength[1];
371     sc->totalLength[1] += bytesToCopy * 8L;
372     if (sc->totalLength[1] < carryCheck)
373       sc->totalLength[0]++;
374 
375     sc->bufferLength += bytesToCopy;
376     data += bytesToCopy;
377     len -= bytesToCopy;
378 
379     if (sc->bufferLength == 128L) {
380       SHA512Guts (sc, sc->buffer.words);
381       needBurn = 1;
382       sc->bufferLength = 0L;
383     }
384   }
385 #endif /* SHA512_FAST_COPY */
386 
387   if (needBurn)
388     burnStack (sizeof (uint64_t[90]) + sizeof (uint64_t *[6]) + sizeof (int));
389 }
390 
391 void
SHA512Final(SHA512Context * sc,uint8_t hash[SHA512_HASH_SIZE])392 SHA512Final (SHA512Context *sc, uint8_t hash[SHA512_HASH_SIZE])
393 {
394   uint32_t bytesToPad;
395   uint64_t lengthPad[2];
396   int i;
397 
398   bytesToPad = 240L - sc->bufferLength;
399   if (bytesToPad > 128L)
400     bytesToPad -= 128L;
401 
402   lengthPad[0] = BYTESWAP64(sc->totalLength[0]);
403   lengthPad[1] = BYTESWAP64(sc->totalLength[1]);
404 
405   SHA512Update (sc, padding, bytesToPad);
406   SHA512Update (sc, lengthPad, 16L);
407 
408   if (hash) {
409     for (i = 0; i < SHA512_HASH_WORDS; i++) {
410 #ifdef SHA384_FAST_COPY
411       *((uint64_t *) hash) = BYTESWAP64(sc->hash[i]);
412 #else /* SHA384_FAST_COPY */
413       hash[0] = (uint8_t) (sc->hash[i] >> 56);
414       hash[1] = (uint8_t) (sc->hash[i] >> 48);
415       hash[2] = (uint8_t) (sc->hash[i] >> 40);
416       hash[3] = (uint8_t) (sc->hash[i] >> 32);
417       hash[4] = (uint8_t) (sc->hash[i] >> 24);
418       hash[5] = (uint8_t) (sc->hash[i] >> 16);
419       hash[6] = (uint8_t) (sc->hash[i] >> 8);
420       hash[7] = (uint8_t) sc->hash[i];
421 #endif /* SHA384_FAST_COPY */
422       hash += 8;
423     }
424   }
425 }
426 
427 #ifdef SHA512_TEST
428 
429 #include <stdio.h>
430 #include <stdlib.h>
431 #include <string.h>
432 
433 int
main(int argc,char * argv[])434 main (int argc, char *argv[])
435 {
436   SHA512Context foo;
437   uint8_t hash[SHA512_HASH_SIZE];
438   char buf[1000];
439   int i;
440 
441   SHA512Init (&foo);
442   SHA512Update (&foo, "abc", 3);
443   SHA512Final (&foo, hash);
444 
445   for (i = 0; i < SHA512_HASH_SIZE;) {
446     printf ("%02x", hash[i++]);
447     if (!(i % 8))
448       printf (" ");
449     if (!(i % 32))
450       printf ("\n");
451   }
452 
453   SHA512Init (&foo);
454   SHA512Update (&foo,
455 		"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
456 		"hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
457 		112);
458   SHA512Final (&foo, hash);
459 
460   for (i = 0; i < SHA512_HASH_SIZE;) {
461     printf ("%02x", hash[i++]);
462     if (!(i % 8))
463       printf (" ");
464     if (!(i % 32))
465       printf ("\n");
466   }
467 
468   SHA512Init (&foo);
469   memset (buf, 'a', sizeof (buf));
470   for (i = 0; i < 1000; i++)
471     SHA512Update (&foo, buf, sizeof (buf));
472   SHA512Final (&foo, hash);
473 
474   for (i = 0; i < SHA512_HASH_SIZE;) {
475     printf ("%02x", hash[i++]);
476     if (!(i % 8))
477       printf (" ");
478     if (!(i % 32))
479       printf ("\n");
480   }
481 
482   exit (0);
483 }
484 
485 #endif /* SHA512_TEST */
486