Session: Include NoC CAT fields, and populate them from the CASE exchange

This commit is contained in:
Kedar Sovani 2023-02-09 15:45:25 +05:30
parent 315b7edbc8
commit 725d19187e
7 changed files with 68 additions and 15 deletions

View file

@ -318,6 +318,18 @@ impl DistNames {
} }
}) })
} }
fn u64_arr(&self, match_id: DnTags, output: &mut [u64]) {
let mut out_index = 0;
for (_, val) in self.dn.iter().filter(|(id, _)| *id == match_id as u8) {
if let DistNameValue::Uint(a) = val {
if out_index < output.len() {
output[out_index] = *a;
out_index += 1;
}
}
}
}
} }
const PRINTABLE_STR_THRESHOLD: u8 = 0x80; const PRINTABLE_STR_THRESHOLD: u8 = 0x80;
@ -543,6 +555,10 @@ impl Cert {
self.subject.u64(DnTags::NodeId).ok_or(Error::NoNodeId) self.subject.u64(DnTags::NodeId).ok_or(Error::NoNodeId)
} }
pub fn get_cat_ids(&self, output: &mut [u64]) {
self.subject.u64_arr(DnTags::NocCat, output)
}
pub fn get_fabric_id(&self) -> Result<u64, Error> { pub fn get_fabric_id(&self) -> Result<u64, Error> {
self.subject.u64(DnTags::FabricId).ok_or(Error::NoFabricId) self.subject.u64(DnTags::FabricId).ok_or(Error::NoFabricId)
} }

View file

