Bug 1882135 - Please enable aarch64 secure boot & enroll keys
Summary: Please enable aarch64 secure boot & enroll keys
Keywords:
Status: NEW
Alias: None
Product: Fedora
Classification: Fedora
Component: edk2
Version: rawhide
Hardware: aarch64
OS: Linux
unspecified
unspecified
Target Milestone: ---
Assignee: Paolo Bonzini
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks: ARMTracker
TreeView+ depends on / blocked
 
Reported: 2020-09-23 21:12 UTC by Jeremy Linton
Modified: 2021-11-07 22:44 UTC (History)
10 users (show)

Fixed In Version:
Doc Type: If docs needed, set a value
Doc Text:
Clone Of:
Environment:
Last Closed:
Type: Bug
Embargoed:


Attachments (Terms of Use)
Testing script for enrolling keys (2.92 KB, application/x-shellscript)
2020-09-24 19:39 UTC, Jeremy Linton
no flags Details

Description Jeremy Linton 2020-09-23 21:12:13 UTC
Description of problem: Aarch64 machines with secure boot (and TPMs/etc) are hard to come by, but are quickly becoming more common (ex: rpi4 with uefi). Enrolling a key in the aarch64 edk2 and enabling secure boot gives everyone with a fedora machine a mechanism to test/verify signed kernels/grub/shim/etc.


Version-Release number of selected component (if applicable): f33


How reproducible: 100%?


Steps to Reproduce:
1. use virt-manager to create a aarch64/guest.
2. Note the lack of options to enroll a key and enable secure boot.

Additional info:

I have provided some sample patches to the edk2 package in fedora to enable this.

https://src.fedoraproject.org/rpms/edk2/pull-request/6

This is an update/rebase of a similar patch set from 2018 or so. Back then there were still some issues with enabling secure boot with aarch64/linux, but enough of those have been corrected that its been enabled on a couple other distros at this point.

Comment 1 Cole Robinson 2020-09-24 18:46:54 UTC
Thanks Jeremy.

Jeremy's PR[1] adds secureboot enrollment for aarch64 to Fedora edk2.spec. It also drops use of qemu-ovmf-secureboot[2] which was added by puiterwijk after a big discussion[3]. Since then philmd and lersek have both contributed patches to that repo FWIW

I have no idea what qemu-ovmf-secureboot adds over Jeremy's simpler approach, so edk2 guys please help me out

[1] https://src.fedoraproject.org/rpms/edk2/pull-request/6
[2] https://github.com/rhuefi/qemu-ovmf-secureboot
[3] https://src.fedoraproject.org/rpms/edk2/pull-request/1

Comment 2 Jeremy Linton 2020-09-24 19:39:31 UTC
Created attachment 1716411 [details]
Testing script for enrolling keys

This is a rough bit of shell code I initially hacked together to test/verify the idea of using expect to enroll the keys during the edk2 build process.

Its useful if one wants to just isolate the enroll/validation process. It is definitely a buyer beware situation where its pretty easy to find oneself hacking the script (same as qosb).

Comment 3 Laszlo Ersek 2020-09-25 06:31:26 UTC
The aarch64 firmware binary in the Fedora edk2 package is not built with
-D SECURE_BOOT_ENABLE -- for good reason --, and so trying to enroll
certificates, or to rely on enrolled certificates in any way, is bound
to fail.

In particular, the following commit:

  https://src.fedoraproject.org/fork/jlinton/rpms/edk2/c/b0c7672e5a5753a7b135237ee165f1b2e98264a2

(titled "enable aarch64 secure boot and enroll keys") has a hunk that
goes:

> - ARM_FLAGS="${CC_FLAGS}"
> + ARM_FLAGS="${CC_FLAGS} -D SECURE_BOOT_ENABLE"

and that's *wrong*.

The combination of:
- the "virt" machine type of qemu-system-aarch64 / qemu-system-arm,
- and the ArmVirtQemu firmware,
does not employ a virtual hardware mechanism for protecting the pflash
chip that contains the authenticated UEFI variables.

This means that 3rd party UEFI applications, and/or the guest OS, can
overwrite the variable store with direct hardware (pflash) access, and
subvert secure boot.

On the x86 guest arch, we prevent this by *adding* "-D SMM_REQUIRE" to
"-D SECURE_BOOT_ENABLE":

> OVMF_SB_FLAGS="${OVMF_SB_FLAGS} -D SECURE_BOOT_ENABLE"
> OVMF_SB_FLAGS="${OVMF_SB_FLAGS} -D SMM_REQUIRE"

