aboutsummaryrefslogtreecommitdiffstats
path: root/sys/linux/socket_netlink_generic_wireguard.txt
blob: 8a904ba110d9ce1bb9b01698a73b09e23afc6e8e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# Copyright 2020 syzkaller project authors. All rights reserved.
# Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.

include <linux/net.h>
include <linux/socket.h>
include <uapi/asm-generic/socket.h>
include <uapi/linux/if.h>
include <uapi/linux/netlink.h>
include <uapi/linux/genetlink.h>
include <uapi/linux/wireguard.h>
include <drivers/net/wireguard/messages.h>

resource wireguard_ifindex[ifindex]
resource genl_wireguard_family_id[int16]

type msghdr_wireguard[CMD] msghdr_netlink[netlink_msg_t[genl_wireguard_family_id, genlmsghdr_t[CMD], device_policy]]

syz_genetlink_get_family_id$wireguard(name ptr[in, string["wireguard"]], fd sock_nl_generic) genl_wireguard_family_id

sendmsg$WG_CMD_GET_DEVICE(fd sock_nl_generic, msg ptr[in, msghdr_wireguard[WG_CMD_GET_DEVICE]], f flags[send_flags])
sendmsg$WG_CMD_SET_DEVICE(fd sock_nl_generic, msg ptr[in, msghdr_wireguard[WG_CMD_SET_DEVICE]], f flags[send_flags])

setsockopt$SO_BINDTODEVICE_wg(fd sock, level const[SOL_SOCKET], optname const[SO_BINDTODEVICE], optval ptr[in, string[wireguard_devname]], optlen len[optval])

ioctl$ifreq_SIOCGIFINDEX_wireguard(fd sock, cmd const[SIOCGIFINDEX], arg ptr[out, ifreq_dev_t[wireguard_devname, wireguard_ifindex]])

device_policy [
	WGDEVICE_A_IFINDEX	nlattr[WGDEVICE_A_IFINDEX, wireguard_ifindex]
	WGDEVICE_A_IFNAME	nlattr[WGDEVICE_A_IFNAME, string[wireguard_devname, IFNAMSIZ]]
	WGDEVICE_A_PRIVATE_KEY	nlattr[WGDEVICE_A_PRIVATE_KEY, wireguard_private_key]
	WGDEVICE_A_FLAGS	nlattr[WGDEVICE_A_FLAGS, flags[wgdevice_flag, int32]]
	WGDEVICE_A_LISTEN_PORT	nlattr[WGDEVICE_A_LISTEN_PORT, sock_port]
	WGDEVICE_A_FWMARK	nlattr[WGDEVICE_A_FWMARK, int32]
	WGDEVICE_A_PEERS	nlnest[WGDEVICE_A_PEERS, array[nlnest[0, array[peer_policy]]]]
] [varlen]

peer_policy [
	WGPEER_A_PUBLIC_KEY			nlattr[WGPEER_A_PUBLIC_KEY, wireguard_public_key]
	WGPEER_A_PRESHARED_KEY			nlattr[WGPEER_A_PRESHARED_KEY, array[int8, NOISE_SYMMETRIC_KEY_LEN]]
	WGPEER_A_FLAGS				nlattr[WGPEER_A_FLAGS, flags[wgpeer_flag, int32]]
	WGPEER_A_ENDPOINT4			nlattr[WGPEER_A_ENDPOINT, sockaddr_in]
	WGPEER_A_ENDPOINT6			nlattr[WGPEER_A_ENDPOINT, sockaddr_in6]
	WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL	nlattr[WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL, int16]
	WGPEER_A_ALLOWEDIPS			nlnest[WGPEER_A_ALLOWEDIPS, array[nlnest[0, array[allowedip_policy]]]]
	WGPEER_A_PROTOCOL_VERSION		nlattr[WGPEER_A_PROTOCOL_VERSION, const[1, int32]]
] [varlen]

allowedip_policy [
	ipv4	allowedip_policy$ipv4
	ipv6	allowedip_policy$ipv6
] [varlen]

allowedip_policy$ipv4 {
	WGALLOWEDIP_A_FAMILY	nlattr[WGALLOWEDIP_A_FAMILY, const[AF_INET, int16]]
	WGALLOWEDIP_A_IPADDR	nlattr[WGALLOWEDIP_A_IPADDR, ipv4_addr]
	WGALLOWEDIP_A_CIDR_MASK	nlattr[WGALLOWEDIP_A_CIDR_MASK, int8[0:3]]
} [packed]

