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}