telepathygabble/src/sha1.c
changeset 10 59927b2d3b75
parent 0 d0f3a028347a
equal deleted inserted replaced
0:d0f3a028347a 10:59927b2d3b75
     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: sha1.c 680 2003-07-25 21:57:38Z asaddi $
       
    27  */
       
    28 
       
    29 /*
       
    30  * Define WORDS_BIGENDIAN if compiling on a big-endian architecture.
       
    31  *
       
    32  * Define SHA1_TEST to test the implementation using the NIST's
       
    33  * sample messages. The output should be:
       
    34  *
       
    35  *   a9993e36 4706816a ba3e2571 7850c26c 9cd0d89d
       
    36  *   84983e44 1c3bd26e baae4aa1 f95129e5 e54670f1
       
    37  *   34aa973c d4c4daa4 f61eeb2b dbad2731 6534016f
       
    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 
       
    55 #include "sha1.h"
       
    56 
       
    57 #ifndef lint
       
    58 static const char rcsid[] =
       
    59 	"$Id: sha1.c 680 2003-07-25 21:57:38Z asaddi $";
       
    60 #endif /* !lint */
       
    61 
       
    62 #define ROTL(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
       
    63 #define ROTR(x, n) (((x) >> (n)) | ((x) << (32 - (n))))
       
    64 
       
    65 #define F_0_19(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
       
    66 #define F_20_39(x, y, z) ((x) ^ (y) ^ (z))
       
    67 #define F_40_59(x, y, z) (((x) & ((y) | (z))) | ((y) & (z)))
       
    68 #define F_60_79(x, y, z) ((x) ^ (y) ^ (z))
       
    69 
       
    70 #define DO_ROUND(F, K) { \
       
    71   temp = ROTL(a, 5) + F(b, c, d) + e + *(W++) + K; \
       
    72   e = d; \
       
    73   d = c; \
       
    74   c = ROTL(b, 30); \
       
    75   b = a; \
       
    76   a = temp; \
       
    77 }
       
    78 
       
    79 #define K_0_19 0x5a827999L
       
    80 #define K_20_39 0x6ed9eba1L
       
    81 #define K_40_59 0x8f1bbcdcL
       
    82 #define K_60_79 0xca62c1d6L
       
    83 
       
    84 #ifndef RUNTIME_ENDIAN
       
    85 
       
    86 #ifdef WORDS_BIGENDIAN
       
    87 
       
    88 #define BYTESWAP(x) (x)
       
    89 #define BYTESWAP64(x) (x)
       
    90 
       
    91 #else /* WORDS_BIGENDIAN */
       
    92 
       
    93 #define BYTESWAP(x) ((ROTR((x), 8) & 0xff00ff00L) | \
       
    94 		     (ROTL((x), 8) & 0x00ff00ffL))
       
    95 #define BYTESWAP64(x) _byteswap64(x)
       
    96 
       
    97 static 
       
    98 #ifdef G_HAVE_INLINE 
       
    99 inline 
       
   100 #endif
       
   101 uint64_t _byteswap64(uint64_t x)
       
   102 {
       
   103   uint32_t a = x >> 32;
       
   104   uint32_t b = (uint32_t) x;
       
   105   return ((uint64_t) BYTESWAP(b) << 32) | (uint64_t) BYTESWAP(a);
       
   106 }
       
   107 
       
   108 #endif /* WORDS_BIGENDIAN */
       
   109 
       
   110 #else /* !RUNTIME_ENDIAN */
       
   111 
       
   112 #define BYTESWAP(x) _byteswap(sc->littleEndian, x)
       
   113 #define BYTESWAP64(x) _byteswap64(sc->littleEndian, x)
       
   114 
       
   115 #define _BYTESWAP(x) ((ROTR((x), 8) & 0xff00ff00L) | \
       
   116 		      (ROTL((x), 8) & 0x00ff00ffL))
       
   117 #define _BYTESWAP64(x) __byteswap64(x)
       
   118 
       
   119 static 
       
   120 #ifdef G_HAVE_INLINE 
       
   121 inline 
       
   122 #endif 
       
   123 uint64_t __byteswap64(uint64_t x)
       
   124 {
       
   125   uint32_t a = x >> 32;
       
   126   uint32_t b = (uint32_t) x;
       
   127   return ((uint64_t) _BYTESWAP(b) << 32) | (uint64_t) _BYTESWAP(a);
       
   128 }
       
   129 
       
   130 static 
       
   131 #ifdef G_HAVE_INLINE
       
   132 inline 
       
   133 #endif
       
   134 uint32_t _byteswap(int littleEndian, uint32_t x)
       
   135 {
       
   136   if (!littleEndian)
       
   137     return x;
       
   138   else
       
   139     return _BYTESWAP(x);
       
   140 }
       
   141 
       
   142 static 
       
   143 #ifdef G_HAVE_INLINE
       
   144 inline 
       
   145 #endif
       
   146 uint64_t _byteswap64(int littleEndian, uint64_t x)
       
   147 {
       
   148   if (!littleEndian)
       
   149     return x;
       
   150   else
       
   151     return _BYTESWAP64(x);
       
   152 }
       
   153 
       
   154 static 
       
   155 #ifdef G_HAVE_INLINE
       
   156 inline 
       
   157 #endif
       
   158 void setEndian(int *littleEndianp)
       
   159 {
       
   160   union {
       
   161     uint32_t w;
       
   162     uint8_t b[4];
       
   163   } endian;
       
   164 
       
   165   endian.w = 1L;
       
   166   *littleEndianp = endian.b[0] != 0;
       
   167 }
       
   168 
       
   169 #endif /* !RUNTIME_ENDIAN */
       
   170 
       
   171 static const uint8_t padding[64] = {
       
   172   0x80, 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   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
       
   180 };
       
   181 
       
   182 void
       
   183 SHA1Init (SHA1Context *sc)
       
   184 {
       
   185 #ifdef RUNTIME_ENDIAN
       
   186   setEndian (&sc->littleEndian);
       
   187 #endif /* RUNTIME_ENDIAN */
       
   188 
       
   189   sc->totalLength = 0LL;
       
   190   sc->hash[0] = 0x67452301L;
       
   191   sc->hash[1] = 0xefcdab89L;
       
   192   sc->hash[2] = 0x98badcfeL;
       
   193   sc->hash[3] = 0x10325476L;
       
   194   sc->hash[4] = 0xc3d2e1f0L;
       
   195   sc->bufferLength = 0L;
       
   196 }
       
   197 
       
   198 static void
       
   199 burnStack (int size)
       
   200 {
       
   201   char buf[128];
       
   202 
       
   203   memset (buf, 0, sizeof (buf));
       
   204   size -= sizeof (buf);
       
   205   if (size > 0)
       
   206     burnStack (size);
       
   207 }
       
   208 
       
   209 static void
       
   210 SHA1Guts (SHA1Context *sc, const uint32_t *cbuf)
       
   211 {
       
   212   uint32_t buf[80];
       
   213   uint32_t *W, *W3, *W8, *W14, *W16;
       
   214   uint32_t a, b, c, d, e, temp;
       
   215   int i;
       
   216 
       
   217   W = buf;
       
   218 
       
   219   for (i = 15; i >= 0; i--) {
       
   220     *(W++) = BYTESWAP(*cbuf);
       
   221     cbuf++;
       
   222   }
       
   223 
       
   224   W16 = &buf[0];
       
   225   W14 = &buf[2];
       
   226   W8 = &buf[8];
       
   227   W3 = &buf[13];
       
   228 
       
   229   for (i = 63; i >= 0; i--) {
       
   230     *W = *(W3++) ^ *(W8++) ^ *(W14++) ^ *(W16++);
       
   231     *W = ROTL(*W, 1);
       
   232     W++;
       
   233   }
       
   234 
       
   235   a = sc->hash[0];
       
   236   b = sc->hash[1];
       
   237   c = sc->hash[2];
       
   238   d = sc->hash[3];
       
   239   e = sc->hash[4];
       
   240 
       
   241   W = buf;
       
   242 
       
   243 #ifndef SHA1_UNROLL
       
   244 #define SHA1_UNROLL 20
       
   245 #endif /* !SHA1_UNROLL */
       
   246 
       
   247 #if SHA1_UNROLL == 1
       
   248   for (i = 19; i >= 0; i--)
       
   249     DO_ROUND(F_0_19, K_0_19);
       
   250 
       
   251   for (i = 19; i >= 0; i--)
       
   252     DO_ROUND(F_20_39, K_20_39);
       
   253 
       
   254   for (i = 19; i >= 0; i--)
       
   255     DO_ROUND(F_40_59, K_40_59);
       
   256 
       
   257   for (i = 19; i >= 0; i--)
       
   258     DO_ROUND(F_60_79, K_60_79);
       
   259 #elif SHA1_UNROLL == 2
       
   260   for (i = 9; i >= 0; i--) {
       
   261     DO_ROUND(F_0_19, K_0_19);
       
   262     DO_ROUND(F_0_19, K_0_19);
       
   263   }
       
   264 
       
   265   for (i = 9; i >= 0; i--) {
       
   266     DO_ROUND(F_20_39, K_20_39);
       
   267     DO_ROUND(F_20_39, K_20_39);
       
   268   }
       
   269 
       
   270   for (i = 9; i >= 0; i--) {
       
   271     DO_ROUND(F_40_59, K_40_59);
       
   272     DO_ROUND(F_40_59, K_40_59);
       
   273   }
       
   274 
       
   275   for (i = 9; i >= 0; i--) {
       
   276     DO_ROUND(F_60_79, K_60_79);
       
   277     DO_ROUND(F_60_79, K_60_79);
       
   278   }
       
   279 #elif SHA1_UNROLL == 4
       
   280   for (i = 4; i >= 0; i--) {
       
   281     DO_ROUND(F_0_19, K_0_19);
       
   282     DO_ROUND(F_0_19, K_0_19);
       
   283     DO_ROUND(F_0_19, K_0_19);
       
   284     DO_ROUND(F_0_19, K_0_19);
       
   285   }
       
   286 
       
   287   for (i = 4; i >= 0; i--) {
       
   288     DO_ROUND(F_20_39, K_20_39);
       
   289     DO_ROUND(F_20_39, K_20_39);
       
   290     DO_ROUND(F_20_39, K_20_39);
       
   291     DO_ROUND(F_20_39, K_20_39);
       
   292   }
       
   293 
       
   294   for (i = 4; i >= 0; i--) {
       
   295     DO_ROUND(F_40_59, K_40_59);
       
   296     DO_ROUND(F_40_59, K_40_59);
       
   297     DO_ROUND(F_40_59, K_40_59);
       
   298     DO_ROUND(F_40_59, K_40_59);
       
   299   }
       
   300 
       
   301   for (i = 4; i >= 0; i--) {
       
   302     DO_ROUND(F_60_79, K_60_79);
       
   303     DO_ROUND(F_60_79, K_60_79);
       
   304     DO_ROUND(F_60_79, K_60_79);
       
   305     DO_ROUND(F_60_79, K_60_79);
       
   306   }
       
   307 #elif SHA1_UNROLL == 5
       
   308   for (i = 3; i >= 0; i--) {
       
   309     DO_ROUND(F_0_19, K_0_19);
       
   310     DO_ROUND(F_0_19, K_0_19);
       
   311     DO_ROUND(F_0_19, K_0_19);
       
   312     DO_ROUND(F_0_19, K_0_19);
       
   313     DO_ROUND(F_0_19, K_0_19);
       
   314   }
       
   315 
       
   316   for (i = 3; i >= 0; i--) {
       
   317     DO_ROUND(F_20_39, K_20_39);
       
   318     DO_ROUND(F_20_39, K_20_39);
       
   319     DO_ROUND(F_20_39, K_20_39);
       
   320     DO_ROUND(F_20_39, K_20_39);
       
   321     DO_ROUND(F_20_39, K_20_39);
       
   322   }
       
   323 
       
   324   for (i = 3; i >= 0; i--) {
       
   325     DO_ROUND(F_40_59, K_40_59);
       
   326     DO_ROUND(F_40_59, K_40_59);
       
   327     DO_ROUND(F_40_59, K_40_59);
       
   328     DO_ROUND(F_40_59, K_40_59);
       
   329     DO_ROUND(F_40_59, K_40_59);
       
   330   }
       
   331 
       
   332   for (i = 3; i >= 0; i--) {
       
   333     DO_ROUND(F_60_79, K_60_79);
       
   334     DO_ROUND(F_60_79, K_60_79);
       
   335     DO_ROUND(F_60_79, K_60_79);
       
   336     DO_ROUND(F_60_79, K_60_79);
       
   337     DO_ROUND(F_60_79, K_60_79);
       
   338   }
       
   339 #elif SHA1_UNROLL == 10
       
   340   for (i = 1; i >= 0; i--) {
       
   341     DO_ROUND(F_0_19, K_0_19);
       
   342     DO_ROUND(F_0_19, K_0_19);
       
   343     DO_ROUND(F_0_19, K_0_19);
       
   344     DO_ROUND(F_0_19, K_0_19);
       
   345     DO_ROUND(F_0_19, K_0_19);
       
   346     DO_ROUND(F_0_19, K_0_19);
       
   347     DO_ROUND(F_0_19, K_0_19);
       
   348     DO_ROUND(F_0_19, K_0_19);
       
   349     DO_ROUND(F_0_19, K_0_19);
       
   350     DO_ROUND(F_0_19, K_0_19);
       
   351   }
       
   352 
       
   353   for (i = 1; i >= 0; i--) {
       
   354     DO_ROUND(F_20_39, K_20_39);
       
   355     DO_ROUND(F_20_39, K_20_39);
       
   356     DO_ROUND(F_20_39, K_20_39);
       
   357     DO_ROUND(F_20_39, K_20_39);
       
   358     DO_ROUND(F_20_39, K_20_39);
       
   359     DO_ROUND(F_20_39, K_20_39);
       
   360     DO_ROUND(F_20_39, K_20_39);
       
   361     DO_ROUND(F_20_39, K_20_39);
       
   362     DO_ROUND(F_20_39, K_20_39);
       
   363     DO_ROUND(F_20_39, K_20_39);
       
   364   }
       
   365 
       
   366   for (i = 1; i >= 0; i--) {
       
   367     DO_ROUND(F_40_59, K_40_59);
       
   368     DO_ROUND(F_40_59, K_40_59);
       
   369     DO_ROUND(F_40_59, K_40_59);
       
   370     DO_ROUND(F_40_59, K_40_59);
       
   371     DO_ROUND(F_40_59, K_40_59);
       
   372     DO_ROUND(F_40_59, K_40_59);
       
   373     DO_ROUND(F_40_59, K_40_59);
       
   374     DO_ROUND(F_40_59, K_40_59);
       
   375     DO_ROUND(F_40_59, K_40_59);
       
   376     DO_ROUND(F_40_59, K_40_59);
       
   377   }
       
   378 
       
   379   for (i = 1; i >= 0; i--) {
       
   380     DO_ROUND(F_60_79, K_60_79);
       
   381     DO_ROUND(F_60_79, K_60_79);
       
   382     DO_ROUND(F_60_79, K_60_79);
       
   383     DO_ROUND(F_60_79, K_60_79);
       
   384     DO_ROUND(F_60_79, K_60_79);
       
   385     DO_ROUND(F_60_79, K_60_79);
       
   386     DO_ROUND(F_60_79, K_60_79);
       
   387     DO_ROUND(F_60_79, K_60_79);
       
   388     DO_ROUND(F_60_79, K_60_79);
       
   389     DO_ROUND(F_60_79, K_60_79);
       
   390   }
       
   391 #elif SHA1_UNROLL == 20
       
   392   DO_ROUND(F_0_19, K_0_19);
       
   393   DO_ROUND(F_0_19, K_0_19);
       
   394   DO_ROUND(F_0_19, K_0_19);
       
   395   DO_ROUND(F_0_19, K_0_19);
       
   396   DO_ROUND(F_0_19, K_0_19);
       
   397   DO_ROUND(F_0_19, K_0_19);
       
   398   DO_ROUND(F_0_19, K_0_19);
       
   399   DO_ROUND(F_0_19, K_0_19);
       
   400   DO_ROUND(F_0_19, K_0_19);
       
   401   DO_ROUND(F_0_19, K_0_19);
       
   402   DO_ROUND(F_0_19, K_0_19);
       
   403   DO_ROUND(F_0_19, K_0_19);
       
   404   DO_ROUND(F_0_19, K_0_19);
       
   405   DO_ROUND(F_0_19, K_0_19);
       
   406   DO_ROUND(F_0_19, K_0_19);
       
   407   DO_ROUND(F_0_19, K_0_19);
       
   408   DO_ROUND(F_0_19, K_0_19);
       
   409   DO_ROUND(F_0_19, K_0_19);
       
   410   DO_ROUND(F_0_19, K_0_19);
       
   411   DO_ROUND(F_0_19, K_0_19);
       
   412 
       
   413   DO_ROUND(F_20_39, K_20_39);
       
   414   DO_ROUND(F_20_39, K_20_39);
       
   415   DO_ROUND(F_20_39, K_20_39);
       
   416   DO_ROUND(F_20_39, K_20_39);
       
   417   DO_ROUND(F_20_39, K_20_39);
       
   418   DO_ROUND(F_20_39, K_20_39);
       
   419   DO_ROUND(F_20_39, K_20_39);
       
   420   DO_ROUND(F_20_39, K_20_39);
       
   421   DO_ROUND(F_20_39, K_20_39);
       
   422   DO_ROUND(F_20_39, K_20_39);
       
   423   DO_ROUND(F_20_39, K_20_39);
       
   424   DO_ROUND(F_20_39, K_20_39);
       
   425   DO_ROUND(F_20_39, K_20_39);
       
   426   DO_ROUND(F_20_39, K_20_39);
       
   427   DO_ROUND(F_20_39, K_20_39);
       
   428   DO_ROUND(F_20_39, K_20_39);
       
   429   DO_ROUND(F_20_39, K_20_39);
       
   430   DO_ROUND(F_20_39, K_20_39);
       
   431   DO_ROUND(F_20_39, K_20_39);
       
   432   DO_ROUND(F_20_39, K_20_39);
       
   433 
       
   434   DO_ROUND(F_40_59, K_40_59);
       
   435   DO_ROUND(F_40_59, K_40_59);
       
   436   DO_ROUND(F_40_59, K_40_59);
       
   437   DO_ROUND(F_40_59, K_40_59);
       
   438   DO_ROUND(F_40_59, K_40_59);
       
   439   DO_ROUND(F_40_59, K_40_59);
       
   440   DO_ROUND(F_40_59, K_40_59);
       
   441   DO_ROUND(F_40_59, K_40_59);
       
   442   DO_ROUND(F_40_59, K_40_59);
       
   443   DO_ROUND(F_40_59, K_40_59);
       
   444   DO_ROUND(F_40_59, K_40_59);
       
   445   DO_ROUND(F_40_59, K_40_59);
       
   446   DO_ROUND(F_40_59, K_40_59);
       
   447   DO_ROUND(F_40_59, K_40_59);
       
   448   DO_ROUND(F_40_59, K_40_59);
       
   449   DO_ROUND(F_40_59, K_40_59);
       
   450   DO_ROUND(F_40_59, K_40_59);
       
   451   DO_ROUND(F_40_59, K_40_59);
       
   452   DO_ROUND(F_40_59, K_40_59);
       
   453   DO_ROUND(F_40_59, K_40_59);
       
   454 
       
   455   DO_ROUND(F_60_79, K_60_79);
       
   456   DO_ROUND(F_60_79, K_60_79);
       
   457   DO_ROUND(F_60_79, K_60_79);
       
   458   DO_ROUND(F_60_79, K_60_79);
       
   459   DO_ROUND(F_60_79, K_60_79);
       
   460   DO_ROUND(F_60_79, K_60_79);
       
   461   DO_ROUND(F_60_79, K_60_79);
       
   462   DO_ROUND(F_60_79, K_60_79);
       
   463   DO_ROUND(F_60_79, K_60_79);
       
   464   DO_ROUND(F_60_79, K_60_79);
       
   465   DO_ROUND(F_60_79, K_60_79);
       
   466   DO_ROUND(F_60_79, K_60_79);
       
   467   DO_ROUND(F_60_79, K_60_79);
       
   468   DO_ROUND(F_60_79, K_60_79);
       
   469   DO_ROUND(F_60_79, K_60_79);
       
   470   DO_ROUND(F_60_79, K_60_79);
       
   471   DO_ROUND(F_60_79, K_60_79);
       
   472   DO_ROUND(F_60_79, K_60_79);
       
   473   DO_ROUND(F_60_79, K_60_79);
       
   474   DO_ROUND(F_60_79, K_60_79);
       
   475 #else /* SHA1_UNROLL */
       
   476 #error SHA1_UNROLL must be 1, 2, 4, 5, 10 or 20!
       
   477 #endif
       
   478 
       
   479   sc->hash[0] += a;
       
   480   sc->hash[1] += b;
       
   481   sc->hash[2] += c;
       
   482   sc->hash[3] += d;
       
   483   sc->hash[4] += e;
       
   484 }
       
   485 
       
   486 void
       
   487 SHA1Update (SHA1Context *sc, const void *vdata, uint32_t len)
       
   488 {
       
   489   const uint8_t *data = vdata;
       
   490   uint32_t bufferBytesLeft;
       
   491   uint32_t bytesToCopy;
       
   492   int needBurn = 0;
       
   493 
       
   494 #ifdef SHA1_FAST_COPY
       
   495   if (sc->bufferLength) {
       
   496     bufferBytesLeft = 64L - sc->bufferLength;
       
   497 
       
   498     bytesToCopy = bufferBytesLeft;
       
   499     if (bytesToCopy > len)
       
   500       bytesToCopy = len;
       
   501 
       
   502     memcpy (&sc->buffer.bytes[sc->bufferLength], data, bytesToCopy);
       
   503 
       
   504     sc->totalLength += bytesToCopy * 8L;
       
   505 
       
   506     sc->bufferLength += bytesToCopy;
       
   507     data += bytesToCopy;
       
   508     len -= bytesToCopy;
       
   509 
       
   510     if (sc->bufferLength == 64L) {
       
   511       SHA1Guts (sc, sc->buffer.words);
       
   512       needBurn = 1;
       
   513       sc->bufferLength = 0L;
       
   514     }
       
   515   }
       
   516 
       
   517   while (len > 63) {
       
   518     sc->totalLength += 512L;
       
   519 
       
   520     SHA1Guts (sc, data);
       
   521     needBurn = 1;
       
   522 
       
   523     data += 64L;
       
   524     len -= 64L;
       
   525   }
       
   526 
       
   527   if (len) {
       
   528     memcpy (&sc->buffer.bytes[sc->bufferLength], data, len);
       
   529 
       
   530     sc->totalLength += len * 8L;
       
   531 
       
   532     sc->bufferLength += len;
       
   533   }
       
   534 #else /* SHA1_FAST_COPY */
       
   535   while (len) {
       
   536     bufferBytesLeft = 64L - sc->bufferLength;
       
   537 
       
   538     bytesToCopy = bufferBytesLeft;
       
   539     if (bytesToCopy > len)
       
   540       bytesToCopy = len;
       
   541 
       
   542     memcpy (&sc->buffer.bytes[sc->bufferLength], data, bytesToCopy);
       
   543 
       
   544     sc->totalLength += bytesToCopy * 8L;
       
   545 
       
   546     sc->bufferLength += bytesToCopy;
       
   547     data += bytesToCopy;
       
   548     len -= bytesToCopy;
       
   549 
       
   550     if (sc->bufferLength == 64L) {
       
   551       SHA1Guts (sc, sc->buffer.words);
       
   552       needBurn = 1;
       
   553       sc->bufferLength = 0L;
       
   554     }
       
   555   }
       
   556 #endif /* SHA1_FAST_COPY */
       
   557 
       
   558   if (needBurn)
       
   559     burnStack (sizeof (uint32_t[86]) + sizeof (uint32_t *[5]) + sizeof (int));
       
   560 }
       
   561 
       
   562 void
       
   563 SHA1Final (SHA1Context *sc, uint8_t hash[SHA1_HASH_SIZE])
       
   564 {
       
   565   uint32_t bytesToPad;
       
   566   uint64_t lengthPad;
       
   567   int i;
       
   568 
       
   569   bytesToPad = 120L - sc->bufferLength;
       
   570   if (bytesToPad > 64L)
       
   571     bytesToPad -= 64L;
       
   572 
       
   573   lengthPad = BYTESWAP64(sc->totalLength);
       
   574 
       
   575   SHA1Update (sc, padding, bytesToPad);
       
   576   SHA1Update (sc, &lengthPad, 8L);
       
   577 
       
   578   if (hash) {
       
   579     for (i = 0; i < SHA1_HASH_WORDS; i++) {
       
   580 #ifdef SHA1_FAST_COPY
       
   581       *((uint32_t *) hash) = BYTESWAP(sc->hash[i]);
       
   582 #else /* SHA1_FAST_COPY */
       
   583       hash[0] = (uint8_t) (sc->hash[i] >> 24);
       
   584       hash[1] = (uint8_t) (sc->hash[i] >> 16);
       
   585       hash[2] = (uint8_t) (sc->hash[i] >> 8);
       
   586       hash[3] = (uint8_t) sc->hash[i];
       
   587 #endif /* SHA1_FAST_COPY */
       
   588       hash += 4;
       
   589     }
       
   590   }
       
   591 }
       
   592 
       
   593 #ifdef SHA1_TEST
       
   594 
       
   595 #include <stdio.h>
       
   596 #include <stdlib.h>
       
   597 #include <string.h>
       
   598 
       
   599 int
       
   600 main (int argc, char *argv[])
       
   601 {
       
   602   SHA1Context foo;
       
   603   uint8_t hash[SHA1_HASH_SIZE];
       
   604   char buf[1000];
       
   605   int i;
       
   606 
       
   607   SHA1Init (&foo);
       
   608   SHA1Update (&foo, "abc", 3);
       
   609   SHA1Final (&foo, hash);
       
   610 
       
   611   for (i = 0; i < SHA1_HASH_SIZE;) {
       
   612     printf ("%02x", hash[i++]);
       
   613     if (!(i % 4))
       
   614       printf (" ");
       
   615   }
       
   616   printf ("\n");
       
   617 
       
   618   SHA1Init (&foo);
       
   619   SHA1Update (&foo,
       
   620 		"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
       
   621 		56);
       
   622   SHA1Final (&foo, hash);
       
   623 
       
   624   for (i = 0; i < SHA1_HASH_SIZE;) {
       
   625     printf ("%02x", hash[i++]);
       
   626     if (!(i % 4))
       
   627       printf (" ");
       
   628   }
       
   629   printf ("\n");
       
   630 
       
   631   SHA1Init (&foo);
       
   632   memset (buf, 'a', sizeof (buf));
       
   633   for (i = 0; i < 1000; i++)
       
   634     SHA1Update (&foo, buf, sizeof (buf));
       
   635   SHA1Final (&foo, hash);
       
   636 
       
   637   for (i = 0; i < SHA1_HASH_SIZE;) {
       
   638     printf ("%02x", hash[i++]);
       
   639     if (!(i % 4))
       
   640       printf (" ");
       
   641   }
       
   642   printf ("\n");
       
   643 
       
   644   exit (0);
       
   645 }
       
   646 
       
   647 #endif /* SHA1_TEST */
       
   648 
       
   649