[Openvpn-devel] [L] Change in openvpn[master]: Replace custom hash_func with siphash
"plaisthos \(Code Review\) via Openvpn-devel" <[email protected]> Thu, 30 Jul 2026 16:04:31 +0000
| Newsgroups | net.sourceforge.lists.openvpn-devel |
|---|---|
| Message-ID | <8a566ad7eb86b588b39e2fdea01c544059ecf202-EmailReplacePatchSet-HTML@gerrit.openvpn.net> |
--===============3546996785282579644==
Content-Transfer-Encoding: 8bit
Content-Disposition: inline
Content-Type: multipart/alternative; boundary="3TqC9ucSO/o="; charset=UTF-8
--3TqC9ucSO/o=
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
Attention is currently required from: flichtenheld=2E
Hello flichtenheld, =
I'd like you to reexamine a change=2E Please visit
http://gerrit=2Eo=
penvpn=2Enet/c/openvpn/+/1573?usp=3Demail
to look at the new patch set (#2=
1)=2E
Change subject: Replace custom hash_func with siphash
=2E=2E=2E=2E=
=2E=2E=2E=2E=2E=2E=2E=2E=2E=2E=2E=2E=2E=2E=2E=2E=2E=2E=2E=2E=2E=2E=2E=2E=2E=
=2E=2E=2E=2E=2E=2E=2E=2E=2E=2E=2E=2E=2E=2E=2E=2E=2E=2E=2E=2E=2E=2E=2E=2E=2E=
=2E=2E=2E=2E=2E=2E=2E=2E=2E=2E=2E=2E=2E=2E=2E=2E
Replace custom hash_func =
with siphash
Benchmarking the two functions gives a bit better
performance=
to the custom hash function but also it is
difficult to get a good measure=
ment since the order of
magnitude that these function use is similar to the=
test framework itself=2E
However siphash24 is a modern and better suited
=
function for the hash tables that we are using
because the inputs are contr=
olled by the
peers (e=2Eg=2E source IP address)=2E
Change-Id: I807f398903a=
c2047530800c29949793c6f4f0ec9
Signed-off-by: Arne Schwabe <arne@rfc2549=2Eo=
rg>
---
M CMakeLists=2Etxt
M src/openvpn/Makefile=2Eam
M src/openvpn/list=
=2Ec
M src/openvpn/list=2Eh
M src/openvpn/mroute=2Ec
M src/openvpn/multi=2E=
c
A src/openvpn/siphash=2Ec
M src/openvpn/siphash=2Eh
M tests/unit_tests/op=
envpn/Makefile=2Eam
M tests/unit_tests/openvpn/test_misc=2Ec
10 files chang=
ed, 81 insertions(+), 187 deletions(-)
git pull ssh://gerrit=2Eopenvpn=
=2Enet:29418/openvpn refs/changes/73/1573/21
diff --git a/CMakeLists=2Etxt=
b/CMakeLists=2Etxt
index 29b53a9=2E=2E9b31b1a 100644
--- a/CMakeLists=2Etx=
t
+++ b/CMakeLists=2Etxt
@@ -572,6 +572,7 @@
src/openvpn/shaper=2Eh
=
src/openvpn/sig=2Ec
src/openvpn/sig=2Eh
+ src/openvpn/siphash=2E=
c
src/openvpn/siphash=2Eh
src/openvpn/siphash_reference=2Ec
=
src/openvpn/socket=2Ec
@@ -835,7 +836,10 @@
src/openvpn/options_ut=
il=2Ec
src/openvpn/ssl_util=2Ec
src/openvpn/list=2Ec
- =
)
+ src/openvpn/siphash=2Eh
+ src/openvpn/siphash=2Ec
+ =
src/openvpn/siphash_reference=2Ec
+ )
target_sources(test_=
ncp PRIVATE
src/openvpn/crypto_epoch=2Ec
diff --git a/src/openvpn/=
Makefile=2Eam b/src/openvpn/Makefile=2Eam
index 1f77384=2E=2Ef5a7621 100644=
--- a/src/openvpn/Makefile=2Eam
+++ b/src/openvpn/Makefile=2Eam
@@ -128,7 =
+128,8 @@
session_id=2Ec session_id=2Eh \
shaper=2Ec shaper=2Eh \
sig=
=2Ec sig=2Eh \
- siphash_reference=2Ec siphash=2Eh \
+ siphash_reference=2E=
c \
+ siphash=2Ec siphash=2Eh \
socket=2Ec socket=2Eh \
socket_util=2Ec=
socket_util=2Eh \
socks=2Ec socks=2Eh \
diff --git a/src/openvpn/list=2E=
c b/src/openvpn/list=2Ec
index e52c778=2E=2E9e80761 100644
--- a/src/openvp=
n/list=2Ec
+++ b/src/openvpn/list=2Ec
@@ -31,9 +31,6 @@
#include "list=2Eh=
"
#include "crypto=2Eh"
-#include "misc=2Eh"
-
-#include "memdbg=2Eh"
=
struct hash *
hash_init(const uint32_t n_buckets,
@@ -316,178 +313,3 @@
=
hi->last->key =3D NULL;
hi->bucket_marked =3D true;
}
-
-
-/*
- *=
--------------------------------------------------------------------
- * h=
ash() -- hash a variable-length key into a 32-bit value
- * k : the key=
(the unaligned variable-length array of bytes)
- * len : the length of t=
he key, counting by bytes
- * level : can be any 4-byte value
- * Returns a=
32-bit value=2E Every bit of the key affects every bit of
- * the return =
value=2E Every 1-bit and 2-bit delta achieves avalanche=2E
- * About 36+6l=
en instructions=2E
- *
- * #define hashsize(n) ((uint32_t)1<<(n))
- * #defi=
ne hashmask(n) (hashsize(n)-1)
- *
- * The best hash table sizes are powers=
of 2=2E There is no need to do
- * mod a prime (mod is sooo slow!)=2E If=
you need less than 32 bits,
- * use a bitmask=2E For example, if you need=
only 10 bits, do
- * h =3D (h & hashmask(10));
- * In which case, the hash=
table should have hashsize(10) elements=2E
- *
- * If you are hashing n st=
rings (uint8_t **)k, do it like this:
- * for (i=3D0, h=3D0; i<n; ++i) h =
=3D hash( k[i], len[i], h);
- *
- * By Bob Jenkins, 1996=2E bob_jenkins@bu=
rtleburtle=2Enet=2E You may use this
- * code any way you wish, private, e=
ducational, or commercial=2E It's free=2E
- *
- * See https://burtleburtle=
=2Enet/bob/hash/evahash=2Ehtml
- * Use for hash table lookup, or anything w=
here one collision in 2^32 is
- * acceptable=2E Do NOT use for cryptograph=
ic purposes=2E
- *
- * ----------------------------------------------------=
----------------
- *
- * mix -- mix 3 32-bit values reversibly=2E
- * For e=
very delta with one or two bit set, and the deltas of all three
- * high bi=
ts or all three low bits, whether the original value of a,b,c
- * is almost=
all zero or is uniformly distributed,
- * If mix() is run forward or backw=
ard, at least 32 bits in a,b,c
- * have at least 1/4 probability of changin=
g=2E
- * If mix() is run forward, every bit of c will change between 1/3 an=
d
- * 2/3 of the time=2E (Well, 22/100 and 78/100 for some 2-bit deltas=2E=
)
- * mix() was built out of 36 single-cycle latency instructions in a
- * =
structure that could supported 2x parallelism, like so:
- * a -=3D b;
- =
* a -=3D c; x =3D (c>>13);
- * b -=3D c; a ^=3D x;
- * b -=3D a; x=
=3D (a<<8);
- * c -=3D a; b ^=3D x;
- * c -=3D b; x =3D (b>>13);
- *=
=2E=2E=2E
- * Unfortunately, superscalar Pentiums and Sparcs can't take=
advantage
- * of that parallelism=2E They've also turned some of those si=
ngle-cycle
- * latency instructions into multi-cycle latency instructions=
=2E Still,
- * this is the fastest good hash I could find=2E There were a=
bout 2^^68
- * to choose from=2E I only looked at a billion or so=2E
- *
-=
* James Yonan Notes:
- *
- * This function is faster than it looks, and ap=
pears to be
- * appropriate for our usage in OpenVPN which is primarily
- *=
for hash-table based address lookup (IPv4, IPv6, and Ethernet MAC)=2E
- * =
NOTE: This function is never used for cryptographic purposes, only
- * to p=
roduce evenly-distributed indexes into hash tables=2E
- *
- * Benchmark res=
ults: 11=2E39 machine cycles per byte on a P2 266Mhz,
- * =
and 12=2E1 machine cycles per byte on a
- * 2=2E2 Ghz P4=
when hashing a 6 byte string=2E
- * --------------------------------------=
------------------------------
- */
-
-#define mix(a, b, c) \
- { =
\
- a -=3D b; \
- a -=3D c; \
=
- a ^=3D (c >> 13); \
- b -=3D c; \
- b -=3D a=
; \
- b ^=3D (a << 8); \
- c -=3D a; \
- =
c -=3D b; \
- c ^=3D (b >> 13); \
- a -=3D b; =
\
- a -=3D c; \
- a ^=3D (c >> 12); \
- b=
-=3D c; \
- b -=3D a; \
- b ^=3D (a << 16); =
\
- c -=3D a; \
- c -=3D b; \
- c ^=3D=
(b >> 5); \
- a -=3D b; \
- a -=3D c; \
- =
a ^=3D (c >> 3); \
- b -=3D c; \
- b -=3D a; =
\
- b ^=3D (a << 10); \
- c -=3D a; \
- =
c -=3D b; \
- c ^=3D (b >> 15); \
- }
-
-uint64_t
-hash_=
func(const uint8_t *k, uint32_t length, uint32_t initval)
-{
- uint32_t =
a, b, c, len;
-
- /* Set up the internal state */
- len =3D length;
-=
a =3D b =3D 0x9e3779b9; /* the golden ratio; an arbitrary value */
- =
c =3D initval; /* the previous hash value */
-
- /*-------------=
--------------------------- handle most of the key */
- while (len >=3D =
12)
- {
- a +=3D (k[0] + ((uint32_t)k[1] << 8) + ((uint32_t)k[2] =
<< 16) + ((uint32_t)k[3] << 24));
- b +=3D (k[4] + ((uint32_t)k[5] <=
< 8) + ((uint32_t)k[6] << 16) + ((uint32_t)k[7] << 24));
- c +=3D (k=
[8] + ((uint32_t)k[9] << 8) + ((uint32_t)k[10] << 16) + ((uint32_t)k[11] <<=
24));
- mix(a, b, c);
- k +=3D 12;
- len -=3D 12;
- =
}
-
- /*------------------------------------- handle the last 11 bytes=
*/
- c +=3D length;
- switch (len) /* all the case statements fall t=
hrough */
- {
- case 11:
- c +=3D ((uint32_t)k[10] << =
24);
- /* Intentional [[fallthrough]]; */
-
- case 10:
- =
c +=3D ((uint32_t)k[9] << 16);
- /* Intentional [[fal=
lthrough]]; */
-
- case 9:
- c +=3D ((uint32_t)k[8] << 8)=
;
- /* Intentional [[fallthrough]]; */
-
- /* the first byte =
of c is reserved for the length */
- case 8:
- b +=3D ((u=
int32_t)k[7] << 24);
- /* Intentional [[fallthrough]]; */
-
- =
case 7:
- b +=3D ((uint32_t)k[6] << 16);
- /* In=
tentional [[fallthrough]]; */
-
- case 6:
- b +=3D ((uint=
32_t)k[5] << 8);
- /* Intentional [[fallthrough]]; */
-
- =
case 5:
- b +=3D k[4];
- /* Intentional [[fallthroug=
h]]; */
-
- case 4:
- a +=3D ((uint32_t)k[3] << 24);
- =
/* Intentional [[fallthrough]]; */
-
- case 3:
- =
a +=3D ((uint32_t)k[2] << 16);
- /* Intentional [[fallthrough]]=
; */
-
- case 2:
- a +=3D ((uint32_t)k[1] << 8);
- =
/* Intentional [[fallthrough]]; */
-
- case 1:
- a +=
=3D k[0];
- /* case 0: nothing left to add */
- }
- mix(a,=
b, c);
- /*-------------------------------------- report the result */
=
- return c;
-}
diff --git a/src/openvpn/list=2Eh b/src/openvpn/list=2Eh
=
index cbf1abf=2E=2E55bc3c8 100644
--- a/src/openvpn/list=2Eh
+++ b/src/open=
vpn/list=2Eh
@@ -50,7 +50,7 @@
};
-#define HASH_KEY_LEN 4
+#define HAS=
H_KEY_LEN 16
struct hash
{
@@ -103,8 +103,6 @@
void hash_iterator_fr=
ee(struct hash_iterator *hi);
-uint64_t hash_func(const uint8_t *k, uint3=
2_t length, uint32_t initval);
-
static inline uint64_t
hash_value(const =
struct hash *hash, const void *key)
{
diff --git a/src/openvpn/mroute=2Ec =
b/src/openvpn/mroute=2Ec
index a5179d0=2E=2Eedf8239 100644
--- a/src/openvp=
n/mroute=2Ec
+++ b/src/openvpn/mroute=2Ec
@@ -33,6 +33,7 @@
#include "sock=
et_util=2Eh"
#include "memdbg=2Eh"
+#include "siphash=2Eh"
void
mrou=
te_addr_init(struct mroute_addr *addr)
@@ -357,8 +358,8 @@
uint64_t
mrout=
e_addr_hash_function(const void *key, const uint8_t hash_key[HASH_KEY_LEN])=
{
- return hash_func(mroute_addr_hash_ptr((const struct mroute_addr *)=
key),
- mroute_addr_hash_len((const struct mroute_addr =
*)key), *(uint32_t *)hash_key);
+ return siphash_hash_func(mroute_addr_h=
ash_ptr((const struct mroute_addr *)key),
+ mro=
ute_addr_hash_len((const struct mroute_addr *)key), hash_key);
}
bool
d=
iff --git a/src/openvpn/multi=2Ec b/src/openvpn/multi=2Ec
index cfa2ad8=2E=
=2E72b0b53 100644
--- a/src/openvpn/multi=2Ec
+++ b/src/openvpn/multi=2Ec
@=
@ -23,6 +23,7 @@
#ifdef HAVE_CONFIG_H
#include "config=2Eh"
#endif
+#inc=
lude "siphash=2Eh"
#ifdef HAVE_SYS_INOTIFY_H
#include <sys/inotify=2Eh>=
diff --git a/src/openvpn/siphash=2Ec b/src/openvpn/siphash=2Ec
new file mo=
de 100644
index 0000000=2E=2Ef8e80ce
--- /dev/null
+++ b/src/openvpn/siphas=
h=2Ec
@@ -0,0 +1,52 @@
+/*
+ * OpenVPN -- An application to securely tunne=
l IP networks
+ * over a single TCP/UDP port, with support for =
SSL/TLS-based
+ * session authentication and key exchange,
+ * =
packet encryption, packet authentication, and
+ * p=
acket compression=2E
+ *
+ * Copyright (C) 2025 OpenVPN Inc <sales@openvpn=
=2Enet>
+ * Copyright (C) 2025 Arne Schwabe <arne@rfc2549=2Eorg>
+ *
+ *
+=
* This program is free software; you can redistribute it and/or modify
+ =
* it under the terms of the GNU General Public License version 2
+ * as p=
ublished by the Free Software Foundation=2E
+ *
+ * This program is distri=
buted in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; wi=
thout even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PA=
RTICULAR PURPOSE=2E See the
+ * GNU General Public License for more detai=
ls=2E
+ *
+ * You should have received a copy of the GNU General Public Li=
cense along
+ * with this program; if not, write to the Free Software Foun=
dation, Inc=2E,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301=
USA=2E
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config=2Eh"
+#endif
+
+#inc=
lude <stdlib=2Eh>
+#include "syshead=2Eh"
+#include "siphash=2Eh"
+#include=
"buffer=2Eh"
+#include "crypto=2Eh"
+#include "list=2Eh"
+
+static_assert(=
SIPHASH_KEY_SIZE <=3D HASH_KEY_LEN, "hash map key size must be at least the=
same as siphash key size");
+
+uint64_t
+siphash_hash_func(const uint8_t *=
k, uint32_t length, const uint8_t hash_key[SIPHASH_KEY_SIZE])
+{
+ /* Th=
is is not endian-safe but we only care about local hashes here
+ * and =
reversing the byte does not make the hash functions any
+ * weaker or l=
ess usable */
+ union
+ {
+ uint8_t out[8];
+ uint64_t =
hash;
+ } ret;
+ siphash(k, length, hash_key, ret=2Eout, sizeof(ret=
=2Eout));
+ return ret=2Ehash;
+}
\ No newline at end of file
diff --git=
a/src/openvpn/siphash=2Eh b/src/openvpn/siphash=2Eh
index ade7762=2E=2E9a5=
a8a1 100644
--- a/src/openvpn/siphash=2Eh
+++ b/src/openvpn/siphash=2Eh
@@ =
-77,4 +77,15 @@
#endif
}
+/**
+ * Wrapper of the siphash function to ea=
sily use it in the
+ * hash map=2E
+ *
+ * @param k the data to hash
+ * @p=
aram length length of the data to hash
+ * @param hash_key the siphash ke=
y
+ * @return a uint64_t containing the result of the hashing
+ */
+uint64_=
t
+siphash_hash_func(const uint8_t *k, uint32_t length, const uint8_t hash_=
key[SIPHASH_KEY_SIZE]);
#endif /* ifndef SIPHASH_H */
diff --git a/tests/u=
nit_tests/openvpn/Makefile=2Eam b/tests/unit_tests/openvpn/Makefile=2Eam
in=
dex c76d94a=2E=2E6af25b1 100644
--- a/tests/unit_tests/openvpn/Makefile=2Ea=
m
+++ b/tests/unit_tests/openvpn/Makefile=2Eam
@@ -86,6 +86,7 @@
$(top_sr=
cdir)/src/openvpn/mtu=2Ec \
$(top_srcdir)/src/openvpn/win32-util=2Ec \
=
$(top_srcdir)/src/openvpn/mss=2Ec \
+ $(top_srcdir)/src/openvpn/siphash=2Ec=
\
$(top_srcdir)/src/openvpn/siphash_reference=2Ec
dhcp_testdriver_CFL=
AGS =3D -I$(top_srcdir)/src/openvpn -I$(top_srcdir)/src/compat @TEST_CFLAG=
S@ -DDHCP_UNIT_TEST
@@ -380,7 +381,9 @@
$(top_srcdir)/src/openvpn/ssl_uti=
l=2Ec \
$(top_srcdir)/src/openvpn/win32-util=2Ec \
$(top_srcdir)/src/op=
envpn/platform=2Ec \
- $(top_srcdir)/src/openvpn/list=2Ec
+ $(top_srcdir)/s=
rc/openvpn/list=2Ec \
+ $(top_srcdir)/src/openvpn/siphash=2Ec \
+ $(top_src=
dir)/src/openvpn/siphash_reference=2Ec
push_update_msg_testdriver_CFLAGS=
=3D -I$(top_srcdir)/src/openvpn \
-I$(top_srcdir)/src/compat \
diff --gi=
t a/tests/unit_tests/openvpn/test_misc=2Ec b/tests/unit_tests/openvpn/test_=
misc=2Ec
index 501286c=2E=2Eab21d5e 100644
--- a/tests/unit_tests/openvpn/t=
est_misc=2Ec
+++ b/tests/unit_tests/openvpn/test_misc=2Ec
@@ -32,6 +32,7 @@=
#include <string=2Eh>
#include <setjmp=2Eh>
#include <cmocka=2Eh>
+#inc=
lude <siphash=2Eh>
#include "ssl_util=2Eh"
#include "options_util=2Eh"
=
@@ -132,7 +133,7 @@
{
const char *str =3D (const char *)key;
con=
st uint32_t len =3D (uint32_t)strlen(str);
- return hash_func((const uin=
t8_t *)str, len, *(uint32_t *)(hash_key));
+ return siphash_hash_func((c=
onst uint8_t *)str, len, hash_key);
}
static bool
--
To view, visit h=
ttp://gerrit=2Eopenvpn=2Enet/c/openvpn/+/1573?usp=3Demail
To unsubscribe, o=
r for help writing mail filters, visit http://gerrit=2Eopenvpn=2Enet/settin=
gs?usp=3Demail
Gerrit-MessageType: newpatchset
Gerrit-Project: openvpn
Ger=
rit-Branch: master
Gerrit-Change-Id: I807f398903ac2047530800c29949793c6f4f0=
ec9
Gerrit-Change-Number: 1573
Gerrit-PatchSet: 21
Gerrit-Owner: plaisthos =
<arne-openvpn@rfc2549=2Eorg>
Gerrit-Reviewer: flichtenheld <frank@lichtenhe=
ld=2Ecom>
Gerrit-CC: openvpn-devel <openvpn-devel@lists=2Esourceforge=2Enet=
>
Gerrit-Attention: flichtenheld <frank@lichtenheld=2Ecom>
--3TqC9ucSO/o=
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<!DOCTYPE html><html><head><style></style></head><body><p> Attention is cur=
rently required from: flichtenheld=2E </p>
<p>plaisthos <strong>uploaded pa=
tch set #21</strong> to this change=2E</p><p><a href=3D"http://gerrit=2Eope=
nvpn=2Enet/c/openvpn/+/1573?usp=3Demail">View Change</a></p><pre class=3D"b=
locks" style=3D"font-family: monospace,monospace; white-space: pre-wrap;">R=
eplace custom hash_func with siphash<br><br>Benchmarking the two functions =
gives a bit better<br>performance to the custom hash function but also it i=
s<br>difficult to get a good measurement since the order of<br>magnitude th=
at these function use is similar to the<br>test framework itself=2E<br><br>=
However siphash24 is a modern and better suited<br>function for the hash ta=
bles that we are using<br>because the inputs are controlled by the<br>peers=
(e=2Eg=2E source IP address)=2E<br><br>Change-Id: I807f398903ac2047530800c=
29949793c6f4f0ec9<br>Signed-off-by: Arne Schwabe <arne@rfc2549=2Eorg>=
<br>---<br>M CMakeLists=2Etxt<br>M src/openvpn/Makefile=2Eam<br>M src/openv=
pn/list=2Ec<br>M src/openvpn/list=2Eh<br>M src/openvpn/mroute=2Ec<br>M src/=
openvpn/multi=2Ec<br>A src/openvpn/siphash=2Ec<br>M src/openvpn/siphash=2Eh=
<br>M tests/unit_tests/openvpn/Makefile=2Eam<br>M tests/unit_tests/openvpn/=
test_misc=2Ec<br>10 files changed, 81 insertions(+), 187 deletions(-)<br><b=
r></pre><pre class=3D"blocks" style=3D"font-family: monospace,monospace; wh=
ite-space: pre-wrap;">git pull ssh://gerrit=2Eopenvpn=2Enet:29418/openvpn r=
efs/changes/73/1573/21</pre><pre style=3D"font-family: monospace,monospace;=
white-space: pre-wrap;"><span>diff --git a/CMakeLists=2Etxt b/CMakeLists=
=2Etxt</span><br><span>index 29b53a9=2E=2E9b31b1a 100644</span><br><span>--=
- a/CMakeLists=2Etxt</span><br><span>+++ b/CMakeLists=2Etxt</span><br><span=
>@@ -572,6 +572,7 @@</span><br><span> src/openvpn/shaper=2Eh</span><br>=
<span> src/openvpn/sig=2Ec</span><br><span> src/openvpn/sig=2Eh</sp=
an><br><span style=3D"color: hsl(120, 100%, 40%);">+ src/openvpn/siphash=
=2Ec</span><br><span> src/openvpn/siphash=2Eh</span><br><span> src/=
openvpn/siphash_reference=2Ec</span><br><span> src/openvpn/socket=2Ec</=
span><br><span>@@ -835,7 +836,10 @@</span><br><span> src/openvpn/op=
tions_util=2Ec</span><br><span> src/openvpn/ssl_util=2Ec</span><br>=
<span> src/openvpn/list=2Ec</span><br><span style=3D"color: hsl(0, =
100%, 40%);">- )</span><br><span style=3D"color: hsl(120, 100%, 40%)=
;">+ src/openvpn/siphash=2Eh</span><br><span style=3D"color: hsl(120=
, 100%, 40%);">+ src/openvpn/siphash=2Ec</span><br><span style=3D"co=
lor: hsl(120, 100%, 40%);">+ src/openvpn/siphash_reference=2Ec</span=
><br><span style=3D"color: hsl(120, 100%, 40%);">+ )</span><br><span> </=
span><br><span> target_sources(test_ncp PRIVATE</span><br><span> =
src/openvpn/crypto_epoch=2Ec</span><br><span>diff --git a/src/openvpn/Mak=
efile=2Eam b/src/openvpn/Makefile=2Eam</span><br><span>index 1f77384=2E=2Ef=
5a7621 100644</span><br><span>--- a/src/openvpn/Makefile=2Eam</span><br><sp=
an>+++ b/src/openvpn/Makefile=2Eam</span><br><span>@@ -128,7 +128,8 @@</spa=
n><br><span> session_id=2Ec session_id=2Eh \</span><br><span> shaper=2Ec =
shaper=2Eh \</span><br><span> sig=2Ec sig=2Eh \</span><br><span style=3D"c=
olor: hsl(0, 100%, 40%);">- siphash_reference=2Ec siphash=2Eh \</span><br><=
span style=3D"color: hsl(120, 100%, 40%);">+ siphash_reference=2Ec \</span>=
<br><span style=3D"color: hsl(120, 100%, 40%);">+ siphash=2Ec siphash=2Eh \=
</span><br><span> socket=2Ec socket=2Eh \</span><br><span> socket_util=2E=
c socket_util=2Eh \</span><br><span> socks=2Ec socks=2Eh \</span><br><span=
>diff --git a/src/openvpn/list=2Ec b/src/openvpn/list=2Ec</span><br><span>i=
ndex e52c778=2E=2E9e80761 100644</span><br><span>--- a/src/openvpn/list=2Ec=
</span><br><span>+++ b/src/openvpn/list=2Ec</span><br><span>@@ -31,9 +31,6 =
@@</span><br><span> #include "list=2Eh"</span><br><span> </span><=
br><span> #include "crypto=2Eh"</span><br><span style=3D"color: h=
sl(0, 100%, 40%);">-#include "misc=2Eh"</span><br><span style=3D"=
color: hsl(0, 100%, 40%);">-</span><br><span style=3D"color: hsl(0, 100%, 4=
0%);">-#include "memdbg=2Eh"</span><br><span> </span><br><span> s=
truct hash *</span><br><span> hash_init(const uint32_t n_buckets,</span><br=
><span>@@ -316,178 +313,3 @@</span><br><span> hi->last->key =3D N=
ULL;</span><br><span> hi->bucket_marked =3D true;</span><br><span> }=
</span><br><span style=3D"color: hsl(0, 100%, 40%);">-</span><br><span styl=
e=3D"color: hsl(0, 100%, 40%);">-</span><br><span style=3D"color: hsl(0, 10=
0%, 40%);">-/*</span><br><span style=3D"color: hsl(0, 100%, 40%);">- * ----=
----------------------------------------------------------------</span><br>=
<span style=3D"color: hsl(0, 100%, 40%);">- * hash() -- hash a variable-len=
gth key into a 32-bit value</span><br><span style=3D"color: hsl(0, 100%, 40=
%);">- * k : the key (the unaligned variable-length array of bytes)</sp=
an><br><span style=3D"color: hsl(0, 100%, 40%);">- * len : the length of =
the key, counting by bytes</span><br><span style=3D"color: hsl(0, 100%, 40%=
);">- * level : can be any 4-byte value</span><br><span style=3D"color: hsl=
(0, 100%, 40%);">- * Returns a 32-bit value=2E Every bit of the key affect=
s every bit of</span><br><span style=3D"color: hsl(0, 100%, 40%);">- * the =
return value=2E Every 1-bit and 2-bit delta achieves avalanche=2E</span><b=
r><span style=3D"color: hsl(0, 100%, 40%);">- * About 36+6len instructions=
=2E</span><br><span style=3D"color: hsl(0, 100%, 40%);">- *</span><br><span=
style=3D"color: hsl(0, 100%, 40%);">- * #define hashsize(n) ((uint32_t)1&l=
t;<(n))</span><br><span style=3D"color: hsl(0, 100%, 40%);">- * #define =
hashmask(n) (hashsize(n)-1)</span><br><span style=3D"color: hsl(0, 100%, 40=
%);">- *</span><br><span style=3D"color: hsl(0, 100%, 40%);">- * The best h=
ash table sizes are powers of 2=2E There is no need to do</span><br><span =
style=3D"color: hsl(0, 100%, 40%);">- * mod a prime (mod is sooo slow!)=2E =
If you need less than 32 bits,</span><br><span style=3D"color: hsl(0, 100%=
, 40%);">- * use a bitmask=2E For example, if you need only 10 bits, do</s=
pan><br><span style=3D"color: hsl(0, 100%, 40%);">- * h =3D (h & hashma=
sk(10));</span><br><span style=3D"color: hsl(0, 100%, 40%);">- * In which c=
ase, the hash table should have hashsize(10) elements=2E</span><br><span st=
yle=3D"color: hsl(0, 100%, 40%);">- *</span><br><span style=3D"color: hsl(0=
, 100%, 40%);">- * If you are hashing n strings (uint8_t **)k, do it like t=
his:</span><br><span style=3D"color: hsl(0, 100%, 40%);">- * for (i=3D0, h=
=3D0; i<n; ++i) h =3D hash( k[i], len[i], h);</span><br><span style=3D"c=
olor: hsl(0, 100%, 40%);">- *</span><br><span style=3D"color: hsl(0, 100%, =
40%);">- * By Bob Jenkins, 1996=2E bob_jenkins@burtleburtle=2Enet=2E You =
may use this</span><br><span style=3D"color: hsl(0, 100%, 40%);">- * code a=
ny way you wish, private, educational, or commercial=2E It's free=2E</=
span><br><span style=3D"color: hsl(0, 100%, 40%);">- *</span><br><span styl=
e=3D"color: hsl(0, 100%, 40%);">- * See https://burtleburtle=2Enet/bob/hash=
/evahash=2Ehtml</span><br><span style=3D"color: hsl(0, 100%, 40%);">- * Use=
for hash table lookup, or anything where one collision in 2^32 is</span><b=
r><span style=3D"color: hsl(0, 100%, 40%);">- * acceptable=2E Do NOT use f=
or cryptographic purposes=2E</span><br><span style=3D"color: hsl(0, 100%, 4=
0%);">- *</span><br><span style=3D"color: hsl(0, 100%, 40%);">- * ---------=
-----------------------------------------------------------</span><br><span=
style=3D"color: hsl(0, 100%, 40%);">- *</span><br><span style=3D"color: hs=
l(0, 100%, 40%);">- * mix -- mix 3 32-bit values reversibly=2E</span><br><s=
pan style=3D"color: hsl(0, 100%, 40%);">- * For every delta with one or two=
bit set, and the deltas of all three</span><br><span style=3D"color: hsl(0=
, 100%, 40%);">- * high bits or all three low bits, whether the original va=
lue of a,b,c</span><br><span style=3D"color: hsl(0, 100%, 40%);">- * is alm=
ost all zero or is uniformly distributed,</span><br><span style=3D"color: h=
sl(0, 100%, 40%);">- * If mix() is run forward or backward, at least 32 bit=
s in a,b,c</span><br><span style=3D"color: hsl(0, 100%, 40%);">- * have at =
least 1/4 probability of changing=2E</span><br><span style=3D"color: hsl(0,=
100%, 40%);">- * If mix() is run forward, every bit of c will change betwe=
en 1/3 and</span><br><span style=3D"color: hsl(0, 100%, 40%);">- * 2/3 of t=
he time=2E (Well, 22/100 and 78/100 for some 2-bit deltas=2E)</span><br><s=
pan style=3D"color: hsl(0, 100%, 40%);">- * mix() was built out of 36 singl=
e-cycle latency instructions in a</span><br><span style=3D"color: hsl(0, 10=
0%, 40%);">- * structure that could supported 2x parallelism, like so:</spa=
n><br><span style=3D"color: hsl(0, 100%, 40%);">- * a -=3D b;</span><br>=
<span style=3D"color: hsl(0, 100%, 40%);">- * a -=3D c; x =3D (c>>=
13);</span><br><span style=3D"color: hsl(0, 100%, 40%);">- * b -=3D c; a=
^=3D x;</span><br><span style=3D"color: hsl(0, 100%, 40%);">- * b -=3D =
a; x =3D (a<<8);</span><br><span style=3D"color: hsl(0, 100%, 40%);">=
- * c -=3D a; b ^=3D x;</span><br><span style=3D"color: hsl(0, 100%, 40%=
);">- * c -=3D b; x =3D (b>>13);</span><br><span style=3D"color: h=
sl(0, 100%, 40%);">- * =2E=2E=2E</span><br><span style=3D"color: hsl(0, =
100%, 40%);">- * Unfortunately, superscalar Pentiums and Sparcs can't t=
ake advantage</span><br><span style=3D"color: hsl(0, 100%, 40%);">- * of th=
at parallelism=2E They've also turned some of those single-cycle</span=
><br><span style=3D"color: hsl(0, 100%, 40%);">- * latency instructions int=
o multi-cycle latency instructions=2E Still,</span><br><span style=3D"colo=
r: hsl(0, 100%, 40%);">- * this is the fastest good hash I could find=2E T=
here were about 2^^68</span><br><span style=3D"color: hsl(0, 100%, 40%);">-=
* to choose from=2E I only looked at a billion or so=2E</span><br><span s=
tyle=3D"color: hsl(0, 100%, 40%);">- *</span><br><span style=3D"color: hsl(=
0, 100%, 40%);">- * James Yonan Notes:</span><br><span style=3D"color: hsl(=
0, 100%, 40%);">- *</span><br><span style=3D"color: hsl(0, 100%, 40%);">- *=
This function is faster than it looks, and appears to be</span><br><span s=
tyle=3D"color: hsl(0, 100%, 40%);">- * appropriate for our usage in OpenVPN=
which is primarily</span><br><span style=3D"color: hsl(0, 100%, 40%);">- *=
for hash-table based address lookup (IPv4, IPv6, and Ethernet MAC)=2E</spa=
n><br><span style=3D"color: hsl(0, 100%, 40%);">- * NOTE: This function is =
never used for cryptographic purposes, only</span><br><span style=3D"color:=
hsl(0, 100%, 40%);">- * to produce evenly-distributed indexes into hash ta=
bles=2E</span><br><span style=3D"color: hsl(0, 100%, 40%);">- *</span><br><=
span style=3D"color: hsl(0, 100%, 40%);">- * Benchmark results: 11=2E39 mac=
hine cycles per byte on a P2 266Mhz,</span><br><span style=3D"color: hsl(0,=
100%, 40%);">- * and 12=2E1 machine cycles per byte on a=
</span><br><span style=3D"color: hsl(0, 100%, 40%);">- * =
2=2E2 Ghz P4 when hashing a 6 byte string=2E</span><br><span style=3D"color=
: hsl(0, 100%, 40%);">- * -------------------------------------------------=
-------------------</span><br><span style=3D"color: hsl(0, 100%, 40%);">- *=
/</span><br><span style=3D"color: hsl(0, 100%, 40%);">-</span><br><span sty=
le=3D"color: hsl(0, 100%, 40%);">-#define mix(a, b, c) \</span><br><span=
style=3D"color: hsl(0, 100%, 40%);">- { \</span><br><=
span style=3D"color: hsl(0, 100%, 40%);">- a -=3D b; \</span=
><br><span style=3D"color: hsl(0, 100%, 40%);">- a -=3D c; \=
</span><br><span style=3D"color: hsl(0, 100%, 40%);">- a ^=3D (c >=
;> 13); \</span><br><span style=3D"color: hsl(0, 100%, 40%);">- b=
-=3D c; \</span><br><span style=3D"color: hsl(0, 100%, 40%);">- =
b -=3D a; \</span><br><span style=3D"color: hsl(0, 100%, 40%);=
">- b ^=3D (a << 8); \</span><br><span style=3D"color: hsl(0,=
100%, 40%);">- c -=3D a; \</span><br><span style=3D"color: =
hsl(0, 100%, 40%);">- c -=3D b; \</span><br><span style=3D"c=
olor: hsl(0, 100%, 40%);">- c ^=3D (b >> 13); \</span><br><spa=
n style=3D"color: hsl(0, 100%, 40%);">- a -=3D b; \</span><b=
r><span style=3D"color: hsl(0, 100%, 40%);">- a -=3D c; \</s=
pan><br><span style=3D"color: hsl(0, 100%, 40%);">- a ^=3D (c >&g=
t; 12); \</span><br><span style=3D"color: hsl(0, 100%, 40%);">- b -=
=3D c; \</span><br><span style=3D"color: hsl(0, 100%, 40%);">- =
b -=3D a; \</span><br><span style=3D"color: hsl(0, 100%, 40%);">=
- b ^=3D (a << 16); \</span><br><span style=3D"color: hsl(0, 1=
00%, 40%);">- c -=3D a; \</span><br><span style=3D"color: hs=
l(0, 100%, 40%);">- c -=3D b; \</span><br><span style=3D"col=
or: hsl(0, 100%, 40%);">- c ^=3D (b >> 5); \</span><br><span =
style=3D"color: hsl(0, 100%, 40%);">- a -=3D b; \</span><br>=
<span style=3D"color: hsl(0, 100%, 40%);">- a -=3D c; \</spa=
n><br><span style=3D"color: hsl(0, 100%, 40%);">- a ^=3D (c >>=
3); \</span><br><span style=3D"color: hsl(0, 100%, 40%);">- b -=3D=
c; \</span><br><span style=3D"color: hsl(0, 100%, 40%);">- =
b -=3D a; \</span><br><span style=3D"color: hsl(0, 100%, 40%);">- =
b ^=3D (a << 10); \</span><br><span style=3D"color: hsl(0, 100%=
, 40%);">- c -=3D a; \</span><br><span style=3D"color: hsl(0=
, 100%, 40%);">- c -=3D b; \</span><br><span style=3D"color:=
hsl(0, 100%, 40%);">- c ^=3D (b >> 15); \</span><br><span sty=
le=3D"color: hsl(0, 100%, 40%);">- }</span><br><span style=3D"color: hsl=
(0, 100%, 40%);">-</span><br><span style=3D"color: hsl(0, 100%, 40%);">-uin=
t64_t</span><br><span style=3D"color: hsl(0, 100%, 40%);">-hash_func(const =
uint8_t *k, uint32_t length, uint32_t initval)</span><br><span style=3D"col=
or: hsl(0, 100%, 40%);">-{</span><br><span style=3D"color: hsl(0, 100%, 40%=
);">- uint32_t a, b, c, len;</span><br><span style=3D"color: hsl(0, 100%=
, 40%);">-</span><br><span style=3D"color: hsl(0, 100%, 40%);">- /* Set =
up the internal state */</span><br><span style=3D"color: hsl(0, 100%, 40%);=
">- len =3D length;</span><br><span style=3D"color: hsl(0, 100%, 40%);">=
- a =3D b =3D 0x9e3779b9; /* the golden ratio; an arbitrary value */</sp=
an><br><span style=3D"color: hsl(0, 100%, 40%);">- c =3D initval; =
/* the previous hash value */</span><br><span style=3D"color: hsl(0, 100%,=
40%);">-</span><br><span style=3D"color: hsl(0, 100%, 40%);">- /*------=
---------------------------------- handle most of the key */</span><br><spa=
n style=3D"color: hsl(0, 100%, 40%);">- while (len >=3D 12)</span><br=
><span style=3D"color: hsl(0, 100%, 40%);">- {</span><br><span style=3D"=
color: hsl(0, 100%, 40%);">- a +=3D (k[0] + ((uint32_t)k[1] <<=
8) + ((uint32_t)k[2] << 16) + ((uint32_t)k[3] << 24));</span><=
br><span style=3D"color: hsl(0, 100%, 40%);">- b +=3D (k[4] + ((uint=
32_t)k[5] << 8) + ((uint32_t)k[6] << 16) + ((uint32_t)k[7] <=
< 24));</span><br><span style=3D"color: hsl(0, 100%, 40%);">- c +=
=3D (k[8] + ((uint32_t)k[9] << 8) + ((uint32_t)k[10] << 16) + (=
(uint32_t)k[11] << 24));</span><br><span style=3D"color: hsl(0, 100%,=
40%);">- mix(a, b, c);</span><br><span style=3D"color: hsl(0, 100%,=
40%);">- k +=3D 12;</span><br><span style=3D"color: hsl(0, 100%, 40=
%);">- len -=3D 12;</span><br><span style=3D"color: hsl(0, 100%, 40%=
);">- }</span><br><span style=3D"color: hsl(0, 100%, 40%);">-</span><br>=
<span style=3D"color: hsl(0, 100%, 40%);">- /*--------------------------=
----------- handle the last 11 bytes */</span><br><span style=3D"color: hsl=
(0, 100%, 40%);">- c +=3D length;</span><br><span style=3D"color: hsl(0,=
100%, 40%);">- switch (len) /* all the case statements fall through */<=
/span><br><span style=3D"color: hsl(0, 100%, 40%);">- {</span><br><span =
style=3D"color: hsl(0, 100%, 40%);">- case 11:</span><br><span style=
=3D"color: hsl(0, 100%, 40%);">- c +=3D ((uint32_t)k[10] <<=
; 24);</span><br><span style=3D"color: hsl(0, 100%, 40%);">- /* =
Intentional [[fallthrough]]; */</span><br><span style=3D"color: hsl(0, 100%=
, 40%);">-</span><br><span style=3D"color: hsl(0, 100%, 40%);">- cas=
e 10:</span><br><span style=3D"color: hsl(0, 100%, 40%);">- c +=
=3D ((uint32_t)k[9] << 16);</span><br><span style=3D"color: hsl(0, 10=
0%, 40%);">- /* Intentional [[fallthrough]]; */</span><br><span =
style=3D"color: hsl(0, 100%, 40%);">-</span><br><span style=3D"color: hsl(0=
, 100%, 40%);">- case 9:</span><br><span style=3D"color: hsl(0, 100%=
, 40%);">- c +=3D ((uint32_t)k[8] << 8);</span><br><span s=
tyle=3D"color: hsl(0, 100%, 40%);">- /* Intentional [[fallthrough]];=
*/</span><br><span style=3D"color: hsl(0, 100%, 40%);">-</span><br><span s=
tyle=3D"color: hsl(0, 100%, 40%);">- /* the first byte of c is reser=
ved for the length */</span><br><span style=3D"color: hsl(0, 100%, 40%);">-=
case 8:</span><br><span style=3D"color: hsl(0, 100%, 40%);">- =
b +=3D ((uint32_t)k[7] << 24);</span><br><span style=3D"color: =
hsl(0, 100%, 40%);">- /* Intentional [[fallthrough]]; */</span><=
br><span style=3D"color: hsl(0, 100%, 40%);">-</span><br><span style=3D"col=
or: hsl(0, 100%, 40%);">- case 7:</span><br><span style=3D"color: hs=
l(0, 100%, 40%);">- b +=3D ((uint32_t)k[6] << 16);</span><=
br><span style=3D"color: hsl(0, 100%, 40%);">- /* Intentional [[=
fallthrough]]; */</span><br><span style=3D"color: hsl(0, 100%, 40%);">-</sp=
an><br><span style=3D"color: hsl(0, 100%, 40%);">- case 6:</span><br=
><span style=3D"color: hsl(0, 100%, 40%);">- b +=3D ((uint32_t)k=
[5] << 8);</span><br><span style=3D"color: hsl(0, 100%, 40%);">- =
/* Intentional [[fallthrough]]; */</span><br><span style=3D"color: h=
sl(0, 100%, 40%);">-</span><br><span style=3D"color: hsl(0, 100%, 40%);">- =
case 5:</span><br><span style=3D"color: hsl(0, 100%, 40%);">- =
b +=3D k[4];</span><br><span style=3D"color: hsl(0, 100%, 40%);">- =
/* Intentional [[fallthrough]]; */</span><br><span style=3D"color: =
hsl(0, 100%, 40%);">-</span><br><span style=3D"color: hsl(0, 100%, 40%);">-=
case 4:</span><br><span style=3D"color: hsl(0, 100%, 40%);">- =
a +=3D ((uint32_t)k[3] << 24);</span><br><span style=3D"color: =
hsl(0, 100%, 40%);">- /* Intentional [[fallthrough]]; */</span><=
br><span style=3D"color: hsl(0, 100%, 40%);">-</span><br><span style=3D"col=
or: hsl(0, 100%, 40%);">- case 3:</span><br><span style=3D"color: hs=
l(0, 100%, 40%);">- a +=3D ((uint32_t)k[2] << 16);</span><=
br><span style=3D"color: hsl(0, 100%, 40%);">- /* Intentional [[=
fallthrough]]; */</span><br><span style=3D"color: hsl(0, 100%, 40%);">-</sp=
an><br><span style=3D"color: hsl(0, 100%, 40%);">- case 2:</span><br=
><span style=3D"color: hsl(0, 100%, 40%);">- a +=3D ((uint32_t)k=
[1] << 8);</span><br><span style=3D"color: hsl(0, 100%, 40%);">- =
/* Intentional [[fallthrough]]; */</span><br><span style=3D"color: h=
sl(0, 100%, 40%);">-</span><br><span style=3D"color: hsl(0, 100%, 40%);">- =
case 1:</span><br><span style=3D"color: hsl(0, 100%, 40%);">- =
a +=3D k[0];</span><br><span style=3D"color: hsl(0, 100%, 40%);">- =
/* case 0: nothing left to add */</span><br><span style=3D"color: h=
sl(0, 100%, 40%);">- }</span><br><span style=3D"color: hsl(0, 100%, 40%)=
;">- mix(a, b, c);</span><br><span style=3D"color: hsl(0, 100%, 40%);">-=
/*-------------------------------------- report the result */</span><br=
><span style=3D"color: hsl(0, 100%, 40%);">- return c;</span><br><span s=
tyle=3D"color: hsl(0, 100%, 40%);">-}</span><br><span>diff --git a/src/open=
vpn/list=2Eh b/src/openvpn/list=2Eh</span><br><span>index cbf1abf=2E=2E55bc=
3c8 100644</span><br><span>--- a/src/openvpn/list=2Eh</span><br><span>+++ b=
/src/openvpn/list=2Eh</span><br><span>@@ -50,7 +50,7 @@</span><br><span> };=
</span><br><span> </span><br><span> </span><br><span style=3D"color: hsl(0,=
100%, 40%);">-#define HASH_KEY_LEN 4</span><br><span style=3D"color: hsl(1=
20, 100%, 40%);">+#define HASH_KEY_LEN 16</span><br><span> </span><br><span=
> struct hash</span><br><span> {</span><br><span>@@ -103,8 +103,6 @@</span>=
<br><span> </span><br><span> void hash_iterator_free(struct hash_iterator *=
hi);</span><br><span> </span><br><span style=3D"color: hsl(0, 100%, 40%);">=
-uint64_t hash_func(const uint8_t *k, uint32_t length, uint32_t initval);</=
span><br><span style=3D"color: hsl(0, 100%, 40%);">-</span><br><span> stati=
c inline uint64_t</span><br><span> hash_value(const struct hash *hash, cons=
t void *key)</span><br><span> {</span><br><span>diff --git a/src/openvpn/mr=
oute=2Ec b/src/openvpn/mroute=2Ec</span><br><span>index a5179d0=2E=2Eedf823=
9 100644</span><br><span>--- a/src/openvpn/mroute=2Ec</span><br><span>+++ b=
/src/openvpn/mroute=2Ec</span><br><span>@@ -33,6 +33,7 @@</span><br><span> =
#include "socket_util=2Eh"</span><br><span> </span><br><span> #in=
clude "memdbg=2Eh"</span><br><span style=3D"color: hsl(120, 100%,=
40%);">+#include "siphash=2Eh"</span><br><span> </span><br><span=
> void</span><br><span> mroute_addr_init(struct mroute_addr *addr)</span><b=
r><span>@@ -357,8 +358,8 @@</span><br><span> uint64_t</span><br><span> mrou=
te_addr_hash_function(const void *key, const uint8_t hash_key[HASH_KEY_LEN]=
)</span><br><span> {</span><br><span style=3D"color: hsl(0, 100%, 40%);">- =
return hash_func(mroute_addr_hash_ptr((const struct mroute_addr *)key),<=
/span><br><span style=3D"color: hsl(0, 100%, 40%);">- m=
route_addr_hash_len((const struct mroute_addr *)key), *(uint32_t *)hash_key=
);</span><br><span style=3D"color: hsl(120, 100%, 40%);">+ return siphas=
h_hash_func(mroute_addr_hash_ptr((const struct mroute_addr *)key),</span><b=
r><span style=3D"color: hsl(120, 100%, 40%);">+ =
mroute_addr_hash_len((const struct mroute_addr *)key), hash_key);</span><b=
r><span> }</span><br><span> </span><br><span> bool</span><br><span>diff --g=
it a/src/openvpn/multi=2Ec b/src/openvpn/multi=2Ec</span><br><span>index cf=
a2ad8=2E=2E72b0b53 100644</span><br><span>--- a/src/openvpn/multi=2Ec</span=
><br><span>+++ b/src/openvpn/multi=2Ec</span><br><span>@@ -23,6 +23,7 @@</s=
pan><br><span> #ifdef HAVE_CONFIG_H</span><br><span> #include "config=
=2Eh"</span><br><span> #endif</span><br><span style=3D"color: hsl(120,=
100%, 40%);">+#include "siphash=2Eh"</span><br><span> </span><br=
><span> #ifdef HAVE_SYS_INOTIFY_H</span><br><span> #include <sys/inotify=
=2Eh></span><br><span>diff --git a/src/openvpn/siphash=2Ec b/src/openvpn=
/siphash=2Ec</span><br><span>new file mode 100644</span><br><span>index 000=
0000=2E=2Ef8e80ce</span><br><span>--- /dev/null</span><br><span>+++ b/src/o=
penvpn/siphash=2Ec</span><br><span>@@ -0,0 +1,52 @@</span><br><span style=
=3D"color: hsl(120, 100%, 40%);">+/*</span><br><span style=3D"color: hsl(12=
0, 100%, 40%);">+ * OpenVPN -- An application to securely tunnel IP networ=
ks</span><br><span style=3D"color: hsl(120, 100%, 40%);">+ * ov=
er a single TCP/UDP port, with support for SSL/TLS-based</span><br><span st=
yle=3D"color: hsl(120, 100%, 40%);">+ * session authentication =
and key exchange,</span><br><span style=3D"color: hsl(120, 100%, 40%);">+ *=
packet encryption, packet authentication, and</span><br><span =
style=3D"color: hsl(120, 100%, 40%);">+ * packet compression=2E=
</span><br><span style=3D"color: hsl(120, 100%, 40%);">+ *</span><br><span =
style=3D"color: hsl(120, 100%, 40%);">+ * Copyright (C) 2025 OpenVPN Inc &=
lt;sales@openvpn=2Enet></span><br><span style=3D"color: hsl(120, 100%, 4=
0%);">+ * Copyright (C) 2025 Arne Schwabe <arne@rfc2549=2Eorg></span=
><br><span style=3D"color: hsl(120, 100%, 40%);">+ *</span><br><span style=
=3D"color: hsl(120, 100%, 40%);">+ *</span><br><span style=3D"color: hsl(12=
0, 100%, 40%);">+ * This program is free software; you can redistribute it=
and/or modify</span><br><span style=3D"color: hsl(120, 100%, 40%);">+ * i=
t under the terms of the GNU General Public License version 2</span><br><sp=
an style=3D"color: hsl(120, 100%, 40%);">+ * as published by the Free Soft=
ware Foundation=2E</span><br><span style=3D"color: hsl(120, 100%, 40%);">+ =
*</span><br><span style=3D"color: hsl(120, 100%, 40%);">+ * This program i=
s distributed in the hope that it will be useful,</span><br><span style=3D"=
color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even th=
e implied warranty of</span><br><span style=3D"color: hsl(120, 100%, 40%);"=
>+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE=2E See the</span=
><br><span style=3D"color: hsl(120, 100%, 40%);">+ * GNU General Public Li=
cense for more details=2E</span><br><span style=3D"color: hsl(120, 100%, 40=
%);">+ *</span><br><span style=3D"color: hsl(120, 100%, 40%);">+ * You sho=
uld have received a copy of the GNU General Public License along</span><br>=
<span style=3D"color: hsl(120, 100%, 40%);">+ * with this program; if not,=
write to the Free Software Foundation, Inc=2E,</span><br><span style=3D"co=
lor: hsl(120, 100%, 40%);">+ * 51 Franklin Street, Fifth Floor, Boston, MA=
02110-1301 USA=2E</span><br><span style=3D"color: hsl(120, 100%, 40%);">+ =
*/</span><br><span style=3D"color: hsl(120, 100%, 40%);">+</span><br><span =
style=3D"color: hsl(120, 100%, 40%);">+#ifdef HAVE_CONFIG_H</span><br><span=
style=3D"color: hsl(120, 100%, 40%);">+#include "config=2Eh"</sp=
an><br><span style=3D"color: hsl(120, 100%, 40%);">+#endif</span><br><span =
style=3D"color: hsl(120, 100%, 40%);">+</span><br><span style=3D"color: hsl=
(120, 100%, 40%);">+#include <stdlib=2Eh></span><br><span style=3D"co=
lor: hsl(120, 100%, 40%);">+#include "syshead=2Eh"</span><br><spa=
n style=3D"color: hsl(120, 100%, 40%);">+#include "siphash=2Eh"</=
span><br><span style=3D"color: hsl(120, 100%, 40%);">+#include "buffer=
=2Eh"</span><br><span style=3D"color: hsl(120, 100%, 40%);">+#include =
"crypto=2Eh"</span><br><span style=3D"color: hsl(120, 100%, 40%);=
">+#include "list=2Eh"</span><br><span style=3D"color: hsl(120, 1=
00%, 40%);">+</span><br><span style=3D"color: hsl(120, 100%, 40%);">+static=
_assert(SIPHASH_KEY_SIZE <=3D HASH_KEY_LEN, "hash map key size must=
be at least the same as siphash key size");</span><br><span style=3D"=
color: hsl(120, 100%, 40%);">+</span><br><span style=3D"color: hsl(120, 100=
%, 40%);">+uint64_t</span><br><span style=3D"color: hsl(120, 100%, 40%);">+=
siphash_hash_func(const uint8_t *k, uint32_t length, const uint8_t hash_key=
[SIPHASH_KEY_SIZE])</span><br><span style=3D"color: hsl(120, 100%, 40%);">+=
{</span><br><span style=3D"color: hsl(120, 100%, 40%);">+ /* This is not=
endian-safe but we only care about local hashes here</span><br><span style=
=3D"color: hsl(120, 100%, 40%);">+ * and reversing the byte does not ma=
ke the hash functions any</span><br><span style=3D"color: hsl(120, 100%, 40=
%);">+ * weaker or less usable */</span><br><span style=3D"color: hsl(1=
20, 100%, 40%);">+ union</span><br><span style=3D"color: hsl(120, 100%, =
40%);">+ {</span><br><span style=3D"color: hsl(120, 100%, 40%);">+ =
uint8_t out[8];</span><br><span style=3D"color: hsl(120, 100%, 40%);">+ =
uint64_t hash;</span><br><span style=3D"color: hsl(120, 100%, 40%);">=
+ } ret;</span><br><span style=3D"color: hsl(120, 100%, 40%);">+ siph=
ash(k, length, hash_key, ret=2Eout, sizeof(ret=2Eout));</span><br><span sty=
le=3D"color: hsl(120, 100%, 40%);">+ return ret=2Ehash;</span><br><span =
style=3D"color: hsl(120, 100%, 40%);">+}</span><br><span>\ No newline at en=
d of file</span><br><span>diff --git a/src/openvpn/siphash=2Eh b/src/openvp=
n/siphash=2Eh</span><br><span>index ade7762=2E=2E9a5a8a1 100644</span><br><=
span>--- a/src/openvpn/siphash=2Eh</span><br><span>+++ b/src/openvpn/siphas=
h=2Eh</span><br><span>@@ -77,4 +77,15 @@</span><br><span> #endif</span><br>=
<span> }</span><br><span> </span><br><span style=3D"color: hsl(120, 100%, 4=
0%);">+/**</span><br><span style=3D"color: hsl(120, 100%, 40%);">+ * Wrappe=
r of the siphash function to easily use it in the</span><br><span style=3D"=
color: hsl(120, 100%, 40%);">+ * hash map=2E</span><br><span style=3D"color=
: hsl(120, 100%, 40%);">+ *</span><br><span style=3D"color: hsl(120, 100%, =
40%);">+ * @param k the data to hash</span><br><span style=3D"color: hsl(12=
0, 100%, 40%);">+ * @param length length of the data to hash</span><br><spa=
n style=3D"color: hsl(120, 100%, 40%);">+ * @param hash_key the siphash k=
ey</span><br><span style=3D"color: hsl(120, 100%, 40%);">+ * @return a uint=
64_t containing the result of the hashing</span><br><span style=3D"color: h=
sl(120, 100%, 40%);">+ */</span><br><span style=3D"color: hsl(120, 100%, 40=
%);">+uint64_t</span><br><span style=3D"color: hsl(120, 100%, 40%);">+sipha=
sh_hash_func(const uint8_t *k, uint32_t length, const uint8_t hash_key[SIPH=
ASH_KEY_SIZE]);</span><br><span> #endif /* ifndef SIPHASH_H */</span><br><s=
pan>diff --git a/tests/unit_tests/openvpn/Makefile=2Eam b/tests/unit_tests/=
openvpn/Makefile=2Eam</span><br><span>index c76d94a=2E=2E6af25b1 100644</sp=
an><br><span>--- a/tests/unit_tests/openvpn/Makefile=2Eam</span><br><span>+=
++ b/tests/unit_tests/openvpn/Makefile=2Eam</span><br><span>@@ -86,6 +86,7 =
@@</span><br><span> $(top_srcdir)/src/openvpn/mtu=2Ec \</span><br><span> =
$(top_srcdir)/src/openvpn/win32-util=2Ec \</span><br><span> $(top_srcdir)/=
src/openvpn/mss=2Ec \</span><br><span style=3D"color: hsl(120, 100%, 40%);"=
>+ $(top_srcdir)/src/openvpn/siphash=2Ec \</span><br><span> $(top_srcdir)/=
src/openvpn/siphash_reference=2Ec</span><br><span> </span><br><span> dhcp_t=
estdriver_CFLAGS =3D -I$(top_srcdir)/src/openvpn -I$(top_srcdir)/src/compa=
t @TEST_CFLAGS@ -DDHCP_UNIT_TEST</span><br><span>@@ -380,7 +381,9 @@</span>=
<br><span> $(top_srcdir)/src/openvpn/ssl_util=2Ec \</span><br><span> $(to=
p_srcdir)/src/openvpn/win32-util=2Ec \</span><br><span> $(top_srcdir)/src/=
openvpn/platform=2Ec \</span><br><span style=3D"color: hsl(0, 100%, 40%);">=
- $(top_srcdir)/src/openvpn/list=2Ec</span><br><span style=3D"color: hsl(12=
0, 100%, 40%);">+ $(top_srcdir)/src/openvpn/list=2Ec \</span><br><span styl=
e=3D"color: hsl(120, 100%, 40%);">+ $(top_srcdir)/src/openvpn/siphash=2Ec \=
</span><br><span style=3D"color: hsl(120, 100%, 40%);">+ $(top_srcdir)/src/=
openvpn/siphash_reference=2Ec</span><br><span> </span><br><span> push_updat=
e_msg_testdriver_CFLAGS =3D -I$(top_srcdir)/src/openvpn \</span><br><span> =
-I$(top_srcdir)/src/compat \</span><br><span>diff --git a/tests/unit_tests=
/openvpn/test_misc=2Ec b/tests/unit_tests/openvpn/test_misc=2Ec</span><br><=
span>index 501286c=2E=2Eab21d5e 100644</span><br><span>--- a/tests/unit_tes=
ts/openvpn/test_misc=2Ec</span><br><span>+++ b/tests/unit_tests/openvpn/tes=
t_misc=2Ec</span><br><span>@@ -32,6 +32,7 @@</span><br><span> #include <=
string=2Eh></span><br><span> #include <setjmp=2Eh></span><br><span=
> #include <cmocka=2Eh></span><br><span style=3D"color: hsl(120, 100%=
, 40%);">+#include <siphash=2Eh></span><br><span> </span><br><span> #=
include "ssl_util=2Eh"</span><br><span> #include "options_ut=
il=2Eh"</span><br><span>@@ -132,7 +133,7 @@</span><br><span> {</span><=
br><span> const char *str =3D (const char *)key;</span><br><span> c=
onst uint32_t len =3D (uint32_t)strlen(str);</span><br><span style=3D"color=
: hsl(0, 100%, 40%);">- return hash_func((const uint8_t *)str, len, *(ui=
nt32_t *)(hash_key));</span><br><span style=3D"color: hsl(120, 100%, 40%);"=
>+ return siphash_hash_func((const uint8_t *)str, len, hash_key);</span>=
<br><span> }</span><br><span> </span><br><span> static bool</span><br><span=
></span><br></pre><p>To view, visit <a href=3D"http://gerrit=2Eopenvpn=2Ene=
t/c/openvpn/+/1573?usp=3Demail">change 1573</a>=2E To unsubscribe, or for h=
elp writing mail filters, visit <a href=3D"http://gerrit=2Eopenvpn=2Enet/se=
ttings?usp=3Demail">settings</a>=2E</p><div itemscope itemtype=3D"http://sc=
hema=2Eorg/EmailMessage"><div itemscope itemprop=3D"action" itemtype=3D"htt=
p://schema=2Eorg/ViewAction"><link itemprop=3D"url" href=3D"http://gerrit=
=2Eopenvpn=2Enet/c/openvpn/+/1573?usp=3Demail"/><meta itemprop=3D"name" con=
tent=3D"View Change"/></div></div>
<div style=3D"display:none"> Gerrit-Mes=
sageType: newpatchset </div>
<div style=3D"display:none"> Gerrit-Project: o=
penvpn </div>
<div style=3D"display:none"> Gerrit-Branch: master </div>
<di=
v style=3D"display:none"> Gerrit-Change-Id: I807f398903ac2047530800c2994979=
3c6f4f0ec9 </div>
<div style=3D"display:none"> Gerrit-Change-Number: 1573 <=
/div>
<div style=3D"display:none"> Gerrit-PatchSet: 21 </div>
<div style=3D=
"display:none"> Gerrit-Owner: plaisthos <arne-openvpn@rfc2549=2Eorg> =
</div>
<div style=3D"display:none"> Gerrit-Reviewer: flichtenheld <frank=
@lichtenheld=2Ecom> </div>
<div style=3D"display:none"> Gerrit-CC: openv=
pn-devel <openvpn-devel@lists=2Esourceforge=2Enet> </div>
<div style=
=3D"display:none"> Gerrit-Attention: flichtenheld <frank@lichtenheld=2Ec=
om> </div>
</body></html>
--3TqC9ucSO/o=--
--===============3546996785282579644==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
--===============3546996785282579644==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
_______________________________________________
Openvpn-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openvpn-devel
--===============3546996785282579644==--