|
|
b400a6 |
From 26970c42bc017ad68b864e7134cf941c07443aa8 Mon Sep 17 00:00:00 2001
|
|
|
b400a6 |
From: Chris Engel <cengel@linux.vnet.ibm.com>
|
|
|
b400a6 |
Date: Tue, 22 Aug 2017 14:59:06 -0500
|
|
|
b400a6 |
Subject: [PATCH] Interface for ibm,physical-attestation rtas call
|
|
|
b400a6 |
|
|
|
b400a6 |
The physical attestation interfaces are provided to allow a
|
|
|
b400a6 |
trusted 3rd party client to retrieve information about the
|
|
|
b400a6 |
trusted boot state of the target PowerVM system. This makes
|
|
|
b400a6 |
use of the systems physical TPM(s). These TPM(s) are used
|
|
|
b400a6 |
by system firmware to extend measurements during the
|
|
|
b400a6 |
boot process.
|
|
|
b400a6 |
|
|
|
b400a6 |
Signed-off-by: Chris Engel <cengel@linux.vnet.ibm.com>
|
|
|
b400a6 |
Reviewed-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
|
|
|
b400a6 |
Signed-off-by: Tyrel Datwyler <tyreld@linux.vnet.ibm.com>
|
|
|
b400a6 |
---
|
|
|
b400a6 |
librtas_src/librtas.h | 2 ++
|
|
|
b400a6 |
librtas_src/syscall_calls.c | 63 +++++++++++++++++++++++++++++++++++++++++++++
|
|
|
b400a6 |
2 files changed, 65 insertions(+)
|
|
|
b400a6 |
|
|
|
b400a6 |
diff --git a/librtas_src/librtas.h b/librtas_src/librtas.h
|
|
|
b400a6 |
index ccab3d9..b84fab1 100644
|
|
|
b400a6 |
--- a/librtas_src/librtas.h
|
|
|
b400a6 |
+++ b/librtas_src/librtas.h
|
|
|
b400a6 |
@@ -105,6 +105,8 @@ extern int rtas_set_time(uint32_t year, uint32_t month, uint32_t day,
|
|
|
b400a6 |
extern int rtas_suspend_me(uint64_t streamid);
|
|
|
b400a6 |
extern int rtas_update_nodes(char *workarea, unsigned int scope);
|
|
|
b400a6 |
extern int rtas_update_properties(char *workarea, unsigned int scope);
|
|
|
b400a6 |
+extern int rtas_physical_attestation(char *workarea, int seq_num,
|
|
|
b400a6 |
+ int *next_seq_num, int *work_area_bytes);
|
|
|
b400a6 |
|
|
|
b400a6 |
#ifdef __cplusplus
|
|
|
b400a6 |
}
|
|
|
b400a6 |
diff --git a/librtas_src/syscall_calls.c b/librtas_src/syscall_calls.c
|
|
|
b400a6 |
index a194e4b..35b6d66 100644
|
|
|
b400a6 |
--- a/librtas_src/syscall_calls.c
|
|
|
b400a6 |
+++ b/librtas_src/syscall_calls.c
|
|
|
b400a6 |
@@ -1329,3 +1329,66 @@ int rtas_update_properties(char *workarea, unsigned int scope)
|
|
|
b400a6 |
dbg("(%p) %d = %d\n", workarea, scope, rc ? rc : status);
|
|
|
b400a6 |
return rc ? rc : status;
|
|
|
b400a6 |
}
|
|
|
b400a6 |
+
|
|
|
b400a6 |
+/**
|
|
|
b400a6 |
+ * rtas_physical_attestation
|
|
|
b400a6 |
+ * @brief Interface for ibm,physical-attestation rtas call.
|
|
|
b400a6 |
+ *
|
|
|
b400a6 |
+ * @param workarea input/output work area for rtas call
|
|
|
b400a6 |
+ * @param seq_num sequence number of the rtas call
|
|
|
b400a6 |
+ * @param next_seq_num next sequence number
|
|
|
b400a6 |
+ * @param work_area_bytes size of work area
|
|
|
b400a6 |
+ * @return 0 on success, !0 on failure
|
|
|
b400a6 |
+ */
|
|
|
b400a6 |
+int rtas_physical_attestation(char *workarea, int seq_num, int *next_seq_num,
|
|
|
b400a6 |
+ int *work_area_bytes)
|
|
|
b400a6 |
+{
|
|
|
b400a6 |
+ uint32_t workarea_pa;
|
|
|
b400a6 |
+ uint64_t elapsed = 0;
|
|
|
b400a6 |
+ void *kernbuf;
|
|
|
b400a6 |
+ int kbuf_sz = 4096;
|
|
|
b400a6 |
+ int rc, status;
|
|
|
b400a6 |
+ int resp_bytes = *work_area_bytes;
|
|
|
b400a6 |
+
|
|
|
b400a6 |
+ rc = sanity_check();
|
|
|
b400a6 |
+ if (rc)
|
|
|
b400a6 |
+ return rc;
|
|
|
b400a6 |
+
|
|
|
b400a6 |
+ /* Caller provided more data than FW can handle */
|
|
|
b400a6 |
+ if (*work_area_bytes == 0 ||
|
|
|
b400a6 |
+ *work_area_bytes > kbuf_sz)
|
|
|
b400a6 |
+ return RTAS_IO_ASSERT;
|
|
|
b400a6 |
+
|
|
|
b400a6 |
+ rc = rtas_get_rmo_buffer(kbuf_sz, &kernbuf, &workarea_pa);
|
|
|
b400a6 |
+ if (rc)
|
|
|
b400a6 |
+ return rc;
|
|
|
b400a6 |
+ memcpy(kernbuf, workarea, *work_area_bytes);
|
|
|
b400a6 |
+
|
|
|
b400a6 |
+ do {
|
|
|
b400a6 |
+ rc = rtas_call("ibm,physical-attestation", 3, 3,
|
|
|
b400a6 |
+ htobe32(workarea_pa), htobe32(kbuf_sz),
|
|
|
b400a6 |
+ htobe32(seq_num),
|
|
|
b400a6 |
+ &status, next_seq_num, &resp_bytes);
|
|
|
b400a6 |
+ if (rc < 0)
|
|
|
b400a6 |
+ break;
|
|
|
b400a6 |
+
|
|
|
b400a6 |
+ rc = handle_delay(status, &elapsed);
|
|
|
b400a6 |
+ } while (rc == CALL_AGAIN);
|
|
|
b400a6 |
+
|
|
|
b400a6 |
+ *next_seq_num = be32toh(*next_seq_num);
|
|
|
b400a6 |
+
|
|
|
b400a6 |
+ /* FW returned more data than we can handle */
|
|
|
b400a6 |
+ if (be32toh(resp_bytes) > *work_area_bytes) {
|
|
|
b400a6 |
+ (void)rtas_free_rmo_buffer(kernbuf, workarea_pa, kbuf_sz);
|
|
|
b400a6 |
+ return RTAS_IO_ASSERT;
|
|
|
b400a6 |
+ }
|
|
|
b400a6 |
+
|
|
|
b400a6 |
+ *work_area_bytes = be32toh(resp_bytes);
|
|
|
b400a6 |
+
|
|
|
b400a6 |
+ if (rc == 0)
|
|
|
b400a6 |
+ memcpy(workarea, kernbuf, *work_area_bytes);
|
|
|
b400a6 |
+
|
|
|
b400a6 |
+ (void)rtas_free_rmo_buffer(kernbuf, workarea_pa, kbuf_sz);
|
|
|
b400a6 |
+
|
|
|
b400a6 |
+ return rc ? rc : status;
|
|
|
b400a6 |
+}
|
|
|
b400a6 |
--
|
|
|
b400a6 |
2.9.5
|
|
|
b400a6 |
|