Hi, This is a basically a recap of ideas I had while talking to Ben Hutchings (benh@) and my friend and colleague Johannes Winter, so a good part of the credit should go to them. All blame, however, should be directed to me. The current plans for implementing Secure Boot are (roughly) as follow: - a shim bootloader is signed by Microsoft [0]; it contains a Debian-specific, (public) signature key; - the actual bootloader is signed by Debian, and the signature is checked by the shim; - the bootloader checks the signature of the kernel; - the kernel only loads signed modules, and disables features that would lead to untrusted ring0 code being executed (securemode = 1). [0] Sadly, Microsoft is the one organisation with a signing key that is trusted out-of-the-box by most computers. Nothing prevents us from packaging a Debian-signed shim for people who wish to mess with their trust store and trust only Debian. While all of that give some guarantees that the kernelspace code is trustworthy [1], it doesn't do anything to ensure that the userspace is. A first step [2] in that direction would be to ensure that a legitimate initrd is booted. This is difficult: the initrd is generated on the device, and so cannot be signed using the Debian key; because of this, I will not even attempt to protect the initrd against somebody gaining root access on the running system [3]. A solution for this could be as follows: - When the shim bootloader is installed, a HMAC key [4] is generated, and sealed to the TPM in such a way that it is accessible iff the platform booted on this specific shim bootloader; the sealed blob is stored on /boot. - The HMAC of each installed initrd is written on /boot (say, in initrd.img-${VERSION}-${ARCH}-${SHIM_VERSION}.mac; the shim version matters). - During boot, the kernel loads a built-in “shim initrd” [5] (that is part of the same binary, and covered by the Debian signature), which unseals the HMAC key, checks that the initrd is correct, and transfers control to it. All of this nicely prevents an adversary (who doesn't have local root) from making us load their “custom” initrd: - it must be authenticated with a HMAC; - the HMAC key is only available after booting on the shim bootloader; - the adversary is in a catch-22: they need local code execution to HMAC the code they want to make us execute. [1] Note that this doesn't do much against an adversary with a kernel 0day. It's not meant to. [2] Actually, ensuring integrity until the initrd is started /and/ using full disk encryption should thwart somebody attempting to compromise a powered down laptop (if we forget that LUKS doesn't, on principle, guarantee integrity of the volume, and if the adversary doesn't replace the on-flash firmware). [3] In principle, it is possible to measure the mkinitramfs run and only allow properly-generated initrdes to be signed. In practice, this very likely breaks in horrible ways because the OS is not meant to protect running processes from root (who can poke at the processes, change the initramfs-tools config, change the data it consumes, ...). [4] I started off with having a device-specific signing key, but ended up with this scheme, where using asymetric crypto isn't required. [5] This seemed to be, to Johannes and I, the least annoying place where to put Debian-specific code; I might be very mistaken. What I glossed over until now is how to deal with a shim {up,down}grade, or with the system being restored from backups. The good news is that there is no state put in the TPM [6], so restoring a backup of /boot should be completely transparent. Handling shim versions change is similarly transparent: generate a new HMAC key for that shim version, seal it to the TPM under the right PCR constraints, and compute HMACs of all currently-installed initrds [7]. However, should a backup of /boot be restored that contains no (sealed) key for the installed shim bootloader, the system would fail to boot; I'm not sure how to handle such a mismatch, nor how likely it is. [6] Aside from the TPM proof value, which would be nuked assuming someone clears ownership, preventing the HMAC keys from being unsealed, which would make the system fail to boot. Oops. [7] Filthy lies: an initrd being built after the shim was changed but before reboot would require special care; it's not a big issue in principle, but still introduces more complexity. This should be effective against an adversary that gains physical access to a device, yet cannot tamper with the live system (by plugging in a device that exploits a buggy driver, by messing with the memory bus or a DMA-capable interface, ...) and cannot replace the firmware. As you can see, this does not outright prevent evil-maid style attacks: the goal here is to make such attacks harder/less practical. Best, nicoo
Attachment:
signature.asc
Description: PGP signature