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 #ifndef __included_wg_noise_h__
19 #define __included_wg_noise_h__
21 #include <vlib/vlib.h>
22 #include <vnet/crypto/crypto.h>
23 #include <wireguard/blake/blake2s.h>
24 #include <wireguard/wireguard_key.h>
26 #define NOISE_PUBLIC_KEY_LEN CURVE25519_KEY_SIZE
27 #define NOISE_SYMMETRIC_KEY_LEN 32 // CHACHA20POLY1305_KEY_SIZE
28 #define NOISE_TIMESTAMP_LEN (sizeof(uint64_t) + sizeof(uint32_t))
29 #define NOISE_AUTHTAG_LEN 16 //CHACHA20POLY1305_AUTHTAG_SIZE
30 #define NOISE_HASH_LEN BLAKE2S_HASH_SIZE
32 /* Protocol string constants */
33 #define NOISE_HANDSHAKE_NAME "Noise_IKpsk2_25519_ChaChaPoly_BLAKE2s"
34 #define NOISE_IDENTIFIER_NAME "WireGuard v1 zx2c4 Jason@zx2c4.com"
36 /* Constants for the counter */
37 #define COUNTER_BITS_TOTAL 8192
38 #define COUNTER_BITS (sizeof(unsigned long) * 8)
39 #define COUNTER_NUM (COUNTER_BITS_TOTAL / COUNTER_BITS)
40 #define COUNTER_WINDOW_SIZE (COUNTER_BITS_TOTAL - COUNTER_BITS)
42 /* Constants for the keypair */
43 #define REKEY_AFTER_MESSAGES (1ull << 60)
44 #define REJECT_AFTER_MESSAGES (UINT64_MAX - COUNTER_WINDOW_SIZE - 1)
45 #define REKEY_AFTER_TIME 120
46 #define REKEY_AFTER_TIME_RECV 165
47 #define REJECT_AFTER_TIME 180
48 #define REJECT_INTERVAL (0.02) /* fifty times per sec */
49 /* 24 = floor(log2(REJECT_INTERVAL)) */
50 #define REJECT_INTERVAL_MASK (~((1ull<<24)-1))
52 enum noise_state_crypt
69 typedef struct noise_handshake
71 enum noise_state_hs hs_state;
72 uint32_t hs_local_index;
73 uint32_t hs_remote_index;
74 uint8_t hs_e[NOISE_PUBLIC_KEY_LEN];
75 uint8_t hs_hash[NOISE_HASH_LEN];
76 uint8_t hs_ck[NOISE_HASH_LEN];
79 typedef struct noise_counter
83 unsigned long c_backtrack[COUNTER_NUM];
86 typedef struct noise_keypair
90 uint32_t kp_local_index;
91 uint32_t kp_remote_index;
92 vnet_crypto_key_index_t kp_send_index;
93 vnet_crypto_key_index_t kp_recv_index;
95 noise_counter_t kp_ctr;
98 typedef struct noise_local noise_local_t;
99 typedef struct noise_remote
102 uint8_t r_public[NOISE_PUBLIC_KEY_LEN];
103 uint32_t r_local_idx;
104 uint8_t r_ss[NOISE_PUBLIC_KEY_LEN];
106 noise_handshake_t r_handshake;
107 uint8_t r_psk[NOISE_SYMMETRIC_KEY_LEN];
108 uint8_t r_timestamp[NOISE_TIMESTAMP_LEN];
111 clib_rwlock_t r_keypair_lock;
112 noise_keypair_t *r_next, *r_current, *r_previous;
115 typedef struct noise_local
117 uint8_t l_public[NOISE_PUBLIC_KEY_LEN];
118 uint8_t l_private[NOISE_PUBLIC_KEY_LEN];
123 noise_remote_t *(*u_remote_get) (const uint8_t[NOISE_PUBLIC_KEY_LEN]);
124 uint32_t (*u_index_set) (noise_remote_t *);
125 void (*u_index_drop) (uint32_t);
129 /* pool of noise_local */
130 extern noise_local_t *noise_local_pool;
132 /* Set/Get noise parameters */
133 static_always_inline noise_local_t *
134 noise_local_get (uint32_t locali)
136 return (pool_elt_at_index (noise_local_pool, locali));
139 void noise_local_init (noise_local_t *, struct noise_upcall *);
140 bool noise_local_set_private (noise_local_t *,
141 const uint8_t[NOISE_PUBLIC_KEY_LEN]);
143 void noise_remote_init (noise_remote_t *, uint32_t,
144 const uint8_t[NOISE_PUBLIC_KEY_LEN], uint32_t);
146 /* Should be called anytime noise_local_set_private is called */
147 void noise_remote_precompute (noise_remote_t *);
149 /* Cryptographic functions */
150 bool noise_create_initiation (vlib_main_t * vm, noise_remote_t *,
152 uint8_t ue[NOISE_PUBLIC_KEY_LEN],
153 uint8_t es[NOISE_PUBLIC_KEY_LEN +
155 uint8_t ets[NOISE_TIMESTAMP_LEN +
158 bool noise_consume_initiation (vlib_main_t * vm, noise_local_t *,
161 uint8_t ue[NOISE_PUBLIC_KEY_LEN],
162 uint8_t es[NOISE_PUBLIC_KEY_LEN +
164 uint8_t ets[NOISE_TIMESTAMP_LEN +
167 bool noise_create_response (vlib_main_t * vm, noise_remote_t *,
170 uint8_t ue[NOISE_PUBLIC_KEY_LEN],
171 uint8_t en[0 + NOISE_AUTHTAG_LEN]);
173 bool noise_consume_response (vlib_main_t * vm, noise_remote_t *,
176 uint8_t ue[NOISE_PUBLIC_KEY_LEN],
177 uint8_t en[0 + NOISE_AUTHTAG_LEN]);
179 bool noise_remote_begin_session (vlib_main_t * vm, noise_remote_t * r);
180 void noise_remote_clear (vlib_main_t * vm, noise_remote_t * r);
181 void noise_remote_expire_current (noise_remote_t * r);
183 bool noise_remote_ready (noise_remote_t *);
185 enum noise_state_crypt
186 noise_remote_encrypt (vlib_main_t * vm, noise_remote_t *,
189 uint8_t * src, size_t srclen, uint8_t * dst);
190 enum noise_state_crypt
191 noise_remote_decrypt (vlib_main_t * vm, noise_remote_t *,
194 uint8_t * src, size_t srclen, uint8_t * dst);
197 #endif /* __included_wg_noise_h__ */
200 * fd.io coding-style-patch-verification: ON
203 * eval: (c-set-style "gnu")