diff options
Diffstat (limited to 'TPM2-Plugin/lib/files.c')
-rw-r--r-- | TPM2-Plugin/lib/files.c | 640 |
1 files changed, 0 insertions, 640 deletions
diff --git a/TPM2-Plugin/lib/files.c b/TPM2-Plugin/lib/files.c deleted file mode 100644 index b28a225..0000000 --- a/TPM2-Plugin/lib/files.c +++ /dev/null @@ -1,640 +0,0 @@ -//**********************************************************************; -// Copyright (c) 2017, Intel Corporation -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// 2. 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. -// -// 3. Neither the name of Intel 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 <errno.h> -#include <inttypes.h> -#include <stdbool.h> -#include <stdio.h> -#include <string.h> - -#include <tss2/tss2_sys.h> -#include <tss2/tss2_mu.h> - -#include "files.h" -#include "log.h" -#include "tpm2_util.h" - -bool files_get_file_size(FILE *fp, unsigned long *file_size, const char *path) { - - long current = ftell(fp); - if (current < 0) { - if (path) { - LOG_ERR("Error getting current file offset for file \"%s\" error: %s", path, strerror(errno)); - } - return false; - } - - int rc = fseek(fp, 0, SEEK_END); - if (rc < 0) { - if (path) { - LOG_ERR("Error seeking to end of file \"%s\" error: %s", path, strerror(errno)); - } - return false; - } - - long size = ftell(fp); - if (size < 0) { - if (path) { - LOG_ERR("ftell on file \"%s\" failed: %s", path, strerror(errno)); - } - return false; - } - - rc = fseek(fp, current, SEEK_SET); - if (rc < 0) { - if (path) { - LOG_ERR("Could not restore initial stream position for file \"%s\" failed: %s", path, strerror(errno)); - } - return false; - } - - /* size cannot be negative at this point */ - *file_size = (unsigned long)size; - return true; -} - -static bool read_bytes_from_file(FILE *f, UINT8 *buf, UINT16 *size, - const char *path) { - unsigned long file_size; - bool result = files_get_file_size(f, &file_size, path); - if (!result) { - /* get_file_size() logs errors */ - return false; - } - - /* max is bounded on UINT16 */ - if (file_size > *size) { - if (path) { - LOG_ERR( - "File \"%s\" size is larger than buffer, got %lu expected less than %u", - path, file_size, *size); - } - return false; - } - - result = files_read_bytes(f, buf, file_size); - if (!result) { - if (path) { - LOG_ERR("Could not read data from file \"%s\"", path); - } - return false; - } - - *size = file_size; - - return true; -} - -bool files_load_bytes_from_path(const char *path, UINT8 *buf, UINT16 *size) { - if (!buf || !size || !path) { - return false; - } - - FILE *f = fopen(path, "rb"); - if (!f) { - LOG_ERR("Could not open file \"%s\" error %s", path, strerror(errno)); - return false; - } - - bool result = read_bytes_from_file(f, buf, size, path); - - fclose(f); - return result; -} - -bool files_save_bytes_to_file(const char *path, UINT8 *buf, UINT16 size) { - - if (!path || !buf) { - return false; - } - - FILE *fp = fopen(path, "wb+"); - if (!fp) { - LOG_ERR("Could not open file \"%s\", error: %s", path, strerror(errno)); - return false; - } - - bool result = files_write_bytes(fp, buf, size); - if (!result) { - LOG_ERR("Could not write data to file \"%s\"", path); - } - fclose(fp); - return result; -} - -/* - * Current version to write TPMS_CONTEXT to disk. - */ -#define CONTEXT_VERSION 1 - -bool files_save_tpm_context_to_file(TSS2_SYS_CONTEXT *sysContext, TPM2_HANDLE handle, - FILE *stream) { - - TPMS_CONTEXT context; - - TSS2_RC rval = Tss2_Sys_ContextSave(sysContext, handle, &context); - if (rval != TPM2_RC_SUCCESS) { - LOG_PERR(Tss2_Sys_ContextSave, rval); - return false; - } - - /* - * Saving the TPMS_CONTEXT structure to disk, format: - * TPM2.0-TOOLS HEADER - * U32 hiearchy - * U32 savedHandle - * U64 sequence - * U16 contextBlobLength - * BYTE[] contextBlob - */ - bool result = files_write_header(stream, CONTEXT_VERSION); - if (!result) { - LOG_ERR("Could not write context file header"); - goto out; - } - - // UINT32 - result = files_write_32(stream, context.hierarchy); - if (!result) { - LOG_ERR("Could not write hierarchy"); - goto out; - } - - result = files_write_32(stream, context.savedHandle); - if (!result) { - LOG_ERR("Could not write savedHandle"); - goto out; - } - - // UINT64 - result = files_write_64(stream, context.sequence); - if (!result) { - LOG_ERR("Could not write sequence"); - goto out; - } - - // U16 LENGTH - result = files_write_16(stream, context.contextBlob.size); - if (!result) { - LOG_ERR("Could not write contextBob size"); - goto out; - } - - // BYTE[] contextBlob - result = files_write_bytes(stream, context.contextBlob.buffer, - context.contextBlob.size); - if (!result) { - LOG_ERR("Could not write contextBlob buffer"); - } - /* result is set by file_write_bytes() */ - -out: - return result; -} - -bool files_save_tpm_context_to_path(TSS2_SYS_CONTEXT *sysContext, TPM2_HANDLE handle, - const char *path) { - - FILE *f = fopen(path, "w+b"); - if (!f) { - LOG_ERR("Error opening file \"%s\" due to error: %s", path, - strerror(errno)); - return false; - } - - bool result = files_save_tpm_context_to_file(sysContext, handle, f); - fclose(f); - return result; -} - - -bool files_load_tpm_context_from_file(TSS2_SYS_CONTEXT *sapi_context, - TPM2_HANDLE *handle, FILE *fstream) { - - TSS2_RC rval; - - /* - * Reading the TPMS_CONTEXT structure to disk, format: - * TPM2.0-TOOLS HEADER - * U32 hiearchy - * U32 savedHandle - * U64 sequence - * U16 contextBlobLength - * BYTE[] contextBlob - */ - UINT32 version; - TPMS_CONTEXT context; - bool result = files_read_header(fstream, &version); - if (!result) { - LOG_WARN( - "The loaded tpm context does not appear to be in the proper format," - "assuming old format, this will be converted on the next save."); - rewind(fstream); - result = files_read_bytes(fstream, (UINT8 *) &context, sizeof(context)); - if (!result) { - LOG_ERR("Could not load tpm context file"); - goto out; - } - /* Success load the context into the TPM */ - goto load_to_tpm; - } - - if (version != CONTEXT_VERSION) { - LOG_ERR("Unsupported context file format version found, got: %"PRIu32, - version); - result = false; - goto out; - } - - result = files_read_32(fstream, &context.hierarchy); - if (!result) { - LOG_ERR("Error reading hierarchy!"); - goto out; - } - - result = files_read_32(fstream, &context.savedHandle); - if (!result) { - LOG_ERR("Error reading savedHandle!"); - goto out; - } - - result = files_read_64(fstream, &context.sequence); - if (!result) { - LOG_ERR("Error reading sequence!"); - goto out; - } - - result = files_read_16(fstream, &context.contextBlob.size); - if (!result) { - LOG_ERR("Error reading contextBlob.size!"); - goto out; - } - - if (context.contextBlob.size > sizeof(context.contextBlob.buffer)) { - LOG_ERR( - "Size mismatch found on contextBlob, got %"PRIu16" expected less than or equal to %zu", - context.contextBlob.size, - sizeof(context.contextBlob.buffer)); - result = false; - goto out; - } - - result = files_read_bytes(fstream, context.contextBlob.buffer, - context.contextBlob.size); - if (!result) { - LOG_ERR("Error reading contextBlob.size!"); - goto out; - } - -load_to_tpm: - rval = Tss2_Sys_ContextLoad(sapi_context, &context, handle); - if (rval != TPM2_RC_SUCCESS) { - LOG_PERR(Tss2_Sys_ContextLoad, rval); - result = false; - goto out; - } - - result = true; - -out: - return result; -} - -bool files_load_tpm_context_from_path(TSS2_SYS_CONTEXT *sapi_context, - TPM2_HANDLE *handle, const char *path) { - - FILE *f = fopen(path, "rb"); - if (!f) { - LOG_ERR("Error opening file \"%s\" due to error: %s", path, - strerror(errno)); - return false; - } - - bool result = files_load_tpm_context_from_file(sapi_context, handle, f); - - fclose(f); - return result; -} - -bool files_does_file_exist(const char *path) { - - if (!path) { - LOG_ERR("Path cannot be NULL"); - return false; - } - - FILE *fp = fopen(path,"rb"); - if (fp) { - fclose(fp); - LOG_ERR("Path: %s already exists. Please rename or delete the file!", - path); - return true; - } - return false; -} - -bool files_get_file_size_path(const char *path, unsigned long *file_size) { - - bool result = false; - - if (!path) { - LOG_ERR("Must specify a path argument, cannot be NULL!"); - return false; - } - - if (!file_size) { - LOG_ERR("Must specify a file size argument, cannot be NULL!"); - return false; - } - - FILE *fp = fopen(path,"rb"); - if(!fp) { - LOG_ERR("Could not open file: \"%s\" error: %s", path, strerror(errno)); - return false; - } - - result = files_get_file_size(fp, file_size, path); - - fclose(fp); - return result; -} - -/** - * This is the magic for the file header. The header is organized - * as a big endian U32 (BEU32) of MAGIC followed by a BEU32 of the - * version number. Tools can define their own, individual file - * formats as they make sense, but they should always have the header. - */ -static const UINT32 MAGIC = 0xBADCC0DE; - -/** - * Writes size bytes to a file, continuing on EINTR short writes. - * @param f - * The file to write to. - * @param data - * The data to write. - * @param size - * The size, in bytes, of that data. - * @return - * True on success, False otherwise. - */ -static bool writex(FILE *f, UINT8 *data, size_t size) { - - size_t wrote = 0; - size_t index = 0; - do { - wrote = fwrite(&data[index], 1, size, f); - if (wrote != size) { - if (errno != EINTR) { - return false; - } - /* continue on EINTR */ - } - size -= wrote; - index += wrote; - } while (size > 0); - - return true; -} - -/** - * Reads size bytes from a file, continuing on EINTR short reads. - * @param f - * The file to read from. - * @param data - * The data buffer to read into. - * @param size - * The size of the buffer, which is also the amount of bytes to read. - * @return - * True on success, False otherwise. - */ -static bool readx(FILE *f, UINT8 *data, size_t size) { - - size_t bread = 0; - size_t index = 0; - do { - bread = fread(&data[index], 1, size, f); - if (bread != size) { - if (feof(f) || (errno != EINTR)) { - return false; - } - /* continue on EINTR */ - } - size -= bread; - index += bread; - } while (size > 0); - - return true; -} - -#define BAIL_ON_NULL(param, x) \ - do { \ - if (!x) { \ - LOG_ERR(param" must be specified"); \ - return false; \ - } \ - } while(0) - -#define BE_CONVERT(value, size) \ - do { \ - if (!tpm2_util_is_big_endian()) { \ - value = tpm2_util_endian_swap_##size(value); \ - } \ - } while (0) - -#define FILE_WRITE(size) \ - bool files_write_##size(FILE *out, UINT##size data) { \ - BAIL_ON_NULL("FILE", out); \ - BE_CONVERT(data, size); \ - return writex(out, (UINT8 *)&data, sizeof(data)); \ - } - -#define FILE_READ(size) \ - bool files_read_##size(FILE *out, UINT##size *data) { \ - BAIL_ON_NULL("FILE", out); \ - BAIL_ON_NULL("data", data); \ - bool res = readx(out, (UINT8 *)data, sizeof(*data)); \ - if (res) { \ - BE_CONVERT(*data, size); \ - } \ - return res; \ - } - -/* - * all the files_read|write_bytes_16|32|64 functions - */ -FILE_READ(16); -FILE_WRITE(16) - -FILE_READ(32); -FILE_WRITE(32) - -FILE_READ(64) -FILE_WRITE(64) - -bool files_read_bytes(FILE *out, UINT8 bytes[], size_t len) { - - BAIL_ON_NULL("FILE", out); - BAIL_ON_NULL("bytes", bytes); - return readx(out, bytes, len); -} - -bool files_write_bytes(FILE *out, uint8_t bytes[], size_t len) { - - BAIL_ON_NULL("FILE", out); - BAIL_ON_NULL("bytes", bytes); - return writex(out, bytes, len); -} - -bool files_write_header(FILE *out, UINT32 version) { - - BAIL_ON_NULL("FILE", out); - - bool res = files_write_32(out, MAGIC); - if (!res) { - return false; - } - return files_write_32(out, version); -} - -bool files_read_header(FILE *out, uint32_t *version) { - - BAIL_ON_NULL("FILE", out); - BAIL_ON_NULL("version", version); - - UINT32 magic; - bool res = files_read_32(out, &magic); - if (!res) { - return false; - } - - if (magic != MAGIC) { - LOG_ERR("Found magic 0x%x did not match expected magic of 0x%x!", - magic, MAGIC); - return false; - } - - return files_read_32(out, version); -} - -bool files_load_bytes_from_file_or_stdin(const char *path, UINT16 *size, BYTE *buf) { - - FILE *file = path ? fopen(path, "rb") : stdin; - path = file != stdin ? path : "<stdin>"; - if (!file) { - LOG_ERR("Could not open file: \"%s\", error: %s", path, - strerror(errno)); - return false; - } - - /* - * Attempt to accurately read the file based on the file size. - * This may fail on stdin when it's a pipe. - */ - if (file == stdin) { - path = NULL; - } - - UINT16 original_size = *size; - bool res = files_load_bytes_from_path(path, buf, - size); - if (!res) { - res = true; - *size = fread(buf, 1, - *size, file); - if (!feof(file)) { - LOG_ERR("Data to be sealed larger than expected. Got %u expected %u", - original_size, res); - res = false; - } - else if (ferror(file)) { - LOG_ERR("Error reading sealed data from \"<stdin>\""); - res = false; - } - } - - if (file != stdin) { - fclose(file); - } - - return res; -} - -#define SAVE_TYPE(type, name) \ - bool files_save_##name(type *name, const char *path) { \ - \ - size_t offset = 0; \ - UINT8 buffer[sizeof(*name)]; \ - TSS2_RC rc = Tss2_MU_##type##_Marshal(name, buffer, sizeof(buffer), &offset); \ - if (rc != TSS2_RC_SUCCESS) { \ - LOG_ERR("Error serializing "str(name)" structure: 0x%x", rc); \ - return false; \ - } \ - \ - return files_save_bytes_to_file(path, buffer, offset); \ - } - -#define LOAD_TYPE(type, name) \ - bool files_load_##name(const char *path, type *name) { \ - \ - UINT8 buffer[sizeof(*name)]; \ - UINT16 size = sizeof(buffer); \ - bool res = files_load_bytes_from_path(path, buffer, &size); \ - if (!res) { \ - return false; \ - } \ - \ - size_t offset = 0; \ - TSS2_RC rc = Tss2_MU_##type##_Unmarshal(buffer, size, &offset, name); \ - if (rc != TSS2_RC_SUCCESS) { \ - LOG_ERR("Error serializing "str(name)" structure: 0x%x", rc); \ - return false; \ - } \ - \ - return rc == TPM2_RC_SUCCESS; \ - } - -SAVE_TYPE(TPM2B_PUBLIC, public) -LOAD_TYPE(TPM2B_PUBLIC, public) - -SAVE_TYPE(TPMT_SIGNATURE, signature) -LOAD_TYPE(TPMT_SIGNATURE, signature) - -SAVE_TYPE(TPMT_TK_VERIFIED, ticket) -LOAD_TYPE(TPMT_TK_VERIFIED, ticket) - -SAVE_TYPE(TPM2B_SENSITIVE, sensitive) -LOAD_TYPE(TPM2B_SENSITIVE, sensitive) - -SAVE_TYPE(TPMT_TK_HASHCHECK, validation) -LOAD_TYPE(TPMT_TK_HASHCHECK, validation) - -SAVE_TYPE(TPM2B_PRIVATE, private) -LOAD_TYPE(TPM2B_PRIVATE, private) |