root/lib/md5.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. md5_init_ctx
  2. set_uint32
  3. md5_read_ctx
  4. md5_finish_ctx
  5. md5_buffer
  6. md5_process_bytes
  7. md5_process_block

     1 /* Functions to compute MD5 message digest of files or memory blocks.
     2    according to the definition of MD5 in RFC 1321 from April 1992.
     3    Copyright (C) 1995-1997, 1999-2001, 2005-2006, 2008-2023 Free Software
     4    Foundation, Inc.
     5    This file is part of the GNU C Library.
     6 
     7    This file is free software: you can redistribute it and/or modify
     8    it under the terms of the GNU Lesser General Public License as
     9    published by the Free Software Foundation; either version 2.1 of the
    10    License, or (at your option) any later version.
    11 
    12    This file is distributed in the hope that it will be useful,
    13    but WITHOUT ANY WARRANTY; without even the implied warranty of
    14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    15    GNU Lesser General Public License for more details.
    16 
    17    You should have received a copy of the GNU Lesser General Public License
    18    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
    19 
    20 /* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.  */
    21 
    22 #include <config.h>
    23 
    24 /* Specification.  */
    25 #if HAVE_OPENSSL_MD5
    26 # define GL_OPENSSL_INLINE _GL_EXTERN_INLINE
    27 #endif
    28 #include "md5.h"
    29 
    30 #include <stdint.h>
    31 #include <string.h>
    32 #include <sys/types.h>
    33 
    34 #ifdef _LIBC
    35 # include <endian.h>
    36 # if __BYTE_ORDER == __BIG_ENDIAN
    37 #  define WORDS_BIGENDIAN 1
    38 # endif
    39 /* We need to keep the namespace clean so define the MD5 function
    40    protected using leading __ .  */
    41 # define md5_init_ctx __md5_init_ctx
    42 # define md5_process_block __md5_process_block
    43 # define md5_process_bytes __md5_process_bytes
    44 # define md5_finish_ctx __md5_finish_ctx
    45 # define md5_read_ctx __md5_read_ctx
    46 # define md5_buffer __md5_buffer
    47 #endif
    48 
    49 #include <byteswap.h>
    50 #ifdef WORDS_BIGENDIAN
    51 # define SWAP(n) bswap_32 (n)
    52 #else
    53 # define SWAP(n) (n)
    54 #endif
    55 
    56 #if ! HAVE_OPENSSL_MD5
    57 
    58 /* This array contains the bytes used to pad the buffer to the next
    59    64-byte boundary.  (RFC 1321, 3.1: Step 1)  */
    60 static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ...  */ };
    61 
    62 
    63 /* Initialize structure containing state of computation.
    64    (RFC 1321, 3.3: Step 3)  */
    65 void
    66 md5_init_ctx (struct md5_ctx *ctx)
    67 {
    68   ctx->A = 0x67452301;
    69   ctx->B = 0xefcdab89;
    70   ctx->C = 0x98badcfe;
    71   ctx->D = 0x10325476;
    72 
    73   ctx->total[0] = ctx->total[1] = 0;
    74   ctx->buflen = 0;
    75 }
    76 
    77 /* Copy the 4 byte value from v into the memory location pointed to by *cp,
    78    If your architecture allows unaligned access this is equivalent to
    79    * (uint32_t *) cp = v  */
    80 static void
    81 set_uint32 (char *cp, uint32_t v)
    82 {
    83   memcpy (cp, &v, sizeof v);
    84 }
    85 
    86 /* Put result from CTX in first 16 bytes following RESBUF.  The result
    87    must be in little endian byte order.  */
    88 void *
    89 md5_read_ctx (const struct md5_ctx *ctx, void *resbuf)
    90 {
    91   char *r = resbuf;
    92   set_uint32 (r + 0 * sizeof ctx->A, SWAP (ctx->A));
    93   set_uint32 (r + 1 * sizeof ctx->B, SWAP (ctx->B));
    94   set_uint32 (r + 2 * sizeof ctx->C, SWAP (ctx->C));
    95   set_uint32 (r + 3 * sizeof ctx->D, SWAP (ctx->D));
    96 
    97   return resbuf;
    98 }
    99 
   100 /* Process the remaining bytes in the internal buffer and the usual
   101    prolog according to the standard and write the result to RESBUF.  */
   102 void *
   103 md5_finish_ctx (struct md5_ctx *ctx, void *resbuf)
   104 {
   105   /* Take yet unprocessed bytes into account.  */
   106   uint32_t bytes = ctx->buflen;
   107   size_t size = (bytes < 56) ? 64 / 4 : 64 * 2 / 4;
   108 
   109   /* Now count remaining bytes.  */
   110   ctx->total[0] += bytes;
   111   if (ctx->total[0] < bytes)
   112     ++ctx->total[1];
   113 
   114   /* Put the 64-bit file length in *bits* at the end of the buffer.  */
   115   ctx->buffer[size - 2] = SWAP (ctx->total[0] << 3);
   116   ctx->buffer[size - 1] = SWAP ((ctx->total[1] << 3) | (ctx->total[0] >> 29));
   117 
   118   memcpy (&((char *) ctx->buffer)[bytes], fillbuf, (size - 2) * 4 - bytes);
   119 
   120   /* Process last bytes.  */
   121   md5_process_block (ctx->buffer, size * 4, ctx);
   122 
   123   return md5_read_ctx (ctx, resbuf);
   124 }
   125 
   126 /* Compute MD5 message digest for LEN bytes beginning at BUFFER.  The
   127    result is always in little endian byte order, so that a byte-wise
   128    output yields to the wanted ASCII representation of the message
   129    digest.  */
   130 void *
   131 md5_buffer (const char *buffer, size_t len, void *resblock)
   132 {
   133   struct md5_ctx ctx;
   134 
   135   /* Initialize the computation context.  */
   136   md5_init_ctx (&ctx);
   137 
   138   /* Process whole buffer but last len % 64 bytes.  */
   139   md5_process_bytes (buffer, len, &ctx);
   140 
   141   /* Put result in desired memory area.  */
   142   return md5_finish_ctx (&ctx, resblock);
   143 }
   144 
   145 
   146 void
   147 md5_process_bytes (const void *buffer, size_t len, struct md5_ctx *ctx)
   148 {
   149   /* When we already have some bits in our internal buffer concatenate
   150      both inputs first.  */
   151   if (ctx->buflen != 0)
   152     {
   153       size_t left_over = ctx->buflen;
   154       size_t add = 128 - left_over > len ? len : 128 - left_over;
   155 
   156       memcpy (&((char *) ctx->buffer)[left_over], buffer, add);
   157       ctx->buflen += add;
   158 
   159       if (ctx->buflen > 64)
   160         {
   161           md5_process_block (ctx->buffer, ctx->buflen & ~63, ctx);
   162 
   163           ctx->buflen &= 63;
   164           /* The regions in the following copy operation cannot overlap,
   165              because ctx->buflen < 64 ≤ (left_over + add) & ~63.  */
   166           memcpy (ctx->buffer,
   167                   &((char *) ctx->buffer)[(left_over + add) & ~63],
   168                   ctx->buflen);
   169         }
   170 
   171       buffer = (const char *) buffer + add;
   172       len -= add;
   173     }
   174 
   175   /* Process available complete blocks.  */
   176   if (len >= 64)
   177     {
   178 #if !(_STRING_ARCH_unaligned || _STRING_INLINE_unaligned)
   179 # define UNALIGNED_P(p) ((uintptr_t) (p) % alignof (uint32_t) != 0)
   180       if (UNALIGNED_P (buffer))
   181         while (len > 64)
   182           {
   183             md5_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx);
   184             buffer = (const char *) buffer + 64;
   185             len -= 64;
   186           }
   187       else
   188 #endif
   189         {
   190           md5_process_block (buffer, len & ~63, ctx);
   191           buffer = (const char *) buffer + (len & ~63);
   192           len &= 63;
   193         }
   194     }
   195 
   196   /* Move remaining bytes in internal buffer.  */
   197   if (len > 0)
   198     {
   199       size_t left_over = ctx->buflen;
   200 
   201       memcpy (&((char *) ctx->buffer)[left_over], buffer, len);
   202       left_over += len;
   203       if (left_over >= 64)
   204         {
   205           md5_process_block (ctx->buffer, 64, ctx);
   206           left_over -= 64;
   207           /* The regions in the following copy operation cannot overlap,
   208              because left_over ≤ 64.  */
   209           memcpy (ctx->buffer, &ctx->buffer[16], left_over);
   210         }
   211       ctx->buflen = left_over;
   212     }
   213 }
   214 
   215 
   216 /* These are the four functions used in the four steps of the MD5 algorithm
   217    and defined in the RFC 1321.  The first function is a little bit optimized
   218    (as found in Colin Plumbs public domain implementation).  */
   219 /* #define FF(b, c, d) ((b & c) | (~b & d)) */
   220 #define FF(b, c, d) (d ^ (b & (c ^ d)))
   221 #define FG(b, c, d) FF (d, b, c)
   222 #define FH(b, c, d) (b ^ c ^ d)
   223 #define FI(b, c, d) (c ^ (b | ~d))
   224 
   225 /* Process LEN bytes of BUFFER, accumulating context into CTX.
   226    It is assumed that LEN % 64 == 0.  */
   227 
   228 void
   229 md5_process_block (const void *buffer, size_t len, struct md5_ctx *ctx)
   230 {
   231   uint32_t correct_words[16];
   232   const uint32_t *words = buffer;
   233   size_t nwords = len / sizeof (uint32_t);
   234   const uint32_t *endp = words + nwords;
   235   uint32_t A = ctx->A;
   236   uint32_t B = ctx->B;
   237   uint32_t C = ctx->C;
   238   uint32_t D = ctx->D;
   239   uint32_t lolen = len;
   240 
   241   /* First increment the byte count.  RFC 1321 specifies the possible
   242      length of the file up to 2^64 bits.  Here we only compute the
   243      number of bytes.  Do a double word increment.  */
   244   ctx->total[0] += lolen;
   245   ctx->total[1] += (len >> 31 >> 1) + (ctx->total[0] < lolen);
   246 
   247   /* Process all bytes in the buffer with 64 bytes in each round of
   248      the loop.  */
   249   while (words < endp)
   250     {
   251       uint32_t *cwp = correct_words;
   252       uint32_t A_save = A;
   253       uint32_t B_save = B;
   254       uint32_t C_save = C;
   255       uint32_t D_save = D;
   256 
   257       /* First round: using the given function, the context and a constant
   258          the next context is computed.  Because the algorithms processing
   259          unit is a 32-bit word and it is determined to work on words in
   260          little endian byte order we perhaps have to change the byte order
   261          before the computation.  To reduce the work for the next steps
   262          we store the swapped words in the array CORRECT_WORDS.  */
   263 
   264 #define OP(a, b, c, d, s, T)                                            \
   265       do                                                                \
   266         {                                                               \
   267           a += FF (b, c, d) + (*cwp++ = SWAP (*words)) + T;             \
   268           ++words;                                                      \
   269           CYCLIC (a, s);                                                \
   270           a += b;                                                       \
   271         }                                                               \
   272       while (0)
   273 
   274       /* It is unfortunate that C does not provide an operator for
   275          cyclic rotation.  Hope the C compiler is smart enough.  */
   276 #define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s)))
   277 
   278       /* Before we start, one word to the strange constants.
   279          They are defined in RFC 1321 as
   280 
   281          T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64
   282 
   283          Here is an equivalent invocation using Perl:
   284 
   285          perl -e 'foreach(1..64){printf "0x%08x\n", int (4294967296 * abs (sin $_))}'
   286        */
   287 
   288       /* Round 1.  */
   289       OP (A, B, C, D, 7, 0xd76aa478);
   290       OP (D, A, B, C, 12, 0xe8c7b756);
   291       OP (C, D, A, B, 17, 0x242070db);
   292       OP (B, C, D, A, 22, 0xc1bdceee);
   293       OP (A, B, C, D, 7, 0xf57c0faf);
   294       OP (D, A, B, C, 12, 0x4787c62a);
   295       OP (C, D, A, B, 17, 0xa8304613);
   296       OP (B, C, D, A, 22, 0xfd469501);
   297       OP (A, B, C, D, 7, 0x698098d8);
   298       OP (D, A, B, C, 12, 0x8b44f7af);
   299       OP (C, D, A, B, 17, 0xffff5bb1);
   300       OP (B, C, D, A, 22, 0x895cd7be);
   301       OP (A, B, C, D, 7, 0x6b901122);
   302       OP (D, A, B, C, 12, 0xfd987193);
   303       OP (C, D, A, B, 17, 0xa679438e);
   304       OP (B, C, D, A, 22, 0x49b40821);
   305 
   306       /* For the second to fourth round we have the possibly swapped words
   307          in CORRECT_WORDS.  Redefine the macro to take an additional first
   308          argument specifying the function to use.  */
   309 #undef OP
   310 #define OP(f, a, b, c, d, k, s, T)                                      \
   311       do                                                                \
   312         {                                                               \
   313           a += f (b, c, d) + correct_words[k] + T;                      \
   314           CYCLIC (a, s);                                                \
   315           a += b;                                                       \
   316         }                                                               \
   317       while (0)
   318 
   319       /* Round 2.  */
   320       OP (FG, A, B, C, D, 1, 5, 0xf61e2562);
   321       OP (FG, D, A, B, C, 6, 9, 0xc040b340);
   322       OP (FG, C, D, A, B, 11, 14, 0x265e5a51);
   323       OP (FG, B, C, D, A, 0, 20, 0xe9b6c7aa);
   324       OP (FG, A, B, C, D, 5, 5, 0xd62f105d);
   325       OP (FG, D, A, B, C, 10, 9, 0x02441453);
   326       OP (FG, C, D, A, B, 15, 14, 0xd8a1e681);
   327       OP (FG, B, C, D, A, 4, 20, 0xe7d3fbc8);
   328       OP (FG, A, B, C, D, 9, 5, 0x21e1cde6);
   329       OP (FG, D, A, B, C, 14, 9, 0xc33707d6);
   330       OP (FG, C, D, A, B, 3, 14, 0xf4d50d87);
   331       OP (FG, B, C, D, A, 8, 20, 0x455a14ed);
   332       OP (FG, A, B, C, D, 13, 5, 0xa9e3e905);
   333       OP (FG, D, A, B, C, 2, 9, 0xfcefa3f8);
   334       OP (FG, C, D, A, B, 7, 14, 0x676f02d9);
   335       OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a);
   336 
   337       /* Round 3.  */
   338       OP (FH, A, B, C, D, 5, 4, 0xfffa3942);
   339       OP (FH, D, A, B, C, 8, 11, 0x8771f681);
   340       OP (FH, C, D, A, B, 11, 16, 0x6d9d6122);
   341       OP (FH, B, C, D, A, 14, 23, 0xfde5380c);
   342       OP (FH, A, B, C, D, 1, 4, 0xa4beea44);
   343       OP (FH, D, A, B, C, 4, 11, 0x4bdecfa9);
   344       OP (FH, C, D, A, B, 7, 16, 0xf6bb4b60);
   345       OP (FH, B, C, D, A, 10, 23, 0xbebfbc70);
   346       OP (FH, A, B, C, D, 13, 4, 0x289b7ec6);
   347       OP (FH, D, A, B, C, 0, 11, 0xeaa127fa);
   348       OP (FH, C, D, A, B, 3, 16, 0xd4ef3085);
   349       OP (FH, B, C, D, A, 6, 23, 0x04881d05);
   350       OP (FH, A, B, C, D, 9, 4, 0xd9d4d039);
   351       OP (FH, D, A, B, C, 12, 11, 0xe6db99e5);
   352       OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8);
   353       OP (FH, B, C, D, A, 2, 23, 0xc4ac5665);
   354 
   355       /* Round 4.  */
   356       OP (FI, A, B, C, D, 0, 6, 0xf4292244);
   357       OP (FI, D, A, B, C, 7, 10, 0x432aff97);
   358       OP (FI, C, D, A, B, 14, 15, 0xab9423a7);
   359       OP (FI, B, C, D, A, 5, 21, 0xfc93a039);
   360       OP (FI, A, B, C, D, 12, 6, 0x655b59c3);
   361       OP (FI, D, A, B, C, 3, 10, 0x8f0ccc92);
   362       OP (FI, C, D, A, B, 10, 15, 0xffeff47d);
   363       OP (FI, B, C, D, A, 1, 21, 0x85845dd1);
   364       OP (FI, A, B, C, D, 8, 6, 0x6fa87e4f);
   365       OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
   366       OP (FI, C, D, A, B, 6, 15, 0xa3014314);
   367       OP (FI, B, C, D, A, 13, 21, 0x4e0811a1);
   368       OP (FI, A, B, C, D, 4, 6, 0xf7537e82);
   369       OP (FI, D, A, B, C, 11, 10, 0xbd3af235);
   370       OP (FI, C, D, A, B, 2, 15, 0x2ad7d2bb);
   371       OP (FI, B, C, D, A, 9, 21, 0xeb86d391);
   372 
   373       /* Add the starting values of the context.  */
   374       A += A_save;
   375       B += B_save;
   376       C += C_save;
   377       D += D_save;
   378     }
   379 
   380   /* Put checksum in context given as argument.  */
   381   ctx->A = A;
   382   ctx->B = B;
   383   ctx->C = C;
   384   ctx->D = D;
   385 }
   386 
   387 #endif
   388 
   389 /*
   390  * Hey Emacs!
   391  * Local Variables:
   392  * coding: utf-8
   393  * End:
   394  */

/* [<][>][^][v][top][bottom][index][help] */