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.iter().any(|m| {
86            m.iter().any(|m| match m {
87                Token::PSK => true,
88                _ => false,
89            })
90        })
91    }
92
93    /// Whether the pattern is a one-way pattern.
94    pub fn is_one_way(&self) -> bool {
95        self.msg_patterns.len() == 1
96    }
97
98    fn with_psks(&self, poses: &[usize], new_name: &'static str) -> HandshakePattern {
99        let mut new_msg_patterns = self.msg_patterns.clone();
100        for pos in poses {
101            if *pos == 0usize {
102                new_msg_patterns[0].insert(0, PSK);
103            } else {
104                new_msg_patterns[pos - 1].push(PSK);
105            }
106        }
107        HandshakePattern {
108            pre_i: self.pre_i.clone(),
109            pre_r: self.pre_r.clone(),
110            msg_patterns: new_msg_patterns,
111            name: new_name,
112        }
113    }
114}
115
116macro_rules! vec {
117    () => {
118        ArrayVec::new()
119    };
120    ( $( $x:expr ),* ) => {
121        {
122            let mut temp_vec = ArrayVec::new();
123            $(
124                temp_vec.push($x);
125            )*
126            temp_vec
127        }
128    };
129}
130
131/// The `Noise_N` pattern.
132pub fn noise_n() -> HandshakePattern {
133    HandshakePattern {
134        pre_i: vec![],
135        pre_r: vec![S],
136        msg_patterns: vec![vec![E, ES]],
137        name: "N",
138    }
139}
140
141/// The `Noise_K` pattern.
142pub fn noise_k() -> HandshakePattern {
143    HandshakePattern {
144        pre_i: vec![S],
145        pre_r: vec![S],
146        msg_patterns: vec![vec![E, ES, SS]],
147        name: "K",
148    }
149}
150
151/// The `Noise_X` pattern.
152pub fn noise_x() -> HandshakePattern {
153    HandshakePattern {
154        pre_i: vec![],
155        pre_r: vec![S],
156        msg_patterns: vec![vec![E, ES, S, SS]],
157        name: "X",
158    }
159}
160
161/// The `Noise_NN` pattern.
162pub fn noise_nn() -> HandshakePattern {
163    HandshakePattern {
164        pre_i: vec![],
165        pre_r: vec![],
166        msg_patterns: vec![vec![E], vec![E, EE]],
167        name: "NN",
168    }
169}
170
171/// The `Noise_NK` pattern.
172pub fn noise_nk() -> HandshakePattern {
173    HandshakePattern {
174        pre_i: vec![],
175        pre_r: vec![S],
176        msg_patterns: vec![vec![E, ES], vec![E, EE]],
177        name: "NK",
178    }
179}
180
181/// The `Noise_NX` pattern.
182pub fn noise_nx() -> HandshakePattern {
183    HandshakePattern {
184        pre_i: vec![],
185        pre_r: vec![],
186        msg_patterns: vec![vec![E], vec![E, EE, S, ES]],
187        name: "NX",
188    }
189}
190
191/// The `Noise_XN` pattern.
192pub fn noise_xn() -> HandshakePattern {
193    HandshakePattern {
194        pre_i: vec![],
195        pre_r: vec![],
196        msg_patterns: vec![vec![E], vec![E, EE], vec![S, SE]],
197        name: "XN",
198    }
199}
200
201/// The `Noise_XK` pattern.
202pub fn noise_xk() -> HandshakePattern {
203    HandshakePattern {
204        pre_i: vec![],
205        pre_r: vec![S],
206        msg_patterns: vec![vec![E, ES], vec![E, EE], vec![S, SE]],
207        name: "XK",
208    }
209}
210
211/// The `Noise_XX` pattern.
212pub fn noise_xx() -> HandshakePattern {
213    HandshakePattern {
214        pre_i: vec![],
215        pre_r: vec![],
216        msg_patterns: vec![vec![E], vec![E, EE, S, ES], vec![S, SE]],
217        name: "XX",
218    }
219}
220
221/// The `Noise_KN` pattern.
222pub fn noise_kn() -> HandshakePattern {
223    HandshakePattern {
224        pre_i: vec![S],
225        pre_r: vec![],
226        msg_patterns: vec![vec![E], vec![E, EE, SE]],
227        name: "KN",
228    }
229}
230
231/// The `Noise_KK` pattern.
232pub fn noise_kk() -> HandshakePattern {
233    HandshakePattern {
234        pre_i: vec![S],
235        pre_r: vec![S],
236        msg_patterns: vec![vec![E, ES, SS], vec![E, EE, SE]],
237        name: "KK",
238    }
239}
240
241/// The `Noise_KX` pattern.
242pub fn noise_kx() -> HandshakePattern {
243    HandshakePattern {
244        pre_i: vec![S],
245        pre_r: vec![],
246        msg_patterns: vec![vec![E], vec![E, EE, SE, S, ES]],
247        name: "KX",
248    }
249}
250
251/// The `Noise_IN` pattern.
252pub fn noise_in() -> HandshakePattern {
253    HandshakePattern {
254        pre_i: vec![],
255        pre_r: vec![],
256        msg_patterns: vec![vec![E, S], vec![E, EE, SE]],
257        name: "IN",
258    }
259}
260
261/// The `Noise_IK` pattern.
262pub fn noise_ik() -> HandshakePattern {
263    HandshakePattern {
264        pre_i: vec![],
265        pre_r: vec![S],
266        msg_patterns: vec![vec![E, ES, S, SS], vec![E, EE, SE]],
267        name: "IK",
268    }
269}
270
271/// The `Noise_IX` pattern.
272pub fn noise_ix() -> HandshakePattern {
273    HandshakePattern {
274        pre_i: vec![],
275        pre_r: vec![],
276        msg_patterns: vec![vec![E, S], vec![E, EE, SE, S, ES]],
277        name: "IX",
278    }
279}
280
281/// The `Noise_XXfallback` pattern.
282///
283/// Something that is used in noise pipes.
284pub fn noise_xx_fallback() -> HandshakePattern {
285    HandshakePattern {
286        pre_i: vec![],
287        pre_r: vec![E],
288        msg_patterns: vec![vec![E, EE, S, SE], vec![S, ES]],
289        name: "XXfallback",
290    }
291}
292
293// PSK Patterns.
294
295/// The `Noise_Npsk0` pattern.
296pub fn noise_n_psk0() -> HandshakePattern {
297    noise_n().with_psks(&[0], "Npsk0")
298}
299
300/// The `Noise_Kpsk0` pattern.
301pub fn noise_k_psk0() -> HandshakePattern {
302    noise_k().with_psks(&[0], "Kpsk0")
303}
304
305/// The `Noise_Xpsk1` pattern.
306pub fn noise_x_psk1() -> HandshakePattern {
307    noise_x().with_psks(&[1], "Xpsk1")
308}
309
310/// The `Noise_NNpsk0` pattern.
311pub fn noise_nn_psk0() -> HandshakePattern {
312    noise_nn().with_psks(&[0], "NNpsk0")
313}
314
315/// The `Noise_NNpsk2` pattern.
316pub fn noise_nn_psk2() -> HandshakePattern {
317    noise_nn().with_psks(&[2], "NNpsk2")
318}
319
320/// The `Noise_NKpsk0` pattern.
321pub fn noise_nk_psk0() -> HandshakePattern {
322    noise_nk().with_psks(&[0], "NKpsk0")
323}
324
325/// The `Noise_NKpsk2` pattern.
326pub fn noise_nk_psk2() -> HandshakePattern {
327    noise_nk().with_psks(&[2], "NKpsk2")
328}
329
330/// The `Noise_NXpsk2` pattern.
331pub fn noise_nx_psk2() -> HandshakePattern {
332    noise_nx().with_psks(&[2], "NXpsk2")
333}
334
335/// The `Noise_XNpsk3` pattern.
336pub fn noise_xn_psk3() -> HandshakePattern {
337    noise_xn().with_psks(&[3], "XNpsk3")
338}
339
340/// The `Noise_XKpsk3` pattern.
341pub fn noise_xk_psk3() -> HandshakePattern {
342    noise_xk().with_psks(&[3], "XKpsk3")
343}
344
345/// The `Noise_XXpsk3` pattern.
346pub fn noise_xx_psk3() -> HandshakePattern {
347    noise_xx().with_psks(&[3], "XXpsk3")
348}
349
350/// The `Noise_KNpsk0` pattern.
351pub fn noise_kn_psk0() -> HandshakePattern {
352    noise_kn().with_psks(&[0], "KNpsk0")
353}
354
355/// The `Noise_KNpsk2` pattern.
356pub fn noise_kn_psk2() -> HandshakePattern {
357    noise_kn().with_psks(&[2], "KNpsk2")
358}
359
360/// The `Noise_KKpsk0` pattern.
361pub fn noise_kk_psk0() -> HandshakePattern {
362    noise_kk().with_psks(&[0], "KKpsk0")
363}
364
365/// The `Noise_KKpsk2` pattern.
366pub fn noise_kk_psk2() -> HandshakePattern {
367    noise_kk().with_psks(&[2], "KKpsk2")
368}
369
370/// The `Noise_KXpsk2` pattern.
371pub fn noise_kx_psk2() -> HandshakePattern {
372    noise_kx().with_psks(&[2], "KXpsk2")
373}
374
375/// The `Noise_INpsk1` pattern.
376pub fn noise_in_psk1() -> HandshakePattern {
377    noise_in().with_psks(&[1], "INpsk1")
378}
379
380/// The `Noise_INpsk2` pattern.
381pub fn noise_in_psk2() -> HandshakePattern {
382    noise_in().with_psks(&[2], "INpsk2")
383}
384
385/// The `Noise_IKpsk1` pattern.
386pub fn noise_ik_psk1() -> HandshakePattern {
387    noise_ik().with_psks(&[1], "IKpsk1")
388}
389
390/// The `Noise_IKpsk2` pattern.
391pub fn noise_ik_psk2() -> HandshakePattern {
392    noise_ik().with_psks(&[2], "IKpsk2")
393}
394
395/// The `Noise_IXpsk2` pattern.
396pub fn noise_ix_psk2() -> HandshakePattern {
397    noise_ix().with_psks(&[2], "IXpsk2")
398}
399
400/// The `Noise_NNpsk0+psk2` pattern.
401pub fn noise_nn_psk0_psk2() -> HandshakePattern {
402    noise_nn().with_psks(&[0, 2], "NNpsk0+psk2")
403}
404
405/// The `Noise_NXpsk0+psk1+psk2` pattern.
406pub fn noise_nx_psk0_psk1_psk2() -> HandshakePattern {
407    noise_nx().with_psks(&[0, 1, 2], "NXpsk0+psk1+psk2")
408}
409
410/// The `Noise_XNpsk1+psk3` pattern.
411pub fn noise_xn_psk1_psk3() -> HandshakePattern {
412    noise_xn().with_psks(&[1, 3], "XNpsk1+psk3")
413}
414
415/// The `Noise_XKpsk0+psk3` pattern.
416pub fn noise_xk_psk0_psk3() -> HandshakePattern {
417    noise_xk().with_psks(&[0, 3], "XKpsk0+psk3")
418}
419
420/// The `Noise_KNpsk1+psk2` pattern.
421pub fn noise_kn_psk1_psk2() -> HandshakePattern {
422    noise_kn().with_psks(&[1, 2], "KNpsk1+psk2")
423}
424
425/// The `Noise_KKpsk0+psk2` pattern
426pub fn noise_kk_psk0_psk2() -> HandshakePattern {
427    noise_kk().with_psks(&[0, 2], "KKpsk0+psk2")
428}
429
430/// The `Noise_INpsk1+psk2` pattern.
431pub fn noise_in_psk1_psk2() -> HandshakePattern {
432    noise_in().with_psks(&[1, 2], "INpsk1+psk2")
433}
434
435/// The `Noise_IKpsk0+psk2` pattern.
436pub fn noise_ik_psk0_psk2() -> HandshakePattern {
437    noise_ik().with_psks(&[0, 2], "IKpsk0+psk2")
438}
439
440/// The `Noise_IXpsk0+psk2` pattern.
441pub fn noise_ix_psk0_psk2() -> HandshakePattern {
442    noise_ix().with_psks(&[0, 2], "IXpsk0+psk2")
443}
444
445/// The `Noise_XXpsk0+psk1` pattern.
446pub fn noise_xx_psk0_psk1() -> HandshakePattern {
447    noise_xx().with_psks(&[0, 1], "XXpsk0+psk1")
448}
449
450/// The `Noise_XXpsk0+psk2` pattern.
451pub fn noise_xx_psk0_psk2() -> HandshakePattern {
452    noise_xx().with_psks(&[0, 2], "XXpsk0+psk2")
453}
454
455/// The `Noise_XXpsk0+psk3` pattern.
456pub fn noise_xx_psk0_psk3() -> HandshakePattern {
457    noise_xx().with_psks(&[0, 3], "XXpsk0+psk3")
458}
459
460/// The `Noise_XXpsk0+psk1+psk2+psk3` pattern.
461pub fn noise_xx_psk0_psk1_psk2_psk3() -> HandshakePattern {
462    noise_xx().with_psks(&[0, 1, 2, 3], "XXpsk0+psk1+psk2+psk3")
463}