static void php_hash_do_hash(INTERNAL_FUNCTION_PARAMETERS, int isfilename, zend_bool raw_output_default) /* {{{ */ { char *algo, *data, *digest; int algo_len, data_len; zend_bool raw_output = raw_output_default; const php_hash_ops *ops; void *context; php_stream *stream = NULL; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|b", &algo, &algo_len, &data, &data_len, &raw_output) == FAILURE) { return; } ops = php_hash_fetch_ops(algo, algo_len); if (!ops) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown hashing algorithm: %s", algo); RETURN_FALSE; } if (isfilename) { if (CHECK_NULL_PATH(data, data_len)) { RETURN_FALSE; } stream = php_stream_open_wrapper_ex(data, "rb", REPORT_ERRORS, NULL, DEFAULT_CONTEXT); if (!stream) { /* Stream will report errors opening file */ RETURN_FALSE; } } context = emalloc(ops->context_size); ops->hash_init(context); if (isfilename) { char buf[1024]; int n; while ((n = php_stream_read(stream, buf, sizeof(buf))) > 0) { ops->hash_update(context, (unsigned char *) buf, n); } php_stream_close(stream); } else { ops->hash_update(context, (unsigned char *) data, data_len); } digest = emalloc(ops->digest_size + 1); ops->hash_final((unsigned char *) digest, context); efree(context); if (raw_output) { digest[ops->digest_size] = 0; RETURN_STRINGL(digest, ops->digest_size, 0); } else { char *hex_digest = safe_emalloc(ops->digest_size, 2, 1); php_hash_bin2hex(hex_digest, (unsigned char *) digest, ops->digest_size); hex_digest[2 * ops->digest_size] = 0; efree(digest); RETURN_STRINGL(hex_digest, 2 * ops->digest_size, 0); } }
static Variant php_hash_do_hash_hmac(CStrRef algo, CStrRef data, bool isfilename, CStrRef key, bool raw_output /* = false */) { HashEnginePtr ops = php_hash_fetch_ops(algo); if (!ops) { raise_warning("Unknown hashing algorithm: %s", algo.data()); return false; } Variant f; if (isfilename) { f = f_fopen(data, "rb"); if (same(f, false)) { return false; } } void *context = malloc(ops->context_size); ops->hash_init(context); char *K = prepare_hmac_key(ops, context, key); if (isfilename) { for (Variant chunk = f_fread(f, 1024); !is_empty_string(chunk); chunk = f_fread(f, 1024)) { String schunk = chunk.toString(); ops->hash_update(context, (unsigned char *)schunk.data(), schunk.size()); } } else { ops->hash_update(context, (unsigned char *)data.data(), data.size()); } String raw = String(ops->digest_size, ReserveString); char *digest = raw.mutableSlice().ptr; ops->hash_final((unsigned char *)digest, context); finalize_hmac_key(K, ops, context, digest); free(context); raw.setSize(ops->digest_size); if (raw_output) { return raw; } return StringUtil::HexEncode(raw); }
static Variant php_hash_do_hash(const String& algo, const String& data, bool isfilename, bool raw_output) { HashEnginePtr ops = php_hash_fetch_ops(algo); if (!ops) { raise_warning("Unknown hashing algorithm: %s", algo.data()); return false; } Variant f; if (isfilename) { f = HHVM_FN(fopen)(data, "rb"); if (same(f, false)) { return false; } } void *context = malloc(ops->context_size); ops->hash_init(context); if (isfilename) { for (Variant chunk = HHVM_FN(fread)(f.toResource(), 1024); !is_empty_string(chunk); chunk = HHVM_FN(fread)(f.toResource(), 1024)) { String schunk = chunk.toString(); ops->hash_update(context, (unsigned char *)schunk.data(), schunk.size()); } } else { ops->hash_update(context, (unsigned char *)data.data(), data.size()); } String raw = String(ops->digest_size, ReserveString); char *digest = raw.mutableData(); ops->hash_final((unsigned char *)digest, context); free(context); raw.setSize(ops->digest_size); if (raw_output) { return raw; } return HHVM_FN(bin2hex)(raw); }
Variant f_hash_init(CStrRef algo, int options /* = 0 */, CStrRef key /* = null_string */) { HashEnginePtr ops = php_hash_fetch_ops(algo); if (!ops) { raise_warning("Unknown hashing algorithm: %s", algo.data()); return false; } if ((options & k_HASH_HMAC) && key.empty()) { raise_warning("HMAC requested without a key"); return false; } void *context = malloc(ops->context_size); ops->hash_init(context); HashContext *hash = new HashContext(ops, context, options); if (options & k_HASH_HMAC) { hash->key = prepare_hmac_key(ops, context, key); } return Object(hash); }
Variant HHVM_FUNCTION(hash_init, const String& algo, int64_t options /* = 0 */, const String& key /* = null_string */) { HashEnginePtr ops = php_hash_fetch_ops(algo); if (!ops) { raise_warning("Unknown hashing algorithm: %s", algo.data()); return false; } if ((options & k_HASH_HMAC) && key.empty()) { raise_warning("HMAC requested without a key"); return false; } void *context = malloc(ops->context_size); ops->hash_init(context); const auto hash = req::make<HashContext>(ops, context, options); if (options & k_HASH_HMAC) { hash->key = prepare_hmac_key(ops, context, key); } return Variant(std::move(hash)); }
static void php_hash_do_hash(INTERNAL_FUNCTION_PARAMETERS, int isfilename, zend_bool raw_output_default) /* {{{ */ { zend_string *digest; char *algo, *data; size_t algo_len, data_len; zend_bool raw_output = raw_output_default; const php_hash_ops *ops; void *context; php_stream *stream = NULL; if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss|b", &algo, &algo_len, &data, &data_len, &raw_output) == FAILURE) { return; } ops = php_hash_fetch_ops(algo, algo_len); if (!ops) { php_error_docref(NULL, E_WARNING, "Unknown hashing algorithm: %s", algo); RETURN_FALSE; } if (isfilename) { if (CHECK_NULL_PATH(data, data_len)) { php_error_docref(NULL, E_WARNING, "Invalid path"); RETURN_FALSE; } stream = php_stream_open_wrapper_ex(data, "rb", REPORT_ERRORS, NULL, FG(default_context)); if (!stream) { /* Stream will report errors opening file */ RETURN_FALSE; } } context = emalloc(ops->context_size); ops->hash_init(context); if (isfilename) { char buf[1024]; size_t n; while ((n = php_stream_read(stream, buf, sizeof(buf))) > 0) { ops->hash_update(context, (unsigned char *) buf, n); } php_stream_close(stream); } else { ops->hash_update(context, (unsigned char *) data, data_len); } digest = zend_string_alloc(ops->digest_size, 0); ops->hash_final((unsigned char *) ZSTR_VAL(digest), context); efree(context); if (raw_output) { ZSTR_VAL(digest)[ops->digest_size] = 0; RETURN_NEW_STR(digest); } else { zend_string *hex_digest = zend_string_safe_alloc(ops->digest_size, 2, 0, 0); php_hash_bin2hex(ZSTR_VAL(hex_digest), (unsigned char *) ZSTR_VAL(digest), ops->digest_size); ZSTR_VAL(hex_digest)[2 * ops->digest_size] = 0; zend_string_release(digest); RETURN_NEW_STR(hex_digest); } }
static void php_hash_do_hash_hmac(INTERNAL_FUNCTION_PARAMETERS, int isfilename, zend_bool raw_output_default) /* {{{ */ { char *algo, *data, *digest, *key, *K; int algo_len, data_len, key_len, i; zend_bool raw_output = raw_output_default; const php_hash_ops *ops; void *context; php_stream *stream = NULL; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss|b", &algo, &algo_len, &data, &data_len, &key, &key_len, &raw_output) == FAILURE) { return; } ops = php_hash_fetch_ops(algo, algo_len); if (!ops) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown hashing algorithm: %s", algo); RETURN_FALSE; } if (isfilename) { stream = php_stream_open_wrapper_ex(data, "rb", REPORT_ERRORS, NULL, DEFAULT_CONTEXT); if (!stream) { /* Stream will report errors opening file */ RETURN_FALSE; } } context = emalloc(ops->context_size); ops->hash_init(context); K = emalloc(ops->block_size); memset(K, 0, ops->block_size); if (key_len > ops->block_size) { /* Reduce the key first */ ops->hash_update(context, (unsigned char *) key, key_len); ops->hash_final((unsigned char *) K, context); /* Make the context ready to start over */ ops->hash_init(context); } else { memcpy(K, key, key_len); } /* XOR ipad */ for(i=0; i < ops->block_size; i++) { K[i] ^= 0x36; } ops->hash_update(context, (unsigned char *) K, ops->block_size); if (isfilename) { char buf[1024]; int n; while ((n = php_stream_read(stream, buf, sizeof(buf))) > 0) { ops->hash_update(context, (unsigned char *) buf, n); } php_stream_close(stream); } else { ops->hash_update(context, (unsigned char *) data, data_len); } digest = emalloc(ops->digest_size + 1); ops->hash_final((unsigned char *) digest, context); /* Convert K to opad -- 0x6A = 0x36 ^ 0x5C */ for(i=0; i < ops->block_size; i++) { K[i] ^= 0x6A; } /* Feed this result into the outter hash */ ops->hash_init(context); ops->hash_update(context, (unsigned char *) K, ops->block_size); ops->hash_update(context, (unsigned char *) digest, ops->digest_size); ops->hash_final((unsigned char *) digest, context); /* Zero the key */ memset(K, 0, ops->block_size); efree(K); efree(context); if (raw_output) { digest[ops->digest_size] = 0; RETURN_STRINGL(digest, ops->digest_size, 0); } else { char *hex_digest = safe_emalloc(ops->digest_size, 2, 1); php_hash_bin2hex(hex_digest, (unsigned char *) digest, ops->digest_size); hex_digest[2 * ops->digest_size] = 0; efree(digest); RETURN_STRINGL(hex_digest, 2 * ops->digest_size, 0); } }
static void php_hash_do_hash_hmac(INTERNAL_FUNCTION_PARAMETERS, int isfilename, zend_bool raw_output_default) /* {{{ */ { char *algo, *data, *digest, *key, *K; int algo_len, data_len, key_len, i; zend_uchar data_type = IS_STRING, key_type = IS_STRING; zend_bool raw_output = raw_output_default; const php_hash_ops *ops; void *context; php_stream *stream = NULL; #if PHP_MAJOR_VERSION >= 6 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) { return; } if (data_type == IS_UNICODE) { if (isfilename) { if (php_stream_path_encode(NULL, &data, &data_len, (UChar *)data, data_len, REPORT_ERRORS, FG(default_context)) == FAILURE) { RETURN_FALSE; } } else { data = zend_unicode_to_ascii((UChar*)data, data_len TSRMLS_CC); if (!data) { /* Non-ASCII Unicode string passed for raw hashing */ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Binary or ASCII-Unicode string expected, non-ASCII-Unicode string received"); RETURN_FALSE; } } } if (key_type == IS_UNICODE) { key = zend_unicode_to_ascii((UChar*)key, key_len TSRMLS_CC); if (!key) { /* Non-ASCII Unicode key passed for raw hashing */ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Binary or ASCII-Unicode key expected, non-ASCII-Unicode key received"); if (data_type == IS_UNICODE) { efree(data); } RETURN_FALSE; } } #else if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss|b", &algo, &algo_len, &data, &data_len, &key, &key_len, &raw_output) == FAILURE) { return; } #endif /* Assume failure */ RETVAL_FALSE; ops = php_hash_fetch_ops(algo, algo_len); if (!ops) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown hashing algorithm: %s", algo); goto hmac_done; } if (isfilename) { stream = php_stream_open_wrapper_ex(data, "rb", REPORT_ERRORS, NULL, DEFAULT_CONTEXT); if (!stream) { /* Stream will report errors opening file */ goto hmac_done; } } context = emalloc(ops->context_size); ops->hash_init(context); K = emalloc(ops->block_size); memset(K, 0, ops->block_size); if (key_len > ops->block_size) { /* Reduce the key first */ ops->hash_update(context, (unsigned char *) key, key_len); ops->hash_final((unsigned char *) K, context); /* Make the context ready to start over */ ops->hash_init(context); } else { memcpy(K, key, key_len); } /* XOR ipad */ for(i=0; i < ops->block_size; i++) { K[i] ^= 0x36; } ops->hash_update(context, (unsigned char *) K, ops->block_size); if (isfilename) { char buf[1024]; int n; while ((n = php_stream_read(stream, buf, sizeof(buf))) > 0) { ops->hash_update(context, (unsigned char *) buf, n); } php_stream_close(stream); } else { ops->hash_update(context, (unsigned char *) data, data_len); } digest = emalloc(ops->digest_size + 1); ops->hash_final((unsigned char *) digest, context); /* Convert K to opad -- 0x6A = 0x36 ^ 0x5C */ for(i=0; i < ops->block_size; i++) { K[i] ^= 0x6A; } /* Feed this result into the outter hash */ ops->hash_init(context); ops->hash_update(context, (unsigned char *) K, ops->block_size); ops->hash_update(context, (unsigned char *) digest, ops->digest_size); ops->hash_final((unsigned char *) digest, context); /* Zero the key */ memset(K, 0, ops->block_size); efree(K); efree(context); if (raw_output) { digest[ops->digest_size] = 0; /* Raw output is binary only */ RETVAL_STRINGL(digest, ops->digest_size, 0); } else { char *hex_digest = safe_emalloc(ops->digest_size, 2, 1); php_hash_bin2hex(hex_digest, (unsigned char *) digest, ops->digest_size); hex_digest[2 * ops->digest_size] = 0; efree(digest); /* hexits can be binary or unicode */ #if PHP_MAJOR_VERSION >= 6 RETVAL_RT_STRINGL(hex_digest, 2 * ops->digest_size, ZSTR_AUTOFREE); #else RETVAL_STRINGL(hex_digest, 2 * ops->digest_size, 0); #endif } hmac_done: if (data_type != IS_STRING) { efree(data); } if (key_type != IS_STRING) { efree(key); } }
static void php_hash_do_hash(INTERNAL_FUNCTION_PARAMETERS, int isfilename, zend_bool raw_output_default) /* {{{ */ { char *algo, *data, *digest; int algo_len, data_len; zend_uchar data_type = IS_STRING; zend_bool raw_output = raw_output_default; const php_hash_ops *ops; void *context; php_stream *stream = NULL; #if PHP_MAJOR_VERSION >= 6 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "st|b", &algo, &algo_len, &data, &data_len, &data_type, &raw_output) == FAILURE) { return; } if (data_type == IS_UNICODE) { if (isfilename) { if (php_stream_path_encode(NULL, &data, &data_len, (UChar *)data, data_len, REPORT_ERRORS, FG(default_context)) == FAILURE) { RETURN_FALSE; } } else { data = zend_unicode_to_ascii((UChar*)data, data_len TSRMLS_CC); if (!data) { /* Non-ASCII Unicode string passed for raw hashing */ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Binary or ASCII-Unicode string expected, non-ASCII-Unicode string received"); RETURN_FALSE; } } } #else if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|b", &algo, &algo_len, &data, &data_len, &raw_output) == FAILURE) { return; } #endif /* Assume failure */ RETVAL_FALSE; ops = php_hash_fetch_ops(algo, algo_len); if (!ops) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown hashing algorithm: %s", algo); goto hash_done; } if (isfilename) { stream = php_stream_open_wrapper_ex(data, "rb", REPORT_ERRORS, NULL, DEFAULT_CONTEXT); if (!stream) { /* Stream will report errors opening file */ goto hash_done; } } context = emalloc(ops->context_size); ops->hash_init(context); if (isfilename) { char buf[1024]; int n; while ((n = php_stream_read(stream, buf, sizeof(buf))) > 0) { ops->hash_update(context, (unsigned char *) buf, n); } php_stream_close(stream); } else { ops->hash_update(context, (unsigned char *) data, data_len); } digest = emalloc(ops->digest_size + 1); ops->hash_final((unsigned char *) digest, context); efree(context); if (raw_output) { digest[ops->digest_size] = 0; /* Raw output is binary only */ RETVAL_STRINGL(digest, ops->digest_size, 0); } else { char *hex_digest = safe_emalloc(ops->digest_size, 2, 1); php_hash_bin2hex(hex_digest, (unsigned char *) digest, ops->digest_size); hex_digest[2 * ops->digest_size] = 0; efree(digest); /* hexits can be binary or unicode */ #if PHP_MAJOR_VERSION >= 6 RETVAL_RT_STRINGL(hex_digest, 2 * ops->digest_size, ZSTR_AUTOFREE); #else RETVAL_STRINGL(hex_digest, 2 * ops->digest_size, 0); #endif } hash_done: if (data_type != IS_STRING) { efree(data); } }