which restricts pflash writes to such code that the VCPU executes in SMM
-- which excludes guest OS code and 3rd party UEFI application code.


In the ArmVirtQemu firmware, "-D SECURE_BOOT_ENABLE" is offered only for
testing / development purposes. It provides the SB software interfaces
to UEFI applications and the OS that run in the guest, but it has no
actual security.

For this reason, a Linux distribution should (a) not pass "-D
SECURE_BOOT_ENABLE" to the ArmVirtQemu build at all, (b) not pass "-D
SECURE_BOOT_ENABLE" to the OVMF build without passing "-D SMM_REQUIRE"
also.

For actually securing "-D SECURE_BOOT_ENABLE" for arm / aarch64, QEMU
machine type changes and firmware changes are necessary first.

(BTW, in OVMF, SECURE_BOOT_ENABLE and SMM_REQUIRE are separate options
only for fw development reasons -- it makes *technical sense* to enable
just one and not the other, as the features are orthogonal, technically
speaking. For end-users, only two cases make sense though: enabling none
of them, or enabling both.)

My understanding is that QEMU *per se* supports TrustZone (?) or Secure
World (?) which I believe is something similar to SMM on x86.
Furthermore, edk2 contains StandaloneMmPkg, which *per se* provides the
firmware-side of the same thing. I believe Ard and others have put
StandaloneMmPkg to actual use on physical machines. However, these
features are not wired up on the "virt" board of
qemu-system-(arm|aarch64), and not consumed in ArmVirtQemu. Personally I
don't know how to do that (I have no idea about TrustZone or the Secure
World); if interested, please spend resources there.


The danger of giving "everyone with a fedora machine a mechanism to
test/verify signed kernels/grub/shim/etc" in aarch64 guests *right now*
is that users would miss that their aarch64 QEMU board + virtual
firmware have no actual security for Secure Boot, and would use that
setup as a "production" virtual machine.

We should not offer RPMs that create a false sense of security. If you
are a developer that needs to test/verify signed UEFI apps / kernels
before installing those on physical hardware, you can also build your
own virtual firmware (and refrain from distributing the binary to normal
end-users, for *their* sake).

