md5c.c revision 1803
1/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
2 * $FreeBSD: head/sys/kern/md5c.c 1803 1994-07-24 03:29:56Z phk $
3 */
4
5/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
6rights reserved.
7
8License to copy and use this software is granted provided that it
9is identified as the "RSA Data Security, Inc. MD5 Message-Digest
10Algorithm" in all material mentioning or referencing this software
11or this function.
12
13License is also granted to make and use derivative works provided
14that such works are identified as "derived from the RSA Data
15Security, Inc. MD5 Message-Digest Algorithm" in all material
16mentioning or referencing the derived work.
17
18RSA Data Security, Inc. makes no representations concerning either
19the merchantability of this software or the suitability of this
20software for any particular purpose. It is provided "as is"
21without express or implied warranty of any kind.
22
23These notices must be retained in any copies of any part of this
24documentation and/or software.
25 */
26
27#include "md5.h"
28
29typedef unsigned char *POINTER;
30typedef unsigned short int UINT2;
31typedef unsigned long int UINT4;
32
33#define PROTO_LIST(list) list
34
35/* Constants for MD5Transform routine.
36 */
37#define S11 7
38#define S12 12
39#define S13 17
40#define S14 22
41#define S21 5
42#define S22 9
43#define S23 14
44#define S24 20
45#define S31 4
46#define S32 11
47#define S33 16
48#define S34 23
49#define S41 6
50#define S42 10
51#define S43 15
52#define S44 21
53
54static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64]));
55static void Encode PROTO_LIST
56  ((unsigned char *, UINT4 *, unsigned int));
57static void Decode PROTO_LIST
58  ((UINT4 *, unsigned char *, unsigned int));
59
60static unsigned char PADDING[64] = {
61  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
62  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
63  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
64};
65
66/* F, G, H and I are basic MD5 functions.
67 */
68#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
69#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
70#define H(x, y, z) ((x) ^ (y) ^ (z))
71#define I(x, y, z) ((y) ^ ((x) | (~z)))
72
73/* ROTATE_LEFT rotates x left n bits.
74 */
75#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
76
77/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
78Rotation is separate from addition to prevent recomputation.
79 */
80#define FF(a, b, c, d, x, s, ac) { \
81 (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
82 (a) = ROTATE_LEFT ((a), (s)); \
83 (a) += (b); \
84  }
85#define GG(a, b, c, d, x, s, ac) { \
86 (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
87 (a) = ROTATE_LEFT ((a), (s)); \
88 (a) += (b); \
89  }
90#define HH(a, b, c, d, x, s, ac) { \
91 (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
92 (a) = ROTATE_LEFT ((a), (s)); \
93 (a) += (b); \
94  }
95#define II(a, b, c, d, x, s, ac) { \
96 (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
97 (a) = ROTATE_LEFT ((a), (s)); \
98 (a) += (b); \
99  }
100
101/* MD5 initialization. Begins an MD5 operation, writing a new context.
102 */
103void MD5Init (context)
104MD5_CTX *context;                                        /* context */
105{
106  context->count[0] = context->count[1] = 0;
107  /* Load magic initialization constants.
108*/
109  context->state[0] = 0x67452301;
110  context->state[1] = 0xefcdab89;
111  context->state[2] = 0x98badcfe;
112  context->state[3] = 0x10325476;
113}
114
115/* MD5 block update operation. Continues an MD5 message-digest
116  operation, processing another message block, and updating the
117  context.
118 */
119void MD5Update (context, input, inputLen)
120MD5_CTX *context;                                        /* context */
121unsigned char *input;                                /* input block */
122unsigned int inputLen;                     /* length of input block */
123{
124  unsigned int i, index, partLen;
125
126  /* Compute number of bytes mod 64 */
127  index = (unsigned int)((context->count[0] >> 3) & 0x3F);
128
129  /* Update number of bits */
130  if ((context->count[0] += ((UINT4)inputLen << 3))
131   < ((UINT4)inputLen << 3))
132 context->count[1]++;
133  context->count[1] += ((UINT4)inputLen >> 29);
134
135  partLen = 64 - index;
136
137  /* Transform as many times as possible.
138*/
139  if (inputLen >= partLen) {
140 memcpy
141   ((POINTER)&context->buffer[index], (POINTER)input, partLen);
142 MD5Transform (context->state, context->buffer);
143
144 for (i = partLen; i + 63 < inputLen; i += 64)
145   MD5Transform (context->state, &input[i]);
146
147 index = 0;
148  }
149  else
150 i = 0;
151
152  /* Buffer remaining input */
153  memcpy
154 ((POINTER)&context->buffer[index], (POINTER)&input[i],
155  inputLen-i);
156}
157
158/* MD5 finalization. Ends an MD5 message-digest operation, writing the
159  the message digest and zeroizing the context.
160 */
161void MD5Final (digest, context)
162unsigned char digest[16];                         /* message digest */
163MD5_CTX *context;                                       /* context */
164{
165  unsigned char bits[8];
166  unsigned int index, padLen;
167
168  /* Save number of bits */
169  Encode (bits, context->count, 8);
170
171  /* Pad out to 56 mod 64.
172*/
173  index = (unsigned int)((context->count[0] >> 3) & 0x3f);
174  padLen = (index < 56) ? (56 - index) : (120 - index);
175  MD5Update (context, PADDING, padLen);
176
177  /* Append length (before padding) */
178  MD5Update (context, bits, 8);
179  /* Store state in digest */
180  Encode (digest, context->state, 16);
181
182  /* Zeroize sensitive information.
183*/
184  memset ((POINTER)context, 0, sizeof (*context));
185}
186
187/* MD5 basic transformation. Transforms state based on block.
188 */
189static void MD5Transform (state, block)
190UINT4 state[4];
191unsigned char block[64];
192{
193  UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
194
195  Decode (x, block, 64);
196
197  /* Round 1 */
198  FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
199  FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
200  FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
201  FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
202  FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
203  FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
204  FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
205  FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
206  FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
207  FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
208  FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
209  FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
210  FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
211  FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
212  FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
213  FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
214
215 /* Round 2 */
216  GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
217  GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
218  GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
219  GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
220  GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
221  GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */
222  GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
223  GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
224  GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
225  GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
226  GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
227  GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
228  GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
229  GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
230  GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
231  GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
232
233  /* Round 3 */
234  HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
235  HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
236  HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
237  HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
238  HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
239  HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
240  HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
241  HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
242  HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
243  HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
244  HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
245  HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
246  HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
247  HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
248  HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
249  HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
250
251  /* Round 4 */
252  II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
253  II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
254  II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
255  II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
256  II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
257  II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
258  II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
259  II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
260  II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
261  II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
262  II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
263  II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
264  II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
265  II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
266  II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
267  II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
268
269  state[0] += a;
270  state[1] += b;
271  state[2] += c;
272  state[3] += d;
273
274  /* Zeroize sensitive information.
275*/
276  memset ((POINTER)x, 0, sizeof (x));
277}
278
279/* Encodes input (UINT4) into output (unsigned char). Assumes len is
280  a multiple of 4.
281 */
282static void Encode (output, input, len)
283unsigned char *output;
284UINT4 *input;
285unsigned int len;
286{
287  unsigned int i, j;
288
289  for (i = 0, j = 0; j < len; i++, j += 4) {
290 output[j] = (unsigned char)(input[i] & 0xff);
291 output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
292 output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
293 output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
294  }
295}
296
297/* Decodes input (unsigned char) into output (UINT4). Assumes len is
298  a multiple of 4.
299 */
300static void Decode (output, input, len)
301UINT4 *output;
302unsigned char *input;
303unsigned int len;
304{
305  unsigned int i, j;
306
307  for (i = 0, j = 0; j < len; i++, j += 4)
308 output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
309   (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
310}
311