 Thanks for all sticking around to the Friday afternoon slot. I'm going to be talking on integrity protection and access control, and actually just a mix of the two. The talk itself is only designed to be about 20 minutes long, which leaves lots of room for discussion. And I've actually got a couple of slides at the end of the talk that I'll be doing for discussion. And so hopefully that will take up the rest of the time, or we'll leave a little bit early. First, caveat, the opinions in here are my own. And so that makes discussion just a little bit easier. I'm not speaking on behalf of the entire company. So let's take a look. What can an attacker do if they actually get physical access to your system? Well, if your file system isn't encrypted, they can do a whole lot. They can basically do whatever they want, right? They can readify the POSIX permissions, read and modify any of the SE Linux labels on the file system, file contents, directory structure. They can do a lot. The question is, of course, who cares? This isn't new. We all know this. This is why we encrypt our file systems. This is why we use things like DM Verity. Well, who actually does care? Android actually does care. And the reason Android cares is because they've got a one partition, which is nice and trusted, and it's got all your file system data on it, your system partition, and they've got another file system where that's supposed to have all of the untrusted data, things like someone's photos, things like all of the apps that you've downloaded, those sorts of things. Your system partition, that's where you put all the trusted stuff. The user data, that's where you put all the untrusted stuff. DM Crypt to the rescue. Now, DM Crypt is great. And it encrypts all of this. Now, there's a couple of caveats. Encryption does not imply integrity protection. So just because you've encrypted something doesn't mean someone can't modify it. And so you have to choose the proper algorithms. And it also doesn't protect against root persistence. So let's say someone does manage to get elevated privileges on your system. Once they've got those elevated privileges, they can go and they can modify those file systems. And DM Crypt is going to give them the unencrypted view so that they can do that. So what happens if we don't use DM Crypt? At least in the Android space, let's take a look at some of those SE Linux permissions. So Android actually has the ability to store your SE Linux policies on the user data partition, as well as storing them on the system partition. And they're stored in a directory called slash data slash security. And that directory is labeled with the security file. And if you actually take a look, security file is pretty locked down. There's only a couple of domains on the system that are allowed to access that directory. Untrusted app is not one of them. However, untrusted app can read and write media data files. This is pretty obviously something that an app might want to do. But what happens if we do have a physical attacker and we don't have DM Verity? Well, let's just update the label. Let's call that entire security directory a media read write data file. And we've all of a sudden given read write access to all the apps on the system. Any app on the system could then say, actually, let's use this SE Linux policy. And that's not really what we're looking to do here. And in fact, there is code in Android to read from these directories and use those as their SE policies. So what we actually did at BlackBerry is we actually developed something and we call it PathTrust. And the whole idea behind PathTrust is prevent applications installed in the user data from running with super user permissions. Now, it's a fairly rudimentary Linux security module. And I'll also caveat this by saying, PathTrust was not the best name we could have chosen. PathTrust is a carryover from QNICS. I don't know how much people know about QNICS. I know I'm wadding into dangerous territory here with another kernel. But QNICS does everything based on paths. And they've got a path manager. This was originally done on QNICS, which is why it's called PathTrust because it relied on the path manager. So what is super user for PathTrust? Well, super user is someone running with some specific capabilities. So DAC override, Mac admin, Sys admin, module, these sorts of Linux capabilities. And it's someone trying to run with specific SE Android types. Things like init probably shouldn't come off of user data. They should be on the system partition. And so if we have an app trying to run under the init context that is also coming from the user data partition, there's something really weird going on. And there's a bunch of other ones as well. What is run? Run is executing something through exec v. M mapping with execute permissions for a file-backed portion of memory. Loading kernel module. Kernel modules have been discussed before. There was another LSM, which was load pin. And that actually pins them to the particular partition where the first kernel or module was loaded from. Loading is firmware, and actually executing is a script as well. And so here's a very, very brief example here. You copy the shell off the system partition onto the user data partition, then you try and run it. And it says, sorry, you're not permitted to do that. And you'll notice here I was trying to run it as root. Now, if you're not trying to run as a super user, I don't care where you run it from. You can run non-root programs from the user data partition. In fact, if you couldn't, your Android system wouldn't work so well. And the other example, of course, is shells. So you can create a simple shell script here, throw it on your user data partition, run and run it. And the shell is going to come back and say, ah, sorry. I'm not going to let you do that. And we do that just by talking to the Linux security module through a device node. OK, how does it work? So there's about six steps involved. And the first step is we want to know which file systems are trustable. And so by trustable, I mean there are file system that was either entirely checked by the previous boot order, or previous component in the boot chain, or it's a file system with DMVarity on it. And so those are the file systems that we consider trustable. And trustable is different than trusted. So the first thing we do is we look at DMVarity. This is a file system, or sorry, DMVarity. This is a block device, which is trustable. I've got to get my terminology right. And then when we go to mount assist file system, we actually added another mount option. And it is trusted. And so when you actually try and mount something as trusted, it'll go through and it'll try and figure out whether or not this is a trustable block device. And we did this because it's really hard to poke down through all of the VFS layers to figure out the underlying block device and whether or not that underlying block device is DMVarity when you're looking at things from the very high level. So we go through and now we have something mounted as trusted because we've pasted the trusted flag to mount and it is trustable. And then we just intercept the Linux security module calls to the various functions that we need to implement, right? And so if we're trying to run with super user permissions, verify that the underlying file system is trusted. And then export a device node so that other people can query and say, hey, I'm gonna try and run this file. Is this file something that I should be running? And based on the permissions of whoever is going to try and run that file, sorry, based on whether or not who is going to run that file is a super user or has running with elevated privileges, we say yes or no, right? And that's how we do things like the shell. All right, that is it in a nutshell. But let's step back from that and let's take a look at the pitfalls of it, right? Because version one is never the most amazing thing in the world, I'm all done, let's go home, pack up. It doesn't stop a privileged application from accessing untrusted files, right? The only thing it does is stop them from running, right? And so if we wanted to expand this and we wanted to go more general, what could we do? Well, we could try and address these sorts of problems, right? What is the intersection between integrity protection, DM verity or whatever else you're using, right? In theory, we could use a file-based integrity protection where you could have certain files on a file system that are integrity protected, right? And therefore maybe we want to give them different permissions. All PATHTrust does is stop a privileged application from invoking, in this case, we're gonna call it attacker-provided code, right? Wait a second, isn't access control what SC Linux is already for, right? If we're gonna try and stop someone from doing something, that sounds like access control, right? And yes, it is, but SC Linux doesn't know anything about the underlying file system that the labels are on, right? It assumes that the labels are good. Uh-oh, profile encryption. Let's throw out DM verity now, right? And let's go to profile encryption. Now, it is coming. It has dropped in EXT4. I don't know whether it's on mainline yet. But are the extended attribute records for EXT4 integrity protected? Are they encrypted? Uh, well, not currently, okay? The only thing that is actually protected by EXT4 encryption, or profile encryption, is the name of the file and the contents of the file, right? And so you can have a file that you can't actually read the contents of if you're an offline attacker. You can change the permissions on it and then just reboot the system, right? And if you change the permissions on it and reboot the system and you also have code running on that system, then you can then start to read the file, right? Because the kernel will helpfully decrypt it for you. Now, extended attribute records, they are a possible future thing. Just like I said, path trust was version one, right? EXT4 per file encryption support is not finished, I'm sure, right? There's probably more patches coming for it. All right. So that's, that's the general overview of the talk. And now I want to actually get into some of the discussion debate and I'm hoping that people in the room will be able to partake in this one, right? And so I've got four questions here and I've got a slide on each, but I'm not gonna put the slide up on each unless we want the slide on each of them. So the first question, of course, is should we include the notion of integrity protection into a access control system such as SE Linux? Now I use SE Linux in this example because Android is tied to SE Linux, right? But it's equally applicable to SMAC, it's equally applicable to App Armor or any of the other access control systems, right? Is it something that we even want to do, right? And I'm not, just because the question is up here, I'm not saying that, you know, we should all go out and do it, right? Or even that I should go out and write the code. It's more of a question of should we, right? Should integrity protection require encryption? Is there any use in actually doing integrity protection for a file without doing encryption? Now, from a purely theoretical standpoint, yes, right? The two shouldn't be tied to each other. However, from a deployability and people outside of this room who are not as versed in security, are we likely to provide a set of tools to them such that they will do one without the other and screw it up, right? Do we want them to integrity protect a file that really should have been encrypted, right? Do we want them to encrypt a file and not put integrity protection on it, right? How much flexibility do we actually wanna give to people? What's the relative priority of protecting metadata, right? I've mentioned that the ext4, or sorry, the extended attributes are not integrity protected. Is it really the top of the list though, right? Or are there bigger fish that we need to fry first? And finally, can we do it generically with loopback and DM crypt, right? I've pointed out that there's a lot of things other than the name of the file and the content of the file that we could use some protection for, right? What happens if we actually take and we create two massive files sparsely allocated, right? On a single file system. Each of these sparse files is the size of the file system, right? And then we create new file systems in these sparse files. Well, in theory, right? We could actually have multiple different encryption domains, right, with multiple different keys, multiple different DM crypts. All of the metadata would be encrypted. However, there's caveats, right? Free space isn't reported correctly, but that's just the beginning of the problem because what happens if you run out of hard drive space on something that is a DM crypt looped back file? I have no idea. I'm gonna guess not good things. That's all I've got. And so those are the four questions. Does anybody have any comments? Yeah. Yeah. How could I have guessed? Yeah, so there's ways of doing encryption where you're not gonna necessarily know. Yeah, okay, but then you're getting expensive. So you're gonna be, in order to do cryptography on small pieces of data, you're going to be massively extending the expense of doing it. If you have to have a key for every, for example, for every iNode, now you're gonna have lots and lots of keys. You're going to, but if you don't do that, then you're gonna get hit, ran smack into predictability. Yeah. Good for you. Okay, well, why aren't you encrypting the metadata then? Because he had to start somewhere and starting with everything is hard. So I do have a patch that allows the file system to specify which keys are being encrypted by which blocks in DM crypt. And so it's possible to, for example, have a DM crypt-wide common key for the entire device while at the same time having the option of being able to choose a different key for individual file contents depending upon which user is logged in and is using the device. And to be clear, I don't know if everybody understands sort of why DM crypt is being phased out in favor of VXT4. DM crypt, if you reboot your device, bad things. I don't get my alarm in the morning, right? I can't encrypt, for example, now with Android for Work where you've got work and personal data on the same device. I can't encrypt them with different keys if I've just got one DM crypt, right? This is just a slide of what I sort of explained verbally earlier about, okay, how do you do DM crypt if you wanna actually have multiple different encryption keys? It's messy. There's a whole lot of gotchas in this one, which are not fully flushed out. Yeah, and I suppose I should also mention that part of the original design was to do encryption with integrity, so GCM mode. And I do actually have a prototype patch for encryption with integrity sitting around and we're just working on making it stable. There are a number of different games you can play at this point where you say, suppose I want metadata protection with integrity. This is where we're gonna have to start talking about where we get the space for the additional cryptographic metadata in the block device. Do you say, okay, we're gonna take a certain amount of available space in the block device and reserve a certain part of that and say, okay, this is where we keep that metadata? Or do we want to start playing games instead of making manipulations at the device mapper layer? Would we want to do a loopback mount on an EXT4 file that's integrity protected? Right, so loopback mounts all the way down. There are also concerns from an implementation standpoint as far as maintaining the consistency between the cryptographic metadata, the authentication tags, and so forth with the cipher text. Those have to be consistent with each other and that presents a challenge because with DM Crypt and unauthenticated modes of encryption, when you write a single block of plain text, you end up getting a single block of cipher text. That's nice and easy, but if instead when you write a single block of cipher text, you additionally have to store an authentication tag, for instance, associated with that, well suddenly now you have an opportunity for a system crash or power failure to result in inconsistency and hence result in data loss. And then you need something like copy on write semantics or log structured volume and the complexity increases at that point. There's a lot of discussion to be had on this. I don't know if I should have a birds in the feather session where those who may be interested want to talk more about it. But I've been thinking very carefully about these issues and writing a lot of prototype code. Yeah, yeah. And that, oh. Dave's effort. Yeah. So a couple of comment on your questions. Historically, should we include the notion of integrity in Desi Linux? Back when Imo was first going in the kernel, we actually sat down with Smalley and et al. And the decision was back then, one option was to stack, one option was for Imo to be an LSM module. And the decision back then was to say, no, we want this separate because any LSM may want to ask the integrity subsystem information about the files. And regardless of which LSM it was. So it was deliberately made a separate thing where the mandatory access control could ask, you know. And they sent decisions on it. And I guess the result of that is that as far as I know, none of the access control systems take the integrity information into account in terms of you're being able to write policy. The integrity protection on the labels. In particular, the SC Linux labels, which are extended attributes, if they want protection from offline attack, they can use EVM and things. The second thing, should integrity protection require encryption, you're not, you're posing this as two things and you're missing kind of the third one, which is authenticity. So I would argue that integrity slash authenticity, first of all, you have to have the concept of authenticity or we can't actually prove, for those use cases that want attestation, you can't just do it with symmetric key, you have to have a public key. And so we need to extend the concept of integrity protection from being just, you know, DM verity to being other types of things like IMA. And that can be very important for people, far more important than encryption. So I would say the argument should be, not should integrity protection require encryption, but all things should require integrity and or authenticity protection. Maybe we might want to do encryption on top of that. Yeah, so being able to do encryption without integrity, are we allowing people to shoot themselves in the foot? No, what we're saying is no, you shouldn't. You should have policy that says, you know, but it's a flip side of what you're asking in the question. It's not should integrity require encryption, it's should encryption require integrity and the obvious answer is yes, it should, but not the other way around. Integrity should not require encryption, encryption should require integrity. For the top question, mostly just a comment, which is I think we go about it the opposite way, which is that we write SE Linux policy with integrity in mind. And so an example would be for kernel module loading, we restrict kernel module loading. We restrict that modules only come from a de-embarity protected partition, for example, or we only allow system server to execute code off the system partition, which is de-embarity protected. So yeah, so that's what I did in PathTrust, but without sort of a system like that, how do you know that that is actually happening? What do you mean? So if you are just loading a kernel module, you have to figure out where the kernel module came from. And that is, well, there's a couple of ways of different loading kernel modules, depending on which syscall you use. You can either pass a file handle into the kernel or you can actually pass just a blob of data into the kernel. Yeah, so we're only allowing FNIT, so we're only allowing, currently we're only allowing file module loading through the file descriptor. Yeah, and so if you have the file descriptor, you can go back and you can get the SELinux context for it, but how do you know whether or not to trust the context? Whether or not you can trust the context associated with that file depends on the file system that it's on and whether or not that file system is actually integrity protected, or whether it's something that the attacker could just take the flash ship and go, I'm gonna set the extended attributes to whatever I want to, and now you will load my kernel module. Yeah, so if your untrusted files, or if your untrusted partition is always mapped to the same location, and you know that it's always gonna be mapped to the same location, then yes, you can actually do a... Yeah, so if we wanted to relabel on every boot or on every mount, then we could do that. I'm not convinced that the overhead in relabeling on every mount is small. Well, for some of the partitions, they're read-only, so we don't have to relabel them. For example, the system partition has the labeling in the system partition itself. But the labeling in the system partition itself, the system partition is also integrity protected, which means that we know we don't have to relabel it. With this, you can mount a file system and mount a specific point and set to context for everything under this moon point. So I don't know exactly how in Android it's made currently when you mount user data, but you could say everything that comes from something that's not then very deep protected is mounted with a specific Linux context, and every context that is set in the files under this won't ever matter. You could. I'll get away from the speaker. And that would enforce that everything on a specific file system had to have a specific label, at which point you're saying there's only one label for that file system. I don't know if that's flexible enough. I thought about it a bit, and I was like, okay, well if we were to include integrity protection into the notion of an actual SE Linux policy, how would we do it? Do we create a new type of class or a new class? Maybe we have file and then we have trusted file. I'm not sold on it. Do we create new permissions on already existing type classes? Do we have read trusted, which is different than read? I'm not sold on that one either. Do we restrict certain labels? And so you say, okay, if you came from an integrity protected file system, you can have all the labels. If you come from not integrity protected file system, you can only have these subset of labels, right? And that's more similar to what you're talking about there. Yes, it does. And so then the question of course is what happens when we take that away? Right, right, and I sense that we probably don't want to try to expand SE Linux's adversarial model after the fact. It's been very carefully designed in that model and treat the platform integrity as a separate problem and address that in a separate layer. But we're not gonna talk about AIMA this time. We're gonna talk about EVM. I couldn't hear David before. I didn't hear David before if he mentioned EVM. I heard about him talking about the decision that integrity was separated intentionally from SE Linux and that it was a separate subsystem. But the question, and that's part of the EVM, and it is an LSM for all practical purposes. But there was never, and they wanted EVM to verify the metadata. It protects the metadata for offline attack. But there is a call from AIMA into EVM. And that same call could be used from SE Linux or from any other LSM. It doesn't have to be called directly from AIMA. If the LSM wants to incorporate that. And so that goes back to, do we actually want to modify SE Linux? Or, as you mentioned, SE Linux has been very carefully architected for a certain threat model. Let's leave it and put all the integrity somewhere else. Yes, there's something else about the context when you mount a specific system somewhere. I'm not 100% sure because the SE Linux maintainer is not here. But when we do CISFS, they are separated as a context for files in CISFS. Of course, CISFS is a virtual file system, so you don't really have extended attributes. But you can write a policy and a specific files in CISFS would get specific labels. So maybe you could do the same thing for specific point points that we have interested data on it. Yeah, and so that actually relies on relabeling CISFS every time we mount it, as far as I know. I don't know. Any other discussion? So we talked about encryption and integrity. Have we considered authenticating encryption with associated data? So put the metadata as the associated data. Right, and so the question was, authenticated encryption mode, such as GCM has the AAD parameter, which is the additional authenticated data. And so your question is, could you just put in the extended attributes as what's included and what's covered there? That way you could wind up protecting the metadata with the key for that individual file as opposed to a key for the entire block device. So, yes, that is a possibility. You could do that. Although you do have a bit of a chicken and an egg issue because there is cryptographic context for the file that is stored in the extended attributes with per file encryption, because it needs to know which key is being used to protect the file in the first place. Anyway, if you picked the wrong key, then you're not going to be able to authenticate anyway, right, and check the integrity. So I'll have to chew on that for a bit and think about whether there's any particular flaw or vulnerability that could extend from that. But in general, we do want to have general protection beyond just the extended attributes of the files. We want to protect the ownership of the files, the sizes of the files, the contents of the directories, how many files are in the directories with the directory hierarchy or structure is. All of this leaks information that might be useful to an attacker who might want to know, are you running Tor or something of that sort? Yeah, and depending on your threat model, another tack too is you completely delete the directory, recreate it under a different encryption domain, and then just wait for them to repopulate the files. Yes, and in fact, we address that in Android through relabeling in essence. And so there is a hierarchical mechanism in EXT4 where every time a child of a particular directory, either a file or another subdirectory, gets accessed, it validates that the encryption policy for that file or directory matches that of its parent. Then when Android boots, it sets the root policy of the directories based on contents that are rooted in the DM Verity Protected System partition. And so we end up having a root of trust that links down there and is validated at runtime. But you have to be careful in whatever context you're deploying to make sure you're actually doing that in order to make sure you have that level of integrity. And so for something that's more general purpose than just a file system on a mobile device, it's something that we have to think about. So you mentioned about the ASGCM, so basically the extra authentication token will bring some overhead plus. It's based on AS counter modes, and you need to make sure that you never use the same nonce value again, so it's gonna be open to some such attacks. And so you've rightly pointed out that Galois Counter Mode is an extraordinarily brittle encryption mechanism. And I look for it, is anyone familiar with the Caesar competition? No, okay, look it up, it's great. Caesar competition, there's actually an effort underway to replace GCM. And so there are a lot of really promising candidates that have been proposed that don't have this vulnerability because the G hashes a linear function. And so the problem is if you wind up using the same initialization vector for any two blocks that are encrypted with the same key, then the auth key pretty much falls out, you lose it. And so you have to be very careful with what you want to architecting, how you use it. I've always used to say crypto is easy and key management is hard. I've since changed the tune of how I say it. I now say crypto is hard, key management is hard. So with ASGCM, what we've done with the architecture for EXD4 is we're actually randomly generating a new key for every single block. So we are doing rapid key derivation in order to help minimize the probability of a collision for any given key and initialization vector. Where are we getting the entropy from? So we're using the kernel entropy pool, which we trust pretty much for everything else, be it IP set keys or what have you. If you happen to be on Intel platform, you have the read-rand instruction which winds up putting entropy into that pool and so forth. But yeah, that is a concern that if you were to boot an embedded device and if you, the embedded device were to not get any information about disk seek timing or network packet timing or something, then yeah, there's a concern that you could wind up hitting, running against an entropy wall there. So it's got multiple VMs, which are all studies. Right, and so if you're using a VM, you would hope that your virtualization layer is passing through the read-rand instruction to the guest, or you're doing some mechanism for passing through entropy from the host into the guest. If you have the read-rand instruction, I don't think exhaustion is a concern that read-rand can actually go as quickly as you need it to from an entropy perspective. But yeah, oh, they don't, oh, it doesn't. Okay, so it's being pointed out to me that I've flubbed. So IPsec entropy actually comes from other sources in the kernel entropy pool. You don't read from dev you random or dev random. You actually get your seed from elsewhere. It's complicated. Okay, I might suggest adding what you get from dev you random into whatever it is you're doing. It can only help. Okay, so there's entropy that's mixed from the two sides of the, through the Diffie-Hulman key exchange mechanism. Okay, so this is an area, I do storage encryption. I don't do this whole wire encryption stuff, so I'm gonna defer to the protocol spokes for expertise and what's happening there. So we got about five minutes left if there's no further discussion. All right, I'll wrap it up. Thanks.