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)
|