#include <isc/ascii.h>
#include <isc/entropy.h>
#include <isc/hash.h> /* IWYU pragma: keep */
-#include <isc/once.h>
#include <isc/random.h>
#include <isc/result.h>
#include <isc/siphash.h>
#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) {
+void
+isc__hash_initialize(void) {
/*
* Set a constant key to help in problem reproduction should
* fuzzing find a crash or a hang.
*/
- uint64_t key[2] = { 0, 1 };
+ uint8_t key[16] = { 1 };
#if !FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
isc_entropy_get(key, sizeof(key));
#endif /* if FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */
+ STATIC_ASSERT(sizeof(key) >= sizeof(isc_hash_key),
+ "sizeof(key) < sizeof(isc_hash_key)");
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;
}
const void *
isc_hash_get_initializer(void) {
- if (!hash_initialized) {
- isc_once_do(&isc_hash_once, isc_hash_initialize);
- }
-
return (isc_hash_key);
}
isc_hash_set_initializer(const void *initializer) {
REQUIRE(initializer != NULL);
- /*
- * Ensure that isc_hash_initialize() is not called after
- * isc_hash_set_initializer() is called.
- */
- if (!hash_initialized) {
- isc_once_do(&isc_hash_once, isc_hash_initialize);
- }
-
memmove(isc_hash_key, initializer, sizeof(isc_hash_key));
}
-uint64_t
-isc_hash64(const void *data, const size_t length, const bool case_sensitive) {
- uint64_t hval;
+void
+isc_hash32_init(isc_hash32_t *restrict state) {
+ isc_halfsiphash24_init(state, isc_hash_key);
+}
+void
+isc_hash32_hash(isc_hash32_t *restrict state, const void *data,
+ const size_t length, const bool case_sensitive) {
REQUIRE(length == 0 || data != NULL);
- isc_once_do(&isc_hash_once, isc_hash_initialize);
+ isc_halfsiphash24_hash(state, data, length, case_sensitive);
+}
+
+uint32_t
+isc_hash32_finalize(isc_hash32_t *restrict state) {
+ uint32_t hval;
- isc_siphash24(isc_hash_key, data, length, case_sensitive,
- (uint8_t *)&hval);
+ isc_halfsiphash24_finalize(state, (uint8_t *)&hval);
return (hval);
}
-uint32_t
-isc_hash32(const void *data, const size_t length, const bool case_sensitive) {
- uint32_t hval;
+void
+isc_hash64_init(isc_hash64_t *restrict state) {
+ isc_siphash24_init(state, isc_hash_key);
+}
+void
+isc_hash64_hash(isc_hash64_t *restrict state, const void *data,
+ const size_t length, const bool case_sensitive) {
REQUIRE(length == 0 || data != NULL);
- isc_once_do(&isc_hash_once, isc_hash_initialize);
+ isc_siphash24_hash(state, data, length, case_sensitive);
+}
+
+uint64_t
+isc_hash64_finalize(isc_hash64_t *restrict state) {
+ uint64_t hval;
- isc_halfsiphash24(isc_hash_key, data, length, case_sensitive,
- (uint8_t *)&hval);
+ isc_siphash24_finalize(state, (uint8_t *)&hval);
return (hval);
}
#include <isc/assertions.h>
#include <isc/lang.h>
+#include <isc/siphash.h>
#include <isc/types.h>
#include <isc/util.h>
#define ISC_HASH_MIN_BITS 2U
#define ISC_HASH_MAX_BITS 32U
+typedef struct isc_halfsiphash24 isc_hash32_t;
+typedef struct isc_siphash24 isc_hash64_t;
+
/***
*** Functions
***/
ISC_LANG_BEGINDECLS
+void
+isc__hash_initialize(void);
+
const void *
isc_hash_get_initializer(void);
#define isc_hash_function isc_hash64
+void
+isc_hash32_init(isc_hash32_t *restrict state);
+void
+isc_hash32_hash(isc_hash32_t *restrict state, const void *data,
+ const size_t length, const bool case_sensitive);
uint32_t
-isc_hash32(const void *data, const size_t length, const bool case_sensitive);
+isc_hash32_finalize(isc_hash32_t *restrict state);
+static inline uint32_t
+isc_hash32(const void *data, const size_t length, const bool case_sensitive) {
+ isc_hash32_t state;
+ isc_hash32_init(&state);
+ isc_hash32_hash(&state, data, length, case_sensitive);
+ return (isc_hash32_finalize(&state));
+}
+
+void
+isc_hash64_init(isc_hash64_t *restrict state);
+void
+isc_hash64_hash(isc_hash64_t *restrict state, const void *data,
+ const size_t length, const bool case_sensitive);
uint64_t
-isc_hash64(const void *data, const size_t length, const bool case_sensitive);
+isc_hash64_finalize(isc_hash64_t *restrict state);
+static inline uint64_t
+isc_hash64(const void *data, const size_t length, const bool case_sensitive) {
+ isc_hash64_t state;
+ isc_hash64_init(&state);
+ isc_hash64_hash(&state, data, length, case_sensitive);
+ return (isc_hash64_finalize(&state));
+}
/*!<
* \brief Calculate a hash over data.
*