2 Copyright (c) 1995-1998 by Cisco systems, Inc.
4 Permission to use, copy, modify, and distribute this software for
5 any purpose and without fee is hereby granted, provided that this
6 copyright and permission notice appear on all copies of the
7 software and supporting documentation, the name of Cisco Systems,
8 Inc. not be used in advertising or publicity pertaining to
9 distribution of the program without specific prior permission, and
10 notice be given in supporting documentation that modification,
11 copying and distribution is by permission of Cisco Systems, Inc.
13 Cisco Systems, Inc. makes no representations about the suitability
14 of this software for any purpose. THIS SOFTWARE IS PROVIDED ``AS
15 IS'' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
16 WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
17 FITNESS FOR A PARTICULAR PURPOSE.
20 /* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
23 /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
26 License to copy and use this software is granted provided that it
27 is identified as the "RSA Data Security, Inc. MD5 Message-Digest
28 Algorithm" in all material mentioning or referencing this software
31 License is also granted to make and use derivative works provided
32 that such works are identified as "derived from the RSA Data
33 Security, Inc. MD5 Message-Digest Algorithm" in all material
34 mentioning or referencing the derived work.
36 RSA Data Security, Inc. makes no representations concerning either
37 the merchantability of this software or the suitability of this
38 software for any particular purpose. It is provided "as is"
39 without express or implied warranty of any kind.
41 These notices must be retained in any copies of any part of this
42 documentation and/or software.
46 * RFC 1321 version #includes global.h, but md5.h has been locally modified
47 * to contain all the information that RFC 1321's global.h contains.
52 /* Constants for MD5Transform routine.
73 static void MD5Transform PROTO_LIST((UINT4[4], unsigned char[64]));
74 static void Encode PROTO_LIST
75 ((unsigned char *, UINT4 *, unsigned int));
76 static void Decode PROTO_LIST
77 ((UINT4 *, unsigned char *, unsigned int));
79 #if !defined(MD5_NEED_MEM_FUNCS)
81 #define MD5_memcpy(out,in,len) memcpy(out, in, len)
82 #define MD5_memset(ptr,val,len) memset(ptr, val, len)
84 #else /* !defined(MD5_NEED_MEM_FUNCS) */
86 static void MD5_memcpy PROTO_LIST((POINTER, POINTER, unsigned int));
87 static void MD5_memset PROTO_LIST((POINTER, int, unsigned int));
89 #endif /* !defined(MD5_NEED_MEM_FUNCS) */
91 static unsigned char PADDING[64] = {
92 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
93 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
94 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
97 /* F, G, H and I are basic MD5 functions.
99 #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
100 #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
101 #define H(x, y, z) ((x) ^ (y) ^ (z))
102 #define I(x, y, z) ((y) ^ ((x) | (~z)))
104 /* ROTATE_LEFT rotates x left n bits.
106 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
108 /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
109 Rotation is separate from addition to prevent recomputation.
111 #define FF(a, b, c, d, x, s, ac) { \
112 (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
113 (a) = ROTATE_LEFT ((a), (s)); \
116 #define GG(a, b, c, d, x, s, ac) { \
117 (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
118 (a) = ROTATE_LEFT ((a), (s)); \
121 #define HH(a, b, c, d, x, s, ac) { \
122 (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
123 (a) = ROTATE_LEFT ((a), (s)); \
126 #define II(a, b, c, d, x, s, ac) { \
127 (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
128 (a) = ROTATE_LEFT ((a), (s)); \
132 /* MD5 initialization. Begins an MD5 operation, writing a new context.
136 MD5_CTX *context; /* context */
138 context->count[0] = context->count[1] = 0;
139 /* Load magic initialization constants. */
140 context->state[0] = 0x67452301;
141 context->state[1] = 0xefcdab89;
142 context->state[2] = 0x98badcfe;
143 context->state[3] = 0x10325476;
146 /* MD5 block update operation. Continues an MD5 message-digest
147 operation, processing another message block, and updating the
151 MD5Update(context, input, inputLen)
152 MD5_CTX *context; /* context */
153 unsigned char *input; /* input block */
154 unsigned int inputLen; /* length of input block */
156 unsigned int i, index, partLen;
158 /* Compute number of bytes mod 64 */
159 index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
161 /* Update number of bits */
162 if ((context->count[0] += ((UINT4) inputLen << 3))
163 < ((UINT4) inputLen << 3))
165 context->count[1] += ((UINT4) inputLen >> 29);
167 partLen = 64 - index;
169 /* Transform as many times as possible. */
170 if (inputLen >= partLen) {
172 ((POINTER) & context->buffer[index], (POINTER) input, partLen);
173 MD5Transform(context->state, context->buffer);
175 for (i = partLen; i + 63 < inputLen; i += 64)
176 MD5Transform(context->state, &input[i]);
182 /* Buffer remaining input */
184 ((POINTER) & context->buffer[index], (POINTER) & input[i],
188 /* MD5 finalization. Ends an MD5 message-digest operation, writing the
189 the message digest and zeroizing the context.
192 MD5Final(digest, context)
193 unsigned char digest[16]; /* message digest */
194 MD5_CTX *context; /* context */
196 unsigned char bits[8];
197 unsigned int index, padLen;
199 /* Save number of bits */
200 Encode(bits, context->count, 8);
202 /* Pad out to 56 mod 64. */
203 index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
204 padLen = (index < 56) ? (56 - index) : (120 - index);
205 MD5Update(context, PADDING, padLen);
207 /* Append length (before padding) */
208 MD5Update(context, bits, 8);
210 /* Store state in digest */
211 Encode(digest, context->state, 16);
213 /* Zeroize sensitive information. */
214 MD5_memset((POINTER) context, 0, sizeof(*context));
217 /* MD5 basic transformation. Transforms state based on block.
220 MD5Transform(state, block)
222 unsigned char block[64];
224 UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
226 Decode(x, block, 64);
229 FF(a, b, c, d, x[0], S11, 0xd76aa478); /* 1 */
230 FF(d, a, b, c, x[1], S12, 0xe8c7b756); /* 2 */
231 FF(c, d, a, b, x[2], S13, 0x242070db); /* 3 */
232 FF(b, c, d, a, x[3], S14, 0xc1bdceee); /* 4 */
233 FF(a, b, c, d, x[4], S11, 0xf57c0faf); /* 5 */
234 FF(d, a, b, c, x[5], S12, 0x4787c62a); /* 6 */
235 FF(c, d, a, b, x[6], S13, 0xa8304613); /* 7 */
236 FF(b, c, d, a, x[7], S14, 0xfd469501); /* 8 */
237 FF(a, b, c, d, x[8], S11, 0x698098d8); /* 9 */
238 FF(d, a, b, c, x[9], S12, 0x8b44f7af); /* 10 */
239 FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
240 FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
241 FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
242 FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
243 FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
244 FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
247 GG(a, b, c, d, x[1], S21, 0xf61e2562); /* 17 */
248 GG(d, a, b, c, x[6], S22, 0xc040b340); /* 18 */
249 GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
250 GG(b, c, d, a, x[0], S24, 0xe9b6c7aa); /* 20 */
251 GG(a, b, c, d, x[5], S21, 0xd62f105d); /* 21 */
252 GG(d, a, b, c, x[10], S22, 0x2441453); /* 22 */
253 GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
254 GG(b, c, d, a, x[4], S24, 0xe7d3fbc8); /* 24 */
255 GG(a, b, c, d, x[9], S21, 0x21e1cde6); /* 25 */
256 GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
257 GG(c, d, a, b, x[3], S23, 0xf4d50d87); /* 27 */
258 GG(b, c, d, a, x[8], S24, 0x455a14ed); /* 28 */
259 GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
260 GG(d, a, b, c, x[2], S22, 0xfcefa3f8); /* 30 */
261 GG(c, d, a, b, x[7], S23, 0x676f02d9); /* 31 */
262 GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
265 HH(a, b, c, d, x[5], S31, 0xfffa3942); /* 33 */
266 HH(d, a, b, c, x[8], S32, 0x8771f681); /* 34 */
267 HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
268 HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
269 HH(a, b, c, d, x[1], S31, 0xa4beea44); /* 37 */
270 HH(d, a, b, c, x[4], S32, 0x4bdecfa9); /* 38 */
271 HH(c, d, a, b, x[7], S33, 0xf6bb4b60); /* 39 */
272 HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
273 HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
274 HH(d, a, b, c, x[0], S32, 0xeaa127fa); /* 42 */
275 HH(c, d, a, b, x[3], S33, 0xd4ef3085); /* 43 */
276 HH(b, c, d, a, x[6], S34, 0x4881d05); /* 44 */
277 HH(a, b, c, d, x[9], S31, 0xd9d4d039); /* 45 */
278 HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
279 HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
280 HH(b, c, d, a, x[2], S34, 0xc4ac5665); /* 48 */
283 II(a, b, c, d, x[0], S41, 0xf4292244); /* 49 */
284 II(d, a, b, c, x[7], S42, 0x432aff97); /* 50 */
285 II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
286 II(b, c, d, a, x[5], S44, 0xfc93a039); /* 52 */
287 II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
288 II(d, a, b, c, x[3], S42, 0x8f0ccc92); /* 54 */
289 II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
290 II(b, c, d, a, x[1], S44, 0x85845dd1); /* 56 */
291 II(a, b, c, d, x[8], S41, 0x6fa87e4f); /* 57 */
292 II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
293 II(c, d, a, b, x[6], S43, 0xa3014314); /* 59 */
294 II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
295 II(a, b, c, d, x[4], S41, 0xf7537e82); /* 61 */
296 II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
297 II(c, d, a, b, x[2], S43, 0x2ad7d2bb); /* 63 */
298 II(b, c, d, a, x[9], S44, 0xeb86d391); /* 64 */
305 /* Zeroize sensitive information. */
306 MD5_memset((POINTER) x, 0, sizeof(x));
309 /* Encodes input (UINT4) into output (unsigned char). Assumes len is
313 Encode(output, input, len)
314 unsigned char *output;
320 for (i = 0, j = 0; j < len; i++, j += 4) {
321 output[j] = (unsigned char) (input[i] & 0xff);
322 output[j + 1] = (unsigned char) ((input[i] >> 8) & 0xff);
323 output[j + 2] = (unsigned char) ((input[i] >> 16) & 0xff);
324 output[j + 3] = (unsigned char) ((input[i] >> 24) & 0xff);
328 /* Decodes input (unsigned char) into output (UINT4). Assumes len is
332 Decode(output, input, len)
334 unsigned char *input;
339 for (i = 0, j = 0; j < len; i++, j += 4)
340 output[i] = ((UINT4) input[j]) | (((UINT4) input[j + 1]) << 8) |
341 (((UINT4) input[j + 2]) << 16) | (((UINT4) input[j + 3]) << 24);
344 #if defined(MD5_NEED_MEM_FUNC)
346 /* Note: Replace "for loop" with standard memcpy if possible.
349 MD5_memcpy(output, input, len)
356 for (i = 0; i < len; i++)
357 output[i] = input[i];
361 /* Note: Replace "for loop" with standard memset if possible.
364 MD5_memset(output, value, len)
371 for (i = 0; i < len; i++)
372 ((char *) output)[i] = (char) value;
375 #endif /* defined(MD5_NEED_MEM_FUNC) */