[Skiboot] [PATCH v2 17/20] hdata/tpmrel.c: add ibm, cvc device tree node

Claudio Carvalho cclaudio at linux.vnet.ibm.com
Sat Dec 9 15:52:31 AEDT 2017


In P9, the Container Verification Code is stored in a hostboot reserved
memory and the list of provided CVC services is stored in the
TPMREL_IDATA_HASH_VERIF_OFFSETS idata array. Each CVC service has an
offset and version.

This adds the ibm,cvc device tree node and its documentation.

Signed-off-by: Claudio Carvalho <cclaudio at linux.vnet.ibm.com>
---
 doc/device-tree/ibm,cvc.rst |  47 ++++++++++++++++++++
 hdata/spira.h               |  14 ++++++
 hdata/tpmrel.c              | 105 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 166 insertions(+)
 create mode 100644 doc/device-tree/ibm,cvc.rst

diff --git a/doc/device-tree/ibm,cvc.rst b/doc/device-tree/ibm,cvc.rst
new file mode 100644
index 0000000..c53df24
--- /dev/null
+++ b/doc/device-tree/ibm,cvc.rst
@@ -0,0 +1,47 @@
+.. _device-tree/ibm,cvc:
+
+ibm,cvc
+=======
+
+This describes the code (a.k.a container verification code) that skiboot uses
+to verify signed firmware blobs. Each ibm,cvc child node describes CVC service,
+which has a version and offset (reg).
+
+Added in the device tree from ``ibm,secureboot-v2``.
+
+Required properties
+-------------------
+
+.. code-block:: none
+
+   compatible:      should be "ibm,container-verification-code"
+
+   memory-region:   this points to the reserved memory where the
+                    container-verification-code is stored.
+
+Example
+-------
+
+.. code-block:: dts
+
+	ibm,cvc {
+		phandle = <0x10f>;
+		#address-cells = <0x1>;
+		#size-cells = <0x0>;
+		compatible = "ibm,container-verification-code";
+		memory-region = <0xaa>;
+
+		ibm,cvc-service at 40 {
+			phandle = <0x110>;
+			compatible = "ibm,cvc-sha512";
+			reg = <0x40>;
+			version = <0x1>;
+		};
+
+		ibm,cvc-service at 50 {
+			phandle = <0x111>;
+			compatible = "ibm,cvc-verify";
+			reg = <0x50>;
+			version = <0x1>;
+		};
+	};
diff --git a/hdata/spira.h b/hdata/spira.h
index e2d45ab..2ef13f3 100644
--- a/hdata/spira.h
+++ b/hdata/spira.h
@@ -529,6 +529,8 @@ struct msvpd_trace {
 /* Idata index 5: Hostboot reserved memory address range */
 #define MSVPD_IDATA_HB_RESERVED_MEM	5
 struct msvpd_hb_reserved_mem {
+#define MSVPD_HBRMEM_RANGE_TYPE	PPC_BITMASK32(0,7)
+#define HBRMEM_CONTAINER_VERIFICATION_CODE 	0x3
 	__be32		type_instance;
 	__be64		start_addr;
 	__be64		end_addr;
@@ -1259,6 +1261,18 @@ struct secureboot_tpm_info {
 	__be32 drtm_log_size;
 } __packed;
 
+/* Idata index 2: Hash and Verification Function Offsets Array */
+#define TPMREL_IDATA_HASH_VERIF_OFFSETS 	2
+
+struct hash_and_verification {
+#define TPMREL_HV_SHA512	0x00
+#define TPMREL_HV_VERIFY	0x01
+	__be32 type;
+	__be32 version;
+	__be32 dbob_id;
+	__be32 offset;
+} __packed;
+
 static inline const char *cpu_state(u32 flags)
 {
 	switch ((flags & CPU_ID_VERIFY_MASK) >> CPU_ID_VERIFY_SHIFT) {
diff --git a/hdata/tpmrel.c b/hdata/tpmrel.c
index 5b6731f..9b09765 100644
--- a/hdata/tpmrel.c
+++ b/hdata/tpmrel.c
@@ -102,6 +102,110 @@ static void tpmrel_add_firmware_event_log(const struct HDIF_common_hdr *hdif_hdr
 	}
 }
 
+static struct dt_node *get_hb_reserved_memory(const char *label)
+{
+	struct dt_node *node, *hb_reserved_mem;
+
+	hb_reserved_mem = dt_find_by_path(dt_root, "/ibm,hostboot/reserved-memory");
+	if (!hb_reserved_mem) {
+		prlog(PR_DEBUG, "/ibm,hostboot/reserved-memory node not found\n");
+		return NULL;
+	}
+
+	dt_for_each_node(hb_reserved_mem, node) {
+		const char *prd_label;
+		if (!dt_find_property(node, "ibm,prd-label"))
+			continue;
+		prd_label = dt_prop_get(node, "ibm,prd-label");
+		if (!strcmp(prd_label, label))
+			return node;
+	}
+	return NULL;
+}
+
+struct {
+	uint32_t type;
+	const char *compat;
+} cvc_services[] = {
+	{ TPMREL_HV_SHA512, "ibm,cvc-sha512" },
+	{ TPMREL_HV_VERIFY, "ibm,cvc-verify" },
+};
+
+static const char* cvc_service_map_compat(uint32_t type) {
+	int i;
+	for (i = 0; i < ARRAY_SIZE(cvc_services); i++) {
+		if (cvc_services[i].type == type)
+			return cvc_services[i].compat;
+	}
+	return NULL;
+}
+
+static void tpmrel_cvc_init(struct HDIF_common_hdr *hdif_hdr)
+{
+	struct dt_node *cvc_reserved_mem, *node, *parent;
+	int count, i;
+	unsigned int asize;
+
+	/* Are the hdat values populated? */
+	if (!HDIF_get_idata(hdif_hdr, TPMREL_IDATA_HASH_VERIF_OFFSETS, &asize))
+		return;
+	if (asize < sizeof(struct HDIF_array_hdr)) {
+		prlog(PR_ERR, "hash_and_verification idata not populated\n");
+		return;
+	}
+
+	node = dt_find_by_path(dt_root, "/ibm,secureboot");
+	if (!node)
+		return;
+
+	cvc_reserved_mem = get_hb_reserved_memory("ibm,secure-crypt-algo-code");
+	if (!cvc_reserved_mem) {
+		prlog(PR_ERR, "CVC reserved memory not found\n");
+		return;
+	}
+
+	parent = dt_new(node, "ibm,cvc");
+	assert(parent);
+	dt_add_property_cells(parent, "#address-cells", 1);
+	dt_add_property_cells(parent, "#size-cells", 0);
+	dt_add_property_strings(parent, "compatible", "ibm,container-verification-code");
+	dt_add_property_cells(parent, "memory-region", cvc_reserved_mem->phandle);
+
+	/*
+	 * Initialize each service provided by the container verification code
+	 */
+	count = HDIF_get_iarray_size(hdif_hdr, TPMREL_IDATA_HASH_VERIF_OFFSETS);
+	if (count <= 0 ) {
+		prlog(PR_ERR, "no CVC service found\n");
+		return;
+	}
+
+	for (i = 0; i < count; i++) {
+		const struct hash_and_verification *hv;
+		uint32_t type, offset, version;
+		const char *compat;
+
+		hv = HDIF_get_iarray_item(hdif_hdr,
+					  TPMREL_IDATA_HASH_VERIF_OFFSETS,
+					  i, NULL);
+		type = be32_to_cpu(hv->type);
+		offset = be32_to_cpu(hv->offset);
+		version = be32_to_cpu(hv->version);
+
+		compat = cvc_service_map_compat(type);
+
+		if (!compat) {
+			prlog(PR_WARNING, "CVC service type 0x%x unknown\n", type);
+			continue;
+		}
+
+		node = dt_new_addr(parent, "ibm,cvc-service", offset);
+		dt_add_property_strings(node, "compatible", compat);
+		dt_add_property_cells(node, "reg", offset);
+		dt_add_property_cells(node, "version", version);
+	}
+}
+
 void node_stb_parse(void)
 {
 	struct HDIF_common_hdr *hdif_hdr;
@@ -113,4 +217,5 @@ void node_stb_parse(void)
 	}
 
 	tpmrel_add_firmware_event_log(hdif_hdr);
+	tpmrel_cvc_init(hdif_hdr);
 }
-- 
2.7.4



More information about the Skiboot mailing list