diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-11-11 01:38:04 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-11-11 01:38:04 +0000 |
commit | e9b9a19ad30e004b3532105af417e43575ce7779 (patch) | |
tree | 149fe884916ee0be75e384fbcbb908695499c8d7 | |
parent | 6f05874b9dc4623512878566d144b0905700525d (diff) | |
download | busybox-w32-e9b9a19ad30e004b3532105af417e43575ce7779.tar.gz busybox-w32-e9b9a19ad30e004b3532105af417e43575ce7779.tar.bz2 busybox-w32-e9b9a19ad30e004b3532105af417e43575ce7779.zip |
libbb: disable a second md5 implementation which managed to creep in :)
function old new delta
sha512_end 239 237 -2
sha256_end 162 160 -2
sha1_end 191 189 -2
md5_end 168 166 -2
__md5__magic 4 - -4
md5_crypt 627 621 -6
static.S 16 - -16
__md5_Init 42 - -42
static.P 64 - -64
__md5_Final 131 - -131
__md5_Update 153 - -153
static.C 268 12 -256
__md5_Transform 293 - -293
------------------------------------------------------------------------------
(add/remove: 0/7 grow/shrink: 0/6 up/down: 0/-973) Total: -973 bytes
-rw-r--r-- | include/libbb.h | 18 | ||||
-rw-r--r-- | libbb/Kbuild | 2 | ||||
-rw-r--r-- | libbb/md5.c | 542 | ||||
-rw-r--r-- | libbb/md5prime.c | 460 | ||||
-rw-r--r-- | libbb/pw_encrypt_md5.c | 549 | ||||
-rw-r--r-- | libbb/sha1.c | 12 |
6 files changed, 781 insertions, 802 deletions
diff --git a/include/libbb.h b/include/libbb.h index 839a0de49..85a915ec1 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -1309,7 +1309,7 @@ typedef struct sha1_ctx_t { | |||
1309 | } sha1_ctx_t; | 1309 | } sha1_ctx_t; |
1310 | void sha1_begin(sha1_ctx_t *ctx) FAST_FUNC; | 1310 | void sha1_begin(sha1_ctx_t *ctx) FAST_FUNC; |
1311 | void sha1_hash(const void *data, size_t length, sha1_ctx_t *ctx) FAST_FUNC; | 1311 | void sha1_hash(const void *data, size_t length, sha1_ctx_t *ctx) FAST_FUNC; |
1312 | void *sha1_end(void *resbuf, sha1_ctx_t *ctx) FAST_FUNC; | 1312 | void sha1_end(void *resbuf, sha1_ctx_t *ctx) FAST_FUNC; |
1313 | typedef struct sha256_ctx_t { | 1313 | typedef struct sha256_ctx_t { |
1314 | uint32_t H[8]; | 1314 | uint32_t H[8]; |
1315 | uint32_t total[2]; /* rename to "count"? */ | 1315 | uint32_t total[2]; /* rename to "count"? */ |
@@ -1318,7 +1318,7 @@ typedef struct sha256_ctx_t { | |||
1318 | } sha256_ctx_t; | 1318 | } sha256_ctx_t; |
1319 | void sha256_begin(sha256_ctx_t *ctx) FAST_FUNC; | 1319 | void sha256_begin(sha256_ctx_t *ctx) FAST_FUNC; |
1320 | void sha256_hash(const void *buffer, size_t len, sha256_ctx_t *ctx) FAST_FUNC; | 1320 | void sha256_hash(const void *buffer, size_t len, sha256_ctx_t *ctx) FAST_FUNC; |
1321 | void* sha256_end(void *resbuf, sha256_ctx_t *ctx) FAST_FUNC; | 1321 | void sha256_end(void *resbuf, sha256_ctx_t *ctx) FAST_FUNC; |
1322 | typedef struct sha512_ctx_t { | 1322 | typedef struct sha512_ctx_t { |
1323 | uint64_t H[8]; | 1323 | uint64_t H[8]; |
1324 | uint64_t total[2]; | 1324 | uint64_t total[2]; |
@@ -1327,7 +1327,8 @@ typedef struct sha512_ctx_t { | |||
1327 | } sha512_ctx_t; | 1327 | } sha512_ctx_t; |
1328 | void sha512_begin(sha512_ctx_t *ctx) FAST_FUNC; | 1328 | void sha512_begin(sha512_ctx_t *ctx) FAST_FUNC; |
1329 | void sha512_hash(const void *buffer, size_t len, sha512_ctx_t *ctx) FAST_FUNC; | 1329 | void sha512_hash(const void *buffer, size_t len, sha512_ctx_t *ctx) FAST_FUNC; |
1330 | void* sha512_end(void *resbuf, sha512_ctx_t *ctx) FAST_FUNC; | 1330 | void sha512_end(void *resbuf, sha512_ctx_t *ctx) FAST_FUNC; |
1331 | #if 1 | ||
1331 | typedef struct md5_ctx_t { | 1332 | typedef struct md5_ctx_t { |
1332 | uint32_t A; | 1333 | uint32_t A; |
1333 | uint32_t B; | 1334 | uint32_t B; |
@@ -1337,9 +1338,18 @@ typedef struct md5_ctx_t { | |||
1337 | uint32_t buflen; | 1338 | uint32_t buflen; |
1338 | char buffer[128]; | 1339 | char buffer[128]; |
1339 | } md5_ctx_t; | 1340 | } md5_ctx_t; |
1341 | #else | ||
1342 | /* libbb/md5prime.c uses a bit different one: */ | ||
1343 | typedef struct md5_ctx_t { | ||
1344 | uint32_t state[4]; /* state (ABCD) */ | ||
1345 | uint32_t count[2]; /* number of bits, modulo 2^64 (lsb first) */ | ||
1346 | unsigned char buffer[64]; /* input buffer */ | ||
1347 | } md5_ctx_t; | ||
1348 | #endif | ||
1340 | void md5_begin(md5_ctx_t *ctx) FAST_FUNC; | 1349 | void md5_begin(md5_ctx_t *ctx) FAST_FUNC; |
1341 | void md5_hash(const void *data, size_t length, md5_ctx_t *ctx) FAST_FUNC; | 1350 | void md5_hash(const void *data, size_t length, md5_ctx_t *ctx) FAST_FUNC; |
1342 | void *md5_end(void *resbuf, md5_ctx_t *ctx) FAST_FUNC; | 1351 | void md5_end(void *resbuf, md5_ctx_t *ctx) FAST_FUNC; |
1352 | |||
1343 | 1353 | ||
1344 | uint32_t *crc32_filltable(uint32_t *tbl256, int endian) FAST_FUNC; | 1354 | uint32_t *crc32_filltable(uint32_t *tbl256, int endian) FAST_FUNC; |
1345 | 1355 | ||
diff --git a/libbb/Kbuild b/libbb/Kbuild index 786cbee80..b82f03c56 100644 --- a/libbb/Kbuild +++ b/libbb/Kbuild | |||
@@ -58,6 +58,8 @@ lib-y += make_directory.o | |||
58 | lib-y += makedev.o | 58 | lib-y += makedev.o |
59 | lib-y += match_fstype.o | 59 | lib-y += match_fstype.o |
60 | lib-y += md5.o | 60 | lib-y += md5.o |
61 | # Alternative (disabled) implementation | ||
62 | #lib-y += md5prime.o | ||
61 | lib-y += messages.o | 63 | lib-y += messages.o |
62 | lib-y += mode_string.o | 64 | lib-y += mode_string.o |
63 | lib-y += mtab_file.o | 65 | lib-y += mtab_file.o |
diff --git a/libbb/md5.c b/libbb/md5.c index 4ab06eb17..eb15d758d 100644 --- a/libbb/md5.c +++ b/libbb/md5.c | |||
@@ -15,8 +15,11 @@ | |||
15 | 15 | ||
16 | #include "libbb.h" | 16 | #include "libbb.h" |
17 | 17 | ||
18 | #if CONFIG_MD5_SIZE_VS_SPEED < 0 || CONFIG_MD5_SIZE_VS_SPEED > 3 | 18 | /* 0: fastest, 3: smallest */ |
19 | # define MD5_SIZE_VS_SPEED 2 | 19 | #if CONFIG_MD5_SIZE_VS_SPEED < 0 |
20 | # define MD5_SIZE_VS_SPEED 0 | ||
21 | #elif CONFIG_MD5_SIZE_VS_SPEED > 3 | ||
22 | # define MD5_SIZE_VS_SPEED 3 | ||
20 | #else | 23 | #else |
21 | # define MD5_SIZE_VS_SPEED CONFIG_MD5_SIZE_VS_SPEED | 24 | # define MD5_SIZE_VS_SPEED CONFIG_MD5_SIZE_VS_SPEED |
22 | #endif | 25 | #endif |
@@ -30,7 +33,6 @@ void FAST_FUNC md5_begin(md5_ctx_t *ctx) | |||
30 | ctx->B = 0xefcdab89; | 33 | ctx->B = 0xefcdab89; |
31 | ctx->C = 0x98badcfe; | 34 | ctx->C = 0x98badcfe; |
32 | ctx->D = 0x10325476; | 35 | ctx->D = 0x10325476; |
33 | |||
34 | ctx->total = 0; | 36 | ctx->total = 0; |
35 | ctx->buflen = 0; | 37 | ctx->buflen = 0; |
36 | } | 38 | } |
@@ -40,10 +42,12 @@ void FAST_FUNC md5_begin(md5_ctx_t *ctx) | |||
40 | * (as found in Colin Plumbs public domain implementation). | 42 | * (as found in Colin Plumbs public domain implementation). |
41 | * #define FF(b, c, d) ((b & c) | (~b & d)) | 43 | * #define FF(b, c, d) ((b & c) | (~b & d)) |
42 | */ | 44 | */ |
43 | # define FF(b, c, d) (d ^ (b & (c ^ d))) | 45 | #define FF(b, c, d) (d ^ (b & (c ^ d))) |
44 | # define FG(b, c, d) FF (d, b, c) | 46 | #define FG(b, c, d) FF(d, b, c) |
45 | # define FH(b, c, d) (b ^ c ^ d) | 47 | #define FH(b, c, d) (b ^ c ^ d) |
46 | # define FI(b, c, d) (c ^ (b | ~d)) | 48 | #define FI(b, c, d) (c ^ (b | ~d)) |
49 | |||
50 | #define rotl32(w, s) (((w) << (s)) | ((w) >> (32 - (s)))) | ||
47 | 51 | ||
48 | /* Hash a single block, 64 bytes long and 4-byte aligned. */ | 52 | /* Hash a single block, 64 bytes long and 4-byte aligned. */ |
49 | static void md5_hash_block(const void *buffer, md5_ctx_t *ctx) | 53 | static void md5_hash_block(const void *buffer, md5_ctx_t *ctx) |
@@ -51,7 +55,7 @@ static void md5_hash_block(const void *buffer, md5_ctx_t *ctx) | |||
51 | uint32_t correct_words[16]; | 55 | uint32_t correct_words[16]; |
52 | const uint32_t *words = buffer; | 56 | const uint32_t *words = buffer; |
53 | 57 | ||
54 | # if MD5_SIZE_VS_SPEED > 0 | 58 | #if MD5_SIZE_VS_SPEED > 0 |
55 | static const uint32_t C_array[] = { | 59 | static const uint32_t C_array[] = { |
56 | /* round 1 */ | 60 | /* round 1 */ |
57 | 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, | 61 | 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, |
@@ -74,26 +78,23 @@ static void md5_hash_block(const void *buffer, md5_ctx_t *ctx) | |||
74 | 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, | 78 | 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, |
75 | 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 | 79 | 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 |
76 | }; | 80 | }; |
77 | |||
78 | static const char P_array[] ALIGN1 = { | 81 | static const char P_array[] ALIGN1 = { |
79 | # if MD5_SIZE_VS_SPEED > 1 | 82 | # if MD5_SIZE_VS_SPEED > 1 |
80 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 1 */ | 83 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 1 */ |
81 | # endif /* MD5_SIZE_VS_SPEED > 1 */ | 84 | # endif |
82 | 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, /* 2 */ | 85 | 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, /* 2 */ |
83 | 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, /* 3 */ | 86 | 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, /* 3 */ |
84 | 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 /* 4 */ | 87 | 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 /* 4 */ |
85 | }; | 88 | }; |
86 | 89 | # if MD5_SIZE_VS_SPEED > 1 | |
87 | # if MD5_SIZE_VS_SPEED > 1 | ||
88 | static const char S_array[] ALIGN1 = { | 90 | static const char S_array[] ALIGN1 = { |
89 | 7, 12, 17, 22, | 91 | 7, 12, 17, 22, |
90 | 5, 9, 14, 20, | 92 | 5, 9, 14, 20, |
91 | 4, 11, 16, 23, | 93 | 4, 11, 16, 23, |
92 | 6, 10, 15, 21 | 94 | 6, 10, 15, 21 |
93 | }; | 95 | }; |
94 | # endif /* MD5_SIZE_VS_SPEED > 1 */ | 96 | # endif /* MD5_SIZE_VS_SPEED > 1 */ |
95 | # endif | 97 | #endif |
96 | |||
97 | uint32_t A = ctx->A; | 98 | uint32_t A = ctx->A; |
98 | uint32_t B = ctx->B; | 99 | uint32_t B = ctx->B; |
99 | uint32_t C = ctx->C; | 100 | uint32_t C = ctx->C; |
@@ -101,263 +102,252 @@ static void md5_hash_block(const void *buffer, md5_ctx_t *ctx) | |||
101 | 102 | ||
102 | /* Process all bytes in the buffer with 64 bytes in each round of | 103 | /* Process all bytes in the buffer with 64 bytes in each round of |
103 | the loop. */ | 104 | the loop. */ |
104 | uint32_t *cwp = correct_words; | 105 | uint32_t *cwp = correct_words; |
105 | uint32_t A_save = A; | 106 | uint32_t A_save = A; |
106 | uint32_t B_save = B; | 107 | uint32_t B_save = B; |
107 | uint32_t C_save = C; | 108 | uint32_t C_save = C; |
108 | uint32_t D_save = D; | 109 | uint32_t D_save = D; |
109 | 110 | ||
110 | # if MD5_SIZE_VS_SPEED > 1 | 111 | #if MD5_SIZE_VS_SPEED > 1 |
111 | # define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s))) | 112 | const uint32_t *pc; |
112 | 113 | const char *pp; | |
113 | const uint32_t *pc; | 114 | const char *ps; |
114 | const char *pp; | 115 | int i; |
115 | const char *ps; | 116 | uint32_t temp; |
116 | int i; | 117 | |
117 | uint32_t temp; | 118 | for (i = 0; i < 16; i++) |
118 | 119 | cwp[i] = SWAP_LE32(words[i]); | |
119 | for (i = 0; i < 16; i++) { | 120 | words += 16; |
120 | cwp[i] = SWAP_LE32(words[i]); | 121 | |
121 | } | 122 | # if MD5_SIZE_VS_SPEED > 2 |
122 | words += 16; | 123 | pc = C_array; |
123 | 124 | pp = P_array; | |
124 | # if MD5_SIZE_VS_SPEED > 2 | 125 | ps = S_array - 4; |
125 | pc = C_array; | 126 | |
126 | pp = P_array; | 127 | for (i = 0; i < 64; i++) { |
127 | ps = S_array - 4; | 128 | if ((i & 0x0f) == 0) |
128 | 129 | ps += 4; | |
129 | for (i = 0; i < 64; i++) { | 130 | temp = A; |
130 | if ((i & 0x0f) == 0) | 131 | switch (i >> 4) { |
131 | ps += 4; | 132 | case 0: |
132 | temp = A; | 133 | temp += FF(B, C, D); |
133 | switch (i >> 4) { | 134 | break; |
134 | case 0: | 135 | case 1: |
135 | temp += FF(B, C, D); | 136 | temp += FG(B, C, D); |
136 | break; | 137 | break; |
137 | case 1: | 138 | case 2: |
138 | temp += FG(B, C, D); | 139 | temp += FH(B, C, D); |
139 | break; | 140 | break; |
140 | case 2: | 141 | case 3: |
141 | temp += FH(B, C, D); | 142 | temp += FI(B, C, D); |
142 | break; | ||
143 | case 3: | ||
144 | temp += FI(B, C, D); | ||
145 | } | ||
146 | temp += cwp[(int) (*pp++)] + *pc++; | ||
147 | CYCLIC(temp, ps[i & 3]); | ||
148 | temp += B; | ||
149 | A = D; | ||
150 | D = C; | ||
151 | C = B; | ||
152 | B = temp; | ||
153 | } | ||
154 | # else | ||
155 | pc = C_array; | ||
156 | pp = P_array; | ||
157 | ps = S_array; | ||
158 | |||
159 | for (i = 0; i < 16; i++) { | ||
160 | temp = A + FF(B, C, D) + cwp[(int) (*pp++)] + *pc++; | ||
161 | CYCLIC(temp, ps[i & 3]); | ||
162 | temp += B; | ||
163 | A = D; | ||
164 | D = C; | ||
165 | C = B; | ||
166 | B = temp; | ||
167 | } | ||
168 | |||
169 | ps += 4; | ||
170 | for (i = 0; i < 16; i++) { | ||
171 | temp = A + FG(B, C, D) + cwp[(int) (*pp++)] + *pc++; | ||
172 | CYCLIC(temp, ps[i & 3]); | ||
173 | temp += B; | ||
174 | A = D; | ||
175 | D = C; | ||
176 | C = B; | ||
177 | B = temp; | ||
178 | } | ||
179 | ps += 4; | ||
180 | for (i = 0; i < 16; i++) { | ||
181 | temp = A + FH(B, C, D) + cwp[(int) (*pp++)] + *pc++; | ||
182 | CYCLIC(temp, ps[i & 3]); | ||
183 | temp += B; | ||
184 | A = D; | ||
185 | D = C; | ||
186 | C = B; | ||
187 | B = temp; | ||
188 | } | ||
189 | ps += 4; | ||
190 | for (i = 0; i < 16; i++) { | ||
191 | temp = A + FI(B, C, D) + cwp[(int) (*pp++)] + *pc++; | ||
192 | CYCLIC(temp, ps[i & 3]); | ||
193 | temp += B; | ||
194 | A = D; | ||
195 | D = C; | ||
196 | C = B; | ||
197 | B = temp; | ||
198 | } | 143 | } |
199 | 144 | temp += cwp[(int) (*pp++)] + *pc++; | |
200 | # endif /* MD5_SIZE_VS_SPEED > 2 */ | 145 | temp = rotl32(temp, ps[i & 3]); |
146 | temp += B; | ||
147 | A = D; | ||
148 | D = C; | ||
149 | C = B; | ||
150 | B = temp; | ||
151 | } | ||
201 | # else | 152 | # else |
202 | /* First round: using the given function, the context and a constant | 153 | pc = C_array; |
203 | the next context is computed. Because the algorithms processing | 154 | pp = P_array; |
204 | unit is a 32-bit word and it is determined to work on words in | 155 | ps = S_array; |
205 | little endian byte order we perhaps have to change the byte order | 156 | |
206 | before the computation. To reduce the work for the next steps | 157 | for (i = 0; i < 16; i++) { |
207 | we store the swapped words in the array CORRECT_WORDS. */ | 158 | temp = A + FF(B, C, D) + cwp[(int) (*pp++)] + *pc++; |
208 | 159 | temp = rotl32(temp, ps[i & 3]); | |
209 | # define OP(a, b, c, d, s, T) \ | 160 | temp += B; |
161 | A = D; | ||
162 | D = C; | ||
163 | C = B; | ||
164 | B = temp; | ||
165 | } | ||
166 | ps += 4; | ||
167 | for (i = 0; i < 16; i++) { | ||
168 | temp = A + FG(B, C, D) + cwp[(int) (*pp++)] + *pc++; | ||
169 | temp = rotl32(temp, ps[i & 3]); | ||
170 | temp += B; | ||
171 | A = D; | ||
172 | D = C; | ||
173 | C = B; | ||
174 | B = temp; | ||
175 | } | ||
176 | ps += 4; | ||
177 | for (i = 0; i < 16; i++) { | ||
178 | temp = A + FH(B, C, D) + cwp[(int) (*pp++)] + *pc++; | ||
179 | temp = rotl32(temp, ps[i & 3]); | ||
180 | temp += B; | ||
181 | A = D; | ||
182 | D = C; | ||
183 | C = B; | ||
184 | B = temp; | ||
185 | } | ||
186 | ps += 4; | ||
187 | for (i = 0; i < 16; i++) { | ||
188 | temp = A + FI(B, C, D) + cwp[(int) (*pp++)] + *pc++; | ||
189 | temp = rotl32(temp, ps[i & 3]); | ||
190 | temp += B; | ||
191 | A = D; | ||
192 | D = C; | ||
193 | C = B; | ||
194 | B = temp; | ||
195 | } | ||
196 | |||
197 | # endif /* MD5_SIZE_VS_SPEED > 2 */ | ||
198 | #else | ||
199 | /* First round: using the given function, the context and a constant | ||
200 | the next context is computed. Because the algorithms processing | ||
201 | unit is a 32-bit word and it is determined to work on words in | ||
202 | little endian byte order we perhaps have to change the byte order | ||
203 | before the computation. To reduce the work for the next steps | ||
204 | we store the swapped words in the array CORRECT_WORDS. */ | ||
205 | # define OP(a, b, c, d, s, T) \ | ||
210 | do { \ | 206 | do { \ |
211 | a += FF (b, c, d) + (*cwp++ = SWAP_LE32(*words)) + T; \ | 207 | a += FF(b, c, d) + (*cwp++ = SWAP_LE32(*words)) + T; \ |
212 | ++words; \ | 208 | ++words; \ |
213 | CYCLIC (a, s); \ | 209 | a = rotl32(a, s); \ |
214 | a += b; \ | 210 | a += b; \ |
215 | } while (0) | 211 | } while (0) |
216 | 212 | ||
217 | /* It is unfortunate that C does not provide an operator for | 213 | /* Before we start, one word to the strange constants. |
218 | cyclic rotation. Hope the C compiler is smart enough. */ | 214 | They are defined in RFC 1321 as |
219 | /* gcc 2.95.4 seems to be --aaronl */ | 215 | T[i] = (int)(4294967296.0 * fabs(sin(i))), i=1..64 |
220 | # define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s))) | 216 | */ |
221 | 217 | ||
222 | /* Before we start, one word to the strange constants. | 218 | # if MD5_SIZE_VS_SPEED == 1 |
223 | They are defined in RFC 1321 as | 219 | const uint32_t *pc; |
224 | 220 | const char *pp; | |
225 | T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64 | 221 | int i; |
226 | */ | 222 | # endif /* MD5_SIZE_VS_SPEED */ |
227 | 223 | ||
228 | # if MD5_SIZE_VS_SPEED == 1 | 224 | /* Round 1. */ |
229 | const uint32_t *pc; | 225 | # if MD5_SIZE_VS_SPEED == 1 |
230 | const char *pp; | 226 | pc = C_array; |
231 | int i; | 227 | for (i = 0; i < 4; i++) { |
232 | # endif /* MD5_SIZE_VS_SPEED */ | 228 | OP(A, B, C, D, 7, *pc++); |
233 | 229 | OP(D, A, B, C, 12, *pc++); | |
234 | /* Round 1. */ | 230 | OP(C, D, A, B, 17, *pc++); |
235 | # if MD5_SIZE_VS_SPEED == 1 | 231 | OP(B, C, D, A, 22, *pc++); |
236 | pc = C_array; | 232 | } |
237 | for (i = 0; i < 4; i++) { | 233 | # else |
238 | OP(A, B, C, D, 7, *pc++); | 234 | OP(A, B, C, D, 7, 0xd76aa478); |
239 | OP(D, A, B, C, 12, *pc++); | 235 | OP(D, A, B, C, 12, 0xe8c7b756); |
240 | OP(C, D, A, B, 17, *pc++); | 236 | OP(C, D, A, B, 17, 0x242070db); |
241 | OP(B, C, D, A, 22, *pc++); | 237 | OP(B, C, D, A, 22, 0xc1bdceee); |
242 | } | 238 | OP(A, B, C, D, 7, 0xf57c0faf); |
243 | # else | 239 | OP(D, A, B, C, 12, 0x4787c62a); |
244 | OP(A, B, C, D, 7, 0xd76aa478); | 240 | OP(C, D, A, B, 17, 0xa8304613); |
245 | OP(D, A, B, C, 12, 0xe8c7b756); | 241 | OP(B, C, D, A, 22, 0xfd469501); |
246 | OP(C, D, A, B, 17, 0x242070db); | 242 | OP(A, B, C, D, 7, 0x698098d8); |
247 | OP(B, C, D, A, 22, 0xc1bdceee); | 243 | OP(D, A, B, C, 12, 0x8b44f7af); |
248 | OP(A, B, C, D, 7, 0xf57c0faf); | 244 | OP(C, D, A, B, 17, 0xffff5bb1); |
249 | OP(D, A, B, C, 12, 0x4787c62a); | 245 | OP(B, C, D, A, 22, 0x895cd7be); |
250 | OP(C, D, A, B, 17, 0xa8304613); | 246 | OP(A, B, C, D, 7, 0x6b901122); |
251 | OP(B, C, D, A, 22, 0xfd469501); | 247 | OP(D, A, B, C, 12, 0xfd987193); |
252 | OP(A, B, C, D, 7, 0x698098d8); | 248 | OP(C, D, A, B, 17, 0xa679438e); |
253 | OP(D, A, B, C, 12, 0x8b44f7af); | 249 | OP(B, C, D, A, 22, 0x49b40821); |
254 | OP(C, D, A, B, 17, 0xffff5bb1); | 250 | # endif/* MD5_SIZE_VS_SPEED == 1 */ |
255 | OP(B, C, D, A, 22, 0x895cd7be); | 251 | |
256 | OP(A, B, C, D, 7, 0x6b901122); | 252 | /* For the second to fourth round we have the possibly swapped words |
257 | OP(D, A, B, C, 12, 0xfd987193); | 253 | in CORRECT_WORDS. Redefine the macro to take an additional first |
258 | OP(C, D, A, B, 17, 0xa679438e); | 254 | argument specifying the function to use. */ |
259 | OP(B, C, D, A, 22, 0x49b40821); | 255 | # undef OP |
260 | # endif /* MD5_SIZE_VS_SPEED == 1 */ | 256 | # define OP(f, a, b, c, d, k, s, T) \ |
261 | |||
262 | /* For the second to fourth round we have the possibly swapped words | ||
263 | in CORRECT_WORDS. Redefine the macro to take an additional first | ||
264 | argument specifying the function to use. */ | ||
265 | # undef OP | ||
266 | # define OP(f, a, b, c, d, k, s, T) \ | ||
267 | do { \ | 257 | do { \ |
268 | a += f (b, c, d) + correct_words[k] + T; \ | 258 | a += f(b, c, d) + correct_words[k] + T; \ |
269 | CYCLIC (a, s); \ | 259 | a = rotl32(a, s); \ |
270 | a += b; \ | 260 | a += b; \ |
271 | } while (0) | 261 | } while (0) |
272 | 262 | ||
273 | /* Round 2. */ | 263 | /* Round 2. */ |
274 | # if MD5_SIZE_VS_SPEED == 1 | 264 | # if MD5_SIZE_VS_SPEED == 1 |
275 | pp = P_array; | 265 | pp = P_array; |
276 | for (i = 0; i < 4; i++) { | 266 | for (i = 0; i < 4; i++) { |
277 | OP(FG, A, B, C, D, (int) (*pp++), 5, *pc++); | 267 | OP(FG, A, B, C, D, (int) (*pp++), 5, *pc++); |
278 | OP(FG, D, A, B, C, (int) (*pp++), 9, *pc++); | 268 | OP(FG, D, A, B, C, (int) (*pp++), 9, *pc++); |
279 | OP(FG, C, D, A, B, (int) (*pp++), 14, *pc++); | 269 | OP(FG, C, D, A, B, (int) (*pp++), 14, *pc++); |
280 | OP(FG, B, C, D, A, (int) (*pp++), 20, *pc++); | 270 | OP(FG, B, C, D, A, (int) (*pp++), 20, *pc++); |
281 | } | 271 | } |
282 | # else | 272 | # else |
283 | OP(FG, A, B, C, D, 1, 5, 0xf61e2562); | 273 | OP(FG, A, B, C, D, 1, 5, 0xf61e2562); |
284 | OP(FG, D, A, B, C, 6, 9, 0xc040b340); | 274 | OP(FG, D, A, B, C, 6, 9, 0xc040b340); |
285 | OP(FG, C, D, A, B, 11, 14, 0x265e5a51); | 275 | OP(FG, C, D, A, B, 11, 14, 0x265e5a51); |
286 | OP(FG, B, C, D, A, 0, 20, 0xe9b6c7aa); | 276 | OP(FG, B, C, D, A, 0, 20, 0xe9b6c7aa); |
287 | OP(FG, A, B, C, D, 5, 5, 0xd62f105d); | 277 | OP(FG, A, B, C, D, 5, 5, 0xd62f105d); |
288 | OP(FG, D, A, B, C, 10, 9, 0x02441453); | 278 | OP(FG, D, A, B, C, 10, 9, 0x02441453); |
289 | OP(FG, C, D, A, B, 15, 14, 0xd8a1e681); | 279 | OP(FG, C, D, A, B, 15, 14, 0xd8a1e681); |
290 | OP(FG, B, C, D, A, 4, 20, 0xe7d3fbc8); | 280 | OP(FG, B, C, D, A, 4, 20, 0xe7d3fbc8); |
291 | OP(FG, A, B, C, D, 9, 5, 0x21e1cde6); | 281 | OP(FG, A, B, C, D, 9, 5, 0x21e1cde6); |
292 | OP(FG, D, A, B, C, 14, 9, 0xc33707d6); | 282 | OP(FG, D, A, B, C, 14, 9, 0xc33707d6); |
293 | OP(FG, C, D, A, B, 3, 14, 0xf4d50d87); | 283 | OP(FG, C, D, A, B, 3, 14, 0xf4d50d87); |
294 | OP(FG, B, C, D, A, 8, 20, 0x455a14ed); | 284 | OP(FG, B, C, D, A, 8, 20, 0x455a14ed); |
295 | OP(FG, A, B, C, D, 13, 5, 0xa9e3e905); | 285 | OP(FG, A, B, C, D, 13, 5, 0xa9e3e905); |
296 | OP(FG, D, A, B, C, 2, 9, 0xfcefa3f8); | 286 | OP(FG, D, A, B, C, 2, 9, 0xfcefa3f8); |
297 | OP(FG, C, D, A, B, 7, 14, 0x676f02d9); | 287 | OP(FG, C, D, A, B, 7, 14, 0x676f02d9); |
298 | OP(FG, B, C, D, A, 12, 20, 0x8d2a4c8a); | 288 | OP(FG, B, C, D, A, 12, 20, 0x8d2a4c8a); |
299 | # endif /* MD5_SIZE_VS_SPEED == 1 */ | 289 | # endif/* MD5_SIZE_VS_SPEED == 1 */ |
300 | 290 | ||
301 | /* Round 3. */ | 291 | /* Round 3. */ |
302 | # if MD5_SIZE_VS_SPEED == 1 | 292 | # if MD5_SIZE_VS_SPEED == 1 |
303 | for (i = 0; i < 4; i++) { | 293 | for (i = 0; i < 4; i++) { |
304 | OP(FH, A, B, C, D, (int) (*pp++), 4, *pc++); | 294 | OP(FH, A, B, C, D, (int) (*pp++), 4, *pc++); |
305 | OP(FH, D, A, B, C, (int) (*pp++), 11, *pc++); | 295 | OP(FH, D, A, B, C, (int) (*pp++), 11, *pc++); |
306 | OP(FH, C, D, A, B, (int) (*pp++), 16, *pc++); | 296 | OP(FH, C, D, A, B, (int) (*pp++), 16, *pc++); |
307 | OP(FH, B, C, D, A, (int) (*pp++), 23, *pc++); | 297 | OP(FH, B, C, D, A, (int) (*pp++), 23, *pc++); |
308 | } | 298 | } |
309 | # else | 299 | # else |
310 | OP(FH, A, B, C, D, 5, 4, 0xfffa3942); | 300 | OP(FH, A, B, C, D, 5, 4, 0xfffa3942); |
311 | OP(FH, D, A, B, C, 8, 11, 0x8771f681); | 301 | OP(FH, D, A, B, C, 8, 11, 0x8771f681); |
312 | OP(FH, C, D, A, B, 11, 16, 0x6d9d6122); | 302 | OP(FH, C, D, A, B, 11, 16, 0x6d9d6122); |
313 | OP(FH, B, C, D, A, 14, 23, 0xfde5380c); | 303 | OP(FH, B, C, D, A, 14, 23, 0xfde5380c); |
314 | OP(FH, A, B, C, D, 1, 4, 0xa4beea44); | 304 | OP(FH, A, B, C, D, 1, 4, 0xa4beea44); |
315 | OP(FH, D, A, B, C, 4, 11, 0x4bdecfa9); | 305 | OP(FH, D, A, B, C, 4, 11, 0x4bdecfa9); |
316 | OP(FH, C, D, A, B, 7, 16, 0xf6bb4b60); | 306 | OP(FH, C, D, A, B, 7, 16, 0xf6bb4b60); |
317 | OP(FH, B, C, D, A, 10, 23, 0xbebfbc70); | 307 | OP(FH, B, C, D, A, 10, 23, 0xbebfbc70); |
318 | OP(FH, A, B, C, D, 13, 4, 0x289b7ec6); | 308 | OP(FH, A, B, C, D, 13, 4, 0x289b7ec6); |
319 | OP(FH, D, A, B, C, 0, 11, 0xeaa127fa); | 309 | OP(FH, D, A, B, C, 0, 11, 0xeaa127fa); |
320 | OP(FH, C, D, A, B, 3, 16, 0xd4ef3085); | 310 | OP(FH, C, D, A, B, 3, 16, 0xd4ef3085); |
321 | OP(FH, B, C, D, A, 6, 23, 0x04881d05); | 311 | OP(FH, B, C, D, A, 6, 23, 0x04881d05); |
322 | OP(FH, A, B, C, D, 9, 4, 0xd9d4d039); | 312 | OP(FH, A, B, C, D, 9, 4, 0xd9d4d039); |
323 | OP(FH, D, A, B, C, 12, 11, 0xe6db99e5); | 313 | OP(FH, D, A, B, C, 12, 11, 0xe6db99e5); |
324 | OP(FH, C, D, A, B, 15, 16, 0x1fa27cf8); | 314 | OP(FH, C, D, A, B, 15, 16, 0x1fa27cf8); |
325 | OP(FH, B, C, D, A, 2, 23, 0xc4ac5665); | 315 | OP(FH, B, C, D, A, 2, 23, 0xc4ac5665); |
326 | # endif /* MD5_SIZE_VS_SPEED == 1 */ | 316 | # endif/* MD5_SIZE_VS_SPEED == 1 */ |
327 | 317 | ||
328 | /* Round 4. */ | 318 | /* Round 4. */ |
329 | # if MD5_SIZE_VS_SPEED == 1 | 319 | # if MD5_SIZE_VS_SPEED == 1 |
330 | for (i = 0; i < 4; i++) { | 320 | for (i = 0; i < 4; i++) { |
331 | OP(FI, A, B, C, D, (int) (*pp++), 6, *pc++); | 321 | OP(FI, A, B, C, D, (int) (*pp++), 6, *pc++); |
332 | OP(FI, D, A, B, C, (int) (*pp++), 10, *pc++); | 322 | OP(FI, D, A, B, C, (int) (*pp++), 10, *pc++); |
333 | OP(FI, C, D, A, B, (int) (*pp++), 15, *pc++); | 323 | OP(FI, C, D, A, B, (int) (*pp++), 15, *pc++); |
334 | OP(FI, B, C, D, A, (int) (*pp++), 21, *pc++); | 324 | OP(FI, B, C, D, A, (int) (*pp++), 21, *pc++); |
335 | } | 325 | } |
336 | # else | 326 | # else |
337 | OP(FI, A, B, C, D, 0, 6, 0xf4292244); | 327 | OP(FI, A, B, C, D, 0, 6, 0xf4292244); |
338 | OP(FI, D, A, B, C, 7, 10, 0x432aff97); | 328 | OP(FI, D, A, B, C, 7, 10, 0x432aff97); |
339 | OP(FI, C, D, A, B, 14, 15, 0xab9423a7); | 329 | OP(FI, C, D, A, B, 14, 15, 0xab9423a7); |
340 | OP(FI, B, C, D, A, 5, 21, 0xfc93a039); | 330 | OP(FI, B, C, D, A, 5, 21, 0xfc93a039); |
341 | OP(FI, A, B, C, D, 12, 6, 0x655b59c3); | 331 | OP(FI, A, B, C, D, 12, 6, 0x655b59c3); |
342 | OP(FI, D, A, B, C, 3, 10, 0x8f0ccc92); | 332 | OP(FI, D, A, B, C, 3, 10, 0x8f0ccc92); |
343 | OP(FI, C, D, A, B, 10, 15, 0xffeff47d); | 333 | OP(FI, C, D, A, B, 10, 15, 0xffeff47d); |
344 | OP(FI, B, C, D, A, 1, 21, 0x85845dd1); | 334 | OP(FI, B, C, D, A, 1, 21, 0x85845dd1); |
345 | OP(FI, A, B, C, D, 8, 6, 0x6fa87e4f); | 335 | OP(FI, A, B, C, D, 8, 6, 0x6fa87e4f); |
346 | OP(FI, D, A, B, C, 15, 10, 0xfe2ce6e0); | 336 | OP(FI, D, A, B, C, 15, 10, 0xfe2ce6e0); |
347 | OP(FI, C, D, A, B, 6, 15, 0xa3014314); | 337 | OP(FI, C, D, A, B, 6, 15, 0xa3014314); |
348 | OP(FI, B, C, D, A, 13, 21, 0x4e0811a1); | 338 | OP(FI, B, C, D, A, 13, 21, 0x4e0811a1); |
349 | OP(FI, A, B, C, D, 4, 6, 0xf7537e82); | 339 | OP(FI, A, B, C, D, 4, 6, 0xf7537e82); |
350 | OP(FI, D, A, B, C, 11, 10, 0xbd3af235); | 340 | OP(FI, D, A, B, C, 11, 10, 0xbd3af235); |
351 | OP(FI, C, D, A, B, 2, 15, 0x2ad7d2bb); | 341 | OP(FI, C, D, A, B, 2, 15, 0x2ad7d2bb); |
352 | OP(FI, B, C, D, A, 9, 21, 0xeb86d391); | 342 | OP(FI, B, C, D, A, 9, 21, 0xeb86d391); |
353 | # endif /* MD5_SIZE_VS_SPEED == 1 */ | 343 | # endif /* MD5_SIZE_VS_SPEED == 1 */ |
354 | # endif /* MD5_SIZE_VS_SPEED > 1 */ | 344 | #endif /* MD5_SIZE_VS_SPEED > 1 */ |
355 | 345 | ||
356 | /* Add the starting values of the context. */ | 346 | /* Add the starting values of the context. */ |
357 | A += A_save; | 347 | A += A_save; |
358 | B += B_save; | 348 | B += B_save; |
359 | C += C_save; | 349 | C += C_save; |
360 | D += D_save; | 350 | D += D_save; |
361 | 351 | ||
362 | /* Put checksum in context given as argument. */ | 352 | /* Put checksum in context given as argument. */ |
363 | ctx->A = A; | 353 | ctx->A = A; |
@@ -370,31 +360,26 @@ static void md5_hash_block(const void *buffer, md5_ctx_t *ctx) | |||
370 | * with chunks of data that are 4-byte aligned and a multiple of 64 bytes. | 360 | * with chunks of data that are 4-byte aligned and a multiple of 64 bytes. |
371 | * This function's internal buffer remembers previous data until it has 64 | 361 | * This function's internal buffer remembers previous data until it has 64 |
372 | * bytes worth to pass on. Call md5_end() to flush this buffer. */ | 362 | * bytes worth to pass on. Call md5_end() to flush this buffer. */ |
373 | |||
374 | void FAST_FUNC md5_hash(const void *buffer, size_t len, md5_ctx_t *ctx) | 363 | void FAST_FUNC md5_hash(const void *buffer, size_t len, md5_ctx_t *ctx) |
375 | { | 364 | { |
376 | char *buf=(char *)buffer; | 365 | char *buf = (char *)buffer; |
377 | 366 | ||
378 | /* RFC 1321 specifies the possible length of the file up to 2^64 bits, | 367 | /* RFC 1321 specifies the possible length of the file up to 2^64 bits, |
379 | * Here we only track the number of bytes. */ | 368 | * Here we only track the number of bytes. */ |
380 | |||
381 | ctx->total += len; | 369 | ctx->total += len; |
382 | 370 | ||
383 | // Process all input. | 371 | /* Process all input. */ |
384 | |||
385 | while (len) { | 372 | while (len) { |
386 | unsigned i = 64 - ctx->buflen; | 373 | unsigned i = 64 - ctx->buflen; |
387 | 374 | ||
388 | // Copy data into aligned buffer. | 375 | /* Copy data into aligned buffer. */ |
389 | |||
390 | if (i > len) i = len; | 376 | if (i > len) i = len; |
391 | memcpy(ctx->buffer + ctx->buflen, buf, i); | 377 | memcpy(ctx->buffer + ctx->buflen, buf, i); |
392 | len -= i; | 378 | len -= i; |
393 | ctx->buflen += i; | 379 | ctx->buflen += i; |
394 | buf += i; | 380 | buf += i; |
395 | 381 | ||
396 | // When buffer fills up, process it. | 382 | /* When buffer fills up, process it. */ |
397 | |||
398 | if (ctx->buflen == 64) { | 383 | if (ctx->buflen == 64) { |
399 | md5_hash_block(ctx->buffer, ctx); | 384 | md5_hash_block(ctx->buffer, ctx); |
400 | ctx->buflen = 0; | 385 | ctx->buflen = 0; |
@@ -410,23 +395,25 @@ void FAST_FUNC md5_hash(const void *buffer, size_t len, md5_ctx_t *ctx) | |||
410 | * IMPORTANT: On some systems it is required that RESBUF is correctly | 395 | * IMPORTANT: On some systems it is required that RESBUF is correctly |
411 | * aligned for a 32 bits value. | 396 | * aligned for a 32 bits value. |
412 | */ | 397 | */ |
413 | void* FAST_FUNC md5_end(void *resbuf, md5_ctx_t *ctx) | 398 | void FAST_FUNC md5_end(void *resbuf, md5_ctx_t *ctx) |
414 | { | 399 | { |
415 | char *buf = ctx->buffer; | 400 | char *buf = ctx->buffer; |
416 | int i; | 401 | int i; |
417 | 402 | ||
418 | /* Pad data to block size. */ | 403 | /* Pad data to block size. */ |
419 | |||
420 | buf[ctx->buflen++] = 0x80; | 404 | buf[ctx->buflen++] = 0x80; |
421 | memset(buf + ctx->buflen, 0, 128 - ctx->buflen); | 405 | memset(buf + ctx->buflen, 0, 128 - ctx->buflen); |
422 | 406 | ||
423 | /* Put the 64-bit file length in *bits* at the end of the buffer. */ | 407 | /* Put the 64-bit file length in *bits* at the end of the buffer. */ |
424 | ctx->total <<= 3; | 408 | ctx->total <<= 3; |
425 | if (ctx->buflen > 56) buf += 64; | 409 | if (ctx->buflen > 56) |
426 | for (i = 0; i < 8; i++) buf[56 + i] = ctx->total >> (i*8); | 410 | buf += 64; |
411 | for (i = 0; i < 8; i++) | ||
412 | buf[56 + i] = ctx->total >> (i*8); | ||
427 | 413 | ||
428 | /* Process last bytes. */ | 414 | /* Process last bytes. */ |
429 | if (buf != ctx->buffer) md5_hash_block(ctx->buffer, ctx); | 415 | if (buf != ctx->buffer) |
416 | md5_hash_block(ctx->buffer, ctx); | ||
430 | md5_hash_block(buf, ctx); | 417 | md5_hash_block(buf, ctx); |
431 | 418 | ||
432 | /* Put result from CTX in first 16 bytes following RESBUF. The result is | 419 | /* Put result from CTX in first 16 bytes following RESBUF. The result is |
@@ -440,7 +427,4 @@ void* FAST_FUNC md5_end(void *resbuf, md5_ctx_t *ctx) | |||
440 | ((uint32_t *) resbuf)[1] = SWAP_LE32(ctx->B); | 427 | ((uint32_t *) resbuf)[1] = SWAP_LE32(ctx->B); |
441 | ((uint32_t *) resbuf)[2] = SWAP_LE32(ctx->C); | 428 | ((uint32_t *) resbuf)[2] = SWAP_LE32(ctx->C); |
442 | ((uint32_t *) resbuf)[3] = SWAP_LE32(ctx->D); | 429 | ((uint32_t *) resbuf)[3] = SWAP_LE32(ctx->D); |
443 | |||
444 | return resbuf; | ||
445 | } | 430 | } |
446 | |||
diff --git a/libbb/md5prime.c b/libbb/md5prime.c new file mode 100644 index 000000000..7986f4d29 --- /dev/null +++ b/libbb/md5prime.c | |||
@@ -0,0 +1,460 @@ | |||
1 | /* This file is not used by busybox right now. | ||
2 | * However, the code here seems to be a tiny bit smaller | ||
3 | * than one in md5.c. Need to investigate which one | ||
4 | * is better overall... | ||
5 | * Hint: grep for md5prime to find places where you can switch | ||
6 | * md5.c/md5prime.c | ||
7 | */ | ||
8 | |||
9 | /* | ||
10 | * MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm | ||
11 | * | ||
12 | * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All | ||
13 | * rights reserved. | ||
14 | * | ||
15 | * License to copy and use this software is granted provided that it | ||
16 | * is identified as the "RSA Data Security, Inc. MD5 Message-Digest | ||
17 | * Algorithm" in all material mentioning or referencing this software | ||
18 | * or this function. | ||
19 | * | ||
20 | * License is also granted to make and use derivative works provided | ||
21 | * that such works are identified as "derived from the RSA Data | ||
22 | * Security, Inc. MD5 Message-Digest Algorithm" in all material | ||
23 | * mentioning or referencing the derived work. | ||
24 | * | ||
25 | * RSA Data Security, Inc. makes no representations concerning either | ||
26 | * the merchantability of this software or the suitability of this | ||
27 | * software for any particular purpose. It is provided "as is" | ||
28 | * without express or implied warranty of any kind. | ||
29 | * | ||
30 | * These notices must be retained in any copies of any part of this | ||
31 | * documentation and/or software. | ||
32 | * | ||
33 | * $FreeBSD: src/lib/libmd/md5c.c,v 1.9.2.1 1999/08/29 14:57:12 peter Exp $ | ||
34 | * | ||
35 | * This code is the same as the code published by RSA Inc. It has been | ||
36 | * edited for clarity and style only. | ||
37 | * | ||
38 | * ---------------------------------------------------------------------------- | ||
39 | * The md5_crypt() function was taken from freeBSD's libcrypt and contains | ||
40 | * this license: | ||
41 | * "THE BEER-WARE LICENSE" (Revision 42): | ||
42 | * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you | ||
43 | * can do whatever you want with this stuff. If we meet some day, and you think | ||
44 | * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp | ||
45 | * | ||
46 | * $FreeBSD: src/lib/libcrypt/crypt.c,v 1.7.2.1 1999/08/29 14:56:33 peter Exp $ | ||
47 | * | ||
48 | * ---------------------------------------------------------------------------- | ||
49 | * On April 19th, 2001 md5_crypt() was modified to make it reentrant | ||
50 | * by Erik Andersen <andersen@uclibc.org> | ||
51 | * | ||
52 | * June 28, 2001 Manuel Novoa III | ||
53 | * | ||
54 | * "Un-inlined" code using loops and static const tables in order to | ||
55 | * reduce generated code size (on i386 from approx 4k to approx 2.5k). | ||
56 | * | ||
57 | * June 29, 2001 Manuel Novoa III | ||
58 | * | ||
59 | * Completely removed static PADDING array. | ||
60 | * | ||
61 | * Reintroduced the loop unrolling in md5_transform and added the | ||
62 | * MD5_SIZE_VS_SPEED option for configurability. Define below as: | ||
63 | * 0 fully unrolled loops | ||
64 | * 1 partially unrolled (4 ops per loop) | ||
65 | * 2 no unrolling -- introduces the need to swap 4 variables (slow) | ||
66 | * 3 no unrolling and all 4 loops merged into one with switch | ||
67 | * in each loop (glacial) | ||
68 | * On i386, sizes are roughly (-Os -fno-builtin): | ||
69 | * 0: 3k 1: 2.5k 2: 2.2k 3: 2k | ||
70 | * | ||
71 | * Since SuSv3 does not require crypt_r, modified again August 7, 2002 | ||
72 | * by Erik Andersen to remove reentrance stuff... | ||
73 | */ | ||
74 | |||
75 | #include "libbb.h" | ||
76 | |||
77 | /* 1: fastest, 3: smallest */ | ||
78 | #if CONFIG_MD5_SIZE_VS_SPEED < 1 | ||
79 | # define MD5_SIZE_VS_SPEED 1 | ||
80 | #elif CONFIG_MD5_SIZE_VS_SPEED > 3 | ||
81 | # define MD5_SIZE_VS_SPEED 3 | ||
82 | #else | ||
83 | # define MD5_SIZE_VS_SPEED CONFIG_MD5_SIZE_VS_SPEED | ||
84 | #endif | ||
85 | |||
86 | #if BB_LITTLE_ENDIAN | ||
87 | #define memcpy32_cpu2le memcpy | ||
88 | #define memcpy32_le2cpu memcpy | ||
89 | #else | ||
90 | /* Encodes input (uint32_t) into output (unsigned char). | ||
91 | * Assumes len is a multiple of 4. */ | ||
92 | static void | ||
93 | memcpy32_cpu2le(unsigned char *output, uint32_t *input, unsigned len) | ||
94 | { | ||
95 | unsigned i, j; | ||
96 | for (i = 0, j = 0; j < len; i++, j += 4) { | ||
97 | output[j] = input[i]; | ||
98 | output[j+1] = (input[i] >> 8); | ||
99 | output[j+2] = (input[i] >> 16); | ||
100 | output[j+3] = (input[i] >> 24); | ||
101 | } | ||
102 | } | ||
103 | /* Decodes input (unsigned char) into output (uint32_t). | ||
104 | * Assumes len is a multiple of 4. */ | ||
105 | static void | ||
106 | memcpy32_le2cpu(uint32_t *output, const unsigned char *input, unsigned len) | ||
107 | { | ||
108 | unsigned i, j; | ||
109 | for (i = 0, j = 0; j < len; i++, j += 4) | ||
110 | output[i] = ((uint32_t)input[j]) | ||
111 | | (((uint32_t)input[j+1]) << 8) | ||
112 | | (((uint32_t)input[j+2]) << 16) | ||
113 | | (((uint32_t)input[j+3]) << 24); | ||
114 | } | ||
115 | #endif /* i386 */ | ||
116 | |||
117 | /* F, G, H and I are basic MD5 functions. */ | ||
118 | #define F(x, y, z) (((x) & (y)) | (~(x) & (z))) | ||
119 | #define G(x, y, z) (((x) & (z)) | ((y) & ~(z))) | ||
120 | #define H(x, y, z) ((x) ^ (y) ^ (z)) | ||
121 | #define I(x, y, z) ((y) ^ ((x) | ~(z))) | ||
122 | |||
123 | /* rotl32 rotates x left n bits. */ | ||
124 | #define rotl32(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) | ||
125 | |||
126 | /* | ||
127 | * FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. | ||
128 | * Rotation is separate from addition to prevent recomputation. | ||
129 | */ | ||
130 | #define FF(a, b, c, d, x, s, ac) { \ | ||
131 | (a) += F((b), (c), (d)) + (x) + (uint32_t)(ac); \ | ||
132 | (a) = rotl32((a), (s)); \ | ||
133 | (a) += (b); \ | ||
134 | } | ||
135 | #define GG(a, b, c, d, x, s, ac) { \ | ||
136 | (a) += G((b), (c), (d)) + (x) + (uint32_t)(ac); \ | ||
137 | (a) = rotl32((a), (s)); \ | ||
138 | (a) += (b); \ | ||
139 | } | ||
140 | #define HH(a, b, c, d, x, s, ac) { \ | ||
141 | (a) += H((b), (c), (d)) + (x) + (uint32_t)(ac); \ | ||
142 | (a) = rotl32((a), (s)); \ | ||
143 | (a) += (b); \ | ||
144 | } | ||
145 | #define II(a, b, c, d, x, s, ac) { \ | ||
146 | (a) += I((b), (c), (d)) + (x) + (uint32_t)(ac); \ | ||
147 | (a) = rotl32((a), (s)); \ | ||
148 | (a) += (b); \ | ||
149 | } | ||
150 | |||
151 | /* MD5 basic transformation. Transforms state based on block. */ | ||
152 | static void md5_transform(uint32_t state[4], const unsigned char block[64]) | ||
153 | { | ||
154 | uint32_t a, b, c, d, x[16]; | ||
155 | #if MD5_SIZE_VS_SPEED > 1 | ||
156 | uint32_t temp; | ||
157 | const unsigned char *ps; | ||
158 | |||
159 | static const unsigned char S[] = { | ||
160 | 7, 12, 17, 22, | ||
161 | 5, 9, 14, 20, | ||
162 | 4, 11, 16, 23, | ||
163 | 6, 10, 15, 21 | ||
164 | }; | ||
165 | #endif /* MD5_SIZE_VS_SPEED > 1 */ | ||
166 | |||
167 | #if MD5_SIZE_VS_SPEED > 0 | ||
168 | const uint32_t *pc; | ||
169 | const unsigned char *pp; | ||
170 | int i; | ||
171 | |||
172 | static const uint32_t C[] = { | ||
173 | /* round 1 */ | ||
174 | 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, | ||
175 | 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, | ||
176 | 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, | ||
177 | 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, | ||
178 | /* round 2 */ | ||
179 | 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, | ||
180 | 0xd62f105d, 0x2441453, 0xd8a1e681, 0xe7d3fbc8, | ||
181 | 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, | ||
182 | 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, | ||
183 | /* round 3 */ | ||
184 | 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, | ||
185 | 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, | ||
186 | 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05, | ||
187 | 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, | ||
188 | /* round 4 */ | ||
189 | 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, | ||
190 | 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, | ||
191 | 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, | ||
192 | 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 | ||
193 | }; | ||
194 | static const unsigned char P[] = { | ||
195 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 1 */ | ||
196 | 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, /* 2 */ | ||
197 | 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, /* 3 */ | ||
198 | 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 /* 4 */ | ||
199 | }; | ||
200 | |||
201 | #endif /* MD5_SIZE_VS_SPEED > 0 */ | ||
202 | |||
203 | memcpy32_le2cpu(x, block, 64); | ||
204 | |||
205 | a = state[0]; | ||
206 | b = state[1]; | ||
207 | c = state[2]; | ||
208 | d = state[3]; | ||
209 | |||
210 | #if MD5_SIZE_VS_SPEED > 2 | ||
211 | pc = C; | ||
212 | pp = P; | ||
213 | ps = S - 4; | ||
214 | for (i = 0; i < 64; i++) { | ||
215 | if ((i & 0x0f) == 0) ps += 4; | ||
216 | temp = a; | ||
217 | switch (i>>4) { | ||
218 | case 0: | ||
219 | temp += F(b, c, d); | ||
220 | break; | ||
221 | case 1: | ||
222 | temp += G(b, c, d); | ||
223 | break; | ||
224 | case 2: | ||
225 | temp += H(b, c, d); | ||
226 | break; | ||
227 | case 3: | ||
228 | temp += I(b, c, d); | ||
229 | break; | ||
230 | } | ||
231 | temp += x[*pp++] + *pc++; | ||
232 | temp = rotl32(temp, ps[i & 3]); | ||
233 | temp += b; | ||
234 | a = d; d = c; c = b; b = temp; | ||
235 | } | ||
236 | #elif MD5_SIZE_VS_SPEED > 1 | ||
237 | pc = C; | ||
238 | pp = P; | ||
239 | ps = S; | ||
240 | /* Round 1 */ | ||
241 | for (i = 0; i < 16; i++) { | ||
242 | FF(a, b, c, d, x[*pp], ps[i & 0x3], *pc); pp++; pc++; | ||
243 | temp = d; d = c; c = b; b = a; a = temp; | ||
244 | } | ||
245 | /* Round 2 */ | ||
246 | ps += 4; | ||
247 | for (; i < 32; i++) { | ||
248 | GG(a, b, c, d, x[*pp], ps[i & 0x3], *pc); pp++; pc++; | ||
249 | temp = d; d = c; c = b; b = a; a = temp; | ||
250 | } | ||
251 | /* Round 3 */ | ||
252 | ps += 4; | ||
253 | for (; i < 48; i++) { | ||
254 | HH(a, b, c, d, x[*pp], ps[i & 0x3], *pc); pp++; pc++; | ||
255 | temp = d; d = c; c = b; b = a; a = temp; | ||
256 | } | ||
257 | /* Round 4 */ | ||
258 | ps += 4; | ||
259 | for (; i < 64; i++) { | ||
260 | II(a, b, c, d, x[*pp], ps[i & 0x3], *pc); pp++; pc++; | ||
261 | temp = d; d = c; c = b; b = a; a = temp; | ||
262 | } | ||
263 | #elif MD5_SIZE_VS_SPEED > 0 | ||
264 | pc = C; | ||
265 | pp = P; | ||
266 | /* Round 1 */ | ||
267 | for (i = 0; i < 4; i++) { | ||
268 | FF(a, b, c, d, x[*pp], 7, *pc); pp++; pc++; | ||
269 | FF(d, a, b, c, x[*pp], 12, *pc); pp++; pc++; | ||
270 | FF(c, d, a, b, x[*pp], 17, *pc); pp++; pc++; | ||
271 | FF(b, c, d, a, x[*pp], 22, *pc); pp++; pc++; | ||
272 | } | ||
273 | /* Round 2 */ | ||
274 | for (i = 0; i < 4; i++) { | ||
275 | GG(a, b, c, d, x[*pp], 5, *pc); pp++; pc++; | ||
276 | GG(d, a, b, c, x[*pp], 9, *pc); pp++; pc++; | ||
277 | GG(c, d, a, b, x[*pp], 14, *pc); pp++; pc++; | ||
278 | GG(b, c, d, a, x[*pp], 20, *pc); pp++; pc++; | ||
279 | } | ||
280 | /* Round 3 */ | ||
281 | for (i = 0; i < 4; i++) { | ||
282 | HH(a, b, c, d, x[*pp], 4, *pc); pp++; pc++; | ||
283 | HH(d, a, b, c, x[*pp], 11, *pc); pp++; pc++; | ||
284 | HH(c, d, a, b, x[*pp], 16, *pc); pp++; pc++; | ||
285 | HH(b, c, d, a, x[*pp], 23, *pc); pp++; pc++; | ||
286 | } | ||
287 | /* Round 4 */ | ||
288 | for (i = 0; i < 4; i++) { | ||
289 | II(a, b, c, d, x[*pp], 6, *pc); pp++; pc++; | ||
290 | II(d, a, b, c, x[*pp], 10, *pc); pp++; pc++; | ||
291 | II(c, d, a, b, x[*pp], 15, *pc); pp++; pc++; | ||
292 | II(b, c, d, a, x[*pp], 21, *pc); pp++; pc++; | ||
293 | } | ||
294 | #else | ||
295 | /* Round 1 */ | ||
296 | #define S11 7 | ||
297 | #define S12 12 | ||
298 | #define S13 17 | ||
299 | #define S14 22 | ||
300 | FF(a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ | ||
301 | FF(d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ | ||
302 | FF(c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ | ||
303 | FF(b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ | ||
304 | FF(a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ | ||
305 | FF(d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ | ||
306 | FF(c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ | ||
307 | FF(b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ | ||
308 | FF(a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ | ||
309 | FF(d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ | ||
310 | FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ | ||
311 | FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ | ||
312 | FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ | ||
313 | FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ | ||
314 | FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ | ||
315 | FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ | ||
316 | /* Round 2 */ | ||
317 | #define S21 5 | ||
318 | #define S22 9 | ||
319 | #define S23 14 | ||
320 | #define S24 20 | ||
321 | GG(a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ | ||
322 | GG(d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ | ||
323 | GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ | ||
324 | GG(b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ | ||
325 | GG(a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ | ||
326 | GG(d, a, b, c, x[10], S22, 0x2441453); /* 22 */ | ||
327 | GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ | ||
328 | GG(b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ | ||
329 | GG(a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ | ||
330 | GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ | ||
331 | GG(c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ | ||
332 | GG(b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ | ||
333 | GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ | ||
334 | GG(d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ | ||
335 | GG(c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ | ||
336 | GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ | ||
337 | /* Round 3 */ | ||
338 | #define S31 4 | ||
339 | #define S32 11 | ||
340 | #define S33 16 | ||
341 | #define S34 23 | ||
342 | HH(a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ | ||
343 | HH(d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ | ||
344 | HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ | ||
345 | HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ | ||
346 | HH(a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ | ||
347 | HH(d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ | ||
348 | HH(c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ | ||
349 | HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ | ||
350 | HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ | ||
351 | HH(d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ | ||
352 | HH(c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ | ||
353 | HH(b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ | ||
354 | HH(a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ | ||
355 | HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ | ||
356 | HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ | ||
357 | HH(b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ | ||
358 | /* Round 4 */ | ||
359 | #define S41 6 | ||
360 | #define S42 10 | ||
361 | #define S43 15 | ||
362 | #define S44 21 | ||
363 | II(a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ | ||
364 | II(d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ | ||
365 | II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ | ||
366 | II(b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ | ||
367 | II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ | ||
368 | II(d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ | ||
369 | II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ | ||
370 | II(b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ | ||
371 | II(a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ | ||
372 | II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ | ||
373 | II(c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ | ||
374 | II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ | ||
375 | II(a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ | ||
376 | II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ | ||
377 | II(c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ | ||
378 | II(b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ | ||
379 | #endif | ||
380 | |||
381 | state[0] += a; | ||
382 | state[1] += b; | ||
383 | state[2] += c; | ||
384 | state[3] += d; | ||
385 | |||
386 | /* Zeroize sensitive information. */ | ||
387 | memset(x, 0, sizeof(x)); | ||
388 | } | ||
389 | |||
390 | |||
391 | /* MD5 initialization. */ | ||
392 | void FAST_FUNC md5_begin(md5_ctx_t *context) | ||
393 | { | ||
394 | context->count[0] = context->count[1] = 0; | ||
395 | /* Load magic initialization constants. */ | ||
396 | context->state[0] = 0x67452301; | ||
397 | context->state[1] = 0xefcdab89; | ||
398 | context->state[2] = 0x98badcfe; | ||
399 | context->state[3] = 0x10325476; | ||
400 | } | ||
401 | |||
402 | /* | ||
403 | * MD5 block update operation. Continues an MD5 message-digest | ||
404 | * operation, processing another message block, and updating | ||
405 | * the context. | ||
406 | */ | ||
407 | void FAST_FUNC md5_hash(const void *buffer, size_t inputLen, md5_ctx_t *context) | ||
408 | { | ||
409 | unsigned i, idx, partLen; | ||
410 | const unsigned char *input = buffer; | ||
411 | |||
412 | /* Compute number of bytes mod 64 */ | ||
413 | idx = (context->count[0] >> 3) & 0x3F; | ||
414 | |||
415 | /* Update number of bits */ | ||
416 | context->count[0] += (inputLen << 3); | ||
417 | if (context->count[0] < (inputLen << 3)) | ||
418 | context->count[1]++; | ||
419 | context->count[1] += (inputLen >> 29); | ||
420 | |||
421 | /* Transform as many times as possible. */ | ||
422 | i = 0; | ||
423 | partLen = 64 - idx; | ||
424 | if (inputLen >= partLen) { | ||
425 | memcpy(&context->buffer[idx], input, partLen); | ||
426 | md5_transform(context->state, context->buffer); | ||
427 | for (i = partLen; i + 63 < inputLen; i += 64) | ||
428 | md5_transform(context->state, &input[i]); | ||
429 | idx = 0; | ||
430 | } | ||
431 | |||
432 | /* Buffer remaining input */ | ||
433 | memcpy(&context->buffer[idx], &input[i], inputLen - i); | ||
434 | } | ||
435 | |||
436 | /* | ||
437 | * MD5 finalization. Ends an MD5 message-digest operation, | ||
438 | * writing the message digest. | ||
439 | */ | ||
440 | void FAST_FUNC md5_end(void *digest, md5_ctx_t *context) | ||
441 | { | ||
442 | unsigned idx, padLen; | ||
443 | unsigned char bits[8]; | ||
444 | unsigned char padding[64]; | ||
445 | |||
446 | /* Add padding followed by original length. */ | ||
447 | memset(padding, 0, sizeof(padding)); | ||
448 | padding[0] = 0x80; | ||
449 | /* save number of bits */ | ||
450 | memcpy32_cpu2le(bits, context->count, 8); | ||
451 | /* pad out to 56 mod 64 */ | ||
452 | idx = (context->count[0] >> 3) & 0x3f; | ||
453 | padLen = (idx < 56) ? (56 - idx) : (120 - idx); | ||
454 | md5_hash(padding, padLen, context); | ||
455 | /* append length (before padding) */ | ||
456 | md5_hash(bits, 8, context); | ||
457 | |||
458 | /* Store state in digest */ | ||
459 | memcpy32_cpu2le(digest, context->state, 16); | ||
460 | } | ||
diff --git a/libbb/pw_encrypt_md5.c b/libbb/pw_encrypt_md5.c index b7478aa9d..b02cbecfa 100644 --- a/libbb/pw_encrypt_md5.c +++ b/libbb/pw_encrypt_md5.c | |||
@@ -61,439 +61,14 @@ | |||
61 | * On i386, sizes are roughly (-Os -fno-builtin): | 61 | * On i386, sizes are roughly (-Os -fno-builtin): |
62 | * 0: 3k 1: 2.5k 2: 2.2k 3: 2k | 62 | * 0: 3k 1: 2.5k 2: 2.2k 3: 2k |
63 | * | 63 | * |
64 | * | ||
65 | * Since SuSv3 does not require crypt_r, modified again August 7, 2002 | 64 | * Since SuSv3 does not require crypt_r, modified again August 7, 2002 |
66 | * by Erik Andersen to remove reentrance stuff... | 65 | * by Erik Andersen to remove reentrance stuff... |
67 | */ | 66 | */ |
68 | 67 | ||
69 | /* | ||
70 | * Valid values are 1 (fastest/largest) to 3 (smallest/slowest). | ||
71 | */ | ||
72 | #define MD5_SIZE_OVER_SPEED 3 | ||
73 | |||
74 | /**********************************************************************/ | ||
75 | |||
76 | /* MD5 context. */ | ||
77 | struct MD5Context { | ||
78 | uint32_t state[4]; /* state (ABCD) */ | ||
79 | uint32_t count[2]; /* number of bits, modulo 2^64 (lsb first) */ | ||
80 | unsigned char buffer[64]; /* input buffer */ | ||
81 | }; | ||
82 | |||
83 | static void __md5_Init(struct MD5Context *); | ||
84 | static void __md5_Update(struct MD5Context *, const unsigned char *, unsigned int); | ||
85 | static void __md5_Pad(struct MD5Context *); | ||
86 | static void __md5_Final(unsigned char [16], struct MD5Context *); | ||
87 | static void __md5_Transform(uint32_t [4], const unsigned char [64]); | ||
88 | |||
89 | |||
90 | #define MD5_MAGIC_STR "$1$" | 68 | #define MD5_MAGIC_STR "$1$" |
91 | #define MD5_MAGIC_LEN (sizeof(MD5_MAGIC_STR) - 1) | 69 | #define MD5_MAGIC_LEN (sizeof(MD5_MAGIC_STR) - 1) |
92 | static const unsigned char __md5__magic[] = MD5_MAGIC_STR; | 70 | static const unsigned char __md5__magic[] = MD5_MAGIC_STR; |
93 | 71 | ||
94 | |||
95 | #ifdef i386 | ||
96 | #define __md5_Encode memcpy | ||
97 | #define __md5_Decode memcpy | ||
98 | #else /* i386 */ | ||
99 | |||
100 | /* | ||
101 | * __md5_Encodes input (uint32_t) into output (unsigned char). Assumes len is | ||
102 | * a multiple of 4. | ||
103 | */ | ||
104 | static void | ||
105 | __md5_Encode(unsigned char *output, uint32_t *input, unsigned int len) | ||
106 | { | ||
107 | unsigned int i, j; | ||
108 | |||
109 | for (i = 0, j = 0; j < len; i++, j += 4) { | ||
110 | output[j] = input[i]; | ||
111 | output[j+1] = (input[i] >> 8); | ||
112 | output[j+2] = (input[i] >> 16); | ||
113 | output[j+3] = (input[i] >> 24); | ||
114 | } | ||
115 | } | ||
116 | |||
117 | /* | ||
118 | * __md5_Decodes input (unsigned char) into output (uint32_t). Assumes len is | ||
119 | * a multiple of 4. | ||
120 | */ | ||
121 | static void | ||
122 | __md5_Decode(uint32_t *output, const unsigned char *input, unsigned int len) | ||
123 | { | ||
124 | unsigned int i, j; | ||
125 | |||
126 | for (i = 0, j = 0; j < len; i++, j += 4) | ||
127 | output[i] = ((uint32_t)input[j]) | (((uint32_t)input[j+1]) << 8) | | ||
128 | (((uint32_t)input[j+2]) << 16) | (((uint32_t)input[j+3]) << 24); | ||
129 | } | ||
130 | #endif /* i386 */ | ||
131 | |||
132 | /* F, G, H and I are basic MD5 functions. */ | ||
133 | #define F(x, y, z) (((x) & (y)) | (~(x) & (z))) | ||
134 | #define G(x, y, z) (((x) & (z)) | ((y) & ~(z))) | ||
135 | #define H(x, y, z) ((x) ^ (y) ^ (z)) | ||
136 | #define I(x, y, z) ((y) ^ ((x) | ~(z))) | ||
137 | |||
138 | /* ROTATE_LEFT rotates x left n bits. */ | ||
139 | #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) | ||
140 | |||
141 | /* | ||
142 | * FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. | ||
143 | * Rotation is separate from addition to prevent recomputation. | ||
144 | */ | ||
145 | #define FF(a, b, c, d, x, s, ac) { \ | ||
146 | (a) += F ((b), (c), (d)) + (x) + (uint32_t)(ac); \ | ||
147 | (a) = ROTATE_LEFT((a), (s)); \ | ||
148 | (a) += (b); \ | ||
149 | } | ||
150 | #define GG(a, b, c, d, x, s, ac) { \ | ||
151 | (a) += G ((b), (c), (d)) + (x) + (uint32_t)(ac); \ | ||
152 | (a) = ROTATE_LEFT((a), (s)); \ | ||
153 | (a) += (b); \ | ||
154 | } | ||
155 | #define HH(a, b, c, d, x, s, ac) { \ | ||
156 | (a) += H ((b), (c), (d)) + (x) + (uint32_t)(ac); \ | ||
157 | (a) = ROTATE_LEFT((a), (s)); \ | ||
158 | (a) += (b); \ | ||
159 | } | ||
160 | #define II(a, b, c, d, x, s, ac) { \ | ||
161 | (a) += I ((b), (c), (d)) + (x) + (uint32_t)(ac); \ | ||
162 | (a) = ROTATE_LEFT((a), (s)); \ | ||
163 | (a) += (b); \ | ||
164 | } | ||
165 | |||
166 | /* MD5 initialization. Begins an MD5 operation, writing a new context. */ | ||
167 | static void __md5_Init(struct MD5Context *context) | ||
168 | { | ||
169 | context->count[0] = context->count[1] = 0; | ||
170 | |||
171 | /* Load magic initialization constants. */ | ||
172 | context->state[0] = 0x67452301; | ||
173 | context->state[1] = 0xefcdab89; | ||
174 | context->state[2] = 0x98badcfe; | ||
175 | context->state[3] = 0x10325476; | ||
176 | } | ||
177 | |||
178 | /* | ||
179 | * MD5 block update operation. Continues an MD5 message-digest | ||
180 | * operation, processing another message block, and updating the | ||
181 | * context. | ||
182 | */ | ||
183 | static void __md5_Update(struct MD5Context *context, const unsigned char *input, unsigned int inputLen) | ||
184 | { | ||
185 | unsigned int i, idx, partLen; | ||
186 | |||
187 | /* Compute number of bytes mod 64 */ | ||
188 | idx = (context->count[0] >> 3) & 0x3F; | ||
189 | |||
190 | /* Update number of bits */ | ||
191 | context->count[0] += (inputLen << 3); | ||
192 | if (context->count[0] < (inputLen << 3)) | ||
193 | context->count[1]++; | ||
194 | context->count[1] += (inputLen >> 29); | ||
195 | |||
196 | partLen = 64 - idx; | ||
197 | |||
198 | /* Transform as many times as possible. */ | ||
199 | if (inputLen >= partLen) { | ||
200 | memcpy(&context->buffer[idx], input, partLen); | ||
201 | __md5_Transform(context->state, context->buffer); | ||
202 | |||
203 | for (i = partLen; i + 63 < inputLen; i += 64) | ||
204 | __md5_Transform(context->state, &input[i]); | ||
205 | |||
206 | idx = 0; | ||
207 | } else | ||
208 | i = 0; | ||
209 | |||
210 | /* Buffer remaining input */ | ||
211 | memcpy(&context->buffer[idx], &input[i], inputLen - i); | ||
212 | } | ||
213 | |||
214 | /* | ||
215 | * MD5 padding. Adds padding followed by original length. | ||
216 | */ | ||
217 | static void __md5_Pad(struct MD5Context *context) | ||
218 | { | ||
219 | unsigned char bits[8]; | ||
220 | unsigned int idx, padLen; | ||
221 | unsigned char PADDING[64]; | ||
222 | |||
223 | memset(PADDING, 0, sizeof(PADDING)); | ||
224 | PADDING[0] = 0x80; | ||
225 | |||
226 | /* Save number of bits */ | ||
227 | __md5_Encode(bits, context->count, 8); | ||
228 | |||
229 | /* Pad out to 56 mod 64. */ | ||
230 | idx = (context->count[0] >> 3) & 0x3f; | ||
231 | padLen = (idx < 56) ? (56 - idx) : (120 - idx); | ||
232 | __md5_Update(context, PADDING, padLen); | ||
233 | |||
234 | /* Append length (before padding) */ | ||
235 | __md5_Update(context, bits, 8); | ||
236 | } | ||
237 | |||
238 | /* | ||
239 | * MD5 finalization. Ends an MD5 message-digest operation, writing the | ||
240 | * the message digest and zeroizing the context. | ||
241 | */ | ||
242 | static void __md5_Final(unsigned char digest[16], struct MD5Context *context) | ||
243 | { | ||
244 | /* Do padding. */ | ||
245 | __md5_Pad(context); | ||
246 | |||
247 | /* Store state in digest */ | ||
248 | __md5_Encode(digest, context->state, 16); | ||
249 | |||
250 | /* Zeroize sensitive information. */ | ||
251 | memset(context, 0, sizeof(*context)); | ||
252 | } | ||
253 | |||
254 | /* MD5 basic transformation. Transforms state based on block. */ | ||
255 | static void __md5_Transform(uint32_t state[4], const unsigned char block[64]) | ||
256 | { | ||
257 | uint32_t a, b, c, d, x[16]; | ||
258 | #if MD5_SIZE_OVER_SPEED > 1 | ||
259 | uint32_t temp; | ||
260 | const unsigned char *ps; | ||
261 | |||
262 | static const unsigned char S[] = { | ||
263 | 7, 12, 17, 22, | ||
264 | 5, 9, 14, 20, | ||
265 | 4, 11, 16, 23, | ||
266 | 6, 10, 15, 21 | ||
267 | }; | ||
268 | #endif /* MD5_SIZE_OVER_SPEED > 1 */ | ||
269 | |||
270 | #if MD5_SIZE_OVER_SPEED > 0 | ||
271 | const uint32_t *pc; | ||
272 | const unsigned char *pp; | ||
273 | int i; | ||
274 | |||
275 | static const uint32_t C[] = { | ||
276 | /* round 1 */ | ||
277 | 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, | ||
278 | 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, | ||
279 | 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, | ||
280 | 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, | ||
281 | /* round 2 */ | ||
282 | 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, | ||
283 | 0xd62f105d, 0x2441453, 0xd8a1e681, 0xe7d3fbc8, | ||
284 | 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, | ||
285 | 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, | ||
286 | /* round 3 */ | ||
287 | 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, | ||
288 | 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, | ||
289 | 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05, | ||
290 | 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, | ||
291 | /* round 4 */ | ||
292 | 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, | ||
293 | 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, | ||
294 | 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, | ||
295 | 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 | ||
296 | }; | ||
297 | |||
298 | static const unsigned char P[] = { | ||
299 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 1 */ | ||
300 | 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, /* 2 */ | ||
301 | 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, /* 3 */ | ||
302 | 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 /* 4 */ | ||
303 | }; | ||
304 | |||
305 | #endif /* MD5_SIZE_OVER_SPEED > 0 */ | ||
306 | |||
307 | __md5_Decode(x, block, 64); | ||
308 | |||
309 | a = state[0]; b = state[1]; c = state[2]; d = state[3]; | ||
310 | |||
311 | #if MD5_SIZE_OVER_SPEED > 2 | ||
312 | pc = C; pp = P; ps = S - 4; | ||
313 | |||
314 | for (i = 0; i < 64; i++) { | ||
315 | if ((i & 0x0f) == 0) ps += 4; | ||
316 | temp = a; | ||
317 | switch (i>>4) { | ||
318 | case 0: | ||
319 | temp += F(b, c, d); | ||
320 | break; | ||
321 | case 1: | ||
322 | temp += G(b, c, d); | ||
323 | break; | ||
324 | case 2: | ||
325 | temp += H(b, c, d); | ||
326 | break; | ||
327 | case 3: | ||
328 | temp += I(b, c, d); | ||
329 | break; | ||
330 | } | ||
331 | temp += x[*pp++] + *pc++; | ||
332 | temp = ROTATE_LEFT(temp, ps[i & 3]); | ||
333 | temp += b; | ||
334 | a = d; d = c; c = b; b = temp; | ||
335 | } | ||
336 | #elif MD5_SIZE_OVER_SPEED > 1 | ||
337 | pc = C; pp = P; ps = S; | ||
338 | |||
339 | /* Round 1 */ | ||
340 | for (i = 0; i < 16; i++) { | ||
341 | FF(a, b, c, d, x[*pp], ps[i & 0x3], *pc); pp++; pc++; | ||
342 | temp = d; d = c; c = b; b = a; a = temp; | ||
343 | } | ||
344 | |||
345 | /* Round 2 */ | ||
346 | ps += 4; | ||
347 | for (; i < 32; i++) { | ||
348 | GG(a, b, c, d, x[*pp], ps[i & 0x3], *pc); pp++; pc++; | ||
349 | temp = d; d = c; c = b; b = a; a = temp; | ||
350 | } | ||
351 | /* Round 3 */ | ||
352 | ps += 4; | ||
353 | for (; i < 48; i++) { | ||
354 | HH(a, b, c, d, x[*pp], ps[i & 0x3], *pc); pp++; pc++; | ||
355 | temp = d; d = c; c = b; b = a; a = temp; | ||
356 | } | ||
357 | |||
358 | /* Round 4 */ | ||
359 | ps += 4; | ||
360 | for (; i < 64; i++) { | ||
361 | II(a, b, c, d, x[*pp], ps[i & 0x3], *pc); pp++; pc++; | ||
362 | temp = d; d = c; c = b; b = a; a = temp; | ||
363 | } | ||
364 | #elif MD5_SIZE_OVER_SPEED > 0 | ||
365 | pc = C; pp = P; | ||
366 | |||
367 | /* Round 1 */ | ||
368 | for (i = 0; i < 4; i++) { | ||
369 | FF(a, b, c, d, x[*pp], 7, *pc); pp++; pc++; | ||
370 | FF(d, a, b, c, x[*pp], 12, *pc); pp++; pc++; | ||
371 | FF(c, d, a, b, x[*pp], 17, *pc); pp++; pc++; | ||
372 | FF(b, c, d, a, x[*pp], 22, *pc); pp++; pc++; | ||
373 | } | ||
374 | |||
375 | /* Round 2 */ | ||
376 | for (i = 0; i < 4; i++) { | ||
377 | GG(a, b, c, d, x[*pp], 5, *pc); pp++; pc++; | ||
378 | GG(d, a, b, c, x[*pp], 9, *pc); pp++; pc++; | ||
379 | GG(c, d, a, b, x[*pp], 14, *pc); pp++; pc++; | ||
380 | GG(b, c, d, a, x[*pp], 20, *pc); pp++; pc++; | ||
381 | } | ||
382 | /* Round 3 */ | ||
383 | for (i = 0; i < 4; i++) { | ||
384 | HH(a, b, c, d, x[*pp], 4, *pc); pp++; pc++; | ||
385 | HH(d, a, b, c, x[*pp], 11, *pc); pp++; pc++; | ||
386 | HH(c, d, a, b, x[*pp], 16, *pc); pp++; pc++; | ||
387 | HH(b, c, d, a, x[*pp], 23, *pc); pp++; pc++; | ||
388 | } | ||
389 | |||
390 | /* Round 4 */ | ||
391 | for (i = 0; i < 4; i++) { | ||
392 | II(a, b, c, d, x[*pp], 6, *pc); pp++; pc++; | ||
393 | II(d, a, b, c, x[*pp], 10, *pc); pp++; pc++; | ||
394 | II(c, d, a, b, x[*pp], 15, *pc); pp++; pc++; | ||
395 | II(b, c, d, a, x[*pp], 21, *pc); pp++; pc++; | ||
396 | } | ||
397 | #else | ||
398 | /* Round 1 */ | ||
399 | #define S11 7 | ||
400 | #define S12 12 | ||
401 | #define S13 17 | ||
402 | #define S14 22 | ||
403 | FF(a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ | ||
404 | FF(d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ | ||
405 | FF(c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ | ||
406 | FF(b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ | ||
407 | FF(a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ | ||
408 | FF(d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ | ||
409 | FF(c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ | ||
410 | FF(b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ | ||
411 | FF(a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ | ||
412 | FF(d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ | ||
413 | FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ | ||
414 | FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ | ||
415 | FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ | ||
416 | FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ | ||
417 | FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ | ||
418 | FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ | ||
419 | |||
420 | /* Round 2 */ | ||
421 | #define S21 5 | ||
422 | #define S22 9 | ||
423 | #define S23 14 | ||
424 | #define S24 20 | ||
425 | GG(a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ | ||
426 | GG(d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ | ||
427 | GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ | ||
428 | GG(b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ | ||
429 | GG(a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ | ||
430 | GG(d, a, b, c, x[10], S22, 0x2441453); /* 22 */ | ||
431 | GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ | ||
432 | GG(b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ | ||
433 | GG(a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ | ||
434 | GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ | ||
435 | GG(c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ | ||
436 | GG(b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ | ||
437 | GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ | ||
438 | GG(d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ | ||
439 | GG(c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ | ||
440 | GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ | ||
441 | |||
442 | /* Round 3 */ | ||
443 | #define S31 4 | ||
444 | #define S32 11 | ||
445 | #define S33 16 | ||
446 | #define S34 23 | ||
447 | HH(a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ | ||
448 | HH(d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ | ||
449 | HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ | ||
450 | HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ | ||
451 | HH(a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ | ||
452 | HH(d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ | ||
453 | HH(c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ | ||
454 | HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ | ||
455 | HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ | ||
456 | HH(d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ | ||
457 | HH(c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ | ||
458 | HH(b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ | ||
459 | HH(a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ | ||
460 | HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ | ||
461 | HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ | ||
462 | HH(b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ | ||
463 | |||
464 | /* Round 4 */ | ||
465 | #define S41 6 | ||
466 | #define S42 10 | ||
467 | #define S43 15 | ||
468 | #define S44 21 | ||
469 | II(a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ | ||
470 | II(d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ | ||
471 | II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ | ||
472 | II(b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ | ||
473 | II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ | ||
474 | II(d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ | ||
475 | II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ | ||
476 | II(b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ | ||
477 | II(a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ | ||
478 | II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ | ||
479 | II(c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ | ||
480 | II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ | ||
481 | II(a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ | ||
482 | II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ | ||
483 | II(c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ | ||
484 | II(b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ | ||
485 | #endif | ||
486 | |||
487 | state[0] += a; | ||
488 | state[1] += b; | ||
489 | state[2] += c; | ||
490 | state[3] += d; | ||
491 | |||
492 | /* Zeroize sensitive information. */ | ||
493 | memset(x, 0, sizeof(x)); | ||
494 | } | ||
495 | |||
496 | |||
497 | /* | 72 | /* |
498 | * UNIX password | 73 | * UNIX password |
499 | * | 74 | * |
@@ -502,94 +77,77 @@ static void __md5_Transform(uint32_t state[4], const unsigned char block[64]) | |||
502 | #define MD5_OUT_BUFSIZE 36 | 77 | #define MD5_OUT_BUFSIZE 36 |
503 | static char * | 78 | static char * |
504 | NOINLINE | 79 | NOINLINE |
505 | md5_crypt(char passwd[MD5_OUT_BUFSIZE], const unsigned char *pw, const unsigned char *salt) | 80 | md5_crypt(char result[MD5_OUT_BUFSIZE], const unsigned char *pw, const unsigned char *salt) |
506 | { | 81 | { |
507 | const unsigned char *sp, *ep; | ||
508 | char *p; | 82 | char *p; |
509 | unsigned char final[17]; /* final[16] exists only to aid in looping */ | 83 | unsigned char final[17]; /* final[16] exists only to aid in looping */ |
510 | int sl, pl, i, pw_len; | 84 | int sl, pl, i, pw_len; |
511 | struct MD5Context ctx, ctx1; | 85 | md5_ctx_t ctx, ctx1; |
512 | |||
513 | /* Refine the Salt first */ | ||
514 | sp = salt; | ||
515 | 86 | ||
516 | // always true for bbox | 87 | /* NB: in busybox, "$1$" in salt is always present */ |
517 | // /* If it starts with the magic string, then skip that */ | ||
518 | // if (!strncmp(sp, __md5__magic, MD5_MAGIC_LEN)) | ||
519 | sp += MD5_MAGIC_LEN; | ||
520 | 88 | ||
521 | /* It stops at the first '$', max 8 chars */ | 89 | /* Refine the Salt first */ |
522 | for (ep = sp; *ep && *ep != '$' && ep < (sp+8); ep++) | ||
523 | continue; | ||
524 | |||
525 | /* get the length of the true salt */ | ||
526 | sl = ep - sp; | ||
527 | 90 | ||
528 | __md5_Init(&ctx); | 91 | /* Get the length of the salt including "$1$" */ |
92 | sl = 3; | ||
93 | while (salt[sl] && salt[sl] != '$' && sl < (3 + 8)) | ||
94 | sl++; | ||
529 | 95 | ||
530 | /* The password first, since that is what is most unknown */ | 96 | /* Hash. the password first, since that is what is most unknown */ |
97 | md5_begin(&ctx); | ||
531 | pw_len = strlen((char*)pw); | 98 | pw_len = strlen((char*)pw); |
532 | __md5_Update(&ctx, pw, pw_len); | 99 | md5_hash(pw, pw_len, &ctx); |
533 | 100 | ||
534 | /* Then our magic string */ | 101 | /* Then the salt including "$1$" */ |
535 | __md5_Update(&ctx, __md5__magic, MD5_MAGIC_LEN); | 102 | md5_hash(salt, sl, &ctx); |
536 | 103 | ||
537 | /* Then the raw salt */ | 104 | /* Copy salt to result; skip "$1$" */ |
538 | __md5_Update(&ctx, sp, sl); | 105 | memcpy(result, salt, sl); |
106 | result[sl] = '$'; | ||
107 | salt += 3; | ||
108 | sl -= 3; | ||
539 | 109 | ||
540 | /* Then just as many characters of the MD5(pw, salt, pw) */ | 110 | /* Then just as many characters of the MD5(pw, salt, pw) */ |
541 | __md5_Init(&ctx1); | 111 | md5_begin(&ctx1); |
542 | __md5_Update(&ctx1, pw, pw_len); | 112 | md5_hash(pw, pw_len, &ctx1); |
543 | __md5_Update(&ctx1, sp, sl); | 113 | md5_hash(salt, sl, &ctx1); |
544 | __md5_Update(&ctx1, pw, pw_len); | 114 | md5_hash(pw, pw_len, &ctx1); |
545 | __md5_Final(final, &ctx1); | 115 | md5_end(final, &ctx1); |
546 | for (pl = pw_len; pl > 0; pl -= 16) | 116 | for (pl = pw_len; pl > 0; pl -= 16) |
547 | __md5_Update(&ctx, final, pl > 16 ? 16 : pl); | 117 | md5_hash(final, pl > 16 ? 16 : pl, &ctx); |
548 | |||
549 | /* Don't leave anything around in vm they could use. */ | ||
550 | //TODO: the above comment seems to be wrong. final is used later. | ||
551 | memset(final, 0, sizeof(final)); | ||
552 | 118 | ||
553 | /* Then something really weird... */ | 119 | /* Then something really weird... */ |
120 | memset(final, 0, sizeof(final)); | ||
554 | for (i = pw_len; i; i >>= 1) { | 121 | for (i = pw_len; i; i >>= 1) { |
555 | __md5_Update(&ctx, ((i & 1) ? final : (const unsigned char *) pw), 1); | 122 | md5_hash(((i & 1) ? final : (const unsigned char *) pw), 1, &ctx); |
556 | } | 123 | } |
124 | md5_end(final, &ctx); | ||
557 | 125 | ||
558 | /* Now make the output string */ | 126 | /* And now, just to make sure things don't run too fast. |
559 | passwd[0] = '$'; | ||
560 | passwd[1] = '1'; | ||
561 | passwd[2] = '$'; | ||
562 | strncpy(passwd + 3, (char*)sp, sl); | ||
563 | passwd[sl + 3] = '$'; | ||
564 | |||
565 | __md5_Final(final, &ctx); | ||
566 | |||
567 | /* | ||
568 | * and now, just to make sure things don't run too fast | ||
569 | * On a 60 Mhz Pentium this takes 34 msec, so you would | 127 | * On a 60 Mhz Pentium this takes 34 msec, so you would |
570 | * need 30 seconds to build a 1000 entry dictionary... | 128 | * need 30 seconds to build a 1000 entry dictionary... |
571 | */ | 129 | */ |
572 | for (i = 0; i < 1000; i++) { | 130 | for (i = 0; i < 1000; i++) { |
573 | __md5_Init(&ctx1); | 131 | md5_begin(&ctx1); |
574 | if (i & 1) | 132 | if (i & 1) |
575 | __md5_Update(&ctx1, pw, pw_len); | 133 | md5_hash(pw, pw_len, &ctx1); |
576 | else | 134 | else |
577 | __md5_Update(&ctx1, final, 16); | 135 | md5_hash(final, 16, &ctx1); |
578 | 136 | ||
579 | if (i % 3) | 137 | if (i % 3) |
580 | __md5_Update(&ctx1, sp, sl); | 138 | md5_hash(salt, sl, &ctx1); |
581 | 139 | ||
582 | if (i % 7) | 140 | if (i % 7) |
583 | __md5_Update(&ctx1, pw, pw_len); | 141 | md5_hash(pw, pw_len, &ctx1); |
584 | 142 | ||
585 | if (i & 1) | 143 | if (i & 1) |
586 | __md5_Update(&ctx1, final, 16); | 144 | md5_hash(final, 16, &ctx1); |
587 | else | 145 | else |
588 | __md5_Update(&ctx1, pw, pw_len); | 146 | md5_hash(pw, pw_len, &ctx1); |
589 | __md5_Final(final, &ctx1); | 147 | md5_end(final, &ctx1); |
590 | } | 148 | } |
591 | 149 | ||
592 | p = passwd + sl + 4; /* 12 bytes max (sl is up to 8 bytes) */ | 150 | p = result + sl + 4; /* 12 bytes max (sl is up to 8 bytes) */ |
593 | 151 | ||
594 | /* Add 5*4+2 = 22 bytes of hash, + NUL byte. */ | 152 | /* Add 5*4+2 = 22 bytes of hash, + NUL byte. */ |
595 | final[16] = final[5]; | 153 | final[16] = final[5]; |
@@ -603,36 +161,7 @@ md5_crypt(char passwd[MD5_OUT_BUFSIZE], const unsigned char *pw, const unsigned | |||
603 | /* Don't leave anything around in vm they could use. */ | 161 | /* Don't leave anything around in vm they could use. */ |
604 | memset(final, 0, sizeof(final)); | 162 | memset(final, 0, sizeof(final)); |
605 | 163 | ||
606 | return passwd; | 164 | return result; |
607 | } | 165 | } |
608 | |||
609 | #undef MD5_SIZE_OVER_SPEED | ||
610 | #undef MD5_MAGIC_STR | 166 | #undef MD5_MAGIC_STR |
611 | #undef MD5_MAGIC_LEN | 167 | #undef MD5_MAGIC_LEN |
612 | #undef __md5_Encode | ||
613 | #undef __md5_Decode | ||
614 | #undef F | ||
615 | #undef G | ||
616 | #undef H | ||
617 | #undef I | ||
618 | #undef ROTATE_LEFT | ||
619 | #undef FF | ||
620 | #undef GG | ||
621 | #undef HH | ||
622 | #undef II | ||
623 | #undef S11 | ||
624 | #undef S12 | ||
625 | #undef S13 | ||
626 | #undef S14 | ||
627 | #undef S21 | ||
628 | #undef S22 | ||
629 | #undef S23 | ||
630 | #undef S24 | ||
631 | #undef S31 | ||
632 | #undef S32 | ||
633 | #undef S33 | ||
634 | #undef S34 | ||
635 | #undef S41 | ||
636 | #undef S42 | ||
637 | #undef S43 | ||
638 | #undef S44 | ||
diff --git a/libbb/sha1.c b/libbb/sha1.c index fa468a295..76d5c8fbb 100644 --- a/libbb/sha1.c +++ b/libbb/sha1.c | |||
@@ -546,7 +546,7 @@ void FAST_FUNC sha512_hash(const void *buffer, size_t len, sha512_ctx_t *ctx) | |||
546 | } | 546 | } |
547 | 547 | ||
548 | 548 | ||
549 | void* FAST_FUNC sha1_end(void *resbuf, sha1_ctx_t *ctx) | 549 | void FAST_FUNC sha1_end(void *resbuf, sha1_ctx_t *ctx) |
550 | { | 550 | { |
551 | /* SHA1 Final padding and digest calculation */ | 551 | /* SHA1 Final padding and digest calculation */ |
552 | #if BB_BIG_ENDIAN | 552 | #if BB_BIG_ENDIAN |
@@ -593,8 +593,6 @@ void* FAST_FUNC sha1_end(void *resbuf, sha1_ctx_t *ctx) | |||
593 | /* misaligned for 32-bit words */ | 593 | /* misaligned for 32-bit words */ |
594 | for (i = 0; i < SHA1_DIGEST_SIZE; ++i) | 594 | for (i = 0; i < SHA1_DIGEST_SIZE; ++i) |
595 | hval[i] = (unsigned char) (ctx->hash[i >> 2] >> 8 * (~i & 3)); | 595 | hval[i] = (unsigned char) (ctx->hash[i >> 2] >> 8 * (~i & 3)); |
596 | |||
597 | return resbuf; | ||
598 | } | 596 | } |
599 | 597 | ||
600 | 598 | ||
@@ -603,7 +601,7 @@ void* FAST_FUNC sha1_end(void *resbuf, sha1_ctx_t *ctx) | |||
603 | 601 | ||
604 | IMPORTANT: On some systems it is required that RESBUF is correctly | 602 | IMPORTANT: On some systems it is required that RESBUF is correctly |
605 | aligned for a 32 bits value. */ | 603 | aligned for a 32 bits value. */ |
606 | void* FAST_FUNC sha256_end(void *resbuf, sha256_ctx_t *ctx) | 604 | void FAST_FUNC sha256_end(void *resbuf, sha256_ctx_t *ctx) |
607 | { | 605 | { |
608 | /* Take yet unprocessed bytes into account. */ | 606 | /* Take yet unprocessed bytes into account. */ |
609 | uint32_t bytes = ctx->buflen; | 607 | uint32_t bytes = ctx->buflen; |
@@ -630,8 +628,6 @@ void* FAST_FUNC sha256_end(void *resbuf, sha256_ctx_t *ctx) | |||
630 | /* Put result from CTX in first 32 bytes following RESBUF. */ | 628 | /* Put result from CTX in first 32 bytes following RESBUF. */ |
631 | for (unsigned i = 0; i < 8; ++i) | 629 | for (unsigned i = 0; i < 8; ++i) |
632 | ((uint32_t *) resbuf)[i] = ntohl(ctx->H[i]); | 630 | ((uint32_t *) resbuf)[i] = ntohl(ctx->H[i]); |
633 | |||
634 | return resbuf; | ||
635 | } | 631 | } |
636 | 632 | ||
637 | /* Process the remaining bytes in the internal buffer and the usual | 633 | /* Process the remaining bytes in the internal buffer and the usual |
@@ -639,7 +635,7 @@ void* FAST_FUNC sha256_end(void *resbuf, sha256_ctx_t *ctx) | |||
639 | 635 | ||
640 | IMPORTANT: On some systems it is required that RESBUF is correctly | 636 | IMPORTANT: On some systems it is required that RESBUF is correctly |
641 | aligned for a 64 bits value. */ | 637 | aligned for a 64 bits value. */ |
642 | void* FAST_FUNC sha512_end(void *resbuf, sha512_ctx_t *ctx) | 638 | void FAST_FUNC sha512_end(void *resbuf, sha512_ctx_t *ctx) |
643 | { | 639 | { |
644 | /* Take yet unprocessed bytes into account. */ | 640 | /* Take yet unprocessed bytes into account. */ |
645 | uint64_t bytes = ctx->buflen; | 641 | uint64_t bytes = ctx->buflen; |
@@ -666,6 +662,4 @@ void* FAST_FUNC sha512_end(void *resbuf, sha512_ctx_t *ctx) | |||
666 | /* Put result from CTX in first 64 bytes following RESBUF. */ | 662 | /* Put result from CTX in first 64 bytes following RESBUF. */ |
667 | for (unsigned i = 0; i < 8; ++i) | 663 | for (unsigned i = 0; i < 8; ++i) |
668 | ((uint64_t *) resbuf)[i] = hton64(ctx->H[i]); | 664 | ((uint64_t *) resbuf)[i] = hton64(ctx->H[i]); |
669 | |||
670 | return resbuf; | ||
671 | } | 665 | } |