FD.io VPP  v21.10.1-2-g0a485f517
Vector Packet Processing
wireguard_noise.c
Go to the documentation of this file.
1 /*
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:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
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.
16  */
17 
18 #include <openssl/hmac.h>
19 #include <wireguard/wireguard.h>
20 
21 /* This implements Noise_IKpsk2:
22  *
23  * <- s
24  * ******
25  * -> e, es, s, ss, {t}
26  * <- e, ee, se, psk, {}
27  */
28 
30 
31 /* Private functions */
34  noise_keypair_t **);
37 
38 static uint64_t noise_counter_send (noise_counter_t *);
39 static bool noise_counter_recv (noise_counter_t *, uint64_t);
40 
41 static void noise_kdf (uint8_t *, uint8_t *, uint8_t *, const uint8_t *,
42  size_t, size_t, size_t, size_t,
43  const uint8_t[NOISE_HASH_LEN]);
44 static bool noise_mix_dh (uint8_t[NOISE_HASH_LEN],
45  uint8_t[NOISE_SYMMETRIC_KEY_LEN],
46  const uint8_t[NOISE_PUBLIC_KEY_LEN],
47  const uint8_t[NOISE_PUBLIC_KEY_LEN]);
48 static bool noise_mix_ss (uint8_t ck[NOISE_HASH_LEN],
50  const uint8_t ss[NOISE_PUBLIC_KEY_LEN]);
51 static void noise_mix_hash (uint8_t[NOISE_HASH_LEN], const uint8_t *, size_t);
52 static void noise_mix_psk (uint8_t[NOISE_HASH_LEN],
53  uint8_t[NOISE_HASH_LEN],
54  uint8_t[NOISE_SYMMETRIC_KEY_LEN],
55  const uint8_t[NOISE_SYMMETRIC_KEY_LEN]);
56 static void noise_param_init (uint8_t[NOISE_HASH_LEN],
57  uint8_t[NOISE_HASH_LEN],
58  const uint8_t[NOISE_PUBLIC_KEY_LEN]);
59 
60 static void noise_msg_encrypt (vlib_main_t * vm, uint8_t *, uint8_t *, size_t,
61  uint32_t key_idx, uint8_t[NOISE_HASH_LEN]);
62 static bool noise_msg_decrypt (vlib_main_t * vm, uint8_t *, uint8_t *, size_t,
63  uint32_t key_idx, uint8_t[NOISE_HASH_LEN]);
64 static void noise_msg_ephemeral (uint8_t[NOISE_HASH_LEN],
65  uint8_t[NOISE_HASH_LEN],
66  const uint8_t src[NOISE_PUBLIC_KEY_LEN]);
67 
68 static void noise_tai64n_now (uint8_t[NOISE_TIMESTAMP_LEN]);
69 
70 static void secure_zero_memory (void *v, size_t n);
71 
72 /* Set/Get noise parameters */
73 void
74 noise_local_init (noise_local_t * l, struct noise_upcall *upcall)
75 {
76  clib_memset (l, 0, sizeof (*l));
77  l->l_upcall = *upcall;
78 }
79 
80 bool
82  const uint8_t private[NOISE_PUBLIC_KEY_LEN])
83 {
85 
86  return curve25519_gen_public (l->l_public, private);
87 }
88 
89 void
90 noise_remote_init (noise_remote_t * r, uint32_t peer_pool_idx,
91  const uint8_t public[NOISE_PUBLIC_KEY_LEN],
92  u32 noise_local_idx)
93 {
94  clib_memset (r, 0, sizeof (*r));
95  clib_memcpy (r->r_public, public, NOISE_PUBLIC_KEY_LEN);
96  clib_rwlock_init (&r->r_keypair_lock);
97  r->r_peer_idx = peer_pool_idx;
98  r->r_local_idx = noise_local_idx;
99  r->r_handshake.hs_state = HS_ZEROED;
100 
102 }
103 
104 void
106 {
107  noise_local_t *l = noise_local_get (r->r_local_idx);
108 
109  if (!curve25519_gen_shared (r->r_ss, l->l_private, r->r_public))
110  clib_memset (r->r_ss, 0, NOISE_PUBLIC_KEY_LEN);
111 
113  secure_zero_memory (&r->r_handshake, sizeof (r->r_handshake));
114 }
115 
116 /* Handshake functions */
117 bool
119  uint32_t * s_idx, uint8_t ue[NOISE_PUBLIC_KEY_LEN],
121  uint8_t ets[NOISE_TIMESTAMP_LEN + NOISE_AUTHTAG_LEN])
122 {
123  noise_handshake_t *hs = &r->r_handshake;
124  noise_local_t *l = noise_local_get (r->r_local_idx);
125  uint8_t _key[NOISE_SYMMETRIC_KEY_LEN];
126  uint32_t key_idx;
127  uint8_t *key;
128  int ret = false;
129 
130  key_idx =
131  vnet_crypto_key_add (vm, VNET_CRYPTO_ALG_CHACHA20_POLY1305, _key,
133  key = vnet_crypto_get_key (key_idx)->data;
134 
135  noise_param_init (hs->hs_ck, hs->hs_hash, r->r_public);
136 
137  /* e */
139  if (!curve25519_gen_public (ue, hs->hs_e))
140  goto error;
141  noise_msg_ephemeral (hs->hs_ck, hs->hs_hash, ue);
142 
143  /* es */
144  if (!noise_mix_dh (hs->hs_ck, key, hs->hs_e, r->r_public))
145  goto error;
146 
147  /* s */
149  hs->hs_hash);
150 
151  /* ss */
152  if (!noise_mix_ss (hs->hs_ck, key, r->r_ss))
153  goto error;
154 
155  /* {t} */
156  noise_tai64n_now (ets);
157  noise_msg_encrypt (vm, ets, ets, NOISE_TIMESTAMP_LEN, key_idx, hs->hs_hash);
161  *s_idx = hs->hs_local_index;
162  ret = true;
163 error:
165  vnet_crypto_key_del (vm, key_idx);
166  return ret;
167 }
168 
169 bool
171  noise_remote_t ** rp, uint32_t s_idx,
172  uint8_t ue[NOISE_PUBLIC_KEY_LEN],
173  uint8_t es[NOISE_PUBLIC_KEY_LEN +
175  uint8_t ets[NOISE_TIMESTAMP_LEN +
177 {
178  noise_remote_t *r;
180  uint8_t _key[NOISE_SYMMETRIC_KEY_LEN];
181  uint8_t r_public[NOISE_PUBLIC_KEY_LEN];
183  u32 key_idx;
184  uint8_t *key;
185  int ret = false;
186 
187  key_idx =
188  vnet_crypto_key_add (vm, VNET_CRYPTO_ALG_CHACHA20_POLY1305, _key,
190  key = vnet_crypto_get_key (key_idx)->data;
191 
192  noise_param_init (hs.hs_ck, hs.hs_hash, l->l_public);
193 
194  /* e */
195  noise_msg_ephemeral (hs.hs_ck, hs.hs_hash, ue);
196 
197  /* es */
198  if (!noise_mix_dh (hs.hs_ck, key, l->l_private, ue))
199  goto error;
200 
201  /* s */
202 
203  if (!noise_msg_decrypt (vm, r_public, es,
205  hs.hs_hash))
206  goto error;
207 
208  /* Lookup the remote we received from */
209  if ((r = l->l_upcall.u_remote_get (r_public)) == NULL)
210  goto error;
211 
212  /* ss */
213  if (!noise_mix_ss (hs.hs_ck, key, r->r_ss))
214  goto error;
215 
216  /* {t} */
217  if (!noise_msg_decrypt (vm, timestamp, ets,
219  hs.hs_hash))
220  goto error;
221  ;
222 
224  hs.hs_local_index = 0;
225  hs.hs_remote_index = s_idx;
227 
228  /* Replay */
229  if (clib_memcmp (timestamp, r->r_timestamp, NOISE_TIMESTAMP_LEN) > 0)
230  clib_memcpy (r->r_timestamp, timestamp, NOISE_TIMESTAMP_LEN);
231  else
232  goto error;
233 
234  /* Flood attack */
235  if (wg_birthdate_has_expired (r->r_last_init, REJECT_INTERVAL))
236  r->r_last_init = vlib_time_now (vm);
237  else
238  goto error;
239 
240  /* Ok, we're happy to accept this initiation now */
242  r->r_handshake = hs;
243  *rp = r;
244  ret = true;
245 
246 error:
248  vnet_crypto_key_del (vm, key_idx);
249  secure_zero_memory (&hs, sizeof (hs));
250  return ret;
251 }
252 
253 bool
255  uint32_t * r_idx, uint8_t ue[NOISE_PUBLIC_KEY_LEN],
256  uint8_t en[0 + NOISE_AUTHTAG_LEN])
257 {
258  noise_handshake_t *hs = &r->r_handshake;
259  uint8_t _key[NOISE_SYMMETRIC_KEY_LEN];
260  uint8_t e[NOISE_PUBLIC_KEY_LEN];
261  uint32_t key_idx;
262  uint8_t *key;
263  int ret = false;
264 
265  key_idx =
266  vnet_crypto_key_add (vm, VNET_CRYPTO_ALG_CHACHA20_POLY1305, _key,
268  key = vnet_crypto_get_key (key_idx)->data;
269 
270  if (hs->hs_state != CONSUMED_INITIATION)
271  goto error;
272 
273  /* e */
275  if (!curve25519_gen_public (ue, e))
276  goto error;
277  noise_msg_ephemeral (hs->hs_ck, hs->hs_hash, ue);
278 
279  /* ee */
280  if (!noise_mix_dh (hs->hs_ck, NULL, e, hs->hs_e))
281  goto error;
282 
283  /* se */
284  if (!noise_mix_dh (hs->hs_ck, NULL, e, r->r_public))
285  goto error;
286 
287  /* psk */
288  noise_mix_psk (hs->hs_ck, hs->hs_hash, key, r->r_psk);
289 
290  /* {} */
291  noise_msg_encrypt (vm, en, NULL, 0, key_idx, hs->hs_hash);
292 
293 
296  *r_idx = hs->hs_remote_index;
297  *s_idx = hs->hs_local_index;
298  ret = true;
299 error:
301  vnet_crypto_key_del (vm, key_idx);
303  return ret;
304 }
305 
306 bool
308  uint32_t r_idx, uint8_t ue[NOISE_PUBLIC_KEY_LEN],
309  uint8_t en[0 + NOISE_AUTHTAG_LEN])
310 {
311  noise_local_t *l = noise_local_get (r->r_local_idx);
313  uint8_t _key[NOISE_SYMMETRIC_KEY_LEN];
314  uint8_t preshared_key[NOISE_PUBLIC_KEY_LEN];
315  uint32_t key_idx;
316  uint8_t *key;
317  int ret = false;
318 
319  key_idx =
320  vnet_crypto_key_add (vm, VNET_CRYPTO_ALG_CHACHA20_POLY1305, _key,
322  key = vnet_crypto_get_key (key_idx)->data;
323 
324  hs = r->r_handshake;
325  clib_memcpy (preshared_key, r->r_psk, NOISE_SYMMETRIC_KEY_LEN);
326 
327  if (hs.hs_state != CREATED_INITIATION || hs.hs_local_index != r_idx)
328  goto error;
329 
330  /* e */
331  noise_msg_ephemeral (hs.hs_ck, hs.hs_hash, ue);
332 
333  /* ee */
334  if (!noise_mix_dh (hs.hs_ck, NULL, hs.hs_e, ue))
335  goto error;
336 
337  /* se */
338  if (!noise_mix_dh (hs.hs_ck, NULL, l->l_private, ue))
339  goto error;
340 
341  /* psk */
342  noise_mix_psk (hs.hs_ck, hs.hs_hash, key, preshared_key);
343 
344  /* {} */
345 
346  if (!noise_msg_decrypt
347  (vm, NULL, en, 0 + NOISE_AUTHTAG_LEN, key_idx, hs.hs_hash))
348  goto error;
349 
350 
351  hs.hs_remote_index = s_idx;
352 
353  if (r->r_handshake.hs_state == hs.hs_state &&
354  r->r_handshake.hs_local_index == hs.hs_local_index)
355  {
356  r->r_handshake = hs;
357  r->r_handshake.hs_state = CONSUMED_RESPONSE;
358  ret = true;
359  }
360 error:
361  secure_zero_memory (&hs, sizeof (hs));
363  vnet_crypto_key_del (vm, key_idx);
364  return ret;
365 }
366 
367 bool
369 {
370  noise_handshake_t *hs = &r->r_handshake;
371  noise_keypair_t kp, *next, *current, *previous;
372 
373  uint8_t key_send[NOISE_SYMMETRIC_KEY_LEN];
374  uint8_t key_recv[NOISE_SYMMETRIC_KEY_LEN];
375 
376  /* We now derive the keypair from the handshake */
377  if (hs->hs_state == CONSUMED_RESPONSE)
378  {
379  kp.kp_is_initiator = 1;
380  noise_kdf (key_send, key_recv, NULL, NULL,
382  hs->hs_ck);
383  }
384  else if (hs->hs_state == CREATED_RESPONSE)
385  {
386  kp.kp_is_initiator = 0;
387  noise_kdf (key_recv, key_send, NULL, NULL,
389  hs->hs_ck);
390  }
391  else
392  {
393  return false;
394  }
395 
396  kp.kp_valid = 1;
398  VNET_CRYPTO_ALG_CHACHA20_POLY1305,
399  key_send, NOISE_SYMMETRIC_KEY_LEN);
401  VNET_CRYPTO_ALG_CHACHA20_POLY1305,
402  key_recv, NOISE_SYMMETRIC_KEY_LEN);
406  clib_memset (&kp.kp_ctr, 0, sizeof (kp.kp_ctr));
407 
408  /* Now we need to add_new_keypair */
409  clib_rwlock_writer_lock (&r->r_keypair_lock);
410  next = r->r_next;
411  current = r->r_current;
412  previous = r->r_previous;
413 
414  if (kp.kp_is_initiator)
415  {
416  if (next != NULL)
417  {
418  r->r_next = NULL;
419  r->r_previous = next;
420  noise_remote_keypair_free (vm, r, &current);
421  }
422  else
423  {
424  r->r_previous = current;
425  }
426 
427  noise_remote_keypair_free (vm, r, &previous);
428 
429  r->r_current = noise_remote_keypair_allocate (r);
430  *r->r_current = kp;
431  }
432  else
433  {
435  r->r_previous = NULL;
436  noise_remote_keypair_free (vm, r, &previous);
437 
438  r->r_next = noise_remote_keypair_allocate (r);
439  *r->r_next = kp;
440  }
441  clib_rwlock_writer_unlock (&r->r_keypair_lock);
442 
443  secure_zero_memory (&r->r_handshake, sizeof (r->r_handshake));
444 
445  secure_zero_memory (&kp, sizeof (kp));
446  return true;
447 }
448 
449 void
451 {
453  secure_zero_memory (&r->r_handshake, sizeof (r->r_handshake));
454 
455  clib_rwlock_writer_lock (&r->r_keypair_lock);
456  noise_remote_keypair_free (vm, r, &r->r_next);
457  noise_remote_keypair_free (vm, r, &r->r_current);
458  noise_remote_keypair_free (vm, r, &r->r_previous);
459  r->r_next = NULL;
460  r->r_current = NULL;
461  r->r_previous = NULL;
462  clib_rwlock_writer_unlock (&r->r_keypair_lock);
463 }
464 
465 void
467 {
468  clib_rwlock_writer_lock (&r->r_keypair_lock);
469  if (r->r_next != NULL)
470  r->r_next->kp_valid = 0;
471  if (r->r_current != NULL)
472  r->r_current->kp_valid = 0;
473  clib_rwlock_writer_unlock (&r->r_keypair_lock);
474 }
475 
476 bool
478 {
479  noise_keypair_t *kp;
480  int ret;
481 
482  clib_rwlock_reader_lock (&r->r_keypair_lock);
483  if ((kp = r->r_current) == NULL ||
484  !kp->kp_valid ||
488  ret = false;
489  else
490  ret = true;
491  clib_rwlock_reader_unlock (&r->r_keypair_lock);
492  return ret;
493 }
494 
495 static bool
497  u8 * src,
498  u32 src_len,
499  u8 * dst,
500  u8 * aad,
501  u32 aad_len,
502  u64 nonce,
503  vnet_crypto_op_id_t op_id,
504  vnet_crypto_key_index_t key_index)
505 {
506  vnet_crypto_op_t _op, *op = &_op;
507  u8 iv[12];
508  u8 tag_[NOISE_AUTHTAG_LEN] = { };
509  u8 src_[] = { };
510 
511  clib_memset (iv, 0, 12);
512  clib_memcpy (iv + 4, &nonce, sizeof (nonce));
513 
514  vnet_crypto_op_init (op, op_id);
515 
517  if (op_id == VNET_CRYPTO_OP_CHACHA20_POLY1305_DEC)
518  {
519  op->tag = src + src_len - NOISE_AUTHTAG_LEN;
520  src_len -= NOISE_AUTHTAG_LEN;
522  }
523  else
524  op->tag = tag_;
525 
526  op->src = !src ? src_ : src;
527  op->len = src_len;
528 
529  op->dst = dst;
530  op->key_index = key_index;
531  op->aad = aad;
532  op->aad_len = aad_len;
533  op->iv = iv;
534 
535  vnet_crypto_process_ops (vm, op, 1);
536  if (op_id == VNET_CRYPTO_OP_CHACHA20_POLY1305_ENC)
537  {
538  clib_memcpy (dst + src_len, op->tag, NOISE_AUTHTAG_LEN);
539  }
540 
541  return (op->status == VNET_CRYPTO_OP_STATUS_COMPLETED);
542 }
543 
546  uint64_t * nonce, uint8_t * src, size_t srclen,
547  uint8_t * dst)
548 {
549  noise_keypair_t *kp;
550  enum noise_state_crypt ret = SC_FAILED;
551 
552  clib_rwlock_reader_lock (&r->r_keypair_lock);
553  if ((kp = r->r_current) == NULL)
554  goto error;
555 
556  /* We confirm that our values are within our tolerances. We want:
557  * - a valid keypair
558  * - our keypair to be less than REJECT_AFTER_TIME seconds old
559  * - our receive counter to be less than REJECT_AFTER_MESSAGES
560  * - our send counter to be less than REJECT_AFTER_MESSAGES
561  */
562  if (!kp->kp_valid ||
565  ((*nonce = noise_counter_send (&kp->kp_ctr)) > REJECT_AFTER_MESSAGES))
566  goto error;
567 
568  /* We encrypt into the same buffer, so the caller must ensure that buf
569  * has NOISE_AUTHTAG_LEN bytes to store the MAC. The nonce and index
570  * are passed back out to the caller through the provided data pointer. */
571  *r_idx = kp->kp_remote_index;
572 
573  chacha20poly1305_calc (vm, src, srclen, dst, NULL, 0, *nonce,
574  VNET_CRYPTO_OP_CHACHA20_POLY1305_ENC,
575  kp->kp_send_index);
576 
577  /* If our values are still within tolerances, but we are approaching
578  * the tolerances, we notify the caller with ESTALE that they should
579  * establish a new keypair. The current keypair can continue to be used
580  * until the tolerances are hit. We notify if:
581  * - our send counter is valid and not less than REKEY_AFTER_MESSAGES
582  * - we're the initiator and our keypair is older than
583  * REKEY_AFTER_TIME seconds */
584  ret = SC_KEEP_KEY_FRESH;
585  if ((kp->kp_valid && *nonce >= REKEY_AFTER_MESSAGES) ||
586  (kp->kp_is_initiator &&
588  goto error;
589 
590  ret = SC_OK;
591 error:
592  clib_rwlock_reader_unlock (&r->r_keypair_lock);
593  return ret;
594 }
595 
598  uint64_t nonce, uint8_t * src, size_t srclen,
599  uint8_t * dst)
600 {
601  noise_keypair_t *kp;
602  enum noise_state_crypt ret = SC_FAILED;
603  clib_rwlock_reader_lock (&r->r_keypair_lock);
604 
605  if (r->r_current != NULL && r->r_current->kp_local_index == r_idx)
606  {
607  kp = r->r_current;
608  }
609  else if (r->r_previous != NULL && r->r_previous->kp_local_index == r_idx)
610  {
611  kp = r->r_previous;
612  }
613  else if (r->r_next != NULL && r->r_next->kp_local_index == r_idx)
614  {
615  kp = r->r_next;
616  }
617  else
618  {
619  goto error;
620  }
621 
622  /* We confirm that our values are within our tolerances. These values
623  * are the same as the encrypt routine.
624  *
625  * kp_ctr isn't locked here, we're happy to accept a racy read. */
628  goto error;
629 
630  /* Decrypt, then validate the counter. We don't want to validate the
631  * counter before decrypting as we do not know the message is authentic
632  * prior to decryption. */
633  if (!chacha20poly1305_calc (vm, src, srclen, dst, NULL, 0, nonce,
634  VNET_CRYPTO_OP_CHACHA20_POLY1305_DEC,
635  kp->kp_recv_index))
636  goto error;
637 
638  if (!noise_counter_recv (&kp->kp_ctr, nonce))
639  goto error;
640 
641  /* If we've received the handshake confirming data packet then move the
642  * next keypair into current. If we do slide the next keypair in, then
643  * we skip the REKEY_AFTER_TIME_RECV check. This is safe to do as a
644  * data packet can't confirm a session that we are an INITIATOR of. */
645  if (kp == r->r_next)
646  {
647  clib_rwlock_reader_unlock (&r->r_keypair_lock);
648  clib_rwlock_writer_lock (&r->r_keypair_lock);
649  if (kp == r->r_next && kp->kp_local_index == r_idx)
650  {
651  noise_remote_keypair_free (vm, r, &r->r_previous);
652  r->r_previous = r->r_current;
653  r->r_current = r->r_next;
654  r->r_next = NULL;
655 
656  ret = SC_CONN_RESET;
657  clib_rwlock_writer_unlock (&r->r_keypair_lock);
658  clib_rwlock_reader_lock (&r->r_keypair_lock);
659  goto error;
660  }
661  clib_rwlock_writer_unlock (&r->r_keypair_lock);
662  clib_rwlock_reader_lock (&r->r_keypair_lock);
663  }
664 
665  /* Similar to when we encrypt, we want to notify the caller when we
666  * are approaching our tolerances. We notify if:
667  * - we're the initiator and the current keypair is older than
668  * REKEY_AFTER_TIME_RECV seconds. */
669  ret = SC_KEEP_KEY_FRESH;
670  kp = r->r_current;
671  if (kp != NULL &&
672  kp->kp_valid &&
673  kp->kp_is_initiator &&
675  goto error;
676 
677  ret = SC_OK;
678 error:
679  clib_rwlock_reader_unlock (&r->r_keypair_lock);
680  return ret;
681 }
682 
683 /* Private functions - these should not be called outside this file under any
684  * circumstances. */
685 static noise_keypair_t *
687 {
688  noise_keypair_t *kp;
689  kp = clib_mem_alloc (sizeof (*kp));
690  return kp;
691 }
692 
693 static void
695  noise_keypair_t ** kp)
696 {
697  noise_local_t *local = noise_local_get (r->r_local_idx);
698  struct noise_upcall *u = &local->l_upcall;
699  if (*kp)
700  {
701  u->u_index_drop ((*kp)->kp_local_index);
702  vnet_crypto_key_del (vm, (*kp)->kp_send_index);
703  vnet_crypto_key_del (vm, (*kp)->kp_recv_index);
704  clib_mem_free (*kp);
705  }
706 }
707 
708 static uint32_t
710 {
711  noise_local_t *local = noise_local_get (r->r_local_idx);
712  struct noise_upcall *u = &local->l_upcall;
713  return u->u_index_set (r);
714 }
715 
716 static void
718 {
719  noise_handshake_t *hs = &r->r_handshake;
720  noise_local_t *local = noise_local_get (r->r_local_idx);
721  struct noise_upcall *u = &local->l_upcall;
722  if (hs->hs_state != HS_ZEROED)
723  u->u_index_drop (hs->hs_local_index);
724 }
725 
726 static uint64_t
728 {
729  uint64_t ret;
730  ret = ctr->c_send++;
731  return ret;
732 }
733 
734 static bool
735 noise_counter_recv (noise_counter_t * ctr, uint64_t recv)
736 {
737  uint64_t i, top, index_recv, index_ctr;
738  unsigned long bit;
739  bool ret = false;
740 
741  /* Check that the recv counter is valid */
742  if (ctr->c_recv >= REJECT_AFTER_MESSAGES || recv >= REJECT_AFTER_MESSAGES)
743  goto error;
744 
745  /* If the packet is out of the window, invalid */
746  if (recv + COUNTER_WINDOW_SIZE < ctr->c_recv)
747  goto error;
748 
749  /* If the new counter is ahead of the current counter, we'll need to
750  * zero out the bitmap that has previously been used */
751  index_recv = recv / COUNTER_BITS;
752  index_ctr = ctr->c_recv / COUNTER_BITS;
753 
754  if (recv > ctr->c_recv)
755  {
756  top = clib_min (index_recv - index_ctr, COUNTER_NUM);
757  for (i = 1; i <= top; i++)
758  ctr->c_backtrack[(i + index_ctr) & (COUNTER_NUM - 1)] = 0;
759  ctr->c_recv = recv;
760  }
761 
762  index_recv %= COUNTER_NUM;
763  bit = 1ul << (recv % COUNTER_BITS);
764 
765  if (ctr->c_backtrack[index_recv] & bit)
766  goto error;
767 
768  ctr->c_backtrack[index_recv] |= bit;
769 
770  ret = true;
771 error:
772  return ret;
773 }
774 
775 static void
776 noise_kdf (uint8_t * a, uint8_t * b, uint8_t * c, const uint8_t * x,
777  size_t a_len, size_t b_len, size_t c_len, size_t x_len,
778  const uint8_t ck[NOISE_HASH_LEN])
779 {
780  uint8_t out[BLAKE2S_HASH_SIZE + 1];
781  uint8_t sec[BLAKE2S_HASH_SIZE];
782 
783  /* Extract entropy from "x" into sec */
784  u32 l = 0;
785  HMAC (EVP_blake2s256 (), ck, NOISE_HASH_LEN, x, x_len, sec, &l);
786  ASSERT (l == BLAKE2S_HASH_SIZE);
787  if (a == NULL || a_len == 0)
788  goto out;
789 
790  /* Expand first key: key = sec, data = 0x1 */
791  out[0] = 1;
792  HMAC (EVP_blake2s256 (), sec, BLAKE2S_HASH_SIZE, out, 1, out, &l);
793  ASSERT (l == BLAKE2S_HASH_SIZE);
794  clib_memcpy (a, out, a_len);
795 
796  if (b == NULL || b_len == 0)
797  goto out;
798 
799  /* Expand second key: key = sec, data = "a" || 0x2 */
800  out[BLAKE2S_HASH_SIZE] = 2;
801  HMAC (EVP_blake2s256 (), sec, BLAKE2S_HASH_SIZE, out, BLAKE2S_HASH_SIZE + 1,
802  out, &l);
803  ASSERT (l == BLAKE2S_HASH_SIZE);
804  clib_memcpy (b, out, b_len);
805 
806  if (c == NULL || c_len == 0)
807  goto out;
808 
809  /* Expand third key: key = sec, data = "b" || 0x3 */
810  out[BLAKE2S_HASH_SIZE] = 3;
811  HMAC (EVP_blake2s256 (), sec, BLAKE2S_HASH_SIZE, out, BLAKE2S_HASH_SIZE + 1,
812  out, &l);
813  ASSERT (l == BLAKE2S_HASH_SIZE);
814 
815  clib_memcpy (c, out, c_len);
816 
817 out:
818  /* Clear sensitive data from stack */
821 }
822 
823 static bool
825  uint8_t key[NOISE_SYMMETRIC_KEY_LEN],
826  const uint8_t private[NOISE_PUBLIC_KEY_LEN],
827  const uint8_t public[NOISE_PUBLIC_KEY_LEN])
828 {
829  uint8_t dh[NOISE_PUBLIC_KEY_LEN];
830  if (!curve25519_gen_shared (dh, private, public))
831  return false;
832  noise_kdf (ck, key, NULL, dh,
834  ck);
836  return true;
837 }
838 
839 static bool
841  uint8_t key[NOISE_SYMMETRIC_KEY_LEN],
842  const uint8_t ss[NOISE_PUBLIC_KEY_LEN])
843 {
844  static uint8_t null_point[NOISE_PUBLIC_KEY_LEN];
845  if (clib_memcmp (ss, null_point, NOISE_PUBLIC_KEY_LEN) == 0)
846  return false;
847  noise_kdf (ck, key, NULL, ss,
849  ck);
850  return true;
851 }
852 
853 static void
854 noise_mix_hash (uint8_t hash[NOISE_HASH_LEN], const uint8_t * src,
855  size_t src_len)
856 {
857  blake2s_state_t blake;
858 
859  blake2s_init (&blake, NOISE_HASH_LEN);
860  blake2s_update (&blake, hash, NOISE_HASH_LEN);
861  blake2s_update (&blake, src, src_len);
862  blake2s_final (&blake, hash, NOISE_HASH_LEN);
863 }
864 
865 static void
866 noise_mix_psk (uint8_t ck[NOISE_HASH_LEN], uint8_t hash[NOISE_HASH_LEN],
867  uint8_t key[NOISE_SYMMETRIC_KEY_LEN],
868  const uint8_t psk[NOISE_SYMMETRIC_KEY_LEN])
869 {
870  uint8_t tmp[NOISE_HASH_LEN];
871 
872  noise_kdf (ck, tmp, key, psk,
877 }
878 
879 static void
880 noise_param_init (uint8_t ck[NOISE_HASH_LEN], uint8_t hash[NOISE_HASH_LEN],
881  const uint8_t s[NOISE_PUBLIC_KEY_LEN])
882 {
883  blake2s_state_t blake;
884 
885  blake2s (ck, NOISE_HASH_LEN, (uint8_t *) NOISE_HANDSHAKE_NAME,
886  strlen (NOISE_HANDSHAKE_NAME), NULL, 0);
887 
888  blake2s_init (&blake, NOISE_HASH_LEN);
889  blake2s_update (&blake, ck, NOISE_HASH_LEN);
890  blake2s_update (&blake, (uint8_t *) NOISE_IDENTIFIER_NAME,
891  strlen (NOISE_IDENTIFIER_NAME));
892  blake2s_final (&blake, hash, NOISE_HASH_LEN);
893 
895 }
896 
897 static void
898 noise_msg_encrypt (vlib_main_t * vm, uint8_t * dst, uint8_t * src,
899  size_t src_len, uint32_t key_idx,
900  uint8_t hash[NOISE_HASH_LEN])
901 {
902  /* Nonce always zero for Noise_IK */
903  chacha20poly1305_calc (vm, src, src_len, dst, hash, NOISE_HASH_LEN, 0,
904  VNET_CRYPTO_OP_CHACHA20_POLY1305_ENC, key_idx);
905  noise_mix_hash (hash, dst, src_len + NOISE_AUTHTAG_LEN);
906 }
907 
908 static bool
909 noise_msg_decrypt (vlib_main_t * vm, uint8_t * dst, uint8_t * src,
910  size_t src_len, uint32_t key_idx,
911  uint8_t hash[NOISE_HASH_LEN])
912 {
913  /* Nonce always zero for Noise_IK */
914  if (!chacha20poly1305_calc (vm, src, src_len, dst, hash, NOISE_HASH_LEN, 0,
915  VNET_CRYPTO_OP_CHACHA20_POLY1305_DEC, key_idx))
916  return false;
917  noise_mix_hash (hash, src, src_len);
918  return true;
919 }
920 
921 static void
923  const uint8_t src[NOISE_PUBLIC_KEY_LEN])
924 {
926  noise_kdf (ck, NULL, NULL, src, NOISE_HASH_LEN, 0, 0,
928 }
929 
930 static void
932 {
933  uint32_t unix_sec;
934  uint32_t unix_nanosec;
935 
936  uint64_t sec;
937  uint32_t nsec;
938 
939  unix_time_now_nsec_fraction (&unix_sec, &unix_nanosec);
940 
941  /* Round down the nsec counter to limit precise timing leak. */
942  unix_nanosec &= REJECT_INTERVAL_MASK;
943 
944  /* https://cr.yp.to/libtai/tai64.html */
945  sec = htobe64 (0x400000000000000aULL + unix_sec);
946  nsec = htobe32 (unix_nanosec);
947 
948  /* memcpy to output buffer, assuming output could be unaligned. */
949  clib_memcpy (output, &sec, sizeof (sec));
950  clib_memcpy (output + sizeof (sec), &nsec, sizeof (nsec));
951 }
952 
953 static void
954 secure_zero_memory (void *v, size_t n)
955 {
956  static void *(*const volatile memset_v) (void *, int, size_t) = &memset;
957  memset_v (v, 0, n);
958 }
959 
960 /*
961  * fd.io coding-style-patch-verification: ON
962  *
963  * Local Variables:
964  * eval: (c-set-style "gnu")
965  * End:
966  */
curve25519_gen_public
bool curve25519_gen_public(u8 public_key[CURVE25519_KEY_SIZE], const u8 secret_key[CURVE25519_KEY_SIZE])
Definition: wireguard_key.c:66
noise_keypair::kp_is_initiator
int kp_is_initiator
Definition: wireguard_noise.h:89
tmp
u32 * tmp
Definition: interface_output.c:1096
noise_local::noise_upcall::u_index_drop
void(* u_index_drop)(uint32_t)
Definition: wireguard_noise.h:125
vnet_crypto_op_init
static_always_inline void vnet_crypto_op_init(vnet_crypto_op_t *op, vnet_crypto_op_id_t type)
Definition: crypto.h:528
noise_remote_expire_current
void noise_remote_expire_current(noise_remote_t *r)
Definition: wireguard_noise.c:466
blake2s_state
Definition: blake2s.h:42
vnet_crypto_op_t::tag
u8 * tag
Definition: crypto.h:298
noise_keypair
Definition: wireguard_noise.h:86
NOISE_HASH_LEN
#define NOISE_HASH_LEN
Definition: wireguard_noise.h:30
clib_memcpy
#define clib_memcpy(d, s, n)
Definition: string.h:197
vnet_crypto_key_del
void vnet_crypto_key_del(vlib_main_t *vm, vnet_crypto_key_index_t index)
Definition: crypto.c:386
NOISE_SYMMETRIC_KEY_LEN
#define NOISE_SYMMETRIC_KEY_LEN
Definition: wireguard_noise.h:27
clib_memcmp
#define clib_memcmp(s1, s2, m1)
Definition: string.h:734
NOISE_AUTHTAG_LEN
#define NOISE_AUTHTAG_LEN
Definition: wireguard_noise.h:29
noise_mix_ss
static bool noise_mix_ss(uint8_t ck[NOISE_HASH_LEN], uint8_t key[NOISE_SYMMETRIC_KEY_LEN], const uint8_t ss[NOISE_PUBLIC_KEY_LEN])
Definition: wireguard_noise.c:840
noise_handshake::hs_hash
uint8_t hs_hash[NOISE_HASH_LEN]
Definition: wireguard_noise.h:75
SC_KEEP_KEY_FRESH
@ SC_KEEP_KEY_FRESH
Definition: wireguard_noise.h:56
vnet_crypto_op_t::status
vnet_crypto_op_status_t status
Definition: crypto.h:260
next
u16 * next
Definition: nat44_ei_out2in.c:718
noise_keypair::kp_birthdate
f64 kp_birthdate
Definition: wireguard_noise.h:94
clib_mem_free
static void clib_mem_free(void *p)
Definition: mem.h:314
noise_local::l_upcall
struct noise_local::noise_upcall l_upcall
noise_counter::c_backtrack
unsigned long c_backtrack[COUNTER_NUM]
Definition: wireguard_noise.h:83
HS_ZEROED
@ HS_ZEROED
Definition: wireguard_noise.h:62
noise_handshake::hs_local_index
uint32_t hs_local_index
Definition: wireguard_noise.h:72
REJECT_AFTER_MESSAGES
#define REJECT_AFTER_MESSAGES
Definition: wireguard_noise.h:44
wg_birthdate_has_expired
static bool wg_birthdate_has_expired(f64 birthday_seconds, f64 expiration_seconds)
Definition: wireguard_timer.h:54
vnet_crypto_op_t::src
u8 * src
Definition: crypto.h:277
chacha20poly1305_calc
static bool chacha20poly1305_calc(vlib_main_t *vm, u8 *src, u32 src_len, u8 *dst, u8 *aad, u32 aad_len, u64 nonce, vnet_crypto_op_id_t op_id, vnet_crypto_key_index_t key_index)
Definition: wireguard_noise.c:496
vnet_crypto_op_t::dst
u8 * dst
Definition: crypto.h:278
vnet_crypto_key_index_t
u32 vnet_crypto_key_index_t
Definition: crypto.h:378
vm
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
CONSUMED_RESPONSE
@ CONSUMED_RESPONSE
Definition: wireguard_noise.h:66
noise_consume_initiation
bool noise_consume_initiation(vlib_main_t *vm, noise_local_t *l, noise_remote_t **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])
Definition: wireguard_noise.c:170
noise_remote_ready
bool noise_remote_ready(noise_remote_t *r)
Definition: wireguard_noise.c:477
REJECT_AFTER_TIME
#define REJECT_AFTER_TIME
Definition: wireguard_noise.h:47
SC_FAILED
@ SC_FAILED
Definition: wireguard_noise.h:57
COUNTER_NUM
#define COUNTER_NUM
Definition: wireguard_noise.h:39
vnet_crypto_op_t::iv
u8 * iv
Definition: crypto.h:293
noise_counter::c_recv
uint64_t c_recv
Definition: wireguard_noise.h:82
vnet_crypto_key_t::data
u8 * data
Definition: crypto.h:204
noise_msg_ephemeral
static void noise_msg_ephemeral(uint8_t[NOISE_HASH_LEN], uint8_t[NOISE_HASH_LEN], const uint8_t src[NOISE_PUBLIC_KEY_LEN])
Definition: wireguard_noise.c:922
clib_rwlock_reader_lock
static void clib_rwlock_reader_lock(clib_rwlock_t *p)
Definition: lock.h:169
r
vnet_hw_if_output_node_runtime_t * r
Definition: interface_output.c:1089
vnet_crypto_op_t::len
u32 len
Definition: crypto.h:287
noise_local::l_private
uint8_t l_private[NOISE_PUBLIC_KEY_LEN]
Definition: wireguard_noise.h:118
clib_rwlock_reader_unlock
static void clib_rwlock_reader_unlock(clib_rwlock_t *p)
Definition: lock.h:184
clib_rwlock_writer_unlock
static void clib_rwlock_writer_unlock(clib_rwlock_t *p)
Definition: lock.h:206
error
Definition: cJSON.c:88
vnet_crypto_op_t::aad_len
u16 aad_len
Definition: crypto.h:271
key
typedef key
Definition: ipsec_types.api:91
vnet_crypto_op_t
Definition: crypto.h:255
noise_keypair::kp_ctr
noise_counter_t kp_ctr
Definition: wireguard_noise.h:95
vnet_crypto_op_t::flags
u8 flags
Definition: crypto.h:261
vnet_crypto_op_t::key_index
u32 key_index
Definition: crypto.h:292
VNET_CRYPTO_OP_FLAG_HMAC_CHECK
#define VNET_CRYPTO_OP_FLAG_HMAC_CHECK
Definition: crypto.h:263
noise_tai64n_now
static void noise_tai64n_now(uint8_t[NOISE_TIMESTAMP_LEN])
Definition: wireguard_noise.c:931
COUNTER_BITS
#define COUNTER_BITS
Definition: wireguard_noise.h:38
noise_handshake::hs_ck
uint8_t hs_ck[NOISE_HASH_LEN]
Definition: wireguard_noise.h:76
REKEY_AFTER_TIME_RECV
#define REKEY_AFTER_TIME_RECV
Definition: wireguard_noise.h:46
NOISE_HANDSHAKE_NAME
#define NOISE_HANDSHAKE_NAME
Definition: wireguard_noise.h:33
vnet_crypto_process_ops
u32 vnet_crypto_process_ops(vlib_main_t *vm, vnet_crypto_op_t ops[], u32 n_ops)
Definition: crypto.c:99
noise_remote_clear
void noise_remote_clear(vlib_main_t *vm, noise_remote_t *r)
Definition: wireguard_noise.c:450
noise_remote_handshake_index_drop
static void noise_remote_handshake_index_drop(noise_remote_t *)
Definition: wireguard_noise.c:717
CREATED_INITIATION
@ CREATED_INITIATION
Definition: wireguard_noise.h:63
noise_local::noise_upcall::u_remote_get
noise_remote_t *(* u_remote_get)(const uint8_t[NOISE_PUBLIC_KEY_LEN])
Definition: wireguard_noise.h:123
BLAKE2S_HASH_SIZE
@ BLAKE2S_HASH_SIZE
Definition: blake2s.h:37
c
svmdb_client_t * c
Definition: vpp_get_metrics.c:48
REJECT_INTERVAL_MASK
#define REJECT_INTERVAL_MASK
Definition: wireguard_noise.h:50
clib_rwlock_writer_lock
static void clib_rwlock_writer_lock(clib_rwlock_t *p)
Definition: lock.h:192
noise_remote
Definition: wireguard_noise.h:99
REKEY_AFTER_TIME
#define REKEY_AFTER_TIME
Definition: wireguard_noise.h:45
noise_counter::c_send
uint64_t c_send
Definition: wireguard_noise.h:81
vnet_crypto_op_id_t
vnet_crypto_op_id_t
Definition: crypto.h:219
noise_state_crypt
noise_state_crypt
Definition: wireguard_noise.h:52
noise_remote_encrypt
enum noise_state_crypt noise_remote_encrypt(vlib_main_t *vm, noise_remote_t *r, uint32_t *r_idx, uint64_t *nonce, uint8_t *src, size_t srclen, uint8_t *dst)
Definition: wireguard_noise.c:545
noise_mix_hash
static void noise_mix_hash(uint8_t[NOISE_HASH_LEN], const uint8_t *, size_t)
Definition: wireguard_noise.c:854
SC_CONN_RESET
@ SC_CONN_RESET
Definition: wireguard_noise.h:55
vnet_crypto_get_key
static_always_inline vnet_crypto_key_t * vnet_crypto_get_key(vnet_crypto_key_index_t index)
Definition: crypto.h:548
src
vl_api_address_t src
Definition: gre.api:54
NOISE_IDENTIFIER_NAME
#define NOISE_IDENTIFIER_NAME
Definition: wireguard_noise.h:34
noise_keypair::kp_valid
int kp_valid
Definition: wireguard_noise.h:88
clib_min
#define clib_min(x, y)
Definition: clib.h:342
curve25519_gen_secret
bool curve25519_gen_secret(u8 secret_key[CURVE25519_KEY_SIZE])
Definition: wireguard_key.c:84
CREATED_RESPONSE
@ CREATED_RESPONSE
Definition: wireguard_noise.h:65
noise_handshake::hs_state
enum noise_state_hs hs_state
Definition: wireguard_noise.h:71
clib_rwlock_init
static void clib_rwlock_init(clib_rwlock_t *p)
Definition: lock.h:152
noise_remote_decrypt
enum noise_state_crypt noise_remote_decrypt(vlib_main_t *vm, noise_remote_t *r, uint32_t r_idx, uint64_t nonce, uint8_t *src, size_t srclen, uint8_t *dst)
Definition: wireguard_noise.c:597
noise_remote_init
void noise_remote_init(noise_remote_t *r, uint32_t peer_pool_idx, const uint8_t public[NOISE_PUBLIC_KEY_LEN], u32 noise_local_idx)
Definition: wireguard_noise.c:90
noise_create_initiation
bool noise_create_initiation(vlib_main_t *vm, noise_remote_t *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])
Definition: wireguard_noise.c:118
noise_local_pool
noise_local_t * noise_local_pool
Definition: wireguard_noise.c:29
vnet_crypto_key_add
u32 vnet_crypto_key_add(vlib_main_t *vm, vnet_crypto_alg_t alg, u8 *data, u16 length)
Definition: crypto.c:360
unix_time_now_nsec_fraction
static void unix_time_now_nsec_fraction(u32 *sec, u32 *nsec)
Definition: time.h:282
vnet_crypto_op_t::tag_len
u8 tag_len
Definition: crypto.h:269
noise_remote_precompute
void noise_remote_precompute(noise_remote_t *r)
Definition: wireguard_noise.c:105
secure_zero_memory
static void secure_zero_memory(void *v, size_t n)
Definition: wireguard_noise.c:954
noise_remote_keypair_free
static void noise_remote_keypair_free(vlib_main_t *vm, noise_remote_t *, noise_keypair_t **)
Definition: wireguard_noise.c:694
noise_mix_psk
static void noise_mix_psk(uint8_t[NOISE_HASH_LEN], uint8_t[NOISE_HASH_LEN], uint8_t[NOISE_SYMMETRIC_KEY_LEN], const uint8_t[NOISE_SYMMETRIC_KEY_LEN])
Definition: wireguard_noise.c:866
u64
unsigned long u64
Definition: types.h:89
noise_local_get
static_always_inline noise_local_t * noise_local_get(uint32_t locali)
Definition: wireguard_noise.h:134
noise_remote_keypair_allocate
static noise_keypair_t * noise_remote_keypair_allocate(noise_remote_t *)
Definition: wireguard_noise.c:686
vnet_crypto_op_t::aad
u8 * aad
Definition: crypto.h:294
ASSERT
#define ASSERT(truth)
Definition: error_bootstrap.h:69
blake2s_final
int blake2s_final(blake2s_state_t *S, void *out, size_t outlen)
Definition: blake2s.c:267
noise_local
Definition: wireguard_noise.h:115
NOISE_PUBLIC_KEY_LEN
#define NOISE_PUBLIC_KEY_LEN
Definition: wireguard_noise.h:26
u32
unsigned int u32
Definition: types.h:88
noise_mix_dh
static bool noise_mix_dh(uint8_t[NOISE_HASH_LEN], uint8_t[NOISE_SYMMETRIC_KEY_LEN], const uint8_t[NOISE_PUBLIC_KEY_LEN], const uint8_t[NOISE_PUBLIC_KEY_LEN])
Definition: wireguard_noise.c:824
dh
vl_api_ikev2_sa_transform_t dh
Definition: ikev2_types.api:160
dst
vl_api_ip4_address_t dst
Definition: pnat.api:41
blake2s_init
int blake2s_init(blake2s_state_t *S, size_t outlen)
Definition: blake2s.c:105
noise_consume_response
bool noise_consume_response(vlib_main_t *vm, noise_remote_t *r, uint32_t s_idx, uint32_t r_idx, uint8_t ue[NOISE_PUBLIC_KEY_LEN], uint8_t en[0+NOISE_AUTHTAG_LEN])
Definition: wireguard_noise.c:307
iv
static u8 iv[]
Definition: aes_cbc.c:24
noise_param_init
static void noise_param_init(uint8_t[NOISE_HASH_LEN], uint8_t[NOISE_HASH_LEN], const uint8_t[NOISE_PUBLIC_KEY_LEN])
Definition: wireguard_noise.c:880
noise_counter_recv
static bool noise_counter_recv(noise_counter_t *, uint64_t)
Definition: wireguard_noise.c:735
noise_create_response
bool noise_create_response(vlib_main_t *vm, noise_remote_t *r, uint32_t *s_idx, uint32_t *r_idx, uint8_t ue[NOISE_PUBLIC_KEY_LEN], uint8_t en[0+NOISE_AUTHTAG_LEN])
Definition: wireguard_noise.c:254
curve25519_gen_shared
bool curve25519_gen_shared(u8 shared_key[CURVE25519_KEY_SIZE], const u8 secret_key[CURVE25519_KEY_SIZE], const u8 basepoint[CURVE25519_KEY_SIZE])
Definition: wireguard_key.c:20
SC_OK
@ SC_OK
Definition: wireguard_noise.h:54
noise_handshake::hs_remote_index
uint32_t hs_remote_index
Definition: wireguard_noise.h:73
clib_memset
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
vlib_main_t
Definition: main.h:102
noise_counter_send
static uint64_t noise_counter_send(noise_counter_t *)
Definition: wireguard_noise.c:727
REJECT_INTERVAL
#define REJECT_INTERVAL
Definition: wireguard_noise.h:48
b
vlib_buffer_t ** b
Definition: nat44_ei_out2in.c:717
u8
unsigned char u8
Definition: types.h:56
a
a
Definition: bitmap.h:525
wireguard.h
noise_local::l_public
uint8_t l_public[NOISE_PUBLIC_KEY_LEN]
Definition: wireguard_noise.h:117
noise_local_init
void noise_local_init(noise_local_t *l, struct noise_upcall *upcall)
Definition: wireguard_noise.c:74
blake2s
int blake2s(void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen)
Definition: blake2s.c:292
blake2s_update
int blake2s_update(blake2s_state_t *S, const void *pin, size_t inlen)
Definition: blake2s.c:237
noise_handshake::hs_e
uint8_t hs_e[NOISE_PUBLIC_KEY_LEN]
Definition: wireguard_noise.h:74
i
int i
Definition: flowhash_template.h:376
noise_counter
Definition: wireguard_noise.h:79
CONSUMED_INITIATION
@ CONSUMED_INITIATION
Definition: wireguard_noise.h:64
noise_remote_handshake_index_get
static uint32_t noise_remote_handshake_index_get(noise_remote_t *)
Definition: wireguard_noise.c:709
REKEY_AFTER_MESSAGES
#define REKEY_AFTER_MESSAGES
Definition: wireguard_noise.h:43
noise_local_set_private
bool noise_local_set_private(noise_local_t *l, const uint8_t private[NOISE_PUBLIC_KEY_LEN])
Definition: wireguard_noise.c:81
vlib_time_now
static f64 vlib_time_now(vlib_main_t *vm)
Definition: main.h:327
noise_keypair::kp_recv_index
vnet_crypto_key_index_t kp_recv_index
Definition: wireguard_noise.h:93
NOISE_TIMESTAMP_LEN
#define NOISE_TIMESTAMP_LEN
Definition: wireguard_noise.h:28
noise_kdf
static void noise_kdf(uint8_t *, uint8_t *, uint8_t *, const uint8_t *, size_t, size_t, size_t, size_t, const uint8_t[NOISE_HASH_LEN])
Definition: wireguard_noise.c:776
noise_remote_begin_session
bool noise_remote_begin_session(vlib_main_t *vm, noise_remote_t *r)
Definition: wireguard_noise.c:368
noise_handshake
Definition: wireguard_noise.h:69
timestamp
f64 timestamp
Definition: vpe_types.api:28
clib_mem_alloc
static void * clib_mem_alloc(uword size)
Definition: mem.h:256
noise_msg_encrypt
static void noise_msg_encrypt(vlib_main_t *vm, uint8_t *, uint8_t *, size_t, uint32_t key_idx, uint8_t[NOISE_HASH_LEN])
Definition: wireguard_noise.c:898
noise_keypair::kp_local_index
uint32_t kp_local_index
Definition: wireguard_noise.h:90
noise_local::noise_upcall::u_index_set
uint32_t(* u_index_set)(noise_remote_t *)
Definition: wireguard_noise.h:124
noise_keypair::kp_remote_index
uint32_t kp_remote_index
Definition: wireguard_noise.h:91
noise_msg_decrypt
static bool noise_msg_decrypt(vlib_main_t *vm, uint8_t *, uint8_t *, size_t, uint32_t key_idx, uint8_t[NOISE_HASH_LEN])
Definition: wireguard_noise.c:909
noise_keypair::kp_send_index
vnet_crypto_key_index_t kp_send_index
Definition: wireguard_noise.h:92