2 * Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
3 * Copyright (C) 2019-2020 Matt Dunwoodie <ncon@noconroy.net>
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 * ======== wg_noise.h ========
19 * This file provides a thread safe interface to the Noise protocol as used in
20 * WireGuard. The three user facing components are:
23 * Stores the local state for a noise peer.
25 * Stores the remote state for a noise peer.
27 * Stores callback routines for index and peers
29 * Additionally a noise_counter, which is invsible to the user is used to track
30 * message nonces, to prevent message replay.
32 * This module uses Curve25519 for asymmetric crypto, and ChaCha20Poly1305 for
33 * symmetric crypto. The handshake uses ephemeral keys, which provide perfect
34 * forward secrecy. Keys are NOISE_KEY_SIZE (32) bytes long and can be
35 * generated with a CSRNG. While this module will clamp the key to form a valid
36 * Curve25519 key, it is recommended that keys are stored in Curve25519 form to
37 * preserve interoperability with other systems. Additionally, there is an
38 * optional PresharedKey of length NOISE_PSK_SIZE (also 32 bytes), which when
39 * used, will provide protection against known quantum attacks. Without it,
40 * Curve25519 is broken by Shor's algorithm.
42 * -------- noise_local --------
44 * void noise_local_init(noise_local *, noise_upcall *)
45 * - Initialise noise_local, should only be called once and before use.
47 * int noise_local_set_private(noise_local *, uint8_t *private)
48 * - Set the local private key. This will also calculate the corresponding
51 * int noise_local_keys(noise_local *, uint8_t *public, uint8_t *private)
52 * - Get the local keys. It will ensure that a key has been set and if
53 * not, will return ENXIO.
55 * -------- noise_remote --------
57 * void noise_remote_init(noise_remote *, uint8_t *public)
58 * - Initialise noise_local, should only be called once and before use. Key
59 * must be provided and it cannot be changed once set.
61 * void noise_remote_set_psk(noise_remote *, uint8_t *psk)
62 * - Set the shared key. To remove the shared key, set a key of all 0x00.
64 * void noise_remote_keys(noise_remote *, uint8_t *public, uint8_t *psk)
65 * - Get the remote keys.
67 * -------- noise_upcall --------
69 * The noise_upcall struct is used to lookup incoming public keys, as well as
70 * allocate and deallocate index for a remote. The allocation and deallocation
71 * are serialised per noise_remote and guaranteed to only have 3 allocated
74 * u_arg - passed to callback functions as void *
75 * u_get_remote - lookup noise_remote based on public key.
76 * u_set_index - allocate index for noise_remote. any further packets that
77 * arrive with this index should be passed to noise_* functions
78 * with the corresponding noise_remote.
79 * u_drop_index - dealloate index passed to callback.
81 * -------- crypto --------
83 * The following functions are used for the crypto side of things:
85 * int noise_create_initiation(noise_remote *, noise_initiation *)
86 * int noise_consume_initiation(noise_local *, noise_remote **, noise_initiation *)
87 * int noise_create_response(noise_remote *, noise_response *)
88 * int noise_consume_response(noise_remote *, noise_response *)
90 * int noise_remote_promote(noise_remote *)
91 * void noise_remote_clear(noise_remote *)
92 * void noise_remote_expire_current(noise_remote *)
93 * int noise_remote_encrypt(noise_remote *, noise_data *, size_t)
94 * int noise_remote_decrypt(noise_remote *, noise_data *, size_t)
102 #include <sys/types.h>
103 #include <sys/time.h>
104 #include <sys/rwlock.h>
105 #include <sys/support.h>
107 #include <crypto/blake2s.h>
108 #include <zinc/chacha20poly1305.h>
109 #include <crypto/curve25519.h>
111 #define NOISE_KEY_SIZE CURVE25519_KEY_SIZE
112 #define NOISE_PSK_SIZE 32
113 #define NOISE_MAC_SIZE CHACHA20POLY1305_AUTHTAG_SIZE
114 #define NOISE_HASH_SIZE BLAKE2S_HASH_SIZE
115 #define NOISE_SYMMETRIC_SIZE CHACHA20POLY1305_KEY_SIZE
116 #define NOISE_TIMESTAMP_SIZE 12
118 /* Protocol string constants */
119 #define NOISE_HANDSHAKE_NAME "Noise_IKpsk2_25519_ChaChaPoly_BLAKE2s"
120 #define NOISE_IDENTIFIER_NAME "WireGuard v1 zx2c4 Jason@zx2c4.com"
122 /* Constants for the counter */
123 #define COUNTER_TYPE size_t
124 #define COUNTER_BITS_TOTAL 512
125 #define COUNTER_TYPE_BITS (sizeof(COUNTER_TYPE) * 8)
126 #define COUNTER_TYPE_NUM (COUNTER_BITS_TOTAL / COUNTER_TYPE_BITS)
127 #define COUNTER_WINDOW_SIZE (COUNTER_BITS_TOTAL - COUNTER_TYPE_BITS)
129 /* Constants for the keypair */
130 #define REKEY_AFTER_MESSAGES (1ull << 60)
131 #define REJECT_AFTER_MESSAGES (UINT64_MAX - COUNTER_WINDOW_SIZE - 1)
132 #define REKEY_AFTER_TIME 120
133 #define REKEY_AFTER_TIME_RECV 165
134 #define REJECT_AFTER_TIME 180
135 #define REJECT_INTERVAL (1000000000 / 50) /* fifty times per sec */
136 /* 24 = floor(log2(REJECT_INTERVAL)) */
137 #define REJECT_INTERVAL_MASK (~((1ull<<24)-1))
139 enum noise_state_hs {
147 struct noise_handshake {
148 enum noise_state_hs hs_state;
149 uint32_t hs_local_index;
150 uint32_t hs_remote_index;
151 uint8_t hs_e[NOISE_KEY_SIZE];
152 uint8_t hs_hash[NOISE_HASH_SIZE];
153 uint8_t hs_ck[NOISE_HASH_SIZE];
156 struct noise_counter {
157 struct rwlock c_lock;
160 COUNTER_TYPE c_backtrack[COUNTER_TYPE_NUM];
163 enum noise_state_kp {
169 struct noise_keypair {
170 SLIST_ENTRY(noise_keypair) kp_entry;
173 uint32_t kp_local_index;
174 uint32_t kp_remote_index;
175 uint8_t kp_send[NOISE_SYMMETRIC_SIZE];
176 uint8_t kp_recv[NOISE_SYMMETRIC_SIZE];
177 struct timespec kp_birthdate; /* nanouptime */
178 struct noise_counter kp_ctr;
181 struct noise_remote {
182 uint8_t r_public[NOISE_KEY_SIZE];
183 struct noise_local *r_local;
184 uint8_t r_ss[NOISE_KEY_SIZE];
186 struct rwlock r_handshake_lock;
187 struct noise_handshake r_handshake;
188 uint8_t r_psk[NOISE_PSK_SIZE];
189 uint8_t r_timestamp[NOISE_TIMESTAMP_SIZE];
190 struct timespec r_last_init; /* nanouptime */
192 struct rwlock r_keypair_lock;
193 SLIST_HEAD(,noise_keypair) r_unused_keypairs;
194 struct noise_keypair *r_next, *r_current, *r_previous;
195 struct noise_keypair r_keypair[3]; /* 3: next, current, previous. */
200 struct rwlock l_identity_lock;
202 uint8_t l_public[NOISE_KEY_SIZE];
203 uint8_t l_private[NOISE_KEY_SIZE];
205 struct noise_upcall {
207 struct noise_remote *
208 (*u_remote_get)(void *, uint8_t[NOISE_KEY_SIZE]);
210 (*u_index_set)(void *, struct noise_remote *);
211 void (*u_index_drop)(void *, uint32_t);
215 struct noise_initiation {
217 uint8_t ue[NOISE_KEY_SIZE];
218 uint8_t es[NOISE_KEY_SIZE + NOISE_MAC_SIZE];
219 uint8_t ets[NOISE_TIMESTAMP_SIZE + NOISE_MAC_SIZE];
222 struct noise_response {
225 uint8_t ue[NOISE_KEY_SIZE];
226 uint8_t en[0 + NOISE_MAC_SIZE];
236 /* Set/Get noise parameters */
237 void noise_local_init(struct noise_local *, struct noise_upcall *);
238 void noise_local_lock_identity(struct noise_local *);
239 void noise_local_unlock_identity(struct noise_local *);
240 int noise_local_set_private(struct noise_local *, uint8_t[NOISE_KEY_SIZE]);
241 int noise_local_keys(struct noise_local *, uint8_t[NOISE_KEY_SIZE],
242 uint8_t[NOISE_KEY_SIZE]);
244 void noise_remote_init(struct noise_remote *, const uint8_t[NOISE_KEY_SIZE],
245 struct noise_local *);
246 int noise_remote_set_psk(struct noise_remote *, const uint8_t[NOISE_PSK_SIZE]);
247 int noise_remote_keys(struct noise_remote *, uint8_t[NOISE_KEY_SIZE],
248 uint8_t[NOISE_PSK_SIZE]);
250 /* Should be called anytime noise_local_set_private is called */
251 void noise_remote_precompute(struct noise_remote *);
253 /* Cryptographic functions */
254 int noise_create_initiation(
255 struct noise_remote *,
256 struct noise_initiation *);
258 int noise_consume_initiation(
259 struct noise_local *,
260 struct noise_remote **,
261 struct noise_initiation *);
263 int noise_create_response(
264 struct noise_remote *,
265 struct noise_response *);
267 int noise_consume_response(
268 struct noise_remote *,
269 struct noise_response *);
271 int noise_remote_begin_session(struct noise_remote *);
272 void noise_remote_clear(struct noise_remote *);
273 void noise_remote_expire_current(struct noise_remote *);
275 int noise_remote_ready(struct noise_remote *);
277 int noise_remote_encrypt(
278 struct noise_remote *,
281 int noise_remote_decrypt(
282 struct noise_remote *,
286 #endif /* __NOISE_H__ */