]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Implement incremental version of isc_hash32 and isc_hash64
authorOndřej Surý <ondrej@isc.org>
Fri, 8 Sep 2023 15:48:45 +0000 (17:48 +0200)
committerOndřej Surý <ondrej@isc.org>
Tue, 12 Sep 2023 14:17:06 +0000 (16:17 +0200)
Add support for incremental hashing to the isc_hash unit, both 32-bit
and 64-bit incremental hashing is now supported.

This is commit second in series adding incremental hashing to libisc.

lib/isc/hash.c
lib/isc/include/isc/hash.h
lib/isc/lib.c

index 1a28a216a70f2108c5749f95a2e704ac094ce5af..2783a37e4123c5b2a4ef9e1d6f2c9bf6183b6302 100644 (file)
@@ -18,7 +18,6 @@
 #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);
 }
 
@@ -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_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);
 }
index c3926157d07f852ef7489300bc532fdf97663493..bac9d9f7b8f90bb92a5816aaeb348e4d85732bd7 100644 (file)
@@ -18,6 +18,7 @@
 
 #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);
 
@@ -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.
  *
index aba5dc1db827aea69c8f7cb09e5a0114095fbc85..4fd65e602031d4c314f490bc3e66a33776b2c6f8 100644 (file)
@@ -13,6 +13,7 @@
 
 /*! \file */
 
+#include <isc/hash.h>
 #include <isc/iterated_hash.h>
 #include <isc/md.h>
 #include <isc/mem.h>
@@ -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();