Skip to content

Commit

Permalink
Merge pull request #3940 from tyler-potyondy/6LoWPAN
Browse files Browse the repository at this point in the history
IEEE802.15.4 RxClient Encrypted Receive
  • Loading branch information
ppannuto committed Apr 12, 2024
2 parents 34352f7 + 221a715 commit 86abc90
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 13 deletions.
2 changes: 2 additions & 0 deletions boards/components/src/ieee802154.rs
Expand Up @@ -324,6 +324,7 @@ impl<
));
mac_device.set_transmit_client(mux_mac);
mac_device.set_receive_client(mux_mac);
mac_device.set_receive_secured_frame_no_decrypt_client(mux_mac);

let userspace_mac =
static_buffer
Expand All @@ -347,6 +348,7 @@ impl<
mac_device.set_device_procedure(radio_driver);
userspace_mac.set_transmit_client(radio_driver);
userspace_mac.set_receive_client(radio_driver);
userspace_mac.set_receive_secured_frame_no_decrypt_client(radio_driver);
userspace_mac.set_pan(self.pan_id);
userspace_mac.set_address(self.short_addr);
userspace_mac.set_address_long(self.long_addr);
Expand Down
38 changes: 36 additions & 2 deletions capsules/extra/src/ieee802154/device.rs
Expand Up @@ -24,6 +24,11 @@ pub trait MacDevice<'a> {
fn set_transmit_client(&self, client: &'a dyn TxClient);
/// Sets the receive client of this MAC device
fn set_receive_client(&self, client: &'a dyn RxClient);
/// Sets the secure frame no decrypt receive client of this MAC device
fn set_receive_secured_frame_no_decrypt_client(
&self,
client: &'a dyn SecuredFrameNoDecryptRxClient,
);

/// The short 16-bit address of the MAC device
fn get_address(&self) -> u16;
Expand Down Expand Up @@ -124,8 +129,8 @@ pub trait RxClient {
/// unsecured frames that have passed the incoming security procedure are
/// exposed to the client.
///
/// - `buf`: The entire buffer containing the frame, including extra bytes
/// in front used for the physical layer.
/// - `buf`: The entire buffer containing the frame, potentially also
/// including extra bytes in front used for the physical layer.
/// - `header`: A fully-parsed representation of the MAC header, with the
/// caveat that the auxiliary security header is still included if the frame
/// was previously secured.
Expand All @@ -135,3 +140,32 @@ pub trait RxClient {
/// - `data_len`: Length of the data payload
fn receive<'a>(&self, buf: &'a [u8], header: Header<'a>, data_offset: usize, data_len: usize);
}

/// Trait to be implemented by users of the IEEE 802.15.4 device that wish to
/// receive frames possessing link layer security that remain secured (i.e.
/// have not been decrypted). This allows the client to perform decryption
/// on the frame. The callback is trigger whenever a valid frame is received.
/// In this context, raw refers to receiving frames without processing the
/// security of the frame. The SecuredFrameNoDecryptRxClient should not be
/// used to pass frames to the higher layers of the network stack that expect
/// unsecured frames.
pub trait SecuredFrameNoDecryptRxClient {
/// When a frame is received, this callback is triggered. The client only
/// receives an immutable borrow of the buffer. All frames, regardless of
/// their secured state, are exposed to the client.
///
/// - `buf`: The entire buffer containing the frame, potentially also
/// including extra bytes in front used for the physical layer.
/// - `header`: A fully-parsed representation of the MAC header.
/// - `data_offset`: Offset of the data payload relative to
/// `buf`, so that the payload of the frame is contained in
/// `buf[data_offset..data_offset + data_len]`.
/// - `data_len`: Length of the data payload
fn receive_secured_frame<'a>(
&self,
buf: &'a [u8],
header: Header<'a>,
data_offset: usize,
data_len: usize,
);
}
16 changes: 16 additions & 0 deletions capsules/extra/src/ieee802154/driver.rs
Expand Up @@ -56,6 +56,7 @@
use crate::ieee802154::{device, framer};
use crate::net::ieee802154::{AddressMode, Header, KeyId, MacAddress, PanID, SecurityLevel};
use crate::net::stream::{decode_bytes, decode_u8, encode_bytes, encode_u8, SResult};
use device::RxClient;

use core::cell::Cell;

Expand Down Expand Up @@ -1083,6 +1084,21 @@ fn encode_address(addr: &Option<MacAddress>) -> usize {
((AddressMode::from(addr) as usize) << 16) | short_addr_only
}

impl<'a, M: device::MacDevice<'a>> device::SecuredFrameNoDecryptRxClient for RadioDriver<'a, M> {
fn receive_secured_frame<'b>(
&self,
buf: &'b [u8],
header: Header<'b>,
data_offset: usize,
data_len: usize,
) {
// The current 15.4 userspace receive accepts both secured and
// unsecured frames. As such, we can simply call the standard
// receive method of the RxClient trait.
self.receive(buf, header, data_offset, data_len)
}
}

