When firmware is uploaded to the LVFS we perform online checks on it. For example, one of the tests is looking for known badness like embedded UTF-8/UTF-16 BEGIN RSA PRIVATE KEY
strings. As part of this we use CHIPSEC (in the form of chipsec_util -n uefi decode
) which searches the binary for a UEFI volume header which is a simple string of _FVH
and then decompresses the volumes which we then read back as component shards. This works well on plain EDK2 firmware, and the packages uploaded by Lenovo and HP which use IBVs of AMI and Phoenix. The nice side effect is that we can show the user what binaries have changed, as the vendor might have accidentally forgotten to mention something in the release notes.
The elephants in the room were all the hundreds of archives from Dell which could not be loaded by chipsec
with no volume header detected. I spent a few hours last night adding support for these archives, and the secret is here:
- Decompress the firmware.cab archive into firmware.bin, disregarding the signing and metadata.
- If CHIPSEC fails to analyse
firmware.bin
, look for a > 512kB decompress-able Zlib section somewhere after the capsule header, actually in the PE binary. - The decompressed blob is in PFS format, which seems to be some Dell-specific format that’s already been reverse engineered.
- The PFS blob is not further compressed and is in one continuous block, and so the entire PFS volume can be passed to chipsec for analysis.
The Zlib start offset seems to jump around for each release, and I’ve not found any information in the original PE file that indicates the offset. If anyone wants to give me a hint to avoid searching the multimegabyte blob for two bytes (and then testing if it’s just chance, or indeed an Zlib stream…) I would be very happy, even if you have to remain anonymous.
So, to sum up:
CapsuleHeader PE Binary Zlib stream PFS FVH PE DXEs PE PEIMs …
I’ll see if chipsec upstream wants a patch to do this as it’s probably useful outside of the LVFS too.