Initial commit

This commit is contained in:
Iurii Egorov
2023-11-30 11:04:56 +03:00
commit 932f0d2134
14 changed files with 2545 additions and 0 deletions

40
kmod-amneziawg/Makefile Normal file
View File

@@ -0,0 +1,40 @@
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=kmod-amneziawg
PKG_RELEASE:=1
include $(INCLUDE_DIR)/package.mk
define KernelPackage/amneziawg
SECTION:=kernel
CATEGORY:=Kernel modules
SUBMENU:=Network Support
TITLE:=AmneziaWG VPN Kernel Module
FILES:=$(PKG_BUILD_DIR)/amneziawg.ko
DEPENDS:= \
+kmod-udptunnel4 \
+kmod-udptunnel6 \
+kmod-crypto-lib-chacha20poly1305 \
+kmod-crypto-lib-curve25519
endef
define Build/Prepare
cp -fr $(LINUX_DIR)/drivers/net/wireguard/{*.c,*.h,selftest/} $(PKG_BUILD_DIR)
mkdir -p $(PKG_BUILD_DIR)/uapi
cp -f $(LINUX_DIR)/include/uapi/linux/wireguard.h $(PKG_BUILD_DIR)/uapi/
patch -d $(PKG_BUILD_DIR)/ < files/amnezia-sources.patch
patch -d $(PKG_BUILD_DIR)/uapi/ < files/amnezia-uapi.patch
cp -f src/Makefile $(PKG_BUILD_DIR)
endef
define Build/Compile
$(MAKE) -C "$(LINUX_DIR)" \
$(KERNEL_MAKE_FLAGS) \
M="$(PKG_BUILD_DIR)" \
EXTRA_CFLAGS="$(BUILDFLAGS)" \
modules
endef
$(eval $(call KernelPackage,amneziawg))

View File