impl<'a, M: device::MacDevice<'a>> device::RxClient for RadioDriver<'a, M> {
fn receive<'b>(&self, buf: &'b [u8], header: Header<'b>, data_offset: usize, data_len: usize) {
self.apps.each(|_, _, kernel_data| {
Expand Down
15 changes: 12 additions & 3 deletions capsules/extra/src/ieee802154/framer.rs
Expand Up @@ -75,7 +75,7 @@
// TODO: Channel scanning
//

use crate::ieee802154::device::{MacDevice, RxClient, TxClient};
use crate::ieee802154::device::{MacDevice, RxClient, SecuredFrameNoDecryptRxClient, TxClient};
use crate::ieee802154::mac::Mac;
use crate::net::ieee802154::{
FrameType, FrameVersion, Header, KeyId, MacAddress, PanID, Security, SecurityLevel,
Expand Down Expand Up @@ -394,6 +394,7 @@ pub struct Framer<'a, M: Mac<'a>, A: AES128CCM<'a>> {
/// `None`, except when transitioning between states.
rx_state: MapCell<RxState>,
rx_client: OptionalCell<&'a dyn RxClient>,
secured_frame_no_decrypt_rx_client: OptionalCell<&'a dyn SecuredFrameNoDecryptRxClient>,
crypt_buf: MapCell<SubSliceMut<'static, u8>>,
}

Expand All @@ -413,6 +414,7 @@ impl<'a, M: Mac<'a>, A: AES128CCM<'a>> Framer<'a, M, A> {
tx_client: OptionalCell::empty(),
rx_state: MapCell::new(RxState::Idle),
rx_client: OptionalCell::empty(),
secured_frame_no_decrypt_rx_client: OptionalCell::empty(),
crypt_buf: MapCell::new(crypt_buf),
}
}
Expand Down Expand Up @@ -498,8 +500,8 @@ impl<'a, M: Mac<'a>, A: AES128CCM<'a>> Framer<'a, M, A> {
Some(key) => key,
None => {
// Key not found -- pass raw encrypted packet to client
self.rx_client.map(|client| {
client.receive(&buf[PSDU_OFFSET..], header, data_offset, data_len);
self.secured_frame_no_decrypt_rx_client.map(|client| {
client.receive_secured_frame(&buf[PSDU_OFFSET..], header, data_offset, data_len);
});
return None;
}
Expand Down Expand Up @@ -780,6 +782,13 @@ impl<'a, M: Mac<'a>, A: AES128CCM<'a>> MacDevice<'a> for Framer<'a, M, A> {
self.rx_client.set(client);
}

fn set_receive_secured_frame_no_decrypt_client(
&self,
client: &'a dyn super::device::SecuredFrameNoDecryptRxClient,
) {
self.secured_frame_no_decrypt_rx_client.set(client);
}

fn get_address(&self) -> u16 {
self.mac.get_address()
}
Expand Down
49 changes: 41 additions & 8 deletions capsules/extra/src/ieee802154/virtual_mac.rs
Expand Up @@ -35,8 +35,6 @@
use crate::ieee802154::{device, framer};
use crate::net::ieee802154::{Header, KeyId, MacAddress, PanID, SecurityLevel};

use core::cell::Cell;

use kernel::collections::list::{List, ListLink, ListNode};
use kernel::utilities::cells::{MapCell, OptionalCell};
use kernel::ErrorCode;
Expand Down Expand Up @@ -67,6 +65,20 @@ impl<'a, M: device::MacDevice<'a>> device::RxClient for MuxMac<'a, M> {
}
}

impl<'a, M: device::MacDevice<'a>> device::SecuredFrameNoDecryptRxClient for MuxMac<'a, M> {
fn receive_secured_frame<'b>(
&self,
buf: &'b [u8],
header: Header<'b>,
data_offset: usize,
data_len: usize,
) {
for user in self.users.iter() {
user.receive_secured_frame(buf, header, data_offset, data_len);
}
}
}

