]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
New sha1.c and sha1.h
authorNeilBrown <neilb@suse.de>
Mon, 14 May 2012 10:09:47 +0000 (20:09 +1000)
committerNeilBrown <neilb@suse.de>
Mon, 14 May 2012 23:24:27 +0000 (09:24 +1000)
These are from:
  http://gcc.gnu.org/svn/gcc/branches/cilkplus/include/sha1.h
and
  http://gcc.gnu.org/svn/gcc/branches/cilkplus/libiberty/sha1.c

and hopefully avoid aliasing issues.

Signed-off-by: NeilBrown <neilb@suse.de>
sha1.c
sha1.h

diff --git a/sha1.c b/sha1.c
index 0258515bf17c3e67f48ffcf8da5088b5913dcd1a..89245820db8a996e98599b0d3fce2f5d0c09b596 100644 (file)
--- a/sha1.c
+++ b/sha1.c
@@ -1,7 +1,8 @@
 /* sha1.c - Functions to compute SHA1 message digest of files or
    memory blocks according to the NIST specification FIPS-180-1.
 
-   Copyright (C) 2000, 2001, 2003, 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2001, 2003, 2004, 2005, 2006, 2008 Free Software
+   Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by the
@@ -22,9 +23,7 @@
       Robert Klep <robert@ilse.nl>  -- Expansion function fix
 */
 
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
+//#include <config.h>
 
 #include "sha1.h"
 
@@ -35,9 +34,6 @@
 # include "unlocked-io.h"
 #endif
 
-/* SWAP does an endian swap on architectures that are little-endian,
-   as SHA1 needs some data in a big-endian form.  */
-
 #ifdef WORDS_BIGENDIAN
 # define SWAP(n) (n)
 #else
 static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ...  */ };
 
 
-/*
-  Takes a pointer to a 160 bit block of data (five 32 bit ints) and
-  intializes it to the start constants of the SHA1 algorithm.  This
-  must be called before using hash in the call to sha1_hash.
-*/
+/* Take a pointer to a 160 bit block of data (five 32 bit ints) and
+   initialize it to the start constants of the SHA1 algorithm.  This
+   must be called before using hash in the call to sha1_hash.  */
 void
 sha1_init_ctx (struct sha1_ctx *ctx)
 {
@@ -77,15 +71,15 @@ sha1_init_ctx (struct sha1_ctx *ctx)
    must be in little endian byte order.
 
    IMPORTANT: On some systems it is required that RESBUF is correctly
-   aligned for a 32 bits value.  */
+   aligned for a 32-bit value.  */
 void *
 sha1_read_ctx (const struct sha1_ctx *ctx, void *resbuf)
 {
-  ((md5_uint32 *) resbuf)[0] = SWAP (ctx->A);
-  ((md5_uint32 *) resbuf)[1] = SWAP (ctx->B);
-  ((md5_uint32 *) resbuf)[2] = SWAP (ctx->C);
-  ((md5_uint32 *) resbuf)[3] = SWAP (ctx->D);
-  ((md5_uint32 *) resbuf)[4] = SWAP (ctx->E);
+  ((sha1_uint32 *) resbuf)[0] = SWAP (ctx->A);
+  ((sha1_uint32 *) resbuf)[1] = SWAP (ctx->B);
+  ((sha1_uint32 *) resbuf)[2] = SWAP (ctx->C);
+  ((sha1_uint32 *) resbuf)[3] = SWAP (ctx->D);
+  ((sha1_uint32 *) resbuf)[4] = SWAP (ctx->E);
 
   return resbuf;
 }
@@ -94,31 +88,27 @@ sha1_read_ctx (const struct sha1_ctx *ctx, void *resbuf)
    prolog according to the standard and write the result to RESBUF.
 
    IMPORTANT: On some systems it is required that RESBUF is correctly
-   aligned for a 32 bits value.  */
+   aligned for a 32-bit value.  */
 void *
 sha1_finish_ctx (struct sha1_ctx *ctx, void *resbuf)
 {
   /* Take yet unprocessed bytes into account.  */
-  md5_uint32 bytes = ctx->buflen;
-  size_t pad;
-  md5_uint32 *ptr;
+  sha1_uint32 bytes = ctx->buflen;
+  size_t size = (bytes < 56) ? 64 / 4 : 64 * 2 / 4;
 
   /* Now count remaining bytes.  */
   ctx->total[0] += bytes;
   if (ctx->total[0] < bytes)
     ++ctx->total[1];
 
-  pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes;
-  memcpy (&ctx->buffer[bytes], fillbuf, pad);
-
   /* Put the 64-bit file length in *bits* at the end of the buffer.  */
-  ptr = (md5_uint32 *) &ctx->buffer[bytes + pad + 4];
-  *ptr = SWAP (ctx->total[0] << 3);
-  ptr = (md5_uint32 *) &ctx->buffer[bytes + pad];
-  *ptr = SWAP ((ctx->total[1] << 3) | (ctx->total[0] >> 29));
+  ctx->buffer[size - 2] = SWAP ((ctx->total[1] << 3) | (ctx->total[0] >> 29));
+  ctx->buffer[size - 1] = SWAP (ctx->total[0] << 3);
+
+  memcpy (&((char *) ctx->buffer)[bytes], fillbuf, (size - 2) * 4 - bytes);
 
   /* Process last bytes.  */
-  sha1_process_block (ctx->buffer, bytes + pad + 8, ctx);
+  sha1_process_block (ctx->buffer, size * 4, ctx);
 
   return sha1_read_ctx (ctx, resbuf);
 }
@@ -189,7 +179,7 @@ sha1_stream (FILE *stream, void *resblock)
   return 0;
 }
 
