diff options
author | Tobias Brunner <tobias@strongswan.org> | 2013-03-26 19:24:24 +0100 |
---|---|---|
committer | Tobias Brunner <tobias@strongswan.org> | 2013-06-11 11:03:11 +0200 |
commit | d1953fe403a91d6f7a08fd4cdd0b01cf7106733d (patch) | |
tree | 5079b1f304e0a682a015ab70047d55ee94ab1fb7 | |
parent | 1255de5a2076dc591dfa1ffefffea077bd218319 (diff) | |
download | strongswan-d1953fe403a91d6f7a08fd4cdd0b01cf7106733d.tar.bz2 strongswan-d1953fe403a91d6f7a08fd4cdd0b01cf7106733d.tar.xz |
Replace chunk_hash() with output from chunk_mac()
The quality is way better, the calculation is a bit slower though.
The key is statically initialized to zero, which will be changed later
to prevent hash flooding.
-rw-r--r-- | src/libstrongswan/utils/chunk.c | 98 | ||||
-rw-r--r-- | src/libstrongswan/utils/chunk.h | 8 |
2 files changed, 31 insertions, 75 deletions
diff --git a/src/libstrongswan/utils/chunk.c b/src/libstrongswan/utils/chunk.c index ca277dac6..9033cbdaf 100644 --- a/src/libstrongswan/utils/chunk.c +++ b/src/libstrongswan/utils/chunk.c @@ -24,16 +24,6 @@ #include "chunk.h" #include "debug.h" -/* required for chunk_hash */ -#undef get16bits -#if (defined(__GNUC__) && defined(__i386__)) -#define get16bits(d) (*((const u_int16_t*)(d))) -#endif -#if !defined (get16bits) -#define get16bits(d) ((((u_int32_t)(((const u_int8_t*)(d))[1])) << 8)\ - + (u_int32_t)(((const u_int8_t*)(d))[0]) ) -#endif - /** * Empty chunk. */ @@ -659,11 +649,11 @@ static inline u_int64_t siplast(size_t len, u_char *pos) } /** - * Described in header. + * Caculate SipHash-2-4 with an optional first block given as argument. */ -u_int64_t chunk_mac(chunk_t chunk, u_char *key) +static u_int64_t chunk_mac_inc(chunk_t chunk, u_char *key, u_int64_t m) { - u_int64_t v0, v1, v2, v3, k0, k1, m; + u_int64_t v0, v1, v2, v3, k0, k1; size_t len = chunk.len; u_char *pos = chunk.ptr, *end; @@ -677,6 +667,11 @@ u_int64_t chunk_mac(chunk_t chunk, u_char *key) v2 = k0 ^ 0x6c7967656e657261ULL; v3 = k1 ^ 0x7465646279746573ULL; + if (m) + { + sipcompress(&v0, &v1, &v2, &v3, m); + } + /* compression with c = 2 */ for (; pos != end; pos += 8) { @@ -696,71 +691,24 @@ u_int64_t chunk_mac(chunk_t chunk, u_char *key) /** * Described in header. - * - * The implementation is based on Paul Hsieh's SuperFastHash: - * http://www.azillionmonkeys.com/qed/hash.html */ -u_int32_t chunk_hash_inc(chunk_t chunk, u_int32_t hash) +u_int64_t chunk_mac(chunk_t chunk, u_char *key) { - u_char *data = chunk.ptr; - size_t len = chunk.len; - u_int32_t tmp; - int rem; - - if (!len || data == NULL) - { - return 0; - } - - rem = len & 3; - len >>= 2; - - /* Main loop */ - for (; len > 0; --len) - { - hash += get16bits(data); - tmp = (get16bits(data + 2) << 11) ^ hash; - hash = (hash << 16) ^ tmp; - data += 2 * sizeof(u_int16_t); - hash += hash >> 11; - } - - /* Handle end cases */ - switch (rem) - { - case 3: - { - hash += get16bits(data); - hash ^= hash << 16; - hash ^= data[sizeof(u_int16_t)] << 18; - hash += hash >> 11; - break; - } - case 2: - { - hash += get16bits(data); - hash ^= hash << 11; - hash += hash >> 17; - break; - } - case 1: - { - hash += *data; - hash ^= hash << 10; - hash += hash >> 1; - break; - } - } + return chunk_mac_inc(chunk, key, 0); +} - /* Force "avalanching" of final 127 bits */ - hash ^= hash << 3; - hash += hash >> 5; - hash ^= hash << 4; - hash += hash >> 17; - hash ^= hash << 25; - hash += hash >> 6; +/** + * Key used for chunk_hash. + */ +static u_char key[16]; - return hash; +/** + * Described in header. + */ +u_int32_t chunk_hash_inc(chunk_t chunk, u_int32_t hash) +{ + /* we could use a mac of the previous hash, but this is faster */ + return chunk_mac_inc(chunk, key, ((u_int64_t)hash) << 32 | hash); } /** @@ -768,7 +716,7 @@ u_int32_t chunk_hash_inc(chunk_t chunk, u_int32_t hash) */ u_int32_t chunk_hash(chunk_t chunk) { - return chunk_hash_inc(chunk, chunk.len); + return chunk_mac(chunk, key); } /** diff --git a/src/libstrongswan/utils/chunk.h b/src/libstrongswan/utils/chunk.h index b28ff12b8..cfda6ee77 100644 --- a/src/libstrongswan/utils/chunk.h +++ b/src/libstrongswan/utils/chunk.h @@ -301,12 +301,20 @@ bool chunk_printable(chunk_t chunk, chunk_t *sane, char replace); /** * Computes a 32 bit hash of the given chunk. + * * @note This hash is only intended for hash tables not for cryptographic purposes. + * + * @param chunk data to hash + * @return hash value */ u_int32_t chunk_hash(chunk_t chunk); /** * Incremental version of chunk_hash. Use this to hash two or more chunks. + * + * @param chunk data to hash + * @param hash previous hash value + * @return hash value */ u_int32_t chunk_hash_inc(chunk_t chunk, u_int32_t hash); |