xref: /openbsd/sys/net/wg_noise.h (revision 72c7c57a)
1 /*	$OpenBSD: wg_noise.h,v 1.3 2024/03/05 17:48:01 mvs Exp $ */
2 /*
3  * Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
4  * Copyright (C) 2019-2020 Matt Dunwoodie <ncon@noconroy.net>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #ifndef __NOISE_H__
20 #define __NOISE_H__
21 
22 #include <sys/types.h>
23 #include <sys/time.h>
24 #include <sys/mutex.h>
25 #include <sys/rwlock.h>
26 
27 #include <crypto/blake2s.h>
28 #include <crypto/chachapoly.h>
29 #include <crypto/curve25519.h>
30 
31 #define NOISE_PUBLIC_KEY_LEN	CURVE25519_KEY_SIZE
32 #define NOISE_SYMMETRIC_KEY_LEN	CHACHA20POLY1305_KEY_SIZE
33 #define NOISE_TIMESTAMP_LEN	(sizeof(uint64_t) + sizeof(uint32_t))
34 #define NOISE_AUTHTAG_LEN	CHACHA20POLY1305_AUTHTAG_SIZE
35 #define NOISE_HASH_LEN		BLAKE2S_HASH_SIZE
36 
37 /* Protocol string constants */
38 #define NOISE_HANDSHAKE_NAME	"Noise_IKpsk2_25519_ChaChaPoly_BLAKE2s"
39 #define NOISE_IDENTIFIER_NAME	"WireGuard v1 zx2c4 Jason@zx2c4.com"
40 
41 /* Constants for the counter */
42 #define COUNTER_BITS_TOTAL	8192
43 #define COUNTER_BITS		(sizeof(unsigned long) * 8)
44 #define COUNTER_NUM		(COUNTER_BITS_TOTAL / COUNTER_BITS)
45 #define COUNTER_WINDOW_SIZE	(COUNTER_BITS_TOTAL - COUNTER_BITS)
46 
47 /* Constants for the keypair */
48 #define REKEY_AFTER_MESSAGES	(1ull << 60)
49 #define REJECT_AFTER_MESSAGES	(UINT64_MAX - COUNTER_WINDOW_SIZE - 1)
50 #define REKEY_AFTER_TIME	120
51 #define REKEY_AFTER_TIME_RECV	165
52 #define REJECT_AFTER_TIME	180
53 #define REJECT_INTERVAL		(1000000000 / 50) /* fifty times per sec */
54 /* 24 = floor(log2(REJECT_INTERVAL)) */
55 #define REJECT_INTERVAL_MASK	(~((1ull<<24)-1))
56 
57 enum noise_state_hs {
58 	HS_ZEROED = 0,
59 	CREATED_INITIATION,
60 	CONSUMED_INITIATION,
61 	CREATED_RESPONSE,
62 	CONSUMED_RESPONSE,
63 };
64 
65 struct noise_handshake {
66 	enum noise_state_hs	 hs_state;
67 	uint32_t		 hs_local_index;
68 	uint32_t		 hs_remote_index;
69 	uint8_t		 	 hs_e[NOISE_PUBLIC_KEY_LEN];
70 	uint8_t		 	 hs_hash[NOISE_HASH_LEN];
71 	uint8_t		 	 hs_ck[NOISE_HASH_LEN];
72 };
73 
74 struct noise_counter {
75 	struct mutex		 c_mtx;
76 	uint64_t		 c_send;
77 	uint64_t		 c_recv;
78 	unsigned long		 c_backtrack[COUNTER_NUM];
79 };
80 
81 struct noise_keypair {
82 	SLIST_ENTRY(noise_keypair)	kp_entry;
83 	int				kp_valid;
84 	int				kp_is_initiator;
85 	uint32_t			kp_local_index;
86 	uint32_t			kp_remote_index;
87 	uint8_t				kp_send[NOISE_SYMMETRIC_KEY_LEN];
88 	uint8_t				kp_recv[NOISE_SYMMETRIC_KEY_LEN];
89 	struct timespec			kp_birthdate; /* nanouptime */
90 	struct noise_counter		kp_ctr;
91 };
92 
93 struct noise_remote {
94 	uint8_t				 r_public[NOISE_PUBLIC_KEY_LEN];
95 	struct noise_local		*r_local;
96 	uint8_t		 		 r_ss[NOISE_PUBLIC_KEY_LEN];
97 
98 	struct rwlock			 r_handshake_lock;
99 	struct noise_handshake		 r_handshake;
100 	uint8_t				 r_psk[NOISE_SYMMETRIC_KEY_LEN];
101 	uint8_t				 r_timestamp[NOISE_TIMESTAMP_LEN];
102 	struct timespec			 r_last_init; /* nanouptime */
103 
104 	struct mutex			 r_keypair_mtx;
105 	SLIST_HEAD(,noise_keypair)	 r_unused_keypairs;
106 	struct noise_keypair		*r_next, *r_current, *r_previous;
107 	struct noise_keypair		 r_keypair[3]; /* 3: next, current, previous. */
108 
109 };
110 
111 struct noise_local {
112 	struct rwlock		l_identity_lock;
113 	int			l_has_identity;
114 	uint8_t			l_public[NOISE_PUBLIC_KEY_LEN];
115 	uint8_t			l_private[NOISE_PUBLIC_KEY_LEN];
116 
117 	struct noise_upcall {
118 		void	 *u_arg;
119 		struct noise_remote *
120 			(*u_remote_get)(void *, uint8_t[NOISE_PUBLIC_KEY_LEN]);
121 		uint32_t
122 			(*u_index_set)(void *, struct noise_remote *);
123 		void	(*u_index_drop)(void *, uint32_t);
124 	}			l_upcall;
125 };
126 
127 /* Set/Get noise parameters */
128 void	noise_local_init(struct noise_local *, struct noise_upcall *);
129 void	noise_local_lock_identity(struct noise_local *);
130 void	noise_local_unlock_identity(struct noise_local *);
131 int	noise_local_set_private(struct noise_local *, uint8_t[NOISE_PUBLIC_KEY_LEN]);
132 int	noise_local_keys(struct noise_local *, uint8_t[NOISE_PUBLIC_KEY_LEN],
133 	    uint8_t[NOISE_PUBLIC_KEY_LEN]);
134 
135 void	noise_remote_init(struct noise_remote *, uint8_t[NOISE_PUBLIC_KEY_LEN],
136 	    struct noise_local *);
137 int	noise_remote_set_psk(struct noise_remote *, uint8_t[NOISE_SYMMETRIC_KEY_LEN]);
138 int	noise_remote_keys(struct noise_remote *, uint8_t[NOISE_PUBLIC_KEY_LEN],
139 	    uint8_t[NOISE_SYMMETRIC_KEY_LEN]);
140 
141 /* Should be called anytime noise_local_set_private is called */
142 void	noise_remote_precompute(struct noise_remote *);
143 
144 /* Cryptographic functions */
145 int	noise_create_initiation(
146 	    struct noise_remote *,
147 	    uint32_t *s_idx,
148 	    uint8_t ue[NOISE_PUBLIC_KEY_LEN],
149 	    uint8_t es[NOISE_PUBLIC_KEY_LEN + NOISE_AUTHTAG_LEN],
150 	    uint8_t ets[NOISE_TIMESTAMP_LEN + NOISE_AUTHTAG_LEN]);
151 
152 int	noise_consume_initiation(
153 	    struct noise_local *,
154 	    struct noise_remote **,
155 	    uint32_t s_idx,
156 	    uint8_t ue[NOISE_PUBLIC_KEY_LEN],
157 	    uint8_t es[NOISE_PUBLIC_KEY_LEN + NOISE_AUTHTAG_LEN],
158 	    uint8_t ets[NOISE_TIMESTAMP_LEN + NOISE_AUTHTAG_LEN]);
159 
160 int	noise_create_response(
161 	    struct noise_remote *,
162 	    uint32_t *s_idx,
163 	    uint32_t *r_idx,
164 	    uint8_t ue[NOISE_PUBLIC_KEY_LEN],
165 	    uint8_t en[0 + NOISE_AUTHTAG_LEN]);
166 
167 int	noise_consume_response(
168 	    struct noise_remote *,
169 	    uint32_t s_idx,
170 	    uint32_t r_idx,
171 	    uint8_t ue[NOISE_PUBLIC_KEY_LEN],
172 	    uint8_t en[0 + NOISE_AUTHTAG_LEN]);
173 
174 int	noise_remote_begin_session(struct noise_remote *);
175 void	noise_remote_clear(struct noise_remote *);
176 void	noise_remote_expire_current(struct noise_remote *);
177 
178 int	noise_remote_ready(struct noise_remote *);
179 
180 int	noise_remote_encrypt(
181 	    struct noise_remote *,
182 	    uint32_t *r_idx,
183 	    uint64_t *nonce,
184 	    uint8_t *buf,
185 	    size_t buflen);
186 int	noise_remote_decrypt(
187 	    struct noise_remote *,
188 	    uint32_t r_idx,
189 	    uint64_t nonce,
190 	    uint8_t *buf,
191 	    size_t buflen);
192 
193 #ifdef WGTEST
194 void	noise_test();
195 #endif /* WGTEST */
196 
197 #endif /* __NOISE_H__ */
198