Blame md5.c

Packit 96c956
/*
Packit 96c956
 ***********************************************************************
Packit 96c956
 ** md5.c -- the source code for MD5 routines                         **
Packit 96c956
 ** RSA Data Security, Inc. MD5 Message-Digest Algorithm              **
Packit 96c956
 ** Created: 2/17/90 RLR                                              **
Packit 96c956
 ** Revised: 1/91 SRD,AJ,BSK,JT Reference C Version                   **
Packit 96c956
 ** Revised (for MD5): RLR 4/27/91                                    **
Packit 96c956
 **   -- G modified to have y&~z instead of y&z                       **
Packit 96c956
 **   -- FF, GG, HH modified to add in last register done             **
Packit 96c956
 **   -- Access pattern: round 2 works mod 5, round 3 works mod 3     **
Packit 96c956
 **   -- distinct additive constant for each step                     **
Packit 96c956
 **   -- round 4 added, working mod 7                                 **
Packit 96c956
 ***********************************************************************
Packit 96c956
 */
Packit 96c956
Packit 96c956
/*
Packit 96c956
 ***********************************************************************
Packit 96c956
 ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved.  **
Packit 96c956
 **                                                                   **
Packit 96c956
 ** License to copy and use this software is granted provided that    **
Packit 96c956
 ** it is identified as the "RSA Data Security, Inc. MD5 Message-     **
Packit 96c956
 ** Digest Algorithm" in all material mentioning or referencing this  **
Packit 96c956
 ** software or this function.                                        **
Packit 96c956
 **                                                                   **
Packit 96c956
 ** License is also granted to make and use derivative works          **
Packit 96c956
 ** provided that such works are identified as "derived from the RSA  **
Packit 96c956
 ** Data Security, Inc. MD5 Message-Digest Algorithm" in all          **
Packit 96c956
 ** material mentioning or referencing the derived work.              **
Packit 96c956
 **                                                                   **
Packit 96c956
 ** RSA Data Security, Inc. makes no representations concerning       **
Packit 96c956
 ** either the merchantability of this software or the suitability    **
Packit 96c956
 ** of this software for any particular purpose.  It is provided "as  **
Packit 96c956
 ** is" without express or implied warranty of any kind.              **
Packit 96c956
 **                                                                   **
Packit 96c956
 ** These notices must be retained in any copies of any part of this  **
Packit 96c956
 ** documentation and/or software.                                    **
Packit 96c956
 ***********************************************************************
Packit 96c956
 */
Packit 96c956
Packit 96c956
#include "md5.h"
Packit 96c956
Packit 96c956
/*
Packit 96c956
 ***********************************************************************
Packit 96c956
 **  Message-digest routines:                                         **
Packit 96c956
 **  To form the message digest for a message M                       **
Packit 96c956
 **    (1) Initialize a context buffer mdContext using MD5Init        **
Packit 96c956
 **    (2) Call MD5Update on mdContext and M                          **
Packit 96c956
 **    (3) Call MD5Final on mdContext                                 **
Packit 96c956
 **  The message digest is now in mdContext->digest[0...15]           **
Packit 96c956
 ***********************************************************************
Packit 96c956
 */
Packit 96c956
Packit 96c956
/* forward declaration */
Packit 96c956
static void Transform (UINT4 *, UINT4 *);
Packit 96c956
Packit 96c956
#ifdef	__STDC__
Packit 96c956
static const
Packit 96c956
#else
Packit 96c956
static
Packit 96c956
#endif
Packit 96c956
unsigned char PADDING[64] = {
Packit 96c956
  0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Packit 96c956
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Packit 96c956
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Packit 96c956
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Packit 96c956
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Packit 96c956
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Packit 96c956
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Packit 96c956
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
Packit 96c956
};
Packit 96c956
Packit 96c956
/* F, G, H and I are basic MD5 functions */
Packit 96c956
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
Packit 96c956
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
Packit 96c956
#define H(x, y, z) ((x) ^ (y) ^ (z))
Packit 96c956
#define I(x, y, z) ((y) ^ ((x) | (~z)))
Packit 96c956
Packit 96c956
/* ROTATE_LEFT rotates x left n bits */
Packit 96c956
#if	defined(FAST_MD5) && defined(__GNUC__) && defined(mc68000)
Packit 96c956
/*
Packit 96c956
 * If we're on a 68000 based CPU and using a GNU C compiler with
Packit 96c956
 * inline assembly code, we can speed this up a bit.
Packit 96c956
 */
