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