-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnoise.h
More file actions
203 lines (166 loc) · 6.67 KB
/
Copy pathnoise.h
File metadata and controls
203 lines (166 loc) · 6.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2015-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
*/
#ifndef _WG_NOISE_H
#define _WG_NOISE_H
#include "messages.h"
#include "peerlookup.h"
#include <linux/types.h>
#include <linux/spinlock.h>
#include <linux/atomic.h>
#include <linux/rwsem.h>
#include <linux/mutex.h>
#include <linux/kref.h>
struct noise_replay_counter {
u64 counter;
spinlock_t lock;
unsigned long backtrack[COUNTER_BITS_TOTAL / BITS_PER_LONG];
};
struct noise_symmetric_key {
u8 key[NOISE_SYMMETRIC_KEY_LEN];
u64 birthdate;
bool is_valid;
};
struct noise_keypair {
struct index_hashtable_entry entry;
struct noise_symmetric_key sending;
atomic64_t sending_counter;
struct noise_symmetric_key receiving;
struct noise_replay_counter receiving_counter;
__le32 remote_index;
bool i_am_the_initiator;
struct kref refcount;
struct rcu_head rcu;
u64 internal_id;
};
struct noise_keypairs {
struct noise_keypair __rcu *current_keypair;
struct noise_keypair __rcu *previous_keypair;
struct noise_keypair __rcu *next_keypair;
spinlock_t keypair_update_lock;
};
struct noise_static_identity {
u8 static_public[NOISE_PUBLIC_KEY_LEN];
u8 static_private[NOISE_PUBLIC_KEY_LEN];
struct rw_semaphore lock;
bool has_identity;
/* PQC (ML-KEM-512) keys */
u8 *pqc_static_public; /* MLKEM512_PUBLIC_KEY_LEN */
u8 *pqc_static_secret; /* MLKEM512_SECRET_KEY_LEN */
bool has_pqc_identity;
/* PQC seed for deterministic key generation */
u8 pqc_seed[128];
size_t pqc_seed_len;
bool has_pqc_seed;
/* ML-DSA-44 signing keys (derived from seed) */
u8 *mldsa_signing_key; /* ML-DSA-44 secret key (2560 bytes) */
u8 *mldsa_verify_key; /* ML-DSA-44 public key (1312 bytes) */
bool has_mldsa_identity;
/* Interface identifier for authentication */
char interface_id[64];
};
enum noise_handshake_state {
HANDSHAKE_ZEROED,
HANDSHAKE_CREATED_INITIATION,
HANDSHAKE_CONSUMED_INITIATION,
HANDSHAKE_CREATED_RESPONSE,
HANDSHAKE_CONSUMED_RESPONSE
};
struct noise_handshake {
struct index_hashtable_entry entry;
enum noise_handshake_state state;
u64 last_initiation_consumption;
struct noise_static_identity *static_identity;
u8 ephemeral_private[NOISE_PUBLIC_KEY_LEN];
u8 remote_static[NOISE_PUBLIC_KEY_LEN];
u8 remote_ephemeral[NOISE_PUBLIC_KEY_LEN];
u8 precomputed_static_static[NOISE_PUBLIC_KEY_LEN];
u8 preshared_key[NOISE_SYMMETRIC_KEY_LEN];
u8 hash[NOISE_HASH_LEN];
u8 chaining_key[NOISE_HASH_LEN];
u8 latest_timestamp[NOISE_TIMESTAMP_LEN];
__le32 remote_index;
/* PQC (ML-KEM-512) handshake keys */
u8 *pqc_ephemeral_public; /* MLKEM512_PUBLIC_KEY_LEN */
u8 *pqc_ephemeral_secret; /* MLKEM512_SECRET_KEY_LEN */
u8 *pqc_remote_static; /* MLKEM512_PUBLIC_KEY_LEN */
u8 *pqc_remote_ephemeral; /* MLKEM512_PUBLIC_KEY_LEN */
u8 *pqc_ciphertext; /* MLKEM512_CIPHERTEXT_LEN */
u8 *pqc_shared_secret; /* MLKEM512_SHARED_SECRET_LEN */
/* PQC peer seed for deterministic remote key derivation */
u8 pqc_peer_seed[128];
size_t pqc_peer_seed_len;
bool has_pqc_peer_seed;
/* Peer's ML-DSA verification key */
u8 *mldsa_remote_verify_key; /* ML-DSA-44 public key of peer (1312 bytes) */
char peer_id[64]; /* Peer identifier from JSON */
/* Protects all members except the immutable (after noise_handshake_
* init): remote_static, precomputed_static_static, static_identity.
*/
struct rw_semaphore lock;
};
struct wg_device;
void wg_noise_init(void);
void wg_noise_handshake_init(struct noise_handshake *handshake,
struct noise_static_identity *static_identity,
const u8 peer_public_key[NOISE_PUBLIC_KEY_LEN],
const u8 peer_preshared_key[NOISE_SYMMETRIC_KEY_LEN],
struct wg_peer *peer);
void wg_noise_handshake_clear(struct noise_handshake *handshake);
static inline void wg_noise_reset_last_sent_handshake(atomic64_t *handshake_ns)
{
atomic64_set(handshake_ns, ktime_get_coarse_boottime_ns() -
(u64)(REKEY_TIMEOUT + 1) * NSEC_PER_SEC);
}
void wg_noise_keypair_put(struct noise_keypair *keypair, bool unreference_now);
struct noise_keypair *wg_noise_keypair_get(struct noise_keypair *keypair);
void wg_noise_keypairs_clear(struct noise_keypairs *keypairs);
bool wg_noise_received_with_keypair(struct noise_keypairs *keypairs,
struct noise_keypair *received_keypair);
void wg_noise_expire_current_peer_keypairs(struct wg_peer *peer);
void wg_noise_set_static_identity_private_key(
struct noise_static_identity *static_identity,
const u8 private_key[NOISE_PUBLIC_KEY_LEN]);
void wg_noise_precompute_static_static(struct wg_peer *peer);
/* PQC seed-based key generation */
int wg_noise_set_pqc_seed(struct noise_static_identity *identity,
const u8 *seed, size_t seed_len);
int wg_noise_set_peer_pqc_seed(struct noise_handshake *handshake,
const u8 *seed, size_t seed_len);
void wg_noise_clear_pqc_seed(struct noise_static_identity *identity);
void wg_noise_clear_peer_pqc_seed(struct noise_handshake *handshake);
bool
wg_noise_handshake_create_initiation(struct message_handshake_initiation *dst,
struct noise_handshake *handshake);
struct wg_peer *
wg_noise_handshake_consume_initiation(struct message_handshake_initiation *src,
struct wg_device *wg);
bool wg_noise_handshake_create_response(struct message_handshake_response *dst,
struct noise_handshake *handshake);
struct wg_peer *
wg_noise_handshake_consume_response(struct message_handshake_response *src,
struct wg_device *wg);
bool wg_noise_handshake_begin_session(struct noise_handshake *handshake,
struct noise_keypairs *keypairs);
/* PQC (ML-KEM-512) handshake functions */
int wg_noise_pqc_init_identity(struct noise_static_identity *identity);
void wg_noise_pqc_clear_identity(struct noise_static_identity *identity);
int wg_noise_pqc_init_handshake(struct noise_handshake *handshake);
void wg_noise_pqc_clear_handshake(struct noise_handshake *handshake);
/* ML-KEM-512 crypto wrapper */
int mlkem512_keypair(uint8_t *pk, uint8_t *sk);
int wg_noise_set_pqc_static_keys(struct noise_static_identity *identity,
const u8 *public_key,
const u8 *secret_key);
int wg_noise_set_pqc_remote_static(struct noise_handshake *handshake,
const u8 *public_key);
bool wg_noise_pqc_handshake_create_initiation(struct message_pqc_initiation *dst,
struct noise_handshake *handshake);
struct wg_peer *wg_noise_pqc_handshake_consume_initiation(struct message_pqc_initiation *src,
struct wg_device *wg);
bool wg_noise_pqc_handshake_create_response(struct message_pqc_response *dst,
struct noise_handshake *handshake);
struct wg_peer *wg_noise_pqc_handshake_consume_response(struct message_pqc_response *src,
struct wg_device *wg);
#endif /* _WG_NOISE_H */