@@ -0,0 +1,757 @@
diff --color -urN -x uapi -x compat -x crypto -x .idea -x tests -x Kbuild -x Kconfig -x Makefile -x dkms.conf ../../linux-source-6.2.0/drivers/net/wireguard/cookie.c ./cookie.c
--- ../../linux-source-6.2.0/drivers/net/wireguard/cookie.c 2023-11-10 18:10:29
+++ ./cookie.c 2023-11-23 18:59:07
@@ -179,13 +179,13 @@
void wg_cookie_message_create(struct message_handshake_cookie *dst,
struct sk_buff *skb, __le32 index,
- struct cookie_checker *checker)
+ struct cookie_checker *checker, u32 message_type)
{
struct message_macs *macs = (struct message_macs *)
((u8 *)skb->data + skb->len - sizeof(*macs));
u8 cookie[COOKIE_LEN];
- dst->header.type = cpu_to_le32(MESSAGE_HANDSHAKE_COOKIE);
+ dst->header.type = cpu_to_le32(message_type);
dst->receiver_index = index;
get_random_bytes_wait(dst->nonce, COOKIE_NONCE_LEN);
diff --color -urN -x uapi -x compat -x crypto -x .idea -x tests -x Kbuild -x Kconfig -x Makefile -x dkms.conf ../../linux-source-6.2.0/drivers/net/wireguard/cookie.h ./cookie.h
--- ../../linux-source-6.2.0/drivers/net/wireguard/cookie.h 2023-11-10 18:10:29
+++ ./cookie.h 2023-11-23 13:11:40
@@ -52,7 +52,7 @@
void wg_cookie_message_create(struct message_handshake_cookie *src,
struct sk_buff *skb, __le32 index,
- struct cookie_checker *checker);
+ struct cookie_checker *checker, u32 message_type);
void wg_cookie_message_consume(struct message_handshake_cookie *src,
struct wg_device *wg);
diff --color -urN -x uapi -x compat -x crypto -x .idea -x tests -x Kbuild -x Kconfig -x Makefile -x dkms.conf ../../linux-source-6.2.0/drivers/net/wireguard/device.c ./device.c
--- ../../linux-source-6.2.0/drivers/net/wireguard/device.c 2023-11-10 18:10:29
+++ ./device.c 2023-11-26 17:42:17
@@ -379,6 +379,11 @@
*/
dev->priv_destructor = wg_destruct;
+ wg->advanced_security_config.init_packet_magic_header = MESSAGE_HANDSHAKE_INITIATION;
+ wg->advanced_security_config.response_packet_magic_header = MESSAGE_HANDSHAKE_RESPONSE;
+ wg->advanced_security_config.cookie_packet_magic_header = MESSAGE_HANDSHAKE_COOKIE;
+ wg->advanced_security_config.transport_packet_magic_header = MESSAGE_DATA;
+
pr_debug("%s: Interface created\n", dev->name);
return ret;
@@ -475,4 +480,79 @@
unregister_random_vmfork_notifier(&vm_notifier);
unregister_pm_notifier(&pm_notifier);
rcu_barrier();
+}
+
+void wg_device_handle_post_config(struct net_device *dev, struct amnezia_config *asc)
+{
+ struct wg_device *wg = netdev_priv(dev);
+ bool a_sec_on = false;
+
+ if (!asc->advanced_security_enabled)
+ return;
+
+ if (asc->junk_packet_count < 0) {
+ // TODO error
+ }
+
+ wg->advanced_security_config.junk_packet_count = asc->junk_packet_count;
+ if (asc->junk_packet_count != 0)
+ a_sec_on = true;
+
+ wg->advanced_security_config.junk_packet_min_size = asc->junk_packet_min_size;
+ if (asc->junk_packet_min_size != 0)
+ a_sec_on = true;
+
+ if (asc->junk_packet_count > 0 && asc->junk_packet_min_size == asc->junk_packet_max_size)
+ asc->junk_packet_max_size++;
+
+ if (asc->junk_packet_max_size >= MESSAGE_MAX_SIZE) {
+ wg->advanced_security_config.junk_packet_min_size = 0;
+ wg->advanced_security_config.junk_packet_max_size = 1;
+
+ // TODO error
+ } else if (asc->junk_packet_max_size < asc->junk_packet_min_size) {
+ // TODO error
+ } else
+ wg->advanced_security_config.junk_packet_max_size = asc->junk_packet_max_size;
+
+ if (asc->junk_packet_max_size != 0)
+ a_sec_on = true;
+
+ if (asc->init_packet_junk_size + MESSAGE_INITIATION_SIZE >= MESSAGE_MAX_SIZE) {
+ // TODO error
+ } else
+ wg->advanced_security_config.init_packet_junk_size = asc->init_packet_junk_size;
+
+ if (asc->init_packet_junk_size != 0)
+ a_sec_on = true;
+
+ if (asc->response_packet_junk_size + MESSAGE_RESPONSE_SIZE >= MESSAGE_MAX_SIZE) {
+ // TODO error
+ } else
+ wg->advanced_security_config.response_packet_junk_size = asc->response_packet_junk_size;
+
+ if (asc->response_packet_junk_size != 0)
+ a_sec_on = true;
+
+ if (asc->init_packet_magic_header > MESSAGE_DATA) {
+ a_sec_on = true;
+ wg->advanced_security_config.init_packet_magic_header = asc->init_packet_magic_header;
+ }
+
+ if (asc->response_packet_magic_header > MESSAGE_DATA) {
+ a_sec_on = true;
+ wg->advanced_security_config.response_packet_magic_header = asc->response_packet_magic_header;
+ }
+
+ if (asc->cookie_packet_magic_header > MESSAGE_DATA) {
+ a_sec_on = true;
+ wg->advanced_security_config.cookie_packet_magic_header = asc->cookie_packet_magic_header;
+ }
+
+ if (asc->transport_packet_magic_header > MESSAGE_DATA) {
+ a_sec_on = true;
+ wg->advanced_security_config.transport_packet_magic_header = asc->transport_packet_magic_header;
+ }
+
+ wg->advanced_security_config.advanced_security_enabled = a_sec_on;
}
diff --color -urN -x uapi -x compat -x crypto -x .idea -x tests -x Kbuild -x Kconfig -x Makefile -x dkms.conf ../../linux-source-6.2.0/drivers/net/wireguard/device.h ./device.h
--- ../../linux-source-6.2.0/drivers/net/wireguard/device.h 2023-11-10 18:10:29
+++ ./device.h 2023-11-23 18:48:52
@@ -37,6 +37,19 @@
atomic_t count;
};
+struct amnezia_config {
+ bool advanced_security_enabled;
+ u16 junk_packet_count;
+ u16 junk_packet_min_size;
+ u16 junk_packet_max_size;
+ u16 init_packet_junk_size;
+ u16 response_packet_junk_size;
+ u32 init_packet_magic_header;
+ u32 response_packet_magic_header;
+ u32 cookie_packet_magic_header;
+ u32 transport_packet_magic_header;
+};
+
struct wg_device {
struct net_device *dev;
struct crypt_queue encrypt_queue, decrypt_queue, handshake_queue;
@@ -50,6 +63,7 @@
struct allowedips peer_allowedips;
struct mutex device_update_lock, socket_update_lock;
struct list_head device_list, peer_list;
+ struct amnezia_config advanced_security_config;
atomic_t handshake_queue_len;
unsigned int num_peers, device_update_gen;
u32 fwmark;
@@ -58,5 +72,6 @@
int wg_device_init(void);
void wg_device_uninit(void);
+void wg_device_handle_post_config(struct net_device *dev, struct amnezia_config *asc);
#endif /* _WG_DEVICE_H */
diff --color -urN -x uapi -x compat -x crypto -x .idea -x tests -x Kbuild -x Kconfig -x Makefile -x dkms.conf ../../linux-source-6.2.0/drivers/net/wireguard/main.c ./main.c
--- ../../linux-source-6.2.0/drivers/net/wireguard/main.c 2023-11-10 18:10:29
+++ ./main.c 2023-11-22 16:37:56
@@ -3,14 +3,13 @@
* Copyright (C) 2015-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
*/
-#include "version.h"
#include "device.h"
#include "noise.h"
#include "queueing.h"
#include "ratelimiter.h"
#include "netlink.h"
-#include <uapi/linux/wireguard.h>
+#include "uapi/wireguard.h"
#include <linux/init.h>
#include <linux/module.h>
@@ -45,7 +44,7 @@
if (ret < 0)
goto err_netlink;
- pr_info("WireGuard " WIREGUARD_VERSION " loaded. See www.wireguard.com for information.\n");
+ pr_info("WireGuard " WIREGUARD_VERSION " (Amnezia VPN) loaded. See www.wireguard.com for information.\n");
pr_info("Copyright (C) 2015-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.\n");
return 0;
@@ -71,7 +70,7 @@
module_init(wg_mod_init);
module_exit(wg_mod_exit);
MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("WireGuard secure network tunnel");
+MODULE_DESCRIPTION("WireGuard (Amnezia VPN) secure network tunnel");
MODULE_AUTHOR("Jason A. Donenfeld <Jason@zx2c4.com>");
MODULE_VERSION(WIREGUARD_VERSION);
MODULE_ALIAS_RTNL_LINK(KBUILD_MODNAME);
diff --color -urN -x uapi -x compat -x crypto -x .idea -x tests -x Kbuild -x Kconfig -x Makefile -x dkms.conf ../../linux-source-6.2.0/drivers/net/wireguard/messages.h ./messages.h
--- ../../linux-source-6.2.0/drivers/net/wireguard/messages.h 2023-11-10 18:10:29
+++ ./messages.h 2023-11-22 19:16:03
@@ -117,6 +117,14 @@
MESSAGE_MINIMUM_LENGTH = message_data_len(0)
};
+enum message_size {
+ MESSAGE_INITIATION_SIZE = sizeof(struct message_handshake_initiation),
+ MESSAGE_RESPONSE_SIZE = sizeof(struct message_handshake_response),
+ MESSAGE_COOKIE_REPLY_SIZE = sizeof(struct message_handshake_cookie),
+ MESSAGE_TRANSPORT_SIZE = sizeof(struct message_data),
+ MESSAGE_MAX_SIZE = 65535
+};
+
#define SKB_HEADER_LEN \
(max(sizeof(struct iphdr), sizeof(struct ipv6hdr)) + \
sizeof(struct udphdr) + NET_SKB_PAD)
diff --color -urN -x uapi -x compat -x crypto -x .idea -x tests -x Kbuild -x Kconfig -x Makefile -x dkms.conf ../../linux-source-6.2.0/drivers/net/wireguard/netlink.c ./netlink.c
--- ../../linux-source-6.2.0/drivers/net/wireguard/netlink.c 2023-11-10 18:10:29
+++ ./netlink.c 2023-11-26 17:34:30
@@ -10,7 +10,7 @@
#include "queueing.h"
#include "messages.h"
-#include <uapi/linux/wireguard.h>
+#include "uapi/wireguard.h"
#include <linux/if.h>
#include <net/genetlink.h>
@@ -27,7 +27,16 @@
[WGDEVICE_A_FLAGS] = { .type = NLA_U32 },
[WGDEVICE_A_LISTEN_PORT] = { .type = NLA_U16 },
[WGDEVICE_A_FWMARK] = { .type = NLA_U32 },
- [WGDEVICE_A_PEERS] = { .type = NLA_NESTED }
+ [WGDEVICE_A_PEERS] = { .type = NLA_NESTED },
+ [WGDEVICE_A_JC] = { .type = NLA_U16 },
+ [WGDEVICE_A_JMIN] = { .type = NLA_U16 },
+ [WGDEVICE_A_JMAX] = { .type = NLA_U16 },
+ [WGDEVICE_A_S1] = { .type = NLA_U16 },
+ [WGDEVICE_A_S2] = { .type = NLA_U16 },
+ [WGDEVICE_A_H1] = { .type = NLA_U32 },
+ [WGDEVICE_A_H2] = { .type = NLA_U32 },
+ [WGDEVICE_A_H3] = { .type = NLA_U32 },
+ [WGDEVICE_A_H4] = { .type = NLA_U32 }
};
static const struct nla_policy peer_policy[WGPEER_A_MAX + 1] = {
@@ -233,7 +242,25 @@
wg->incoming_port) ||
nla_put_u32(skb, WGDEVICE_A_FWMARK, wg->fwmark) ||
nla_put_u32(skb, WGDEVICE_A_IFINDEX, wg->dev->ifindex) ||
- nla_put_string(skb, WGDEVICE_A_IFNAME, wg->dev->name))
+ nla_put_string(skb, WGDEVICE_A_IFNAME, wg->dev->name) ||
+ nla_put_u16(skb, WGDEVICE_A_JC,
+ wg->advanced_security_config.junk_packet_count) ||
+ nla_put_u16(skb, WGDEVICE_A_JMIN,
+ wg->advanced_security_config.junk_packet_min_size) ||
+ nla_put_u16(skb, WGDEVICE_A_JMAX,
+ wg->advanced_security_config.junk_packet_max_size) ||
+ nla_put_u16(skb, WGDEVICE_A_S1,
+ wg->advanced_security_config.init_packet_junk_size) ||
+ nla_put_u16(skb, WGDEVICE_A_S2,
+ wg->advanced_security_config.response_packet_junk_size) ||
+ nla_put_u32(skb, WGDEVICE_A_H1,
+ wg->advanced_security_config.init_packet_magic_header) ||
+ nla_put_u32(skb, WGDEVICE_A_H2,
+ wg->advanced_security_config.response_packet_magic_header) ||
+ nla_put_u32(skb, WGDEVICE_A_H3,
+ wg->advanced_security_config.cookie_packet_magic_header) ||
+ nla_put_u32(skb, WGDEVICE_A_H4,
+ wg->advanced_security_config.transport_packet_magic_header))
goto out;
down_read(&wg->static_identity.lock);
@@ -493,6 +520,7 @@
static int wg_set_device(struct sk_buff *skb, struct genl_info *info)
{
struct wg_device *wg = lookup_interface(info->attrs, skb);
+ struct amnezia_config *asc = kzalloc(sizeof(*asc), GFP_KERNEL);
u32 flags = 0;
int ret;
@@ -537,6 +565,51 @@
goto out;
}
+ if (info->attrs[WGDEVICE_A_JC]) {
+ asc->advanced_security_enabled = true;
+ asc->junk_packet_count = nla_get_u16(info->attrs[WGDEVICE_A_JC]);
+ }
+
+ if (info->attrs[WGDEVICE_A_JMIN]) {
+ asc->advanced_security_enabled = true;
+ asc->junk_packet_min_size = nla_get_u16(info->attrs[WGDEVICE_A_JMIN]);
+ }
+
+ if (info->attrs[WGDEVICE_A_JMAX]) {
+ asc->advanced_security_enabled = true;
+ asc->junk_packet_max_size = nla_get_u16(info->attrs[WGDEVICE_A_JMAX]);
+ }
+
+ if (info->attrs[WGDEVICE_A_S1]) {
+ asc->advanced_security_enabled = true;
+ asc->init_packet_junk_size = nla_get_u16(info->attrs[WGDEVICE_A_S1]);
+ }
+
+ if (info->attrs[WGDEVICE_A_S2]) {
+ asc->advanced_security_enabled = true;
+ asc->response_packet_junk_size = nla_get_u16(info->attrs[WGDEVICE_A_S2]);
+ }
+
+ if (info->attrs[WGDEVICE_A_H1]) {
+ asc->advanced_security_enabled = true;
+ asc->init_packet_magic_header = nla_get_u32(info->attrs[WGDEVICE_A_H1]);
+ }
+
+ if (info->attrs[WGDEVICE_A_H2]) {
+ asc->advanced_security_enabled = true;
+ asc->response_packet_magic_header = nla_get_u32(info->attrs[WGDEVICE_A_H2]);
+ }
+
+ if (info->attrs[WGDEVICE_A_H3]) {
+ asc->advanced_security_enabled = true;
+ asc->cookie_packet_magic_header = nla_get_u32(info->attrs[WGDEVICE_A_H3]);
+ }
+
+ if (info->attrs[WGDEVICE_A_H4]) {
+ asc->advanced_security_enabled = true;
+ asc->transport_packet_magic_header = nla_get_u32(info->attrs[WGDEVICE_A_H4]);
+ }
+
if (flags & WGDEVICE_F_REPLACE_PEERS)
wg_peer_remove_all(wg);
@@ -597,10 +670,12 @@
ret = 0;
out:
+ wg_device_handle_post_config(wg->dev, asc);
mutex_unlock(&wg->device_update_lock);
rtnl_unlock();
dev_put(wg->dev);
out_nodev:
+ kfree(asc);
if (info->attrs[WGDEVICE_A_PRIVATE_KEY])
memzero_explicit(nla_data(info->attrs[WGDEVICE_A_PRIVATE_KEY]),
nla_len(info->attrs[WGDEVICE_A_PRIVATE_KEY]));
diff --color -urN -x uapi -x compat -x crypto -x .idea -x tests -x Kbuild -x Kconfig -x Makefile -x dkms.conf ../../linux-source-6.2.0/drivers/net/wireguard/noise.c ./noise.c
--- ../../linux-source-6.2.0/drivers/net/wireguard/noise.c 2023-11-10 18:10:29
+++ ./noise.c 2023-11-23 18:58:26
@@ -515,7 +515,7 @@
bool
wg_noise_handshake_create_initiation(struct message_handshake_initiation *dst,
- struct noise_handshake *handshake)
+ struct noise_handshake *handshake, u32 message_type)
{
u8 timestamp[NOISE_TIMESTAMP_LEN];
u8 key[NOISE_SYMMETRIC_KEY_LEN];
@@ -532,7 +532,7 @@
if (unlikely(!handshake->static_identity->has_identity))
goto out;
- dst->header.type = cpu_to_le32(MESSAGE_HANDSHAKE_INITIATION);
+ dst->header.type = cpu_to_le32(message_type);
handshake_init(handshake->chaining_key, handshake->hash,
handshake->remote_static);
@@ -665,7 +665,7 @@
}
bool wg_noise_handshake_create_response(struct message_handshake_response *dst,
- struct noise_handshake *handshake)
+ struct noise_handshake *handshake, u32 message_type)
{
u8 key[NOISE_SYMMETRIC_KEY_LEN];
bool ret = false;
@@ -681,7 +681,7 @@
if (handshake->state != HANDSHAKE_CONSUMED_INITIATION)
goto out;
- dst->header.type = cpu_to_le32(MESSAGE_HANDSHAKE_RESPONSE);
+ dst->header.type = cpu_to_le32(message_type);
dst->receiver_index = handshake->remote_index;
/* e */
diff --color -urN -x uapi -x compat -x crypto -x .idea -x tests -x Kbuild -x Kconfig -x Makefile -x dkms.conf ../../linux-source-6.2.0/drivers/net/wireguard/noise.h ./noise.h
--- ../../linux-source-6.2.0/drivers/net/wireguard/noise.h 2023-11-10 18:10:29
+++ ./noise.h 2023-11-23 13:12:55
@@ -118,13 +118,13 @@
bool
wg_noise_handshake_create_initiation(struct message_handshake_initiation *dst,
- struct noise_handshake *handshake);
+ struct noise_handshake *handshake, u32 message_type);
struct wg_peer *
wg_noise_handshake_consume_initiation(struct message_handshake_initiation *src,
struct wg_device *wg);
bool wg_noise_handshake_create_response(struct message_handshake_response *dst,
- struct noise_handshake *handshake);
+ struct noise_handshake *handshake, u32 message_type);
struct wg_peer *
wg_noise_handshake_consume_response(struct message_handshake_response *src,
struct wg_device *wg);
diff --color -urN -x uapi -x compat -x crypto -x .idea -x tests -x Kbuild -x Kconfig -x Makefile -x dkms.conf ../../linux-source-6.2.0/drivers/net/wireguard/receive.c ./receive.c
--- ../../linux-source-6.2.0/drivers/net/wireguard/receive.c 2023-11-10 18:10:29
+++ ./receive.c 2023-11-23 19:15:51
@@ -25,25 +25,51 @@
#define SKB_TYPE_LE32(skb) (((struct message_header *)(skb)->data)->type)
-static size_t validate_header_len(struct sk_buff *skb)
+static size_t validate_header_len(struct sk_buff *skb, struct wg_device *wg)
{
if (unlikely(skb->len < sizeof(struct message_header)))
return 0;
- if (SKB_TYPE_LE32(skb) == cpu_to_le32(MESSAGE_DATA) &&
+ if (SKB_TYPE_LE32(skb) == cpu_to_le32(wg->advanced_security_config.transport_packet_magic_header) &&
skb->len >= MESSAGE_MINIMUM_LENGTH)
return sizeof(struct message_data);
- if (SKB_TYPE_LE32(skb) == cpu_to_le32(MESSAGE_HANDSHAKE_INITIATION) &&
- skb->len == sizeof(struct message_handshake_initiation))
- return sizeof(struct message_handshake_initiation);
- if (SKB_TYPE_LE32(skb) == cpu_to_le32(MESSAGE_HANDSHAKE_RESPONSE) &&
- skb->len == sizeof(struct message_handshake_response))
- return sizeof(struct message_handshake_response);
- if (SKB_TYPE_LE32(skb) == cpu_to_le32(MESSAGE_HANDSHAKE_COOKIE) &&
- skb->len == sizeof(struct message_handshake_cookie))
- return sizeof(struct message_handshake_cookie);
+ if (SKB_TYPE_LE32(skb) == cpu_to_le32(wg->advanced_security_config.init_packet_magic_header) &&
+ skb->len == MESSAGE_INITIATION_SIZE)
+ return MESSAGE_INITIATION_SIZE;
+ if (SKB_TYPE_LE32(skb) == cpu_to_le32(wg->advanced_security_config.response_packet_magic_header) &&
+ skb->len == MESSAGE_RESPONSE_SIZE)
+ return MESSAGE_RESPONSE_SIZE;
+ if (SKB_TYPE_LE32(skb) == cpu_to_le32(wg->advanced_security_config.cookie_packet_magic_header) &&
+ skb->len == MESSAGE_COOKIE_REPLY_SIZE)
+ return MESSAGE_COOKIE_REPLY_SIZE;
return 0;
}
+void prepare_advanced_secured_message(struct sk_buff *skb, struct wg_device *wg)
+{
+ u32 assumed_type = SKB_TYPE_LE32(skb);
+ u32 assumed_offset;
+
+ if (wg->advanced_security_config.advanced_security_enabled) {
+ if (skb->len == MESSAGE_INITIATION_SIZE + wg->advanced_security_config.init_packet_junk_size) {
+ assumed_type = cpu_to_le32(wg->advanced_security_config.init_packet_magic_header);
+ assumed_offset = wg->advanced_security_config.init_packet_junk_size;
+ } else if (skb->len == MESSAGE_RESPONSE_SIZE + wg->advanced_security_config.response_packet_junk_size) {
+ assumed_type = cpu_to_le32(wg->advanced_security_config.response_packet_magic_header);
+ assumed_offset = wg->advanced_security_config.response_packet_junk_size;
+ } else
+ return;
+
+ if (unlikely(assumed_offset <= 0) || unlikely(!pskb_may_pull(skb, assumed_offset)))
+ return;
+
+ skb_pull(skb, assumed_offset);
+
+ if (SKB_TYPE_LE32(skb) != assumed_type) {
+ skb_push(skb, assumed_offset);
+ }
+ }
+}
+
static int prepare_skb_header(struct sk_buff *skb, struct wg_device *wg)
{
size_t data_offset, data_len, header_len;
@@ -79,7 +105,8 @@
if (unlikely(skb->len != data_len))
/* Final len does not agree with calculated len */
return -EINVAL;
- header_len = validate_header_len(skb);
+ prepare_advanced_secured_message(skb, wg);
+ header_len = validate_header_len(skb, wg);
if (unlikely(!header_len))
return -EINVAL;
__skb_push(skb, data_offset);
@@ -101,7 +128,7 @@
bool packet_needs_cookie;
bool under_load;
- if (SKB_TYPE_LE32(skb) == cpu_to_le32(MESSAGE_HANDSHAKE_COOKIE)) {
+ if (SKB_TYPE_LE32(skb) == cpu_to_le32(wg->advanced_security_config.cookie_packet_magic_header)) {
net_dbg_skb_ratelimited("%s: Receiving cookie response from %pISpfsc\n",
wg->dev->name, skb);
wg_cookie_message_consume(
@@ -131,8 +158,7 @@
return;
}
- switch (SKB_TYPE_LE32(skb)) {
- case cpu_to_le32(MESSAGE_HANDSHAKE_INITIATION): {
+ if (SKB_TYPE_LE32(skb) == cpu_to_le32(wg->advanced_security_config.init_packet_magic_header)) {
struct message_handshake_initiation *message =
(struct message_handshake_initiation *)skb->data;
@@ -152,9 +178,8 @@
wg->dev->name, peer->internal_id,
&peer->endpoint.addr);
wg_packet_send_handshake_response(peer);
- break;
}
- case cpu_to_le32(MESSAGE_HANDSHAKE_RESPONSE): {
+ if (SKB_TYPE_LE32(skb) == cpu_to_le32(wg->advanced_security_config.response_packet_magic_header)) {
struct message_handshake_response *message =
(struct message_handshake_response *)skb->data;
@@ -185,9 +210,7 @@
*/
wg_packet_send_keepalive(peer);
}
- break;
}
- }
if (unlikely(!peer)) {
WARN(1, "Somehow a wrong type of packet wound up in the handshake queue!\n");
@@ -543,10 +566,10 @@
{
if (unlikely(prepare_skb_header(skb, wg) < 0))
goto err;
- switch (SKB_TYPE_LE32(skb)) {
- case cpu_to_le32(MESSAGE_HANDSHAKE_INITIATION):
- case cpu_to_le32(MESSAGE_HANDSHAKE_RESPONSE):
- case cpu_to_le32(MESSAGE_HANDSHAKE_COOKIE): {
+
+ if (SKB_TYPE_LE32(skb) == cpu_to_le32(wg->advanced_security_config.init_packet_magic_header) ||
+ SKB_TYPE_LE32(skb) == cpu_to_le32(wg->advanced_security_config.response_packet_magic_header) ||
+ SKB_TYPE_LE32(skb) == cpu_to_le32(wg->advanced_security_config.cookie_packet_magic_header)) {
int cpu, ret = -EBUSY;
if (unlikely(!rng_is_initialized()))
@@ -559,23 +582,20 @@
} else
ret = ptr_ring_produce_bh(&wg->handshake_queue.ring, skb);
if (ret) {
- drop:
+drop:
net_dbg_skb_ratelimited("%s: Dropping handshake packet from %pISpfsc\n",
- wg->dev->name, skb);
+ wg->dev->name, skb);
goto err;
}
atomic_inc(&wg->handshake_queue_len);
cpu = wg_cpumask_next_online(&wg->handshake_queue.last_cpu);
/* Queues up a call to packet_process_queued_handshake_packets(skb): */
queue_work_on(cpu, wg->handshake_receive_wq,
- &per_cpu_ptr(wg->handshake_queue.worker, cpu)->work);
- break;
- }
- case cpu_to_le32(MESSAGE_DATA):
+ &per_cpu_ptr(wg->handshake_queue.worker, cpu)->work);
+ } else if (SKB_TYPE_LE32(skb) == cpu_to_le32(wg->advanced_security_config.transport_packet_magic_header)) {
PACKET_CB(skb)->ds = ip_tunnel_get_dsfield(ip_hdr(skb), skb);
wg_packet_consume_data(wg, skb);
- break;
- default:
+ } else {
WARN(1, "Non-exhaustive parsing of packet header lead to unknown packet type!\n");
goto err;
}
diff --color -urN -x uapi -x compat -x crypto -x .idea -x tests -x Kbuild -x Kconfig -x Makefile -x dkms.conf ../../linux-source-6.2.0/drivers/net/wireguard/send.c ./send.c
--- ../../linux-source-6.2.0/drivers/net/wireguard/send.c 2023-11-10 18:10:29
+++ ./send.c 2023-11-24 18:25:50
@@ -14,13 +14,24 @@
#include <linux/uio.h>
#include <linux/inetdevice.h>
#include <linux/socket.h>
+#include <linux/random.h>
#include <net/ip_tunnels.h>
#include <net/udp.h>
#include <net/sock.h>
+u32 wg_get_random_u32_inclusive(u32 floor, u32 ceil)
+{
+ u32 diff = ceil - floor + 1;
+ return floor + (get_random_u32() % diff);
+}
+
static void wg_packet_send_handshake_initiation(struct wg_peer *peer)
{
struct message_handshake_initiation packet;
+ struct wg_device *wg = peer->device;
+ void *buffer;
+ u8 ds;
+ u16 junk_packet_count, junk_packet_size;
if (!wg_birthdate_has_expired(atomic64_read(&peer->last_sent_handshake),
REKEY_TIMEOUT))
@@ -31,14 +42,37 @@
peer->device->dev->name, peer->internal_id,
&peer->endpoint.addr);
- if (wg_noise_handshake_create_initiation(&packet, &peer->handshake)) {
+ if (wg->advanced_security_config.advanced_security_enabled) {
+ junk_packet_count = wg->advanced_security_config.junk_packet_count;
+ buffer = kzalloc(wg->advanced_security_config.junk_packet_max_size, GFP_KERNEL);
+
+ while (junk_packet_count-- > 0) {
+ junk_packet_size = (u16) wg_get_random_u32_inclusive(
+ wg->advanced_security_config.junk_packet_min_size,
+ wg->advanced_security_config.junk_packet_max_size);
+
+ get_random_bytes(buffer, junk_packet_size);
+ get_random_bytes(&ds, 1);
+ wg_socket_send_buffer_to_peer(peer, buffer, junk_packet_size, ds);
+ }
+
+ kfree(buffer);
+ }
+
+ if (wg_noise_handshake_create_initiation(&packet, &peer->handshake, wg->advanced_security_config.init_packet_magic_header)) {
wg_cookie_add_mac_to_packet(&packet, sizeof(packet), peer);
wg_timers_any_authenticated_packet_traversal(peer);
wg_timers_any_authenticated_packet_sent(peer);
atomic64_set(&peer->last_sent_handshake,
ktime_get_coarse_boottime_ns());
- wg_socket_send_buffer_to_peer(peer, &packet, sizeof(packet),
- HANDSHAKE_DSCP);
+
+ if (wg->advanced_security_config.advanced_security_enabled) {
+ wg_socket_send_junked_buffer_to_peer(peer, &packet, sizeof(packet),
+ HANDSHAKE_DSCP, wg->advanced_security_config.init_packet_junk_size);
+ } else {
+ wg_socket_send_buffer_to_peer(peer, &packet, sizeof(packet),
+ HANDSHAKE_DSCP);
+ }
wg_timers_handshake_initiated(peer);
}
}
@@ -85,13 +119,14 @@
void wg_packet_send_handshake_response(struct wg_peer *peer)
{
struct message_handshake_response packet;
+ struct wg_device *wg = peer->device;
atomic64_set(&peer->last_sent_handshake, ktime_get_coarse_boottime_ns());
net_dbg_ratelimited("%s: Sending handshake response to peer %llu (%pISpfsc)\n",
peer->device->dev->name, peer->internal_id,
&peer->endpoint.addr);
- if (wg_noise_handshake_create_response(&packet, &peer->handshake)) {
+ if (wg_noise_handshake_create_response(&packet, &peer->handshake, wg->advanced_security_config.response_packet_magic_header)) {
wg_cookie_add_mac_to_packet(&packet, sizeof(packet), peer);
if (wg_noise_handshake_begin_session(&peer->handshake,
&peer->keypairs)) {
@@ -100,9 +135,16 @@
wg_timers_any_authenticated_packet_sent(peer);
atomic64_set(&peer->last_sent_handshake,
ktime_get_coarse_boottime_ns());
- wg_socket_send_buffer_to_peer(peer, &packet,
- sizeof(packet),
- HANDSHAKE_DSCP);
+ if (wg->advanced_security_config.advanced_security_enabled) {
+ wg_socket_send_junked_buffer_to_peer(peer, &packet,
+ sizeof(packet),
+ HANDSHAKE_DSCP,
+ wg->advanced_security_config.response_packet_junk_size);
+ } else {
+ wg_socket_send_buffer_to_peer(peer, &packet,
+ sizeof(packet),
+ HANDSHAKE_DSCP);
+ }
}
}
}
@@ -116,7 +158,7 @@
net_dbg_skb_ratelimited("%s: Sending cookie response for denied handshake message for %pISpfsc\n",
wg->dev->name, initiating_skb);
wg_cookie_message_create(&packet, initiating_skb, sender_index,
- &wg->cookie_checker);
+ &wg->cookie_checker, wg->advanced_security_config.cookie_packet_magic_header);
wg_socket_send_buffer_as_reply_to_skb(wg, initiating_skb, &packet,
sizeof(packet));
}
@@ -159,7 +201,7 @@
return padded_size - last_unit;
}
-static bool encrypt_packet(struct sk_buff *skb, struct noise_keypair *keypair)
+static bool encrypt_packet(struct sk_buff *skb, struct noise_keypair *keypair, u32 message_type)
{
unsigned int padding_len, plaintext_len, trailer_len;
struct scatterlist sg[MAX_SKB_FRAGS + 8];
@@ -203,7 +245,7 @@
*/
skb_set_inner_network_header(skb, 0);
header = (struct message_data *)skb_push(skb, sizeof(*header));
- header->header.type = cpu_to_le32(MESSAGE_DATA);
+ header->header.type = cpu_to_le32(message_type);
header->key_idx = keypair->remote_index;
header->counter = cpu_to_le64(PACKET_CB(skb)->nonce);
pskb_put(skb, trailer, trailer_len);
@@ -289,13 +331,17 @@
struct crypt_queue *queue = container_of(work, struct multicore_worker,
work)->ptr;
struct sk_buff *first, *skb, *next;
+ struct wg_device *wg;
while ((first = ptr_ring_consume_bh(&queue->ring)) != NULL) {
enum packet_state state = PACKET_STATE_CRYPTED;
skb_list_walk_safe(first, skb, next) {
+ wg = PACKET_PEER(first)->device;
+
if (likely(encrypt_packet(skb,
- PACKET_CB(first)->keypair))) {
+ PACKET_CB(first)->keypair,
+ wg->advanced_security_config.transport_packet_magic_header))) {
wg_reset_packet(skb, true);
} else {
state = PACKET_STATE_DEAD;
diff --color -urN -x uapi -x compat -x crypto -x .idea -x tests -x Kbuild -x Kconfig -x Makefile -x dkms.conf ../../linux-source-6.2.0/drivers/net/wireguard/socket.c ./socket.c
--- ../../linux-source-6.2.0/drivers/net/wireguard/socket.c 2023-11-10 18:10:29
+++ ./socket.c 2023-11-23 15:45:07
@@ -200,6 +200,18 @@
return wg_socket_send_skb_to_peer(peer, skb, ds);
}
+int wg_socket_send_junked_buffer_to_peer(struct wg_peer *peer, void *buffer,
+ size_t len, u8 ds, u16 junk_size)
+{
+ int ret;
+ void *new_buffer = kzalloc(len + junk_size, GFP_KERNEL);
+ get_random_bytes(new_buffer, junk_size);
+ memcpy(new_buffer + junk_size, buffer, len);
+ ret = wg_socket_send_buffer_to_peer(peer, new_buffer, len + junk_size, ds);
+ kfree(new_buffer);
+ return ret;
+}
+
int wg_socket_send_buffer_as_reply_to_skb(struct wg_device *wg,
struct sk_buff *in_skb, void *buffer,
size_t len)
diff --color -urN -x uapi -x compat -x crypto -x .idea -x tests -x Kbuild -x Kconfig -x Makefile -x dkms.conf ../../linux-source-6.2.0/drivers/net/wireguard/socket.h ./socket.h
--- ../../linux-source-6.2.0/drivers/net/wireguard/socket.h 2023-11-10 18:10:29
+++ ./socket.h 2023-11-23 13:20:24
@@ -16,6 +16,8 @@
struct sock *new6);
int wg_socket_send_buffer_to_peer(struct wg_peer *peer, void *data,
size_t len, u8 ds);
+int wg_socket_send_junked_buffer_to_peer(struct wg_peer *peer, void *data,
+ size_t len, u8 ds, u16 junk_size);
int wg_socket_send_skb_to_peer(struct wg_peer *peer, struct sk_buff *skb,
u8 ds);
int wg_socket_send_buffer_as_reply_to_skb(struct wg_device *wg,
diff --color -urN -x uapi -x compat -x crypto -x .idea -x tests -x Kbuild -x Kconfig -x Makefile -x dkms.conf ../../linux-source-6.2.0/drivers/net/wireguard/version.h ./version.h
--- ../../linux-source-6.2.0/drivers/net/wireguard/version.h 2023-11-10 18:10:29
+++ ./version.h 1970-01-01 02:00:00
@@ -1 +0,0 @@
-#define WIREGUARD_VERSION "1.0.0"

View File

@@ -0,0 +1,27 @@
--- ../../linux-source-6.2.0/include/uapi/linux/wireguard.h 2023-09-23 12:11:13
+++ ./uapi/wireguard.h 2023-11-28 16:12:36
@@ -131,7 +131,7 @@
#ifndef _WG_UAPI_WIREGUARD_H
#define _WG_UAPI_WIREGUARD_H
-#define WG_GENL_NAME "wireguard"
+#define WG_GENL_NAME "amneziawg"
#define WG_GENL_VERSION 1
#define WG_KEY_LEN 32
@@ -157,6 +157,15 @@
WGDEVICE_A_LISTEN_PORT,
WGDEVICE_A_FWMARK,
WGDEVICE_A_PEERS,
+ WGDEVICE_A_JC,
+ WGDEVICE_A_JMIN,
+ WGDEVICE_A_JMAX,
+ WGDEVICE_A_S1,
+ WGDEVICE_A_S2,
+ WGDEVICE_A_H1,
+ WGDEVICE_A_H2,
+ WGDEVICE_A_H3,
+ WGDEVICE_A_H4,
__WGDEVICE_A_LAST
};
#define WGDEVICE_A_MAX (__WGDEVICE_A_LAST - 1)

View File

@@ -0,0 +1,20 @@
WIREGUARD_VERSION = 1.0.0-awg
ccflags-y := -D'pr_fmt(fmt)=KBUILD_MODNAME ": " fmt'
ccflags-y += -D'WIREGUARD_VERSION="$(WIREGUARD_VERSION)"'
# ccflags-y += -DDEBUG
amneziawg-y := main.o
amneziawg-y += noise.o
amneziawg-y += device.o
amneziawg-y += peer.o
amneziawg-y += timers.o
amneziawg-y += queueing.o
amneziawg-y += send.o
amneziawg-y += receive.o
amneziawg-y += socket.o
amneziawg-y += peerlookup.o
amneziawg-y += allowedips.o
amneziawg-y += ratelimiter.o
amneziawg-y += cookie.o
amneziawg-y += netlink.o
obj-m := amneziawg.o