Packit 96c956
inline UINT4 ROTATE_LEFT(UINT4 x, int n)
Packit 96c956
{   
Packit 96c956
    asm("roll %2,%0" : "=d" (x) : "0" (x), "Ir" (n));
Packit 96c956
    return x;
Packit 96c956
}
Packit 96c956
#else
Packit 96c956
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
Packit 96c956
#endif
Packit 96c956
Packit 96c956
Packit 96c956
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */
Packit 96c956
/* Rotation is separate from addition to prevent recomputation */
Packit 96c956
#define FF(a, b, c, d, x, s, ac) \
Packit 96c956
  {(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
Packit 96c956
   (a) = ROTATE_LEFT ((a), (s)); \
Packit 96c956
   (a) += (b); \
Packit 96c956
  }
Packit 96c956
#define GG(a, b, c, d, x, s, ac) \
Packit 96c956
  {(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
Packit 96c956
   (a) = ROTATE_LEFT ((a), (s)); \
Packit 96c956
   (a) += (b); \
Packit 96c956
  }
Packit 96c956
#define HH(a, b, c, d, x, s, ac) \
Packit 96c956
  {(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
Packit 96c956
   (a) = ROTATE_LEFT ((a), (s)); \
Packit 96c956
   (a) += (b); \
Packit 96c956
  }
Packit 96c956
#define II(a, b, c, d, x, s, ac) \
Packit 96c956
  {(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
Packit 96c956
   (a) = ROTATE_LEFT ((a), (s)); \
Packit 96c956
   (a) += (b); \
Packit 96c956
  }
Packit 96c956
Packit 96c956
/* The routine MD5Init initializes the message-digest context
Packit 96c956
   mdContext. All fields are set to zero.
Packit 96c956
 */
Packit 96c956
void MD5Init (mdContext)
Packit 96c956
MD5_CTX *mdContext;
Packit 96c956
{
Packit 96c956
  mdContext->i[0] = mdContext->i[1] = (UINT4)0;
Packit 96c956
Packit 96c956
  /* Load magic initialization constants.
Packit 96c956
   */
Packit 96c956
  mdContext->buf[0] = (UINT4)0x67452301;
Packit 96c956
  mdContext->buf[1] = (UINT4)0xefcdab89;
Packit 96c956
  mdContext->buf[2] = (UINT4)0x98badcfe;
Packit 96c956
  mdContext->buf[3] = (UINT4)0x10325476;
Packit 96c956
}
Packit 96c956
Packit 96c956
/* The routine MD5Update updates the message-digest context to
Packit 96c956
   account for the presence of each of the characters inBuf[0..inLen-1]
Packit 96c956
   in the message whose digest is being computed.
Packit 96c956
 */
Packit 96c956
void MD5Update (mdContext, inBuf, inLen)
Packit 96c956
MD5_CTX *mdContext;
Packit 96c956
unsigned const char *inBuf;
Packit 96c956
unsigned int inLen;
Packit 96c956
{
Packit 96c956
  UINT4 in[16];
Packit 96c956
  int mdi;
Packit 96c956
  unsigned int i, ii;
Packit 96c956
Packit 96c956
  /* compute number of bytes mod 64 */
Packit 96c956
  mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
Packit 96c956
Packit 96c956
  /* update number of bits */
Packit 96c956
  if ((mdContext->i[0] + ((UINT4)inLen << 3)) < mdContext->i[0])
Packit 96c956
    mdContext->i[1]++;
Packit 96c956
  mdContext->i[0] += ((UINT4)inLen << 3);
Packit 96c956
  mdContext->i[1] += ((UINT4)inLen >> 29);
Packit 96c956
Packit 96c956
  while (inLen--) {
Packit 96c956
    /* add new character to buffer, increment mdi */
Packit 96c956
    mdContext->in[mdi++] = *inBuf++;
Packit 96c956
Packit 96c956
    /* transform if necessary */
Packit 96c956
    if (mdi == 0x40) {
Packit 96c956
      for (i = 0, ii = 0; i < 16; i++, ii += 4)
Packit 96c956
        in[i] = (((UINT4)mdContext->in[ii+3]) << 24) |
Packit 96c956
                (((UINT4)mdContext->in[ii+2]) << 16) |
Packit 96c956
                (((UINT4)mdContext->in[ii+1]) << 8) |
Packit 96c956
                ((UINT4)mdContext->in[ii]);
Packit 96c956
      Transform (mdContext->buf, in);
Packit 96c956
      mdi = 0;
Packit 96c956
    }
Packit 96c956
  }
Packit 96c956
}
Packit 96c956
Packit 96c956
/* The routine MD5Final terminates the message-digest computation and
Packit 96c956
   ends with the desired message digest in mdContext->digest[0...15].
Packit 96c956
 */
Packit 96c956
Packit 96c956
void MD5Final (mdContext)
Packit 96c956
MD5_CTX *mdContext;
Packit 96c956
{
Packit 96c956
  UINT4 in[16];
Packit 96c956
  int mdi;
Packit 96c956
  unsigned int i, ii;
Packit 96c956
  unsigned int padLen;
Packit 96c956
Packit 96c956
  /* save number of bits */
Packit 96c956
  in[14] = mdContext->i[0];
Packit 96c956
  in[15] = mdContext->i[1];
Packit 96c956
Packit 96c956
  /* compute number of bytes mod 64 */
Packit 96c956
  mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
Packit 96c956
Packit 96c956
  /* pad out to 56 mod 64 */
Packit 96c956
  padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi);
Packit 96c956
  MD5Update (mdContext, PADDING, padLen);
Packit 96c956
Packit 96c956
  /* append length in bits and transform */
Packit 96c956
  for (i = 0, ii = 0; i < 14; i++, ii += 4)
Packit 96c956
    in[i] = (((UINT4)mdContext->in[ii+3]) << 24) |
Packit 96c956
            (((UINT4)mdContext->in[ii+2]) << 16) |
Packit 96c956
            (((UINT4)mdContext->in[ii+1]) << 8) |
Packit 96c956
            ((UINT4)mdContext->in[ii]);
Packit 96c956
  Transform (mdContext->buf, in);
Packit 96c956
Packit 96c956
  /* store buffer in digest */
Packit 96c956
  for (i = 0, ii = 0; i < 4; i++, ii += 4) {
Packit 96c956
    mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF);
Packit 96c956
    mdContext->digest[ii+1] =
Packit 96c956
      (unsigned char)((mdContext->buf[i] >> 8) & 0xFF);
Packit 96c956
    mdContext->digest[ii+2] =
Packit 96c956
      (unsigned char)((mdContext->buf[i] >> 16) & 0xFF);
Packit 96c956
    mdContext->digest[ii+3] =
Packit 96c956
      (unsigned char)((mdContext->buf[i] >> 24) & 0xFF);
Packit 96c956
  }
Packit 96c956
}
Packit 96c956
Packit 96c956
/* Basic MD5 step. Transforms buf based on in.
Packit 96c956
 */
Packit 96c956
static void Transform (buf, in)
Packit 96c956
UINT4 *buf;
Packit 96c956
UINT4 *in;
Packit 96c956
{
Packit 96c956
  UINT4 a = buf[0], b = buf[1], c = buf[2], d = buf[3];
Packit 96c956
Packit 96c956
  /* Round 1 */
Packit 96c956
#define S11 7
Packit 96c956
#define S12 12
Packit 96c956
#define S13 17
Packit 96c956
#define S14 22
Packit 96c956
Packit 96c956
  FF ( a, b, c, d, in[ 0], S11, 0xd76aa478); /* 1 */
Packit 96c956
  FF ( d, a, b, c, in[ 1], S12, 0xe8c7b756); /* 2 */
Packit 96c956
  FF ( c, d, a, b, in[ 2], S13, 0x242070db); /* 3 */
Packit 96c956
  FF ( b, c, d, a, in[ 3], S14, 0xc1bdceee); /* 4 */
Packit 96c956
  FF ( a, b, c, d, in[ 4], S11, 0xf57c0faf); /* 5 */
Packit 96c956
  FF ( d, a, b, c, in[ 5], S12, 0x4787c62a); /* 6 */
Packit 96c956
  FF ( c, d, a, b, in[ 6], S13, 0xa8304613); /* 7 */
Packit 96c956
  FF ( b, c, d, a, in[ 7], S14, 0xfd469501); /* 8 */
Packit 96c956
  FF ( a, b, c, d, in[ 8], S11, 0x698098d8); /* 9 */
Packit 96c956
  FF ( d, a, b, c, in[ 9], S12, 0x8b44f7af); /* 10 */
Packit 96c956
  FF ( c, d, a, b, in[10], S13, 0xffff5bb1); /* 11 */
Packit 96c956
  FF ( b, c, d, a, in[11], S14, 0x895cd7be); /* 12 */
Packit 96c956
  FF ( a, b, c, d, in[12], S11, 0x6b901122); /* 13 */
Packit 96c956
  FF ( d, a, b, c, in[13], S12, 0xfd987193); /* 14 */
Packit 96c956
  FF ( c, d, a, b, in[14], S13, 0xa679438e); /* 15 */
Packit 96c956
  FF ( b, c, d, a, in[15], S14, 0x49b40821); /* 16 */
Packit 96c956
Packit 96c956
  /* Round 2 */
Packit 96c956
#define S21 5
Packit 96c956
#define S22 9
Packit 96c956
#define S23 14
Packit 96c956
#define S24 20
Packit 96c956
  GG ( a, b, c, d, in[ 1], S21, 0xf61e2562); /* 17 */
Packit 96c956
  GG ( d, a, b, c, in[ 6], S22, 0xc040b340); /* 18 */
Packit 96c956
  GG ( c, d, a, b, in[11], S23, 0x265e5a51); /* 19 */
Packit 96c956
  GG ( b, c, d, a, in[ 0], S24, 0xe9b6c7aa); /* 20 */
Packit 96c956
  GG ( a, b, c, d, in[ 5], S21, 0xd62f105d); /* 21 */
Packit 96c956
  GG ( d, a, b, c, in[10], S22,  0x2441453); /* 22 */
Packit 96c956
  GG ( c, d, a, b, in[15], S23, 0xd8a1e681); /* 23 */
Packit 96c956
  GG ( b, c, d, a, in[ 4], S24, 0xe7d3fbc8); /* 24 */
Packit 96c956
  GG ( a, b, c, d, in[ 9], S21, 0x21e1cde6); /* 25 */
Packit 96c956
  GG ( d, a, b, c, in[14], S22, 0xc33707d6); /* 26 */
Packit 96c956
  GG ( c, d, a, b, in[ 3], S23, 0xf4d50d87); /* 27 */
Packit 96c956
  GG ( b, c, d, a, in[ 8], S24, 0x455a14ed); /* 28 */
Packit 96c956
  GG ( a, b, c, d, in[13], S21, 0xa9e3e905); /* 29 */
Packit 96c956
  GG ( d, a, b, c, in[ 2], S22, 0xfcefa3f8); /* 30 */
Packit 96c956
  GG ( c, d, a, b, in[ 7], S23, 0x676f02d9); /* 31 */
Packit 96c956
  GG ( b, c, d, a, in[12], S24, 0x8d2a4c8a); /* 32 */
Packit 96c956
Packit 96c956
  /* Round 3 */
Packit 96c956
#define S31 4
Packit 96c956
#define S32 11
Packit 96c956
#define S33 16
Packit 96c956
#define S34 23
Packit 96c956
  HH ( a, b, c, d, in[ 5], S31, 0xfffa3942); /* 33 */
Packit 96c956
  HH ( d, a, b, c, in[ 8], S32, 0x8771f681); /* 34 */
Packit 96c956
  HH ( c, d, a, b, in[11], S33, 0x6d9d6122); /* 35 */
Packit 96c956
  HH ( b, c, d, a, in[14], S34, 0xfde5380c); /* 36 */
Packit 96c956
  HH ( a, b, c, d, in[ 1], S31, 0xa4beea44); /* 37 */
Packit 96c956
  HH ( d, a, b, c, in[ 4], S32, 0x4bdecfa9); /* 38 */
Packit 96c956
  HH ( c, d, a, b, in[ 7], S33, 0xf6bb4b60); /* 39 */
Packit 96c956
  HH ( b, c, d, a, in[10], S34, 0xbebfbc70); /* 40 */
Packit 96c956
  HH ( a, b, c, d, in[13], S31, 0x289b7ec6); /* 41 */
Packit 96c956
  HH ( d, a, b, c, in[ 0], S32, 0xeaa127fa); /* 42 */
Packit 96c956
  HH ( c, d, a, b, in[ 3], S33, 0xd4ef3085); /* 43 */
Packit 96c956
  HH ( b, c, d, a, in[ 6], S34,  0x4881d05); /* 44 */
Packit 96c956
  HH ( a, b, c, d, in[ 9], S31, 0xd9d4d039); /* 45 */
Packit 96c956
  HH ( d, a, b, c, in[12], S32, 0xe6db99e5); /* 46 */
Packit 96c956
  HH ( c, d, a, b, in[15], S33, 0x1fa27cf8); /* 47 */
Packit 96c956
  HH ( b, c, d, a, in[ 2], S34, 0xc4ac5665); /* 48 */
Packit 96c956
Packit 96c956
  /* Round 4 */
Packit 96c956
#define S41 6
Packit 96c956
#define S42 10
Packit 96c956
#define S43 15
Packit 96c956
#define S44 21
Packit 96c956
  II ( a, b, c, d, in[ 0], S41, 0xf4292244); /* 49 */
Packit 96c956
  II ( d, a, b, c, in[ 7], S42, 0x432aff97); /* 50 */
Packit 96c956
  II ( c, d, a, b, in[14], S43, 0xab9423a7); /* 51 */
Packit 96c956
  II ( b, c, d, a, in[ 5], S44, 0xfc93a039); /* 52 */
Packit 96c956
  II ( a, b, c, d, in[12], S41, 0x655b59c3); /* 53 */
Packit 96c956
  II ( d, a, b, c, in[ 3], S42, 0x8f0ccc92); /* 54 */
Packit 96c956
  II ( c, d, a, b, in[10], S43, 0xffeff47d); /* 55 */
Packit 96c956
  II ( b, c, d, a, in[ 1], S44, 0x85845dd1); /* 56 */
Packit 96c956
  II ( a, b, c, d, in[ 8], S41, 0x6fa87e4f); /* 57 */
Packit 96c956
  II ( d, a, b, c, in[15], S42, 0xfe2ce6e0); /* 58 */
Packit 96c956
  II ( c, d, a, b, in[ 6], S43, 0xa3014314); /* 59 */
Packit 96c956
  II ( b, c, d, a, in[13], S44, 0x4e0811a1); /* 60 */
Packit 96c956
  II ( a, b, c, d, in[ 4], S41, 0xf7537e82); /* 61 */
Packit 96c956
  II ( d, a, b, c, in[11], S42, 0xbd3af235); /* 62 */
Packit 96c956
  II ( c, d, a, b, in[ 2], S43, 0x2ad7d2bb); /* 63 */
Packit 96c956
  II ( b, c, d, a, in[ 9], S44, 0xeb86d391); /* 64 */
Packit 96c956
Packit 96c956
  buf[0] += a;
Packit 96c956
  buf[1] += b;
Packit 96c956
  buf[2] += c;
Packit 96c956
  buf[3] += d;
Packit 96c956
}
Packit 96c956
Packit 96c956
/*
Packit 96c956
 ***********************************************************************
Packit 96c956
 ** End of md5.c                                                      **
Packit 96c956
 ******************************** (cut) ********************************
Packit 96c956
 */