On Aug 2, 2016 5:20 AM, "Jason Cooper" <jason@lakedaemon.net> wrote:
>
> Morning Andy,
>
> On Mon, Aug 01, 2016 at 04:45:20PM -0700, Andy Lutomirski wrote:
> > On Aug 1, 2016 4:30 PM, "Jason Cooper" <jason@lakedaemon.net> wrote:
> > > On Mon, Aug 01, 2016 at 04:13:50PM -0700, Andy Lutomirski wrote:
> > > > On Aug 1, 2016 4:04 PM, "Jason Cooper" <jason@lakedaemon.net> wrote:
> ...
> > > > > Assuming Andy's lightweight signature scheme, it would probably be best
> > > > > to do a lookup based on the sha256 hash of the file.  Then pathnames
> > > > > don't matter, and bad files don't even get to the signature checking
> > > > > code.
> > > > >
> > > >
> > > > I'm not sure I understand what you mean.  What table would we look the hash
> > > > up in?  What are we finding in that table?
> > >
> > > From the other subthread:
> > >
> > > > Then, to verify a signature, the kernel hashes the blob, generates its
> > > > own linux_blob_signed_data, memcmps it to the one that Kyle signed
> > > > (and rejects if they differ *at all*), and then verifies the
> > > > signature.  (Do not try to be clever and parse the supplied
> > > > linux_blob_signed_data -- there is a long and storied history of
> > > > equivalent ideas being implemented incorrectly, and I can dig out
> > > > literature references if you really want.  Just generate your own and
> > > > memcmp it, which leaves no room for ambiguity.)
> > > >
> > >
> > > So, I'm suggesting that when "the kernel hashes the blob", it use that
> > > hash to locate *which* "Kyle-signed" linux_blob_signed_data it needs to
> > > compare against.  That's all, just removing the filename from the
> > > equation. :-)
> >
> > So Kyle would generate a list of signatures indexed by the blob's hash
> > instead of generating things like "iwlwifi-whatever.ucode.sig"?  Seems
> > okay.  It'll keep the existing hooks working, I think.  Of course, we still
> > need to check the "iwlwifi-whatever.ucode" bit to confirm that it matches
> > Kyle's signed data.
>
> Right.  That's where it may be better to use a version string, say the
> sha1 from linux-firmware.git, or the upstream version number.  However,
> that route means we can't easily 'build our own linux_blob_signed_data
> and do a memcmp.' since userspace may not have that info handy.

I don't think I agree, although iwlwifi may not be the best example.

The driver will say request_firmware("iwlwifi-whatever.ucode", ..., "Intel") or similar.  The distro compiles the driver.  Afterwards, Intel releases an updated, backwards-compatible blob.

If root trusts Intel, root can install that blob along with Kyle or Intel's signature, and the kernel should accept it.  We can achieve this by Kyle signing the whole struct *and providing the signed struct* or by Intel doing the equivalent operation.

But we do need the kernel to verify the "iwlwifi-whatever.ucode" string to prevent an attack in which someone does:

cp other-signed-thing.ucode iwlwifi-whatever.ucode

and thus causes the driver to upload something harmful to the card.  The reason the textual firmware name works here (for using Kyle's signature and for distro signatures) is that the string does uniquely define the firmware purpose for Linux.

If needed for vendor relations, we could accept an alternate format for vendor keys.  In that case, we avoid the wrong-blob attack by checking that the key we verify with matches the expected vendor and hope that the vendor doesn't release two pieces of hardware with firmwares that damage or attack each other.