2024-05-28 21:09:25

by Mario Limonciello

[permalink] [raw]
Subject: [PATCH v2 0/5] Enable PSP security attributes on more SoCs

On some older SoCs the PSP doesn't export security attributes in the
capabilities register. On these SoCs it is however possible to get
the information by a platform access command.

Restructure the driver to move all security attribute handling to
a central location and then add support for calling the platform
access command on those processors.

v1->v2:
* Add tags (except patch 2)
* Fix kernel robot reported issue
* Move a check from patch 4 to patch 5
Mario Limonciello (5):
crypto: ccp: Represent capabilities register as a union
crypto: ccp: Move security attributes to their own file
crypto: ccp: align psp_platform_access_msg
crypto: ccp: Add support for getting security attributes on some older
systems
crypto: ccp: Move message about TSME being enabled later in init

MAINTAINERS | 6 ++
drivers/crypto/ccp/Makefile | 3 +-
drivers/crypto/ccp/dbc.c | 2 +-
drivers/crypto/ccp/hsti.c | 138 ++++++++++++++++++++++++++++
drivers/crypto/ccp/hsti.h | 17 ++++
drivers/crypto/ccp/psp-dev.c | 23 ++---
drivers/crypto/ccp/psp-dev.h | 46 +++++-----
drivers/crypto/ccp/sp-dev.h | 2 +-
drivers/crypto/ccp/sp-pci.c | 67 ++------------
include/linux/psp-platform-access.h | 5 +-
10 files changed, 210 insertions(+), 99 deletions(-)
create mode 100644 drivers/crypto/ccp/hsti.c
create mode 100644 drivers/crypto/ccp/hsti.h

--
2.43.0



2024-05-28 21:10:02

by Mario Limonciello

[permalink] [raw]
Subject: [PATCH v2 1/5] crypto: ccp: Represent capabilities register as a union

Making the capabilities register a union makes it easier to refer
to the members instead of always doing bit shifts.

No intended functional changes.

Acked-by: Tom Lendacky <[email protected]>
Suggested-by: Yazen Ghannam <[email protected]>
Signed-off-by: Mario Limonciello <[email protected]>
---
v1->v2:
* Add tag
---
drivers/crypto/ccp/dbc.c | 2 +-
drivers/crypto/ccp/psp-dev.c | 11 ++++-----
drivers/crypto/ccp/psp-dev.h | 44 ++++++++++++++++++++----------------
drivers/crypto/ccp/sp-dev.h | 1 -
drivers/crypto/ccp/sp-pci.c | 26 ++++++++++-----------
5 files changed, 42 insertions(+), 42 deletions(-)

diff --git a/drivers/crypto/ccp/dbc.c b/drivers/crypto/ccp/dbc.c
index d373caab52f8..5b105a23f699 100644
--- a/drivers/crypto/ccp/dbc.c
+++ b/drivers/crypto/ccp/dbc.c
@@ -223,7 +223,7 @@ int dbc_dev_init(struct psp_device *psp)
dbc_dev->dev = dev;
dbc_dev->psp = psp;

