"Fossies" - the Fresh Open Source Software Archive

Member "duff-0.5.2/src/sha256.c" (10 Apr 2011, 12509 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: sha256.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 SHA256_TEST to test the implementation using the NIST's
   33  * sample messages. The output should be:
   34  *
   35  *   ba7816bf 8f01cfea 414140de 5dae2223 b00361a3 96177a9c b410ff61 f20015ad
   36  *   248d6a61 d20638b8 e5c02693 0c3e6039 a33ce459 64ff2167 f6ecedd4 19db06c1
   37  *   cdc76e5c 9914fb92 81a1c7e2 84d73e67 f1809a48 a497200e 046d39cc c7112cd0
   38  */
   39 
   40 #ifdef HAVE_CONFIG_H
   41 #include <config.h>
   42 #endif /* HAVE_CONFIG_H */
   43 
   44 #if HAVE_INTTYPES_H
   45 # include <inttypes.h>
   46 #else
   47 # if HAVE_STDINT_H
   48 #  include <stdint.h>
   49 # endif
   50 #endif
   51 
   52 #include <string.h>
   53 
   54 #include "sha256.h"
   55 
   56 #ifndef lint
   57 static const char rcsid[] =
   58     "$Id: sha256.c,v 1.1 2009/01/03 00:01:04 elmindreda Exp $";
   59 #endif /* !lint */
   60 
   61 #define ROTL(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
   62 #define ROTR(x, n) (((x) >> (n)) | ((x) << (32 - (n))))
   63 
   64 #define Ch(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
   65 #define Maj(x, y, z) (((x) & ((y) | (z))) | ((y) & (z)))
   66 #define SIGMA0(x) (ROTR((x), 2) ^ ROTR((x), 13) ^ ROTR((x), 22))
   67 #define SIGMA1(x) (ROTR((x), 6) ^ ROTR((x), 11) ^ ROTR((x), 25))
   68 #define sigma0(x) (ROTR((x), 7) ^ ROTR((x), 18) ^ ((x) >> 3))
   69 #define sigma1(x) (ROTR((x), 17) ^ ROTR((x), 19) ^ ((x) >> 10))
   70 
   71 #define DO_ROUND() { \
   72   t1 = h + SIGMA1(e) + Ch(e, f, g) + *(Kp++) + *(W++); \
   73   t2 = SIGMA0(a) + Maj(a, b, c); \
   74   h = g; \
   75   g = f; \
   76   f = e; \
   77   e = d + t1; \
   78   d = c; \
   79   c = b; \
   80   b = a; \
   81   a = t1 + t2; \
   82 }
   83 
   84 static const uint32_t K[64] = {
   85   0x428a2f98L, 0x71374491L, 0xb5c0fbcfL, 0xe9b5dba5L,
   86   0x3956c25bL, 0x59f111f1L, 0x923f82a4L, 0xab1c5ed5L,
   87   0xd807aa98L, 0x12835b01L, 0x243185beL, 0x550c7dc3L,
   88   0x72be5d74L, 0x80deb1feL, 0x9bdc06a7L, 0xc19bf174L,
   89   0xe49b69c1L, 0xefbe4786L, 0x0fc19dc6L, 0x240ca1ccL,
   90   0x2de92c6fL, 0x4a7484aaL, 0x5cb0a9dcL, 0x76f988daL,
   91   0x983e5152L, 0xa831c66dL, 0xb00327c8L, 0xbf597fc7L,
   92   0xc6e00bf3L, 0xd5a79147L, 0x06ca6351L, 0x14292967L,
   93   0x27b70a85L, 0x2e1b2138L, 0x4d2c6dfcL, 0x53380d13L,
   94   0x650a7354L, 0x766a0abbL, 0x81c2c92eL, 0x92722c85L,
   95   0xa2bfe8a1L, 0xa81a664bL, 0xc24b8b70L, 0xc76c51a3L,
   96   0xd192e819L, 0xd6990624L, 0xf40e3585L, 0x106aa070L,
   97   0x19a4c116L, 0x1e376c08L, 0x2748774cL, 0x34b0bcb5L,
   98   0x391c0cb3L, 0x4ed8aa4aL, 0x5b9cca4fL, 0x682e6ff3L,
   99   0x748f82eeL, 0x78a5636fL, 0x84c87814L, 0x8cc70208L,
  100   0x90befffaL, 0xa4506cebL, 0xbef9a3f7L, 0xc67178f2L
  101 };
  102 
  103 #ifndef RUNTIME_ENDIAN
  104 
  105 #ifdef WORDS_BIGENDIAN
  106 
  107 #define BYTESWAP(x) (x)
  108 #define BYTESWAP64(x) (x)
  109 
  110 #else /* WORDS_BIGENDIAN */
  111 
  112 #define BYTESWAP(x) ((ROTR((x), 8) & 0xff00ff00L) | \
  113              (ROTL((x), 8) & 0x00ff00ffL))
  114 #define BYTESWAP64(x) _byteswap64(x)
  115 
  116 static inline uint64_t _byteswap64(uint64_t x)
  117 {
  118   uint32_t a = x >> 32;
  119   uint32_t b = (uint32_t) x;
  120   return ((uint64_t) BYTESWAP(b) << 32) | (uint64_t) BYTESWAP(a);
  121 }
  122 
  123 #endif /* WORDS_BIGENDIAN */
  124 
  125 #else /* !RUNTIME_ENDIAN */
  126 
  127 #define BYTESWAP(x) _byteswap(sc->littleEndian, x)
  128 #define BYTESWAP64(x) _byteswap64(sc->littleEndian, x)
  129 
  130 #define _BYTESWAP(x) ((ROTR((x), 8) & 0xff00ff00L) | \
  131               (ROTL((x), 8) & 0x00ff00ffL))
  132 #define _BYTESWAP64(x) __byteswap64(x)
  133 
  134 static inline uint64_t __byteswap64(uint64_t x)
  135 {
  136   uint32_t a = x >> 32;
  137   uint32_t b = (uint32_t) x;
  138   return ((uint64_t) _BYTESWAP(b) << 32) | (uint64_t) _BYTESWAP(a);
  139 }
  140 
  141 static inline uint32_t _byteswap(int littleEndian, uint32_t x)
  142 {
  143   if (!littleEndian)
  144     return x;
  145   else
  146     return _BYTESWAP(x);
  147 }
  148 
  149 static inline uint64_t _byteswap64(int littleEndian, uint64_t x)
  150 {
  151   if (!littleEndian)
  152     return x;
  153   else
  154     return _BYTESWAP64(x);
  155 }
  156 
  157 static inline void setEndian(int *littleEndianp)
  158 {
  159   union {
  160     uint32_t w;
  161     uint8_t b[4];
  162   } endian;
  163 
  164   endian.w = 1L;
  165   *littleEndianp = endian.b[0] != 0;
  166 }
  167 
  168 #endif /* !RUNTIME_ENDIAN */
  169 
  170 static const uint8_t padding[64] = {
  171   0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  172   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  173   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  174   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  175   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  176   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  177   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  178   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  179 };
  180 
  181 void
  182 SHA256Init (SHA256Context *sc)
  183 {
  184 #ifdef RUNTIME_ENDIAN
  185   setEndian (&sc->littleEndian);
  186 #endif /* RUNTIME_ENDIAN */
  187 
  188   sc->totalLength = 0LL;
  189   sc->hash[0] = 0x6a09e667L;
  190   sc->hash[1] = 0xbb67ae85L;
  191   sc->hash[2] = 0x3c6ef372L;
  192   sc->hash[3] = 0xa54ff53aL;
  193   sc->hash[4] = 0x510e527fL;
  194   sc->hash[5] = 0x9b05688cL;
  195   sc->hash[6] = 0x1f83d9abL;
  196   sc->hash[7] = 0x5be0cd19L;
  197   sc->bufferLength = 0L;
  198 }
  199 
  200 static void
  201 burnStack (int size)
  202 {
  203   char buf[128];
  204 
  205   memset (buf, 0, sizeof (buf));
  206   size -= sizeof (buf);
  207   if (size > 0)
  208     burnStack (size);
  209 }
  210 
  211 static void
  212 SHA256Guts (SHA256Context *sc, const uint32_t *cbuf)
  213 {
  214   uint32_t buf[64];
  215   uint32_t *W, *W2, *W7, *W15, *W16;
  216   uint32_t a, b, c, d, e, f, g, h;
  217   uint32_t t1, t2;
  218   const uint32_t *Kp;
  219   int i;
  220 
  221   W = buf;
  222 
  223   for (i = 15; i >= 0; i--) {
  224     *(W++) = BYTESWAP(*cbuf);
  225     cbuf++;
  226   }
  227 
  228   W16 = &buf[0];
  229   W15 = &buf[1];
  230   W7 = &buf[9];
  231   W2 = &buf[14];
  232 
  233   for (i = 47; i >= 0; i--) {
  234     *(W++) = sigma1(*W2) + *(W7++) + sigma0(*W15) + *(W16++);
  235     W2++;
  236     W15++;
  237   }
  238 
  239   a = sc->hash[0];
  240   b = sc->hash[1];
  241   c = sc->hash[2];
  242   d = sc->hash[3];
  243   e = sc->hash[4];
  244   f = sc->hash[5];
  245   g = sc->hash[6];
  246   h = sc->hash[7];
  247 
  248   Kp = K;
  249   W = buf;
  250 
  251 #ifndef SHA256_UNROLL
  252 #define SHA256_UNROLL 1
  253 #endif /* !SHA256_UNROLL */
  254 
  255 #if SHA256_UNROLL == 1
  256   for (i = 63; i >= 0; i--)
  257     DO_ROUND();
  258 #elif SHA256_UNROLL == 2
  259   for (i = 31; i >= 0; i--) {
  260     DO_ROUND(); DO_ROUND();
  261   }
  262 #elif SHA256_UNROLL == 4
  263   for (i = 15; i >= 0; i--) {
  264     DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
  265   }
  266 #elif SHA256_UNROLL == 8
  267   for (i = 7; i >= 0; i--) {
  268     DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
  269     DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
  270   }
  271 #elif SHA256_UNROLL == 16
  272   for (i = 3; i >= 0; i--) {
  273     DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
  274     DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
  275     DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
  276     DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
  277   }
  278 #elif SHA256_UNROLL == 32
  279   for (i = 1; i >= 0; i--) {
  280     DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
  281     DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
  282     DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
  283     DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
  284     DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
  285     DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
  286     DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
  287     DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
  288   }
  289 #elif SHA256_UNROLL == 64
  290   DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
  291   DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
  292   DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
  293   DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
  294   DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
  295   DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
  296   DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
  297   DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
  298   DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
  299   DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
  300   DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
  301   DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
  302   DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
  303   DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
  304   DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
  305   DO_ROUND(); DO_ROUND(); DO_ROUND(); DO_ROUND();
  306 #else
  307 #error "SHA256_UNROLL must be 1, 2, 4, 8, 16, 32, or 64!"
  308 #endif
  309 
  310   sc->hash[0] += a;
  311   sc->hash[1] += b;
  312   sc->hash[2] += c;
  313   sc->hash[3] += d;
  314   sc->hash[4] += e;
  315   sc->hash[5] += f;
  316   sc->hash[6] += g;
  317   sc->hash[7] += h;
  318 }
  319 
  320 void
  321 SHA256Update (SHA256Context *sc, const void *vdata, uint32_t len)
  322 {
  323   const uint8_t *data = vdata;
  324   uint32_t bufferBytesLeft;
  325   uint32_t bytesToCopy;
  326   int needBurn = 0;
  327 
  328 #ifdef SHA256_FAST_COPY
  329   if (sc->bufferLength) {
  330     bufferBytesLeft = 64L - sc->bufferLength;
  331 
  332     bytesToCopy = bufferBytesLeft;
  333     if (bytesToCopy > len)
  334       bytesToCopy = len;
  335 
  336     memcpy (&sc->buffer.bytes[sc->bufferLength], data, bytesToCopy);
  337 
  338     sc->totalLength += bytesToCopy * 8L;
  339 
  340     sc->bufferLength += bytesToCopy;
  341     data += bytesToCopy;
  342     len -= bytesToCopy;
  343 
  344     if (sc->bufferLength == 64L) {
  345       SHA256Guts (sc, sc->buffer.words);
  346       needBurn = 1;
  347       sc->bufferLength = 0L;
  348     }
  349   }
  350 
  351   while (len > 63L) {
  352     sc->totalLength += 512L;
  353 
  354     SHA256Guts (sc, data);
  355     needBurn = 1;
  356 
  357     data += 64L;
  358     len -= 64L;
  359   }
  360 
  361   if (len) {
  362     memcpy (&sc->buffer.bytes[sc->bufferLength], data, len);
  363 
  364     sc->totalLength += len * 8L;
  365 
  366     sc->bufferLength += len;
  367   }
  368 #else /* SHA256_FAST_COPY */
  369   while (len) {
  370     bufferBytesLeft = 64L - sc->bufferLength;
  371 
  372     bytesToCopy = bufferBytesLeft;
  373     if (bytesToCopy > len)
  374       bytesToCopy = len;
  375 
  376     memcpy (&sc->buffer.bytes[sc->bufferLength], data, bytesToCopy);
  377 
  378     sc->totalLength += bytesToCopy * 8L;
  379 
  380     sc->bufferLength += bytesToCopy;
  381     data += bytesToCopy;
  382     len -= bytesToCopy;
  383 
  384     if (sc->bufferLength == 64L) {
  385       SHA256Guts (sc, sc->buffer.words);
  386       needBurn = 1;
  387       sc->bufferLength = 0L;
  388     }
  389   }
  390 #endif /* SHA256_FAST_COPY */
  391 
  392   if (needBurn)
  393     burnStack (sizeof (uint32_t[74]) + sizeof (uint32_t *[6]) + sizeof (int));
  394 }
  395 
  396 void
  397 SHA256Final (SHA256Context *sc, uint8_t hash[SHA256_HASH_SIZE])
  398 {
  399   uint32_t bytesToPad;
  400   uint64_t lengthPad;
  401   int i;
  402 
  403   bytesToPad = 120L - sc->bufferLength;
  404   if (bytesToPad > 64L)
  405     bytesToPad -= 64L;
  406 
  407   lengthPad = BYTESWAP64(sc->totalLength);
  408 
  409   SHA256Update (sc, padding, bytesToPad);
  410   SHA256Update (sc, &lengthPad, 8L);
  411 
  412   if (hash) {
  413     for (i = 0; i < SHA256_HASH_WORDS; i++) {
  414 #ifdef SHA256_FAST_COPY
  415       *((uint32_t *) hash) = BYTESWAP(sc->hash[i]);
  416 #else /* SHA256_FAST_COPY */
  417       hash[0] = (uint8_t) (sc->hash[i] >> 24);
  418       hash[1] = (uint8_t) (sc->hash[i] >> 16);
  419       hash[2] = (uint8_t) (sc->hash[i] >> 8);
  420       hash[3] = (uint8_t) sc->hash[i];
  421 #endif /* SHA256_FAST_COPY */
  422       hash += 4;
  423     }
  424   }
  425 }
  426 
  427 #ifdef SHA256_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   SHA256Context foo;
  437   uint8_t hash[SHA256_HASH_SIZE];
  438   char buf[1000];
  439   int i;
  440 
  441   SHA256Init (&foo);
  442   SHA256Update (&foo, "abc", 3);
  443   SHA256Final (&foo, hash);
  444 
  445   for (i = 0; i < SHA256_HASH_SIZE;) {
  446     printf ("%02x", hash[i++]);
  447     if (!(i % 4))
  448       printf (" ");
  449   }
  450   printf ("\n");
  451 
  452   SHA256Init (&foo);
  453   SHA256Update (&foo,
  454         "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
  455         56);
  456   SHA256Final (&foo, hash);
  457 
  458   for (i = 0; i < SHA256_HASH_SIZE;) {
  459     printf ("%02x", hash[i++]);
  460     if (!(i % 4))
  461       printf (" ");
  462   }
  463   printf ("\n");
  464 
  465   SHA256Init (&foo);
  466   memset (buf, 'a', sizeof (buf));
  467   for (i = 0; i < 1000; i++)
  468     SHA256Update (&foo, buf, sizeof (buf));
  469   SHA256Final (&foo, hash);
  470 
  471   for (i = 0; i < SHA256_HASH_SIZE;) {
  472     printf ("%02x", hash[i++]);
  473     if (!(i % 4))
  474       printf (" ");
  475   }
  476   printf ("\n");
  477 
  478   exit (0);
  479 }
  480 
  481 #endif /* SHA256_TEST */