[wlan][rsn] Ref-counted byte slice for parsing
Note: This will slow down parsing. Parsing RSNEs will increase from
somewhere around 180ns to 300ns. This change will be reverted once
future async/await landed which supports lifetime bounded futures.
Test: are already included and run successfully
NET-550
Change-Id: I038fa27ddca98b1c2d9c9480c77229f31c384010
diff --git a/lib/rust/crates/eapol/src/lib.rs b/lib/rust/crates/eapol/src/lib.rs
index 49b8113..7c14626 100644
--- a/lib/rust/crates/eapol/src/lib.rs
+++ b/lib/rust/crates/eapol/src/lib.rs
@@ -6,10 +6,12 @@
#[macro_use]
extern crate bitfield;
+extern crate bytes;
#[macro_use]
extern crate nom;
extern crate test;
+use bytes::Bytes;
use nom::{be_u16, be_u64, be_u8};
// IEEE Std 802.1X-2010, 11.9, Table 11-5
@@ -63,7 +65,7 @@
// IEEE Std 802.11-2016, 12.7.2, Figure 12-32
#[derive(Default, Debug)]
-pub struct KeyFrame<'a> {
+pub struct KeyFrame {
pub version: u8,
pub packet_type: u8,
pub packet_body_len: u16,
@@ -72,13 +74,13 @@
pub key_info: KeyInformation,
pub key_len: u16,
pub key_replay_counter: u64,
- pub key_nonce: &'a [u8], // 32 octets
- pub key_iv: &'a [u8], // 16 octets
+ pub key_nonce: Bytes, // 32 octets
+ pub key_iv: Bytes, // 16 octets
pub key_rsc: u64,
// 8 octests reserved.
- pub key_mic: &'a [u8], // AKM dependent size
+ pub key_mic: Bytes, // AKM dependent size
pub key_data_len: u16,
- pub key_data: &'a [u8],
+ pub key_data: Bytes,
}
named_args!(pub key_frame_from_bytes(mic_size: u16) <KeyFrame>,
@@ -107,12 +109,12 @@
key_info: key_info,
key_len: key_len,
key_replay_counter: key_replay_counter,
- key_mic: key_mic,
+ key_mic: Bytes::from(key_mic),
key_rsc: key_rsc,
- key_iv: key_iv,
- key_nonce: key_nonce,
+ key_iv: Bytes::from(key_iv),
+ key_nonce: Bytes::from(key_nonce),
key_data_len: key_data_len,
- key_data: key_data,
+ key_data: Bytes::from(key_data),
})
)
);
diff --git a/lib/rust/crates/wlan-rsn/src/akm.rs b/lib/rust/crates/wlan-rsn/src/akm.rs
index e9f0288..ebfa596 100644
--- a/lib/rust/crates/wlan-rsn/src/akm.rs
+++ b/lib/rust/crates/wlan-rsn/src/akm.rs
@@ -4,6 +4,7 @@
#![allow(dead_code)]
use auth::{config, psk};
+use bytes::Bytes;
use crypto_utils;
use futures::Future;
use integrity;
@@ -37,12 +38,12 @@
pub const FT_EAP_SHA384: u8 = 13;
// 14-255 - Reserved.
-pub struct Akm<'a> {
- pub oui: &'a [u8],
+pub struct Akm {
+ pub oui: Bytes,
pub suite_type: u8,
}
-impl<'a> Akm<'a> {
+impl Akm {
/// Only AKMs specified in IEEE 802.11-2016, 9.4.2.25.4, Table 9-133 have known algorithms.
fn has_known_algorithm(&self) -> bool {
if self.is_reserved() || self.is_vendor_specific() {
@@ -54,7 +55,7 @@
pub fn is_vendor_specific(&self) -> bool {
// IEEE 802.11-2016, 9.4.2.25.4, Table 9-133
- !self.oui.eq(&suite_selector::OUI)
+ !&self.oui[..].eq(&suite_selector::OUI)
}
pub fn is_reserved(&self) -> bool {
@@ -162,10 +163,10 @@
}
}
-impl<'a> suite_selector::Factory<'a> for Akm<'a> {
- type Suite = Akm<'a>;
+impl suite_selector::Factory for Akm {
+ type Suite = Akm;
- fn new(oui: &'a [u8], suite_type: u8) -> Result<Self::Suite> {
+ fn new(oui: Bytes, suite_type: u8) -> Result<Self::Suite> {
if oui.len() != 3 {
Err(Error::InvalidOuiLength(oui.len()))
} else {
@@ -174,7 +175,7 @@
}
}
-impl<'a> fmt::Debug for Akm<'a> {
+impl fmt::Debug for Akm {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
diff --git a/lib/rust/crates/wlan-rsn/src/cipher.rs b/lib/rust/crates/wlan-rsn/src/cipher.rs
index 9ef588e..3052e8c 100644
--- a/lib/rust/crates/wlan-rsn/src/cipher.rs
+++ b/lib/rust/crates/wlan-rsn/src/cipher.rs
@@ -4,6 +4,7 @@
#![allow(dead_code)]
use super::{Error, Result};
+use bytes::Bytes;
use std::fmt;
use suite_selector;
@@ -32,12 +33,12 @@
pub const BIP_CMAC_256: u8 = 13;
// 14-255 - Reserved.
-pub struct Cipher<'a> {
- pub oui: &'a [u8],
+pub struct Cipher {
+ pub oui: Bytes,
pub suite_type: u8,
}
-impl<'a> Cipher<'a> {
+impl Cipher {
/// Reserved and vendor specific cipher suites have no known usage and require special
/// treatments.
fn has_known_usage(&self) -> bool {
@@ -46,7 +47,7 @@
pub fn is_vendor_specific(&self) -> bool {
// IEEE 802.11-2016, 9.4.2.25.2, Table 9-131
- !self.oui.eq(&suite_selector::OUI)
+ !&self.oui[..].eq(&suite_selector::OUI)
}
pub fn is_reserved(&self) -> bool {
@@ -101,10 +102,10 @@
}
}
-impl<'a> suite_selector::Factory<'a> for Cipher<'a> {
- type Suite = Cipher<'a>;
+impl suite_selector::Factory for Cipher {
+ type Suite = Cipher;
- fn new(oui: &'a [u8], suite_type: u8) -> Result<Self::Suite> {
+ fn new(oui: Bytes, suite_type: u8) -> Result<Self::Suite> {
if oui.len() != 3 {
Err(Error::InvalidOuiLength(oui.len()))
} else {
@@ -113,7 +114,7 @@
}
}
-impl<'a> fmt::Debug for Cipher<'a> {
+impl fmt::Debug for Cipher {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
diff --git a/lib/rust/crates/wlan-rsn/src/key/ptk.rs b/lib/rust/crates/wlan-rsn/src/key/ptk.rs
index 40b8bec..88ebcdf 100644
--- a/lib/rust/crates/wlan-rsn/src/key/ptk.rs
+++ b/lib/rust/crates/wlan-rsn/src/key/ptk.rs
@@ -3,6 +3,7 @@
// found in the LICENSE file.
use akm::Akm;
+use bytes::Bytes;
use cipher::Cipher;
use crypto_utils::prf;
use std::cmp::{max, min};
@@ -112,8 +113,8 @@
}
fn new_ptk(data: &TestData, akm_suite: u8, cipher_suite: u8) -> Result<Ptk> {
- let akm = Akm::new(&OUI[..], akm_suite).unwrap();
- let cipher = Cipher::new(&OUI[..], cipher_suite).unwrap();
+ let akm = Akm::new(Bytes::from(&OUI[..]), akm_suite).unwrap();
+ let cipher = Cipher::new(Bytes::from(&OUI[..]), cipher_suite).unwrap();
new(
&data.pmk[..],
&data.aa,
diff --git a/lib/rust/crates/wlan-rsn/src/key_data/mod.rs b/lib/rust/crates/wlan-rsn/src/key_data/mod.rs
index 07700a9..696cd2f 100644
--- a/lib/rust/crates/wlan-rsn/src/key_data/mod.rs
+++ b/lib/rust/crates/wlan-rsn/src/key_data/mod.rs
@@ -11,9 +11,9 @@
use {Error, Result};
#[derive(Debug)]
-pub enum Element<'a> {
+pub enum Element {
Gtk(kde::Header, kde::Gtk),
- Rsne(rsne::Rsne<'a>),
+ Rsne(rsne::Rsne),
Padding,
UnsupportedKde(kde::Header),
UnsupportedIe(u8, u8),
diff --git a/lib/rust/crates/wlan-rsn/src/pmkid.rs b/lib/rust/crates/wlan-rsn/src/pmkid.rs
index c4ffec6..35bcfa8 100644
--- a/lib/rust/crates/wlan-rsn/src/pmkid.rs
+++ b/lib/rust/crates/wlan-rsn/src/pmkid.rs
@@ -3,10 +3,11 @@
// found in the LICENSE file.
use super::{Error, Result};
+use bytes::Bytes;
-pub type Pmkid<'a> = &'a [u8];
+pub type Pmkid = Bytes;
-pub fn new<'a>(pmkid: &'a [u8]) -> Result<Pmkid> {
+pub fn new(pmkid: Bytes) -> Result<Pmkid> {
if pmkid.len() != 16 {
Err(Error::InvalidPmkidLength(pmkid.len()))
} else {
diff --git a/lib/rust/crates/wlan-rsn/src/rsne.rs b/lib/rust/crates/wlan-rsn/src/rsne.rs
index b9ea898..d02becf 100644
--- a/lib/rust/crates/wlan-rsn/src/rsne.rs
+++ b/lib/rust/crates/wlan-rsn/src/rsne.rs
@@ -3,6 +3,7 @@
// found in the LICENSE file.
use akm;
+use bytes::Bytes;
use cipher;
use pmkid;
use suite_selector;
@@ -17,30 +18,32 @@
// IEEE 802.11-2016, 9.4.2.25.1
#[derive(Default, Debug)]
-pub struct Rsne<'a> {
+pub struct Rsne {
pub element_id: u8,
pub length: u8,
pub version: u16,
- pub group_data_cipher_suite: Option<cipher::Cipher<'a>>,
- pub pairwise_cipher_suites: Vec<cipher::Cipher<'a>>,
- pub akm_suites: Vec<akm::Akm<'a>>,
+ pub group_data_cipher_suite: Option<cipher::Cipher>,
+ pub pairwise_cipher_suites: Vec<cipher::Cipher>,
+ pub akm_suites: Vec<akm::Akm>,
pub rsn_capabilities: u16,
- pub pmkids: Vec<pmkid::Pmkid<'a>>,
- pub group_mgmt_cipher_suite: Option<cipher::Cipher<'a>>,
+ pub pmkids: Vec<pmkid::Pmkid>,
+ pub group_mgmt_cipher_suite: Option<cipher::Cipher>,
}
fn read_suite_selector<'a, T>(input: &'a [u8]) -> IResult<&'a [u8], T>
where
- T: suite_selector::Factory<'a, Suite = T>,
+ T: suite_selector::Factory<Suite = T>,
{
let (i1, bytes) = try_parse!(input, take!(4));
- let (i2, ctor_result) = try_parse!(i1, expr_res!(T::new(&bytes[0..3], bytes[3])));
+ let oui = Bytes::from(&bytes[0..3]);
+ let (i2, ctor_result) = try_parse!(i1, expr_res!(T::new(oui, bytes[3])));
return IResult::Done(i2, ctor_result);
}
fn read_pmkid<'a>(input: &'a [u8]) -> IResult<&'a [u8], pmkid::Pmkid> {
let (i1, bytes) = try_parse!(input, take!(16));
- let (i2, result) = try_parse!(i1, expr_res!(pmkid::new(&bytes)));
+ let pmkid_data = Bytes::from(bytes);
+ let (i2, result) = try_parse!(i1, expr_res!(pmkid::new(pmkid_data)));
return IResult::Done(i2, result);
}
diff --git a/lib/rust/crates/wlan-rsn/src/suite_selector.rs b/lib/rust/crates/wlan-rsn/src/suite_selector.rs
index b1b7969..ce9da67 100644
--- a/lib/rust/crates/wlan-rsn/src/suite_selector.rs
+++ b/lib/rust/crates/wlan-rsn/src/suite_selector.rs
@@ -3,11 +3,12 @@
// found in the LICENSE file.
use super::Result;
+use bytes::Bytes;
pub const OUI: [u8; 3] = [0x00, 0x0F, 0xAC];
-pub trait Factory<'a> {
+pub trait Factory {
type Suite;
- fn new(oui: &'a [u8], suite_type: u8) -> Result<Self::Suite>;
+ fn new(oui: Bytes, suite_type: u8) -> Result<Self::Suite>;
}