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