2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-25 11:38:29 +00:00
bind/lib/isc/hash.c

128 lines
3.2 KiB
C
Raw Normal View History

/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* SPDX-License-Identifier: MPL-2.0
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
#include <inttypes.h>
#include <stdbool.h>
#include <stddef.h>
#include "entropy_private.h"
#include "isc/ascii.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/string.h"
#include "isc/types.h"
#include "isc/util.h"
2020-02-13 14:44:37 -08:00
static uint8_t isc_hash_key[16];
static uint8_t isc_hash32_key[8];
2020-02-13 14:44:37 -08:00
static bool hash_initialized = false;
static isc_once_t isc_hash_once = ISC_ONCE_INIT;
static void
2020-02-13 14:44:37 -08:00
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 };
#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;
}
const void *
2020-02-13 14:44:37 -08:00
isc_hash_get_initializer(void) {
if (!hash_initialized) {
RUNTIME_CHECK(
isc_once_do(&isc_hash_once, isc_hash_initialize) ==
ISC_R_SUCCESS);
}
return (isc_hash_key);
}
void
2020-02-13 14:44:37 -08:00
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) {
RUNTIME_CHECK(
isc_once_do(&isc_hash_once, isc_hash_initialize) ==
ISC_R_SUCCESS);
}
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;
2015-12-09 19:07:20 +05:30
REQUIRE(length == 0 || data != NULL);
RUNTIME_CHECK(isc_once_do(&isc_hash_once, isc_hash_initialize) ==
ISC_R_SUCCESS);
2015-12-09 19:07:20 +05:30
if (case_sensitive) {
isc_siphash24(isc_hash_key, data, length, (uint8_t *)&hval);
2015-12-09 19:07:20 +05:30
} else {
const uint8_t *byte = data;
uint8_t lower[1024];
REQUIRE(length <= 1024);
for (unsigned i = 0; i < length; i++) {
lower[i] = isc_ascii_tolower(byte[i]);
2015-12-09 19:07:20 +05:30
}
isc_siphash24(isc_hash_key, lower, length, (uint8_t *)&hval);
2015-12-09 19:07:20 +05:30
}
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 {
const uint8_t *byte = data;
uint8_t lower[1024];
REQUIRE(length <= 1024);
for (unsigned i = 0; i < length; i++) {
lower[i] = isc_ascii_tolower(byte[i]);
}
isc_halfsiphash24(isc_hash_key, lower, length,
(uint8_t *)&hval);
}
return (hval);
}