diff --git a/lib/isc/hash.c b/lib/isc/hash.c index 1a28a216a7..2783a37e41 100644 --- a/lib/isc/hash.c +++ b/lib/isc/hash.c @@ -18,7 +18,6 @@ #include #include #include /* IWYU pragma: keep */ -#include #include #include #include @@ -27,34 +26,24 @@ #include 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); } @@ -62,41 +51,49 @@ void 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_siphash24(isc_hash_key, data, length, case_sensitive, - (uint8_t *)&hval); - - return (hval); + isc_halfsiphash24_hash(state, data, length, 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) { uint32_t hval; - REQUIRE(length == 0 || data != NULL); - - isc_once_do(&isc_hash_once, isc_hash_initialize); - - isc_halfsiphash24(isc_hash_key, data, length, case_sensitive, - (uint8_t *)&hval); + isc_halfsiphash24_finalize(state, (uint8_t *)&hval); + + return (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_siphash24_hash(state, data, length, case_sensitive); +} + +uint64_t +isc_hash64_finalize(isc_hash64_t *restrict state) { + uint64_t hval; + + isc_siphash24_finalize(state, (uint8_t *)&hval); return (hval); } diff --git a/lib/isc/include/isc/hash.h b/lib/isc/include/isc/hash.h index c3926157d0..bac9d9f7b8 100644 --- a/lib/isc/include/isc/hash.h +++ b/lib/isc/include/isc/hash.h @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -26,11 +27,17 @@ #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); @@ -39,10 +46,35 @@ isc_hash_set_initializer(const void *initializer); #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. * diff --git a/lib/isc/lib.c b/lib/isc/lib.c index aba5dc1db8..4fd65e6020 100644 --- a/lib/isc/lib.c +++ b/lib/isc/lib.c @@ -13,6 +13,7 @@ /*! \file */ +#include #include #include #include @@ -50,6 +51,7 @@ isc__initialize(void) { isc__uv_initialize(); isc__xml_initialize(); isc__md_initialize(); + isc__hash_initialize(); isc__iterated_hash_initialize(); (void)isc_os_ncpus(); rcu_register_thread();