2 * MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
4 * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
7 * License to copy and use this software is granted provided that it
8 * is identified as the "RSA Data Security, Inc. MD5 Message-Digest
9 * Algorithm" in all material mentioning or referencing this software
12 * License is also granted to make and use derivative works provided
13 * that such works are identified as "derived from the RSA Data
14 * Security, Inc. MD5 Message-Digest Algorithm" in all material
15 * mentioning or referencing the derived work.
17 * RSA Data Security, Inc. makes no representations concerning either
18 * the merchantability of this software or the suitability of this
19 * software for any particular purpose. It is provided "as is"
20 * without express or implied warranty of any kind.
22 * These notices must be retained in any copies of any part of this
23 * documentation and/or software.
25 * $FreeBSD: src/lib/libmd/md5c.c,v 1.9.2.1 1999/08/29 14:57:12 peter Exp $
27 * This code is the same as the code published by RSA Inc. It has been
28 * edited for clarity and style only.
30 * ----------------------------------------------------------------------------
31 * The md5_crypt() function was taken from freeBSD's libcrypt and contains
33 * "THE BEER-WARE LICENSE" (Revision 42):
34 * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you
35 * can do whatever you want with this stuff. If we meet some day, and you think
36 * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
38 * $FreeBSD: src/lib/libcrypt/crypt.c,v 1.7.2.1 1999/08/29 14:56:33 peter Exp $
40 * ----------------------------------------------------------------------------
41 * On April 19th, 2001 md5_crypt() was modified to make it reentrant
42 * by Erik Andersen <andersen@uclibc.org>
45 * June 28, 2001 Manuel Novoa III
47 * "Un-inlined" code using loops and static const tables in order to
48 * reduce generated code size (on i386 from approx 4k to approx 2.5k).
50 * June 29, 2001 Manuel Novoa III
52 * Completely removed static PADDING array.
54 * Reintroduced the loop unrolling in MD5_Transform and added the
55 * MD5_SIZE_OVER_SPEED option for configurability. Define below as:
56 * 0 fully unrolled loops
57 * 1 partially unrolled (4 ops per loop)
58 * 2 no unrolling -- introduces the need to swap 4 variables (slow)
59 * 3 no unrolling and all 4 loops merged into one with switch
60 * in each loop (glacial)
61 * On i386, sizes are roughly (-Os -fno-builtin):
62 * 0: 3k 1: 2.5k 2: 2.2k 3: 2k
65 * Since SuSv3 does not require crypt_r, modified again August 7, 2002
66 * by Erik Andersen to remove reentrance stuff...
70 * Valid values are 1 (fastest/largest) to 3 (smallest/slowest).
72 #define MD5_SIZE_OVER_SPEED 3
74 /**********************************************************************/
76 #include <sys/types.h>
81 #include <sys/cdefs.h>
86 u_int32_t state
[4]; /* state (ABCD) */
87 u_int32_t count
[2]; /* number of bits, modulo 2^64 (lsb first) */
88 unsigned char buffer
[64]; /* input buffer */
91 static void __md5_Init (struct MD5Context
*);
92 static void __md5_Update (struct MD5Context
*, const unsigned char *, unsigned int);
93 static void __md5_Pad (struct MD5Context
*);
94 static void __md5_Final (unsigned char [16], struct MD5Context
*);
95 static void __md5_Transform
__P((u_int32_t
[4], const unsigned char [64]));
98 #define MD5_MAGIC_STR "$1$"
99 #define MD5_MAGIC_LEN (sizeof(MD5_MAGIC_STR) - 1)
100 static const unsigned char __md5__magic
[] = MD5_MAGIC_STR
;
101 static const unsigned char __md5_itoa64
[] = /* 0 ... 63 => ascii - 64 */
102 "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
106 #define __md5_Encode memcpy
107 #define __md5_Decode memcpy
111 * __md5_Encodes input (u_int32_t) into output (unsigned char). Assumes len is
116 __md5_Encode (unsigned char *output
, u_int32_t
*input
, unsigned int len
)
120 for (i
= 0, j
= 0; j
< len
; i
++, j
+= 4) {
121 output
[j
] = (unsigned char)(input
[i
] & 0xff);
122 output
[j
+1] = (unsigned char)((input
[i
] >> 8) & 0xff);
123 output
[j
+2] = (unsigned char)((input
[i
] >> 16) & 0xff);
124 output
[j
+3] = (unsigned char)((input
[i
] >> 24) & 0xff);
129 * __md5_Decodes input (unsigned char) into output (u_int32_t). Assumes len is
134 __md5_Decode (u_int32_t
*output
, const unsigned char *input
, unsigned int len
)
138 for (i
= 0, j
= 0; j
< len
; i
++, j
+= 4)
139 output
[i
] = ((u_int32_t
)input
[j
]) | (((u_int32_t
)input
[j
+1]) << 8) |
140 (((u_int32_t
)input
[j
+2]) << 16) | (((u_int32_t
)input
[j
+3]) << 24);
144 /* F, G, H and I are basic MD5 functions. */
145 #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
146 #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
147 #define H(x, y, z) ((x) ^ (y) ^ (z))
148 #define I(x, y, z) ((y) ^ ((x) | (~z)))
150 /* ROTATE_LEFT rotates x left n bits. */
151 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
154 * FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
155 * Rotation is separate from addition to prevent recomputation.
157 #define FF(a, b, c, d, x, s, ac) { \
158 (a) += F ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
159 (a) = ROTATE_LEFT ((a), (s)); \
162 #define GG(a, b, c, d, x, s, ac) { \
163 (a) += G ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
164 (a) = ROTATE_LEFT ((a), (s)); \
167 #define HH(a, b, c, d, x, s, ac) { \
168 (a) += H ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
169 (a) = ROTATE_LEFT ((a), (s)); \
172 #define II(a, b, c, d, x, s, ac) { \
173 (a) += I ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
174 (a) = ROTATE_LEFT ((a), (s)); \
178 /* MD5 initialization. Begins an MD5 operation, writing a new context. */
180 static void __md5_Init (struct MD5Context
*context
)
182 context
->count
[0] = context
->count
[1] = 0;
184 /* Load magic initialization constants. */
185 context
->state
[0] = 0x67452301;
186 context
->state
[1] = 0xefcdab89;
187 context
->state
[2] = 0x98badcfe;
188 context
->state
[3] = 0x10325476;
192 * MD5 block update operation. Continues an MD5 message-digest
193 * operation, processing another message block, and updating the
197 static void __md5_Update ( struct MD5Context
*context
, const unsigned char *input
, unsigned int inputLen
)
199 unsigned int i
, idx
, partLen
;
201 /* Compute number of bytes mod 64 */
202 idx
= (unsigned int)((context
->count
[0] >> 3) & 0x3F);
204 /* Update number of bits */
205 if ((context
->count
[0] += ((u_int32_t
)inputLen
<< 3))
206 < ((u_int32_t
)inputLen
<< 3))
208 context
->count
[1] += ((u_int32_t
)inputLen
>> 29);
212 /* Transform as many times as possible. */
213 if (inputLen
>= partLen
) {
214 memcpy((void *)&context
->buffer
[idx
], (const void *)input
,
216 __md5_Transform (context
->state
, context
->buffer
);
218 for (i
= partLen
; i
+ 63 < inputLen
; i
+= 64)
219 __md5_Transform (context
->state
, &input
[i
]);
226 /* Buffer remaining input */
227 memcpy ((void *)&context
->buffer
[idx
], (const void *)&input
[i
],
232 * MD5 padding. Adds padding followed by original length.
235 static void __md5_Pad ( struct MD5Context
*context
)
237 unsigned char bits
[8];
238 unsigned int idx
, padLen
;
239 unsigned char PADDING
[64];
241 memset(PADDING
, 0, sizeof(PADDING
));
244 /* Save number of bits */
245 __md5_Encode (bits
, context
->count
, 8);
247 /* Pad out to 56 mod 64. */
248 idx
= (unsigned int)((context
->count
[0] >> 3) & 0x3f);
249 padLen
= (idx
< 56) ? (56 - idx
) : (120 - idx
);
250 __md5_Update (context
, PADDING
, padLen
);
252 /* Append length (before padding) */
253 __md5_Update (context
, bits
, 8);
257 * MD5 finalization. Ends an MD5 message-digest operation, writing the
258 * the message digest and zeroizing the context.
261 static void __md5_Final ( unsigned char digest
[16], struct MD5Context
*context
)
266 /* Store state in digest */
267 __md5_Encode (digest
, context
->state
, 16);
269 /* Zeroize sensitive information. */
270 memset ((void *)context
, 0, sizeof (*context
));
273 /* MD5 basic transformation. Transforms state based on block. */
275 static void __md5_Transform (u_int32_t state
[4], const unsigned char block
[64])
277 u_int32_t a
, b
, c
, d
, x
[16];
278 #if MD5_SIZE_OVER_SPEED > 1
282 static const char S
[] = {
288 #endif /* MD5_SIZE_OVER_SPEED > 1 */
290 #if MD5_SIZE_OVER_SPEED > 0
295 static const u_int32_t C
[] = {
297 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
298 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
299 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
300 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
302 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
303 0xd62f105d, 0x2441453, 0xd8a1e681, 0xe7d3fbc8,
304 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
305 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
307 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
308 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
309 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05,
310 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
312 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
313 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
314 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
315 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391
318 static const char P
[] = {
319 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 1 */
320 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, /* 2 */
321 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, /* 3 */
322 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 /* 4 */
325 #endif /* MD5_SIZE_OVER_SPEED > 0 */
327 __md5_Decode (x
, block
, 64);
329 a
= state
[0]; b
= state
[1]; c
= state
[2]; d
= state
[3];
331 #if MD5_SIZE_OVER_SPEED > 2
332 pc
= C
; pp
= P
; ps
= S
- 4;
334 for ( i
= 0 ; i
< 64 ; i
++ ) {
335 if ((i
&0x0f) == 0) ps
+= 4;
351 temp
+= x
[(int)(*pp
++)] + *pc
++;
352 temp
= ROTATE_LEFT(temp
, ps
[i
&3]);
354 a
= d
; d
= c
; c
= b
; b
= temp
;
356 #elif MD5_SIZE_OVER_SPEED > 1
357 pc
= C
; pp
= P
; ps
= S
;
360 for ( i
= 0 ; i
< 16 ; i
++ ) {
361 FF (a
, b
, c
, d
, x
[(int)(*pp
++)], ps
[i
&0x3], *pc
++);
362 temp
= d
; d
= c
; c
= b
; b
= a
; a
= temp
;
367 for ( ; i
< 32 ; i
++ ) {
368 GG (a
, b
, c
, d
, x
[(int)(*pp
++)], ps
[i
&0x3], *pc
++);
369 temp
= d
; d
= c
; c
= b
; b
= a
; a
= temp
;
373 for ( ; i
< 48 ; i
++ ) {
374 HH (a
, b
, c
, d
, x
[(int)(*pp
++)], ps
[i
&0x3], *pc
++);
375 temp
= d
; d
= c
; c
= b
; b
= a
; a
= temp
;
380 for ( ; i
< 64 ; i
++ ) {
381 II (a
, b
, c
, d
, x
[(int)(*pp
++)], ps
[i
&0x3], *pc
++);
382 temp
= d
; d
= c
; c
= b
; b
= a
; a
= temp
;
384 #elif MD5_SIZE_OVER_SPEED > 0
388 for ( i
= 0 ; i
< 4 ; i
++ ) {
389 FF (a
, b
, c
, d
, x
[(int)(*pp
++)], 7, *pc
++);
390 FF (d
, a
, b
, c
, x
[(int)(*pp
++)], 12, *pc
++);
391 FF (c
, d
, a
, b
, x
[(int)(*pp
++)], 17, *pc
++);
392 FF (b
, c
, d
, a
, x
[(int)(*pp
++)], 22, *pc
++);
396 for ( i
= 0 ; i
< 4 ; i
++ ) {
397 GG (a
, b
, c
, d
, x
[(int)(*pp
++)], 5, *pc
++);
398 GG (d
, a
, b
, c
, x
[(int)(*pp
++)], 9, *pc
++);
399 GG (c
, d
, a
, b
, x
[(int)(*pp
++)], 14, *pc
++);
400 GG (b
, c
, d
, a
, x
[(int)(*pp
++)], 20, *pc
++);
403 for ( i
= 0 ; i
< 4 ; i
++ ) {
404 HH (a
, b
, c
, d
, x
[(int)(*pp
++)], 4, *pc
++);
405 HH (d
, a
, b
, c
, x
[(int)(*pp
++)], 11, *pc
++);
406 HH (c
, d
, a
, b
, x
[(int)(*pp
++)], 16, *pc
++);
407 HH (b
, c
, d
, a
, x
[(int)(*pp
++)], 23, *pc
++);
411 for ( i
= 0 ; i
< 4 ; i
++ ) {
412 II (a
, b
, c
, d
, x
[(int)(*pp
++)], 6, *pc
++);
413 II (d
, a
, b
, c
, x
[(int)(*pp
++)], 10, *pc
++);
414 II (c
, d
, a
, b
, x
[(int)(*pp
++)], 15, *pc
++);
415 II (b
, c
, d
, a
, x
[(int)(*pp
++)], 21, *pc
++);
423 FF (a
, b
, c
, d
, x
[ 0], S11
, 0xd76aa478); /* 1 */
424 FF (d
, a
, b
, c
, x
[ 1], S12
, 0xe8c7b756); /* 2 */
425 FF (c
, d
, a
, b
, x
[ 2], S13
, 0x242070db); /* 3 */
426 FF (b
, c
, d
, a
, x
[ 3], S14
, 0xc1bdceee); /* 4 */
427 FF (a
, b
, c
, d
, x
[ 4], S11
, 0xf57c0faf); /* 5 */
428 FF (d
, a
, b
, c
, x
[ 5], S12
, 0x4787c62a); /* 6 */
429 FF (c
, d
, a
, b
, x
[ 6], S13
, 0xa8304613); /* 7 */
430 FF (b
, c
, d
, a
, x
[ 7], S14
, 0xfd469501); /* 8 */
431 FF (a
, b
, c
, d
, x
[ 8], S11
, 0x698098d8); /* 9 */
432 FF (d
, a
, b
, c
, x
[ 9], S12
, 0x8b44f7af); /* 10 */
433 FF (c
, d
, a
, b
, x
[10], S13
, 0xffff5bb1); /* 11 */
434 FF (b
, c
, d
, a
, x
[11], S14
, 0x895cd7be); /* 12 */
435 FF (a
, b
, c
, d
, x
[12], S11
, 0x6b901122); /* 13 */
436 FF (d
, a
, b
, c
, x
[13], S12
, 0xfd987193); /* 14 */
437 FF (c
, d
, a
, b
, x
[14], S13
, 0xa679438e); /* 15 */
438 FF (b
, c
, d
, a
, x
[15], S14
, 0x49b40821); /* 16 */
445 GG (a
, b
, c
, d
, x
[ 1], S21
, 0xf61e2562); /* 17 */
446 GG (d
, a
, b
, c
, x
[ 6], S22
, 0xc040b340); /* 18 */
447 GG (c
, d
, a
, b
, x
[11], S23
, 0x265e5a51); /* 19 */
448 GG (b
, c
, d
, a
, x
[ 0], S24
, 0xe9b6c7aa); /* 20 */
449 GG (a
, b
, c
, d
, x
[ 5], S21
, 0xd62f105d); /* 21 */
450 GG (d
, a
, b
, c
, x
[10], S22
, 0x2441453); /* 22 */
451 GG (c
, d
, a
, b
, x
[15], S23
, 0xd8a1e681); /* 23 */
452 GG (b
, c
, d
, a
, x
[ 4], S24
, 0xe7d3fbc8); /* 24 */
453 GG (a
, b
, c
, d
, x
[ 9], S21
, 0x21e1cde6); /* 25 */
454 GG (d
, a
, b
, c
, x
[14], S22
, 0xc33707d6); /* 26 */
455 GG (c
, d
, a
, b
, x
[ 3], S23
, 0xf4d50d87); /* 27 */
456 GG (b
, c
, d
, a
, x
[ 8], S24
, 0x455a14ed); /* 28 */
457 GG (a
, b
, c
, d
, x
[13], S21
, 0xa9e3e905); /* 29 */
458 GG (d
, a
, b
, c
, x
[ 2], S22
, 0xfcefa3f8); /* 30 */
459 GG (c
, d
, a
, b
, x
[ 7], S23
, 0x676f02d9); /* 31 */
460 GG (b
, c
, d
, a
, x
[12], S24
, 0x8d2a4c8a); /* 32 */
467 HH (a
, b
, c
, d
, x
[ 5], S31
, 0xfffa3942); /* 33 */
468 HH (d
, a
, b
, c
, x
[ 8], S32
, 0x8771f681); /* 34 */
469 HH (c
, d
, a
, b
, x
[11], S33
, 0x6d9d6122); /* 35 */
470 HH (b
, c
, d
, a
, x
[14], S34
, 0xfde5380c); /* 36 */
471 HH (a
, b
, c
, d
, x
[ 1], S31
, 0xa4beea44); /* 37 */
472 HH (d
, a
, b
, c
, x
[ 4], S32
, 0x4bdecfa9); /* 38 */
473 HH (c
, d
, a
, b
, x
[ 7], S33
, 0xf6bb4b60); /* 39 */
474 HH (b
, c
, d
, a
, x
[10], S34
, 0xbebfbc70); /* 40 */
475 HH (a
, b
, c
, d
, x
[13], S31
, 0x289b7ec6); /* 41 */
476 HH (d
, a
, b
, c
, x
[ 0], S32
, 0xeaa127fa); /* 42 */
477 HH (c
, d
, a
, b
, x
[ 3], S33
, 0xd4ef3085); /* 43 */
478 HH (b
, c
, d
, a
, x
[ 6], S34
, 0x4881d05); /* 44 */
479 HH (a
, b
, c
, d
, x
[ 9], S31
, 0xd9d4d039); /* 45 */
480 HH (d
, a
, b
, c
, x
[12], S32
, 0xe6db99e5); /* 46 */
481 HH (c
, d
, a
, b
, x
[15], S33
, 0x1fa27cf8); /* 47 */
482 HH (b
, c
, d
, a
, x
[ 2], S34
, 0xc4ac5665); /* 48 */
489 II (a
, b
, c
, d
, x
[ 0], S41
, 0xf4292244); /* 49 */
490 II (d
, a
, b
, c
, x
[ 7], S42
, 0x432aff97); /* 50 */
491 II (c
, d
, a
, b
, x
[14], S43
, 0xab9423a7); /* 51 */
492 II (b
, c
, d
, a
, x
[ 5], S44
, 0xfc93a039); /* 52 */
493 II (a
, b
, c
, d
, x
[12], S41
, 0x655b59c3); /* 53 */
494 II (d
, a
, b
, c
, x
[ 3], S42
, 0x8f0ccc92); /* 54 */
495 II (c
, d
, a
, b
, x
[10], S43
, 0xffeff47d); /* 55 */
496 II (b
, c
, d
, a
, x
[ 1], S44
, 0x85845dd1); /* 56 */
497 II (a
, b
, c
, d
, x
[ 8], S41
, 0x6fa87e4f); /* 57 */
498 II (d
, a
, b
, c
, x
[15], S42
, 0xfe2ce6e0); /* 58 */
499 II (c
, d
, a
, b
, x
[ 6], S43
, 0xa3014314); /* 59 */
500 II (b
, c
, d
, a
, x
[13], S44
, 0x4e0811a1); /* 60 */
501 II (a
, b
, c
, d
, x
[ 4], S41
, 0xf7537e82); /* 61 */
502 II (d
, a
, b
, c
, x
[11], S42
, 0xbd3af235); /* 62 */
503 II (c
, d
, a
, b
, x
[ 2], S43
, 0x2ad7d2bb); /* 63 */
504 II (b
, c
, d
, a
, x
[ 9], S44
, 0xeb86d391); /* 64 */
512 /* Zeroize sensitive information. */
513 memset ((void *)x
, 0, sizeof (x
));
517 static void __md5_to64( char *s
, unsigned long v
, int n
)
520 *s
++ = __md5_itoa64
[v
&0x3f];
528 * Use MD5 for what it is best at...
531 char *__md5_crypt(const unsigned char *pw
, const unsigned char *salt
)
534 /* "$1$" + salt_up_to_8_chars + "$" + 22_bytes_of_hash + NUL */
535 static char passwd
[3 + 8 + 1 + 22 + 1];
537 const unsigned char *sp
, *ep
;
539 unsigned char final
[17]; /* final[16] exists only to aid in looping */
541 struct MD5Context ctx
,ctx1
;
544 /* Refine the Salt first */
547 /* If it starts with the magic string, then skip that */
548 if(!strncmp(sp
,__md5__magic
,MD5_MAGIC_LEN
))
551 /* It stops at the first '$', max 8 chars */
552 for(ep
=sp
;*ep
&& *ep
!= '$' && ep
< (sp
+8);ep
++)
555 /* get the length of the true salt */
560 /* The password first, since that is what is most unknown */
562 __md5_Update(&ctx
,pw
,pw_len
);
564 /* Then our magic string */
565 __md5_Update(&ctx
,__md5__magic
,MD5_MAGIC_LEN
);
567 /* Then the raw salt */
568 __md5_Update(&ctx
,sp
,sl
);
570 /* Then just as many characters of the MD5(pw,salt,pw) */
572 __md5_Update(&ctx1
,pw
,pw_len
);
573 __md5_Update(&ctx1
,sp
,sl
);
574 __md5_Update(&ctx1
,pw
,pw_len
);
575 __md5_Final(final
,&ctx1
);
576 for(pl
= pw_len
; pl
> 0; pl
-= 16)
577 __md5_Update(&ctx
,final
,pl
>16 ? 16 : pl
);
579 /* Don't leave anything around in vm they could use. */
580 memset(final
,0,sizeof final
);
582 /* Then something really weird... */
583 for (i
= pw_len
; i
; i
>>= 1) {
584 __md5_Update(&ctx
, ((i
&1) ? final
: (const unsigned char *) pw
), 1);
587 /* Now make the output string */
588 strcpy(passwd
,__md5__magic
); /* 3 bytes */
589 strncpy(passwd
+MD5_MAGIC_LEN
,(char*)sp
,sl
); /* 8 or less */
590 passwd
[MD5_MAGIC_LEN
+sl
] = '$';
592 __md5_Final(final
,&ctx
);
595 * and now, just to make sure things don't run too fast
596 * On a 60 Mhz Pentium this takes 34 msec, so you would
597 * need 30 seconds to build a 1000 entry dictionary...
599 for(i
=0;i
<1000;i
++) {
602 __md5_Update(&ctx1
,pw
,pw_len
);
604 __md5_Update(&ctx1
,final
,16);
607 __md5_Update(&ctx1
,sp
,sl
);
610 __md5_Update(&ctx1
,pw
,pw_len
);
613 __md5_Update(&ctx1
,final
,16);
615 __md5_Update(&ctx1
,pw
,pw_len
);
616 __md5_Final(final
,&ctx1
);
619 /* Add 5*4+2 = 22 bytes of hash, + NUL byte. */
620 p
= passwd
+ MD5_MAGIC_LEN
+ sl
+ 1;
621 final
[16] = final
[5];
622 for ( i
=0 ; i
< 5 ; i
++ ) {
623 l
= (final
[i
]<<16) | (final
[i
+6]<<8) | final
[i
+12];
632 /* Don't leave anything around in vm they could use. */
633 memset(final
,0,sizeof final
);