mirror of
https://git.proxmox.com/git/fwupd
synced 2025-08-05 22:47:32 +00:00
Add new plugin for AMD PSP
This plugin reads in values exported by the PSP on supported AMD SOCs to calculate the system state based on this information
This commit is contained in:
parent
65e3bc57c5
commit
1a66818970
@ -455,6 +455,7 @@ done
|
||||
%{_libdir}/fwupd-plugins-%{fwupdplugin_version}/libfu_plugin_acpi_dmar.so
|
||||
%{_libdir}/fwupd-plugins-%{fwupdplugin_version}/libfu_plugin_acpi_ivrs.so
|
||||
%{_libdir}/fwupd-plugins-%{fwupdplugin_version}/libfu_plugin_msr.so
|
||||
%{_libdir}/fwupd-plugins-%{fwupdplugin_version}/libfu_plugin_pci_psp.so
|
||||
%endif
|
||||
%{_libdir}/fwupd-plugins-%{fwupdplugin_version}/libfu_plugin_mtd.so
|
||||
%{_libdir}/fwupd-plugins-%{fwupdplugin_version}/libfu_plugin_nitrokey.so
|
||||
|
@ -66,6 +66,7 @@ subdir('optionrom')
|
||||
subdir('parade-lspcon')
|
||||
subdir('pci-bcr')
|
||||
subdir('pci-mei')
|
||||
subdir('pci-psp')
|
||||
subdir('pixart-rf')
|
||||
subdir('platform-integrity')
|
||||
subdir('powerd')
|
||||
|
16
plugins/pci-psp/README.md
Normal file
16
plugins/pci-psp/README.md
Normal file
@ -0,0 +1,16 @@
|
||||
# PCI PSP
|
||||
|
||||
## Introduction
|
||||
|
||||
This plugin checks all information reported from the AMD Platform Security processor into
|
||||
the operating system on select SOCs.
|
||||
|
||||
The lack of these sysfs files does *NOT* indicate the lack of these security features, it only
|
||||
indicates the lack of the ability to export it to the operating system.
|
||||
|
||||
The availability of the sysfs files indicates that the PSP supports exporting this information
|
||||
into the operating system.
|
||||
|
||||
## External Interface Access
|
||||
|
||||
This plugin requires read only access to attributes located within `/sys/bus/pci/devices/`.
|
278
plugins/pci-psp/fu-plugin-pci-psp.c
Normal file
278
plugins/pci-psp/fu-plugin-pci-psp.c
Normal file
@ -0,0 +1,278 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Advanced Micro Devices Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <fwupdplugin.h>
|
||||
|
||||
static void
|
||||
fu_plugin_pci_psp_init(FuPlugin *plugin)
|
||||
{
|
||||
fu_plugin_add_udev_subsystem(plugin, "pci");
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_plugin_pci_psp_backend_device_added(FuPlugin *plugin, FuDevice *device, GError **error)
|
||||
{
|
||||
/* interesting device? */
|
||||
if (!FU_IS_UDEV_DEVICE(device))
|
||||
return TRUE;
|
||||
if (g_strcmp0(fu_udev_device_get_subsystem(FU_UDEV_DEVICE(device)), "pci") != 0)
|
||||
return TRUE;
|
||||
|
||||
fu_plugin_cache_add(plugin, "pci-psp-device", device);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_plugin_pci_psp_get_attr(FwupdSecurityAttr *attr,
|
||||
const gchar *path,
|
||||
const gchar *file,
|
||||
gboolean *out,
|
||||
GError **error)
|
||||
{
|
||||
g_autofree gchar *fn = g_build_filename(path, file, NULL);
|
||||
g_autofree gchar *buf = NULL;
|
||||
gsize bufsz = 0;
|
||||
|
||||
if (!g_file_get_contents(fn, &buf, &bufsz, error)) {
|
||||
g_prefix_error(error, "could not open %s: ", fn);
|
||||
fwupd_security_attr_add_flag(attr, FWUPD_SECURITY_ATTR_FLAG_MISSING_DATA);
|
||||
return FALSE;
|
||||
}
|
||||
*out = fu_common_strtoull(buf) ? TRUE : FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_plugin_add_security_attrs_tsme(const gchar *path, FuSecurityAttrs *attrs)
|
||||
{
|
||||
g_autoptr(FwupdSecurityAttr) attr = NULL;
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
gboolean val;
|
||||
|
||||
attr = fwupd_security_attr_new(FWUPD_SECURITY_ATTR_ID_ENCRYPTED_RAM);
|
||||
fwupd_security_attr_set_plugin(attr, "pci_psp");
|
||||
fwupd_security_attr_set_level(attr, FWUPD_SECURITY_ATTR_LEVEL_SYSTEM_PROTECTION);
|
||||
fu_security_attrs_append(attrs, attr);
|
||||
|
||||
if (!fu_plugin_pci_psp_get_attr(attr, path, "tsme_status", &val, &error_local)) {
|
||||
g_debug("%s", error_local->message);
|
||||
return;
|
||||
}
|
||||
|
||||
if (val)
|
||||
fwupd_security_attr_set_result(attr, FWUPD_SECURITY_ATTR_RESULT_ENCRYPTED);
|
||||
|
||||
/* success */
|
||||
fwupd_security_attr_add_flag(attr, FWUPD_SECURITY_ATTR_FLAG_SUCCESS);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_plugin_add_security_attrs_fused_part(const gchar *path, FuSecurityAttrs *attrs)
|
||||
{
|
||||
g_autoptr(FwupdSecurityAttr) attr = NULL;
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
gboolean val;
|
||||
|
||||
attr = fwupd_security_attr_new(FWUPD_SECURITY_ATTR_ID_PLATFORM_FUSED);
|
||||
fwupd_security_attr_set_plugin(attr, "pci_psp");
|
||||
fwupd_security_attr_set_level(attr, FWUPD_SECURITY_ATTR_LEVEL_CRITICAL);
|
||||
fu_security_attrs_append(attrs, attr);
|
||||
|
||||
if (!fu_plugin_pci_psp_get_attr(attr, path, "fused_part", &val, &error_local)) {
|
||||
g_debug("%s", error_local->message);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!val) {
|
||||
g_debug("part is not fused");
|
||||
fwupd_security_attr_set_result(attr, FWUPD_SECURITY_ATTR_RESULT_NOT_LOCKED);
|
||||
return;
|
||||
}
|
||||
|
||||
/* success */
|
||||
fwupd_security_attr_set_result(attr, FWUPD_SECURITY_ATTR_RESULT_LOCKED);
|
||||
fwupd_security_attr_add_flag(attr, FWUPD_SECURITY_ATTR_FLAG_SUCCESS);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_plugin_add_security_attrs_debug_locked_part(const gchar *path, FuSecurityAttrs *attrs)
|
||||
{
|
||||
g_autoptr(FwupdSecurityAttr) attr = NULL;
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
gboolean val;
|
||||
|
||||
attr = fwupd_security_attr_new(FWUPD_SECURITY_ATTR_ID_PLATFORM_DEBUG_LOCKED);
|
||||
fwupd_security_attr_set_plugin(attr, "pci_psp");
|
||||
fwupd_security_attr_set_level(attr, FWUPD_SECURITY_ATTR_LEVEL_IMPORTANT);
|
||||
fu_security_attrs_append(attrs, attr);
|
||||
|
||||
if (!fu_plugin_pci_psp_get_attr(attr, path, "debug_lock_on", &val, &error_local)) {
|
||||
g_debug("%s", error_local->message);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!val) {
|
||||
g_debug("debug lock disabled");
|
||||
fwupd_security_attr_set_result(attr, FWUPD_SECURITY_ATTR_RESULT_NOT_LOCKED);
|
||||
return;
|
||||
}
|
||||
|
||||
/* success */
|
||||
fwupd_security_attr_set_result(attr, FWUPD_SECURITY_ATTR_RESULT_LOCKED);
|
||||
fwupd_security_attr_add_flag(attr, FWUPD_SECURITY_ATTR_FLAG_SUCCESS);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_plugin_add_security_attrs_rollback_protection(const gchar *path, FuSecurityAttrs *attrs)
|
||||
{
|
||||
g_autoptr(FwupdSecurityAttr) attr = NULL;
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
gboolean val;
|
||||
|
||||
attr = fwupd_security_attr_new(FWUPD_SECURITY_ATTR_ID_AMD_ROLLBACK_PROTECTION);
|
||||
fwupd_security_attr_set_plugin(attr, "pci_psp");
|
||||
fwupd_security_attr_set_level(attr, FWUPD_SECURITY_ATTR_LEVEL_CRITICAL);
|
||||
fu_security_attrs_append(attrs, attr);
|
||||
|
||||
if (!fu_plugin_pci_psp_get_attr(attr, path, "anti_rollback_status", &val, &error_local)) {
|
||||
g_debug("%s", error_local->message);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!val) {
|
||||
g_debug("rollback protection not enforced");
|
||||
fwupd_security_attr_set_result(attr, FWUPD_SECURITY_ATTR_RESULT_NOT_ENABLED);
|
||||
return;
|
||||
}
|
||||
|
||||
fwupd_security_attr_set_result(attr, FWUPD_SECURITY_ATTR_RESULT_ENABLED);
|
||||
fwupd_security_attr_add_flag(attr, FWUPD_SECURITY_ATTR_FLAG_SUCCESS);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_plugin_add_security_attrs_rom_armor(const gchar *path, FuSecurityAttrs *attrs)
|
||||
{
|
||||
g_autoptr(FwupdSecurityAttr) attr = NULL;
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
gboolean val;
|
||||
|
||||
/* create attr */
|
||||
attr = fwupd_security_attr_new(FWUPD_SECURITY_ATTR_ID_AMD_SPI_WRITE_PROTECTION);
|
||||
fwupd_security_attr_set_plugin(attr, "pci_psp");
|
||||
fwupd_security_attr_set_level(attr, FWUPD_SECURITY_ATTR_LEVEL_IMPORTANT);
|
||||
fu_security_attrs_append(attrs, attr);
|
||||
|
||||
if (!fu_plugin_pci_psp_get_attr(attr, path, "rom_armor_enforced", &val, &error_local)) {
|
||||
g_debug("%s", error_local->message);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!val) {
|
||||
g_debug("ROM armor not enforced");
|
||||
fwupd_security_attr_set_result(attr, FWUPD_SECURITY_ATTR_RESULT_NOT_ENABLED);
|
||||
return;
|
||||
}
|
||||
|
||||
/* success */
|
||||
fwupd_security_attr_set_result(attr, FWUPD_SECURITY_ATTR_RESULT_ENABLED);
|
||||
fwupd_security_attr_add_flag(attr, FWUPD_SECURITY_ATTR_FLAG_SUCCESS);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_plugin_add_security_attrs_rpmc(const gchar *path, FuSecurityAttrs *attrs)
|
||||
{
|
||||
g_autoptr(FwupdSecurityAttr) attr = NULL;
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
gboolean val;
|
||||
|
||||
/* create attr */
|
||||
attr = fwupd_security_attr_new(FWUPD_SECURITY_ATTR_ID_AMD_SPI_REPLAY_PROTECTION);
|
||||
fwupd_security_attr_set_plugin(attr, "pci_psp");
|
||||
fwupd_security_attr_set_level(attr, FWUPD_SECURITY_ATTR_LEVEL_THEORETICAL);
|
||||
fu_security_attrs_append(attrs, attr);
|
||||
|
||||
if (!fu_plugin_pci_psp_get_attr(attr, path, "rpmc_spirom_available", &val, &error_local)) {
|
||||
g_debug("%s", error_local->message);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!val) {
|
||||
g_debug("no RPMC compatible SPI rom present");
|
||||
fwupd_security_attr_set_result(attr, FWUPD_SECURITY_ATTR_RESULT_NOT_SUPPORTED);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!fu_plugin_pci_psp_get_attr(attr,
|
||||
path,
|
||||
"rpmc_production_enabled",
|
||||
&val,
|
||||
&error_local)) {
|
||||
g_debug("%s", error_local->message);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!val) {
|
||||
g_debug("no RPMC compatible SPI rom present");
|
||||
fwupd_security_attr_set_result(attr, FWUPD_SECURITY_ATTR_RESULT_NOT_ENABLED);
|
||||
return;
|
||||
}
|
||||
|
||||
/* success */
|
||||
fwupd_security_attr_set_result(attr, FWUPD_SECURITY_ATTR_RESULT_ENABLED);
|
||||
fwupd_security_attr_add_flag(attr, FWUPD_SECURITY_ATTR_FLAG_SUCCESS);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_plugin_pci_psp_set_missing_data(FuSecurityAttrs *attrs)
|
||||
{
|
||||
g_autoptr(FwupdSecurityAttr) attr = NULL;
|
||||
|
||||
attr = fwupd_security_attr_new(FWUPD_SECURITY_ATTR_ID_SUPPORTED_CPU);
|
||||
fwupd_security_attr_set_plugin(attr, "pci_psp");
|
||||
fwupd_security_attr_set_level(attr, FWUPD_SECURITY_ATTR_LEVEL_CRITICAL);
|
||||
fwupd_security_attr_add_obsolete(attr, "cpu");
|
||||
fwupd_security_attr_add_flag(attr, FWUPD_SECURITY_ATTR_FLAG_MISSING_DATA);
|
||||
fu_security_attrs_append(attrs, attr);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_plugin_pci_psp_add_security_attrs(FuPlugin *plugin, FuSecurityAttrs *attrs)
|
||||
{
|
||||
FuDevice *psp_device = fu_plugin_cache_lookup(plugin, "pci-psp-device");
|
||||
const gchar *sysfs_path = NULL;
|
||||
|
||||
/* only AMD */
|
||||
if (fu_common_get_cpu_vendor() != FU_CPU_VENDOR_AMD)
|
||||
return;
|
||||
|
||||
/* ccp not loaded */
|
||||
if (psp_device)
|
||||
sysfs_path = fu_udev_device_get_sysfs_path(FU_UDEV_DEVICE(psp_device));
|
||||
if (sysfs_path == NULL) {
|
||||
fu_plugin_pci_psp_set_missing_data(attrs);
|
||||
return;
|
||||
}
|
||||
|
||||
fu_plugin_add_security_attrs_tsme(sysfs_path, attrs);
|
||||
fu_plugin_add_security_attrs_fused_part(sysfs_path, attrs);
|
||||
fu_plugin_add_security_attrs_debug_locked_part(sysfs_path, attrs);
|
||||
fu_plugin_add_security_attrs_rollback_protection(sysfs_path, attrs);
|
||||
fu_plugin_add_security_attrs_rpmc(sysfs_path, attrs);
|
||||
fu_plugin_add_security_attrs_rom_armor(sysfs_path, attrs);
|
||||
}
|
||||
|
||||
void
|
||||
fu_plugin_init_vfuncs(FuPluginVfuncs *vfuncs)
|
||||
{
|
||||
vfuncs->build_hash = FU_BUILD_HASH;
|
||||
vfuncs->init = fu_plugin_pci_psp_init;
|
||||
vfuncs->add_security_attrs = fu_plugin_pci_psp_add_security_attrs;
|
||||
vfuncs->backend_device_added = fu_plugin_pci_psp_backend_device_added;
|
||||
}
|
31
plugins/pci-psp/meson.build
Normal file
31
plugins/pci-psp/meson.build
Normal file
@ -0,0 +1,31 @@
|
||||
if get_option('hsi') and \
|
||||
host_machine.system() == 'linux' and \
|
||||
host_cpu == 'x86_64'
|
||||
cargs = ['-DG_LOG_DOMAIN="FuPluginPciPsp"']
|
||||
|
||||
install_data(['pci-psp.quirk'],
|
||||
install_dir: join_paths(datadir, 'fwupd', 'quirks.d')
|
||||
)
|
||||
|
||||
shared_module('fu_plugin_pci_psp',
|
||||
fu_hash,
|
||||
sources : [
|
||||
'fu-plugin-pci-psp.c',
|
||||
],
|
||||
include_directories : [
|
||||
root_incdir,
|
||||
fwupd_incdir,
|
||||
fwupdplugin_incdir,
|
||||
],
|
||||
install : true,
|
||||
install_dir: plugin_dir,
|
||||
link_with : [
|
||||
fwupd,
|
||||
fwupdplugin,
|
||||
],
|
||||
c_args : cargs,
|
||||
dependencies : [
|
||||
plugin_deps,
|
||||
],
|
||||
)
|
||||
endif
|
2
plugins/pci-psp/pci-psp.quirk
Normal file
2
plugins/pci-psp/pci-psp.quirk
Normal file
@ -0,0 +1,2 @@
|
||||
[PCI\DRIVER_ccp]
|
||||
Plugin = pci_psp
|
Loading…
Reference in New Issue
Block a user