feat: implement H1-H4 ranged headers

This commit is contained in:
Yaroslav Gurov
2025-09-23 23:32:25 +02:00
committed by Yaroslav Gurov
parent 9eb888d250
commit e939553f72
11 changed files with 198 additions and 150 deletions

View File

@@ -8,7 +8,7 @@ ccflags-$(CONFIG_AMNEZIAWG_DEBUG) += -DDEBUG -g
ccflags-$(if $(WIREGUARD_VERSION),y,) += -D'WIREGUARD_VERSION="$(WIREGUARD_VERSION)"'
ccflags-$(if $(OMIT_ENDPOINTS),y,) += -D'OMIT_ENDPOINTS="$(OMIT_ENDPOINTS)"'
amneziawg-y := main.o noise.o device.o peer.o timers.o queueing.o send.o receive.o socket.o peerlookup.o allowedips.o ratelimiter.o cookie.o netlink.o
amneziawg-y := main.o noise.o device.o peer.o timers.o queueing.o send.o receive.o socket.o peerlookup.o allowedips.o ratelimiter.o cookie.o netlink.o magic_header.o
ifeq ($(shell [ $(VERSION) -lt 6 -o \( $(VERSION) -eq 6 -a $(PATCHLEVEL) -lt 1 \) ] && echo y),y)
kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))

View File

