Author Archives: jejb

UEFI Secure Boot Tools Updated for 2.4

UEFI 2.4 has been out for a while (18 months to be exact).  However, it’s taken me a while to redo the tianocore builds for the 2.4 base.  This is now done, so the OVMF packages are now building 2.4 roms

https://build.opensuse.org/package/show/home:jejb1:UEFI/OVMF

Please remember that this is bleeding edge.  I found a few bugs while testing the tools, so there are likely many more lurking in there.  I’ve also updated the tools package

https://build.opensuse.org/package/show/home:jejb1:UEFI/efitools

As of version 1.5.1, there’s a new generator for hashed revocation certificates and KeyTool now supports the timestamp signature database.  I’ve also published a version of sbsigntools

https://build.opensuse.org/package/show/home:jejb1:UEFI/sbsigntools

Which, as of 0.7, has support for multiple signatures.

Getting a Windows Printer (Ricoh Aficio SP 204) natively running on Linux

Printing and scanning has always been the bane of Linux.  I thought I solved it three years ago by getting a nice network printer (HP OfficeJet Pro 8600) which spoke postscript and could scan to folder (provided you have samba installed).  Unfortunately, this is an inkjet printer and about three months ago the initial cartridges (which are deliberately lightly loaded) ran out of ink.  Purchasing new ones (it’s colour so I need four) turned out to be an arm and a leg (or 2x what the printer cost to buy in the first place).  Three months after replacement, the whole thing died with a call HP technicians error.  This turns out mostly to mean my ink cartridges are leaking.  Sure enough the entire inside is awash with a substance more costly than liquid gold … plus it’s now all over my shirt and trousers.  Trying to clean it out just gets ink all over the desk and some important papers.  Of course, since it’s a UK purchased printer and I’m now living in the US, HP support “cannot help”.  Vowing never to purchase another @!**#@ inkjet printer as long as I live, it’s time to find a cheap multi-function laser (did I mention the scanner function on the HP won’t work either now because when it gets this error it locks every function).

Investigating lasers, the cheapest multi-function seems to be a Ricoh Aficio SP204 N (the N means netowrk connected, which is nice) for US$60, which is a bargain, plus it’s a laser.  Google confirms it can scan to pdf (via file share or email), the only drawback is that the printer engine is “windows only” (one of those direct render on the system and send to printer ones).  Further googling around for the printer and linux drivers (and even DDST, the Ricoh name for their direct rendering protocol on linux) yields nothing.  Looks like I’ll be writing a driver when it arrives.  Fortunately, there is a way of running it (using KVM instead of VirtualBox) providing you have a windows virtual machine, so that’s the initial plan.  The only other annoyance is it doesn’t do duplex (either for scanning or printing).  Bummer, but you can’t have everything for US$60.

When the printer arrives, it turns out it has a web interface (yay) but you can’t program scan destinations with it (and without scan destinations, it won’t scan) … bummer.  Install the windows virtual machine with the Ricoh driver and use the tool to program scan to email; amazingly enough it all works correctly (it even scans in colour).  Followed the redirection directions with ghostview, ghostscript and redmon and successfully attach the printer to Linux.

Now to get the thing working under linux.  First step is to use tcpdump to track the communication between the windows machine and the printer:

tcpdump -n -w /tmp/trace.ricoh -i eth0 <printer ip>

And then print something.  Looking at the trace file in wireshark, the windows driver uses the HP Jetdirect port (9100).  In wireshark, select the first packet to this port and right click on “follow TCP stream”.  That gives the whole file the windows system sent.  Now save it to a file (tmp.winprint) and see if that’s enough the get the printer going.  You do this by sending the saved file to the printer with netcat:

nc <printer ip> 9100 < tmp.winprint

Wonder of wonders, it prints the same page again, so now we have the correct format to send.  A quick view with emacs reveals a HP PJL (Print Job Language) encoded header and footer with binary data in between.  This is the header:

