All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] Add support for signing grub with an appended signature
@ 2020-10-16 11:20 Michal Suchánek
       [not found] ` <871rhuwi80.fsf@dja-thinkpad.axtens.net>
  0 siblings, 1 reply; 8+ messages in thread
From: Michal Suchánek @ 2020-10-16 11:20 UTC (permalink / raw)
  To: dja, grub-devel

Hello,

It has been pointed out in the plumbers session that the ELF note will
cause problems when user wants to add additional signature.

The normal appended signature has only one size information - in the
footer at the end of the binary, and that is not part of the signed
data. So if you want to add additional signature it if possible to
expand the room for the signature data.

In contrast the ELF note size is present in the ELF header which is
also signed. This does not allow adjusting the size of the signature
data once the binary is signed.

A simpler scheme would be for grub-install to parse the signature
footer, split-off the signature, write the ELF binary at the start of
the PReP partition, and the signature at the end. Then the grub
signature can use exactly same format as the kernel and modules.

The disadvantage is that for signed grub dd is no longer an alternative
to grub-install.

There was also concern about distinguishing signed and un-signed grub.
That is that writing an un-signed grub might lease a stale signature
leading to an error.

However, secure boot is something that should be enabled or disabled in
firmware settings, and not triggered by the PPeP partition containing a
signature. 

When secure boot is enabled checking the grub signature is required and
un-signed grub is invalid. When secure boot is disabled the signature
is irrelevant and stale signature should not cause any error.

grub-install can also remove the signature magic when installing
un-signed grub for consistency. Users using dd to install un-signed
grub might still have an old signature at the end of the partition.

Thanks

Michal


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

* Re: [PATCH 0/3] Add support for signing grub with an appended signature
       [not found] ` <871rhuwi80.fsf@dja-thinkpad.axtens.net>
@ 2020-10-19 23:18   ` Daniel Axtens
  2020-10-22  4:25   ` Daniel Axtens
  1 sibling, 0 replies; 8+ messages in thread
From: Daniel Axtens @ 2020-10-19 23:18 UTC (permalink / raw)
  To: grub-devel

