All of lore.kernel.org
 help / color / mirror / Atom feed
* [Ksummit-discuss] [TOPIC] Secure/verified boot and roots of trust
@ 2016-08-03  2:58 Andy Lutomirski
  2016-08-03  3:24 ` Kees Cook
                   ` (5 more replies)
  0 siblings, 6 replies; 29+ messages in thread
From: Andy Lutomirski @ 2016-08-03  2:58 UTC (permalink / raw)
  To: Ard Biesheuvel, David Howells, Jason Cooper, Josh Boyer,
	Kees Cook, Ben Hutchings
  Cc: James Bottomley, Mark Brown, ksummit-discuss

I got module hashing working.  It ended up being fairly
straightforward.  I still need to deal with debug info and
disentangling it from CONFIG_MODULE_SIG, but that's just a bit of
engineering.

While doing it, occurred to me that it might be worth considering a
different way of thinking about roots of trust.

When a system does a verified boot using a static root of trust (which
should cover most of the interesting cases), we have:

 - Bootloader verifies kernel
 - Kernel verifies modules
 - Kernel verifies firmware
 - Kernel verifies filesystem (if using dm-verify or IMA)
 - Kernel verifies initramfs (AFAIK no one has worked out the details)
 - Kernel verifies device tree (seems messy to get right)
 - Kernel should maybe verify the command line (?)

The kernel does its verification with a combination of keys baked into
the kernel image and keys supplied by Secure Boot firmware (if
enabled, which I think is only the case out-of-tree).

By doing all this, we're accomplishing two goals:

 - Establishing a chain of trust rooted in or above the bootloader
 - Appeasing the Secure Boot deities.  AFAIK this specifically
requires that we verify the kernel and its modules using a combination
of EFI-supplied and distro keys.

To hold all the pieces together, we've established a rather ad-hoc and
complicated way of baking keys into the kernel (see the contents of
the certs/ directory).

I think we've made our lives considerably more complicated than they
need to be with the approach to keying that we're taking.

I'd like to discuss whether we can move a lot more of the keying into
the bootloader.  I'm envisioning:

 - Bootloader supplies public keys and policy to the kernel.
 - Bootloader verifies the initramfs if it needs to.
 - Bootloader verifies the command line if it needs to.
 - Bootloader verifies the device tree if it needs to.
 - Kernel verifies modules using a combination of module hashes and
keys from bootloader.
 - Kernel initializes IMO and/or dm-verity if needed according to
policy supplied by bootloader.
 - Bootloader extends a PCR with the keys and policy if needed.

This should cover the chain of trust case as well as the current
approach without needing to worry about baking keys into the kernel
image -- after all, a compromised bootloader can already change the
kernel image or the baked-in keys and thus do whatever it wants.

We get to simplify EFI-based keying: the bootloader or an intermediate
EFI application could pull whatever keys it likes from EFI variables
and feed them to the kernel.

The trickier part is appeasing the Secure Boot deities.  I'm not privy
to the internal discussions here, but I think this could be done in a
few ways.  For example, the bootloader could ensure that the policy it
sets is compliant.  Alternatively (since I think that some
implementations sign the kernel image itself with a key chained to the
MS roots), we could add a config option to enforce, in the kernel,
that modules must match an in-tree module hash or be signed by a key
that is built in or (optionally) chains to an EFI-supplied key.

(NB: I think that the Secure Boot rules are silly, but that's beside
the point.  I would prefer that the kernel honor them in the least
silly way possible.)

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Ksummit-discuss] [TOPIC] Secure/verified boot and roots of trust
  2016-08-03  2:58 [Ksummit-discuss] [TOPIC] Secure/verified boot and roots of trust Andy Lutomirski
@ 2016-08-03  3:24 ` Kees Cook
  2016-08-03  3:32 ` Matthew Garrett
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 29+ messages in thread
From: Kees Cook @ 2016-08-03  3:24 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: James Bottomley, Josh Boyer, Jason Cooper, ksummit-discuss, Mark Brown

On Tue, Aug 2, 2016 at 7:58 PM, Andy Lutomirski <luto@amacapital.net> wrote:
> I got module hashing working.  It ended up being fairly
> straightforward.  I still need to deal with debug info and
> disentangling it from CONFIG_MODULE_SIG, but that's just a bit of
> engineering.
>
> While doing it, occurred to me that it might be worth considering a
> different way of thinking about roots of trust.
>
> When a system does a verified boot using a static root of trust (which
> should cover most of the interesting cases), we have:
>
>  - Bootloader verifies kernel
>  - Kernel verifies modules
>  - Kernel verifies firmware
>  - Kernel verifies filesystem (if using dm-verify or IMA)
>  - Kernel verifies initramfs (AFAIK no one has worked out the details)
>  - Kernel verifies device tree (seems messy to get right)
>  - Kernel should maybe verify the command line (?)

Your proposal is similar to what Chrome OS does for its static root of
trust. Specifically it has no initramfs (though the methodology could
be trivially extended to include it).

- Bootloader has public keys baked in
- Bootloader verifies the "kernel block", which contains:
  - Kernel
  - Kernel command line
  - Device Tree
- The kernel mounts read-only root filesystem on dm-verity using
kernel command line (which has the top-level hash)
- Modules and firmware are restricted with LoadPin to come off the
root filesystem

This way there are no keys in the kernel at all, and everything is
done in the bootloader.

Chrome OS cheats in that the OS is image-based, so the root filesystem
can always be read-only. (It does upgrades in an alternate partition
and the bootloader switches between partitions after upgrade at the
next boot.) However, I don't think it's too hard to extend the basic
idea to a "normal" distro, it'd just need to have some smarts to deal
with a "kernel block" and the partition that holds modules, etc.

> The kernel does its verification with a combination of keys baked into
> the kernel image and keys supplied by Secure Boot firmware (if
> enabled, which I think is only the case out-of-tree).
>
> By doing all this, we're accomplishing two goals:
>
>  - Establishing a chain of trust rooted in or above the bootloader
>  - Appeasing the Secure Boot deities.  AFAIK this specifically
> requires that we verify the kernel and its modules using a combination
> of EFI-supplied and distro keys.
>
> To hold all the pieces together, we've established a rather ad-hoc and
> complicated way of baking keys into the kernel (see the contents of
> the certs/ directory).
>
> I think we've made our lives considerably more complicated than they
> need to be with the approach to keying that we're taking.
>
> I'd like to discuss whether we can move a lot more of the keying into
> the bootloader.  I'm envisioning:
>
>  - Bootloader supplies public keys and policy to the kernel.
>  - Bootloader verifies the initramfs if it needs to.
>  - Bootloader verifies the command line if it needs to.
>  - Bootloader verifies the device tree if it needs to.
>  - Kernel verifies modules using a combination of module hashes and
> keys from bootloader.
>  - Kernel initializes IMA and/or dm-verity if needed according to
> policy supplied by bootloader.

Even in this case, modules could be pinned to a known-good partition
without module signing. (And I would point out that without LoadPin or
IMA doing verification, firmware loading doesn't have a way to be
known-good.)

>  - Bootloader extends a PCR with the keys and policy if needed.
>
> This should cover the chain of trust case as well as the current
> approach without needing to worry about baking keys into the kernel
> image -- after all, a compromised bootloader can already change the
> kernel image or the baked-in keys and thus do whatever it wants.
>
> We get to simplify EFI-based keying: the bootloader or an intermediate
> EFI application could pull whatever keys it likes from EFI variables
> and feed them to the kernel.

I would love to just see coreboot used everywhere. UEFI is a giant
code base and hasn't been quick to embrace best-practices for
defensive security (stack canaries? W^X memory?). I know it's probably
a pipe-dream, but coreboot seems so much saner to me. (I have no
interest in dual-booting Windows, e.g.)

> The trickier part is appeasing the Secure Boot deities.  I'm not privy
> to the internal discussions here, but I think this could be done in a
> few ways.  For example, the bootloader could ensure that the policy it
> sets is compliant.  Alternatively (since I think that some
> implementations sign the kernel image itself with a key chained to the
> MS roots), we could add a config option to enforce, in the kernel,
> that modules must match an in-tree module hash or be signed by a key
> that is built in or (optionally) chains to an EFI-supplied key.
>
> (NB: I think that the Secure Boot rules are silly, but that's beside
> the point.  I would prefer that the kernel honor them in the least
> silly way possible.)

-Kees

-- 
Kees Cook
Brillo & Chrome OS Security

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Ksummit-discuss] [TOPIC] Secure/verified boot and roots of trust
  2016-08-03  2:58 [Ksummit-discuss] [TOPIC] Secure/verified boot and roots of trust Andy Lutomirski
  2016-08-03  3:24 ` Kees Cook
@ 2016-08-03  3:32 ` Matthew Garrett
  2016-08-03  4:34   ` Andy Lutomirski
  2016-08-03  8:33 ` Alexandre Belloni
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 29+ messages in thread
From: Matthew Garrett @ 2016-08-03  3:32 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: James Bottomley, Josh Boyer, Jason Cooper, ksummit-discuss, Mark Brown

On Tue, Aug 2, 2016 at 7:58 PM, Andy Lutomirski <luto@amacapital.net> wrote:
>  - Appeasing the Secure Boot deities.  AFAIK this specifically
> requires that we verify the kernel and its modules using a combination
> of EFI-supplied and distro keys.

Eh not quite. The rules are basically that if a Microsoft-signed
object can be used to compromise other operating systems, Microsoft
may unilaterally blacklist that object. Allowing arbitrary module
loading or arbitrary kexec clearly makes it straightforward to simply
use a signed Linux boot chain to then boot a compromised version of
any other operating system, defeating the point of Secure Boot. Distro
keys are used for module signing because that's the easiest way to
handle it (sign them during build and then discard the key), UEFI keys
are used to appease some manufacturers (they can ship their
binary-only drivers signed with a key that's in firmware) and shim
keys are used to allow users to sign their own modules. Since it's not
possible to insert any additional keys without physical access to the
system, that's good enough. It's probably the case that you could come
up with an entirely different policy that has the same property, and
that would also be entirely acceptable.

>  - Bootloader supplies public keys and policy to the kernel.

The main problem here is the lack of a standardised way of passing
data from bootloader to kernel. We can't just append a CPIO to the
initramfs because using arbitrary initramfs is a reasonable policy for
many usecases. Having a secure architecture-independent communications
channel between the bootloader and the kernel would be helpful in
various ways.

>  - Bootloader verifies the initramfs if it needs to.
>  - Bootloader verifies the command line if it needs to.
>  - Bootloader verifies the device tree if it needs to.
>
>  - Kernel verifies modules using a combination of module hashes and
> keys from bootloader.
>  - Kernel initializes IMO and/or dm-verity if needed according to
> policy supplied by bootloader.
>  - Bootloader extends a PCR with the keys and policy if needed.

Otherwise, yes, this all seems good.

> This should cover the chain of trust case as well as the current
> approach without needing to worry about baking keys into the kernel
> image -- after all, a compromised bootloader can already change the
> kernel image or the baked-in keys and thus do whatever it wants.

Yeah, the baked in keys are there out of convenience rather than out
of necessity.

> The trickier part is appeasing the Secure Boot deities.  I'm not privy
> to the internal discussions here, but I think this could be done in a
> few ways.  For example, the bootloader could ensure that the policy it
> sets is compliant.  Alternatively (since I think that some
> implementations sign the kernel image itself with a key chained to the
> MS roots), we could add a config option to enforce, in the kernel,
> that modules must match an in-tree module hash or be signed by a key
> that is built in or (optionally) chains to an EFI-supplied key.

I don't see any incompatibility between this functionality and
something that would be acceptable to any signing authority.

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Ksummit-discuss] [TOPIC] Secure/verified boot and roots of trust
  2016-08-03  3:32 ` Matthew Garrett
@ 2016-08-03  4:34   ` Andy Lutomirski
  2016-08-03  4:42     ` Michael S. Tsirkin
  2016-08-03  5:15     ` Matthew Garrett
  0 siblings, 2 replies; 29+ messages in thread
