OLD | NEW |
1 /* | 1 /* |
2 * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc. | 2 * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc. |
3 * MD5 Message-Digest Algorithm (RFC 1321). | 3 * MD5 Message-Digest Algorithm (RFC 1321). |
4 * | 4 * |
5 * Homepage: | 5 * Homepage: |
6 * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5 | 6 * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5 |
7 * | 7 * |
8 * Author: | 8 * Author: |
9 * Alexander Peslyak, better known as Solar Designer <solar at openwall.com> | 9 * Alexander Peslyak, better known as Solar Designer <solar at openwall.com> |
10 * | 10 * |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
43 | 43 |
44 /* | 44 /* |
45 * The basic MD5 functions. | 45 * The basic MD5 functions. |
46 * | 46 * |
47 * F and G are optimized compared to their RFC 1321 definitions for | 47 * F and G are optimized compared to their RFC 1321 definitions for |
48 * architectures that lack an AND-NOT instruction, just like in Colin Plumb's | 48 * architectures that lack an AND-NOT instruction, just like in Colin Plumb's |
49 * implementation. | 49 * implementation. |
50 */ | 50 */ |
51 #define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) | 51 #define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) |
52 #define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y)))) | 52 #define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y)))) |
53 #define H(x, y, z)» » » ((x) ^ (y) ^ (z)) | 53 #define H(x, y, z)» » » (((x) ^ (y)) ^ (z)) |
| 54 #define H2(x, y, z)» » » ((x) ^ ((y) ^ (z))) |
54 #define I(x, y, z) ((y) ^ ((x) | ~(z))) | 55 #define I(x, y, z) ((y) ^ ((x) | ~(z))) |
55 | 56 |
56 /* | 57 /* |
57 * The MD5 transformation for all four rounds. | 58 * The MD5 transformation for all four rounds. |
58 */ | 59 */ |
59 #define STEP(f, a, b, c, d, x, t, s) \ | 60 #define STEP(f, a, b, c, d, x, t, s) \ |
60 (a) += f((b), (c), (d)) + (x) + (t); \ | 61 (a) += f((b), (c), (d)) + (x) + (t); \ |
61 (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \ | 62 (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \ |
62 (a) += (b); | 63 (a) += (b); |
63 | 64 |
(...skipping 18 matching lines...) Expand all Loading... |
82 ((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \ | 83 ((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \ |
83 ((MD5_u32plus)ptr[(n) * 4 + 3] << 24)) | 84 ((MD5_u32plus)ptr[(n) * 4 + 3] << 24)) |
84 #define GET(n) \ | 85 #define GET(n) \ |
85 (ctx->block[(n)]) | 86 (ctx->block[(n)]) |
86 #endif | 87 #endif |
87 | 88 |
88 /* | 89 /* |
89 * This processes one or more 64-byte data blocks, but does NOT update | 90 * This processes one or more 64-byte data blocks, but does NOT update |
90 * the bit counters. There are no alignment requirements. | 91 * the bit counters. There are no alignment requirements. |
91 */ | 92 */ |
92 static void *body(MD5_CTX *ctx, void *data, unsigned long size) | 93 static const void *body(MD5_CTX *ctx, const void *data, unsigned long size) |
93 { | 94 { |
94 » unsigned char *ptr; | 95 » const unsigned char *ptr; |
95 MD5_u32plus a, b, c, d; | 96 MD5_u32plus a, b, c, d; |
96 MD5_u32plus saved_a, saved_b, saved_c, saved_d; | 97 MD5_u32plus saved_a, saved_b, saved_c, saved_d; |
97 | 98 |
98 » ptr = (unsigned char *)data; | 99 » ptr = (const unsigned char *)data; |
99 | 100 |
100 a = ctx->a; | 101 a = ctx->a; |
101 b = ctx->b; | 102 b = ctx->b; |
102 c = ctx->c; | 103 c = ctx->c; |
103 d = ctx->d; | 104 d = ctx->d; |
104 | 105 |
105 do { | 106 do { |
106 saved_a = a; | 107 saved_a = a; |
107 saved_b = b; | 108 saved_b = b; |
108 saved_c = c; | 109 saved_c = c; |
(...skipping 30 matching lines...) Expand all Loading... |
139 STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9) | 140 STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9) |
140 STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14) | 141 STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14) |
141 STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20) | 142 STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20) |
142 STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5) | 143 STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5) |
143 STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9) | 144 STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9) |
144 STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14) | 145 STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14) |
145 STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20) | 146 STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20) |
146 | 147 |
147 /* Round 3 */ | 148 /* Round 3 */ |
148 STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4) | 149 STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4) |
149 » » STEP(H, d, a, b, c, GET(8), 0x8771f681, 11) | 150 » » STEP(H2, d, a, b, c, GET(8), 0x8771f681, 11) |
150 STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16) | 151 STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16) |
151 » » STEP(H, b, c, d, a, GET(14), 0xfde5380c, 23) | 152 » » STEP(H2, b, c, d, a, GET(14), 0xfde5380c, 23) |
152 STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4) | 153 STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4) |
153 » » STEP(H, d, a, b, c, GET(4), 0x4bdecfa9, 11) | 154 » » STEP(H2, d, a, b, c, GET(4), 0x4bdecfa9, 11) |
154 STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16) | 155 STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16) |
155 » » STEP(H, b, c, d, a, GET(10), 0xbebfbc70, 23) | 156 » » STEP(H2, b, c, d, a, GET(10), 0xbebfbc70, 23) |
156 STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4) | 157 STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4) |
157 » » STEP(H, d, a, b, c, GET(0), 0xeaa127fa, 11) | 158 » » STEP(H2, d, a, b, c, GET(0), 0xeaa127fa, 11) |
158 STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16) | 159 STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16) |
159 » » STEP(H, b, c, d, a, GET(6), 0x04881d05, 23) | 160 » » STEP(H2, b, c, d, a, GET(6), 0x04881d05, 23) |
160 STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4) | 161 STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4) |
161 » » STEP(H, d, a, b, c, GET(12), 0xe6db99e5, 11) | 162 » » STEP(H2, d, a, b, c, GET(12), 0xe6db99e5, 11) |
162 STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16) | 163 STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16) |
163 » » STEP(H, b, c, d, a, GET(2), 0xc4ac5665, 23) | 164 » » STEP(H2, b, c, d, a, GET(2), 0xc4ac5665, 23) |
164 | 165 |
165 /* Round 4 */ | 166 /* Round 4 */ |
166 STEP(I, a, b, c, d, GET(0), 0xf4292244, 6) | 167 STEP(I, a, b, c, d, GET(0), 0xf4292244, 6) |
167 STEP(I, d, a, b, c, GET(7), 0x432aff97, 10) | 168 STEP(I, d, a, b, c, GET(7), 0x432aff97, 10) |
168 STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15) | 169 STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15) |
169 STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21) | 170 STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21) |
170 STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6) | 171 STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6) |
171 STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10) | 172 STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10) |
172 STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15) | 173 STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15) |
173 STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21) | 174 STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21) |
(...skipping 26 matching lines...) Expand all Loading... |
200 { | 201 { |
201 ctx->a = 0x67452301; | 202 ctx->a = 0x67452301; |
202 ctx->b = 0xefcdab89; | 203 ctx->b = 0xefcdab89; |
203 ctx->c = 0x98badcfe; | 204 ctx->c = 0x98badcfe; |
204 ctx->d = 0x10325476; | 205 ctx->d = 0x10325476; |
205 | 206 |
206 ctx->lo = 0; | 207 ctx->lo = 0; |
207 ctx->hi = 0; | 208 ctx->hi = 0; |
208 } | 209 } |
209 | 210 |
210 void MD5_Update(MD5_CTX *ctx, void *data, unsigned long size) | 211 void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size) |
211 { | 212 { |
212 MD5_u32plus saved_lo; | 213 MD5_u32plus saved_lo; |
213 » unsigned long used, free; | 214 » unsigned long used, available; |
214 | 215 |
215 saved_lo = ctx->lo; | 216 saved_lo = ctx->lo; |
216 if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo) | 217 if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo) |
217 ctx->hi++; | 218 ctx->hi++; |
218 ctx->hi += size >> 29; | 219 ctx->hi += size >> 29; |
219 | 220 |
220 used = saved_lo & 0x3f; | 221 used = saved_lo & 0x3f; |
221 | 222 |
222 if (used) { | 223 if (used) { |
223 » » free = 64 - used; | 224 » » available = 64 - used; |
224 | 225 |
225 » » if (size < free) { | 226 » » if (size < available) { |
226 memcpy(&ctx->buffer[used], data, size); | 227 memcpy(&ctx->buffer[used], data, size); |
227 return; | 228 return; |
228 } | 229 } |
229 | 230 |
230 » » memcpy(&ctx->buffer[used], data, free); | 231 » » memcpy(&ctx->buffer[used], data, available); |
231 » » data = (unsigned char *)data + free; | 232 » » data = (const unsigned char *)data + available; |
232 » » size -= free; | 233 » » size -= available; |
233 body(ctx, ctx->buffer, 64); | 234 body(ctx, ctx->buffer, 64); |
234 } | 235 } |
235 | 236 |
236 if (size >= 64) { | 237 if (size >= 64) { |
237 data = body(ctx, data, size & ~(unsigned long)0x3f); | 238 data = body(ctx, data, size & ~(unsigned long)0x3f); |
238 size &= 0x3f; | 239 size &= 0x3f; |
239 } | 240 } |
240 | 241 |
241 memcpy(ctx->buffer, data, size); | 242 memcpy(ctx->buffer, data, size); |
242 } | 243 } |
243 | 244 |
244 void MD5_Final(unsigned char *result, MD5_CTX *ctx) | 245 void MD5_Final(unsigned char *result, MD5_CTX *ctx) |
245 { | 246 { |
246 » unsigned long used, free; | 247 » unsigned long used, available; |
247 | 248 |
248 used = ctx->lo & 0x3f; | 249 used = ctx->lo & 0x3f; |
249 | 250 |
250 ctx->buffer[used++] = 0x80; | 251 ctx->buffer[used++] = 0x80; |
251 | 252 |
252 » free = 64 - used; | 253 » available = 64 - used; |
253 | 254 |
254 » if (free < 8) { | 255 » if (available < 8) { |
255 » » memset(&ctx->buffer[used], 0, free); | 256 » » memset(&ctx->buffer[used], 0, available); |
256 body(ctx, ctx->buffer, 64); | 257 body(ctx, ctx->buffer, 64); |
257 used = 0; | 258 used = 0; |
258 » » free = 64; | 259 » » available = 64; |
259 } | 260 } |
260 | 261 |
261 » memset(&ctx->buffer[used], 0, free - 8); | 262 » memset(&ctx->buffer[used], 0, available - 8); |
262 | 263 |
263 ctx->lo <<= 3; | 264 ctx->lo <<= 3; |
264 ctx->buffer[56] = ctx->lo; | 265 ctx->buffer[56] = ctx->lo; |
265 ctx->buffer[57] = ctx->lo >> 8; | 266 ctx->buffer[57] = ctx->lo >> 8; |
266 ctx->buffer[58] = ctx->lo >> 16; | 267 ctx->buffer[58] = ctx->lo >> 16; |
267 ctx->buffer[59] = ctx->lo >> 24; | 268 ctx->buffer[59] = ctx->lo >> 24; |
268 ctx->buffer[60] = ctx->hi; | 269 ctx->buffer[60] = ctx->hi; |
269 ctx->buffer[61] = ctx->hi >> 8; | 270 ctx->buffer[61] = ctx->hi >> 8; |
270 ctx->buffer[62] = ctx->hi >> 16; | 271 ctx->buffer[62] = ctx->hi >> 16; |
271 ctx->buffer[63] = ctx->hi >> 24; | 272 ctx->buffer[63] = ctx->hi >> 24; |
(...skipping 14 matching lines...) Expand all Loading... |
286 result[11] = ctx->c >> 24; | 287 result[11] = ctx->c >> 24; |
287 result[12] = ctx->d; | 288 result[12] = ctx->d; |
288 result[13] = ctx->d >> 8; | 289 result[13] = ctx->d >> 8; |
289 result[14] = ctx->d >> 16; | 290 result[14] = ctx->d >> 16; |
290 result[15] = ctx->d >> 24; | 291 result[15] = ctx->d >> 24; |
291 | 292 |
292 memset(ctx, 0, sizeof(*ctx)); | 293 memset(ctx, 0, sizeof(*ctx)); |
293 } | 294 } |
294 | 295 |
295 #endif | 296 #endif |
OLD | NEW |