NOC CAT: The CAT IDs in the NoC are only 32-bit, account for that

This commit is contained in:
Kedar Sovani 2023-02-12 10:14:47 +05:30
parent 0149d30a0c
commit 707d3700c0
5 changed files with 30 additions and 21 deletions

View file

@ -90,8 +90,10 @@ fn get_noc_cat_version(id: u64) -> u64 {
id & NOC_CAT_VERSION_MASK id & NOC_CAT_VERSION_MASK
} }
pub fn gen_noc_cat(id: u16, version: u16) -> u64 { /// Generate CAT that is embeddedable in the NoC
NOC_CAT_SUBJECT_PREFIX | ((id as u64) << 16) | version as u64 /// 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]); pub struct AccessorSubjects([u64; MAX_ACCESSOR_SUBJECTS]);
@ -103,10 +105,10 @@ impl AccessorSubjects {
a 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() { for (i, val) in self.0.iter().enumerate() {
if *val == 0 { if *val == 0 {
self.0[i] = subject; self.0[i] = NOC_CAT_SUBJECT_PREFIX | (subject as u64);
return Ok(()); return Ok(());
} }
} }
@ -287,6 +289,10 @@ impl AclEntry {
Ok(()) 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> { pub fn add_target(&mut self, target: Target) -> Result<(), Error> {
let index = self let index = self
.targets .targets
@ -650,7 +656,7 @@ mod tests {
let v3 = 3; let v3 = 3;
// Accessor has nodeif and CAT 0xABCD_0002 // Accessor has nodeif and CAT 0xABCD_0002
let mut subjects = AccessorSubjects::new(112233); 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 accessor = Accessor::new(2, subjects, AuthMode::Case, am.clone());
let path = GenericPath::new(Some(1), Some(1234), None); let path = GenericPath::new(Some(1), Some(1234), None);
@ -659,19 +665,20 @@ mod tests {
// Deny for CAT id mismatch // Deny for CAT id mismatch
let mut new = AclEntry::new(2, Privilege::VIEW, AuthMode::Case); 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(); am.add(new).unwrap();
assert_eq!(req.allow(), false); assert_eq!(req.allow(), false);
// Deny of CAT version mismatch // Deny of CAT version mismatch
let mut new = AclEntry::new(2, Privilege::VIEW, AuthMode::Case); 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(); am.add(new).unwrap();
assert_eq!(req.allow(), false); assert_eq!(req.allow(), false);
// Allow for CAT match // Allow for CAT match
let mut new = AclEntry::new(2, Privilege::VIEW, AuthMode::Case); 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(); am.add(new).unwrap();
assert_eq!(req.allow(), true); assert_eq!(req.allow(), true);
} }
@ -687,7 +694,7 @@ mod tests {
let v3 = 3; let v3 = 3;
// Accessor has nodeif and CAT 0xABCD_0003 // Accessor has nodeif and CAT 0xABCD_0003
let mut subjects = AccessorSubjects::new(112233); 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 accessor = Accessor::new(2, subjects, AuthMode::Case, am.clone());
let path = GenericPath::new(Some(1), Some(1234), None); let path = GenericPath::new(Some(1), Some(1234), None);
@ -696,13 +703,14 @@ mod tests {
// Deny for CAT id mismatch // Deny for CAT id mismatch
let mut new = AclEntry::new(2, Privilege::VIEW, AuthMode::Case); 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(); am.add(new).unwrap();
assert_eq!(req.allow(), false); assert_eq!(req.allow(), false);
// Allow for CAT match and version more than ACL version // Allow for CAT match and version more than ACL version
let mut new = AclEntry::new(2, Privilege::VIEW, AuthMode::Case); 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(); am.add(new).unwrap();
assert_eq!(req.allow(), true); assert_eq!(req.allow(), true);
} }

View file

@ -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; let mut out_index = 0;
for (_, val) in self.dn.iter().filter(|(id, _)| *id == match_id as u8) { for (_, val) in self.dn.iter().filter(|(id, _)| *id == match_id as u8) {
if let DistNameValue::Uint(a) = val { if let DistNameValue::Uint(a) = val {
if out_index < output.len() { if out_index < output.len() {
output[out_index] = *a; // CatIds are actually just 32-bit
output[out_index] = *a as u32;
out_index += 1; out_index += 1;
} }
} }
@ -555,8 +556,8 @@ 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]) { pub fn get_cat_ids(&self, output: &mut [u32]) {
self.subject.u64_arr(DnTags::NocCat, output) self.subject.u32_arr(DnTags::NocCat, output)
} }
pub fn get_fabric_id(&self) -> Result<u64, Error> { pub fn get_fabric_id(&self) -> Result<u64, Error> {

View file

@ -224,7 +224,7 @@ impl DataModel {
AccessorSubjects::new(sess.get_peer_node_id().unwrap_or_default()); AccessorSubjects::new(sess.get_peer_node_id().unwrap_or_default());
for i in c.cat_ids { for i in c.cat_ids {
if i != 0 { if i != 0 {
let _ = subject.add(i); let _ = subject.add_catid(i);
} }
} }
Accessor::new(c.fab_idx, subject, AuthMode::Case, self.acl_mgr.clone()) Accessor::new(c.fab_idx, subject, AuthMode::Case, self.acl_mgr.clone())

View file

@ -38,16 +38,18 @@ use super::{
}; };
pub const MAX_CAT_IDS_PER_NOC: usize = 3; 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; const MATTER_AES128_KEY_SIZE: usize = 16;
#[derive(Debug, Default, Copy, Clone, PartialEq)] #[derive(Debug, Default, Copy, Clone, PartialEq)]
pub struct CaseDetails { pub struct CaseDetails {
pub fab_idx: u8, pub fab_idx: u8,
pub cat_ids: [u64; MAX_CAT_IDS_PER_NOC], pub cat_ids: NocCatIds,
} }
impl CaseDetails { 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 { Self {
fab_idx, fab_idx,
cat_ids: *cat_ids, cat_ids: *cat_ids,
@ -69,8 +71,6 @@ 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,

View file

@ -420,7 +420,7 @@ fn exact_write_attribute_noc_cat() {
// Add ACL to allow our peer to access any endpoint // Add ACL to allow our peer to access any endpoint
let mut acl = AclEntry::new(1, Privilege::ADMIN, AuthMode::Case); 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(); im.acl_mgr.add(acl).unwrap();
// Test 1: Exact write to an attribute with permission should grant // Test 1: Exact write to an attribute with permission should grant