diff options
Diffstat (limited to 'roms/skiboot/libstb/tss2/ibmtpm20tss/utils/tssfile.c')
-rw-r--r-- | roms/skiboot/libstb/tss2/ibmtpm20tss/utils/tssfile.c | 321 |
1 files changed, 321 insertions, 0 deletions
diff --git a/roms/skiboot/libstb/tss2/ibmtpm20tss/utils/tssfile.c b/roms/skiboot/libstb/tss2/ibmtpm20tss/utils/tssfile.c new file mode 100644 index 000000000..3c200d598 --- /dev/null +++ b/roms/skiboot/libstb/tss2/ibmtpm20tss/utils/tssfile.c @@ -0,0 +1,321 @@ +/********************************************************************************/ +/* */ +/* TSS and Application File Utilities */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* */ +/* (c) Copyright IBM Corporation 2015 - 2019 */ +/* */ +/* 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 <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> + +#include <ibmtss/tssresponsecode.h> +#include <ibmtss/tsserror.h> +#include <ibmtss/tssprint.h> +#include <ibmtss/tssfile.h> + +extern int tssVerbose; +extern int tssVverbose; + +/* TSS_File_Open() opens the 'filename' for 'mode' + */ + +int TSS_File_Open(FILE **file, + const char *filename, + const char* mode) +{ + int rc = 0; + + if (rc == 0) { + *file = fopen(filename, mode); + if (*file == NULL) { + if (tssVerbose) printf("TSS_File_Open: Error opening %s for %s, %s\n", + filename, mode, strerror(errno)); + rc = TSS_RC_FILE_OPEN; + } + } + return rc; +} + +/* TSS_File_ReadBinaryFile() reads 'filename'. The results are put into 'data', which must be freed + by the caller. 'length' indicates the number of bytes read. + +*/ + +TPM_RC TSS_File_ReadBinaryFile(unsigned char **data, /* must be freed by caller */ + size_t *length, + const char *filename) +{ + int rc = 0; + long lrc; + size_t src; + int irc; + FILE *file = NULL; + + *data = NULL; + *length = 0; + /* open the file */ + if (rc == 0) { + rc = TSS_File_Open(&file, filename, "rb"); /* closed @1 */ + } + /* determine the file length */ + if (rc == 0) { + irc = fseek(file, 0L, SEEK_END); /* seek to end of file */ + if (irc == -1L) { + if (tssVerbose) printf("TSS_File_ReadBinaryFile: Error seeking to end of %s\n", + filename); + rc = TSS_RC_FILE_SEEK; + } + } + if (rc == 0) { + lrc = ftell(file); /* get position in the stream */ + if (lrc == -1L) { + if (tssVerbose) printf("TSS_File_ReadBinaryFile: Error ftell'ing %s\n", filename); + rc = TSS_RC_FILE_FTELL; + } + else { + *length = (size_t)lrc; /* save the length */ + } + } + if (rc == 0) { + irc = fseek(file, 0L, SEEK_SET); /* seek back to the beginning of the file */ + if (irc == -1L) { + if (tssVerbose) printf("TSS_File_ReadBinaryFile: Error seeking to beginning of %s\n", + filename); + rc = TSS_RC_FILE_SEEK; + } + } + /* allocate a buffer for the actual data */ + if ((rc == 0) && (*length != 0)) { + rc = TSS_Malloc(data, *length); + } + /* read the contents of the file into the data buffer */ + if ((rc == 0) && *length != 0) { + src = fread(*data, 1, *length, file); + if (src != *length) { + if (tssVerbose) + printf("TSS_File_ReadBinaryFile: Error reading %s, %u bytes, got %lu\n", + filename, (unsigned int)*length, (unsigned long)src); + rc = TSS_RC_FILE_READ; + } + } + if (file != NULL) { + irc = fclose(file); /* @1 */ + if (irc != 0) { + if (tssVerbose) printf("TSS_File_ReadBinaryFile: Error closing %s\n", + filename); + rc = TSS_RC_FILE_CLOSE; + } + } + if (rc != 0) { + if (tssVerbose) printf("TSS_File_ReadBinaryFile: Error reading %s\n", filename); + free(*data); + *data = NULL; + } + return rc; +} + +/* TSS_File_WriteBinaryFile() writes 'data' of 'length' to 'filename' + */ + +TPM_RC TSS_File_WriteBinaryFile(const unsigned char *data, + size_t length, + const char *filename) +{ + long rc = 0; + size_t src; + int irc; + FILE *file = NULL; + + /* open the file */ + if (rc == 0) { + rc = TSS_File_Open(&file, filename, "wb"); /* closed @1 */ + } + /* write the contents of the data buffer into the file */ + if (rc == 0) { + src = fwrite(data, 1, length, file); + if (src != length) { + if (tssVerbose) + printf("TSS_File_WriteBinaryFile: Error writing %s, %lu bytes, got %lu\n", + filename, (unsigned long)length, (unsigned long)src); + rc = TSS_RC_FILE_WRITE; + } + } + if (file != NULL) { + irc = fclose(file); /* @1 */ + if (irc != 0) { + if (tssVerbose) printf("TSS_File_WriteBinaryFile: Error closing %s\n", + filename); + rc = TSS_RC_FILE_CLOSE; + } + } + return rc; +} + +/* TSS_File_ReadStructure() is a general purpose "read a structure" function. + + It reads the filename, and then unmarshals the structure using "unmarshalFunction". +*/ + +TPM_RC TSS_File_ReadStructure(void *structure, + UnmarshalFunction_t unmarshalFunction, + const char *filename) +{ + TPM_RC rc = 0; + uint8_t *buffer = NULL; /* for the free */ + uint8_t *buffer1 = NULL; /* for unmarshaling */ + size_t length = 0; + + if (rc == 0) { + rc = TSS_File_ReadBinaryFile(&buffer, /* freed @1 */ + &length, + filename); + } + if (rc == 0) { + uint32_t ilength = length; + buffer1 = buffer; + rc = unmarshalFunction(structure, &buffer1, &ilength); + } + free(buffer); /* @1 */ + return rc; +} + +/* TSS_File_ReadStructureFlag() is a general purpose "read a structure" function. + + It reads the filename, and then unmarshals the structure using "unmarshalFunction". + + It is similar to TSS_File_ReadStructure() but is used when the structure unmarshal function + requires the allowNull flag. +*/ + +TPM_RC TSS_File_ReadStructureFlag(void *structure, + UnmarshalFunctionFlag_t unmarshalFunction, + BOOL allowNull, + const char *filename) +{ + TPM_RC rc = 0; + uint8_t *buffer = NULL; /* for the free */ + uint8_t *buffer1 = NULL; /* for unmarshaling */ + size_t length = 0; + + if (rc == 0) { + rc = TSS_File_ReadBinaryFile(&buffer, /* freed @1 */ + &length, + filename); + } + if (rc == 0) { + uint32_t ilength = length; + buffer1 = buffer; + rc = unmarshalFunction(structure, &buffer1, &ilength, allowNull); + } + free(buffer); /* @1 */ + return rc; +} + +/* TSS_File_WriteStructure() is a general purpose "write a structure" function. + + It marshals the structure using "marshalFunction", and then writes it to filename. +*/ + +TPM_RC TSS_File_WriteStructure(void *structure, + MarshalFunction_t marshalFunction, + const char *filename) +{ + TPM_RC rc = 0; + uint16_t written = 0; + uint8_t *buffer = NULL; /* for the free */ + + if (rc == 0) { + rc = TSS_Structure_Marshal(&buffer, /* freed @1 */ + &written, + structure, + marshalFunction); + } + if (rc == 0) { + rc = TSS_File_WriteBinaryFile(buffer, + written, + filename); + } + free(buffer); /* @1 */ + return rc; +} + +/* TSS_File_Read2B() reads 'filename' and copies the data to 'tpm2b', checking targetSize + + */ + +TPM_RC TSS_File_Read2B(TPM2B *tpm2b, + uint16_t targetSize, + const char *filename) +{ + TPM_RC rc = 0; + uint8_t *buffer = NULL; + size_t length = 0; + + if (rc == 0) { + rc = TSS_File_ReadBinaryFile(&buffer, /* freed @1 */ + &length, + filename); + } + if (rc == 0) { + if (length > 0xffff) { /* overflow TPM2B uint16_t */ + if (tssVerbose) printf("TSS_File_Read2B: size %u greater than 0xffff\n", + (unsigned int)length); + rc = TSS_RC_INSUFFICIENT_BUFFER; + } + } + /* copy it into the TPM2B */ + if (rc == 0) { + rc = TSS_TPM2B_Create(tpm2b, buffer, (uint16_t)length, targetSize); + } + free(buffer); /* @1 */ + return rc; +} + +/* FIXME need to add - ignore failure if does not exist */ + +TPM_RC TSS_File_DeleteFile(const char *filename) +{ + TPM_RC rc = 0; + int irc; + + if (rc == 0) { + irc = remove(filename); + if (irc != 0) { + rc = TSS_RC_FILE_REMOVE; + } + } + return rc; +} |