1  /* MD5.H - header file for MD5C.C - Source: RFC1321
  2  This program is derived from the RSA Data Security,
  3  Inc. MD5 Message-Digest Algorithm. */
  4  
  5  #ifndef _MD5_H_
  6  #define _MD5_H_
  7  
  8  #include <string.h>
  9  #include <windows.h>
 10  
 11  /* F, G, H and I are basic MD5 functions. */
 12  #define F(x, y, z) (((x) &  (y)) | ((~x) & ( z)))
 13  #define G(x, y, z) (((x) &  (z)) | (( y) & (~z)))
 14  #define H(x, y, z) ( (x) ^  (y)          ^ ( z))
 15  #define I(x, y, z) ( (y) ^ ((x)          | (~z)))
 16  
 17  /* ROTATE_LEFT rotates x left n bits. */
 18  #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
 19  
 20  /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
 21  Rotation is separate from addition to prevent recomputation. */
 22  #define MM(a, b, c, d, x, s, t, sw, _M_)  {                                 \
 23      ((a) = (b) + ROTATE_LEFT(((a) + _M_((b), (c), (d)) + (x) + (t)), (s))); \
 24      (sw) = (d); (d) = (c); (c) = (b); (b) = (a); (a) = (sw); continue; }
 25  
 26  #define FF(a, b, c, d, x, s, t, sw)  MM(a, b, c, d, x, s, t, sw, F)
 27  #define GG(a, b, c, d, x, s, t, sw)  MM(a, b, c, d, x, s, t, sw, G)
 28  #define HH(a, b, c, d, x, s, t, sw)  MM(a, b, c, d, x, s, t, sw, H)
 29  #define II(a, b, c, d, x, s, t, sw)  MM(a, b, c, d, x, s, t, sw, I)
 30  
 31  #define U8( addr, offset)  (unsigned char) (* (                        (( (unsigned char *) (addr)) + (offset) )) )  /* UINT32 to UCHAR  */
 32  #define U32(addr, offset)                  (* ( (unsigned int       *) ((                   (addr)) + (offset) )) )  /* UCHAR  to UINT32 */
 33  #define U64(addr, offset)                  (* ( (unsigned long long *) ((                   (addr)) + (offset) )) )  /* UCHAR  to UINT64 */
 34  
 35  #define MD5_BUFFER 4096
 36  
 37  typedef struct  /* MD5 context. */
 38  {
 39      UINT32 state[4];   /* state (ABCD) */
 40      UINT32 count[2];   /* number of bits, modulo 2^64 (lsb first) */
 41      UCHAR buffer[64];  /* input buffer */
 42  } MD5_CTX;
 43  
 44  UCHAR Padding[64] = { 0x80  /* , 0, 0, 0, ... */  };
 45  
 46  UCHAR wOrder[48] =  /* wOrder[64] = */
 47  { /*0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, */
 48      1,  6, 11,  0,  5, 10, 15,  4,  9, 14,  3,  8, 13,  2,  7, 12,
 49      5,  8, 11, 14,  1,  4,  7, 10, 13,  0,  3,  6,  9, 12, 15,  2,
 50      0,  7, 14,  5, 12,  3, 10,  1,  8, 15,  6, 13,  4, 11,  2,  9
 51  };
 52  
 53  UCHAR rOrder[64] =
 54  {
 55      7, 12, 17, 22,  7, 12, 17, 22,  7, 12, 17, 22,  7, 12, 17, 22,
 56      5,  9, 14, 20,  5,  9, 14, 20,  5,  9, 14, 20,  5,  9, 14, 20,
 57      4, 11, 16, 23,  4, 11, 16, 23,  4, 11, 16, 23,  4, 11, 16, 23,
 58      6, 10, 15, 21,  6, 10, 15, 21,  6, 10, 15, 21,  6, 10, 15, 21
 59  };
 60  
 61  UINT32 kOrder[64] =
 62  {
 63      0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
 64      0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
 65      0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
 66      0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
 67      0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
 68      0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
 69      0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
 70      0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391
 71  };
 72  
 73  static void MD5Init   (MD5_CTX *context);
 74  static void MD5Update (MD5_CTX *context, const UCHAR *input, const UINT32 inputLen);
 75  static void MD5Final  (UCHAR digest[16], MD5_CTX *context);
 76  
 77  /* MD5 basic transformation. Transforms state based on block. */
 78  static void MD5Transform (UINT32 state[4], const UCHAR block[64])
 79  {
 80      UINT32 i, t, a = state[0], b = state[1], c = state[2], d = state[3], x[16];
 81  
 82      /* Decodes input (UCHAR) into output (UINT32). Assumes len is a multiple of 4. */
 83      for (i = 0; i < 16; i++)
 84          x[i] = U32 (block, i << 2);
 85  
 86      for (i = 0; i < 64; i++)
 87      {
 88          if (           i < 16) FF (a, b, c, d, x[i           ], rOrder[i], kOrder[i], t);  /* wOrder[0..15] = i */
 89          if (i >= 16 && i < 32) GG (a, b, c, d, x[wOrder[i-16]], rOrder[i], kOrder[i], t);
 90          if (i >= 32 && i < 48) HH (a, b, c, d, x[wOrder[i-16]], rOrder[i], kOrder[i], t);
 91          if (i >= 48          ) II (a, b, c, d, x[wOrder[i-16]], rOrder[i], kOrder[i], t);
 92      }
 93  
 94      state[0] += a;
 95      state[1] += b;
 96      state[2] += c;
 97      state[3] += d;
 98  }  /* MD5Transform */
 99  
