Merge: Secure boot sysfs enhancements

MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/merge_requests/7306

Description: Secure boot sysfs enhancements

JIRA: https://issues.redhat.com/browse/RHEL-101853

Build Info: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=68771671

Tested: Verified Brew build test kernel RPMs

Signed-off-by: Mamatha Inamdar <minamdar@redhat.com>

Approved-by: Steve Best <sbest@redhat.com>
Approved-by: Tony Camuso <tcamuso@redhat.com>
Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com>

Merged-by: CKI GitLab Kmaint Pipeline Bot <26919896-cki-kmaint-pipeline-bot@users.noreply.gitlab.com>
This commit is contained in:
CKI KWF Bot 2025-09-10 14:25:54 +00:00
commit 17e9e7b6f9
3 changed files with 88 additions and 40 deletions

View File

@ -22,9 +22,13 @@ Description: A string indicating which backend is in use by the firmware.
and is expected to be "ibm,edk2-compat-v1".
On pseries/PLPKS, this is generated by the kernel based on the
version number in the SB_VERSION variable in the keystore, and
has the form "ibm,plpks-sb-v<version>", or
"ibm,plpks-sb-unknown" if there is no SB_VERSION variable.
version number in the SB_VERSION variable in the keystore. The
version numbering in the SB_VERSION variable starts from 1. The
format string takes the form "ibm,plpks-sb-v<version>" in the
case of dynamic key management mode. If the SB_VERSION variable
does not exist (or there is an error while reading it), it takes
the form "ibm,plpks-sb-v0", indicating that the key management
mode is static.
What: /sys/firmware/secvar/vars/<variable name>
Date: August 2019
@ -34,6 +38,13 @@ Description: Each secure variable is represented as a directory named as
representation. The data and size can be determined by reading
their respective attribute files.
Only secvars relevant to the key management mode are exposed.
Only in the dynamic key management mode should the user have
access (read and write) to the secure boot secvars db, dbx,
grubdb, grubdbx, and sbat. These secvars are not consumed in the
static key management mode. PK, trustedcadb and moduledb are the
secvars common to both static and dynamic key management modes.
What: /sys/firmware/secvar/vars/<variable_name>/size
Date: August 2019
Contact: Nayna Jain <nayna@linux.ibm.com>

View File

