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_ */