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