Last week, it became public that there is an attack against Secure Boot, utilizing one of Microsoft’s utilities to install a set of security policies which effectively disables bootloader verification.

In the announcement, the authors liken the this vulnerability to a “secure golden key”, referencing the Washington Post Editorial Board’s suggestion of cryptographic back doors in their wildly misguided apologia on cell phone decryption from 2014. On social media, one author has gone so far as to declare Secure Boot dead. The trade press has widely covered this as a leak of signing keys, and as such treated this as a major vulnerability with long-term implications for the ability to stop bootkits.

Rumours of My Death

The implication of a signing key leak is a strange analogy to make, since no such key has been made public, as is the declaration that this renders Secure Boot “dead”. Clear descriptions of what has actually gone wrong have been published elsewhere, and while these are vulnerabilities, they don’t defeat1 the Secure Boot mechanism. The vulnerabilities are in the interaction of Microsoft’s bootloaders and other tools. As such, Secure Boot can be used to block those binaries, mitigating the issue and stopping exploitation.

In response, UEFI is distributing an updated version of the Secure Boot revocation list, aka dbx. dbx is used to remove previously granted access from a UEFI driver or application, or from a signing certificate, declaring that signature invalid or signatures with the blacklisted certificate to be invalid. This update adds 64 new individual signature entries into dbx, raising the total to 77. The policy for issuing dbx updates has always been stated as requiring well known public vulnerabilities or active exploitation in the wild, so some entries may be for Microsoft bootloaders, while some are plausibly batched updates for minor vulnerabilities in more obscure tools—vendor drivers and tools which may have vulnerabilities but are not well known.

Obviously, a major malfunction has occurred

There has been some confusion about exactly what has been blacklisted, as the original discoverers of the vulnerability note on their updated website:

I checked the hash in the signature of several bootmgrs of several architectures against this list, and found no matches. So either this revokes many “obscure” bootmgrs and bootmgfws, or I’m checking the wrong hash. As I’m sure they know, they did not check the wrong hash. It appears Microsoft has only added dbx entries to blacklist bootloaders for their ARM-based Windows RT platforms, on which you can normally not disable Secure Boot. This seems to indicate that either Microsoft does not believe x86 machines are vulnerable2, or that their threat model has defined this as a major problem on one platform because you can’t disable Secure Boot there, but not on the other, where you normally can. It’s also likely that the threat model takes into consideration whether they believe the exploit can be used manually or is automatable, and on whether local presence is required at any point of the exploit. Part of the impetus for such distinctions lies in the economics of dbx entries.

When you update dbx, the system firmware performs a special append operation which adds any entries in the new list which are not in the existing list into the persistent storage, and the resulting value represents the combined set of entries. On a typical system, that storage is a different region of the same flash part as the system firmware. That flash part is as small as the vendor can possibly make it, due to market pressure to minimize the cost of goods sold for system’s components, to keep the marginal revenue as high as possible. In a market where pennies per machine can determine profitability, the difference between shipping 10000 64Mb W25Q64FV chips at $0.65132/per vs the 128Mb W25Q128FV at $1.05315 is a decision that will receive significant scrutiny. Even one-off machines for firmware developers often ship with the smaller part3.

The result is that the governing principle for the minimum size of a flash part you can ship winds up being the Windows logo requirements, because the Windows logo certification includes participation with Microsoft marketing programs, thus increasing revenue. Those requirements mandate that in order to use the Windows logo, systems must implement particular UEFI features, have certain defaults, et cetera. On the subject of the flash part, they say:

System.Fundamentals.Firmware.UEFISecureBoot Reserved Memory for Windows Secure Boot UEFI Variables. A total of at least 64 KB of non-volatile NVRAM storage memory must be reserved for NV UEFI variables (authenticated and unauthenticated, BS and RT) used by UEFI Secure Boot and Windows, and the maximum supported variable size must be at least 32kB. There is no maximum NVRAM storage limit.

