"Fossies" - the Fresh Open Source Software Archive

Member "bind-9.16.7/lib/isc/hash.c" (4 Sep 2020, 4924 Bytes) of package /linux/misc/dns/bind9/9.16.7/bind-9.16.7.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "hash.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 9.17.3_vs_9.17.4.

    1 /*
    2  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
    3  *
    4  * This Source Code Form is subject to the terms of the Mozilla Public
    5  * License, v. 2.0. If a copy of the MPL was not distributed with this
    6  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
    7  *
    8  * See the COPYRIGHT file distributed with this work for additional
    9  * information regarding copyright ownership.
   10  */
   11 
   12 #include <inttypes.h>
   13 #include <stdbool.h>
   14 #include <stddef.h>
   15 #if defined(WIN32) || defined(WIN64)
   16 #include <malloc.h>
   17 #endif /* if defined(WIN32) || defined(WIN64) */
   18 
   19 #include "entropy_private.h"
   20 #include "isc/hash.h" /* IWYU pragma: keep */
   21 #include "isc/likely.h"
   22 #include "isc/once.h"
   23 #include "isc/random.h"
   24 #include "isc/result.h"
   25 #include "isc/siphash.h"
   26 #include "isc/string.h"
   27 #include "isc/types.h"
   28 #include "isc/util.h"
   29 
   30 static uint8_t isc_hash_key[16];
   31 static uint8_t isc_hash32_key[8];
   32 static bool hash_initialized = false;
   33 static isc_once_t isc_hash_once = ISC_ONCE_INIT;
   34 
   35 static void
   36 isc_hash_initialize(void) {
   37     /*
   38      * Set a constant key to help in problem reproduction should
   39      * fuzzing find a crash or a hang.
   40      */
   41     uint64_t key[2] = { 0, 1 };
   42 #if !FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
   43     isc_entropy_get(key, sizeof(key));
   44 #endif /* if FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */
   45     memmove(isc_hash_key, key, sizeof(isc_hash_key));
   46 #if !FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
   47     isc_entropy_get(key, sizeof(key));
   48 #endif /* if FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */
   49     memmove(isc_hash32_key, key, sizeof(isc_hash32_key));
   50     hash_initialized = true;
   51 }
   52 
   53 static uint8_t maptolower[] = {
   54     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
   55     0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
   56     0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
   57     0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
   58     0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
   59     0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
   60     0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73,
   61     0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
   62     0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
   63     0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
   64     0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83,
   65     0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
   66     0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b,
   67     0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
   68     0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3,
   69     0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
   70     0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb,
   71     0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
   72     0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3,
   73     0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
   74     0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb,
   75     0xfc, 0xfd, 0xfe, 0xff
   76 };
   77 
   78 const void *
   79 isc_hash_get_initializer(void) {
   80     if (ISC_UNLIKELY(!hash_initialized)) {
   81         RUNTIME_CHECK(
   82             isc_once_do(&isc_hash_once, isc_hash_initialize) ==
   83             ISC_R_SUCCESS);
   84     }
   85 
   86     return (isc_hash_key);
   87 }
   88 
   89 void
   90 isc_hash_set_initializer(const void *initializer) {
   91     REQUIRE(initializer != NULL);
   92 
   93     /*
   94      * Ensure that isc_hash_initialize() is not called after
   95      * isc_hash_set_initializer() is called.
   96      */
   97     if (ISC_UNLIKELY(!hash_initialized)) {
   98         RUNTIME_CHECK(
   99             isc_once_do(&isc_hash_once, isc_hash_initialize) ==
  100             ISC_R_SUCCESS);
  101     }
  102 
  103     memmove(isc_hash_key, initializer, sizeof(isc_hash_key));
  104 }
  105 
  106 uint64_t
  107 isc_hash64(const void *data, const size_t length, const bool case_sensitive) {
  108     uint64_t hval;
  109 
  110     REQUIRE(length == 0 || data != NULL);
  111 
  112     RUNTIME_CHECK(isc_once_do(&isc_hash_once, isc_hash_initialize) ==
  113               ISC_R_SUCCESS);
  114 
  115     if (case_sensitive) {
  116         isc_siphash24(isc_hash_key, data, length, (uint8_t *)&hval);
  117     } else {
  118         uint8_t input[1024];
  119         REQUIRE(length <= 1024);
  120         for (unsigned int i = 0; i < length; i++) {
  121             input[i] = maptolower[((const uint8_t *)data)[i]];
  122         }
  123         isc_siphash24(isc_hash_key, input, length, (uint8_t *)&hval);
  124     }
  125 
  126     return (hval);
  127 }
  128 
  129 uint32_t
  130 isc_hash32(const void *data, const size_t length, const bool case_sensitive) {
  131     uint32_t hval;
  132 
  133     REQUIRE(length == 0 || data != NULL);
  134 
  135     RUNTIME_CHECK(isc_once_do(&isc_hash_once, isc_hash_initialize) ==
  136               ISC_R_SUCCESS);
  137 
  138     if (case_sensitive) {
  139         isc_halfsiphash24(isc_hash_key, data, length, (uint8_t *)&hval);
  140     } else {
  141         uint8_t input[1024];
  142         REQUIRE(length <= 1024);
  143         for (unsigned int i = 0; i < length; i++) {
  144             input[i] = maptolower[((const uint8_t *)data)[i]];
  145         }
  146         isc_halfsiphash24(isc_hash_key, input, length,
  147                   (uint8_t *)&hval);
  148     }
  149 
  150     return (hval);
  151 }