diff options
author | 2023-10-10 14:33:42 +0000 | |
---|---|---|
committer | 2023-10-10 14:33:42 +0000 | |
commit | af1a266670d040d2f4083ff309d732d648afba2a (patch) | |
tree | 2fc46203448ddcc6f81546d379abfaeb323575e9 /roms/skiboot/libstb/tss2/ibmtpm20tss/utils/tssdev.c | |
parent | e02cda008591317b1625707ff8e115a4841aa889 (diff) |
Change-Id: Iaf8d18082d3991dec7c0ebbea540f092188eb4ec
Diffstat (limited to 'roms/skiboot/libstb/tss2/ibmtpm20tss/utils/tssdev.c')
-rw-r--r-- | roms/skiboot/libstb/tss2/ibmtpm20tss/utils/tssdev.c | 213 |
1 files changed, 213 insertions, 0 deletions
diff --git a/roms/skiboot/libstb/tss2/ibmtpm20tss/utils/tssdev.c b/roms/skiboot/libstb/tss2/ibmtpm20tss/utils/tssdev.c new file mode 100644 index 000000000..affd9db01 --- /dev/null +++ b/roms/skiboot/libstb/tss2/ibmtpm20tss/utils/tssdev.c @@ -0,0 +1,213 @@ +/********************************************************************************/ +/* */ +/* Linux Device Transmit and Receive Utilities */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* */ +/* (c) Copyright IBM Corporation 2015 - 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. */ +/********************************************************************************/ + +#ifdef TPM_POSIX + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> +#include <errno.h> + +#include <unistd.h> +#include <fcntl.h> + +#include <ibmtss/tssresponsecode.h> +#include <ibmtss/tsserror.h> +#include <ibmtss/tssprint.h> +#include "tssproperties.h" + +#include "tssdev.h" + +/* local prototypes */ + +static uint32_t TSS_Dev_Open(TSS_CONTEXT *tssContext); +static uint32_t TSS_Dev_SendCommand(int dev_fd, const uint8_t *buffer, uint16_t length, + const char *message); +static uint32_t TSS_Dev_ReceiveResponse(int dev_fd, uint8_t *buffer, uint32_t *length); + +/* global configuration */ + +extern int tssVverbose; +extern int tssVerbose; + +/* TSS_Dev_Transmit() transmits the command and receives the response. + + 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 *read, + const uint8_t *commandBuffer, uint32_t written, + const char *message) +{ + TPM_RC rc = 0; + + /* open on first transmit */ + if (tssContext->tssFirstTransmit) { + if (rc == 0) { + rc = TSS_Dev_Open(tssContext); + } + if (rc == 0) { + tssContext->tssFirstTransmit = FALSE; + } + } + /* send the command to the device. Error if the device send fails. */ + if (rc == 0) { + rc = TSS_Dev_SendCommand(tssContext->dev_fd, commandBuffer, written, message); + } + /* receive the response from the dev_fd. Returns dev_fd errors, malformed response errors. + Else returns the TPM response code. */ + if (rc == 0) { + rc = TSS_Dev_ReceiveResponse(tssContext->dev_fd, responseBuffer, read); + } + return rc; +} + +/* TSS_Dev_Open() opens the TPM device (through the device driver) */ + +static uint32_t TSS_Dev_Open(TSS_CONTEXT *tssContext) +{ + uint32_t rc = 0; + + if (rc == 0) { + if (tssVverbose) printf("TSS_Dev_Open: Opening %s\n", tssContext->tssDevice); + tssContext->dev_fd = open(tssContext->tssDevice, O_RDWR); + if (tssContext->dev_fd < 0) { + if (tssVerbose) printf("TSS_Dev_Open: Error opening %s\n", tssContext->tssDevice); + rc = TSS_RC_NO_CONNECTION; + } + } + return rc; +} + +/* TSS_Dev_SendCommand() sends the TPM command buffer to the device. + + Returns an error if the device write fails. +*/ + +static uint32_t TSS_Dev_SendCommand(int dev_fd, + const uint8_t *buffer, uint16_t length, + const char *message) +{ + uint32_t rc = 0; + int irc; + + if (message != NULL) { + if (tssVverbose) printf("TSS_Dev_SendCommand: %s\n", message); + } + if ((rc == 0) && tssVverbose) { + TSS_PrintAll("TSS_Dev_SendCommand", + buffer, length); + } + if (rc == 0) { + irc = write(dev_fd, buffer, length); + if (irc < 0) { + if (tssVerbose) printf("TSS_Dev_SendCommand: write error %d %s\n", + errno, strerror(errno)); + rc = TSS_RC_BAD_CONNECTION; + } + } + return rc; +} + +/* TSS_Dev_ReceiveResponse() reads a response buffer from the device. 'buffer' must be at least + MAX_RESPONSE_SIZE bytes. + + Returns TPM packet error code. + + Validates that the packet length and the packet responseSize match +*/ + +static uint32_t TSS_Dev_ReceiveResponse(int dev_fd, uint8_t *buffer, uint32_t *length) +{ + uint32_t rc = 0; + int irc; /* read() return code, negative is error, positive is length */ + uint32_t responseSize = 0; /* from TPM packet response stream */ + + if (tssVverbose) printf("TSS_Dev_ReceiveResponse:\n"); + /* read the TPM device */ + if (rc == 0) { + irc = read(dev_fd, buffer, MAX_RESPONSE_SIZE); + if (irc <= 0) { + rc = TSS_RC_BAD_CONNECTION; + if (irc < 0) { + if (tssVerbose) printf("TSS_Dev_ReceiveResponse: read error %d %s\n", + errno, strerror(errno)); + } + } + } + /* read() is successful, trace the response */ + if ((rc == 0) && tssVverbose) { + TSS_PrintAll("TSS_Dev_ReceiveResponse", + buffer, irc); + } + /* verify that there is at least a tag, responseSize, and responseCode in TPM response */ + if (rc == 0) { + if ((unsigned int)irc < (sizeof(TPM_ST) + sizeof(uint32_t) + sizeof(uint32_t))) { + if (tssVerbose) printf("TSS_Dev_ReceiveResponse: read bytes %u < header\n", irc); + rc = TSS_RC_MALFORMED_RESPONSE; + } + } + /* get responseSize from the packet */ + if (rc == 0) { + responseSize = ntohl(*(uint32_t *)(buffer + sizeof(TPM_ST))); + /* sanity check against the length actually received, the return code */ + if ((uint32_t)irc != responseSize) { + if (tssVerbose) printf("TSS_Dev_ReceiveResponse: read bytes %u != responseSize %u\n", + (uint32_t)irc, responseSize); + rc = TSS_RC_MALFORMED_RESPONSE; + } + } + /* if there was no lower level failure, return the TPM packet responseCode */ + if (rc == 0) { + rc = ntohl(*(uint32_t *)(buffer + sizeof(TPM_ST)+ sizeof(uint32_t))); + } + *length = responseSize; + if (tssVverbose) printf("TSS_Dev_ReceiveResponse: rc %08x\n", rc); + return rc; +} + +TPM_RC TSS_Dev_Close(TSS_CONTEXT *tssContext) +{ + if (tssVverbose) printf("TSS_Dev_Close: Closing %s\n", tssContext->tssDevice); + close(tssContext->dev_fd); + return 0; +} + +#endif /* TPM_POSIX */ |