allowedip_policy$ipv6 {
	WGALLOWEDIP_A_FAMILY	nlattr[WGALLOWEDIP_A_FAMILY, const[AF_INET6, int16]]
	WGALLOWEDIP_A_IPADDR	nlattr[WGALLOWEDIP_A_IPADDR, ipv6_addr]
	WGALLOWEDIP_A_CIDR_MASK	nlattr[WGALLOWEDIP_A_CIDR_MASK, int8[0:3]]
} [packed]

wireguard_private_key [
	zero	stringnoz[`0000000000000000000000000000000000000000000000000000000000000000`]
	a	stringnoz[`a05ca84f6c9c8e3853e2fd7a70ae0fb20fa152600cb00845174f08076f8d7843`]
	b	stringnoz[`b08073e8d44e91e3da922c22438244bb885c69e269c8e9d835b114293a4ddc6e`]
	c	stringnoz[`a0cb879a47f5bc644c0e693fa6d031c74a1553b6e901b9ff2f518c78042fb542`]
]

wireguard_public_key [
	zero	stringnoz[`0000000000000000000000000000000000000000000000000000000000000000`]
	neg	stringnoz[`dbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff`]
	a_g	stringnoz[`975c9d81c983c8209ee781254b899f8ed925ae9f0923c23c62f53c57cdbf691c`]
	b_g	stringnoz[`d1732899f611cd8994034d7f413dc957630e5493c285aca40065cb6311be696b`]
	c_g	stringnoz[`f44da367a88ee6564f020211456727082f5cebee8b1bf5eb7337341b459b3922`]
]

wgdevice_flag = WGDEVICE_F_REPLACE_PEERS
wgpeer_flag = WGPEER_F_REMOVE_ME, WGPEER_F_REPLACE_ALLOWEDIPS, WGPEER_F_UPDATE_ONLY
wireguard_devname = "wg0", "wg1", "wg2"

wg_packet [
	initiation	message_handshake_initiation
	response	message_handshake_response
	cookie		message_handshake_cookie
	data		message_data
] [varlen]

message_handshake_initiation {
	type			const[MESSAGE_HANDSHAKE_INITIATION, int32]
# Not clear if these indexes are also generated randomly and we need to guess them or not.
	sender_index		int32[0:4]
	unencrypted_ephemeral	array[int8, NOISE_PUBLIC_KEY_LEN]
	encrypted_static	array[int8, NOISE_PUBLIC_KEY_ENCRYPTED_LEN]
	encrypted_timestamp	array[int8, NOISE_TIMESTAMP_ENCRYPTED_LEN]
	macs			message_macs
}

message_handshake_response {
	type			const[MESSAGE_HANDSHAKE_RESPONSE, int32]
	sender_index		int32[0:4]
	receiver_index		int32[0:4]
	unencrypted_ephemeral	array[int8, NOISE_PUBLIC_KEY_LEN]
	encrypted_nothing	array[int8, NOISE_NOTHING_ENCRYPTED_LEN]
	macs			message_macs
}

message_handshake_cookie {
	type			const[MESSAGE_HANDSHAKE_COOKIE, int32]
	receiver_index		int32[0:4]
	nonce			array[int8, COOKIE_NONCE_LEN]
	encrypted_cookie	array[int8, NOISE_COOKIE_ENCRYPTED_LEN]
}

message_data {
	type		const[MESSAGE_DATA, int32]
# These are allocated randomly, so little chances guessing.
	key_idx		int32
# This is used as chacha20poly1305 decryption nonce.
	counter		int64
	encrypted_data	array[int8]
}

message_macs {
	mac1	array[int8, COOKIE_LEN]
	mac2	array[int8, COOKIE_LEN]
}

define NOISE_PUBLIC_KEY_ENCRYPTED_LEN	noise_encrypted_len(NOISE_PUBLIC_KEY_LEN)
define NOISE_TIMESTAMP_ENCRYPTED_LEN	noise_encrypted_len(NOISE_TIMESTAMP_LEN)
define NOISE_COOKIE_ENCRYPTED_LEN	noise_encrypted_len(COOKIE_LEN)
define NOISE_NOTHING_ENCRYPTED_LEN	noise_encrypted_len(0)