Closed lbdroid closed 8 years ago
What I suggest we could do (I'm not sure if it's possible, it depends on the write permissions of the eMMC) is:
And then have su_sensitive accessible only with this password. Once we have this, there wouldn't be much left to do to be able to regenerate verity data.
1) true, but it would at least require consideration to support this kind of operation from superuser, and besides that, I don't really know anywhere else to file this kind of idea. 2) What do you know? I didn't realize that you could bind mount on a file like that. Requires busybox, the factory mount command errors out. Not that this negates the utility of being able to do that. 3) If I understand how it all works properly, the private key doesn't need to be on the device at all, in fact should not be on the device. In fact, the private key can probably even be discarded once it is used to sign the metadata. The public key (/verity_key) is used to validate the metadata signature.
4 and on... I think you're going a step further than what I was thinking, which was to stop at the verity process to protect against software sourced attacks, but not physical access with unlocked bootloader. I was figuring that the su_sensitive password could be entered on first boot just to a standard hash file on the userdata partition, which is write-protected against all but su-sensitive. Under those circumstances, if the bootloader is locked, physical access tampering would (assuming ability to bypass the userspace component of bootloader unlock) cause userdata wipe, which would be a clear indicator of tampering. If the bootloader is unlocked, then anyone with physical access can change everything anyway, nothing much we can do about that.
I have to admit that I'm not familiar with fastboot oem verified mode. I presume that that would be to cause the bootloader to take a dive if the boot partition signature can't verify against the key? If that's the case, then what is preventing someone who is attacking the boot partition from also attacking the key?
Edit: The password hash for su_sensitive would be protected by mandatory userdata encryption, thus even an attacker with physical access would be locked out from that.
1) Agreed, that's why I keep discussing it here ;) 2) it's easy to just have the call in C, but you should be able to do it with original mount command, though the syntax is: mount -o bind /src/test /dst/target 3) Well, if you want to change the system partition, and keep having a verified key, you NEED th private key to sign again the new system partition.
I agree on doing baby steps and starting with only dm-verity :) If you want to have on-the-fly verity update, you /need/ to have the private key somewhere on the device. That's why I suggest having it password-protected, and using the deciphering of this key as the access to su_sensitive (and we could use android's keystore API, so users can protect the key with any factor the device has to offer like fingerprinting! ok I'm going too far, sorry. (and using fingerprint for that would be stupid)).
As for the whole security-chain thingy: http://source.android.com/devices/tech/security/verifiedboot/verified-boot.html is a fairly nice explanation (though I think it's missing some steps) To sum up, when there is no blackhat around, the device has three states: locked, verified, unlocked There are two keystores readable by the bootloader, one is the OEM one, usually built in the bootloader itself (in lk/platform/msm_shared/include/oem_keystore.h for Qualcomm's lk), which can't be changed because bootloader is signed (by another key, but it's on a SoC matter). Another one, is the one in the partition called keystore. The behaviour of the bootloader, is the following: If in locked mode, only OEM key is checked, if it's ok, status is green, failed is red If in verified mode, OEM key AND keystore partitions' key are checked, if it's ok, status is yellow, failed is red If in unlocked mode, no keystore is checked, and status is also orange. keystore partition is always flashable from fastboot, but can be flashed from locked mode only if it is signed with OEM key, if in verified mode only if it is OEM or keystore.
I'm not totally sure as to which transitions are permitted how. I know locked -> unlocked needs to have the proper option ticked in Settings I guess unlocked -> locked, unlocked -> verified and verified ->locked doesn't require anything. I have no clue about verified -> unlocked.
As for the case of a vulnerability which would enable an attacker to write to eMMC, assuming he doesn't get the password of the keystore, he'll have change the key, thus changing the fingerprint, which should be displayed:
YELLOW, indicating the boot partition has been verified using the embedded certificate, and the signature is valid. The bootloader is required to display a notification and the fingerprint of the public key during boot.
Please note that I have yet to find a real implementation of all those recommendations (I assume Nexus6/Nexus9 implement it). Current Qualcomm/CAF baseline doesn't implement the yellow/orange/red screens (though they handle the states). I'm also skeptical about the 5s timeout on the red state...
2) Perfect application for implementing sudo: receiver for on boot completed, and run through a few bind mounts that are pre-authorized. 3) Unless you create a new key pair on demand, re-sign the metadata with the new key, and install the new public key on the boot partition. Then you can dump the private key.
But probably your option would be faster and has the advantage of killing two birds with one stone.
I saw that link, but what isn't clear is how to determine if a device supports that mode.
I think I agree it would be a good example. Though I think this sort of access should require su_sensitive (it's overwriting /system after all...) Easiest way to know if your device supports it, is to check if there is a partition called "keystore". Most/all CAF-based devices >= 5.1 should support it. Another way to know if your device supports it is by checking cmdline, if it has androidboot.verifiedbootstate flag (though this is not a requirement. devices can support verified boot without having this flag)
Ok understood your way. I like it, because it means to never have the private key on the device, not even in RAM (so there is no attack possible). I don't like it because means that on the Yellow screen, the fingerprint will change everytime you change the system partition. Also, using my way, we could totally deny write access to boot.img, even to su_sensitive, without preventing the rewrite of system partition from su_sensitive context. I'm quite balanced.
(I'm thinking that I'm trying to be even more secure than "standard" non-rooted ROMs, that's perhaps a bit optimistic.)
Hmm, good point about it messing with system, or at least having the same impact as messing with system. That implies that we would need to allow su_sensitive automatic execution privileges under some circumstances, its either that, or force the user to authenticate for both su_sensive and userdata decryption during boot... and then the lockscreen. Thats a lot of passwords. For automated su_sensitive execution, this would definitely require something sudo-like, in order to restrict it to very specific commands.
Or on the other hand, having the userdata partition protected by crypto, and the system partition protected by verity, maybe that's enough to allow a bind over the system partition. After all, you wouldn't be able to bind without permission to root, and baddies will be prevented from achieving that by the userdata crypto, even with direct physical access (except for unlocked phone, by rigging up something in the boot partition to auto-start after booting up).
I think that for the purposes of security, we can assume a locked bootloader, which means data wipe if somebody messes with it. Which means that we can assume by the fact that the userdata partition isn't wiped, and the kernel isn't complaining about failing verity, that the device hasn't been compromised through physical access.
Hmm, the only hole that I can immediately see here involves other root-applications messing with things like the list of bind mounts or directly creating them. Further supporting the need for implementing sudo and disabling permanent authorizations on conventional use of su. The way that su is abused in Android is probably a big part of the reason why google is working to lock it up.
Hmm... perhaps another degree of su-edness. su_bindmount, transition to it during boot to read and mount a list of bind mounts that is only readable by su_bindmount and only writable by su_sensitive, and the data that is being bound... readable globally, but writable only by su_sensitive...? Or this could lead us down a path of infinite degrees of root.
I've got the keystore partition on my N6, but not the verifiedbootstate argument, nor the alternative that they list --> firmware/android/verifiedbootstate. I wonder if that is just because it isn't activated? But you would think that being unlocked, it should send an orange....
I agree on su_bindmount, and also on the infinite degrees of root. My biggest concern is compatibility with existing apps. My proposal is to add a su_supreme, which is permissive, but which makes big red alarms everywhere (make it a persistent notification?), to first get users/devs. We implement the su_sensitive/su_bindmount/su thingies, and in the big red popup, we add a link for developers to let them reduce the sensitivity of their app.
For N6, running strings on the bootloader gives me results: yellow_continue orange_continue red_warning WARNING: Your device is unable to start because the boot image has failed the integrity check yellow_warning WARNING: Your device is not in its factory configuration The device can't verify the keystore with ID: orange_warning WARNING: Your device is not in its factory configuration If you did not make any changes, the security of your device may be at risk ID: Timeout, go ahead
I'm impressed by all the fastboot command added, just few I've noticed: fastboot oem ramdump fastboot oem show_screen vbs_screen green|red|orange|yellow
I see: usage: fastboot oem partition [options](none given) list all partitions
I think we can maintain compatibility by just dropping the option of remembering a "general" su request. That will make it slightly annoying until the application is updated to work with a higher security model without actually breaking it.
In the very least, it is at least more consistent with desktop linux, since the su command always (unless you are already root) asks for the password of the target user. In the Android case, it will always pop up and annoy the user.
Why would su_supreme need to be permissive in order to maintain compatibility? I've been playing around with the policy generated by my current source, and have yet to come across any kind of denial except when I try to interfere with kernel security, which I think only supersu would actually try to do ;). We can selectively lock out mounts over system and messing with boot partition, which shouldn't break many (if any) root applications.
My guess is that we will loads of apps not working if we don't. We can break them, and fix them one by one, or we can just log everything to see the status.
I bet you we won't have as much trouble as you think. But in any case, it is probably worth waiting to see if it becomes a problem before adding a security compromise to work around something that may not actually be a problem.
Let's merge this bug with #13
From https://source.android.com/devices/tech/security/verifiedboot/dm-verity.html
Using su_sensitive domain as discussed in issue #10 ... we may calculate new metadata and key for dm-verity based on the current filesystem, and input them into metadata partition and boot image verity key. This will allow end user to make customizations to system partition (such as ad-blocking using /system/etc/hosts list) without being forced to disable dm-verity.