impl<'a, M: device::MacDevice<'a>> MuxMac<'a, M> {
pub const fn new(mac: &'a M) -> MuxMac<'a, M> {
MuxMac {
Expand Down Expand Up @@ -196,8 +208,9 @@ pub struct MacUser<'a, M: device::MacDevice<'a>> {
mux: &'a MuxMac<'a, M>,
operation: MapCell<Op>,
next: ListLink<'a, MacUser<'a, M>>,
tx_client: Cell<Option<&'a dyn device::TxClient>>,
rx_client: Cell<Option<&'a dyn device::RxClient>>,
tx_client: OptionalCell<&'a dyn device::TxClient>,
rx_client: OptionalCell<&'a dyn device::RxClient>,
secure_frame_no_decrypt_rx_client: OptionalCell<&'a dyn device::SecuredFrameNoDecryptRxClient>,
}

impl<'a, M: device::MacDevice<'a>> MacUser<'a, M> {
Expand All @@ -206,8 +219,9 @@ impl<'a, M: device::MacDevice<'a>> MacUser<'a, M> {
mux: mux,
operation: MapCell::new(Op::Idle),
next: ListLink::empty(),
tx_client: Cell::new(None),
rx_client: Cell::new(None),
tx_client: OptionalCell::empty(),
rx_client: OptionalCell::empty(),
secure_frame_no_decrypt_rx_client: OptionalCell::empty(),
}
}
}
Expand All @@ -224,6 +238,18 @@ impl<'a, M: device::MacDevice<'a>> MacUser<'a, M> {
.get()
.map(move |client| client.receive(buf, header, data_offset, data_len));
}

fn receive_secured_frame<'b>(
&self,
buf: &'b [u8],
header: Header<'b>,
data_offset: usize,
data_len: usize,
) {
self.secure_frame_no_decrypt_rx_client
.get()
.map(move |client| client.receive_secured_frame(buf, header, data_offset, data_len));
}
}

impl<'a, M: device::MacDevice<'a>> ListNode<'a, MacUser<'a, M>> for MacUser<'a, M> {
Expand All @@ -234,11 +260,18 @@ impl<'a, M: device::MacDevice<'a>> ListNode<'a, MacUser<'a, M>> for MacUser<'a,

impl<'a, M: device::MacDevice<'a>> device::MacDevice<'a> for MacUser<'a, M> {
fn set_transmit_client(&self, client: &'a dyn device::TxClient) {
self.tx_client.set(Some(client));
self.tx_client.set(client);
}

fn set_receive_client(&self, client: &'a dyn device::RxClient) {
self.rx_client.set(Some(client));
self.rx_client.set(client);
}

fn set_receive_secured_frame_no_decrypt_client(
&self,
client: &'a dyn device::SecuredFrameNoDecryptRxClient,
) {
self.secure_frame_no_decrypt_rx_client.set(client);
}

fn get_address(&self) -> u16 {
Expand Down

0 comments on commit 86abc90

Please sign in to comment.