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