summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordlg <dlg@openbsd.org>2015-04-10 12:31:55 +0000
committerdlg <dlg@openbsd.org>2015-04-10 12:31:55 +0000
commit4a986ace487a392c82584294d9a92188249d8385 (patch)
treed0658ad1deb7e955a7cb79d04f5c0d74ae500ff6
parentMove irqs_disabled() and in_dbg_master() out of the i386/amd64 ifdef block (diff)
downloadwireguard-openbsd-4a986ace487a392c82584294d9a92188249d8385.tar.xz
wireguard-openbsd-4a986ace487a392c82584294d9a92188249d8385.zip
replace the guts of tdb_hash with SipHash24
tested by (including some statistical measurement) and ok mikeb@
-rw-r--r--sys/netinet/ip_ipsp.c38
1 files changed, 11 insertions, 27 deletions
diff --git a/sys/netinet/ip_ipsp.c b/sys/netinet/ip_ipsp.c
index d9e62a6e7dd..928e8c4d45b 100644
--- a/sys/netinet/ip_ipsp.c
+++ b/sys/netinet/ip_ipsp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_ipsp.c,v 1.204 2015/03/14 03:38:52 jsg Exp $ */
+/* $OpenBSD: ip_ipsp.c,v 1.205 2015/04/10 12:31:55 dlg Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
* Angelos D. Keromytis (kermit@csd.uch.gr),
@@ -124,6 +124,7 @@ struct xformsw *xformswNXFORMSW = &xformsw[nitems(xformsw)];
#define TDB_HASHSIZE_INIT 32
+static SIPHASH_KEY tdbkey;
static struct tdb **tdbh = NULL;
static struct tdb **tdbaddr = NULL;
static struct tdb **tdbsrc = NULL;
@@ -138,34 +139,15 @@ int
tdb_hash(u_int rdomain, u_int32_t spi, union sockaddr_union *dst,
u_int8_t proto)
{
- static u_int32_t mult1 = 0, mult2 = 0;
- u_int8_t *ptr = (u_int8_t *) dst;
- int i, shift;
- u_int64_t hash;
- int val32 = 0;
-
- while (mult1 == 0)
- mult1 = arc4random();
- while (mult2 == 0)
- mult2 = arc4random();
-
- hash = (spi ^ proto ^ rdomain) * mult1;
- for (i = 0; i < SA_LEN(&dst->sa); i++) {
- val32 = (val32 << 8) | ptr[i];
- if (i % 4 == 3) {
- hash ^= val32 * mult2;
- val32 = 0;
- }
- }
-
- if (i % 4 != 0)
- hash ^= val32 * mult2;
+ SIPHASH_CTX ctx;
- shift = ffs(tdb_hashmask + 1);
- while ((hash & ~tdb_hashmask) != 0)
- hash = (hash >> shift) ^ (hash & tdb_hashmask);
+ SipHash24_Init(&ctx, &tdbkey);
+ SipHash24_Update(&ctx, &rdomain, sizeof(rdomain));
+ SipHash24_Update(&ctx, &spi, sizeof(spi));
+ SipHash24_Update(&ctx, &proto, sizeof(proto));
+ SipHash24_Update(&ctx, dst, SA_LEN(&dst->sa));
- return hash;
+ return (SipHash24_End(&ctx) & tdb_hashmask);
}
/*
@@ -590,6 +572,7 @@ tdb_rehash(void)
tdb_hashmask = (tdb_hashmask << 1) | 1;
+ arc4random_buf(&tdbkey, sizeof(tdbkey));
new_tdbh = mallocarray(tdb_hashmask + 1, sizeof(struct tdb *), M_TDB,
M_WAITOK | M_ZERO);
new_tdbaddr = mallocarray(tdb_hashmask + 1, sizeof(struct tdb *), M_TDB,
@@ -646,6 +629,7 @@ puttdb(struct tdb *tdbp)
int s = splsoftnet();
if (tdbh == NULL) {
+ arc4random_buf(&tdbkey, sizeof(tdbkey));
tdbh = mallocarray(tdb_hashmask + 1, sizeof(struct tdb *),
M_TDB, M_WAITOK | M_ZERO);
tdbaddr = mallocarray(tdb_hashmask + 1, sizeof(struct tdb *),