xref: /freebsd/sys/dev/wg/wg_noise.c (revision 744bfb213144c63cbaf38d91a1c4f7aebb9b9fbc)
1*744bfb21SJohn Baldwin /* SPDX-License-Identifier: ISC
2*744bfb21SJohn Baldwin  *
3*744bfb21SJohn Baldwin  * Copyright (C) 2015-2021 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
4*744bfb21SJohn Baldwin  * Copyright (C) 2019-2021 Matt Dunwoodie <ncon@noconroy.net>
5*744bfb21SJohn Baldwin  * Copyright (c) 2022 The FreeBSD Foundation
6*744bfb21SJohn Baldwin  */
7*744bfb21SJohn Baldwin 
8*744bfb21SJohn Baldwin #include <sys/param.h>
9*744bfb21SJohn Baldwin #include <sys/systm.h>
10*744bfb21SJohn Baldwin #include <sys/ck.h>
11*744bfb21SJohn Baldwin #include <sys/endian.h>
12*744bfb21SJohn Baldwin #include <sys/epoch.h>
13*744bfb21SJohn Baldwin #include <sys/kernel.h>
14*744bfb21SJohn Baldwin #include <sys/lock.h>
15*744bfb21SJohn Baldwin #include <sys/malloc.h>
16*744bfb21SJohn Baldwin #include <sys/mutex.h>
17*744bfb21SJohn Baldwin #include <sys/refcount.h>
18*744bfb21SJohn Baldwin #include <sys/rwlock.h>
19*744bfb21SJohn Baldwin #include <crypto/siphash/siphash.h>
20*744bfb21SJohn Baldwin 
21*744bfb21SJohn Baldwin #include "crypto.h"
22*744bfb21SJohn Baldwin #include "wg_noise.h"
23*744bfb21SJohn Baldwin #include "support.h"
24*744bfb21SJohn Baldwin 
25*744bfb21SJohn Baldwin /* Protocol string constants */
26*744bfb21SJohn Baldwin #define NOISE_HANDSHAKE_NAME	"Noise_IKpsk2_25519_ChaChaPoly_BLAKE2s"
27*744bfb21SJohn Baldwin #define NOISE_IDENTIFIER_NAME	"WireGuard v1 zx2c4 Jason@zx2c4.com"
28*744bfb21SJohn Baldwin 
29*744bfb21SJohn Baldwin /* Constants for the counter */
30*744bfb21SJohn Baldwin #define COUNTER_BITS_TOTAL	8192
31*744bfb21SJohn Baldwin #ifdef __LP64__
32*744bfb21SJohn Baldwin #define COUNTER_ORDER		6
33*744bfb21SJohn Baldwin #define COUNTER_BITS		64
34*744bfb21SJohn Baldwin #else
35*744bfb21SJohn Baldwin #define COUNTER_ORDER		5
36*744bfb21SJohn Baldwin #define COUNTER_BITS		32
37*744bfb21SJohn Baldwin #endif
38*744bfb21SJohn Baldwin #define COUNTER_REDUNDANT_BITS	COUNTER_BITS
39*744bfb21SJohn Baldwin #define COUNTER_WINDOW_SIZE	(COUNTER_BITS_TOTAL - COUNTER_REDUNDANT_BITS)
40*744bfb21SJohn Baldwin 
41*744bfb21SJohn Baldwin /* Constants for the keypair */
42*744bfb21SJohn Baldwin #define REKEY_AFTER_MESSAGES	(1ull << 60)
43*744bfb21SJohn Baldwin #define REJECT_AFTER_MESSAGES	(UINT64_MAX - COUNTER_WINDOW_SIZE - 1)
44*744bfb21SJohn Baldwin #define REKEY_AFTER_TIME	120
45*744bfb21SJohn Baldwin #define REKEY_AFTER_TIME_RECV	165
46*744bfb21SJohn Baldwin #define REJECT_INTERVAL		(1000000000 / 50) /* fifty times per sec */
47*744bfb21SJohn Baldwin /* 24 = floor(log2(REJECT_INTERVAL)) */
48*744bfb21SJohn Baldwin #define REJECT_INTERVAL_MASK	(~((1ull<<24)-1))
49*744bfb21SJohn Baldwin #define TIMER_RESET		(SBT_1S * -(REKEY_TIMEOUT+1))
50*744bfb21SJohn Baldwin 
51*744bfb21SJohn Baldwin #define HT_INDEX_SIZE		(1 << 13)
52*744bfb21SJohn Baldwin #define HT_INDEX_MASK		(HT_INDEX_SIZE - 1)
53*744bfb21SJohn Baldwin #define HT_REMOTE_SIZE		(1 << 11)
54*744bfb21SJohn Baldwin #define HT_REMOTE_MASK		(HT_REMOTE_SIZE - 1)
55*744bfb21SJohn Baldwin #define MAX_REMOTE_PER_LOCAL	(1 << 20)
56*744bfb21SJohn Baldwin 
57*744bfb21SJohn Baldwin struct noise_index {
58*744bfb21SJohn Baldwin 	CK_LIST_ENTRY(noise_index)	 i_entry;
59*744bfb21SJohn Baldwin 	uint32_t			 i_local_index;
60*744bfb21SJohn Baldwin 	uint32_t			 i_remote_index;
61*744bfb21SJohn Baldwin 	int				 i_is_keypair;
62*744bfb21SJohn Baldwin };
63*744bfb21SJohn Baldwin 
64*744bfb21SJohn Baldwin struct noise_keypair {
65*744bfb21SJohn Baldwin 	struct noise_index		 kp_index;
66*744bfb21SJohn Baldwin 	u_int				 kp_refcnt;
67*744bfb21SJohn Baldwin 	bool				 kp_can_send;
68*744bfb21SJohn Baldwin 	bool				 kp_is_initiator;
69*744bfb21SJohn Baldwin 	sbintime_t			 kp_birthdate; /* sbinuptime */
70*744bfb21SJohn Baldwin 	struct noise_remote		*kp_remote;
71*744bfb21SJohn Baldwin 
72*744bfb21SJohn Baldwin 	uint8_t				 kp_send[NOISE_SYMMETRIC_KEY_LEN];
73*744bfb21SJohn Baldwin 	uint8_t				 kp_recv[NOISE_SYMMETRIC_KEY_LEN];
74*744bfb21SJohn Baldwin 
75*744bfb21SJohn Baldwin 	/* Counter elements */
76*744bfb21SJohn Baldwin 	struct rwlock			 kp_nonce_lock;
77*744bfb21SJohn Baldwin 	uint64_t			 kp_nonce_send;
78*744bfb21SJohn Baldwin 	uint64_t			 kp_nonce_recv;
79*744bfb21SJohn Baldwin 	unsigned long			 kp_backtrack[COUNTER_BITS_TOTAL / COUNTER_BITS];
80*744bfb21SJohn Baldwin 
81*744bfb21SJohn Baldwin 	struct epoch_context		 kp_smr;
82*744bfb21SJohn Baldwin };
83*744bfb21SJohn Baldwin 
84*744bfb21SJohn Baldwin struct noise_handshake {
85*744bfb21SJohn Baldwin 	uint8_t	 			 hs_e[NOISE_PUBLIC_KEY_LEN];
86*744bfb21SJohn Baldwin 	uint8_t	 			 hs_hash[NOISE_HASH_LEN];
87*744bfb21SJohn Baldwin 	uint8_t	 			 hs_ck[NOISE_HASH_LEN];
88*744bfb21SJohn Baldwin };
89*744bfb21SJohn Baldwin 
90*744bfb21SJohn Baldwin enum noise_handshake_state {
91*744bfb21SJohn Baldwin 	HANDSHAKE_DEAD,
92*744bfb21SJohn Baldwin 	HANDSHAKE_INITIATOR,
93*744bfb21SJohn Baldwin 	HANDSHAKE_RESPONDER,
94*744bfb21SJohn Baldwin };
95*744bfb21SJohn Baldwin 
96*744bfb21SJohn Baldwin struct noise_remote {
97*744bfb21SJohn Baldwin 	struct noise_index		 r_index;
98*744bfb21SJohn Baldwin 
99*744bfb21SJohn Baldwin 	CK_LIST_ENTRY(noise_remote) 	 r_entry;
100*744bfb21SJohn Baldwin 	bool				 r_entry_inserted;
101*744bfb21SJohn Baldwin 	uint8_t				 r_public[NOISE_PUBLIC_KEY_LEN];
102*744bfb21SJohn Baldwin 
103*744bfb21SJohn Baldwin 	struct rwlock			 r_handshake_lock;
104*744bfb21SJohn Baldwin 	struct noise_handshake		 r_handshake;
105*744bfb21SJohn Baldwin 	enum noise_handshake_state	 r_handshake_state;
106*744bfb21SJohn Baldwin 	sbintime_t			 r_last_sent; /* sbinuptime */
107*744bfb21SJohn Baldwin 	sbintime_t			 r_last_init_recv; /* sbinuptime */
108*744bfb21SJohn Baldwin 	uint8_t				 r_timestamp[NOISE_TIMESTAMP_LEN];
109*744bfb21SJohn Baldwin 	uint8_t				 r_psk[NOISE_SYMMETRIC_KEY_LEN];
110*744bfb21SJohn Baldwin 	uint8_t		 		 r_ss[NOISE_PUBLIC_KEY_LEN];
111*744bfb21SJohn Baldwin 
112*744bfb21SJohn Baldwin 	u_int				 r_refcnt;
113*744bfb21SJohn Baldwin 	struct noise_local		*r_local;
114*744bfb21SJohn Baldwin 	void				*r_arg;
115*744bfb21SJohn Baldwin 
116*744bfb21SJohn Baldwin 	struct mtx			 r_keypair_mtx;
117*744bfb21SJohn Baldwin 	struct noise_keypair		*r_next, *r_current, *r_previous;
118*744bfb21SJohn Baldwin 
119*744bfb21SJohn Baldwin 	struct epoch_context		 r_smr;
120*744bfb21SJohn Baldwin 	void				(*r_cleanup)(struct noise_remote *);
121*744bfb21SJohn Baldwin };
122*744bfb21SJohn Baldwin 
123*744bfb21SJohn Baldwin struct noise_local {
124*744bfb21SJohn Baldwin 	struct rwlock			 l_identity_lock;
125*744bfb21SJohn Baldwin 	bool				 l_has_identity;
126*744bfb21SJohn Baldwin 	uint8_t				 l_public[NOISE_PUBLIC_KEY_LEN];
127*744bfb21SJohn Baldwin 	uint8_t				 l_private[NOISE_PUBLIC_KEY_LEN];
128*744bfb21SJohn Baldwin 
129*744bfb21SJohn Baldwin 	u_int				 l_refcnt;
130*744bfb21SJohn Baldwin 	uint8_t				 l_hash_key[SIPHASH_KEY_LENGTH];
131*744bfb21SJohn Baldwin 	void				*l_arg;
132*744bfb21SJohn Baldwin 	void				(*l_cleanup)(struct noise_local *);
133*744bfb21SJohn Baldwin 
134*744bfb21SJohn Baldwin 	struct mtx			 l_remote_mtx;
135*744bfb21SJohn Baldwin 	size_t				 l_remote_num;
136*744bfb21SJohn Baldwin 	CK_LIST_HEAD(,noise_remote)	 l_remote_hash[HT_REMOTE_SIZE];
137*744bfb21SJohn Baldwin 
138*744bfb21SJohn Baldwin 	struct mtx			 l_index_mtx;
139*744bfb21SJohn Baldwin 	CK_LIST_HEAD(,noise_index)	 l_index_hash[HT_INDEX_SIZE];
140*744bfb21SJohn Baldwin };
141*744bfb21SJohn Baldwin 
142*744bfb21SJohn Baldwin static void	noise_precompute_ss(struct noise_local *, struct noise_remote *);
143*744bfb21SJohn Baldwin 
144*744bfb21SJohn Baldwin static void	noise_remote_index_insert(struct noise_local *, struct noise_remote *);
145*744bfb21SJohn Baldwin static struct noise_remote *
146*744bfb21SJohn Baldwin 		noise_remote_index_lookup(struct noise_local *, uint32_t, bool);
147*744bfb21SJohn Baldwin static int	noise_remote_index_remove(struct noise_local *, struct noise_remote *);
148*744bfb21SJohn Baldwin static void	noise_remote_expire_current(struct noise_remote *);
149*744bfb21SJohn Baldwin 
150*744bfb21SJohn Baldwin static void	noise_add_new_keypair(struct noise_local *, struct noise_remote *, struct noise_keypair *);
151*744bfb21SJohn Baldwin static int	noise_begin_session(struct noise_remote *);
152*744bfb21SJohn Baldwin static void	noise_keypair_drop(struct noise_keypair *);
153*744bfb21SJohn Baldwin 
154*744bfb21SJohn Baldwin static void	noise_kdf(uint8_t *, uint8_t *, uint8_t *, const uint8_t *,
155*744bfb21SJohn Baldwin 		    size_t, size_t, size_t, size_t,
156*744bfb21SJohn Baldwin 		    const uint8_t [NOISE_HASH_LEN]);
157*744bfb21SJohn Baldwin static int	noise_mix_dh(uint8_t [NOISE_HASH_LEN], uint8_t [NOISE_SYMMETRIC_KEY_LEN],
158*744bfb21SJohn Baldwin 		    const uint8_t [NOISE_PUBLIC_KEY_LEN],
159*744bfb21SJohn Baldwin 		    const uint8_t [NOISE_PUBLIC_KEY_LEN]);
160*744bfb21SJohn Baldwin static int	noise_mix_ss(uint8_t ck[NOISE_HASH_LEN], uint8_t [NOISE_SYMMETRIC_KEY_LEN],
161*744bfb21SJohn Baldwin 		    const uint8_t [NOISE_PUBLIC_KEY_LEN]);
162*744bfb21SJohn Baldwin static void	noise_mix_hash(uint8_t [NOISE_HASH_LEN], const uint8_t *, size_t);
163*744bfb21SJohn Baldwin static void	noise_mix_psk(uint8_t [NOISE_HASH_LEN], uint8_t [NOISE_HASH_LEN],
164*744bfb21SJohn Baldwin 		    uint8_t [NOISE_SYMMETRIC_KEY_LEN], const uint8_t [NOISE_SYMMETRIC_KEY_LEN]);
165*744bfb21SJohn Baldwin static void	noise_param_init(uint8_t [NOISE_HASH_LEN], uint8_t [NOISE_HASH_LEN],
166*744bfb21SJohn Baldwin 		    const uint8_t [NOISE_PUBLIC_KEY_LEN]);
167*744bfb21SJohn Baldwin static void	noise_msg_encrypt(uint8_t *, const uint8_t *, size_t,
168*744bfb21SJohn Baldwin 		    uint8_t [NOISE_SYMMETRIC_KEY_LEN], uint8_t [NOISE_HASH_LEN]);
169*744bfb21SJohn Baldwin static int	noise_msg_decrypt(uint8_t *, const uint8_t *, size_t,
170*744bfb21SJohn Baldwin 		    uint8_t [NOISE_SYMMETRIC_KEY_LEN], uint8_t [NOISE_HASH_LEN]);
171*744bfb21SJohn Baldwin static void	noise_msg_ephemeral(uint8_t [NOISE_HASH_LEN], uint8_t [NOISE_HASH_LEN],
172*744bfb21SJohn Baldwin 		    const uint8_t [NOISE_PUBLIC_KEY_LEN]);
173*744bfb21SJohn Baldwin static void	noise_tai64n_now(uint8_t [NOISE_TIMESTAMP_LEN]);
174*744bfb21SJohn Baldwin static int	noise_timer_expired(sbintime_t, uint32_t, uint32_t);
175*744bfb21SJohn Baldwin static uint64_t siphash24(const uint8_t [SIPHASH_KEY_LENGTH], const void *, size_t);
176*744bfb21SJohn Baldwin 
177*744bfb21SJohn Baldwin MALLOC_DEFINE(M_NOISE, "NOISE", "wgnoise");
178*744bfb21SJohn Baldwin 
179*744bfb21SJohn Baldwin /* Local configuration */
180*744bfb21SJohn Baldwin struct noise_local *
181*744bfb21SJohn Baldwin noise_local_alloc(void *arg)
182*744bfb21SJohn Baldwin {
183*744bfb21SJohn Baldwin 	struct noise_local *l;
184*744bfb21SJohn Baldwin 	size_t i;
185*744bfb21SJohn Baldwin 
186*744bfb21SJohn Baldwin 	l = malloc(sizeof(*l), M_NOISE, M_WAITOK | M_ZERO);
187*744bfb21SJohn Baldwin 
188*744bfb21SJohn Baldwin 	rw_init(&l->l_identity_lock, "noise_identity");
189*744bfb21SJohn Baldwin 	l->l_has_identity = false;
190*744bfb21SJohn Baldwin 	bzero(l->l_public, NOISE_PUBLIC_KEY_LEN);
191*744bfb21SJohn Baldwin 	bzero(l->l_private, NOISE_PUBLIC_KEY_LEN);
192*744bfb21SJohn Baldwin 
193*744bfb21SJohn Baldwin 	refcount_init(&l->l_refcnt, 1);
194*744bfb21SJohn Baldwin 	arc4random_buf(l->l_hash_key, sizeof(l->l_hash_key));
195*744bfb21SJohn Baldwin 	l->l_arg = arg;
196*744bfb21SJohn Baldwin 	l->l_cleanup = NULL;
197*744bfb21SJohn Baldwin 
198*744bfb21SJohn Baldwin 	mtx_init(&l->l_remote_mtx, "noise_remote", NULL, MTX_DEF);
199*744bfb21SJohn Baldwin 	l->l_remote_num = 0;
200*744bfb21SJohn Baldwin 	for (i = 0; i < HT_REMOTE_SIZE; i++)
201*744bfb21SJohn Baldwin 		CK_LIST_INIT(&l->l_remote_hash[i]);
202*744bfb21SJohn Baldwin 
203*744bfb21SJohn Baldwin 	mtx_init(&l->l_index_mtx, "noise_index", NULL, MTX_DEF);
204*744bfb21SJohn Baldwin 	for (i = 0; i < HT_INDEX_SIZE; i++)
205*744bfb21SJohn Baldwin 		CK_LIST_INIT(&l->l_index_hash[i]);
206*744bfb21SJohn Baldwin 
207*744bfb21SJohn Baldwin 	return (l);
208*744bfb21SJohn Baldwin }
209*744bfb21SJohn Baldwin 
210*744bfb21SJohn Baldwin struct noise_local *
211*744bfb21SJohn Baldwin noise_local_ref(struct noise_local *l)
212*744bfb21SJohn Baldwin {
213*744bfb21SJohn Baldwin 	refcount_acquire(&l->l_refcnt);
214*744bfb21SJohn Baldwin 	return (l);
215*744bfb21SJohn Baldwin }
216*744bfb21SJohn Baldwin 
217*744bfb21SJohn Baldwin void
218*744bfb21SJohn Baldwin noise_local_put(struct noise_local *l)
219*744bfb21SJohn Baldwin {
220*744bfb21SJohn Baldwin 	if (refcount_release(&l->l_refcnt)) {
221*744bfb21SJohn Baldwin 		if (l->l_cleanup != NULL)
222*744bfb21SJohn Baldwin 			l->l_cleanup(l);
223*744bfb21SJohn Baldwin 		rw_destroy(&l->l_identity_lock);
224*744bfb21SJohn Baldwin 		mtx_destroy(&l->l_remote_mtx);
225*744bfb21SJohn Baldwin 		mtx_destroy(&l->l_index_mtx);
226*744bfb21SJohn Baldwin 		explicit_bzero(l, sizeof(*l));
227*744bfb21SJohn Baldwin 		free(l, M_NOISE);
228*744bfb21SJohn Baldwin 	}
229*744bfb21SJohn Baldwin }
230*744bfb21SJohn Baldwin 
231*744bfb21SJohn Baldwin void
232*744bfb21SJohn Baldwin noise_local_free(struct noise_local *l, void (*cleanup)(struct noise_local *))
233*744bfb21SJohn Baldwin {
234*744bfb21SJohn Baldwin 	l->l_cleanup = cleanup;
235*744bfb21SJohn Baldwin 	noise_local_put(l);
236*744bfb21SJohn Baldwin }
237*744bfb21SJohn Baldwin 
238*744bfb21SJohn Baldwin void *
239*744bfb21SJohn Baldwin noise_local_arg(struct noise_local *l)
240*744bfb21SJohn Baldwin {
241*744bfb21SJohn Baldwin 	return (l->l_arg);
242*744bfb21SJohn Baldwin }
243*744bfb21SJohn Baldwin 
244*744bfb21SJohn Baldwin void
245*744bfb21SJohn Baldwin noise_local_private(struct noise_local *l, const uint8_t private[NOISE_PUBLIC_KEY_LEN])
246*744bfb21SJohn Baldwin {
247*744bfb21SJohn Baldwin 	struct epoch_tracker et;
248*744bfb21SJohn Baldwin 	struct noise_remote *r;
249*744bfb21SJohn Baldwin 	size_t i;
250*744bfb21SJohn Baldwin 
251*744bfb21SJohn Baldwin 	rw_wlock(&l->l_identity_lock);
252*744bfb21SJohn Baldwin 	memcpy(l->l_private, private, NOISE_PUBLIC_KEY_LEN);
253*744bfb21SJohn Baldwin 	curve25519_clamp_secret(l->l_private);
254*744bfb21SJohn Baldwin 	l->l_has_identity = curve25519_generate_public(l->l_public, l->l_private);
255*744bfb21SJohn Baldwin 
256*744bfb21SJohn Baldwin 	NET_EPOCH_ENTER(et);
257*744bfb21SJohn Baldwin 	for (i = 0; i < HT_REMOTE_SIZE; i++) {
258*744bfb21SJohn Baldwin 		CK_LIST_FOREACH(r, &l->l_remote_hash[i], r_entry) {
259*744bfb21SJohn Baldwin 			noise_precompute_ss(l, r);
260*744bfb21SJohn Baldwin 			noise_remote_expire_current(r);
261*744bfb21SJohn Baldwin 		}
262*744bfb21SJohn Baldwin 	}
263*744bfb21SJohn Baldwin 	NET_EPOCH_EXIT(et);
264*744bfb21SJohn Baldwin 	rw_wunlock(&l->l_identity_lock);
265*744bfb21SJohn Baldwin }
266*744bfb21SJohn Baldwin 
267*744bfb21SJohn Baldwin int
268*744bfb21SJohn Baldwin noise_local_keys(struct noise_local *l, uint8_t public[NOISE_PUBLIC_KEY_LEN],
269*744bfb21SJohn Baldwin     uint8_t private[NOISE_PUBLIC_KEY_LEN])
270*744bfb21SJohn Baldwin {
271*744bfb21SJohn Baldwin 	int has_identity;
272*744bfb21SJohn Baldwin 	rw_rlock(&l->l_identity_lock);
273*744bfb21SJohn Baldwin 	if ((has_identity = l->l_has_identity)) {
274*744bfb21SJohn Baldwin 		if (public != NULL)
275*744bfb21SJohn Baldwin 			memcpy(public, l->l_public, NOISE_PUBLIC_KEY_LEN);
276*744bfb21SJohn Baldwin 		if (private != NULL)
277*744bfb21SJohn Baldwin 			memcpy(private, l->l_private, NOISE_PUBLIC_KEY_LEN);
278*744bfb21SJohn Baldwin 	}
279*744bfb21SJohn Baldwin 	rw_runlock(&l->l_identity_lock);
280*744bfb21SJohn Baldwin 	return (has_identity ? 0 : ENXIO);
281*744bfb21SJohn Baldwin }
282*744bfb21SJohn Baldwin 
283*744bfb21SJohn Baldwin static void
284*744bfb21SJohn Baldwin noise_precompute_ss(struct noise_local *l, struct noise_remote *r)
285*744bfb21SJohn Baldwin {
286*744bfb21SJohn Baldwin 	rw_wlock(&r->r_handshake_lock);
287*744bfb21SJohn Baldwin 	if (!l->l_has_identity ||
288*744bfb21SJohn Baldwin 	    !curve25519(r->r_ss, l->l_private, r->r_public))
289*744bfb21SJohn Baldwin 		bzero(r->r_ss, NOISE_PUBLIC_KEY_LEN);
290*744bfb21SJohn Baldwin 	rw_wunlock(&r->r_handshake_lock);
291*744bfb21SJohn Baldwin }
292*744bfb21SJohn Baldwin 
293*744bfb21SJohn Baldwin /* Remote configuration */
294*744bfb21SJohn Baldwin struct noise_remote *
295*744bfb21SJohn Baldwin noise_remote_alloc(struct noise_local *l, void *arg,
296*744bfb21SJohn Baldwin     const uint8_t public[NOISE_PUBLIC_KEY_LEN])
297*744bfb21SJohn Baldwin {
298*744bfb21SJohn Baldwin 	struct noise_remote *r;
299*744bfb21SJohn Baldwin 
300*744bfb21SJohn Baldwin 	r = malloc(sizeof(*r), M_NOISE, M_WAITOK | M_ZERO);
301*744bfb21SJohn Baldwin 	memcpy(r->r_public, public, NOISE_PUBLIC_KEY_LEN);
302*744bfb21SJohn Baldwin 
303*744bfb21SJohn Baldwin 	rw_init(&r->r_handshake_lock, "noise_handshake");
304*744bfb21SJohn Baldwin 	r->r_handshake_state = HANDSHAKE_DEAD;
305*744bfb21SJohn Baldwin 	r->r_last_sent = TIMER_RESET;
306*744bfb21SJohn Baldwin 	r->r_last_init_recv = TIMER_RESET;
307*744bfb21SJohn Baldwin 	noise_precompute_ss(l, r);
308*744bfb21SJohn Baldwin 
309*744bfb21SJohn Baldwin 	refcount_init(&r->r_refcnt, 1);
310*744bfb21SJohn Baldwin 	r->r_local = noise_local_ref(l);
311*744bfb21SJohn Baldwin 	r->r_arg = arg;
312*744bfb21SJohn Baldwin 
313*744bfb21SJohn Baldwin 	mtx_init(&r->r_keypair_mtx, "noise_keypair", NULL, MTX_DEF);
314*744bfb21SJohn Baldwin 
315*744bfb21SJohn Baldwin 	return (r);
316*744bfb21SJohn Baldwin }
317*744bfb21SJohn Baldwin 
318*744bfb21SJohn Baldwin int
319*744bfb21SJohn Baldwin noise_remote_enable(struct noise_remote *r)
320*744bfb21SJohn Baldwin {
321*744bfb21SJohn Baldwin 	struct noise_local *l = r->r_local;
322*744bfb21SJohn Baldwin 	uint64_t idx;
323*744bfb21SJohn Baldwin 	int ret = 0;
324*744bfb21SJohn Baldwin 
325*744bfb21SJohn Baldwin 	/* Insert to hashtable */
326*744bfb21SJohn Baldwin 	idx = siphash24(l->l_hash_key, r->r_public, NOISE_PUBLIC_KEY_LEN) & HT_REMOTE_MASK;
327*744bfb21SJohn Baldwin 
328*744bfb21SJohn Baldwin 	mtx_lock(&l->l_remote_mtx);
329*744bfb21SJohn Baldwin 	if (!r->r_entry_inserted) {
330*744bfb21SJohn Baldwin 		if (l->l_remote_num < MAX_REMOTE_PER_LOCAL) {
331*744bfb21SJohn Baldwin 			r->r_entry_inserted = true;
332*744bfb21SJohn Baldwin 			l->l_remote_num++;
333*744bfb21SJohn Baldwin 			CK_LIST_INSERT_HEAD(&l->l_remote_hash[idx], r, r_entry);
334*744bfb21SJohn Baldwin 		} else {
335*744bfb21SJohn Baldwin 			ret = ENOSPC;
336*744bfb21SJohn Baldwin 		}
337*744bfb21SJohn Baldwin 	}
338*744bfb21SJohn Baldwin 	mtx_unlock(&l->l_remote_mtx);
339*744bfb21SJohn Baldwin 
340*744bfb21SJohn Baldwin 	return ret;
341*744bfb21SJohn Baldwin }
342*744bfb21SJohn Baldwin 
343*744bfb21SJohn Baldwin void
344*744bfb21SJohn Baldwin noise_remote_disable(struct noise_remote *r)
345*744bfb21SJohn Baldwin {
346*744bfb21SJohn Baldwin 	struct noise_local *l = r->r_local;
347*744bfb21SJohn Baldwin 	/* remove from hashtable */
348*744bfb21SJohn Baldwin 	mtx_lock(&l->l_remote_mtx);
349*744bfb21SJohn Baldwin 	if (r->r_entry_inserted) {
350*744bfb21SJohn Baldwin 		r->r_entry_inserted = false;
351*744bfb21SJohn Baldwin 		CK_LIST_REMOVE(r, r_entry);
352*744bfb21SJohn Baldwin 		l->l_remote_num--;
353*744bfb21SJohn Baldwin 	};
354*744bfb21SJohn Baldwin 	mtx_unlock(&l->l_remote_mtx);
355*744bfb21SJohn Baldwin }
356*744bfb21SJohn Baldwin 
357*744bfb21SJohn Baldwin struct noise_remote *
358*744bfb21SJohn Baldwin noise_remote_lookup(struct noise_local *l, const uint8_t public[NOISE_PUBLIC_KEY_LEN])
359*744bfb21SJohn Baldwin {
360*744bfb21SJohn Baldwin 	struct epoch_tracker et;
361*744bfb21SJohn Baldwin 	struct noise_remote *r, *ret = NULL;
362*744bfb21SJohn Baldwin 	uint64_t idx;
363*744bfb21SJohn Baldwin 
364*744bfb21SJohn Baldwin 	idx = siphash24(l->l_hash_key, public, NOISE_PUBLIC_KEY_LEN) & HT_REMOTE_MASK;
365*744bfb21SJohn Baldwin 
366*744bfb21SJohn Baldwin 	NET_EPOCH_ENTER(et);
367*744bfb21SJohn Baldwin 	CK_LIST_FOREACH(r, &l->l_remote_hash[idx], r_entry) {
368*744bfb21SJohn Baldwin 		if (timingsafe_bcmp(r->r_public, public, NOISE_PUBLIC_KEY_LEN) == 0) {
369*744bfb21SJohn Baldwin 			if (refcount_acquire_if_not_zero(&r->r_refcnt))
370*744bfb21SJohn Baldwin 				ret = r;
371*744bfb21SJohn Baldwin 			break;
372*744bfb21SJohn Baldwin 		}
373*744bfb21SJohn Baldwin 	}
374*744bfb21SJohn Baldwin 	NET_EPOCH_EXIT(et);
375*744bfb21SJohn Baldwin 	return (ret);
376*744bfb21SJohn Baldwin }
377*744bfb21SJohn Baldwin 
378*744bfb21SJohn Baldwin static void
379*744bfb21SJohn Baldwin noise_remote_index_insert(struct noise_local *l, struct noise_remote *r)
380*744bfb21SJohn Baldwin {
381*744bfb21SJohn Baldwin 	struct noise_index *i, *r_i = &r->r_index;
382*744bfb21SJohn Baldwin 	struct epoch_tracker et;
383*744bfb21SJohn Baldwin 	uint32_t idx;
384*744bfb21SJohn Baldwin 
385*744bfb21SJohn Baldwin 	noise_remote_index_remove(l, r);
386*744bfb21SJohn Baldwin 
387*744bfb21SJohn Baldwin 	NET_EPOCH_ENTER(et);
388*744bfb21SJohn Baldwin assign_id:
389*744bfb21SJohn Baldwin 	r_i->i_local_index = arc4random();
390*744bfb21SJohn Baldwin 	idx = r_i->i_local_index & HT_INDEX_MASK;
391*744bfb21SJohn Baldwin 	CK_LIST_FOREACH(i, &l->l_index_hash[idx], i_entry) {
392*744bfb21SJohn Baldwin 		if (i->i_local_index == r_i->i_local_index)
393*744bfb21SJohn Baldwin 			goto assign_id;
394*744bfb21SJohn Baldwin 	}
395*744bfb21SJohn Baldwin 
396*744bfb21SJohn Baldwin 	mtx_lock(&l->l_index_mtx);
397*744bfb21SJohn Baldwin 	CK_LIST_FOREACH(i, &l->l_index_hash[idx], i_entry) {
398*744bfb21SJohn Baldwin 		if (i->i_local_index == r_i->i_local_index) {
399*744bfb21SJohn Baldwin 			mtx_unlock(&l->l_index_mtx);
400*744bfb21SJohn Baldwin 			goto assign_id;
401*744bfb21SJohn Baldwin 		}
402*744bfb21SJohn Baldwin 	}
403*744bfb21SJohn Baldwin 	CK_LIST_INSERT_HEAD(&l->l_index_hash[idx], r_i, i_entry);
404*744bfb21SJohn Baldwin 	mtx_unlock(&l->l_index_mtx);
405*744bfb21SJohn Baldwin 
406*744bfb21SJohn Baldwin 	NET_EPOCH_EXIT(et);
407*744bfb21SJohn Baldwin }
408*744bfb21SJohn Baldwin 
409*744bfb21SJohn Baldwin static struct noise_remote *
410*744bfb21SJohn Baldwin noise_remote_index_lookup(struct noise_local *l, uint32_t idx0, bool lookup_keypair)
411*744bfb21SJohn Baldwin {
412*744bfb21SJohn Baldwin 	struct epoch_tracker et;
413*744bfb21SJohn Baldwin 	struct noise_index *i;
414*744bfb21SJohn Baldwin 	struct noise_keypair *kp;
415*744bfb21SJohn Baldwin 	struct noise_remote *r, *ret = NULL;
416*744bfb21SJohn Baldwin 	uint32_t idx = idx0 & HT_INDEX_MASK;
417*744bfb21SJohn Baldwin 
418*744bfb21SJohn Baldwin 	NET_EPOCH_ENTER(et);
419*744bfb21SJohn Baldwin 	CK_LIST_FOREACH(i, &l->l_index_hash[idx], i_entry) {
420*744bfb21SJohn Baldwin 		if (i->i_local_index == idx0) {
421*744bfb21SJohn Baldwin 			if (!i->i_is_keypair) {
422*744bfb21SJohn Baldwin 				r = (struct noise_remote *) i;
423*744bfb21SJohn Baldwin 			} else if (lookup_keypair) {
424*744bfb21SJohn Baldwin 				kp = (struct noise_keypair *) i;
425*744bfb21SJohn Baldwin 				r = kp->kp_remote;
426*744bfb21SJohn Baldwin 			} else {
427*744bfb21SJohn Baldwin 				break;
428*744bfb21SJohn Baldwin 			}
429*744bfb21SJohn Baldwin 			if (refcount_acquire_if_not_zero(&r->r_refcnt))
430*744bfb21SJohn Baldwin 				ret = r;
431*744bfb21SJohn Baldwin 			break;
432*744bfb21SJohn Baldwin 		}
433*744bfb21SJohn Baldwin 	}
434*744bfb21SJohn Baldwin 	NET_EPOCH_EXIT(et);
435*744bfb21SJohn Baldwin 	return (ret);
436*744bfb21SJohn Baldwin }
437*744bfb21SJohn Baldwin 
438*744bfb21SJohn Baldwin struct noise_remote *
439*744bfb21SJohn Baldwin noise_remote_index(struct noise_local *l, uint32_t idx)
440*744bfb21SJohn Baldwin {
441*744bfb21SJohn Baldwin 	return noise_remote_index_lookup(l, idx, true);
442*744bfb21SJohn Baldwin }
443*744bfb21SJohn Baldwin 
444*744bfb21SJohn Baldwin static int
445*744bfb21SJohn Baldwin noise_remote_index_remove(struct noise_local *l, struct noise_remote *r)
446*744bfb21SJohn Baldwin {
447*744bfb21SJohn Baldwin 	rw_assert(&r->r_handshake_lock, RA_WLOCKED);
448*744bfb21SJohn Baldwin 	if (r->r_handshake_state != HANDSHAKE_DEAD) {
449*744bfb21SJohn Baldwin 		mtx_lock(&l->l_index_mtx);
450*744bfb21SJohn Baldwin 		r->r_handshake_state = HANDSHAKE_DEAD;
451*744bfb21SJohn Baldwin 		CK_LIST_REMOVE(&r->r_index, i_entry);
452*744bfb21SJohn Baldwin 		mtx_unlock(&l->l_index_mtx);
453*744bfb21SJohn Baldwin 		return (1);
454*744bfb21SJohn Baldwin 	}
455*744bfb21SJohn Baldwin 	return (0);
456*744bfb21SJohn Baldwin }
457*744bfb21SJohn Baldwin 
458*744bfb21SJohn Baldwin struct noise_remote *
459*744bfb21SJohn Baldwin noise_remote_ref(struct noise_remote *r)
460*744bfb21SJohn Baldwin {
461*744bfb21SJohn Baldwin 	refcount_acquire(&r->r_refcnt);
462*744bfb21SJohn Baldwin 	return (r);
463*744bfb21SJohn Baldwin }
464*744bfb21SJohn Baldwin 
465*744bfb21SJohn Baldwin static void
466*744bfb21SJohn Baldwin noise_remote_smr_free(struct epoch_context *smr)
467*744bfb21SJohn Baldwin {
468*744bfb21SJohn Baldwin 	struct noise_remote *r;
469*744bfb21SJohn Baldwin 	r = __containerof(smr, struct noise_remote, r_smr);
470*744bfb21SJohn Baldwin 	if (r->r_cleanup != NULL)
471*744bfb21SJohn Baldwin 		r->r_cleanup(r);
472*744bfb21SJohn Baldwin 	noise_local_put(r->r_local);
473*744bfb21SJohn Baldwin 	rw_destroy(&r->r_handshake_lock);
474*744bfb21SJohn Baldwin 	mtx_destroy(&r->r_keypair_mtx);
475*744bfb21SJohn Baldwin 	explicit_bzero(r, sizeof(*r));
476*744bfb21SJohn Baldwin 	free(r, M_NOISE);
477*744bfb21SJohn Baldwin }
478*744bfb21SJohn Baldwin 
479*744bfb21SJohn Baldwin void
480*744bfb21SJohn Baldwin noise_remote_put(struct noise_remote *r)
481*744bfb21SJohn Baldwin {
482*744bfb21SJohn Baldwin 	if (refcount_release(&r->r_refcnt))
483*744bfb21SJohn Baldwin 		NET_EPOCH_CALL(noise_remote_smr_free, &r->r_smr);
484*744bfb21SJohn Baldwin }
485*744bfb21SJohn Baldwin 
486*744bfb21SJohn Baldwin void
487*744bfb21SJohn Baldwin noise_remote_free(struct noise_remote *r, void (*cleanup)(struct noise_remote *))
488*744bfb21SJohn Baldwin {
489*744bfb21SJohn Baldwin 	r->r_cleanup = cleanup;
490*744bfb21SJohn Baldwin 	noise_remote_disable(r);
491*744bfb21SJohn Baldwin 
492*744bfb21SJohn Baldwin 	/* now clear all keypairs and handshakes, then put this reference */
493*744bfb21SJohn Baldwin 	noise_remote_handshake_clear(r);
494*744bfb21SJohn Baldwin 	noise_remote_keypairs_clear(r);
495*744bfb21SJohn Baldwin 	noise_remote_put(r);
496*744bfb21SJohn Baldwin }
497*744bfb21SJohn Baldwin 
498*744bfb21SJohn Baldwin struct noise_local *
499*744bfb21SJohn Baldwin noise_remote_local(struct noise_remote *r)
500*744bfb21SJohn Baldwin {
501*744bfb21SJohn Baldwin 	return (noise_local_ref(r->r_local));
502*744bfb21SJohn Baldwin }
503*744bfb21SJohn Baldwin 
504*744bfb21SJohn Baldwin void *
505*744bfb21SJohn Baldwin noise_remote_arg(struct noise_remote *r)
506*744bfb21SJohn Baldwin {
507*744bfb21SJohn Baldwin 	return (r->r_arg);
508*744bfb21SJohn Baldwin }
509*744bfb21SJohn Baldwin 
510*744bfb21SJohn Baldwin void
511*744bfb21SJohn Baldwin noise_remote_set_psk(struct noise_remote *r,
512*744bfb21SJohn Baldwin     const uint8_t psk[NOISE_SYMMETRIC_KEY_LEN])
513*744bfb21SJohn Baldwin {
514*744bfb21SJohn Baldwin 	rw_wlock(&r->r_handshake_lock);
515*744bfb21SJohn Baldwin 	if (psk == NULL)
516*744bfb21SJohn Baldwin 		bzero(r->r_psk, NOISE_SYMMETRIC_KEY_LEN);
517*744bfb21SJohn Baldwin 	else
518*744bfb21SJohn Baldwin 		memcpy(r->r_psk, psk, NOISE_SYMMETRIC_KEY_LEN);
519*744bfb21SJohn Baldwin 	rw_wunlock(&r->r_handshake_lock);
520*744bfb21SJohn Baldwin }
521*744bfb21SJohn Baldwin 
522*744bfb21SJohn Baldwin int
523*744bfb21SJohn Baldwin noise_remote_keys(struct noise_remote *r, uint8_t public[NOISE_PUBLIC_KEY_LEN],
524*744bfb21SJohn Baldwin     uint8_t psk[NOISE_SYMMETRIC_KEY_LEN])
525*744bfb21SJohn Baldwin {
526*744bfb21SJohn Baldwin 	static uint8_t null_psk[NOISE_SYMMETRIC_KEY_LEN];
527*744bfb21SJohn Baldwin 	int ret;
528*744bfb21SJohn Baldwin 
529*744bfb21SJohn Baldwin 	if (public != NULL)
530*744bfb21SJohn Baldwin 		memcpy(public, r->r_public, NOISE_PUBLIC_KEY_LEN);
531*744bfb21SJohn Baldwin 
532*744bfb21SJohn Baldwin 	rw_rlock(&r->r_handshake_lock);
533*744bfb21SJohn Baldwin 	if (psk != NULL)
534*744bfb21SJohn Baldwin 		memcpy(psk, r->r_psk, NOISE_SYMMETRIC_KEY_LEN);
535*744bfb21SJohn Baldwin 	ret = timingsafe_bcmp(r->r_psk, null_psk, NOISE_SYMMETRIC_KEY_LEN);
536*744bfb21SJohn Baldwin 	rw_runlock(&r->r_handshake_lock);
537*744bfb21SJohn Baldwin 
538*744bfb21SJohn Baldwin 	return (ret ? 0 : ENOENT);
539*744bfb21SJohn Baldwin }
540*744bfb21SJohn Baldwin 
541*744bfb21SJohn Baldwin int
542*744bfb21SJohn Baldwin noise_remote_initiation_expired(struct noise_remote *r)
543*744bfb21SJohn Baldwin {
544*744bfb21SJohn Baldwin 	int expired;
545*744bfb21SJohn Baldwin 	rw_rlock(&r->r_handshake_lock);
546*744bfb21SJohn Baldwin 	expired = noise_timer_expired(r->r_last_sent, REKEY_TIMEOUT, 0);
547*744bfb21SJohn Baldwin 	rw_runlock(&r->r_handshake_lock);
548*744bfb21SJohn Baldwin 	return (expired);
549*744bfb21SJohn Baldwin }
550*744bfb21SJohn Baldwin 
551*744bfb21SJohn Baldwin void
552*744bfb21SJohn Baldwin noise_remote_handshake_clear(struct noise_remote *r)
553*744bfb21SJohn Baldwin {
554*744bfb21SJohn Baldwin 	rw_wlock(&r->r_handshake_lock);
555*744bfb21SJohn Baldwin 	if (noise_remote_index_remove(r->r_local, r))
556*744bfb21SJohn Baldwin 		bzero(&r->r_handshake, sizeof(r->r_handshake));
557*744bfb21SJohn Baldwin 	r->r_last_sent = TIMER_RESET;
558*744bfb21SJohn Baldwin 	rw_wunlock(&r->r_handshake_lock);
559*744bfb21SJohn Baldwin }
560*744bfb21SJohn Baldwin 
561*744bfb21SJohn Baldwin void
562*744bfb21SJohn Baldwin noise_remote_keypairs_clear(struct noise_remote *r)
563*744bfb21SJohn Baldwin {
564*744bfb21SJohn Baldwin 	struct noise_keypair *kp;
565*744bfb21SJohn Baldwin 
566*744bfb21SJohn Baldwin 	mtx_lock(&r->r_keypair_mtx);
567*744bfb21SJohn Baldwin 	kp = ck_pr_load_ptr(&r->r_next);
568*744bfb21SJohn Baldwin 	ck_pr_store_ptr(&r->r_next, NULL);
569*744bfb21SJohn Baldwin 	noise_keypair_drop(kp);
570*744bfb21SJohn Baldwin 
571*744bfb21SJohn Baldwin 	kp = ck_pr_load_ptr(&r->r_current);
572*744bfb21SJohn Baldwin 	ck_pr_store_ptr(&r->r_current, NULL);
573*744bfb21SJohn Baldwin 	noise_keypair_drop(kp);
574*744bfb21SJohn Baldwin 
575*744bfb21SJohn Baldwin 	kp = ck_pr_load_ptr(&r->r_previous);
576*744bfb21SJohn Baldwin 	ck_pr_store_ptr(&r->r_previous, NULL);
577*744bfb21SJohn Baldwin 	noise_keypair_drop(kp);
578*744bfb21SJohn Baldwin 	mtx_unlock(&r->r_keypair_mtx);
579*744bfb21SJohn Baldwin }
580*744bfb21SJohn Baldwin 
581*744bfb21SJohn Baldwin static void
582*744bfb21SJohn Baldwin noise_remote_expire_current(struct noise_remote *r)
583*744bfb21SJohn Baldwin {
584*744bfb21SJohn Baldwin 	struct epoch_tracker et;
585*744bfb21SJohn Baldwin 	struct noise_keypair *kp;
586*744bfb21SJohn Baldwin 
587*744bfb21SJohn Baldwin 	noise_remote_handshake_clear(r);
588*744bfb21SJohn Baldwin 
589*744bfb21SJohn Baldwin 	NET_EPOCH_ENTER(et);
590*744bfb21SJohn Baldwin 	kp = ck_pr_load_ptr(&r->r_next);
591*744bfb21SJohn Baldwin 	if (kp != NULL)
592*744bfb21SJohn Baldwin 		ck_pr_store_bool(&kp->kp_can_send, false);
593*744bfb21SJohn Baldwin 	kp = ck_pr_load_ptr(&r->r_current);
594*744bfb21SJohn Baldwin 	if (kp != NULL)
595*744bfb21SJohn Baldwin 		ck_pr_store_bool(&kp->kp_can_send, false);
596*744bfb21SJohn Baldwin 	NET_EPOCH_EXIT(et);
597*744bfb21SJohn Baldwin }
598*744bfb21SJohn Baldwin 
599*744bfb21SJohn Baldwin /* Keypair functions */
600*744bfb21SJohn Baldwin static void
601*744bfb21SJohn Baldwin noise_add_new_keypair(struct noise_local *l, struct noise_remote *r,
602*744bfb21SJohn Baldwin     struct noise_keypair *kp)
603*744bfb21SJohn Baldwin {
604*744bfb21SJohn Baldwin 	struct noise_keypair *next, *current, *previous;
605*744bfb21SJohn Baldwin 	struct noise_index *r_i = &r->r_index;
606*744bfb21SJohn Baldwin 
607*744bfb21SJohn Baldwin 	/* Insert into the keypair table */
608*744bfb21SJohn Baldwin 	mtx_lock(&r->r_keypair_mtx);
609*744bfb21SJohn Baldwin 	next = ck_pr_load_ptr(&r->r_next);
610*744bfb21SJohn Baldwin 	current = ck_pr_load_ptr(&r->r_current);
611*744bfb21SJohn Baldwin 	previous = ck_pr_load_ptr(&r->r_previous);
612*744bfb21SJohn Baldwin 
613*744bfb21SJohn Baldwin 	if (kp->kp_is_initiator) {
614*744bfb21SJohn Baldwin 		if (next != NULL) {
615*744bfb21SJohn Baldwin 			ck_pr_store_ptr(&r->r_next, NULL);
616*744bfb21SJohn Baldwin 			ck_pr_store_ptr(&r->r_previous, next);
617*744bfb21SJohn Baldwin 			noise_keypair_drop(current);
618*744bfb21SJohn Baldwin 		} else {
619*744bfb21SJohn Baldwin 			ck_pr_store_ptr(&r->r_previous, current);
620*744bfb21SJohn Baldwin 		}
621*744bfb21SJohn Baldwin 		noise_keypair_drop(previous);
622*744bfb21SJohn Baldwin 		ck_pr_store_ptr(&r->r_current, kp);
623*744bfb21SJohn Baldwin 	} else {
624*744bfb21SJohn Baldwin 		ck_pr_store_ptr(&r->r_next, kp);
625*744bfb21SJohn Baldwin 		noise_keypair_drop(next);
626*744bfb21SJohn Baldwin 		ck_pr_store_ptr(&r->r_previous, NULL);
627*744bfb21SJohn Baldwin 		noise_keypair_drop(previous);
628*744bfb21SJohn Baldwin 
629*744bfb21SJohn Baldwin 	}
630*744bfb21SJohn Baldwin 	mtx_unlock(&r->r_keypair_mtx);
631*744bfb21SJohn Baldwin 
632*744bfb21SJohn Baldwin 	/* Insert into index table */
633*744bfb21SJohn Baldwin 	rw_assert(&r->r_handshake_lock, RA_WLOCKED);
634*744bfb21SJohn Baldwin 
635*744bfb21SJohn Baldwin 	kp->kp_index.i_is_keypair = true;
636*744bfb21SJohn Baldwin 	kp->kp_index.i_local_index = r_i->i_local_index;
637*744bfb21SJohn Baldwin 	kp->kp_index.i_remote_index = r_i->i_remote_index;
638*744bfb21SJohn Baldwin 
639*744bfb21SJohn Baldwin 	mtx_lock(&l->l_index_mtx);
640*744bfb21SJohn Baldwin 	CK_LIST_INSERT_BEFORE(r_i, &kp->kp_index, i_entry);
641*744bfb21SJohn Baldwin 	r->r_handshake_state = HANDSHAKE_DEAD;
642*744bfb21SJohn Baldwin 	CK_LIST_REMOVE(r_i, i_entry);
643*744bfb21SJohn Baldwin 	mtx_unlock(&l->l_index_mtx);
644*744bfb21SJohn Baldwin 
645*744bfb21SJohn Baldwin 	explicit_bzero(&r->r_handshake, sizeof(r->r_handshake));
646*744bfb21SJohn Baldwin }
647*744bfb21SJohn Baldwin 
648*744bfb21SJohn Baldwin static int
649*744bfb21SJohn Baldwin noise_begin_session(struct noise_remote *r)
650*744bfb21SJohn Baldwin {
651*744bfb21SJohn Baldwin 	struct noise_keypair *kp;
652*744bfb21SJohn Baldwin 
653*744bfb21SJohn Baldwin 	rw_assert(&r->r_handshake_lock, RA_WLOCKED);
654*744bfb21SJohn Baldwin 
655*744bfb21SJohn Baldwin 	if ((kp = malloc(sizeof(*kp), M_NOISE, M_NOWAIT | M_ZERO)) == NULL)
656*744bfb21SJohn Baldwin 		return (ENOSPC);
657*744bfb21SJohn Baldwin 
658*744bfb21SJohn Baldwin 	refcount_init(&kp->kp_refcnt, 1);
659*744bfb21SJohn Baldwin 	kp->kp_can_send = true;
660*744bfb21SJohn Baldwin 	kp->kp_is_initiator = r->r_handshake_state == HANDSHAKE_INITIATOR;
661*744bfb21SJohn Baldwin 	kp->kp_birthdate = getsbinuptime();
662*744bfb21SJohn Baldwin 	kp->kp_remote = noise_remote_ref(r);
663*744bfb21SJohn Baldwin 
664*744bfb21SJohn Baldwin 	if (kp->kp_is_initiator)
665*744bfb21SJohn Baldwin 		noise_kdf(kp->kp_send, kp->kp_recv, NULL, NULL,
666*744bfb21SJohn Baldwin 		    NOISE_SYMMETRIC_KEY_LEN, NOISE_SYMMETRIC_KEY_LEN, 0, 0,
667*744bfb21SJohn Baldwin 		    r->r_handshake.hs_ck);
668*744bfb21SJohn Baldwin 	else
669*744bfb21SJohn Baldwin 		noise_kdf(kp->kp_recv, kp->kp_send, NULL, NULL,
670*744bfb21SJohn Baldwin 		    NOISE_SYMMETRIC_KEY_LEN, NOISE_SYMMETRIC_KEY_LEN, 0, 0,
671*744bfb21SJohn Baldwin 		    r->r_handshake.hs_ck);
672*744bfb21SJohn Baldwin 
673*744bfb21SJohn Baldwin 	rw_init(&kp->kp_nonce_lock, "noise_nonce");
674*744bfb21SJohn Baldwin 
675*744bfb21SJohn Baldwin 	noise_add_new_keypair(r->r_local, r, kp);
676*744bfb21SJohn Baldwin 	return (0);
677*744bfb21SJohn Baldwin }
678*744bfb21SJohn Baldwin 
679*744bfb21SJohn Baldwin struct noise_keypair *
680*744bfb21SJohn Baldwin noise_keypair_lookup(struct noise_local *l, uint32_t idx0)
681*744bfb21SJohn Baldwin {
682*744bfb21SJohn Baldwin 	struct epoch_tracker et;
683*744bfb21SJohn Baldwin 	struct noise_index *i;
684*744bfb21SJohn Baldwin 	struct noise_keypair *kp, *ret = NULL;
685*744bfb21SJohn Baldwin 	uint32_t idx = idx0 & HT_INDEX_MASK;
686*744bfb21SJohn Baldwin 
687*744bfb21SJohn Baldwin 	NET_EPOCH_ENTER(et);
688*744bfb21SJohn Baldwin 	CK_LIST_FOREACH(i, &l->l_index_hash[idx], i_entry) {
689*744bfb21SJohn Baldwin 		if (i->i_local_index == idx0 && i->i_is_keypair) {
690*744bfb21SJohn Baldwin 			kp = (struct noise_keypair *) i;
691*744bfb21SJohn Baldwin 			if (refcount_acquire_if_not_zero(&kp->kp_refcnt))
692*744bfb21SJohn Baldwin 				ret = kp;
693*744bfb21SJohn Baldwin 			break;
694*744bfb21SJohn Baldwin 		}
695*744bfb21SJohn Baldwin 	}
696*744bfb21SJohn Baldwin 	NET_EPOCH_EXIT(et);
697*744bfb21SJohn Baldwin 	return (ret);
698*744bfb21SJohn Baldwin }
699*744bfb21SJohn Baldwin 
700*744bfb21SJohn Baldwin struct noise_keypair *
701*744bfb21SJohn Baldwin noise_keypair_current(struct noise_remote *r)
702*744bfb21SJohn Baldwin {
703*744bfb21SJohn Baldwin 	struct epoch_tracker et;
704*744bfb21SJohn Baldwin 	struct noise_keypair *kp, *ret = NULL;
705*744bfb21SJohn Baldwin 
706*744bfb21SJohn Baldwin 	NET_EPOCH_ENTER(et);
707*744bfb21SJohn Baldwin 	kp = ck_pr_load_ptr(&r->r_current);
708*744bfb21SJohn Baldwin 	if (kp != NULL && ck_pr_load_bool(&kp->kp_can_send)) {
709*744bfb21SJohn Baldwin 		if (noise_timer_expired(kp->kp_birthdate, REJECT_AFTER_TIME, 0))
710*744bfb21SJohn Baldwin 			ck_pr_store_bool(&kp->kp_can_send, false);
711*744bfb21SJohn Baldwin 		else if (refcount_acquire_if_not_zero(&kp->kp_refcnt))
712*744bfb21SJohn Baldwin 			ret = kp;
713*744bfb21SJohn Baldwin 	}
714*744bfb21SJohn Baldwin 	NET_EPOCH_EXIT(et);
715*744bfb21SJohn Baldwin 	return (ret);
716*744bfb21SJohn Baldwin }
717*744bfb21SJohn Baldwin 
718*744bfb21SJohn Baldwin struct noise_keypair *
719*744bfb21SJohn Baldwin noise_keypair_ref(struct noise_keypair *kp)
720*744bfb21SJohn Baldwin {
721*744bfb21SJohn Baldwin 	refcount_acquire(&kp->kp_refcnt);
722*744bfb21SJohn Baldwin 	return (kp);
723*744bfb21SJohn Baldwin }
724*744bfb21SJohn Baldwin 
725*744bfb21SJohn Baldwin int
726*744bfb21SJohn Baldwin noise_keypair_received_with(struct noise_keypair *kp)
727*744bfb21SJohn Baldwin {
728*744bfb21SJohn Baldwin 	struct noise_keypair *old;
729*744bfb21SJohn Baldwin 	struct noise_remote *r = kp->kp_remote;
730*744bfb21SJohn Baldwin 
731*744bfb21SJohn Baldwin 	if (kp != ck_pr_load_ptr(&r->r_next))
732*744bfb21SJohn Baldwin 		return (0);
733*744bfb21SJohn Baldwin 
734*744bfb21SJohn Baldwin 	mtx_lock(&r->r_keypair_mtx);
735*744bfb21SJohn Baldwin 	if (kp != ck_pr_load_ptr(&r->r_next)) {
736*744bfb21SJohn Baldwin 		mtx_unlock(&r->r_keypair_mtx);
737*744bfb21SJohn Baldwin 		return (0);
738*744bfb21SJohn Baldwin 	}
739*744bfb21SJohn Baldwin 
740*744bfb21SJohn Baldwin 	old = ck_pr_load_ptr(&r->r_previous);
741*744bfb21SJohn Baldwin 	ck_pr_store_ptr(&r->r_previous, ck_pr_load_ptr(&r->r_current));
742*744bfb21SJohn Baldwin 	noise_keypair_drop(old);
743*744bfb21SJohn Baldwin 	ck_pr_store_ptr(&r->r_current, kp);
744*744bfb21SJohn Baldwin 	ck_pr_store_ptr(&r->r_next, NULL);
745*744bfb21SJohn Baldwin 	mtx_unlock(&r->r_keypair_mtx);
746*744bfb21SJohn Baldwin 
747*744bfb21SJohn Baldwin 	return (ECONNRESET);
748*744bfb21SJohn Baldwin }
749*744bfb21SJohn Baldwin 
750*744bfb21SJohn Baldwin static void
751*744bfb21SJohn Baldwin noise_keypair_smr_free(struct epoch_context *smr)
752*744bfb21SJohn Baldwin {
753*744bfb21SJohn Baldwin 	struct noise_keypair *kp;
754*744bfb21SJohn Baldwin 	kp = __containerof(smr, struct noise_keypair, kp_smr);
755*744bfb21SJohn Baldwin 	noise_remote_put(kp->kp_remote);
756*744bfb21SJohn Baldwin 	rw_destroy(&kp->kp_nonce_lock);
757*744bfb21SJohn Baldwin 	explicit_bzero(kp, sizeof(*kp));
758*744bfb21SJohn Baldwin 	free(kp, M_NOISE);
759*744bfb21SJohn Baldwin }
760*744bfb21SJohn Baldwin 
761*744bfb21SJohn Baldwin void
762*744bfb21SJohn Baldwin noise_keypair_put(struct noise_keypair *kp)
763*744bfb21SJohn Baldwin {
764*744bfb21SJohn Baldwin 	if (refcount_release(&kp->kp_refcnt))
765*744bfb21SJohn Baldwin 		NET_EPOCH_CALL(noise_keypair_smr_free, &kp->kp_smr);
766*744bfb21SJohn Baldwin }
767*744bfb21SJohn Baldwin 
768*744bfb21SJohn Baldwin static void
769*744bfb21SJohn Baldwin noise_keypair_drop(struct noise_keypair *kp)
770*744bfb21SJohn Baldwin {
771*744bfb21SJohn Baldwin 	struct noise_remote *r;
772*744bfb21SJohn Baldwin 	struct noise_local *l;
773*744bfb21SJohn Baldwin 
774*744bfb21SJohn Baldwin 	if (kp == NULL)
775*744bfb21SJohn Baldwin 		return;
776*744bfb21SJohn Baldwin 
777*744bfb21SJohn Baldwin 	r = kp->kp_remote;
778*744bfb21SJohn Baldwin 	l = r->r_local;
779*744bfb21SJohn Baldwin 
780*744bfb21SJohn Baldwin 	mtx_lock(&l->l_index_mtx);
781*744bfb21SJohn Baldwin 	CK_LIST_REMOVE(&kp->kp_index, i_entry);
782*744bfb21SJohn Baldwin 	mtx_unlock(&l->l_index_mtx);
783*744bfb21SJohn Baldwin 
784*744bfb21SJohn Baldwin 	noise_keypair_put(kp);
785*744bfb21SJohn Baldwin }
786*744bfb21SJohn Baldwin 
787*744bfb21SJohn Baldwin struct noise_remote *
788*744bfb21SJohn Baldwin noise_keypair_remote(struct noise_keypair *kp)
789*744bfb21SJohn Baldwin {
790*744bfb21SJohn Baldwin 	return (noise_remote_ref(kp->kp_remote));
791*744bfb21SJohn Baldwin }
792*744bfb21SJohn Baldwin 
793*744bfb21SJohn Baldwin int
794*744bfb21SJohn Baldwin noise_keypair_nonce_next(struct noise_keypair *kp, uint64_t *send)
795*744bfb21SJohn Baldwin {
796*744bfb21SJohn Baldwin 	if (!ck_pr_load_bool(&kp->kp_can_send))
797*744bfb21SJohn Baldwin 		return (EINVAL);
798*744bfb21SJohn Baldwin 
799*744bfb21SJohn Baldwin #ifdef __LP64__
800*744bfb21SJohn Baldwin 	*send = ck_pr_faa_64(&kp->kp_nonce_send, 1);
801*744bfb21SJohn Baldwin #else
802*744bfb21SJohn Baldwin 	rw_wlock(&kp->kp_nonce_lock);
803*744bfb21SJohn Baldwin 	*send = kp->kp_nonce_send++;
804*744bfb21SJohn Baldwin 	rw_wunlock(&kp->kp_nonce_lock);
805*744bfb21SJohn Baldwin #endif
806*744bfb21SJohn Baldwin 	if (*send < REJECT_AFTER_MESSAGES)
807*744bfb21SJohn Baldwin 		return (0);
808*744bfb21SJohn Baldwin 	ck_pr_store_bool(&kp->kp_can_send, false);
809*744bfb21SJohn Baldwin 	return (EINVAL);
810*744bfb21SJohn Baldwin }
811*744bfb21SJohn Baldwin 
812*744bfb21SJohn Baldwin int
813*744bfb21SJohn Baldwin noise_keypair_nonce_check(struct noise_keypair *kp, uint64_t recv)
814*744bfb21SJohn Baldwin {
815*744bfb21SJohn Baldwin 	unsigned long index, index_current, top, i, bit;
816*744bfb21SJohn Baldwin 	int ret = EEXIST;
817*744bfb21SJohn Baldwin 
818*744bfb21SJohn Baldwin 	rw_wlock(&kp->kp_nonce_lock);
819*744bfb21SJohn Baldwin 
820*744bfb21SJohn Baldwin 	if (__predict_false(kp->kp_nonce_recv >= REJECT_AFTER_MESSAGES + 1 ||
821*744bfb21SJohn Baldwin 			    recv >= REJECT_AFTER_MESSAGES))
822*744bfb21SJohn Baldwin 		goto error;
823*744bfb21SJohn Baldwin 
824*744bfb21SJohn Baldwin 	++recv;
825*744bfb21SJohn Baldwin 
826*744bfb21SJohn Baldwin 	if (__predict_false(recv + COUNTER_WINDOW_SIZE < kp->kp_nonce_recv))
827*744bfb21SJohn Baldwin 		goto error;
828*744bfb21SJohn Baldwin 
829*744bfb21SJohn Baldwin 	index = recv >> COUNTER_ORDER;
830*744bfb21SJohn Baldwin 
831*744bfb21SJohn Baldwin 	if (__predict_true(recv > kp->kp_nonce_recv)) {
832*744bfb21SJohn Baldwin 		index_current = kp->kp_nonce_recv >> COUNTER_ORDER;
833*744bfb21SJohn Baldwin 		top = MIN(index - index_current, COUNTER_BITS_TOTAL / COUNTER_BITS);
834*744bfb21SJohn Baldwin 		for (i = 1; i <= top; i++)
835*744bfb21SJohn Baldwin 			kp->kp_backtrack[
836*744bfb21SJohn Baldwin 			    (i + index_current) &
837*744bfb21SJohn Baldwin 				((COUNTER_BITS_TOTAL / COUNTER_BITS) - 1)] = 0;
838*744bfb21SJohn Baldwin #ifdef __LP64__
839*744bfb21SJohn Baldwin 		ck_pr_store_64(&kp->kp_nonce_recv, recv);
840*744bfb21SJohn Baldwin #else
841*744bfb21SJohn Baldwin 		kp->kp_nonce_recv = recv;
842*744bfb21SJohn Baldwin #endif
843*744bfb21SJohn Baldwin 	}
844*744bfb21SJohn Baldwin 
845*744bfb21SJohn Baldwin 	index &= (COUNTER_BITS_TOTAL / COUNTER_BITS) - 1;
846*744bfb21SJohn Baldwin 	bit = 1ul << (recv & (COUNTER_BITS - 1));
847*744bfb21SJohn Baldwin 	if (kp->kp_backtrack[index] & bit)
848*744bfb21SJohn Baldwin 		goto error;
849*744bfb21SJohn Baldwin 
850*744bfb21SJohn Baldwin 	kp->kp_backtrack[index] |= bit;
851*744bfb21SJohn Baldwin 	ret = 0;
852*744bfb21SJohn Baldwin error:
853*744bfb21SJohn Baldwin 	rw_wunlock(&kp->kp_nonce_lock);
854*744bfb21SJohn Baldwin 	return (ret);
855*744bfb21SJohn Baldwin }
856*744bfb21SJohn Baldwin 
857*744bfb21SJohn Baldwin int
858*744bfb21SJohn Baldwin noise_keep_key_fresh_send(struct noise_remote *r)
859*744bfb21SJohn Baldwin {
860*744bfb21SJohn Baldwin 	struct epoch_tracker et;
861*744bfb21SJohn Baldwin 	struct noise_keypair *current;
862*744bfb21SJohn Baldwin 	int keep_key_fresh;
863*744bfb21SJohn Baldwin 	uint64_t nonce;
864*744bfb21SJohn Baldwin 
865*744bfb21SJohn Baldwin 	NET_EPOCH_ENTER(et);
866*744bfb21SJohn Baldwin 	current = ck_pr_load_ptr(&r->r_current);
867*744bfb21SJohn Baldwin 	keep_key_fresh = current != NULL && ck_pr_load_bool(&current->kp_can_send);
868*744bfb21SJohn Baldwin 	if (!keep_key_fresh)
869*744bfb21SJohn Baldwin 		goto out;
870*744bfb21SJohn Baldwin #ifdef __LP64__
871*744bfb21SJohn Baldwin 	nonce = ck_pr_load_64(&current->kp_nonce_send);
872*744bfb21SJohn Baldwin #else
873*744bfb21SJohn Baldwin 	rw_rlock(&current->kp_nonce_lock);
874*744bfb21SJohn Baldwin 	nonce = current->kp_nonce_send;
875*744bfb21SJohn Baldwin 	rw_runlock(&current->kp_nonce_lock);
876*744bfb21SJohn Baldwin #endif
877*744bfb21SJohn Baldwin 	keep_key_fresh = nonce > REKEY_AFTER_MESSAGES;
878*744bfb21SJohn Baldwin 	if (keep_key_fresh)
879*744bfb21SJohn Baldwin 		goto out;
880*744bfb21SJohn Baldwin 	keep_key_fresh = current->kp_is_initiator && noise_timer_expired(current->kp_birthdate, REKEY_AFTER_TIME, 0);
881*744bfb21SJohn Baldwin 
882*744bfb21SJohn Baldwin out:
883*744bfb21SJohn Baldwin 	NET_EPOCH_EXIT(et);
884*744bfb21SJohn Baldwin 	return (keep_key_fresh ? ESTALE : 0);
885*744bfb21SJohn Baldwin }
886*744bfb21SJohn Baldwin 
887*744bfb21SJohn Baldwin int
888*744bfb21SJohn Baldwin noise_keep_key_fresh_recv(struct noise_remote *r)
889*744bfb21SJohn Baldwin {
890*744bfb21SJohn Baldwin 	struct epoch_tracker et;
891*744bfb21SJohn Baldwin 	struct noise_keypair *current;
892*744bfb21SJohn Baldwin 	int keep_key_fresh;
893*744bfb21SJohn Baldwin 
894*744bfb21SJohn Baldwin 	NET_EPOCH_ENTER(et);
895*744bfb21SJohn Baldwin 	current = ck_pr_load_ptr(&r->r_current);
896*744bfb21SJohn Baldwin 	keep_key_fresh = current != NULL && ck_pr_load_bool(&current->kp_can_send) &&
897*744bfb21SJohn Baldwin 	    current->kp_is_initiator && noise_timer_expired(current->kp_birthdate,
898*744bfb21SJohn Baldwin 	    REJECT_AFTER_TIME - KEEPALIVE_TIMEOUT - REKEY_TIMEOUT, 0);
899*744bfb21SJohn Baldwin 	NET_EPOCH_EXIT(et);
900*744bfb21SJohn Baldwin 
901*744bfb21SJohn Baldwin 	return (keep_key_fresh ? ESTALE : 0);
902*744bfb21SJohn Baldwin }
903*744bfb21SJohn Baldwin 
904*744bfb21SJohn Baldwin int
905*744bfb21SJohn Baldwin noise_keypair_encrypt(struct noise_keypair *kp, uint32_t *r_idx, uint64_t nonce, struct mbuf *m)
906*744bfb21SJohn Baldwin {
907*744bfb21SJohn Baldwin 	int ret;
908*744bfb21SJohn Baldwin 
909*744bfb21SJohn Baldwin 	ret = chacha20poly1305_encrypt_mbuf(m, nonce, kp->kp_send);
910*744bfb21SJohn Baldwin 	if (ret)
911*744bfb21SJohn Baldwin 		return (ret);
912*744bfb21SJohn Baldwin 
913*744bfb21SJohn Baldwin 	*r_idx = kp->kp_index.i_remote_index;
914*744bfb21SJohn Baldwin 	return (0);
915*744bfb21SJohn Baldwin }
916*744bfb21SJohn Baldwin 
917*744bfb21SJohn Baldwin int
918*744bfb21SJohn Baldwin noise_keypair_decrypt(struct noise_keypair *kp, uint64_t nonce, struct mbuf *m)
919*744bfb21SJohn Baldwin {
920*744bfb21SJohn Baldwin 	uint64_t cur_nonce;
921*744bfb21SJohn Baldwin 	int ret;
922*744bfb21SJohn Baldwin 
923*744bfb21SJohn Baldwin #ifdef __LP64__
924*744bfb21SJohn Baldwin 	cur_nonce = ck_pr_load_64(&kp->kp_nonce_recv);
925*744bfb21SJohn Baldwin #else
926*744bfb21SJohn Baldwin 	rw_rlock(&kp->kp_nonce_lock);
927*744bfb21SJohn Baldwin 	cur_nonce = kp->kp_nonce_recv;
928*744bfb21SJohn Baldwin 	rw_runlock(&kp->kp_nonce_lock);
929*744bfb21SJohn Baldwin #endif
930*744bfb21SJohn Baldwin 
931*744bfb21SJohn Baldwin 	if (cur_nonce >= REJECT_AFTER_MESSAGES ||
932*744bfb21SJohn Baldwin 	    noise_timer_expired(kp->kp_birthdate, REJECT_AFTER_TIME, 0))
933*744bfb21SJohn Baldwin 		return (EINVAL);
934*744bfb21SJohn Baldwin 
935*744bfb21SJohn Baldwin 	ret = chacha20poly1305_decrypt_mbuf(m, nonce, kp->kp_recv);
936*744bfb21SJohn Baldwin 	if (ret)
937*744bfb21SJohn Baldwin 		return (ret);
938*744bfb21SJohn Baldwin 
939*744bfb21SJohn Baldwin 	return (0);
940*744bfb21SJohn Baldwin }
941*744bfb21SJohn Baldwin 
942*744bfb21SJohn Baldwin /* Handshake functions */
943*744bfb21SJohn Baldwin int
944*744bfb21SJohn Baldwin noise_create_initiation(struct noise_remote *r,
945*744bfb21SJohn Baldwin     uint32_t *s_idx,
946*744bfb21SJohn Baldwin     uint8_t ue[NOISE_PUBLIC_KEY_LEN],
947*744bfb21SJohn Baldwin     uint8_t es[NOISE_PUBLIC_KEY_LEN + NOISE_AUTHTAG_LEN],
948*744bfb21SJohn Baldwin     uint8_t ets[NOISE_TIMESTAMP_LEN + NOISE_AUTHTAG_LEN])
949*744bfb21SJohn Baldwin {
950*744bfb21SJohn Baldwin 	struct noise_handshake *hs = &r->r_handshake;
951*744bfb21SJohn Baldwin 	struct noise_local *l = r->r_local;
952*744bfb21SJohn Baldwin 	uint8_t key[NOISE_SYMMETRIC_KEY_LEN];
953*744bfb21SJohn Baldwin 	int ret = EINVAL;
954*744bfb21SJohn Baldwin 
955*744bfb21SJohn Baldwin 	rw_rlock(&l->l_identity_lock);
956*744bfb21SJohn Baldwin 	rw_wlock(&r->r_handshake_lock);
957*744bfb21SJohn Baldwin 	if (!l->l_has_identity)
958*744bfb21SJohn Baldwin 		goto error;
959*744bfb21SJohn Baldwin 	if (!noise_timer_expired(r->r_last_sent, REKEY_TIMEOUT, 0))
960*744bfb21SJohn Baldwin 		goto error;
961*744bfb21SJohn Baldwin 	noise_param_init(hs->hs_ck, hs->hs_hash, r->r_public);
962*744bfb21SJohn Baldwin 
963*744bfb21SJohn Baldwin 	/* e */
964*744bfb21SJohn Baldwin 	curve25519_generate_secret(hs->hs_e);
965*744bfb21SJohn Baldwin 	if (curve25519_generate_public(ue, hs->hs_e) == 0)
966*744bfb21SJohn Baldwin 		goto error;
967*744bfb21SJohn Baldwin 	noise_msg_ephemeral(hs->hs_ck, hs->hs_hash, ue);
968*744bfb21SJohn Baldwin 
969*744bfb21SJohn Baldwin 	/* es */
970*744bfb21SJohn Baldwin 	if (noise_mix_dh(hs->hs_ck, key, hs->hs_e, r->r_public) != 0)
971*744bfb21SJohn Baldwin 		goto error;
972*744bfb21SJohn Baldwin 
973*744bfb21SJohn Baldwin 	/* s */
974*744bfb21SJohn Baldwin 	noise_msg_encrypt(es, l->l_public,
975*744bfb21SJohn Baldwin 	    NOISE_PUBLIC_KEY_LEN, key, hs->hs_hash);
976*744bfb21SJohn Baldwin 
977*744bfb21SJohn Baldwin 	/* ss */
978*744bfb21SJohn Baldwin 	if (noise_mix_ss(hs->hs_ck, key, r->r_ss) != 0)
979*744bfb21SJohn Baldwin 		goto error;
980*744bfb21SJohn Baldwin 
981*744bfb21SJohn Baldwin 	/* {t} */
982*744bfb21SJohn Baldwin 	noise_tai64n_now(ets);
983*744bfb21SJohn Baldwin 	noise_msg_encrypt(ets, ets,
984*744bfb21SJohn Baldwin 	    NOISE_TIMESTAMP_LEN, key, hs->hs_hash);
985*744bfb21SJohn Baldwin 
986*744bfb21SJohn Baldwin 	noise_remote_index_insert(l, r);
987*744bfb21SJohn Baldwin 	r->r_handshake_state = HANDSHAKE_INITIATOR;
988*744bfb21SJohn Baldwin 	r->r_last_sent = getsbinuptime();
989*744bfb21SJohn Baldwin 	*s_idx = r->r_index.i_local_index;
990*744bfb21SJohn Baldwin 	ret = 0;
991*744bfb21SJohn Baldwin error:
992*744bfb21SJohn Baldwin 	rw_wunlock(&r->r_handshake_lock);
993*744bfb21SJohn Baldwin 	rw_runlock(&l->l_identity_lock);
994*744bfb21SJohn Baldwin 	explicit_bzero(key, NOISE_SYMMETRIC_KEY_LEN);
995*744bfb21SJohn Baldwin 	return (ret);
996*744bfb21SJohn Baldwin }
997*744bfb21SJohn Baldwin 
998*744bfb21SJohn Baldwin int
999*744bfb21SJohn Baldwin noise_consume_initiation(struct noise_local *l, struct noise_remote **rp,
1000*744bfb21SJohn Baldwin     uint32_t s_idx,
1001*744bfb21SJohn Baldwin     uint8_t ue[NOISE_PUBLIC_KEY_LEN],
1002*744bfb21SJohn Baldwin     uint8_t es[NOISE_PUBLIC_KEY_LEN + NOISE_AUTHTAG_LEN],
1003*744bfb21SJohn Baldwin     uint8_t ets[NOISE_TIMESTAMP_LEN + NOISE_AUTHTAG_LEN])
1004*744bfb21SJohn Baldwin {
1005*744bfb21SJohn Baldwin 	struct noise_remote *r;
1006*744bfb21SJohn Baldwin 	struct noise_handshake hs;
1007*744bfb21SJohn Baldwin 	uint8_t key[NOISE_SYMMETRIC_KEY_LEN];
1008*744bfb21SJohn Baldwin 	uint8_t r_public[NOISE_PUBLIC_KEY_LEN];
1009*744bfb21SJohn Baldwin 	uint8_t	timestamp[NOISE_TIMESTAMP_LEN];
1010*744bfb21SJohn Baldwin 	int ret = EINVAL;
1011*744bfb21SJohn Baldwin 
1012*744bfb21SJohn Baldwin 	rw_rlock(&l->l_identity_lock);
1013*744bfb21SJohn Baldwin 	if (!l->l_has_identity)
1014*744bfb21SJohn Baldwin 		goto error;
1015*744bfb21SJohn Baldwin 	noise_param_init(hs.hs_ck, hs.hs_hash, l->l_public);
1016*744bfb21SJohn Baldwin 
1017*744bfb21SJohn Baldwin 	/* e */
1018*744bfb21SJohn Baldwin 	noise_msg_ephemeral(hs.hs_ck, hs.hs_hash, ue);
1019*744bfb21SJohn Baldwin 
1020*744bfb21SJohn Baldwin 	/* es */
1021*744bfb21SJohn Baldwin 	if (noise_mix_dh(hs.hs_ck, key, l->l_private, ue) != 0)
1022*744bfb21SJohn Baldwin 		goto error;
1023*744bfb21SJohn Baldwin 
1024*744bfb21SJohn Baldwin 	/* s */
1025*744bfb21SJohn Baldwin 	if (noise_msg_decrypt(r_public, es,
1026*744bfb21SJohn Baldwin 	    NOISE_PUBLIC_KEY_LEN + NOISE_AUTHTAG_LEN, key, hs.hs_hash) != 0)
1027*744bfb21SJohn Baldwin 		goto error;
1028*744bfb21SJohn Baldwin 
1029*744bfb21SJohn Baldwin 	/* Lookup the remote we received from */
1030*744bfb21SJohn Baldwin 	if ((r = noise_remote_lookup(l, r_public)) == NULL)
1031*744bfb21SJohn Baldwin 		goto error;
1032*744bfb21SJohn Baldwin 
1033*744bfb21SJohn Baldwin 	/* ss */
1034*744bfb21SJohn Baldwin 	if (noise_mix_ss(hs.hs_ck, key, r->r_ss) != 0)
1035*744bfb21SJohn Baldwin 		goto error_put;
1036*744bfb21SJohn Baldwin 
1037*744bfb21SJohn Baldwin 	/* {t} */
1038*744bfb21SJohn Baldwin 	if (noise_msg_decrypt(timestamp, ets,
1039*744bfb21SJohn Baldwin 	    NOISE_TIMESTAMP_LEN + NOISE_AUTHTAG_LEN, key, hs.hs_hash) != 0)
1040*744bfb21SJohn Baldwin 		goto error_put;
1041*744bfb21SJohn Baldwin 
1042*744bfb21SJohn Baldwin 	memcpy(hs.hs_e, ue, NOISE_PUBLIC_KEY_LEN);
1043*744bfb21SJohn Baldwin 
1044*744bfb21SJohn Baldwin 	/* We have successfully computed the same results, now we ensure that
1045*744bfb21SJohn Baldwin 	 * this is not an initiation replay, or a flood attack */
1046*744bfb21SJohn Baldwin 	rw_wlock(&r->r_handshake_lock);
1047*744bfb21SJohn Baldwin 
1048*744bfb21SJohn Baldwin 	/* Replay */
1049*744bfb21SJohn Baldwin 	if (memcmp(timestamp, r->r_timestamp, NOISE_TIMESTAMP_LEN) > 0)
1050*744bfb21SJohn Baldwin 		memcpy(r->r_timestamp, timestamp, NOISE_TIMESTAMP_LEN);
1051*744bfb21SJohn Baldwin 	else
1052*744bfb21SJohn Baldwin 		goto error_set;
1053*744bfb21SJohn Baldwin 	/* Flood attack */
1054*744bfb21SJohn Baldwin 	if (noise_timer_expired(r->r_last_init_recv, 0, REJECT_INTERVAL))
1055*744bfb21SJohn Baldwin 		r->r_last_init_recv = getsbinuptime();
1056*744bfb21SJohn Baldwin 	else
1057*744bfb21SJohn Baldwin 		goto error_set;
1058*744bfb21SJohn Baldwin 
1059*744bfb21SJohn Baldwin 	/* Ok, we're happy to accept this initiation now */
1060*744bfb21SJohn Baldwin 	noise_remote_index_insert(l, r);
1061*744bfb21SJohn Baldwin 	r->r_index.i_remote_index = s_idx;
1062*744bfb21SJohn Baldwin 	r->r_handshake_state = HANDSHAKE_RESPONDER;
1063*744bfb21SJohn Baldwin 	r->r_handshake = hs;
1064*744bfb21SJohn Baldwin 	*rp = noise_remote_ref(r);
1065*744bfb21SJohn Baldwin 	ret = 0;
1066*744bfb21SJohn Baldwin error_set:
1067*744bfb21SJohn Baldwin 	rw_wunlock(&r->r_handshake_lock);
1068*744bfb21SJohn Baldwin error_put:
1069*744bfb21SJohn Baldwin 	noise_remote_put(r);
1070*744bfb21SJohn Baldwin error:
1071*744bfb21SJohn Baldwin 	rw_runlock(&l->l_identity_lock);
1072*744bfb21SJohn Baldwin 	explicit_bzero(key, NOISE_SYMMETRIC_KEY_LEN);
1073*744bfb21SJohn Baldwin 	explicit_bzero(&hs, sizeof(hs));
1074*744bfb21SJohn Baldwin 	return (ret);
1075*744bfb21SJohn Baldwin }
1076*744bfb21SJohn Baldwin 
1077*744bfb21SJohn Baldwin int
1078*744bfb21SJohn Baldwin noise_create_response(struct noise_remote *r,
1079*744bfb21SJohn Baldwin     uint32_t *s_idx, uint32_t *r_idx,
1080*744bfb21SJohn Baldwin     uint8_t ue[NOISE_PUBLIC_KEY_LEN],
1081*744bfb21SJohn Baldwin     uint8_t en[0 + NOISE_AUTHTAG_LEN])
1082*744bfb21SJohn Baldwin {
1083*744bfb21SJohn Baldwin 	struct noise_handshake *hs = &r->r_handshake;
1084*744bfb21SJohn Baldwin 	struct noise_local *l = r->r_local;
1085*744bfb21SJohn Baldwin 	uint8_t key[NOISE_SYMMETRIC_KEY_LEN];
1086*744bfb21SJohn Baldwin 	uint8_t e[NOISE_PUBLIC_KEY_LEN];
1087*744bfb21SJohn Baldwin 	int ret = EINVAL;
1088*744bfb21SJohn Baldwin 
1089*744bfb21SJohn Baldwin 	rw_rlock(&l->l_identity_lock);
1090*744bfb21SJohn Baldwin 	rw_wlock(&r->r_handshake_lock);
1091*744bfb21SJohn Baldwin 
1092*744bfb21SJohn Baldwin 	if (r->r_handshake_state != HANDSHAKE_RESPONDER)
1093*744bfb21SJohn Baldwin 		goto error;
1094*744bfb21SJohn Baldwin 
1095*744bfb21SJohn Baldwin 	/* e */
1096*744bfb21SJohn Baldwin 	curve25519_generate_secret(e);
1097*744bfb21SJohn Baldwin 	if (curve25519_generate_public(ue, e) == 0)
1098*744bfb21SJohn Baldwin 		goto error;
1099*744bfb21SJohn Baldwin 	noise_msg_ephemeral(hs->hs_ck, hs->hs_hash, ue);
1100*744bfb21SJohn Baldwin 
1101*744bfb21SJohn Baldwin 	/* ee */
1102*744bfb21SJohn Baldwin 	if (noise_mix_dh(hs->hs_ck, NULL, e, hs->hs_e) != 0)
1103*744bfb21SJohn Baldwin 		goto error;
1104*744bfb21SJohn Baldwin 
1105*744bfb21SJohn Baldwin 	/* se */
1106*744bfb21SJohn Baldwin 	if (noise_mix_dh(hs->hs_ck, NULL, e, r->r_public) != 0)
1107*744bfb21SJohn Baldwin 		goto error;
1108*744bfb21SJohn Baldwin 
1109*744bfb21SJohn Baldwin 	/* psk */
1110*744bfb21SJohn Baldwin 	noise_mix_psk(hs->hs_ck, hs->hs_hash, key, r->r_psk);
1111*744bfb21SJohn Baldwin 
1112*744bfb21SJohn Baldwin 	/* {} */
1113*744bfb21SJohn Baldwin 	noise_msg_encrypt(en, NULL, 0, key, hs->hs_hash);
1114*744bfb21SJohn Baldwin 
1115*744bfb21SJohn Baldwin 	if ((ret = noise_begin_session(r)) == 0) {
1116*744bfb21SJohn Baldwin 		r->r_last_sent = getsbinuptime();
1117*744bfb21SJohn Baldwin 		*s_idx = r->r_index.i_local_index;
1118*744bfb21SJohn Baldwin 		*r_idx = r->r_index.i_remote_index;
1119*744bfb21SJohn Baldwin 	}
1120*744bfb21SJohn Baldwin error:
1121*744bfb21SJohn Baldwin 	rw_wunlock(&r->r_handshake_lock);
1122*744bfb21SJohn Baldwin 	rw_runlock(&l->l_identity_lock);
1123*744bfb21SJohn Baldwin 	explicit_bzero(key, NOISE_SYMMETRIC_KEY_LEN);
1124*744bfb21SJohn Baldwin 	explicit_bzero(e, NOISE_PUBLIC_KEY_LEN);
1125*744bfb21SJohn Baldwin 	return (ret);
1126*744bfb21SJohn Baldwin }
1127*744bfb21SJohn Baldwin 
1128*744bfb21SJohn Baldwin int
1129*744bfb21SJohn Baldwin noise_consume_response(struct noise_local *l, struct noise_remote **rp,
1130*744bfb21SJohn Baldwin     uint32_t s_idx, uint32_t r_idx,
1131*744bfb21SJohn Baldwin     uint8_t ue[NOISE_PUBLIC_KEY_LEN],
1132*744bfb21SJohn Baldwin     uint8_t en[0 + NOISE_AUTHTAG_LEN])
1133*744bfb21SJohn Baldwin {
1134*744bfb21SJohn Baldwin 	uint8_t preshared_key[NOISE_SYMMETRIC_KEY_LEN];
1135*744bfb21SJohn Baldwin 	uint8_t key[NOISE_SYMMETRIC_KEY_LEN];
1136*744bfb21SJohn Baldwin 	struct noise_handshake hs;
1137*744bfb21SJohn Baldwin 	struct noise_remote *r = NULL;
1138*744bfb21SJohn Baldwin 	int ret = EINVAL;
1139*744bfb21SJohn Baldwin 
1140*744bfb21SJohn Baldwin 	if ((r = noise_remote_index_lookup(l, r_idx, false)) == NULL)
1141*744bfb21SJohn Baldwin 		return (ret);
1142*744bfb21SJohn Baldwin 
1143*744bfb21SJohn Baldwin 	rw_rlock(&l->l_identity_lock);
1144*744bfb21SJohn Baldwin 	if (!l->l_has_identity)
1145*744bfb21SJohn Baldwin 		goto error;
1146*744bfb21SJohn Baldwin 
1147*744bfb21SJohn Baldwin 	rw_rlock(&r->r_handshake_lock);
1148*744bfb21SJohn Baldwin 	if (r->r_handshake_state != HANDSHAKE_INITIATOR) {
1149*744bfb21SJohn Baldwin 		rw_runlock(&r->r_handshake_lock);
1150*744bfb21SJohn Baldwin 		goto error;
1151*744bfb21SJohn Baldwin 	}
1152*744bfb21SJohn Baldwin 	memcpy(preshared_key, r->r_psk, NOISE_SYMMETRIC_KEY_LEN);
1153*744bfb21SJohn Baldwin 	hs = r->r_handshake;
1154*744bfb21SJohn Baldwin 	rw_runlock(&r->r_handshake_lock);
1155*744bfb21SJohn Baldwin 
1156*744bfb21SJohn Baldwin 	/* e */
1157*744bfb21SJohn Baldwin 	noise_msg_ephemeral(hs.hs_ck, hs.hs_hash, ue);
1158*744bfb21SJohn Baldwin 
1159*744bfb21SJohn Baldwin 	/* ee */
1160*744bfb21SJohn Baldwin 	if (noise_mix_dh(hs.hs_ck, NULL, hs.hs_e, ue) != 0)
1161*744bfb21SJohn Baldwin 		goto error_zero;
1162*744bfb21SJohn Baldwin 
1163*744bfb21SJohn Baldwin 	/* se */
1164*744bfb21SJohn Baldwin 	if (noise_mix_dh(hs.hs_ck, NULL, l->l_private, ue) != 0)
1165*744bfb21SJohn Baldwin 		goto error_zero;
1166*744bfb21SJohn Baldwin 
1167*744bfb21SJohn Baldwin 	/* psk */
1168*744bfb21SJohn Baldwin 	noise_mix_psk(hs.hs_ck, hs.hs_hash, key, preshared_key);
1169*744bfb21SJohn Baldwin 
1170*744bfb21SJohn Baldwin 	/* {} */
1171*744bfb21SJohn Baldwin 	if (noise_msg_decrypt(NULL, en,
1172*744bfb21SJohn Baldwin 	    0 + NOISE_AUTHTAG_LEN, key, hs.hs_hash) != 0)
1173*744bfb21SJohn Baldwin 		goto error_zero;
1174*744bfb21SJohn Baldwin 
1175*744bfb21SJohn Baldwin 	rw_wlock(&r->r_handshake_lock);
1176*744bfb21SJohn Baldwin 	if (r->r_handshake_state == HANDSHAKE_INITIATOR &&
1177*744bfb21SJohn Baldwin 	    r->r_index.i_local_index == r_idx) {
1178*744bfb21SJohn Baldwin 		r->r_handshake = hs;
1179*744bfb21SJohn Baldwin 		r->r_index.i_remote_index = s_idx;
1180*744bfb21SJohn Baldwin 		if ((ret = noise_begin_session(r)) == 0)
1181*744bfb21SJohn Baldwin 			*rp = noise_remote_ref(r);
1182*744bfb21SJohn Baldwin 	}
1183*744bfb21SJohn Baldwin 	rw_wunlock(&r->r_handshake_lock);
1184*744bfb21SJohn Baldwin error_zero:
1185*744bfb21SJohn Baldwin 	explicit_bzero(preshared_key, NOISE_SYMMETRIC_KEY_LEN);
1186*744bfb21SJohn Baldwin 	explicit_bzero(key, NOISE_SYMMETRIC_KEY_LEN);
1187*744bfb21SJohn Baldwin 	explicit_bzero(&hs, sizeof(hs));
1188*744bfb21SJohn Baldwin error:
1189*744bfb21SJohn Baldwin 	rw_runlock(&l->l_identity_lock);
1190*744bfb21SJohn Baldwin 	noise_remote_put(r);
1191*744bfb21SJohn Baldwin 	return (ret);
1192*744bfb21SJohn Baldwin }
1193*744bfb21SJohn Baldwin 
1194*744bfb21SJohn Baldwin static void
1195*744bfb21SJohn Baldwin hmac(uint8_t *out, const uint8_t *in, const uint8_t *key, const size_t outlen,
1196*744bfb21SJohn Baldwin      const size_t inlen, const size_t keylen)
1197*744bfb21SJohn Baldwin {
1198*744bfb21SJohn Baldwin 	struct blake2s_state state;
1199*744bfb21SJohn Baldwin 	uint8_t x_key[BLAKE2S_BLOCK_SIZE] __aligned(sizeof(uint32_t)) = { 0 };
1200*744bfb21SJohn Baldwin 	uint8_t i_hash[BLAKE2S_HASH_SIZE] __aligned(sizeof(uint32_t));
1201*744bfb21SJohn Baldwin 	int i;
1202*744bfb21SJohn Baldwin 
1203*744bfb21SJohn Baldwin 	if (keylen > BLAKE2S_BLOCK_SIZE) {
1204*744bfb21SJohn Baldwin 		blake2s_init(&state, BLAKE2S_HASH_SIZE);
1205*744bfb21SJohn Baldwin 		blake2s_update(&state, key, keylen);
1206*744bfb21SJohn Baldwin 		blake2s_final(&state, x_key);
1207*744bfb21SJohn Baldwin 	} else
1208*744bfb21SJohn Baldwin 		memcpy(x_key, key, keylen);
1209*744bfb21SJohn Baldwin 
1210*744bfb21SJohn Baldwin 	for (i = 0; i < BLAKE2S_BLOCK_SIZE; ++i)
1211*744bfb21SJohn Baldwin 		x_key[i] ^= 0x36;
1212*744bfb21SJohn Baldwin 
1213*744bfb21SJohn Baldwin 	blake2s_init(&state, BLAKE2S_HASH_SIZE);
1214*744bfb21SJohn Baldwin 	blake2s_update(&state, x_key, BLAKE2S_BLOCK_SIZE);
1215*744bfb21SJohn Baldwin 	blake2s_update(&state, in, inlen);
1216*744bfb21SJohn Baldwin 	blake2s_final(&state, i_hash);
1217*744bfb21SJohn Baldwin 
1218*744bfb21SJohn Baldwin 	for (i = 0; i < BLAKE2S_BLOCK_SIZE; ++i)
1219*744bfb21SJohn Baldwin 		x_key[i] ^= 0x5c ^ 0x36;
1220*744bfb21SJohn Baldwin 
1221*744bfb21SJohn Baldwin 	blake2s_init(&state, BLAKE2S_HASH_SIZE);
1222*744bfb21SJohn Baldwin 	blake2s_update(&state, x_key, BLAKE2S_BLOCK_SIZE);
1223*744bfb21SJohn Baldwin 	blake2s_update(&state, i_hash, BLAKE2S_HASH_SIZE);
1224*744bfb21SJohn Baldwin 	blake2s_final(&state, i_hash);
1225*744bfb21SJohn Baldwin 
1226*744bfb21SJohn Baldwin 	memcpy(out, i_hash, outlen);
1227*744bfb21SJohn Baldwin 	explicit_bzero(x_key, BLAKE2S_BLOCK_SIZE);
1228*744bfb21SJohn Baldwin 	explicit_bzero(i_hash, BLAKE2S_HASH_SIZE);
1229*744bfb21SJohn Baldwin }
1230*744bfb21SJohn Baldwin 
1231*744bfb21SJohn Baldwin /* Handshake helper functions */
1232*744bfb21SJohn Baldwin static void
1233*744bfb21SJohn Baldwin noise_kdf(uint8_t *a, uint8_t *b, uint8_t *c, const uint8_t *x,
1234*744bfb21SJohn Baldwin     size_t a_len, size_t b_len, size_t c_len, size_t x_len,
1235*744bfb21SJohn Baldwin     const uint8_t ck[NOISE_HASH_LEN])
1236*744bfb21SJohn Baldwin {
1237*744bfb21SJohn Baldwin 	uint8_t out[BLAKE2S_HASH_SIZE + 1];
1238*744bfb21SJohn Baldwin 	uint8_t sec[BLAKE2S_HASH_SIZE];
1239*744bfb21SJohn Baldwin 
1240*744bfb21SJohn Baldwin 	/* Extract entropy from "x" into sec */
1241*744bfb21SJohn Baldwin 	hmac(sec, x, ck, BLAKE2S_HASH_SIZE, x_len, NOISE_HASH_LEN);
1242*744bfb21SJohn Baldwin 
1243*744bfb21SJohn Baldwin 	if (a == NULL || a_len == 0)
1244*744bfb21SJohn Baldwin 		goto out;
1245*744bfb21SJohn Baldwin 
1246*744bfb21SJohn Baldwin 	/* Expand first key: key = sec, data = 0x1 */
1247*744bfb21SJohn Baldwin 	out[0] = 1;
1248*744bfb21SJohn Baldwin 	hmac(out, out, sec, BLAKE2S_HASH_SIZE, 1, BLAKE2S_HASH_SIZE);
1249*744bfb21SJohn Baldwin 	memcpy(a, out, a_len);
1250*744bfb21SJohn Baldwin 
1251*744bfb21SJohn Baldwin 	if (b == NULL || b_len == 0)
1252*744bfb21SJohn Baldwin 		goto out;
1253*744bfb21SJohn Baldwin 
1254*744bfb21SJohn Baldwin 	/* Expand second key: key = sec, data = "a" || 0x2 */
1255*744bfb21SJohn Baldwin 	out[BLAKE2S_HASH_SIZE] = 2;
1256*744bfb21SJohn Baldwin 	hmac(out, out, sec, BLAKE2S_HASH_SIZE, BLAKE2S_HASH_SIZE + 1, BLAKE2S_HASH_SIZE);
1257*744bfb21SJohn Baldwin 	memcpy(b, out, b_len);
1258*744bfb21SJohn Baldwin 
1259*744bfb21SJohn Baldwin 	if (c == NULL || c_len == 0)
1260*744bfb21SJohn Baldwin 		goto out;
1261*744bfb21SJohn Baldwin 
1262*744bfb21SJohn Baldwin 	/* Expand third key: key = sec, data = "b" || 0x3 */
1263*744bfb21SJohn Baldwin 	out[BLAKE2S_HASH_SIZE] = 3;
1264*744bfb21SJohn Baldwin 	hmac(out, out, sec, BLAKE2S_HASH_SIZE, BLAKE2S_HASH_SIZE + 1, BLAKE2S_HASH_SIZE);
1265*744bfb21SJohn Baldwin 	memcpy(c, out, c_len);
1266*744bfb21SJohn Baldwin 
1267*744bfb21SJohn Baldwin out:
1268*744bfb21SJohn Baldwin 	/* Clear sensitive data from stack */
1269*744bfb21SJohn Baldwin 	explicit_bzero(sec, BLAKE2S_HASH_SIZE);
1270*744bfb21SJohn Baldwin 	explicit_bzero(out, BLAKE2S_HASH_SIZE + 1);
1271*744bfb21SJohn Baldwin }
1272*744bfb21SJohn Baldwin 
1273*744bfb21SJohn Baldwin static int
1274*744bfb21SJohn Baldwin noise_mix_dh(uint8_t ck[NOISE_HASH_LEN], uint8_t key[NOISE_SYMMETRIC_KEY_LEN],
1275*744bfb21SJohn Baldwin     const uint8_t private[NOISE_PUBLIC_KEY_LEN],
1276*744bfb21SJohn Baldwin     const uint8_t public[NOISE_PUBLIC_KEY_LEN])
1277*744bfb21SJohn Baldwin {
1278*744bfb21SJohn Baldwin 	uint8_t dh[NOISE_PUBLIC_KEY_LEN];
1279*744bfb21SJohn Baldwin 
1280*744bfb21SJohn Baldwin 	if (!curve25519(dh, private, public))
1281*744bfb21SJohn Baldwin 		return (EINVAL);
1282*744bfb21SJohn Baldwin 	noise_kdf(ck, key, NULL, dh,
1283*744bfb21SJohn Baldwin 	    NOISE_HASH_LEN, NOISE_SYMMETRIC_KEY_LEN, 0, NOISE_PUBLIC_KEY_LEN, ck);
1284*744bfb21SJohn Baldwin 	explicit_bzero(dh, NOISE_PUBLIC_KEY_LEN);
1285*744bfb21SJohn Baldwin 	return (0);
1286*744bfb21SJohn Baldwin }
1287*744bfb21SJohn Baldwin 
1288*744bfb21SJohn Baldwin static int
1289*744bfb21SJohn Baldwin noise_mix_ss(uint8_t ck[NOISE_HASH_LEN], uint8_t key[NOISE_SYMMETRIC_KEY_LEN],
1290*744bfb21SJohn Baldwin     const uint8_t ss[NOISE_PUBLIC_KEY_LEN])
1291*744bfb21SJohn Baldwin {
1292*744bfb21SJohn Baldwin 	static uint8_t null_point[NOISE_PUBLIC_KEY_LEN];
1293*744bfb21SJohn Baldwin 	if (timingsafe_bcmp(ss, null_point, NOISE_PUBLIC_KEY_LEN) == 0)
1294*744bfb21SJohn Baldwin 		return (ENOENT);
1295*744bfb21SJohn Baldwin 	noise_kdf(ck, key, NULL, ss,
1296*744bfb21SJohn Baldwin 	    NOISE_HASH_LEN, NOISE_SYMMETRIC_KEY_LEN, 0, NOISE_PUBLIC_KEY_LEN, ck);
1297*744bfb21SJohn Baldwin 	return (0);
1298*744bfb21SJohn Baldwin }
1299*744bfb21SJohn Baldwin 
1300*744bfb21SJohn Baldwin static void
1301*744bfb21SJohn Baldwin noise_mix_hash(uint8_t hash[NOISE_HASH_LEN], const uint8_t *src,
1302*744bfb21SJohn Baldwin     size_t src_len)
1303*744bfb21SJohn Baldwin {
1304*744bfb21SJohn Baldwin 	struct blake2s_state blake;
1305*744bfb21SJohn Baldwin 
1306*744bfb21SJohn Baldwin 	blake2s_init(&blake, NOISE_HASH_LEN);
1307*744bfb21SJohn Baldwin 	blake2s_update(&blake, hash, NOISE_HASH_LEN);
1308*744bfb21SJohn Baldwin 	blake2s_update(&blake, src, src_len);
1309*744bfb21SJohn Baldwin 	blake2s_final(&blake, hash);
1310*744bfb21SJohn Baldwin }
1311*744bfb21SJohn Baldwin 
1312*744bfb21SJohn Baldwin static void
1313*744bfb21SJohn Baldwin noise_mix_psk(uint8_t ck[NOISE_HASH_LEN], uint8_t hash[NOISE_HASH_LEN],
1314*744bfb21SJohn Baldwin     uint8_t key[NOISE_SYMMETRIC_KEY_LEN],
1315*744bfb21SJohn Baldwin     const uint8_t psk[NOISE_SYMMETRIC_KEY_LEN])
1316*744bfb21SJohn Baldwin {
1317*744bfb21SJohn Baldwin 	uint8_t tmp[NOISE_HASH_LEN];
1318*744bfb21SJohn Baldwin 
1319*744bfb21SJohn Baldwin 	noise_kdf(ck, tmp, key, psk,
1320*744bfb21SJohn Baldwin 	    NOISE_HASH_LEN, NOISE_HASH_LEN, NOISE_SYMMETRIC_KEY_LEN,
1321*744bfb21SJohn Baldwin 	    NOISE_SYMMETRIC_KEY_LEN, ck);
1322*744bfb21SJohn Baldwin 	noise_mix_hash(hash, tmp, NOISE_HASH_LEN);
1323*744bfb21SJohn Baldwin 	explicit_bzero(tmp, NOISE_HASH_LEN);
1324*744bfb21SJohn Baldwin }
1325*744bfb21SJohn Baldwin 
1326*744bfb21SJohn Baldwin static void
1327*744bfb21SJohn Baldwin noise_param_init(uint8_t ck[NOISE_HASH_LEN], uint8_t hash[NOISE_HASH_LEN],
1328*744bfb21SJohn Baldwin     const uint8_t s[NOISE_PUBLIC_KEY_LEN])
1329*744bfb21SJohn Baldwin {
1330*744bfb21SJohn Baldwin 	struct blake2s_state blake;
1331*744bfb21SJohn Baldwin 
1332*744bfb21SJohn Baldwin 	blake2s(ck, (uint8_t *)NOISE_HANDSHAKE_NAME, NULL,
1333*744bfb21SJohn Baldwin 	    NOISE_HASH_LEN, strlen(NOISE_HANDSHAKE_NAME), 0);
1334*744bfb21SJohn Baldwin 	blake2s_init(&blake, NOISE_HASH_LEN);
1335*744bfb21SJohn Baldwin 	blake2s_update(&blake, ck, NOISE_HASH_LEN);
1336*744bfb21SJohn Baldwin 	blake2s_update(&blake, (uint8_t *)NOISE_IDENTIFIER_NAME,
1337*744bfb21SJohn Baldwin 	    strlen(NOISE_IDENTIFIER_NAME));
1338*744bfb21SJohn Baldwin 	blake2s_final(&blake, hash);
1339*744bfb21SJohn Baldwin 
1340*744bfb21SJohn Baldwin 	noise_mix_hash(hash, s, NOISE_PUBLIC_KEY_LEN);
1341*744bfb21SJohn Baldwin }
1342*744bfb21SJohn Baldwin 
1343*744bfb21SJohn Baldwin static void
1344*744bfb21SJohn Baldwin noise_msg_encrypt(uint8_t *dst, const uint8_t *src, size_t src_len,
1345*744bfb21SJohn Baldwin     uint8_t key[NOISE_SYMMETRIC_KEY_LEN], uint8_t hash[NOISE_HASH_LEN])
1346*744bfb21SJohn Baldwin {
1347*744bfb21SJohn Baldwin 	/* Nonce always zero for Noise_IK */
1348*744bfb21SJohn Baldwin 	chacha20poly1305_encrypt(dst, src, src_len,
1349*744bfb21SJohn Baldwin 	    hash, NOISE_HASH_LEN, 0, key);
1350*744bfb21SJohn Baldwin 	noise_mix_hash(hash, dst, src_len + NOISE_AUTHTAG_LEN);
1351*744bfb21SJohn Baldwin }
1352*744bfb21SJohn Baldwin 
1353*744bfb21SJohn Baldwin static int
1354*744bfb21SJohn Baldwin noise_msg_decrypt(uint8_t *dst, const uint8_t *src, size_t src_len,
1355*744bfb21SJohn Baldwin     uint8_t key[NOISE_SYMMETRIC_KEY_LEN], uint8_t hash[NOISE_HASH_LEN])
1356*744bfb21SJohn Baldwin {
1357*744bfb21SJohn Baldwin 	/* Nonce always zero for Noise_IK */
1358*744bfb21SJohn Baldwin 	if (!chacha20poly1305_decrypt(dst, src, src_len,
1359*744bfb21SJohn Baldwin 	    hash, NOISE_HASH_LEN, 0, key))
1360*744bfb21SJohn Baldwin 		return (EINVAL);
1361*744bfb21SJohn Baldwin 	noise_mix_hash(hash, src, src_len);
1362*744bfb21SJohn Baldwin 	return (0);
1363*744bfb21SJohn Baldwin }
1364*744bfb21SJohn Baldwin 
1365*744bfb21SJohn Baldwin static void
1366*744bfb21SJohn Baldwin noise_msg_ephemeral(uint8_t ck[NOISE_HASH_LEN], uint8_t hash[NOISE_HASH_LEN],
1367*744bfb21SJohn Baldwin     const uint8_t src[NOISE_PUBLIC_KEY_LEN])
1368*744bfb21SJohn Baldwin {
1369*744bfb21SJohn Baldwin 	noise_mix_hash(hash, src, NOISE_PUBLIC_KEY_LEN);
1370*744bfb21SJohn Baldwin 	noise_kdf(ck, NULL, NULL, src, NOISE_HASH_LEN, 0, 0,
1371*744bfb21SJohn Baldwin 		  NOISE_PUBLIC_KEY_LEN, ck);
1372*744bfb21SJohn Baldwin }
1373*744bfb21SJohn Baldwin 
1374*744bfb21SJohn Baldwin static void
1375*744bfb21SJohn Baldwin noise_tai64n_now(uint8_t output[NOISE_TIMESTAMP_LEN])
1376*744bfb21SJohn Baldwin {
1377*744bfb21SJohn Baldwin 	struct timespec time;
1378*744bfb21SJohn Baldwin 	uint64_t sec;
1379*744bfb21SJohn Baldwin 	uint32_t nsec;
1380*744bfb21SJohn Baldwin 
1381*744bfb21SJohn Baldwin 	getnanotime(&time);
1382*744bfb21SJohn Baldwin 
1383*744bfb21SJohn Baldwin 	/* Round down the nsec counter to limit precise timing leak. */
1384*744bfb21SJohn Baldwin 	time.tv_nsec &= REJECT_INTERVAL_MASK;
1385*744bfb21SJohn Baldwin 
1386*744bfb21SJohn Baldwin 	/* https://cr.yp.to/libtai/tai64.html */
1387*744bfb21SJohn Baldwin 	sec = htobe64(0x400000000000000aULL + time.tv_sec);
1388*744bfb21SJohn Baldwin 	nsec = htobe32(time.tv_nsec);
1389*744bfb21SJohn Baldwin 
1390*744bfb21SJohn Baldwin 	/* memcpy to output buffer, assuming output could be unaligned. */
1391*744bfb21SJohn Baldwin 	memcpy(output, &sec, sizeof(sec));
1392*744bfb21SJohn Baldwin 	memcpy(output + sizeof(sec), &nsec, sizeof(nsec));
1393*744bfb21SJohn Baldwin }
1394*744bfb21SJohn Baldwin 
1395*744bfb21SJohn Baldwin static inline int
1396*744bfb21SJohn Baldwin noise_timer_expired(sbintime_t timer, uint32_t sec, uint32_t nsec)
1397*744bfb21SJohn Baldwin {
1398*744bfb21SJohn Baldwin 	sbintime_t now = getsbinuptime();
1399*744bfb21SJohn Baldwin 	return (now > (timer + sec * SBT_1S + nstosbt(nsec))) ? ETIMEDOUT : 0;
1400*744bfb21SJohn Baldwin }
1401*744bfb21SJohn Baldwin 
1402*744bfb21SJohn Baldwin static uint64_t siphash24(const uint8_t key[SIPHASH_KEY_LENGTH], const void *src, size_t len)
1403*744bfb21SJohn Baldwin {
1404*744bfb21SJohn Baldwin 	SIPHASH_CTX ctx;
1405*744bfb21SJohn Baldwin 	return (SipHashX(&ctx, 2, 4, key, src, len));
1406*744bfb21SJohn Baldwin }
1407*744bfb21SJohn Baldwin 
1408*744bfb21SJohn Baldwin #ifdef SELFTESTS
1409*744bfb21SJohn Baldwin #include "selftest/counter.c"
1410*744bfb21SJohn Baldwin #endif /* SELFTESTS */
1411