"Fossies" - the Fresh Open Source Software Archive

Member "duff-0.5.2/src/sha384.c" (10 Apr 2011, 13033 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: sha384.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 SHA384_TEST to test the implementation using the NIST's
   33  * sample messages. The output should be:
   34  *
   35  *   cb00753f45a35e8b b5a03d699ac65007 272c32ab0eded163 1a8b605a43ff5bed
   36  *   8086072ba1e7cc23 58baeca134c825a7
   37  *   09330c33f71147e8 3d192fc782cd1b47 53111b173b3b05d2 2fa08086e3b0f712
   38  *   fcc7c71a557e2db9 66c3e9fa91746039
   39  *   9d0e1809716474cb 086e834e310a4a1c ed149e9c00f24852 7972cec5704c2a5b
   40  *   07b8b3dc38ecc4eb ae97ddd87f3d8985
   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 "sha384.h"
   58 
   59 #ifndef lint
   60 static const char rcsid[] =
   61     "$Id: sha384.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 SHA384Init (SHA384Context *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] = 0xcbbb9d5dc1059ed8LL;
  228   sc->hash[1] = 0x629a292a367cd507LL;
  229   sc->hash[2] = 0x9159015a3070dd17LL;
  230   sc->hash[3] = 0x152fecd8f70e5939LL;
  231   sc->hash[4] = 0x67332667ffc00b31LL;
  232   sc->hash[5] = 0x8eb44a8768581511LL;
  233   sc->hash[6] = 0xdb0c2e0d64f98fa7LL;
  234   sc->hash[7] = 0x47b5481dbefa4fa4LL;
  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 SHA384Guts (SHA384Context *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 SHA384Update (SHA384Context *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 SHA384_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       SHA384Guts (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     SHA384Guts (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 /* SHA384_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       SHA384Guts (sc, sc->buffer.words);
  381       needBurn = 1;
  382       sc->bufferLength = 0L;
  383     }
  384   }
  385 #endif /* SHA384_FAST_COPY */
  386 
  387   if (needBurn)
  388     burnStack (sizeof (uint64_t[90]) + sizeof (uint64_t *[6]) + sizeof (int));
  389 }
  390 
  391 void
  392 SHA384Final (SHA384Context *sc, uint8_t hash[SHA384_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   SHA384Update (sc, padding, bytesToPad);
  406   SHA384Update (sc, lengthPad, 16L);
  407 
  408   if (hash) {
  409     for (i = 0; i < SHA384_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 SHA384_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   SHA384Context foo;
  437   uint8_t hash[SHA384_HASH_SIZE];
  438   char buf[1000];
  439   int i;
  440 
  441   SHA384Init (&foo);
  442   SHA384Update (&foo, "abc", 3);
  443   SHA384Final (&foo, hash);
  444 
  445   for (i = 0; i < SHA384_HASH_SIZE;) {
  446     printf ("%02x", hash[i++]);
  447     if (!(i % 8))
  448       printf (" ");
  449     if (!(i % 32))
  450       printf ("\n");
  451   }
  452   printf ("\n");
  453 
  454   SHA384Init (&foo);
  455   SHA384Update (&foo,
  456         "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
  457         "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
  458         112);
  459   SHA384Final (&foo, hash);
  460 
  461   for (i = 0; i < SHA384_HASH_SIZE;) {
  462     printf ("%02x", hash[i++]);
  463     if (!(i % 8))
  464       printf (" ");
  465     if (!(i % 32))
  466       printf ("\n");
  467   }
  468   printf ("\n");
  469 
  470   SHA384Init (&foo);
  471   memset (buf, 'a', sizeof (buf));
  472   for (i = 0; i < 1000; i++)
  473     SHA384Update (&foo, buf, sizeof (buf));
  474   SHA384Final (&foo, hash);
  475 
  476   for (i = 0; i < SHA384_HASH_SIZE;) {
  477     printf ("%02x", hash[i++]);
  478     if (!(i % 8))
  479       printf (" ");
  480     if (!(i % 32))
  481       printf ("\n");
  482   }
  483   printf ("\n");
  484 
  485   exit (0);
  486 }
  487 
  488 #endif /* SHA384_TEST */