@@ -307,6 +307,23 @@ static void wg_setup(struct net_device *dev)
memset(wg, 0, sizeof(*wg));
wg->dev = dev;
wg->headers[MSGIDX_HANDSHAKE_INIT] = (struct magic_header) {
.start = MESSAGE_HANDSHAKE_INITIATION,
.end = MESSAGE_HANDSHAKE_INITIATION
};
wg->headers[MSGIDX_HANDSHAKE_RESPONSE] = (struct magic_header) {
.start = MESSAGE_HANDSHAKE_RESPONSE,
.end = MESSAGE_HANDSHAKE_RESPONSE
};
wg->headers[MSGIDX_HANDSHAKE_COOKIE] = (struct magic_header) {
.start = MESSAGE_HANDSHAKE_COOKIE,
.end = MESSAGE_HANDSHAKE_COOKIE
};
wg->headers[MSGIDX_TRANSPORT] = (struct magic_header) {
.start = MESSAGE_DATA,
.end = MESSAGE_DATA
};
}
static int wg_newlink(struct net *src_net, struct net_device *dev,
@@ -382,11 +399,6 @@ static int wg_newlink(struct net *src_net, struct net_device *dev,
*/
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;
@@ -550,39 +562,15 @@ int wg_device_handle_post_config(struct net_device *dev, struct amnezia_config *
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;
}
if (wg->advanced_security_config.init_packet_magic_header == wg->advanced_security_config.response_packet_magic_header ||
wg->advanced_security_config.init_packet_magic_header == wg->advanced_security_config.cookie_packet_magic_header ||
wg->advanced_security_config.init_packet_magic_header == wg->advanced_security_config.transport_packet_magic_header ||
wg->advanced_security_config.response_packet_magic_header == wg->advanced_security_config.cookie_packet_magic_header ||
wg->advanced_security_config.response_packet_magic_header == wg->advanced_security_config.transport_packet_magic_header ||
wg->advanced_security_config.cookie_packet_magic_header == wg->advanced_security_config.transport_packet_magic_header) {
net_dbg_ratelimited("%s: magic headers should differ; got: init:%d; recv:%d; unde:%d; tran:%d\n",
dev->name,
wg->advanced_security_config.init_packet_magic_header,
wg->advanced_security_config.response_packet_magic_header,
wg->advanced_security_config.cookie_packet_magic_header,
wg->advanced_security_config.transport_packet_magic_header);
ret = -EINVAL;
for (i = 0; i < ARRAY_SIZE(wg->headers); ++i) {
for (j = i + 1; j < ARRAY_SIZE(wg->headers); ++j) {
if (!(wg->headers[j].end < wg->headers[i].start ||
wg->headers[i].end < wg->headers[j].start)) {
net_dbg_ratelimited("%s: H%d and H%d ranges must not overlap\n", wg->dev->name, i + 1, j + 1);
ret = -EINVAL;
}
a_sec_on = true;
}
}
if (MESSAGE_INITIATION_SIZE + wg->advanced_security_config.init_packet_junk_size ==

View File

@@ -10,6 +10,7 @@
#include "allowedips.h"
#include "peerlookup.h"
#include "cookie.h"
#include "magic_header.h"
#include <linux/types.h>
#include <linux/netdevice.h>
@@ -44,10 +45,6 @@ struct amnezia_config {
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 {
@@ -68,6 +65,8 @@ struct wg_device {
unsigned int num_peers, device_update_gen;
u32 fwmark;
u16 incoming_port;
struct magic_header headers[4];
};
int wg_device_init(void);

47
src/magic_header.c Normal file
View File

@@ -0,0 +1,47 @@
#include "magic_header.h"
#include <linux/string.h>
#include <linux/kstrtox.h>
#include <linux/sprintf.h>
#include <linux/random.h>
int mh_parse(struct magic_header *mh, char *desc) {
int err;
char* val;
val = strsep(&desc, "-");
if (!val)
return -EINVAL;
err = kstrtouint(val, 10, &mh->start);
if (err)
return err;
if (desc) {
err = kstrtouint(desc, 10, &mh->end);
if (err)
return err;
}
else
mh->end = mh->start;
if (mh->start > mh->end)
return -EINVAL;
return 0;
}
int mh_genspec(struct magic_header *mh, char *buf, size_t buflen) {
if (mh->start == mh->end)
return scnprintf(buf, buflen, "%u", mh->start);
return scnprintf(buf, buflen, "%u-%u", mh->start, mh->end);
}
bool mh_validate(__le32 received, struct magic_header* mh) {
u32 received_host = le32_to_cpu(received);
return received_host >= mh->start && received_host <= mh->end;
}
u32 mh_genheader(struct magic_header *mh) {
return get_random_u32_inclusive(mh->start, mh->end);
}

17
src/magic_header.h Normal file
View File

@@ -0,0 +1,17 @@
#ifndef H_MAGIC_HEADER
#define H_MAGIC_HEADER
#include <linux/types.h>
struct magic_header {
u32 start;
u32 end;
};
int mh_parse(struct magic_header *mh, char *desc);
int mh_genspec(struct magic_header *mh, char *desc, size_t buflen);
bool mh_validate(__le32 received, struct magic_header* mh);
u32 mh_genheader(struct magic_header* mh);
#endif

View File

@@ -61,6 +61,13 @@ enum message_type {
MESSAGE_DATA = 4
};
enum message_index {
MSGIDX_HANDSHAKE_INIT = MESSAGE_HANDSHAKE_INITIATION - 1,
MSGIDX_HANDSHAKE_RESPONSE = MESSAGE_HANDSHAKE_RESPONSE - 1,
MSGIDX_HANDSHAKE_COOKIE = MESSAGE_HANDSHAKE_COOKIE - 1,
MSGIDX_TRANSPORT = MESSAGE_DATA - 1
};
struct message_header {
/* The actual layout of this that we want is:
* u8 type

View File

@@ -5,6 +5,7 @@
#include "netlink.h"
#include "device.h"
#include "magic_header.h"
#include "peer.h"
#include "socket.h"
#include "queueing.h"
@@ -46,10 +47,10 @@ static const struct nla_policy device_policy[WGDEVICE_A_MAX + 1] = {
[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 },
[WGDEVICE_A_H1] = { .type = NLA_NUL_STRING },
[WGDEVICE_A_H2] = { .type = NLA_NUL_STRING },
[WGDEVICE_A_H3] = { .type = NLA_NUL_STRING },
[WGDEVICE_A_H4] = { .type = NLA_NUL_STRING },
[WGDEVICE_A_PEER] = { .type = NLA_NESTED }
};
@@ -408,6 +409,7 @@ static int wg_get_device_dump(struct sk_buff *skb, struct netlink_callback *cb)
int ret = -EMSGSIZE;
bool done = true;
void *hdr;
char buf[32];
rtnl_lock();
mutex_lock(&wg->device_update_lock);
@@ -436,14 +438,14 @@ static int wg_get_device_dump(struct sk_buff *skb, struct netlink_callback *cb)
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))
(mh_genspec(&wg->headers[MSGIDX_HANDSHAKE_INIT], buf, sizeof(buf)) &&
nla_put_string(skb, WGDEVICE_A_H1, buf)) ||
(mh_genspec(&wg->headers[MSGIDX_HANDSHAKE_RESPONSE], buf, sizeof(buf)) &&
nla_put_string(skb, WGDEVICE_A_H2, buf)) ||
(mh_genspec(&wg->headers[MSGIDX_HANDSHAKE_COOKIE], buf, sizeof(buf)) &&
nla_put_string(skb, WGDEVICE_A_H3, buf)) ||
(mh_genspec(&wg->headers[MSGIDX_TRANSPORT], buf, sizeof(buf)) &&
nla_put_string(skb, WGDEVICE_A_H4, buf))
goto out;
down_read(&wg->static_identity.lock);
@@ -712,6 +714,7 @@ static int wg_set_device(struct sk_buff *skb, struct genl_info *info)
struct amnezia_config *asc = kzalloc(sizeof(*asc), GFP_KERNEL);
u32 flags = 0;
int ret;
char *str;
if (IS_ERR(wg)) {
ret = PTR_ERR(wg);
@@ -781,22 +784,38 @@ static int wg_set_device(struct sk_buff *skb, struct genl_info *info)
if (info->attrs[WGDEVICE_A_H1]) {
asc->advanced_security = true;
asc->init_packet_magic_header = nla_get_u32(info->attrs[WGDEVICE_A_H1]);
str = nla_strdup(info->attrs[WGDEVICE_A_H1], GFP_KERNEL);
ret = mh_parse(&wg->headers[MSGIDX_HANDSHAKE_INIT], str);
kfree(str);
if (ret)
goto out;
}
if (info->attrs[WGDEVICE_A_H2]) {
asc->advanced_security = true;
asc->response_packet_magic_header = nla_get_u32(info->attrs[WGDEVICE_A_H2]);
str = nla_strdup(info->attrs[WGDEVICE_A_H2], GFP_KERNEL);
ret = mh_parse(&wg->headers[MSGIDX_HANDSHAKE_RESPONSE], str);
kfree(str);
if (ret)
goto out;
}
if (info->attrs[WGDEVICE_A_H3]) {
asc->advanced_security = true;
asc->cookie_packet_magic_header = nla_get_u32(info->attrs[WGDEVICE_A_H3]);
str = nla_strdup(info->attrs[WGDEVICE_A_H3], GFP_KERNEL);
ret = mh_parse(&wg->headers[MSGIDX_HANDSHAKE_COOKIE], str);
kfree(str);
if (ret)
goto out;
}
if (info->attrs[WGDEVICE_A_H4]) {
asc->advanced_security = true;
asc->transport_packet_magic_header = nla_get_u32(info->attrs[WGDEVICE_A_H4]);
str = nla_strdup(info->attrs[WGDEVICE_A_H4], GFP_KERNEL);
ret = mh_parse(&wg->headers[MSGIDX_TRANSPORT], str);
kfree(str);
if (ret)
goto out;
}
if (flags & WGDEVICE_F_REPLACE_PEERS)

View File

@@ -5,6 +5,7 @@
#include "noise.h"
#include "device.h"
#include "magic_header.h"
#include "peer.h"
#include "messages.h"
#include "queueing.h"
@@ -360,7 +361,7 @@ static void kdf(u8 *first_dst, u8 *second_dst, u8 *third_dst, const u8 *data,
/* Extract entropy from data into secret */
hmac(secret, data, chaining_key, data_len, NOISE_HASH_LEN);
if (!first_dst || !first_len)
goto out;
@@ -598,7 +599,7 @@ wg_noise_handshake_consume_initiation(struct message_handshake_initiation *src,
u8 t[NOISE_TIMESTAMP_LEN];
u64 initiation_consumption;
bool advanced_security = wg->advanced_security_config.advanced_security &&
(SKB_TYPE_LE32(skb) == cpu_to_le32(wg->advanced_security_config.init_packet_magic_header));
mh_validate(SKB_TYPE_LE32(skb), &wg->headers[MSGIDX_HANDSHAKE_INIT]);
down_read(&wg->static_identity.lock);
if (unlikely(!wg->static_identity.has_identity))

View File

@@ -10,6 +10,7 @@
#include "messages.h"
#include "cookie.h"
#include "socket.h"
#include "magic_header.h"
#include <linux/simd.h>
#include <linux/ip.h>
@@ -24,58 +25,44 @@ static void update_rx_stats(struct wg_peer *peer, size_t len)
peer->rx_bytes += len;
}
static size_t validate_header_len(struct sk_buff *skb, struct wg_device *wg)
static size_t prepare_awg_message(struct sk_buff *skb, struct wg_device *wg)
{
if (unlikely(skb->len < sizeof(struct message_header)))
if (skb_is_nonlinear(skb) && unlikely(skb_linearize(skb))) {
net_dbg_skb_ratelimited("%s: non-linear sk_buff from %pISpfsc could not be linearized, dropping packet\n",
wg->dev->name, skb);
return 0;
if ((SKB_TYPE_LE32(skb) == cpu_to_le32(wg->advanced_security_config.transport_packet_magic_header) ||
SKB_TYPE_LE32(skb) == cpu_to_le32(MESSAGE_DATA)) &&
skb->len >= MESSAGE_MINIMUM_LENGTH)
return sizeof(struct message_data);
if ((SKB_TYPE_LE32(skb) == cpu_to_le32(wg->advanced_security_config.init_packet_magic_header) ||
SKB_TYPE_LE32(skb) == cpu_to_le32(MESSAGE_HANDSHAKE_INITIATION)) &&
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_TYPE_LE32(skb) == cpu_to_le32(MESSAGE_HANDSHAKE_RESPONSE)) &&
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_TYPE_LE32(skb) == cpu_to_le32(MESSAGE_HANDSHAKE_COOKIE)) &&
skb->len == MESSAGE_COOKIE_REPLY_SIZE)
return MESSAGE_COOKIE_REPLY_SIZE;
return 0;
}
static void prepare_advanced_secured_message(struct sk_buff *skb, struct wg_device *wg)
{
u32 assumed_type, assumed_offset;
if (wg->advanced_security_config.advanced_security) {
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;
if (skb_is_nonlinear(skb) && unlikely(skb_linearize(skb))) {
net_dbg_skb_ratelimited("%s: non-linear sk_buff from %pISpfsc could not be linearized, dropping packet\n",
wg->dev->name, skb);
return;
}
skb_pull(skb, assumed_offset);
if (SKB_TYPE_LE32(skb) != assumed_type) {
skb_push(skb, assumed_offset);
}
}
if (skb->len == wg->advanced_security_config.init_packet_junk_size + MESSAGE_INITIATION_SIZE) {
skb_pull(skb, wg->advanced_security_config.init_packet_junk_size);
if (mh_validate(SKB_TYPE_LE32(skb), &wg->headers[MSGIDX_HANDSHAKE_INIT]))
return MESSAGE_INITIATION_SIZE;
else
skb_push(skb, wg->advanced_security_config.init_packet_junk_size);
}
if (skb->len == wg->advanced_security_config.response_packet_junk_size + MESSAGE_RESPONSE_SIZE) {
skb_pull(skb, wg->advanced_security_config.response_packet_junk_size);
if (mh_validate(SKB_TYPE_LE32(skb), &wg->headers[MSGIDX_HANDSHAKE_RESPONSE]))
return MESSAGE_RESPONSE_SIZE;
else
skb_push(skb, wg->advanced_security_config.response_packet_junk_size);
}
if (skb->len == MESSAGE_COOKIE_REPLY_SIZE) {
if (mh_validate(SKB_TYPE_LE32(skb), &wg->headers[MSGIDX_HANDSHAKE_COOKIE]))
return MESSAGE_HANDSHAKE_COOKIE;
}
if (skb->len >= MESSAGE_TRANSPORT_SIZE) {
if (mh_validate(SKB_TYPE_LE32(skb), &wg->headers[MSGIDX_TRANSPORT]))
return MESSAGE_TRANSPORT_SIZE;
}
net_dbg_skb_ratelimited("%s: Unknown message from %pISpfsc encountered, packet dropped\n",
wg->dev->name, skb);
return 0;
}
static int prepare_skb_header(struct sk_buff *skb, struct wg_device *wg)
@@ -113,8 +100,7 @@ static int prepare_skb_header(struct sk_buff *skb, struct wg_device *wg)
if (unlikely(skb->len != data_len))
/* Final len does not agree with calculated len */
return -EINVAL;
prepare_advanced_secured_message(skb, wg);
header_len = validate_header_len(skb, wg);
header_len = prepare_awg_message(skb, wg);
if (unlikely(!header_len))
return -EINVAL;
__skb_push(skb, data_offset);
@@ -136,8 +122,7 @@ static void wg_receive_handshake_packet(struct wg_device *wg,
bool packet_needs_cookie;
bool under_load;
if (SKB_TYPE_LE32(skb) == cpu_to_le32(wg->advanced_security_config.cookie_packet_magic_header) ||
SKB_TYPE_LE32(skb) == cpu_to_le32(MESSAGE_HANDSHAKE_COOKIE)) {
if (mh_validate(SKB_TYPE_LE32(skb), &wg->headers[MSGIDX_HANDSHAKE_COOKIE])) {
net_dbg_skb_ratelimited("%s: Receiving cookie response from %pISpfsc\n",
wg->dev->name, skb);
wg_cookie_message_consume(
@@ -167,8 +152,7 @@ static void wg_receive_handshake_packet(struct wg_device *wg,
return;
}
if (SKB_TYPE_LE32(skb) == cpu_to_le32(wg->advanced_security_config.init_packet_magic_header) ||
SKB_TYPE_LE32(skb) == cpu_to_le32(MESSAGE_HANDSHAKE_INITIATION)) {
if (mh_validate(SKB_TYPE_LE32(skb), &wg->headers[MSGIDX_HANDSHAKE_INIT])) {
struct message_handshake_initiation *message =
(struct message_handshake_initiation *)skb->data;
@@ -189,8 +173,7 @@ static void wg_receive_handshake_packet(struct wg_device *wg,
&peer->endpoint.addr);
wg_packet_send_handshake_response(peer);
}
if (SKB_TYPE_LE32(skb) == cpu_to_le32(wg->advanced_security_config.response_packet_magic_header) ||
SKB_TYPE_LE32(skb) == cpu_to_le32(MESSAGE_HANDSHAKE_RESPONSE)) {
if (mh_validate(SKB_TYPE_LE32(skb), &wg->headers[MSGIDX_HANDSHAKE_RESPONSE])) {
struct message_handshake_response *message =
(struct message_handshake_response *)skb->data;
@@ -586,12 +569,9 @@ void wg_packet_receive(struct wg_device *wg, struct sk_buff *skb)
if (unlikely(prepare_skb_header(skb, wg) < 0))
goto err;
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) ||
SKB_TYPE_LE32(skb) == cpu_to_le32(MESSAGE_HANDSHAKE_INITIATION) ||
SKB_TYPE_LE32(skb) == cpu_to_le32(MESSAGE_HANDSHAKE_RESPONSE) ||
SKB_TYPE_LE32(skb) == cpu_to_le32(MESSAGE_HANDSHAKE_COOKIE)) {
if (mh_validate(SKB_TYPE_LE32(skb), &wg->headers[MSGIDX_HANDSHAKE_INIT]) ||
mh_validate(SKB_TYPE_LE32(skb), &wg->headers[MSGIDX_HANDSHAKE_RESPONSE]) ||
mh_validate(SKB_TYPE_LE32(skb), &wg->headers[MSGIDX_HANDSHAKE_COOKIE])) {
int cpu, ret = -EBUSY;
if (unlikely(!rng_is_initialized()))
@@ -614,8 +594,7 @@ drop:
/* 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);
} else if (SKB_TYPE_LE32(skb) == cpu_to_le32(wg->advanced_security_config.transport_packet_magic_header) ||
SKB_TYPE_LE32(skb) == cpu_to_le32(MESSAGE_DATA)) {
} else if (mh_validate(SKB_TYPE_LE32(skb), &wg->headers[MSGIDX_TRANSPORT])) {
PACKET_CB(skb)->ds = ip_tunnel_get_dsfield(ip_hdr(skb), skb);
wg_packet_consume_data(wg, skb);
} else {

View File

@@ -4,6 +4,7 @@
*/
#include "compat/compat.h"
#include "magic_header.h"
#include "queueing.h"
#include "timers.h"
#include "device.h"
@@ -61,13 +62,7 @@ static void wg_packet_send_handshake_initiation(struct wg_peer *peer)
kfree(buffer);
}
net_dbg_ratelimited("%s: Initiation magic header: %u\n",
peer->device->dev->name,
peer->advanced_security ? wg->advanced_security_config.init_packet_magic_header :
MESSAGE_HANDSHAKE_INITIATION);
if (wg_noise_handshake_create_initiation(&packet, &peer->handshake, peer->advanced_security ?
wg->advanced_security_config.init_packet_magic_header : MESSAGE_HANDSHAKE_INITIATION)) {
if (wg_noise_handshake_create_initiation(&packet, &peer->handshake, mh_genheader(&wg->headers[MSGIDX_HANDSHAKE_INIT]))) {
wg_cookie_add_mac_to_packet(&packet, sizeof(packet), peer);
wg_timers_any_authenticated_packet_traversal(peer);
wg_timers_any_authenticated_packet_sent(peer);
@@ -134,10 +129,7 @@ void wg_packet_send_handshake_response(struct wg_peer *peer)
peer->device->dev->name, peer->internal_id,
&peer->endpoint.addr);
if (wg_noise_handshake_create_response(&packet, &peer->handshake,
peer->advanced_security ?
wg->advanced_security_config.response_packet_magic_header :
MESSAGE_HANDSHAKE_RESPONSE)) {
if (wg_noise_handshake_create_response(&packet, &peer->handshake, mh_genheader(&wg->headers[MSGIDX_HANDSHAKE_RESPONSE]))) {
wg_cookie_add_mac_to_packet(&packet, sizeof(packet), peer);
if (wg_noise_handshake_begin_session(&peer->handshake,
&peer->keypairs)) {
@@ -169,17 +161,8 @@ void wg_packet_send_handshake_cookie(struct wg_device *wg,
net_dbg_skb_ratelimited("%s: Sending cookie response for denied handshake message for %pISpfsc\n",
wg->dev->name, initiating_skb);
if (SKB_TYPE_LE32(initiating_skb) == cpu_to_le32(MESSAGE_HANDSHAKE_INITIATION) ||
SKB_TYPE_LE32(initiating_skb) == cpu_to_le32(MESSAGE_HANDSHAKE_RESPONSE)) {
wg_cookie_message_create(&packet, initiating_skb, sender_index,
&wg->cookie_checker, MESSAGE_HANDSHAKE_COOKIE);
} else {
wg_cookie_message_create(&packet, initiating_skb, sender_index,
&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));
wg_cookie_message_create(&packet, initiating_skb, sender_index, &wg->cookie_checker, mh_genheader(&wg->headers[MSGIDX_HANDSHAKE_COOKIE]));
wg_socket_send_buffer_as_reply_to_skb(wg, initiating_skb, &packet, sizeof(packet));
}
static void keep_key_fresh(struct wg_peer *peer)
@@ -364,7 +347,8 @@ void wg_packet_encrypt_worker(struct work_struct *work)
skb_list_walk_safe(first, skb, next) {
wg = PACKET_PEER(first)->device;
if (likely(encrypt_packet(PACKET_PEER(first)->advanced_security ?
if (likely(encrypt_packet(
mh_genheader(&wg->headers[MSGIDX_TRANSPORT]),
wg->advanced_security_config.transport_packet_magic_header : MESSAGE_DATA,
skb,
PACKET_CB(first)->keypair

View File

@@ -154,7 +154,7 @@
#define _WG_UAPI_WIREGUARD_H
#define WG_GENL_NAME "amneziawg"
#define WG_GENL_VERSION 1
#define WG_GENL_VERSION 2
#define WG_KEY_LEN 32
@@ -192,6 +192,13 @@ enum wgdevice_attribute {
WGDEVICE_A_H3,
WGDEVICE_A_H4,
WGDEVICE_A_PEER,
WGDEVICE_A_S3,
WGDEVICE_A_S4,
WGDEVICE_A_I1,
WGDEVICE_A_I2,
WGDEVICE_A_I3,
WGDEVICE_A_I4,
WGDEVICE_A_I5,
__WGDEVICE_A_LAST
};
#define WGDEVICE_A_MAX (__WGDEVICE_A_LAST - 1)