From: Andy Lutomirski @ 2016-08-03  4:34 UTC (permalink / raw)
  To: Matthew Garrett
  Cc: James Bottomley, Josh Boyer, Jason Cooper, ksummit-discuss, Mark Brown

On Tue, Aug 2, 2016 at 8:32 PM, Matthew Garrett <mjg59@coreos.com> wrote:
> On Tue, Aug 2, 2016 at 7:58 PM, Andy Lutomirski <luto@amacapital.net> wrote:
>>  - Appeasing the Secure Boot deities.  AFAIK this specifically
>> requires that we verify the kernel and its modules using a combination
>> of EFI-supplied and distro keys.
>
> Eh not quite. The rules are basically that if a Microsoft-signed
> object can be used to compromise other operating systems, Microsoft
> may unilaterally blacklist that object. Allowing arbitrary module
> loading or arbitrary kexec clearly makes it straightforward to simply
> use a signed Linux boot chain to then boot a compromised version of
> any other operating system, defeating the point of Secure Boot.

> Distro
> keys are used for module signing because that's the easiest way to
> handle it (sign them during build and then discard the key),

With my module hashing patches, that'll be even simpler.  The kernel
image will contain a list of SHA256 hashes of in-tree .ko files and
will accept those files.

> UEFI keys
> are used to appease some manufacturers (they can ship their
> binary-only drivers signed with a key that's in firmware) and shim
> keys are used to allow users to sign their own modules.

Hmm.  Would it be okay if a physically present user could subvert it?
For example, if a physically present user typed "insecure" into a
bootloader command line and thus turned off signature verification?

>>  - Bootloader supplies public keys and policy to the kernel.
>
> The main problem here is the lack of a standardised way of passing
> data from bootloader to kernel. We can't just append a CPIO to the
> initramfs because using arbitrary initramfs is a reasonable policy for
> many usecases. Having a secure architecture-independent communications
> channel between the bootloader and the kernel would be helpful in
> various ways.

Indeed.  I wonder if we could design such a thing?  Or at least
something that requires only minimal arch-specific work.

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Ksummit-discuss] [TOPIC] Secure/verified boot and roots of trust
  2016-08-03  4:34   ` Andy Lutomirski
@ 2016-08-03  4:42     ` Michael S. Tsirkin
  2016-08-03  4:46       ` Andy Lutomirski
  2016-08-03  5:15     ` Matthew Garrett
  1 sibling, 1 reply; 29+ messages in thread
From: Michael S. Tsirkin @ 2016-08-03  4:42 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: Josh Boyer, Jason Cooper, ksummit-discuss, James Bottomley, Mark Brown

On Tue, Aug 02, 2016 at 09:34:14PM -0700, Andy Lutomirski wrote:
> On Tue, Aug 2, 2016 at 8:32 PM, Matthew Garrett <mjg59@coreos.com> wrote:
> > On Tue, Aug 2, 2016 at 7:58 PM, Andy Lutomirski <luto@amacapital.net> wrote:
> >>  - Appeasing the Secure Boot deities.  AFAIK this specifically
> >> requires that we verify the kernel and its modules using a combination
> >> of EFI-supplied and distro keys.
> >
> > Eh not quite. The rules are basically that if a Microsoft-signed
> > object can be used to compromise other operating systems, Microsoft
> > may unilaterally blacklist that object. Allowing arbitrary module
> > loading or arbitrary kexec clearly makes it straightforward to simply
> > use a signed Linux boot chain to then boot a compromised version of
> > any other operating system, defeating the point of Secure Boot.
> 
> > Distro
> > keys are used for module signing because that's the easiest way to
> > handle it (sign them during build and then discard the key),
> 
> With my module hashing patches, that'll be even simpler.  The kernel
> image will contain a list of SHA256 hashes of in-tree .ko files and
> will accept those files.

Hmm. I kind of like ability to build and add modules to a running
kernel. And I think some distros might use it too, updating modules
without updating the kernel (doesn't work if you discard the key,
obviously).

> > UEFI keys
> > are used to appease some manufacturers (they can ship their
> > binary-only drivers signed with a key that's in firmware) and shim
> > keys are used to allow users to sign their own modules.
> 
> Hmm.  Would it be okay if a physically present user could subvert it?
> For example, if a physically present user typed "insecure" into a
> bootloader command line and thus turned off signature verification?

Typically already possible with firmware menus.

> >>  - Bootloader supplies public keys and policy to the kernel.
> >
> > The main problem here is the lack of a standardised way of passing
> > data from bootloader to kernel. We can't just append a CPIO to the
> > initramfs because using arbitrary initramfs is a reasonable policy for
> > many usecases. Having a secure architecture-independent communications
> > channel between the bootloader and the kernel would be helpful in
> > various ways.
> 
> Indeed.  I wonder if we could design such a thing?  Or at least
> something that requires only minimal arch-specific work.
> _______________________________________________
> Ksummit-discuss mailing list
> Ksummit-discuss@lists.linuxfoundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/ksummit-discuss

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Ksummit-discuss] [TOPIC] Secure/verified boot and roots of trust
  2016-08-03  4:42     ` Michael S. Tsirkin
@ 2016-08-03  4:46       ` Andy Lutomirski
  0 siblings, 0 replies; 29+ messages in thread
From: Andy Lutomirski @ 2016-08-03  4:46 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: Josh Boyer, Jason Cooper, ksummit-discuss, James Bottomley, Mark Brown

