[Skiboot] [RFC 0/8] Implement secvar system mode and built-in key support

Eric Richter erichte at linux.ibm.com
Wed Sep 22 13:11:21 AEST 2021


The goal of this patch set is to provide support for a closed appliance to
enable OS secure boot utilizing either user-managed secure boot keys, or a
set of keys provided by the manufacturer at firmware compile time.

NOTE: This set has only been compile-tested, and will certainly not work on
hardware. Please consider this as a design draft, and not a complete
implementation.

This set attempts to achieve this by implementing the following:
 1. a new secure boot "mode"
 2. a storage driver that manages this mode
 3. a new physical presence mode to switch between secure boot modes
 4. a mechanism for a user to embed their keys in skiboot
 5. a backend driver specifically for embedded keys only
 6. a backend driver that switches behavior based on the secure boot mode

The two modes implemented by this set are USER_MODE, which behaves exactly
as secvar does now, and SYSTEM_MODE, which force-enables secure boot, and
will only expose embedded keys without permitting user-managed variables or
updates.

Modes can be switched by asserting physical presence with the appropriate
key clearing request setting:
 - clear-os-keys: disable secure boot and enter USER_MODE
 - reset-default-keys: enter SYSTEM_MODE, and enable secure boot with the
     embedded keys.

The secure boot modes are implemented through the use of two switchable
drivers -- drivers that extend the existing drivers without needing to
modify them by wrapping driver hooks with ones that dynamically select
which driver hook to call based on the mode. For example: in USER_MODE,
the edk2-switchable driver will call the edk2-compat-v1 hooks. In
SYSTEM_MODE, the switchable driver will instead call the edk2-compat-static
hooks.

The current secure boot mode will be exposed in the device tree as a child
of the existing "secvar" node (the code for this is not included in this
version of the set).

More detail on each of these components can be found in their respective
patch description.


Why this way?
Ultimately, the design circled around trying not to break existing
machines that may be updated to firmware that includes these changes. That
led to utilizing unused space in protected TPM NV storage to determine
if a machine has had secvar initialized once before (in which we should
default to USER_MODE), or if a machine is booting for the first time. By
adding a switchable mode, a user is also permitted to switch from their
previous user-managed keys to the firmware-supplied keys, and back again.

The storage driver is responsible for loading the variables, and more
importantly, loading the root of trust that determines secure boot state.
Therefore, it must also be responsible for mananging the preservation of
the secure boot mode as well.

However, the storage driver is not aware of the context of variables and
variable data. As it is, the format of the data is defined by the backend
driver, and is exposed to kernels via the compatible flag. Therefore, the
backend driver must be responsible for managing the embedded default keys.


This is a very drafty RFC, and I have left many TODOs in the code. I am
sending this now to gather some initial feedback on this design before I
spend too much time on any one component or refactor. Please take note of
the RFC NOTEs in each patch description, which highlight some of my
thoughts, reasonings, and where I am looking for more specific
feedback/suggestions.


Eric Richter (8):
  secvar_devtree: add hook for reset-default-keys physical presence mode
  secvar/secboot_tpm: expose some helper functions for future use
  secvar/drivers: add mode-switchable storage driver for secboot_tpm
  secboot_tpm_switchable merge
  secvar: add build-time mechanism to inject default variable data
  secvar/drivers: add a edk2-derived static key backend
  secvar/backend: add a switchable-mode edk2-based backend
  mowgli: (EXAMPLE) enable mode-switchable drivers for secvar

 Makefile.main                                 |   1 +
 include/secvar.h                              |   4 +
 libstb/secvar/Makefile.inc                    |   3 +-
 libstb/secvar/backend/Makefile.inc            |   2 +-
 libstb/secvar/backend/edk2-compat-static.c    |  80 ++++++
 libstb/secvar/backend/edk2-switchable.c       |  46 ++++
 libstb/secvar/defaultvars/Makefile.inc        |  31 +++
 libstb/secvar/secvar_devtree.c                |  18 +-
 libstb/secvar/secvar_devtree.h                |   3 +-
 libstb/secvar/storage/Makefile.inc            |   2 +-
 libstb/secvar/storage/secboot_tpm.c           |  12 +-
 libstb/secvar/storage/secboot_tpm.h           |   8 +
 .../secvar/storage/secboot_tpm_switchable.c   | 251 ++++++++++++++++++
 .../secvar/storage/secboot_tpm_switchable.h   |  15 ++
 libstb/secvar/test/secvar-test-secboot-tpm.c  |   2 +-
 platforms/astbmc/mowgli.c                     |   4 +-
 16 files changed, 469 insertions(+), 13 deletions(-)
 create mode 100644 libstb/secvar/backend/edk2-compat-static.c
 create mode 100644 libstb/secvar/backend/edk2-switchable.c
 create mode 100644 libstb/secvar/defaultvars/Makefile.inc
 create mode 100644 libstb/secvar/storage/secboot_tpm_switchable.c
 create mode 100644 libstb/secvar/storage/secboot_tpm_switchable.h

--
2.33.0



More information about the Skiboot mailing list