[Skiboot] [PATCH 4/5] hdata/tpmrel.c: add the ibm, container-verification-code node
Claudio Carvalho
cclaudio at linux.vnet.ibm.com
Thu Aug 31 17:42:51 AEST 2017
In the secureboot-v2, the container verification code is stored in a
hostboot reserved memory.
This walks through the ms_vpd hdat structure to identify what hostboot
reserved memory the container verification code is stored in and then
creates the 'ibm,container-verification-code' node, which has a cross
reference (memory-region property) to that hostboot reserved memory.
Signed-off-by: Claudio Carvalho <cclaudio at linux.vnet.ibm.com>
---
hdata/spira.h | 3 ++
hdata/tpmrel.c | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 123 insertions(+), 2 deletions(-)
diff --git a/hdata/spira.h b/hdata/spira.h
index 0056887..d4c3023 100644
--- a/hdata/spira.h
+++ b/hdata/spira.h
@@ -529,6 +529,9 @@ 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_CVC_CONTAINER_V1 0x3
+#define MSVPD_HBRMEM_INSTANCE_NUMBER PPC_BITMASK32(8,31)
__be32 type_instance;
__be64 start_addr;
__be64 end_addr;
diff --git a/hdata/tpmrel.c b/hdata/tpmrel.c
index f2e2ec8..81e6443 100644
--- a/hdata/tpmrel.c
+++ b/hdata/tpmrel.c
@@ -20,6 +20,7 @@
#include <skiboot.h>
#include <device.h>
+#include <ccan/str/str.h>
#include "spira.h"
#include "hdata.h"
@@ -75,9 +76,121 @@ static void add_tpmrel_tpm_eventlog(const struct HDIF_common_hdr *hdif_hdr)
}
}
+struct hdat_container_verification_code {
+ uint32_t container_version;
+ uint32_t hb_reserved_mem_type;
+ uint32_t num_offsets;
+ const char *compat;
+};
+
+static struct hdat_container_verification_code cvc[] = {
+ /* ibm,secure-crypt-algo-code */
+ { 0x1, HBRMEM_CVC_CONTAINER_V1, 2, "ibm,container-v1-verification-code"}
+};
+
+static struct hdat_container_verification_code *map_cvc(uint32_t type)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(cvc); i++) {
+ if (cvc[i].hb_reserved_mem_type == type)
+ return &cvc[i];
+ }
+ return NULL;
+}
+
+#define HRMOR_BIT (1ul << 63)
+
+static struct dt_node *get_reserved_memory(const struct msvpd_hb_reserved_mem *hb_resv_mem)
+{
+ struct dt_node *node;
+ uint64_t start_addr, end_addr;
+ const char *reserved = "/ibm,hostboot/reserved-memory/";
+ char *path;
+ size_t len;
+
+ start_addr = be64_to_cpu(hb_resv_mem->start_addr);
+ end_addr = be64_to_cpu(hb_resv_mem->end_addr);
+
+ start_addr &= ~HRMOR_BIT;
+ end_addr &= ~HRMOR_BIT;
+
+ len = strlen(reserved) + strlen(hb_resv_mem->label) +
+ STR_MAX_CHARS(start_addr) + 2;
+ path = malloc(len);
+ assert(path);
+ snprintf(path, len, "%s%s@%llx", reserved,
+ hb_resv_mem->label, (long long) start_addr);
+ node = dt_find_by_path(dt_root, path);
+ free(path);
+
+ return node;
+}
+
+static void cvc_init(struct dt_node *parent)
+{
+ const struct msvpd_hb_reserved_mem *hb_resv_mem;
+ const struct HDIF_common_hdr *ms_vpd;
+ struct hdat_container_verification_code *cvc;
+ uint32_t type;
+ int count, i;
+
+ ms_vpd = get_hdif(&spira.ntuples.ms_vpd, MSVPD_HDIF_SIG);
+
+ if (!ms_vpd) {
+ prerror("TPMREL: MS VPD invalid\n");
+ return;
+ }
+
+ count = HDIF_get_iarray_size(ms_vpd, MSVPD_IDATA_HB_RESERVED_MEM);
+ if (count <= 0) {
+ prerror("TPMREL: No hostboot reserved memory found\n");
+ return;
+ }
+ /*
+ * The secureboot container verification code is stored in a hosboot
+ * reserved memory. We walk through the hostboot reserved memory nodes
+ * to find it.
+ *
+ * Once we find the container verification code we create a new node
+ * with a cross reference to its reserved memory.
+ */
+ for (i = 0; i < count; i++) {
+ hb_resv_mem = HDIF_get_iarray_item(ms_vpd,
+ MSVPD_IDATA_HB_RESERVED_MEM,
+ i, NULL);
+ if (!CHECK_SPPTR(hb_resv_mem))
+ continue;
+
+ type = be32_to_cpu(hb_resv_mem->type_instance);
+ type = GETFIELD(MSVPD_HBRMEM_RANGE_TYPE, type);
+ cvc = map_cvc(type);
+ if (cvc) {
+ struct dt_node *reserved_mem, *node;
+
+ reserved_mem= get_reserved_memory(hb_resv_mem);
+ if (!reserved_mem) {
+ prlog(PR_INFO, "reserved memory for %s not found\n",
+ cvc->compat);
+ return;
+ }
+
+ node = dt_new(parent, "ibm,container-verification-code");
+ assert(node);
+
+ dt_add_property_cells(node, "#address-cells", 1);
+ dt_add_property_cells(node, "#size-cells", 0);
+ dt_add_property_strings(node, "compatible", cvc->compat);
+ dt_add_property_cells(node, "memory-region", reserved_mem->phandle);
+ }
+ }
+ return;
+}
+
void node_stb_parse(void)
{
struct HDIF_common_hdr *hdif_hdr;
+ struct dt_node *node;
hdif_hdr = get_hdif(&spira.ntuples.node_stb_data, "TPMREL");
if (!hdif_hdr) {
@@ -87,6 +200,11 @@ void node_stb_parse(void)
add_tpmrel_tpm_eventlog(hdif_hdr);
- /* TODO: Idata 1: User Physical Interaction Mechanism Info */
- /* TODO: Idata 2: Hash and Verification Function Offset Array */
+ node = dt_find_by_path(dt_root, "/ibm,secureboot");
+ if (!node) {
+ prlog(PR_INFO, "'ibm,secureboot' node not found\n");
+ return;
+ }
+
+ cvc_init(node);
}
--
2.7.4
More information about the Skiboot
mailing list