From ebb2b055cc95ac1bdfd5eea075b62dc4c3f056cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= Date: Thu, 16 Jul 2020 17:29:44 +0200 Subject: [PATCH] Add isc_hash32() and rename isc_hash_function() to isc_hash64() As the names suggest the original isc_hash64 function returns 64-bit long hash values and the isc_hash32() returns 32-bit values. (cherry picked from commit f59fd49fd88e6efa966fd9c91a6ad319e1388679) --- lib/isc/hash.c | 41 +++++++++++++++++++++++++++++-------- lib/isc/include/isc/hash.h | 14 +++++++------ lib/isc/win32/libisc.def.in | 3 ++- 3 files changed, 42 insertions(+), 16 deletions(-) diff --git a/lib/isc/hash.c b/lib/isc/hash.c index b00cd148cf..8ef93f5f94 100644 --- a/lib/isc/hash.c +++ b/lib/isc/hash.c @@ -9,10 +9,6 @@ * information regarding copyright ownership. */ -/* - * 32 bit Fowler/Noll/Vo FNV-1a hash code with modification for BIND - */ - #include #include #include @@ -32,21 +28,25 @@ #include "isc/util.h" static uint8_t isc_hash_key[16]; +static uint8_t isc_hash32_key[8]; static bool hash_initialized = false; static isc_once_t isc_hash_once = ISC_ONCE_INIT; static void isc_hash_initialize(void) { - uint64_t key[2] = { 0, 1 }; -#if FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION /* * Set a constant key to help in problem reproduction should * fuzzing find a crash or a hang. */ -#else /* if FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ + uint64_t key[2] = { 0, 1 }; +#if !FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION isc_entropy_get(key, sizeof(key)); #endif /* if FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ memmove(isc_hash_key, key, sizeof(isc_hash_key)); +#if !FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + isc_entropy_get(key, sizeof(key)); +#endif /* if FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ + memmove(isc_hash32_key, key, sizeof(isc_hash32_key)); hash_initialized = true; } @@ -104,8 +104,7 @@ isc_hash_set_initializer(const void *initializer) { } uint64_t -isc_hash_function(const void *data, const size_t length, - const bool case_sensitive) { +isc_hash64(const void *data, const size_t length, const bool case_sensitive) { uint64_t hval; REQUIRE(length == 0 || data != NULL); @@ -126,3 +125,27 @@ isc_hash_function(const void *data, const size_t length, return (hval); } + +uint32_t +isc_hash32(const void *data, const size_t length, const bool case_sensitive) { + uint32_t hval; + + REQUIRE(length == 0 || data != NULL); + + RUNTIME_CHECK(isc_once_do(&isc_hash_once, isc_hash_initialize) == + ISC_R_SUCCESS); + + if (case_sensitive) { + isc_halfsiphash24(isc_hash_key, data, length, (uint8_t *)&hval); + } else { + uint8_t input[1024]; + REQUIRE(length <= 1024); + for (unsigned int i = 0; i < length; i++) { + input[i] = maptolower[((const uint8_t *)data)[i]]; + } + isc_halfsiphash24(isc_hash_key, input, length, + (uint8_t *)&hval); + } + + return (hval); +} diff --git a/lib/isc/include/isc/hash.h b/lib/isc/include/isc/hash.h index 3989d0449e..e2d36e1807 100644 --- a/lib/isc/include/isc/hash.h +++ b/lib/isc/include/isc/hash.h @@ -29,9 +29,12 @@ isc_hash_get_initializer(void); void isc_hash_set_initializer(const void *initializer); +#define isc_hash_function isc_hash64 + +uint32_t +isc_hash32(const void *data, const size_t length, const bool case_sensitive); uint64_t -isc_hash_function(const void *data, const size_t length, - const bool case_sensitive); +isc_hash64(const void *data, const size_t length, const bool case_sensitive); /*!< * \brief Calculate a hash over data. * @@ -41,7 +44,7 @@ isc_hash_function(const void *data, const size_t length, * process using this library is run, but will have uniform * distribution. * - * isc_hash_function() calculates the hash from start to end over the + * isc_hash_32/64() calculates the hash from start to end over the * input data. * * 'data' is the data to be hashed. @@ -52,9 +55,8 @@ isc_hash_function(const void *data, const size_t length, * case_sensitive values. It should typically be false if the hash key * is a DNS name. * - * WARNING: In case of case insensitive input, the input buffer cannot - * be longer than 1024, which should be fine, as it is only used for - * DNS names. + * Returns: + * \li 32 or 64-bit hash value */ ISC_LANG_ENDDECLS diff --git a/lib/isc/win32/libisc.def.in b/lib/isc/win32/libisc.def.in index a1f2e961d9..8e948420df 100644 --- a/lib/isc/win32/libisc.def.in +++ b/lib/isc/win32/libisc.def.in @@ -238,7 +238,8 @@ isc_fsaccess_add isc_fsaccess_changeowner isc_fsaccess_remove isc_fsaccess_set -isc_hash_function +isc_hash32 +isc_hash64 isc_hash_get_initializer isc_hash_set_initializer isc_heap_create