[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CACYkzJ5XJOj08+hKheWDcqbPrFAwa+fFvOw+4QPAHBz1u2HgAg@mail.gmail.com>
Date: Wed, 14 May 2025 19:17:25 +0200
From: KP Singh <kpsingh@...nel.org>
To: James Bottomley <James.Bottomley@...senpartnership.com>
Cc: Paul Moore <paul@...l-moore.com>, bboscaccy@...ux.microsoft.com, bpf@...r.kernel.org,
code@...icks.com, corbet@....net, davem@...emloft.net, dhowells@...hat.com,
gnoack@...gle.com, herbert@...dor.apana.org.au, jarkko@...nel.org,
jmorris@...ei.org, jstancek@...hat.com, justinstitt@...gle.com,
keyrings@...r.kernel.org, linux-crypto@...r.kernel.org,
linux-doc@...r.kernel.org, linux-kbuild@...r.kernel.org,
linux-kernel@...r.kernel.org, linux-kselftest@...r.kernel.org,
linux-security-module@...r.kernel.org, llvm@...ts.linux.dev,
masahiroy@...nel.org, mic@...ikod.net, morbo@...gle.com, nathan@...nel.org,
neal@...pa.dev, nick.desaulniers+lkml@...il.com, nicolas@...sle.eu,
nkapron@...gle.com, roberto.sassu@...wei.com, serge@...lyn.com,
shuah@...nel.org, teknoraver@...a.com, xiyou.wangcong@...il.com,
kysrinivasan@...il.com, Linus Torvalds <torvalds@...ux-foundation.org>
Subject: Re: [PATCH v3 0/4] Introducing Hornet LSM
On Wed, May 14, 2025 at 5:39 PM James Bottomley
<James.Bottomley@...senpartnership.com> wrote:
>
> On Sun, 2025-05-11 at 04:01 +0200, KP Singh wrote:
> [...]
> > >
> > For this specific BPF case, we will directly sign a composite of the
> > first message and the hash of the second. Let H_meta = H(M_metadata).
> > The block to be signed is effectively:
> >
> > B_signed = I_loader || H_meta
> >
> > The signature generated is Sig(B_signed).
> >
> > The process then follows a similar pattern to the Alice and Bob
> > model,
> > where the kernel (Bob) verifies I_loader and H_meta using the
> > signature. Then, the trusted I_loader is responsible for verifying
> > M_metadata against the trusted H_meta.
> >
> > From an implementation standpoint:
> >
> > # Build
> >
> > bpftool (or some other tool in the user's build environment) knows
> > about the metadata (M_metadata) and the loader program (I_loader). It
> > first calculates H_meta = H(M_metadata). Then it constructs the
> > object
> > to be signed and computes the signature:
> >
> > Sig(I_loader || H_meta)
> >
> > # Loader
> >
> > bpftool generates the loader program. The initial instructions of
> > this loader program are designed to verify the SHA256 hash of the
> > metadata (M_metadata) that will be passed in a map. These
> > instructions effectively embed the precomputed H_meta as immediate
> > values.
> >
> > ld_imm64 r1, const_ptr_to_map // insn[0].src_reg ==
> > BPF_PSEUDO_MAP_IDX
> > r2 = *(u64 *)(r1 + 0);
> > ld_imm64 r3, sha256_of_map_part1 // constant precomputed by
> > bpftool (part of H_meta)
> > if r2 != r3 goto out;
> >
> > r2 = *(u64 *)(r1 + 8);
> > ld_imm64 r3, sha256_of_map_part2 // (part of H_meta)
> > if r2 != r3 goto out;
> >
> > r2 = *(u64 *)(r1 + 16);
> > ld_imm64 r3, sha256_of_map_part3 // (part of H_meta)
> > if r2 != r3 goto out;
> >
> > r2 = *(u64 *)(r1 + 24);
> > ld_imm64 r3, sha256_of_map_part4 // (part of H_meta)
> > if r2 != r3 goto out;
> > ...
> >
> > This implicitly makes the payload equivalent to the signed block
> > (B_signed)
> >
> > I_loader || H_meta
> >
> > bpftool then generates the signature of this I_loader payload (which
> > now contains the expected H_meta) using a key (system or user) with
> > new flags that work in combination with bpftool -L
>
> Could I just push back a bit on this. The theory of hash chains (which
> I've cut to shorten) is about pure data structures. The reason for
> that is that the entire hash chain is supposed to be easily
> independently verifiable in any environment because anything can
> compute the hashes of the blocks and links. This independent
> verification of the chain is key to formally proving hash chains to be
> correct. In your proposal we lose the easy verifiability because the
> link hash is embedded in the ebpf loader program which has to be
> disassembled to do the extraction of the hash and verify the loader is
> actually checking it.
I am not sure I understand your concern. This is something that can
easily be built into tooling / annotations.
bpftool -S -v <verification_key> <loader> <metadata>
Could you explain what's the use-case for "easy verifiability".
>
> I was looking at ways we could use a pure hash chain (i.e. signature
> over loader and real map hash) and it does strike me that the above
> ebpf hash verification code is pretty invariant and easy to construct,
> so it could run as a separate BPF fragment that then jumps to the real
> loader. In that case, it could be constructed on the fly in a trusted
> environment, like the kernel, from the link hash in the signature and
> the signature could just be Sig(loader || map hash) which can then be
The design I proposed does the same thing:
Sig(loader || H_metadata)
metadata is actually the data (programs, context etc) that's passed in
the map. The verification just happens in the loader program and the
loader || H_metadata is implemented elegantly to avoid any separate
payloads.
> easily verified without having to disassemble ebpf code. So we get the
> formal provability benefits of using a real hash chain while still
> keeping your verification in BPF.
>
> Regards,
>
> James
>
>
Powered by blists - more mailing lists