1 1.9 christos /* $NetBSD: hash.c,v 1.10 2026/01/29 18:37:54 christos Exp $ */ 2 1.1 christos 3 1.1 christos /* 4 1.1 christos * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 5 1.1 christos * 6 1.7 christos * SPDX-License-Identifier: MPL-2.0 7 1.7 christos * 8 1.1 christos * This Source Code Form is subject to the terms of the Mozilla Public 9 1.1 christos * License, v. 2.0. If a copy of the MPL was not distributed with this 10 1.6 christos * file, you can obtain one at https://mozilla.org/MPL/2.0/. 11 1.1 christos * 12 1.1 christos * See the COPYRIGHT file distributed with this work for additional 13 1.1 christos * information regarding copyright ownership. 14 1.1 christos */ 15 1.1 christos 16 1.5 christos #include <inttypes.h> 17 1.3 christos #include <stdbool.h> 18 1.3 christos #include <stddef.h> 19 1.3 christos 20 1.9 christos #include <isc/ascii.h> 21 1.9 christos #include <isc/hash.h> /* IWYU pragma: keep */ 22 1.9 christos #include <isc/random.h> 23 1.9 christos #include <isc/result.h> 24 1.9 christos #include <isc/siphash.h> 25 1.9 christos #include <isc/string.h> 26 1.9 christos #include <isc/types.h> 27 1.9 christos #include <isc/util.h> 28 1.1 christos 29 1.4 christos static uint8_t isc_hash_key[16]; 30 1.4 christos 31 1.9 christos void 32 1.9 christos isc__hash_initialize(void) { 33 1.4 christos /* 34 1.4 christos * Set a constant key to help in problem reproduction should 35 1.4 christos * fuzzing find a crash or a hang. 36 1.4 christos */ 37 1.9 christos uint8_t key[16] = { 1 }; 38 1.6 christos #if !FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION 39 1.10 christos isc_random_buf(key, sizeof(key)); 40 1.5 christos #endif /* if FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ 41 1.9 christos STATIC_ASSERT(sizeof(key) >= sizeof(isc_hash_key), 42 1.9 christos "sizeof(key) < sizeof(isc_hash_key)"); 43 1.4 christos memmove(isc_hash_key, key, sizeof(isc_hash_key)); 44 1.4 christos } 45 1.4 christos 46 1.1 christos const void * 47 1.1 christos isc_hash_get_initializer(void) { 48 1.9 christos return isc_hash_key; 49 1.1 christos } 50 1.1 christos 51 1.1 christos void 52 1.1 christos isc_hash_set_initializer(const void *initializer) { 53 1.1 christos REQUIRE(initializer != NULL); 54 1.1 christos 55 1.4 christos memmove(isc_hash_key, initializer, sizeof(isc_hash_key)); 56 1.1 christos } 57 1.1 christos 58 1.9 christos void 59 1.9 christos isc_hash32_init(isc_hash32_t *restrict state) { 60 1.9 christos isc_halfsiphash24_init(state, isc_hash_key); 61 1.9 christos } 62 1.1 christos 63 1.9 christos void 64 1.9 christos isc_hash32_hash(isc_hash32_t *restrict state, const void *data, 65 1.9 christos const size_t length, const bool case_sensitive) { 66 1.1 christos REQUIRE(length == 0 || data != NULL); 67 1.1 christos 68 1.9 christos isc_halfsiphash24_hash(state, data, length, case_sensitive); 69 1.9 christos } 70 1.9 christos 71 1.9 christos uint32_t 72 1.9 christos isc_hash32_finalize(isc_hash32_t *restrict state) { 73 1.9 christos uint32_t hval; 74 1.1 christos 75 1.9 christos isc_halfsiphash24_finalize(state, (uint8_t *)&hval); 76 1.1 christos 77 1.9 christos return hval; 78 1.1 christos } 79 1.6 christos 80 1.9 christos void 81 1.9 christos isc_hash64_init(isc_hash64_t *restrict state) { 82 1.9 christos isc_siphash24_init(state, isc_hash_key); 83 1.9 christos } 84 1.6 christos 85 1.9 christos void 86 1.9 christos isc_hash64_hash(isc_hash64_t *restrict state, const void *data, 87 1.9 christos const size_t length, const bool case_sensitive) { 88 1.6 christos REQUIRE(length == 0 || data != NULL); 89 1.6 christos 90 1.9 christos isc_siphash24_hash(state, data, length, case_sensitive); 91 1.9 christos } 92 1.9 christos 93 1.9 christos uint64_t 94 1.9 christos isc_hash64_finalize(isc_hash64_t *restrict state) { 95 1.9 christos uint64_t hval; 96 1.6 christos 97 1.9 christos isc_siphash24_finalize(state, (uint8_t *)&hval); 98 1.6 christos 99 1.9 christos return hval; 100 1.6 christos } 101