[SLOF] [PATCH v3 2/2] tpm: Implement firmware API call pass-through-to-tpm
Stefan Berger
stefanb at linux.vnet.ibm.com
Tue Oct 29 23:49:34 AEDT 2024
From: Stefan Berger <stefanb at linux.ibm.com>
Implement the firmware API call pass-through-to-tpm that allows a caller
to pass a TPM command to the TPM. Since the buffer provided by the user
will be used for returning the TPM's response it must be sufficiently
large. To be safe, it should be of the size returned by the firmware API
call tpm-get-maximum-cmd-size.
Signed-off-by: Stefan Berger <stefanb at linux.ibm.com>
---
board-qemu/slof/vio-vtpm-cdriver.fs | 11 +++++++++++
lib/libtpm/tcgbios.c | 25 +++++++++++++++++++++++++
lib/libtpm/tcgbios.h | 1 +
lib/libtpm/tpm.code | 11 +++++++++++
lib/libtpm/tpm.in | 1 +
5 files changed, 49 insertions(+)
diff --git a/board-qemu/slof/vio-vtpm-cdriver.fs b/board-qemu/slof/vio-vtpm-cdriver.fs
index 21c2190..ced2ac0 100644
--- a/board-qemu/slof/vio-vtpm-cdriver.fs
+++ b/board-qemu/slof/vio-vtpm-cdriver.fs
@@ -57,6 +57,17 @@ LOG-SIZE BUFFER: log-base
THEN
;
+\ firmware API call
+: pass-through-to-tpm ( buf-addr cmd-size -- rsp-size )
+ vtpm-debug? IF
+ ." Call to pass-through-to-tpm" cr
+ THEN
+ tpm-pass-through-to-tpm ( rsp-size )
+ vtpm-debug? IF
+ ." VTPM: tpm-pass-through-to-tpm returned size: " dup . cr
+ THEN
+;
+
\ firmware API call
: get-maximum-cmd-size ( -- max-size )
vtpm-debug? IF
diff --git a/lib/libtpm/tcgbios.c b/lib/libtpm/tcgbios.c
index a64afde..366eda9 100644
--- a/lib/libtpm/tcgbios.c
+++ b/lib/libtpm/tcgbios.c
@@ -972,6 +972,31 @@ uint32_t tpm_get_maximum_cmd_size(void)
return PAPR_VTPM_MAX_BUFFER_SIZE;
}
+uint32_t tpm_pass_through_to_tpm(void *buffer, uint32_t cmd_size)
+{
+ unsigned char respbuffer[PAPR_VTPM_MAX_BUFFER_SIZE];
+ uint32_t respbufferlen = sizeof(respbuffer);
+ struct tpm_req_header *hdr = buffer;
+ uint32_t totlen;
+ int ret;
+
+ if (cmd_size < sizeof(struct tpm_req_header))
+ return 0;
+
+ memcpy(&totlen, &hdr->totlen, sizeof(totlen));
+ if (cmd_size != be32_to_cpu(totlen))
+ return 0;
+
+ ret = spapr_transmit(0, buffer, respbuffer, &respbufferlen,
+ TPM_DURATION_TYPE_LONG);
+ if (ret)
+ return 0;
+
+ memcpy(buffer, respbuffer, respbufferlen);
+
+ return respbufferlen;
+}
+
/*
* Add an EV_ACTION measurement to the list of measurements
*/
diff --git a/lib/libtpm/tcgbios.h b/lib/libtpm/tcgbios.h
index 83148e0..0e98e63 100644
--- a/lib/libtpm/tcgbios.h
+++ b/lib/libtpm/tcgbios.h
@@ -42,5 +42,6 @@ uint32_t tpm_2hash_ext_log(uint32_t pcrindex,
const char *info, uint32_t infolen,
const void *data, uint64_t datalen);
uint32_t tpm_get_maximum_cmd_size(void);
+uint32_t tpm_pass_through_to_tpm(void *buffer, uint32_t cmdsize);
#endif /* TCGBIOS_H */
diff --git a/lib/libtpm/tpm.code b/lib/libtpm/tpm.code
index 23075b8..27a87c9 100644
--- a/lib/libtpm/tpm.code
+++ b/lib/libtpm/tpm.code
@@ -216,3 +216,14 @@ PRIM(tpm_X2d_get_X2d_maximum_X2d_cmd_X2d_size)
PUSH;
TOS.u = tpm_get_maximum_cmd_size();
MIRP
+
+/****************************************************************************************/
+/* SLOF: tpm-pass-through-to-tpm ( buf-addr cmd-size -- rsp-size ) */
+/* LIBTPM: rsp_size = tpm-pass-through-to-tpm */
+/****************************************************************************************/
+PRIM(tpm_X2d_pass_X2d_through_X2d_to_X2d_tpm)
+ uint32_t cmd_size = TOS.u; POP;
+ void *buf = TOS.a;
+
+ TOS.u = tpm_pass_through_to_tpm(buf, cmd_size);
+MIRP
diff --git a/lib/libtpm/tpm.in b/lib/libtpm/tpm.in
index d76c479..b413a24 100644
--- a/lib/libtpm/tpm.in
+++ b/lib/libtpm/tpm.in
@@ -31,3 +31,4 @@ cod(tpm-measure-gpt)
cod(tpm-hash-log-extend-event-buffer)
cod(tpm-2hash-ext-log)
cod(tpm-get-maximum-cmd-size)
+cod(tpm-pass-through-to-tpm)
--
2.25.1
More information about the SLOF
mailing list