100  /* MD5 initialization. Begins an MD5 operation, writing a new context. */
101  static void MD5Init (MD5_CTX *context)
102  {
103      context->count[0] = context->count[1] = 0;
104      /* Load magic initialization constants. */
105      context->state[0] = 0x67452301;
106      context->state[1] = 0xefcdab89;
107      context->state[2] = 0x98badcfe;
108      context->state[3] = 0x10325476;
109  }  /* MD5Init */
110  
111  /* MD5 block update operation. Continues an MD5 message-digest operation,
112  processing another message block, and updating the context. */
113  static void MD5Update (MD5_CTX *context, const UCHAR *input, const UINT32 inputLen)
114  {
115      /* Compute number of bytes mod 64 */
116      UINT32 index   = (context->count[0] >> 3) & 0x3f;
117      UINT32 partLen = 64 - index, i = 0;
118  
119      /* Update number of bits */
120      context->count[0] += inputLen << 3 ;
121      context->count[1] += inputLen >> 29;
122  
123      if (inputLen >= partLen)  /* Transform as many times as possible. */
124      {
125          memcpy (&context->buffer[index], input, partLen);
126          MD5Transform (context->state, context->buffer);
127  
128          for (i = partLen; i + 63 < inputLen; i += 64)
129              MD5Transform (context->state, &input[i]);
130  
131          index = 0;
132      }
133  
134      /* Buffer remaining input */
135      memcpy (&context->buffer[index], &input[i], inputLen - i);
136  }  /* MD5Update */
137  
138  /* MD5 finalization. Ends an MD5 message-digest operation,
139  writing the the message digest and zeroizing the context. */
140  static void MD5Final (UCHAR digest[16], MD5_CTX *context)
141  {
142      UCHAR bits[8];
143      UINT32 padLen = (context->count[0] >> 3) & 0x3f, i;  /* Pad out to 56 mod 64. */
144      padLen = (padLen < 56) ? (56 - padLen) : (120 - padLen);
145  
146      for (i = 0; i < 8; i++)               /* Save number of bits */
147          bits[i] = U8 (context->count, i);
148      MD5Update (context, Padding, padLen);
149      MD5Update (context, bits, 8);         /* Append length (before padding) */
150      for (i = 0; i < 16; i++)              /* Store state in digest */
151          digest[i] = U8 (context->state, i);
152  }  /* MD5Final */
153  
154  #endif  /* _MD5_H_ */