- if (PSP_CAPABILITY(psp, DBC_THRU_EXT)) {
+ if (psp->capability.dbc_thru_ext) {
dbc_dev->use_ext = true;
dbc_dev->payload_size = &dbc_dev->mbox->ext_req.header.payload_size;
dbc_dev->result = &dbc_dev->mbox->ext_req.header.status;
diff --git a/drivers/crypto/ccp/psp-dev.c b/drivers/crypto/ccp/psp-dev.c
index 56bf832c2947..7d9d2042be35 100644
--- a/drivers/crypto/ccp/psp-dev.c
+++ b/drivers/crypto/ccp/psp-dev.c
@@ -154,11 +154,10 @@ static unsigned int psp_get_capability(struct psp_device *psp)
dev_notice(psp->dev, "psp: unable to access the device: you might be running a broken BIOS.\n");
return -ENODEV;
}
- psp->capability = val;
+ psp->capability.raw = val;

/* Detect TSME and/or SME status */
- if (PSP_CAPABILITY(psp, PSP_SECURITY_REPORTING) &&
- psp->capability & (PSP_SECURITY_TSME_STATUS << PSP_CAPABILITY_PSP_SECURITY_OFFSET)) {
+ if (psp->capability.security_reporting && psp->capability.tsme_status) {
if (cc_platform_has(CC_ATTR_HOST_MEM_ENCRYPT))
dev_notice(psp->dev, "psp: Both TSME and SME are active, SME is unnecessary when TSME is active.\n");
else
@@ -171,7 +170,7 @@ static unsigned int psp_get_capability(struct psp_device *psp)
static int psp_check_sev_support(struct psp_device *psp)
{
/* Check if device supports SEV feature */
- if (!PSP_CAPABILITY(psp, SEV)) {
+ if (!psp->capability.sev) {
dev_dbg(psp->dev, "psp does not support SEV\n");
return -ENODEV;
}
@@ -182,7 +181,7 @@ static int psp_check_sev_support(struct psp_device *psp)
static int psp_check_tee_support(struct psp_device *psp)
{
/* Check if device supports TEE feature */
- if (!PSP_CAPABILITY(psp, TEE)) {
+ if (!psp->capability.tee) {
dev_dbg(psp->dev, "psp does not support TEE\n");
return -ENODEV;
}
@@ -214,7 +213,7 @@ static int psp_init(struct psp_device *psp)

/* dbc must come after platform access as it tests the feature */
if (PSP_FEATURE(psp, DBC) ||
- PSP_CAPABILITY(psp, DBC_THRU_EXT)) {
+ psp->capability.dbc_thru_ext) {
ret = dbc_dev_init(psp);
if (ret)
return ret;
diff --git a/drivers/crypto/ccp/psp-dev.h b/drivers/crypto/ccp/psp-dev.h
index ae582ba63729..02a7c94c02df 100644
--- a/drivers/crypto/ccp/psp-dev.h
+++ b/drivers/crypto/ccp/psp-dev.h
@@ -26,6 +26,29 @@ extern struct psp_device *psp_master;

typedef void (*psp_irq_handler_t)(int, void *, unsigned int);

+union psp_cap_register {
+ unsigned int raw;
+ struct {
+ unsigned int sev :1,
+ tee :1,
+ dbc_thru_ext :1,
+ rsvd1 :4,
+ security_reporting :1,
+ fused_part :1,
+ rsvd2 :1,
+ debug_lock_on :1,
+ rsvd3 :2,
+ tsme_status :1,
+ rsvd4 :1,
+ anti_rollback_status :1,
+ rpmc_production_enabled :1,
+ rpmc_spirom_available :1,
+ hsp_tpm_available :1,
+ rom_armor_enforced :1,
+ rsvd5 :12;
+ };
+};
+
struct psp_device {
struct list_head entry;

@@ -46,7 +69,7 @@ struct psp_device {
void *platform_access_data;
void *dbc_data;

- unsigned int capability;
+ union psp_cap_register capability;
};

void psp_set_sev_irq_handler(struct psp_device *psp, psp_irq_handler_t handler,
@@ -55,26 +78,7 @@ void psp_clear_sev_irq_handler(struct psp_device *psp);

struct psp_device *psp_get_master_device(void);

-#define PSP_CAPABILITY_SEV BIT(0)
-#define PSP_CAPABILITY_TEE BIT(1)
-#define PSP_CAPABILITY_DBC_THRU_EXT BIT(2)
-#define PSP_CAPABILITY_PSP_SECURITY_REPORTING BIT(7)
-
#define PSP_CAPABILITY_PSP_SECURITY_OFFSET 8
-/*
- * The PSP doesn't directly store these bits in the capability register
- * but instead copies them from the results of query command.
- *
- * The offsets from the query command are below, and shifted when used.
- */
-#define PSP_SECURITY_FUSED_PART BIT(0)
-#define PSP_SECURITY_DEBUG_LOCK_ON BIT(2)
-#define PSP_SECURITY_TSME_STATUS BIT(5)
-#define PSP_SECURITY_ANTI_ROLLBACK_STATUS BIT(7)
-#define PSP_SECURITY_RPMC_PRODUCTION_ENABLED BIT(8)
-#define PSP_SECURITY_RPMC_SPIROM_AVAILABLE BIT(9)
-#define PSP_SECURITY_HSP_TPM_AVAILABLE BIT(10)
-#define PSP_SECURITY_ROM_ARMOR_ENFORCED BIT(11)

/**
* enum psp_cmd - PSP mailbox commands
diff --git a/drivers/crypto/ccp/sp-dev.h b/drivers/crypto/ccp/sp-dev.h
index 03d5b9e04084..c4e125efe6c7 100644
--- a/drivers/crypto/ccp/sp-dev.h
+++ b/drivers/crypto/ccp/sp-dev.h
@@ -30,7 +30,6 @@

#define PLATFORM_FEATURE_DBC 0x1

-#define PSP_CAPABILITY(psp, cap) (psp->capability & PSP_CAPABILITY_##cap)
#define PSP_FEATURE(psp, feat) (psp->vdata && psp->vdata->platform_features & PLATFORM_FEATURE_##feat)

/* Structure to hold CCP device data */
diff --git a/drivers/crypto/ccp/sp-pci.c b/drivers/crypto/ccp/sp-pci.c
index 300dda14182b..b57392292af1 100644
--- a/drivers/crypto/ccp/sp-pci.c
+++ b/drivers/crypto/ccp/sp-pci.c
@@ -39,31 +39,30 @@ struct sp_pci {
};
static struct sp_device *sp_dev_master;

-#define security_attribute_show(name, def) \
+#define security_attribute_show(name) \
static ssize_t name##_show(struct device *d, struct device_attribute *attr, \
char *buf) \
{ \
struct sp_device *sp = dev_get_drvdata(d); \
struct psp_device *psp = sp->psp_data; \
- int bit = PSP_SECURITY_##def << PSP_CAPABILITY_PSP_SECURITY_OFFSET; \
- return sysfs_emit(buf, "%d\n", (psp->capability & bit) > 0); \
+ return sysfs_emit(buf, "%d\n", psp->capability.name); \
}

-security_attribute_show(fused_part, FUSED_PART)
+security_attribute_show(fused_part)
static DEVICE_ATTR_RO(fused_part);
-security_attribute_show(debug_lock_on, DEBUG_LOCK_ON)
+security_attribute_show(debug_lock_on)
static DEVICE_ATTR_RO(debug_lock_on);
-security_attribute_show(tsme_status, TSME_STATUS)
+security_attribute_show(tsme_status)
static DEVICE_ATTR_RO(tsme_status);
-security_attribute_show(anti_rollback_status, ANTI_ROLLBACK_STATUS)
+security_attribute_show(anti_rollback_status)
static DEVICE_ATTR_RO(anti_rollback_status);
-security_attribute_show(rpmc_production_enabled, RPMC_PRODUCTION_ENABLED)
+security_attribute_show(rpmc_production_enabled)
static DEVICE_ATTR_RO(rpmc_production_enabled);
-security_attribute_show(rpmc_spirom_available, RPMC_SPIROM_AVAILABLE)
+security_attribute_show(rpmc_spirom_available)
static DEVICE_ATTR_RO(rpmc_spirom_available);
-security_attribute_show(hsp_tpm_available, HSP_TPM_AVAILABLE)
+security_attribute_show(hsp_tpm_available)
static DEVICE_ATTR_RO(hsp_tpm_available);
-security_attribute_show(rom_armor_enforced, ROM_ARMOR_ENFORCED)
+security_attribute_show(rom_armor_enforced)
static DEVICE_ATTR_RO(rom_armor_enforced);

static struct attribute *psp_security_attrs[] = {
@@ -84,7 +83,7 @@ static umode_t psp_security_is_visible(struct kobject *kobj, struct attribute *a
struct sp_device *sp = dev_get_drvdata(dev);
struct psp_device *psp = sp->psp_data;

- if (psp && PSP_CAPABILITY(psp, PSP_SECURITY_REPORTING))
+ if (psp && psp->capability.security_reporting)
return 0444;

return 0;
@@ -134,8 +133,7 @@ static umode_t psp_firmware_is_visible(struct kobject *kobj, struct attribute *a
psp->vdata->bootloader_info_reg)
val = ioread32(psp->io_regs + psp->vdata->bootloader_info_reg);

- if (attr == &dev_attr_tee_version.attr &&
- PSP_CAPABILITY(psp, TEE) &&
+ if (attr == &dev_attr_tee_version.attr && psp->capability.tee &&
psp->vdata->tee->info_reg)
val = ioread32(psp->io_regs + psp->vdata->tee->info_reg);

--
2.43.0


2024-05-28 21:10:14

by Mario Limonciello

[permalink] [raw]
Subject: [PATCH v2 5/5] crypto: ccp: Move message about TSME being enabled later in init

Some of the security attributes data is now populated from an HSTI
command on some processors, so show the message after it has been
populated.

Signed-off-by: Mario Limonciello <[email protected]>
---
v1->v2:
* Move code from patch 4
---
drivers/crypto/ccp/hsti.c | 15 +++++++++++++++
drivers/crypto/ccp/psp-dev.c | 8 --------
2 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/drivers/crypto/ccp/hsti.c b/drivers/crypto/ccp/hsti.c
index 8b99bbd4efe2..1b39a4fb55c0 100644
--- a/drivers/crypto/ccp/hsti.c
+++ b/drivers/crypto/ccp/hsti.c
@@ -119,5 +119,20 @@ int psp_init_hsti(struct psp_device *psp)
return ret;
}

+ /*
+ * At this stage, if security information hasn't been populated by
+ * either the PSP or by the driver through the platform command,
+ * then there is nothing more to do.
+ */
+ if (!psp->capability.security_reporting)
+ return 0;
+
+ if (psp->capability.tsme_status) {
+ if (cc_platform_has(CC_ATTR_HOST_MEM_ENCRYPT))
+ dev_notice(psp->dev, "psp: Both TSME and SME are active, SME is unnecessary when TSME is active.\n");
+ else
+ dev_notice(psp->dev, "psp: TSME enabled\n");
+ }
+
return 0;
}
diff --git a/drivers/crypto/ccp/psp-dev.c b/drivers/crypto/ccp/psp-dev.c
index 0a01ad134609..1c5a7189631e 100644
--- a/drivers/crypto/ccp/psp-dev.c
+++ b/drivers/crypto/ccp/psp-dev.c
@@ -157,14 +157,6 @@ static unsigned int psp_get_capability(struct psp_device *psp)
}
psp->capability.raw = val;

- /* Detect TSME and/or SME status */
- if (psp->capability.security_reporting && psp->capability.tsme_status) {
- if (cc_platform_has(CC_ATTR_HOST_MEM_ENCRYPT))
- dev_notice(psp->dev, "psp: Both TSME and SME are active, SME is unnecessary when TSME is active.\n");
- else
- dev_notice(psp->dev, "psp: TSME enabled\n");
- }
-
return 0;
}

--
2.43.0