twizzler_security/sec_ctx/
base.rs

1use core::fmt::Display;
2
3use heapless::{FnvIndexMap, Vec};
4use twizzler_abi::object::{ObjID, Protections, NULLPAGE_SIZE};
5
6/// completely arbitrary amount of mask entries in a security context
7pub const MASKS_MAX: usize = 16;
8/// completely arbitrary amount of capabilites and delegations in a security context
9pub const SEC_CTX_MAP_LEN: usize = 16;
10/// arbitrary number of map items per target object
11pub const MAP_ITEMS_PER_OBJ: usize = 16;
12
13#[derive(Debug)]
14/// Used to store `Mask` data that will be applied to permissions granted by a `SecCtx` for
15/// specific target object.
16pub struct Mask {
17    /// object whose permissions will be masked.
18    pub target: ObjID,
19    /// Specifies a mask on the permissions granted by capabilties and delegations in this security
20    /// context.
21    pub permmask: Protections,
22    /// an override mask on the context's global mask.
23    pub ovrmask: Protections,
24    // not sure what these flags are for?
25    // flags: BitField
26}
27
28impl Mask {
29    /// Creates a new instance of `Mask`.
30    pub fn new(target: ObjID, permmask: Protections, ovrmask: Protections) -> Self {
31        Mask {
32            target,
33            permmask,
34            ovrmask,
35        }
36    }
37}
38
39#[derive(Clone, Copy, Debug, Default)]
40/// The type of item stored inside the map inside the `SecCtx`.
41pub enum CtxMapItemType {
42    #[default]
43    /// A capability is stored.
44    Cap,
45    /// A Delegation is stored.
46    Del,
47}
48
49#[derive(Clone, Copy, Debug, Default)]
50
51/// This type is stored inside the `CtxMap`. The map serves to store information about where
52/// `Cap`s and `Del`s are stored inside the `SecCtx` object.
53pub struct CtxMapItem {
54    /// Type of the Map Item
55    pub item_type: CtxMapItemType,
56    /// The offset into the object
57    pub offset: usize,
58}
59
60bitflags::bitflags! {
61    #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
62    /// Flags for a `SecCtx`.
63    pub struct SecCtxFlags: u16 {
64        /// Makes this `SecCtx` undetachable, meaning once its active, its not possible to detach from.
65        const UNDETACHABLE = 1;
66    }
67}
68
69/// The base of a Security Context, holding a map to the capabilities and delegations stored inside,
70/// masks on targets
71#[derive(Debug)]
72pub struct SecCtxBase {
73    /// A map that holds the mapping from an ObjID to the capabilities and delegations stored
74    /// inside this context that apply to that target ObjID.
75    pub map: FnvIndexMap<ObjID, Vec<CtxMapItem, MAP_ITEMS_PER_OBJ>, SEC_CTX_MAP_LEN>,
76    /// A map holding masks that apply for a target ObjID.
77    pub masks: FnvIndexMap<ObjID, Mask, MASKS_MAX>,
78    /// The global mask that applies to all protections gratned by this Security Context.
79    pub global_mask: Protections,
80    /// The running offset into the object where a new entry can be inserted.
81    pub offset: usize,
82    /// Flags specific to this security context.
83    pub flags: SecCtxFlags,
84}
85
86/// The root offset into the object, after the size of the base.
87pub const OBJECT_ROOT_OFFSET: usize = size_of::<SecCtxBase>() + NULLPAGE_SIZE;
88
89impl SecCtxBase {
90    /// Creates a new `SecCtxBase`.
91    pub fn new(global_mask: Protections, flags: SecCtxFlags) -> Self {
92        Self {
93            map: FnvIndexMap::<ObjID, Vec<CtxMapItem, MAP_ITEMS_PER_OBJ>, SEC_CTX_MAP_LEN>::new(),
94            masks: FnvIndexMap::<ObjID, Mask, MASKS_MAX>::new(),
95            global_mask,
96            offset: 0,
97            flags,
98        }
99    }
100}
101
102#[cfg(feature = "user")]
103use twizzler::marker::BaseType;
104
105#[cfg(feature = "user")]
106impl BaseType for SecCtxBase {
107    //NOTE: unsure if this is what the fingerprint "should" be, just chose a random number.
108    fn fingerprint() -> u64 {
109        16
110    }
111}
112
113impl Display for CtxMapItem {
114    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
115        write!(f, "Item Type: {:?}\n", self.item_type)?;
116        write!(f, "Offset: {:#X}\n", self.offset)?;
117        Ok(())
118    }
119}
120
121impl Default for SecCtxBase {
122    fn default() -> Self {
123        Self::new(Protections::all(), SecCtxFlags::empty())
124    }
125}