Prior to this update, the shared dbx list was 13 entries, all SHA-256 hashes of individual binaries, for a total of 680 bytes4. This update adds 64 new entries, also all SHA-256 hashes of individual binaries, which brings the size up 775 entries taking 3780 bytes. This update is 9.5% of the guaranteed available space, and 11.5% is now in use. The good news, though, is that each binary only needs to be blacklisted once; any new exploit in the same binary is covered by the same entry.

I say we take off and nuke the site from orbit. It's the only way to be sure.

Burning through a cool 10% of the space in one afternoon is obviously not a sustainable plan, so you can see why one might conclude that this is a death knell to Secure Boot. I don’t think that’s the case. There is more we can do. In the worst case scenario, all signing keys are re-generated, every vendor updates all their boot media, UEFI drivers, and whatnot to have new signatures, and updates are issued to wipe dbx completely6, add a dbx entry for the signing certificate, and add a new signing certificate to db7. That’s clearly the nuclear option, and there are some better options.

Currently the Microsoft bootloaders are signed by a certificate with CN=Microsoft Windows, which is issued by CN=Microsoft Windows Production PCA 2011, and it in turn is issued by Microsoft’s CA, CN=Microsoft Root Certificate Authority 2010, a self-signed CA certificate. The PCA certificate in the middle of this chain is required by Windows logo requirements to be in a system’s db.

For other UEFI binaries, such as drivers and bootloaders which aren’t from Microsoft, the signing chain is different: they’re signed by CN=Microsoft Windows UEFI Driver Publisher, which is issued by CN=Microsoft Corporation UEFI CA 2011, and it is issued by CN=Microsoft Corporation Third Party Marketplace Root, which is a self-signed CA certificate. As in the Windows case, it’s the CA cert in the middle of the chain which is in the system’s db.

This organization means it’s possible to have a slightly smaller nuclear option than just blacklisting everything—all of the Windows bootloaders can be blacklisted without blacklisting everything else. That’s obviously still not a palatable solution for Microsoft for this exploit, but it hints at changes in policy by the Signing Service and the CA that could help keep this situation from recurring.

As a first step, every organization getting anything signed should be under a signing cert unique to them, and those certificates should be periodically retired and replaced. Organizations that get a large number of binaries signed should be subdivided into different signing certificates and cycled more often, possibly with an intermediate CA certificate. That would enable blacklisting of either individual signing certificates or intermediate CAs8, removing relatively broad swathes of applications en masse, rather than having to blacklist individual binaries.

This is all more overhead, but the cost of generating more certificates, storing them appropriately on HSMs, and choosing which to use on a per-binary basis pales in comparison to the prospect of filling up the flash part with dbx entries. In this setup, the ARM Windows 8.1 RT signatures could have been issued by a series of signing certificates each issued by a single intermediate CA specific to that product. This could have been one entry in the blacklist. It would not have affected other versions of Windows or other products. It would have blacklisted the exact same list of binaries, taking up 76 bytes.

  1. Or even directly involve… 

  2. It certainly seems that x86 is vulnerable. 

  3. I’ve had vendors mail me the larger one and tell me to replace it before applying a test update. Good thing I’ve got that hot air rework station handy. 

  4. Many systems have one or two more entries the system vendor has blacklisted, but they’re generally for binaries signed by that vendor’s own signer, not the UEFI signing service, and so they’re not part of the common blacklist. 

  5. This figure assumes that it’s 3 EFI_SIGNATURE_LIST headers, followed by 9, 4, and 64 entries, respectively. It’s conceivable that some well engineered firmware could re-write that as one header followed by 77 entries, since they’re all of the same type, which would make this only 3724 bytes. The UEFI Spec is silent on this optimization. I suspect nobody is using it, and really 56 bytes is not on the scale of problem we’re facing. Also most people don’t say “well engineered firmware” very often. 

  6. I don’t think this will work at all with any OS’s current tooling, but that’s a surmountable problem. 

  7. The whitelist that goes along with dbx

  8. Certificates have a section containing the really important stuff called the To-Be-Signed data. The signature by the cert’s issuer is actually a cryptographic signature on the hash of this data. Secure Boot allows blacklisting of the TBS hash for a cert, which again is a single SHA-256 hash.