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); }
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)); }