@ -221,7 +221,7 @@ impl DataModel {
match sess.get_session_mode() { match sess.get_session_mode() {
SessionMode::Case(c) => { SessionMode::Case(c) => {
let subject = AccessorSubjects::new(sess.get_peer_node_id().unwrap_or_default()); let subject = AccessorSubjects::new(sess.get_peer_node_id().unwrap_or_default());
Accessor::new(c, subject, AuthMode::Case, self.acl_mgr.clone()) Accessor::new(c.fab_idx, subject, AuthMode::Case, self.acl_mgr.clone())
} }
SessionMode::Pase => Accessor::new( SessionMode::Pase => Accessor::new(
0, 0,

View file

@ -89,10 +89,15 @@ impl FailSafe {
match c.noc_state { match c.noc_state {
NocState::NocNotRecvd => return Err(Error::Invalid), NocState::NocNotRecvd => return Err(Error::Invalid),
NocState::AddNocRecvd(idx) | NocState::UpdateNocRecvd(idx) => { NocState::AddNocRecvd(idx) | NocState::UpdateNocRecvd(idx) => {
if SessionMode::Case(idx) != session_mode { if let SessionMode::Case(c) = session_mode {
error!( if c.fab_idx != idx {
"Received disarm in separate session from previous Add/Update NOC" error!(
); "Received disarm in separate session from previous Add/Update NOC"
);
return Err(Error::Invalid);
}
} else {
error!("Received disarm in a non-CASE session");
return Err(Error::Invalid); return Err(Error::Invalid);
} }
} }

View file

@ -248,11 +248,11 @@ impl NocCluster {
.map_err(|_| IMStatusCode::InvalidDataType)?; .map_err(|_| IMStatusCode::InvalidDataType)?;
let (result, fab_idx) = let (result, fab_idx) =
if let SessionMode::Case(fab_idx) = cmd_req.trans.session.get_session_mode() { if let SessionMode::Case(c) = cmd_req.trans.session.get_session_mode() {
if self.fabric_mgr.set_label(fab_idx, label).is_err() { if self.fabric_mgr.set_label(c.fab_idx, label).is_err() {
(NocStatus::LabelConflict, fab_idx) (NocStatus::LabelConflict, c.fab_idx)
} else { } else {
(NocStatus::Ok, fab_idx) (NocStatus::Ok, c.fab_idx)
} }
} else { } else {
// Update Fabric Label not allowed // Update Fabric Label not allowed

View file

@ -33,7 +33,7 @@ use crate::{
network::Address, network::Address,
proto_demux::{ProtoCtx, ResponseRequired}, proto_demux::{ProtoCtx, ResponseRequired},
queue::{Msg, WorkQ}, queue::{Msg, WorkQ},
session::{CloneData, SessionMode}, session::{CaseDetails, CloneData, NocCatIds, SessionMode},
}, },
utils::writebuf::WriteBuf, utils::writebuf::WriteBuf,
}; };
@ -155,6 +155,8 @@ impl Case {
} }
// Only now do we add this message to the TT Hash // Only now do we add this message to the TT Hash
let mut peer_catids: NocCatIds = Default::default();
initiator_noc.get_cat_ids(&mut peer_catids);
case_session.tt_hash.update(ctx.rx.as_borrow_slice())?; case_session.tt_hash.update(ctx.rx.as_borrow_slice())?;
let clone_data = Case::get_session_clone_data( let clone_data = Case::get_session_clone_data(
fabric.ipk.op_key(), fabric.ipk.op_key(),
@ -162,6 +164,7 @@ impl Case {
initiator_noc.get_node_id()?, initiator_noc.get_node_id()?,
ctx.exch_ctx.sess.get_peer_addr(), ctx.exch_ctx.sess.get_peer_addr(),
&case_session, &case_session,
&peer_catids,
)?; )?;
// Queue a transport mgr request to add a new session // Queue a transport mgr request to add a new session
WorkQ::get()?.sync_send(Msg::NewSession(clone_data))?; WorkQ::get()?.sync_send(Msg::NewSession(clone_data))?;
@ -281,6 +284,7 @@ impl Case {
peer_nodeid: u64, peer_nodeid: u64,
peer_addr: Address, peer_addr: Address,
case_session: &CaseSession, case_session: &CaseSession,
peer_catids: &NocCatIds,
) -> Result<CloneData, Error> { ) -> Result<CloneData, Error> {
let mut session_keys = [0_u8; 3 * crypto::SYMM_KEY_LEN_BYTES]; let mut session_keys = [0_u8; 3 * crypto::SYMM_KEY_LEN_BYTES];
Case::get_session_keys( Case::get_session_keys(
@ -296,7 +300,10 @@ impl Case {
case_session.peer_sessid, case_session.peer_sessid,
case_session.local_sessid, case_session.local_sessid,
peer_addr, peer_addr,
SessionMode::Case(case_session.local_fabric_idx as u8), SessionMode::Case(CaseDetails::new(
case_session.local_fabric_idx as u8,
peer_catids,
)),
); );
clone_data.dec_key.copy_from_slice(&session_keys[0..16]); clone_data.dec_key.copy_from_slice(&session_keys[0..16]);

View file

@ -37,12 +37,28 @@ use super::{
packet::{Packet, PacketPool}, packet::{Packet, PacketPool},
}; };
pub const MAX_CAT_IDS_PER_NOC: usize = 3;
const MATTER_AES128_KEY_SIZE: usize = 16; const MATTER_AES128_KEY_SIZE: usize = 16;
#[derive(Debug, Default, Copy, Clone, PartialEq)]
pub struct CaseDetails {
pub fab_idx: u8,
pub cat_ids: [u64; MAX_CAT_IDS_PER_NOC],
}
impl CaseDetails {
pub fn new(fab_idx: u8, cat_ids: &[u64; MAX_CAT_IDS_PER_NOC]) -> Self {
Self {
fab_idx,
cat_ids: *cat_ids,
}
}
}
#[derive(Debug, PartialEq, Copy, Clone)] #[derive(Debug, PartialEq, Copy, Clone)]
pub enum SessionMode { pub enum SessionMode {
// The Case session will capture the local fabric index // The Case session will capture the local fabric index
Case(u8), Case(CaseDetails),
Pase, Pase,
PlainText, PlainText,
} }
@ -53,6 +69,8 @@ impl Default for SessionMode {
} }
} }
pub type NocCatIds = [u64; MAX_CAT_IDS_PER_NOC];
#[derive(Debug)] #[derive(Debug)]
pub struct Session { pub struct Session {
peer_addr: Address, peer_addr: Address,
@ -188,9 +206,16 @@ impl Session {
self.peer_nodeid self.peer_nodeid
} }
pub fn get_peer_cat_ids(&self) -> Option<&NocCatIds> {
match &self.mode {
SessionMode::Case(a) => Some(&a.cat_ids),
_ => None,
}
}
pub fn get_local_fabric_idx(&self) -> Option<u8> { pub fn get_local_fabric_idx(&self) -> Option<u8> {
match self.mode { match self.mode {
SessionMode::Case(a) => Some(a), SessionMode::Case(a) => Some(a.fab_idx),
_ => None, _ => None,
} }
} }

View file

@ -32,7 +32,6 @@ use matter::{
secure_channel::pake::PaseMgr, secure_channel::pake::PaseMgr,
tlv::{TLVWriter, TagType, ToTLV}, tlv::{TLVWriter, TagType, ToTLV},
transport::packet::Packet, transport::packet::Packet,
transport::proto_demux::HandleProto,
transport::{ transport::{
exchange::{self, Exchange, ExchangeCtx}, exchange::{self, Exchange, ExchangeCtx},
network::Address, network::Address,
@ -40,6 +39,7 @@ use matter::{
proto_demux::ProtoCtx, proto_demux::ProtoCtx,
session::{CloneData, SessionMgr, SessionMode}, session::{CloneData, SessionMgr, SessionMode},
}, },
transport::{proto_demux::HandleProto, session::CaseDetails},
utils::writebuf::WriteBuf, utils::writebuf::WriteBuf,
}; };
use std::{ use std::{
@ -146,7 +146,7 @@ impl ImEngine {
std::net::IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), std::net::IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)),
5542, 5542,
)), )),
SessionMode::Case(1), SessionMode::Case(CaseDetails::new(1, &Default::default())),
); );
let sess_idx = sess_mgr.clone_session(&clone_data).unwrap(); let sess_idx = sess_mgr.clone_session(&clone_data).unwrap();
let sess = sess_mgr.get_session_handle(sess_idx); let sess = sess_mgr.get_session_handle(sess_idx);