Comment 4 Laszlo Ersek 2020-09-25 06:38:16 UTC
(In reply to Laszlo Ersek from comment #3)

> On the x86 guest arch, we prevent this by *adding* "-D SMM_REQUIRE" to
> "-D SECURE_BOOT_ENABLE":
>
> > OVMF_SB_FLAGS="${OVMF_SB_FLAGS} -D SECURE_BOOT_ENABLE"
> > OVMF_SB_FLAGS="${OVMF_SB_FLAGS} -D SMM_REQUIRE"
>
> which restricts pflash writes to such code that the VCPU executes in
> SMM -- which excludes guest OS code and 3rd party UEFI application
> code.

More precisely: "-D SMM_REQUIRE" ensures that the firmware perform
variable writes to the pflash chip in such code that *runs in SMM*.

The actual *restriction* of pflash writes to SMM is implemented by QEMU,
in response to the following QEMU cmdline flag:

  -global driver=cfi.pflash01,property=secure,value=on

(In the libvirt domain XML, the same restriction is expressed with:

<domain>
  <os>
    <loader readonly='yes' secure='yes' type='pflash'>...</loader>
                           ^^^^^^^^^^^^
    <nvram>...</nvram>
  </os>
</domain>
)

Comment 5 Jeremy Linton 2020-09-25 16:09:23 UTC
In the "more security" better realm your right, the x86 version here has a bit of additional security. I personally view it as your trusting a piece of signed code not to corrupt/modify the variable store using the official firmware/runtime paths, vs trusting a different piece of signed code to limit your access to the backing store that firmware is updating. So, realistically this is a case of making it _harder_ following an existing exploit vs there being a giant hole in the security model. AFAIK (and i'm far from a security expert) the uefi specification is silent about the actual storage mechanism, and all this SMM protected variable storage is a much more recent implementation.

To whether a similar mechanism could be implemented, yes, arm has additional security levels (in some ways similar to smm) that can be used. Although oddly enough tpm/measured boot support is i'm told in place with armvirt/qemu, although i'm told using the virtual tpm completely for variable storage is not in place either.

Comment 6 Laszlo Ersek 2020-09-28 17:04:33 UTC
(In reply to Jeremy Linton from comment #5)

> your trusting a piece of signed code not to corrupt/modify the
> variable store using the official firmware/runtime paths, vs trusting
> a different piece of signed code to limit your access to the backing
> store that firmware is updating.

To the extent that I'm able to follow, I disagree.

When the guest calls gRT->SetVariable(), if the payload is not correctly
signed, the request is rejected. No difference between the target arches
here, indeed.

If the guest is malicious, it may attempt to direct memory writes at the
pflash MMIO range.

- With the "virt" machine type running ArmVirtQemu, this attempt will
  succeed.

- With the "q35" machine type running OVMF built with SMM_REQUIRE, and
  the QEMU command line correctly restricting pflash writes to guest
  code executing in SMM, this attempt will fail. The logic that prevents
  the guest from performing this write runs on the *host* side. It's
  *QEMU* that prevents the write. Signedness (as a guest-side concept)
  is meaningless (undefined) for this protection.

> So, realistically this is a case of making it _harder_ following an
> existing exploit vs there being a giant hole in the security model.

If the Secure Boot interfaces appear available to the guest, but they
are not resistant to guest-side hardware access (= they are not
tamper-resistant), that's worse than not offering Secure Boot interfaces
at all. Ultimately, the security of authenticating executables before
launching them, as offered to the guest OS, is identical in both cases
(= "nil"), except in the first case, we lie about that fact.

> AFAIK (and i'm far from a security expert) the uefi specification is
> silent about the actual storage mechanism, and all this SMM protected
> variable storage is a much more recent implementation.

SMM is not spelled out in the UEFI spec; it's an x86 implementation
detail.

Tamper-resistance is required by the UEFI spec however (quotes from
v2.8):

- 32.3.6 Platform Firmware Key Storage Requirements

  "Platform Keys: The public key must be stored in non-volatile storage
  which is tamper and delete resistant."

  "Key Exchange Keys: The public key must be stored in non-volatile
  storage which is tamper resistant."

- 32.6.1 UEFI Image Variable GUID & Variable Name

  "The signature database variables db, dbt, dbx, and dbr must be stored
  in tamper-resistant non-volatile storage."

If the guest kernel can overwrite the flash, that's "tampering".

> To whether a similar mechanism could be implemented, yes, arm has
> additional security levels (in some ways similar to smm) that can be
> used.

That would be great. I don't know nearly enough about ARM to research
this, unfortunately.

> Although oddly enough tpm/measured boot support is i'm told in place
> with armvirt/qemu,

TPM (Trusted Boot) is different from Secure Boot. Secure Boot
authenticates (verifies) executables before they are launched. Trusted
Boot does not attempt to prevent the execution of any binaries; the TPM
only hashes data that it is given, into its platform config registers.
If the data hashed into the TPM is legit, then the TPM unseals a secret,
by virtue of the crypto mathematically producing (outputting) the right
secret. Otherwise, garbage is output "as" the secret. Nothing is hidden
or prevented; only the data stream doesn't hash / decode to the
sought-after secret. This is my understanding anyway.

Feeding data to the TPM, unlike writing to the varstore in flash, is not
a privileged operation.

Trusted boot for UEFI is provided by the swtpm daemon (= backend) +
QEMU's TPM frontend together; there is nothing (or almost nothing)
arch-specific about that feature, AIUI. (Perhaps the MMIO address range
of the TPM2 front-end chip is different between the "virt" and the
"pc/q35" machine types.)

> although i'm told using the virtual tpm completely for variable
> storage is not in place either.

The TPM is unsuitable for storing non-volatile UEFI variables.

Thanks!
Laszlo

Comment 7 Ben Cotton 2021-11-04 17:31:30 UTC
This message is a reminder that Fedora 33 is nearing its end of life.
Fedora will stop maintaining and issuing updates for Fedora 33 on 2021-11-30.
It is Fedora's policy to close all bug reports from releases that are no longer
maintained. At that time this bug will be closed as EOL if it remains open with a
Fedora 'version' of '33'.

Package Maintainer: If you wish for this bug to remain open because you
plan to fix it in a currently maintained version, simply change the 'version' 
to a later Fedora version.

Thank you for reporting this issue and we are sorry that we were not 
able to fix it before Fedora 33 is end of life. If you would still like 
to see this bug fixed and are able to reproduce it against a later version 
of Fedora, you are encouraged  change the 'version' to a later Fedora 
version prior this bug is closed as described in the policy above.

Although we aim to fix as many bugs as possible during every release's 
lifetime, sometimes those efforts are overtaken by events. Often a 
more recent Fedora release includes newer upstream software that fixes 
bugs or makes them obsolete.


Note You need to log in before you can comment on or make changes to this bug.