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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
|
/* $OpenBSD: if_wg.h,v 1.1 2019/04/27 05:14:33 dlg Exp $ */
/*
* Copyright (c) 2018 David Gwynne <dlg@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _NET_IF_WG_H_
#define _NET_IF_WG_H_
/* the timing side of messages */
#define WG_MSGS_WINDOW 2000
#define WG_REKEY_MSGS (~0ULL - 0xffffULL)
#define WG_REKEY_TIME 120000 /* msec */
#define WG_KEEPALIVE 10000 /* msec */
#define WG_REKEY_TIMEOUT 5000 /* msec */
#define WG_REKEY_JITTER 333 /* msec */
#define WG_REKEY_MAX 90000 /* msec */
#define WG_REJECT_MSGS (~0ULL - WG_MSGS_WINDOW)
#define WG_REJECT_TIME 180000 /* msec */
/* the bytes side of messages */
#define WG_POLY1305_TAG_LEN 16
#define WG_CURVE25519_KEY_LEN 32
#define WG_AEAD_CHACHA20_POLY1305_KEY_LEN \
32
#define WG_BLAKE2S_OUTPUT_LEN 16
#define WG_CHACHA20_POLY1305_NONCE_LEN \
24
#define WG_AEAD_LEN(_l) ((_l) + WG_POLY1305_TAG_LEN)
#define WG_ENCRYPTED_STATIC_LEN WG_AEAD_LEN(WG_CURVE25519_KEY_LEN)
#define WG_MSG_HANDSHAKE_INIT 1
#define WG_MSG_HANDSHAKE_RESP 2
#define WG_MSG_COOKIE_RESP 3
#define WG_MSG_DATA 4
struct wg_header {
uint8_t msg_type;
uint8_t zero[3];
} __packed __aligned(4);
struct wg_tai64n {
uint64_t tai_seconds; /* BE */
uint32_t tai_nanoseconds; /* BE */
} __packed __aligned(4);
#define WG_ENCRYPTED_TAI64N_LEN WG_AEAD_LEN(sizeof(struct wg_tai64n))
struct wg_handshake_init {
struct wg_header hdr;
uint32_t sndr_idx; /* LE */
uint8_t unencrypted_ephemeral[WG_CURVE25519_KEY_LEN];
uint8_t encrypted_static[WG_ENCRYPTED_STATIC_LEN];
uint8_t encrypted_timestamp[WG_ENCRYPTED_TAI64N_LEN];
uint8_t mac1[WG_BLAKE2S_OUTPUT_LEN];
uint8_t mac2[WG_BLAKE2S_OUTPUT_LEN];
} __packed __aligned(4);
struct wg_handshake_resp {
struct wg_header hdr;
uint32_t sndr_idx; /* LE */
uint32_t rcvr_idx; /* LE */
uint8_t unencrypted_ephemeral[WG_CURVE25519_KEY_LEN];
uint8_t encrypted_nothing[WG_AEAD_LEN(0)];
uint8_t mac1[WG_BLAKE2S_OUTPUT_LEN];
uint8_t mac2[WG_BLAKE2S_OUTPUT_LEN];
} __packed __aligned(4);
struct wg_cookie_resp {
struct wg_header hdr;
uint32_t rcvr_idx; /* LE */
uint8_t nonce[24];
uint8_t encrypted_cookie[WG_AEAD_LEN(0)];
} __packed __aligned(4);
struct wg_data {
struct wg_header hdr;
uint32_t rcvr_idx;
uint32_t counter_lo;
uint32_t counter_hi;
/* followed by encrypted data */
} __packed __aligned(4);
/*
* ioctl interface
*/
#include <sys/ioccom.h>
#define WGIFCREATE _IOW('w', 10, unsigned int)
#define WGIFATTACH _IOW('w', 11, unsigned int)
#define WGIFDETACH _IOW('w', 12, unsigned int)
#define WGIFDESTROY _IOW('w', 13, unsigned int)
struct wg_if_sock {
unsigned int wg_unit;
int wg_sock;
};
#define WGIFSSOCK _IOW('w', 14, struct wg_if_sock)
#define WGIFDSOCK _IOW('w', 15, unsigned int)
struct wg_aead_key {
uint8_t key[WG_AEAD_CHACHA20_POLY1305_KEY_LEN];
};
struct wg_if_data_keys {
unsigned int wg_unit;
uint32_t wg_tx_index; /* LE */
uint32_t wg_rx_index; /* LE */
struct wg_aead_key wg_tx_key;
struct wg_aead_key wg_rx_key;
};
#define WGIFADDKEYS _IOW('w', 16, struct wg_if_data_keys)
#define WGIFDELKEYS _IOW('w', 17, struct wg_if_data_keys)
struct wg_if_role {
unsigned int wg_unit;
unsigned int wg_role;
#define WG_DATA_INITIATOR 0x696e6974
#define WG_DATA_RESPONDER 0x72657370
};
#define WGIFSROLE _IOW('w', 18, struct wg_if_role)
#define WGIFGROLE _IOWR('w', 20, struct wg_if_role)
/*
* messages via reads
*/
#define WG_MSG_REKEY 0x746b6579
struct wg_msg {
unsigned int wg_unit;
unsigned int wg_type;
};
#endif /* _NET_IF_WG_H_ */
|