1/*-
2 * Copyright (c) 2015 Patrick Kelsey
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27/*
28 * This is a server-side implementation of TCP Fast Open (TFO) [RFC7413].
29 *
30 * This implementation is currently considered to be experimental and is not
31 * included in kernel builds by default.  To include this code, add the
32 * following line to your kernel config:
33 *
34 * options TCP_RFC7413
35 *
36 * The generated TFO cookies are the 64-bit output of
37 * SipHash24(<16-byte-key><client-ip>).  Multiple concurrent valid keys are
38 * supported so that time-based rolling cookie invalidation policies can be
39 * implemented in the system.  The default number of concurrent keys is 2.
40 * This can be adjusted in the kernel config as follows:
41 *
42 * options TCP_RFC7413_MAX_KEYS=<num-keys>
43 *
44 *
45 * The following TFO-specific sysctls are defined:
46 *
47 * net.inet.tcp.fastopen.acceptany (RW, default 0)
48 *     When non-zero, all client-supplied TFO cookies will be considered to
49 *     be valid.
50 *
51 * net.inet.tcp.fastopen.autokey (RW, default 120)
52 *     When this and net.inet.tcp.fastopen.enabled are non-zero, a new key
53 *     will be automatically generated after this many seconds.
54 *
55 * net.inet.tcp.fastopen.enabled (RW, default 0)
56 *     When zero, no new TFO connections can be created.  On the transition
57 *     from enabled to disabled, all installed keys are removed.  On the
58 *     transition from disabled to enabled, if net.inet.tcp.fastopen.autokey
59 *     is non-zero and there are no keys installed, a new key will be
60 *     generated immediately.  The transition from enabled to disabled does
61 *     not affect any TFO connections in progress; it only prevents new ones
62 *     from being made.
63 *
64 * net.inet.tcp.fastopen.keylen (RO)
65 *     The key length in bytes.
66 *
67 * net.inet.tcp.fastopen.maxkeys (RO)
68 *     The maximum number of keys supported.
69 *
70 * net.inet.tcp.fastopen.numkeys (RO)
71 *     The current number of keys installed.
72 *
73 * net.inet.tcp.fastopen.setkey (WO)
74 *     Install a new key by writing net.inet.tcp.fastopen.keylen bytes to this
75 *     sysctl.
76 *
77 *
78 * In order for TFO connections to be created via a listen socket, that
79 * socket must have the TCP_FASTOPEN socket option set on it.  This option
80 * can be set on the socket either before or after the listen() is invoked.
81 * Clearing this option on a listen socket after it has been set has no
82 * effect on existing TFO connections or TFO connections in progress; it
83 * only prevents new TFO connections from being made.
84 *
85 * For passively-created sockets, the TCP_FASTOPEN socket option can be
86 * queried to determine whether the connection was established using TFO.
87 * Note that connections that are established via a TFO SYN, but that fall
88 * back to using a non-TFO SYN|ACK will have the TCP_FASTOPEN socket option
89 * set.
90 *
91 * Per the RFC, this implementation limits the number of TFO connections
92 * that can be in the SYN_RECEIVED state on a per listen-socket basis.
93 * Whenever this limit is exceeded, requests for new TFO connections are
94 * serviced as non-TFO requests.  Without such a limit, given a valid TFO
95 * cookie, an attacker could keep the listen queue in an overflow condition
96 * using a TFO SYN flood.  This implementation sets the limit at half the
97 * configured listen backlog.
98 *
99 */
100
101#include <sys/cdefs.h>
102__FBSDID("$FreeBSD: stable/11/sys/netinet/tcp_fastopen.c 339037 2018-10-01 09:40:41Z ae $");
103
104#include "opt_inet.h"
105
106#include <sys/param.h>
107#include <sys/kernel.h>
108#include <sys/limits.h>
109#include <sys/lock.h>
110#include <sys/rmlock.h>
111#include <sys/socket.h>
112#include <sys/socketvar.h>
113#include <sys/sysctl.h>
114#include <sys/systm.h>
115
116#include <crypto/siphash/siphash.h>
117
118#include <net/vnet.h>
119
120#include <netinet/in.h>
121#include <netinet/in_pcb.h>
122#include <netinet/tcp_fastopen.h>
123#include <netinet/tcp_var.h>
124
125
126#define	TCP_FASTOPEN_KEY_LEN	SIPHASH_KEY_LENGTH
127
128#if !defined(TCP_RFC7413_MAX_KEYS) || (TCP_RFC7413_MAX_KEYS < 1)
129#define	TCP_FASTOPEN_MAX_KEYS	2
130#else
131#define	TCP_FASTOPEN_MAX_KEYS	TCP_RFC7413_MAX_KEYS
132#endif
133
134struct tcp_fastopen_keylist {
135	unsigned int newest;
136	uint8_t key[TCP_FASTOPEN_MAX_KEYS][TCP_FASTOPEN_KEY_LEN];
137};
138
139struct tcp_fastopen_callout {
140	struct callout c;
141	struct vnet *v;
142};
143
144SYSCTL_NODE(_net_inet_tcp, OID_AUTO, fastopen, CTLFLAG_RW, 0, "TCP Fast Open");
145
146static VNET_DEFINE(int, tcp_fastopen_acceptany) = 0;
147#define	V_tcp_fastopen_acceptany	VNET(tcp_fastopen_acceptany)
148SYSCTL_INT(_net_inet_tcp_fastopen, OID_AUTO, acceptany,
149    CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_fastopen_acceptany), 0,
150    "Accept any non-empty cookie");
151
152static VNET_DEFINE(unsigned int, tcp_fastopen_autokey) = 120;
153#define	V_tcp_fastopen_autokey	VNET(tcp_fastopen_autokey)
154static int sysctl_net_inet_tcp_fastopen_autokey(SYSCTL_HANDLER_ARGS);
155SYSCTL_PROC(_net_inet_tcp_fastopen, OID_AUTO, autokey,
156    CTLFLAG_VNET | CTLTYPE_UINT | CTLFLAG_RW, NULL, 0,
157    &sysctl_net_inet_tcp_fastopen_autokey, "IU",
158    "Number of seconds between auto-generation of a new key; zero disables");
159
160VNET_DEFINE(unsigned int, tcp_fastopen_enabled) = 0;
161static int sysctl_net_inet_tcp_fastopen_enabled(SYSCTL_HANDLER_ARGS);
162SYSCTL_PROC(_net_inet_tcp_fastopen, OID_AUTO, enabled,
163    CTLFLAG_VNET | CTLTYPE_UINT | CTLFLAG_RW, NULL, 0,
164    &sysctl_net_inet_tcp_fastopen_enabled, "IU",
165    "Enable/disable TCP Fast Open processing");
166
167SYSCTL_INT(_net_inet_tcp_fastopen, OID_AUTO, keylen,
168    CTLFLAG_RD, SYSCTL_NULL_INT_PTR, TCP_FASTOPEN_KEY_LEN,
169    "Key length in bytes");
170
171SYSCTL_INT(_net_inet_tcp_fastopen, OID_AUTO, maxkeys,
172    CTLFLAG_RD, SYSCTL_NULL_INT_PTR, TCP_FASTOPEN_MAX_KEYS,
173    "Maximum number of keys supported");
174
175static VNET_DEFINE(unsigned int, tcp_fastopen_numkeys) = 0;
176#define	V_tcp_fastopen_numkeys	VNET(tcp_fastopen_numkeys)
177SYSCTL_UINT(_net_inet_tcp_fastopen, OID_AUTO, numkeys,
178    CTLFLAG_VNET | CTLFLAG_RD, &VNET_NAME(tcp_fastopen_numkeys), 0,
179    "Number of keys installed");
180
181static int sysctl_net_inet_tcp_fastopen_setkey(SYSCTL_HANDLER_ARGS);
182SYSCTL_PROC(_net_inet_tcp_fastopen, OID_AUTO, setkey,
183    CTLFLAG_VNET | CTLTYPE_OPAQUE | CTLFLAG_WR, NULL, 0,
184    &sysctl_net_inet_tcp_fastopen_setkey, "",
185    "Install a new key");
186
187static VNET_DEFINE(struct rmlock, tcp_fastopen_keylock);
188#define	V_tcp_fastopen_keylock	VNET(tcp_fastopen_keylock)
189
190#define TCP_FASTOPEN_KEYS_RLOCK(t)	rm_rlock(&V_tcp_fastopen_keylock, (t))
191#define TCP_FASTOPEN_KEYS_RUNLOCK(t)	rm_runlock(&V_tcp_fastopen_keylock, (t))
192#define TCP_FASTOPEN_KEYS_WLOCK()	rm_wlock(&V_tcp_fastopen_keylock)
193#define TCP_FASTOPEN_KEYS_WUNLOCK()	rm_wunlock(&V_tcp_fastopen_keylock)
194
195static VNET_DEFINE(struct tcp_fastopen_keylist, tcp_fastopen_keys);
196#define V_tcp_fastopen_keys	VNET(tcp_fastopen_keys)
197
198static VNET_DEFINE(struct tcp_fastopen_callout, tcp_fastopen_autokey_ctx);
199#define V_tcp_fastopen_autokey_ctx	VNET(tcp_fastopen_autokey_ctx)
200
201static VNET_DEFINE(uma_zone_t, counter_zone);
202#define	V_counter_zone			VNET(counter_zone)
203
204void
205tcp_fastopen_init(void)
206{
207	V_counter_zone = uma_zcreate("tfo", sizeof(unsigned int),
208	    NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
209	rm_init(&V_tcp_fastopen_keylock, "tfo_keylock");
210	callout_init_rm(&V_tcp_fastopen_autokey_ctx.c,
211	    &V_tcp_fastopen_keylock, 0);
212	V_tcp_fastopen_autokey_ctx.v = curvnet;
213	V_tcp_fastopen_keys.newest = TCP_FASTOPEN_MAX_KEYS - 1;
214}
215
216void
217tcp_fastopen_destroy(void)
218{
219	callout_drain(&V_tcp_fastopen_autokey_ctx.c);
220	rm_destroy(&V_tcp_fastopen_keylock);
221	uma_zdestroy(V_counter_zone);
222}
223
224unsigned int *
225tcp_fastopen_alloc_counter(void)
226{
227	unsigned int *counter;
228	counter = uma_zalloc(V_counter_zone, M_NOWAIT);
229	if (counter)
230		*counter = 1;
231	return (counter);
232}
233
234void
235tcp_fastopen_decrement_counter(unsigned int *counter)
236{
237	if (*counter == 1)
238		uma_zfree(V_counter_zone, counter);
239	else
240		atomic_subtract_int(counter, 1);
241}
242
243static void
244tcp_fastopen_addkey_locked(uint8_t *key)
245{
246
247	V_tcp_fastopen_keys.newest++;
248	if (V_tcp_fastopen_keys.newest == TCP_FASTOPEN_MAX_KEYS)
249		V_tcp_fastopen_keys.newest = 0;
250	memcpy(V_tcp_fastopen_keys.key[V_tcp_fastopen_keys.newest], key,
251	    TCP_FASTOPEN_KEY_LEN);
252	if (V_tcp_fastopen_numkeys < TCP_FASTOPEN_MAX_KEYS)
253		V_tcp_fastopen_numkeys++;
254}
255
256static void
257tcp_fastopen_autokey_locked(void)
258{
259	uint8_t newkey[TCP_FASTOPEN_KEY_LEN];
260
261	arc4rand(newkey, TCP_FASTOPEN_KEY_LEN, 0);
262	tcp_fastopen_addkey_locked(newkey);
263}
264
265static void
266tcp_fastopen_autokey_callout(void *arg)
267{
268	struct tcp_fastopen_callout *ctx = arg;
269
270	CURVNET_SET(ctx->v);
271	tcp_fastopen_autokey_locked();
272	callout_reset(&ctx->c, V_tcp_fastopen_autokey * hz,
273		      tcp_fastopen_autokey_callout, ctx);
274	CURVNET_RESTORE();
275}
276
277
278static uint64_t
279tcp_fastopen_make_cookie(uint8_t key[SIPHASH_KEY_LENGTH], struct in_conninfo *inc)
280{
281	SIPHASH_CTX ctx;
282	uint64_t siphash;
283
284	SipHash24_Init(&ctx);
285	SipHash_SetKey(&ctx, key);
286	switch (inc->inc_flags & INC_ISIPV6) {
287#ifdef INET
288	case 0:
289		SipHash_Update(&ctx, &inc->inc_faddr, sizeof(inc->inc_faddr));
290		break;
291#endif
292#ifdef INET6
293	case INC_ISIPV6:
294		SipHash_Update(&ctx, &inc->inc6_faddr, sizeof(inc->inc6_faddr));
295		break;
296#endif
297	}
298	SipHash_Final((u_int8_t *)&siphash, &ctx);
299
300	return (siphash);
301}
302
303
304/*
305 * Return values:
306 *	-1	the cookie is invalid and no valid cookie is available
307 *	 0	the cookie is invalid and the latest cookie has been returned
308 *	 1	the cookie is valid and the latest cookie has been returned
309 */
310int
311tcp_fastopen_check_cookie(struct in_conninfo *inc, uint8_t *cookie,
312    unsigned int len, uint64_t *latest_cookie)
313{
314	struct rm_priotracker tracker;
315	unsigned int i, key_index;
316	uint64_t cur_cookie;
317
318	if (V_tcp_fastopen_acceptany) {
319		*latest_cookie = 0;
320		return (1);
321	}
322
323	if (len != TCP_FASTOPEN_COOKIE_LEN) {
324		if (V_tcp_fastopen_numkeys > 0) {
325			*latest_cookie =
326			    tcp_fastopen_make_cookie(
327				V_tcp_fastopen_keys.key[V_tcp_fastopen_keys.newest],
328				inc);
329			return (0);
330		}
331 		return (-1);
332	}
333
334	/*
335	 * Check against each available key, from newest to oldest.
336	 */
337	TCP_FASTOPEN_KEYS_RLOCK(&tracker);
338	key_index = V_tcp_fastopen_keys.newest;
339	for (i = 0; i < V_tcp_fastopen_numkeys; i++) {
340		cur_cookie =
341		    tcp_fastopen_make_cookie(V_tcp_fastopen_keys.key[key_index],
342			inc);
343		if (i == 0)
344			*latest_cookie = cur_cookie;
345		if (memcmp(cookie, &cur_cookie, TCP_FASTOPEN_COOKIE_LEN) == 0) {
346			TCP_FASTOPEN_KEYS_RUNLOCK(&tracker);
347			return (1);
348		}
349		if (key_index == 0)
350			key_index = TCP_FASTOPEN_MAX_KEYS - 1;
351		else
352			key_index--;
353	}
354	TCP_FASTOPEN_KEYS_RUNLOCK(&tracker);
355
356	return (0);
357}
358
359static int
360sysctl_net_inet_tcp_fastopen_autokey(SYSCTL_HANDLER_ARGS)
361{
362	int error;
363	unsigned int new;
364
365	new = V_tcp_fastopen_autokey;
366	error = sysctl_handle_int(oidp, &new, 0, req);
367	if (error == 0 && req->newptr) {
368		if (new > (INT_MAX / hz))
369			return (EINVAL);
370
371		TCP_FASTOPEN_KEYS_WLOCK();
372		if (V_tcp_fastopen_enabled) {
373			if (V_tcp_fastopen_autokey && !new)
374				callout_stop(&V_tcp_fastopen_autokey_ctx.c);
375			else if (new)
376				callout_reset(&V_tcp_fastopen_autokey_ctx.c,
377				    new * hz, tcp_fastopen_autokey_callout,
378				    &V_tcp_fastopen_autokey_ctx);
379		}
380		V_tcp_fastopen_autokey = new;
381		TCP_FASTOPEN_KEYS_WUNLOCK();
382	}
383
384	return (error);
385}
386
387static int
388sysctl_net_inet_tcp_fastopen_enabled(SYSCTL_HANDLER_ARGS)
389{
390	int error;
391	unsigned int new;
392
393	new = V_tcp_fastopen_enabled;
394	error = sysctl_handle_int(oidp, &new, 0, req);
395	if (error == 0 && req->newptr) {
396		if (V_tcp_fastopen_enabled && !new) {
397			/* enabled -> disabled */
398			TCP_FASTOPEN_KEYS_WLOCK();
399			V_tcp_fastopen_numkeys = 0;
400			V_tcp_fastopen_keys.newest = TCP_FASTOPEN_MAX_KEYS - 1;
401			if (V_tcp_fastopen_autokey)
402				callout_stop(&V_tcp_fastopen_autokey_ctx.c);
403			V_tcp_fastopen_enabled = 0;
404			TCP_FASTOPEN_KEYS_WUNLOCK();
405		} else if (!V_tcp_fastopen_enabled && new) {
406			/* disabled -> enabled */
407			TCP_FASTOPEN_KEYS_WLOCK();
408			if (V_tcp_fastopen_autokey &&
409			    (V_tcp_fastopen_numkeys == 0)) {
410				tcp_fastopen_autokey_locked();
411				callout_reset(&V_tcp_fastopen_autokey_ctx.c,
412				    V_tcp_fastopen_autokey * hz,
413				    tcp_fastopen_autokey_callout,
414				    &V_tcp_fastopen_autokey_ctx);
415			}
416			V_tcp_fastopen_enabled = 1;
417			TCP_FASTOPEN_KEYS_WUNLOCK();
418		}
419	}
420	return (error);
421}
422
423static int
424sysctl_net_inet_tcp_fastopen_setkey(SYSCTL_HANDLER_ARGS)
425{
426	int error;
427	uint8_t newkey[TCP_FASTOPEN_KEY_LEN];
428
429	if (req->oldptr != NULL || req->oldlen != 0)
430		return (EINVAL);
431	if (req->newptr == NULL)
432		return (EPERM);
433	if (req->newlen != sizeof(newkey))
434		return (EINVAL);
435	error = SYSCTL_IN(req, newkey, sizeof(newkey));
436	if (error)
437		return (error);
438
439	TCP_FASTOPEN_KEYS_WLOCK();
440	tcp_fastopen_addkey_locked(newkey);
441	TCP_FASTOPEN_KEYS_WUNLOCK();
442
443	return (0);
444}
445