2 * Copyright (c) 2020 Doc.ai and/or its affiliates.
3 * Copyright (c) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>.
4 * Copyright (c) 2019-2020 Matt Dunwoodie <ncon@noconroy.net>.
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
18 #include <openssl/hmac.h>
19 #include <wireguard/wireguard.h>
21 /* This implements Noise_IKpsk2:
25 * -> e, es, s, ss, {t}
26 * <- e, ee, se, psk, {}
29 /* Private functions */
30 static noise_keypair_t *noise_remote_keypair_allocate (noise_remote_t *);
31 static void noise_remote_keypair_free (vlib_main_t * vm, noise_remote_t *,
33 static uint32_t noise_remote_handshake_index_get (noise_remote_t *);
34 static void noise_remote_handshake_index_drop (noise_remote_t *);
36 static uint64_t noise_counter_send (noise_counter_t *);
37 static bool noise_counter_recv (noise_counter_t *, uint64_t);
39 static void noise_kdf (uint8_t *, uint8_t *, uint8_t *, const uint8_t *,
40 size_t, size_t, size_t, size_t,
41 const uint8_t[NOISE_HASH_LEN]);
42 static bool noise_mix_dh (uint8_t[NOISE_HASH_LEN],
43 uint8_t[NOISE_SYMMETRIC_KEY_LEN],
44 const uint8_t[NOISE_PUBLIC_KEY_LEN],
45 const uint8_t[NOISE_PUBLIC_KEY_LEN]);
46 static bool noise_mix_ss (uint8_t ck[NOISE_HASH_LEN],
47 uint8_t key[NOISE_SYMMETRIC_KEY_LEN],
48 const uint8_t ss[NOISE_PUBLIC_KEY_LEN]);
49 static void noise_mix_hash (uint8_t[NOISE_HASH_LEN], const uint8_t *, size_t);
50 static void noise_mix_psk (uint8_t[NOISE_HASH_LEN],
51 uint8_t[NOISE_HASH_LEN],
52 uint8_t[NOISE_SYMMETRIC_KEY_LEN],
53 const uint8_t[NOISE_SYMMETRIC_KEY_LEN]);
54 static void noise_param_init (uint8_t[NOISE_HASH_LEN],
55 uint8_t[NOISE_HASH_LEN],
56 const uint8_t[NOISE_PUBLIC_KEY_LEN]);
58 static void noise_msg_encrypt (vlib_main_t * vm, uint8_t *, uint8_t *, size_t,
59 uint32_t key_idx, uint8_t[NOISE_HASH_LEN]);
60 static bool noise_msg_decrypt (vlib_main_t * vm, uint8_t *, uint8_t *, size_t,
61 uint32_t key_idx, uint8_t[NOISE_HASH_LEN]);
62 static void noise_msg_ephemeral (uint8_t[NOISE_HASH_LEN],
63 uint8_t[NOISE_HASH_LEN],
64 const uint8_t src[NOISE_PUBLIC_KEY_LEN]);
66 static void noise_tai64n_now (uint8_t[NOISE_TIMESTAMP_LEN]);
68 static void secure_zero_memory (void *v, size_t n);
70 /* Set/Get noise parameters */
72 noise_local_init (noise_local_t * l, struct noise_upcall *upcall)
74 clib_memset (l, 0, sizeof (*l));
75 l->l_upcall = *upcall;
79 noise_local_set_private (noise_local_t * l,
80 const uint8_t private[NOISE_PUBLIC_KEY_LEN])
82 clib_memcpy (l->l_private, private, NOISE_PUBLIC_KEY_LEN);
83 l->l_has_identity = curve25519_gen_public (l->l_public, private);
85 return l->l_has_identity;
89 noise_local_keys (noise_local_t * l, uint8_t public[NOISE_PUBLIC_KEY_LEN],
90 uint8_t private[NOISE_PUBLIC_KEY_LEN])
92 if (l->l_has_identity)
95 clib_memcpy (public, l->l_public, NOISE_PUBLIC_KEY_LEN);
97 clib_memcpy (private, l->l_private, NOISE_PUBLIC_KEY_LEN);
107 noise_remote_init (noise_remote_t * r, uint32_t peer_pool_idx,
108 const uint8_t public[NOISE_PUBLIC_KEY_LEN],
111 clib_memset (r, 0, sizeof (*r));
112 clib_memcpy (r->r_public, public, NOISE_PUBLIC_KEY_LEN);
113 r->r_peer_idx = peer_pool_idx;
117 r->r_handshake.hs_state = HS_ZEROED;
118 noise_remote_precompute (r);
122 noise_remote_set_psk (noise_remote_t * r,
123 uint8_t psk[NOISE_SYMMETRIC_KEY_LEN])
126 same = !clib_memcmp (r->r_psk, psk, NOISE_SYMMETRIC_KEY_LEN);
129 clib_memcpy (r->r_psk, psk, NOISE_SYMMETRIC_KEY_LEN);
135 noise_remote_keys (noise_remote_t * r, uint8_t public[NOISE_PUBLIC_KEY_LEN],
136 uint8_t psk[NOISE_SYMMETRIC_KEY_LEN])
138 static uint8_t null_psk[NOISE_SYMMETRIC_KEY_LEN];
142 clib_memcpy (public, r->r_public, NOISE_PUBLIC_KEY_LEN);
145 clib_memcpy (psk, r->r_psk, NOISE_SYMMETRIC_KEY_LEN);
146 ret = clib_memcmp (r->r_psk, null_psk, NOISE_SYMMETRIC_KEY_LEN);
152 noise_remote_precompute (noise_remote_t * r)
154 noise_local_t *l = r->r_local;
155 if (!l->l_has_identity)
156 clib_memset (r->r_ss, 0, NOISE_PUBLIC_KEY_LEN);
157 else if (!curve25519_gen_shared (r->r_ss, l->l_private, r->r_public))
158 clib_memset (r->r_ss, 0, NOISE_PUBLIC_KEY_LEN);
160 noise_remote_handshake_index_drop (r);
161 secure_zero_memory (&r->r_handshake, sizeof (r->r_handshake));
164 /* Handshake functions */
166 noise_create_initiation (vlib_main_t * vm, noise_remote_t * r,
167 uint32_t * s_idx, uint8_t ue[NOISE_PUBLIC_KEY_LEN],
168 uint8_t es[NOISE_PUBLIC_KEY_LEN + NOISE_AUTHTAG_LEN],
169 uint8_t ets[NOISE_TIMESTAMP_LEN + NOISE_AUTHTAG_LEN])
171 noise_handshake_t *hs = &r->r_handshake;
172 noise_local_t *l = r->r_local;
173 uint8_t _key[NOISE_SYMMETRIC_KEY_LEN];
179 vnet_crypto_key_add (vm, VNET_CRYPTO_ALG_CHACHA20_POLY1305, _key,
180 NOISE_SYMMETRIC_KEY_LEN);
181 key = vnet_crypto_get_key (key_idx)->data;
183 if (!l->l_has_identity)
185 noise_param_init (hs->hs_ck, hs->hs_hash, r->r_public);
188 curve25519_gen_secret (hs->hs_e);
189 if (!curve25519_gen_public (ue, hs->hs_e))
191 noise_msg_ephemeral (hs->hs_ck, hs->hs_hash, ue);
194 if (!noise_mix_dh (hs->hs_ck, key, hs->hs_e, r->r_public))
198 noise_msg_encrypt (vm, es, l->l_public, NOISE_PUBLIC_KEY_LEN, key_idx,
202 if (!noise_mix_ss (hs->hs_ck, key, r->r_ss))
206 noise_tai64n_now (ets);
207 noise_msg_encrypt (vm, ets, ets, NOISE_TIMESTAMP_LEN, key_idx, hs->hs_hash);
208 noise_remote_handshake_index_drop (r);
209 hs->hs_state = CREATED_INITIATION;
210 hs->hs_local_index = noise_remote_handshake_index_get (r);
211 *s_idx = hs->hs_local_index;
214 vnet_crypto_key_del (vm, key_idx);
215 secure_zero_memory (key, NOISE_SYMMETRIC_KEY_LEN);
220 noise_consume_initiation (vlib_main_t * vm, noise_local_t * l,
221 noise_remote_t ** rp, uint32_t s_idx,
222 uint8_t ue[NOISE_PUBLIC_KEY_LEN],
223 uint8_t es[NOISE_PUBLIC_KEY_LEN +
225 uint8_t ets[NOISE_TIMESTAMP_LEN +
229 noise_handshake_t hs;
230 uint8_t _key[NOISE_SYMMETRIC_KEY_LEN];
231 uint8_t r_public[NOISE_PUBLIC_KEY_LEN];
232 uint8_t timestamp[NOISE_TIMESTAMP_LEN];
238 vnet_crypto_key_add (vm, VNET_CRYPTO_ALG_CHACHA20_POLY1305, _key,
239 NOISE_SYMMETRIC_KEY_LEN);
240 key = vnet_crypto_get_key (key_idx)->data;
242 if (!l->l_has_identity)
244 noise_param_init (hs.hs_ck, hs.hs_hash, l->l_public);
247 noise_msg_ephemeral (hs.hs_ck, hs.hs_hash, ue);
250 if (!noise_mix_dh (hs.hs_ck, key, l->l_private, ue))
255 if (!noise_msg_decrypt (vm, r_public, es,
256 NOISE_PUBLIC_KEY_LEN + NOISE_AUTHTAG_LEN, key_idx,
260 /* Lookup the remote we received from */
261 if ((r = l->l_upcall.u_remote_get (r_public)) == NULL)
265 if (!noise_mix_ss (hs.hs_ck, key, r->r_ss))
269 if (!noise_msg_decrypt (vm, timestamp, ets,
270 NOISE_TIMESTAMP_LEN + NOISE_AUTHTAG_LEN, key_idx,
275 hs.hs_state = CONSUMED_INITIATION;
276 hs.hs_local_index = 0;
277 hs.hs_remote_index = s_idx;
278 clib_memcpy (hs.hs_e, ue, NOISE_PUBLIC_KEY_LEN);
281 if (clib_memcmp (timestamp, r->r_timestamp, NOISE_TIMESTAMP_LEN) > 0)
282 clib_memcpy (r->r_timestamp, timestamp, NOISE_TIMESTAMP_LEN);
287 if (wg_birthdate_has_expired (r->r_last_init, REJECT_INTERVAL))
288 r->r_last_init = vlib_time_now (vm);
292 /* Ok, we're happy to accept this initiation now */
293 noise_remote_handshake_index_drop (r);
298 vnet_crypto_key_del (vm, key_idx);
299 secure_zero_memory (key, NOISE_SYMMETRIC_KEY_LEN);
300 secure_zero_memory (&hs, sizeof (hs));
305 noise_create_response (vlib_main_t * vm, noise_remote_t * r, uint32_t * s_idx,
306 uint32_t * r_idx, uint8_t ue[NOISE_PUBLIC_KEY_LEN],
307 uint8_t en[0 + NOISE_AUTHTAG_LEN])
309 noise_handshake_t *hs = &r->r_handshake;
310 uint8_t _key[NOISE_SYMMETRIC_KEY_LEN];
311 uint8_t e[NOISE_PUBLIC_KEY_LEN];
317 vnet_crypto_key_add (vm, VNET_CRYPTO_ALG_CHACHA20_POLY1305, _key,
318 NOISE_SYMMETRIC_KEY_LEN);
319 key = vnet_crypto_get_key (key_idx)->data;
321 if (hs->hs_state != CONSUMED_INITIATION)
325 curve25519_gen_secret (e);
326 if (!curve25519_gen_public (ue, e))
328 noise_msg_ephemeral (hs->hs_ck, hs->hs_hash, ue);
331 if (!noise_mix_dh (hs->hs_ck, NULL, e, hs->hs_e))
335 if (!noise_mix_dh (hs->hs_ck, NULL, e, r->r_public))
339 noise_mix_psk (hs->hs_ck, hs->hs_hash, key, r->r_psk);
342 noise_msg_encrypt (vm, en, NULL, 0, key_idx, hs->hs_hash);
345 hs->hs_state = CREATED_RESPONSE;
346 hs->hs_local_index = noise_remote_handshake_index_get (r);
347 *r_idx = hs->hs_remote_index;
348 *s_idx = hs->hs_local_index;
351 vnet_crypto_key_del (vm, key_idx);
352 secure_zero_memory (key, NOISE_SYMMETRIC_KEY_LEN);
353 secure_zero_memory (e, NOISE_PUBLIC_KEY_LEN);
358 noise_consume_response (vlib_main_t * vm, noise_remote_t * r, uint32_t s_idx,
359 uint32_t r_idx, uint8_t ue[NOISE_PUBLIC_KEY_LEN],
360 uint8_t en[0 + NOISE_AUTHTAG_LEN])
362 noise_local_t *l = r->r_local;
363 noise_handshake_t hs;
364 uint8_t _key[NOISE_SYMMETRIC_KEY_LEN];
365 uint8_t preshared_key[NOISE_PUBLIC_KEY_LEN];
371 vnet_crypto_key_add (vm, VNET_CRYPTO_ALG_CHACHA20_POLY1305, _key,
372 NOISE_SYMMETRIC_KEY_LEN);
373 key = vnet_crypto_get_key (key_idx)->data;
375 if (!l->l_has_identity)
379 clib_memcpy (preshared_key, r->r_psk, NOISE_SYMMETRIC_KEY_LEN);
381 if (hs.hs_state != CREATED_INITIATION || hs.hs_local_index != r_idx)
385 noise_msg_ephemeral (hs.hs_ck, hs.hs_hash, ue);
388 if (!noise_mix_dh (hs.hs_ck, NULL, hs.hs_e, ue))
392 if (!noise_mix_dh (hs.hs_ck, NULL, l->l_private, ue))
396 noise_mix_psk (hs.hs_ck, hs.hs_hash, key, preshared_key);
400 if (!noise_msg_decrypt
401 (vm, NULL, en, 0 + NOISE_AUTHTAG_LEN, key_idx, hs.hs_hash))
405 hs.hs_remote_index = s_idx;
407 if (r->r_handshake.hs_state == hs.hs_state &&
408 r->r_handshake.hs_local_index == hs.hs_local_index)
411 r->r_handshake.hs_state = CONSUMED_RESPONSE;
415 vnet_crypto_key_del (vm, key_idx);
416 secure_zero_memory (&hs, sizeof (hs));
417 secure_zero_memory (key, NOISE_SYMMETRIC_KEY_LEN);
422 noise_remote_begin_session (vlib_main_t * vm, noise_remote_t * r)
424 noise_handshake_t *hs = &r->r_handshake;
425 noise_keypair_t kp, *next, *current, *previous;
427 uint8_t key_send[NOISE_SYMMETRIC_KEY_LEN];
428 uint8_t key_recv[NOISE_SYMMETRIC_KEY_LEN];
430 /* We now derive the keypair from the handshake */
431 if (hs->hs_state == CONSUMED_RESPONSE)
433 kp.kp_is_initiator = 1;
434 noise_kdf (key_send, key_recv, NULL, NULL,
435 NOISE_SYMMETRIC_KEY_LEN, NOISE_SYMMETRIC_KEY_LEN, 0, 0,
438 else if (hs->hs_state == CREATED_RESPONSE)
440 kp.kp_is_initiator = 0;
441 noise_kdf (key_recv, key_send, NULL, NULL,
442 NOISE_SYMMETRIC_KEY_LEN, NOISE_SYMMETRIC_KEY_LEN, 0, 0,
451 kp.kp_send_index = vnet_crypto_key_add (vm,
452 VNET_CRYPTO_ALG_CHACHA20_POLY1305,
453 key_send, NOISE_SYMMETRIC_KEY_LEN);
454 kp.kp_recv_index = vnet_crypto_key_add (vm,
455 VNET_CRYPTO_ALG_CHACHA20_POLY1305,
456 key_recv, NOISE_SYMMETRIC_KEY_LEN);
457 kp.kp_local_index = hs->hs_local_index;
458 kp.kp_remote_index = hs->hs_remote_index;
459 kp.kp_birthdate = vlib_time_now (vm);
460 clib_memset (&kp.kp_ctr, 0, sizeof (kp.kp_ctr));
462 /* Now we need to add_new_keypair */
464 current = r->r_current;
465 previous = r->r_previous;
467 if (kp.kp_is_initiator)
472 r->r_previous = next;
473 noise_remote_keypair_free (vm, r, ¤t);
477 r->r_previous = current;
480 noise_remote_keypair_free (vm, r, &previous);
482 r->r_current = noise_remote_keypair_allocate (r);
487 noise_remote_keypair_free (vm, r, &next);
488 r->r_previous = NULL;
489 noise_remote_keypair_free (vm, r, &previous);
491 r->r_next = noise_remote_keypair_allocate (r);
494 secure_zero_memory (&r->r_handshake, sizeof (r->r_handshake));
495 secure_zero_memory (&kp, sizeof (kp));
500 noise_remote_clear (vlib_main_t * vm, noise_remote_t * r)
502 noise_remote_handshake_index_drop (r);
503 secure_zero_memory (&r->r_handshake, sizeof (r->r_handshake));
505 noise_remote_keypair_free (vm, r, &r->r_next);
506 noise_remote_keypair_free (vm, r, &r->r_current);
507 noise_remote_keypair_free (vm, r, &r->r_previous);
510 r->r_previous = NULL;
514 noise_remote_expire_current (noise_remote_t * r)
516 if (r->r_next != NULL)
517 r->r_next->kp_valid = 0;
518 if (r->r_current != NULL)
519 r->r_current->kp_valid = 0;
523 noise_remote_ready (noise_remote_t * r)
528 if ((kp = r->r_current) == NULL ||
530 wg_birthdate_has_expired (kp->kp_birthdate, REJECT_AFTER_TIME) ||
531 kp->kp_ctr.c_recv >= REJECT_AFTER_MESSAGES ||
532 kp->kp_ctr.c_send >= REJECT_AFTER_MESSAGES)
540 chacha20poly1305_calc (vlib_main_t * vm,
547 vnet_crypto_op_id_t op_id,
548 vnet_crypto_key_index_t key_index)
550 vnet_crypto_op_t _op, *op = &_op;
552 u8 tag_[NOISE_AUTHTAG_LEN] = { };
555 clib_memset (iv, 0, 12);
556 clib_memcpy (iv + 4, &nonce, sizeof (nonce));
558 vnet_crypto_op_init (op, op_id);
560 op->tag_len = NOISE_AUTHTAG_LEN;
561 if (op_id == VNET_CRYPTO_OP_CHACHA20_POLY1305_DEC)
563 op->tag = src + src_len - NOISE_AUTHTAG_LEN;
564 src_len -= NOISE_AUTHTAG_LEN;
569 op->src = !src ? src_ : src;
573 op->key_index = key_index;
575 op->aad_len = aad_len;
578 vnet_crypto_process_ops (vm, op, 1);
579 if (op_id == VNET_CRYPTO_OP_CHACHA20_POLY1305_ENC)
581 clib_memcpy (dst + src_len, op->tag, NOISE_AUTHTAG_LEN);
585 enum noise_state_crypt
586 noise_remote_encrypt (vlib_main_t * vm, noise_remote_t * r, uint32_t * r_idx,
587 uint64_t * nonce, uint8_t * src, size_t srclen,
591 enum noise_state_crypt ret = SC_FAILED;
593 if ((kp = r->r_current) == NULL)
596 /* We confirm that our values are within our tolerances. We want:
598 * - our keypair to be less than REJECT_AFTER_TIME seconds old
599 * - our receive counter to be less than REJECT_AFTER_MESSAGES
600 * - our send counter to be less than REJECT_AFTER_MESSAGES
603 wg_birthdate_has_expired (kp->kp_birthdate, REJECT_AFTER_TIME) ||
604 kp->kp_ctr.c_recv >= REJECT_AFTER_MESSAGES ||
605 ((*nonce = noise_counter_send (&kp->kp_ctr)) > REJECT_AFTER_MESSAGES))
608 /* We encrypt into the same buffer, so the caller must ensure that buf
609 * has NOISE_AUTHTAG_LEN bytes to store the MAC. The nonce and index
610 * are passed back out to the caller through the provided data pointer. */
611 *r_idx = kp->kp_remote_index;
613 chacha20poly1305_calc (vm, src, srclen, dst, NULL, 0, *nonce,
614 VNET_CRYPTO_OP_CHACHA20_POLY1305_ENC,
617 /* If our values are still within tolerances, but we are approaching
618 * the tolerances, we notify the caller with ESTALE that they should
619 * establish a new keypair. The current keypair can continue to be used
620 * until the tolerances are hit. We notify if:
621 * - our send counter is valid and not less than REKEY_AFTER_MESSAGES
622 * - we're the initiator and our keypair is older than
623 * REKEY_AFTER_TIME seconds */
624 ret = SC_KEEP_KEY_FRESH;
625 if ((kp->kp_valid && *nonce >= REKEY_AFTER_MESSAGES) ||
626 (kp->kp_is_initiator &&
627 wg_birthdate_has_expired (kp->kp_birthdate, REKEY_AFTER_TIME)))
635 enum noise_state_crypt
636 noise_remote_decrypt (vlib_main_t * vm, noise_remote_t * r, uint32_t r_idx,
637 uint64_t nonce, uint8_t * src, size_t srclen,
641 enum noise_state_crypt ret = SC_FAILED;
643 if (r->r_current != NULL && r->r_current->kp_local_index == r_idx)
647 else if (r->r_previous != NULL && r->r_previous->kp_local_index == r_idx)
651 else if (r->r_next != NULL && r->r_next->kp_local_index == r_idx)
660 /* We confirm that our values are within our tolerances. These values
661 * are the same as the encrypt routine.
663 * kp_ctr isn't locked here, we're happy to accept a racy read. */
664 if (wg_birthdate_has_expired (kp->kp_birthdate, REJECT_AFTER_TIME) ||
665 kp->kp_ctr.c_recv >= REJECT_AFTER_MESSAGES)
668 /* Decrypt, then validate the counter. We don't want to validate the
669 * counter before decrypting as we do not know the message is authentic
670 * prior to decryption. */
671 chacha20poly1305_calc (vm, src, srclen, dst, NULL, 0, nonce,
672 VNET_CRYPTO_OP_CHACHA20_POLY1305_DEC,
675 if (!noise_counter_recv (&kp->kp_ctr, nonce))
678 /* If we've received the handshake confirming data packet then move the
679 * next keypair into current. If we do slide the next keypair in, then
680 * we skip the REKEY_AFTER_TIME_RECV check. This is safe to do as a
681 * data packet can't confirm a session that we are an INITIATOR of. */
682 if (kp == r->r_next && kp->kp_local_index == r_idx)
684 noise_remote_keypair_free (vm, r, &r->r_previous);
685 r->r_previous = r->r_current;
686 r->r_current = r->r_next;
694 /* Similar to when we encrypt, we want to notify the caller when we
695 * are approaching our tolerances. We notify if:
696 * - we're the initiator and the current keypair is older than
697 * REKEY_AFTER_TIME_RECV seconds. */
698 ret = SC_KEEP_KEY_FRESH;
702 kp->kp_is_initiator &&
703 wg_birthdate_has_expired (kp->kp_birthdate, REKEY_AFTER_TIME_RECV))
711 /* Private functions - these should not be called outside this file under any
713 static noise_keypair_t *
714 noise_remote_keypair_allocate (noise_remote_t * r)
717 kp = clib_mem_alloc (sizeof (*kp));
722 noise_remote_keypair_free (vlib_main_t * vm, noise_remote_t * r,
723 noise_keypair_t ** kp)
725 struct noise_upcall *u = &r->r_local->l_upcall;
728 u->u_index_drop ((*kp)->kp_local_index);
729 vnet_crypto_key_del (vm, (*kp)->kp_send_index);
730 vnet_crypto_key_del (vm, (*kp)->kp_recv_index);
736 noise_remote_handshake_index_get (noise_remote_t * r)
738 struct noise_upcall *u = &r->r_local->l_upcall;
739 return u->u_index_set (r);
743 noise_remote_handshake_index_drop (noise_remote_t * r)
745 noise_handshake_t *hs = &r->r_handshake;
746 struct noise_upcall *u = &r->r_local->l_upcall;
747 if (hs->hs_state != HS_ZEROED)
748 u->u_index_drop (hs->hs_local_index);
752 noise_counter_send (noise_counter_t * ctr)
754 uint64_t ret = ctr->c_send++;
759 noise_counter_recv (noise_counter_t * ctr, uint64_t recv)
761 uint64_t i, top, index_recv, index_ctr;
766 /* Check that the recv counter is valid */
767 if (ctr->c_recv >= REJECT_AFTER_MESSAGES || recv >= REJECT_AFTER_MESSAGES)
770 /* If the packet is out of the window, invalid */
771 if (recv + COUNTER_WINDOW_SIZE < ctr->c_recv)
774 /* If the new counter is ahead of the current counter, we'll need to
775 * zero out the bitmap that has previously been used */
776 index_recv = recv / COUNTER_BITS;
777 index_ctr = ctr->c_recv / COUNTER_BITS;
779 if (recv > ctr->c_recv)
781 top = clib_min (index_recv - index_ctr, COUNTER_NUM);
782 for (i = 1; i <= top; i++)
783 ctr->c_backtrack[(i + index_ctr) & (COUNTER_NUM - 1)] = 0;
787 index_recv %= COUNTER_NUM;
788 bit = 1ul << (recv % COUNTER_BITS);
790 if (ctr->c_backtrack[index_recv] & bit)
793 ctr->c_backtrack[index_recv] |= bit;
801 noise_kdf (uint8_t * a, uint8_t * b, uint8_t * c, const uint8_t * x,
802 size_t a_len, size_t b_len, size_t c_len, size_t x_len,
803 const uint8_t ck[NOISE_HASH_LEN])
805 uint8_t out[BLAKE2S_HASH_SIZE + 1];
806 uint8_t sec[BLAKE2S_HASH_SIZE];
808 /* Extract entropy from "x" into sec */
810 HMAC (EVP_blake2s256 (), ck, NOISE_HASH_LEN, x, x_len, sec, &l);
811 ASSERT (l == BLAKE2S_HASH_SIZE);
812 if (a == NULL || a_len == 0)
815 /* Expand first key: key = sec, data = 0x1 */
817 HMAC (EVP_blake2s256 (), sec, BLAKE2S_HASH_SIZE, out, 1, out, &l);
818 ASSERT (l == BLAKE2S_HASH_SIZE);
819 clib_memcpy (a, out, a_len);
821 if (b == NULL || b_len == 0)
824 /* Expand second key: key = sec, data = "a" || 0x2 */
825 out[BLAKE2S_HASH_SIZE] = 2;
826 HMAC (EVP_blake2s256 (), sec, BLAKE2S_HASH_SIZE, out, BLAKE2S_HASH_SIZE + 1,
828 ASSERT (l == BLAKE2S_HASH_SIZE);
829 clib_memcpy (b, out, b_len);
831 if (c == NULL || c_len == 0)
834 /* Expand third key: key = sec, data = "b" || 0x3 */
835 out[BLAKE2S_HASH_SIZE] = 3;
836 HMAC (EVP_blake2s256 (), sec, BLAKE2S_HASH_SIZE, out, BLAKE2S_HASH_SIZE + 1,
838 ASSERT (l == BLAKE2S_HASH_SIZE);
840 clib_memcpy (c, out, c_len);
843 /* Clear sensitive data from stack */
844 secure_zero_memory (sec, BLAKE2S_HASH_SIZE);
845 secure_zero_memory (out, BLAKE2S_HASH_SIZE + 1);
849 noise_mix_dh (uint8_t ck[NOISE_HASH_LEN],
850 uint8_t key[NOISE_SYMMETRIC_KEY_LEN],
851 const uint8_t private[NOISE_PUBLIC_KEY_LEN],
852 const uint8_t public[NOISE_PUBLIC_KEY_LEN])
854 uint8_t dh[NOISE_PUBLIC_KEY_LEN];
855 if (!curve25519_gen_shared (dh, private, public))
857 noise_kdf (ck, key, NULL, dh,
858 NOISE_HASH_LEN, NOISE_SYMMETRIC_KEY_LEN, 0, NOISE_PUBLIC_KEY_LEN,
860 secure_zero_memory (dh, NOISE_PUBLIC_KEY_LEN);
865 noise_mix_ss (uint8_t ck[NOISE_HASH_LEN],
866 uint8_t key[NOISE_SYMMETRIC_KEY_LEN],
867 const uint8_t ss[NOISE_PUBLIC_KEY_LEN])
869 static uint8_t null_point[NOISE_PUBLIC_KEY_LEN];
870 if (clib_memcmp (ss, null_point, NOISE_PUBLIC_KEY_LEN) == 0)
872 noise_kdf (ck, key, NULL, ss,
873 NOISE_HASH_LEN, NOISE_SYMMETRIC_KEY_LEN, 0, NOISE_PUBLIC_KEY_LEN,
879 noise_mix_hash (uint8_t hash[NOISE_HASH_LEN], const uint8_t * src,
882 blake2s_state_t blake;
884 blake2s_init (&blake, NOISE_HASH_LEN);
885 blake2s_update (&blake, hash, NOISE_HASH_LEN);
886 blake2s_update (&blake, src, src_len);
887 blake2s_final (&blake, hash, NOISE_HASH_LEN);
891 noise_mix_psk (uint8_t ck[NOISE_HASH_LEN], uint8_t hash[NOISE_HASH_LEN],
892 uint8_t key[NOISE_SYMMETRIC_KEY_LEN],
893 const uint8_t psk[NOISE_SYMMETRIC_KEY_LEN])
895 uint8_t tmp[NOISE_HASH_LEN];
897 noise_kdf (ck, tmp, key, psk,
898 NOISE_HASH_LEN, NOISE_HASH_LEN, NOISE_SYMMETRIC_KEY_LEN,
899 NOISE_SYMMETRIC_KEY_LEN, ck);
900 noise_mix_hash (hash, tmp, NOISE_HASH_LEN);
901 secure_zero_memory (tmp, NOISE_HASH_LEN);
905 noise_param_init (uint8_t ck[NOISE_HASH_LEN], uint8_t hash[NOISE_HASH_LEN],
906 const uint8_t s[NOISE_PUBLIC_KEY_LEN])
908 blake2s_state_t blake;
910 blake2s (ck, NOISE_HASH_LEN, (uint8_t *) NOISE_HANDSHAKE_NAME,
911 strlen (NOISE_HANDSHAKE_NAME), NULL, 0);
913 blake2s_init (&blake, NOISE_HASH_LEN);
914 blake2s_update (&blake, ck, NOISE_HASH_LEN);
915 blake2s_update (&blake, (uint8_t *) NOISE_IDENTIFIER_NAME,
916 strlen (NOISE_IDENTIFIER_NAME));
917 blake2s_final (&blake, hash, NOISE_HASH_LEN);
919 noise_mix_hash (hash, s, NOISE_PUBLIC_KEY_LEN);
923 noise_msg_encrypt (vlib_main_t * vm, uint8_t * dst, uint8_t * src,
924 size_t src_len, uint32_t key_idx,
925 uint8_t hash[NOISE_HASH_LEN])
927 /* Nonce always zero for Noise_IK */
928 chacha20poly1305_calc (vm, src, src_len, dst, hash, NOISE_HASH_LEN, 0,
929 VNET_CRYPTO_OP_CHACHA20_POLY1305_ENC, key_idx);
930 noise_mix_hash (hash, dst, src_len + NOISE_AUTHTAG_LEN);
934 noise_msg_decrypt (vlib_main_t * vm, uint8_t * dst, uint8_t * src,
935 size_t src_len, uint32_t key_idx,
936 uint8_t hash[NOISE_HASH_LEN])
938 /* Nonce always zero for Noise_IK */
939 chacha20poly1305_calc (vm, src, src_len, dst, hash, NOISE_HASH_LEN, 0,
940 VNET_CRYPTO_OP_CHACHA20_POLY1305_DEC, key_idx);
941 noise_mix_hash (hash, src, src_len);
946 noise_msg_ephemeral (uint8_t ck[NOISE_HASH_LEN], uint8_t hash[NOISE_HASH_LEN],
947 const uint8_t src[NOISE_PUBLIC_KEY_LEN])
949 noise_mix_hash (hash, src, NOISE_PUBLIC_KEY_LEN);
950 noise_kdf (ck, NULL, NULL, src, NOISE_HASH_LEN, 0, 0,
951 NOISE_PUBLIC_KEY_LEN, ck);
955 noise_tai64n_now (uint8_t output[NOISE_TIMESTAMP_LEN])
958 uint32_t unix_nanosec;
963 unix_time_now_nsec_fraction (&unix_sec, &unix_nanosec);
965 /* Round down the nsec counter to limit precise timing leak. */
966 unix_nanosec &= REJECT_INTERVAL_MASK;
968 /* https://cr.yp.to/libtai/tai64.html */
969 sec = htobe64 (0x400000000000000aULL + unix_sec);
970 nsec = htobe32 (unix_nanosec);
972 /* memcpy to output buffer, assuming output could be unaligned. */
973 clib_memcpy (output, &sec, sizeof (sec));
974 clib_memcpy (output + sizeof (sec), &nsec, sizeof (nsec));
978 secure_zero_memory (void *v, size_t n)
980 static void *(*const volatile memset_v) (void *, int, size_t) = &memset;
985 * fd.io coding-style-patch-verification: ON
988 * eval: (c-set-style "gnu")