cl_noise_protocol/
handshakepattern.rs

1//! Handshake patterns.
2
3use arrayvec::ArrayVec;
4
5/// A token in noise message patterns.
6#[allow(missing_docs)]
7#[derive(Copy, Clone)]
8pub enum Token {
9    E,
10    S,
11    EE,
12    ES,
13    SE,
14    SS,
15    PSK,
16}
17
18use self::Token::*;
19
20/// Noise handshake pattern.
21#[derive(Clone)]
22pub struct HandshakePattern {
23    pre_i: ArrayVec<Token, 4>,
24    pre_r: ArrayVec<Token, 4>,
25    msg_patterns: ArrayVec<ArrayVec<Token, 8>, 8>,
26    name: &'static str,
27}
28
29impl HandshakePattern {
30    /// Construct a new HandshakePattern from pre-message patterns, message patterns and name.
31    ///
32    /// # Pattern validity
33    ///
34    /// It is the caller's responlity to ensure that the pattern is *valid*.
35    ///
36    /// # Panics
37    ///
38    /// If any of the patterns are too long (longer than 8 tokens).
39    ///
40    /// Or if the number of patterns are too large (larger than 8).
41    pub fn new(
42        pre_i: &[Token],
43        pre_r: &[Token],
44        msg_patterns: &[&[Token]],
45        name: &'static str,
46    ) -> Self {
47        HandshakePattern {
48            pre_i: pre_i.iter().cloned().collect(),
49            pre_r: pre_r.iter().cloned().collect(),
50            msg_patterns: msg_patterns
51                .iter()
52                .map(|p| p.iter().cloned().collect())
53                .collect(),
54            name,
55        }
56    }
57
58    /// Get initiator pre-messages.
59    pub fn get_pre_i(&self) -> &[Token] {
60        &self.pre_i
61    }
62
63    /// Get responder pre-messages.
64    pub fn get_pre_r(&self) -> &[Token] {
65        &self.pre_r
66    }
67
68    /// Get message patterns.
69    pub fn get_message_pattern(&self, i: usize) -> &[Token] {
70        &self.msg_patterns[i]
71    }
72
73    /// Get number of message patterns.
74    pub fn get_message_patterns_len(&self) -> usize {
75        self.msg_patterns.len()
76    }
77
78    /// Get pattern name.
79    pub fn get_name(&self) -> &'static str {
80        self.name
81    }
82
83    /// Whether there are any psk tokens in this pattern.
84    pub fn has_psk(&self) -> bool {
85        self.msg_patterns
86            .iter()
87            .any(|m| m.iter().any(|m| matches!(m, Token::PSK)))
88    }
89
90    /// Whether the pattern is a one-way pattern.
91    pub fn is_one_way(&self) -> bool {
92        self.msg_patterns.len() == 1
93    }
94
95    fn with_psks(&self, poses: &[usize], new_name: &'static str) -> HandshakePattern {
96        let mut new_msg_patterns = self.msg_patterns.clone();
97        for pos in poses {
98            if *pos == 0usize {
99                new_msg_patterns[0].insert(0, PSK);
100            } else {
101                new_msg_patterns[pos - 1].push(PSK);
102            }
103        }
104        HandshakePattern {
105            pre_i: self.pre_i.clone(),
106            pre_r: self.pre_r.clone(),
107            msg_patterns: new_msg_patterns,
108            name: new_name,
109        }
110    }
111}
112
113macro_rules! vec {
114    () => {
115        ArrayVec::new()
116    };
117    ( $( $x:expr ),* ) => {
118        {
119            let mut temp_vec = ArrayVec::new();
120            $(
121                temp_vec.push($x);
122            )*
123            temp_vec
124        }
125    };
126}
127
128/// The `Noise_N` pattern.
129pub fn noise_n() -> HandshakePattern {
130    HandshakePattern {
131        pre_i: vec![],
132        pre_r: vec![S],
133        msg_patterns: vec![vec![E, ES]],
134        name: "N",
135    }
136}
137
138/// The `Noise_K` pattern.
139pub fn noise_k() -> HandshakePattern {
140    HandshakePattern {
141        pre_i: vec![S],
142        pre_r: vec![S],
143        msg_patterns: vec![vec![E, ES, SS]],
144        name: "K",
145    }
146}
147
148/// The `Noise_X` pattern.
149pub fn noise_x() -> HandshakePattern {
150    HandshakePattern {
151        pre_i: vec![],
152        pre_r: vec![S],
153        msg_patterns: vec![vec![E, ES, S, SS]],
154        name: "X",
155    }
156}
157
158/// The `Noise_NN` pattern.
159pub fn noise_nn() -> HandshakePattern {
160    HandshakePattern {
161        pre_i: vec![],
162        pre_r: vec![],
163        msg_patterns: vec![vec![E], vec![E, EE]],
164        name: "NN",
165    }
166}
167
168/// The `Noise_NK` pattern.
169pub fn noise_nk() -> HandshakePattern {
170    HandshakePattern {
171        pre_i: vec![],
172        pre_r: vec![S],
173        msg_patterns: vec![vec![E, ES], vec![E, EE]],
174        name: "NK",
175    }
176}
177
178/// The `Noise_NX` pattern.
179pub fn noise_nx() -> HandshakePattern {
180    HandshakePattern {
181        pre_i: vec![],
182        pre_r: vec![],
183        msg_patterns: vec![vec![E], vec![E, EE, S, ES]],
184        name: "NX",
185    }
186}
187
188/// The `Noise_XN` pattern.
189pub fn noise_xn() -> HandshakePattern {
190    HandshakePattern {
191        pre_i: vec![],
192        pre_r: vec![],
193        msg_patterns: vec![vec![E], vec![E, EE], vec![S, SE]],
194        name: "XN",
195    }
196}
197
198/// The `Noise_XK` pattern.
199pub fn noise_xk() -> HandshakePattern {
200    HandshakePattern {
201        pre_i: vec![],
202        pre_r: vec![S],
203        msg_patterns: vec![vec![E, ES], vec![E, EE], vec![S, SE]],
204        name: "XK",
205    }
206}
207
208/// The `Noise_XX` pattern.
209pub fn noise_xx() -> HandshakePattern {
210    HandshakePattern {
211        pre_i: vec![],
212        pre_r: vec![],
213        msg_patterns: vec![vec![E], vec![E, EE, S, ES], vec![S, SE]],
214        name: "XX",
215    }
216}
217
218/// The `Noise_KN` pattern.
219pub fn noise_kn() -> HandshakePattern {
220    HandshakePattern {
221        pre_i: vec![S],
222        pre_r: vec![],
223        msg_patterns: vec![vec![E], vec![E, EE, SE]],
224        name: "KN",
225    }
226}
227
228/// The `Noise_KK` pattern.
229pub fn noise_kk() -> HandshakePattern {
230    HandshakePattern {
231        pre_i: vec![S],
232        pre_r: vec![S],
233        msg_patterns: vec![vec![E, ES, SS], vec![E, EE, SE]],
234        name: "KK",
235    }
236}
237
238/// The `Noise_KX` pattern.
239pub fn noise_kx() -> HandshakePattern {
240    HandshakePattern {
241        pre_i: vec![S],
242        pre_r: vec![],
243        msg_patterns: vec![vec![E], vec![E, EE, SE, S, ES]],
244        name: "KX",
245    }
246}
247
248/// The `Noise_IN` pattern.
249pub fn noise_in() -> HandshakePattern {
250    HandshakePattern {
251        pre_i: vec![],
252        pre_r: vec![],
253        msg_patterns: vec![vec![E, S], vec![E, EE, SE]],
254        name: "IN",
255    }
256}
257
258/// The `Noise_IK` pattern.
259pub fn noise_ik() -> HandshakePattern {
260    HandshakePattern {
261        pre_i: vec![],
262        pre_r: vec![S],
263        msg_patterns: vec![vec![E, ES, S, SS], vec![E, EE, SE]],
264        name: "IK",
265    }
266}
267
268/// The `Noise_IX` pattern.
269pub fn noise_ix() -> HandshakePattern {
270    HandshakePattern {
271        pre_i: vec![],
272        pre_r: vec![],
273        msg_patterns: vec![vec![E, S], vec![E, EE, SE, S, ES]],
274        name: "IX",
275    }
276}
277
278/// The `Noise_XXfallback` pattern.
279///
280/// Something that is used in noise pipes.
281pub fn noise_xx_fallback() -> HandshakePattern {
282    HandshakePattern {
283        pre_i: vec![],
284        pre_r: vec![E],
285        msg_patterns: vec![vec![E, EE, S, SE], vec![S, ES]],
286        name: "XXfallback",
287    }
288}
289
290// PSK Patterns.
291
292/// The `Noise_Npsk0` pattern.
293pub fn noise_n_psk0() -> HandshakePattern {
294    noise_n().with_psks(&[0], "Npsk0")
295}
296
297/// The `Noise_Kpsk0` pattern.
298pub fn noise_k_psk0() -> HandshakePattern {
299    noise_k().with_psks(&[0], "Kpsk0")
300}
301
302/// The `Noise_Xpsk1` pattern.
303pub fn noise_x_psk1() -> HandshakePattern {
304    noise_x().with_psks(&[1], "Xpsk1")
305}
306
307/// The `Noise_NNpsk0` pattern.
308pub fn noise_nn_psk0() -> HandshakePattern {
309    noise_nn().with_psks(&[0], "NNpsk0")
310}
311
312/// The `Noise_NNpsk2` pattern.
313pub fn noise_nn_psk2() -> HandshakePattern {
314    noise_nn().with_psks(&[2], "NNpsk2")
315}
316
317/// The `Noise_NKpsk0` pattern.
318pub fn noise_nk_psk0() -> HandshakePattern {
319    noise_nk().with_psks(&[0], "NKpsk0")
320}
321
322/// The `Noise_NKpsk2` pattern.
323pub fn noise_nk_psk2() -> HandshakePattern {
324    noise_nk().with_psks(&[2], "NKpsk2")
325}
326
327/// The `Noise_NXpsk2` pattern.
328pub fn noise_nx_psk2() -> HandshakePattern {
329    noise_nx().with_psks(&[2], "NXpsk2")
330}
331
332/// The `Noise_XNpsk3` pattern.
333pub fn noise_xn_psk3() -> HandshakePattern {
334    noise_xn().with_psks(&[3], "XNpsk3")
335}
336
337/// The `Noise_XKpsk3` pattern.
338pub fn noise_xk_psk3() -> HandshakePattern {
339    noise_xk().with_psks(&[3], "XKpsk3")
340}
341
342/// The `Noise_XXpsk3` pattern.
343pub fn noise_xx_psk3() -> HandshakePattern {
344    noise_xx().with_psks(&[3], "XXpsk3")
345}
346
347/// The `Noise_KNpsk0` pattern.
348pub fn noise_kn_psk0() -> HandshakePattern {
349    noise_kn().with_psks(&[0], "KNpsk0")
350}
351
352/// The `Noise_KNpsk2` pattern.
353pub fn noise_kn_psk2() -> HandshakePattern {
354    noise_kn().with_psks(&[2], "KNpsk2")
355}
356
357/// The `Noise_KKpsk0` pattern.
358pub fn noise_kk_psk0() -> HandshakePattern {
359    noise_kk().with_psks(&[0], "KKpsk0")
360}
361
362/// The `Noise_KKpsk2` pattern.
363pub fn noise_kk_psk2() -> HandshakePattern {
364    noise_kk().with_psks(&[2], "KKpsk2")
365}
366
367/// The `Noise_KXpsk2` pattern.
368pub fn noise_kx_psk2() -> HandshakePattern {
369    noise_kx().with_psks(&[2], "KXpsk2")
370}
371
372/// The `Noise_INpsk1` pattern.
373pub fn noise_in_psk1() -> HandshakePattern {
374    noise_in().with_psks(&[1], "INpsk1")
375}
376
377/// The `Noise_INpsk2` pattern.
378pub fn noise_in_psk2() -> HandshakePattern {
379    noise_in().with_psks(&[2], "INpsk2")
380}
381
382/// The `Noise_IKpsk1` pattern.
383pub fn noise_ik_psk1() -> HandshakePattern {
384    noise_ik().with_psks(&[1], "IKpsk1")
385}
386
387/// The `Noise_IKpsk2` pattern.
388pub fn noise_ik_psk2() -> HandshakePattern {
389    noise_ik().with_psks(&[2], "IKpsk2")
390}
391
392/// The `Noise_IXpsk2` pattern.
393pub fn noise_ix_psk2() -> HandshakePattern {
394    noise_ix().with_psks(&[2], "IXpsk2")
395}
396
397/// The `Noise_NNpsk0+psk2` pattern.
398pub fn noise_nn_psk0_psk2() -> HandshakePattern {
399    noise_nn().with_psks(&[0, 2], "NNpsk0+psk2")
400}
401
402/// The `Noise_NXpsk0+psk1+psk2` pattern.
403pub fn noise_nx_psk0_psk1_psk2() -> HandshakePattern {
404    noise_nx().with_psks(&[0, 1, 2], "NXpsk0+psk1+psk2")
405}
406
407/// The `Noise_XNpsk1+psk3` pattern.
408pub fn noise_xn_psk1_psk3() -> HandshakePattern {
409    noise_xn().with_psks(&[1, 3], "XNpsk1+psk3")
410}
411
412/// The `Noise_XKpsk0+psk3` pattern.
413pub fn noise_xk_psk0_psk3() -> HandshakePattern {
414    noise_xk().with_psks(&[0, 3], "XKpsk0+psk3")
415}
416
417/// The `Noise_KNpsk1+psk2` pattern.
418pub fn noise_kn_psk1_psk2() -> HandshakePattern {
419    noise_kn().with_psks(&[1, 2], "KNpsk1+psk2")
420}
421
422/// The `Noise_KKpsk0+psk2` pattern
423pub fn noise_kk_psk0_psk2() -> HandshakePattern {
424    noise_kk().with_psks(&[0, 2], "KKpsk0+psk2")
425}
426
427/// The `Noise_INpsk1+psk2` pattern.
428pub fn noise_in_psk1_psk2() -> HandshakePattern {
429    noise_in().with_psks(&[1, 2], "INpsk1+psk2")
430}
431
432/// The `Noise_IKpsk0+psk2` pattern.
433pub fn noise_ik_psk0_psk2() -> HandshakePattern {
434    noise_ik().with_psks(&[0, 2], "IKpsk0+psk2")
435}
436
437/// The `Noise_IXpsk0+psk2` pattern.
438pub fn noise_ix_psk0_psk2() -> HandshakePattern {
439    noise_ix().with_psks(&[0, 2], "IXpsk0+psk2")
440}
441
442/// The `Noise_XXpsk0+psk1` pattern.
443pub fn noise_xx_psk0_psk1() -> HandshakePattern {
444    noise_xx().with_psks(&[0, 1], "XXpsk0+psk1")
445}
446
447/// The `Noise_XXpsk0+psk2` pattern.
448pub fn noise_xx_psk0_psk2() -> HandshakePattern {
449    noise_xx().with_psks(&[0, 2], "XXpsk0+psk2")
450}
451
452/// The `Noise_XXpsk0+psk3` pattern.
453pub fn noise_xx_psk0_psk3() -> HandshakePattern {
454    noise_xx().with_psks(&[0, 3], "XXpsk0+psk3")
455}
456
457/// The `Noise_XXpsk0+psk1+psk2+psk3` pattern.
458pub fn noise_xx_psk0_psk1_psk2_psk3() -> HandshakePattern {
459    noise_xx().with_psks(&[0, 1, 2, 3], "XXpsk0+psk1+psk2+psk3")
460}