[This bounced from the list for some reason, so I'm trying again.]

Hi Michal,

That's a really interesting proposal - thank you. I'm still thinking
about it and experimenting with it in SLOF.

Some thoughts:

> It has been pointed out in the plumbers session that the ELF note will
> cause problems when user wants to add additional signature.
>
> The normal appended signature has only one size information - in the
> footer at the end of the binary, and that is not part of the signed
> data. So if you want to add additional signature it if possible to
> expand the room for the signature data.

The appended signature metadata doesn't contain information about the
size of the signed data. It contains the size of the PKCS#7/CMS
signature block - because that can change in size based on the hash
function and the identity of the signing certificate.

Normally this doesn't matter: you can get a size of the whole file from
the filesystem and then because you know the size of the appended
signature data, you can work out the size of the signed data.

> In contrast the ELF note size is present in the ELF header which is
> also signed. This does not allow adjusting the size of the signature
> data once the binary is signed.

Correct. We could potentially allocate lots of space, but you are
correct that the size of the ELF note is fixed by the signature.

> A simpler scheme would be for grub-install to parse the signature
> footer, split-off the signature, write the ELF binary at the start of
> the PReP partition, and the signature at the end. Then the grub
> signature can use exactly same format as the kernel and modules.

I got part way through implementing this today in SLOF and realised that
it's not immediately clear what the size of the signed data is for
verifying the appended signature - that is, how much of the PReP
partition should I be hashing? As I said, the appended signature
metadata doesn't encode this particular size value.

One thing that we might be able to do is to base the size of the
verified data on a size calculated from the ELF header: basically figure
out the maximum file offset + size for all the program headers, capped
at (partition size - appended signature size), and hash that many
bytes. If I understand correctly, and assuming grub-mkimage constructs
valid ELF files, this should be correct.

I'll give this a go in SLOF tomorrow, and I'll also need to confer with
the team that develops the proprietary firmware used by PowerVM.

> The disadvantage is that for signed grub dd is no longer an alternative
> to grub-install.
>
> There was also concern about distinguishing signed and un-signed grub.
> That is that writing an un-signed grub might lease a stale signature
> leading to an error.
>
> However, secure boot is something that should be enabled or disabled in
> firmware settings, and not triggered by the PPeP partition containing a
> signature. 
>
> When secure boot is enabled checking the grub signature is required and
> un-signed grub is invalid. When secure boot is disabled the signature
> is irrelevant and stale signature should not cause any error.

What I'm concerned about here - and it's possible I explained it poorly
at Plumbers - is how a systems administrator would distinguish between
having accidentally installed an unsigned grub, and having installed a
grub with a broken or untrusted signature.

Having said that, ...

> grub-install can also remove the signature magic when installing
> un-signed grub for consistency. Users using dd to install un-signed
> grub might still have an old signature at the end of the partition.

if we make grub-install do the right thing, I think that sufficiently
mitigates my concern.

Thanks again, and I'll let you know how I get on shortly.

Kind regards,
Daniel



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

* Re: [PATCH 0/3] Add support for signing grub with an appended signature
       [not found] ` <871rhuwi80.fsf@dja-thinkpad.axtens.net>
  2020-10-19 23:18   ` Daniel Axtens
@ 2020-10-22  4:25   ` Daniel Axtens
  2020-10-22 11:14     ` Michal Suchánek
  1 sibling, 1 reply; 8+ messages in thread
From: Daniel Axtens @ 2020-10-22  4:25 UTC (permalink / raw)
  To: Michal Suchánek, grub-devel

Hi Michal,

>> A simpler scheme would be for grub-install to parse the signature
>> footer, split-off the signature, write the ELF binary at the start of
>> the PReP partition, and the signature at the end. Then the grub
>> signature can use exactly same format as the kernel and modules.
>
> I got part way through implementing this today in SLOF and realised that
> it's not immediately clear what the size of the signed data is for
> verifying the appended signature - that is, how much of the PReP
> partition should I be hashing? As I said, the appended signature
> metadata doesn't encode this particular size value.
>
> One thing that we might be able to do is to base the size of the
> verified data on a size calculated from the ELF header: basically figure
> out the maximum file offset + size for all the program headers, capped
> at (partition size - appended signature size), and hash that many
> bytes. If I understand correctly, and assuming grub-mkimage constructs
> valid ELF files, this should be correct.
>
> I'll give this a go in SLOF tomorrow, and I'll also need to confer with
> the team that develops the proprietary firmware used by PowerVM.
>

I talked to the firmware team this morning.

So grub is usually loaded from the PReP partition if you are booting
from disk. But, if you are booting from a CD/USB/etc, we first parse
/ppc/boot-info.txt and then load whatever file it identifies. If you're
netbooting we load the file we get from the network.

One strength of the ELF-note based scheme is that verification of the
appended signature is exactly the same in all these scenarios, and in
each case it can live entirely in the ELF parsing and loading code.

In contrast, if we don't have an elf note, we have to handle PReP
partitions, CHRP boot-info.txt and netboot separately. At least in the
PReP case we also have to do parse enough of the ELF header to determine
how much data we need to be hashing for signature verification, and this
crosses a couple of previously separate steps of the process.

To illustrate from SLOF, currently the ELF note stuff lives almost
entirely in elf32.c, but for the scheme you describe we need to patch
load-from-dos-boot-partition, load-from-gpt-prep-partition, whatever
code we use for where we boot a file directly from disk for CHRP
boot-info.txt loading, and something somewhere in the netboot code.

We can still support multiple signers disjoint in time with the scheme I
suggest at
https://lists.gnu.org/archive/html/grub-devel/2020-09/msg00081.html
although I do agree it's ugly in its own separate way.

Kind regards,
Daniel

>> The disadvantage is that for signed grub dd is no longer an alternative
>> to grub-install.
>>
>> There was also concern about distinguishing signed and un-signed grub.
>> That is that writing an un-signed grub might lease a stale signature
>> leading to an error.
>>
>> However, secure boot is something that should be enabled or disabled in
>> firmware settings, and not triggered by the PPeP partition containing a
>> signature. 
>>
>> When secure boot is enabled checking the grub signature is required and
>> un-signed grub is invalid. When secure boot is disabled the signature
>> is irrelevant and stale signature should not cause any error.
>
> What I'm concerned about here - and it's possible I explained it poorly
> at Plumbers - is how a systems administrator would distinguish between
> having accidentally installed an unsigned grub, and having installed a
> grub with a broken or untrusted signature.
>
> Having said that, ...
>
>> grub-install can also remove the signature magic when installing
>> un-signed grub for consistency. Users using dd to install un-signed
>> grub might still have an old signature at the end of the partition.
>
> if we make grub-install do the right thing, I think that sufficiently
> mitigates my concern.
>
> Thanks again, and I'll let you know how I get on shortly.
>
> Kind regards,
> Daniel


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

* Re: [PATCH 0/3] Add support for signing grub with an appended signature
  2020-10-22  4:25   ` Daniel Axtens
@ 2020-10-22 11:14     ` Michal Suchánek
  2020-10-23  5:33       ` Daniel Axtens
  0 siblings, 1 reply; 8+ messages in thread
From: Michal Suchánek @ 2020-10-22 11:14 UTC (permalink / raw)
  To: Daniel Axtens; +Cc: grub-devel

Hello,

thanks for looking into this

On Thu, Oct 22, 2020 at 03:25:33PM +1100, Daniel Axtens wrote:
> Hi Michal,
> 
> >> A simpler scheme would be for grub-install to parse the signature
> >> footer, split-off the signature, write the ELF binary at the start of
> >> the PReP partition, and the signature at the end. Then the grub
> >> signature can use exactly same format as the kernel and modules.
> >
> > I got part way through implementing this today in SLOF and realised that
> > it's not immediately clear what the size of the signed data is for
> > verifying the appended signature - that is, how much of the PReP
> > partition should I be hashing? As I said, the appended signature
> > metadata doesn't encode this particular size value.
> >
> > One thing that we might be able to do is to base the size of the
> > verified data on a size calculated from the ELF header: basically figure
> > out the maximum file offset + size for all the program headers, capped
> > at (partition size - appended signature size), and hash that many
> > bytes. If I understand correctly, and assuming grub-mkimage constructs
> > valid ELF files, this should be correct.
> >
> > I'll give this a go in SLOF tomorrow, and I'll also need to confer with
> > the team that develops the proprietary firmware used by PowerVM.
> >
> 
> I talked to the firmware team this morning.
> 
> So grub is usually loaded from the PReP partition if you are booting
> from disk. But, if you are booting from a CD/USB/etc, we first parse
> /ppc/boot-info.txt and then load whatever file it identifies. If you're
> netbooting we load the file we get from the network.
> 
> One strength of the ELF-note based scheme is that verification of the
> appended signature is exactly the same in all these scenarios, and in
> each case it can live entirely in the ELF parsing and loading code.
> 
> In contrast, if we don't have an elf note, we have to handle PReP
> partitions, CHRP boot-info.txt and netboot separately. At least in the
> PReP case we also have to do parse enough of the ELF header to determine
> how much data we need to be hashing for signature verification, and this
> crosses a couple of previously separate steps of the process.
> 
> To illustrate from SLOF, currently the ELF note stuff lives almost
> entirely in elf32.c, but for the scheme you describe we need to patch
> load-from-dos-boot-partition, load-from-gpt-prep-partition, whatever
> code we use for where we boot a file directly from disk for CHRP
> boot-info.txt loading, and something somewhere in the netboot code.

Why do you have to handle different boot media separately, though?

There is this bug, supposedly in 'old firmware' that when the PReP
partition is large (gigabytes in size) the firmware crashes trying to
load the whole thing to memory and hand it over to the elf parser. If
this is fixed today you need to parse the header anyway to know how much
to load, or you need to just hand over some handle to the partition and
let the elf parser do the reading.

The appended signature format is exactly the same in each case: there is
a container such as a partition, a file, or a block of memory that has
an elf binary at the start, optional padding, and optinal signature at
the end. There is nothing stopping the elf parser from parsing both
the elf header and the signature footer when it gets the data.

In the case of the partition containing the elf binary it is expected
that the padding is non-zero, in the other cases having padding is
suspicious.

In the case of a partition you have to read the data in some
device-specific sectors while files can be read at arbitrary sized
chunks.

If you choose to write separate code to fetch the elf binary from
different media due to these differences then these separate code paths
must be adjusted. However, that is inherent to lack of suitable
abstraction in the code, and not the appended signature format.

I think it is more productive to clean up the code to handle all media
the same way rather than inventing new unique quirky and deficient
signature format.

Thanks

Michal

> 
> We can still support multiple signers disjoint in time with the scheme I
> suggest at
> https://lists.gnu.org/archive/html/grub-devel/2020-09/msg00081.html
> although I do agree it's ugly in its own separate way.
> 
> Kind regards,
> Daniel
> 
> >> The disadvantage is that for signed grub dd is no longer an alternative
> >> to grub-install.
> >>
> >> There was also concern about distinguishing signed and un-signed grub.
> >> That is that writing an un-signed grub might lease a stale signature
> >> leading to an error.
> >>
> >> However, secure boot is something that should be enabled or disabled in
> >> firmware settings, and not triggered by the PPeP partition containing a
> >> signature. 
> >>
> >> When secure boot is enabled checking the grub signature is required and
> >> un-signed grub is invalid. When secure boot is disabled the signature
> >> is irrelevant and stale signature should not cause any error.
> >
> > What I'm concerned about here - and it's possible I explained it poorly
> > at Plumbers - is how a systems administrator would distinguish between
> > having accidentally installed an unsigned grub, and having installed a
> > grub with a broken or untrusted signature.
> >
> > Having said that, ...
> >
> >> grub-install can also remove the signature magic when installing
> >> un-signed grub for consistency. Users using dd to install un-signed
> >> grub might still have an old signature at the end of the partition.
> >
> > if we make grub-install do the right thing, I think that sufficiently
> > mitigates my concern.
> >
> > Thanks again, and I'll let you know how I get on shortly.
> >
> > Kind regards,
> > Daniel


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

* Re: [PATCH 0/3] Add support for signing grub with an appended signature
  2020-10-22 11:14     ` Michal Suchánek
@ 2020-10-23  5:33       ` Daniel Axtens
  2020-11-04 18:04         ` Michal Suchánek
  0 siblings, 1 reply; 8+ messages in thread
From: Daniel Axtens @ 2020-10-23  5:33 UTC (permalink / raw)
  To: Michal Suchánek; +Cc: grub-devel

Hi Michal,

>> So grub is usually loaded from the PReP partition if you are booting
>> from disk. But, if you are booting from a CD/USB/etc, we first parse
>> /ppc/boot-info.txt and then load whatever file it identifies. If you're
>> netbooting we load the file we get from the network.
>> 
>> One strength of the ELF-note based scheme is that verification of the
>> appended signature is exactly the same in all these scenarios, and in
>> each case it can live entirely in the ELF parsing and loading code.
>> 
>> In contrast, if we don't have an elf note, we have to handle PReP
>> partitions, CHRP boot-info.txt and netboot separately. At least in the
>> PReP case we also have to do parse enough of the ELF header to determine
>> how much data we need to be hashing for signature verification, and this
>> crosses a couple of previously separate steps of the process.
>> 
>> To illustrate from SLOF, currently the ELF note stuff lives almost
>> entirely in elf32.c, but for the scheme you describe we need to patch
>> load-from-dos-boot-partition, load-from-gpt-prep-partition, whatever
>> code we use for where we boot a file directly from disk for CHRP
>> boot-info.txt loading, and something somewhere in the netboot code.
>
> Why do you have to handle different boot media separately, though?
>
> There is this bug, supposedly in 'old firmware' that when the PReP
> partition is large (gigabytes in size) the firmware crashes trying to
> load the whole thing to memory and hand it over to the elf parser. If
> this is fixed today you need to parse the header anyway to know how much
> to load, or you need to just hand over some handle to the partition and
> let the elf parser do the reading.

Hmm, I will pass this on to the enterprise/proprietary Partiton Firmware
(PFW) team to confirm that it's been fixed.

It won't affect (at least modern versions of) SLOF, as SLOF caps the
amount of PReP partition that it reads at 32MB. It reads min(partition
size, 32MB) and passes that to the ELF loader. (I suppose that will
break if a bootloader ever grows to be > 32MB, but most distros only
allocate something like 8MB to PReP today, so you'd hit partition size
limits first anyway.)

> The appended signature format is exactly the same in each case: there is
> a container such as a partition, a file, or a block of memory that has
> an elf binary at the start, optional padding, and optinal signature at
> the end. There is nothing stopping the elf parser from parsing both
> the elf header and the signature footer when it gets the data.

Reflecting on it, the proposed new design is also pretty quirky.

The existing appended signature format is:

 data || pkcs7 || metadata || magic

If you strip off the signature, only the data remains, which you can
immediately calculate the hash on and verify the signature. The ELF note
format perserves this property.

Moving the signature to the end of the PReP partition gives you:

  data || [padding] || pkcs7 || metadata || magic

Once you've stripped off the signature, you now need an extra processing
step to strip off the padding. And - unusually for appended signatures -
you need to know about the format of the data to distinguish data from
padding.

> In the case of the partition containing the elf binary it is expected
> that the padding is non-zero, in the other cases having padding is
> suspicious.
>
> In the case of a partition you have to read the data in some
> device-specific sectors while files can be read at arbitrary sized
> chunks.
>
> If you choose to write separate code to fetch the elf binary from
> different media due to these differences then these separate code paths
> must be adjusted. However, that is inherent to lack of suitable
> abstraction in the code, and not the appended signature format.
>
> I think it is more productive to clean up the code to handle all media
> the same way rather than inventing new unique quirky and deficient
> signature format.

You would need to handle the new padding at some stage in the pipeline,
and that pipeline stage needs to know how to read an ELF header. So I
agree that it would be logical to put signature verification in the ELF
parsing stage.

However, if you want to flag the existence of padding in non-PReP cases
- either to reject it or warn about it - then the signature verifier
needs to know if it's parsing a PReP partition. If the signature
validation lives in the ELF parser, you now need to tell the ELF parser
that you are parsing a PReP partion. This seems like an abstraction or
layering problem - the ELF parser shouldn't need to know or care where
the ELF binary comes from.

So I think that merely cleaning up the code wouldn't be sufficient.

Kind regards,
Daniel

>
> Thanks
>
> Michal
>
>> 
>> We can still support multiple signers disjoint in time with the scheme I
>> suggest at
>> https://lists.gnu.org/archive/html/grub-devel/2020-09/msg00081.html
>> although I do agree it's ugly in its own separate way.
>> 
>> Kind regards,
>> Daniel
>> 
>> >> The disadvantage is that for signed grub dd is no longer an alternative
>> >> to grub-install.
>> >>
>> >> There was also concern about distinguishing signed and un-signed grub.
>> >> That is that writing an un-signed grub might lease a stale signature
>> >> leading to an error.
>> >>
>> >> However, secure boot is something that should be enabled or disabled in
>> >> firmware settings, and not triggered by the PPeP partition containing a
>> >> signature. 
>> >>
>> >> When secure boot is enabled checking the grub signature is required and
>> >> un-signed grub is invalid. When secure boot is disabled the signature
>> >> is irrelevant and stale signature should not cause any error.
>> >
>> > What I'm concerned about here - and it's possible I explained it poorly
>> > at Plumbers - is how a systems administrator would distinguish between
>> > having accidentally installed an unsigned grub, and having installed a
>> > grub with a broken or untrusted signature.
>> >
>> > Having said that, ...
>> >
>> >> grub-install can also remove the signature magic when installing
>> >> un-signed grub for consistency. Users using dd to install un-signed
>> >> grub might still have an old signature at the end of the partition.
>> >
>> > if we make grub-install do the right thing, I think that sufficiently
>> > mitigates my concern.
>> >
>> > Thanks again, and I'll let you know how I get on shortly.
>> >
>> > Kind regards,
>> > Daniel


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

* Re: [PATCH 0/3] Add support for signing grub with an appended signature
  2020-10-23  5:33       ` Daniel Axtens
@ 2020-11-04 18:04         ` Michal Suchánek
  0 siblings, 0 replies; 8+ messages in thread
From: Michal Suchánek @ 2020-11-04 18:04 UTC (permalink / raw)
  To: Daniel Axtens; +Cc: grub-devel

On Fri, Oct 23, 2020 at 04:33:58PM +1100, Daniel Axtens wrote:
> Hi Michal,
> 
> >> So grub is usually loaded from the PReP partition if you are booting
> >> from disk. But, if you are booting from a CD/USB/etc, we first parse
> >> /ppc/boot-info.txt and then load whatever file it identifies. If you're
> >> netbooting we load the file we get from the network.
> >> 
> >> One strength of the ELF-note based scheme is that verification of the
> >> appended signature is exactly the same in all these scenarios, and in
> >> each case it can live entirely in the ELF parsing and loading code.
> >> 
> >> In contrast, if we don't have an elf note, we have to handle PReP
> >> partitions, CHRP boot-info.txt and netboot separately. At least in the
> >> PReP case we also have to do parse enough of the ELF header to determine
> >> how much data we need to be hashing for signature verification, and this
> >> crosses a couple of previously separate steps of the process.
> >> 
> >> To illustrate from SLOF, currently the ELF note stuff lives almost
> >> entirely in elf32.c, but for the scheme you describe we need to patch
> >> load-from-dos-boot-partition, load-from-gpt-prep-partition, whatever
> >> code we use for where we boot a file directly from disk for CHRP
> >> boot-info.txt loading, and something somewhere in the netboot code.
> >
> > Why do you have to handle different boot media separately, though?
> >
> > There is this bug, supposedly in 'old firmware' that when the PReP
> > partition is large (gigabytes in size) the firmware crashes trying to
> > load the whole thing to memory and hand it over to the elf parser. If
> > this is fixed today you need to parse the header anyway to know how much
> > to load, or you need to just hand over some handle to the partition and
> > let the elf parser do the reading.
> 
> Hmm, I will pass this on to the enterprise/proprietary Partiton Firmware
> (PFW) team to confirm that it's been fixed.
> 
> It won't affect (at least modern versions of) SLOF, as SLOF caps the
> amount of PReP partition that it reads at 32MB. It reads min(partition
> size, 32MB) and passes that to the ELF loader. (I suppose that will
> break if a bootloader ever grows to be > 32MB, but most distros only
> allocate something like 8MB to PReP today, so you'd hit partition size
> limits first anyway.)
> 
> > The appended signature format is exactly the same in each case: there is
> > a container such as a partition, a file, or a block of memory that has
> > an elf binary at the start, optional padding, and optinal signature at
> > the end. There is nothing stopping the elf parser from parsing both
> > the elf header and the signature footer when it gets the data.
> 
> Reflecting on it, the proposed new design is also pretty quirky.
> 
> The existing appended signature format is:
> 
>  data || pkcs7 || metadata || magic
> 
> If you strip off the signature, only the data remains, which you can
> immediately calculate the hash on and verify the signature. The ELF note
> format perserves this property.
> 
> Moving the signature to the end of the PReP partition gives you:
> 
>   data || [padding] || pkcs7 || metadata || magic
> 
> Once you've stripped off the signature, you now need an extra processing
> step to strip off the padding. And - unusually for appended signatures -
> you need to know about the format of the data to distinguish data from
> padding.

And you need to know about the format of the data to make use of it -
specifically to execute it as an ELF binary, anyway.

> 
> > In the case of the partition containing the elf binary it is expected
> > that the padding is non-zero, in the other cases having padding is
> > suspicious.
> >
> > In the case of a partition you have to read the data in some
> > device-specific sectors while files can be read at arbitrary sized
> > chunks.
> >
> > If you choose to write separate code to fetch the elf binary from
> > different media due to these differences then these separate code paths
> > must be adjusted. However, that is inherent to lack of suitable
> > abstraction in the code, and not the appended signature format.
> >
> > I think it is more productive to clean up the code to handle all media
> > the same way rather than inventing new unique quirky and deficient
> > signature format.
> 
> You would need to handle the new padding at some stage in the pipeline,
> and that pipeline stage needs to know how to read an ELF header. So I
> agree that it would be logical to put signature verification in the ELF
> parsing stage.
> 
> However, if you want to flag the existence of padding in non-PReP cases
> - either to reject it or warn about it - then the signature verifier
> needs to know if it's parsing a PReP partition. If the signature
> validation lives in the ELF parser, you now need to tell the ELF parser
> that you are parsing a PReP partion. This seems like an abstraction or
> layering problem - the ELF parser shouldn't need to know or care where
> the ELF binary comes from.
> 
> So I think that merely cleaning up the code wouldn't be sufficient.

Adding the flag is something optional, and otherwise the data passed is
the same.

If you read PReP either pass the whole thing if it is smaller than 32MB
or you pass the first 32MB and append the signature (if it exists), and
there is quirky case when the signature crosses the boundary of your
'maximum binary size'. This quirky case is caused by another layering
violation - the code is reading something it does not understand from
the partition.

Thanks

Michal

> 
> Kind regards,
> Daniel
> 
> >
> > Thanks
> >
> > Michal
> >
> >> 
> >> We can still support multiple signers disjoint in time with the scheme I
> >> suggest at
> >> https://lists.gnu.org/archive/html/grub-devel/2020-09/msg00081.html
> >> although I do agree it's ugly in its own separate way.
> >> 
> >> Kind regards,
> >> Daniel
> >> 
> >> >> The disadvantage is that for signed grub dd is no longer an alternative
> >> >> to grub-install.
> >> >>
> >> >> There was also concern about distinguishing signed and un-signed grub.
> >> >> That is that writing an un-signed grub might lease a stale signature
> >> >> leading to an error.
> >> >>
> >> >> However, secure boot is something that should be enabled or disabled in
> >> >> firmware settings, and not triggered by the PPeP partition containing a
> >> >> signature. 
> >> >>
> >> >> When secure boot is enabled checking the grub signature is required and
> >> >> un-signed grub is invalid. When secure boot is disabled the signature
> >> >> is irrelevant and stale signature should not cause any error.
> >> >
> >> > What I'm concerned about here - and it's possible I explained it poorly
> >> > at Plumbers - is how a systems administrator would distinguish between
> >> > having accidentally installed an unsigned grub, and having installed a
> >> > grub with a broken or untrusted signature.
> >> >
> >> > Having said that, ...
> >> >
> >> >> grub-install can also remove the signature magic when installing
> >> >> un-signed grub for consistency. Users using dd to install un-signed
> >> >> grub might still have an old signature at the end of the partition.
> >> >
> >> > if we make grub-install do the right thing, I think that sufficiently
> >> > mitigates my concern.
> >> >
> >> > Thanks again, and I'll let you know how I get on shortly.
> >> >
> >> > Kind regards,
> >> > Daniel


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

* Re: [PATCH 0/3] Add support for signing grub with an appended signature
  2020-08-21  2:37 Daniel Axtens
@ 2020-09-23 15:11 ` Daniel Axtens
  0 siblings, 0 replies; 8+ messages in thread
From: Daniel Axtens @ 2020-09-23 15:11 UTC (permalink / raw)
  To: grub-devel, pjones, xnox; +Cc: rashmica.g, alastair

Hi,

> Part of a secure boot chain is allowing boot firmware to verify the
> grub core.img. For UEFI platforms, this is done by signing the PE
> binary with a tool like pesign or sb-sign. However, for platforms that
> don't implement UEFI, an alternative scheme is required.
>
> These patches provide some infrastructure and documentation for
> signing grub's core.img with a Linux-kernel-module style appended
> signature.
>
> Because some platforms, such as powerpc-ieee1275, load grub from a raw
> disk partition rather than a filesystem, we extend grub-install to add
> an ELF note that allows us to specify the size and location of the
> signature.

This is following up on the discussion out of Linux Plumbers [1].
Hopefully I've got the main question-askers, apologies if I've missed
anyone or sent emails to the wrong people. I'm also emailing grub-devel@
in hopes of catching anyone else who is interested.

One of the big requirements I heard was a desire to support key
rotation, for example by being able to embed multiple signatures in a
single signed grub.

I checked, and this is possible with appended signatures as I have
proposed them, because the size of the full signature block is known
when grub-mkimage is called.

You do have to do a bit of magic with openssl and sign-file, but it's
not particuarly bad. This demonstrates the openssl side and it's easy
to integrate with grub-mkimage:

# sign data/hello-world with both signing1 and signing2, placing just the
# PKCS#7 message in out/double-sig.p7s
openssl cms -sign -binary -in data/hello-world \
    -signer signing1.pem -inkey signing1.key \
    -signer signing2.pem -inkey signing2.key \
    -out out/double-sig.p7s -outform DER -noattr -md sha512

# append it to data/hello-world using sign-file's -s option, creating
# out/hello-world-sha512-2keys
../tools/sign-file -s out/double-sig.p7s sha512 /dev/null data/hello-world out/hello-world-sha512-2keys

# to verify, extract the cryptographic message with
# extract-module-sig.pl from the kernel source

./extract-module-sig.pl -s out/hello-world-sha512-2keys > out/hello-world-sha512-2keys.sig 2> /dev/null
if ! cmp out/double-sig.p7s out/hello-world-sha512-2keys.sig ; then
	echo "Input signature and data from extract-module-sig.pl -s do not agree!"
	exit 1;
fi

# openssl's verify requires that _both_ signatures are made with
# embedded certs which validate against a trusted CA
openssl cms -verify -binary -in out/hello-world-sha512-2keys.sig -inform der \
            -content hello-world -CAfile ca.pem -out /dev/null
if [ $? -ne 0 ]; then
	echo "OpenSSL failed to verify with both keys"
	exit 1
fi

For our application, firmware will allow a grub binary to boot if any
of the signatures in the PKCS#7 message match a key that is trusted by
firmware. This should allow keys to be rotated with firmware releases
without breaking backwards compatibility.

I've updated https://github.com/daxtens/SLOF to demonstrate this: if
any signature can be validated by a built-in key, it will pass
verification.



Another thing that was raised was the ability to make multiple
signatures separated in time, where the second signer didn't have
access to the private keys for the first signer. The example given was
for someone to sign a distro binary with a second set of keys
(e.g. specific keys for a data center) - then the binary would be
bootable on machines with distro keys, and also on machines that have
only the second set of keys.

This is not so easy. For grub, with the elf note, the data over which
the signature is made contains the size of the signature. To add a
signature would be to change the size of the signature stored in the
signed data. That would either break the old signature, or we would need
to make it not a true appended signature any more: rather than being a
'dumb' signature over everything before the start of the appended
signature data, it'd be more complex. We'd need to teach the signer and
verifier how to deal with that, and then we've thrown away the
advantages of appended signatures and reinvented many of the
complexities of Authenticode.

One thing we could potentially do without going down that route is to
include a quantity of 'blank space' for signatures - we could for
example always allocate a few kilobytes for signatures. The distro
signatures would take up the first part of the buffer, leaving space
for some for 'user' signatures.

We can get this to work with the appended-signature format "as is": we
specify how big the PKCS#7 message is, and if the message happens to be
smaller than the size we give, both openssl and mbedtls will just ignore
any trailing data.

This does at least kinda-sorta work, but OpenSSL's 'cms -resign' command
only works if we include signed attributes and at the moment our mbedtls
implementation cannot handle that. I don't think the PKCS#7 standard
mandates that behaviour, so maybe we can hack around it with the OpenSSL
C API. Or maybe we can extend mbedtls to handle signed
attributes. (eek!)

The concern I have is that this approach creates a big block of
arbitrary unsigned data in the grub binary. An attacker under our threat
model (root on the host) could put any data they like into that space. I
worry that in combination with some other vulernability, this could be
used to more easily pass useful data in to grub. However, maybe that's
not that much of a win for the attacker: if they are root they also have
complete control of grub.cfg and can instruct grub to do quite a bit as
it is.

I'm also not sure that the use-case is quite as likely with Power
systems vs x86 systems. But if I'm overthinking the security
implications of a blank space in the binary, it seems like we could get
it to work and I'd be happy to chase it up further.

Thoughts? (on or off-list is fine.)

Kind regards,
Daniel

[1] https://linuxplumbersconf.org/event/7/contributions/738/
    https://youtu.be/IJUNxHnopH4?t=537

> More details are in patch 1, including a link to an open-source firmware
> capable of verifying a grub image signed this way.
>
> Daniel Axtens (2):
>   docs/grub: Document signing grub under UEFI
>   docs/grub: Document signing grub with an appended signature
>
> Rashmica Gupta (1):
>   Add suport for signing grub with an appended signature
>
>  docs/grub.texi              | 64 ++++++++++++++++++++++++++++++++++++-
>  include/grub/util/install.h |  8 +++--
>  include/grub/util/mkimage.h |  4 +--
>  util/grub-install-common.c  | 16 ++++++++--
>  util/grub-mkimage.c         | 11 +++++++
>  util/grub-mkimagexx.c       | 39 +++++++++++++++++++++-
>  util/mkimage.c              | 10 +++---
>  7 files changed, 138 insertions(+), 14 deletions(-)
>
> -- 
> 2.25.1


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

* [PATCH 0/3] Add support for signing grub with an appended signature
@ 2020-08-21  2:37 Daniel Axtens
  2020-09-23 15:11 ` Daniel Axtens
  0 siblings, 1 reply; 8+ messages in thread
From: Daniel Axtens @ 2020-08-21  2:37 UTC (permalink / raw)
  To: grub-devel; +Cc: rashmica.g, alastair, Daniel Axtens

Part of a secure boot chain is allowing boot firmware to verify the
grub core.img. For UEFI platforms, this is done by signing the PE
binary with a tool like pesign or sb-sign. However, for platforms that
don't implement UEFI, an alternative scheme is required.

These patches provide some infrastructure and documentation for
signing grub's core.img with a Linux-kernel-module style appended
signature.

Because some platforms, such as powerpc-ieee1275, load grub from a raw
disk partition rather than a filesystem, we extend grub-install to add
an ELF note that allows us to specify the size and location of the
signature.

More details are in patch 1, including a link to an open-source firmware
capable of verifying a grub image signed this way.

Daniel Axtens (2):
  docs/grub: Document signing grub under UEFI
  docs/grub: Document signing grub with an appended signature

Rashmica Gupta (1):
  Add suport for signing grub with an appended signature

 docs/grub.texi              | 64 ++++++++++++++++++++++++++++++++++++-
 include/grub/util/install.h |  8 +++--
 include/grub/util/mkimage.h |  4 +--
 util/grub-install-common.c  | 16 ++++++++--
 util/grub-mkimage.c         | 11 +++++++
 util/grub-mkimagexx.c       | 39 +++++++++++++++++++++-
 util/mkimage.c              | 10 +++---
 7 files changed, 138 insertions(+), 14 deletions(-)

-- 
2.25.1



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

end of thread, other threads:[~2020-11-04 18:04 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-16 11:20 [PATCH 0/3] Add support for signing grub with an appended signature Michal Suchánek
     [not found] ` <871rhuwi80.fsf@dja-thinkpad.axtens.net>
2020-10-19 23:18   ` Daniel Axtens
2020-10-22  4:25   ` Daniel Axtens
2020-10-22 11:14     ` Michal Suchánek
2020-10-23  5:33       ` Daniel Axtens
2020-11-04 18:04         ` Michal Suchánek
  -- strict thread matches above, loose matches on Subject: below --
2020-08-21  2:37 Daniel Axtens
2020-09-23 15:11 ` Daniel Axtens

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.