"Fossies" - the Fresh Open Source Software Archive

Member "duff-0.5.2/src/sha512.c" (10 Apr 2011, 13084 Bytes) of package /linux/privat/old/duff-0.5.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    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,v 1.1 2009/01/03 00:01:04 elmindreda Exp $
   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,v 1.1 2009/01/03 00:01:04 elmindreda Exp $";
   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 
  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 
  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 
  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 
  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 
  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
  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
  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
  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
  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
  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
  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 */