[-- Attachment #1: Type: text/plain, Size: 2217 bytes --]

On Aug 2, 2016 9:42 PM, "Michael S. Tsirkin" <mst@redhat.com> wrote:
>
> On Tue, Aug 02, 2016 at 09:34:14PM -0700, Andy Lutomirski wrote:
> > On Tue, Aug 2, 2016 at 8:32 PM, Matthew Garrett <mjg59@coreos.com>
wrote:
> > > On Tue, Aug 2, 2016 at 7:58 PM, Andy Lutomirski <luto@amacapital.net>
wrote:
> > >>  - Appeasing the Secure Boot deities.  AFAIK this specifically
> > >> requires that we verify the kernel and its modules using a
combination
> > >> of EFI-supplied and distro keys.
> > >
> > > Eh not quite. The rules are basically that if a Microsoft-signed
> > > object can be used to compromise other operating systems, Microsoft
> > > may unilaterally blacklist that object. Allowing arbitrary module
> > > loading or arbitrary kexec clearly makes it straightforward to simply
> > > use a signed Linux boot chain to then boot a compromised version of
> > > any other operating system, defeating the point of Secure Boot.
> >
> > > Distro
> > > keys are used for module signing because that's the easiest way to
> > > handle it (sign them during build and then discard the key),
> >
> > With my module hashing patches, that'll be even simpler.  The kernel
> > image will contain a list of SHA256 hashes of in-tree .ko files and
> > will accept those files.
>
> Hmm. I kind of like ability to build and add modules to a running
> kernel. And I think some distros might use it too, updating modules
> without updating the kernel (doesn't work if you discard the key,
> obviously).

I have no plans to prevent the existing module signature verification
scheme from working.  I just see no reason that in-tree modules should need
to be signed.

>
> > > UEFI keys
> > > are used to appease some manufacturers (they can ship their
> > > binary-only drivers signed with a key that's in firmware) and shim
> > > keys are used to allow users to sign their own modules.
> >
> > Hmm.  Would it be okay if a physically present user could subvert it?
> > For example, if a physically present user typed "insecure" into a
> > bootloader command line and thus turned off signature verification?
>
> Typically already possible with firmware menus.

Sure, but I'm trying to understand what types of attacks we need to resist.

[-- Attachment #2: Type: text/html, Size: 2929 bytes --]

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Ksummit-discuss] [TOPIC] Secure/verified boot and roots of trust
  2016-08-03  4:34   ` Andy Lutomirski
  2016-08-03  4:42     ` Michael S. Tsirkin
@ 2016-08-03  5:15     ` Matthew Garrett
  1 sibling, 0 replies; 29+ messages in thread
From: Matthew Garrett @ 2016-08-03  5:15 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: James Bottomley, Josh Boyer, Jason Cooper, ksummit-discuss, Mark Brown

On Tue, Aug 2, 2016 at 9:34 PM, Andy Lutomirski <luto@amacapital.net> wrote:
> On Tue, Aug 2, 2016 at 8:32 PM, Matthew Garrett <mjg59@coreos.com> wrote:
>> UEFI keys
>> are used to appease some manufacturers (they can ship their
>> binary-only drivers signed with a key that's in firmware) and shim
>> keys are used to allow users to sign their own modules.
>
> Hmm.  Would it be okay if a physically present user could subvert it?
> For example, if a physically present user typed "insecure" into a
> bootloader command line and thus turned off signature verification?

A physically present user can just disable Secure Boot. Shim has
support for doing this, at which point enforcement is disabled for the
rest of the boot chain.

>>>  - Bootloader supplies public keys and policy to the kernel.
>>
>> The main problem here is the lack of a standardised way of passing
>> data from bootloader to kernel. We can't just append a CPIO to the
>> initramfs because using arbitrary initramfs is a reasonable policy for
>> many usecases. Having a secure architecture-independent communications
>> channel between the bootloader and the kernel would be helpful in
>> various ways.
>
> Indeed.  I wonder if we could design such a thing?  Or at least
> something that requires only minimal arch-specific work.

Yeah, I think in general this would be incredibly useful. There's
various things that I've ended up implementing in x86 specific ways
because there's no standard way to pass significant quantities of data
between the boot environment and the kernel proper. DeviceTree is
probably the closest we have, but it's still somewhat architecture
specific and then we're suddenly having to deal with DTB+ACPI
scenarios we haven't necessarily planned for.

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Ksummit-discuss] [TOPIC] Secure/verified boot and roots of trust
  2016-08-03  2:58 [Ksummit-discuss] [TOPIC] Secure/verified boot and roots of trust Andy Lutomirski
  2016-08-03  3:24 ` Kees Cook
  2016-08-03  3:32 ` Matthew Garrett
@ 2016-08-03  8:33 ` Alexandre Belloni
  2016-08-03 10:31 ` Mark Brown
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 29+ messages in thread
From: Alexandre Belloni @ 2016-08-03  8:33 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: James Bottomley, Josh Boyer, Jason Cooper, ksummit-discuss, Mark Brown

Hi,

On 02/08/2016 at 19:58:07 -0700, Andy Lutomirski wrote :
> I got module hashing working.  It ended up being fairly
> straightforward.  I still need to deal with debug info and
> disentangling it from CONFIG_MODULE_SIG, but that's just a bit of
> engineering.
> 
> While doing it, occurred to me that it might be worth considering a
> different way of thinking about roots of trust.
> 
> When a system does a verified boot using a static root of trust (which
> should cover most of the interesting cases), we have:
> 
>  - Bootloader verifies kernel
>  - Kernel verifies modules
>  - Kernel verifies firmware
>  - Kernel verifies filesystem (if using dm-verify or IMA)
>  - Kernel verifies initramfs (AFAIK no one has worked out the details)
>  - Kernel verifies device tree (seems messy to get right)
>  - Kernel should maybe verify the command line (?)
> 
> The kernel does its verification with a combination of keys baked into
> the kernel image and keys supplied by Secure Boot firmware (if
> enabled, which I think is only the case out-of-tree).
> 
> By doing all this, we're accomplishing two goals:
> 
>  - Establishing a chain of trust rooted in or above the bootloader
>  - Appeasing the Secure Boot deities.  AFAIK this specifically
> requires that we verify the kernel and its modules using a combination
> of EFI-supplied and distro keys.
> 
> To hold all the pieces together, we've established a rather ad-hoc and
> complicated way of baking keys into the kernel (see the contents of
> the certs/ directory).
> 
> I think we've made our lives considerably more complicated than they
> need to be with the approach to keying that we're taking.
> 
> I'd like to discuss whether we can move a lot more of the keying into
> the bootloader.  I'm envisioning:
> 
>  - Bootloader supplies public keys and policy to the kernel.
>  - Bootloader verifies the initramfs if it needs to.
>  - Bootloader verifies the command line if it needs to.
>  - Bootloader verifies the device tree if it needs to.
>  - Kernel verifies modules using a combination of module hashes and
> keys from bootloader.
>  - Kernel initializes IMO and/or dm-verity if needed according to
> policy supplied by bootloader.
>  - Bootloader extends a PCR with the keys and policy if needed.
> 
> This should cover the chain of trust case as well as the current
> approach without needing to worry about baking keys into the kernel
> image -- after all, a compromised bootloader can already change the
> kernel image or the baked-in keys and thus do whatever it wants.
> 

There are SoCs were the ROM code is able to load a kernel image to RAM,
verify and execute it. In that case there is no bootloader involved. The
kernel then has to verify pretty much everything so I think we have to
keep a way of baking keys inside the kernel.

However, the setups I've seen until now are embedding the device tree
and the initramfs inside the kernel image so those are verified by the
ROM code.


-- 
Alexandre Belloni, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Ksummit-discuss] [TOPIC] Secure/verified boot and roots of trust
  2016-08-03  2:58 [Ksummit-discuss] [TOPIC] Secure/verified boot and roots of trust Andy Lutomirski
                   ` (2 preceding siblings ...)
  2016-08-03  8:33 ` Alexandre Belloni
@ 2016-08-03 10:31 ` Mark Brown
  2016-08-03 10:43 ` David Howells
  2016-08-03 12:42 ` James Bottomley
  5 siblings, 0 replies; 29+ messages in thread
From: Mark Brown @ 2016-08-03 10:31 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: James Bottomley, Josh Boyer, Jason Cooper, ksummit-discuss

[-- Attachment #1: Type: text/plain, Size: 410 bytes --]

On Tue, Aug 02, 2016 at 07:58:07PM -0700, Andy Lutomirski wrote:
> I got module hashing working.  It ended up being fairly
> straightforward.  I still need to deal with debug info and
> disentangling it from CONFIG_MODULE_SIG, but that's just a bit of
> engineering.

I know I let my @sirena.org.uk address leak into one of the other
threads but please use my @kernel.org address, it goes to different
places.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Ksummit-discuss] [TOPIC] Secure/verified boot and roots of trust
  2016-08-03  2:58 [Ksummit-discuss] [TOPIC] Secure/verified boot and roots of trust Andy Lutomirski
                   ` (3 preceding siblings ...)
  2016-08-03 10:31 ` Mark Brown
@ 2016-08-03 10:43 ` David Howells
  2016-08-03 16:46   ` Andy Lutomirski
  2016-08-03 12:42 ` James Bottomley
  5 siblings, 1 reply; 29+ messages in thread
From: David Howells @ 2016-08-03 10:43 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: James Bottomley, Josh Boyer, Jason Cooper, ksummit-discuss, Mark Brown

Andy Lutomirski <luto@amacapital.net> wrote:

> I got module hashing working.  It ended up being fairly
> straightforward.

It's not particularly difficult to use a flat hash table (assuming that's what
you've done), however, it's redundant, less efficient when not being used and
makes the build process more complicated.

To elaborate:

 (1) We have to keep the module signing by keys stuff in the kernel along with
     a supply of keys for it to use *anyway*.  Yes, we might then be able to
     drop the build-time transient key, but that doesn't account for very much
     image space or memory.

 (2) The x86_64 Fedora RPMs for the kernel running on my desktop right now
     contain 8783 modules.  Assuming we have a SHA256 hash for each of those
     (to keep UEFI compatibility), that's 274KiB - assuming you have just a
     simple contiguous array of hashes with no metadata of any sort.

     Add to this approx 1135 firmware binaries for another 35KiB of space.

     Assuming you bake this into the kernel image, that increases both the
     image size and the memory usage by more than a quarter of a Meg - and,
     due to the nature of the data, it cannot be compressed.

     [Note that using signatures on modules and firmware blobs does also
      require at least this much space on the *medium*, but it's (i)
      distributed and (ii) may in some cases get lost in the fs block size,
      and the amount you require inside the initrd image is automatically kept
      small.]

     Now, you can alleviate this in various ways:

     (a) You could demand-load the entire table as one lump and have a single
     	 hash in the kernel to cover the table.  This means (i) having some
     	 mechanism to do the loading before any modules or firmware is loaded,
     	 and (ii) getting the table into the initrd/initramfs image.

     (b) You could split the table up, but then the kernel needs a hash for
     	 each segment.  You could have a hash-of-table-hashes that the kernel
     	 loads (and would also need a hash for), but this means demand-loading
     	 still, and now the mechanism is getting more complicated.

	 If you did do this, you could split the table up mechanically, but
	 then mkinitrd would have to be able to work out which hash segments
	 in needs to load a particular module/firmware blob (it could do this
	 by hashing the blob and then scanning the tables for a match, then
	 selecting that table).

	 Or you could try and anticipate at build time what modules the
	 initial boot process would need and split the table that way.

     (c) You could bake in just the module/firmware hashes that you think the
     	 boot process might need and then discard those and load the full
     	 table 

 (3) If someone adds or updates a firmware blob, you can't simply add a new
     hash to the table without rebuilding your kernel.  So you need to fall
     back to using a key-based signature for this.

 (4) Unless you want to implement demand loading of the table, you can't
     discard it, which means it eats resources.  If you demand load each time
     you load a module and then discard after, that's much less efficient than
     key checking.

     You could alleviate this by not discarding the table during boot, but
     only initiate discarding at the end of the boot process since most of the
     module loading is done by that point.

 (5) The build process gets more complicated.  You can't do the hashing
     procedure until after the builder has had a chance to strip the modules.
     You then *have* to rebuild/alter the kernel image after the hashing
     procedure has completed, whether you bake in one monolithic hash table or
     demand load it.

     It's easier to do the signing procedure as the kernel image doesn't need
     to be modified.

I don't see a compelling argument for why we'd want to do module hashing at
all, given that we have to have the signature checking mechanism around anyway
for various reasons.

Firmware hashing might be a bit simpler since then you don't need a bunch of
detached signatures installing along with the firmware.

David

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Ksummit-discuss] [TOPIC] Secure/verified boot and roots of trust
  2016-08-03  2:58 [Ksummit-discuss] [TOPIC] Secure/verified boot and roots of trust Andy Lutomirski
                   ` (4 preceding siblings ...)
  2016-08-03 10:43 ` David Howells
@ 2016-08-03 12:42 ` James Bottomley
  2016-08-03 17:04   ` Andy Lutomirski
  5 siblings, 1 reply; 29+ messages in thread
From: James Bottomley @ 2016-08-03 12:42 UTC (permalink / raw)
  To: Andy Lutomirski, Ard Biesheuvel, David Howells, Jason Cooper,
	Josh Boyer, Kees Cook, Ben Hutchings
  Cc: Mark Brown, ksummit-discuss

On Tue, 2016-08-02 at 19:58 -0700, Andy Lutomirski wrote:
> I got module hashing working.  It ended up being fairly
> straightforward.  I still need to deal with debug info and
> disentangling it from CONFIG_MODULE_SIG, but that's just a bit of
> engineering.
> 
> While doing it, occurred to me that it might be worth considering a
> different way of thinking about roots of trust.
> 
> When a system does a verified boot using a static root of trust 
> (which should cover most of the interesting cases), we have:
> 
>  - Bootloader verifies kernel
>  - Kernel verifies modules
>  - Kernel verifies firmware
>  - Kernel verifies filesystem (if using dm-verify or IMA)
>  - Kernel verifies initramfs (AFAIK no one has worked out the
> details)

Measured boot has, but we don't have this in secure boot yet.

>  - Kernel verifies device tree (seems messy to get right)
>  - Kernel should maybe verify the command line (?)

Yes, we really should.  Again, measured boot does this but we currently
don't with secure boot.

> The kernel does its verification with a combination of keys baked 
> into the kernel image and keys supplied by Secure Boot firmware (if
> enabled, which I think is only the case out-of-tree).
> 
> By doing all this, we're accomplishing two goals:
> 
>  - Establishing a chain of trust rooted in or above the bootloader
>  - Appeasing the Secure Boot deities.  AFAIK this specifically
> requires that we verify the kernel and its modules using a 
> combination of EFI-supplied and distro keys.

There's nothing really to appease here.  The initial fears were
grounded in how strictly Microsoft would blacklist something that was a
threat to windows.  In practice there have been no blacklists of linux
loaders (yet).

However, it is for us to try to root the system trust in something and
we have two use cases:

   1. The shim use case where we pivot away from the default root of trust
      (the Microsoft one) to a different Linux one stored in the MokList
      variables
   2. an owned system where the user has replaced the PK and the roots of
      trust are in the secure boot variables.

The question we really want to ask is how far should the initial root
of trust (either 1 or 2 above) be used to verify the system before
giving way to alternate pivots?  Our initial pivot in 1 effectively
drops the MS root (although if you're doing 2 you keep the secure boot
root).  I think it's reasonable to verify the kernel, initrd and
command line through the same root we used for the bootloader.  But I'm
afraid I think the true answer is a policy question.  I can see some
people who would want this trust baked into the system immutable
keyring and I can also see that some people would really not want this
because they want to pivot the root of trust again.

> To hold all the pieces together, we've established a rather ad-hoc 
> and complicated way of baking keys into the kernel (see the contents 
> of the certs/ directory).
> 
> I think we've made our lives considerably more complicated than they
> need to be with the approach to keying that we're taking.
> 
> I'd like to discuss whether we can move a lot more of the keying into
> the bootloader.  I'm envisioning:
> 
>  - Bootloader supplies public keys and policy to the kernel.
>  - Bootloader verifies the initramfs if it needs to.
>  - Bootloader verifies the command line if it needs to.
>  - Bootloader verifies the device tree if it needs to.

Agreed.

>  - Kernel verifies modules using a combination of module hashes and
> keys from bootloader.

Hm, too strict: third party modules would then need a third party key
in the bootloader.

>  - Kernel initializes IMO and/or dm-verity if needed according to
> policy supplied by bootloader.
>  - Bootloader extends a PCR with the keys and policy if needed.

The rest of this looks nice (particularly the PCR part, which allows us
to seal TPM stuff to proof the boot sequence executed properly).

The bit you're missing is how the policy is communicated (more on this
below).

> This should cover the chain of trust case as well as the current
> approach without needing to worry about baking keys into the kernel
> image -- after all, a compromised bootloader can already change the
> kernel image or the baked-in keys and thus do whatever it wants.
> 
> We get to simplify EFI-based keying: the bootloader or an 
> intermediate EFI application could pull whatever keys it likes from 
> EFI variables and feed them to the kernel.
> 
> The trickier part is appeasing the Secure Boot deities.  I'm not 
> privy to the internal discussions here, but I think this could be 
> done in a few ways.  For example, the bootloader could ensure that 
> the policy it sets is compliant.  Alternatively (since I think that 
> some implementations sign the kernel image itself with a key chained 
> to the MS roots), we could add a config option to enforce, in the 
> kernel, that modules must match an in-tree module hash or be signed 
> by a key that is built in or (optionally) chains to an EFI-supplied
> key.
> 
> (NB: I think that the Secure Boot rules are silly, but that's beside
> the point.  I would prefer that the kernel honor them in the least
> silly way possible.)

I really don't think we need to worry about this bit: anything you come
up with is most likely to go way beyond what Microsoft would need as
its minimum base.

The current way secure boot policy is communicated from UEFI to the
bootloader is via the shimprotocol. It's a UEFI protocol which the
bootloader uses to verify the kernel (but not the command line or the
initrd currently).  It's actually differently constructed depending on
whether you're booting case 1 or 2.

I think we could extend the protocol to pass keys through to the kernel
(the kernel currently doesn't even load the shimprotocol in early boot,
but it could load a new shimkeyprotocol whose only job was to pass
through acceptable keys).  The next problem is how to verify the
command line and initrd.  The problem with the secure boot chain is
that it's largely static and created away from the system (great for
security but not so great for verifying dynamically created things like
the initrd).  Our problem is that even if you only install distro rpms,
the initrd is created dynamically on the running system by the rpm
scripts, so it can't come with a-priori trust from the distros, nor can
it be signed (unless the scripts have access to a private key, which is
a security risk).  One of the things I've been playing with is having a
TPM controlled key sign this (meaning that the user installing the RPM
has to type in a password to get the signature to happen), but it's
also possible to imagine a less complex system where the hashes of
acceptable command lines and initrds are stored in verified UEFI
variables and shim (or the thing which installs the shim protocol)
notifies the user there's been a change and asks for approval. 

I think this is a long winded way of saying that our problem isn't the
verification mechanisms itself, it's all in the policy.

The only real way around this initrd policy problem I can think is
either have the default what we do (or rather don't do) today: no
verification or have the distros deliver generic initrds which can be
signed (but which would be rather large).  Even if we do the latter,
the command line has to have the disk uuid, so it's still going to be
dynamic (and thus unsigned).

James

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Ksummit-discuss] [TOPIC] Secure/verified boot and roots of trust
  2016-08-03 10:43 ` David Howells
@ 2016-08-03 16:46   ` Andy Lutomirski
  2016-08-03 17:17     ` Matthew Garrett
  2016-08-03 23:01     ` Ben Hutchings
  0 siblings, 2 replies; 29+ messages in thread
From: Andy Lutomirski @ 2016-08-03 16:46 UTC (permalink / raw)
  To: David Howells
  Cc: Josh Boyer, Jason Cooper, ksummit-discuss, James Bottomley, Mark Brown

On Aug 3, 2016 3:43 AM, "David Howells" <dhowells@redhat.com> wrote:
>
> Andy Lutomirski <luto@amacapital.net> wrote:
>
> > I got module hashing working.  It ended up being fairly
> > straightforward.
>
> It's not particularly difficult to use a flat hash table (assuming that's what
> you've done), however, it's redundant, less efficient when not being used and
> makes the build process more complicated.

I think it's less complexity than the current automatic generation of
the key.  And yes, I have it working right now in a branch.

>
> To elaborate:
>
>  (1) We have to keep the module signing by keys stuff in the kernel along with
>      a supply of keys for it to use *anyway*.  Yes, we might then be able to
>      drop the build-time transient key, but that doesn't account for very much
>      image space or memory.

I object to the existence of the build-time key.  It completely breaks
reproducible builds.

>
>  (2) The x86_64 Fedora RPMs for the kernel running on my desktop right now
>      contain 8783 modules.  Assuming we have a SHA256 hash for each of those
>      (to keep UEFI compatibility), that's 274KiB - assuming you have just a
>      simple contiguous array of hashes with no metadata of any sort.

Agreed, it's annoyingly large.  This isn't the end of the world for a
couple of reasons.  We could swap it out if we cared about it.  We
could also use a hash tree, although that would further complicate the
build process, albeit not by a vast amount.

>
>      Add to this approx 1135 firmware binaries for another 35KiB of space.
>

Firmware wouldn't be covered by this mechanism.  It can't: firmware
can be updated without updating the kernel.

>
>      Now, you can alleviate this in various ways:
>

>
>  (3) If someone adds or updates a firmware blob, you can't simply add a new
>      hash to the table without rebuilding your kernel.  So you need to fall
>      back to using a key-based signature for this.
>

As above, firmware isn't affected.

>
>  (5) The build process gets more complicated.  You can't do the hashing
>      procedure until after the builder has had a chance to strip the modules.
>      You then *have* to rebuild/alter the kernel image after the hashing
>      procedure has completed, whether you bake in one monolithic hash table or
>      demand load it.

That's solvable in any number of ways.  I intend to implement at least
one solution to this problem.

>
>      It's easier to do the signing procedure as the kernel image doesn't need
>      to be modified.
>
> I don't see a compelling argument for why we'd want to do module hashing at
> all, given that we have to have the signature checking mechanism around anyway
> for various reasons.

I think that, for the Secure Boot usecase, we actually wouldn't need
the signature checking mechanism at all.  Firmware signature checking
in-kernel is important for some chain-of-trust use cases but AFAIK not
for Secure Boot for standard desktop distros.

And it gets rid of the IMO extremely nasty temporary key.  I
personally think that reproducible builds would add considerable value
to many use cases, and we currently can't simultaneously support
reproducible builds and Secure Boot without a big mess involving
trusted parties, and the whole point of reproducible builds is to
avoid needed to trust the packager.

The only real issue I'm seeing is the large size of the table for
distros.  I'll implement a hash tree and fix it at the cost forcing
the .ko files to be regenerated after any kernel changes.

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Ksummit-discuss] [TOPIC] Secure/verified boot and roots of trust
  2016-08-03 12:42 ` James Bottomley
@ 2016-08-03 17:04   ` Andy Lutomirski
  2016-08-03 17:23     ` Matthew Garrett
  2016-08-03 22:09     ` James Bottomley
  0 siblings, 2 replies; 29+ messages in thread
From: Andy Lutomirski @ 2016-08-03 17:04 UTC (permalink / raw)
  To: James Bottomley; +Cc: Josh Boyer, Jason Cooper, ksummit-discuss, Mark Brown

On Wed, Aug 3, 2016 at 5:42 AM, James Bottomley
<James.Bottomley@hansenpartnership.com> wrote:
> On Tue, 2016-08-02 at 19:58 -0700, Andy Lutomirski wrote:
>> I got module hashing working.  It ended up being fairly
>> straightforward.  I still need to deal with debug info and
>> disentangling it from CONFIG_MODULE_SIG, but that's just a bit of
>> engineering.
>>
>> While doing it, occurred to me that it might be worth considering a
>> different way of thinking about roots of trust.
>>
>> When a system does a verified boot using a static root of trust
>> (which should cover most of the interesting cases), we have:
>>
>>  - Bootloader verifies kernel
>>  - Kernel verifies modules
>>  - Kernel verifies firmware
>>  - Kernel verifies filesystem (if using dm-verify or IMA)
>>  - Kernel verifies initramfs (AFAIK no one has worked out the
>> details)
>
> Measured boot has, but we don't have this in secure boot yet.
>
>>  - Kernel verifies device tree (seems messy to get right)
>>  - Kernel should maybe verify the command line (?)
>
> Yes, we really should.  Again, measured boot does this but we currently
> don't with secure boot.

It's not really clear to me that we need it for secure boot.  We get
it for free with real verified boot a la Chromium -- the bootloader
and its configuration is trusted.

>
>> The kernel does its verification with a combination of keys baked
>> into the kernel image and keys supplied by Secure Boot firmware (if
>> enabled, which I think is only the case out-of-tree).
>>
>> By doing all this, we're accomplishing two goals:
>>
>>  - Establishing a chain of trust rooted in or above the bootloader
>>  - Appeasing the Secure Boot deities.  AFAIK this specifically
>> requires that we verify the kernel and its modules using a
>> combination of EFI-supplied and distro keys.
>
> There's nothing really to appease here.  The initial fears were
> grounded in how strictly Microsoft would blacklist something that was a
> threat to windows.  In practice there have been no blacklists of linux
> loaders (yet).
>
> However, it is for us to try to root the system trust in something and
> we have two use cases:
>
>    1. The shim use case where we pivot away from the default root of trust
>       (the Microsoft one) to a different Linux one stored in the MokList
>       variables
>    2. an owned system where the user has replaced the PK and the roots of
>       trust are in the secure boot variables.
>
> The question we really want to ask is how far should the initial root
> of trust (either 1 or 2 above) be used to verify the system before
> giving way to alternate pivots?  Our initial pivot in 1 effectively
> drops the MS root (although if you're doing 2 you keep the secure boot
> root).  I think it's reasonable to verify the kernel, initrd and
> command line through the same root we used for the bootloader.  But I'm
> afraid I think the true answer is a policy question.  I can see some
> people who would want this trust baked into the system immutable
> keyring and I can also see that some people would really not want this
> because they want to pivot the root of trust again.
>

What I'm arguing for is moving that pivot earlier and stopping
worrying about baking roots of trust into the kernel image.  If we
just decide that we're going to trust the bootloader (or some other
pre-kernel code) in some well-defined way, then this dilemma goes
away.  If you want to require signatures by a static key, bake that
key into the *bootloader* instead of the kernel.  If you want to
pivot, make the bootloader (or shim or whatever) do the pivoting.

Then the kernel can simply stop worrying about what is essentially a
policy decision.  The kernel can receive a key from the bootloader and
accept modules and such that are signed by that key.

I think the only hard parts are establishing the communication channel
from the bootloader to the kernel (which various people probably want
anyway) and defining what happens when the in-kernel EFI stub is used.

>> To hold all the pieces together, we've established a rather ad-hoc
>> and complicated way of baking keys into the kernel (see the contents
>> of the certs/ directory).
>>
>> I think we've made our lives considerably more complicated than they
>> need to be with the approach to keying that we're taking.
>>
>> I'd like to discuss whether we can move a lot more of the keying into
>> the bootloader.  I'm envisioning:
>>
>>  - Bootloader supplies public keys and policy to the kernel.
>>  - Bootloader verifies the initramfs if it needs to.
>>  - Bootloader verifies the command line if it needs to.
>>  - Bootloader verifies the device tree if it needs to.
>
> Agreed.
>
>>  - Kernel verifies modules using a combination of module hashes and
>> keys from bootloader.
>
> Hm, too strict: third party modules would then need a third party key
> in the bootloader.

What's wrong with that?  In grub language, this would be approximately:

linuxefi path/to/image
linuxkeypolicy path/to/policy

and the bootloader can presumably verify the policy file in the same
way that it verifies the image itself.

>
>>  - Kernel initializes IMO and/or dm-verity if needed according to
>> policy supplied by bootloader.
>>  - Bootloader extends a PCR with the keys and policy if needed.
>
> The rest of this looks nice (particularly the PCR part, which allows us
> to seal TPM stuff to proof the boot sequence executed properly).
>
> The bit you're missing is how the policy is communicated (more on this
> below).
>
>> This should cover the chain of trust case as well as the current
>> approach without needing to worry about baking keys into the kernel
>> image -- after all, a compromised bootloader can already change the
>> kernel image or the baked-in keys and thus do whatever it wants.
>>
>> We get to simplify EFI-based keying: the bootloader or an
>> intermediate EFI application could pull whatever keys it likes from
>> EFI variables and feed them to the kernel.
>>
>> The trickier part is appeasing the Secure Boot deities.  I'm not
>> privy to the internal discussions here, but I think this could be
>> done in a few ways.  For example, the bootloader could ensure that
>> the policy it sets is compliant.  Alternatively (since I think that
>> some implementations sign the kernel image itself with a key chained
>> to the MS roots), we could add a config option to enforce, in the
>> kernel, that modules must match an in-tree module hash or be signed
>> by a key that is built in or (optionally) chains to an EFI-supplied
>> key.
>>
>> (NB: I think that the Secure Boot rules are silly, but that's beside
>> the point.  I would prefer that the kernel honor them in the least
>> silly way possible.)
>
> I really don't think we need to worry about this bit: anything you come
> up with is most likely to go way beyond what Microsoft would need as
> its minimum base.
>
> The current way secure boot policy is communicated from UEFI to the
> bootloader is via the shimprotocol. It's a UEFI protocol which the
> bootloader uses to verify the kernel (but not the command line or the
> initrd currently).  It's actually differently constructed depending on
> whether you're booting case 1 or 2.
>
> I think we could extend the protocol to pass keys through to the kernel
> (the kernel currently doesn't even load the shimprotocol in early boot,
> but it could load a new shimkeyprotocol whose only job was to pass
> through acceptable keys).  The next problem is how to verify the
> command line and initrd.  The problem with the secure boot chain is
> that it's largely static and created away from the system (great for
> security but not so great for verifying dynamically created things like
> the initrd).  Our problem is that even if you only install distro rpms,
> the initrd is created dynamically on the running system by the rpm
> scripts, so it can't come with a-priori trust from the distros, nor can
> it be signed (unless the scripts have access to a private key, which is
> a security risk).  One of the things I've been playing with is having a
> TPM controlled key sign this (meaning that the user installing the RPM
> has to type in a password to get the signature to happen), but it's
> also possible to imagine a less complex system where the hashes of
> acceptable command lines and initrds are stored in verified UEFI
> variables and shim (or the thing which installs the shim protocol)
> notifies the user there's been a change and asks for approval.
>
> I think this is a long winded way of saying that our problem isn't the
> verification mechanisms itself, it's all in the policy.
>
> The only real way around this initrd policy problem I can think is
> either have the default what we do (or rather don't do) today: no
> verification or have the distros deliver generic initrds which can be
> signed (but which would be rather large).  Even if we do the latter,
> the command line has to have the disk uuid, so it's still going to be
> dynamic (and thus unsigned).
>

I'm not personally too worried about verifying initramfs -- initramfs
is functionally equivalent to the root filesystem, and they ought to
be verifiable the same way.  For an average desktop distro that
*doesn't* verify the rootfs, what's the point of trying to verify
initramfs?

Anyway, here's a concrete proposal for a cross-arch way to pass
trusted policy from the bootloader to the kernel: define a new
structure:

struct trusted_policy_header {
  unsigned long size;
};

Rig up the linker script so the trusted_policy is at the very end of
the kernel virtual address space and lives in its own ELF segment (or
arch equivalent).  That segment will have filesize == 0 and memsize ==
sizeof(struct trusted_policy_header).  Mark the segment so the
bootloader knows about it.

Now the bootloader can supply policy (keys and whatever else it wants)
by simply writing it to the trusted_policy_header and beyond in
memory.

As an added benefit, it would be easy to write a tool to append policy
to a compiled kernel image: literally append it to the end of the ELF
file and adjust the program table accordingly.  So desktop distros
could install their default policy to be used by the EFI stub, and the
bootloader could override the policy if it wanted to.  The build
process ends up being quite simple.

Thoughts?

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Ksummit-discuss] [TOPIC] Secure/verified boot and roots of trust
  2016-08-03 16:46   ` Andy Lutomirski
@ 2016-08-03 17:17     ` Matthew Garrett
  2016-08-03 17:23       ` Andy Lutomirski
  2016-08-03 23:01     ` Ben Hutchings
  1 sibling, 1 reply; 29+ messages in thread
From: Matthew Garrett @ 2016-08-03 17:17 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: James Bottomley, Josh Boyer, Jason Cooper, ksummit-discuss, Mark Brown

On Wed, Aug 3, 2016 at 9:46 AM, Andy Lutomirski <luto@amacapital.net> wrote:
> On Aug 3, 2016 3:43 AM, "David Howells" <dhowells@redhat.com> wrote:
>>  (1) We have to keep the module signing by keys stuff in the kernel along with
>>      a supply of keys for it to use *anyway*.  Yes, we might then be able to
>>      drop the build-time transient key, but that doesn't account for very much
>>      image space or memory.
>
> I object to the existence of the build-time key.  It completely breaks
> reproducible builds.

Keys could be stored in a separate section and ignored for the
purposes of build comparison.

>>  (3) If someone adds or updates a firmware blob, you can't simply add a new
>>      hash to the table without rebuilding your kernel.  So you need to fall
>>      back to using a key-based signature for this.
>>
>
> As above, firmware isn't affected.

There's no fundamental problem with using signed firmware (although
you'd probably need detached signatures to comply with licenses) -
it's more of a logistical problem in that you'd need an actual key
rather than a build-time one, but it's still more practical than
hashing.

>> I don't see a compelling argument for why we'd want to do module hashing at
>> all, given that we have to have the signature checking mechanism around anyway
>> for various reasons.
>
> I think that, for the Secure Boot usecase, we actually wouldn't need
> the signature checking mechanism at all.  Firmware signature checking
> in-kernel is important for some chain-of-trust use cases but AFAIK not
> for Secure Boot for standard desktop distros.

Without an IOMMU you can probably subvert any DMA capable device that
loads unsigned firmware, at which point you're in a bad place again.
This isn't something I'm losing much sleep over, since attacks that
only work if you have a specific piece of hardware installed are much
less exciting. We'd still need signature checking so that users can
install their own signing keys, and I don't see distributions being
terribly enthusiastic about having two unrelated module validation
systems.

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Ksummit-discuss] [TOPIC] Secure/verified boot and roots of trust
  2016-08-03 17:17     ` Matthew Garrett
@ 2016-08-03 17:23       ` Andy Lutomirski
  2016-08-03 17:26         ` Matthew Garrett
  2016-08-03 18:00         ` Michael S. Tsirkin
  0 siblings, 2 replies; 29+ messages in thread
From: Andy Lutomirski @ 2016-08-03 17:23 UTC (permalink / raw)
  To: Matthew Garrett
  Cc: James Bottomley, Josh Boyer, Jason Cooper, ksummit-discuss, Mark Brown

On Wed, Aug 3, 2016 at 10:17 AM, Matthew Garrett <mjg59@coreos.com> wrote:
> On Wed, Aug 3, 2016 at 9:46 AM, Andy Lutomirski <luto@amacapital.net> wrote:
>> On Aug 3, 2016 3:43 AM, "David Howells" <dhowells@redhat.com> wrote:
>>>  (1) We have to keep the module signing by keys stuff in the kernel along with
>>>      a supply of keys for it to use *anyway*.  Yes, we might then be able to
>>>      drop the build-time transient key, but that doesn't account for very much
>>>      image space or memory.
>>
>> I object to the existence of the build-time key.  It completely breaks
>> reproducible builds.
>
> Keys could be stored in a separate section and ignored for the
> purposes of build comparison.

But that defeats the purpose.  If I'm verifying a reproducible build,
I don't want to have to take it on faith that the packager didn't keep
a copy of the build-time key.

>
>>>  (3) If someone adds or updates a firmware blob, you can't simply add a new
>>>      hash to the table without rebuilding your kernel.  So you need to fall
>>>      back to using a key-based signature for this.
>>>
>>
>> As above, firmware isn't affected.
>
> There's no fundamental problem with using signed firmware (although
> you'd probably need detached signatures to comply with licenses) -
> it's more of a logistical problem in that you'd need an actual key
> rather than a build-time one, but it's still more practical than
> hashing.

I agree.  I don't think my module hashing proposal should cover firmware at all.

>
>>> I don't see a compelling argument for why we'd want to do module hashing at
>>> all, given that we have to have the signature checking mechanism around anyway
>>> for various reasons.
>>
>> I think that, for the Secure Boot usecase, we actually wouldn't need
>> the signature checking mechanism at all.  Firmware signature checking
>> in-kernel is important for some chain-of-trust use cases but AFAIK not
>> for Secure Boot for standard desktop distros.
>
> Without an IOMMU you can probably subvert any DMA capable device that
> loads unsigned firmware, at which point you're in a bad place again.
> This isn't something I'm losing much sleep over, since attacks that
> only work if you have a specific piece of hardware installed are much
> less exciting. We'd still need signature checking so that users can
> install their own signing keys, and I don't see distributions being
> terribly enthusiastic about having two unrelated module validation
> systems.

That's a question for the distros.  My intent would be to make the
module hashing scheme as painless as possible for the distros: distros
would just enable a config option and, if needed, adjust their debug
info generation slightly.

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Ksummit-discuss] [TOPIC] Secure/verified boot and roots of trust
  2016-08-03 17:04   ` Andy Lutomirski
@ 2016-08-03 17:23     ` Matthew Garrett
  2016-08-03 17:29       ` Andy Lutomirski
  2016-08-03 22:09     ` James Bottomley
  1 sibling, 1 reply; 29+ messages in thread
From: Matthew Garrett @ 2016-08-03 17:23 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: James Bottomley, Josh Boyer, Jason Cooper, ksummit-discuss, Mark Brown

On Wed, Aug 3, 2016 at 10:04 AM, Andy Lutomirski <luto@amacapital.net> wrote:
> What's wrong with that?  In grub language, this would be approximately:
>
> linuxefi path/to/image
> linuxkeypolicy path/to/policy

Thinking about it further - there's no real problem integrating this
with a build-time key. Rather than having the public half in the
kernel, stash the public half in the packaging and then have the
signing step (that's signing the kernel anyway) also sign the key. The
bootloader verifies that the key is signed by a trusted root and
passes that on to the kernel. If we have a standardised mechanism for
the bootloader to pass this information on, it's absolutely possible
to push the root of trust down to the bootloader (and also make it
responsible for pulling any other signing keys out of EFI variables or
wherever)

> Anyway, here's a concrete proposal for a cross-arch way to pass
> trusted policy from the bootloader to the kernel: define a new
> structure:
>
> struct trusted_policy_header {
>   unsigned long size;
> };
>
> Rig up the linker script so the trusted_policy is at the very end of
> the kernel virtual address space and lives in its own ELF segment (or
> arch equivalent).  That segment will have filesize == 0 and memsize ==
> sizeof(struct trusted_policy_header).  Mark the segment so the
> bootloader knows about it.
>
> Now the bootloader can supply policy (keys and whatever else it wants)
> by simply writing it to the trusted_policy_header and beyond in
> memory.

The bootloader doesn't see the ELF object on (at least) x86?

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Ksummit-discuss] [TOPIC] Secure/verified boot and roots of trust
  2016-08-03 17:23       ` Andy Lutomirski
@ 2016-08-03 17:26         ` Matthew Garrett
  2016-08-03 17:28           ` Andy Lutomirski
  2016-08-03 18:00         ` Michael S. Tsirkin
  1 sibling, 1 reply; 29+ messages in thread
From: Matthew Garrett @ 2016-08-03 17:26 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: James Bottomley, Josh Boyer, Jason Cooper, ksummit-discuss, Mark Brown

On Wed, Aug 3, 2016 at 10:23 AM, Andy Lutomirski <luto@amacapital.net> wrote:
> On Wed, Aug 3, 2016 at 10:17 AM, Matthew Garrett <mjg59@coreos.com> wrote:
>> Keys could be stored in a separate section and ignored for the
>> purposes of build comparison.
>
> But that defeats the purpose.  If I'm verifying a reproducible build,
> I don't want to have to take it on faith that the packager didn't keep
> a copy of the build-time key.

If you're trusting your upstream's signed bootloader you're already
forced to trust your packagers. If you want to establish your own root
of trust you could simply strip that section, replace it with your own
and re-sign the modules and kernel. Or just keep using signatures,
sign the public module signing key with the kernel signing key and
push the policy decision out to the bootloader.

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Ksummit-discuss] [TOPIC] Secure/verified boot and roots of trust
  2016-08-03 17:26         ` Matthew Garrett
@ 2016-08-03 17:28           ` Andy Lutomirski
  0 siblings, 0 replies; 29+ messages in thread
From: Andy Lutomirski @ 2016-08-03 17:28 UTC (permalink / raw)
  To: Matthew Garrett
  Cc: James Bottomley, Josh Boyer, Jason Cooper, ksummit-discuss, Mark Brown

On Wed, Aug 3, 2016 at 10:26 AM, Matthew Garrett <mjg59@coreos.com> wrote:
> On Wed, Aug 3, 2016 at 10:23 AM, Andy Lutomirski <luto@amacapital.net> wrote:
>> On Wed, Aug 3, 2016 at 10:17 AM, Matthew Garrett <mjg59@coreos.com> wrote:
>>> Keys could be stored in a separate section and ignored for the
>>> purposes of build comparison.
>>
>> But that defeats the purpose.  If I'm verifying a reproducible build,
>> I don't want to have to take it on faith that the packager didn't keep
>> a copy of the build-time key.
>
> If you're trusting your upstream's signed bootloader you're already
> forced to trust your packagers. If you want to establish your own root
> of trust you could simply strip that section, replace it with your own
> and re-sign the modules and kernel. Or just keep using signatures,
> sign the public module signing key with the kernel signing key and
> push the policy decision out to the bootloader.

But only sort of.  If the upstream bootloader signature serves only to
make Secure Boot accept it, then I don't really care if the owner of
that signing key is evil, because they can't do anything with that key
without physical access.

-- 
Andy Lutomirski
AMA Capital Management, LLC

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Ksummit-discuss] [TOPIC] Secure/verified boot and roots of trust
  2016-08-03 17:23     ` Matthew Garrett
@ 2016-08-03 17:29       ` Andy Lutomirski
  0 siblings, 0 replies; 29+ messages in thread
From: Andy Lutomirski @ 2016-08-03 17:29 UTC (permalink / raw)
  To: Matthew Garrett
  Cc: James Bottomley, Josh Boyer, Jason Cooper, ksummit-discuss, Mark Brown

On Wed, Aug 3, 2016 at 10:23 AM, Matthew Garrett <mjg59@coreos.com> wrote:
> On Wed, Aug 3, 2016 at 10:04 AM, Andy Lutomirski <luto@amacapital.net> wrote:
>> What's wrong with that?  In grub language, this would be approximately:
>>
>> linuxefi path/to/image
>> linuxkeypolicy path/to/policy
>
> Thinking about it further - there's no real problem integrating this
> with a build-time key. Rather than having the public half in the
> kernel, stash the public half in the packaging and then have the
> signing step (that's signing the kernel anyway) also sign the key. The
> bootloader verifies that the key is signed by a trusted root and
> passes that on to the kernel. If we have a standardised mechanism for
> the bootloader to pass this information on, it's absolutely possible
> to push the root of trust down to the bootloader (and also make it
> responsible for pulling any other signing keys out of EFI variables or
-- 
Andy Lutomirski
AMA Capital Management, LLC
> wherever)
>
>> Anyway, here's a concrete proposal for a cross-arch way to pass
>> trusted policy from the bootloader to the kernel: define a new
>> structure:
>>
>> struct trusted_policy_header {
>>   unsigned long size;
>> };
>>
>> Rig up the linker script so the trusted_policy is at the very end of
>> the kernel virtual address space and lives in its own ELF segment (or
>> arch equivalent).  That segment will have filesize == 0 and memsize ==
>> sizeof(struct trusted_policy_header).  Mark the segment so the
>> bootloader knows about it.
>>
>> Now the bootloader can supply policy (keys and whatever else it wants)
>> by simply writing it to the trusted_policy_header and beyond in
>> memory.
>
> The bootloader doesn't see the ELF object on (at least) x86?

:(

On the other hand, x86's bzImage appears to be an ELF object too, and
maybe it could learn to propagate the policy segment.  In other words,
bzImage would speak the same protocol, and the x86 stub that hands off
from bzImage to vmlinux could copy the data over.  This gets a bit
nasty if we want to do embedding because it's also a PE file and
probably a few other things, so there would be lots of headers to
update.

-- 
Andy Lutomirski
AMA Capital Management, LLC

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Ksummit-discuss] [TOPIC] Secure/verified boot and roots of trust
  2016-08-03 17:23       ` Andy Lutomirski
  2016-08-03 17:26         ` Matthew Garrett
@ 2016-08-03 18:00         ` Michael S. Tsirkin
  1 sibling, 0 replies; 29+ messages in thread
From: Michael S. Tsirkin @ 2016-08-03 18:00 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: Josh Boyer, Jason Cooper, ksummit-discuss, James Bottomley, Mark Brown

On Wed, Aug 03, 2016 at 10:23:00AM -0700, Andy Lutomirski wrote:
> >>> I don't see a compelling argument for why we'd want to do module hashing at
> >>> all, given that we have to have the signature checking mechanism around anyway
> >>> for various reasons.
> >>
> >> I think that, for the Secure Boot usecase, we actually wouldn't need
> >> the signature checking mechanism at all.  Firmware signature checking
> >> in-kernel is important for some chain-of-trust use cases but AFAIK not
> >> for Secure Boot for standard desktop distros.
> >
> > Without an IOMMU you can probably subvert any DMA capable device that
> > loads unsigned firmware, at which point you're in a bad place again.
> > This isn't something I'm losing much sleep over, since attacks that
> > only work if you have a specific piece of hardware installed are much
> > less exciting. We'd still need signature checking so that users can
> > install their own signing keys, and I don't see distributions being
> > terribly enthusiastic about having two unrelated module validation
> > systems.
> 
> That's a question for the distros.  My intent would be to make the
> module hashing scheme as painless as possible for the distros: distros
> would just enable a config option and, if needed, adjust their debug
> info generation slightly.

It's actually nice not having to rebuild the kernel each time though.
Can the hash-checking code itself be a module (LSM?), such that hash isn't
checked if it's not loaded? One could imagine loading that
e.g. from the initrd.

> _______________________________________________
> Ksummit-discuss mailing list
> Ksummit-discuss@lists.linuxfoundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/ksummit-discuss

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Ksummit-discuss] [TOPIC] Secure/verified boot and roots of trust
  2016-08-03 17:04   ` Andy Lutomirski
  2016-08-03 17:23     ` Matthew Garrett
@ 2016-08-03 22:09     ` James Bottomley
       [not found]       ` <CALCETrVpCnfOJ2aXkNsOXatQAF6NG-AcJpxeYfA9wG_t2ocykg@mail.gmail.com>
  1 sibling, 1 reply; 29+ messages in thread
From: James Bottomley @ 2016-08-03 22:09 UTC (permalink / raw)
  To: Andy Lutomirski; +Cc: Josh Boyer, Jason Cooper, ksummit-discuss, Mark Brown

On Wed, 2016-08-03 at 10:04 -0700, Andy Lutomirski wrote:
> On Wed, Aug 3, 2016 at 5:42 AM, James Bottomley
> <James.Bottomley@hansenpartnership.com> wrote:
> > On Tue, 2016-08-02 at 19:58 -0700, Andy Lutomirski wrote:
> > > I got module hashing working.  It ended up being fairly
> > > straightforward.  I still need to deal with debug info and
> > > disentangling it from CONFIG_MODULE_SIG, but that's just a bit of
> > > engineering.
> > > 
> > > While doing it, occurred to me that it might be worth considering
> > > a
> > > different way of thinking about roots of trust.
> > > 
> > > When a system does a verified boot using a static root of trust
> > > (which should cover most of the interesting cases), we have:
> > > 
> > >  - Bootloader verifies kernel
> > >  - Kernel verifies modules
> > >  - Kernel verifies firmware
> > >  - Kernel verifies filesystem (if using dm-verify or IMA)
> > >  - Kernel verifies initramfs (AFAIK no one has worked out the
> > > details)
> > 
> > Measured boot has, but we don't have this in secure boot yet.
> > 
> > >  - Kernel verifies device tree (seems messy to get right)
> > >  - Kernel should maybe verify the command line (?)
> > 
> > Yes, we really should.  Again, measured boot does this but we
> > currently
> > don't with secure boot.
> 
> It's not really clear to me that we need it for secure boot.  We get
> it for free with real verified boot a la Chromium -- the bootloader
> and its configuration is trusted.
> 
> > 
> > > The kernel does its verification with a combination of keys baked
> > > into the kernel image and keys supplied by Secure Boot firmware
> > > (if
> > > enabled, which I think is only the case out-of-tree).
> > > 
> > > By doing all this, we're accomplishing two goals:
> > > 
> > >  - Establishing a chain of trust rooted in or above the
> > > bootloader
> > >  - Appeasing the Secure Boot deities.  AFAIK this specifically
> > > requires that we verify the kernel and its modules using a
> > > combination of EFI-supplied and distro keys.
> > 
> > There's nothing really to appease here.  The initial fears were
> > grounded in how strictly Microsoft would blacklist something that
> > was a
> > threat to windows.  In practice there have been no blacklists of
> > linux
> > loaders (yet).
> > 
> > However, it is for us to try to root the system trust in something
> > and
> > we have two use cases:
> > 
> >    1. The shim use case where we pivot away from the default root
> > of trust
> >       (the Microsoft one) to a different Linux one stored in the
> > MokList
> >       variables
> >    2. an owned system where the user has replaced the PK and the
> > roots of
> >       trust are in the secure boot variables.
> > 
> > The question we really want to ask is how far should the initial
> > root
> > of trust (either 1 or 2 above) be used to verify the system before
> > giving way to alternate pivots?  Our initial pivot in 1 effectively
> > drops the MS root (although if you're doing 2 you keep the secure
> > boot
> > root).  I think it's reasonable to verify the kernel, initrd and
> > command line through the same root we used for the bootloader.  But
> > I'm
> > afraid I think the true answer is a policy question.  I can see
> > some
> > people who would want this trust baked into the system immutable
> > keyring and I can also see that some people would really not want
> > this
> > because they want to pivot the root of trust again.
> > 
> 
> What I'm arguing for is moving that pivot earlier and stopping
> worrying about baking roots of trust into the kernel image.  If we
> just decide that we're going to trust the bootloader (or some other
> pre-kernel code) in some well-defined way, then this dilemma goes
> away.  If you want to require signatures by a static key, bake that
> key into the *bootloader* instead of the kernel.  If you want to
> pivot, make the bootloader (or shim or whatever) do the pivoting.
> 
> Then the kernel can simply stop worrying about what is essentially a
> policy decision.  The kernel can receive a key from the bootloader
> and
> accept modules and such that are signed by that key.
> 
> I think the only hard parts are establishing the communication
> channel
> from the bootloader to the kernel (which various people probably want
> anyway) and defining what happens when the in-kernel EFI stub is
> used.
> 
> > > To hold all the pieces together, we've established a rather ad
> > > -hoc
> > > and complicated way of baking keys into the kernel (see the
> > > contents
> > > of the certs/ directory).
> > > 
> > > I think we've made our lives considerably more complicated than
> > > they
> > > need to be with the approach to keying that we're taking.
> > > 
> > > I'd like to discuss whether we can move a lot more of the keying
> > > into
> > > the bootloader.  I'm envisioning:
> > > 
> > >  - Bootloader supplies public keys and policy to the kernel.
> > >  - Bootloader verifies the initramfs if it needs to.
> > >  - Bootloader verifies the command line if it needs to.
> > >  - Bootloader verifies the device tree if it needs to.
> > 
> > Agreed.
> > 
> > >  - Kernel verifies modules using a combination of module hashes
> > > and
> > > keys from bootloader.
> > 
> > Hm, too strict: third party modules would then need a third party
> > key
> > in the bootloader.
> 
> What's wrong with that?  In grub language, this would be
> approximately:
> 
> linuxefi path/to/image
> linuxkeypolicy path/to/policy

