aboutsummaryrefslogtreecommitdiffstats
path: root/roms/skiboot/libstb/tss2/ibmtpm20tss/utils/tssdevskiboot.c
diff options
context:
space:
mode:
authorAngelos Mouzakitis <a.mouzakitis@virtualopensystems.com>2023-10-10 14:33:42 +0000
committerAngelos Mouzakitis <a.mouzakitis@virtualopensystems.com>2023-10-10 14:33:42 +0000
commitaf1a266670d040d2f4083ff309d732d648afba2a (patch)
tree2fc46203448ddcc6f81546d379abfaeb323575e9 /roms/skiboot/libstb/tss2/ibmtpm20tss/utils/tssdevskiboot.c
parente02cda008591317b1625707ff8e115a4841aa889 (diff)
Add submodule dependency filesHEADmaster
Change-Id: Iaf8d18082d3991dec7c0ebbea540f092188eb4ec
Diffstat (limited to 'roms/skiboot/libstb/tss2/ibmtpm20tss/utils/tssdevskiboot.c')
-rw-r--r--roms/skiboot/libstb/tss2/ibmtpm20tss/utils/tssdevskiboot.c195
1 files changed, 195 insertions, 0 deletions
diff --git a/roms/skiboot/libstb/tss2/ibmtpm20tss/utils/tssdevskiboot.c b/roms/skiboot/libstb/tss2/ibmtpm20tss/utils/tssdevskiboot.c
new file mode 100644
index 000000000..24d437985
--- /dev/null
+++ b/roms/skiboot/libstb/tss2/ibmtpm20tss/utils/tssdevskiboot.c
@@ -0,0 +1,195 @@
+/********************************************************************************/
+/* */
+/* Skiboot Transmit and Receive Utilities */
+/* */
+/* (c) Copyright IBM Corporation 2020. */
+/* */
+/* All rights reserved. */
+/* */
+/* Redistribution and use in source and binary forms, with or without */
+/* modification, are permitted provided that the following conditions are */
+/* met: */
+/* */
+/* Redistributions of source code must retain the above copyright notice, */
+/* this list of conditions and the following disclaimer. */
+/* */
+/* Redistributions in binary form must reproduce the above copyright */
+/* notice, this list of conditions and the following disclaimer in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* Neither the names of the IBM Corporation nor the names of its */
+/* contributors may be used to endorse or promote products derived from */
+/* this software without specific prior written permission. */
+/* */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
+/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
+/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */
+/* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
+/* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
+/* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */
+/* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */
+/* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
+/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */
+/* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
+/********************************************************************************/
+
+#include <string.h>
+
+#include <ibmtss/tssresponsecode.h>
+#include <ibmtss/Implementation.h>
+#include <ibmtss/tsserror.h>
+#include <ibmtss/tssprint.h>
+#include <tssproperties.h>
+
+#include <tssdev.h>
+#include <tpm_chip.h>
+
+/* global configuration */
+
+extern int tssVerbose;
+extern int tssVverbose;
+
+/*
+ * TSS_Dev_Transmit() transmits the command and receives the response in
+ * skiboot.
+ * Can return device transmit and receive packet errors, but normally returns
+ * the TPM response code.
+*/
+TPM_RC TSS_Dev_Transmit(TSS_CONTEXT *tssContext,
+ uint8_t *responseBuffer, uint32_t *length,
+ const uint8_t *commandBuffer, uint32_t written,
+ const char *message)
+{
+ TPM_RC rc = 0;
+ size_t responseSize;
+
+ /* skiboot driver's transmit function expects a size_t value as buffer
+ * length instead of uint32_t used in this function header, so this
+ * variable exists just for type compatibility.
+ */
+ size_t buffer_length;
+
+ if (message != NULL) {
+ if (tssVverbose) printf("TSS_Skiboot_Transmit: %s\n", message);
+ }
+ if ((rc == 0) && tssVverbose) {
+ TSS_PrintAll("TSS_Skiboot_Transmit: Command ",
+ commandBuffer, written);
+ }
+
+ /* we don't need to open a device as it is done in user space but we
+ * need to be sure a device and the driver are available for use.
+ */
+ if (rc == 0) {
+ if (tssContext->tssFirstTransmit) {
+ tssContext->tpm_device = tpm_get_device();
+ if (tssContext->tpm_device == NULL) {
+ if (tssVerbose)
+ printf("TSS_Skiboot_Transmit: TPM device not set\n");
+ rc = TSS_RC_NO_CONNECTION;
+ }
+ if (rc == 0) {
+ tssContext->tpm_driver = tpm_get_driver();
+ if (tssContext->tpm_driver == NULL) {
+ if (tssVerbose)
+ printf("TSS_Skiboot_Transmit: TPM driver not set\n");
+ rc = TSS_RC_NO_CONNECTION;
+ }
+ }
+ }
+ }
+
+ if (rc == 0 ) {
+ tssContext->tssFirstTransmit = FALSE;
+ }
+
+ /*
+ * Let's issue compilation issue if eventually MAX_COMMAND_SIZE becomes
+ * potentially greater than MAX_RESPONSE_SIZE
+ */
+#if MAX_COMMAND_SIZE > MAX_RESPONSE_SIZE
+#error "MAX_COMMAND_SIZE cannot be greater than MAX_RESPONSE_SIZE. Potential overflow on the buffer for Command and Response"
+#endif
+ if (rc == 0) {
+ if (written > MAX_RESPONSE_SIZE) {
+ if (tssVerbose)
+ printf("TSS_Skiboot_Transmit: Response Overflow. TPM wrote %u bytes, Max response size is %u ",
+ written, MAX_RESPONSE_SIZE);
+ rc = TSS_RC_BAD_CONNECTION;
+ }
+ }
+
+ /*
+ * the buffer used to send the command will be overwritten and store the
+ * response data after TPM execution. So here we copy the contents of
+ * commandBuffer to responseBuffer, using the latter to perform the
+ * operation and storing the response and keeping the former safe.
+ */
+ if (rc == 0) {
+ /*
+ * skiboot driver checks for overflow, so we need to share the
+ * max response size to length. In the response length will
+ * contain the length of the response buffer.
+ */
+ buffer_length = MAX_RESPONSE_SIZE;
+
+ memcpy(responseBuffer, commandBuffer, written);
+ rc = tssContext->tpm_driver->transmit(tssContext->tpm_device,
+ responseBuffer, written, &buffer_length);
+ /* now that we have buffer length set we save it to length so it
+ * can be used by the callers
+ */
+ *length = buffer_length;
+
+ if (rc != 0) {
+ if (tssVerbose)
+ printf("TSS_Skiboot_Transmit: receive error %u\n", rc);
+ rc = TSS_RC_BAD_CONNECTION;
+ }
+ }
+
+ if (rc == 0) {
+ if (tssVverbose)
+ TSS_PrintAll("TSS_Skiboot_Transmit: Response", responseBuffer, *length);
+
+ /* verify that there is at least a tag, responseSize, and responseCode */
+ if (*length < (sizeof(TPM_ST) + (2 * sizeof(uint32_t)))) {
+ if (tssVerbose)
+ printf("TSS_Skiboot_Transmit: received %u bytes < header\n", *length);
+ rc = TSS_RC_MALFORMED_RESPONSE;
+ }
+ }
+
+ /*
+ * length and the response size in the response body should match. Check
+ * it here.
+ */
+ if (rc == 0) {
+ responseSize = ntohl(*(uint32_t *)(responseBuffer + sizeof(TPM_ST)));
+ if (responseSize != *length) {
+ if (tssVerbose)
+ printf("TSS_Skiboot_Transmit: Bytes read (%u) and Buffer responseSize field (%lu) don't match\n",
+ *length, responseSize);
+ rc = TSS_RC_MALFORMED_RESPONSE;
+ }
+ }
+
+ /*
+ * Now we need to get the actual return code from the response buffer
+ * and deliver it to the upper layers
+ */
+ if (rc == 0)
+ rc = ntohl(*(uint32_t *)(responseBuffer + sizeof(TPM_ST) + sizeof(uint32_t)));
+
+ if (tssVverbose)
+ printf("TSS_Skiboot_Transmit: Response Code: %08x", rc);
+
+ return rc;
+}
+
+TPM_RC TSS_Dev_Close(TSS_CONTEXT *tssContext)
+{
+ tssContext = tssContext;
+ return 0;
+}