diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/Makefile.in | 30 | ||||
| -rw-r--r-- | lib/gnulib.mk | 11 | ||||
| -rw-r--r-- | lib/md5.c | 462 | ||||
| -rw-r--r-- | lib/md5.h | 161 | 
4 files changed, 649 insertions, 15 deletions
| diff --git a/lib/Makefile.in b/lib/Makefile.in index 82e23967865..b0fd92237cd 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -24,7 +24,7 @@  # the same distribution terms as the rest of that program.  #  # Generated by gnulib-tool. -# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=. --makefile-name=gnulib.mk --no-libtool --macro-prefix=gl --no-vc-files dtoastr getloadavg getopt-gnu ignore-value mktime strftime +# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=. --makefile-name=gnulib.mk --no-libtool --macro-prefix=gl --no-vc-files crypto/md5 dtoastr getloadavg getopt-gnu ignore-value mktime strftime  VPATH = @srcdir@  pkgdatadir = $(datadir)/@PACKAGE@ @@ -53,13 +53,13 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/00gnulib.m4 \  	$(top_srcdir)/m4/c-strtod.m4 $(top_srcdir)/m4/extensions.m4 \  	$(top_srcdir)/m4/getloadavg.m4 $(top_srcdir)/m4/getopt.m4 \  	$(top_srcdir)/m4/gl-comp.m4 $(top_srcdir)/m4/gnulib-common.m4 \ -	$(top_srcdir)/m4/include_next.m4 $(top_srcdir)/m4/mktime.m4 \ -	$(top_srcdir)/m4/multiarch.m4 $(top_srcdir)/m4/stdbool.m4 \ -	$(top_srcdir)/m4/stddef_h.m4 $(top_srcdir)/m4/stdlib_h.m4 \ -	$(top_srcdir)/m4/strftime.m4 $(top_srcdir)/m4/time_h.m4 \ -	$(top_srcdir)/m4/time_r.m4 $(top_srcdir)/m4/tm_gmtoff.m4 \ -	$(top_srcdir)/m4/unistd_h.m4 $(top_srcdir)/m4/wchar_t.m4 \ -	$(top_srcdir)/configure.in +	$(top_srcdir)/m4/include_next.m4 $(top_srcdir)/m4/md5.m4 \ +	$(top_srcdir)/m4/mktime.m4 $(top_srcdir)/m4/multiarch.m4 \ +	$(top_srcdir)/m4/stdbool.m4 $(top_srcdir)/m4/stddef_h.m4 \ +	$(top_srcdir)/m4/stdlib_h.m4 $(top_srcdir)/m4/strftime.m4 \ +	$(top_srcdir)/m4/time_h.m4 $(top_srcdir)/m4/time_r.m4 \ +	$(top_srcdir)/m4/tm_gmtoff.m4 $(top_srcdir)/m4/unistd_h.m4 \ +	$(top_srcdir)/m4/wchar_t.m4 $(top_srcdir)/configure.in  am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \  	$(ACLOCAL_M4)  mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs @@ -536,10 +536,11 @@ x_default_search_path = @x_default_search_path@  BUILT_SOURCES = arg-nonnull.h c++defs.h $(GETOPT_H) $(STDBOOL_H) \  	$(STDDEF_H) stdlib.h time.h unistd.h warn-on-use.h  EXTRA_DIST = $(top_srcdir)/./arg-nonnull.h $(top_srcdir)/./c++defs.h \ -	ftoastr.c ftoastr.h getloadavg.c getopt.c getopt.in.h \ -	getopt1.c getopt_int.h intprops.h mktime-internal.h mktime.c \ -	stdbool.in.h stddef.in.h stdlib.in.h strftime.c strftime.h \ -	time.in.h time_r.c unistd.in.h $(top_srcdir)/./warn-on-use.h +	md5.c md5.h ftoastr.c ftoastr.h getloadavg.c getopt.c \ +	getopt.in.h getopt1.c getopt_int.h intprops.h \ +	mktime-internal.h mktime.c stdbool.in.h stddef.in.h \ +	stdlib.in.h strftime.c strftime.h time.in.h time_r.c \ +	unistd.in.h $(top_srcdir)/./warn-on-use.h  MOSTLYCLEANFILES = core *.stackdump arg-nonnull.h arg-nonnull.h-t \  	c++defs.h c++defs.h-t getopt.h getopt.h-t stdbool.h \  	stdbool.h-t stddef.h stddef.h-t stdlib.h stdlib.h-t time.h \ @@ -549,8 +550,8 @@ DEFAULT_INCLUDES = -I. -I../src -I$(top_srcdir)/src  libgnu_a_SOURCES = dtoastr.c gettext.h ignore-value.h  libgnu_a_LIBADD = $(gl_LIBOBJS)  libgnu_a_DEPENDENCIES = $(gl_LIBOBJS) -EXTRA_libgnu_a_SOURCES = ftoastr.c getloadavg.c getopt.c getopt1.c \ -	mktime.c strftime.c time_r.c +EXTRA_libgnu_a_SOURCES = md5.c ftoastr.c getloadavg.c getopt.c \ +	getopt1.c mktime.c strftime.c time_r.c  ARG_NONNULL_H = arg-nonnull.h  CXXDEFS_H = c++defs.h  WARN_ON_USE_H = warn-on-use.h @@ -608,6 +609,7 @@ distclean-compile:  @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getloadavg.Po@am__quote@  @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt.Po@am__quote@  @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt1.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5.Po@am__quote@  @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mktime.Po@am__quote@  @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strftime.Po@am__quote@  @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/time_r.Po@am__quote@ diff --git a/lib/gnulib.mk b/lib/gnulib.mk index 0e7263a002b..31f0fd0328e 100644 --- a/lib/gnulib.mk +++ b/lib/gnulib.mk @@ -9,7 +9,7 @@  # the same distribution terms as the rest of that program.  #  # Generated by gnulib-tool. -# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=. --makefile-name=gnulib.mk --no-libtool --macro-prefix=gl --no-vc-files dtoastr getloadavg getopt-gnu ignore-value mktime strftime +# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=. --makefile-name=gnulib.mk --no-libtool --macro-prefix=gl --no-vc-files crypto/md5 dtoastr getloadavg getopt-gnu ignore-value mktime strftime  MOSTLYCLEANFILES += core *.stackdump @@ -69,6 +69,15 @@ EXTRA_DIST += $(top_srcdir)/./c++defs.h  ## end   gnulib module c++defs +## begin gnulib module crypto/md5 + + +EXTRA_DIST += md5.c md5.h + +EXTRA_libgnu_a_SOURCES += md5.c + +## end   gnulib module crypto/md5 +  ## begin gnulib module dtoastr  libgnu_a_SOURCES += dtoastr.c diff --git a/lib/md5.c b/lib/md5.c new file mode 100644 index 00000000000..7a172e35aa7 --- /dev/null +++ b/lib/md5.c @@ -0,0 +1,462 @@ +/* Functions to compute MD5 message digest of files or memory blocks. +   according to the definition of MD5 in RFC 1321 from April 1992. +   Copyright (C) 1995-1997, 1999-2001, 2005-2006, 2008-2011 Free Software +   Foundation, Inc. +   This file is part of the GNU C Library. + +   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 3, or (at your option) any +   later version. + +   This program is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +   GNU General Public License for more details. + +   You should have received a copy of the GNU General Public License +   along with this program; if not, write to the Free Software Foundation, +   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */ + +/* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.  */ + +#include <config.h> + +#include "md5.h" + +#include <stddef.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> + +#if USE_UNLOCKED_IO +# include "unlocked-io.h" +#endif + +#ifdef _LIBC +# include <endian.h> +# if __BYTE_ORDER == __BIG_ENDIAN +#  define WORDS_BIGENDIAN 1 +# endif +/* We need to keep the namespace clean so define the MD5 function +   protected using leading __ .  */ +# define md5_init_ctx __md5_init_ctx +# define md5_process_block __md5_process_block +# define md5_process_bytes __md5_process_bytes +# define md5_finish_ctx __md5_finish_ctx +# define md5_read_ctx __md5_read_ctx +# define md5_stream __md5_stream +# define md5_buffer __md5_buffer +#endif + +#ifdef WORDS_BIGENDIAN +# define SWAP(n)                                                        \ +    (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24)) +#else +# define SWAP(n) (n) +#endif + +#define BLOCKSIZE 32768 +#if BLOCKSIZE % 64 != 0 +# error "invalid BLOCKSIZE" +#endif + +/* This array contains the bytes used to pad the buffer to the next +   64-byte boundary.  (RFC 1321, 3.1: Step 1)  */ +static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ...  */ }; + + +/* Initialize structure containing state of computation. +   (RFC 1321, 3.3: Step 3)  */ +void +md5_init_ctx (struct md5_ctx *ctx) +{ +  ctx->A = 0x67452301; +  ctx->B = 0xefcdab89; +  ctx->C = 0x98badcfe; +  ctx->D = 0x10325476; + +  ctx->total[0] = ctx->total[1] = 0; +  ctx->buflen = 0; +} + +/* Copy the 4 byte value from v into the memory location pointed to by *cp, +   If your architecture allows unaligned access this is equivalent to +   * (md5_uint32 *) cp = v  */ +static inline void +set_uint32 (char *cp, md5_uint32 v) +{ +  memcpy (cp, &v, sizeof v); +} + +/* Put result from CTX in first 16 bytes following RESBUF.  The result +   must be in little endian byte order.  */ +void * +md5_read_ctx (const struct md5_ctx *ctx, void *resbuf) +{ +  char *r = resbuf; +  set_uint32 (r + 0 * sizeof ctx->A, SWAP (ctx->A)); +  set_uint32 (r + 1 * sizeof ctx->B, SWAP (ctx->B)); +  set_uint32 (r + 2 * sizeof ctx->C, SWAP (ctx->C)); +  set_uint32 (r + 3 * sizeof ctx->D, SWAP (ctx->D)); + +  return resbuf; +} + +/* Process the remaining bytes in the internal buffer and the usual +   prolog according to the standard and write the result to RESBUF.  */ +void * +md5_finish_ctx (struct md5_ctx *ctx, void *resbuf) +{ +  /* Take yet unprocessed bytes into account.  */ +  md5_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]; + +  /* Put the 64-bit file length in *bits* at the end of the buffer.  */ +  ctx->buffer[size - 2] = SWAP (ctx->total[0] << 3); +  ctx->buffer[size - 1] = SWAP ((ctx->total[1] << 3) | (ctx->total[0] >> 29)); + +  memcpy (&((char *) ctx->buffer)[bytes], fillbuf, (size - 2) * 4 - bytes); + +  /* Process last bytes.  */ +  md5_process_block (ctx->buffer, size * 4, ctx); + +  return md5_read_ctx (ctx, resbuf); +} + +/* Compute MD5 message digest for bytes read from STREAM.  The +   resulting message digest number will be written into the 16 bytes +   beginning at RESBLOCK.  */ +int +md5_stream (FILE *stream, void *resblock) +{ +  struct md5_ctx ctx; +  size_t sum; + +  char *buffer = malloc (BLOCKSIZE + 72); +  if (!buffer) +    return 1; + +  /* Initialize the computation context.  */ +  md5_init_ctx (&ctx); + +  /* Iterate over full file contents.  */ +  while (1) +    { +      /* We read the file in blocks of BLOCKSIZE bytes.  One call of the +         computation function processes the whole buffer so that with the +         next round of the loop another block can be read.  */ +      size_t n; +      sum = 0; + +      /* Read block.  Take care for partial reads.  */ +      while (1) +        { +          n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream); + +          sum += n; + +          if (sum == BLOCKSIZE) +            break; + +          if (n == 0) +            { +              /* Check for the error flag IFF N == 0, so that we don't +                 exit the loop after a partial read due to e.g., EAGAIN +                 or EWOULDBLOCK.  */ +              if (ferror (stream)) +                { +                  free (buffer); +                  return 1; +                } +              goto process_partial_block; +            } + +          /* We've read at least one byte, so ignore errors.  But always +             check for EOF, since feof may be true even though N > 0. +             Otherwise, we could end up calling fread after EOF.  */ +          if (feof (stream)) +            goto process_partial_block; +        } + +      /* Process buffer with BLOCKSIZE bytes.  Note that +         BLOCKSIZE % 64 == 0 +       */ +      md5_process_block (buffer, BLOCKSIZE, &ctx); +    } + +process_partial_block: + +  /* Process any remaining bytes.  */ +  if (sum > 0) +    md5_process_bytes (buffer, sum, &ctx); + +  /* Construct result in desired memory.  */ +  md5_finish_ctx (&ctx, resblock); +  free (buffer); +  return 0; +} + +/* Compute MD5 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.  */ +void * +md5_buffer (const char *buffer, size_t len, void *resblock) +{ +  struct md5_ctx ctx; + +  /* Initialize the computation context.  */ +  md5_init_ctx (&ctx); + +  /* Process whole buffer but last len % 64 bytes.  */ +  md5_process_bytes (buffer, len, &ctx); + +  /* Put result in desired memory area.  */ +  return md5_finish_ctx (&ctx, resblock); +} + + +void +md5_process_bytes (const void *buffer, size_t len, struct md5_ctx *ctx) +{ +  /* When we already have some bits in our internal buffer concatenate +     both inputs first.  */ +  if (ctx->buflen != 0) +    { +      size_t left_over = ctx->buflen; +      size_t add = 128 - left_over > len ? len : 128 - left_over; + +      memcpy (&((char *) ctx->buffer)[left_over], buffer, add); +      ctx->buflen += add; + +      if (ctx->buflen > 64) +        { +          md5_process_block (ctx->buffer, ctx->buflen & ~63, ctx); + +          ctx->buflen &= 63; +          /* The regions in the following copy operation cannot overlap.  */ +          memcpy (ctx->buffer, +                  &((char *) ctx->buffer)[(left_over + add) & ~63], +                  ctx->buflen); +        } + +      buffer = (const char *) buffer + add; +      len -= add; +    } + +  /* Process available complete blocks.  */ +  if (len >= 64) +    { +#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) +      if (UNALIGNED_P (buffer)) +        while (len > 64) +          { +            md5_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx); +            buffer = (const char *) buffer + 64; +            len -= 64; +          } +      else +#endif +        { +          md5_process_block (buffer, len & ~63, ctx); +          buffer = (const char *) buffer + (len & ~63); +          len &= 63; +        } +    } + +  /* Move remaining bytes in internal buffer.  */ +  if (len > 0) +    { +      size_t left_over = ctx->buflen; + +      memcpy (&((char *) ctx->buffer)[left_over], buffer, len); +      left_over += len; +      if (left_over >= 64) +        { +          md5_process_block (ctx->buffer, 64, ctx); +          left_over -= 64; +          memcpy (ctx->buffer, &ctx->buffer[16], left_over); +        } +      ctx->buflen = left_over; +    } +} + + +/* These are the four functions used in the four steps of the MD5 algorithm +   and defined in the RFC 1321.  The first function is a little bit optimized +   (as found in Colin Plumbs public domain implementation).  */ +/* #define FF(b, c, d) ((b & c) | (~b & d)) */ +#define FF(b, c, d) (d ^ (b & (c ^ d))) +#define FG(b, c, d) FF (d, b, c) +#define FH(b, c, d) (b ^ c ^ d) +#define FI(b, c, d) (c ^ (b | ~d)) + +/* Process LEN bytes of BUFFER, accumulating context into CTX. +   It is assumed that LEN % 64 == 0.  */ + +void +md5_process_block (const void *buffer, size_t len, struct md5_ctx *ctx) +{ +  md5_uint32 correct_words[16]; +  const md5_uint32 *words = buffer; +  size_t nwords = len / sizeof (md5_uint32); +  const md5_uint32 *endp = words + nwords; +  md5_uint32 A = ctx->A; +  md5_uint32 B = ctx->B; +  md5_uint32 C = ctx->C; +  md5_uint32 D = ctx->D; + +  /* First increment the byte count.  RFC 1321 specifies the possible +     length of the file up to 2^64 bits.  Here we only compute the +     number of bytes.  Do a double word increment.  */ +  ctx->total[0] += len; +  if (ctx->total[0] < len) +    ++ctx->total[1]; + +  /* Process all bytes in the buffer with 64 bytes in each round of +     the loop.  */ +  while (words < endp) +    { +      md5_uint32 *cwp = correct_words; +      md5_uint32 A_save = A; +      md5_uint32 B_save = B; +      md5_uint32 C_save = C; +      md5_uint32 D_save = D; + +      /* First round: using the given function, the context and a constant +         the next context is computed.  Because the algorithms processing +         unit is a 32-bit word and it is determined to work on words in +         little endian byte order we perhaps have to change the byte order +         before the computation.  To reduce the work for the next steps +         we store the swapped words in the array CORRECT_WORDS.  */ + +#define OP(a, b, c, d, s, T)                                            \ +      do                                                                \ +        {                                                               \ +          a += FF (b, c, d) + (*cwp++ = SWAP (*words)) + T;             \ +          ++words;                                                      \ +          CYCLIC (a, s);                                                \ +          a += b;                                                       \ +        }                                                               \ +      while (0) + +      /* It is unfortunate that C does not provide an operator for +         cyclic rotation.  Hope the C compiler is smart enough.  */ +#define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s))) + +      /* Before we start, one word to the strange constants. +         They are defined in RFC 1321 as + +         T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64 + +         Here is an equivalent invocation using Perl: + +         perl -e 'foreach(1..64){printf "0x%08x\n", int (4294967296 * abs (sin $_))}' +       */ + +      /* Round 1.  */ +      OP (A, B, C, D, 7, 0xd76aa478); +      OP (D, A, B, C, 12, 0xe8c7b756); +      OP (C, D, A, B, 17, 0x242070db); +      OP (B, C, D, A, 22, 0xc1bdceee); +      OP (A, B, C, D, 7, 0xf57c0faf); +      OP (D, A, B, C, 12, 0x4787c62a); +      OP (C, D, A, B, 17, 0xa8304613); +      OP (B, C, D, A, 22, 0xfd469501); +      OP (A, B, C, D, 7, 0x698098d8); +      OP (D, A, B, C, 12, 0x8b44f7af); +      OP (C, D, A, B, 17, 0xffff5bb1); +      OP (B, C, D, A, 22, 0x895cd7be); +      OP (A, B, C, D, 7, 0x6b901122); +      OP (D, A, B, C, 12, 0xfd987193); +      OP (C, D, A, B, 17, 0xa679438e); +      OP (B, C, D, A, 22, 0x49b40821); + +      /* For the second to fourth round we have the possibly swapped words +         in CORRECT_WORDS.  Redefine the macro to take an additional first +         argument specifying the function to use.  */ +#undef OP +#define OP(f, a, b, c, d, k, s, T)                                      \ +      do                                                                \ +        {                                                               \ +          a += f (b, c, d) + correct_words[k] + T;                      \ +          CYCLIC (a, s);                                                \ +          a += b;                                                       \ +        }                                                               \ +      while (0) + +      /* Round 2.  */ +      OP (FG, A, B, C, D, 1, 5, 0xf61e2562); +      OP (FG, D, A, B, C, 6, 9, 0xc040b340); +      OP (FG, C, D, A, B, 11, 14, 0x265e5a51); +      OP (FG, B, C, D, A, 0, 20, 0xe9b6c7aa); +      OP (FG, A, B, C, D, 5, 5, 0xd62f105d); +      OP (FG, D, A, B, C, 10, 9, 0x02441453); +      OP (FG, C, D, A, B, 15, 14, 0xd8a1e681); +      OP (FG, B, C, D, A, 4, 20, 0xe7d3fbc8); +      OP (FG, A, B, C, D, 9, 5, 0x21e1cde6); +      OP (FG, D, A, B, C, 14, 9, 0xc33707d6); +      OP (FG, C, D, A, B, 3, 14, 0xf4d50d87); +      OP (FG, B, C, D, A, 8, 20, 0x455a14ed); +      OP (FG, A, B, C, D, 13, 5, 0xa9e3e905); +      OP (FG, D, A, B, C, 2, 9, 0xfcefa3f8); +      OP (FG, C, D, A, B, 7, 14, 0x676f02d9); +      OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a); + +      /* Round 3.  */ +      OP (FH, A, B, C, D, 5, 4, 0xfffa3942); +      OP (FH, D, A, B, C, 8, 11, 0x8771f681); +      OP (FH, C, D, A, B, 11, 16, 0x6d9d6122); +      OP (FH, B, C, D, A, 14, 23, 0xfde5380c); +      OP (FH, A, B, C, D, 1, 4, 0xa4beea44); +      OP (FH, D, A, B, C, 4, 11, 0x4bdecfa9); +      OP (FH, C, D, A, B, 7, 16, 0xf6bb4b60); +      OP (FH, B, C, D, A, 10, 23, 0xbebfbc70); +      OP (FH, A, B, C, D, 13, 4, 0x289b7ec6); +      OP (FH, D, A, B, C, 0, 11, 0xeaa127fa); +      OP (FH, C, D, A, B, 3, 16, 0xd4ef3085); +      OP (FH, B, C, D, A, 6, 23, 0x04881d05); +      OP (FH, A, B, C, D, 9, 4, 0xd9d4d039); +      OP (FH, D, A, B, C, 12, 11, 0xe6db99e5); +      OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8); +      OP (FH, B, C, D, A, 2, 23, 0xc4ac5665); + +      /* Round 4.  */ +      OP (FI, A, B, C, D, 0, 6, 0xf4292244); +      OP (FI, D, A, B, C, 7, 10, 0x432aff97); +      OP (FI, C, D, A, B, 14, 15, 0xab9423a7); +      OP (FI, B, C, D, A, 5, 21, 0xfc93a039); +      OP (FI, A, B, C, D, 12, 6, 0x655b59c3); +      OP (FI, D, A, B, C, 3, 10, 0x8f0ccc92); +      OP (FI, C, D, A, B, 10, 15, 0xffeff47d); +      OP (FI, B, C, D, A, 1, 21, 0x85845dd1); +      OP (FI, A, B, C, D, 8, 6, 0x6fa87e4f); +      OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0); +      OP (FI, C, D, A, B, 6, 15, 0xa3014314); +      OP (FI, B, C, D, A, 13, 21, 0x4e0811a1); +      OP (FI, A, B, C, D, 4, 6, 0xf7537e82); +      OP (FI, D, A, B, C, 11, 10, 0xbd3af235); +      OP (FI, C, D, A, B, 2, 15, 0x2ad7d2bb); +      OP (FI, B, C, D, A, 9, 21, 0xeb86d391); + +      /* Add the starting values of the context.  */ +      A += A_save; +      B += B_save; +      C += C_save; +      D += D_save; +    } + +  /* Put checksum in context given as argument.  */ +  ctx->A = A; +  ctx->B = B; +  ctx->C = C; +  ctx->D = D; +} diff --git a/lib/md5.h b/lib/md5.h new file mode 100644 index 00000000000..332b036590a --- /dev/null +++ b/lib/md5.h @@ -0,0 +1,161 @@ +/* Declaration of functions and data types used for MD5 sum computing +   library functions. +   Copyright (C) 1995-1997, 1999-2001, 2004-2006, 2008-2011 Free Software +   Foundation, Inc. +   This file is part of the GNU C Library. + +   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 3, or (at your option) any +   later version. + +   This program is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +   GNU General Public License for more details. + +   You should have received a copy of the GNU General Public License +   along with this program; if not, write to the Free Software Foundation, +   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */ + +#ifndef _MD5_H +#define _MD5_H 1 + +#include <stdio.h> + +#define MD5_DIGEST_SIZE 16 +#define MD5_BLOCK_SIZE 64 + +#ifndef __GNUC_PREREQ +# if defined __GNUC__ && defined __GNUC_MINOR__ +#  define __GNUC_PREREQ(maj, min)                                       \ +  ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min)) +# else +#  define __GNUC_PREREQ(maj, min) 0 +# endif +#endif + +#ifndef __THROW +# if defined __cplusplus && __GNUC_PREREQ (2,8) +#  define __THROW       throw () +# else +#  define __THROW +# endif +#endif + +#ifndef _LIBC +# define __md5_buffer md5_buffer +# define __md5_finish_ctx md5_finish_ctx +# define __md5_init_ctx md5_init_ctx +# define __md5_process_block md5_process_block +# define __md5_process_bytes md5_process_bytes +# define __md5_read_ctx md5_read_ctx +# define __md5_stream md5_stream +#endif + +# ifdef __cplusplus +extern "C" { +# endif + +/* 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.  */ + +#if defined _LIBC +# include <stdint.h> +typedef uint32_t md5_uint32; +#else +# if defined __STDC__ && __STDC__ +#  define UINT_MAX_32_BITS 4294967295U +# else +#  define UINT_MAX_32_BITS 0xFFFFFFFF +# endif + +# include <limits.h> + +# if UINT_MAX == UINT_MAX_32_BITS +   typedef unsigned int md5_uint32; +# else +#  if USHRT_MAX == UINT_MAX_32_BITS +    typedef unsigned short md5_uint32; +#  else +#   if ULONG_MAX == UINT_MAX_32_BITS +     typedef unsigned long md5_uint32; +#   else +     /* A machine this weird should have <stdint.h>.  */ +#    include <stdint.h> +     typedef uint32_t md5_uint32; +#   endif +#  endif +# endif +#endif + +/* Structure to save state of computation between the single steps.  */ +struct md5_ctx +{ +  md5_uint32 A; +  md5_uint32 B; +  md5_uint32 C; +  md5_uint32 D; + +  md5_uint32 total[2]; +  md5_uint32 buflen; +  md5_uint32 buffer[32]; +}; + +/* + * The following three functions are build up the low level used in + * the functions `md5_stream' and `md5_buffer'. + */ + +/* Initialize structure containing state of computation. +   (RFC 1321, 3.3: Step 3)  */ +extern void __md5_init_ctx (struct md5_ctx *ctx) __THROW; + +/* Starting with the result of former calls of this function (or the +   initialization function update the context for the next LEN bytes +   starting at BUFFER. +   It is necessary that LEN is a multiple of 64!!! */ +extern void __md5_process_block (const void *buffer, size_t len, +                                 struct md5_ctx *ctx) __THROW; + +/* Starting with the result of former calls of this function (or the +   initialization function update the context for the next LEN bytes +   starting at BUFFER. +   It is NOT required that LEN is a multiple of 64.  */ +extern void __md5_process_bytes (const void *buffer, size_t len, +                                 struct md5_ctx *ctx) __THROW; + +/* Process the remaining bytes in the buffer and put result from CTX +   in first 16 bytes following RESBUF.  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.  */ +extern void *__md5_finish_ctx (struct md5_ctx *ctx, void *resbuf) __THROW; + + +/* Put result from CTX in first 16 bytes following RESBUF.  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.  */ +extern void *__md5_read_ctx (const struct md5_ctx *ctx, void *resbuf) __THROW; + + +/* Compute MD5 message digest for bytes read from STREAM.  The +   resulting message digest number will be written into the 16 bytes +   beginning at RESBLOCK.  */ +extern int __md5_stream (FILE *stream, void *resblock) __THROW; + +/* Compute MD5 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.  */ +extern void *__md5_buffer (const char *buffer, size_t len, +                           void *resblock) __THROW; + +# ifdef __cplusplus +} +# endif + +#endif /* md5.h */ | 
