Re: [RFC 6/8] KEYS: PGP data parser

From: Roberto Sassu
Date: Wed Feb 28 2024 - 13:00:21 EST


On Fri, 2024-02-16 at 20:54 +0100, Roberto Sassu wrote:
> On 2/16/2024 7:44 PM, Matthew Wilcox wrote:
> > On Fri, Feb 16, 2024 at 05:53:01PM +0100, Roberto Sassu wrote:
> > > On Fri, 2024-02-16 at 16:44 +0000, Matthew Wilcox wrote:
> > > > On Fri, Feb 16, 2024 at 04:24:33PM +0100, Petr Tesarik wrote:
> > > > > From: David Howells <dhowells@xxxxxxxxxx>
> > > > >
> > > > > Implement a PGP data parser for the crypto key type to use when
> > > > > instantiating a key.
> > > > >
> > > > > This parser attempts to parse the instantiation data as a PGP packet
> > > > > sequence (RFC 4880) and if it parses okay, attempts to extract a public-key
> > > > > algorithm key or subkey from it.
> > > >
> > > > I don't understand why we want to do this in-kernel instead of in
> > > > userspace and then pass in the actual key.
> > >
> > > Sigh, this is a long discussion.
> >
> > Well, yes. When you don't lay out why this is of value, it turns into a
> > long discussion. This isn't fun for me either.
> >
> > > PGP keys would be used as a system-wide trust anchor to verify RPM
> > > package headers, which already contain file digests that can be used as
> > > reference values for kernel-enforced integrity appraisal.
> >
> > The one example we have of usage comes in patch 7 of this series and is:
> >
> > gpg --dearmor < <PGP key> | keyctl padd asymmetric "" @u
> >
> > And you're already using two userspace programs there. Why not a third?
>
> I think this is very easy to answer. Why not extracting the public key
> from an x509 certificate in user space, sending it to the kernel, and
> using it for kernel module verification?
>
> > gpg --dearmor < <PGP key> | ./scripts/parse-pgp-packets | keyctl padd asymmetric "" @u
> >
> > > With the assumptions that:
> > >
> > > - In a locked-down system the kernel has more privileges than root
> > > - The kernel cannot offload this task to an user space process due to
> > > insufficient isolation
> > >
> > > the only available option is to do it in the kernel (that is what I got
> > > as suggestion).
> >
> > This sounds like there's some other way of getting the key into the
> > kernel which doesn't rely on userspace. Or are you assuming that nobody
> > bothered to trojan 'cat'?
>
> Apologies for not providing the full information at once. I'm worried
> that would be too long, and pieces can be lost in the way. If it is not
> a problem, I'm going to clarify on request.
>
> Ok, so, I'm not going to use cat to upload the PGP keys. These will be
> embedded in the kernel image, when the Linux distribution vendors build
> their kernel.
>
> This works for both secure boot and trusted boot, since the kernel image
> can be measured/verified by the boot loader.
>
> Another source for keys is the MOK database, since users might want the
> ability to verify their own software, which does not come from the Linux
> distribution.
>
> I briefly anticipated the full picture, but I will tell it more explicitly.
>
> The kernel, with the embedded PGP keys, will be able to verify the
> signature of the RPM package headers.
>
> A component that I recently developed, the digest_cache LSM, has the
> ability to extract file digests from RPM headers and provide a simple
> interface for IMA, IPE, BPF LSM and any other component to query the
> calculated digest of files being accessed, and allow/deny access to them
> depending on whether the query is successful or not.

Not the proper thread, but since we talked about it...

I finally put together the PGP key and signature parser, the
digest_cache LSM and the IMA integration patch sets, and built three
openSUSE Tumbleweed packages (kernel, digest-cache-tools, dracut),
which basically enable the integrity features that the kernel (IMA)
supports:

- IMA measurement list with RPM headers and (eventually) unknown files
that are not from Tumbleweed;

- Ability to obtain a deterministic TPM PCR value, suitable for sealing
of TPM keys

- Out of the box integrity enforcement on executable code, based on the
provenance from openSUSE Tumbleweed; nothing else is required other
than those three packages

An introduction and a guide with configuration steps can be found at:

https://github.com/linux-integrity/digest-cache-tools

I would also appreciate your comments.

Thanks

Roberto

> I already anticipate the question, if you have the problem parsing PGP
> keys, why don't you have the problem parsing RPM package headers?
>
> I started finding a solution before this became available, and the only
> alternative I found was to formally verify my code. So, I took Frama-C,
> wrote the assertions, and verified that not only the code is
> functionally correct for correct sequences of bytes, but that there is
> no illegal memory access for any arbitrary sequence (unfortunately, I
> can prove for a small buffer size).
>
> So, I'm probably going to do the same for the PGP parser, if this does
> not fly. But, we were very optimistic that this could be a valid
> alternative!
>
> Roberto