Work is now being co-ordinated via #820036 so this page may be out of date.
Contents
Implementation choices
Open questions
- Can the signature on shim be detached from the binary and combined with it during the build? This would allow reproducible builds.
- - Yes, sbattach in sbsigntool supports this
- How to verify that Microsoft hasn't tampered with the shim binary before signing?
- - Applying 'sbattach --remove' to signed shim should yield the unsigned version we sent
- How many people and who should hold the private keys for the certificate(s)? DSA? Secure Boot team? How should we backup the private keys?
- What is the verification process for the EV cert, which identity is being verified?
- Sign shim by just MS key or one package for the Debian key, one for the MS key?
Do we want a canary like the canary for Fedora/RHEL/shim upstream.
Proposed signing architecture
First option: by-hand script in dak
The main idea is to have a signing-box with access to the signing usb keys.
Basically, the steps can be described as:
- The maintainer of the package (grub/linux) uploads it to Dak
- A by-hand script inside dak is called, which will send the binaries to be signed by the signing-box
The signing-box (which runs as user 'codesign' in the diagram above) uses the ?YubiKey to sign the binaries inside the tarball
- The signing-box sends a tarball back to the by-hand script in dak with all the detached signatures
- The by-hand script sends the detached signatures to a machine accessible by the DDs
- Another (or the same) DD retrieves the detached signatures and makes a signed version of the package
- The maintainer uploads the signed package to dak
Ideally dak would upload the -signed version of the package automatically, but this can be done later. Right now, we currently have the ?YubiKeys plugged into the fasolo machine, so the signing-box would also run in fasolo for now. For security and better key management, the signing-box would run as another user that we called codesign in the diagram above.
One of the suggestions is to use a machine called coccia to host the detached signatures for the DDs to retrieve them.
what we have
signing-box code:
bash version (by Helen Koike): https://github.com/helen-fornazier/dsigning-box
Python version (by Julian Cristau): https://anonscm.debian.org/git/users/jcristau/dsa-puppet.git/commit/?h=signing&id=fe90da10367c1a3ba67829da5c7eeb43e379373a
dak patch:
what we need
- To patch dak's code, adding the by-hand script
- Install the signing-box scripts on fasolo
Second option: use buildd + debhelper instead of dak
The idea is that instead of changing dak, add the signing logic in debhelper and use it in buildd
Basically, the steps can be described as:
- The maintainer uploads the source package to Dak (without the x86_64 binary packages)
- Dak sends the package to buildd as usual
- Buildd do the usual work and build the package
- As part of the build process, in the debian/rules file of the package, it uses the dh_efisign tool (which doesn't exist yet) to build the signed version of it
- dh_efisign sends the binaries to be signed to the signing-box
- The signing-box checks if the package is in the authorized list of packages to be signed
The signing-box uses the ?YubiKey to sign the binaries inside the tarball
- The signing-box sends a tarball back to dh_efisign with all the detached signatures
- dh_efisign assembles the signed version of the binary package
- buildd publishes the package.deb and the package-signed.deb in the archive
Issues
When the package enters in the NEW queue, the binary package sent by the maintainer is not discarded, see https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=798000 Possible solutions:
- Upload source+all to the NEW queue, but it won't work with other packages as grub which doesn't provide a build for "all", we could add a grub-doc (sounds like a hack)
- Modify the NEW queue policy and accept source only uploads
- Modify the NEW queue policy for only some specific packages/maintainers
- Upload the binary packages without the -signed version of it, but make buildd to rebuild it again and discard the binaries uploaded by the maintainer
what we have
signing-box code:
bash version (by Helen Koike): https://github.com/helen-fornazier/dsigning-box
Python version (by Julian Cristau): https://anonscm.debian.org/git/users/jcristau/dsa-puppet.git/commit/?h=signing&id=fe90da10367c1a3ba67829da5c7eeb43e379373a
what we need
- Install the signing-box scripts on fasolo
- Develop the dh_efisign tool in debhelper
- Configure buildd with the debhelper tool
- Solve the NEW queue issue described above
Secure Boot General Information
The idea is to use the latest shim signed by Microsoft that will enable us to bootstrap into a later boot loader that can be signed by Debian. grub itself will need to be signed by a FTP master, so we will need to sort out key signing. Same for the kernel.
Roughly matches existing deployment in Ubuntu, although hopefully with some further improvements on top.
Software
The shim is an EFI executable that is in a format that is acceptable for signing by microsoft. UEFI has a database of keys that can be used for signing, the shim is to be used by a 3rd party.
It supports its own user-modifiable key database (?MokManager) so an end user can install their own key (requires the user to be physically present). Grub will call into the shim to verify the kernel, so you get a fully signed root of trust. Could theoretically verify initramfs and root filesystem. You can also disable sig validation so shim will launch anything you give it (again requiring physical presence)... from then on it will boot any copy of grub/kernel, without disabling secure boot entirely... allows for kernel and grub development without having to jump through a lot of hoops.
The aim is the least worst that still respects user's freedoms. Local key management was implemented by SUSE, the rest by redhat.
Potential improvements: fall-back bootloader so if a system loses all boot entries, the shim will re-enroll and register them and boot normally.
Grub has many patches from redhat/mjg causing it to operate in a secure boot way. When grub core is signed it refuses to load any modules that are unsigned. Secure boot core images are larger as a result. That code is in debian, some of it is configured off by default, but that is trivial to change. There is code to build custom uploads. For more information, please see: http://thread.gmane.org/gmane.linux.debian.devel.boot/143954
Involved and related software/packages: shim grub efilinux linux openssl mokutil pesign sbsigntool secureboot-db efitools vboot-kernel-utils
MSFT key requirements
MSFT has a short list of requirements, it boils down to these critical points:
- EV cert: this requires identify verification
- code must not be subject to GPLv3, "or any license that purports to give someone the right to demand authorization keys to be able to install modified forms of the code on a device. Code that is subject to such a license that has already been signed might have that signature revoked. For example, GRUB 2 is licensed under GPLv3 and won’t be signed."
- because of the above, we use a shim (which hands off executation to another bootloader)...this is a model where the vendor cert is embedded in a new place in the executable. Even if you receive a binary from debian, you can still verify the executables are identical. This will allow MSFT to verify the binary is the same, with only the certificate changed.
code that hasn't been SecureBoot "enlightened" won't be signed
- code signing keys must be backed up, stored, and recovered only by personnel in trusted roles, using at least dual-factor authorization in a physically secured environment.
- The private key must be protected with a hardware cryptography module. This includes but is not limited to HSMs, smart cards, smart card–like USB tokens, and TPMs. The operating environment must achieve a level of security at least equal to FIPS 140-2 Level 2.
- submitter must design and implement a strong revocation mechanism for everything the shim loads, directly and subsequently.
some shims are known to present weaknesses into the SecureBoot system. For a faster signing turnaround, we recommend that you use source code of 0.8 or higher from shim - GitHub branch.
TODO: Ubuntu does a key sharding process, required some kind of approval from Microsoft, find out what this procedure is
Task list
Package the software
sbsigntool is in the archive.
shim: 820052
secureboot-db does not have an ITP.
Prove the setup
Prove the setup works using qemu, the non-free OVMF firmware and a test dak install, see the Ubuntu wiki for details.
Generate a key
We need a RSA 2048 bit key for debian to get into ?MokManager. Debian must generate the key and the self-signed certificate of the correct form, which is embedded in the shim package that is then submitted to Microsoft. The signing request requires obtaining an EV code-signing cert, and then this has to be uploaded via Windows to Microsoft.
Here is the procedure for how it is done in Ubuntu.
TODO 1. tollef: DSA generates key and obtains EV cert for submission to MS 2. tollef: DSA generates key and self-signed cert for shim
Prepare shim
Vorlon said he would include the public key and cert from step 2 in the shim package, upload this to debian and gets through binary NEW. This will embed our own set of public keys (corresponding to those used by dak) and can load any other EFI executable signed by one of them. Later, there will be a shim-signed package containing the same executable with a Microsoft signature. (This costs money and takes several days, but shim should require only very infrequent changes.)
Then Tollef (or whoever has control of the EV cert) extracts the shim binary, puts it into a cab, signs that with the EV cert
Need ?MokManager support in the shim (in order to allow user to enable/disable kernel signature verification). Ubuntu has packaging that has mokmanager, though it has not yet passed through Microsoft review and is therefore not currently live in any Ubuntu release. TODO: vorlon will maintain this in debian, but is going to wait on this until we have a key
Sacrifice goats
Some poor soul sacrifices their remaining dignity and runs windows to upload this
dak changes
Ben Hutchings and Julien Cristau working on this in 821051.
For reference: Launchpad code, tests
grub
Colin will update the GRUB package to build a to-be-signed monolithic EFI executable separate from the package. Then he will add a grub-signed package (820050) that includes the Debian-signed executable from the archive. This executable would be suitable for use on both removable media and the installed system.
Note: this cannot be done until the dak changes are in place and configured with an appropriate signing key. However, once they are, it's a trivial switch in grub2/debian/rules to enable it, since the necessary code is already there, just conditionalised for Ubuntu.
kernel
The kernel team will need to upload kernel images for signing and add linux-image-signed packages (820006) with the Debian-signed kernel images.
Locking down things in the kernel: you need to be able to distinguish between root and the kernel in a secure boot environment. In the past root could modify kernel... secure boot prevents that, so there is an incentive to lock down the kernel so root cannot do that in various ways. There would be an external patch set that would do this that debian would have to carry until upstream Linux will do their reimplementation. We are going to turn on this patchset by default when secureboot is enabled (820008).