Blame alg-md5.c

Packit 13e0ca
/* Functions to compute MD5 message digest of files or memory blocks.
Packit 13e0ca
   according to the definition of MD5 in RFC 1321 from April 1992.
Packit 13e0ca
Packit 13e0ca
   Copyright (C) 1995-2017 Free Software Foundation, Inc.
Packit 13e0ca
Packit 13e0ca
   This library is free software; you can redistribute it and/or
Packit 13e0ca
   modify it under the terms of the GNU Lesser General Public License
Packit 13e0ca
   as published by the Free Software Foundation; either version 2.1 of
Packit 13e0ca
   the License, or (at your option) any later version.
Packit 13e0ca
Packit 13e0ca
   This library is distributed in the hope that it will be useful,
Packit 13e0ca
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 13e0ca
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 13e0ca
   GNU Lesser General Public License for more details.
Packit 13e0ca
Packit 13e0ca
   You should have received a copy of the GNU Lesser General Public
Packit 13e0ca
   License along with this library; if not, see
Packit 13e0ca
   <https://www.gnu.org/licenses/>.  */
Packit 13e0ca
Packit 13e0ca
/* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.  */
Packit 13e0ca
Packit 13e0ca
#include "crypt-port.h"
Packit 13e0ca
#include "alg-md5.h"
Packit 13e0ca
#include "byteorder.h"
Packit 13e0ca
Packit 13e0ca
#if INCLUDE_md5 || INCLUDE_sunmd5
Packit 13e0ca
Packit 13e0ca
static void md5_process_block (const void *buffer, size_t len,
Packit 13e0ca
                               struct md5_ctx *ctx);
Packit 13e0ca
Packit 13e0ca
/* Initialize structure containing state of computation.
Packit 13e0ca
   (RFC 1321, 3.3: Step 3)  */
Packit 13e0ca
void
Packit 13e0ca
md5_init_ctx (struct md5_ctx *ctx)
Packit 13e0ca
{
Packit 13e0ca
  ctx->A = 0x67452301;
Packit 13e0ca
  ctx->B = 0xefcdab89;
Packit 13e0ca
  ctx->C = 0x98badcfe;
Packit 13e0ca
  ctx->D = 0x10325476;
Packit 13e0ca
Packit 13e0ca
  ctx->total = 0;
Packit 13e0ca
  ctx->buflen = 0;
Packit 13e0ca
}
Packit 13e0ca
Packit 13e0ca
/* Put result from CTX in first 16 bytes following RESBUF.  The result
Packit 13e0ca
   will be in little endian byte order.  */
Packit 13e0ca
static void *
Packit 13e0ca
md5_read_ctx (struct md5_ctx *ctx, void *resbuf)
Packit 13e0ca
{
Packit 13e0ca
  unsigned char *buf = resbuf;
Packit 13e0ca
  cpu_to_le32 (buf +  0, ctx->A);
Packit 13e0ca
  cpu_to_le32 (buf +  4, ctx->B);
Packit 13e0ca
  cpu_to_le32 (buf +  8, ctx->C);
Packit 13e0ca
  cpu_to_le32 (buf + 12, ctx->D);
Packit 13e0ca
  XCRYPT_SECURE_MEMSET (ctx, sizeof(*ctx));
Packit 13e0ca
  return resbuf;
Packit 13e0ca
}
Packit 13e0ca
Packit 13e0ca
/* Process the remaining bytes in the internal buffer and the usual
Packit 13e0ca
   prolog according to the standard and write the result to RESBUF.  */