Two problems:

   1. We have to talk to grub people.  They don't seem to agree over these
      type of extensions, which is why the uefi signature stuff is passed
      through as a separate patch in the distros.
   2. We now have to specify the policy somehow, so we're inventing a
      policy language.

> and the bootloader can presumably verify the policy file in the same
> way that it verifies the image itself.

So a signature is part of this?  OK.

> > 
> > >  - Kernel initializes IMO and/or dm-verity if needed according to
> > > policy supplied by bootloader.
> > >  - Bootloader extends a PCR with the keys and policy if needed.
> > 
> > The rest of this looks nice (particularly the PCR part, which 
> > allows us to seal TPM stuff to proof the boot sequence executed
> > properly).
> > 
> > The bit you're missing is how the policy is communicated (more on 
> > this below).
> > 
> > > This should cover the chain of trust case as well as the current
> > > approach without needing to worry about baking keys into the 
> > > kernel image -- after all, a compromised bootloader can already 
> > > change the kernel image or the baked-in keys and thus do whatever
> > > it wants.
> > > 
> > > We get to simplify EFI-based keying: the bootloader or an
> > > intermediate EFI application could pull whatever keys it likes 
> > > from EFI variables and feed them to the kernel.
> > > 
> > > The trickier part is appeasing the Secure Boot deities.  I'm not
> > > privy to the internal discussions here, but I think this could be
> > > done in a few ways.  For example, the bootloader could ensure 
> > > that the policy it sets is compliant.  Alternatively (since I 
> > > think that some implementations sign the kernel image itself with 
> > > a key chained to the MS roots), we could add a config option to 
> > > enforce, in the kernel, that modules must match an in-tree module 
> > > hash or be signed by a key that is built in or (optionally) 
> > > chains to an EFI-supplied key.
> > > 
> > > (NB: I think that the Secure Boot rules are silly, but that's 
> > > beside the point.  I would prefer that the kernel honor them in 
> > > the least silly way possible.)
> > 
> > I really don't think we need to worry about this bit: anything you 
> > come up with is most likely to go way beyond what Microsoft would 
> > need as its minimum base.
> > 
> > The current way secure boot policy is communicated from UEFI to the
> > bootloader is via the shimprotocol. It's a UEFI protocol which the
> > bootloader uses to verify the kernel (but not the command line or 
> > the initrd currently).  It's actually differently constructed 
> > depending on whether you're booting case 1 or 2.
> > 
> > I think we could extend the protocol to pass keys through to the 
> > kernel (the kernel currently doesn't even load the shimprotocol in 
> > early boot, but it could load a new shimkeyprotocol whose only job 
> > was to pass through acceptable keys).  The next problem is how to 
> > verify the command line and initrd.  The problem with the secure 
> > boot chain is that it's largely static and created away from the 
> > system (great for security but not so great for verifying 
> > dynamically created things like the initrd).  Our problem is that 
> > even if you only install distro rpms, the initrd is created 
> > dynamically on the running system by the rpm scripts, so it can't 
> > come with a-priori trust from the distros, nor can it be signed 
> > (unless the scripts have access to a private key, which is
> > a security risk).  One of the things I've been playing with is 
> > having a TPM controlled key sign this (meaning that the user 
> > installing the RPM has to type in a password to get the signature 
> > to happen), but it's also possible to imagine a less complex system 
> > where the hashes of acceptable command lines and initrds are stored 
> > in verified UEFI variables and shim (or the thing which installs 
> > the shim protocol) notifies the user there's been a change and asks
> > for approval.
> > 
> > I think this is a long winded way of saying that our problem isn't 
> > the verification mechanisms itself, it's all in the policy. 
> > 
> > The only real way around this initrd policy problem I can think is
> > either have the default what we do (or rather don't do) today: no
> > verification or have the distros deliver generic initrds which can 
> > be signed (but which would be rather large).  Even if we do the
> > latter, the command line has to have the disk uuid, so it's still 
> > going to be dynamic (and thus unsigned).
> > 
> 
> I'm not personally too worried about verifying initramfs -- initramfs
> is functionally equivalent to the root filesystem, and they ought to
> be verifiable the same way.

Yes, but if you worry about protecting yourself from hackers, IMA can
verify no-one tampers with your rootfs; what verifies that no-one
tampers with your initrd (which is a very powerful instrument to
subvert a linux boot)?

>   For an average desktop distro that *doesn't* verify the rootfs, 
> what's the point of trying to verify initramfs?

If we're talking about standard distros, then do nothing about security
is probably OK.  However, for people who do use IMA to verify their
root fs, we really do need some way of verifying the initramfs.

Matthew already answered the rest, so I'm going to catch my flight.

James

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Ksummit-discuss] [TOPIC] Secure/verified boot and roots of trust
       [not found]         ` <CALCETrWgS0XObzxfQWQbyntVEn6QF81K2TVbS4bGNyN6EcYb_A@mail.gmail.com>
@ 2016-08-03 22:39           ` Andy Lutomirski
  0 siblings, 0 replies; 29+ messages in thread
