1 /* $OpenBSD: wg_noise.c,v 1.7 2024/03/05 17:48:01 mvs Exp $ */
2 /*
3 * Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
4 * Copyright (C) 2019-2020 Matt Dunwoodie <ncon@noconroy.net>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19 #include <sys/types.h>
20 #include <sys/systm.h>
21 #include <sys/param.h>
22 #include <sys/atomic.h>
23 #include <sys/mutex.h>
24 #include <sys/rwlock.h>
25
26 #include <crypto/blake2s.h>
27 #include <crypto/curve25519.h>
28 #include <crypto/chachapoly.h>
29
30 #include <net/wg_noise.h>
31
32 /* Private functions */
33 static struct noise_keypair *
34 noise_remote_keypair_allocate(struct noise_remote *);
35 static void
36 noise_remote_keypair_free(struct noise_remote *,
37 struct noise_keypair *);
38 static uint32_t noise_remote_handshake_index_get(struct noise_remote *);
39 static void noise_remote_handshake_index_drop(struct noise_remote *);
40
41 static uint64_t noise_counter_send(struct noise_counter *);
42 static int noise_counter_recv(struct noise_counter *, uint64_t);
43
44 static void noise_kdf(uint8_t *, uint8_t *, uint8_t *, const uint8_t *,
45 size_t, size_t, size_t, size_t,
46 const uint8_t [NOISE_HASH_LEN]);
47 static int noise_mix_dh(
48 uint8_t [NOISE_HASH_LEN],
49 uint8_t [NOISE_SYMMETRIC_KEY_LEN],
50 const uint8_t [NOISE_PUBLIC_KEY_LEN],
51 const uint8_t [NOISE_PUBLIC_KEY_LEN]);
52 static int noise_mix_ss(
53 uint8_t ck[NOISE_HASH_LEN],
54 uint8_t key[NOISE_SYMMETRIC_KEY_LEN],
55 const uint8_t ss[NOISE_PUBLIC_KEY_LEN]);
56 static void noise_mix_hash(
57 uint8_t [NOISE_HASH_LEN],
58 const uint8_t *,
59 size_t);
60 static void noise_mix_psk(
61 uint8_t [NOISE_HASH_LEN],
62 uint8_t [NOISE_HASH_LEN],
63 uint8_t [NOISE_SYMMETRIC_KEY_LEN],
64 const uint8_t [NOISE_SYMMETRIC_KEY_LEN]);
65 static void noise_param_init(
66 uint8_t [NOISE_HASH_LEN],
67 uint8_t [NOISE_HASH_LEN],
68 const uint8_t [NOISE_PUBLIC_KEY_LEN]);
69
70 static void noise_msg_encrypt(uint8_t *, const uint8_t *, size_t,
71 uint8_t [NOISE_SYMMETRIC_KEY_LEN],
72 uint8_t [NOISE_HASH_LEN]);
73 static int noise_msg_decrypt(uint8_t *, const uint8_t *, size_t,
74 uint8_t [NOISE_SYMMETRIC_KEY_LEN],
75 uint8_t [NOISE_HASH_LEN]);
76 static void noise_msg_ephemeral(
77 uint8_t [NOISE_HASH_LEN],
78 uint8_t [NOISE_HASH_LEN],
79 const uint8_t src[NOISE_PUBLIC_KEY_LEN]);
80
81 static void noise_tai64n_now(uint8_t [NOISE_TIMESTAMP_LEN]);
82 static int noise_timer_expired(struct timespec *, time_t, long);
83
84 /* Set/Get noise parameters */
85 void
noise_local_init(struct noise_local * l,struct noise_upcall * upcall)86 noise_local_init(struct noise_local *l, struct noise_upcall *upcall)
87 {
88 bzero(l, sizeof(*l));
89 rw_init(&l->l_identity_lock, "noise_local_identity");
90 l->l_upcall = *upcall;
91 }
92
93 void
noise_local_lock_identity(struct noise_local * l)94 noise_local_lock_identity(struct noise_local *l)
95 {
96 rw_enter_write(&l->l_identity_lock);
97 }
98
99 void
noise_local_unlock_identity(struct noise_local * l)100 noise_local_unlock_identity(struct noise_local *l)
101 {
102 rw_exit_write(&l->l_identity_lock);
103 }
104
105 int
noise_local_set_private(struct noise_local * l,uint8_t private[NOISE_PUBLIC_KEY_LEN])106 noise_local_set_private(struct noise_local *l,
107 uint8_t private[NOISE_PUBLIC_KEY_LEN])
108 {
109 rw_assert_wrlock(&l->l_identity_lock);
110
111 memcpy(l->l_private, private, NOISE_PUBLIC_KEY_LEN);
112 curve25519_clamp_secret(l->l_private);
113 l->l_has_identity = curve25519_generate_public(l->l_public, private);
114
115 return l->l_has_identity ? 0 : ENXIO;
116 }
117
118 int
noise_local_keys(struct noise_local * l,uint8_t public[NOISE_PUBLIC_KEY_LEN],uint8_t private[NOISE_PUBLIC_KEY_LEN])119 noise_local_keys(struct noise_local *l, uint8_t public[NOISE_PUBLIC_KEY_LEN],
120 uint8_t private[NOISE_PUBLIC_KEY_LEN])
121 {
122 int ret = 0;
123 rw_enter_read(&l->l_identity_lock);
124 if (l->l_has_identity) {
125 if (public != NULL)
126 memcpy(public, l->l_public, NOISE_PUBLIC_KEY_LEN);
127 if (private != NULL)
128 memcpy(private, l->l_private, NOISE_PUBLIC_KEY_LEN);
129 } else {
130 ret = ENXIO;
131 }
132 rw_exit_read(&l->l_identity_lock);
133 return ret;
134 }
135
136 void
noise_remote_init(struct noise_remote * r,uint8_t public[NOISE_PUBLIC_KEY_LEN],struct noise_local * l)137 noise_remote_init(struct noise_remote *r, uint8_t public[NOISE_PUBLIC_KEY_LEN],
138 struct noise_local *l)
139 {
140 bzero(r, sizeof(*r));
141 memcpy(r->r_public, public, NOISE_PUBLIC_KEY_LEN);
142 rw_init(&r->r_handshake_lock, "noise_handshake");
143 mtx_init_flags(&r->r_keypair_mtx, IPL_NET, "noise_keypair", 0);
144
145 SLIST_INSERT_HEAD(&r->r_unused_keypairs, &r->r_keypair[0], kp_entry);
146 SLIST_INSERT_HEAD(&r->r_unused_keypairs, &r->r_keypair[1], kp_entry);
147 SLIST_INSERT_HEAD(&r->r_unused_keypairs, &r->r_keypair[2], kp_entry);
148
149 KASSERT(l != NULL);
150 r->r_local = l;
151
152 rw_enter_write(&l->l_identity_lock);
153 noise_remote_precompute(r);
154 rw_exit_write(&l->l_identity_lock);
155 }
156
157 int
noise_remote_set_psk(struct noise_remote * r,uint8_t psk[NOISE_SYMMETRIC_KEY_LEN])158 noise_remote_set_psk(struct noise_remote *r,
159 uint8_t psk[NOISE_SYMMETRIC_KEY_LEN])
160 {
161 int same;
162 rw_enter_write(&r->r_handshake_lock);
163 same = !timingsafe_bcmp(r->r_psk, psk, NOISE_SYMMETRIC_KEY_LEN);
164 if (!same) {
165 memcpy(r->r_psk, psk, NOISE_SYMMETRIC_KEY_LEN);
166 }
167 rw_exit_write(&r->r_handshake_lock);
168 return same ? EEXIST : 0;
169 }
170
171 int
noise_remote_keys(struct noise_remote * r,uint8_t public[NOISE_PUBLIC_KEY_LEN],uint8_t psk[NOISE_SYMMETRIC_KEY_LEN])172 noise_remote_keys(struct noise_remote *r, uint8_t public[NOISE_PUBLIC_KEY_LEN],
173 uint8_t psk[NOISE_SYMMETRIC_KEY_LEN])
174 {
175 static uint8_t null_psk[NOISE_SYMMETRIC_KEY_LEN];
176 int ret;
177
178 if (public != NULL)
179 memcpy(public, r->r_public, NOISE_PUBLIC_KEY_LEN);
180
181 rw_enter_read(&r->r_handshake_lock);
182 if (psk != NULL)
183 memcpy(psk, r->r_psk, NOISE_SYMMETRIC_KEY_LEN);
184 ret = timingsafe_bcmp(r->r_psk, null_psk, NOISE_SYMMETRIC_KEY_LEN);
185 rw_exit_read(&r->r_handshake_lock);
186
187 /* If r_psk != null_psk return 0, else ENOENT (no psk) */
188 return ret ? 0 : ENOENT;
189 }
190
191 void
noise_remote_precompute(struct noise_remote * r)192 noise_remote_precompute(struct noise_remote *r)
193 {
194 struct noise_local *l = r->r_local;
195 rw_assert_wrlock(&l->l_identity_lock);
196 if (!l->l_has_identity)
197 bzero(r->r_ss, NOISE_PUBLIC_KEY_LEN);
198 else if (!curve25519(r->r_ss, l->l_private, r->r_public))
199 bzero(r->r_ss, NOISE_PUBLIC_KEY_LEN);
200
201 rw_enter_write(&r->r_handshake_lock);
202 noise_remote_handshake_index_drop(r);
203 explicit_bzero(&r->r_handshake, sizeof(r->r_handshake));
204 rw_exit_write(&r->r_handshake_lock);
205 }
206
207 /* Handshake functions */
208 int
noise_create_initiation(struct noise_remote * r,uint32_t * s_idx,uint8_t ue[NOISE_PUBLIC_KEY_LEN],uint8_t es[NOISE_PUBLIC_KEY_LEN+NOISE_AUTHTAG_LEN],uint8_t ets[NOISE_TIMESTAMP_LEN+NOISE_AUTHTAG_LEN])209 noise_create_initiation(struct noise_remote *r, uint32_t *s_idx,
210 uint8_t ue[NOISE_PUBLIC_KEY_LEN],
211 uint8_t es[NOISE_PUBLIC_KEY_LEN + NOISE_AUTHTAG_LEN],
212 uint8_t ets[NOISE_TIMESTAMP_LEN + NOISE_AUTHTAG_LEN])
213 {
214 struct noise_handshake *hs = &r->r_handshake;
215 struct noise_local *l = r->r_local;
216 uint8_t key[NOISE_SYMMETRIC_KEY_LEN];
217 int ret = EINVAL;
218
219 rw_enter_read(&l->l_identity_lock);
220 rw_enter_write(&r->r_handshake_lock);
221 if (!l->l_has_identity)
222 goto error;
223 noise_param_init(hs->hs_ck, hs->hs_hash, r->r_public);
224
225 /* e */
226 curve25519_generate_secret(hs->hs_e);
227 if (curve25519_generate_public(ue, hs->hs_e) == 0)
228 goto error;
229 noise_msg_ephemeral(hs->hs_ck, hs->hs_hash, ue);
230
231 /* es */
232 if (noise_mix_dh(hs->hs_ck, key, hs->hs_e, r->r_public) != 0)
233 goto error;
234
235 /* s */
236 noise_msg_encrypt(es, l->l_public,
237 NOISE_PUBLIC_KEY_LEN, key, hs->hs_hash);
238
239 /* ss */
240 if (noise_mix_ss(hs->hs_ck, key, r->r_ss) != 0)
241 goto error;
242
243 /* {t} */
244 noise_tai64n_now(ets);
245 noise_msg_encrypt(ets, ets,
246 NOISE_TIMESTAMP_LEN, key, hs->hs_hash);
247
248 noise_remote_handshake_index_drop(r);
249 hs->hs_state = CREATED_INITIATION;
250 hs->hs_local_index = noise_remote_handshake_index_get(r);
251 *s_idx = hs->hs_local_index;
252 ret = 0;
253 error:
254 rw_exit_write(&r->r_handshake_lock);
255 rw_exit_read(&l->l_identity_lock);
256 explicit_bzero(key, NOISE_SYMMETRIC_KEY_LEN);
257 return ret;
258 }
259
260 int
noise_consume_initiation(struct noise_local * l,struct noise_remote ** rp,uint32_t s_idx,uint8_t ue[NOISE_PUBLIC_KEY_LEN],uint8_t es[NOISE_PUBLIC_KEY_LEN+NOISE_AUTHTAG_LEN],uint8_t ets[NOISE_TIMESTAMP_LEN+NOISE_AUTHTAG_LEN])261 noise_consume_initiation(struct noise_local *l, struct noise_remote **rp,
262 uint32_t s_idx, uint8_t ue[NOISE_PUBLIC_KEY_LEN],
263 uint8_t es[NOISE_PUBLIC_KEY_LEN + NOISE_AUTHTAG_LEN],
264 uint8_t ets[NOISE_TIMESTAMP_LEN + NOISE_AUTHTAG_LEN])
265 {
266 struct noise_remote *r;
267 struct noise_handshake hs;
268 uint8_t key[NOISE_SYMMETRIC_KEY_LEN];
269 uint8_t r_public[NOISE_PUBLIC_KEY_LEN];
270 uint8_t timestamp[NOISE_TIMESTAMP_LEN];
271 int ret = EINVAL;
272
273 rw_enter_read(&l->l_identity_lock);
274 if (!l->l_has_identity)
275 goto error;
276 noise_param_init(hs.hs_ck, hs.hs_hash, l->l_public);
277
278 /* e */
279 noise_msg_ephemeral(hs.hs_ck, hs.hs_hash, ue);
280
281 /* es */
282 if (noise_mix_dh(hs.hs_ck, key, l->l_private, ue) != 0)
283 goto error;
284
285 /* s */
286 if (noise_msg_decrypt(r_public, es,
287 NOISE_PUBLIC_KEY_LEN + NOISE_AUTHTAG_LEN, key, hs.hs_hash) != 0)
288 goto error;
289
290 /* Lookup the remote we received from */
291 if ((r = l->l_upcall.u_remote_get(l->l_upcall.u_arg, r_public)) == NULL)
292 goto error;
293
294 /* ss */
295 if (noise_mix_ss(hs.hs_ck, key, r->r_ss) != 0)
296 goto error;
297
298 /* {t} */
299 if (noise_msg_decrypt(timestamp, ets,
300 NOISE_TIMESTAMP_LEN + NOISE_AUTHTAG_LEN, key, hs.hs_hash) != 0)
301 goto error;
302
303 memcpy(hs.hs_e, ue, NOISE_PUBLIC_KEY_LEN);
304
305 /* We have successfully computed the same results, now we ensure that
306 * this is not an initiation replay, or a flood attack */
307 rw_enter_write(&r->r_handshake_lock);
308
309 /* Replay */
310 if (memcmp(timestamp, r->r_timestamp, NOISE_TIMESTAMP_LEN) > 0)
311 memcpy(r->r_timestamp, timestamp, NOISE_TIMESTAMP_LEN);
312 else
313 goto error_set;
314 /* Flood attack */
315 if (noise_timer_expired(&r->r_last_init, 0, REJECT_INTERVAL))
316 getnanouptime(&r->r_last_init);
317 else
318 goto error_set;
319
320 /* Ok, we're happy to accept this initiation now */
321 noise_remote_handshake_index_drop(r);
322 hs.hs_state = CONSUMED_INITIATION;
323 hs.hs_local_index = noise_remote_handshake_index_get(r);
324 hs.hs_remote_index = s_idx;
325 r->r_handshake = hs;
326 *rp = r;
327 ret = 0;
328 error_set:
329 rw_exit_write(&r->r_handshake_lock);
330 error:
331 rw_exit_read(&l->l_identity_lock);
332 explicit_bzero(key, NOISE_SYMMETRIC_KEY_LEN);
333 explicit_bzero(&hs, sizeof(hs));
334 return ret;
335 }
336
337 int
noise_create_response(struct noise_remote * r,uint32_t * s_idx,uint32_t * r_idx,uint8_t ue[NOISE_PUBLIC_KEY_LEN],uint8_t en[0+NOISE_AUTHTAG_LEN])338 noise_create_response(struct noise_remote *r, uint32_t *s_idx, uint32_t *r_idx,
339 uint8_t ue[NOISE_PUBLIC_KEY_LEN], uint8_t en[0 + NOISE_AUTHTAG_LEN])
340 {
341 struct noise_handshake *hs = &r->r_handshake;
342 uint8_t key[NOISE_SYMMETRIC_KEY_LEN];
343 uint8_t e[NOISE_PUBLIC_KEY_LEN];
344 int ret = EINVAL;
345
346 rw_enter_read(&r->r_local->l_identity_lock);
347 rw_enter_write(&r->r_handshake_lock);
348
349 if (hs->hs_state != CONSUMED_INITIATION)
350 goto error;
351
352 /* e */
353 curve25519_generate_secret(e);
354 if (curve25519_generate_public(ue, e) == 0)
355 goto error;
356 noise_msg_ephemeral(hs->hs_ck, hs->hs_hash, ue);
357
358 /* ee */
359 if (noise_mix_dh(hs->hs_ck, NULL, e, hs->hs_e) != 0)
360 goto error;
361
362 /* se */
363 if (noise_mix_dh(hs->hs_ck, NULL, e, r->r_public) != 0)
364 goto error;
365
366 /* psk */
367 noise_mix_psk(hs->hs_ck, hs->hs_hash, key, r->r_psk);
368
369 /* {} */
370 noise_msg_encrypt(en, NULL, 0, key, hs->hs_hash);
371
372 hs->hs_state = CREATED_RESPONSE;
373 *r_idx = hs->hs_remote_index;
374 *s_idx = hs->hs_local_index;
375 ret = 0;
376 error:
377 rw_exit_write(&r->r_handshake_lock);
378 rw_exit_read(&r->r_local->l_identity_lock);
379 explicit_bzero(key, NOISE_SYMMETRIC_KEY_LEN);
380 explicit_bzero(e, NOISE_PUBLIC_KEY_LEN);
381 return ret;
382 }
383
384 int
noise_consume_response(struct noise_remote * r,uint32_t s_idx,uint32_t r_idx,uint8_t ue[NOISE_PUBLIC_KEY_LEN],uint8_t en[0+NOISE_AUTHTAG_LEN])385 noise_consume_response(struct noise_remote *r, uint32_t s_idx, uint32_t r_idx,
386 uint8_t ue[NOISE_PUBLIC_KEY_LEN], uint8_t en[0 + NOISE_AUTHTAG_LEN])
387 {
388 struct noise_local *l = r->r_local;
389 struct noise_handshake hs;
390 uint8_t key[NOISE_SYMMETRIC_KEY_LEN];
391 uint8_t preshared_key[NOISE_PUBLIC_KEY_LEN];
392 int ret = EINVAL;
393
394 rw_enter_read(&l->l_identity_lock);
395 if (!l->l_has_identity)
396 goto error;
397
398 rw_enter_read(&r->r_handshake_lock);
399 hs = r->r_handshake;
400 memcpy(preshared_key, r->r_psk, NOISE_SYMMETRIC_KEY_LEN);
401 rw_exit_read(&r->r_handshake_lock);
402
403 if (hs.hs_state != CREATED_INITIATION ||
404 hs.hs_local_index != r_idx)
405 goto error;
406
407 /* e */
408 noise_msg_ephemeral(hs.hs_ck, hs.hs_hash, ue);
409
410 /* ee */
411 if (noise_mix_dh(hs.hs_ck, NULL, hs.hs_e, ue) != 0)
412 goto error;
413
414 /* se */
415 if (noise_mix_dh(hs.hs_ck, NULL, l->l_private, ue) != 0)
416 goto error;
417
418 /* psk */
419 noise_mix_psk(hs.hs_ck, hs.hs_hash, key, preshared_key);
420
421 /* {} */
422 if (noise_msg_decrypt(NULL, en,
423 0 + NOISE_AUTHTAG_LEN, key, hs.hs_hash) != 0)
424 goto error;
425
426 hs.hs_remote_index = s_idx;
427
428 rw_enter_write(&r->r_handshake_lock);
429 if (r->r_handshake.hs_state == hs.hs_state &&
430 r->r_handshake.hs_local_index == hs.hs_local_index) {
431 r->r_handshake = hs;
432 r->r_handshake.hs_state = CONSUMED_RESPONSE;
433 ret = 0;
434 }
435 rw_exit_write(&r->r_handshake_lock);
436 error:
437 rw_exit_read(&l->l_identity_lock);
438 explicit_bzero(&hs, sizeof(hs));
439 explicit_bzero(key, NOISE_SYMMETRIC_KEY_LEN);
440 return ret;
441 }
442
443 int
noise_remote_begin_session(struct noise_remote * r)444 noise_remote_begin_session(struct noise_remote *r)
445 {
446 struct noise_handshake *hs = &r->r_handshake;
447 struct noise_keypair kp, *next, *current, *previous;
448
449 rw_enter_write(&r->r_handshake_lock);
450
451 /* We now derive the keypair from the handshake */
452 if (hs->hs_state == CONSUMED_RESPONSE) {
453 kp.kp_is_initiator = 1;
454 noise_kdf(kp.kp_send, kp.kp_recv, NULL, NULL,
455 NOISE_SYMMETRIC_KEY_LEN, NOISE_SYMMETRIC_KEY_LEN, 0, 0,
456 hs->hs_ck);
457 } else if (hs->hs_state == CREATED_RESPONSE) {
458 kp.kp_is_initiator = 0;
459 noise_kdf(kp.kp_recv, kp.kp_send, NULL, NULL,
460 NOISE_SYMMETRIC_KEY_LEN, NOISE_SYMMETRIC_KEY_LEN, 0, 0,
461 hs->hs_ck);
462 } else {
463 rw_exit_write(&r->r_handshake_lock);
464 return EINVAL;
465 }
466
467 kp.kp_valid = 1;
468 kp.kp_local_index = hs->hs_local_index;
469 kp.kp_remote_index = hs->hs_remote_index;
470 getnanouptime(&kp.kp_birthdate);
471 bzero(&kp.kp_ctr, sizeof(kp.kp_ctr));
472 mtx_init_flags(&kp.kp_ctr.c_mtx, IPL_NET, "noise_counter", 0);
473
474 /* Now we need to add_new_keypair */
475 mtx_enter(&r->r_keypair_mtx);
476 next = r->r_next;
477 current = r->r_current;
478 previous = r->r_previous;
479
480 if (kp.kp_is_initiator) {
481 if (next != NULL) {
482 r->r_next = NULL;
483 r->r_previous = next;
484 noise_remote_keypair_free(r, current);
485 } else {
486 r->r_previous = current;
487 }
488
489 noise_remote_keypair_free(r, previous);
490
491 r->r_current = noise_remote_keypair_allocate(r);
492 *r->r_current = kp;
493 } else {
494 noise_remote_keypair_free(r, next);
495 r->r_previous = NULL;
496 noise_remote_keypair_free(r, previous);
497
498 r->r_next = noise_remote_keypair_allocate(r);
499 *r->r_next = kp;
500 }
501 mtx_leave(&r->r_keypair_mtx);
502
503 explicit_bzero(&r->r_handshake, sizeof(r->r_handshake));
504 rw_exit_write(&r->r_handshake_lock);
505
506 explicit_bzero(&kp, sizeof(kp));
507 return 0;
508 }
509
510 void
noise_remote_clear(struct noise_remote * r)511 noise_remote_clear(struct noise_remote *r)
512 {
513 rw_enter_write(&r->r_handshake_lock);
514 noise_remote_handshake_index_drop(r);
515 explicit_bzero(&r->r_handshake, sizeof(r->r_handshake));
516 rw_exit_write(&r->r_handshake_lock);
517
518 mtx_enter(&r->r_keypair_mtx);
519 noise_remote_keypair_free(r, r->r_next);
520 noise_remote_keypair_free(r, r->r_current);
521 noise_remote_keypair_free(r, r->r_previous);
522 r->r_next = NULL;
523 r->r_current = NULL;
524 r->r_previous = NULL;
525 mtx_leave(&r->r_keypair_mtx);
526 }
527
528 void
noise_remote_expire_current(struct noise_remote * r)529 noise_remote_expire_current(struct noise_remote *r)
530 {
531 mtx_enter(&r->r_keypair_mtx);
532 if (r->r_next != NULL)
533 r->r_next->kp_valid = 0;
534 if (r->r_current != NULL)
535 r->r_current->kp_valid = 0;
536 mtx_leave(&r->r_keypair_mtx);
537 }
538
539 int
noise_remote_ready(struct noise_remote * r)540 noise_remote_ready(struct noise_remote *r)
541 {
542 struct noise_keypair *kp;
543 int ret;
544
545 mtx_enter(&r->r_keypair_mtx);
546 /* kp_ctr isn't locked here, we're happy to accept a racy read. */
547 if ((kp = r->r_current) == NULL ||
548 !kp->kp_valid ||
549 noise_timer_expired(&kp->kp_birthdate, REJECT_AFTER_TIME, 0) ||
550 kp->kp_ctr.c_recv >= REJECT_AFTER_MESSAGES ||
551 kp->kp_ctr.c_send >= REJECT_AFTER_MESSAGES)
552 ret = EINVAL;
553 else
554 ret = 0;
555 mtx_leave(&r->r_keypair_mtx);
556 return ret;
557 }
558
559 int
noise_remote_encrypt(struct noise_remote * r,uint32_t * r_idx,uint64_t * nonce,uint8_t * buf,size_t buflen)560 noise_remote_encrypt(struct noise_remote *r, uint32_t *r_idx, uint64_t *nonce,
561 uint8_t *buf, size_t buflen)
562 {
563 struct noise_keypair *kp;
564 int ret = EINVAL;
565
566 mtx_enter(&r->r_keypair_mtx);
567 if ((kp = r->r_current) == NULL)
568 goto error;
569
570 /* We confirm that our values are within our tolerances. We want:
571 * - a valid keypair
572 * - our keypair to be less than REJECT_AFTER_TIME seconds old
573 * - our receive counter to be less than REJECT_AFTER_MESSAGES
574 * - our send counter to be less than REJECT_AFTER_MESSAGES
575 *
576 * kp_ctr isn't locked here, we're happy to accept a racy read. */
577 if (!kp->kp_valid ||
578 noise_timer_expired(&kp->kp_birthdate, REJECT_AFTER_TIME, 0) ||
579 kp->kp_ctr.c_recv >= REJECT_AFTER_MESSAGES ||
580 ((*nonce = noise_counter_send(&kp->kp_ctr)) > REJECT_AFTER_MESSAGES))
581 goto error;
582
583 /* We encrypt into the same buffer, so the caller must ensure that buf
584 * has NOISE_AUTHTAG_LEN bytes to store the MAC. The nonce and index
585 * are passed back out to the caller through the provided data pointer. */
586 *r_idx = kp->kp_remote_index;
587 chacha20poly1305_encrypt(buf, buf, buflen,
588 NULL, 0, *nonce, kp->kp_send);
589
590 /* If our values are still within tolerances, but we are approaching
591 * the tolerances, we notify the caller with ESTALE that they should
592 * establish a new keypair. The current keypair can continue to be used
593 * until the tolerances are hit. We notify if:
594 * - our send counter is valid and not less than REKEY_AFTER_MESSAGES
595 * - we're the initiator and our keypair is older than
596 * REKEY_AFTER_TIME seconds */
597 ret = ESTALE;
598 if ((kp->kp_valid && *nonce >= REKEY_AFTER_MESSAGES) ||
599 (kp->kp_is_initiator &&
600 noise_timer_expired(&kp->kp_birthdate, REKEY_AFTER_TIME, 0)))
601 goto error;
602
603 ret = 0;
604 error:
605 mtx_leave(&r->r_keypair_mtx);
606 return ret;
607 }
608
609 int
noise_remote_decrypt(struct noise_remote * r,uint32_t r_idx,uint64_t nonce,uint8_t * buf,size_t buflen)610 noise_remote_decrypt(struct noise_remote *r, uint32_t r_idx, uint64_t nonce,
611 uint8_t *buf, size_t buflen)
612 {
613 struct noise_keypair *kp;
614 int ret = EINVAL;
615
616 /* We retrieve the keypair corresponding to the provided index. We
617 * attempt the current keypair first as that is most likely. We also
618 * want to make sure that the keypair is valid as it would be
619 * catastrophic to decrypt against a zero'ed keypair. */
620 mtx_enter(&r->r_keypair_mtx);
621
622 if (r->r_current != NULL && r->r_current->kp_local_index == r_idx) {
623 kp = r->r_current;
624 } else if (r->r_previous != NULL && r->r_previous->kp_local_index == r_idx) {
625 kp = r->r_previous;
626 } else if (r->r_next != NULL && r->r_next->kp_local_index == r_idx) {
627 kp = r->r_next;
628 } else {
629 goto error;
630 }
631
632 /* We confirm that our values are within our tolerances. These values
633 * are the same as the encrypt routine.
634 *
635 * kp_ctr isn't locked here, we're happy to accept a racy read. */
636 if (noise_timer_expired(&kp->kp_birthdate, REJECT_AFTER_TIME, 0) ||
637 kp->kp_ctr.c_recv >= REJECT_AFTER_MESSAGES)
638 goto error;
639
640 /* Decrypt, then validate the counter. We don't want to validate the
641 * counter before decrypting as we do not know the message is authentic
642 * prior to decryption. */
643 if (chacha20poly1305_decrypt(buf, buf, buflen,
644 NULL, 0, nonce, kp->kp_recv) == 0)
645 goto error;
646
647 if (noise_counter_recv(&kp->kp_ctr, nonce) != 0)
648 goto error;
649
650 /* If we've received the handshake confirming data packet then move the
651 * next keypair into current. If we do slide the next keypair in, then
652 * we skip the REKEY_AFTER_TIME_RECV check. This is safe to do as a
653 * data packet can't confirm a session that we are an INITIATOR of. */
654 if (kp == r->r_next) {
655 if (kp == r->r_next && kp->kp_local_index == r_idx) {
656 noise_remote_keypair_free(r, r->r_previous);
657 r->r_previous = r->r_current;
658 r->r_current = r->r_next;
659 r->r_next = NULL;
660
661 ret = ECONNRESET;
662 goto error;
663 }
664 }
665
666 /* Similar to when we encrypt, we want to notify the caller when we
667 * are approaching our tolerances. We notify if:
668 * - we're the initiator and the current keypair is older than
669 * REKEY_AFTER_TIME_RECV seconds. */
670 ret = ESTALE;
671 kp = r->r_current;
672 if (kp != NULL &&
673 kp->kp_valid &&
674 kp->kp_is_initiator &&
675 noise_timer_expired(&kp->kp_birthdate, REKEY_AFTER_TIME_RECV, 0))
676 goto error;
677
678 ret = 0;
679
680 error:
681 mtx_leave(&r->r_keypair_mtx);
682 return ret;
683 }
684
685 /* Private functions - these should not be called outside this file under any
686 * circumstances. */
687 static struct noise_keypair *
noise_remote_keypair_allocate(struct noise_remote * r)688 noise_remote_keypair_allocate(struct noise_remote *r)
689 {
690 struct noise_keypair *kp;
691 kp = SLIST_FIRST(&r->r_unused_keypairs);
692 SLIST_REMOVE_HEAD(&r->r_unused_keypairs, kp_entry);
693 return kp;
694 }
695
696 static void
noise_remote_keypair_free(struct noise_remote * r,struct noise_keypair * kp)697 noise_remote_keypair_free(struct noise_remote *r, struct noise_keypair *kp)
698 {
699 struct noise_upcall *u = &r->r_local->l_upcall;
700 if (kp != NULL) {
701 SLIST_INSERT_HEAD(&r->r_unused_keypairs, kp, kp_entry);
702 u->u_index_drop(u->u_arg, kp->kp_local_index);
703 bzero(kp->kp_send, sizeof(kp->kp_send));
704 bzero(kp->kp_recv, sizeof(kp->kp_recv));
705 }
706 }
707
708 static uint32_t
noise_remote_handshake_index_get(struct noise_remote * r)709 noise_remote_handshake_index_get(struct noise_remote *r)
710 {
711 struct noise_upcall *u = &r->r_local->l_upcall;
712 return u->u_index_set(u->u_arg, r);
713 }
714
715 static void
noise_remote_handshake_index_drop(struct noise_remote * r)716 noise_remote_handshake_index_drop(struct noise_remote *r)
717 {
718 struct noise_handshake *hs = &r->r_handshake;
719 struct noise_upcall *u = &r->r_local->l_upcall;
720 rw_assert_wrlock(&r->r_handshake_lock);
721 if (hs->hs_state != HS_ZEROED)
722 u->u_index_drop(u->u_arg, hs->hs_local_index);
723 }
724
725 static uint64_t
noise_counter_send(struct noise_counter * ctr)726 noise_counter_send(struct noise_counter *ctr)
727 {
728 #ifdef __LP64__
729 return atomic_inc_long_nv((u_long *)&ctr->c_send) - 1;
730 #else
731 uint64_t ret;
732 mtx_enter(&ctr->c_mtx);
733 ret = ctr->c_send++;
734 mtx_leave(&ctr->c_mtx);
735 return ret;
736 #endif
737 }
738
739 static int
noise_counter_recv(struct noise_counter * ctr,uint64_t recv)740 noise_counter_recv(struct noise_counter *ctr, uint64_t recv)
741 {
742 uint64_t i, top, index_recv, index_ctr;
743 unsigned long bit;
744 int ret = EEXIST;
745
746 mtx_enter(&ctr->c_mtx);
747
748 /* Check that the recv counter is valid */
749 if (ctr->c_recv >= REJECT_AFTER_MESSAGES ||
750 recv >= REJECT_AFTER_MESSAGES)
751 goto error;
752
753 /* If the packet is out of the window, invalid */
754 if (recv + COUNTER_WINDOW_SIZE < ctr->c_recv)
755 goto error;
756
757 /* If the new counter is ahead of the current counter, we'll need to
758 * zero out the bitmap that has previously been used */
759 index_recv = recv / COUNTER_BITS;
760 index_ctr = ctr->c_recv / COUNTER_BITS;
761
762 if (recv > ctr->c_recv) {
763 top = MIN(index_recv - index_ctr, COUNTER_NUM);
764 for (i = 1; i <= top; i++)
765 ctr->c_backtrack[
766 (i + index_ctr) & (COUNTER_NUM - 1)] = 0;
767 ctr->c_recv = recv;
768 }
769
770 index_recv %= COUNTER_NUM;
771 bit = 1ul << (recv % COUNTER_BITS);
772
773 if (ctr->c_backtrack[index_recv] & bit)
774 goto error;
775
776 ctr->c_backtrack[index_recv] |= bit;
777
778 ret = 0;
779 error:
780 mtx_leave(&ctr->c_mtx);
781 return ret;
782 }
783
784 static void
noise_kdf(uint8_t * a,uint8_t * b,uint8_t * c,const uint8_t * x,size_t a_len,size_t b_len,size_t c_len,size_t x_len,const uint8_t ck[NOISE_HASH_LEN])785 noise_kdf(uint8_t *a, uint8_t *b, uint8_t *c, const uint8_t *x,
786 size_t a_len, size_t b_len, size_t c_len, size_t x_len,
787 const uint8_t ck[NOISE_HASH_LEN])
788 {
789 uint8_t out[BLAKE2S_HASH_SIZE + 1];
790 uint8_t sec[BLAKE2S_HASH_SIZE];
791
792 KASSERT(a_len <= BLAKE2S_HASH_SIZE && b_len <= BLAKE2S_HASH_SIZE &&
793 c_len <= BLAKE2S_HASH_SIZE);
794 KASSERT(!(b || b_len || c || c_len) || (a && a_len));
795 KASSERT(!(c || c_len) || (b && b_len));
796
797 /* Extract entropy from "x" into sec */
798 blake2s_hmac(sec, x, ck, BLAKE2S_HASH_SIZE, x_len, NOISE_HASH_LEN);
799
800 if (a == NULL || a_len == 0)
801 goto out;
802
803 /* Expand first key: key = sec, data = 0x1 */
804 out[0] = 1;
805 blake2s_hmac(out, out, sec, BLAKE2S_HASH_SIZE, 1, BLAKE2S_HASH_SIZE);
806 memcpy(a, out, a_len);
807
808 if (b == NULL || b_len == 0)
809 goto out;
810
811 /* Expand second key: key = sec, data = "a" || 0x2 */
812 out[BLAKE2S_HASH_SIZE] = 2;
813 blake2s_hmac(out, out, sec, BLAKE2S_HASH_SIZE, BLAKE2S_HASH_SIZE + 1,
814 BLAKE2S_HASH_SIZE);
815 memcpy(b, out, b_len);
816
817 if (c == NULL || c_len == 0)
818 goto out;
819
820 /* Expand third key: key = sec, data = "b" || 0x3 */
821 out[BLAKE2S_HASH_SIZE] = 3;
822 blake2s_hmac(out, out, sec, BLAKE2S_HASH_SIZE, BLAKE2S_HASH_SIZE + 1,
823 BLAKE2S_HASH_SIZE);
824 memcpy(c, out, c_len);
825
826 out:
827 /* Clear sensitive data from stack */
828 explicit_bzero(sec, BLAKE2S_HASH_SIZE);
829 explicit_bzero(out, BLAKE2S_HASH_SIZE + 1);
830 }
831
832 static int
noise_mix_dh(uint8_t ck[NOISE_HASH_LEN],uint8_t key[NOISE_SYMMETRIC_KEY_LEN],const uint8_t private[NOISE_PUBLIC_KEY_LEN],const uint8_t public[NOISE_PUBLIC_KEY_LEN])833 noise_mix_dh(uint8_t ck[NOISE_HASH_LEN], uint8_t key[NOISE_SYMMETRIC_KEY_LEN],
834 const uint8_t private[NOISE_PUBLIC_KEY_LEN],
835 const uint8_t public[NOISE_PUBLIC_KEY_LEN])
836 {
837 uint8_t dh[NOISE_PUBLIC_KEY_LEN];
838
839 if (!curve25519(dh, private, public))
840 return EINVAL;
841 noise_kdf(ck, key, NULL, dh,
842 NOISE_HASH_LEN, NOISE_SYMMETRIC_KEY_LEN, 0, NOISE_PUBLIC_KEY_LEN, ck);
843 explicit_bzero(dh, NOISE_PUBLIC_KEY_LEN);
844 return 0;
845 }
846
847 static int
noise_mix_ss(uint8_t ck[NOISE_HASH_LEN],uint8_t key[NOISE_SYMMETRIC_KEY_LEN],const uint8_t ss[NOISE_PUBLIC_KEY_LEN])848 noise_mix_ss(uint8_t ck[NOISE_HASH_LEN], uint8_t key[NOISE_SYMMETRIC_KEY_LEN],
849 const uint8_t ss[NOISE_PUBLIC_KEY_LEN])
850 {
851 static uint8_t null_point[NOISE_PUBLIC_KEY_LEN];
852 if (timingsafe_bcmp(ss, null_point, NOISE_PUBLIC_KEY_LEN) == 0)
853 return ENOENT;
854 noise_kdf(ck, key, NULL, ss,
855 NOISE_HASH_LEN, NOISE_SYMMETRIC_KEY_LEN, 0, NOISE_PUBLIC_KEY_LEN, ck);
856 return 0;
857 }
858
859 static void
noise_mix_hash(uint8_t hash[NOISE_HASH_LEN],const uint8_t * src,size_t src_len)860 noise_mix_hash(uint8_t hash[NOISE_HASH_LEN], const uint8_t *src,
861 size_t src_len)
862 {
863 struct blake2s_state blake;
864
865 blake2s_init(&blake, NOISE_HASH_LEN);
866 blake2s_update(&blake, hash, NOISE_HASH_LEN);
867 blake2s_update(&blake, src, src_len);
868 blake2s_final(&blake, hash);
869 }
870
871 static void
noise_mix_psk(uint8_t ck[NOISE_HASH_LEN],uint8_t hash[NOISE_HASH_LEN],uint8_t key[NOISE_SYMMETRIC_KEY_LEN],const uint8_t psk[NOISE_SYMMETRIC_KEY_LEN])872 noise_mix_psk(uint8_t ck[NOISE_HASH_LEN], uint8_t hash[NOISE_HASH_LEN],
873 uint8_t key[NOISE_SYMMETRIC_KEY_LEN],
874 const uint8_t psk[NOISE_SYMMETRIC_KEY_LEN])
875 {
876 uint8_t tmp[NOISE_HASH_LEN];
877
878 noise_kdf(ck, tmp, key, psk,
879 NOISE_HASH_LEN, NOISE_HASH_LEN, NOISE_SYMMETRIC_KEY_LEN,
880 NOISE_SYMMETRIC_KEY_LEN, ck);
881 noise_mix_hash(hash, tmp, NOISE_HASH_LEN);
882 explicit_bzero(tmp, NOISE_HASH_LEN);
883 }
884
885 static void
noise_param_init(uint8_t ck[NOISE_HASH_LEN],uint8_t hash[NOISE_HASH_LEN],const uint8_t s[NOISE_PUBLIC_KEY_LEN])886 noise_param_init(uint8_t ck[NOISE_HASH_LEN], uint8_t hash[NOISE_HASH_LEN],
887 const uint8_t s[NOISE_PUBLIC_KEY_LEN])
888 {
889 struct blake2s_state blake;
890
891 blake2s(ck, (uint8_t *)NOISE_HANDSHAKE_NAME, NULL,
892 NOISE_HASH_LEN, strlen(NOISE_HANDSHAKE_NAME), 0);
893 blake2s_init(&blake, NOISE_HASH_LEN);
894 blake2s_update(&blake, ck, NOISE_HASH_LEN);
895 blake2s_update(&blake, (uint8_t *)NOISE_IDENTIFIER_NAME,
896 strlen(NOISE_IDENTIFIER_NAME));
897 blake2s_final(&blake, hash);
898
899 noise_mix_hash(hash, s, NOISE_PUBLIC_KEY_LEN);
900 }
901
902 static void
noise_msg_encrypt(uint8_t * dst,const uint8_t * src,size_t src_len,uint8_t key[NOISE_SYMMETRIC_KEY_LEN],uint8_t hash[NOISE_HASH_LEN])903 noise_msg_encrypt(uint8_t *dst, const uint8_t *src, size_t src_len,
904 uint8_t key[NOISE_SYMMETRIC_KEY_LEN], uint8_t hash[NOISE_HASH_LEN])
905 {
906 /* Nonce always zero for Noise_IK */
907 chacha20poly1305_encrypt(dst, src, src_len,
908 hash, NOISE_HASH_LEN, 0, key);
909 noise_mix_hash(hash, dst, src_len + NOISE_AUTHTAG_LEN);
910 }
911
912 static int
noise_msg_decrypt(uint8_t * dst,const uint8_t * src,size_t src_len,uint8_t key[NOISE_SYMMETRIC_KEY_LEN],uint8_t hash[NOISE_HASH_LEN])913 noise_msg_decrypt(uint8_t *dst, const uint8_t *src, size_t src_len,
914 uint8_t key[NOISE_SYMMETRIC_KEY_LEN], uint8_t hash[NOISE_HASH_LEN])
915 {
916 /* Nonce always zero for Noise_IK */
917 if (!chacha20poly1305_decrypt(dst, src, src_len,
918 hash, NOISE_HASH_LEN, 0, key))
919 return EINVAL;
920 noise_mix_hash(hash, src, src_len);
921 return 0;
922 }
923
924 static void
noise_msg_ephemeral(uint8_t ck[NOISE_HASH_LEN],uint8_t hash[NOISE_HASH_LEN],const uint8_t src[NOISE_PUBLIC_KEY_LEN])925 noise_msg_ephemeral(uint8_t ck[NOISE_HASH_LEN], uint8_t hash[NOISE_HASH_LEN],
926 const uint8_t src[NOISE_PUBLIC_KEY_LEN])
927 {
928 noise_mix_hash(hash, src, NOISE_PUBLIC_KEY_LEN);
929 noise_kdf(ck, NULL, NULL, src, NOISE_HASH_LEN, 0, 0,
930 NOISE_PUBLIC_KEY_LEN, ck);
931 }
932
933 static void
noise_tai64n_now(uint8_t output[NOISE_TIMESTAMP_LEN])934 noise_tai64n_now(uint8_t output[NOISE_TIMESTAMP_LEN])
935 {
936 struct timespec time;
937 uint64_t sec;
938 uint32_t nsec;
939
940 getnanotime(&time);
941
942 /* Round down the nsec counter to limit precise timing leak. */
943 time.tv_nsec &= REJECT_INTERVAL_MASK;
944
945 /* https://cr.yp.to/libtai/tai64.html */
946 sec = htobe64(0x400000000000000aULL + time.tv_sec);
947 nsec = htobe32(time.tv_nsec);
948
949 /* memcpy to output buffer, assuming output could be unaligned. */
950 memcpy(output, &sec, sizeof(sec));
951 memcpy(output + sizeof(sec), &nsec, sizeof(nsec));
952 }
953
954 static int
noise_timer_expired(struct timespec * birthdate,time_t sec,long nsec)955 noise_timer_expired(struct timespec *birthdate, time_t sec, long nsec)
956 {
957 struct timespec uptime;
958 struct timespec expire = { .tv_sec = sec, .tv_nsec = nsec };
959
960 /* We don't really worry about a zeroed birthdate, to avoid the extra
961 * check on every encrypt/decrypt. This does mean that r_last_init
962 * check may fail if getnanouptime is < REJECT_INTERVAL from 0. */
963
964 getnanouptime(&uptime);
965 timespecadd(birthdate, &expire, &expire);
966 return timespeccmp(&uptime, &expire, >) ? ETIMEDOUT : 0;
967 }
968
969 #ifdef WGTEST
970
971 #define MESSAGE_LEN 64
972 #define LARGE_MESSAGE_LEN 1420
973
974 #define T_LIM (COUNTER_WINDOW_SIZE + 1)
975 #define T_INIT do { \
976 bzero(&ctr, sizeof(ctr)); \
977 mtx_init_flags(&ctr.c_mtx, IPL_NET, "counter", 0); \
978 } while (0)
979 #define T(num, v, e) do { \
980 if (noise_counter_recv(&ctr, v) != e) { \
981 printf("%s, test %d: failed.\n", __func__, num); \
982 return; \
983 } \
984 } while (0)
985 #define T_FAILED(test) do { \
986 printf("%s %s: failed\n", __func__, test); \
987 return; \
988 } while (0)
989 #define T_PASSED printf("%s: passed.\n", __func__)
990
991 static struct noise_local al, bl;
992 static struct noise_remote ar, br;
993
994 static struct noise_initiation {
995 uint32_t s_idx;
996 uint8_t ue[NOISE_PUBLIC_KEY_LEN];
997 uint8_t es[NOISE_PUBLIC_KEY_LEN + NOISE_AUTHTAG_LEN];
998 uint8_t ets[NOISE_TIMESTAMP_LEN + NOISE_AUTHTAG_LEN];
999 } init;
1000
1001 static struct noise_response {
1002 uint32_t s_idx;
1003 uint32_t r_idx;
1004 uint8_t ue[NOISE_PUBLIC_KEY_LEN];
1005 uint8_t en[0 + NOISE_AUTHTAG_LEN];
1006 } resp;
1007
1008 static uint64_t nonce;
1009 static uint32_t index;
1010 static uint8_t data[MESSAGE_LEN + NOISE_AUTHTAG_LEN];
1011 static uint8_t largedata[LARGE_MESSAGE_LEN + NOISE_AUTHTAG_LEN];
1012
1013 static struct noise_remote *
upcall_get(void * x0,uint8_t * x1)1014 upcall_get(void *x0, uint8_t *x1) { return x0; }
1015 static uint32_t
upcall_set(void * x0,struct noise_remote * x1)1016 upcall_set(void *x0, struct noise_remote *x1) { return 5; }
1017 static void
upcall_drop(void * x0,uint32_t x1)1018 upcall_drop(void *x0, uint32_t x1) { }
1019
1020 static void
noise_counter_test()1021 noise_counter_test()
1022 {
1023 struct noise_counter ctr;
1024 int i;
1025
1026 T_INIT;
1027 /* T(test number, nonce, expected_response) */
1028 T( 1, 0, 0);
1029 T( 2, 1, 0);
1030 T( 3, 1, EEXIST);
1031 T( 4, 9, 0);
1032 T( 5, 8, 0);
1033 T( 6, 7, 0);
1034 T( 7, 7, EEXIST);
1035 T( 8, T_LIM, 0);
1036 T( 9, T_LIM - 1, 0);
1037 T(10, T_LIM - 1, EEXIST);
1038 T(11, T_LIM - 2, 0);
1039 T(12, 2, 0);
1040 T(13, 2, EEXIST);
1041 T(14, T_LIM + 16, 0);
1042 T(15, 3, EEXIST);
1043 T(16, T_LIM + 16, EEXIST);
1044 T(17, T_LIM * 4, 0);
1045 T(18, T_LIM * 4 - (T_LIM - 1), 0);
1046 T(19, 10, EEXIST);
1047 T(20, T_LIM * 4 - T_LIM, EEXIST);
1048 T(21, T_LIM * 4 - (T_LIM + 1), EEXIST);
1049 T(22, T_LIM * 4 - (T_LIM - 2), 0);
1050 T(23, T_LIM * 4 + 1 - T_LIM, EEXIST);
1051 T(24, 0, EEXIST);
1052 T(25, REJECT_AFTER_MESSAGES, EEXIST);
1053 T(26, REJECT_AFTER_MESSAGES - 1, 0);
1054 T(27, REJECT_AFTER_MESSAGES, EEXIST);
1055 T(28, REJECT_AFTER_MESSAGES - 1, EEXIST);
1056 T(29, REJECT_AFTER_MESSAGES - 2, 0);
1057 T(30, REJECT_AFTER_MESSAGES + 1, EEXIST);
1058 T(31, REJECT_AFTER_MESSAGES + 2, EEXIST);
1059 T(32, REJECT_AFTER_MESSAGES - 2, EEXIST);
1060 T(33, REJECT_AFTER_MESSAGES - 3, 0);
1061 T(34, 0, EEXIST);
1062
1063 T_INIT;
1064 for (i = 1; i <= COUNTER_WINDOW_SIZE; ++i)
1065 T(35, i, 0);
1066 T(36, 0, 0);
1067 T(37, 0, EEXIST);
1068
1069 T_INIT;
1070 for (i = 2; i <= COUNTER_WINDOW_SIZE + 1; ++i)
1071 T(38, i, 0);
1072 T(39, 1, 0);
1073 T(40, 0, EEXIST);
1074
1075 T_INIT;
1076 for (i = COUNTER_WINDOW_SIZE + 1; i-- > 0;)
1077 T(41, i, 0);
1078
1079 T_INIT;
1080 for (i = COUNTER_WINDOW_SIZE + 2; i-- > 1;)
1081 T(42, i, 0);
1082 T(43, 0, EEXIST);
1083
1084 T_INIT;
1085 for (i = COUNTER_WINDOW_SIZE + 1; i-- > 1;)
1086 T(44, i, 0);
1087 T(45, COUNTER_WINDOW_SIZE + 1, 0);
1088 T(46, 0, EEXIST);
1089
1090 T_INIT;
1091 for (i = COUNTER_WINDOW_SIZE + 1; i-- > 1;)
1092 T(47, i, 0);
1093 T(48, 0, 0);
1094 T(49, COUNTER_WINDOW_SIZE + 1, 0);
1095
1096 T_PASSED;
1097 }
1098
1099 static void
noise_handshake_init(struct noise_local * al,struct noise_remote * ar,struct noise_local * bl,struct noise_remote * br)1100 noise_handshake_init(struct noise_local *al, struct noise_remote *ar,
1101 struct noise_local *bl, struct noise_remote *br)
1102 {
1103 uint8_t apriv[NOISE_PUBLIC_KEY_LEN], bpriv[NOISE_PUBLIC_KEY_LEN];
1104 uint8_t apub[NOISE_PUBLIC_KEY_LEN], bpub[NOISE_PUBLIC_KEY_LEN];
1105 uint8_t psk[NOISE_SYMMETRIC_KEY_LEN];
1106
1107 struct noise_upcall upcall = {
1108 .u_arg = NULL,
1109 .u_remote_get = upcall_get,
1110 .u_index_set = upcall_set,
1111 .u_index_drop = upcall_drop,
1112 };
1113
1114 upcall.u_arg = ar;
1115 noise_local_init(al, &upcall);
1116 upcall.u_arg = br;
1117 noise_local_init(bl, &upcall);
1118
1119 arc4random_buf(apriv, NOISE_PUBLIC_KEY_LEN);
1120 arc4random_buf(bpriv, NOISE_PUBLIC_KEY_LEN);
1121
1122 noise_local_lock_identity(al);
1123 noise_local_set_private(al, apriv);
1124 noise_local_unlock_identity(al);
1125
1126 noise_local_lock_identity(bl);
1127 noise_local_set_private(bl, bpriv);
1128 noise_local_unlock_identity(bl);
1129
1130 noise_local_keys(al, apub, NULL);
1131 noise_local_keys(bl, bpub, NULL);
1132
1133 noise_remote_init(ar, bpub, al);
1134 noise_remote_init(br, apub, bl);
1135
1136 arc4random_buf(psk, NOISE_SYMMETRIC_KEY_LEN);
1137 noise_remote_set_psk(ar, psk);
1138 noise_remote_set_psk(br, psk);
1139 }
1140
1141 static void
noise_handshake_test()1142 noise_handshake_test()
1143 {
1144 struct noise_remote *r;
1145 int i;
1146
1147 noise_handshake_init(&al, &ar, &bl, &br);
1148
1149 /* Create initiation */
1150 if (noise_create_initiation(&ar, &init.s_idx,
1151 init.ue, init.es, init.ets) != 0)
1152 T_FAILED("create_initiation");
1153
1154 /* Check encrypted (es) validation */
1155 for (i = 0; i < sizeof(init.es); i++) {
1156 init.es[i] = ~init.es[i];
1157 if (noise_consume_initiation(&bl, &r, init.s_idx,
1158 init.ue, init.es, init.ets) != EINVAL)
1159 T_FAILED("consume_initiation_es");
1160 init.es[i] = ~init.es[i];
1161 }
1162
1163 /* Check encrypted (ets) validation */
1164 for (i = 0; i < sizeof(init.ets); i++) {
1165 init.ets[i] = ~init.ets[i];
1166 if (noise_consume_initiation(&bl, &r, init.s_idx,
1167 init.ue, init.es, init.ets) != EINVAL)
1168 T_FAILED("consume_initiation_ets");
1169 init.ets[i] = ~init.ets[i];
1170 }
1171
1172 /* Consume initiation properly */
1173 if (noise_consume_initiation(&bl, &r, init.s_idx,
1174 init.ue, init.es, init.ets) != 0)
1175 T_FAILED("consume_initiation");
1176 if (r != &br)
1177 T_FAILED("remote_lookup");
1178
1179 /* Replay initiation */
1180 if (noise_consume_initiation(&bl, &r, init.s_idx,
1181 init.ue, init.es, init.ets) != EINVAL)
1182 T_FAILED("consume_initiation_replay");
1183 if (r != &br)
1184 T_FAILED("remote_lookup_r_unchanged");
1185
1186 /* Create response */
1187 if (noise_create_response(&br, &resp.s_idx,
1188 &resp.r_idx, resp.ue, resp.en) != 0)
1189 T_FAILED("create_response");
1190
1191 /* Check encrypted (en) validation */
1192 for (i = 0; i < sizeof(resp.en); i++) {
1193 resp.en[i] = ~resp.en[i];
1194 if (noise_consume_response(&ar, resp.s_idx,
1195 resp.r_idx, resp.ue, resp.en) != EINVAL)
1196 T_FAILED("consume_response_en");
1197 resp.en[i] = ~resp.en[i];
1198 }
1199
1200 /* Consume response properly */
1201 if (noise_consume_response(&ar, resp.s_idx,
1202 resp.r_idx, resp.ue, resp.en) != 0)
1203 T_FAILED("consume_response");
1204
1205 /* Derive keys on both sides */
1206 if (noise_remote_begin_session(&ar) != 0)
1207 T_FAILED("promote_ar");
1208 if (noise_remote_begin_session(&br) != 0)
1209 T_FAILED("promote_br");
1210
1211 for (i = 0; i < MESSAGE_LEN; i++)
1212 data[i] = i;
1213
1214 /* Since bob is responder, he must not encrypt until confirmed */
1215 if (noise_remote_encrypt(&br, &index, &nonce,
1216 data, MESSAGE_LEN) != EINVAL)
1217 T_FAILED("encrypt_kci_wait");
1218
1219 /* Alice now encrypt and gets bob to decrypt */
1220 if (noise_remote_encrypt(&ar, &index, &nonce,
1221 data, MESSAGE_LEN) != 0)
1222 T_FAILED("encrypt_akp");
1223 if (noise_remote_decrypt(&br, index, nonce,
1224 data, MESSAGE_LEN + NOISE_AUTHTAG_LEN) != ECONNRESET)
1225 T_FAILED("decrypt_bkp");
1226
1227 for (i = 0; i < MESSAGE_LEN; i++)
1228 if (data[i] != i)
1229 T_FAILED("decrypt_message_akp_bkp");
1230
1231 /* Now bob has received confirmation, he can encrypt */
1232 if (noise_remote_encrypt(&br, &index, &nonce,
1233 data, MESSAGE_LEN) != 0)
1234 T_FAILED("encrypt_kci_ready");
1235 if (noise_remote_decrypt(&ar, index, nonce,
1236 data, MESSAGE_LEN + NOISE_AUTHTAG_LEN) != 0)
1237 T_FAILED("decrypt_akp");
1238
1239 for (i = 0; i < MESSAGE_LEN; i++)
1240 if (data[i] != i)
1241 T_FAILED("decrypt_message_bkp_akp");
1242
1243 T_PASSED;
1244 }
1245
1246 static void
noise_speed_test()1247 noise_speed_test()
1248 {
1249 #define SPEED_ITER (1<<16)
1250 struct timespec start, end;
1251 struct noise_remote *r;
1252 int nsec, i;
1253
1254 #define NSEC 1000000000
1255 #define T_TIME_START(iter, size) do { \
1256 printf("%s %d %d byte encryptions\n", __func__, iter, size); \
1257 nanouptime(&start); \
1258 } while (0)
1259 #define T_TIME_END(iter, size) do { \
1260 nanouptime(&end); \
1261 timespecsub(&end, &start, &end); \
1262 nsec = (end.tv_sec * NSEC + end.tv_nsec) / iter; \
1263 printf("%s %d nsec/iter, %d iter/sec, %d byte/sec\n", \
1264 __func__, nsec, NSEC / nsec, NSEC / nsec * size); \
1265 } while (0)
1266 #define T_TIME_START_SINGLE(name) do { \
1267 printf("%s %s\n", __func__, name); \
1268 nanouptime(&start); \
1269 } while (0)
1270 #define T_TIME_END_SINGLE() do { \
1271 nanouptime(&end); \
1272 timespecsub(&end, &start, &end); \
1273 nsec = (end.tv_sec * NSEC + end.tv_nsec); \
1274 printf("%s %d nsec/iter, %d iter/sec\n", \
1275 __func__, nsec, NSEC / nsec); \
1276 } while (0)
1277
1278 noise_handshake_init(&al, &ar, &bl, &br);
1279
1280 T_TIME_START_SINGLE("create_initiation");
1281 if (noise_create_initiation(&ar, &init.s_idx,
1282 init.ue, init.es, init.ets) != 0)
1283 T_FAILED("create_initiation");
1284 T_TIME_END_SINGLE();
1285
1286 T_TIME_START_SINGLE("consume_initiation");
1287 if (noise_consume_initiation(&bl, &r, init.s_idx,
1288 init.ue, init.es, init.ets) != 0)
1289 T_FAILED("consume_initiation");
1290 T_TIME_END_SINGLE();
1291
1292 T_TIME_START_SINGLE("create_response");
1293 if (noise_create_response(&br, &resp.s_idx,
1294 &resp.r_idx, resp.ue, resp.en) != 0)
1295 T_FAILED("create_response");
1296 T_TIME_END_SINGLE();
1297
1298 T_TIME_START_SINGLE("consume_response");
1299 if (noise_consume_response(&ar, resp.s_idx,
1300 resp.r_idx, resp.ue, resp.en) != 0)
1301 T_FAILED("consume_response");
1302 T_TIME_END_SINGLE();
1303
1304 /* Derive keys on both sides */
1305 T_TIME_START_SINGLE("derive_keys");
1306 if (noise_remote_begin_session(&ar) != 0)
1307 T_FAILED("begin_ar");
1308 T_TIME_END_SINGLE();
1309 if (noise_remote_begin_session(&br) != 0)
1310 T_FAILED("begin_br");
1311
1312 /* Small data encryptions */
1313 T_TIME_START(SPEED_ITER, MESSAGE_LEN);
1314 for (i = 0; i < SPEED_ITER; i++) {
1315 if (noise_remote_encrypt(&ar, &index, &nonce,
1316 data, MESSAGE_LEN) != 0)
1317 T_FAILED("encrypt_akp");
1318 }
1319 T_TIME_END(SPEED_ITER, MESSAGE_LEN);
1320
1321
1322 /* Large data encryptions */
1323 T_TIME_START(SPEED_ITER, LARGE_MESSAGE_LEN);
1324 for (i = 0; i < SPEED_ITER; i++) {
1325 if (noise_remote_encrypt(&ar, &index, &nonce,
1326 largedata, LARGE_MESSAGE_LEN) != 0)
1327 T_FAILED("encrypt_akp");
1328 }
1329 T_TIME_END(SPEED_ITER, LARGE_MESSAGE_LEN);
1330 }
1331
1332 void
noise_test()1333 noise_test()
1334 {
1335 noise_counter_test();
1336 noise_handshake_test();
1337 noise_speed_test();
1338 }
1339
1340 #endif /* WGTEST */
1341