Packit 13e0ca
Packit 13e0ca
void *
Packit 13e0ca
md5_finish_ctx (struct md5_ctx *ctx, void *resbuf)
Packit 13e0ca
{
Packit 13e0ca
  /* Take yet unprocessed bytes into account.  */
Packit 13e0ca
  uint32_t bytes = ctx->buflen;
Packit 13e0ca
  size_t pad;
Packit 13e0ca
Packit 13e0ca
  /* Now count remaining bytes.  */
Packit 13e0ca
  ctx->total += bytes;
Packit 13e0ca
Packit 13e0ca
  pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes;
Packit 13e0ca
Packit 13e0ca
  /* The first byte of padding should be 0x80 and the rest should be
Packit 13e0ca
     zero.  (RFC 1321, 3.1: Step 1) */
Packit 13e0ca
  ctx->buffer[bytes] = 0x80u;
Packit 13e0ca
  XCRYPT_SECURE_MEMSET (&ctx->buffer[bytes+1], pad-1);
Packit 13e0ca
Packit 13e0ca
  /* Put the 64-bit file length in little-endian *bits* at the end of
Packit 13e0ca
     the buffer.  */
Packit 13e0ca
  cpu_to_le64 (&ctx->buffer[bytes + pad], ctx->total << 3);
Packit 13e0ca
Packit 13e0ca
  /* Process last bytes.  */
Packit 13e0ca
  md5_process_block (ctx->buffer, bytes + pad + 8, ctx);
Packit 13e0ca
Packit 13e0ca
  return md5_read_ctx (ctx, resbuf);
Packit 13e0ca
}
Packit 13e0ca
Packit 13e0ca
Packit 13e0ca
void
Packit 13e0ca
md5_process_bytes (const void *buffer, size_t len, struct md5_ctx *ctx)
Packit 13e0ca
{
Packit 13e0ca
  /* When we already have some bits in our internal buffer concatenate
Packit 13e0ca
     both inputs first.  */
Packit 13e0ca
  if (ctx->buflen != 0)
Packit 13e0ca
    {
Packit 13e0ca
      uint32_t left_over = ctx->buflen;
Packit 13e0ca
      uint32_t add = 128 - left_over > len ? (uint32_t)len : 128 - left_over;
Packit 13e0ca
Packit 13e0ca
      memcpy (&ctx->buffer[left_over], buffer, add);
Packit 13e0ca
      ctx->buflen += add;
Packit 13e0ca
Packit 13e0ca
      if (ctx->buflen > 64)
Packit 13e0ca
        {
Packit 13e0ca
          md5_process_block (ctx->buffer, ctx->buflen & ~63u, ctx);
Packit 13e0ca
Packit 13e0ca
          ctx->buflen &= 63;
Packit 13e0ca
          /* The regions in the following copy operation cannot overlap.  */
Packit 13e0ca
          memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~63u],
Packit 13e0ca
                  ctx->buflen);
Packit 13e0ca
        }
Packit 13e0ca
Packit 13e0ca
      buffer = (const char *) buffer + add;
Packit 13e0ca
      len -= add;
Packit 13e0ca
    }
Packit 13e0ca
Packit 13e0ca
  /* Process available complete blocks.  */
Packit 13e0ca
  if (len > 64)
Packit 13e0ca
    {
Packit 13e0ca
      md5_process_block (buffer, len & ~63u, ctx);
Packit 13e0ca
      buffer = (const char *) buffer + (len & ~63u);
Packit 13e0ca
      len &= 63;
Packit 13e0ca
    }
Packit 13e0ca
Packit 13e0ca
  /* Move remaining bytes in internal buffer.  */
Packit 13e0ca
  if (len > 0)
Packit 13e0ca
    {
Packit 13e0ca
      uint32_t left_over = ctx->buflen;
Packit 13e0ca
Packit 13e0ca
      memcpy (&ctx->buffer[left_over], buffer, len);
Packit 13e0ca
      left_over += (uint32_t)len;
Packit 13e0ca
      if (left_over >= 64)
Packit 13e0ca
        {
Packit 13e0ca
          md5_process_block (ctx->buffer, 64, ctx);
Packit 13e0ca
          left_over -= 64;
Packit 13e0ca
          memcpy (ctx->buffer, &ctx->buffer[64], left_over);
Packit 13e0ca
        }
Packit 13e0ca
      ctx->buflen = left_over;
Packit 13e0ca
    }
