diff options
Diffstat (limited to 'usr.bin/dig/lib/isc/hash.c')
| -rw-r--r-- | usr.bin/dig/lib/isc/hash.c | 270 |
1 files changed, 1 insertions, 269 deletions
diff --git a/usr.bin/dig/lib/isc/hash.c b/usr.bin/dig/lib/isc/hash.c index a92ece943fb..8e848f08ca6 100644 --- a/usr.bin/dig/lib/isc/hash.c +++ b/usr.bin/dig/lib/isc/hash.c @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: hash.c,v 1.1 2020/02/07 09:58:53 florian Exp $ */ +/* $Id: hash.c,v 1.2 2020/02/17 18:58:39 jung Exp $ */ /*! \file * Some portion of this code was derived from universal hash function @@ -91,8 +91,6 @@ struct isc_hash { hash_random_t *rndvector; /*%< random vector for universal hashing */ }; -static isc_hash_t *hash = NULL; - static unsigned char maptolower[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, @@ -128,202 +126,6 @@ static unsigned char maptolower[] = { 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff }; -isc_result_t -isc_hash_ctxcreate(size_t limit, isc_hash_t **hctxp) -{ - isc_result_t result; - isc_hash_t *hctx; - size_t vlen; - hash_random_t *rv; - hash_accum_t overflow_limit; - - REQUIRE(hctxp != NULL && *hctxp == NULL); - - /* - * Overflow check. Since our implementation only does a modulo - * operation at the last stage of hash calculation, the accumulator - * must not overflow. - */ - overflow_limit = - 1 << (((sizeof(hash_accum_t) - sizeof(hash_random_t))) * 8); - if (overflow_limit < (limit + 1) * 0xff) - return (ISC_R_RANGE); - - hctx = malloc(sizeof(isc_hash_t)); - if (hctx == NULL) - return (ISC_R_NOMEMORY); - - vlen = sizeof(hash_random_t) * (limit + 1); - rv = malloc(vlen); - if (rv == NULL) { - result = ISC_R_NOMEMORY; - goto errout; - } - - /* - * From here down, no failures will/can occur. - */ - hctx->magic = HASH_MAGIC; - hctx->initialized = ISC_FALSE; - result = isc_refcount_init(&hctx->refcnt, 1); - if (result != ISC_R_SUCCESS) - goto cleanup_lock; - hctx->limit = limit; - hctx->vectorlen = vlen; - hctx->rndvector = rv; - - *hctxp = hctx; - return (ISC_R_SUCCESS); - - cleanup_lock: - errout: - free(hctx); - if (rv != NULL) - free(rv); - - return (result); -} - -isc_result_t -isc_hash_create(size_t limit) { - isc_result_t result = ISC_R_SUCCESS; - - INSIST(hash == NULL); - - if (hash == NULL) - result = isc_hash_ctxcreate(limit, &hash); - - return (result); -} - -void -isc_hash_ctxinit(isc_hash_t *hctx) { - if (hctx->initialized == ISC_TRUE) - return - - arc4random_buf(hctx->rndvector, hctx->vectorlen); - hctx->initialized = ISC_TRUE; -} - -void -isc_hash_init(void) { - INSIST(hash != NULL && VALID_HASH(hash)); - - isc_hash_ctxinit(hash); -} - -void -isc_hash_ctxattach(isc_hash_t *hctx, isc_hash_t **hctxp) { - REQUIRE(VALID_HASH(hctx)); - REQUIRE(hctxp != NULL && *hctxp == NULL); - - isc_refcount_increment(&hctx->refcnt, NULL); - *hctxp = hctx; -} - -static void -destroy(isc_hash_t **hctxp) { - isc_hash_t *hctx; - - REQUIRE(hctxp != NULL && *hctxp != NULL); - hctx = *hctxp; - *hctxp = NULL; - - isc_refcount_destroy(&hctx->refcnt); - - if (hctx->rndvector != NULL) - free(hctx->rndvector); - - memset(hctx, 0, sizeof(isc_hash_t)); - free(hctx); -} - -void -isc_hash_ctxdetach(isc_hash_t **hctxp) { - isc_hash_t *hctx; - unsigned int refs; - - REQUIRE(hctxp != NULL && VALID_HASH(*hctxp)); - hctx = *hctxp; - - isc_refcount_decrement(&hctx->refcnt, &refs); - if (refs == 0) - destroy(&hctx); - - *hctxp = NULL; -} - -void -isc_hash_destroy(void) { - unsigned int refs; - - INSIST(hash != NULL && VALID_HASH(hash)); - - isc_refcount_decrement(&hash->refcnt, &refs); - INSIST(refs == 0); - - destroy(&hash); -} - -static inline unsigned int -hash_calc(isc_hash_t *hctx, const unsigned char *key, unsigned int keylen, - isc_boolean_t case_sensitive) -{ - hash_accum_t partial_sum = 0; - hash_random_t *p = hctx->rndvector; - unsigned int i = 0; - - /* Make it sure that the hash context is initialized. */ - if (hctx->initialized == ISC_FALSE) - isc_hash_ctxinit(hctx); - - if (case_sensitive) { - for (i = 0; i < keylen; i++) - partial_sum += key[i] * (hash_accum_t)p[i]; - } else { - for (i = 0; i < keylen; i++) - partial_sum += maptolower[key[i]] * (hash_accum_t)p[i]; - } - - partial_sum += p[i]; - - return ((unsigned int)(partial_sum % PRIME32)); -} - -unsigned int -isc_hash_ctxcalc(isc_hash_t *hctx, const unsigned char *key, - unsigned int keylen, isc_boolean_t case_sensitive) -{ - REQUIRE(hctx != NULL && VALID_HASH(hctx)); - REQUIRE(keylen <= hctx->limit); - - return (hash_calc(hctx, key, keylen, case_sensitive)); -} - -unsigned int -isc_hash_calc(const unsigned char *key, unsigned int keylen, - isc_boolean_t case_sensitive) -{ - INSIST(hash != NULL && VALID_HASH(hash)); - REQUIRE(keylen <= hash->limit); - - return (hash_calc(hash, key, keylen, case_sensitive)); -} - -void -isc__hash_setvec(const uint16_t *vec) { - int i; - hash_random_t *p; - - if (hash == NULL) - return; - - p = hash->rndvector; - for (i = 0; i < 256; i++) { - p[i] = vec[i]; - } -} - static uint32_t fnv_offset_basis; static isc_boolean_t fnv_once = ISC_FALSE; @@ -340,76 +142,6 @@ fnv_initialize(void) { } uint32_t -isc_hash_function(const void *data, size_t length, - isc_boolean_t case_sensitive, - const uint32_t *previous_hashp) -{ - uint32_t hval; - const unsigned char *bp; - const unsigned char *be; - - REQUIRE(length == 0 || data != NULL); - if (!fnv_once) { - fnv_once = ISC_TRUE; - fnv_initialize(); - } - - hval = previous_hashp != NULL ? - *previous_hashp : fnv_offset_basis; - - if (length == 0) - return (hval); - - bp = (const unsigned char *) data; - be = bp + length; - - /* - * Fowler-Noll-Vo FNV-1a hash function. - * - * NOTE: A random fnv_offset_basis is used by default to avoid - * collision attacks as the hash function is reversible. This - * makes the mapping non-deterministic, but the distribution in - * the domain is still uniform. - */ - - if (case_sensitive) { - while (bp < be - 4) { - hval ^= (uint32_t) bp[0]; - hval *= 16777619; - hval ^= (uint32_t) bp[1]; - hval *= 16777619; - hval ^= (uint32_t) bp[2]; - hval *= 16777619; - hval ^= (uint32_t) bp[3]; - hval *= 16777619; - bp += 4; - } - while (bp < be) { - hval ^= (uint32_t) *bp++; - hval *= 16777619; - } - } else { - while (bp < be - 4) { - hval ^= (uint32_t) maptolower[bp[0]]; - hval *= 16777619; - hval ^= (uint32_t) maptolower[bp[1]]; - hval *= 16777619; - hval ^= (uint32_t) maptolower[bp[2]]; - hval *= 16777619; - hval ^= (uint32_t) maptolower[bp[3]]; - hval *= 16777619; - bp += 4; - } - while (bp < be) { - hval ^= (uint32_t) maptolower[*bp++]; - hval *= 16777619; - } - } - - return (hval); -} - -uint32_t isc_hash_function_reverse(const void *data, size_t length, isc_boolean_t case_sensitive, const uint32_t *previous_hashp) |