@ -59,7 +59,14 @@ static u32 get_policy(const char *name)
return PLPKS_SIGNEDUPDATE;
}
static const char * const plpks_var_names[] = {
static const char * const plpks_var_names_static[] = {
"PK",
"moduledb",
"trustedcadb",
NULL,
};
static const char * const plpks_var_names_dynamic[] = {
"PK",
"KEK",
"db",
@ -152,39 +159,55 @@ err:
return rc;
}
// PLPKS dynamic secure boot doesn't give us a format string in the same way OPAL does.
// Instead, report the format using the SB_VERSION variable in the keystore.
// The string is made up by us, and takes the form "ibm,plpks-sb-v<n>" (or "ibm,plpks-sb-unknown"
// if the SB_VERSION variable doesn't exist). Hypervisor defines the SB_VERSION variable as a
// "1 byte unsigned integer value".
/*
* Return the key management mode.
*
* SB_VERSION is defined as a "1 byte unsigned integer value", taking values
* starting from 1. It is owned by the Partition Firmware and its presence
* indicates that the key management mode is dynamic. Any failure in
* reading SB_VERSION defaults the key management mode to static. The error
* codes -ENOENT or -EPERM are expected in static key management mode. An
* unexpected error code will have to be investigated. Only signed variables
* have null bytes in their names, SB_VERSION does not.
*
* Return 0 to indicate that the key management mode is static. Otherwise
* return the SB_VERSION value to indicate that the key management mode is
* dynamic.
*/
static u8 plpks_get_sb_keymgmt_mode(void)
{
u8 mode;
ssize_t rc;
struct plpks_var var = {
.component = NULL,
.name = "SB_VERSION",
.namelen = 10,
.datalen = 1,
.data = &mode,
};
rc = plpks_read_fw_var(&var);
if (rc) {
if (rc != -ENOENT && rc != -EPERM)
pr_info("Error %ld reading SB_VERSION from firmware\n", rc);
mode = 0;
}
return mode;
}
/*
* PLPKS dynamic secure boot doesn't give us a format string in the same way
* OPAL does. Instead, report the format using the SB_VERSION variable in the
* keystore. The string, made up by us, takes the form of either
* "ibm,plpks-sb-v<n>" or "ibm,plpks-sb-v0", based on the key management mode,
* and return the length of the secvar format property.
*/
static ssize_t plpks_secvar_format(char *buf, size_t bufsize)
{
struct plpks_var var = {0};
ssize_t ret;
u8 version;
u8 mode;
var.component = NULL;
// Only the signed variables have null bytes in their names, this one doesn't
var.name = "SB_VERSION";
var.namelen = strlen(var.name);
var.datalen = 1;
var.data = &version;
// Unlike the other vars, SB_VERSION is owned by firmware instead of the OS
ret = plpks_read_fw_var(&var);
if (ret) {
if (ret == -ENOENT) {
ret = snprintf(buf, bufsize, "ibm,plpks-sb-unknown");
} else {
pr_err("Error %ld reading SB_VERSION from firmware\n", ret);
ret = -EIO;
}
goto err;
}
ret = snprintf(buf, bufsize, "ibm,plpks-sb-v%hhu", version);
err:
return ret;
mode = plpks_get_sb_keymgmt_mode();
return snprintf(buf, bufsize, "ibm,plpks-sb-v%hhu", mode);
}
static int plpks_max_size(u64 *max_size)
@ -197,21 +220,34 @@ static int plpks_max_size(u64 *max_size)
return 0;
}
static const struct secvar_operations plpks_secvar_ops = {
static const struct secvar_operations plpks_secvar_ops_static = {
.get = plpks_get_variable,
.set = plpks_set_variable,
.format = plpks_secvar_format,
.max_size = plpks_max_size,
.config_attrs = config_attrs,
.var_names = plpks_var_names,
.var_names = plpks_var_names_static,
};
static const struct secvar_operations plpks_secvar_ops_dynamic = {
.get = plpks_get_variable,
.set = plpks_set_variable,
.format = plpks_secvar_format,
.max_size = plpks_max_size,
.config_attrs = config_attrs,
.var_names = plpks_var_names_dynamic,
};
static int plpks_secvar_init(void)
{
u8 mode;
if (!plpks_is_available())
return -ENODEV;
return set_secvar_ops(&plpks_secvar_ops);
mode = plpks_get_sb_keymgmt_mode();
if (mode)
return set_secvar_ops(&plpks_secvar_ops_dynamic);
return set_secvar_ops(&plpks_secvar_ops_static);
}
machine_device_initcall(pseries, plpks_secvar_init);

View File

@ -75,12 +75,13 @@ static int __init load_powerpc_certs(void)
return -ENODEV;
// Check for known secure boot implementations from OPAL or PLPKS
if (strcmp("ibm,edk2-compat-v1", buf) && strcmp("ibm,plpks-sb-v1", buf)) {
if (strcmp("ibm,edk2-compat-v1", buf) && strcmp("ibm,plpks-sb-v1", buf) &&
strcmp("ibm,plpks-sb-v0", buf)) {
pr_err("Unsupported secvar implementation \"%s\", not loading certs\n", buf);
return -ENODEV;
}
if (strcmp("ibm,plpks-sb-v1", buf) == 0)
if (strcmp("ibm,plpks-sb-v1", buf) == 0 || strcmp("ibm,plpks-sb-v0", buf) == 0)
/* PLPKS authenticated variables ESL data is prefixed with 8 bytes of timestamp */
offset = 8;