-/* Compute MD5 message digest for LEN bytes beginning at BUFFER.  The
+/* Compute SHA1 message digest for LEN bytes beginning at BUFFER.  The
    result is always in little endian byte order, so that a byte-wise
    output yields to the wanted ASCII representation of the message
    digest.  */
@@ -218,7 +208,7 @@ sha1_process_bytes (const void *buffer, size_t len, struct sha1_ctx *ctx)
       size_t left_over = ctx->buflen;
       size_t add = 128 - left_over > len ? len : 128 - left_over;
 
-      memcpy (&ctx->buffer[left_over], buffer, add);
+      memcpy (&((char *) ctx->buffer)[left_over], buffer, add);
       ctx->buflen += add;
 
       if (ctx->buflen > 64)
@@ -227,7 +217,8 @@ sha1_process_bytes (const void *buffer, size_t len, struct sha1_ctx *ctx)
 
          ctx->buflen &= 63;
          /* The regions in the following copy operation cannot overlap.  */
-         memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~63],
+         memcpy (ctx->buffer,
+                 &((char *) ctx->buffer)[(left_over + add) & ~63],
                  ctx->buflen);
        }
 
@@ -240,7 +231,7 @@ sha1_process_bytes (const void *buffer, size_t len, struct sha1_ctx *ctx)
     {
 #if !_STRING_ARCH_unaligned
 # define alignof(type) offsetof (struct { char c; type x; }, x)
-# define UNALIGNED_P(p) (((size_t) p) % alignof (md5_uint32) != 0)
+# define UNALIGNED_P(p) (((size_t) p) % alignof (sha1_uint32) != 0)
       if (UNALIGNED_P (buffer))
        while (len > 64)
          {
@@ -262,13 +253,13 @@ sha1_process_bytes (const void *buffer, size_t len, struct sha1_ctx *ctx)
     {
       size_t left_over = ctx->buflen;
 
-      memcpy (&ctx->buffer[left_over], buffer, len);
+      memcpy (&((char *) ctx->buffer)[left_over], buffer, len);
       left_over += len;
       if (left_over >= 64)
        {
          sha1_process_block (ctx->buffer, 64, ctx);
          left_over -= 64;
-         memcpy (ctx->buffer, &ctx->buffer[64], left_over);
+         memcpy (ctx->buffer, &ctx->buffer[16], left_over);
        }
       ctx->buflen = left_over;
     }
@@ -277,10 +268,10 @@ sha1_process_bytes (const void *buffer, size_t len, struct sha1_ctx *ctx)
 /* --- Code below is the primary difference between md5.c and sha1.c --- */
 
 /* SHA1 round constants */
-#define K1 0x5a827999L
-#define K2 0x6ed9eba1L
-#define K3 0x8f1bbcdcL
-#define K4 0xca62c1d6L
+#define K1 0x5a827999
+#define K2 0x6ed9eba1
+#define K3 0x8f1bbcdc
+#define K4 0xca62c1d6
 
 /* Round functions.  Note that F2 is the same as F4.  */
 #define F1(B,C,D) ( D ^ ( B & ( C ^ D ) ) )
@@ -295,15 +286,15 @@ sha1_process_bytes (const void *buffer, size_t len, struct sha1_ctx *ctx)
 void
 sha1_process_block (const void *buffer, size_t len, struct sha1_ctx *ctx)
 {
-  const md5_uint32 *words = buffer;
-  size_t nwords = len / sizeof (md5_uint32);
-  const md5_uint32 *endp = words + nwords;
-  md5_uint32 x[16];
-  md5_uint32 a = ctx->A;
-  md5_uint32 b = ctx->B;
-  md5_uint32 c = ctx->C;
-  md5_uint32 d = ctx->D;
-  md5_uint32 e = ctx->E;
+  const sha1_uint32 *words = (const sha1_uint32*) buffer;
+  size_t nwords = len / sizeof (sha1_uint32);
+  const sha1_uint32 *endp = words + nwords;
+  sha1_uint32 x[16];
+  sha1_uint32 a = ctx->A;
+  sha1_uint32 b = ctx->B;
+  sha1_uint32 c = ctx->C;
+  sha1_uint32 d = ctx->D;
+  sha1_uint32 e = ctx->E;
 
   /* First increment the byte count.  RFC 1321 specifies the possible
      length of the file up to 2^64 bits.  Here we only compute the
@@ -312,7 +303,7 @@ sha1_process_block (const void *buffer, size_t len, struct sha1_ctx *ctx)
   if (ctx->total[0] < len)
     ++ctx->total[1];
 
-#define rol(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
+#define rol(x, n) (((x) << (n)) | ((sha1_uint32) (x) >> (32 - (n))))
 
 #define M(I) ( tm =   x[I&0x0f] ^ x[(I-14)&0x0f] \
                    ^ x[(I-8)&0x0f] ^ x[(I-3)&0x0f] \
@@ -327,7 +318,7 @@ sha1_process_block (const void *buffer, size_t len, struct sha1_ctx *ctx)
 
   while (words < endp)
     {
-      md5_uint32 tm;
+      sha1_uint32 tm;
       int t;
       for (t = 0; t < 16; t++)
        {
diff --git a/sha1.h b/sha1.h
index bb48855b8da8b694f33bdcd8b03edf692789c786..5473f91f412b9a6fc0bfc2e9af3dbfef90012640 100644 (file)
--- a/sha1.h
+++ b/sha1.h
@@ -1,10 +1,11 @@
 /* Declarations of functions and data types used for SHA1 sum
    library functions.
-   Copyright (C) 2000, 2001, 2003, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2001, 2003, 2005, 2006, 2008, 2010
+   Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by the
-   Free Software Foundation; either version 2, or (at your option) any
+   Free Software Foundation; either version 3, or (at your option) any
    later version.
 
    This program is distributed in the hope that it will be useful,
 #ifndef SHA1_H
 # define SHA1_H 1
 
-# include <stdio.h>
-# include "md5.h"
+#include <stdio.h>
+
+#if defined HAVE_LIMITS_H || _LIBC
+# include <limits.h>
+#endif
+
+#include "ansidecl.h"
+
+/* The following contortions are an attempt to use the C preprocessor
+   to determine an unsigned integral type that is 32 bits wide.  An
+   alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but
+   doing that would require that the configure script compile and *run*
+   the resulting executable.  Locally running cross-compiled executables
+   is usually not possible.  */
+
+#ifdef _LIBC
+# include <sys/types.h>
+typedef u_int32_t sha1_uint32;
+typedef uintptr_t sha1_uintptr;
+#else
+#  define INT_MAX_32_BITS 2147483647
+
+/* If UINT_MAX isn't defined, assume it's a 32-bit type.
+   This should be valid for all systems GNU cares about because
+   that doesn't include 16-bit systems, and only modern systems
+   (that certainly have <limits.h>) have 64+-bit integral types.  */
+
+# ifndef INT_MAX
+#  define INT_MAX INT_MAX_32_BITS
+# endif
+
+# if INT_MAX == INT_MAX_32_BITS
+   typedef unsigned int sha1_uint32;
+# else
+#  if SHRT_MAX == INT_MAX_32_BITS
+    typedef unsigned short sha1_uint32;
+#  else
+#   if LONG_MAX == INT_MAX_32_BITS
+     typedef unsigned long sha1_uint32;
+#   else
+     /* The following line is intended to evoke an error.
+        Using #error is not portable enough.  */
+     "Cannot determine unsigned 32-bit data type."
+#   endif
+#  endif
+# endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
 
 /* Structure to save state of computation between the single steps.  */
 struct sha1_ctx
 {
-  md5_uint32 A;
-  md5_uint32 B;
-  md5_uint32 C;
-  md5_uint32 D;
-  md5_uint32 E;
-
-  md5_uint32 total[2];
-  md5_uint32 buflen;
-  char buffer[128] __attribute__ ((__aligned__ (__alignof__ (md5_uint32))));
+  sha1_uint32 A;
+  sha1_uint32 B;
+  sha1_uint32 C;
+  sha1_uint32 D;
+  sha1_uint32 E;
+
+  sha1_uint32 total[2];
+  sha1_uint32 buflen;
+  sha1_uint32 buffer[32];
 };
 
 
@@ -84,4 +134,8 @@ extern int sha1_stream (FILE *stream, void *resblock);
    digest.  */
 extern void *sha1_buffer (const char *buffer, size_t len, void *resblock);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif