Linux firmware_class enhancements
This page documents progress on ongoing enhancements to the firmware_class, both ongoing development, theoretical issues, and desired bells/whistles.
Extensible firmware API
At the 2015 kernel summit it was agreed that the firmware signing facility would be generalized, callers of the firmware API already exist outside of "firmware" use, so re-branding is over due to annotate for this. [http://lkml.kernel.org/r/20151006090821.GB9030@kroah.com|Greg has noted we cannot get rid of the usermode helper], but even [http://lkml.kernel.org/r/CA+55aFwOT3azA9pBXeJFOm5oxNhQFOKWMX7Gq9Ey8mKrrFJQAw@mail.gmail.com|Linus has called for deprecating the usermode helper], a compromise is to phase the usermode helper out of most common kernel users by having the usermode helper exist only for old users. A clean series of APIs for "firmware loading" with a rebranded set of APIs will be added to enable to skip the usermode helper, make emphasis that the loader is not just for firmware, but for other things, and later get support for "firmware signing". The usermode helper code then would be compartmentalized and slowly faded.
One particular prospect user of the user mode helper was Daniel Vetter for graphics driver (hopefully he can add some info here on prospective requirements).
Proposed mock-up by Andy at the 2015 Kernel summit, sent October 26, 2015:
This is a simple mockup.
Suppose that there's some trusted keypair. The SHA256 hash of the public key is cdbcba8ee7cd604391d409872a0655d9170fcf93fd3cfca4b648559881ce4a70. There's a firmware file called "firmware.bin". The firmware file has sha256sum 81357924283b5a6a803e8bcc8fce12b0f11bf575abff9356d1a32f987b0f0022.
To sign it, create a file that looks like:
Linux firmware signature 1.0 firmware.bin 81357924283b5a6a803e8bcc8fce12b0f11bf575abff9356d1a32f987b0f0022
Then sign that using whatever signature algorithm. The signature is the public key hash followed by the raw signature. RSA PKCS #1 2.0 signatures would be fine. PKCS #1 1.5 would be okay, too, but it's a little sad. ECDSA over P-256 would probably be fine.
To verify it, you sha256sum the provided firmware blob and regenerate the same signed data:
Linux firmware signature data 1.0 firmware.bin 81357924283b5a6a803e8bcc8fce12b0f11bf575abff9356d1a32f987b0f0022
then you look up the provided key to see if you have a trusted key that hashes to the provided key hash. If you do, verify the signature.
The kernel could have any number of global trusted keys that are trusted for any firmware file whatsoever as well as any number of per-driver keys.
FWIW, I don't actually see how to use the openssl client to generate a PKCS#7 blob with authenticated data, but I didn't look that hard.
Firmware calls on init and probe
Asynchronous probe was added to help with delayed boots caused by use of fw API calls, and by the generic 30 second systemd timeout. There is still an issue present when fw APIs are used on init or probe: the kernel cannot be sure that /lib/firmware is ready. In particular when switching initramfs with pivot_root(), etc, etc.
A coccinelle rule is being worked on which maps out the users of the firmware API on init and probe, interprocedurally (calls that calls fw API too), the list is pretty big, the patch / details wil be posted soon for review.
A userspace hint to the kernel when /lib/firmware is ready is needed. Note that this hint might be something we likely can make use of for other subsystems which may need file loading on other paths on the filesystem, depending on where the subsystem is loading files from the kernel.
Core file loader
There are now 3 known kernel core file loaders:
- firmware_class: fw_read_file()
- module: kernel_read()
- kexec: copy_file_fd()
We should unify these. Since history on firmware_class has shown that races can exist on users of its APIs on init/probe against pivot_root() and other things, we probably should devise a generic userspace hint helper that informs the kernel when a path is available. The core kernel file loader could use this to ensure that when it returns 'file not found' it actually means it. The requirements for when a given path is to be ready should then be determined in userspace.
Core file loader users might want to user async file loaders then to wait for such signals.
Add a hook to let drivers stale cache (or should the OS only do this and hide the symbol?)