aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--contrib/examples/nat-hole-punching/README4
-rw-r--r--src/compat/compat.h8
-rw-r--r--src/crypto/zinc/poly1305/poly1305-x86_64.pl2
-rw-r--r--src/crypto/zinc/selftest/chacha20poly1305.c67
-rw-r--r--src/dkms.conf2
-rw-r--r--src/main.c1
-rw-r--r--src/receive.c2
-rw-r--r--src/socket.c7
-rw-r--r--src/tools/man/wg.82
-rw-r--r--src/tools/wg-quick/android.c4
-rwxr-xr-xsrc/tools/wg-quick/linux.bash78
-rw-r--r--src/uapi/wireguard.h8
-rw-r--r--src/version.h2
13 files changed, 131 insertions, 56 deletions
diff --git a/contrib/examples/nat-hole-punching/README b/contrib/examples/nat-hole-punching/README
index 46e6201..99c20e5 100644
--- a/contrib/examples/nat-hole-punching/README
+++ b/contrib/examples/nat-hole-punching/README
@@ -9,8 +9,8 @@ Compile with:
Server is 1.2.3.4 and is on the public internet accepting UDP:49918.
-Client A is NAT'd and doesnt't know its IP address.
-Client B is NAT'd and doesnt't know its IP address.
+Client A is NAT'd and doesn't know its IP address.
+Client B is NAT'd and doesn't know its IP address.
Server runs:
diff --git a/src/compat/compat.h b/src/compat/compat.h
index ab22fa4..824f57c 100644
--- a/src/compat/compat.h
+++ b/src/compat/compat.h
@@ -326,7 +326,7 @@ static inline int wait_for_random_bytes(void)
}
#endif
-#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0) && LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0) && LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0) && !defined(ISRHEL8)
#include <linux/random.h>
#include <linux/slab.h>
struct rng_is_initialized_callback {
@@ -831,7 +831,7 @@ static inline void skb_mark_not_on_list(struct sk_buff *skb)
}
#endif
-#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0) && !defined(ISRHEL8)
#define NLA_EXACT_LEN NLA_UNSPEC
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0)
@@ -861,6 +861,10 @@ static inline void skb_mark_not_on_list(struct sk_buff *skb)
})
#endif
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 5) && LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) || LINUX_VERSION_CODE < KERNEL_VERSION(5, 3, 18)
+#define ipv6_dst_lookup_flow(a, b, c, d) ipv6_dst_lookup(a, b, &dst, c) + (void *)0 ?: dst
+#endif
+
#if defined(ISUBUNTU1604)
#include <linux/siphash.h>
#ifndef _WG_LINUX_SIPHASH_H
diff --git a/src/crypto/zinc/poly1305/poly1305-x86_64.pl b/src/crypto/zinc/poly1305/poly1305-x86_64.pl
index 94c3c42..f994855 100644
--- a/src/crypto/zinc/poly1305/poly1305-x86_64.pl
+++ b/src/crypto/zinc/poly1305/poly1305-x86_64.pl
@@ -35,7 +35,7 @@
# Skylake-X system performance. Since we are likely to suppress
# AVX512F capability flag [at least on Skylake-X], conversion serves
# as kind of "investment protection". Note that next *lake processor,
-# Cannolake, has AVX512IFMA code path to execute...
+# Cannonlake, has AVX512IFMA code path to execute...
#
# Numbers are cycles per processed byte with poly1305_blocks alone,
# measured with rdtsc at fixed clock frequency.
diff --git a/src/crypto/zinc/selftest/chacha20poly1305.c b/src/crypto/zinc/selftest/chacha20poly1305.c
index d3b928d..c58ac6e 100644
--- a/src/crypto/zinc/selftest/chacha20poly1305.c
+++ b/src/crypto/zinc/selftest/chacha20poly1305.c
@@ -8879,14 +8879,15 @@ decryption_success(bool func_ret, bool expect_failure, int memcmp_result)
static bool __init chacha20poly1305_selftest(void)
{
enum { MAXIMUM_TEST_BUFFER_LEN = 1UL << 12 };
- size_t i;
- u8 *computed_output = NULL;
+ size_t i, j, k, total_len;
+ u8 *computed_output = NULL, *input = NULL;
bool success = true, ret;
simd_context_t simd_context;
- struct scatterlist sg_src;
+ struct scatterlist sg_src[3];
computed_output = kmalloc(MAXIMUM_TEST_BUFFER_LEN, GFP_KERNEL);
- if (!computed_output) {
+ input = kmalloc(MAXIMUM_TEST_BUFFER_LEN, GFP_KERNEL);
+ if (!computed_output || !input) {
pr_err("chacha20poly1305 self-test malloc: FAIL\n");
success = false;
goto out;
@@ -8917,10 +8918,10 @@ static bool __init chacha20poly1305_selftest(void)
continue;
memcpy(computed_output, chacha20poly1305_enc_vectors[i].input,
chacha20poly1305_enc_vectors[i].ilen);
- sg_init_one(&sg_src, computed_output,
+ sg_init_one(sg_src, computed_output,
chacha20poly1305_enc_vectors[i].ilen +
POLY1305_MAC_SIZE);
- ret = chacha20poly1305_encrypt_sg_inplace(&sg_src,
+ ret = chacha20poly1305_encrypt_sg_inplace(sg_src,
chacha20poly1305_enc_vectors[i].ilen,
chacha20poly1305_enc_vectors[i].assoc,
chacha20poly1305_enc_vectors[i].alen,
@@ -8961,9 +8962,9 @@ static bool __init chacha20poly1305_selftest(void)
for (i = 0; i < ARRAY_SIZE(chacha20poly1305_dec_vectors); ++i) {
memcpy(computed_output, chacha20poly1305_dec_vectors[i].input,
chacha20poly1305_dec_vectors[i].ilen);
- sg_init_one(&sg_src, computed_output,
+ sg_init_one(sg_src, computed_output,
chacha20poly1305_dec_vectors[i].ilen);
- ret = chacha20poly1305_decrypt_sg_inplace(&sg_src,
+ ret = chacha20poly1305_decrypt_sg_inplace(sg_src,
chacha20poly1305_dec_vectors[i].ilen,
chacha20poly1305_dec_vectors[i].assoc,
chacha20poly1305_dec_vectors[i].alen,
@@ -9019,7 +9020,57 @@ static bool __init chacha20poly1305_selftest(void)
}
}
+ simd_get(&simd_context);
+ for (total_len = POLY1305_MAC_SIZE; IS_ENABLED(DEBUG_CHACHA20POLY1305_SLOW_CHUNK_TEST)
+ && total_len <= 1 << 10; ++total_len) {
+ for (i = 0; i <= total_len; ++i) {
+ for (j = i; j <= total_len; ++j) {
+ sg_init_table(sg_src, 3);
+ sg_set_buf(&sg_src[0], input, i);
+ sg_set_buf(&sg_src[1], input + i, j - i);
+ sg_set_buf(&sg_src[2], input + j, total_len - j);
+ memset(computed_output, 0, total_len);
+ memset(input, 0, total_len);
+
+ if (!chacha20poly1305_encrypt_sg_inplace(sg_src,
+ total_len - POLY1305_MAC_SIZE, NULL, 0,
+ 0, enc_key001, &simd_context))
+ goto chunkfail;
+ chacha20poly1305_encrypt(computed_output,
+ computed_output,
+ total_len - POLY1305_MAC_SIZE, NULL, 0, 0,
+ enc_key001);
+ if (memcmp(computed_output, input, total_len))
+ goto chunkfail;;
+ if (!chacha20poly1305_decrypt(computed_output,
+ input, total_len, NULL, 0, 0, enc_key001))
+ goto chunkfail;
+ for (k = 0; k < total_len - POLY1305_MAC_SIZE; ++k) {
+ if (computed_output[k])
+ goto chunkfail;
+ }
+ if (!chacha20poly1305_decrypt_sg_inplace(sg_src,
+ total_len, NULL, 0, 0, enc_key001,
+ &simd_context))
+ goto chunkfail;
+ for (k = 0; k < total_len - POLY1305_MAC_SIZE; ++k) {
+ if (input[k])
+ goto chunkfail;
+ }
+ continue;
+
+ chunkfail:
+ pr_err("chacha20poly1305 chunked self-test %zu/%zu/%zu: FAIL\n",
+ total_len, i, j);
+ success = false;
+ }
+
+ }
+ }
+ simd_put(&simd_context);
+
out:
kfree(computed_output);
+ kfree(input);
return success;
}
diff --git a/src/dkms.conf b/src/dkms.conf
index 194f27b..cdcd2e7 100644
--- a/src/dkms.conf
+++ b/src/dkms.conf
@@ -1,5 +1,5 @@
PACKAGE_NAME="wireguard"
-PACKAGE_VERSION="0.0.20191205"
+PACKAGE_VERSION="0.0.20191219"
AUTOINSTALL=yes
BUILT_MODULE_NAME="wireguard"
diff --git a/src/main.c b/src/main.c
index 4b5b58e..9ca4195 100644
--- a/src/main.c
+++ b/src/main.c
@@ -12,7 +12,6 @@
#include "uapi/wireguard.h"
#include "crypto/zinc.h"
-#include <linux/version.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/genetlink.h>
diff --git a/src/receive.c b/src/receive.c
index dfd6e40..e00f0f4 100644
--- a/src/receive.c
+++ b/src/receive.c
@@ -382,7 +382,7 @@ static void wg_packet_consume_data_done(struct wg_peer *peer,
/* We've already verified the Poly1305 auth tag, which means this packet
* was not modified in transit. We can therefore tell the networking
* stack that all checksums of every layer of encapsulation have already
- * been checked "by the hardware" and therefore is unneccessary to check
+ * been checked "by the hardware" and therefore is unnecessary to check
* again in software.
*/
skb->ip_summed = CHECKSUM_UNNECESSARY;
diff --git a/src/socket.c b/src/socket.c
index a90dadd..c46256d 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -142,9 +142,10 @@ static int send6(struct wg_device *wg, struct sk_buff *skb,
if (cache)
dst_cache_reset(cache);
}
- ret = ipv6_stub->ipv6_dst_lookup(sock_net(sock), sock, &dst,
- &fl);
- if (unlikely(ret)) {
+ dst = ipv6_stub->ipv6_dst_lookup_flow(sock_net(sock), sock, &fl,
+ NULL);
+ if (unlikely(IS_ERR(dst))) {
+ ret = PTR_ERR(dst);
net_dbg_ratelimited("%s: No route to %pISpfsc, error %d\n",
wg->dev->name, &endpoint->addr, ret);
goto err;
diff --git a/src/tools/man/wg.8 b/src/tools/man/wg.8
index 043ffb0..ac281bc 100644
--- a/src/tools/man/wg.8
+++ b/src/tools/man/wg.8
@@ -122,7 +122,7 @@ A private key and a corresponding public key may be generated at once by calling
$ wg genkey | tee private.key | wg pubkey > public.key
.TP
\fBhelp\fP
-Show usage message.
+Shows usage message.
.SH CONFIGURATION FILE FORMAT
The configuration file format is based on \fIINI\fP. There are two top level sections
diff --git a/src/tools/wg-quick/android.c b/src/tools/wg-quick/android.c
index 144d462..ad05895 100644
--- a/src/tools/wg-quick/android.c
+++ b/src/tools/wg-quick/android.c
@@ -390,10 +390,10 @@ static int32_t string_array_size(char *const *array)
return size;
}
-static const char *string_array_getter(const void *array_data, size_t index, int32_t *outlength)
+static const char *string_array_getter(const void *array_data, size_t index, int32_t *out_length)
{
const char **array = (const char **)array_data;
- *outlength = array[index] ? strlen(array[index]) : -1;
+ *out_length = array[index] ? strlen(array[index]) : -1;
return array[index];
}
diff --git a/src/tools/wg-quick/linux.bash b/src/tools/wg-quick/linux.bash
index fc90e55..e9c9052 100755
--- a/src/tools/wg-quick/linux.bash
+++ b/src/tools/wg-quick/linux.bash
@@ -95,18 +95,18 @@ add_if() {
del_if() {
local table
[[ $HAVE_SET_DNS -eq 0 ]] || unset_dns
- [[ $HAVE_SET_IPTABLES -eq 0 ]] || remove_iptables
+ [[ $HAVE_SET_FIREWALL -eq 0 ]] || remove_firewall
if [[ -z $TABLE || $TABLE == auto ]] && get_fwmark table && [[ $(wg show "$INTERFACE" allowed-ips) =~ /0(\ |$'\n'|$) ]]; then
- while [[ $(ip -4 rule show) == *"lookup $table"* ]]; do
+ while [[ $(ip -4 rule show 2>/dev/null) == *"lookup $table"* ]]; do
cmd ip -4 rule delete table $table
done
- while [[ $(ip -4 rule show) == *"from all lookup main suppress_prefixlength 0"* ]]; do
+ while [[ $(ip -4 rule show 2>/dev/null) == *"from all lookup main suppress_prefixlength 0"* ]]; do
cmd ip -4 rule delete table main suppress_prefixlength 0
done
- while [[ $(ip -6 rule show) == *"lookup $table"* ]]; do
+ while [[ $(ip -6 rule show 2>/dev/null) == *"lookup $table"* ]]; do
cmd ip -6 rule delete table $table
done
- while [[ $(ip -6 rule show) == *"from all lookup main suppress_prefixlength 0"* ]]; do
+ while [[ $(ip -6 rule show 2>/dev/null) == *"from all lookup main suppress_prefixlength 0"* ]]; do
cmd ip -6 rule delete table main suppress_prefixlength 0
done
fi
@@ -181,22 +181,31 @@ get_fwmark() {
return 0
}
-remove_iptables() {
- local line iptables found restore
- for iptables in iptables ip6tables; do
- restore="" found=0
- while read -r line; do
- [[ $line == "*"* || $line == COMMIT || $line == "-A "*"-m comment --comment \"wg-quick(8) rule for $INTERFACE\""* ]] || continue
- [[ $line == "-A"* ]] && found=1
- printf -v restore '%s\n%s' "$restore" "${line/#-A/-D}"
- done < <($iptables-save)
- [[ $found -ne 1 ]] || echo "$restore" | cmd $iptables-restore -n
- done
+remove_firewall() {
+ if type -p nft >/dev/null; then
+ local table nftcmd
+ while read -r table; do
+ [[ $table == *" wg-quick-$INTERFACE" ]] && printf -v nftcmd '%sdelete %s\n' "$nftcmd" "$table"
+ done < <(nft list tables 2>/dev/null)
+ [[ -z $nftcmd ]] || cmd nft -f <(echo -n "$nftcmd")
+ fi
+ if type -p iptables >/dev/null; then
+ local line iptables found restore
+ for iptables in iptables ip6tables; do
+ restore="" found=0
+ while read -r line; do
+ [[ $line == "*"* || $line == COMMIT || $line == "-A "*"-m comment --comment \"wg-quick(8) rule for $INTERFACE\""* ]] || continue
+ [[ $line == "-A"* ]] && found=1
+ printf -v restore '%s%s\n' "$restore" "${line/#-A/-D}"
+ done < <($iptables-save 2>/dev/null)
+ [[ $found -ne 1 ]] || echo -n "$restore" | cmd $iptables-restore -n
+ done
+ fi
}
-HAVE_SET_IPTABLES=0
+HAVE_SET_FIREWALL=0
add_default() {
- local table proto i iptables
+ local table line
if ! get_fwmark table; then
table=51820
while [[ -n $(ip -4 route show table $table 2>/dev/null) || -n $(ip -6 route show table $table 2>/dev/null) ]]; do
@@ -204,21 +213,32 @@ add_default() {
done
cmd wg set "$INTERFACE" fwmark $table
fi
- proto=-4 iptables=iptables
- [[ $1 == *:* ]] && proto=-6 iptables=ip6tables
+ local proto=-4 iptables=iptables pf=ip
+ [[ $1 == *:* ]] && proto=-6 iptables=ip6tables pf=ip6
cmd ip $proto route add "$1" dev "$INTERFACE" table $table
cmd ip $proto rule add not fwmark $table table $table
cmd ip $proto rule add table main suppress_prefixlength 0
- local marker="-m comment --comment \"wg-quick(8) rule for $INTERFACE\"" restore="*raw"
- for i in "${ADDRESSES[@]}"; do
- [[ ( $proto == -4 && $i != *:* ) || ( $proto == -6 && $i == *:* ) ]] || continue
- printf -v restore '%s\n-I PREROUTING ! -i %s -d %s -m addrtype ! --src-type LOCAL -j DROP %s\n' "$restore" "$INTERFACE" "${i%/*}" "$marker"
- done
- printf -v restore '%s\nCOMMIT\n*mangle\n-I POSTROUTING -m mark --mark %d -p udp -j CONNMARK --save-mark %s\n-I PREROUTING -p udp -j CONNMARK --restore-mark %s\nCOMMIT\n' "$restore" $table "$marker" "$marker"
+ local marker="-m comment --comment \"wg-quick(8) rule for $INTERFACE\"" restore=$'*raw\n' nftable="wg-quick-$INTERFACE" nftcmd
+ printf -v nftcmd '%sadd table %s %s\n' "$nftcmd" "$pf" "$nftable"
+ printf -v nftcmd '%sadd chain %s %s preraw { type filter hook prerouting priority -300; }\n' "$nftcmd" "$pf" "$nftable"
+ printf -v nftcmd '%sadd chain %s %s premangle { type filter hook prerouting priority -150; }\n' "$nftcmd" "$pf" "$nftable"
+ printf -v nftcmd '%sadd chain %s %s postmangle { type filter hook postrouting priority -150; }\n' "$nftcmd" "$pf" "$nftable"
+ while read -r line; do
+ [[ $line =~ .*inet6?\ ([0-9a-f:.]+)/[0-9]+.* ]] || continue
+ printf -v restore '%s-I PREROUTING ! -i %s -d %s -m addrtype ! --src-type LOCAL -j DROP %s\n' "$restore" "$INTERFACE" "${BASH_REMATCH[1]}" "$marker"
+ printf -v nftcmd '%sadd rule %s %s preraw iifname != %s %s daddr %s fib saddr type != local drop\n' "$nftcmd" "$pf" "$nftable" "$INTERFACE" "$pf" "${BASH_REMATCH[1]}"
+ done < <(ip -o $proto addr show dev "$INTERFACE" 2>/dev/null)
+ printf -v restore '%sCOMMIT\n*mangle\n-I POSTROUTING -m mark --mark %d -p udp -j CONNMARK --save-mark %s\n-I PREROUTING -p udp -j CONNMARK --restore-mark %s\nCOMMIT\n' "$restore" $table "$marker" "$marker"
+ printf -v nftcmd '%sadd rule %s %s postmangle meta l4proto udp mark %d ct mark set mark \n' "$nftcmd" "$pf" "$nftable" $table
+ printf -v nftcmd '%sadd rule %s %s premangle meta l4proto udp meta mark set ct mark \n' "$nftcmd" "$pf" "$nftable"
[[ $proto == -4 ]] && cmd sysctl -q net.ipv4.conf.all.src_valid_mark=1
- echo "$restore" | cmd $iptables-restore -n
- HAVE_SET_IPTABLES=1
+ if type -p nft >/dev/null; then
+ cmd nft -f <(echo -n "$nftcmd")
+ else
+ echo -n "$restore" | cmd $iptables-restore -n
+ fi
+ HAVE_SET_FIREWALL=1
return 0
}
@@ -323,7 +343,7 @@ cmd_down() {
[[ $SAVE_CONFIG -eq 0 ]] || save_config
del_if
unset_dns || true
- remove_iptables || true
+ remove_firewall || true
execute_hooks "${POST_DOWN[@]}"
}
diff --git a/src/uapi/wireguard.h b/src/uapi/wireguard.h
index dd8a47c..ae88be1 100644
--- a/src/uapi/wireguard.h
+++ b/src/uapi/wireguard.h
@@ -18,13 +18,13 @@
* one but not both of:
*
* WGDEVICE_A_IFINDEX: NLA_U32
- * WGDEVICE_A_IFNAME: NLA_NUL_STRING, maxlen IFNAMESIZ - 1
+ * WGDEVICE_A_IFNAME: NLA_NUL_STRING, maxlen IFNAMSIZ - 1
*
* The kernel will then return several messages (NLM_F_MULTI) containing the
* following tree of nested items:
*
* WGDEVICE_A_IFINDEX: NLA_U32
- * WGDEVICE_A_IFNAME: NLA_NUL_STRING, maxlen IFNAMESIZ - 1
+ * WGDEVICE_A_IFNAME: NLA_NUL_STRING, maxlen IFNAMSIZ - 1
* WGDEVICE_A_PRIVATE_KEY: NLA_EXACT_LEN, len WG_KEY_LEN
* WGDEVICE_A_PUBLIC_KEY: NLA_EXACT_LEN, len WG_KEY_LEN
* WGDEVICE_A_LISTEN_PORT: NLA_U16
@@ -77,7 +77,7 @@
* WGDEVICE_A_IFINDEX and WGDEVICE_A_IFNAME:
*
* WGDEVICE_A_IFINDEX: NLA_U32
- * WGDEVICE_A_IFNAME: NLA_NUL_STRING, maxlen IFNAMESIZ - 1
+ * WGDEVICE_A_IFNAME: NLA_NUL_STRING, maxlen IFNAMSIZ - 1
* WGDEVICE_A_FLAGS: NLA_U32, 0 or WGDEVICE_F_REPLACE_PEERS if all current
* peers should be removed prior to adding the list below.
* WGDEVICE_A_PRIVATE_KEY: len WG_KEY_LEN, all zeros to remove
@@ -121,7 +121,7 @@
* filling in information not contained in the prior. Note that if
* WGDEVICE_F_REPLACE_PEERS is specified in the first message, it probably
* should not be specified in fragments that come after, so that the list
- * of peers is only cleared the first time but appened after. Likewise for
+ * of peers is only cleared the first time but appended after. Likewise for
* peers, if WGPEER_F_REPLACE_ALLOWEDIPS is specified in the first message
* of a peer, it likely should not be specified in subsequent fragments.
*
diff --git a/src/version.h b/src/version.h
index 4e2bb40..ddba103 100644
--- a/src/version.h
+++ b/src/version.h
@@ -1 +1 @@
-#define WIREGUARD_VERSION "0.0.20191205"
+#define WIREGUARD_VERSION "0.0.20191219"