From 707d3700c0271b09cfa279b33e3953898b1b25fa Mon Sep 17 00:00:00 2001 From: Kedar Sovani Date: Sun, 12 Feb 2023 10:14:47 +0530 Subject: [PATCH] NOC CAT: The CAT IDs in the NoC are only 32-bit, account for that --- matter/src/acl.rs | 30 ++++++++++++++-------- matter/src/cert/mod.rs | 9 ++++--- matter/src/data_model/core.rs | 2 +- matter/src/transport/session.rs | 8 +++--- matter/tests/data_model/acl_and_dataver.rs | 2 +- 5 files changed, 30 insertions(+), 21 deletions(-) diff --git a/matter/src/acl.rs b/matter/src/acl.rs index 2260062..8625a7b 100644 --- a/matter/src/acl.rs +++ b/matter/src/acl.rs @@ -90,8 +90,10 @@ fn get_noc_cat_version(id: u64) -> u64 { id & NOC_CAT_VERSION_MASK } -pub fn gen_noc_cat(id: u16, version: u16) -> u64 { - NOC_CAT_SUBJECT_PREFIX | ((id as u64) << 16) | version as u64 +/// Generate CAT that is embeddedable in the NoC +/// This only generates the 32-bit CAT ID +pub fn gen_noc_cat(id: u16, version: u16) -> u32 { + ((id as u32) << 16) | version as u32 } pub struct AccessorSubjects([u64; MAX_ACCESSOR_SUBJECTS]); @@ -103,10 +105,10 @@ impl AccessorSubjects { a } - pub fn add(&mut self, subject: u64) -> Result<(), Error> { + pub fn add_catid(&mut self, subject: u32) -> Result<(), Error> { for (i, val) in self.0.iter().enumerate() { if *val == 0 { - self.0[i] = subject; + self.0[i] = NOC_CAT_SUBJECT_PREFIX | (subject as u64); return Ok(()); } } @@ -287,6 +289,10 @@ impl AclEntry { Ok(()) } + pub fn add_subject_catid(&mut self, cat_id: u32) -> Result<(), Error> { + self.add_subject(NOC_CAT_SUBJECT_PREFIX | cat_id as u64) + } + pub fn add_target(&mut self, target: Target) -> Result<(), Error> { let index = self .targets @@ -650,7 +656,7 @@ mod tests { let v3 = 3; // Accessor has nodeif and CAT 0xABCD_0002 let mut subjects = AccessorSubjects::new(112233); - subjects.add(gen_noc_cat(allow_cat, v2)).unwrap(); + subjects.add_catid(gen_noc_cat(allow_cat, v2)).unwrap(); let accessor = Accessor::new(2, subjects, AuthMode::Case, am.clone()); let path = GenericPath::new(Some(1), Some(1234), None); @@ -659,19 +665,20 @@ mod tests { // Deny for CAT id mismatch let mut new = AclEntry::new(2, Privilege::VIEW, AuthMode::Case); - new.add_subject(gen_noc_cat(disallow_cat, v2)).unwrap(); + new.add_subject_catid(gen_noc_cat(disallow_cat, v2)) + .unwrap(); am.add(new).unwrap(); assert_eq!(req.allow(), false); // Deny of CAT version mismatch let mut new = AclEntry::new(2, Privilege::VIEW, AuthMode::Case); - new.add_subject(gen_noc_cat(allow_cat, v3)).unwrap(); + new.add_subject_catid(gen_noc_cat(allow_cat, v3)).unwrap(); am.add(new).unwrap(); assert_eq!(req.allow(), false); // Allow for CAT match let mut new = AclEntry::new(2, Privilege::VIEW, AuthMode::Case); - new.add_subject(gen_noc_cat(allow_cat, v2)).unwrap(); + new.add_subject_catid(gen_noc_cat(allow_cat, v2)).unwrap(); am.add(new).unwrap(); assert_eq!(req.allow(), true); } @@ -687,7 +694,7 @@ mod tests { let v3 = 3; // Accessor has nodeif and CAT 0xABCD_0003 let mut subjects = AccessorSubjects::new(112233); - subjects.add(gen_noc_cat(allow_cat, v3)).unwrap(); + subjects.add_catid(gen_noc_cat(allow_cat, v3)).unwrap(); let accessor = Accessor::new(2, subjects, AuthMode::Case, am.clone()); let path = GenericPath::new(Some(1), Some(1234), None); @@ -696,13 +703,14 @@ mod tests { // Deny for CAT id mismatch let mut new = AclEntry::new(2, Privilege::VIEW, AuthMode::Case); - new.add_subject(gen_noc_cat(disallow_cat, v2)).unwrap(); + new.add_subject_catid(gen_noc_cat(disallow_cat, v2)) + .unwrap(); am.add(new).unwrap(); assert_eq!(req.allow(), false); // Allow for CAT match and version more than ACL version let mut new = AclEntry::new(2, Privilege::VIEW, AuthMode::Case); - new.add_subject(gen_noc_cat(allow_cat, v2)).unwrap(); + new.add_subject_catid(gen_noc_cat(allow_cat, v2)).unwrap(); am.add(new).unwrap(); assert_eq!(req.allow(), true); } diff --git a/matter/src/cert/mod.rs b/matter/src/cert/mod.rs index 93e5e40..cc6bd31 100644 --- a/matter/src/cert/mod.rs +++ b/matter/src/cert/mod.rs @@ -319,12 +319,13 @@ impl DistNames { }) } - fn u64_arr(&self, match_id: DnTags, output: &mut [u64]) { + fn u32_arr(&self, match_id: DnTags, output: &mut [u32]) { 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; + // CatIds are actually just 32-bit + output[out_index] = *a as u32; out_index += 1; } } @@ -555,8 +556,8 @@ impl Cert { 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_cat_ids(&self, output: &mut [u32]) { + self.subject.u32_arr(DnTags::NocCat, output) } pub fn get_fabric_id(&self) -> Result { diff --git a/matter/src/data_model/core.rs b/matter/src/data_model/core.rs index 7ea9659..55a0e9e 100644 --- a/matter/src/data_model/core.rs +++ b/matter/src/data_model/core.rs @@ -224,7 +224,7 @@ impl DataModel { AccessorSubjects::new(sess.get_peer_node_id().unwrap_or_default()); for i in c.cat_ids { if i != 0 { - let _ = subject.add(i); + let _ = subject.add_catid(i); } } Accessor::new(c.fab_idx, subject, AuthMode::Case, self.acl_mgr.clone()) diff --git a/matter/src/transport/session.rs b/matter/src/transport/session.rs index da8d7cd..bba2149 100644 --- a/matter/src/transport/session.rs +++ b/matter/src/transport/session.rs @@ -38,16 +38,18 @@ use super::{ }; pub const MAX_CAT_IDS_PER_NOC: usize = 3; +pub type NocCatIds = [u32; MAX_CAT_IDS_PER_NOC]; + 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], + pub cat_ids: NocCatIds, } impl CaseDetails { - pub fn new(fab_idx: u8, cat_ids: &[u64; MAX_CAT_IDS_PER_NOC]) -> Self { + pub fn new(fab_idx: u8, cat_ids: &NocCatIds) -> Self { Self { fab_idx, cat_ids: *cat_ids, @@ -69,8 +71,6 @@ impl Default for SessionMode { } } -pub type NocCatIds = [u64; MAX_CAT_IDS_PER_NOC]; - #[derive(Debug)] pub struct Session { peer_addr: Address, diff --git a/matter/tests/data_model/acl_and_dataver.rs b/matter/tests/data_model/acl_and_dataver.rs index d692c6a..34eb234 100644 --- a/matter/tests/data_model/acl_and_dataver.rs +++ b/matter/tests/data_model/acl_and_dataver.rs @@ -420,7 +420,7 @@ fn exact_write_attribute_noc_cat() { // Add ACL to allow our peer to access any endpoint let mut acl = AclEntry::new(1, Privilege::ADMIN, AuthMode::Case); - acl.add_subject(cat_in_acl).unwrap(); + acl.add_subject_catid(cat_in_acl).unwrap(); im.acl_mgr.add(acl).unwrap(); // Test 1: Exact write to an attribute with permission should grant