Packit 13e0ca
}
Packit 13e0ca
Packit 13e0ca
Packit 13e0ca
/* These are the four functions used in the four steps of the MD5 algorithm
Packit 13e0ca
   and defined in the RFC 1321.  The first function is a little bit optimized
Packit 13e0ca
   (as found in Colin Plumbs public domain implementation).  */
Packit 13e0ca
/* #define FF(b, c, d) ((b & c) | (~b & d)) */
Packit 13e0ca
#define FF(b, c, d) (d ^ (b & (c ^ d)))
Packit 13e0ca
#define FG(b, c, d) FF (d, b, c)
Packit 13e0ca
#define FH(b, c, d) (b ^ c ^ d)
Packit 13e0ca
#define FI(b, c, d) (c ^ (b | ~d))
Packit 13e0ca
Packit 13e0ca
/* Process LEN bytes of BUFFER, accumulating context into CTX.
Packit 13e0ca
   It is assumed that LEN % 64 == 0.  */
Packit 13e0ca
Packit 13e0ca
static void
Packit 13e0ca
md5_process_block (const void *buffer, size_t len, struct md5_ctx *ctx)
Packit 13e0ca
{
Packit 13e0ca
  const unsigned char *p = buffer;
Packit 13e0ca
  const unsigned char *endp = p + len;
Packit 13e0ca
  uint32_t A = ctx->A;
Packit 13e0ca
  uint32_t B = ctx->B;
Packit 13e0ca
  uint32_t C = ctx->C;
Packit 13e0ca
  uint32_t D = ctx->D;
Packit 13e0ca
Packit 13e0ca
  /* First increment the byte count.  RFC 1321 specifies the possible
Packit 13e0ca
     length of the file up to 2^64 bits.  Here we only compute the
Packit 13e0ca
     number of bytes.  */
Packit 13e0ca
  ctx->total += len;
Packit 13e0ca
Packit 13e0ca
  /* Process all bytes in the buffer with 64 bytes in each round of
Packit 13e0ca
     the loop.  */
Packit 13e0ca
  while (p < endp)
Packit 13e0ca
    {
Packit 13e0ca
      uint32_t *cwp = ctx->correct_words;
Packit 13e0ca
      uint32_t A_save = A;
Packit 13e0ca
      uint32_t B_save = B;
Packit 13e0ca
      uint32_t C_save = C;
Packit 13e0ca
      uint32_t D_save = D;
Packit 13e0ca
Packit 13e0ca
      /* First round: using the given function, the context and a constant
Packit 13e0ca
         the next context is computed.  Because the algorithms processing
Packit 13e0ca
         unit is a 32-bit word and it is determined to work on words in
Packit 13e0ca
         little endian byte order we perhaps have to change the byte order
Packit 13e0ca
         before the computation.  To reduce the work for the next steps
Packit 13e0ca
         we store the swapped words in the array CORRECT_WORDS.  */
Packit 13e0ca
Packit 13e0ca
#define OP(a, b, c, d, s, T)                                            \
Packit 13e0ca
      do                                                                \
Packit 13e0ca
        {                                                               \
Packit 13e0ca
          uint32_t word = le32_to_cpu (p);                              \
Packit 13e0ca
          p += 4;                                                       \
Packit 13e0ca
          *cwp++ = word;                                                \
Packit 13e0ca
          a += FF (b, c, d) + word + T;                                 \
Packit 13e0ca
          CYCLIC (a, s);                                                \
Packit 13e0ca
          a += b;                                                       \
Packit 13e0ca
        }                                                               \
Packit 13e0ca
      while (0)
Packit 13e0ca
Packit 13e0ca
      /* It is unfortunate that C does not provide an operator for
Packit 13e0ca
         cyclic rotation.  Hope the C compiler is smart enough.  */
Packit 13e0ca
#define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s)))
Packit 13e0ca
Packit 13e0ca
      /* Before we start, one word to the strange constants.
Packit 13e0ca
         They are defined in RFC 1321 as
Packit 13e0ca
Packit 13e0ca
         T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64
Packit 13e0ca
       */
Packit 13e0ca
Packit 13e0ca
      /* Round 1.  */
Packit 13e0ca
      OP (A, B, C, D,  7, 0xd76aa478);
Packit 13e0ca
      OP (D, A, B, C, 12, 0xe8c7b756);
Packit 13e0ca
      OP (C, D, A, B, 17, 0x242070db);
Packit 13e0ca
      OP (B, C, D, A, 22, 0xc1bdceee);
Packit 13e0ca
      OP (A, B, C, D,  7, 0xf57c0faf);
Packit 13e0ca
      OP (D, A, B, C, 12, 0x4787c62a);
Packit 13e0ca
      OP (C, D, A, B, 17, 0xa8304613);
Packit 13e0ca
      OP (B, C, D, A, 22, 0xfd469501);
Packit 13e0ca
      OP (A, B, C, D,  7, 0x698098d8);
Packit 13e0ca
      OP (D, A, B, C, 12, 0x8b44f7af);
Packit 13e0ca
      OP (C, D, A, B, 17, 0xffff5bb1);
Packit 13e0ca
      OP (B, C, D, A, 22, 0x895cd7be);
Packit 13e0ca
      OP (A, B, C, D,  7, 0x6b901122);
Packit 13e0ca
      OP (D, A, B, C, 12, 0xfd987193);
Packit 13e0ca
      OP (C, D, A, B, 17, 0xa679438e);
Packit 13e0ca
      OP (B, C, D, A, 22, 0x49b40821);
Packit 13e0ca
Packit 13e0ca
      /* For the second to fourth round we have the possibly swapped words
Packit 13e0ca
         in CORRECT_WORDS.  Redefine the macro to take an additional first
Packit 13e0ca
         argument specifying the function to use.  */
Packit 13e0ca
#undef OP
Packit 13e0ca
#define OP(f, a, b, c, d, k, s, T)                                      \
Packit 13e0ca
      do                                                                \
Packit 13e0ca
        {                                                               \
Packit 13e0ca
          a += f (b, c, d) + ctx->correct_words[k] + T;                 \
Packit 13e0ca
          CYCLIC (a, s);                                                \
Packit 13e0ca
          a += b;                                                       \
Packit 13e0ca
        }                                                               \
Packit 13e0ca
      while (0)
Packit 13e0ca
Packit 13e0ca
      /* Round 2.  */
Packit 13e0ca
      OP (FG, A, B, C, D,  1,  5, 0xf61e2562);
Packit 13e0ca
      OP (FG, D, A, B, C,  6,  9, 0xc040b340);
Packit 13e0ca
      OP (FG, C, D, A, B, 11, 14, 0x265e5a51);
Packit 13e0ca
      OP (FG, B, C, D, A,  0, 20, 0xe9b6c7aa);
Packit 13e0ca
      OP (FG, A, B, C, D,  5,  5, 0xd62f105d);
Packit 13e0ca
      OP (FG, D, A, B, C, 10,  9, 0x02441453);
Packit 13e0ca
      OP (FG, C, D, A, B, 15, 14, 0xd8a1e681);
Packit 13e0ca
      OP (FG, B, C, D, A,  4, 20, 0xe7d3fbc8);
Packit 13e0ca
      OP (FG, A, B, C, D,  9,  5, 0x21e1cde6);
Packit 13e0ca
      OP (FG, D, A, B, C, 14,  9, 0xc33707d6);
Packit 13e0ca
      OP (FG, C, D, A, B,  3, 14, 0xf4d50d87);
Packit 13e0ca
      OP (FG, B, C, D, A,  8, 20, 0x455a14ed);
Packit 13e0ca
      OP (FG, A, B, C, D, 13,  5, 0xa9e3e905);
Packit 13e0ca
      OP (FG, D, A, B, C,  2,  9, 0xfcefa3f8);
Packit 13e0ca
      OP (FG, C, D, A, B,  7, 14, 0x676f02d9);
Packit 13e0ca
      OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a);
Packit 13e0ca
Packit 13e0ca
      /* Round 3.  */
Packit 13e0ca
      OP (FH, A, B, C, D,  5,  4, 0xfffa3942);
Packit 13e0ca
      OP (FH, D, A, B, C,  8, 11, 0x8771f681);
Packit 13e0ca
      OP (FH, C, D, A, B, 11, 16, 0x6d9d6122);
Packit 13e0ca
      OP (FH, B, C, D, A, 14, 23, 0xfde5380c);
Packit 13e0ca
      OP (FH, A, B, C, D,  1,  4, 0xa4beea44);
Packit 13e0ca
      OP (FH, D, A, B, C,  4, 11, 0x4bdecfa9);
Packit 13e0ca
      OP (FH, C, D, A, B,  7, 16, 0xf6bb4b60);
Packit 13e0ca
      OP (FH, B, C, D, A, 10, 23, 0xbebfbc70);
Packit 13e0ca
      OP (FH, A, B, C, D, 13,  4, 0x289b7ec6);
Packit 13e0ca
      OP (FH, D, A, B, C,  0, 11, 0xeaa127fa);
Packit 13e0ca
      OP (FH, C, D, A, B,  3, 16, 0xd4ef3085);
Packit 13e0ca
      OP (FH, B, C, D, A,  6, 23, 0x04881d05);
Packit 13e0ca
      OP (FH, A, B, C, D,  9,  4, 0xd9d4d039);
Packit 13e0ca
      OP (FH, D, A, B, C, 12, 11, 0xe6db99e5);
Packit 13e0ca
      OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8);
