Skip to content

Commit 169f252

Browse files
authored
Merge pull request #38 from datdenkikniet/security_features
Security features
2 parents c1b747f + 1d8198d commit 169f252

File tree

9 files changed

+1954
-77
lines changed

9 files changed

+1954
-77
lines changed

Cargo.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,9 @@ travis-ci = { repository = "braun-robotics/ieee802154" }
2121
hash32 = "0.1"
2222
hash32-derive = "0.1"
2323
byte = "0.2.4"
24+
cipher = { version = "0.2", default-features = false }
25+
ccm = {version = "0.3.0", default-features = false}
26+
27+
[dev-dependencies]
28+
aes-soft = {version = "0.6.4", default-features = false}
29+
rand = "0.8.3"

src/mac/frame/frame_control.rs

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -144,18 +144,6 @@ impl AddressMode {
144144
}
145145
}
146146

147-
/// Defines whether an auxiliary security header is present in the MAC header
148-
///
149-
/// Part of [`Header`]. Auxiliary security headers are currently unsupported by
150-
/// this implementation.
151-
///
152-
/// [`Header`]: super::header::Header
153-
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
154-
pub enum Security {
155-
/// No auxiliary security header is present
156-
None = 0b0,
157-
}
158-
159147
pub mod offset {
160148
pub const FRAME_TYPE: u16 = 0;
161149
pub const SECURITY: u16 = 3;

src/mac/frame/header.rs

Lines changed: 75 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,16 @@
55
//! [`Header`]: struct.Header.html
66
77
use byte::{check_len, BytesExt, TryRead, TryWrite, LE};
8+
use cipher::{consts::U16, BlockCipher, NewBlockCipher};
89
use hash32_derive::Hash32;
910

10-
use super::frame_control::*;
11-
pub use super::frame_control::{AddressMode, FrameType, FrameVersion, Security};
11+
pub use super::frame_control::{AddressMode, FrameType, FrameVersion};
1212
use super::DecodeError;
13+
use super::{
14+
frame_control::{mask, offset},
15+
security::{KeyDescriptorLookup, SecurityContext},
16+
};
17+
use super::{security::AuxiliarySecurityHeader, EncodeError};
1318

1419
/// MAC frame header
1520
///
@@ -22,9 +27,6 @@ pub struct Header {
2227
/// Frame Type
2328
pub frame_type: FrameType,
2429

25-
/// Auxiliary Security header
26-
pub security: Security,
27-
2830
/// Frame Pending
2931
///
3032
/// The Frame Pending field shall be set to `true` if the device sending the frame has more data
@@ -67,6 +69,39 @@ pub struct Header {
6769

6870
/// Source Address
6971
pub source: Option<Address>,
72+
73+
/// Auxiliary security header. If security is enabled in this header,
74+
/// this field will be Some, else it will be None
75+
pub auxiliary_security_header: Option<AuxiliarySecurityHeader>,
76+
}
77+
78+
impl Header {
79+
/// Get the size of this header in octets
80+
pub fn get_octet_size(&self) -> usize {
81+
// Frame control + sequence number
82+
let mut len = 3;
83+
84+
for i in [self.destination, self.source].iter() {
85+
match i {
86+
Some(addr) => {
87+
// pan ID
88+
len += 2;
89+
// Address length
90+
match addr {
91+
Address::Short(..) => len += 2,
92+
Address::Extended(..) => len += 8,
93+
}
94+
}
95+
_ => {}
96+
}
97+
}
98+
len
99+
}
100+
101+
/// Whether this header has security enabled
102+
pub fn has_security(&self) -> bool {
103+
self.auxiliary_security_header.is_some()
104+
}
70105
}
71106

72107
impl TryRead<'_> for Header {
@@ -97,11 +132,7 @@ impl TryRead<'_> for Header {
97132
let src_addr_mode = AddressMode::from_bits(src_addr_mode)?;
98133

99134
// make bool values
100-
let security = if security > 0 {
101-
return Err(DecodeError::SecurityNotSupported.into());
102-
} else {
103-
Security::None
104-
};
135+
let security = security > 0;
105136
let frame_pending = frame_pending > 0;
106137
let ack_request = ack_request > 0;
107138
let pan_id_compress = pan_id_compress > 0;
@@ -148,31 +179,46 @@ impl TryRead<'_> for Header {
148179
}
149180
};
150181

182+
let auxiliary_security_header = match security {
183+
true => Some(bytes.read(offset)?),
184+
false => None,
185+
};
186+
151187
let header = Header {
152188
frame_type,
153-
security,
154189
frame_pending,
155190
ack_request,
156191
pan_id_compress,
157192
version,
158-
159193
seq,
160194
destination,
161195
source,
196+
auxiliary_security_header,
162197
};
163198

164199
Ok((header, *offset))
165200
}
166201
}
167202

168-
impl TryWrite for Header {
169-
fn try_write(self, bytes: &mut [u8], _ctx: ()) -> byte::Result<usize> {
203+
impl<AEADBLKCIPH, KEYDESCLO> TryWrite<&Option<&mut SecurityContext<AEADBLKCIPH, KEYDESCLO>>>
204+
for Header
205+
where
206+
AEADBLKCIPH: NewBlockCipher + BlockCipher<BlockSize = U16>,
207+
KEYDESCLO: KeyDescriptorLookup<AEADBLKCIPH::KeySize>,
208+
{
209+
fn try_write(
210+
self,
211+
bytes: &mut [u8],
212+
sec_ctx: &Option<&mut SecurityContext<AEADBLKCIPH, KEYDESCLO>>,
213+
) -> byte::Result<usize> {
170214
let offset = &mut 0;
171215
let dest_addr_mode = AddressMode::from(self.destination);
172216
let src_addr_mode = AddressMode::from(self.source);
173217

218+
let security = self.auxiliary_security_header.is_some();
219+
174220
let frame_control_raw = (self.frame_type as u16) << offset::FRAME_TYPE
175-
| (self.security as u16) << offset::SECURITY
221+
| (security as u16) << offset::SECURITY
176222
| (self.frame_pending as u16) << offset::PENDING
177223
| (self.ack_request as u16) << offset::ACK
178224
| (self.pan_id_compress as u16) << offset::PAN_ID_COMPRESS
@@ -202,6 +248,20 @@ impl TryWrite for Header {
202248
}
203249
(None, false) => (),
204250
}
251+
252+
if security && sec_ctx.is_none() {
253+
return Err(EncodeError::MissingSecurityCtx)?;
254+
} else if security {
255+
match self.auxiliary_security_header {
256+
Some(aux_sec_head) => match sec_ctx {
257+
Some(sec_ctx) => {
258+
bytes.write_with(offset, aux_sec_head, sec_ctx)?;
259+
}
260+
None => return Err(EncodeError::UnknownError)?,
261+
},
262+
None => return Err(EncodeError::UnknownError)?,
263+
}
264+
}
205265
Ok(*offset)
206266
}
207267
}

0 commit comments

Comments
 (0)