1 : /*
2 : +----------------------------------------------------------------------+
3 : | PHP Version 6 |
4 : +----------------------------------------------------------------------+
5 : | Copyright (c) 1997-2009 The PHP Group |
6 : +----------------------------------------------------------------------+
7 : | This source file is subject to version 3.01 of the PHP license, |
8 : | that is bundled with this package in the file LICENSE, and is |
9 : | available through the world-wide-web at the following url: |
10 : | http://www.php.net/license/3_01.txt |
11 : | If you did not receive a copy of the PHP license and are unable to |
12 : | obtain it through the world-wide-web, please send a note to |
13 : | license@php.net so we can mail you a copy immediately. |
14 : +----------------------------------------------------------------------+
15 : | Author: Sara Golemon <pollita@php.net> |
16 : | Scott MacVicar <scottmac@php.net> |
17 : +----------------------------------------------------------------------+
18 : */
19 :
20 : /* $Id: hash.c 287429 2009-08-17 21:28:22Z garretts $ */
21 :
22 : #ifdef HAVE_CONFIG_H
23 : #include "config.h"
24 : #endif
25 :
26 : #include "php_hash.h"
27 : #include "ext/standard/info.h"
28 : #include "ext/standard/file.h"
29 :
30 : static int php_hash_le_hash;
31 : HashTable php_hash_hashtable;
32 :
33 : #if (PHP_MAJOR_VERSION >= 5)
34 : # define DEFAULT_CONTEXT FG(default_context)
35 : #else
36 : # define DEFAULT_CONTEXT NULL
37 : #endif
38 :
39 : #ifdef PHP_MHASH_BC
40 : struct mhash_bc_entry {
41 : char *mhash_name;
42 : char *hash_name;
43 : int value;
44 : };
45 :
46 : #define MHASH_NUM_ALGOS 29
47 :
48 : static struct mhash_bc_entry mhash_to_hash[MHASH_NUM_ALGOS] = {
49 : {"CRC32", "crc32", 0},
50 : {"MD5", "md5", 1},
51 : {"SHA1", "sha1", 2},
52 : {"HAVAL256", "haval256,3", 3},
53 : {NULL, NULL, 4},
54 : {"RIPEMD160", "ripemd160", 5},
55 : {NULL, NULL, 6},
56 : {"TIGER", "tiger192,3", 7},
57 : {"GOST", "gost", 8},
58 : {"CRC32B", "crc32b", 9},
59 : {"HAVAL224", "haval224,3", 10},
60 : {"HAVAL192", "haval192,3", 11},
61 : {"HAVAL160", "haval160,3", 12},
62 : {"HAVAL128", "haval128,3", 13},
63 : {"TIGER128", "tiger128,3", 14},
64 : {"TIGER160", "tiger160,3", 15},
65 : {"MD4", "md4", 16},
66 : {"SHA256", "sha256", 17},
67 : {"ADLER32", "adler32", 18},
68 : {"SHA224", "sha224", 19},
69 : {"SHA512", "sha512", 20},
70 : {"SHA384", "sha384", 21},
71 : {"WHIRLPOOL", "whirlpool", 22},
72 : {"RIPEMD128", "ripemd128", 23},
73 : {"RIPEMD256", "ripemd256", 24},
74 : {"RIPEMD320", "ripemd320", 25},
75 : {NULL, NULL, 26}, /* support needs to be added for snefru 128 */
76 : {"SNEFRU256", "snefru256", 27},
77 : {"MD2", "md2", 28}
78 : };
79 : #endif
80 :
81 : /* Hash Registry Access */
82 :
83 : PHP_HASH_API const php_hash_ops *php_hash_fetch_ops(const char *algo, int algo_len) /* {{{ */
84 356 : {
85 : php_hash_ops *ops;
86 356 : char *lower = estrndup(algo, algo_len);
87 :
88 356 : zend_str_tolower(lower, algo_len);
89 356 : if (SUCCESS != zend_hash_find(&php_hash_hashtable, lower, algo_len + 1, (void*)&ops)) {
90 4 : ops = NULL;
91 : }
92 356 : efree(lower);
93 :
94 356 : return ops;
95 : }
96 : /* }}} */
97 :
98 : PHP_HASH_API void php_hash_register_algo(const char *algo, const php_hash_ops *ops) /* {{{ */
99 714294 : {
100 714294 : int algo_len = strlen(algo);
101 714294 : char *lower = estrndup(algo, algo_len);
102 :
103 714294 : zend_str_tolower(lower, algo_len);
104 714294 : zend_hash_add(&php_hash_hashtable, lower, algo_len + 1, (void*)ops, sizeof(php_hash_ops), NULL);
105 714294 : efree(lower);
106 714294 : }
107 : /* }}} */
108 :
109 : PHP_HASH_API int php_hash_copy(const void *ops, void *orig_context, void *dest_context) /* {{{ */
110 79 : {
111 79 : php_hash_ops *hash_ops = (php_hash_ops *)ops;
112 :
113 79 : memcpy(dest_context, orig_context, hash_ops->context_size);
114 79 : return SUCCESS;
115 : }
116 : /* }}} */
117 :
118 : /* Userspace */
119 :
120 : static void php_hash_do_hash(INTERNAL_FUNCTION_PARAMETERS, int isfilename, zend_bool raw_output_default) /* {{{ */
121 217 : {
122 : char *algo, *data, *digest;
123 : int algo_len, data_len;
124 217 : zend_uchar data_type = IS_STRING;
125 217 : zend_bool raw_output = raw_output_default;
126 : const php_hash_ops *ops;
127 : void *context;
128 217 : php_stream *stream = NULL;
129 :
130 : #if PHP_MAJOR_VERSION >= 6
131 217 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "st|b", &algo, &algo_len, &data, &data_len, &data_type, &raw_output) == FAILURE) {
132 5 : return;
133 : }
134 :
135 212 : if (data_type == IS_UNICODE) {
136 212 : if (isfilename) {
137 28 : if (php_stream_path_encode(NULL, &data, &data_len, (UChar *)data, data_len, REPORT_ERRORS, FG(default_context)) == FAILURE) {
138 0 : RETURN_FALSE;
139 : }
140 : } else {
141 184 : data = zend_unicode_to_ascii((UChar*)data, data_len TSRMLS_CC);
142 184 : if (!data) {
143 : /* Non-ASCII Unicode string passed for raw hashing */
144 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Binary or ASCII-Unicode string expected, non-ASCII-Unicode string received");
145 0 : RETURN_FALSE;
146 : }
147 : }
148 : }
149 : #else
150 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|b", &algo, &algo_len, &data, &data_len, &raw_output) == FAILURE) {
151 : return;
152 : }
153 : #endif
154 : /* Assume failure */
155 212 : RETVAL_FALSE;
156 :
157 212 : ops = php_hash_fetch_ops(algo, algo_len);
158 212 : if (!ops) {
159 2 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown hashing algorithm: %s", algo);
160 2 : goto hash_done;
161 : }
162 210 : if (isfilename) {
163 27 : stream = php_stream_open_wrapper_ex(data, "rb", REPORT_ERRORS, NULL, DEFAULT_CONTEXT);
164 27 : if (!stream) {
165 : /* Stream will report errors opening file */
166 1 : goto hash_done;
167 : }
168 : }
169 :
170 209 : context = emalloc(ops->context_size);
171 209 : ops->hash_init(context);
172 :
173 209 : if (isfilename) {
174 : char buf[1024];
175 : int n;
176 :
177 78 : while ((n = php_stream_read(stream, buf, sizeof(buf))) > 0) {
178 26 : ops->hash_update(context, (unsigned char *) buf, n);
179 : }
180 26 : php_stream_close(stream);
181 : } else {
182 183 : ops->hash_update(context, (unsigned char *) data, data_len);
183 : }
184 :
185 209 : digest = emalloc(ops->digest_size + 1);
186 209 : ops->hash_final((unsigned char *) digest, context);
187 209 : efree(context);
188 :
189 209 : if (raw_output) {
190 18 : digest[ops->digest_size] = 0;
191 :
192 : /* Raw output is binary only */
193 18 : RETVAL_STRINGL(digest, ops->digest_size, 0);
194 : } else {
195 191 : char *hex_digest = safe_emalloc(ops->digest_size, 2, 1);
196 :
197 191 : php_hash_bin2hex(hex_digest, (unsigned char *) digest, ops->digest_size);
198 191 : hex_digest[2 * ops->digest_size] = 0;
199 191 : efree(digest);
200 :
201 : /* hexits can be binary or unicode */
202 : #if PHP_MAJOR_VERSION >= 6
203 191 : RETVAL_RT_STRINGL(hex_digest, 2 * ops->digest_size, ZSTR_AUTOFREE);
204 : #else
205 : RETVAL_STRINGL(hex_digest, 2 * ops->digest_size, 0);
206 : #endif
207 : }
208 :
209 212 : hash_done:
210 212 : if (data_type != IS_STRING) {
211 212 : efree(data);
212 : }
213 : }
214 : /* }}} */
215 :
216 : /* {{{ proto string hash(string algo, string data[, bool raw_output = false]) U
217 : Generate a hash of a given input string
218 : Returns lowercase hexits by default */
219 : PHP_FUNCTION(hash)
220 175 : {
221 175 : php_hash_do_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0, 0);
222 175 : }
223 : /* }}} */
224 :
225 : /* {{{ proto string hash_file(string algo, string filename[, bool raw_output = false]) U
226 : Generate a hash of a given file
227 : Returns lowercase hexits by default */
228 : PHP_FUNCTION(hash_file)
229 30 : {
230 30 : php_hash_do_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1, 0);
231 30 : }
232 : /* }}} */
233 :
234 : static void php_hash_do_hash_hmac(INTERNAL_FUNCTION_PARAMETERS, int isfilename, zend_bool raw_output_default) /* {{{ */
235 56 : {
236 : char *algo, *data, *digest, *key, *K;
237 : int algo_len, data_len, key_len, i;
238 56 : zend_uchar data_type = IS_STRING, key_type = IS_STRING;
239 56 : zend_bool raw_output = raw_output_default;
240 : const php_hash_ops *ops;
241 : void *context;
242 56 : php_stream *stream = NULL;
243 :
244 : #if PHP_MAJOR_VERSION >= 6
245 56 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "stt|b", &algo, &algo_len, &data, &data_len, &data_type, &key, &key_len, &key_type, &raw_output) == FAILURE) {
246 11 : return;
247 : }
248 :
249 45 : if (data_type == IS_UNICODE) {
250 45 : if (isfilename) {
251 22 : if (php_stream_path_encode(NULL, &data, &data_len, (UChar *)data, data_len, REPORT_ERRORS, FG(default_context)) == FAILURE) {
252 0 : RETURN_FALSE;
253 : }
254 : } else {
255 23 : data = zend_unicode_to_ascii((UChar*)data, data_len TSRMLS_CC);
256 23 : if (!data) {
257 : /* Non-ASCII Unicode string passed for raw hashing */
258 1 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Binary or ASCII-Unicode string expected, non-ASCII-Unicode string received");
259 1 : RETURN_FALSE;
260 : }
261 : }
262 : }
263 44 : if (key_type == IS_UNICODE) {
264 44 : key = zend_unicode_to_ascii((UChar*)key, key_len TSRMLS_CC);
265 44 : if (!key) {
266 : /* Non-ASCII Unicode key passed for raw hashing */
267 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Binary or ASCII-Unicode key expected, non-ASCII-Unicode key received");
268 0 : if (data_type == IS_UNICODE) {
269 0 : efree(data);
270 : }
271 0 : RETURN_FALSE;
272 : }
273 : }
274 : #else
275 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss|b", &algo, &algo_len, &data, &data_len, &key, &key_len, &raw_output) == FAILURE) {
276 : return;
277 : }
278 : #endif
279 : /* Assume failure */
280 44 : RETVAL_FALSE;
281 :
282 44 : ops = php_hash_fetch_ops(algo, algo_len);
283 44 : if (!ops) {
284 2 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown hashing algorithm: %s", algo);
285 2 : goto hmac_done;
286 : }
287 42 : if (isfilename) {
288 21 : stream = php_stream_open_wrapper_ex(data, "rb", REPORT_ERRORS, NULL, DEFAULT_CONTEXT);
289 21 : if (!stream) {
290 : /* Stream will report errors opening file */
291 0 : goto hmac_done;
292 : }
293 : }
294 :
295 42 : context = emalloc(ops->context_size);
296 42 : ops->hash_init(context);
297 :
298 42 : K = emalloc(ops->block_size);
299 42 : memset(K, 0, ops->block_size);
300 :
301 42 : if (key_len > ops->block_size) {
302 : /* Reduce the key first */
303 6 : ops->hash_update(context, (unsigned char *) key, key_len);
304 6 : ops->hash_final((unsigned char *) K, context);
305 :
306 : /* Make the context ready to start over */
307 6 : ops->hash_init(context);
308 : } else {
309 36 : memcpy(K, key, key_len);
310 : }
311 :
312 : /* XOR ipad */
313 2530 : for(i=0; i < ops->block_size; i++) {
314 2488 : K[i] ^= 0x36;
315 : }
316 42 : ops->hash_update(context, (unsigned char *) K, ops->block_size);
317 :
318 42 : if (isfilename) {
319 : char buf[1024];
320 : int n;
321 :
322 63 : while ((n = php_stream_read(stream, buf, sizeof(buf))) > 0) {
323 21 : ops->hash_update(context, (unsigned char *) buf, n);
324 : }
325 21 : php_stream_close(stream);
326 : } else {
327 21 : ops->hash_update(context, (unsigned char *) data, data_len);
328 : }
329 :
330 42 : digest = emalloc(ops->digest_size + 1);
331 42 : ops->hash_final((unsigned char *) digest, context);
332 :
333 : /* Convert K to opad -- 0x6A = 0x36 ^ 0x5C */
334 2530 : for(i=0; i < ops->block_size; i++) {
335 2488 : K[i] ^= 0x6A;
336 : }
337 :
338 : /* Feed this result into the outter hash */
339 42 : ops->hash_init(context);
340 42 : ops->hash_update(context, (unsigned char *) K, ops->block_size);
341 42 : ops->hash_update(context, (unsigned char *) digest, ops->digest_size);
342 42 : ops->hash_final((unsigned char *) digest, context);
343 :
344 : /* Zero the key */
345 42 : memset(K, 0, ops->block_size);
346 42 : efree(K);
347 42 : efree(context);
348 :
349 42 : if (raw_output) {
350 6 : digest[ops->digest_size] = 0;
351 :
352 : /* Raw output is binary only */
353 6 : RETVAL_STRINGL(digest, ops->digest_size, 0);
354 : } else {
355 36 : char *hex_digest = safe_emalloc(ops->digest_size, 2, 1);
356 :
357 36 : php_hash_bin2hex(hex_digest, (unsigned char *) digest, ops->digest_size);
358 36 : hex_digest[2 * ops->digest_size] = 0;
359 36 : efree(digest);
360 :
361 : /* hexits can be binary or unicode */
362 : #if PHP_MAJOR_VERSION >= 6
363 36 : RETVAL_RT_STRINGL(hex_digest, 2 * ops->digest_size, ZSTR_AUTOFREE);
364 : #else
365 : RETVAL_STRINGL(hex_digest, 2 * ops->digest_size, 0);
366 : #endif
367 : }
368 :
369 44 : hmac_done:
370 44 : if (data_type != IS_STRING) {
371 44 : efree(data);
372 : }
373 44 : if (key_type != IS_STRING) {
374 44 : efree(key);
375 : }
376 : }
377 : /* }}} */
378 :
379 : /* {{{ proto string hash_hmac(string algo, string data, string key[, bool raw_output = false]) U
380 : Generate a hash of a given input string with a key using HMAC
381 : Returns lowercase hexits by default */
382 : PHP_FUNCTION(hash_hmac)
383 27 : {
384 27 : php_hash_do_hash_hmac(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0, 0);
385 27 : }
386 : /* }}} */
387 :
388 : /* {{{ proto string hash_hmac_file(string algo, string filename, string key[, bool raw_output = false]) U
389 : Generate a hash of a given file with a key using HMAC
390 : Returns lowercase hexits by default */
391 : PHP_FUNCTION(hash_hmac_file)
392 29 : {
393 29 : php_hash_do_hash_hmac(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1, 0);
394 29 : }
395 : /* }}} */
396 :
397 :
398 : /* {{{ proto resource hash_init(string algo[, int options, string key]) U
399 : Initialize a hashing context */
400 : PHP_FUNCTION(hash_init)
401 87 : {
402 87 : char *algo, *key = NULL;
403 87 : int algo_len, key_len = 0, argc = ZEND_NUM_ARGS();
404 87 : long options = 0;
405 : void *context;
406 : const php_hash_ops *ops;
407 : php_hash_data *hash;
408 :
409 : #if PHP_MAJOR_VERSION >= 6
410 : zend_uchar key_type;
411 :
412 87 : if (zend_parse_parameters(argc TSRMLS_CC, "s|lt", &algo, &algo_len, &options, &key, &key_len, &key_type) == FAILURE) {
413 : #else
414 : if (zend_parse_parameters(argc TSRMLS_CC, "s|ls", &algo, &algo_len, &options, &key, &key_len) == FAILURE) {
415 : #endif
416 0 : return;
417 : }
418 :
419 87 : ops = php_hash_fetch_ops(algo, algo_len);
420 87 : if (!ops) {
421 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown hashing algorithm: %s", algo);
422 0 : RETURN_FALSE;
423 : }
424 :
425 87 : if (options & PHP_HASH_HMAC &&
426 : key_len <= 0) {
427 : /* Note: a zero length key is no key at all */
428 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "HMAC requested without a key");
429 0 : RETURN_FALSE;
430 : }
431 :
432 : #if PHP_MAJOR_VERSION >= 6
433 87 : if (key && key_type == IS_UNICODE) {
434 2 : key = zend_unicode_to_ascii((UChar*)key, key_len TSRMLS_CC);
435 2 : if (!key) {
436 : /* Non-ASCII Unicode key passed for raw hashing */
437 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Binary or ASCII-Unicode key expected, non-ASCII-Unicode key received");
438 0 : RETURN_FALSE;
439 : }
440 : }
441 : #endif
442 :
443 87 : context = emalloc(ops->context_size);
444 87 : ops->hash_init(context);
445 :
446 87 : hash = emalloc(sizeof(php_hash_data));
447 87 : hash->ops = ops;
448 87 : hash->context = context;
449 87 : hash->options = options;
450 87 : hash->key = NULL;
451 :
452 87 : if (options & PHP_HASH_HMAC) {
453 2 : char *K = emalloc(ops->block_size);
454 : int i;
455 :
456 2 : memset(K, 0, ops->block_size);
457 :
458 2 : if (key_len > ops->block_size) {
459 : /* Reduce the key first */
460 0 : ops->hash_update(context, (unsigned char *) key, key_len);
461 0 : ops->hash_final((unsigned char *) K, context);
462 : /* Make the context ready to start over */
463 0 : ops->hash_init(context);
464 : } else {
465 2 : memcpy(K, key, key_len);
466 : }
467 :
468 : /* XOR ipad */
469 130 : for(i=0; i < ops->block_size; i++) {
470 128 : K[i] ^= 0x36;
471 : }
472 2 : ops->hash_update(context, (unsigned char *) K, ops->block_size);
473 2 : hash->key = (unsigned char *) K;
474 : }
475 :
476 : #if PHP_MAJOR_VERSION >= 6
477 87 : if (key && key_type == IS_UNICODE) {
478 2 : efree(key);
479 : }
480 : #endif
481 :
482 87 : ZEND_REGISTER_RESOURCE(return_value, hash, php_hash_le_hash);
483 : }
484 : /* }}} */
485 :
486 : /* {{{ proto bool hash_update(resource context, string data) U
487 : Pump data into the hashing algorithm */
488 : PHP_FUNCTION(hash_update)
489 128 : {
490 : zval *zhash;
491 : php_hash_data *hash;
492 : char *data;
493 : int data_len;
494 128 : zend_uchar data_type = IS_STRING;
495 :
496 : #if PHP_MAJOR_VERSION >= 6
497 128 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rt", &zhash, &data, &data_len, &data_type) == FAILURE) {
498 0 : return;
499 : }
500 :
501 128 : if (data_type == IS_UNICODE) {
502 2 : data = zend_unicode_to_ascii((UChar*)data, data_len TSRMLS_CC);
503 2 : if (!data) {
504 : /* Non-ASCII Unicode string passed for raw hashing */
505 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Binary or ASCII-Unicode string expected, non-ASCII-Unicode string received");
506 0 : RETURN_FALSE;
507 : }
508 : }
509 : #else
510 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &zhash, &data, &data_len) == FAILURE) {
511 : return;
512 : }
513 : #endif
514 :
515 128 : ZEND_FETCH_RESOURCE(hash, php_hash_data*, &zhash, -1, PHP_HASH_RESNAME, php_hash_le_hash);
516 :
517 128 : hash->ops->hash_update(hash->context, (unsigned char *) data, data_len);
518 :
519 128 : if (data_type != IS_STRING) {
520 2 : efree(data);
521 : }
522 :
523 128 : RETURN_TRUE;
524 : }
525 : /* }}} */
526 :
527 : /* {{{ proto int hash_update_stream(resource context, resource handle[, integer length]) U
528 : Pump data into the hashing algorithm from an open stream */
529 : PHP_FUNCTION(hash_update_stream)
530 0 : {
531 : zval *zhash, *zstream;
532 : php_hash_data *hash;
533 0 : php_stream *stream = NULL;
534 0 : long length = -1, didread = 0;
535 :
536 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rr|l", &zhash, &zstream, &length) == FAILURE) {
537 0 : return;
538 : }
539 :
540 0 : ZEND_FETCH_RESOURCE(hash, php_hash_data*, &zhash, -1, PHP_HASH_RESNAME, php_hash_le_hash);
541 0 : php_stream_from_zval(stream, &zstream);
542 :
543 0 : while (length) {
544 : char buf[1024];
545 0 : long n, toread = 1024;
546 :
547 0 : if (length > 0 && toread > length) {
548 0 : toread = length;
549 : }
550 :
551 0 : if ((n = php_stream_read(stream, buf, toread)) <= 0) {
552 : /* Nada mas */
553 0 : RETURN_LONG(didread);
554 : }
555 0 : hash->ops->hash_update(hash->context, (unsigned char *) buf, n);
556 0 : length -= n;
557 0 : didread += n;
558 : }
559 :
560 0 : RETURN_LONG(didread);
561 : }
562 : /* }}} */
563 :
564 : /* {{{ proto bool hash_update_file(resource context, string filename[, resource context]) U
565 : Pump data into the hashing algorithm from a file */
566 : PHP_FUNCTION(hash_update_file)
567 0 : {
568 0 : zval *zhash, *zcontext = NULL;
569 : php_hash_data *hash;
570 : void *stream_context;
571 : php_stream *stream;
572 : char *filename, buf[1024];
573 : int filename_len, n;
574 0 : zend_uchar filename_type = IS_STRING;
575 :
576 : #if PHP_MAJOR_VERSION >= 6
577 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rt|r", &zhash, &filename, &filename_len, &filename_type, &zcontext) == FAILURE) {
578 0 : return;
579 : }
580 :
581 0 : stream_context = php_stream_context_from_zval(zcontext, 0);
582 :
583 0 : if (filename_type == IS_UNICODE) {
584 0 : if (php_stream_path_encode(NULL, &filename, &filename_len, (UChar *)filename, filename_len, REPORT_ERRORS, stream_context) == FAILURE) {
585 0 : RETURN_FALSE;
586 : }
587 : }
588 : #elif defined(php_stream_context_from_zval)
589 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|r", &zhash, &filename, &filename_len, &zcontext) == FAILURE) {
590 : return;
591 : }
592 :
593 : stream_context = php_stream_context_from_zval(zcontext, 0);
594 : #else
595 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &zhash, &filename, &filename_len) == FAILURE) {
596 : return;
597 : }
598 : stream_context = NULL;
599 : #endif
600 :
601 0 : ZEND_FETCH_RESOURCE(hash, php_hash_data*, &zhash, -1, PHP_HASH_RESNAME, php_hash_le_hash);
602 :
603 0 : stream = php_stream_open_wrapper_ex(filename, "rb", REPORT_ERRORS, NULL, stream_context);
604 0 : if (filename_type != IS_STRING) {
605 : /* Original filename was UNICODE, this string is a converted copy */
606 0 : efree(filename);
607 : }
608 0 : if (!stream) {
609 : /* Stream will report errors opening file */
610 0 : RETURN_FALSE;
611 : }
612 :
613 0 : while ((n = php_stream_read(stream, buf, sizeof(buf))) > 0) {
614 0 : hash->ops->hash_update(hash->context, (unsigned char *) buf, n);
615 : }
616 0 : php_stream_close(stream);
617 :
618 0 : RETURN_TRUE;
619 : }
620 : /* }}} */
621 :
622 : /* {{{ proto string hash_final(resource context[, bool raw_output=false]) U
623 : Output resulting digest */
624 : PHP_FUNCTION(hash_final)
625 170 : {
626 : zval *zhash;
627 : php_hash_data *hash;
628 170 : zend_bool raw_output = 0;
629 : zend_rsrc_list_entry *le;
630 : char *digest;
631 : int digest_len;
632 :
633 170 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|b", &zhash, &raw_output) == FAILURE) {
634 0 : return;
635 : }
636 :
637 170 : ZEND_FETCH_RESOURCE(hash, php_hash_data*, &zhash, -1, PHP_HASH_RESNAME, php_hash_le_hash);
638 :
639 170 : digest_len = hash->ops->digest_size;
640 170 : digest = emalloc(digest_len + 1);
641 170 : hash->ops->hash_final((unsigned char *) digest, hash->context);
642 170 : if (hash->options & PHP_HASH_HMAC) {
643 : int i;
644 :
645 : /* Convert K to opad -- 0x6A = 0x36 ^ 0x5C */
646 130 : for(i=0; i < hash->ops->block_size; i++) {
647 128 : hash->key[i] ^= 0x6A;
648 : }
649 :
650 : /* Feed this result into the outter hash */
651 2 : hash->ops->hash_init(hash->context);
652 2 : hash->ops->hash_update(hash->context, (unsigned char *) hash->key, hash->ops->block_size);
653 2 : hash->ops->hash_update(hash->context, (unsigned char *) digest, hash->ops->digest_size);
654 2 : hash->ops->hash_final((unsigned char *) digest, hash->context);
655 :
656 : /* Zero the key */
657 2 : memset(hash->key, 0, hash->ops->block_size);
658 2 : efree(hash->key);
659 2 : hash->key = NULL;
660 : }
661 170 : digest[digest_len] = 0;
662 170 : efree(hash->context);
663 170 : hash->context = NULL;
664 :
665 : /* zend_list_REAL_delete() */
666 170 : if (zend_hash_index_find(&EG(regular_list), Z_RESVAL_P(zhash), (void *) &le)==SUCCESS) {
667 : /* This is a hack to avoid letting the resource hide elsewhere (like in separated vars)
668 : FETCH_RESOURCE is intelligent enough to handle dealing with any issues this causes */
669 170 : le->refcount = 1;
670 : } /* FAILURE is not an option */
671 170 : zend_list_delete(Z_RESVAL_P(zhash));
672 :
673 170 : if (raw_output) {
674 : /* Raw output can only be binary */
675 0 : RETURN_STRINGL(digest, digest_len, 0);
676 : } else {
677 170 : char *hex_digest = safe_emalloc(digest_len,2,1);
678 :
679 170 : php_hash_bin2hex(hex_digest, (unsigned char *) digest, digest_len);
680 170 : hex_digest[2 * digest_len] = 0;
681 170 : efree(digest);
682 :
683 : /* Hexits can be either binary or unicode */
684 : #if PHP_MAJOR_VERSION >= 6
685 170 : RETURN_RT_STRINGL(hex_digest, 2 * digest_len, ZSTR_AUTOFREE);
686 : #else
687 : RETURN_STRINGL(hex_digest, 2 * digest_len, 0);
688 : #endif
689 : }
690 : }
691 : /* }}} */
692 :
693 : /* {{{ proto resource hash_copy(resource context) U
694 : Copy hash resource */
695 : PHP_FUNCTION(hash_copy)
696 87 : {
697 : zval *zhash;
698 : php_hash_data *hash, *copy_hash;
699 : void *context;
700 : int res;
701 :
702 87 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zhash) == FAILURE) {
703 2 : return;
704 : }
705 :
706 85 : ZEND_FETCH_RESOURCE(hash, php_hash_data*, &zhash, -1, PHP_HASH_RESNAME, php_hash_le_hash);
707 :
708 :
709 85 : context = emalloc(hash->ops->context_size);
710 85 : hash->ops->hash_init(context);
711 :
712 85 : res = hash->ops->hash_copy(hash->ops, hash->context, context);
713 85 : if (res != SUCCESS) {
714 0 : efree(context);
715 0 : RETURN_FALSE;
716 : }
717 :
718 85 : copy_hash = emalloc(sizeof(php_hash_data));
719 85 : copy_hash->ops = hash->ops;
720 85 : copy_hash->context = context;
721 85 : copy_hash->options = hash->options;
722 85 : copy_hash->key = hash->key;
723 :
724 85 : ZEND_REGISTER_RESOURCE(return_value, copy_hash, php_hash_le_hash);
725 : }
726 : /* }}} */
727 :
728 : /* {{{ proto array hash_algos(void) U
729 : Return a list of registered hashing algorithms */
730 : PHP_FUNCTION(hash_algos)
731 2 : {
732 : #if (PHP_MAJOR_VERSION >= 6)
733 : zstr str;
734 : #else
735 : char *str;
736 : #endif
737 : int str_len;
738 : ulong idx;
739 : long type;
740 : HashPosition pos;
741 :
742 2 : array_init(return_value);
743 2 : for(zend_hash_internal_pointer_reset_ex(&php_hash_hashtable, &pos);
744 88 : (type = zend_hash_get_current_key_ex(&php_hash_hashtable, &str, &str_len, &idx, 0, &pos)) != HASH_KEY_NON_EXISTANT;
745 84 : zend_hash_move_forward_ex(&php_hash_hashtable, &pos)) {
746 : #if (PHP_MAJOR_VERSION >= 6)
747 84 : add_next_index_ascii_stringl(return_value, str.s, str_len-1, 1);
748 : #else
749 : add_next_index_stringl(return_value, str, str_len-1, 1);
750 : #endif
751 : }
752 2 : }
753 : /* }}} */
754 :
755 : /* Module Housekeeping */
756 :
757 : static void php_hash_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */
758 172 : {
759 172 : php_hash_data *hash = (php_hash_data*)rsrc->ptr;
760 :
761 : /* Just in case the algo has internally allocated resources */
762 172 : if (hash->context) {
763 2 : unsigned char *dummy = emalloc(hash->ops->digest_size);
764 2 : hash->ops->hash_final(dummy, hash->context);
765 2 : efree(dummy);
766 2 : efree(hash->context);
767 : }
768 :
769 172 : if (hash->key) {
770 0 : memset(hash->key, 0, hash->ops->block_size);
771 0 : efree(hash->key);
772 : }
773 172 : efree(hash);
774 172 : }
775 : /* }}} */
776 :
777 : #ifdef PHP_MHASH_BC
778 :
779 : PHP_MINFO_FUNCTION(mhash)
780 43 : {
781 43 : php_info_print_table_start();
782 43 : php_info_print_table_row(2, "MHASH support", "Enabled");
783 43 : php_info_print_table_row(2, "MHASH API Version", "Emulated Support");
784 43 : php_info_print_table_end();
785 43 : }
786 :
787 : zend_module_entry mhash_module_entry = {
788 : STANDARD_MODULE_HEADER,
789 : "mhash",
790 : NULL,
791 : NULL,
792 : NULL,
793 : NULL,
794 : NULL,
795 : PHP_MINFO(mhash),
796 : NO_VERSION_YET,
797 : STANDARD_MODULE_PROPERTIES,
798 : };
799 :
800 : static void mhash_init(INIT_FUNC_ARGS)
801 17007 : {
802 : char buf[128];
803 : int len;
804 17007 : int algo_number = 0;
805 :
806 510210 : for (algo_number = 0; algo_number < MHASH_NUM_ALGOS; algo_number++) {
807 493203 : struct mhash_bc_entry algorithm = mhash_to_hash[algo_number];
808 493203 : if (algorithm.mhash_name == NULL) {
809 51021 : continue;
810 : }
811 :
812 442182 : len = slprintf(buf, 127, "MHASH_%s", algorithm.mhash_name, strlen(algorithm.mhash_name));
813 442182 : zend_register_long_constant(buf, len + 1, algorithm.value, CONST_CS | CONST_PERSISTENT, module_number TSRMLS_CC);
814 : }
815 17007 : zend_register_internal_module(&mhash_module_entry TSRMLS_CC);
816 17007 : }
817 :
818 : /* {{{ proto binary mhash(int hash, binary data [, binary key]) U
819 : Hash data with hash */
820 : PHP_FUNCTION(mhash)
821 12 : {
822 : zval **z_algorithm;
823 : long algorithm;
824 :
825 12 : if (zend_parse_parameters(1 TSRMLS_CC, "Z", &z_algorithm) == FAILURE) {
826 0 : return;
827 : }
828 :
829 12 : SEPARATE_ZVAL(z_algorithm);
830 12 : convert_to_long_ex(z_algorithm);
831 12 : algorithm = Z_LVAL_PP(z_algorithm);
832 :
833 : /* need to conver the first parameter from int to string */
834 12 : if (algorithm >= 0 && algorithm < MHASH_NUM_ALGOS) {
835 12 : struct mhash_bc_entry algorithm_lookup = mhash_to_hash[algorithm];
836 12 : if (algorithm_lookup.hash_name) {
837 12 : ZVAL_STRING(*z_algorithm, algorithm_lookup.hash_name, 1);
838 : }
839 : }
840 :
841 12 : if (ZEND_NUM_ARGS() == 3) {
842 0 : php_hash_do_hash_hmac(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0, 1);
843 12 : } else if (ZEND_NUM_ARGS() == 2) {
844 12 : php_hash_do_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0, 1);
845 : } else {
846 0 : WRONG_PARAM_COUNT;
847 : }
848 : }
849 : /* }}} */
850 :
851 : /* {{{ proto string mhash_get_hash_name(int hash) U
852 : Gets the name of hash */
853 : PHP_FUNCTION(mhash_get_hash_name)
854 29 : {
855 : long algorithm;
856 :
857 29 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &algorithm) == FAILURE) {
858 0 : return;
859 : }
860 :
861 29 : if (algorithm >= 0 && algorithm < MHASH_NUM_ALGOS) {
862 29 : struct mhash_bc_entry algorithm_lookup = mhash_to_hash[algorithm];
863 29 : if (algorithm_lookup.mhash_name) {
864 26 : RETURN_STRING(algorithm_lookup.mhash_name, 1);
865 : }
866 : }
867 3 : RETURN_FALSE;
868 : }
869 : /* }}} */
870 :
871 : /* {{{ proto int mhash_count(void) U
872 : Gets the number of available hashes */
873 : PHP_FUNCTION(mhash_count)
874 1 : {
875 1 : if (zend_parse_parameters_none() == FAILURE) {
876 0 : return;
877 : }
878 1 : RETURN_LONG(MHASH_NUM_ALGOS - 1);
879 : }
880 : /* }}} */
881 :
882 : /* {{{ proto int mhash_get_block_size(int hash) U
883 : Gets the block size of hash */
884 : PHP_FUNCTION(mhash_get_block_size)
885 0 : {
886 : long algorithm;
887 :
888 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &algorithm) == FAILURE) {
889 0 : return;
890 : }
891 0 : RETVAL_FALSE;
892 :
893 0 : if (algorithm >= 0 && algorithm < MHASH_NUM_ALGOS) {
894 0 : struct mhash_bc_entry algorithm_lookup = mhash_to_hash[algorithm];
895 0 : if (algorithm_lookup.mhash_name) {
896 0 : const php_hash_ops *ops = php_hash_fetch_ops(algorithm_lookup.hash_name, strlen(algorithm_lookup.hash_name));
897 0 : if (ops) {
898 0 : RETVAL_LONG(ops->digest_size);
899 : }
900 : }
901 : }
902 : }
903 : /* }}} */
904 :
905 : #define SALT_SIZE 8
906 :
907 : /* {{{ proto binary mhash_keygen_s2k(int hash, binary input_password, binary salt, int bytes)
908 : Generates a key using hash functions */
909 : PHP_FUNCTION(mhash_keygen_s2k)
910 11 : {
911 : long algorithm, bytes;
912 : char *password, *salt;
913 : int password_len, salt_len;
914 : char padded_salt[SALT_SIZE];
915 :
916 11 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lSSl", &algorithm, &password, &password_len, &salt, &salt_len, &bytes) == FAILURE) {
917 0 : return;
918 : }
919 :
920 11 : if (bytes <= 0){
921 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "the byte parameter must be greater than 0");
922 0 : RETURN_FALSE;
923 : }
924 :
925 11 : salt_len = MIN(salt_len, SALT_SIZE);
926 :
927 11 : memcpy(padded_salt, salt, salt_len);
928 11 : if (salt_len < SALT_SIZE) {
929 0 : memset(padded_salt + salt_len, 0, SALT_SIZE - salt_len);
930 : }
931 11 : salt_len = SALT_SIZE;
932 :
933 11 : RETVAL_FALSE;
934 11 : if (algorithm >= 0 && algorithm < MHASH_NUM_ALGOS) {
935 11 : struct mhash_bc_entry algorithm_lookup = mhash_to_hash[algorithm];
936 11 : if (algorithm_lookup.mhash_name) {
937 11 : const php_hash_ops *ops = php_hash_fetch_ops(algorithm_lookup.hash_name, strlen(algorithm_lookup.hash_name));
938 11 : if (ops) {
939 11 : unsigned char null = '\0';
940 : void *context;
941 : char *key, *digest;
942 11 : int i = 0, j = 0;
943 11 : int block_size = ops->digest_size;
944 11 : int times = bytes / block_size;
945 11 : if (bytes % block_size != 0) times++;
946 :
947 11 : context = emalloc(ops->context_size);
948 11 : ops->hash_init(context);
949 :
950 11 : key = ecalloc(1, times * block_size);
951 11 : digest = emalloc(ops->digest_size + 1);
952 :
953 105 : for (i = 0; i < times; i++) {
954 94 : ops->hash_init(context);
955 :
956 783 : for (j=0;j<i;j++) {
957 689 : ops->hash_update(context, &null, 1);
958 : }
959 94 : ops->hash_update(context, (unsigned char *)padded_salt, salt_len);
960 94 : ops->hash_update(context, (unsigned char *)password, password_len);
961 94 : ops->hash_final((unsigned char *)digest, context);
962 94 : memcpy( &key[i*block_size], digest, block_size);
963 : }
964 :
965 11 : RETVAL_STRINGL(key, bytes, 1);
966 11 : memset(key, 0, bytes);
967 11 : efree(digest);
968 11 : efree(context);
969 11 : efree(key);
970 : }
971 : }
972 : }
973 : }
974 : /* }}} */
975 : #endif
976 :
977 : #define PHP_HASH_HAVAL_REGISTER(p,b) php_hash_register_algo("haval" #b "," #p , &php_hash_##p##haval##b##_ops);
978 :
979 : /* {{{ PHP_MINIT_FUNCTION
980 : */
981 : PHP_MINIT_FUNCTION(hash)
982 17007 : {
983 17007 : php_hash_le_hash = zend_register_list_destructors_ex(php_hash_dtor, NULL, PHP_HASH_RESNAME, module_number);
984 :
985 17007 : zend_hash_init(&php_hash_hashtable, 35, NULL, NULL, 1);
986 :
987 17007 : php_hash_register_algo("md2", &php_hash_md2_ops);
988 17007 : php_hash_register_algo("md4", &php_hash_md4_ops);
989 17007 : php_hash_register_algo("md5", &php_hash_md5_ops);
990 17007 : php_hash_register_algo("sha1", &php_hash_sha1_ops);
991 17007 : php_hash_register_algo("sha224", &php_hash_sha224_ops);
992 17007 : php_hash_register_algo("sha256", &php_hash_sha256_ops);
993 17007 : php_hash_register_algo("sha384", &php_hash_sha384_ops);
994 17007 : php_hash_register_algo("sha512", &php_hash_sha512_ops);
995 17007 : php_hash_register_algo("ripemd128", &php_hash_ripemd128_ops);
996 17007 : php_hash_register_algo("ripemd160", &php_hash_ripemd160_ops);
997 17007 : php_hash_register_algo("ripemd256", &php_hash_ripemd256_ops);
998 17007 : php_hash_register_algo("ripemd320", &php_hash_ripemd320_ops);
999 17007 : php_hash_register_algo("whirlpool", &php_hash_whirlpool_ops);
1000 17007 : php_hash_register_algo("tiger128,3", &php_hash_3tiger128_ops);
1001 17007 : php_hash_register_algo("tiger160,3", &php_hash_3tiger160_ops);
1002 17007 : php_hash_register_algo("tiger192,3", &php_hash_3tiger192_ops);
1003 17007 : php_hash_register_algo("tiger128,4", &php_hash_4tiger128_ops);
1004 17007 : php_hash_register_algo("tiger160,4", &php_hash_4tiger160_ops);
1005 17007 : php_hash_register_algo("tiger192,4", &php_hash_4tiger192_ops);
1006 17007 : php_hash_register_algo("snefru", &php_hash_snefru_ops);
1007 17007 : php_hash_register_algo("snefru256", &php_hash_snefru_ops);
1008 17007 : php_hash_register_algo("gost", &php_hash_gost_ops);
1009 17007 : php_hash_register_algo("adler32", &php_hash_adler32_ops);
1010 17007 : php_hash_register_algo("crc32", &php_hash_crc32_ops);
1011 17007 : php_hash_register_algo("crc32b", &php_hash_crc32b_ops);
1012 17007 : php_hash_register_algo("salsa10", &php_hash_salsa10_ops);
1013 17007 : php_hash_register_algo("salsa20", &php_hash_salsa20_ops);
1014 :
1015 17007 : PHP_HASH_HAVAL_REGISTER(3,128);
1016 17007 : PHP_HASH_HAVAL_REGISTER(3,160);
1017 17007 : PHP_HASH_HAVAL_REGISTER(3,192);
1018 17007 : PHP_HASH_HAVAL_REGISTER(3,224);
1019 17007 : PHP_HASH_HAVAL_REGISTER(3,256);
1020 :
1021 17007 : PHP_HASH_HAVAL_REGISTER(4,128);
1022 17007 : PHP_HASH_HAVAL_REGISTER(4,160);
1023 17007 : PHP_HASH_HAVAL_REGISTER(4,192);
1024 17007 : PHP_HASH_HAVAL_REGISTER(4,224);
1025 17007 : PHP_HASH_HAVAL_REGISTER(4,256);
1026 :
1027 17007 : PHP_HASH_HAVAL_REGISTER(5,128);
1028 17007 : PHP_HASH_HAVAL_REGISTER(5,160);
1029 17007 : PHP_HASH_HAVAL_REGISTER(5,192);
1030 17007 : PHP_HASH_HAVAL_REGISTER(5,224);
1031 17007 : PHP_HASH_HAVAL_REGISTER(5,256);
1032 :
1033 17007 : REGISTER_LONG_CONSTANT("HASH_HMAC", PHP_HASH_HMAC, CONST_CS | CONST_PERSISTENT);
1034 :
1035 : #ifdef PHP_MHASH_BC
1036 17007 : mhash_init(INIT_FUNC_ARGS_PASSTHRU);
1037 : #endif
1038 :
1039 17007 : return SUCCESS;
1040 : }
1041 : /* }}} */
1042 :
1043 : /* {{{ PHP_MSHUTDOWN_FUNCTION
1044 : */
1045 : PHP_MSHUTDOWN_FUNCTION(hash)
1046 17039 : {
1047 17039 : zend_hash_destroy(&php_hash_hashtable);
1048 :
1049 17039 : return SUCCESS;
1050 : }
1051 : /* }}} */
1052 :
1053 : /* {{{ PHP_MINFO_FUNCTION
1054 : */
1055 : PHP_MINFO_FUNCTION(hash)
1056 43 : {
1057 : HashPosition pos;
1058 : char buffer[2048];
1059 43 : char *s = buffer, *e = s + sizeof(buffer);
1060 : ulong idx;
1061 : long type;
1062 : #if (PHP_MAJOR_VERSION >= 6)
1063 : zstr str;
1064 : #else
1065 : char *str;
1066 : #endif
1067 :
1068 43 : for(zend_hash_internal_pointer_reset_ex(&php_hash_hashtable, &pos);
1069 1892 : (type = zend_hash_get_current_key_ex(&php_hash_hashtable, &str, NULL, &idx, 0, &pos)) != HASH_KEY_NON_EXISTANT;
1070 1806 : zend_hash_move_forward_ex(&php_hash_hashtable, &pos)) {
1071 : #if (PHP_MAJOR_VERSION >= 6)
1072 1806 : s += slprintf(s, e - s, "%s ", str.s);
1073 : #else
1074 : s += slprintf(s, e - s, "%s ", str);
1075 : #endif
1076 : }
1077 43 : *s = 0;
1078 :
1079 43 : php_info_print_table_start();
1080 43 : php_info_print_table_row(2, "hash support", "enabled");
1081 43 : php_info_print_table_row(2, "Hashing Engines", buffer);
1082 43 : php_info_print_table_end();
1083 43 : }
1084 : /* }}} */
1085 :
1086 : /* {{{ arginfo */
1087 : #if PHP_MAJOR_VERSION >= 5
1088 : ZEND_BEGIN_ARG_INFO_EX(arginfo_hash, 0, 0, 2)
1089 : ZEND_ARG_INFO(0, algo)
1090 : ZEND_ARG_INFO(0, data)
1091 : ZEND_ARG_INFO(0, raw_output)
1092 : ZEND_END_ARG_INFO()
1093 :
1094 : ZEND_BEGIN_ARG_INFO_EX(arginfo_hash_file, 0, 0, 2)
1095 : ZEND_ARG_INFO(0, algo)
1096 : ZEND_ARG_INFO(0, filename)
1097 : ZEND_ARG_INFO(0, raw_output)
1098 : ZEND_END_ARG_INFO()
1099 :
1100 : ZEND_BEGIN_ARG_INFO_EX(arginfo_hash_hmac, 0, 0, 3)
1101 : ZEND_ARG_INFO(0, algo)
1102 : ZEND_ARG_INFO(0, data)
1103 : ZEND_ARG_INFO(0, key)
1104 : ZEND_ARG_INFO(0, raw_output)
1105 : ZEND_END_ARG_INFO()
1106 :
1107 : ZEND_BEGIN_ARG_INFO_EX(arginfo_hash_hmac_file, 0, 0, 3)
1108 : ZEND_ARG_INFO(0, algo)
1109 : ZEND_ARG_INFO(0, filename)
1110 : ZEND_ARG_INFO(0, key)
1111 : ZEND_ARG_INFO(0, raw_output)
1112 : ZEND_END_ARG_INFO()
1113 :
1114 : ZEND_BEGIN_ARG_INFO_EX(arginfo_hash_init, 0, 0, 1)
1115 : ZEND_ARG_INFO(0, algo)
1116 : ZEND_ARG_INFO(0, options)
1117 : ZEND_ARG_INFO(0, key)
1118 : ZEND_END_ARG_INFO()
1119 :
1120 : ZEND_BEGIN_ARG_INFO(arginfo_hash_update, 0)
1121 : ZEND_ARG_INFO(0, context)
1122 : ZEND_ARG_INFO(0, data)
1123 : ZEND_END_ARG_INFO()
1124 :
1125 : ZEND_BEGIN_ARG_INFO_EX(arginfo_hash_update_stream, 0, 0, 2)
1126 : ZEND_ARG_INFO(0, context)
1127 : ZEND_ARG_INFO(0, handle)
1128 : ZEND_ARG_INFO(0, length)
1129 : ZEND_END_ARG_INFO()
1130 :
1131 : ZEND_BEGIN_ARG_INFO_EX(arginfo_hash_update_file, 0, 0, 2)
1132 : ZEND_ARG_INFO(0, context)
1133 : ZEND_ARG_INFO(0, filename)
1134 : ZEND_ARG_INFO(0, context)
1135 : ZEND_END_ARG_INFO()
1136 :
1137 : ZEND_BEGIN_ARG_INFO_EX(arginfo_hash_final, 0, 0, 1)
1138 : ZEND_ARG_INFO(0, context)
1139 : ZEND_ARG_INFO(0, raw_output)
1140 : ZEND_END_ARG_INFO()
1141 :
1142 : ZEND_BEGIN_ARG_INFO(arginfo_hash_copy, 0)
1143 : ZEND_ARG_INFO(0, context)
1144 : ZEND_END_ARG_INFO()
1145 :
1146 : ZEND_BEGIN_ARG_INFO(arginfo_hash_algos, 0)
1147 : ZEND_END_ARG_INFO()
1148 :
1149 : /* BC Land */
1150 : #ifdef PHP_MHASH_BC
1151 : ZEND_BEGIN_ARG_INFO(arginfo_mhash_get_block_size, 0)
1152 : ZEND_ARG_INFO(0, hash)
1153 : ZEND_END_ARG_INFO()
1154 :
1155 : ZEND_BEGIN_ARG_INFO(arginfo_mhash_get_hash_name, 0)
1156 : ZEND_ARG_INFO(0, hash)
1157 : ZEND_END_ARG_INFO()
1158 :
1159 : ZEND_BEGIN_ARG_INFO(arginfo_mhash_keygen_s2k, 0)
1160 : ZEND_ARG_INFO(0, hash)
1161 : ZEND_ARG_INFO(0, input_password)
1162 : ZEND_ARG_INFO(0, salt)
1163 : ZEND_ARG_INFO(0, bytes)
1164 : ZEND_END_ARG_INFO()
1165 :
1166 : ZEND_BEGIN_ARG_INFO(arginfo_mhash_count, 0)
1167 : ZEND_END_ARG_INFO()
1168 :
1169 : ZEND_BEGIN_ARG_INFO_EX(arginfo_mhash, 0, 0, 2)
1170 : ZEND_ARG_INFO(0, hash)
1171 : ZEND_ARG_INFO(0, data)
1172 : ZEND_ARG_INFO(0, key)
1173 : ZEND_END_ARG_INFO()
1174 : #endif
1175 :
1176 : # define PHP_HASH_FE(n) PHP_FE(n,arginfo_##n)
1177 : #else
1178 : # define PHP_HASH_FE(n) PHP_FE(n,NULL)
1179 : #endif
1180 : /* }}} */
1181 :
1182 : /* {{{ hash_functions[]
1183 : */
1184 : const zend_function_entry hash_functions[] = {
1185 : PHP_HASH_FE(hash)
1186 : PHP_HASH_FE(hash_file)
1187 :
1188 : PHP_HASH_FE(hash_hmac)
1189 : PHP_HASH_FE(hash_hmac_file)
1190 :
1191 : PHP_HASH_FE(hash_init)
1192 : PHP_HASH_FE(hash_update)
1193 : PHP_HASH_FE(hash_update_stream)
1194 : PHP_HASH_FE(hash_update_file)
1195 : PHP_HASH_FE(hash_final)
1196 : PHP_HASH_FE(hash_copy)
1197 :
1198 : PHP_HASH_FE(hash_algos)
1199 :
1200 : #ifdef PHP_MHASH_BC
1201 : PHP_FE(mhash_keygen_s2k, arginfo_mhash_keygen_s2k)
1202 : PHP_FE(mhash_get_block_size, arginfo_mhash_get_block_size)
1203 : PHP_FE(mhash_get_hash_name, arginfo_mhash_get_hash_name)
1204 : PHP_FE(mhash_count, arginfo_mhash_count)
1205 : PHP_FE(mhash, arginfo_mhash)
1206 : #endif
1207 :
1208 : {NULL, NULL, NULL}
1209 : };
1210 : /* }}} */
1211 :
1212 : /* {{{ hash_module_entry
1213 : */
1214 : zend_module_entry hash_module_entry = {
1215 : #if ZEND_MODULE_API_NO >= 20010901
1216 : STANDARD_MODULE_HEADER,
1217 : #endif
1218 : PHP_HASH_EXTNAME,
1219 : hash_functions,
1220 : PHP_MINIT(hash),
1221 : PHP_MSHUTDOWN(hash),
1222 : NULL, /* RINIT */
1223 : NULL, /* RSHUTDOWN */
1224 : PHP_MINFO(hash),
1225 : #if ZEND_MODULE_API_NO >= 20010901
1226 : PHP_HASH_EXTVER, /* Replace with version number for your extension */
1227 : #endif
1228 : STANDARD_MODULE_PROPERTIES
1229 : };
1230 : /* }}} */
1231 :
1232 : #ifdef COMPILE_DL_HASH
1233 : ZEND_GET_MODULE(hash)
1234 : #endif
1235 :
1236 : /*
1237 : * Local variables:
1238 : * tab-width: 4
1239 : * c-basic-offset: 4
1240 : * End:
1241 : * vim600: noet sw=4 ts=4 fdm=marker
1242 : * vim<600: noet sw=4 ts=4
1243 : */
|