xref: /openbsd-src/sys/net/wg_cookie.h (revision f8148103d5d9180a01fa85d1c7014aa7debf5629)
1*f8148103Stb /*	$OpenBSD: wg_cookie.h,v 1.2 2020/12/09 05:53:33 tb Exp $ */
258360b13Sdlg /*
358360b13Sdlg  * Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
458360b13Sdlg  * Copyright (C) 2019-2020 Matt Dunwoodie <ncon@noconroy.net>
558360b13Sdlg  *
658360b13Sdlg  * Permission to use, copy, modify, and distribute this software for any
758360b13Sdlg  * purpose with or without fee is hereby granted, provided that the above
858360b13Sdlg  * copyright notice and this permission notice appear in all copies.
958360b13Sdlg  *
1058360b13Sdlg  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1158360b13Sdlg  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1258360b13Sdlg  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1358360b13Sdlg  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1458360b13Sdlg  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1558360b13Sdlg  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1658360b13Sdlg  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1758360b13Sdlg  */
1858360b13Sdlg 
1958360b13Sdlg #ifndef __COOKIE_H__
2058360b13Sdlg #define __COOKIE_H__
2158360b13Sdlg 
2258360b13Sdlg #include <sys/types.h>
2358360b13Sdlg #include <sys/time.h>
2458360b13Sdlg #include <sys/rwlock.h>
2558360b13Sdlg #include <sys/queue.h>
2658360b13Sdlg 
2758360b13Sdlg #include <netinet/in.h>
2858360b13Sdlg 
2958360b13Sdlg #include <crypto/chachapoly.h>
3058360b13Sdlg #include <crypto/blake2s.h>
3158360b13Sdlg #include <crypto/siphash.h>
3258360b13Sdlg 
3358360b13Sdlg #define COOKIE_MAC_SIZE		16
3458360b13Sdlg #define COOKIE_KEY_SIZE		32
3558360b13Sdlg #define COOKIE_NONCE_SIZE	XCHACHA20POLY1305_NONCE_SIZE
3658360b13Sdlg #define COOKIE_COOKIE_SIZE	16
3758360b13Sdlg #define COOKIE_SECRET_SIZE	32
3858360b13Sdlg #define COOKIE_INPUT_SIZE	32
3958360b13Sdlg #define COOKIE_ENCRYPTED_SIZE	(COOKIE_COOKIE_SIZE + COOKIE_MAC_SIZE)
4058360b13Sdlg 
4158360b13Sdlg #define COOKIE_MAC1_KEY_LABEL	"mac1----"
4258360b13Sdlg #define COOKIE_COOKIE_KEY_LABEL	"cookie--"
4358360b13Sdlg #define COOKIE_SECRET_MAX_AGE	120
4458360b13Sdlg #define COOKIE_SECRET_LATENCY	5
4558360b13Sdlg 
4658360b13Sdlg /* Constants for initiation rate limiting */
4758360b13Sdlg #define RATELIMIT_SIZE		(1 << 13)
4858360b13Sdlg #define RATELIMIT_SIZE_MAX	(RATELIMIT_SIZE * 8)
4958360b13Sdlg #define NSEC_PER_SEC		1000000000LL
5058360b13Sdlg #define INITIATIONS_PER_SECOND	20
5158360b13Sdlg #define INITIATIONS_BURSTABLE	5
5258360b13Sdlg #define INITIATION_COST		(NSEC_PER_SEC / INITIATIONS_PER_SECOND)
5358360b13Sdlg #define TOKEN_MAX		(INITIATION_COST * INITIATIONS_BURSTABLE)
5458360b13Sdlg #define ELEMENT_TIMEOUT		1
5558360b13Sdlg #define IPV4_MASK_SIZE		4 /* Use all 4 bytes of IPv4 address */
5658360b13Sdlg #define IPV6_MASK_SIZE		8 /* Use top 8 bytes (/64) of IPv6 address */
5758360b13Sdlg 
5858360b13Sdlg struct cookie_macs {
5958360b13Sdlg 	uint8_t	mac1[COOKIE_MAC_SIZE];
6058360b13Sdlg 	uint8_t	mac2[COOKIE_MAC_SIZE];
6158360b13Sdlg };
6258360b13Sdlg 
6358360b13Sdlg struct ratelimit_entry {
6458360b13Sdlg 	LIST_ENTRY(ratelimit_entry)	 r_entry;
6558360b13Sdlg 	sa_family_t			 r_af;
6658360b13Sdlg 	union {
6758360b13Sdlg 		struct in_addr		 r_in;
6858360b13Sdlg #ifdef INET6
6958360b13Sdlg 		struct in6_addr		 r_in6;
7058360b13Sdlg #endif
7158360b13Sdlg 	};
7258360b13Sdlg 	struct timespec			 r_last_time;	/* nanouptime */
7358360b13Sdlg 	uint64_t			 r_tokens;
7458360b13Sdlg };
7558360b13Sdlg 
7658360b13Sdlg struct ratelimit {
7758360b13Sdlg 	SIPHASH_KEY			 rl_secret;
7858360b13Sdlg 	struct pool			*rl_pool;
7958360b13Sdlg 
8058360b13Sdlg 	struct rwlock			 rl_lock;
8158360b13Sdlg 	LIST_HEAD(, ratelimit_entry)	*rl_table;
8258360b13Sdlg 	u_long				 rl_table_mask;
8358360b13Sdlg 	size_t				 rl_table_num;
8458360b13Sdlg 	struct timespec			 rl_last_gc;	/* nanouptime */
8558360b13Sdlg };
8658360b13Sdlg 
8758360b13Sdlg struct cookie_maker {
8858360b13Sdlg 	uint8_t		cp_mac1_key[COOKIE_KEY_SIZE];
8958360b13Sdlg 	uint8_t		cp_cookie_key[COOKIE_KEY_SIZE];
9058360b13Sdlg 
9158360b13Sdlg 	struct rwlock	cp_lock;
9258360b13Sdlg 	uint8_t		cp_cookie[COOKIE_COOKIE_SIZE];
9358360b13Sdlg 	struct timespec	cp_birthdate;	/* nanouptime */
9458360b13Sdlg 	int		cp_mac1_valid;
9558360b13Sdlg 	uint8_t		cp_mac1_last[COOKIE_MAC_SIZE];
9658360b13Sdlg };
9758360b13Sdlg 
9858360b13Sdlg struct cookie_checker {
9958360b13Sdlg 	struct ratelimit	cc_ratelimit_v4;
10058360b13Sdlg #ifdef INET6
10158360b13Sdlg 	struct ratelimit	cc_ratelimit_v6;
10258360b13Sdlg #endif
10358360b13Sdlg 
10458360b13Sdlg 	struct rwlock		cc_key_lock;
10558360b13Sdlg 	uint8_t			cc_mac1_key[COOKIE_KEY_SIZE];
10658360b13Sdlg 	uint8_t			cc_cookie_key[COOKIE_KEY_SIZE];
10758360b13Sdlg 
10858360b13Sdlg 	struct rwlock		cc_secret_lock;
10958360b13Sdlg 	struct timespec		cc_secret_birthdate;	/* nanouptime */
11058360b13Sdlg 	uint8_t			cc_secret[COOKIE_SECRET_SIZE];
11158360b13Sdlg };
11258360b13Sdlg 
11358360b13Sdlg void	cookie_maker_init(struct cookie_maker *, uint8_t[COOKIE_INPUT_SIZE]);
11458360b13Sdlg int	cookie_checker_init(struct cookie_checker *, struct pool *);
11558360b13Sdlg void	cookie_checker_update(struct cookie_checker *,
11658360b13Sdlg 	    uint8_t[COOKIE_INPUT_SIZE]);
11758360b13Sdlg void	cookie_checker_deinit(struct cookie_checker *);
11858360b13Sdlg void	cookie_checker_create_payload(struct cookie_checker *,
11958360b13Sdlg 	    struct cookie_macs *cm, uint8_t[COOKIE_NONCE_SIZE],
12058360b13Sdlg 	    uint8_t [COOKIE_ENCRYPTED_SIZE], struct sockaddr *);
12158360b13Sdlg int	cookie_maker_consume_payload(struct cookie_maker *,
12258360b13Sdlg 	    uint8_t[COOKIE_NONCE_SIZE], uint8_t[COOKIE_ENCRYPTED_SIZE]);
12358360b13Sdlg void	cookie_maker_mac(struct cookie_maker *, struct cookie_macs *,
12458360b13Sdlg 	    void *, size_t);
12558360b13Sdlg int	cookie_checker_validate_macs(struct cookie_checker *,
12658360b13Sdlg 	    struct cookie_macs *, void *, size_t, int, struct sockaddr *);
12758360b13Sdlg 
12858360b13Sdlg #ifdef WGTEST
12958360b13Sdlg void	cookie_test();
13058360b13Sdlg #endif /* WGTEST */
13158360b13Sdlg 
13258360b13Sdlg #endif /* __COOKIE_H__ */
133