Packit 13e0ca
      OP (FH, B, C, D, A,  2, 23, 0xc4ac5665);
Packit 13e0ca
Packit 13e0ca
      /* Round 4.  */
Packit 13e0ca
      OP (FI, A, B, C, D,  0,  6, 0xf4292244);
Packit 13e0ca
      OP (FI, D, A, B, C,  7, 10, 0x432aff97);
Packit 13e0ca
      OP (FI, C, D, A, B, 14, 15, 0xab9423a7);
Packit 13e0ca
      OP (FI, B, C, D, A,  5, 21, 0xfc93a039);
Packit 13e0ca
      OP (FI, A, B, C, D, 12,  6, 0x655b59c3);
Packit 13e0ca
      OP (FI, D, A, B, C,  3, 10, 0x8f0ccc92);
Packit 13e0ca
      OP (FI, C, D, A, B, 10, 15, 0xffeff47d);
Packit 13e0ca
      OP (FI, B, C, D, A,  1, 21, 0x85845dd1);
Packit 13e0ca
      OP (FI, A, B, C, D,  8,  6, 0x6fa87e4f);
Packit 13e0ca
      OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
Packit 13e0ca
      OP (FI, C, D, A, B,  6, 15, 0xa3014314);
Packit 13e0ca
      OP (FI, B, C, D, A, 13, 21, 0x4e0811a1);
Packit 13e0ca
      OP (FI, A, B, C, D,  4,  6, 0xf7537e82);
Packit 13e0ca
      OP (FI, D, A, B, C, 11, 10, 0xbd3af235);
Packit 13e0ca
      OP (FI, C, D, A, B,  2, 15, 0x2ad7d2bb);
Packit 13e0ca
      OP (FI, B, C, D, A,  9, 21, 0xeb86d391);
Packit 13e0ca
Packit 13e0ca
      /* Add the starting values of the context.  */
Packit 13e0ca
      A += A_save;
Packit 13e0ca
      B += B_save;
Packit 13e0ca
      C += C_save;
Packit 13e0ca
      D += D_save;
Packit 13e0ca
    }
Packit 13e0ca
Packit 13e0ca
  /* Put checksum in context given as argument.  */
Packit 13e0ca
  ctx->A = A;
Packit 13e0ca
  ctx->B = B;
Packit 13e0ca
  ctx->C = C;
Packit 13e0ca
  ctx->D = D;
Packit 13e0ca
}
Packit 13e0ca
Packit 13e0ca
#endif