[PATCH 0/4] powerpc/pseries: expose firmware security variables via filesystem

Nayna Jain
2022-11-06T21:10:01Z

PowerVM provides an isolated Platform KeyStore (PKS)[1] storage allocation
for each logical partition (LPAR) with individually managed access controls
to store sensitive information securely. The Linux kernel can access this
storage by interfacing with the hypervisor using a new set of hypervisor
calls.

The PowerVM guest secure boot feature intends to use PKS for the purpose of
storing public keys. Secure boot requires public keys in order to verify
GRUB and the boot kernel. To allow authenticated manipulation of keys, PKS
supports variables to store key authorities namely, PK and KEK. Other
variables are used to store code signing keys, db and grubdb. It also
supports deny lists to disallow booting GRUB or kernels even if they are
signed with valid keys. This is done via deny list databases stored in dbx
and sbat variables. These variables are stored in PKS and are managed and
controlled by firmware.

The purpose of this patchset is to add the userspace interface to manage
these variables.

Currently, OpenPOWER exposes variables via sysfs, while EFI platforms have
used sysfs and then moved to their own efivarfs filesystem. The recent
coco feature uses securityfs to expose secrets to TEEs. All of these
environments are different both syntactically and semantically.

securityfs is meant for Linux security subsystems to expose policies, logs,
and other information and it does not interact with firmware for managing
these variables. However, there are various firmware security features that
expose their variables for user management via pseudo filesystems as
discussed above. There is currently no single place to expose these
variables. Different platforms use sysfs, platform-specific filesystems
such as efivars, or securityfs as they have found appropriate. This has
resulted in interfaces scattered around the tree. The multiple interfac
problem can be addressed by providing a single pseudo filesystem for all
platforms to expose their variables for firmware security features. Doing
so simplifies the interface for users of these platforms.

This patchset introduces a new firmware security pseudo filesystem,
fwsecurityfs. Any platform can expose the variables that are required by
firmware security features via this interface. It provides a common place
for exposing variables managed by firmware while still allowing platforms
to implement their own underlying semantics.

This design consists of two parts:

1. Firmware security filesystem (fwsecurityfs) that provides platforms
with APIs to create their own underlying directory and file structure.
It should be mounted on a new well-known mountpoint,
/sys/firmware/security.
2. Platform-specific layer for these variables that implements underlying
semantics. Platforms can expose their variables as files allowing
read/write/add/delete operations by defining their own inode and file
functions.

This patchset adds:
1. An update to the PLPKS driver to support the signed update H_CALL for
authenticated variables used in guest secure boot.
2. A firmware security filesystem named fwsecurityfs.
3. An interface to expose secure variables stored in the LPAR's PKS via
fwsecurityfs.

Note: This patchset is not intended to modify existing interfaces already
used by OpenPOWER or EFI but rather to ensure that new similar interfaces
have a common base going forward.

The first patch related to PLPKS driver is dependent on bugfixes posted
as part of patchset[4].

Changelog:

First non-RFC version after RFC versions[2,3].
Feedback from non-RFC version are included to update fwsecurityfs.
* PLPKS driver patch had been upstreamed separately. In this set, Patch 1
updates existing driver to include signed update support.
* Fix fwsecurityfs to also pin the file system, refactor and cleanup. The
consideration of namespacing has been done and is concluded that currently
no firmware object or entity is handled by namespacing. The purpose of
fwsecurityfs is to expose firmware space which is similar to exposing
space in TPM. And TPM is also not currently namespaced. If containers have
to make use of some such space in the future, it would have to be some
software space. With that, this currently only considers the host using the
firmware space.
* Fix secvars support for powerpc. It supports policy handling within the
kernel, supports UCS2 naming and cleanups.
* Read-only PLPKS configuration is exposed.
* secvars directory is now moved within a new parent directory plpks.
* Patch is now no more an RFC version.

[1] https://community.ibm.com/community/user/power/blogs/chris-engel1/2020/11/20/powervm-introduces-the-platform-keystore
[2] RFC v2: https://lore.kernel.org/linuxppc-dev/20220622215648.96723-1-nayna@linux.ibm.com/
[3] RFC v1: https://lore.kernel.org/linuxppc-dev/20220122005637.28199-1-nayna@linux.ibm.com/
[4] https://lore.kernel.org/linuxppc-dev/20221106205839.600442-1-nayna@linux.ibm.com/T/#t

Nayna Jain (4):
powerpc/pseries: Add new functions to PLPKS driver
fs: define a firmware security filesystem named fwsecurityfs
powerpc/pseries: initialize fwsecurityfs with plpks arch-specific
structure
powerpc/pseries: expose authenticated variables stored in LPAR PKS

arch/powerpc/include/asm/hvcall.h | 3 +-
arch/powerpc/platforms/pseries/Kconfig | 20 +
arch/powerpc/platforms/pseries/Makefile | 2 +
.../platforms/pseries/fwsecurityfs_arch.c | 124 ++++++
arch/powerpc/platforms/pseries/plpks.c | 112 +++++-
arch/powerpc/platforms/pseries/plpks.h | 38 ++
arch/powerpc/platforms/pseries/secvars.c | 365 ++++++++++++++++++
fs/Kconfig | 1 +
fs/Makefile | 1 +
fs/fwsecurityfs/Kconfig | 14 +
fs/fwsecurityfs/Makefile | 10 +
fs/fwsecurityfs/super.c | 263 +++++++++++++
include/linux/fwsecurityfs.h | 33 ++
include/uapi/linux/magic.h | 1 +
14 files changed, 981 insertions(+), 6 deletions(-)
create mode 100644 arch/powerpc/platforms/pseries/fwsecurityfs_arch.c
create mode 100644 arch/powerpc/platforms/pseries/secvars.c
create mode 100644 fs/fwsecurityfs/Kconfig
create mode 100644 fs/fwsecurityfs/Makefile
create mode 100644 fs/fwsecurityfs/super.c
create mode 100644 include/linux/fwsecurityfs.h

--
2.31.1