From: Andy Lutomirski @ 2016-08-03 22:39 UTC (permalink / raw)
  To: James Bottomley; +Cc: Josh Boyer, Mark Brown, ksummit-discuss, Jason Cooper

[-- Attachment #1: Type: text/plain, Size: 632 bytes --]

On Aug 3, 2016 3:09 PM, "James Bottomley" <
James.Bottomley@hansenpartnership.com> wrote:

> >
> > I'm not personally too worried about verifying initramfs -- initramfs
> > is functionally equivalent to the root filesystem, and they ought to
> > be verifiable the same way.
>
> Yes, but if you worry about protecting yourself from hackers, IMA can
> verify no-one tampers with your rootfs; what verifies that no-one
> tampers with your initrd (which is a very powerful instrument to
> subvert a linux boot)?

IMA?  Awhile ago I suggested adding tar parsing with xattrs to initramfs,
and I'm not sure what went wrong with that idea.

[-- Attachment #2: Type: text/html, Size: 871 bytes --]

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Ksummit-discuss] [TOPIC] Secure/verified boot and roots of trust
  2016-08-03 16:46   ` Andy Lutomirski
  2016-08-03 17:17     ` Matthew Garrett
@ 2016-08-03 23:01     ` Ben Hutchings
  2016-08-03 23:22       ` Andy Lutomirski
  2016-08-17 11:38       ` Ben Hutchings
  1 sibling, 2 replies; 29+ messages in thread
From: Ben Hutchings @ 2016-08-03 23:01 UTC (permalink / raw)
  To: Andy Lutomirski, David Howells
  Cc: Josh Boyer, Jason Cooper, ksummit-discuss, James Bottomley, Mark Brown

[-- Attachment #1: Type: text/plain, Size: 990 bytes --]

On Wed, 2016-08-03 at 09:46 -0700, Andy Lutomirski wrote:
[...]
> And it gets rid of the IMO extremely nasty temporary key.  I
> personally think that reproducible builds would add considerable value
> to many use cases, and we currently can't simultaneously support
> reproducible builds and Secure Boot without a big mess involving
> trusted parties, and the whole point of reproducible builds is to
> avoid needed to trust the packager.
[...]

You need that trusted party to supply a signature for the kernel, so
why is it so much worse to have them do that for the modules as well?

As you may be aware, I'm dealing with this in Debian by putting
detached signatures into the source package that builds signed
binaries.  The two package build processes are each reproducible (aside
from a recently discovered dependence on whether /bin/sh is bash or
dash).

Ben.

-- 

Ben Hutchings
Nothing is ever a complete failure; it can always serve as a bad
example.

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Ksummit-discuss] [TOPIC] Secure/verified boot and roots of trust
  2016-08-03 23:01     ` Ben Hutchings
@ 2016-08-03 23:22       ` Andy Lutomirski
  2016-08-04  5:26         ` Kees Cook
  2016-08-17 11:38       ` Ben Hutchings
  1 sibling, 1 reply; 29+ messages in thread
From: Andy Lutomirski @ 2016-08-03 23:22 UTC (permalink / raw)
  To: Ben Hutchings
  Cc: James Bottomley, Josh Boyer, Jason Cooper, ksummit-discuss, Mark Brown

On Wed, Aug 3, 2016 at 4:01 PM, Ben Hutchings <ben@decadent.org.uk> wrote:
> On Wed, 2016-08-03 at 09:46 -0700, Andy Lutomirski wrote:
> [...]
>> And it gets rid of the IMO extremely nasty temporary key.  I
>> personally think that reproducible builds would add considerable value
>> to many use cases, and we currently can't simultaneously support
>> reproducible builds and Secure Boot without a big mess involving
>> trusted parties, and the whole point of reproducible builds is to
>> avoid needed to trust the packager.
> [...]
>
> You need that trusted party to supply a signature for the kernel, so
> why is it so much worse to have them do that for the modules as well?
>

For Chromium-like setups, I don't think the kernel is signed as such
-- it's verified (by hash?  by loading from trusted storage?) and
executed.

> As you may be aware, I'm dealing with this in Debian by putting
> detached signatures into the source package that builds signed
> binaries.  The two package build processes are each reproducible (aside
> from a recently discovered dependence on whether /bin/sh is bash or
> dash).

That is a nifty solution, although don't you have to put a detached
signature into the source package for every single module?  Limiting
it to just one signature for the kernel seems like it would be a win.

--Andy

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Ksummit-discuss] [TOPIC] Secure/verified boot and roots of trust
  2016-08-03 23:22       ` Andy Lutomirski
@ 2016-08-04  5:26         ` Kees Cook
  0 siblings, 0 replies; 29+ messages in thread
From: Kees Cook @ 2016-08-04  5:26 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: James Bottomley, Josh Boyer, Jason Cooper, ksummit-discuss, Mark Brown

On Wed, Aug 3, 2016 at 4:22 PM, Andy Lutomirski <luto@amacapital.net> wrote:
> On Wed, Aug 3, 2016 at 4:01 PM, Ben Hutchings <ben@decadent.org.uk> wrote:
>> On Wed, 2016-08-03 at 09:46 -0700, Andy Lutomirski wrote:
>> [...]
>>> And it gets rid of the IMO extremely nasty temporary key.  I
>>> personally think that reproducible builds would add considerable value
>>> to many use cases, and we currently can't simultaneously support
>>> reproducible builds and Secure Boot without a big mess involving
>>> trusted parties, and the whole point of reproducible builds is to
>>> avoid needed to trust the packager.
>> [...]
>>
>> You need that trusted party to supply a signature for the kernel, so
>> why is it so much worse to have them do that for the modules as well?
>>
>
> For Chromium-like setups, I don't think the kernel is signed as such
> -- it's verified (by hash?  by loading from trusted storage?) and
> executed.

The kernel (and command line) are in a single partition with a signed
hash which the bootloader verifies before running the kernel.

-Kees

-- 
Kees Cook
Brillo & Chrome OS Security

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Ksummit-discuss] [TOPIC] Secure/verified boot and roots of trust
  2016-08-03 23:01     ` Ben Hutchings
  2016-08-03 23:22       ` Andy Lutomirski
@ 2016-08-17 11:38       ` Ben Hutchings
  2016-08-17 13:03         ` Mimi Zohar
  1 sibling, 1 reply; 29+ messages in thread
From: Ben Hutchings @ 2016-08-17 11:38 UTC (permalink / raw)
  To: Andy Lutomirski, David Howells
  Cc: James Bottomley, Josh Boyer, Jason Cooper, ksummit-discuss, Mark Brown

[-- Attachment #1: Type: text/plain, Size: 1546 bytes --]

On Thu, 2016-08-04 at 00:01 +0100, Ben Hutchings wrote:
> On Wed, 2016-08-03 at 09:46 -0700, Andy Lutomirski wrote:
> [...]
> > 
> > And it gets rid of the IMO extremely nasty temporary key.  I
> > personally think that reproducible builds would add considerable
> > value
> > to many use cases, and we currently can't simultaneously support
> > reproducible builds and Secure Boot without a big mess involving
> > trusted parties, and the whole point of reproducible builds is to
> > avoid needed to trust the packager.
> [...]
> 
> You need that trusted party to supply a signature for the kernel, so
> why is it so much worse to have them do that for the modules as well?
[...]

I think I can now answer this myself.

Where there's a separate certificate store, the signing stage can be
entirely independent of the initial build.  A user of a distribution
can reproduce the distribution's unsigned binaries and then use their
own keys to build signed binaries for their own use.

However, the module signing certificate embedded in the kernel - even
if it refers to a persistent signing key, making it reproducible - has
to be established before the initial build, so it doesn't allow for
users to use a different root of trust.  So there ought to be an option
to require signatures but without defining any trusted keys at build
time.

Ben.

-- 
Ben Hutchings
Kids!  Bringing about Armageddon can be dangerous.  Do not attempt it
in
your own home. - Terry Pratchett and Neil Gaiman, `Good Omens'

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Ksummit-discuss] [TOPIC] Secure/verified boot and roots of trust
  2016-08-17 11:38       ` Ben Hutchings
@ 2016-08-17 13:03         ` Mimi Zohar
  2016-08-17 16:11           ` Ben Hutchings
  0 siblings, 1 reply; 29+ messages in thread
From: Mimi Zohar @ 2016-08-17 13:03 UTC (permalink / raw)
  To: Ben Hutchings
  Cc: James Bottomley, Josh Boyer, Jason Cooper, ksummit-discuss, Mark Brown

On Wed, 2016-08-17 at 12:38 +0100, Ben Hutchings wrote:
> On Thu, 2016-08-04 at 00:01 +0100, Ben Hutchings wrote:
> > On Wed, 2016-08-03 at 09:46 -0700, Andy Lutomirski wrote:
> > [...]
> > > 
> > > And it gets rid of the IMO extremely nasty temporary key.  I
> > > personally think that reproducible builds would add considerable
> > > value
> > > to many use cases, and we currently can't simultaneously support
> > > reproducible builds and Secure Boot without a big mess involving
> > > trusted parties, and the whole point of reproducible builds is to
> > > avoid needed to trust the packager.
> > [...]
> > 
> > You need that trusted party to supply a signature for the kernel, so
> > why is it so much worse to have them do that for the modules as well?
> [...]
> 
> I think I can now answer this myself.
> 
> Where there's a separate certificate store, the signing stage can be
> entirely independent of the initial build.  A user of a distribution
> can reproduce the distribution's unsigned binaries and then use their
> own keys to build signed binaries for their own use.
> 
> However, the module signing certificate embedded in the kernel - even
> if it refers to a persistent signing key, making it reproducible - has
> to be established before the initial build, so it doesn't allow for
> users to use a different root of trust.  So there ought to be an option
> to require signatures but without defining any trusted keys at build
> time.

With Mehmet Kayaalp's patches memory can be reserved for adding keys
post build.  After adding the key, the kernel would need to be
(re-)signed.

c4c3610 "KEYS: Reserve an extra certificate symbol for inserting without
recompiling"
8e16789 "KEYS: Use the symbol value for list size, updated by
scripts/insert-sys-cert"

Mimi

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Ksummit-discuss] [TOPIC] Secure/verified boot and roots of trust
  2016-08-17 13:03         ` Mimi Zohar
