dot15d4_frame/
aux_sec_header.rs

1//! Auxiliary Security Header readers and writers.
2
3// TODO: once this part is finished, remove the `allow` directive.
4#![allow(missing_docs)]
5
6/// A reader/writer for the IEEE 802.15.4 Auxiliary Security Header.
7#[derive(Debug)]
8pub struct AuxiliarySecurityHeader<T: AsRef<[u8]>> {
9    buffer: T,
10}
11
12impl<T: AsRef<[u8]>> AuxiliarySecurityHeader<T> {
13    pub fn new(buffer: T) -> Self {
14        Self { buffer }
15    }
16
17    #[allow(clippy::len_without_is_empty)]
18    pub fn len(&self) -> usize {
19        1 + self.security_control().security_level().mic_length()
20    }
21
22    pub fn security_control(&self) -> SecurityControl {
23        SecurityControl::from(self.buffer.as_ref()[0])
24    }
25}
26
27/// A reader/writer for the IEEE 802.15.4 Security Control field.
28pub struct SecurityControl {
29    buffer: u8,
30}
31
32impl SecurityControl {
33    pub fn from(buffer: u8) -> Self {
34        Self { buffer }
35    }
36
37    /// Return the security level field.
38    pub fn security_level(&self) -> SecurityLevel {
39        SecurityLevel::from(self.buffer & 0b111)
40    }
41
42    /// Return the key identifier mode field.
43    pub fn key_identifier_mode(&self) -> KeyIdentifierField {
44        KeyIdentifierField::from((self.buffer >> 3) & 0b11)
45    }
46
47    /// Returns `true` the frame counter is suppressed.
48    pub fn frame_counter_suppression(&self) -> bool {
49        (self.buffer >> 5) & 0b1 == 1
50    }
51
52    /// Returns `true` when the ASN is included in the nonce.
53    pub fn asn_in_nonce(&self) -> bool {
54        (self.buffer >> 6) & 0b1 == 1
55    }
56}
57
58/// A Security Level field.
59pub struct SecurityLevel {
60    buffer: u8,
61}
62
63impl SecurityLevel {
64    pub fn from(buffer: u8) -> Self {
65        Self { buffer }
66    }
67
68    /// Return the used Security Attributes.
69    pub fn security_attributes(&self) -> SecurityAttributes {
70        match self.buffer {
71            0 => SecurityAttributes::None,
72            1 => SecurityAttributes::Mic32,
73            2 => SecurityAttributes::Mic64,
74            3 => SecurityAttributes::Mic128,
75            5 => SecurityAttributes::EncMic32,
76            6 => SecurityAttributes::EncMic64,
77            7 => SecurityAttributes::EncMic128,
78            _ => SecurityAttributes::Unknown,
79        }
80    }
81
82    /// Return `true` when confidentiality is enabled.
83    pub fn data_confidentiality(&self) -> bool {
84        (self.buffer >> 3) & 0b1 == 1
85    }
86
87    /// Return `true` when authenticity is enabled.
88    pub fn data_authenticity(&self) -> bool {
89        self.buffer != 0
90    }
91
92    /// Return the MIC length.
93    pub fn mic_length(&self) -> usize {
94        match self.security_attributes() {
95            SecurityAttributes::Mic32 | SecurityAttributes::EncMic32 => 4,
96            SecurityAttributes::Mic64 | SecurityAttributes::EncMic64 => 8,
97            SecurityAttributes::Mic128 | SecurityAttributes::EncMic128 => 16,
98            _ => 0,
99        }
100    }
101}
102
103pub enum SecurityAttributes {
104    None,
105    Mic32,
106    Mic64,
107    Mic128,
108    EncMic32,
109    EncMic64,
110    EncMic128,
111    Unknown,
112}
113
114/// A Key Identifier Mode field.
115pub struct KeyIdentifierField {
116    buffer: u8,
117}
118
119impl KeyIdentifierField {
120    pub fn from(buffer: u8) -> Self {
121        Self { buffer }
122    }
123
124    /// Return the Key Identifier Mode.
125    pub fn key_identifier_mode(&self) -> KeyIdentifierMode {
126        match self.buffer {
127            0 => KeyIdentifierMode::Implicit,
128            1 => KeyIdentifierMode::Explicit,
129            _ => KeyIdentifierMode::Unknown,
130        }
131    }
132}
133
134pub enum KeyIdentifierMode {
135    Implicit,
136    Explicit,
137    Unknown,
138}