dot15d4_frame/
aux_sec_header.rs

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
//! Auxiliary Security Header readers and writers.

// TODO: once this part is finished, remove the `allow` directive.
#![allow(missing_docs)]

/// A reader/writer for the IEEE 802.15.4 Auxiliary Security Header.
#[derive(Debug)]
pub struct AuxiliarySecurityHeader<T: AsRef<[u8]>> {
    buffer: T,
}

impl<T: AsRef<[u8]>> AuxiliarySecurityHeader<T> {
    pub fn new(buffer: T) -> Self {
        Self { buffer }
    }

    #[allow(clippy::len_without_is_empty)]
    pub fn len(&self) -> usize {
        1 + self.security_control().security_level().mic_length()
    }

    pub fn security_control(&self) -> SecurityControl {
        SecurityControl::from(self.buffer.as_ref()[0])
    }
}

/// A reader/writer for the IEEE 802.15.4 Security Control field.
pub struct SecurityControl {
    buffer: u8,
}

impl SecurityControl {
    pub fn from(buffer: u8) -> Self {
        Self { buffer }
    }

    /// Return the security level field.
    pub fn security_level(&self) -> SecurityLevel {
        SecurityLevel::from(self.buffer & 0b111)
    }

    /// Return the key identifier mode field.
    pub fn key_identifier_mode(&self) -> KeyIdentifierField {
        KeyIdentifierField::from((self.buffer >> 3) & 0b11)
    }

    /// Returns `true` the frame counter is suppressed.
    pub fn frame_counter_suppression(&self) -> bool {
        (self.buffer >> 5) & 0b1 == 1
    }

    /// Returns `true` when the ASN is included in the nonce.
    pub fn asn_in_nonce(&self) -> bool {
        (self.buffer >> 6) & 0b1 == 1
    }
}

/// A Security Level field.
pub struct SecurityLevel {
    buffer: u8,
}

impl SecurityLevel {
    pub fn from(buffer: u8) -> Self {
        Self { buffer }
    }

    /// Return the used Security Attributes.
    pub fn security_attributes(&self) -> SecurityAttributes {
        match self.buffer {
            0 => SecurityAttributes::None,
            1 => SecurityAttributes::Mic32,
            2 => SecurityAttributes::Mic64,
            3 => SecurityAttributes::Mic128,
            5 => SecurityAttributes::EncMic32,
            6 => SecurityAttributes::EncMic64,
            7 => SecurityAttributes::EncMic128,
            _ => SecurityAttributes::Unknown,
        }
    }

    /// Return `true` when confidentiality is enabled.
    pub fn data_confidentiality(&self) -> bool {
        (self.buffer >> 3) & 0b1 == 1
    }

    /// Return `true` when authenticity is enabled.
    pub fn data_authenticity(&self) -> bool {
        self.buffer != 0
    }

    /// Return the MIC length.
    pub fn mic_length(&self) -> usize {
        match self.security_attributes() {
            SecurityAttributes::Mic32 | SecurityAttributes::EncMic32 => 4,
            SecurityAttributes::Mic64 | SecurityAttributes::EncMic64 => 8,
            SecurityAttributes::Mic128 | SecurityAttributes::EncMic128 => 16,
            _ => 0,
        }
    }
}

pub enum SecurityAttributes {
    None,
    Mic32,
    Mic64,
    Mic128,
    EncMic32,
    EncMic64,
    EncMic128,
    Unknown,
}

/// A Key Identifier Mode field.
pub struct KeyIdentifierField {
    buffer: u8,
}

impl KeyIdentifierField {
    pub fn from(buffer: u8) -> Self {
        Self { buffer }
    }

    /// Return the Key Identifier Mode.
    pub fn key_identifier_mode(&self) -> KeyIdentifierMode {
        match self.buffer {
            0 => KeyIdentifierMode::Implicit,
            1 => KeyIdentifierMode::Explicit,
            _ => KeyIdentifierMode::Unknown,
        }
    }
}

pub enum KeyIdentifierMode {
    Implicit,
    Explicit,
    Unknown,
}