@ 2016-08-17 16:11           ` Ben Hutchings
  2016-08-18 12:28             ` Mimi Zohar
  0 siblings, 1 reply; 29+ messages in thread
From: Ben Hutchings @ 2016-08-17 16:11 UTC (permalink / raw)
  To: Mimi Zohar
  Cc: James Bottomley, Josh Boyer, Jason Cooper, ksummit-discuss, Mark Brown

[-- Attachment #1: Type: text/plain, Size: 2225 bytes --]

On Wed, 2016-08-17 at 09:03 -0400, Mimi Zohar wrote:
> On Wed, 2016-08-17 at 12:38 +0100, Ben Hutchings wrote:
> > 
> > On Thu, 2016-08-04 at 00:01 +0100, Ben Hutchings wrote:
> > > 
> > > On Wed, 2016-08-03 at 09:46 -0700, Andy Lutomirski wrote:
> > > [...]
> > > > 
> > > > 
> > > > And it gets rid of the IMO extremely nasty temporary key.  I
> > > > personally think that reproducible builds would add considerable
> > > > value
> > > > to many use cases, and we currently can't simultaneously support
> > > > reproducible builds and Secure Boot without a big mess involving
> > > > trusted parties, and the whole point of reproducible builds is to
> > > > avoid needed to trust the packager.
> > > [...]
> > > 
> > > You need that trusted party to supply a signature for the kernel, so
> > > why is it so much worse to have them do that for the modules as well?
> > [...]
> > 
> > I think I can now answer this myself.
> > 
> > Where there's a separate certificate store, the signing stage can be
> > entirely independent of the initial build.  A user of a distribution
> > can reproduce the distribution's unsigned binaries and then use their
> > own keys to build signed binaries for their own use.
> > 
> > However, the module signing certificate embedded in the kernel - even
> > if it refers to a persistent signing key, making it reproducible - has
> > to be established before the initial build, so it doesn't allow for
> > users to use a different root of trust.  So there ought to be an option
> > to require signatures but without defining any trusted keys at build
> > time.
> 
> With Mehmet Kayaalp's patches memory can be reserved for adding keys
> post build.  After adding the key, the kernel would need to be
> (re-)signed.

I know, but it doesn't replace the first certificate.

Ben.

> > c4c3610 "KEYS: Reserve an extra certificate symbol for inserting without
> recompiling"
> 8e16789 "KEYS: Use the symbol value for list size, updated by
> scripts/insert-sys-cert"
> 
> Mimi
> 
-- 
Ben Hutchings
Kids!  Bringing about Armageddon can be dangerous.  Do not attempt it
in
your own home. - Terry Pratchett and Neil Gaiman, `Good Omens'

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Ksummit-discuss] [TOPIC] Secure/verified boot and roots of trust
  2016-08-17 16:11           ` Ben Hutchings
@ 2016-08-18 12:28             ` Mimi Zohar
  0 siblings, 0 replies; 29+ messages in thread
From: Mimi Zohar @ 2016-08-18 12:28 UTC (permalink / raw)
  To: Ben Hutchings
  Cc: James Bottomley, Josh Boyer, Jason Cooper, ksummit-discuss, Mark Brown

On Wed, 2016-08-17 at 17:11 +0100, Ben Hutchings wrote:
> On Wed, 2016-08-17 at 09:03 -0400, Mimi Zohar wrote:
> > On Wed, 2016-08-17 at 12:38 +0100, Ben Hutchings wrote:
> > > 
> > > On Thu, 2016-08-04 at 00:01 +0100, Ben Hutchings wrote:
> > > > 
> > > > On Wed, 2016-08-03 at 09:46 -0700, Andy Lutomirski wrote:
> > > > [...]
> > > > > 
> > > > > 
> > > > > And it gets rid of the IMO extremely nasty temporary key.  I
> > > > > personally think that reproducible builds would add considerable
> > > > > value
> > > > > to many use cases, and we currently can't simultaneously support
> > > > > reproducible builds and Secure Boot without a big mess involving
> > > > > trusted parties, and the whole point of reproducible builds is to
> > > > > avoid needed to trust the packager.
> > > > [...]
> > > > 
> > > > You need that trusted party to supply a signature for the kernel, so
> > > > why is it so much worse to have them do that for the modules as well?
> > > [...]
> > > 
> > > I think I can now answer this myself.
> > > 
> > > Where there's a separate certificate store, the signing stage can be
> > > entirely independent of the initial build.  A user of a distribution
> > > can reproduce the distribution's unsigned binaries and then use their
> > > own keys to build signed binaries for their own use.
> > > 
> > > However, the module signing certificate embedded in the kernel - even
> > > if it refers to a persistent signing key, making it reproducible - has
> > > to be established before the initial build, so it doesn't allow for
> > > users to use a different root of trust.  So there ought to be an option
> > > to require signatures but without defining any trusted keys at build
> > > time.
> > 
> > With Mehmet Kayaalp's patches memory can be reserved for adding keys
> > post build.  After adding the key, the kernel would need to be
> > (re-)signed.
> 
> I know, but it doesn't replace the first certificate.

A kernel is being built for a product development group without any
builtin keys, but with reserved memory.   They've enabled
CONFIG_MODULE_SIG, but disabled CONFIG_MODULE_SIG_ALL.

Both inserting the key into the kernel and signing the kernel modules
are done post build.

For reproducible builds, instead of filling the reserved memory with
random numbers, so that it isn't compressed out, we would need to modify
the build process to use predefined uncompressible junk.

Mimi

^ permalink raw reply	[flat|nested] 29+ messages in thread

end of thread, other threads:[~2016-08-18 12:28 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-08-03  2:58 [Ksummit-discuss] [TOPIC] Secure/verified boot and roots of trust Andy Lutomirski
2016-08-03  3:24 ` Kees Cook
2016-08-03  3:32 ` Matthew Garrett
2016-08-03  4:34   ` Andy Lutomirski
2016-08-03  4:42     ` Michael S. Tsirkin
2016-08-03  4:46       ` Andy Lutomirski
2016-08-03  5:15     ` Matthew Garrett
2016-08-03  8:33 ` Alexandre Belloni
2016-08-03 10:31 ` Mark Brown
2016-08-03 10:43 ` David Howells
2016-08-03 16:46   ` Andy Lutomirski
2016-08-03 17:17     ` Matthew Garrett
2016-08-03 17:23       ` Andy Lutomirski
2016-08-03 17:26         ` Matthew Garrett
2016-08-03 17:28           ` Andy Lutomirski
2016-08-03 18:00         ` Michael S. Tsirkin
2016-08-03 23:01     ` Ben Hutchings
2016-08-03 23:22       ` Andy Lutomirski
2016-08-04  5:26         ` Kees Cook
2016-08-17 11:38       ` Ben Hutchings
2016-08-17 13:03         ` Mimi Zohar
2016-08-17 16:11           ` Ben Hutchings
2016-08-18 12:28             ` Mimi Zohar
2016-08-03 12:42 ` James Bottomley
2016-08-03 17:04   ` Andy Lutomirski
2016-08-03 17:23     ` Matthew Garrett
2016-08-03 17:29       ` Andy Lutomirski
2016-08-03 22:09     ` James Bottomley
     [not found]       ` <CALCETrVpCnfOJ2aXkNsOXatQAF6NG-AcJpxeYfA9wG_t2ocykg@mail.gmail.com>
     [not found]         ` <CALCETrWgS0XObzxfQWQbyntVEn6QF81K2TVbS4bGNyN6EcYb_A@mail.gmail.com>
2016-08-03 22:39           ` Andy Lutomirski

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.