^[%-12345X@PJL 
@PJL SET TIMESTAMP=2014/07/22 18:31:06 
@PJL SET FILENAME=gsprint 
@PJL SET COMPRESS=JBIG 
@PJL SET USERNAME=SYSTEM 
@PJL SET COVER=OFF 
@PJL SET HOLD=OFF 
@PJL SET PAGESTATUS=START 
@PJL SET COPIES=1 
@PJL SET MEDIASOURCE=TRAY1 
@PJL SET MEDIATYPE=PLAINRECYCLE 
@PJL SET PAPER=A4 
@PJL SET PAPERWIDTH=4961 
@PJL SET PAPERLENGTH=7016 
@PJL SET RESOLUTION=600 
@PJL SET IMAGELEN=61304

And this is the footer:

@PJL SET DOTCOUNT=995745 
@PJL SET PAGESTATUS=END 
@PJL EOJ 
^[%-12345X

So it all seems relatively straightforwards: each page is rendered as a pixel map in the jbig compressed image format (it’s lossless, like gif) and the header describes exactly the size and dimensions of the image.  So getting it working seems to be very straightforward: just generate the jbig images and slap on the header and footer.  Ghostscript doesn’t render natively to jbig, but it will render to ppm and the jbigkit renders what I need.  The image dimensions can be obtained from the ppm with the ImageMagick identify command.  The only fly in the ointment is the DOTCOUNT.  This shows per page how many black pixels are printed and must be something to do with the way the printer tracks the cartridge use; however, it can be faked for the moment.

The jbig format is also used in faxes, so I asked google if anyone else had a piece of code that does the split.  Since it would have the “@PJL SET COMPRESS=JBIG” line, I did a code search for that;  what do you know, it turns up a linux driver for the Ricoh Aficio SP 100:

https://github.com/madlynx/ricoh-sp100

To add insult to injury, the READMEs mention terms I’ve been searching for for ages (like Ricoh and DDST) and the driver filter even has them in the file name … honestly, for being allegedly the primary search engine of the internet, you’d sometimes wonder if google could find its own arse with both hands.

So, download this and install it and, yay, it works.  Looks like the only real difference between the SP 100 and the SP 204 is that the latter has a higher resolution mode (1200×600) and also can be adjusted to use a bypass tray (which is set in the header too).

I’ve done an initial package here and will be updating for the SP 204 additional features.

Problems with TianoCore after multi-sign (r14141) Fixed

For technical reasons, all of my tools broke with all versions of TianoCore after r14141 (Update the DxeImageVerificationLib to support for Authenticode-signed UEFI images with multiple signatures.)  What actually happened is that the multi signature verification code got stricter on the alignment requirements for signatures.  The current sbsigntools (and even pesign) simply slapped the signature block immediately at the end of the binary.  Unfortunately this meant that most of the time it wasn’t actually aligned on a long word boundary meaning that most signatures with old versions of sbsign and pesign start giving security violations on new TianoCore platforms.  I’ve fixed sbsigntools to pad the end of the binary and ensure that the signature block always starts on a long word alignment and verified that the signatures now work again with the latest versions of TianoCore.

I’ve updated the OVMF, efitools and sbsigntools packages with fixes for this problem and they should now be propagating through the system.

efitools 1.4 with linux key manipulation utilities released

This is a short post to announce the release of efitools version 1.4. The packages are available here:

http://download.opensuse.org/repositories/home:/jejb1:/UEFI/

Just select your distribution (various versions of Debian, Ubuntu, Fedora and openSUSE).

The main additions over version 1.3 is that there are two new utilities: efi-readvar and efi-updatevar that allow you to read and manipulate the UEFI signatures database from linux userspace.  The disadvantage of these tools is that they require the new efivarfs filesystem to be mounted somewhere in the system (efivarfs was added in kernel 3.8, so you either have to be running a very recent distribution, like openSUSE Tumbleweed, or you have to build your own kernels to use it).    To mount the efivarfs filesystem, just do

modprobe efivars

mount -o efivarfs none /mnt (or some other useful mount point)

As long as this is successful, you can now use the efi- tools to read and write the secure variables.  In order to write the variables in User Mode, you must have the private part of the Platform and Key Exchange Keys available.  So, assuming your private part of the platform key is PK.key, you can add your own KEK with

efi-updatevar -a -c KEK.crt -k PK.key KEK

And then add your own signature database key with

efi-updatevar -a -c DB.crt -k KEK.key db

Where KEK.crt and DB.crt are X509 certificates.

Note that by default, files in the efivarfs filesystem are owned by root and have permission 0644, so efi-readvar can be executed by any user, but efi-updatevar needs to be able to write to the variable files (i.e. would have to run as root).

There’s also extensive man pages documenting all the options for both efi-readvar and efi-updatevar.

Debian and Ubuntu packages for sbsigntools and efitools built

I got a lot of complaints about the lack of Debian or Ubuntu packages.  Apparently alien doesn’t work all that well, and some of the packages (like libc) are too new anyway on openSUSE.  So I finally figured out how to get OBS to build debian packages.  You can find them here:

http://download.opensuse.org/repositories/home:/jejb1:/UEFI/

I should note that don’t have an Ubuntu system, so the Ubuntu debs are untested.  The Debian packages work on my wheezy and testing systems.  In spite of the directory name, I severely doubt they’ll work properly on Debian 6.0: the openssl on that platform is too old, so I had to construct a special one just to get it to build.

If you want to keep them up to date, add this line to /etc/apt/sources

deb http://download.opensuse.org/repositories/home:/jejb1:/UEFI/Debian_6.0/ ./

And also add the repository key with apt-key add

Owning your Windows 8 UEFI Platform

Even if you only ever plan to run Windows or stock distributions of Linux that already have secure boot support, I’d encourage everybody who has a new UEFI secure boot platform to take ownership of it.  The way you do this is by installing your own Platform Key.  Once you have done this, you can use key database maintenance tools like keytool to edit all the keys on the Platform and move the platform programmatically from Setup Mode to User Mode and back again.  This blog post describes how you go about doing this.

First Save the Variables

The first thing to do is to install and run KeyTool either directly (the platform must have secure boot turned off, because keytool is unsigned) or via the mini USB image and save all the current secure variable keys (select the ‘Save Keys’ option from the top level menu).  This will save the contents of each variable as a single esl (EFI Signature List) file, so you should end up with three files: PK.esl, KEK.esl and db.esl.  These files can later be used to restore the contents if something goes wrong in the updates (and because some platforms put you into setup mode by erasing the contents of all the secure variables), so save them in a safe place.

Use the UEFI Menus to remove the Platform Key

This is the step that it’s impossible to be precise about.  Every UEFI platform seems to be different in how you do this.  The Linux Foundation hosts a web page collecting the information but so far it only has the Intel Tunnel Mountain system on it, but if you work it out for your platform, leave me a comment describing what you did and I’ll add it to the LF page.

The most common way to get a UEFI system to display the UEFI menus is to press ESC as it boots up.

Create your own Platform Key

If you rpm installed efitools, it will automatically have created a Platform Key for you in /usr/share/efitools/keys, plus all of the PK.auth and noPK.auth files.

A platform key may be self signed, but doesn’t have to be (I’m using one signed with my root certificate). However, assuming you want to create a self-signed platform key manually, here are the steps: The standard command for doing this with openssl is

openssl req -new -x509 -newkey rsa:2048 -subj “/CN=<my CN text>/” -keyout PK.key -out PK.crt -days 3650 -nodes -sha256

None of the parameters for the key (Like the Common Name) matters, so you can replace <my CN text> with anything you like (mine says ‘James Bottomley Platform Key 2013’) you can also add other X509 well known objects like your address.  Once you have the two files PK.crt and PK.key, you need to save them in a safe location (PK.key is the one to guard since it’s your private key).

Next, create an EFI Signature List file with the public key in (this and the next steps require that you have either installed the efitools rpm or compiled the unix commands from efitools.git and installed them on your system)

cert-to-efi-sig-list -g <my random guid> PK.crt PK.esl

where <my random guid> is any random GUID you choose.  You also need to create an empty noPK.esl file which can be used to remove the platform key again

> noPK.esl

(do an ls -l on it to make sure it has zero size).

Now you create the signed update files (called .auth files)

sign-efi-sig-list -k PK.key -c PK.crt PK PK.esl PK.auth

sign-efi-sig-list -k PK.key -c PK.crt PK noPK.esl noPK.auth

copy the two .auth files to your USB key and you should now be able to use KeyTool to insert them into where the platform key is.  Go to ‘Edit Keys’, select the ‘The Platform Key (PK)’ and then ‘Replace Keys(s)’.  Navigate the file Chooser to your PK.auth file and you now are the platform Owner.  Press ESC to go to the top level menu and it should tell you the platform is in User Mode and Secure Boot is enabled.  Now verify you can move back to Setup Mode by going to ‘Edit Keys’, ‘The Platform Key (PK)’ and this time selecting the first entry (showing the GUID you chose for your platform key) and then ‘Delete with .auth file’.  This time navigate to noPK.auth and select it.  The platform key should now be gone and when you ESC to the top menu it will tell you you are in Setup Mode.  You now own your own platform and can move easily between setup and user modes.

Replace or Edit the rest of the Keys

Now you own your own platform, restoring or replacing the current platform keys is easy.  Where you saved the original keys, you should have a KEK.esl and a db.esl file.  If you find that KEK and db are blank, you can restore them with this file, simply place the platform into Setup Mode, go to ‘Edit Keys’, ‘The Key Exchange Key Database (KEK)’ and ‘Replace Key(s)’ and finally navigate to the KEK.esl file you saved.  You can also do the same thing with db.esl

Now your platform should be back to its original condition except that you own the Platform Key and can decide easily to flip it into Setup Mode.  Once in setup mode, you can edit the actual keys.  One thing you can do is create your own signature key (using the method above for PK) and place it into db.  You could also (assuming you never plan to boot windows) delete all the microsoft keys from the system.  Beware if you decide to do this that some of your UEFI drivers may be signed by microsoft keys, and removing them all may limit the functionality of your UEFI platform.  Additionally, any UEFI update to your system is also likely to come signed with the microsoft keys, however, in this case you can put the Microsoft keys back before doing the update.

If pieces of your UEFI system do need to be signed, it might be possible to extract them and sign them with your key instead of Microsoft’s, but I haven’t yet found a system that needs this, so I don’t really have much of an idea how to do it.

Remember to move your platform back to User Mode to enable secure boot before you exit KeyTool.

Linux Foundation Secure Boot System Released

As promised, here is the Linux Foundation UEFI secure boot system.  This was actually released to us by Microsoft on Wednesday 6 February, but with travel, conferences and meetings I didn’t really get time to validate it all until today.  The files are here

I’ve also put together a mini-USB image that is bootable (just dd it on to any USB key; the image is gpt partitioned, so use the whole disk device).  It has an EFI shell where the kernel should be and uses gummiboot to load.  You can find it here (md5sum 7971231d133e41dd667a184c255b599f).

To use the mini-USB image, you have to enroll the hashes for loader.efi (in the \EFI\BOOT directory; actually gummiboot) as well as shell.efi (in the top level directory).  It also includes a copy of KeyTool.efi which you have to enrol the hash of to run as well.

What Happened to KeyTool.efi?

Originally this was going to be part of our signed release kit.  However, during testing Microsoft discovered that because of a bug in one of the UEFI platforms, it could be used to remove the platform key programmatically, which would rather subvert the UEFI security system.  Until we can resolve this (we’ve now got the particular vendor in the loop), they declined to sign KeyTool.efi although you can, of course, authorize it by hash in the MOK variables if you want to run it.

Let me know how this goes because I’m very interested to gather feedback about what works and what doesn’t work.  In particular, there’s a worry that the security protocol override might not work on some platforms, so I particularly want to know if it doesn’t work for you.

LCA2013 and Rearchitecting Secure Boot

I’ve been quiet for a while, so it’s time to give an update about what’s happening with the Linux Foundation secure boot loader (Especially as this has recently been presented at LCA2013 [slides]).

The gist of the problem is that GregKH discovered in early December that the proposed Pre-BootLoader wouldn’t work in its current form with Gummiboot.  This was a bit disheartening because it meant that it didn’t fulfill the Linux Foundation mission of enabling all bootloaders.  On investigation, the reason was simple: Gummiboot was created to demonstrate you could make a small and simple bootloader that takes advantage of all the services available in the UEFI platform instead of being the massive link loader that things like grub are.  Unfortunately this means that it boots kernels using BootServices->LoadImage(), which means that the kernel to be booted is run through the UEFI platform secure boot checks.  Originally Pre-BootLoader, like shim, was written to use PE/Coff link loading to defeat the secure boot checks.  Unfortunately, this means that something run by the Pre-BootLoader must also use link loading to defeat the secure boot checks on anything it wants to load and thus, Gummiboot, which is deliberately not a link loader, won’t work under this scheme.

So time for a re-architecture and a re-write:  The problem has now gone from being how do we create a Microsoft signed link loader that obeys their policies to how do we enable all children of the bootloader to use BootServices->LoadImage() in a way that obeys their policies.  Fortunately, there is a way to intercept the UEFI platform signing infrastructure by installing your own security architecture protocol (See the Platform Initialization spec Volume 2 section 12.9).  Unfortunately, the PI Spec isn’t actually part of the UEFI specification, but fortunately it is implemented by every Windows 8 system that I can find.  The new architecture now Intercepts this protocol and adds its own security check.  However, there’s a second problem: While we’re in the security architecture protocol callback, we don’t necessarily own the screen of the UEFI system, making it completely impossible to do a present user test for authorising the running of the bnary.  Fortunately, there does exist a non interactive way of doing this and that’s the SUSE MOK mechanism.  Thus, the Linux Foundation Pre-BootLoader has now evolved to use the standard MOK variables to store hashes of authorized binaries.

The upshot of all of this is you can now use Pre-BootLoader with Gummiboot (as demoed at LCA2013).  To boot, you have to add two hashes: one for Gummiboot itself and one for the kernel you’re booting, but actually this is a good thing because now you have a single security policy controlling all of your boot sequence.  Gummiboot itself has also been patched to recognise a failure due to secure boot and pop up a helpful message telling you which hash to enrol.

I’ll be doing a separate post explaining how the new architecture works (or you can read the slides), but I thought I’d better explain what’s been going on for the last month.

The ARM Windows 8 Lockdown

A lot of people have been asking why the Linux Foundation is concentrating on making sure there’s a Linux Boot solution for Windows 8 PCs that’s compatible with the GPLv3 requirements and not really doing anything about ARM (for which the current Windows 8 hardware requirements mandate no ability either to turn off secure boot or to replace the keys).

The answer to this comes in several parts: firstly in the PC space, Microsoft has an effective headlock on the OEM and ODMs: no desktop PC ships without a Windows compatibility sticker (the situation is different in the server market, but this is specifically about desktop PCs).  Therefore in order to continue simply booting Linux on laptops and desktops, it is a huge priority to find a solution to this problem.  Secondly: in the overall mobile marketplace, which encompasses tablets and smartphones, Microsoft has a very tiny presence: somewhere between 2-5%.  Linux (Android) has the majority presence: by some counts, Android is >50% in this market space with Apple a close second.  Therefore, a Microsoft mandate in an industry where they have no dominance is simply not really threatening (unlike the PC space where they have complete dominance).

The third problem is more philosophical: all Apple phones and tablets are locked down via cryptographic or other means (it’s not exactly the same as the UEFI secure boot lockdown, but it is similar) so it seems unreasonable to attack Microsoft but not Apple for doing this.  Additionally, a lot of Android devices also come locked down out of the box, so we haven’t even got our own house in order yet.  HTC and Samsung have bought into the argument that a flourishing mod rom ecosystem aids sales of mobile devices, so a growing number of Android phones ship with the oem unlock functionality (which turns off the boot lock in exchange for voiding the warranty) and thus we’ve been making considerable headway opening up the Android mobile ecosystem to the mod roms.  In this instance, I’d like to proceed with the economic argument and use persuasion to make at least the Android ecosystem more open.  Since Apple wants to retain a tight leash on what they regard as their hardware, I can’t ever see them doing anything other than battle with their mod rom ecosystems, and Microsoft is pretty much of the same mind set.  In the long run it cuts them off from external sources of innovation and limits their horizons to what their in-house engineers can think of, so I really believe that having Microsoft and Apple employ lockdowns will actually contribute, at least in part, to the rise of Linux on mobile devices.

The final argument is pragmatic: every apple phone and tablet has been rooted within a few weeks of release, so in practical terms, using cryptographic methods to lock determined users out of their own hardware is ineffective.  It’s actually rarely the cryptographic protection that’s broken; most often the rootkits exploit bugs and problems in the actual boot sequence itself.  So if the Surface (or Windows phone) hardware is really enticing, I’ve no doubt we’ll see a Linux variant running on it in the near future regardless of UEFI secure boot.

Adventures in Microsoft UEFI Signing

As I explained in my previous post, we have the code for the Linux Foundation pre-bootloader in place.  However, there was a delay while we got access to the Microsoft signing system.

The first thing you have to do is pay your $99 to Verisign (now Symantec) and get a verified by Verisign key.  We did this for the Linux Foundation, and all they want to do is call head office to verify. The key comes back in a URL that installs it in your browser, but the standard Linux SSL tools can be used to extract this and create a usual PEM certificate and key.  This is nothing to do with UEFI signing, but it’s used to validate to the Microsoft sysdev system that you are who you say you are.  Before you can even create a sysdev account, you have to prove this by signing an executable they give you and upload it.  They make strict requirements that you sign it on a specific Windows platform, but sbsign worked just as well and bingo our account is created.

Once the account is created, you still can’t upload UEFI binaries for signature without first signing a paper contract.  The agreements are pretty onerous, include a ton of excluded licences (including all GPL ones for drivers, but not bootloaders).  The most onerous part is that the agreements seem to reach beyond the actual UEFI objects you sign.  The Linux Foundation lawyers concluded it is mostly harmless to the LF because we don’t ship any products, but it could be nasty for other companies.  According to Matthew Garrett, Microsoft is willing to negotiate special agreements with distributions to mitigate some of these problems.

Once the agreements are signed then the real technical fun begins.  You don’t just upload a UEFI binary and have it signed.  First of all you have to wrap the binary in a Microsoft Cabinet file.  Fortunately, there is one open source project that can create cabinet files called lcab. Next you have to sign the cabinet file with your Verisign key.  Again, there is one open source project that can do this: osslsigncode. For anyone else needing these tools, they’re now available in my openSUSE Build Service UEFI repository. The final problem is that the file upload requires silverlight.  Unfortunately, moonlight doesn’t seem to cut it and even with the version 4 preview, the upload box shows up blank, so time to fire up windows 7 under kvm. When you get to this stage, you also have to certify that the binary “to be signed must not be licensed under GPLv3 or similar open source licenses”.  I assume the fear here is key disclosure but it’s not at all clear (or indeed what “similar open source licences” actually are).

Once the upload is done, the cabinet file goes through seven stages.  Unfortunately, the first test upload got stuck in stage 6 (signing the files).  After about 6 days, I sent a support email in to Microsoft asking what was going on.  The response: “The error code thrown by our signing process  is that your file is not a valid Win32 application? Is it valid Win32 application?”.  Reply: obviously not, it’s a valid UEFI 64 bit binary.  No further response …

Tried again.  This time I got a download email for the signed file and the dashboard says the signing failed.  Downloaded and verified.  The binary works on the secure boot platform and is signed with the key

subject=/C=US/ST=Washington/L=Redmond/O=Microsoft Corporation/OU=MOPR/CN=Microsoft Windows UEFI Driver Publisher
issuer=/C=US/ST=Washington/L=Redmond/O=Microsoft Corporation/CN=Microsoft Corporation UEFI CA 2011

Asked support why the process was indicating failed but I had a valid download and, after a flurry of emails, got back “Don’t use that file that is incorrectly signed. I will get back to you.”  I’m still not sure what the actual problem is, but if you look at the Subject of the signing key, there’s nothing in the signing key to indicate the Linux Foundation, therefore I suspect the problem is that the binary is signed with a generic Microsoft key instead of a specific (and revocable) key tied to the Linux Foundation.

However, that’s the status: We’re still waiting for Microsoft to give the Linux Foundation a validly signed pre-bootloader.  When that happens, it will get uploaded to the Linux Foundation website for all to use.