diff options
Diffstat (limited to 'lib/isc/include/isc/hash.h')
-rw-r--r-- | lib/isc/include/isc/hash.h | 250 |
1 files changed, 250 insertions, 0 deletions
diff --git a/lib/isc/include/isc/hash.h b/lib/isc/include/isc/hash.h new file mode 100644 index 0000000..fd558f7 --- /dev/null +++ b/lib/isc/include/isc/hash.h @@ -0,0 +1,250 @@ +/* + * Copyright (C) Internet Systems Consortium, Inc. ("ISC") + * + * 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 http://mozilla.org/MPL/2.0/. + * + * See the COPYRIGHT file distributed with this work for additional + * information regarding copyright ownership. + */ + +#ifndef ISC_HASH_H +#define ISC_HASH_H 1 + +#include <stdbool.h> + +#include <isc/deprecated.h> +#include <isc/types.h> + +/***** + ***** Module Info + *****/ + +/*! \file isc/hash.h + * + * \brief The hash API + * provides an unpredictable hash value for variable length data. + * A hash object contains a random vector (which is hidden from clients + * of this API) to make the actual hash value unpredictable. + * + * The algorithm used in the API guarantees the probability of hash + * collision; in the current implementation, as long as the values stored + * in the random vector are unpredictable, the probability of hash + * collision between arbitrary two different values is at most 1/2^16. + * + * Although the API is generic about the hash keys, it mainly expects + * DNS names (and sometimes IPv4/v6 addresses) as inputs. It has an + * upper limit of the input length, and may run slow to calculate the + * hash values for large inputs. + * + * This API is designed to be general so that it can provide multiple + * different hash contexts that have different random vectors. However, + * it should be typical to have a single context for an entire system. + * To support such cases, the API also provides a single-context mode. + * + * \li MP: + * The hash object is almost read-only. Once the internal random vector + * is initialized, no write operation will occur, and there will be no + * need to lock the object to calculate actual hash values. + * + * \li Reliability: + * In some cases this module uses low-level data copy to initialize the + * random vector. Errors in this part are likely to crash the server or + * corrupt memory. + * + * \li Resources: + * A buffer, used as a random vector for calculating hash values. + * + * \li Security: + * This module intends to provide unpredictable hash values in + * adversarial environments in order to avoid denial of service attacks + * to hash buckets. + * Its unpredictability relies on the quality of entropy to build the + * random vector. + * + * \li Standards: + * None. + */ + +/*** + *** Imports + ***/ + +#include <isc/types.h> + +/*** + *** Functions + ***/ +ISC_LANG_BEGINDECLS + +LIBISC_EXTERNAL_DATA extern isc_hash_t *isc_hashctx; + +isc_result_t +isc_hash_ctxcreate(isc_mem_t *mctx, isc_entropy_t *entropy, size_t limit, + isc_hash_t **hctx); +isc_result_t +isc_hash_create(isc_mem_t *mctx, isc_entropy_t *entropy, size_t limit); +/*!< + * \brief Create a new hash object. + * + * isc_hash_ctxcreate() creates a different object. + * + * isc_hash_create() creates a module-internal object to support the + * single-context mode. It should be called only once. + * + * 'entropy' must be NULL or a valid entropy object. If 'entropy' is NULL, + * pseudo random values will be used to build the random vector, which may + * weaken security. + * + * 'limit' specifies the maximum number of hash keys. If it is too large, + * these functions may fail. + */ + +void +isc_hash_ctxattach(isc_hash_t *hctx, isc_hash_t **hctxp) + ISC_DEPRECATED; +/*!< + * \brief Attach to a hash object. + * + * This function is only necessary for the multiple-context mode. + */ + +void +isc_hash_ctxdetach(isc_hash_t **hctxp) + ISC_DEPRECATED; +/*!< + * \brief Detach from a hash object. + * + * This function is for the multiple-context mode, and takes a valid + * hash object as an argument. + */ + +void +isc_hash_destroy(void); +/*!< + * \brief This function is for the single-context mode, and is expected to be used + * as a counterpart of isc_hash_create(). + * + * A valid module-internal hash object must have been created, and this + * function should be called only once. + */ + +/*@{*/ +void +isc_hash_ctxinit(isc_hash_t *hctx); +void +isc_hash_init(void); +/*!< + * \brief Initialize a hash object. + * + * It fills in the random vector with a proper + * source of entropy, which is typically from the entropy object specified + * at the creation. Thus, it is desirable to call these functions after + * initializing the entropy object with some good entropy sources. + * + * These functions should be called before the first hash calculation. + * + * isc_hash_ctxinit() is for the multiple-context mode, and takes a valid hash + * object as an argument. + * + * isc_hash_init() is for the single-context mode. A valid module-internal + * hash object must have been created, and this function should be called only + * once. + */ +/*@}*/ + +/*@{*/ +unsigned int +isc_hash_ctxcalc(isc_hash_t *hctx, const unsigned char *key, + unsigned int keylen, bool case_sensitive) + ISC_DEPRECATED; +unsigned int +isc_hash_calc(const unsigned char *key, unsigned int keylen, + bool case_sensitive) + ISC_DEPRECATED; +/*!< + * \brief Calculate a hash value. + * + * isc_hash_ctxinit() is for the multiple-context mode, and takes a valid hash + * object as an argument. + * + * isc_hash_init() is for the single-context mode. A valid module-internal + * hash object must have been created. + * + * 'key' is the hash key, which is a variable length buffer. + * + * 'keylen' specifies the key length, which must not be larger than the limit + * specified for the corresponding hash object. + * + * 'case_sensitive' specifies whether the hash key should be treated as + * case_sensitive values. It should typically be false if the hash key + * is a DNS name. + */ +/*@}*/ + +void +isc__hash_setvec(const uint16_t *vec) + ISC_DEPRECATED; + +/*!< + * \brief Set the contents of the random vector used in hashing. + * + * WARNING: This function is meant to be used only in testing code. It + * must not be used anywhere in normally running code. + * + * The hash context must have been created beforehand, otherwise this + * function is a nop. + * + * 'vec' is not documented here on purpose. You should know what you are + * doing before using this function. + */ + +const void * +isc_hash_get_initializer(void); + +void +isc_hash_set_initializer(const void *initializer); + +uint32_t +isc_hash_function(const void *data, size_t length, + bool case_sensitive, + const uint32_t *previous_hashp); +uint32_t +isc_hash_function_reverse(const void *data, size_t length, + bool case_sensitive, + const uint32_t *previous_hashp); +/*!< + * \brief Calculate a hash over data. + * + * This hash function is useful for hashtables. The hash function is + * opaque and not important to the caller. The returned hash values are + * non-deterministic and will have different mapping every time a + * process using this library is run, but will have uniform + * distribution. + * + * isc_hash_function() calculates the hash from start to end over the + * input data. isc_hash_function_reverse() calculates the hash from the + * end to the start over the input data. The difference in order is + * useful in incremental hashing; for example, a previously hashed + * value for 'com' can be used as input when hashing 'example.com'. + * + * This is a new variant of isc_hash_calc() and will supercede + * isc_hash_calc() eventually. + * + * 'data' is the data to be hashed. + * + * 'length' is the size of the data to be hashed. + * + * 'case_sensitive' specifies whether the hash key should be treated as + * case_sensitive values. It should typically be false if the hash key + * is a DNS name. + * + * 'previous_hashp' is a pointer to a previous hash value returned by + * this function. It can be used to perform incremental hashing. NULL + * must be passed during first calls. + */ + +ISC_LANG_ENDDECLS + +#endif /* ISC_HASH_H */ |