This source file includes following definitions.
- make_digest
- make_digest_ex
- PHP_NAMED_FUNCTION
- PHP_NAMED_FUNCTION
- body
- PHP_MD5Init
- PHP_MD5Update
- PHP_MD5Final
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 #include "php.h"
24 #include "md5.h"
25
26 PHPAPI void make_digest(char *md5str, const unsigned char *digest)
27 {
28 make_digest_ex(md5str, digest, 16);
29 }
30
31
32 PHPAPI void make_digest_ex(char *md5str, const unsigned char *digest, int len)
33 {
34 static const char hexits[17] = "0123456789abcdef";
35 int i;
36
37 for (i = 0; i < len; i++) {
38 md5str[i * 2] = hexits[digest[i] >> 4];
39 md5str[(i * 2) + 1] = hexits[digest[i] & 0x0F];
40 }
41 md5str[len * 2] = '\0';
42 }
43
44
45
46
47 PHP_NAMED_FUNCTION(php_if_md5)
48 {
49 char *arg;
50 int arg_len;
51 zend_bool raw_output = 0;
52 char md5str[33];
53 PHP_MD5_CTX context;
54 unsigned char digest[16];
55
56 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) {
57 return;
58 }
59
60 md5str[0] = '\0';
61 PHP_MD5Init(&context);
62 PHP_MD5Update(&context, arg, arg_len);
63 PHP_MD5Final(digest, &context);
64 if (raw_output) {
65 RETURN_STRINGL(digest, 16, 1);
66 } else {
67 make_digest_ex(md5str, digest, 16);
68 RETVAL_STRING(md5str, 1);
69 }
70
71 }
72
73
74
75
76 PHP_NAMED_FUNCTION(php_if_md5_file)
77 {
78 char *arg;
79 int arg_len;
80 zend_bool raw_output = 0;
81 char md5str[33];
82 unsigned char buf[1024];
83 unsigned char digest[16];
84 PHP_MD5_CTX context;
85 int n;
86 php_stream *stream;
87
88 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|b", &arg, &arg_len, &raw_output) == FAILURE) {
89 return;
90 }
91
92 stream = php_stream_open_wrapper(arg, "rb", REPORT_ERRORS, NULL);
93 if (!stream) {
94 RETURN_FALSE;
95 }
96
97 PHP_MD5Init(&context);
98
99 while ((n = php_stream_read(stream, buf, sizeof(buf))) > 0) {
100 PHP_MD5Update(&context, buf, n);
101 }
102
103 PHP_MD5Final(digest, &context);
104
105 php_stream_close(stream);
106
107 if (n<0) {
108 RETURN_FALSE;
109 }
110
111 if (raw_output) {
112 RETURN_STRINGL(digest, 16, 1);
113 } else {
114 make_digest_ex(md5str, digest, 16);
115 RETVAL_STRING(md5str, 1);
116 }
117 }
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137 #include <string.h>
138
139
140
141
142
143
144
145
146 #define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
147 #define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y))))
148 #define H(x, y, z) ((x) ^ (y) ^ (z))
149 #define I(x, y, z) ((y) ^ ((x) | ~(z)))
150
151
152
153
154 #define STEP(f, a, b, c, d, x, t, s) \
155 (a) += f((b), (c), (d)) + (x) + (t); \
156 (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \
157 (a) += (b);
158
159
160
161
162
163
164
165
166
167 #if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
168 # define SET(n) \
169 (*(php_uint32 *)&ptr[(n) * 4])
170 # define GET(n) \
171 SET(n)
172 #else
173 # define SET(n) \
174 (ctx->block[(n)] = \
175 (php_uint32)ptr[(n) * 4] | \
176 ((php_uint32)ptr[(n) * 4 + 1] << 8) | \
177 ((php_uint32)ptr[(n) * 4 + 2] << 16) | \
178 ((php_uint32)ptr[(n) * 4 + 3] << 24))
179 # define GET(n) \
180 (ctx->block[(n)])
181 #endif
182
183
184
185
186
187 static const void *body(PHP_MD5_CTX *ctx, const void *data, size_t size)
188 {
189 const unsigned char *ptr;
190 php_uint32 a, b, c, d;
191 php_uint32 saved_a, saved_b, saved_c, saved_d;
192
193 ptr = data;
194
195 a = ctx->a;
196 b = ctx->b;
197 c = ctx->c;
198 d = ctx->d;
199
200 do {
201 saved_a = a;
202 saved_b = b;
203 saved_c = c;
204 saved_d = d;
205
206
207 STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7)
208 STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12)
209 STEP(F, c, d, a, b, SET(2), 0x242070db, 17)
210 STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22)
211 STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7)
212 STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12)
213 STEP(F, c, d, a, b, SET(6), 0xa8304613, 17)
214 STEP(F, b, c, d, a, SET(7), 0xfd469501, 22)
215 STEP(F, a, b, c, d, SET(8), 0x698098d8, 7)
216 STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12)
217 STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17)
218 STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22)
219 STEP(F, a, b, c, d, SET(12), 0x6b901122, 7)
220 STEP(F, d, a, b, c, SET(13), 0xfd987193, 12)
221 STEP(F, c, d, a, b, SET(14), 0xa679438e, 17)
222 STEP(F, b, c, d, a, SET(15), 0x49b40821, 22)
223
224
225 STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5)
226 STEP(G, d, a, b, c, GET(6), 0xc040b340, 9)
227 STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14)
228 STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20)
229 STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5)
230 STEP(G, d, a, b, c, GET(10), 0x02441453, 9)
231 STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14)
232 STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20)
233 STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5)
234 STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9)
235 STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14)
236 STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20)
237 STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5)
238 STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9)
239 STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14)
240 STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20)
241
242
243 STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4)
244 STEP(H, d, a, b, c, GET(8), 0x8771f681, 11)
245 STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16)
246 STEP(H, b, c, d, a, GET(14), 0xfde5380c, 23)
247 STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4)
248 STEP(H, d, a, b, c, GET(4), 0x4bdecfa9, 11)
249 STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16)
250 STEP(H, b, c, d, a, GET(10), 0xbebfbc70, 23)
251 STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4)
252 STEP(H, d, a, b, c, GET(0), 0xeaa127fa, 11)
253 STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16)
254 STEP(H, b, c, d, a, GET(6), 0x04881d05, 23)
255 STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4)
256 STEP(H, d, a, b, c, GET(12), 0xe6db99e5, 11)
257 STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16)
258 STEP(H, b, c, d, a, GET(2), 0xc4ac5665, 23)
259
260
261 STEP(I, a, b, c, d, GET(0), 0xf4292244, 6)
262 STEP(I, d, a, b, c, GET(7), 0x432aff97, 10)
263 STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15)
264 STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21)
265 STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6)
266 STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10)
267 STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15)
268 STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21)
269 STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6)
270 STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10)
271 STEP(I, c, d, a, b, GET(6), 0xa3014314, 15)
272 STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21)
273 STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6)
274 STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10)
275 STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15)
276 STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21)
277
278 a += saved_a;
279 b += saved_b;
280 c += saved_c;
281 d += saved_d;
282
283 ptr += 64;
284 } while (size -= 64);
285
286 ctx->a = a;
287 ctx->b = b;
288 ctx->c = c;
289 ctx->d = d;
290
291 return ptr;
292 }
293
294 PHPAPI void PHP_MD5Init(PHP_MD5_CTX *ctx)
295 {
296 ctx->a = 0x67452301;
297 ctx->b = 0xefcdab89;
298 ctx->c = 0x98badcfe;
299 ctx->d = 0x10325476;
300
301 ctx->lo = 0;
302 ctx->hi = 0;
303 }
304
305 PHPAPI void PHP_MD5Update(PHP_MD5_CTX *ctx, const void *data, size_t size)
306 {
307 php_uint32 saved_lo;
308 php_uint32 used, free;
309
310 saved_lo = ctx->lo;
311 if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo) {
312 ctx->hi++;
313 }
314 ctx->hi += size >> 29;
315
316 used = saved_lo & 0x3f;
317
318 if (used) {
319 free = 64 - used;
320
321 if (size < free) {
322 memcpy(&ctx->buffer[used], data, size);
323 return;
324 }
325
326 memcpy(&ctx->buffer[used], data, free);
327 data = (unsigned char *)data + free;
328 size -= free;
329 body(ctx, ctx->buffer, 64);
330 }
331
332 if (size >= 64) {
333 data = body(ctx, data, size & ~(size_t)0x3f);
334 size &= 0x3f;
335 }
336
337 memcpy(ctx->buffer, data, size);
338 }
339
340 PHPAPI void PHP_MD5Final(unsigned char *result, PHP_MD5_CTX *ctx)
341 {
342 php_uint32 used, free;
343
344 used = ctx->lo & 0x3f;
345
346 ctx->buffer[used++] = 0x80;
347
348 free = 64 - used;
349
350 if (free < 8) {
351 memset(&ctx->buffer[used], 0, free);
352 body(ctx, ctx->buffer, 64);
353 used = 0;
354 free = 64;
355 }
356
357 memset(&ctx->buffer[used], 0, free - 8);
358
359 ctx->lo <<= 3;
360 ctx->buffer[56] = ctx->lo;
361 ctx->buffer[57] = ctx->lo >> 8;
362 ctx->buffer[58] = ctx->lo >> 16;
363 ctx->buffer[59] = ctx->lo >> 24;
364 ctx->buffer[60] = ctx->hi;
365 ctx->buffer[61] = ctx->hi >> 8;
366 ctx->buffer[62] = ctx->hi >> 16;
367 ctx->buffer[63] = ctx->hi >> 24;
368
369 body(ctx, ctx->buffer, 64);
370
371 result[0] = ctx->a;
372 result[1] = ctx->a >> 8;
373 result[2] = ctx->a >> 16;
374 result[3] = ctx->a >> 24;
375 result[4] = ctx->b;
376 result[5] = ctx->b >> 8;
377 result[6] = ctx->b >> 16;
378 result[7] = ctx->b >> 24;
379 result[8] = ctx->c;
380 result[9] = ctx->c >> 8;
381 result[10] = ctx->c >> 16;
382 result[11] = ctx->c >> 24;
383 result[12] = ctx->d;
384 result[13] = ctx->d >> 8;
385 result[14] = ctx->d >> 16;
386 result[15] = ctx->d >> 24;
387
388 memset(ctx, 0, sizeof(*ctx));
389 }