···6677// talk about the standard unix abstractions
8899-In mainstream operating systems, security policy is enforced at runtime by a
1010-omnicient and all powerful kernel.
99+In mainstream operating systems, a
1010+omnicient and all-powerful kernel enforces security policy at runtime.
1111// what am i trying to say here.
1212It acts as the bodyguard, holding all i/o and data protected unless the
1313requesting party has the authorization to access some resource. This tight
1414-coupling of security policy and access mechanisms works well since any accesses
1515-must be done through the kernel, so why not perform security checks right
1616-along-side an access. However
1414+coupling of security policy and access mechanisms works well since any access
1515+must be done through the kernel, so why not perform security checks
1616+alongside accesses? However,
1717the enforcement of security policy starts getting complicated when we try
1818-to seperate the access mechanisms from the kernel. This notion arises
1818+to separate the access mechanisms from the kernel. This problem arises
1919in a certain class of operating systems.
20202121-== Data Centric Operating Systems
2121+== Data-Centric Operating Systems
22222323-Data centric operating systems are defined by two principles @twizzler:
2323+Data-centric operating systems are defined by two principles @twizzler:
24242525- + Provide direct, kernel-free, access to data.
2525+ + They provide direct, kernel-free, access to data.
26262727- + A notion of pointers that are tied to the data they represent.
2727+ + They have a notion of pointers that are tied to the data they represent.
28282929Mainstream operating systems fail to classify as data-centric operating
3030systems, as they rely on the kernel for all data access, and use virtualized
3131pointers per process to represent underlying data. The benefit of this "class"
3232of operating systems comes from the low overhead for data manipulation, due to the lack
3333-of kernel involvement. However our previous security model fails to operate
3434-here as, by defenition, the kernel cannot be infront of accesses to data. So,
3333+of kernel involvement. However, the mainstream security model fails to operate
3434+here as, by definition, the kernel cannot be in front of access to data. So,
3535something new must be investigated.
36363737== Capability Based Security Systems
···4141//
4242// how they are different from earlier thingies
43434444-Capability based security systems have a rich history in research, and offer
4545-an alternative approach to security, in opposition to the ACL's of prevalent OS's @linux_security.
4646-Boiled down, a capability is a token of authority, holding at mininum some
4444+Capability-based security systems have a rich history in research, and offer
4545+an alternative approach to security, in opposition to the Access Control Lists of prevalent OS's @linux_security.
4646+Boiled down, a capability is a token of authority, holding at minimum some
4747permissions and a unique identifier to which "thing" those permissions apply
4848-to @cap-book. This simple approach of having a "token", allows for a large seperation
4848+to @cap-book. This simple approach of having a "token", allows for a separation
4949of the kernel's involvement in the creation and management of security policy.
5050-In a well designed system, as we see in @twizsec and described later, allows for
5050+In a well-designed system, as we see in @twizsec and described later, this allows
5151users to completely create and manage security policy while the kernel is left to enforce
5252-it. This paradigm allows for the kernel-free access of data, while also guaranteeing
5252+it. This paradigm permits kernel-free access of data, while also guaranteeing
5353security.
54545555···5959In this thesis, I detail the fundamentals of security in the Twizzler
6060operating system, and discuss how I implement and refine some of the high
6161level ideas described in Twizzler @twizzler and an early draft of a Twizzler security
6262-paper @twizsec. Additionally we evaluate these systems inside kernel and user space,
6363-with comparsions to micro-benchmarks done with an older version of twizzler.
6262+paper @twizsec. Additionally, we evaluate these systems inside kernel and user space, using
6363+Alice/Bob scenarios and microbenchmarks.
6464Code can be found in this
6565#link("https://github.com/twizzler-operating-system/twizzler/issues/268")[Github
6666tracking issue].
+18-18
2-keypair.typ
···44#mol-chapter("Key Pairs")
5566// what are keypair objects ?
77-Key pairs in Twizzler are the representation of the cryptographic signing
88-schemes used to create a signed capability, discussed in 3.1. We design
99-the keypair objects to be agnostic towards what cryptographic schemes are
1010-underneath, allowing for the underlying algorithm to be changed @twizzler. The
1111-keys themselves are stored inside of objects, allowing for persistent or
1212-volatile storage depending on object specification, and allows for keys
1313-themselves to be treated as any other object and have security policy applied
1414-to them. This allows for powerful primitives and rich expressiveness for
1515-describing secruity policy, while also being flexible enough to make basic
1616-policy easy.
77+Key pairs in Twizzler are representation of the cryptographic signing
88+schemes used to create a signed capability, as discussed in 3.1. We design
99+the keypair objects to be agnostic towards the underlying scheme to allow for
1010+multiple schemes, as described in @twizzler. This also helps with backwards
1111+compatibilty when adding new, more secure schemes, in the future. The keys
1212+are stored inside of objects, allowing for persistent or volatile
1313+storage depending on object specification, and allows for keys themselves to
1414+be treated as any other object and have security policy applied to them. This
1515+allows for powerful primitives and rich expressiveness for describing secruity
1616+policy, while also being intuitive enough to construct basic policy easily.
171718181919== Abstraction
···2929for an outdated signing scheme to be used in support of older programs /
3030files. An existing drawback for backward compatibility is the maximum size
3131of the buffer we store the key in. Currently we set the maximum size as 256
3232-bytes, meaning if a future cryptographic signing scheme was to be found with
3333-a private key size larger than 256 bytes, we would have to drop backwards
3434-compatibility. Sure this can be prevented by setting the maximum size to
3535-something larger, but that a tradeoff between possible cryptographic schemes
3232+bytes, meaning if a future cryptographic signing scheme was to be created with
3333+a key size larger than 256 bytes, we would have to drop backwards
3434+compatibility. Sure this can be prevented now by setting the maximum size to
3535+something larger, but thats a tradeoff between possible cryptographic schemes
3636vs the real on-disk cost of larger buffers.
37373838== Compartmentalization
···4747Suppose for instance we have Alice on Twizzler, and all users on twizzler have
4848a "user-root" keypair that allows for them to create an arbitrary number of
4949objects. Also suppose that access to this user-root keypair is protected by
5050-some login program, where only alice can log in. This now means that Alice
5151-now can create new keypair objects from her user-root keypair. Since all
5252-her new keypairs originate from her original user-root keypair, only she can
5050+some login program, where only alice can log in. This means that Alice
5151+can create new keypair objects from her user-root keypair. Since all
5252+*her* new keypairs originate from *her* original user-root keypair, only *she* can
5353access the keys required to create new signatures allowing permissions into
5454-her objects. It forms an elegant solution for capability creation without
5454+*her* objects. It forms an elegant solution for key management without
5555the involvement of the kernel.
56565757
+28-17
3-cap.typ
···66// define a capability
77Capabilities are the atomic unit of security in Twizzler, acting as tokens of
88protections granted to a process, allowing it to access some object in the ways
99-it describes. A Capability is built up of the following fields.
99+it describes. Colloquially a capability is defined as permissions and
1010+a unique object to which those permissions apply, but in Twizzler we add
1111+the signature component to allow the kernel to validate that the security policy was created by an authorized party.
1212+1313+Thus, a Capability is represented as follows:
101411151216```rust
···1721 flags: CapFlags, // Cryptographic configuration for capability validation.
1822 gates: Gates, // Additional constraints on when this capability can be used.
1923 revocation: Revoc, // Specifies when this capability is invalid, i.e. expiration.
2020- sig: Signature, // The signature inside the capability.
2424+ sig: Signature, // The signature.
2125}
2226```
23272428//
2529== Signature
2626-The signature inside is what determines the validity of this capability. The
3030+The signature is what determines the validity of the capability. The
2731only possible signer of some capability is who ever has permissions to the
2828-signing key object, or the kernel. In this way, if the signer decides to
2929-make the signing key private to them, no other entity can administer this
3030-signature for this capability. The signature is built up of a array with
3232+signing key object, or the kernel itself. The signature is built up of a array with
3133a maximum length and a enum representing what type of cryptographic scheme
3234was used to create it; quite similar to the keys mentioned previously.
3333-The message being signed to form the signature is the bytes of each of the
3434-fields inside the capability being hashed. There is support for multiple
3535-hashing algorithms as described in 3.1.
3636-3535+The fields of the capability are serialized and hashed to form the message that gets signed,
3636+and then stored in the signature field. Currently we support Blake3 and
3737+Sha256 as hashing algorithms.
37383839// what do i want to talk about regarding signatures?
39404041== Gates
4242+Gates act as a limited entry point into objects. If a capability has a non-trivial gate,
4343+which is made up of an offset field, and a length field, the kernel will read that and ensure
4444+that any memory accesses into that object are within the gate bounds. The original Twizzler
4545+paper @twizzler describes gates as a way to perform IPC, and calls between distinct programs,
4646+but in the context of this thesis it is sufficient to think of them as a region of allowed
4747+memory access.
41484249== Flags
4343-Currently flags in capabilities are used to specify which hashing algorithm to use in order
4444-to form a message to be signed. We allow for multiple algorithms to be used in order to
4545-allow for backwards capability when newer, more efficient hashing algorithms are created.
4646-4747-There is also plenty of space left in the bitmap, allowing for future work to develop more
4848-expressive ways of using capabilities, such as planned future work to implement information
4949-flow control into the twizzler security system.
5050+Currently, flags in capabilities are used to specify which hashing algorithm to use to form a message to be signed. We allow for multiple algorithms to be used to
5151+allow for backward capability when newer, more efficient hashing algorithms are created.
50525353+The flags inside a capability is a bitmask providing information about distinct feautures
5454+of that capability. Currently we only use them to mark what hashing algorithm was used to
5555+form the message for the signature, but there's plenty of bits left to use.
5656+We hope for future work to develop more expressive ways of using capabilities, i.e. Decentralized Information Flow Control, as specified in
5757+6.1.
515852595360#load-bib(read("refs.bib"))
6161+6262+6363+6464+
+36-22
4-secctx.typ
···2233#mol-chapter("Security Contexts")
4455-Security Contexts are objects that store capabilites, which processes can attach onto, inherting the
66-permissions granted by the capabilities that reside inside.
77-88-== Enforcement
99-1010-The enforcement of security policy in Twizzler happens on page fault when trying to access
1111-a new object @twizzler. Then the kernel inspects the security contexts attached to
1212-the accessing proccess, looking up what capabilities those contexts hold and if they are applicable
1313-to the object being accessed. The original twizzler paper @twizzler, and the following security paper
1414-go into more detail about the philosophy behind why enforcement works this way, such as the
1515-performance benefits of letting programs access objects directly without kernel involvement, etc.
1616-1717-1818-55+Security Contexts are objects that processes attach to in-order to inherit the
66+permissions inside the context. The contexts store capabilities, allowing for userspace
77+programs to add capabilities to contexts, and kernel space to efficiently search
88+through them to determie whether a process has the permissions to perform a memory access.
1992010== Base
21112212Since security contexts can be interacted with by the kernel and userspace, there needs to
2323-be a consistent defenition that both parties can adhere to, which we define. Objects in twizzler
1313+be a consistent definition that both parties can adhere to, which we define. Objects in Twizzler
2414have a notion of a `Base` which defines an arbitrary block of data at the "bottom" of an object
2515that is represented as a type in rust. We define the `Base` for a security context as follows:
2616···35253626=== Map
3727The map holds positions to Capabilities relevant to some target object, which
3838-the relevant security context implementations for kernel and userspaces to
2828+the relevant security context implementations for kernel and userspace to
3929parse security context objects. Implicitly, the kernel uses
4030this map for lookup while the user interacts with this map to indicate the insertion, removal, or modification of
4131a capability.
···4333=== Masks
4434Masks act as a restraint on the permissions this context can provide for some targeted object.
4535This allows for more expressive security policy, such as being able to quickly restrict
4646-permissions for an object, without having to remove a capability, and recreating one with the
3636+permissions for an object, without having to remove a capability and recreating one with the
4737dersired restricted permissions.
48384939The global mask is quite similar to the masks mentioned above, except that it operates on
···5141// what now
5242//
5343=== Flags
5454-5555-5656-4444+Flags is a bitmap allowing for a Security Context to have different properties. Currently, there
4545+is only one value, UNDETACHABLE, marking the security context as a jail of sorts, as
4646+once a process attaches to it, it won't be able to detach. This acts as a way to
4747+limit the transfer of information if a thread attaches to a sensitive object. Once a thread
4848+attaches to such a context, it is forced to end its execution with the objects that context grants
4949+permission to. We also plan to utilize these flags in future works, as described in 6.1.
575058515252+== Enforcement
59536060-// on disk storage for security contexts for efficient lookup
5454+All enforcement happens inside the kernel, which has a seperate view into Security Contexts
5555+than userspace. The kernel keeps track of all security contexts that threads in Twizzler
5656+attach to, instantiating a cache inside each one. Additionally, a thread can attach
5757+to multiple security contexts, but can only utilize the permissions granted by one unless
5858+they switch @twizzler. To manage these threads, the kernel assigns a Security Context Manager,
5959+which holds onto security context references that a thread has.
61606161+The enforcement of security policy in Twizzler happens on page fault when trying to access
6262+a new object @twizzler. Upon fault, the kernel inspects the target object and identifies the
6363+default permissnons of that object. Then the kernel checks if the currently active
6464+security context for the accessing thread has either cached or capabilities that provide
6565+permissions. If default permissions + the active context permissions arent enough to
6666+permit the access, the kernel then checks each of the inactive contexts to see if they
6767+have any relevant permissions. If there exists such permissions, then the kernel will
6868+switch the active context of that process to the previously inactive context where the permission
6969+was found. If it fails all of these, then the kernel terminates the process, citing inadequate
7070+permissions.
62716363-// what else is special about security contexts?
7272+Since the security context can have a mask per object, while also having a global_mask to
7373+the protections it can grant, the kernel also takes this into account while determining if
7474+a process has the permissions for access.
64757676+The original Twizzler paper @twizzler, and the following security paper
7777+go into more detail about the philosophy behind why enforcement works this way, such as the
7878+performance benefits of letting programs access objects directly without kernel involvement, etc.
65796680#load-bib(read("refs.bib"))
+15-16
5-results.typ
···1919== Validation
20202121The first test is a basic scenario as a check to make sure the system is behaving as intended, and
2222-a more expressive test to demonstrate the flexibility of the model. Eventually I intend to work with
2222+a more expressive test to demonstrate the flexibility of the model. Eventually, I intend to work with
2323my advisor and peers to form a proof of correctness for the security model, as well
2424as empirical testing to demonstrate its rigidity.
2525···303031313232== Micro Benchmarks
3333-Additionally we have microbenchmarks of core security operations in Twizzler. All
3434-benchmarks were ran with a Ryzen 5 2600, with Twizzler virtualized in QEMU. Unfortunately
3333+Additionally, we have microbenchmarks of core security operations in Twizzler. All
3434+benchmarks were run with a Ryzen 5 2600, with Twizzler virtualized in QEMU. Unfortunately
3535I ran out of time to perform benchmarks on bare metal, but they should be the same, if
3636not more, performant.
37373838=== Kernel
39394040-Theres a couple things we benchmark inside the kernel, including core cryptographic
4040+There a couple of things we benchmark inside the kernel, including core cryptographic
4141operations like signature generation and verification, as well as the total time it takes
4242to verify a capability.
4343#figure(
···8484)
85858686We see that signatures are vastly more expensive than hashing, on an order
8787-of $10^3$, meaning that your choice of hashing algorithm doesnt affection the
8787+of $10^3$, meaning that your choice of hashing algorithm doesn't affect the
8888total time taken for the verification of a capability. It's also important to
8989-note that this cost of verifying a capability for access is done on the first
9090-pagefault, then the kernel uses caching to store the granted permissions and
9191-provieds those on subsequent page faults into that object. In the future I hope
9292-to measure the difference between a cached and uncached verification. Secondly
9393-we only measure verification inside kernel space; as disscussed in section 3,
8989+note that this cost of verifying a capability for access is done on the first-page fault, then the kernel uses caching to store the granted permissions and
9090+provides those on subsequent page faults into that object. In the future, I hope
9191+to measure the difference between a cached and uncached verification. Secondly,
9292+we only measure verification inside kernel space; as discussed in section 3,
9493capability creation only takes place in user space.
95949695=== UserSpace
97969898-In userspace we benchmark keypair and capability creation, as these operations are core to
9999-creating security policy.
9797+In userspace, we benchmark keypair and capability creation, as these operations are core to
9898+creating a security policy.
10099101100102101#figure(
···130129)
131130132131Almost all the time spent in creating a capability is the cryptographic operations used
133133-to form its signature, which is why its in the same ballpark as signature creation we saw earlier.
132132+to form its signature, which is why it's in the same ballpark as the signature creation we saw earlier.
134133135135-The high varince in Keypair objects and Security contexts creation happens from the
136136-unpredictable time it takes for the kernel to create an object on disk. The reason keypair's
137137-are almost 2x more expensive since it creates two seperate objects, one for the signing key,
134134+The high standard deviation in Keypair objects and Security context creation happens from the
135135+unpredictable time it takes for the kernel to create an object on disk. The reason keypairs
136136+are almost 2x more expensive since they create two separate objects, one for the signing key,
138137and one for the verifying key.
thesis.pdf
This is a binary file and will not be displayed.
+10-3
thesis.typ
···2424)
25252626#mol-abstract[
2727- whatevea
2828- lowkey not even sure what to write
2929- ]
2727+ Traditional operating systems permit data access through the kernel, applying
2828+ security policy as a part of that pipeline. The Twizzler operating system
2929+ flips that relationship on its head, focusing on an approach where data
3030+ access is a first-class citizen, getting rid of the kernel as a middleman. With
3131+ this data-centric approach, it requires us to rethink how security policy
3232+ interacts with users and the kernel. In this thesis, I present the design and
3333+ implementation of core security primitives in Twizzler. Then I evaluate the
3434+ security model with a basic and advanced scenario, as well as microbenchmarks
3535+ of core security operations. Lastly, I discuss future work built off this
3636+ thesis, such as the incorporation of Decentralized Information Flow Control.]
303731383239