Contents of /trunk/mkinitrd-magellan/busybox/libbb/pw_encrypt_md5.c
Parent Directory | Revision Log
Revision 984 -
(show annotations)
(download)
Sun May 30 11:32:42 2010 UTC (14 years, 4 months ago) by niro
File MIME type: text/plain
File size: 5119 byte(s)
Sun May 30 11:32:42 2010 UTC (14 years, 4 months ago) by niro
File MIME type: text/plain
File size: 5119 byte(s)
-updated to busybox-1.16.1 and enabled blkid/uuid support in default config
1 | /* |
2 | * MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm |
3 | * |
4 | * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All |
5 | * rights reserved. |
6 | * |
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 |
10 | * or this function. |
11 | * |
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. |
16 | * |
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. |
21 | * |
22 | * These notices must be retained in any copies of any part of this |
23 | * documentation and/or software. |
24 | * |
25 | * $FreeBSD: src/lib/libmd/md5c.c,v 1.9.2.1 1999/08/29 14:57:12 peter Exp $ |
26 | * |
27 | * This code is the same as the code published by RSA Inc. It has been |
28 | * edited for clarity and style only. |
29 | * |
30 | * ---------------------------------------------------------------------------- |
31 | * The md5_crypt() function was taken from freeBSD's libcrypt and contains |
32 | * this license: |
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 |
37 | * |
38 | * $FreeBSD: src/lib/libcrypt/crypt.c,v 1.7.2.1 1999/08/29 14:56:33 peter Exp $ |
39 | * |
40 | * ---------------------------------------------------------------------------- |
41 | * On April 19th, 2001 md5_crypt() was modified to make it reentrant |
42 | * by Erik Andersen <andersen@uclibc.org> |
43 | * |
44 | * |
45 | * June 28, 2001 Manuel Novoa III |
46 | * |
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). |
49 | * |
50 | * June 29, 2001 Manuel Novoa III |
51 | * |
52 | * Completely removed static PADDING array. |
53 | * |
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 |
63 | * |
64 | * Since SuSv3 does not require crypt_r, modified again August 7, 2002 |
65 | * by Erik Andersen to remove reentrance stuff... |
66 | */ |
67 | |
68 | /* |
69 | * UNIX password |
70 | * |
71 | * Use MD5 for what it is best at... |
72 | */ |
73 | #define MD5_OUT_BUFSIZE 36 |
74 | static char * |
75 | NOINLINE |
76 | md5_crypt(char result[MD5_OUT_BUFSIZE], const unsigned char *pw, const unsigned char *salt) |
77 | { |
78 | char *p; |
79 | unsigned char final[17]; /* final[16] exists only to aid in looping */ |
80 | int sl, pl, i, pw_len; |
81 | md5_ctx_t ctx, ctx1; |
82 | |
83 | /* NB: in busybox, "$1$" in salt is always present */ |
84 | |
85 | /* Refine the Salt first */ |
86 | |
87 | /* Get the length of the salt including "$1$" */ |
88 | sl = 3; |
89 | while (salt[sl] && salt[sl] != '$' && sl < (3 + 8)) |
90 | sl++; |
91 | |
92 | /* Hash. the password first, since that is what is most unknown */ |
93 | md5_begin(&ctx); |
94 | pw_len = strlen((char*)pw); |
95 | md5_hash(pw, pw_len, &ctx); |
96 | |
97 | /* Then the salt including "$1$" */ |
98 | md5_hash(salt, sl, &ctx); |
99 | |
100 | /* Copy salt to result; skip "$1$" */ |
101 | memcpy(result, salt, sl); |
102 | result[sl] = '$'; |
103 | salt += 3; |
104 | sl -= 3; |
105 | |
106 | /* Then just as many characters of the MD5(pw, salt, pw) */ |
107 | md5_begin(&ctx1); |
108 | md5_hash(pw, pw_len, &ctx1); |
109 | md5_hash(salt, sl, &ctx1); |
110 | md5_hash(pw, pw_len, &ctx1); |
111 | md5_end(final, &ctx1); |
112 | for (pl = pw_len; pl > 0; pl -= 16) |
113 | md5_hash(final, pl > 16 ? 16 : pl, &ctx); |
114 | |
115 | /* Then something really weird... */ |
116 | memset(final, 0, sizeof(final)); |
117 | for (i = pw_len; i; i >>= 1) { |
118 | md5_hash(((i & 1) ? final : (const unsigned char *) pw), 1, &ctx); |
119 | } |
120 | md5_end(final, &ctx); |
121 | |
122 | /* And now, just to make sure things don't run too fast. |
123 | * On a 60 Mhz Pentium this takes 34 msec, so you would |
124 | * need 30 seconds to build a 1000 entry dictionary... |
125 | */ |
126 | for (i = 0; i < 1000; i++) { |
127 | md5_begin(&ctx1); |
128 | if (i & 1) |
129 | md5_hash(pw, pw_len, &ctx1); |
130 | else |
131 | md5_hash(final, 16, &ctx1); |
132 | |
133 | if (i % 3) |
134 | md5_hash(salt, sl, &ctx1); |
135 | |
136 | if (i % 7) |
137 | md5_hash(pw, pw_len, &ctx1); |
138 | |
139 | if (i & 1) |
140 | md5_hash(final, 16, &ctx1); |
141 | else |
142 | md5_hash(pw, pw_len, &ctx1); |
143 | md5_end(final, &ctx1); |
144 | } |
145 | |
146 | p = result + sl + 4; /* 12 bytes max (sl is up to 8 bytes) */ |
147 | |
148 | /* Add 5*4+2 = 22 bytes of hash, + NUL byte. */ |
149 | final[16] = final[5]; |
150 | for (i = 0; i < 5; i++) { |
151 | unsigned l = (final[i] << 16) | (final[i+6] << 8) | final[i+12]; |
152 | p = to64(p, l, 4); |
153 | } |
154 | p = to64(p, final[11], 2); |
155 | *p = '\0'; |
156 | |
157 | /* Don't leave anything around in vm they could use. */ |
158 | memset(final, 0, sizeof(final)); |
159 | |
160 | return result; |
161 | } |