diff options
Diffstat (limited to 'TPM2-Plugin')
32 files changed, 711 insertions, 5907 deletions
diff --git a/TPM2-Plugin/LICENSE b/TPM2-Plugin/LICENSE new file mode 100644 index 0000000..366ca6c --- /dev/null +++ b/TPM2-Plugin/LICENSE @@ -0,0 +1,14 @@ +/* Copyright 2018 Intel Corporation, Inc +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ diff --git a/TPM2-Plugin/Makefile.am b/TPM2-Plugin/Makefile.am index 38afb93..1d84d5f 100644 --- a/TPM2-Plugin/Makefile.am +++ b/TPM2-Plugin/Makefile.am @@ -1,2 +1,2 @@ -SUBDIRS = lib src +SUBDIRS = lib test ACLOCAL_AMFLAGS = -I m4 diff --git a/TPM2-Plugin/README.md b/TPM2-Plugin/README.md index e80adc3..978495c 100644 --- a/TPM2-Plugin/README.md +++ b/TPM2-Plugin/README.md @@ -1,7 +1,6 @@ ## Introduction -This is TPM2-Plugin to gererate asymetric key pairs from TPM2.0 module -and save them in SoftHSM Token object folder in encryped fasion. +This is TPM2-Plugin to load asymetric key pairs to TPM2.0 module. The private part of keys can only be used for signing when it is loaded in TPM module. ### Build diff --git a/TPM2-Plugin/configure.ac b/TPM2-Plugin/configure.ac index 90f6902..a4738e1 100644 --- a/TPM2-Plugin/configure.ac +++ b/TPM2-Plugin/configure.ac @@ -11,5 +11,5 @@ AM_PROG_AR LT_INIT AC_PROG_CC AC_CONFIG_HEADERS([config.h]) -AC_CONFIG_FILES([Makefile lib/Makefile src/Makefile]) +AC_CONFIG_FILES([Makefile lib/Makefile test/Makefile]) AC_OUTPUT diff --git a/TPM2-Plugin/lib/Makefile.am b/TPM2-Plugin/lib/Makefile.am index ed5f3c0..3d52e9a 100644 --- a/TPM2-Plugin/lib/Makefile.am +++ b/TPM2-Plugin/lib/Makefile.am @@ -1,4 +1,4 @@ -AM_CPPFLAGS = -I ./include -I /opt/openssl +AM_CPPFLAGS = -I ./include lib_LTLIBRARIES = libtpm2-plugin.la -libtpm2_plugin_la_SOURCES = tpm2_error.c tpm2_plugin_api.c tpm2_plugin_init.c tpm2_tcti_ldr.c tpm2_util.c log.c files.c tpm2_attr_util.c tpm2_alg_util.c tpm2_hash.c tpm2_convert.c -libtpm2_plugin_la_LDFLAGS = -version-info @VERSION_INFO@ -lsapi -ltss2-mu -ltcti-socket -ltcti-device -lcrypto -lssl -ldl +libtpm2_plugin_la_SOURCES = tpm2_plugin_api.c tpm2_plugin_init.c +libtpm2_plugin_la_LDFLAGS = -version-info @VERSION_INFO@ -lsapi -ltcti-tabrmd -ltcti-socket -ltcti-device -lcrypto -lssl -ldl 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) diff --git a/TPM2-Plugin/lib/include/files.h b/TPM2-Plugin/lib/include/files.h deleted file mode 100644 index a4befc8..0000000 --- a/TPM2-Plugin/lib/include/files.h +++ /dev/null @@ -1,398 +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. -//**********************************************************************; -#ifndef FILES_H -#define FILES_H - -#include <stdbool.h> -#include <stdio.h> - -#include <tss2/tss2_sys.h> - -/** - * Reads a series of bytes from a file as a byte array. This is similar to files_read_bytes(), - * but opens and closes the FILE for the caller. Size is both an input and output value where - * the size value is the max buffer size on call and the returned size is how much was read. - * - * This interface could be cleaned up in a later revision. - * @param path - * The path to the file to open. - * @param buf - * The buffer to read the data into - * @param size - * The max size of the buffer on call, and the size of the data read on return. - * @return - * True on success, false otherwise. - */ -bool files_load_bytes_from_path(const char *path, UINT8 *buf, UINT16 *size); - -/** - * Loads data from a file path or stdin enforcing an upper bound on size. - * @param path - * The path to load data from, NULL means stdin. - * @param size - * The maximum size. - * @param buf - * The buffer to write the data into. - * @return - * True on success or false otherwise. - */ -bool files_load_bytes_from_file_or_stdin(const char *path, UINT16 *size, BYTE *buf); - -/** - * Similar to files_write_bytes(), in that it writes an array of bytes to disk, - * but this routine opens and closes the file on the callers behalf. - * @param path - * The path to the file to write the data to. - * @param buf - * The buffer of data to write - * @param size - * The size of the data to write in bytes. - * @return - * True on success, false otherwise. - */ -bool files_save_bytes_to_file(const char *path, UINT8 *buf, UINT16 size); - -/** - * Saves the TPM context for an object handle to disk by calling Tss2_Sys_ContextSave() and serializing the - * resulting TPMS_CONTEXT structure to disk. - * @param sapi_context - * The system api context - * @param handle - * The object handle for the object to save. - * @param path - * The output path of the file. - * - * @return - * True on success, False on error. - */ -bool files_save_tpm_context_to_path(TSS2_SYS_CONTEXT *sapi_context, TPM2_HANDLE handle, const char *path); - -/** - * Like files_save_tpm_context_to_path() but saves a tpm session to a FILE stream. - * @param sapi_context - * The system api context - * @param handle - * The object handle for the object to save. - * @param stream - * The FILE stream to save too. - * @return - * True on success, False on error. - */ -bool files_save_tpm_context_to_file(TSS2_SYS_CONTEXT *sapi_context, TPM2_HANDLE handle, - FILE *stream); - -/** - * Loads a TPM object context from disk. - * @param sapi_context - * The system API context - * @param handle - * The object handle that was saved. - * @param path - * The path to the input file. - * @return - * True on Success, false on error. - */ -bool files_load_tpm_context_from_path(TSS2_SYS_CONTEXT *sapi_context, TPM2_HANDLE *handle, const char *path); - -/** - * Like files_load_tpm_context_from_path() but loads the context from a FILE stream. - * @param sapi_context - * The system API context - * @param handle - * The object handle that was saved. - * @param stream - * The FILE stream to read from. - * @return - * True on success, False on error. - */ -bool files_load_tpm_context_from_file(TSS2_SYS_CONTEXT *sapi_context, - TPM2_HANDLE *handle, FILE *stream); - -/** - * Serializes a TPM2B_PUBLIC to the file path provided. - * @param public - * The TPM2B_PUBLIC to save to disk. - * @param path - * The path to save to. - * @return - * true on success, false on error. - */ -bool files_save_public(TPM2B_PUBLIC *public, const char *path); - -/** - * Loads a TPM2B_PUBLIC from disk that was saved with files_save_pubkey() - * @param path - * The path to load from. - * @param public - * The TPM2B_PUBLIC to load. - * @return - * true on success, false on error. - */ -bool files_load_public(const char *path, TPM2B_PUBLIC *public); - -/** - * Serializes a TPMT_SIGNATURE to the file path provided. - * @param signature - * The TPMT_SIGNATURE to save to disk. - * @param path - * The path to save to. - * @return - * true on success, false on error. - */ -bool files_save_signature(TPMT_SIGNATURE *signature, const char *path); - -/** - * Loads a TPMT_SIGNATURE from disk that was saved with files_save_signature() - * @param path - * The path to load from. - * @param signature - * The TPMT_SIGNATURE to load. - * @return - * true on success, false on error. - */ -bool files_load_signature(const char *path, TPMT_SIGNATURE *signature); - -/** - * Serializes a TPMT_TK_VERIFIED to the file path provided. - * @param signature - * The TPMT_SIGNATURE to save to disk. - * @param path - * The path to save to. - * @return - * true on success, false on error. - */ -bool files_save_ticket(TPMT_TK_VERIFIED *ticket, const char *path); - -/** - * Loads a TPMT_TK_VERIFIED from disk that was saved with files_save_ticket() - * @param path - * The path to load from. - * @param signature - * The TPMT_TK_VERIFIED to load. - * @return - * true on success, false on error. - */ -bool files_load_ticket(const char *path, TPMT_TK_VERIFIED *ticket); - -/** - * Loads a TPM2B_SENSITIVE from disk. - * @param path - * The path to load from. - * @param signature - * The TPM2B_SENSITIVE to load. - * @return - * true on success, false on error. - */ -bool files_load_sensitive(const char *path, TPM2B_SENSITIVE *sensitive); - -/** - * Serializes a TPM2B_SENSITIVE to the file path provided. - * @param sensitive - * The TPM2B_SENSITIVE to save to disk. - * @param path - * The path to save to. - * @return - * true on success, false on error. - */ -bool files_save_sensitive(TPM2B_SENSITIVE *sensitive, const char *path); -/** - * Serializes a TPMT_TK_HASHCHECK to the file path provided. - * @param validation - * The TPMT_TK_HASHCHECK to save to disk. - * @param path - * The path to save to. - * @return - * true on success, false on error. - */ -bool files_save_validation(TPMT_TK_HASHCHECK *validation, const char *path); - -/** - * Loads a TPMT_TK_HASHCHECK from disk. - * @param path - * The path to load from. - * @param validation - * The TPMT_TK_HASHCHECK to load. - * @return - * true on success, false on error. - */ -bool files_load_validation(const char *path, TPMT_TK_HASHCHECK *validation); - -/** - * Serializes a TPM2B_PRIVATE to the file path provided. - * @param private - * The TPM2B_PRIVATE to save to disk. - * @param path - * The path to save to. - * @return - * true on success, false on error. - */ -bool files_save_private(TPM2B_PRIVATE *private, const char *path); - -/** - * Loads a TPM2B_PRIVATE from disk. - * @param private - * The path to load from. - * @param validation - * The TPM2B_PRIVATE to load. - * @return - * true on success, false on error. - */ -bool files_load_private(const char *path, TPM2B_PRIVATE *private); - -/** - * Checks a file for existence. - * @param path - * The file to check for existence. - * @return - * true if a file exists with read permissions, false if it doesn't exist or an error occurs. - * - */ -bool files_does_file_exist(const char *path); - -/** - * Retrieves a files size given a file path. - * @param path - * The path of the file to retreive the size of. - * @param file_size - * A pointer to an unsigned long to return the file size. The - * pointed to value is valid only on a true return. - * - * @return - * True for success or False for error. - */ -bool files_get_file_size_path(const char *path, unsigned long *file_size); - -/** - * Similar to files_get_file_size_path(), but uses an already opened FILE object. - * @param fp - * The file pointer to query the size of. - * @param file_size - * Output of the file size. - * @param path - * An optional path used for error reporting, a NULL path disables error logging. - * @return - * True on success, False otherwise. - */ -bool files_get_file_size(FILE *fp, unsigned long *file_size, const char *path); - -/** - * Writes a TPM2.0 header to a file. - * @param f - * The file to write to. - * @param version - * The version number of the format of the file. - * @return - * True on success, false on error. - */ -bool files_write_header(FILE *f, UINT32 version); - -/** - * Reads a TPM2.0 header from a file. - * @param f - * The file to read. - * @param version - * The version that was found. - * @return - * True on Success, False on error. - */ -bool files_read_header(FILE *f, UINT32 *version); - -/** - * Writes a 16 bit value to the file in big endian, converting - * if needed. - * @param out - * The file to write. - * @param data - * The 16 bit value to write. - * @return - * True on success, False on error. - */ -bool files_write_16(FILE *out, UINT16 data); - -/** - * Same as files_write_16 but for 32 bit values. - */ -bool files_write_32(FILE *out, UINT32 data); - -/** - * Same as files_write_16 but for 64 bit values. - */ -bool files_write_64(FILE *out, UINT64 data); - -/** - * Writes a byte array out to a file. - * @param out - * The file to write to. - * @param data - * The data to write. - * @param size - * The size of the data to write in bytes. - * @return - * True on success, False otherwise. - */ -bool files_write_bytes(FILE *out, UINT8 data[], size_t size); - -/** - * Reads a 16 bit value from a file converting from big endian to host - * endianess. - * @param out - * The file to read from. - * @param data - * The data that is read, valid on a true return. - * @return - * True on success, False on error. - */ -bool files_read_16(FILE *out, UINT16 *data); - -/** - * Same as files_read_16 but for 32 bit values. - */ -bool files_read_32(FILE *out, UINT32 *data); - -/** - * Same as files_read_16 but for 64 bit values. - */ -bool files_read_64(FILE *out, UINT64 *data); - -/** - * Reads len bytes from a file. - * @param out - * The file to read from. - * @param data - * The buffer to read into, only valid on a True return. - * @param size - * The number of bytes to read. - * @return - * True on success, False otherwise. - */ -bool files_read_bytes(FILE *out, UINT8 data[], size_t size); - -#endif /* FILES_H */ diff --git a/TPM2-Plugin/lib/include/log.h b/TPM2-Plugin/lib/include/log.h deleted file mode 100644 index a93c1c2..0000000 --- a/TPM2-Plugin/lib/include/log.h +++ /dev/null @@ -1,107 +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. -//**********************************************************************; -#ifndef SRC_LOG_H_ -#define SRC_LOG_H_ - -#include <stdbool.h> -#include <stdio.h> - -#include <tss2/tss2_sys.h> - -#include "tpm2_error.h" -#include "tpm2_util.h" - -typedef enum log_level log_level; -enum log_level { - log_level_error, - log_level_warning, - log_level_verbose -}; - -void _log (log_level level, const char *file, unsigned lineno, const char *fmt, ...) - COMPILER_ATTR(format (printf, 4, 5)); - -/* - * Prints an error message. The fmt and variadic arguments mirror printf. - * - * Use this to log all error conditions. - */ -#define LOG_ERR(fmt, ...) _log(log_level_error, __FILE__, __LINE__, fmt, ##__VA_ARGS__) - -/** - * Prints an error message for a TSS2_Sys call to the TPM. - * The format is <function-name>(0x<rc>) - <error string> - * @param func - * The function that caused the error - * @param rc - * The return code to print. - */ -#define LOG_PERR(func, rc) _LOG_PERR(xstr(func), rc) - -/** - * Internal use only. - * - * Handles the expanded LOG_PERR call checking argument values - * and handing them off to LOG_ERR. - * @param func - * The function name. - * @param rc - * The rc to decode. - */ -static inline void _LOG_PERR(const char *func, TSS2_RC rc) { - - LOG_ERR("%s(0x%X) - %s", func, rc, tpm2_error_str(rc)); -} - -/* - * Prints an warning message. The fmt and variadic arguments mirror printf. - * - * Use this to log a warning. A warning is when something is wrong, but it is not a fatal - * issue. - */ -#define LOG_WARN(fmt, ...) _log(log_level_warning, __FILE__, __LINE__, fmt, ##__VA_ARGS__) - -/* - * Prints an informational message. The fmt and variadic arguments mirror printf. - * - * Informational messages are only shown when verboseness is increased. Valid messages - * would be debugging type messages where additional, extraneous information is printed. - */ -#define LOG_INFO(fmt, ...) _log(log_level_verbose, __FILE__, __LINE__, fmt, ##__VA_ARGS__) - -/** - * Sets the log level so only messages <= to it print. - * @param level - * The logging level to set. - */ -void log_set_level (log_level level); - -#endif /* SRC_LOG_H_ */ diff --git a/TPM2-Plugin/lib/include/tcti_util.h b/TPM2-Plugin/lib/include/tcti_util.h deleted file mode 100644 index 1b3b289..0000000 --- a/TPM2-Plugin/lib/include/tcti_util.h +++ /dev/null @@ -1,109 +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. -// -// 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. -//**********************************************************************; - -// -// The context for TCTI implementations is on opaque -// structure. There shall never be a definition of its content. -// Implementation provide the size information to -// applications via the initialize call. -// This makes use of a compiler trick that allows type -// checking of the pointer even though the type isn't -// defined. -// -// The first field of a Context must be the common part -// (see below). -#ifndef TSS2_TCTI_UTIL_H -#define TSS2_TCTI_UTIL_H - -#if defined linux || defined unix -#include <sys/socket.h> -#define SOCKET int -#endif - -#include <tcti/common.h> - -#define TCTI_MAGIC 0x7e18e9defa8bc9e2 -#define TCTI_VERSION 0x1 - -#define TCTI_LOG_CALLBACK(ctx) ((TSS2_TCTI_CONTEXT_INTEL*)ctx)->logCallback -#define TCTI_LOG_DATA(ctx) ((TSS2_TCTI_CONTEXT_INTEL*)ctx)->logData -#define TCTI_LOG_BUFFER_CALLBACK(ctx) ((TSS2_TCTI_CONTEXT_INTEL*)ctx)->logBufferCallback - -typedef TSS2_RC (*TCTI_TRANSMIT_PTR)( TSS2_TCTI_CONTEXT *tctiContext, size_t size, uint8_t *command); -typedef TSS2_RC (*TCTI_RECEIVE_PTR) (TSS2_TCTI_CONTEXT *tctiContext, size_t *size, uint8_t *response, int32_t timeout); - -enum tctiStates { TCTI_STAGE_INITIALIZE, TCTI_STAGE_SEND_COMMAND, TCTI_STAGE_RECEIVE_RESPONSE }; - -/* current Intel version */ -typedef struct { - uint64_t magic; - uint32_t version; - TCTI_TRANSMIT_PTR transmit; - TCTI_RECEIVE_PTR receive; - TSS2_RC (*finalize) (TSS2_TCTI_CONTEXT *tctiContext); - TSS2_RC (*cancel) (TSS2_TCTI_CONTEXT *tctiContext); - TSS2_RC (*getPollHandles) (TSS2_TCTI_CONTEXT *tctiContext, - TSS2_TCTI_POLL_HANDLE *handles, size_t *num_handles); - TSS2_RC (*setLocality) (TSS2_TCTI_CONTEXT *tctiContext, uint8_t locality); - struct { - UINT32 debugMsgEnabled: 1; - UINT32 locality: 8; - UINT32 commandSent: 1; - UINT32 rmDebugPrefix: 1; // Used to add a prefix to RM debug messages. This is ONLY used - // for TPM commands and responses as a way to differentiate - // RM generated TPM commands from application generated ones. - - // Following two fields used to save partial response status in case receive buffer's too small. - UINT32 tagReceived: 1; - UINT32 responseSizeReceived: 1; - UINT32 protocolResponseSizeReceived: 1; - } status; - - // Following two fields used to save partial response in case receive buffer's too small. - TPM_ST tag; - TPM_RC responseSize; - - TSS2_TCTI_CONTEXT *currentTctiContext; - - // Sockets if socket interface is being used. - SOCKET otherSock; - SOCKET tpmSock; - SOCKET currentConnectSock; - - // File descriptor for device file if real TPM is being used. - int devFile; - UINT8 previousStage; // Used to check for sequencing errors. - unsigned char responseBuffer[4096]; - TCTI_LOG_CALLBACK logCallback; - TCTI_LOG_BUFFER_CALLBACK logBufferCallback; - void *logData; -} TSS2_TCTI_CONTEXT_INTEL; - -#define TCTI_CONTEXT ( (TSS2_TCTI_CONTEXT_COMMON_CURRENT *)(SYS_CONTEXT->tctiContext) ) -#define TCTI_CONTEXT_INTEL ( (TSS2_TCTI_CONTEXT_INTEL *)tctiContext ) - -#endif diff --git a/TPM2-Plugin/lib/include/tpm2_alg_util.h b/TPM2-Plugin/lib/include/tpm2_alg_util.h deleted file mode 100644 index b9511dc..0000000 --- a/TPM2-Plugin/lib/include/tpm2_alg_util.h +++ /dev/null @@ -1,196 +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. -//**********************************************************************; -#ifndef LIB_TPM2_ALG_UTIL_H_ -#define LIB_TPM2_ALG_UTIL_H_ - -#include <stdbool.h> - -#include <tss2/tss2_sys.h> - -/** - * Iterator callback routine for iterating over known algorithm name and value - * pairs. - * @param id - * The algorithm id. - * @param name - * The associated "nice-name". - * @param userdata - * A user supplied data pointer. - * @return - * True to stop iterating, false to keep iterating. - */ -typedef bool (*tpm2_alg_util_alg_iteraror)(TPM2_ALG_ID id, const char *name, void *userdata); - -/** - * Iterate over the algorithm name-value pairs calling the iterator callback for each pair. - * @param iterator - * The iterator callback function. - * @param userdata - * A pointer to user supplied data, this is passed to the iterator for each call. - */ -void tpm2_alg_util_for_each_alg(tpm2_alg_util_alg_iteraror iterator, void *userdata); - -/** - * Convert a "nice-name" string to an algorithm id. - * @param name - * The "nice-name" to convert. - * @return - * TPM2_ALG_ERROR on error, or a valid algorithm identifier. - */ -TPM2_ALG_ID tpm2_alg_util_strtoalg(const char *name); - -/** - * Convert an id to a nice-name. - * @param id - * The id to convert. - * @return - * The nice-name. - */ -const char *tpm2_alg_util_algtostr(TPM2_ALG_ID id); - -/** - * Converts either a string from algrotithm number or algorithm nice-name to - * an algorithm id. - * @param optarg - * The string to convert from an algorithm number or nice name. - * @return - * TPM2_ALG_ERROR on error or the algorithm id. - */ -TPM2_ALG_ID tpm2_alg_util_from_optarg(char *optarg); - -/** - * Detects if an algorithm is considered a hashing algorithm. - * @param id - * The algorithm id to check. - * @return - * True if it is a hash algorithm, False otherwise. - */ -bool tpm2_alg_util_is_hash_alg(TPM2_ALG_ID id); - -/** - * Contains the information from parsing an argv style vector of strings for - * pcr digest language specifications. - */ -typedef struct tpm2_pcr_digest_spec tpm2_pcr_digest_spec; -struct tpm2_pcr_digest_spec { - TPML_DIGEST_VALUES digests; - TPMI_DH_PCR pcr_index; -}; - -/** - * Parses an argv array that contains a digest specification at each location - * within argv. - * - * The digest specification is as follows: - * - A pcr identifier as understood by strtoul with 0 as the base. - * - A colon followed by the algorithm hash specification. - * - The algorithm hash specification is as follows: - * - The algorithm friendly name or raw numerical as understood by - * strtoul with a base of 0. - * - An equals sign - * - The hex hash value, - * - * This all distills to a string that looks like this: - * <pcr index>:<hash alg id>=<hash value> - * - * Example: - * "4:sha=f1d2d2f924e986ac86fdf7b36c94bcdf32beec15" - * - * Note: - * Multiple specifications of PCR and hash are OK. Multiple hashes - * cause the pcr to be extended with both hashes. Multiple same PCR - * values cause the PCR to be extended multiple times. Extension - * is done in order from left to right as specified. - * - * At most 5 hash extensions per PCR entry are supported. This - * is to keep the parser simple. - * - * @param sapi_context - * The system API context for hashing files with the tpm. This can - * be NULL if the argument vector doesn't have a file spec for the hash. - * @param argv - * The argv of digest specifications to parse. - * @param len - * The number of digest specifications to parse. - * @param digests - * An array of tpm2_pcr_digest_spec big enough to hold len items. - * @return - * True if parsing was successful, False otherwise. - * @note - * This function logs errors via LOG_ERR. - */ -bool pcr_parse_digest_list(char **argv, int len, - tpm2_pcr_digest_spec *digest_spec); - -/** - * Retrieves the size of a hash in bytes for a given hash - * algorithm or 0 if unknown/not found. - * @param id - * The HASH algorithm identifier. - * @return - * 0 on failure or the size of the hash bytes. - */ -UINT16 tpm2_alg_util_get_hash_size(TPMI_ALG_HASH id); - -/** - * Extracts the plain signature data without any headers - * - * Communicates errors via LOG_ERR. - * - * @param size - * Will receive the number of bytes stored in buffer. - * @signature The actual signature struct to extract the plain signature from. - * @return - * Returns a buffer filled with the extracted signature or NULL on error. - * Needs to be free()'d by the caller. - */ -UINT8* tpm2_extract_plain_signature(UINT16 *size, TPMT_SIGNATURE *signature); - -/** - * Retrieves an approproate signature scheme (scheme) signable by - * specified key (keyHandle) and hash algorithm (halg). - * @param sapi_context - * System API context for tpm - * @param keyHandle - * Handle to key used in signing operation - * @param halg - * Hash algoritm for message - * @param scheme - * Signature scheme output - * @return - * True if successful - * False otherwise, and scheme is left unmodified - */ -bool get_signature_scheme(TSS2_SYS_CONTEXT *sapi_context, - TPMI_DH_OBJECT keyHandle, TPMI_ALG_HASH halg, - TPMT_SIG_SCHEME *scheme); - -#endif /* LIB_TPM2_ALG_UTIL_H_ */ diff --git a/TPM2-Plugin/lib/include/tpm2_attr_util.h b/TPM2-Plugin/lib/include/tpm2_attr_util.h deleted file mode 100644 index 5964174..0000000 --- a/TPM2-Plugin/lib/include/tpm2_attr_util.h +++ /dev/null @@ -1,98 +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. -//**********************************************************************; -#ifndef LIB_TPM2_ATTR_UTIL_H_ -#define LIB_TPM2_ATTR_UTIL_H_ - -#include <stdbool.h> - -#include <tss2/tss2_sys.h> - -/** - * Converts a list of | (pipe) separated attributes as defined in tavle 204 - * of https://trustedcomputinggroup.org/wp-content/uploads/TPM-Rev-2.0-Part-2-Structures-01.38.pdf - * to an actual bit field representation. The trailing TPMA_NV_ can be omitted and must be lower-case. - * For exmaple, TPMA_NV_PPWRITE, bcomes ppwrite. To append them together, just do the pipe inbetwwen. - * ppwrite|ownerwrite. - * - * @param attribute_list - * The attribute string to parse, which may be modified in place. - * @param nvattrs - * The TPMA_NV attributes set based on the attribute list. Only valid on true returns. - * @return - * true on success, false on error. - */ -bool tpm2_attr_util_nv_strtoattr(char *attribute_list, TPMA_NV *nvattrs); - -/** - * Like tpm2_attr_util_nv_strtoattr() but converts TPMA_OBJECT attributes as defined in: - * Table 31 of https://trustedcomputinggroup.org/wp-content/uploads/TPM-Rev-2.0-Part-2-Structures-01.38.pdf - * @param attribute_list - * The attribute string to parse, which may be modified in place. - * The TPMA_OBJECT attributes set based on the attribute list. Only valid on true returns. - * @return - * true on success, false on error. - */ -bool tpm2_attr_util_obj_strtoattr(char *attribute_list, TPMA_OBJECT *objattrs); - -/** - * Converts a numerical or friendly string described object attribute into the - * TPMA_OBJECT. Similar to tpm2_alg_util_from_optarg(). - * @param argvalue - * Either a raw numeric for a UINT32 or a friendly name object attribute list - * as in tpm2_attr_util_nv_strtoattr(). - * @param objattrs - * The converted bits for a TPMA_OBJECT - * @return - * true on success or false on error. - */ -bool tpm2_attr_util_obj_from_optarg(char *argvalue, TPMA_OBJECT *objattrs); - -/** - * Converts a TPMA_NV structure to a friendly name style string. - * @param nvattrs - * The nvattrs to convert to nice name. - * @return A string allocated with calloc(), callers shall use - * free() to free it. The string is a null terminated text representation - * of the TPMA_NV attributes. - */ -char *tpm2_attr_util_nv_attrtostr(TPMA_NV nvattrs); - -/** - * Like tpm2_nv_util_obj_strtoattr() but converts TPMA_OBJECT attributes as defined in: - * Table 31 of https://trustedcomputinggroup.org/wp-content/uploads/TPM-Rev-2.0-Part-2-Structures-01.38.pdf - * @param objattrs - * The object parameters to convert to a name - * @return - * The name of the object attrs as a string that must be freed via free(). - */ -char *tpm2_attr_util_obj_attrtostr(TPMA_OBJECT objattrs); - -#endif /* LIB_TPM2_ATTR_UTIL_H_ */ diff --git a/TPM2-Plugin/lib/include/tpm2_convert.h b/TPM2-Plugin/lib/include/tpm2_convert.h deleted file mode 100644 index 275d96a..0000000 --- a/TPM2-Plugin/lib/include/tpm2_convert.h +++ /dev/null @@ -1,99 +0,0 @@ -//**********************************************************************; -// Copyright (c) 2017, SUSE GmbH -// 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. -// -// 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. -//**********************************************************************; - -#ifndef CONVERSION_H -#define CONVERSION_H - -#include <stdbool.h> - -#include <tss2/tss2_sys.h> - -typedef enum tpm2_convert_pubkey_fmt tpm2_convert_pubkey_fmt; -enum tpm2_convert_pubkey_fmt { - pubkey_format_tss, - pubkey_format_pem, - pubkey_format_der, - pubkey_format_err -}; - -typedef enum tpm2_convert_sig_fmt tpm2_convert_sig_fmt; -enum tpm2_convert_sig_fmt { - signature_format_tss, - signature_format_plain, - signature_format_err -}; - -/** - * Parses the given command line public key format option string and returns - * the corresponding pubkey_format enum value. - * - * LOG_ERR is used to communicate errors. - * - * @return - * On error pubkey_format_err is returned. - */ -tpm2_convert_pubkey_fmt tpm2_convert_pubkey_fmt_from_optarg(const char *label); - -/** - * Converts the given public key structure into the requested target format - * and writes the result to the given file system path. - * - * LOG_ERR is used to communicate errors. - */ -bool tpm2_convert_pubkey_save(TPM2B_PUBLIC *public, tpm2_convert_pubkey_fmt format, const char *path); - -/** - * Loads a public key in the TSS format from a file. - * @param public - * The public key to load - * @param format - * @param path - * @return - */ -bool tpm2_convert_pubkey_load(TPM2B_PUBLIC *public, const char *path); - -/** - * Parses the given command line signature format option string and returns - * the corresponding signature_format enum value. - * - * LOG_ERR is used to communicate errors. - * - * @return - * On error signature_format_err is returned. - */ -tpm2_convert_sig_fmt tpm2_convert_sig_fmt_from_optarg(const char *label); - -/** - * Converts the given signature data into the requested target format and - * writes the result to the given file system path. - * - * LOG_ERR is used to communicate errors. - */ -bool tpm2_convert_sig(TPMT_SIGNATURE *signature, tpm2_convert_sig_fmt format, - const char *path); - -#endif /* CONVERSION_H */ diff --git a/TPM2-Plugin/lib/include/tpm2_error.h b/TPM2-Plugin/lib/include/tpm2_error.h deleted file mode 100644 index 01ec043..0000000 --- a/TPM2-Plugin/lib/include/tpm2_error.h +++ /dev/null @@ -1,136 +0,0 @@ -//**********************************************************************; -// Copyright (c) 2018, 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. -// -// 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. -//**********************************************************************; - -#ifndef LIB_TPM2_ERROR_H_ -#define LIB_TPM2_ERROR_H_ - -#include <stdbool.h> - -#include <tss2/tss2_sys.h> - -/** - * Number of error layers - */ -#define TPM2_ERROR_TSS2_RC_LAYER_COUNT (TSS2_RC_LAYER_MASK >> TSS2_RC_LAYER_SHIFT) - -/** - * Mask for the error bits of tpm2 compliant return code. - */ -#define TPM2_ERROR_TSS2_RC_ERROR_MASK 0xFFFF - -/** - * Retrieves the error bits from a TSS2_RC. The error bits are - * contained in the first 2 octets. - * @param rc - * The rc to query for the error bits. - * @return - * The error bits. - */ -static inline UINT16 tpm2_error_get(TSS2_RC rc) { - return ((rc & TPM2_ERROR_TSS2_RC_ERROR_MASK)); -} - -/** - * A custom error handler prototype. - * @param rc - * The rc to decode with only the error bits set, ie no need to mask the - * layer bits out. Handlers will never be invoked with the error bits set - * to 0, as zero always indicates success. - * @return - * An error string describing the rc. If the handler cannot determine - * a valid response, it can return NULL indicating that the framework - * should just print the raw hexidecimal value of the error field of - * a tpm2_err_layer_rc. - * Note that this WILL NOT BE FREED by the caller, - * i.e. static. - */ -typedef const char *(*tpm2_error_handler)(TSS2_RC rc); - -/** - * Register or unregister a custom layer error handler. - * @param layer - * The layer in which to register a handler for. It is an error - * to register for the following reserved layers: - * - TSS2_TPM_RC_LAYER - layer 0 - * - TSS2_SYS_RC_LAYER - layer 8 - * - TSS2_MU_RC_LAYER - layer 9 - * - TSS2_TCTI_RC_LAYER - layer 10 - * @param name - * A friendly layer name. It is an error for the name to be of - * length 0 or greater than 4. - * @param handler - * The handler function to register or NULL to unregister. - * @return - * True on success or False on error. - */ -bool tpm2_error_set_handler(UINT8 layer, const char *name, - tpm2_error_handler handler); - -/** - * Given a TSS2_RC return code, provides a static error string in the format: - * <layer-name>:<layer-specific-msg>. - * - * The layer-name section will either be the friendly name, or if no layer - * handler is registered, the base10 layer number. - * - * The "layer-specific-msg" is layer specific and will contain details on the - * error that occurred or the error code if it couldn't look it up. - * - * Known layer specific substrings: - * TPM - The tpm layer produces 2 distinct format codes that allign with: - * - Section 6.6 of: https://trustedcomputinggroup.org/wp-content/uploads/TPM-Rev-2.0-Part-2-Structures-01.38.pdf - * - Section 39.4 of: https://trustedcomputinggroup.org/wp-content/uploads/TPM-Rev-2.0-Part-1-Architecture-01.38.pdf - * - * The two formats are format 0 and format 1. - * Format 0 string format: - * - "<error|warn>(<version>): <description> - * - Examples: - * - error(1.2): bad tag - * - warn(2.0): the 1st handle in the handle area references a transient object or session that is not loaded - * - * Format 1 string format: - * - <handle|session|parameter>(<index>):<description> - * - Examples: - * - handle(unk):value is out of range or is not correct for the context - * - tpm:handle(5):value is out of range or is not correct for the context - * - * Note that passing TPM2_RC_SUCCESS results in the layer specific message of "success". - * - * The System, TCTI and Marshaling (MU) layers, all define simple string - * returns analogous to strerror(3). - * - * Unknown layers will have the layer number in decimal and then a layer specific string of - * a hex value representing the error code. For example: 9:0x3 - * - * @param rc - * The error code to decode. - * @return - * A human understandable error description string. - */ -const char *tpm2_error_str(TSS2_RC rc); - -#endif /* LIB_TPM2_ERROR_H_ */ diff --git a/TPM2-Plugin/lib/include/tpm2_hash.h b/TPM2-Plugin/lib/include/tpm2_hash.h deleted file mode 100644 index 627a95a..0000000 --- a/TPM2-Plugin/lib/include/tpm2_hash.h +++ /dev/null @@ -1,84 +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. -//**********************************************************************; -#ifndef SRC_TPM_HASH_H_ -#define SRC_TPM_HASH_H_ - -#include <stdbool.h> - -#include <tss2/tss2_sys.h> - -/** - * Hashes a BYTE array via the tpm. - * @param sapi_context - * The system api context. - * @param hash_alg - * The hashing algorithm to use. - * @param hierarchy - * The hierarchy. - * @param buffer - * The data to hash. - * @param length - * The length of the data. - * @param result - * The digest result. - * @param validation - * The validation ticket. Note that some hierarchies don't produce a - * validation ticket and thus size will be 0. - * @return - * True on success, false otherwise. - */ -bool tpm2_hash_compute_data(TSS2_SYS_CONTEXT *sapi_context, TPMI_ALG_HASH halg, - TPMI_RH_HIERARCHY hierarchy, BYTE *buffer, UINT16 length, - TPM2B_DIGEST *result, TPMT_TK_HASHCHECK *validation); - -/** - * Hashes a FILE * object via the tpm. - * @param sapi_context - * The system api context. - * @param hash_alg - * The hashing algorithm to use. - * @param hierarchy - * The hierarchy. - * @param input - * The FILE object to hash. - * @param result - * The digest result. - * @param validation - * The validation ticket. Note that some hierarchies don't produce a - * validation ticket and thus size will be 0. - * @return - * True on success, false otherwise. - */ -bool tpm2_hash_file(TSS2_SYS_CONTEXT *sapi_context, TPMI_ALG_HASH halg, - TPMI_RH_HIERARCHY hierarchy, FILE *input, TPM2B_DIGEST *result, - TPMT_TK_HASHCHECK *validation); - -#endif /* SRC_TPM_HASH_H_ */ diff --git a/TPM2-Plugin/lib/include/tpm2_options.h b/TPM2-Plugin/lib/include/tpm2_options.h deleted file mode 100644 index 860d9b0..0000000 --- a/TPM2-Plugin/lib/include/tpm2_options.h +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright (c) 2016, 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. - */ -#ifndef OPTIONS_H -#define OPTIONS_H - -#include <stdbool.h> -#include <stdint.h> -#include <stdio.h> - -#include <getopt.h> - -#include <tss2/tss2_sys.h> - -typedef union tpm2_option_flags tpm2_option_flags; -union tpm2_option_flags { - struct { - UINT8 verbose : 1; - UINT8 quiet : 1; - UINT8 enable_errata : 1; - }; - UINT8 all; -}; - -/** - * This function pointer defines the interface for tcti initialization. - * ALL tool supported TCTIs should implement this interface. - * @param opts - * An option string, that is defined by the tcti, and is passed - * via the --tcti= or -T options. - * - * Anything following the : in the --tcti option is provides as opts. - * @return - * NULL on error or an initialized TCTI. - */ -typedef TSS2_TCTI_CONTEXT *(*tcti_init)(char *opts); - -/** - * Tools may implement this optional interface if they need - * to handle options. - * @param key - * The key of the option, ie short option return value from getopt_long(). - * @param value - * The getopt_long optarg value. - * @return - * true on success, false on error. - * @note - * LOG_INFO and TOOL_OUTPUT will not work correctly during this callback. - * This is called after onstart() finishes, but before - * onrun() is invoked. - * - */ -typedef bool (*tpm2_option_handler)(char key, char *value); - -/** - * Called after option handling to process arguments, if specified. - * @param argc - * The number of args in argv. - * @param argv - * The arguments. - * @return - * true on success, false otherwise. - * @note - * LOG_INFO adn TOOL_OUTPUT will not work correctly during this callback. - * This is called after onstart() and tpm2_option_handler() (if specified), - * but before onrun() is invoked. - * - */ -typedef bool (*tpm2_arg_handler)(int argc, char **argv); - -/** - * TPM2_OPTIONS_* flags change default behavior of the argument parser - * - * TPM2_OPTIONS_SHOW_USAGE: - * Enable printing a short usage summary (I.e. help) - * TPM2_OPTIONS_NO_SAPI: - * Skip SAPI initialization. Removes the "-T" common option. - */ -#define TPM2_OPTIONS_SHOW_USAGE 0x1 -#define TPM2_OPTIONS_NO_SAPI 0x2 - -struct tpm2_options { - struct { - tpm2_option_handler on_opt; - tpm2_arg_handler on_arg; - } callbacks; - char *short_opts; - size_t len; - UINT32 flags; - struct option long_opts[]; -}; - -typedef struct tpm2_options tpm2_options; - -/** - * The onstart() routine expects a return of NULL or a tpm2_options structure. - * This routine initializes said object. - * @param short_opts - * Any short options you wish to specify to getopt_long. - * @param len - * The length of the long_opts array. - * @param long_opts - * Any long options you wish to specify to getopt_long(). - * @param on_opt - * An option handling callback, which may be null if you don't wish - * to handle options. - * @param on_arg - * An argument handling callback, which may be null if you don't wish - * to handle arguments. - * @param flags - * TPM2_OPTIONS_* bit flags - * @return - * NULL on failure or an initialized tpm2_options object. - */ -tpm2_options *tpm2_options_new(const char *short_opts, size_t len, - const struct option *long_opts, tpm2_option_handler on_opt, - tpm2_arg_handler on_arg, UINT32 flags); - -/** - * Concatenates two tpm2_options objects, with src appended on - * dest. The internal callbacks for tpm2_arg_handler and tpm2_option_handler - * which were specified during tpm2_options_new() are copied from src to - * dest, thus overwriting dest. Short and long options are concatenated. - * @param dest - * The tpm2_options object to append to. - * @param src - * The source tpm2_options to append onto dest. - * @return - * true on success, false otherwise. - */ -bool tpm2_options_cat(tpm2_options **dest, tpm2_options *src); - -/** - * Free's a tpm2_options created via tpm2_options_new(). - * @param opts - * The tpm2_options object to deallocate. - */ -void tpm2_options_free(tpm2_options *opts); - -typedef enum tpm2_option_code tpm2_option_code; -enum tpm2_option_code { - tpm2_option_code_continue, - tpm2_option_code_stop, - tpm2_option_code_err -}; - -/** - * Parses the tpm2_tool command line. - * - * @param argc - * The argc from main. - * @param argv - * The argv from main. - * @param tool_opts - * The tool options gathered during onstart() lifecycle call. - * @param flags - * The tpm2_option_flags to set during parsing. - * @param tcti - * The tcti initialized from the tcti options. - * @return - * A tpm option code indicating if an error, further processing - * or an immediate exit is desired. - * @note - * Used by tpm2_tool, and likely should only be used there. - * - */ -tpm2_option_code tpm2_handle_options (int argc, char **argv, - tpm2_options *tool_opts, tpm2_option_flags *flags, - TSS2_TCTI_CONTEXT **tcti); - -/** - * Print usage summary for a given tpm2 tool. - * - * @param command - * The command to print its usage summary text. - * @param tool_opts - * The tpm2_options array that contains the tool options to print as a summary. - */ -void tpm2_print_usage(const char *command, struct tpm2_options *tool_opts); - -#endif /* OPTIONS_H */ diff --git a/TPM2-Plugin/lib/include/tpm2_plugin_api.h b/TPM2-Plugin/lib/include/tpm2_plugin_api.h index e166071..2a0ace0 100644 --- a/TPM2-Plugin/lib/include/tpm2_plugin_api.h +++ b/TPM2-Plugin/lib/include/tpm2_plugin_api.h @@ -1,29 +1,17 @@ -//**********************************************************************; -// 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. -// -// 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. -//**********************************************************************; +/* Copyright 2018 Intel Corporation, Inc +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ #ifndef __TPM_API_H__ #define __TPM_API_H__ @@ -35,8 +23,7 @@ #include <ctype.h> #include <getopt.h> -#include <tss2/tss2_sys.h> - +#include <sapi/tpm20.h> #include "hwpluginif.h" #ifdef __cplusplus @@ -67,6 +54,10 @@ extern "C" { #define TSS2_APP_RC_TEARDOWN_SYS_CONTEXT_FAILED (APP_RC_TEARDOWN_SYS_CONTEXT_FAILED + APP_RC_OFFSET + TSS2_APP_ERROR_LEVEL) #define TSS2_APP_RC_BAD_LOCALITY (APP_RC_BAD_LOCALITY + APP_RC_OFFSET + TSS2_APP_ERROR_LEVEL) + +//#define HAVE_TCTI_DEV 1 +#define HAVE_TCTI_TABRMD 1 +//#define TCTI_DEFAULT HAVE_TCTI_DEV enum TSS2_APP_RC_CODE { APP_RC_PASSED, @@ -90,6 +81,66 @@ void TeardownSysContext( TSS2_SYS_CONTEXT **sysContext ); TSS2_RC TeardownTctiResMgrContext( TSS2_TCTI_CONTEXT *tctiContext ); + +#ifdef HAVE_TCTI_TABRMD + #define TCTI_DEFAULT TABRMD_TCTI + #define TCTI_DEFAULT_STR "tabrmd" +#elif HAVE_TCTI_SOCK + #define TCTI_DEFAULT SOCKET_TCTI + #define TCTI_DEFAULT_STR "socket" +#elif HAVE_TCTI_DEV + #define TCTI_DEFAULT DEVICE_TCTI + #define TCTI_DEFAULT_STR "device" +#endif + + +/* Defaults for Device TCTI */ +#define TCTI_DEVICE_DEFAULT_PATH "/dev/tpm0" + +/* Deafults for Socket TCTI connections, port default is for resourcemgr */ +#define TCTI_SOCKET_DEFAULT_ADDRESS "127.0.0.1" +#define TCTI_SOCKET_DEFAULT_PORT 2321 + +/* Environment variables usable as alternatives to command line options */ +#define TPM2TOOLS_ENV_TCTI_NAME "TPM2TOOLS_TCTI_NAME" +#define TPM2TOOLS_ENV_DEVICE_FILE "TPM2TOOLS_DEVICE_FILE" +#define TPM2TOOLS_ENV_SOCKET_ADDRESS "TPM2TOOLS_SOCKET_ADDRESS" +#define TPM2TOOLS_ENV_SOCKET_PORT "TPM2TOOLS_SOCKET_PORT" + +#define COMMON_OPTS_INITIALIZER { \ + .tcti_type = TCTI_DEFAULT, \ + .device_file = TCTI_DEVICE_DEFAULT_PATH, \ + .socket_address = TCTI_SOCKET_DEFAULT_ADDRESS, \ + .socket_port = TCTI_SOCKET_DEFAULT_PORT, \ + .help = false, \ + .verbose = false, \ + .version = false, \ +} + +typedef enum { +#ifdef HAVE_TCTI_DEV + DEVICE_TCTI, +#endif +#ifdef HAVE_TCTI_SOCK + SOCKET_TCTI, +#endif +#ifdef HAVE_TCTI_TABRMD + TABRMD_TCTI, +#endif + UNKNOWN_TCTI, + N_TCTI, +} TCTI_TYPE; + +typedef struct { + TCTI_TYPE tcti_type; + char *device_file; + char *socket_address; + uint16_t socket_port; + int help; + int verbose; + int version; +} common_opts_t; + int tpm2_plugin_init(); int tpm2_plugin_uninit(); int tpm2_plugin_activate(SSHSM_HW_PLUGIN_ACTIVATE_LOAD_IN_INFO_t *activate_in_info); @@ -114,7 +165,7 @@ int tpm2_rsa_delete_object( int tpm2_plugin_rsa_sign_init( void *keyHandle, - unsigned long mechanish, + unsigned long mechanism, void *param, int len); diff --git a/TPM2-Plugin/lib/include/tpm2_tcti_ldr.h b/TPM2-Plugin/lib/include/tpm2_tcti_ldr.h deleted file mode 100644 index 684e5e2..0000000 --- a/TPM2-Plugin/lib/include/tpm2_tcti_ldr.h +++ /dev/null @@ -1,72 +0,0 @@ -//**********************************************************************; -// Copyright (c) 2018, 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. -// -// 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 <tss2/tss2_sys.h> - -#ifndef LIB_TPM2_TCTI_LDR_H_ -#define LIB_TPM2_TCTI_LDR_H_ - -/** - * Loads a TCTI from a friendly name, library name, or path. - * For example - * friendly: path = tabrmd - * library name: path = libtss2-tcti-mssim.so - * full path: path = /home/user/lib/libtss2-tcti-custom.so - * @param path - * The path/library to load. - * @param opts - * The tcti option configs. - * @return - * A tcti context on success or NULL on failure. - */ -TSS2_TCTI_CONTEXT *tpm2_tcti_ldr_load(const char *path, const char *opts); - -/** - * Returns the loaded TCTIs information structure, - * which contains the initialization routine, description - * and help string amongst other things. - * @return - * NULL if no TCTI is loaded, else the info structure pointer. - */ -const TSS2_TCTI_INFO *tpm2_tcti_ldr_getinfo(void); - -/** - * Given a tcti name, like mssim, tells you if the - * library is present using dlopen(3). - * @param name - * The friendly name of the tcti. - * @return - * True if present, false otherwise. - */ -bool tpm2_tcti_ldr_is_tcti_present(const char *name); - -/** - * Unloads the tcti loaded via tpm2_tcti_ldr_load(); - */ -void tpm2_tcti_ldr_unload(void); - -#endif /* LIB_TPM2_TCTI_LDR_H_ */ diff --git a/TPM2-Plugin/lib/include/tpm2_tool.h b/TPM2-Plugin/lib/include/tpm2_tool.h deleted file mode 100644 index f24be38..0000000 --- a/TPM2-Plugin/lib/include/tpm2_tool.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2016, 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. - */ -#ifndef MAIN_H -#define MAIN_H - -#include <tss2/tss2_sys.h> -#include <stdbool.h> - -#include "tpm2_options.h" - -extern bool output_enabled; - -/** - * An optional interface for tools to specify what options they support. - * They are concatenated with main's options and passed to getopt_long. - * @param opts - * The callee can choose to set *opts to a tpm_options pointer allocated - * via tpm2_options_new(). Setting *opts to NULL is not an error, and - * Indicates that no options are specified by the tool. - * - * @return - * True on success, false on error. - */ -bool tpm2_tool_onstart(tpm2_options **opts) __attribute__((weak)); - -/** - * This is the main interface for tools, after tcti and sapi initialization - * are performed. - * @param sapi_context - * The system api context. - * @param flags - * Flags that tools may wish to respect. - * @return - * 0 on success. - */ -int tpm2_tool_onrun (TSS2_SYS_CONTEXT *sapi_context, tpm2_option_flags flags) __attribute__((weak)); - -/** - * Called when the tool is exiting, useful for cleanup. - */ -void tpm2_tool_onexit(void) __attribute__((weak)); - -/** - * prints output to stdout respecting the quiet option. - * Ie when quiet, don't print. - * @param fmt - * The format specifier, ala printf. - * @param ... - * The varargs, just like printf. - */ -#define tpm2_tool_output(fmt, ...) \ - do { \ - if (output_enabled) { \ - printf(fmt, ##__VA_ARGS__); \ - } \ - } while (0) - -#endif /* MAIN_H */ diff --git a/TPM2-Plugin/lib/include/tpm2_util.h b/TPM2-Plugin/lib/include/tpm2_util.h deleted file mode 100644 index de02777..0000000 --- a/TPM2-Plugin/lib/include/tpm2_util.h +++ /dev/null @@ -1,298 +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. -//**********************************************************************; -#ifndef STRING_BYTES_H -#define STRING_BYTES_H - -#include <stdbool.h> -#include <stdint.h> -#include <stdio.h> - -#include <tss2/tss2_sys.h> - -#include "tpm2_error.h" - -#if defined (__GNUC__) -#define COMPILER_ATTR(...) __attribute__((__VA_ARGS__)) -#else -#define COMPILER_ATTR(...) -#endif - -#define xstr(s) str(s) -#define str(s) #s - -#define UNUSED(x) (void)x - -#define ARRAY_LEN(x) (sizeof(x)/sizeof(x[0])) - -#define BUFFER_SIZE(type, field) (sizeof((((type *)NULL)->field))) - -#define TSS2_APP_RC_LAYER TSS2_RC_LAYER(5) - -#define TPM2B_TYPE_INIT(type, field) { .size = BUFFER_SIZE(type, field), } -#define TPM2B_INIT(xsize) { .size = xsize, } -#define TPM2B_EMPTY_INIT TPM2B_INIT(0) -#define TPM2B_SENSITIVE_CREATE_EMPTY_INIT { \ - .sensitive = { \ - .data = { \ - .size = 0 \ - }, \ - .userAuth = { \ - .size = 0 \ - } \ - } \ - } - -#define TPMS_AUTH_COMMAND_INIT(session_handle) { \ - .sessionHandle = session_handle,\ - .nonce = TPM2B_EMPTY_INIT, \ - .sessionAttributes = TPMA_SESSION_CONTINUESESSION, \ - .hmac = TPM2B_EMPTY_INIT \ - } - -#define TPMS_AUTH_COMMAND_EMPTY_INIT TPMS_AUTH_COMMAND_INIT(0) - - -#define TPMT_TK_CREATION_EMPTY_INIT { \ - .tag = 0, \ - .hierarchy = 0, \ - .digest = TPM2B_EMPTY_INIT \ - } - -#define TPML_PCR_SELECTION_EMPTY_INIT { \ - .count = 0, \ - } //ignore pcrSelections since count is 0. - -#define TPMS_CAPABILITY_DATA_EMPTY_INIT { \ - .capability = 0, \ - } // ignore data since capability is 0. - -#define TPMT_TK_HASHCHECK_EMPTY_INIT { \ - .tag = 0, \ - .hierarchy = 0, \ - .digest = TPM2B_EMPTY_INIT \ - } - -#define TSS2L_SYS_AUTH_COMMAND_INIT(cnt, array) { \ - .count = cnt, \ - .auths = array, \ - } - -/* - * This macro is useful as a wrapper around SAPI functions to automatically - * retry function calls when the RC is TPM2_RC_RETRY. - */ -#define TSS2_RETRY_EXP(expression) \ - ({ \ - TSS2_RC __result = 0; \ - do { \ - __result = (expression); \ - } while (tpm2_error_get(__result) == TPM2_RC_RETRY); \ - __result; \ - }) - -typedef struct { - UINT16 size; - BYTE buffer[0]; -} TPM2B; - -int tpm2_util_hex_to_byte_structure(const char *inStr, UINT16 *byteLenth, BYTE *byteBuffer); - -/** - * Appends a TPM2B buffer to a MAX buffer. - * @param result - * The MAX buffer to append to - * @param append - * The buffer to append to result. - * @return - * true on success, false otherwise. - */ -bool tpm2_util_concat_buffer(TPM2B_MAX_BUFFER *result, TPM2B *append); - -/** - * Converts a numerical string into a uint32 value. - * @param str - * The numerical string to convert. - * @param value - * The value to store the conversion into. - * @return - * true on success, false otherwise. - */ -bool tpm2_util_string_to_uint32(const char *str, uint32_t *value); - -/** - * Converts a numerical string into a uint16 value. - * @param str - * The numerical string to convert. - * @param value - * The value to store the conversion into. - * @return - * true on success, false otherwise. - */ -bool tpm2_util_string_to_uint16(const char *str, uint16_t *value); - -/** - * Prints an xxd compatible hexdump to stdout if output is enabled, - * ie no -Q option. - * - * @param data - * The data to print. - * @param len - * The length of the data. - */ -void tpm2_util_hexdump(const BYTE *data, size_t len); - -/** - * Prints a file as a hex string to stdout if quiet mode - * is not enabled. - * ie no -Q option. - * - * @param fd - * A readable open file. - * @param len - * The length of the data to read and print. - * @return - * true if len bytes were successfully read and printed, - * false otherwise - */ -bool tpm2_util_hexdump_file(FILE *fd, size_t len); - -/** - * Prints a TPM2B as a hex dump. - * @param buffer the TPM2B to print. - */ -static inline void tpm2_util_print_tpm2b(TPM2B *buffer) { - - return tpm2_util_hexdump(buffer->buffer, buffer->size); -} - -/** - * Reads a TPM2B object from FILE* and prints data in hex. - * @param fd - * A readable open file. - */ -bool tpm2_util_print_tpm2b_file(FILE *fd); - -/** - * Checks if the host is big endian - * @return - * True of the host is big endian false otherwise. - */ -bool tpm2_util_is_big_endian(void); - -/** - * Swaps the endianess of 16 bit value. - * @param data - * A 16 bit value to swap the endianess on. - * @return - * The 16 bit value with the endianess swapped. - */ -UINT16 tpm2_util_endian_swap_16(UINT16 data); - -/** - * Just like string_bytes_endian_convert_16 but for 32 bit values. - */ -UINT32 tpm2_util_endian_swap_32(UINT32 data); - -/** - * Just like string_bytes_endian_convert_16 but for 64 bit values. - */ -UINT64 tpm2_util_endian_swap_64(UINT64 data); - -/** - * Converts a 16 bit value from host endianess to network endianess. - * @param data - * The data to possibly swap endianess. - * @return - * The swapped data. - */ -UINT16 tpm2_util_hton_16(UINT16 data); - -/** - * Just like string_bytes_endian_hton_16 but for 32 bit values. - */ -UINT32 tpm2_util_hton_32(UINT32 data); - -/** - * Just like string_bytes_endian_hton_16 but for 64 bit values. - */ -UINT64 tpm2_util_hton_64(UINT64 data); - -/** - * Converts a 16 bit value from network endianess to host endianess. - * @param data - * The data to possibly swap endianess. - * @return - * The swapped data. - */ -UINT16 tpm2_util_ntoh_16(UINT16 data); - -/** - * Just like string_bytes_endian_ntoh_16 but for 32 bit values. - */ -UINT32 tpm2_util_ntoh_32(UINT32 data); - -/** - * Just like string_bytes_endian_ntoh_16 but for 64 bit values. - */ -UINT64 tpm2_util_ntoh_64(UINT64 data); - -/** - * Counts the number of set bits aka a population count. - * @param data - * The data to count set bits in. - * @return - * The number of set bits or population count. - */ -UINT32 tpm2_util_pop_count(UINT32 data); - -/** - * Prints whitespace indention for yaml output. - * @param indent_count - * Number of times to indent - */ -void print_yaml_indent(size_t indent_count); - -/** - * Convert a TPM2B_PUBLIC into a yaml format and output if not quiet. - * @param public - * The TPM2B_PUBLIC to output in YAML format. - */ -void tpm2_util_public_to_yaml(TPM2B_PUBLIC *public); - - -/** - * Convert a TPMA_OBJECT to a yaml format and output if not quiet. - * @param obj - * The TPMA_OBJECT attributes to print. - */ -void tpm2_util_tpma_object_to_yaml(TPMA_OBJECT obj); - -#endif /* STRING_BYTES_H */ diff --git a/TPM2-Plugin/lib/log.c b/TPM2-Plugin/lib/log.c deleted file mode 100644 index 14797e4..0000000 --- a/TPM2-Plugin/lib/log.c +++ /dev/null @@ -1,93 +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 <stdarg.h> -#include <stdbool.h> -#include <stdio.h> - -#include "log.h" - -/* - * Note that the logging library is not thread safe, thus calls on separate - * threads will yield an interleaved output on stderr. - */ - -static log_level current_log_level = log_level_warning; - -void -log_set_level (log_level value) -{ - current_log_level = value; -} - -static const char * -get_level_msg (log_level level) -{ - const char *value = "UNK"; - switch (level) - { - case log_level_error: - value = "ERROR"; - break; - case log_level_warning: - value = "WARN"; - break; - case log_level_verbose: - value = "INFO"; - } - return value; -} - -void -_log (log_level level, const char *file, unsigned lineno, const char *fmt, ...) -{ - - /* Skip printing messages outside of the log level */ - if (level > current_log_level) - return; - - va_list argptr; - va_start(argptr, fmt); - - /* Verbose output prints file and line on error */ - if (current_log_level >= log_level_verbose) - fprintf (stderr, "%s on line: \"%u\" in file: \"%s\": ", - get_level_msg (level), lineno, file); - else - fprintf (stderr, "%s: ", get_level_msg (level)); - - /* Print the user supplied message */ - vfprintf (stderr, fmt, argptr); - - /* always add a new line so the user doesn't have to */ - fprintf (stderr, "\n"); - - va_end(argptr); -} diff --git a/TPM2-Plugin/lib/tpm2_alg_util.c b/TPM2-Plugin/lib/tpm2_alg_util.c deleted file mode 100644 index 3683b6e..0000000 --- a/TPM2-Plugin/lib/tpm2_alg_util.c +++ /dev/null @@ -1,437 +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 <stdbool.h> -#include <stdlib.h> -#include <string.h> - -#include <tss2/tss2_sys.h> - -#include "files.h" -#include "log.h" -#include "tpm2_hash.h" -#include "tpm2_alg_util.h" -#include "tpm2_util.h" - -typedef struct alg_pair alg_pair; -struct alg_pair { - const char *name; - TPM2_ALG_ID id; -}; - -void tpm2_alg_util_for_each_alg(tpm2_alg_util_alg_iteraror iterator, void *userdata) { - - static const alg_pair algs[] = { - { .name = "rsa", .id = TPM2_ALG_RSA }, - { .name = "sha1", .id = TPM2_ALG_SHA1 }, - { .name = "hmac", .id = TPM2_ALG_HMAC }, - { .name = "aes", .id = TPM2_ALG_AES }, - { .name = "mgf1", .id = TPM2_ALG_MGF1 }, - { .name = "keyedhash", .id = TPM2_ALG_KEYEDHASH }, - { .name = "xor", .id = TPM2_ALG_XOR }, - { .name = "sha256", .id = TPM2_ALG_SHA256 }, - { .name = "sha384", .id = TPM2_ALG_SHA384 }, - { .name = "sha512", .id = TPM2_ALG_SHA512 }, - { .name = "null", .id = TPM2_ALG_NULL }, - { .name = "sm3_256", .id = TPM2_ALG_SM3_256 }, - { .name = "sm4", .id = TPM2_ALG_SM4 }, - { .name = "rsassa", .id = TPM2_ALG_RSASSA }, - { .name = "rsaes", .id = TPM2_ALG_RSAES }, - { .name = "rsapss", .id = TPM2_ALG_RSAPSS }, - { .name = "oaep", .id = TPM2_ALG_OAEP }, - { .name = "ecdsa", .id = TPM2_ALG_ECDSA }, - { .name = "ecdh", .id = TPM2_ALG_ECDH }, - { .name = "ecdaa", .id = TPM2_ALG_ECDAA }, - { .name = "sm2", .id = TPM2_ALG_SM2 }, - { .name = "ecschnorr", .id = TPM2_ALG_ECSCHNORR }, - { .name = "ecmqv", .id = TPM2_ALG_ECMQV }, - { .name = "kdf1_sp800_56a", .id = TPM2_ALG_KDF1_SP800_56A }, - { .name = "kdf2", .id = TPM2_ALG_KDF2 }, - { .name = "kdf1_sp800_108", .id = TPM2_ALG_KDF1_SP800_108 }, - { .name = "ecc", .id = TPM2_ALG_ECC }, - { .name = "symcipher", .id = TPM2_ALG_SYMCIPHER }, - { .name = "camellia", .id = TPM2_ALG_CAMELLIA }, - { .name = "sha3_256", .id = TPM2_ALG_SHA3_256 }, - { .name = "sha3_384", .id = TPM2_ALG_SHA3_384 }, - { .name = "sha3_512", .id = TPM2_ALG_SHA3_512 }, - { .name = "ctr", .id = TPM2_ALG_CTR }, - { .name = "ofb", .id = TPM2_ALG_OFB }, - { .name = "cbc", .id = TPM2_ALG_CBC }, - { .name = "cfb", .id = TPM2_ALG_CFB }, - { .name = "ecb", .id = TPM2_ALG_ECB }, - }; - - size_t i; - for (i=0; i < ARRAY_LEN(algs); i++) { - const alg_pair *alg = &algs[i]; - bool result = iterator(alg->id, alg->name, userdata); - if (result) { - return; - } - } -} - -static bool find_match(TPM2_ALG_ID id, const char *name, void *userdata) { - - alg_pair *search_data = (alg_pair *)userdata; - - /* - * if name, then search on name, else - * search by id. - */ - if (search_data->name && !strcmp(search_data->name, name)) { - search_data->id = id; - return true; - } else if (search_data->id == id) { - search_data->name = name; - return true; - } - - return false; -} - -TPM2_ALG_ID tpm2_alg_util_strtoalg(const char *name) { - - alg_pair userdata = { - .name = name, - .id = TPM2_ALG_ERROR - }; - - if (name) { - tpm2_alg_util_for_each_alg(find_match, &userdata); - } - - return userdata.id; -} - -const char *tpm2_alg_util_algtostr(TPM2_ALG_ID id) { - - alg_pair userdata = { - .name = NULL, - .id = id - }; - - tpm2_alg_util_for_each_alg(find_match, &userdata); - - return userdata.name; -} - -TPM2_ALG_ID tpm2_alg_util_from_optarg(char *optarg) { - - TPM2_ALG_ID halg; - bool res = tpm2_util_string_to_uint16(optarg, &halg); - if (!res) { - halg = tpm2_alg_util_strtoalg(optarg); - } - return halg; -} - -bool tpm2_alg_util_is_hash_alg(TPM2_ALG_ID id) { - - switch (id) { - case TPM2_ALG_SHA1 : - /* fallsthrough */ - case TPM2_ALG_SHA256 : - /* fallsthrough */ - case TPM2_ALG_SHA384 : - /* fallsthrough */ - case TPM2_ALG_SHA512 : - /* fallsthrough */ - case TPM2_ALG_SM3_256 : - return true; - /* no default */ - } - - return false; -} - -UINT16 tpm2_alg_util_get_hash_size(TPMI_ALG_HASH id) { - - switch (id) { - case TPM2_ALG_SHA1 : - return TPM2_SHA1_DIGEST_SIZE; - case TPM2_ALG_SHA256 : - return TPM2_SHA256_DIGEST_SIZE; - case TPM2_ALG_SHA384 : - return TPM2_SHA384_DIGEST_SIZE; - case TPM2_ALG_SHA512 : - return TPM2_SHA512_DIGEST_SIZE; - case TPM2_ALG_SM3_256 : - return TPM2_SM3_256_DIGEST_SIZE; - /* no default */ - } - - return 0; -} - -static const char *hex_to_byte_err(int rc) { - - switch (rc) { - case -2: - return "String not even in length"; - case -3: - return "Non hex digit found"; - case -4: - return "Hex value too big for digest"; - } - return "unknown"; -} - -bool pcr_parse_digest_list(char **argv, int len, - tpm2_pcr_digest_spec *digest_spec) { - - /* - * int is chosen because of what is passed in from main, avoids - * sign differences. - * */ - int i; - for (i = 0; i < len; i++) { - tpm2_pcr_digest_spec *dspec = &digest_spec[i]; - - UINT32 count = 0; - - /* - * Split <pcr index>:<hash alg>=<hash value>,... on : and separate with null byte, ie: - * <pce index> '\0' <hash alg>'\0'<data> - * - * Start by splitting out the pcr index, and validating it. - */ - char *spec_str = argv[i]; - char *pcr_index_str = spec_str; - char *digest_spec_str = strchr(spec_str, ':'); - if (!digest_spec_str) { - LOG_ERR("Expecting : in digest spec, not found, got: \"%s\"", spec_str); - return false; - } - - *digest_spec_str = '\0'; - digest_spec_str++; - - bool result = tpm2_util_string_to_uint32(pcr_index_str, &dspec->pcr_index); - if (!result) { - LOG_ERR("Got invalid PCR Index: \"%s\", in digest spec: \"%s\"", - pcr_index_str, spec_str); - return false; - } - - /* now that the pcr_index is removed, parse the remaining <hash_name>=<hash_value>,.. */ - char *digest_hash_tok; - char *save_ptr = NULL; - - /* keep track of digests we have seen */ - - while ((digest_hash_tok = strtok_r(digest_spec_str, ",", &save_ptr))) { - digest_spec_str = NULL; - - if (count >= ARRAY_LEN(dspec->digests.digests)) { - LOG_ERR("Specified too many digests per spec, max is: %zu", - ARRAY_LEN(dspec->digests.digests)); - return false; - } - - TPMT_HA *d = &dspec->digests.digests[count]; - - char *stralg = digest_hash_tok; - char *split = strchr(digest_hash_tok, '='); - if (!split) { - LOG_ERR("Expecting = in <hash alg>=<hash value> spec, got: " - "\"%s\"", digest_hash_tok); - return false; - } - *split = '\0'; - split++; - - char *data = split; - - /* - * Convert and validate the hash algorithm. It should be a hash algorithm - */ - TPM2_ALG_ID alg = tpm2_alg_util_from_optarg(stralg); - if (alg == TPM2_ALG_ERROR) { - LOG_ERR("Could not convert algorithm, got: \"%s\"", stralg); - return false; - } - - bool is_hash_alg = tpm2_alg_util_is_hash_alg(alg); - if (!is_hash_alg) { - LOG_ERR("Algorithm is not a hash algorithm, got: \"%s\"", - stralg); - return false; - } - - d->hashAlg = alg; - - /* fill up the TPMT_HA structure with algorithm and digest */ - BYTE *digest_data = (BYTE *) &d->digest; - - UINT16 expected_hash_size = tpm2_alg_util_get_hash_size(alg); - /* strip any preceding hex on the data as tpm2_util_hex_to_byte_structure doesn't support it */ - bool is_hex = !strncmp("0x", data, 2); - if (is_hex) { - data += 2; - } - - UINT16 size = expected_hash_size; - int rc = tpm2_util_hex_to_byte_structure(data, &size, - digest_data); - if (rc) { - LOG_ERR("Error \"%s\" converting hex string as data, got:" - " \"%s\"", hex_to_byte_err(rc), data); - return false; - } - - if (expected_hash_size != size) { - LOG_ERR( - "Algorithm \"%s\" expects a size of %u bytes, got: %u", - stralg, expected_hash_size, size); - return false; - } - - count++; - } - - if (!count) { - LOG_ERR("Missing or invalid <hash alg>=<hash value> spec for pcr:" - " \"%s\"", pcr_index_str); - return false; - } - - /* assign count at the end, so count is 0 on error */ - dspec->digests.count = count; - } - - return true; -} - -UINT8* tpm2_extract_plain_signature(UINT16 *size, TPMT_SIGNATURE *signature) { - - UINT8 *buffer = NULL; - *size = 0; - - switch (signature->sigAlg) { - case TPM2_ALG_RSASSA: - *size = sizeof(signature->signature.rsassa.sig.buffer); - buffer = malloc(*size); - if (!buffer) { - goto nomem; - } - memcpy(buffer, signature->signature.rsassa.sig.buffer, *size); - break; - case TPM2_ALG_HMAC: { - TPMU_HA *hmac_sig = &(signature->signature.hmac.digest); - *size = tpm2_alg_util_get_hash_size(signature->signature.hmac.hashAlg); - buffer = malloc(*size); - if (!buffer) { - goto nomem; - } - memcpy(buffer, hmac_sig, *size); - break; - } - case TPM2_ALG_ECDSA: { - const size_t ECC_PAR_LEN = sizeof(TPM2B_ECC_PARAMETER); - *size = ECC_PAR_LEN * 2; - buffer = malloc(*size); - if (!buffer) { - goto nomem; - } - memcpy(buffer, - (UINT8*)&(signature->signature.ecdsa.signatureR), - ECC_PAR_LEN - ); - memcpy(buffer + ECC_PAR_LEN, - (UINT8*)&(signature->signature.ecdsa.signatureS), - ECC_PAR_LEN - ); - break; - } - default: - LOG_ERR("%s: unknown signature scheme: 0x%x", __func__, - signature->sigAlg); - return NULL; - } - - return buffer; -nomem: - LOG_ERR("%s: couldn't allocate memory", __func__); - return NULL; -} - -static bool get_key_type(TSS2_SYS_CONTEXT *sapi_context, TPMI_DH_OBJECT objectHandle, - TPMI_ALG_PUBLIC *type) { - - TSS2L_SYS_AUTH_RESPONSE sessions_data_out; - - TPM2B_PUBLIC out_public = TPM2B_EMPTY_INIT; - - TPM2B_NAME name = TPM2B_TYPE_INIT(TPM2B_NAME, name); - - TPM2B_NAME qaulified_name = TPM2B_TYPE_INIT(TPM2B_NAME, name); - - TSS2_RC rval = Tss2_Sys_ReadPublic(sapi_context, objectHandle, 0, &out_public, &name, - &qaulified_name, &sessions_data_out); - if (rval != TPM2_RC_SUCCESS) { - LOG_ERR("Sys_ReadPublic failed, error code: 0x%x", rval); - return false; - } - *type = out_public.publicArea.type; - return true; -} - -bool get_signature_scheme(TSS2_SYS_CONTEXT *sapi_context, - TPMI_DH_OBJECT keyHandle, TPMI_ALG_HASH halg, - TPMT_SIG_SCHEME *scheme) { - - TPM2_ALG_ID type; - bool result = get_key_type(sapi_context, keyHandle, &type); - if (!result) { - return false; - } - - switch (type) { - case TPM2_ALG_RSA : - scheme->scheme = TPM2_ALG_RSASSA; - scheme->details.rsassa.hashAlg = halg; - break; - case TPM2_ALG_KEYEDHASH : - scheme->scheme = TPM2_ALG_HMAC; - scheme->details.hmac.hashAlg = halg; - break; - case TPM2_ALG_ECC : - scheme->scheme = TPM2_ALG_ECDSA; - scheme->details.ecdsa.hashAlg = halg; - break; - case TPM2_ALG_SYMCIPHER : - default: - LOG_ERR("Unknown key type, got: 0x%x", type); - return false; - } - - return true; -} diff --git a/TPM2-Plugin/lib/tpm2_attr_util.c b/TPM2-Plugin/lib/tpm2_attr_util.c deleted file mode 100644 index b21141d..0000000 --- a/TPM2-Plugin/lib/tpm2_attr_util.c +++ /dev/null @@ -1,645 +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 <stdbool.h> -#include <stdlib.h> -#include <string.h> - -#include <tss2/tss2_sys.h> - -#include "log.h" -#include "tpm2_attr_util.h" -#include "tpm2_util.h" - -#define dispatch_no_arg_add(x) \ - { .name = str(x), .callback=(action)x, .width = 1 } - -#define dispatch_arg_add(x, w) \ - { .name = str(x), .callback=(action)x, .width = w } - -#define dispatch_reserved(pos) \ - { .name = "<reserved("xstr(pos)")>", .callback=NULL, .width = 1 } - -typedef enum dispatch_error dispatch_error; -enum dispatch_error { - dispatch_ok = 0, - dispatch_err, - dispatch_no_match, -}; - -typedef bool (*action)(void *obj, char *arg); - -typedef struct dispatch_table dispatch_table; -struct dispatch_table { - char *name; - action callback; - unsigned width; /* the width of the field, CANNOT be 0 */ -}; - -static bool authread(TPMA_NV *nv, char *arg) { - - UNUSED(arg); - *nv |= TPMA_NV_AUTHREAD; - return true; -} - -static bool authwrite(TPMA_NV *nv, char *arg) { - - UNUSED(arg); - *nv |= TPMA_NV_AUTHWRITE; - return true; -} - -static bool clear_stclear(TPMA_NV *nv, char *arg) { - - UNUSED(arg); - *nv |= TPMA_NV_CLEAR_STCLEAR; - return true; -} - -static bool globallock(TPMA_NV *nv, char *arg) { - - UNUSED(arg); - *nv |= TPMA_NV_GLOBALLOCK; - return true; -} - -static bool no_da(TPMA_NV *nv, char *arg) { - - UNUSED(arg); - *nv |= TPMA_NV_NO_DA; - return true; -} - -static bool orderly(TPMA_NV *nv, char *arg) { - - UNUSED(arg); - *nv |= TPMA_NV_ORDERLY; - return true; -} - -static bool ownerread(TPMA_NV *nv, char *arg) { - - UNUSED(arg); - *nv |= TPMA_NV_OWNERREAD; - return true; -} - -static bool ownerwrite(TPMA_NV *nv, char *arg) { - - UNUSED(arg); - *nv |= TPMA_NV_OWNERWRITE; - return true; -} - -static bool platformcreate(TPMA_NV *nv, char *arg) { - - UNUSED(arg); - *nv |= TPMA_NV_PLATFORMCREATE; - return true; -} - -static bool policyread(TPMA_NV *nv, char *arg) { - - UNUSED(arg); - *nv |= TPMA_NV_POLICYREAD; - return true; -} - -static bool policywrite(TPMA_NV *nv, char *arg) { - - UNUSED(arg); - *nv |= TPMA_NV_POLICYWRITE; - return true; -} - -static bool policydelete(TPMA_NV *nv, char *arg) { - - UNUSED(arg); - *nv |= TPMA_NV_POLICY_DELETE; - return true; -} - -static bool ppread(TPMA_NV *nv, char *arg) { - - UNUSED(arg); - *nv |= TPMA_NV_PPREAD; - return true; -} - -static bool ppwrite(TPMA_NV *nv, char *arg) { - - UNUSED(arg); - *nv |= TPMA_NV_PPWRITE; - return true; -} - -static bool readlocked(TPMA_NV *nv, char *arg) { - - UNUSED(arg); - *nv |= TPMA_NV_READLOCKED; - return true; -} - -static bool read_stclear(TPMA_NV *nv, char *arg) { - - UNUSED(arg); - *nv |= TPMA_NV_READ_STCLEAR; - return true; -} - -static bool writeall(TPMA_NV *nv, char *arg) { - - UNUSED(arg); - *nv |= TPMA_NV_WRITEALL; - return true; -} - -static bool writedefine(TPMA_NV *nv, char *arg) { - - UNUSED(arg); - *nv |= TPMA_NV_WRITEDEFINE; - return true; -} - -static bool writelocked(TPMA_NV *nv, char *arg) { - - UNUSED(arg); - *nv |= TPMA_NV_WRITELOCKED; - return true; -} - -static bool write_stclear(TPMA_NV *nv, char *arg) { - - UNUSED(arg); - *nv |= TPMA_NV_WRITE_STCLEAR; - return true; -} - -static bool written(TPMA_NV *nv, char *arg) { - - UNUSED(arg); - *nv |= TPMA_NV_WRITTEN; - return true; -} - -static bool nt(TPMA_NV *nv, char *arg) { - - uint16_t value; - bool result = tpm2_util_string_to_uint16(arg, &value); - if (!result) { - LOG_ERR("Could not convert \"%s\", to a number", arg); - return false; - } - - /* nt space is 4 bits, so max of 15 */ - if (value > 0x0F) { - LOG_ERR("Field TPM_NT of type TPMA_NV is only 4 bits," - "value \"%s\" to big!", arg); - return false; - } - - *nv &= ~TPMA_NV_TPM2_NT_MASK; - *nv |= value << 4; - return true; -} - -/* - * The order of this table must be in order with the bit defines in table 204: - * https://trustedcomputinggroup.org/wp-content/uploads/TPM-Rev-2.0-Part-2-Structures-01.38.pdf - * - * This table is in bitfield order, thus the index of a bit set in a TPMA_NV - * can be used to lookup the name. - * - * if not the logic in tpm2_nv_util_strtoattr would need to change! - */ -static dispatch_table nv_attr_table[] = { // Bit Index - dispatch_no_arg_add(ppwrite), // 0 - dispatch_no_arg_add(ownerwrite), // 1 - dispatch_no_arg_add(authwrite), // 2 - dispatch_no_arg_add(policywrite), // 3 - dispatch_arg_add(nt, 4), // 4 - dispatch_arg_add(nt, 3), // 5 - dispatch_arg_add(nt, 2), // 6 - dispatch_arg_add(nt, 1), // 7 - dispatch_reserved(8), // 8 - dispatch_reserved(9), // 9 - dispatch_no_arg_add(policydelete), // 10 - dispatch_no_arg_add(writelocked), // 11 - dispatch_no_arg_add(writeall), // 12 - dispatch_no_arg_add(writedefine), // 13 - dispatch_no_arg_add(write_stclear), // 14 - dispatch_no_arg_add(globallock), // 15 - dispatch_no_arg_add(ppread), // 16 - dispatch_no_arg_add(ownerread), // 17 - dispatch_no_arg_add(authread), // 18 - dispatch_no_arg_add(policyread), // 19 - dispatch_reserved(20), // 20 - dispatch_reserved(21), // 21 - dispatch_reserved(22), // 22 - dispatch_reserved(23), // 23 - dispatch_reserved(24), // 24 - dispatch_no_arg_add(no_da), // 25 - dispatch_no_arg_add(orderly), // 26 - dispatch_no_arg_add(clear_stclear), // 27 - dispatch_no_arg_add(readlocked), // 28 - dispatch_no_arg_add(written), // 29 - dispatch_no_arg_add(platformcreate), // 30 - dispatch_no_arg_add(read_stclear), // 31 -}; - -static bool fixedtpm(TPMA_OBJECT *obj, char *arg) { - - UNUSED(arg); - *obj |= TPMA_OBJECT_FIXEDTPM; - return true; -} - -static bool stclear(TPMA_OBJECT *obj, char *arg) { - - UNUSED(arg); - *obj |= TPMA_OBJECT_STCLEAR; - return true; -} - -static bool fixedparent(TPMA_OBJECT *obj, char *arg) { - - UNUSED(arg); - *obj |= TPMA_OBJECT_FIXEDPARENT; - return true; -} - -static bool sensitivedataorigin(TPMA_OBJECT *obj, char *arg) { - - UNUSED(arg); - *obj |= TPMA_OBJECT_SENSITIVEDATAORIGIN; - return true; -} - -static bool userwithauth(TPMA_OBJECT *obj, char *arg) { - - UNUSED(arg); - *obj |= TPMA_OBJECT_USERWITHAUTH; - return true; -} - -static bool adminwithpolicy(TPMA_OBJECT *obj, char *arg) { - - UNUSED(arg); - *obj |= TPMA_OBJECT_ADMINWITHPOLICY; - return true; -} - -static bool noda(TPMA_OBJECT *obj, char *arg) { - - UNUSED(arg); - *obj |= TPMA_OBJECT_NODA; - return true; -} - -static bool encryptedduplication(TPMA_OBJECT *obj, char *arg) { - - UNUSED(arg); - *obj |= TPMA_OBJECT_ENCRYPTEDDUPLICATION; - return true; -} - -static bool restricted(TPMA_OBJECT *obj, char *arg) { - - UNUSED(arg); - *obj |= TPMA_OBJECT_RESTRICTED; - return true; -} - -static bool decrypt(TPMA_OBJECT *obj, char *arg) { - - UNUSED(arg); - *obj |= TPMA_OBJECT_DECRYPT; - return true; -} - -static bool sign(TPMA_OBJECT *obj, char *arg) { - - UNUSED(arg); - *obj |= TPMA_OBJECT_SIGN_ENCRYPT; - return true; -} - -static dispatch_table obj_attr_table[] = { // Bit Index - dispatch_reserved(0), // 0 - dispatch_no_arg_add(fixedtpm), // 1 - dispatch_no_arg_add(stclear), // 2 - dispatch_reserved(3), // 3 - dispatch_no_arg_add(fixedparent), // 4 - dispatch_no_arg_add(sensitivedataorigin), // 5 - dispatch_no_arg_add(userwithauth), // 6 - dispatch_no_arg_add(adminwithpolicy), // 7 - dispatch_reserved(8), // 8 - dispatch_reserved(9), // 9 - dispatch_no_arg_add(noda), // 10 - dispatch_no_arg_add(encryptedduplication), // 11 - dispatch_reserved(12), // 12 - dispatch_reserved(13), // 13 - dispatch_reserved(14), // 14 - dispatch_reserved(15), // 15 - dispatch_no_arg_add(restricted), // 16 - dispatch_no_arg_add(decrypt), // 17 - dispatch_no_arg_add(sign), // 18 - dispatch_reserved(19), // 19 - dispatch_reserved(20), // 20 - dispatch_reserved(21), // 21 - dispatch_reserved(22), // 22 - dispatch_reserved(23), // 23 - dispatch_reserved(24), // 24 - dispatch_reserved(25), // 25 - dispatch_reserved(26), // 26 - dispatch_reserved(27), // 27 - dispatch_reserved(28), // 28 - dispatch_reserved(29), // 29 - dispatch_reserved(30), // 30 - dispatch_reserved(31), // 31 -}; - -static bool token_match(const char *name, const char *token, bool has_arg, char **sep) { - - /* if it has an argument, we expect a separator */ - size_t match_len = strlen(token); - if (has_arg) { - *sep = strchr(token, '='); - if (*sep) { - match_len = *sep - token; - } - } - - return !strncmp(name, token, match_len); -} - -static dispatch_error handle_dispatch(dispatch_table *d, char *token, - TPMA_NV *nvattrs) { - - char *name = d->name; - action cb = d->callback; - bool has_arg = d->width > 1; - - /* if no callback, then its a reserved block, just skip it */ - if (!cb) { - return dispatch_no_match; - } - - char *sep = NULL; - bool match = token_match(name, token, has_arg, &sep); - if (!match) { - return dispatch_no_match; - } - - /* - * If it has an argument, match should have found the seperator. - */ - char *arg = NULL; - if (has_arg) { - if (!sep) { - LOG_ERR("Expected argument for \"%s\", got none.", token); - return dispatch_err; - } - - /* split token on = */ - *sep = '\0'; - sep++; - if (!*sep) { - LOG_ERR("Expected argument for \"%s\", got none.", token); - return dispatch_err; - } - - /* valid argument string, assign */ - arg = sep; - } - - bool result = cb(nvattrs, arg); - return result ? dispatch_ok : dispatch_err; -} - -static bool common_strtoattr(char *attribute_list, void *attrs, dispatch_table *table, size_t size) { - - char *token; - char *save; - - /* - * This check is soley to prevent GCC from complaining on: - * error: ‘attribute_list’ may be used uninitialized in this function [-Werror=maybe-uninitialized] - * Might as well check nvattrs as well. - */ - if (!attribute_list || !attrs) { - LOG_ERR("attribute list or attributes structure is NULL"); - return false; - } - - while ((token = strtok_r(attribute_list, "|", &save))) { - attribute_list = NULL; - - bool did_dispatch = false; - - size_t i; - for (i = 0; i < size; i++) { - dispatch_table *d = &table[i]; - - dispatch_error err = handle_dispatch(d, token, attrs); - if (err == dispatch_ok) { - did_dispatch = true; - break; - } else if (err == dispatch_err) { - return false; - } - /* dispatch_no_match --> keep looking */ - } - - /* did we dispatch?, If not log error and return */ - if (!did_dispatch) { - char *tmp = strchr(token, '='); - if (tmp) { - *tmp = '\0'; - } - LOG_ERR("Unknown token: \"%s\" found.", token); - return false; - } - } - - return true; -} - -bool tpm2_attr_util_nv_strtoattr(char *attribute_list, TPMA_NV *nvattrs) { - - return common_strtoattr(attribute_list, nvattrs, nv_attr_table, ARRAY_LEN(nv_attr_table)); -} - -bool tpm2_attr_util_obj_strtoattr(char *attribute_list, TPMA_OBJECT *objattrs) { - - return common_strtoattr(attribute_list, objattrs, obj_attr_table, ARRAY_LEN(obj_attr_table)); -} - - -static UINT8 find_first_set(UINT32 bits) { - - UINT8 n = 0; - - if (!bits) { - return n; - } - - if (!(bits & 0x0000FFFF)) { n += 16; bits >>= 16; } - if (!(bits & 0x000000FF)) { n += 8; bits >>= 8; } - if (!(bits & 0x0000000F)) { n += 4; bits >>= 4; } - if (!(bits & 0x00000003)) { n += 2; bits >>= 2; } - if (!(bits & 0x00000001)) n += 1; - - return n; -} - -static char *tpm2_attr_util_common_attrtostr(UINT32 attrs, dispatch_table *table, size_t size) { - - if (attrs == 0) { - return strdup("<none>"); - } - - /* - * Get how many bits are set in the attributes and then find the longest - * "name". - * - * pop_cnt * max_name_len + pop_cnt - 1 (for the | separators) + 4 - * (for nv field equals in hex) + 1 for null byte. - * - * This will provide us an ample buffer size for generating the string - * in without having to constantly realloc. - */ - UINT32 pop_cnt = tpm2_util_pop_count(attrs); - - size_t i; - size_t max_name_len = 0; - for (i=0; i < size; i++) { - dispatch_table *d = &table[i]; - size_t name_len = strlen(d->name); - max_name_len = name_len > max_name_len ? name_len : max_name_len; - } - - size_t length = pop_cnt * max_name_len + pop_cnt - 1 + 3; - - char *str = calloc(length, 1); - if (!str) { - return NULL; - } - - - size_t string_index = 0; - - /* - * Start at the lowest, first bit set, index into the array, - * grab the data needed, and move on. - */ - while (attrs) { - UINT8 bit_index = find_first_set(attrs); - - dispatch_table *d = &table[bit_index]; - - const char *name = d->name; - unsigned w = d->width; - - /* current position and size left of the string */ - char *s = &str[string_index]; - size_t left = length - string_index; - - /* this is a mask that is field width wide */ - UINT8 mask = ((UINT32)1 << w) - 1; - - /* get the value in the field before clearing attrs out */ - UINT8 field_values = (attrs & mask << bit_index) >> bit_index; - - /* - * turn off the parsed bit(s) index, using width to turn off everything in a - * field - */ - attrs &= ~(mask << bit_index); - - /* - * if the callback is NULL, we are either in a field middle or reserved - * section which is weird, just add the name in. In the case of being - * in the middle of the field, we will add a bunch of errors to the string, - * but it would be better to attempt to show all the data in string form, - * rather than bail. - * - * Fields are either 1 or > 1. - */ - if (w == 1) { - /* - * set the format to a middle output, unless we're parsing - * the first or last. Let the format be static with the routine - * so the compiler can do printf style format specifier checking. - */ - if (!string_index) { - /* on the first write, if we are already done, no pipes */ - string_index += !attrs ? snprintf(s, left, "%s", name) : - snprintf(s, left, "%s|", name); - } else if (!attrs) { - string_index += snprintf(s, left, "%s", name); - } else { - string_index += snprintf(s, left, "%s|", name); - } - } else { - /* deal with the field */ - if (!string_index) { - /* on the first write, if we are already done, no pipes */ - string_index += !attrs ? snprintf(s, left, "%s=0x%X", name, field_values) : - snprintf(s, left, "%s=0x%X|", name, field_values); - } else if (!attrs) { - string_index += snprintf(s, left, "%s=0x%X", name, field_values); - } else { - string_index += snprintf(s, left, "%s=0x%X|", name, field_values); - } - } - } - - return str; -} - -char *tpm2_attr_util_nv_attrtostr(TPMA_NV nvattrs) { - return tpm2_attr_util_common_attrtostr(nvattrs, nv_attr_table, ARRAY_LEN(nv_attr_table)); -} - -char *tpm2_attr_util_obj_attrtostr(TPMA_OBJECT objattrs) { - return tpm2_attr_util_common_attrtostr(objattrs, obj_attr_table, ARRAY_LEN(obj_attr_table)); -} - -bool tpm2_attr_util_obj_from_optarg(char *argvalue, TPMA_OBJECT *objattrs) { - - bool res = tpm2_util_string_to_uint32(argvalue, objattrs); - if (!res) { - res = tpm2_attr_util_obj_strtoattr(argvalue, objattrs); - } - - return res; -} diff --git a/TPM2-Plugin/lib/tpm2_convert.c b/TPM2-Plugin/lib/tpm2_convert.c deleted file mode 100644 index 9b09c81..0000000 --- a/TPM2-Plugin/lib/tpm2_convert.c +++ /dev/null @@ -1,216 +0,0 @@ -//**********************************************************************; -// Copyright (c) 2017, SUSE Linux GmbH -// 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 <string.h> -#include <errno.h> - -#include <openssl/rsa.h> -#include <openssl/pem.h> -#include <openssl/bn.h> -#include <openssl/err.h> - -#include "files.h" -#include "log.h" -#include "tpm2_alg_util.h" -#include "tpm2_convert.h" -#include "tpm2_util.h" - -static bool tpm2_convert_pubkey_ssl(TPMT_PUBLIC *public, tpm2_convert_pubkey_fmt format, const char *path); - -tpm2_convert_pubkey_fmt tpm2_convert_pubkey_fmt_from_optarg(const char *label) { - if (strcasecmp(label, "der") == 0) { - return pubkey_format_der; - } - else if (strcasecmp(label, "pem") == 0) { - return pubkey_format_pem; - } - else if (strcasecmp(label, "tss") == 0) { - return pubkey_format_tss; - } - - LOG_ERR("Invalid public key output format '%s' specified", label); - - return pubkey_format_err; -} - -tpm2_convert_sig_fmt tpm2_convert_sig_fmt_from_optarg(const char *label) { - if (strcasecmp(label, "tss") == 0) { - return signature_format_tss; - } - else if (strcasecmp(label, "plain") == 0) { - return signature_format_plain; - } - - LOG_ERR("Invalid signature output format '%s' specified", label); - - return signature_format_err; -} - -static void print_ssl_error(const char *failed_action) { - char errstr[256] = {0}; - unsigned long errnum = ERR_get_error(); - - ERR_error_string_n(errnum, errstr, sizeof(errstr)); - LOG_ERR("%s: %s", failed_action, errstr); -} - -bool tpm2_convert_pubkey_save(TPM2B_PUBLIC *public, tpm2_convert_pubkey_fmt format, const char *path) { - - if (format == pubkey_format_der || format == pubkey_format_pem) { - return tpm2_convert_pubkey_ssl(&public->publicArea, format, path); - } - else if (format == pubkey_format_tss) { - return files_save_public(public, path); - } - - LOG_ERR("Unsupported public key output format."); - return false; -} - -static bool tpm2_convert_pubkey_ssl(TPMT_PUBLIC *public, tpm2_convert_pubkey_fmt format, const char *path) { - bool ret = false; - FILE *fp = NULL; - RSA *ssl_rsa_key = NULL; - BIGNUM *e = NULL, *n = NULL; - - // need this before the first SSL call for getting human readable error - // strings in print_ssl_error() - ERR_load_crypto_strings(); - - if (public->type != TPM2_ALG_RSA) { - LOG_ERR("Unsupported key type for requested output format. Only RSA is supported."); - goto error; - } - - UINT32 exponent = (public->parameters).rsaDetail.exponent; - if (exponent == 0) { - exponent = 0x10001; - } - - // OpenSSL expects this in network byte order - exponent = tpm2_util_hton_32(exponent); - ssl_rsa_key = RSA_new(); - if (!ssl_rsa_key) { - print_ssl_error("Failed to allocate OpenSSL RSA structure"); - goto error; - } - - e = BN_bin2bn((void*)&exponent, sizeof(exponent), NULL); - n = BN_bin2bn(public->unique.rsa.buffer, public->unique.rsa.size, - NULL); - - if (!n || !e) { - print_ssl_error("Failed to convert data to SSL internal format"); - goto error; - } - -#if OPENSSL_VERSION_NUMBER < 0x1010000fL || defined(LIBRESSL_VERSION_NUMBER) /* OpenSSL 1.1.0 */ - ssl_rsa_key->e = e; - ssl_rsa_key->n = n; -#else - if (!RSA_set0_key(ssl_rsa_key, n, e, NULL)) { - print_ssl_error("Failed to set RSA modulus and exponent components"); - goto error; - } -#endif - - /* modulus and exponent components are now owned by the RSA struct */ - n = e = NULL; - - fp = fopen(path, "wb"); - if (!fp) { - LOG_ERR("Failed to open public key output file '%s': %s", - path, strerror(errno)); - goto error; - } - - int ssl_res = 0; - - switch(format) { - case pubkey_format_pem: - ssl_res = PEM_write_RSA_PUBKEY(fp, ssl_rsa_key); - break; - case pubkey_format_der: - ssl_res = i2d_RSA_PUBKEY_fp(fp, ssl_rsa_key); - break; - default: - LOG_ERR("Invalid OpenSSL target format %d encountered", format); - goto error; - } - - if (ssl_res <= 0) { - print_ssl_error("OpenSSL public key conversion failed"); - goto error; - } - - ret = true; - -error: - if (fp) { - fclose(fp); - } - if (n) { - BN_free(n); - } - if (e) { - BN_free(e); - } - if (ssl_rsa_key) { - RSA_free(ssl_rsa_key); - } - ERR_free_strings(); - - return ret; -} - -bool tpm2_convert_sig(TPMT_SIGNATURE *signature, tpm2_convert_sig_fmt format, const char *path) { - - switch(format) { - case signature_format_tss: - return files_save_signature(signature, path); - case signature_format_plain: { - UINT8 *buffer; - UINT16 size; - - buffer = tpm2_extract_plain_signature(&size, signature); - if (buffer == NULL) { - return false; - } - - bool ret = files_save_bytes_to_file(path, buffer, size); - free(buffer); - return ret; - } - default: - LOG_ERR("Unsupported signature output format."); - return false; - } -} diff --git a/TPM2-Plugin/lib/tpm2_error.c b/TPM2-Plugin/lib/tpm2_error.c deleted file mode 100644 index 32eeb41..0000000 --- a/TPM2-Plugin/lib/tpm2_error.c +++ /dev/null @@ -1,871 +0,0 @@ -//**********************************************************************; -// Copyright (c) 2018, 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. -// -// 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 <stdarg.h> -#include <stdbool.h> -#include <stdio.h> -#include <string.h> - -#include <tss2/tss2_sys.h> - -#include "tpm2_error.h" -#include "tpm2_util.h" - -/** - * The maximum size of a layer name. - */ -#define TSS2_ERR_LAYER_NAME_MAX 4 - -/** - * The maximum size for layer specific error strings. - */ -#define TSS2_ERR_LAYER_ERROR_STR_MAX 512 - -/** - * Concatenates (safely) onto a static buffer given a format and varaidic - * arguments similar to sprintf. - * @param b - * The static buffer to concatenate onto. - * @param fmt - * The format specifier as understood by printf followed by the variadic - * parameters for the specifier. - */ -#define catbuf(b, fmt, ...) _catbuf(b, sizeof(b), fmt, ##__VA_ARGS__) - -/** - * Clears out a static buffer by setting index 0 to the null byte. - * @param buffer - * The buffer to clear out. - */ -static void clearbuf(char *buffer) { - buffer[0] = '\0'; -} - -/** - * Prints to a buffer using snprintf(3) using the supplied fmt - * and varaiadic arguments. - * @param buf - * The buffer to print into. - * @param len - * The length of that buffer. - * @param fmt - * The format string - * @warning - * DO NOT CALL DIRECTLY, use the catbuf() macro. - */ -static void COMPILER_ATTR(format (printf, 3, 4)) -_catbuf(char *buf, size_t len, const char *fmt, ...) { - va_list argptr; - va_start(argptr, fmt); - size_t offset = strlen(buf); - vsnprintf(&buf[offset], len - offset, fmt, argptr); - va_end(argptr); -} - -/** - * Retrieves the layer number. The layer number is in the 3rd - * octet and is thus 1 byte big. - * - * @param rc - * The rc to query for the layer number. - * @return - * The layer number. - */ -static inline UINT8 tss2_rc_layer_number_get(TSS2_RC rc) { - return ((rc & TSS2_RC_LAYER_MASK) >> TSS2_RC_LAYER_SHIFT); -} - -/** - * Queries a TPM format 1 error codes N field. The N field - * is a 4 bit field located at bits 8:12. - * @param rc - * The rc to query the N field for. - * @return - * The N field value. - */ -static inline UINT8 tpm2_rc_fmt1_N_get(TPM2_RC rc) { - return ((rc & (0xF << 8)) >> 8); -} - -/** - * Queries the index bits out of the N field contained in a TPM format 1 - * error code. The index bits are the low 3 bits of the N field. - * @param rc - * The TPM format 1 error code to query for the index bits. - * @return - * The index bits from the N field. - */ -static inline UINT8 tpm2_rc_fmt1_N_index_get(TPM2_RC rc) { - return (tpm2_rc_fmt1_N_get(rc) & 0x7); -} - -/** - * Determines if the N field in a TPM format 1 error code is - * a handle or not. - * @param rc - * The TPM format 1 error code to query. - * @return - * True if it is a handle, false otherwise. - */ -static inline bool tpm2_rc_fmt1_N_is_handle(TPM2_RC rc) { - return ((tpm2_rc_fmt1_N_get(rc) & 0x8) == 0); -} - -static inline UINT8 tpm2_rc_fmt1_P_get(TPM2_RC rc) { - return ((rc & (1 << 6)) >> 6); -} - -static inline UINT16 tpm2_rc_fmt1_error_get(TPM2_RC rc) { - return (rc & 0x3F); -} - -static inline UINT16 tpm2_rc_fmt0_error_get(TPM2_RC rc) { - return (rc & 0x7F); -} - -static inline UINT8 tpm2_rc_tpm_fmt0_V_get(TPM2_RC rc) { - return ((rc & (1 << 8)) >> 8); -} - -static inline UINT8 tpm2_rc_fmt0_T_get(TPM2_RC rc) { - return ((rc & (1 << 10)) >> 8); -} - -static inline UINT8 tpm2_rc_fmt0_S_get(TSS2_RC rc) { - return ((rc & (1 << 11)) >> 8); -} - -/** - * Helper macro for adding a layer handler to the layer - * registration array. - */ -#define ADD_HANDLER(name, handler) \ - { name, handler } - -/** - * Same as ADD_HANDLER but sets it to NULL. Used as a placeholder - * for non-registered indexes into the handler array. - */ -#define ADD_NULL_HANDLER ADD_HANDLER(NULL, NULL) - -static const char *tpm2_err_handler_fmt1(TPM2_RC rc) { - - /* - * format 1 error codes start at 1, so - * add a NULL entry to index 0. - */ - static const char *fmt1_err_strs[] = { - // 0x0 - EMPTY - NULL, - // 0x1 - TPM2_RC_ASYMMETRIC - "asymmetric algorithm not supported or not correct", - // 0x2 - TPM2_RC_ATTRIBUTES - "inconsistent attributes", - // 0x3 - TPM2_RC_HASH - "hash algorithm not supported or not appropriate", - // 0x4 - TPM2_RC_VALUE - "value is out of range or is not correct for the context", - // 0x5 - TPM2_RC_HIERARCHY - "hierarchy is not enabled or is not correct for the use", - // 0x6 - EMPTY - NULL, - // 0x7 - TPM2_RC_KEY_SIZE - "key size is not supported", - // 0x8 - TPM2_RC_MGF - "mask generation function not supported", - // 0x9 - TPM2_RC_MODE - "mode of operation not supported", - // 0xA - TPM2_RC_TYPE - "the type of the value is not appropriate for the use", - // 0xB - TPM2_RC_HANDLE - "the handle is not correct for the use", - // 0xC - TPM2_RC_KDF - "unsupported key derivation function or function not appropriate for " - "use", - // 0xD - TPM2_RC_RANGE - "value was out of allowed range", - // 0xE - TPM2_RC_AUTH_FAIL - "the authorization HMAC check failed and DA counter incremented", - // 0xF - TPM2_RC_NONCE - "invalid nonce size or nonce value mismatch", - // 0x10 - TPM2_RC_PP - "authorization requires assertion of PP", - // 0x11 - EMPTY - NULL, - // 0x12 - TPM2_RC_SCHEME - "unsupported or incompatible scheme", - // 0x13 - EMPTY - NULL, - // 0x14 - EMPTY - NULL, - // 0x15 - TPM2_RC_SIZE - "structure is the wrong size", - // 0x16 - TPM2_RC_SYMMETRIC - "unsupported symmetric algorithm or key size, or not appropriate for" - " instance", - // 0x17 - TPM2_RC_TAG - "incorrect structure tag", - // 0x18 - TPM2_RC_SELECTOR - "union selector is incorrect", - // 0x19 - EMPTY - NULL, - // 0x1A - TPM2_RC_INSUFFICIENT - "the TPM was unable to unmarshal a value because there were not enough" - " octets in the input buffer", - // 0x1B - TPM2_RC_SIGNATURE - "the signature is not valid", - // 0x1C - TPM2_RC_KEY - "key fields are not compatible with the selected use", - // 0x1D - TPM2_RC_POLICY_FAIL - "a policy check failed", - // 0x1E - EMPTY - NULL, - // 0x1F - TPM2_RC_INTEGRITY - "integrity check failed", - // 0x20 - TPM2_RC_TICKET - "invalid ticket", - // 0x21 - TPM2_RC_RESERVED_BITS - "reserved bits not set to zero as required", - // 0x22 - TPM2_RC_BAD_AUTH - "authorization failure without DA implications", - // 0x23 - TPM2_RC_EXPIRED - "the policy has expired", - // 0x24 - TPM2_RC_POLICY_CC - "the commandCode in the policy is not the commandCode of the command" - " or the command code in a policy command references a command that" - " is not implemented", - // 0x25 - TPM2_RC_BINDING - "public and sensitive portions of an object are not cryptographically bound", - // 0x26 - TPM2_RC_CURVE - "curve not supported", - // 0x27 - TPM2_RC_ECC_POINT - "point is not on the required curve", - }; - - static char buf[TSS2_ERR_LAYER_ERROR_STR_MAX + 1]; - - clearbuf(buf); - - /* Print whether or not the error is caused by a bad - * handle or parameter. On the case of a Handle (P == 0) - * then the N field top bit will be set. Un-set this bit - * to get the handle index by subtracting 8 as N is a 4 - * bit field. - * - * the lower 3 bits of N indicate index, and the high bit - * indicates - */ - UINT8 index = tpm2_rc_fmt1_N_index_get(rc); - - bool is_handle = tpm2_rc_fmt1_N_is_handle(rc); - const char *m = tpm2_rc_fmt1_P_get(rc) ? "parameter" : - is_handle ? "handle" : "session"; - catbuf(buf, "%s", m); - - if (index) { - catbuf(buf, "(%u):", index); - } else { - catbuf(buf, "%s", "(unk):"); - } - - UINT8 errnum = tpm2_rc_fmt1_error_get(rc); - if (errnum < ARRAY_LEN(fmt1_err_strs)) { - m = fmt1_err_strs[errnum]; - catbuf(buf, "%s", m); - } else { - catbuf(buf, "unknown error num: 0x%X", errnum); - } - - return buf; -} - -static const char *tpm2_err_handler_fmt0(TSS2_RC rc) { - - /* - * format 0 error codes start at 1, so - * add a NULL entry to index 0. - * Thus, no need to offset the error bits - * and fmt0 and fmt1 arrays can be used - * in-place of each other for lookups. - */ - static const char *fmt0_warn_strs[] = { - // 0x0 - EMPTY - NULL, - // 0x1 - TPM2_RC_CONTEXT_GAP - "gap for context ID is too large", - // 0x2 - TPM2_RC_OBJECT_MEMORY - "out of memory for object contexts", - // 0x3 - TPM2_RC_SESSION_MEMORY - "out of memory for session contexts", - // 0x4 - TPM2_RC_MEMORY - "out of shared object/session memory or need space for internal" - " operations", - // 0x5 - TPM2_RC_SESSION_HANDLES - "out of session handles", - // 0x6 - TPM2_RC_OBJECT_HANDLES - "out of object handles", - // 0x7 - TPM2_RC_LOCALITY - "bad locality", - // 0x8 - TPM2_RC_YIELDED - "the TPM has suspended operation on the command; forward progress" - " was made and the command may be retried", - // 0x9 - TPM2_RC_CANCELED - "the command was canceled", - // 0xA - TPM2_RC_TESTING - "TPM is performing self-tests", - // 0xB - EMPTY - NULL, - // 0xC - EMPTY - NULL, - // 0xD - EMPTY - NULL, - // 0xE - EMPTY - NULL, - // 0xF - EMPTY - NULL, - // 0x10 - TPM2_RC_REFERENCE_H0 - "the 1st handle in the handle area references a transient object" - " or session that is not loaded", - // 0x11 - TPM2_RC_REFERENCE_H1 - "the 2nd handle in the handle area references a transient object" - " or session that is not loaded", - // 0x12 - TPM2_RC_REFERENCE_H2 - "the 3rd handle in the handle area references a transient object" - " or session that is not loaded", - // 0x13 - TPM2_RC_REFERENCE_H3 - "the 4th handle in the handle area references a transient object" - " or session that is not loaded", - // 0x14 - TPM2_RC_REFERENCE_H4 - "the 5th handle in the handle area references a transient object" - " or session that is not loaded", - // 0x15 - TPM2_RC_REFERENCE_H5 - "the 6th handle in the handle area references a transient object" - " or session that is not loaded", - // 0x16 - TPM2_RC_REFERENCE_H6 - "the 7th handle in the handle area references a transient object" - " or session that is not loaded", - // 0x17 - EMPTY, - // 0x18 - TPM2_RC_REFERENCE_S0 - "the 1st authorization session handle references a session that" - " is not loaded", - // 0x19 - TPM2_RC_REFERENCE_S1 - "the 2nd authorization session handle references a session that" - " is not loaded", - // 0x1A - TPM2_RC_REFERENCE_S2 - "the 3rd authorization session handle references a session that" - " is not loaded", - // 0x1B - TPM2_RC_REFERENCE_S3 - "the 4th authorization session handle references a session that" - " is not loaded", - // 0x1C - TPM2_RC_REFERENCE_S4 - "the 5th authorization session handle references a session that" - " is not loaded", - // 0x1D - TPM2_RC_REFERENCE_S5 - "the 6th authorization session handle references a session that" - " is not loaded", - // 0x1E - TPM2_RC_REFERENCE_S6 - "the 7th authorization session handle references a session that" - " is not loaded", - // 0x20 -TPM2_RC_NV_RATE - "the TPM is rate-limiting accesses to prevent wearout of NV", - // 0x21 - TPM2_RC_LOCKOUT - "authorizations for objects subject to DA protection are not" - " allowed at this time because the TPM is in DA lockout mode", - // 0x22 - TPM2_RC_RETRY - "the TPM was not able to start the command", - // 0x23 - TPM2_RC_NV_UNAVAILABLE - "the command may require writing of NV and NV is not current" - " accessible", - }; - - /* - * format 1 error codes start at 0, so - * no need to offset the error bits. - */ - static const char *fmt0_err_strs[] = { - // 0x0 - TPM2_RC_INITIALIZE - "TPM not initialized by TPM2_Startup or already initialized", - // 0x1 - TPM2_RC_FAILURE - "commands not being accepted because of a TPM failure", - // 0x2 - EMPTY - NULL, - // 0x3 - TPM2_RC_SEQUENCE - "improper use of a sequence handle", - // 0x4 - EMPTY - NULL, - // 0x5 - EMPTY - NULL, - // 0x6 - EMPTY - NULL, - // 0x7 - EMPTY - NULL, - // 0x8 - EMPTY - NULL, - // 0x9 - EMPTY - NULL, - // 0xA - EMPTY - NULL, - // 0xB - TPM2_RC_PRIVATE - "not currently used", - // 0xC - EMPTY - NULL, - // 0xD - EMPTY - NULL, - // 0xE - EMPTY - NULL, - // 0xF - EMPTY - NULL, - // 0x10 - EMPTY - NULL, - // 0x11 - EMPTY - NULL, - // 0x12 - EMPTY - NULL, - // 0x13 - EMPTY - NULL, - // 0x14 - EMPTY - NULL, - // 0x15 - EMPTY - NULL, - // 0x16 - EMPTY - NULL, - // 0x17 - EMPTY - NULL, - // 0x18 - EMPTY - NULL, - // 0x19 - TPM2_RC_HMAC - "not currently used", - // 0x1A - EMPTY - NULL, - // 0x1B - EMPTY - NULL, - // 0x1C - EMPTY - NULL, - // 0x1D - EMPTY - NULL, - // 0x1E - EMPTY - NULL, - // 0x1F - EMPTY - NULL, - // 0x20 - TPM2_RC_DISABLED - "the command is disabled", - // 0x21 - TPM2_RC_EXCLUSIVE - "command failed because audit sequence required exclusivity", - // 0x22 - EMPTY - NULL, - // 0x23 - EMPTY, - NULL, - // 0x24 - TPM2_RC_AUTH_TYPE - "authorization handle is not correct for command", - // 0x25 - TPM2_RC_AUTH_MISSING - "command requires an authorization session for handle and it is" - " not present", - // 0x26 - TPM2_RC_POLICY - "policy failure in math operation or an invalid authPolicy value", - // 0x27 - TPM2_RC_PCR - "PCR check fail", - // 0x28 - TPM2_RC_PCR_CHANGED - "PCR have changed since checked", - // 0x29 - EMPTY - NULL, - // 0x2A - EMPTY - NULL, - // 0x2B - EMPTY - NULL, - // 0x2C - EMPTY - NULL, - // 0x2D - TPM2_RC_UPGRADE - "TPM is in field upgrade mode unless called via" - " TPM2_FieldUpgradeData(), then it is not in field upgrade mode", - // 0x2E - TPM2_RC_TOO_MANY_CONTEXTS - "context ID counter is at maximum", - // 0x2F - TPM2_RC_AUTH_UNAVAILABLE - "authValue or authPolicy is not available for selected entity", - // 0x30 - TPM2_RC_REBOOT - "a _TPM_Init and Startup(CLEAR) is required before the TPM can" - " resume operation", - // 0x31 - TPM2_RC_UNBALANCED - "the protection algorithms (hash and symmetric) are not reasonably" - " balanced. The digest size of the hash must be larger than the key" - " size of the symmetric algorithm.", - // 0x32 - EMPTY - NULL, - // 0x33 - EMPTY - NULL, - // 0x34 - EMPTY - NULL, - // 0x35 - EMPTY - NULL, - // 0x36 - EMPTY - NULL, - // 0x37 - EMPTY - NULL, - // 0x38 - EMPTY - NULL, - // 0x39 - EMPTY - NULL, - // 0x3A - EMPTY - NULL, - // 0x3B - EMPTY - NULL, - // 0x3C - EMPTY - NULL, - // 0x3D - EMPTY - NULL, - // 0x3E - EMPTY - NULL, - // 0x3F - EMPTY - NULL, - // 0x40 - EMPTY - NULL, - // 0x41 - EMPTY - NULL, - // 0x42 - TPM2_RC_COMMAND_SIZE - "command commandSize value is inconsistent with contents of the" - " command buffer; either the size is not the same as the octets" - " loaded by the hardware interface layer or the value is not large" - " enough to hold a command header", - // 0x43 - TPM2_RC_COMMAND_CODE - "command code not supported", - // 0x44 - TPM2_RC_AUTHSIZE - "the value of authorizationSize is out of range or the number of" - " octets in the Authorization Area is greater than required", - // 0x45 - TPM2_RC_AUTH_CONTEXT - "use of an authorization session with a context command or another" - " command that cannot have an authorization session", - // 0x46 - TPM2_RC_NV_RANGE - "NV offset+size is out of range", - // 0x47 - TPM2_RC_NV_SIZE - "Requested allocation size is larger than allowed", - // 0x48 - TPM2_RC_NV_LOCKED - "NV access locked", - // 0x49 - TPM2_RC_NV_AUTHORIZATION - "NV access authorization fails in command actions", - // 0x4A - TPM2_RC_NV_UNINITIALIZED - "an NV Index is used before being initialized or the state saved" - " by TPM2_Shutdown(STATE) could not be restored", - // 0x4B - TPM2_RC_NV_SPACE - "insufficient space for NV allocation", - // 0x4C - TPM2_RC_NV_DEFINED - "NV Index or persistent object already defined", - // 0x4D - EMPTY - NULL, - // 0x4E - EMPTY - NULL, - // 0x4F - EMPTY - NULL, - // 0x50 - TPM2_RC_BAD_CONTEXT - "context in TPM2_ContextLoad() is not valid", - // 0x51 - TPM2_RC_CPHASH - "cpHash value already set or not correct for use", - // 0x52 - TPM2_RC_PARENT - "handle for parent is not a valid parent", - // 0x53 - TPM2_RC_NEEDS_TEST - "some function needs testing", - // 0x54 - TPM2_RC_NO_RESULT - "returned when an internal function cannot process a request due to" - " an unspecified problem. This code is usually related to invalid" - " parameters that are not properly filtered by the input" - " unmarshaling code", - // 0x55 - TPM2_RC_SENSITIVE - "the sensitive area did not unmarshal correctly after decryption", - }; - - static char buf[TSS2_ERR_LAYER_ERROR_STR_MAX + 1]; - - clearbuf(buf); - - char *e = tpm2_rc_fmt0_S_get(rc) ? "warn" : "error"; - char *v = tpm2_rc_tpm_fmt0_V_get(rc) ? "2.0" : "1.2"; - catbuf(buf, "%s(%s): ", e, v); - - UINT8 errnum = tpm2_rc_fmt0_error_get(rc); - /* We only have version 2.0 spec codes defined */ - if (tpm2_rc_tpm_fmt0_V_get(rc)) { - /* TCG specific error code */ - if (tpm2_rc_fmt0_T_get(rc)) { - catbuf(buf, "Vendor specific error: 0x%X", errnum); - return buf; - } - - /* is it a warning (version 2 error string) or is it a 1.2 error? */ - size_t len = - tpm2_rc_fmt0_S_get(rc) ? - ARRAY_LEN(fmt0_warn_strs) : ARRAY_LEN(fmt0_err_strs); - const char **selection = - tpm2_rc_fmt0_S_get(rc) ? fmt0_warn_strs : fmt0_err_strs; - if (errnum >= len) { - return NULL; - } - - const char *m = selection[errnum]; - if (!m) { - return NULL; - } - - catbuf(buf, "%s", m); - return buf; - } - - catbuf(buf, "%s", "unknown version 1.2 error code"); - - return buf; -} - -/** - * Retrieves the layer field from a TSS2_RC code. - * @param rc - * The rc to query the layer index of. - * @return - * The layer index. - */ -static inline UINT8 tss2_rc_layer_format_get(TSS2_RC rc) { - - return ((rc & (1 << 7)) >> 7); -} - -/** - * Handler for tpm2 error codes. ie codes - * coming from the tpm layer aka layer 0. - * @param rc - * The rc to decode. - * @return - * An error string. - */ -static const char *tpm2_ehandler(TSS2_RC rc) { - - bool is_fmt_1 = tss2_rc_layer_format_get(rc); - - return is_fmt_1 ? tpm2_err_handler_fmt1(rc) : tpm2_err_handler_fmt0(rc); -} - -/** - * The default system code handler. This handles codes - * from the RM (itself and simlated tpm responses), the marshaling - * library (mu), and the tcti layers. - * @param rc - * The rc to decode. - * @return - * An error string. - */ -static const char *sys_err_handler (TSS2_RC rc) { - UNUSED(rc); - - /* - * subtract 1 from the error number - * before indexing into this array. - * - * Commented offsets are for the corresponding - * error number *before* subtraction. Ie error - * number 4 is at array index 3. - */ - static const char *errors[] = { - // 1 - TSS2_BASE_RC_GENERAL_FAILURE - "Catch all for all errors not otherwise specified", - // 2 - TSS2_BASE_RC_NOT_IMPLEMENTED - "If called functionality isn't implemented", - // 3 - TSS2_BASE_RC_BAD_CONTEXT - "A context structure is bad", - // 4 - TSS2_BASE_RC_ABI_MISMATCH - "Passed in ABI version doesn't match called module's ABI version", - // 5 - TSS2_BASE_RC_BAD_REFERENCE - "A pointer is NULL that isn't allowed to be NULL.", - // 6 - TSS2_BASE_RC_INSUFFICIENT_BUFFER - "A buffer isn't large enough", - // 7 - TSS2_BASE_RC_BAD_SEQUENCE - "Function called in the wrong order", - // 8 - TSS2_BASE_RC_NO_CONNECTION - "Fails to connect to next lower layer", - // 9 - TSS2_BASE_RC_TRY_AGAIN - "Operation timed out; function must be called again to be completed", - // 10 - TSS2_BASE_RC_IO_ERROR - "IO failure", - // 11 - TSS2_BASE_RC_BAD_VALUE - "A parameter has a bad value", - // 12 - TSS2_BASE_RC_NOT_PERMITTED - "Operation not permitted.", - // 13 - TSS2_BASE_RC_INVALID_SESSIONS - "Session structures were sent, but command doesn't use them or doesn't" - " use the specified number of them", - // 14 - TSS2_BASE_RC_NO_DECRYPT_PARAM - "If function called that uses decrypt parameter, but command doesn't" - " support decrypt parameter.", - // 15 - TSS2_BASE_RC_NO_ENCRYPT_PARAM - "If function called that uses encrypt parameter, but command doesn't" - " support decrypt parameter.", - // 16 - TSS2_BASE_RC_BAD_SIZE - "If size of a parameter is incorrect", - // 17 - TSS2_BASE_RC_MALFORMED_RESPONSE - "Response is malformed", - // 18 - TSS2_BASE_RC_INSUFFICIENT_CONTEXT - "Context not large enough", - // 19 - TSS2_BASE_RC_INSUFFICIENT_RESPONSE - "Response is not long enough", - // 20 - TSS2_BASE_RC_INCOMPATIBLE_TCTI - "Unknown or unusable TCTI version", - // 21 - TSS2_BASE_RC_NOT_SUPPORTED - "Functionality not supported", - // 22 - TSS2_BASE_RC_BAD_TCTI_STRUCTURE - "TCTI context is bad" - }; - - return (rc - 1u < ARRAY_LEN(errors)) ? errors[rc - 1u] : NULL; -} - - -static struct { - const char *name; - tpm2_error_handler handler; -} layer_handler[TPM2_ERROR_TSS2_RC_LAYER_COUNT] = { - ADD_HANDLER("tpm" , tpm2_ehandler), - ADD_NULL_HANDLER, // layer 1 is unused - ADD_NULL_HANDLER, // layer 2 is unused - ADD_NULL_HANDLER, // layer 3 is unused - ADD_NULL_HANDLER, // layer 4 is unused - ADD_NULL_HANDLER, // layer 5 is unused - ADD_NULL_HANDLER, // layer 6 is the feature rc - ADD_HANDLER("fapi", NULL), // layer 7 is the esapi rc - ADD_HANDLER("sys", sys_err_handler), // layer 8 is the sys rc - ADD_HANDLER("mu", sys_err_handler), // layer 9 is the mu rc - // Defaults to the system handler - ADD_HANDLER("tcti", sys_err_handler), // layer 10 is the tcti rc - // Defaults to the system handler - ADD_HANDLER("rmt", tpm2_ehandler), // layer 11 is the resource manager TPM RC - // The RM usually duplicates TPM responses - // So just default the handler to tpm2. - ADD_HANDLER("rm", NULL), // layer 12 is the rm rc - ADD_HANDLER("drvr", NULL), // layer 13 is the driver rc -}; - -/** - * Determines if the layer allowed to be registered to. - * @param layer - * The layer to determine handler assignment eligibility of. - * @return - * True if it is reserved and thus non-assignable, false otherwise. - */ -static bool is_reserved_layer(UINT8 layer) { - return layer == 0; -} - -/** - * If a layer has no handler registered, default to this - * handler that prints the error number in hex. - * @param rc - * The rc to print the error number of. - * @return - * The string. - */ -static const char *unkown_layer_handler(TSS2_RC rc) { - UNUSED(rc); - - static char buf[32]; - - clearbuf(buf); - catbuf(buf, "0x%X", tpm2_error_get(rc)); - - return buf; -} - -/** - * Register or unregister a custom layer error handler. - * @param layer - * The layer in which to register a handler for. It is an error - * to register for the following reserved layers: - * - TSS2_TPM_RC_LAYER - layer 0 - * - TSS2_SYS_RC_LAYER - layer 8 - * - TSS2_MU_RC_LAYER - layer 9 - * - TSS2_TCTI_RC_LAYER - layer 10 - * @param name - * A friendly layer name. It is an error for the name to be of - * length 0 or greater than 4. - * @param handler - * The handler function to register or NULL to unregister. - * @return - * True on success or False on error. - */ -bool tpm2_error_set_handler(UINT8 layer, const char *name, - tpm2_error_handler handler) { - - /* don't allow setting reserved layers */ - if (is_reserved_layer(layer)) { - return false; - } - - /* - * if they are clearing the handler, name doesn't matter - * clear it too. - */ - if (!handler) { - name = NULL; - } - - /* Perform a zero and max-name length check if name is being set */ - if (name) { - size_t len = name ? strlen(name) : 0; - if (!len || len > TSS2_ERR_LAYER_NAME_MAX) - return false; - } - - layer_handler[layer].handler = handler; - layer_handler[layer].name = name; - - return true; -} - -const char * tpm2_error_str(TSS2_RC rc) { - - static char buf[TSS2_ERR_LAYER_NAME_MAX + TSS2_ERR_LAYER_ERROR_STR_MAX + 1]; - - clearbuf(buf); - - UINT8 layer = tss2_rc_layer_number_get(rc); - - tpm2_error_handler handler = layer_handler[layer].handler; - const char *lname = layer_handler[layer].name; - - if (lname) { - catbuf(buf, "%s:", lname); - } else { - catbuf(buf, "%u:", layer); - } - - handler = !handler ? unkown_layer_handler : handler; - - // Handlers only need the error bits. This way they don't - // need to concern themselves with masking off the layer - // bits or anything else. - UINT16 err_bits = tpm2_error_get(rc); - const char *e = err_bits ? handler(err_bits) : "success"; - if (e) { - catbuf(buf, "%s", e); - } else { - catbuf(buf, "0x%X", err_bits); - } - - return buf; -} diff --git a/TPM2-Plugin/lib/tpm2_hash.c b/TPM2-Plugin/lib/tpm2_hash.c deleted file mode 100644 index 5ea7400..0000000 --- a/TPM2-Plugin/lib/tpm2_hash.c +++ /dev/null @@ -1,162 +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 <string.h> - -#include <tss2/tss2_sys.h> - -#include "log.h" -#include "files.h" -#include "tpm2_hash.h" -#include "tpm2_util.h" - -bool tpm2_hash_compute_data(TSS2_SYS_CONTEXT *sapi_context, TPMI_ALG_HASH halg, - TPMI_RH_HIERARCHY hierarchy, BYTE *buffer, UINT16 length, - TPM2B_DIGEST *result, TPMT_TK_HASHCHECK *validation) { - - FILE *mem = fmemopen(buffer, length, "rb"); - if (!mem) { - LOG_ERR("Error converting buffer to memory stream: %s", - strerror(errno)); - return false; - } - - return tpm2_hash_file(sapi_context, halg, hierarchy, mem, result, validation); -} - -bool tpm2_hash_file(TSS2_SYS_CONTEXT *sapi_context, TPMI_ALG_HASH halg, - TPMI_RH_HIERARCHY hierarchy, FILE *input, TPM2B_DIGEST *result, - TPMT_TK_HASHCHECK *validation) { - - TPM2B_AUTH nullAuth = TPM2B_EMPTY_INIT; - TPMI_DH_OBJECT sequenceHandle; - - TSS2L_SYS_AUTH_COMMAND cmdAuthArray = { 1, {{.sessionHandle = TPM2_RS_PW, - .nonce = TPM2B_EMPTY_INIT, .hmac = TPM2B_EMPTY_INIT, - .sessionAttributes = 0, }}}; - unsigned long file_size = 0; - - /* Suppress error reporting with NULL path */ - bool res = files_get_file_size(input, &file_size, NULL); - - /* If we can get the file size and its less than 1024, just do it in one hash invocation */ - if (res && file_size <= TPM2_MAX_DIGEST_BUFFER) { - - TPM2B_MAX_BUFFER buffer = { .size = file_size }; - - res = files_read_bytes(input, buffer.buffer, buffer.size); - if (!res) { - LOG_ERR("Error reading input file!"); - return false; - } - - TSS2_RC rval = TSS2_RETRY_EXP(Tss2_Sys_Hash(sapi_context, NULL, &buffer, halg, - hierarchy, result, validation, NULL)); - if (rval != TSS2_RC_SUCCESS) { - LOG_PERR(Tss2_Sys_Hash, rval); - return false; - } - - return true; - } - - /* - * Size is either unkown because the FILE * is a fifo, or it's too big - * to do in a single hash call. Based on the size figure out the chunks - * to loop over, if possible. This way we can call Complete with data. - */ - TSS2_RC rval = TSS2_RETRY_EXP(Tss2_Sys_HashSequenceStart(sapi_context, NULL, &nullAuth, - halg, &sequenceHandle, NULL)); - if (rval != TPM2_RC_SUCCESS) { - LOG_PERR(Tss2_Sys_HashSequenceStart, rval); - return rval; - } - - /* If we know the file size, we decrement the amount read and terminate the loop - * when 1 block is left, else we go till feof. - */ - size_t left = file_size; - bool use_left = !!res; - - TPM2B_MAX_BUFFER data; - - bool done = false; - while (!done) { - - size_t bytes_read = fread(data.buffer, 1, - BUFFER_SIZE(typeof(data), buffer), input); - if (ferror(input)) { - LOG_ERR("Error reading from input file"); - return false; - } - - data.size = bytes_read; - - /* if data was read, update the sequence */ - rval = TSS2_RETRY_EXP(Tss2_Sys_SequenceUpdate(sapi_context, sequenceHandle, - &cmdAuthArray, &data, NULL)); - if (rval != TPM2_RC_SUCCESS) { - LOG_PERR(Tss2_Sys_SequenceUpdate, rval); - return false; - } - - if (use_left) { - left -= bytes_read; - if (left <= TPM2_MAX_DIGEST_BUFFER) { - done = true; - continue; - } - } else if (feof(input)) { - done = true; - } - } /* end file read/hash update loop */ - - if (use_left) { - data.size = left; - bool res = files_read_bytes(input, data.buffer, left); - if (!res) { - LOG_ERR("Error reading from input file."); - return false; - } - } else { - data.size = 0; - } - - rval = TSS2_RETRY_EXP(Tss2_Sys_SequenceComplete(sapi_context, sequenceHandle, - &cmdAuthArray, &data, hierarchy, result, validation, - NULL)); - if (rval != TSS2_RC_SUCCESS) { - LOG_PERR(Tss2_Sys_SequenceComplete, rval); - return false; - } - - return true; -} diff --git a/TPM2-Plugin/lib/tpm2_plugin_api.c b/TPM2-Plugin/lib/tpm2_plugin_api.c index d63550e..b9fc75b 100644 --- a/TPM2-Plugin/lib/tpm2_plugin_api.c +++ b/TPM2-Plugin/lib/tpm2_plugin_api.c @@ -1,60 +1,47 @@ -//**********************************************************************; -// 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 <tss2/tss2_sys.h> +/* Copyright 2018 Intel Corporation, Inc +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include <sapi/tpm20.h> #include <stdbool.h> +#include <errno.h> #include <unistd.h> #include "tpm2_plugin_api.h" -#include "tpm2_convert.h" -#include "tpm2_tcti_ldr.h" -#include "tpm2_tool.h" -#include "tpm2_hash.h" -#include "tpm2_alg_util.h" -#include "log.h" -#include "files.h" - +#ifdef HAVE_TCTI_DEV +#include <tcti/tcti_device.h> +#endif +#ifdef HAVE_TCTI_SOCK +#include <tcti/tcti_socket.h> +#endif +#ifdef HAVE_TCTI_TABRMD +#include <tcti/tcti-tabrmd.h> +#endif bool output_enabled = true; - +bool hexPasswd = false; +TPM_HANDLE handle2048rsa; const char *tcti_path="libtss2-tcti-device.so"; -static void tcti_teardown (TSS2_TCTI_CONTEXT *tcti_context) +static void tcti_teardown(TSS2_TCTI_CONTEXT *tcti_context) { - - Tss2_Tcti_Finalize (tcti_context); + if (tcti_context == NULL) + return; + tss2_tcti_finalize (tcti_context); free (tcti_context); } -static void sapi_teardown (TSS2_SYS_CONTEXT *sapi_context) +static void sapi_teardown(TSS2_SYS_CONTEXT *sapi_context) { - if (sapi_context == NULL) return; Tss2_Sys_Finalize (sapi_context); @@ -63,49 +50,16 @@ static void sapi_teardown (TSS2_SYS_CONTEXT *sapi_context) static void sapi_teardown_full (TSS2_SYS_CONTEXT *sapi_context) { - TSS2_TCTI_CONTEXT *tcti_context = NULL; TSS2_RC rc; rc = Tss2_Sys_GetTctiContext (sapi_context, &tcti_context); - if (rc != TPM2_RC_SUCCESS) + if (rc != TSS2_RC_SUCCESS) return; sapi_teardown (sapi_context); tcti_teardown (tcti_context); } -#define SUPPORTED_ABI_VERSION \ -{ \ - .tssCreator = 1, \ - .tssFamily = 2, \ - .tssLevel = 1, \ - .tssVersion = 108, \ -} - -static TSS2_SYS_CONTEXT* sapi_ctx_init(TSS2_TCTI_CONTEXT *tcti_ctx) -{ - - TSS2_ABI_VERSION abi_version = SUPPORTED_ABI_VERSION; - - size_t size = Tss2_Sys_GetContextSize(0); - TSS2_SYS_CONTEXT *sapi_ctx = (TSS2_SYS_CONTEXT*) calloc(1, size); - if (sapi_ctx == NULL) { - LOG_ERR("Failed to allocate 0x%zx bytes for the SAPI context\n", - size); - return NULL; - } - - TSS2_RC rval = Tss2_Sys_Initialize(sapi_ctx, size, tcti_ctx, &abi_version); - if (rval != TPM2_RC_SUCCESS) { - LOG_PERR(Tss2_Sys_Initialize, rval); - free(sapi_ctx); - return NULL; - } - - return sapi_ctx; -} - - int tpm2_plugin_init() { printf("Init API done for TPM plugin ! \n"); @@ -118,7 +72,7 @@ int tpm2_plugin_uninit() return 0; } -TPM2_HANDLE srk_handle; +TPM_HANDLE srk_handle; int tpm2_plugin_activate(SSHSM_HW_PLUGIN_ACTIVATE_LOAD_IN_INFO_t *activate_in_info) { /* @@ -137,137 +91,322 @@ int tpm2_plugin_activate(SSHSM_HW_PLUGIN_ACTIVATE_LOAD_IN_INFO_t *activate_in_in return 0; } -TPM2_HANDLE handle_load; - -typedef struct tpm_load_ctx tpm_load_ctx; -struct tpm_load_ctx { - TPMS_AUTH_COMMAND session_data; - TPMI_DH_OBJECT parent_handle; - TPM2B_PUBLIC in_public; - TPM2B_PRIVATE in_private; - char *out_file; - char *context_file; - char *context_parent_file; - struct { - UINT8 H : 1; - UINT8 u : 1; - UINT8 r : 1; - UINT8 c : 1; - UINT8 C : 1; - } flags; -}; +TPMI_DH_OBJECT handle_load; + +#ifdef HAVE_TCTI_DEV +TSS2_TCTI_CONTEXT* +tcti_device_init (char const *device_file) +{ + TCTI_DEVICE_CONF conf = { + .device_path = device_file, + .logCallback = NULL, + .logData = NULL, + }; + size_t size; + TSS2_RC rc; + TSS2_TCTI_CONTEXT *tcti_ctx; -static tpm_load_ctx ctx_load = { - .session_data = { - .sessionHandle = TPM2_RS_PW, - .nonce = TPM2B_EMPTY_INIT, - .hmac = TPM2B_EMPTY_INIT, - .sessionAttributes = 0 + rc = InitDeviceTcti (NULL, &size, 0); + if (rc != TSS2_RC_SUCCESS) { + fprintf (stderr, + "Failed to get allocation size for device tcti context: " + "0x%x\n", rc); + return NULL; } -}; + tcti_ctx = (TSS2_TCTI_CONTEXT*)calloc (1, size); + if (tcti_ctx == NULL) { + fprintf (stderr, + "Allocation for device TCTI context failed: %s\n", + strerror (errno)); + return NULL; + } + rc = InitDeviceTcti (tcti_ctx, &size, &conf); + if (rc != TSS2_RC_SUCCESS) { + fprintf (stderr, + "Failed to initialize device TCTI context: 0x%x\n", + rc); + free (tcti_ctx); + return NULL; + } + return tcti_ctx; +} +#endif + + +#ifdef HAVE_TCTI_SOCK +TSS2_TCTI_CONTEXT* tcti_socket_init (char const *address, uint16_t port) +{ + TCTI_SOCKET_CONF conf = { + .hostname = address, + .port = port, + .logCallback = NULL, + .logBufferCallback = NULL, + .logData = NULL, + }; + size_t size; + TSS2_RC rc; + TSS2_TCTI_CONTEXT *tcti_ctx; + + rc = InitSocketTcti (NULL, &size, &conf, 0); + if (rc != TSS2_RC_SUCCESS) { + fprintf (stderr, "Faled to get allocation size for tcti context: " + "0x%x\n", rc); + return NULL; + } + tcti_ctx = (TSS2_TCTI_CONTEXT*)calloc (1, size); + if (tcti_ctx == NULL) { + fprintf (stderr, "Allocation for tcti context failed: %s\n", + strerror (errno)); + return NULL; + } + rc = InitSocketTcti (tcti_ctx, &size, &conf, 0); + if (rc != TSS2_RC_SUCCESS) { + fprintf (stderr, "Failed to initialize tcti context: 0x%x\n", rc); + free (tcti_ctx); + return NULL; + } + return tcti_ctx; +} +#endif +#ifdef HAVE_TCTI_TABRMD +TSS2_TCTI_CONTEXT *tcti_tabrmd_init (void) +{ + TSS2_TCTI_CONTEXT *tcti_ctx; + TSS2_RC rc; + size_t size; + + rc = tss2_tcti_tabrmd_init(NULL, &size); + if (rc != TSS2_RC_SUCCESS) { + printf("Failed to get size for TABRMD TCTI context: 0x%x", rc); + return NULL; + } + tcti_ctx = (TSS2_TCTI_CONTEXT*)calloc (1, size); + if (tcti_ctx == NULL) { + printf("Allocation for TABRMD TCTI context failed: %s", strerror (errno)); + return NULL; + } + rc = tss2_tcti_tabrmd_init (tcti_ctx, &size); + if (rc != TSS2_RC_SUCCESS) { + printf("Failed to initialize TABRMD TCTI context: 0x%x", rc); + free(tcti_ctx); + return NULL; + } + return tcti_ctx; +} +#endif +TSS2_TCTI_CONTEXT *tcti_init_from_options(common_opts_t *options) +{ + switch (options->tcti_type) { +#ifdef HAVE_TCTI_DEV + case DEVICE_TCTI: + return tcti_device_init (options->device_file); +#endif +#ifdef HAVE_TCTI_SOCK + case SOCKET_TCTI: + return tcti_socket_init (options->socket_address, + options->socket_port); +#endif +#ifdef HAVE_TCTI_TABRMD + case TABRMD_TCTI: + return tcti_tabrmd_init (); +#endif + default: + return NULL; + } +} + +static TSS2_SYS_CONTEXT *sapi_ctx_init (TSS2_TCTI_CONTEXT *tcti_ctx) +{ + TSS2_SYS_CONTEXT *sapi_ctx; + TSS2_RC rc; + size_t size; + TSS2_ABI_VERSION abi_version = { + .tssCreator = TSSWG_INTEROP, + .tssFamily = TSS_SAPI_FIRST_FAMILY, + .tssLevel = TSS_SAPI_FIRST_LEVEL, + .tssVersion = TSS_SAPI_FIRST_VERSION, + }; + + size = Tss2_Sys_GetContextSize (0); + sapi_ctx = (TSS2_SYS_CONTEXT*)calloc (1, size); + if (sapi_ctx == NULL) { + fprintf (stderr, + "Failed to allocate 0x%zx bytes for the SAPI context\n", + size); + return NULL; + } + rc = Tss2_Sys_Initialize (sapi_ctx, size, tcti_ctx, &abi_version); + if (rc != TSS2_RC_SUCCESS) { + fprintf (stderr, "Failed to initialize SAPI context: 0x%x\n", rc); + free (sapi_ctx); + return NULL; + } + return sapi_ctx; +} -int load (TSS2_SYS_CONTEXT *sapi_context) { +#define BUFFER_SIZE(type, field) (sizeof((((type *)NULL)->t.field))) +#define TPM2B_TYPE_INIT(type, field) { .t = { .size = BUFFER_SIZE(type, field), }, } +TPMS_AUTH_COMMAND sessionData; +int hex2ByteStructure(const char *inStr, UINT16 *byteLength, BYTE *byteBuffer) +{ + int strLength;//if the inStr likes "1a2b...", no prefix "0x" + int i = 0; + if(inStr == NULL || byteLength == NULL || byteBuffer == NULL) + return -1; + strLength = strlen(inStr); + if(strLength%2) + return -2; + for(i = 0; i < strLength; i++) + { + if(!isxdigit(inStr[i])) + return -3; + } + + if(*byteLength < strLength/2) + return -4; + + *byteLength = strLength/2; + + for(i = 0; i < *byteLength; i++) + { + char tmpStr[4] = {0}; + tmpStr[0] = inStr[i*2]; + tmpStr[1] = inStr[i*2+1]; + byteBuffer[i] = strtol(tmpStr, NULL, 16); + } + return 0; +} +int load_key(TSS2_SYS_CONTEXT *sapi_context, + TPMI_DH_OBJECT parentHandle, + TPM2B_PUBLIC *inPublic, + TPM2B_PRIVATE *inPrivate, + int P_flag) +{ UINT32 rval; - TSS2L_SYS_AUTH_COMMAND sessionsData; - TSS2L_SYS_AUTH_RESPONSE sessionsDataOut; + TPMS_AUTH_RESPONSE sessionDataOut; + TSS2_SYS_CMD_AUTHS sessionsData; + TSS2_SYS_RSP_AUTHS sessionsDataOut; + TPMS_AUTH_COMMAND *sessionDataArray[1]; + TPMS_AUTH_RESPONSE *sessionDataOutArray[1]; TPM2B_NAME nameExt = TPM2B_TYPE_INIT(TPM2B_NAME, name); - sessionsData.count = 1; - sessionsData.auths[0] = ctx_load.session_data; - - rval = TSS2_RETRY_EXP(Tss2_Sys_Load(sapi_context, - ctx_load.parent_handle, - &sessionsData, - &ctx_load.in_private, - &ctx_load.in_public, - &handle_load, - &nameExt, - &sessionsDataOut)); - if(rval != TPM2_RC_SUCCESS) + sessionDataArray[0] = &sessionData; + sessionDataOutArray[0] = &sessionDataOut; + + sessionsDataOut.rspAuths = &sessionDataOutArray[0]; + sessionsData.cmdAuths = &sessionDataArray[0]; + + sessionsDataOut.rspAuthsCount = 1; + sessionsData.cmdAuthsCount = 1; + + sessionData.sessionHandle = TPM_RS_PW; + sessionData.nonce.t.size = 0; + + if(P_flag == 0) + sessionData.hmac.t.size = 0; + + *((UINT8 *)((void *)&sessionData.sessionAttributes)) = 0; + if (sessionData.hmac.t.size > 0 && hexPasswd) { - LOG_PERR(Tss2_Sys_Load, rval); - return -1; + sessionData.hmac.t.size = sizeof(sessionData.hmac) - 2; + if (hex2ByteStructure((char *)sessionData.hmac.t.buffer, + &sessionData.hmac.t.size, + sessionData.hmac.t.buffer) != 0) + { + printf( "Failed to convert Hex format password for parent Passwd.\n"); + return -1; + } } - tpm2_tool_output("handle_load: 0x%08x\n", handle_load); - if (ctx_load.out_file) { - if(!files_save_bytes_to_file(ctx_load.out_file, nameExt.name, nameExt.size)) { - return -2; - } + rval = Tss2_Sys_Load (sapi_context, + parentHandle, + &sessionsData, + inPrivate, + inPublic, + &handle2048rsa, + &nameExt, + &sessionsDataOut); + if(rval != TPM_RC_SUCCESS) + { + printf("\nLoad Object Failed ! ErrorCode: 0x%0x\n\n",rval); + return -1; } + printf("\nLoad succ.\nLoadedHandle: 0x%08x\n\n",handle2048rsa); return 0; } -int tpm2_tool_load_key(TSS2_SYS_CONTEXT *sapi_context) +TPMS_CONTEXT loaded_key_context; + +int load_key_execute(SSHSM_HW_PLUGIN_ACTIVATE_LOAD_IN_INFO_t *loadkey_in_info, + void **keyHandle, TSS2_SYS_CONTEXT *sapi_context) { + TPMI_DH_OBJECT parentHandle; + TPM2B_PUBLIC inPublic; + TPM2B_PRIVATE inPrivate; + UINT16 size; int returnVal = 0; - if ((!ctx_load.flags.H && !ctx_load.flags.c) || (!ctx_load.flags.u || !ctx_load.flags.r)) { - LOG_ERR("Expected options (H or c) and u and r"); - return 1; - } + memset(&inPublic,0,sizeof(TPM2B_PUBLIC)); + memset(&inPrivate,0,sizeof(TPM2B_SENSITIVE)); - if(ctx_load.flags.c) { - returnVal = files_load_tpm_context_from_path(sapi_context, - &ctx_load.parent_handle, - ctx_load.context_parent_file) != true; - if (returnVal) { - return 1; - } - } + setbuf(stdout, NULL); + setvbuf (stdout, NULL, _IONBF, BUFSIZ); - returnVal = load(sapi_context); - if (returnVal) { - return 1; - } + //parentHandle = 0x81000011; + parentHandle = srk_handle; - if (ctx_load.flags.C) { - returnVal = files_save_tpm_context_to_path (sapi_context, - handle_load, - ctx_load.context_file) != true; - if (returnVal) { - return 1; - } + if (loadkey_in_info->num_buffers != 2) + return -1; + memcpy(&inPublic, loadkey_in_info->buffer_info[0]->buffer, + loadkey_in_info->buffer_info[0]->length_of_buffer); + memcpy(&inPrivate, loadkey_in_info->buffer_info[1]->buffer, + loadkey_in_info->buffer_info[1]->length_of_buffer); + + printf("we are here now\n"); + returnVal = load_key (sapi_context, + parentHandle, + &inPublic, + &inPrivate, + 0); + + TPM_RC rval = Tss2_Sys_ContextSave(sapi_context, handle2048rsa, &loaded_key_context); + if (rval != TPM_RC_SUCCESS) { + printf("Tss2_Sys_ContextSave: Saving handle 0x%x context failed. TPM Error:0x%x", handle2048rsa, rval); + return -1; } - + *keyHandle = &handle2048rsa; return 0; } -int tpm2_plugin_load_key( - SSHSM_HW_PLUGIN_ACTIVATE_LOAD_IN_INFO_t *loadkey_in_info, - void **keyHandle - ) +int tpm2_plugin_load_key(SSHSM_HW_PLUGIN_ACTIVATE_LOAD_IN_INFO_t *loadkey_in_info, + void **keyHandle) { int ret = 1; - TSS2_TCTI_CONTEXT *tcti; - tcti = tpm2_tcti_ldr_load(tcti_path, NULL); - if (!tcti) { - LOG_ERR("Could not load tcti, got: \"%s\"", tcti_path); + common_opts_t opts = COMMON_OPTS_INITIALIZER; + TSS2_TCTI_CONTEXT *tcti_ctx; + tcti_ctx = tcti_init_from_options(&opts); + if (tcti_ctx == NULL) return -1; - } TSS2_SYS_CONTEXT *sapi_context = NULL; - if (tcti) { - sapi_context = sapi_ctx_init(tcti); + if (tcti_ctx) { + sapi_context = sapi_ctx_init(tcti_ctx); if (!sapi_context) { - goto free_tcti; + free(tcti_ctx); + return -1; } } - ret = tpm2_tool_load_key(sapi_context); - if (ret != 0) { - LOG_ERR("Unable to run tpm2_tool_iload_key"); - sapi_teardown_full(sapi_context); + ret = load_key_execute(loadkey_in_info, keyHandle, sapi_context); + if (ret !=0) + printf("Load key API failed in TPM plugin ! \n"); -free_tcti: - tpm2_tcti_ldr_unload(); - return ret; - } + sapi_teardown_full(sapi_context); - printf("Load key API done for TPM plugin ! \n"); + printf("Load key API successful in TPM plugin ! \n"); return 0; } @@ -278,161 +417,228 @@ struct tpm_sign_ctx { TPMS_AUTH_COMMAND sessionData; TPMI_DH_OBJECT keyHandle; TPMI_ALG_HASH halg; - TPM2B_DIGEST digest; - char *outFilePath; + char outFilePath[PATH_MAX]; BYTE *msg; UINT16 length; - char *contextKeyFile; - char *inMsgFileName; - tpm2_convert_sig_fmt sig_format; - struct { - UINT16 k : 1; - UINT16 P : 1; - UINT16 g : 1; - UINT16 m : 1; - UINT16 t : 1; - UINT16 s : 1; - UINT16 c : 1; - UINT16 f : 1; - UINT16 D : 1; - } flags; -}; - -tpm_sign_ctx ctx_sign = { - .msg = NULL, - .sessionData = TPMS_AUTH_COMMAND_INIT(TPM2_RS_PW), - .halg = TPM2_ALG_SHA1, - .digest = TPM2B_TYPE_INIT(TPM2B_DIGEST, buffer), + TSS2_SYS_CONTEXT *sapi_context; }; - int tpm2_plugin_rsa_sign_init( void *keyHandle, - unsigned long mechanish, + unsigned long mechanism, void *param, int len) { + printf("rsa_sign_init API mechanism is %lx \n", mechanism); printf("rsa_sign_init API done for tpm2_plugin... \n"); return 0; } -static bool init_sign(TSS2_SYS_CONTEXT *sapi_context) { +UINT32 tpm_hash(TSS2_SYS_CONTEXT *sapi_context, TPMI_ALG_HASH hashAlg, + UINT16 size, BYTE *data, TPM2B_DIGEST *result) { + TPM2B_MAX_BUFFER dataSizedBuffer; - if (!((ctx_sign.flags.k || ctx_sign.flags.c) && (ctx_sign.flags.m || ctx_sign.flags.D) && ctx_sign.flags.s)) { - LOG_ERR("Expected options (k or c) and (m or D) and s"); - return false; + dataSizedBuffer.t.size = size; + memcpy(dataSizedBuffer.t.buffer, data, size); + return Tss2_Sys_Hash(sapi_context, 0, &dataSizedBuffer, hashAlg, + TPM_RH_NULL, result, 0, 0); +} + +static TPM_RC hash_sequence_ex(TSS2_SYS_CONTEXT *sapi_context, + + TPMI_ALG_HASH hashAlg, UINT32 numBuffers, TPM2B_MAX_BUFFER *bufferList, + TPM2B_DIGEST *result) { + TPM_RC rval; + TPM2B_AUTH nullAuth; + TPMI_DH_OBJECT sequenceHandle; + TPM2B emptyBuffer; + TPMT_TK_HASHCHECK validation; + + TPMS_AUTH_COMMAND cmdAuth; + TPMS_AUTH_COMMAND *cmdSessionArray[1] = { &cmdAuth }; + TSS2_SYS_CMD_AUTHS cmdAuthArray = { 1, &cmdSessionArray[0] }; + + nullAuth.t.size = 0; + emptyBuffer.size = 0; + + // Set result size to 0, in case any errors occur + result->b.size = 0; + + // Init input sessions struct + cmdAuth.sessionHandle = TPM_RS_PW; + cmdAuth.nonce.t.size = 0; + *((UINT8 *) ((void *) &cmdAuth.sessionAttributes)) = 0; + cmdAuth.hmac.t.size = 0; + + rval = Tss2_Sys_HashSequenceStart(sapi_context, 0, &nullAuth, hashAlg, + &sequenceHandle, 0); + if (rval != TPM_RC_SUCCESS) { + return rval; } - if (ctx_sign.flags.D && (ctx_sign.flags.t || ctx_sign.flags.m)) { - LOG_WARN("Option D provided, options m and t are ignored."); + unsigned i; + for (i = 0; i < numBuffers; i++) { + rval = Tss2_Sys_SequenceUpdate(sapi_context, sequenceHandle, + &cmdAuthArray, &bufferList[i], 0); + + if (rval != TPM_RC_SUCCESS) { + return rval; + } } - if (ctx_sign.flags.D || !ctx_sign.flags.t) { - ctx_sign.validation.tag = TPM2_ST_HASHCHECK; - ctx_sign.validation.hierarchy = TPM2_RH_NULL; - memset(&ctx_sign.validation.digest, 0, sizeof(ctx_sign.validation.digest)); + rval = Tss2_Sys_SequenceComplete(sapi_context, sequenceHandle, + &cmdAuthArray, (TPM2B_MAX_BUFFER *) &emptyBuffer, + TPM_RH_PLATFORM, result, &validation, 0); + + if (rval != TPM_RC_SUCCESS) { + return rval; } - /* - * load tpm context from a file if -c is provided - */ - if (ctx_sign.flags.c) { - bool result = files_load_tpm_context_from_path(sapi_context, &ctx_sign.keyHandle, - ctx_sign.contextKeyFile); - if (!result) { - return false; - } + return rval; +} + +int tpm_hash_compute_data(TSS2_SYS_CONTEXT *sapi_context, BYTE *buffer, + UINT16 length, TPMI_ALG_HASH halg, TPM2B_DIGEST *result) { + + if (length <= MAX_DIGEST_BUFFER) { + if (tpm_hash(sapi_context, halg, length, buffer, + result) == TPM_RC_SUCCESS) + return 0; + else + return -1; } - /* - * Process the msg file if needed - */ - if (ctx_sign.flags.m && !ctx_sign.flags.D) { - unsigned long file_size; - bool result = files_get_file_size_path(ctx_sign.inMsgFileName, &file_size); - if (!result) { - return false; - } - if (file_size == 0) { - LOG_ERR("The message file \"%s\" is empty!", ctx_sign.inMsgFileName); - return false; - } - - if (file_size > UINT16_MAX) { - LOG_ERR( - "The message file \"%s\" is too large, got: %lu bytes, expected less than: %u bytes!", - ctx_sign.inMsgFileName, file_size, UINT16_MAX + 1); - return false; - } - - ctx_sign.msg = (BYTE*) calloc(required_argument, file_size); - if (!ctx_sign.msg) { - LOG_ERR("oom"); - return false; - } - - ctx_sign.length = file_size; - result = files_load_bytes_from_path(ctx_sign.inMsgFileName, ctx_sign.msg, &ctx_sign.length); - if (!result) { - free(ctx_sign.msg); - return false; - } + UINT8 numBuffers = (length - 1) / MAX_DIGEST_BUFFER + 1; + + TPM2B_MAX_BUFFER *bufferList = (TPM2B_MAX_BUFFER *) calloc(numBuffers, + sizeof(TPM2B_MAX_BUFFER)); + if (bufferList == NULL) + return -2; + + UINT32 i; + for (i = 0; i < (UINT32)(numBuffers - 1); i++) { + bufferList[i].t.size = MAX_DIGEST_BUFFER; + memcpy(bufferList[i].t.buffer, buffer + i * MAX_DIGEST_BUFFER, + MAX_DIGEST_BUFFER); } + bufferList[i].t.size = length - i * MAX_DIGEST_BUFFER; + memcpy(bufferList[i].t.buffer, buffer + i * MAX_DIGEST_BUFFER, + bufferList[i].t.size); - return true; + TPM_RC rval = hash_sequence_ex(sapi_context, halg, numBuffers, bufferList, result); + free(bufferList); + return rval == TPM_RC_SUCCESS ? 0 : -3; } -static bool sign_and_save(TSS2_SYS_CONTEXT *sapi_context) { +static bool get_key_type(TSS2_SYS_CONTEXT *sapi_context, TPMI_DH_OBJECT objectHandle, + TPMI_ALG_PUBLIC *type) { - TPMT_SIG_SCHEME in_scheme; - TPMT_SIGNATURE signature; + TPMS_AUTH_RESPONSE session_data_out; + + TPMS_AUTH_RESPONSE *session_data_out_array[1] = { + &session_data_out + }; + + TSS2_SYS_RSP_AUTHS sessions_data_out = { + 1, + &session_data_out_array[0] + }; + + TPM2B_PUBLIC out_public = { + { 0, } + }; + + TPM2B_NAME name = TPM2B_TYPE_INIT(TPM2B_NAME, name); - TSS2L_SYS_AUTH_COMMAND sessions_data = { 1, { ctx_sign.sessionData }}; - TSS2L_SYS_AUTH_RESPONSE sessions_data_out; + TPM2B_NAME qaulified_name = TPM2B_TYPE_INIT(TPM2B_NAME, name); - if (!ctx_sign.flags.D) { - bool res = tpm2_hash_compute_data(sapi_context, ctx_sign.halg, TPM2_RH_NULL, - ctx_sign.msg, ctx_sign.length, &ctx_sign.digest, NULL); - if (!res) { - LOG_ERR("Compute message hash failed!"); - return false; - } + TPM_RC rval = Tss2_Sys_ReadPublic(sapi_context, objectHandle, 0, &out_public, &name, + &qaulified_name, &sessions_data_out); + if (rval != TPM_RC_SUCCESS) { + printf("Sys_ReadPublic failed, error code: 0x%x", rval); + return false; } + *type = out_public.t.publicArea.type; + return true; +} - bool result = get_signature_scheme(sapi_context, ctx_sign.keyHandle, ctx_sign.halg, &in_scheme); +static bool set_scheme(TSS2_SYS_CONTEXT *sapi_context, TPMI_DH_OBJECT keyHandle, + TPMI_ALG_HASH halg, TPMT_SIG_SCHEME *inScheme) { + + TPM_ALG_ID type; + bool result = get_key_type(sapi_context, keyHandle, &type); if (!result) { return false; } - TSS2_RC rval = TSS2_RETRY_EXP(Tss2_Sys_Sign(sapi_context, ctx_sign.keyHandle, - &sessions_data, &ctx_sign.digest, &in_scheme, &ctx_sign.validation, &signature, - &sessions_data_out)); - if (rval != TPM2_RC_SUCCESS) { - LOG_PERR(Tss2_Sys_Sign, rval); + switch (type) { + case TPM_ALG_RSA : + inScheme->scheme = TPM_ALG_RSASSA; + inScheme->details.rsassa.hashAlg = halg; + break; + case TPM_ALG_KEYEDHASH : + inScheme->scheme = TPM_ALG_HMAC; + inScheme->details.hmac.hashAlg = halg; + break; + case TPM_ALG_ECC : + inScheme->scheme = TPM_ALG_ECDSA; + inScheme->details.ecdsa.hashAlg = halg; + break; + case TPM_ALG_SYMCIPHER : + default: + printf("Unknown key type, got: 0x%x", type); return false; } - return tpm2_convert_sig(&signature, ctx_sign.sig_format, ctx_sign.outFilePath); + return true; } +static bool sign_and_save(tpm_sign_ctx *ctx, unsigned char *sig, int *sig_len) { + TPM2B_DIGEST digest = TPM2B_TYPE_INIT(TPM2B_DIGEST, buffer); + TPMT_SIG_SCHEME in_scheme; + TPMT_SIGNATURE signature; + int signature_len; + TSS2_SYS_CMD_AUTHS sessions_data; + TPMS_AUTH_RESPONSE session_data_out; + TSS2_SYS_RSP_AUTHS sessions_data_out; + TPMS_AUTH_COMMAND *session_data_array[1]; + TPMS_AUTH_RESPONSE *session_data_out_array[1]; + + session_data_array[0] = &ctx->sessionData; + sessions_data.cmdAuths = &session_data_array[0]; + session_data_out_array[0] = &session_data_out; + sessions_data_out.rspAuths = &session_data_out_array[0]; + sessions_data_out.rspAuthsCount = 1; + sessions_data.cmdAuthsCount = 1; + + int rc = tpm_hash_compute_data(ctx->sapi_context, ctx->msg, ctx->length, ctx->halg, &digest); + if (rc) { + printf("Compute message hash failed!"); + return false; + } -int tpm2_tool_sign(TSS2_SYS_CONTEXT *sapi_context) -{ - - bool result = init_sign(sapi_context); + bool result = set_scheme(ctx->sapi_context, ctx->keyHandle, ctx->halg, &in_scheme); if (!result) { - return 1; + return false; } - result = sign_and_save(sapi_context); + TPM_RC rval = Tss2_Sys_Sign(ctx->sapi_context, ctx->keyHandle, + &sessions_data, &digest, &in_scheme, + &ctx->validation, &signature, + &sessions_data_out); - free(ctx_sign.msg); + if (rval != TPM_RC_SUCCESS) { + printf("Sys_Sign failed, error code: 0x%x", rval); + return false; + } + signature_len = sizeof(signature); + sig_len = &signature_len; + sig = (unsigned char *)&signature; - return result != true; + return true; } - int tpm2_plugin_rsa_sign( void *keyHandle, unsigned long mechanism, @@ -441,61 +647,58 @@ int tpm2_plugin_rsa_sign( unsigned char *sig, int *sig_len) { - int ret = 1; - TSS2_TCTI_CONTEXT *tcti; - tcti = tpm2_tcti_ldr_load(tcti_path, NULL); - if (!tcti) { - LOG_ERR("Could not load tcti, got: \"%s\"", tcti_path); + TPM_RC rval; + common_opts_t opts = COMMON_OPTS_INITIALIZER; + TSS2_TCTI_CONTEXT *tcti_ctx; + tcti_ctx = tcti_init_from_options(&opts); + if (tcti_ctx == NULL) return -1; - } - + TSS2_SYS_CONTEXT *sapi_context = NULL; - if (tcti) { - sapi_context = sapi_ctx_init(tcti); - if (!sapi_context) { - goto free_tcti; - } + if (tcti_ctx) { + sapi_context = sapi_ctx_init(tcti_ctx); + if (!sapi_context) { + free(tcti_ctx); + return -1; + } } + + tpm_sign_ctx ctx = { + .msg = NULL, + .sessionData = { 0 }, + .halg = 0, + .keyHandle = 0, + .validation = { 0 }, + .sapi_context = sapi_context + }; - ret = tpm2_tool_sign(sapi_context); - if (ret != 0) { - LOG_ERR("Unable to run tpm2_tool_sign"); - sapi_teardown_full(sapi_context); + printf("rsa_sign API mechanism is %lx \n", mechanism); + ctx.sessionData.sessionHandle = TPM_RS_PW; + ctx.validation.tag = TPM_ST_HASHCHECK; + ctx.validation.hierarchy = TPM_RH_NULL; + ctx.halg = TPM_ALG_SHA256; + ctx.keyHandle = *(TPMI_DH_OBJECT *)keyHandle; + + rval = Tss2_Sys_ContextLoad(ctx.sapi_context, &loaded_key_context, &ctx.keyHandle); + if (rval != TPM_RC_SUCCESS) { + printf("ContextLoad Error in RSA Sign API. TPM Error:0x%x", rval); + goto out; + } + ctx.length = msg_len; + ctx.msg = msg; -free_tcti: - tpm2_tcti_ldr_unload(); - return ret; + if (!sign_and_save(&ctx, sig, sig_len)){ + printf("RSA sign failed\n"); + goto out; } - printf("rsa_sign API done for tpm2_plugin... \n"); -} -int tpm2_rsa_create_object( - unsigned long appHandle, - //DhsmWPKRSAFormat* wpk, - void *wpk, - unsigned char* swk, - int swk_len, - unsigned char* iv, - int iv_len, - int tag_len, - void **cb_object) -{ - return 0; -} + printf("RSA sign API successful in TPM plugin ! \n"); + +out: + sapi_teardown_full(sapi_context); -int tpm2_rsa_delete_object(void *cb_object) -{ return 0; + } -int tpm2_import_object(unsigned long appHandle, - unsigned char* tlvbuffer, - int buflen, - unsigned char* iv, - int iv_len, - unsigned char* tpm_pwd, - int tpm_pwd_len) -{ - return 0; -} diff --git a/TPM2-Plugin/lib/tpm2_plugin_init.c b/TPM2-Plugin/lib/tpm2_plugin_init.c index d09020f..b221bd2 100644 --- a/TPM2-Plugin/lib/tpm2_plugin_init.c +++ b/TPM2-Plugin/lib/tpm2_plugin_init.c @@ -1,33 +1,17 @@ -//**********************************************************************; -// 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. -//**********************************************************************; +/* Copyright 2018 Intel Corporation, Inc +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ #include <stdio.h> diff --git a/TPM2-Plugin/lib/tpm2_tcti_ldr.c b/TPM2-Plugin/lib/tpm2_tcti_ldr.c deleted file mode 100644 index 5b827a9..0000000 --- a/TPM2-Plugin/lib/tpm2_tcti_ldr.c +++ /dev/null @@ -1,137 +0,0 @@ -//**********************************************************************; -// Copyright (c) 2018, 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. -// -// 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 <limits.h> -#include <stdlib.h> -#include <stdio.h> -#include <dlfcn.h> - -#include <tss2/tss2_sys.h> - -#include "log.h" -#include "tpm2_tcti_ldr.h" - -static void *handle; -static const TSS2_TCTI_INFO *info; - -void tpm2_tcti_ldr_unload(void) { - if (handle) { -#ifndef DISABLE_DLCLOSE - dlclose(handle); -#endif - handle = NULL; - info = NULL; - } -} - -const TSS2_TCTI_INFO *tpm2_tcti_ldr_getinfo(void) { - return info; -} - -bool tpm2_tcti_ldr_is_tcti_present(const char *name) { - - char path[PATH_MAX]; - snprintf(path, sizeof(path), "libtss2-tcti-%s.so", name); - - void *handle = dlopen (path, RTLD_LAZY); - if (handle) { - dlclose(handle); - } - - return handle != NULL; -} - -TSS2_TCTI_CONTEXT *tpm2_tcti_ldr_load(const char *path, const char *opts) { - - TSS2_TCTI_CONTEXT *tcti_ctx = NULL; - - if (handle) { - LOG_ERR("Attempting to load multiple tcti's simultaneously is not supported!"); - return NULL; - } - - /* - * Try what they gave us, if it doesn't load up, try - * libtss2-tcti-xxx.so replacing xxx with what they gave us. - */ - handle = dlopen (path, RTLD_LAZY); - if (!handle) { - - char buf[PATH_MAX]; - size_t size = snprintf(buf, sizeof(buf), "libtss2-tcti-%s.so", path); - if (size >= sizeof(buf)) { - LOG_ERR("Truncated friendly name conversion, got: \"%s\", made: \"%s\"", - path, buf); - return NULL; - } - - handle = dlopen (buf, RTLD_LAZY); - if (!handle) { - LOG_ERR("Could not dlopen library: \"%s\"", buf); - return NULL; - } - } - - TSS2_TCTI_INFO_FUNC infofn = (TSS2_TCTI_INFO_FUNC)dlsym(handle, TSS2_TCTI_INFO_SYMBOL); - if (!infofn) { - LOG_ERR("Symbol \"%s\"not found in library: \"%s\"", - TSS2_TCTI_INFO_SYMBOL, path); - goto err; - } - - info = infofn(); - - TSS2_TCTI_INIT_FUNC init = info->init; - - size_t size; - TSS2_RC rc = init(NULL, &size, opts); - if (rc != TPM2_RC_SUCCESS) { - LOG_ERR("tcti init setup routine failed for library: \"%s\"" - " options: \"%s\"", path, opts); - goto err; - } - - tcti_ctx = (TSS2_TCTI_CONTEXT*) calloc(1, size); - if (tcti_ctx == NULL) { - LOG_ERR("oom"); - goto err; - } - - rc = init(tcti_ctx, &size, opts); - if (rc != TPM2_RC_SUCCESS) { - LOG_ERR("tcti init allocation routine failed for library: \"%s\"" - " options: \"%s\"", path, opts); - goto err; - } - - return tcti_ctx; - -err: - free(tcti_ctx); - dlclose(handle); - return NULL; -} diff --git a/TPM2-Plugin/lib/tpm2_util.c b/TPM2-Plugin/lib/tpm2_util.c deleted file mode 100644 index c0a6cc4..0000000 --- a/TPM2-Plugin/lib/tpm2_util.c +++ /dev/null @@ -1,347 +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 <ctype.h> -#include <errno.h> -#include <stdbool.h> -#include <stdlib.h> -#include <string.h> - -#include "log.h" -#include "files.h" -#include "tpm2_alg_util.h" -#include "tpm2_attr_util.h" -#include "tpm2_tool.h" -#include "tpm2_util.h" - -bool tpm2_util_concat_buffer(TPM2B_MAX_BUFFER *result, TPM2B *append) { - - if (!result || !append) { - return false; - } - - if ((result->size + append->size) < result->size) { - return false; - } - - if ((result->size + append->size) > TPM2_MAX_DIGEST_BUFFER) { - return false; - } - - memcpy(&result->buffer[result->size], append->buffer, append->size); - result->size += append->size; - - return true; -} - -bool tpm2_util_string_to_uint16(const char *str, uint16_t *value) { - - uint32_t tmp; - bool result = tpm2_util_string_to_uint32(str, &tmp); - if (!result) { - return false; - } - - /* overflow on 16 bits? */ - if (tmp > UINT16_MAX) { - return false; - } - - *value = (uint16_t) tmp; - return true; -} - -bool tpm2_util_string_to_uint32(const char *str, uint32_t *value) { - - char *endptr; - - if (str == NULL || *str == '\0') { - return false; - } - - /* clear errno before the call, should be 0 afterwards */ - errno = 0; - uint32_t tmp = strtoul(str, &endptr, 0); - if (errno) { - return false; - } - - /* - * The entire string should be able to be converted or fail - * We already checked that str starts with a null byte, so no - * need to check that again per the man page. - */ - if (*endptr != '\0') { - return false; - } - - *value = tmp; - return true; -} - -int tpm2_util_hex_to_byte_structure(const char *inStr, UINT16 *byteLength, - BYTE *byteBuffer) { - int strLength; //if the inStr likes "1a2b...", no prefix "0x" - int i = 0; - if (inStr == NULL || byteLength == NULL || byteBuffer == NULL) - return -1; - strLength = strlen(inStr); - if (strLength % 2) - return -2; - for (i = 0; i < strLength; i++) { - if (!isxdigit(inStr[i])) - return -3; - } - - if (*byteLength < strLength / 2) - return -4; - - *byteLength = strLength / 2; - - for (i = 0; i < *byteLength; i++) { - char tmpStr[4] = { 0 }; - tmpStr[0] = inStr[i * 2]; - tmpStr[1] = inStr[i * 2 + 1]; - byteBuffer[i] = strtol(tmpStr, NULL, 16); - } - return 0; -} - -void tpm2_util_hexdump(const BYTE *data, size_t len) { - - if (!output_enabled) { - return; - } - - size_t i; - for (i=0; i < len; i++) { - printf("%02x", data[i]); - } -} - -bool tpm2_util_hexdump_file(FILE *fd, size_t len) { - BYTE* buff = (BYTE*)malloc(len); - if (!buff) { - LOG_ERR("malloc() failed"); - return false; - } - - bool res = files_read_bytes(fd, buff, len); - if (!res) { - LOG_ERR("Failed to read file"); - free(buff); - return false; - } - - tpm2_util_hexdump(buff, len); - - free(buff); - return true; -} - -bool tpm2_util_print_tpm2b_file(FILE *fd) -{ - UINT16 len; - bool res = files_read_16(fd, &len); - if(!res) { - LOG_ERR("File read failed"); - return false; - } - return tpm2_util_hexdump_file(fd, len); -} - -bool tpm2_util_is_big_endian(void) { - - uint32_t test_word; - uint8_t *test_byte; - - test_word = 0xFF000000; - test_byte = (uint8_t *) (&test_word); - - return test_byte[0] == 0xFF; -} - -#define STRING_BYTES_ENDIAN_CONVERT(size) \ - UINT##size tpm2_util_endian_swap_##size(UINT##size data) { \ - \ - UINT##size converted; \ - UINT8 *bytes = (UINT8 *)&data; \ - UINT8 *tmp = (UINT8 *)&converted; \ - \ - size_t i; \ - for(i=0; i < sizeof(UINT##size); i ++) { \ - tmp[i] = bytes[sizeof(UINT##size) - i - 1]; \ - } \ - \ - return converted; \ - } - -STRING_BYTES_ENDIAN_CONVERT(16) -STRING_BYTES_ENDIAN_CONVERT(32) -STRING_BYTES_ENDIAN_CONVERT(64) - -#define STRING_BYTES_ENDIAN_HTON(size) \ - UINT##size tpm2_util_hton_##size(UINT##size data) { \ - \ - bool is_big_endian = tpm2_util_is_big_endian(); \ - if (is_big_endian) { \ - return data; \ - } \ - \ - return tpm2_util_endian_swap_##size(data); \ - } - -STRING_BYTES_ENDIAN_HTON(16) -STRING_BYTES_ENDIAN_HTON(32) -STRING_BYTES_ENDIAN_HTON(64) - -/* - * Converting from host-to-network (hton) or network-to-host (ntoh) is - * the same operation: if endianess differs between host and data, swap - * endianess. Thus we can just call the hton routines, but have some nice - * names for folks. - */ -UINT16 tpm2_util_ntoh_16(UINT16 data) { - return tpm2_util_hton_16(data); -} - -UINT32 tpm2_util_ntoh_32(UINT32 data) { - return tpm2_util_hton_32(data); -} -UINT64 tpm2_util_ntoh_64(UINT64 data) { - return tpm2_util_hton_64(data); -} - -UINT32 tpm2_util_pop_count(UINT32 data) { - - static const UINT8 bits_per_nibble[] = - {0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4}; - - UINT8 count = 0; - UINT8 *d = (UINT8 *)&data; - - size_t i; - for (i=0; i < sizeof(data); i++) { - count += bits_per_nibble[d[i] & 0x0f]; - count += bits_per_nibble[d[i] >> 4]; - } - - return count; -} - -#define TPM2_UTIL_KEYDATA_INIT { .len = 0 }; - -typedef struct tpm2_util_keydata tpm2_util_keydata; -struct tpm2_util_keydata { - UINT16 len; - struct { - const char *name; - TPM2B *value; - } entries[2]; -}; - -static void tpm2_util_public_to_keydata(TPM2B_PUBLIC *public, tpm2_util_keydata *keydata) { - - switch (public->publicArea.type) { - case TPM2_ALG_RSA: - keydata->len = 1; - keydata->entries[0].name = tpm2_alg_util_algtostr(public->publicArea.type); - keydata->entries[0].value = (TPM2B *)&public->publicArea.unique.rsa; - return; - case TPM2_ALG_KEYEDHASH: - keydata->len = 1; - keydata->entries[0].name = tpm2_alg_util_algtostr(public->publicArea.type); - keydata->entries[0].value = (TPM2B *)&public->publicArea.unique.keyedHash; - return; - case TPM2_ALG_SYMCIPHER: - keydata->len = 1; - keydata->entries[0].name = tpm2_alg_util_algtostr(public->publicArea.type); - keydata->entries[0].value = (TPM2B *)&public->publicArea.unique.sym; - return; - case TPM2_ALG_ECC: - keydata->len = 2; - keydata->entries[0].name = "x"; - keydata->entries[0].value = (TPM2B *)&public->publicArea.unique.ecc.x; - keydata->entries[1].name = "y"; - keydata->entries[1].value = (TPM2B *)&public->publicArea.unique.ecc.y; - return; - default: - LOG_WARN("The algorithm type(0x%4.4x) is not supported", - public->publicArea.type); - } - - return; -} - -void print_yaml_indent(size_t indent_count) { - while (indent_count--) { - tpm2_tool_output(" "); - } -} - -void tpm2_util_tpma_object_to_yaml(TPMA_OBJECT obj) { - - char *attrs = tpm2_attr_util_obj_attrtostr(obj); - tpm2_tool_output("attributes:\n"); - tpm2_tool_output(" value: %s\n", attrs); - tpm2_tool_output(" raw: 0x%x\n", obj); - free(attrs); -} - -void tpm2_util_public_to_yaml(TPM2B_PUBLIC *public) { - - tpm2_tool_output("algorithm:\n"); - tpm2_tool_output(" value: %s\n", tpm2_alg_util_algtostr(public->publicArea.nameAlg)); - tpm2_tool_output(" raw: 0x%x\n", public->publicArea.nameAlg); - - tpm2_util_tpma_object_to_yaml(public->publicArea.objectAttributes); - - tpm2_tool_output("type: \n"); - tpm2_tool_output(" value: %s\n", tpm2_alg_util_algtostr(public->publicArea.type)); - tpm2_tool_output(" raw: 0x%x\n", public->publicArea.type); - - tpm2_util_keydata keydata = TPM2_UTIL_KEYDATA_INIT; - tpm2_util_public_to_keydata(public, &keydata); - - UINT16 i; - /* if no keydata len will be 0 and it wont print */ - for (i=0; i < keydata.len; i++) { - tpm2_tool_output(" %s: ", keydata.entries[i].name); - tpm2_util_print_tpm2b(keydata.entries[i].value); - tpm2_tool_output("\n"); - } - - if (public->publicArea.authPolicy.size) { - tpm2_tool_output("authorization policy: "); - tpm2_util_hexdump(public->publicArea.authPolicy.buffer, - public->publicArea.authPolicy.size); - tpm2_tool_output("\n"); - } -} diff --git a/TPM2-Plugin/src/main.c b/TPM2-Plugin/src/main.c deleted file mode 100644 index 5020ce6..0000000 --- a/TPM2-Plugin/src/main.c +++ /dev/null @@ -1,75 +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 <stdio.h> -#include "tpm2_plugin_api.h" -//#include "plugin_register.h" -//#include "hwpluginif.h" - -void main(void) -{ - unsigned long mechanism =1; - void *param = NULL; - size_t len = 100; - void *keyHandle_sign = NULL; - - unsigned char *msg; - int msg_len; - unsigned char *sig; - int *sig_len; - - SSHSM_HW_PLUGIN_ACTIVATE_LOAD_IN_INFO_t *activate_in_info; - activate_in_info = malloc(sizeof(SSHSM_HW_PLUGIN_ACTIVATE_LOAD_IN_INFO_t)); - SSHSM_HW_PLUGIN_ACTIVATE_LOAD_IN_INFO_t *loadkey_in_info; - void **keyHandle; - - printf("---------------------------------------------\n"); - printf("Test app calling tpm2_plugin APIs\n"); - - printf("---------------------------------------------\n"); - tpm2_plugin_init(); - - printf("---------------------------------------------\n"); - tpm2_plugin_uninit(); - - printf("---------------------------------------------\n"); - tpm2_plugin_activate(activate_in_info); - - printf("---------------------------------------------\n"); - tpm2_plugin_load_key(loadkey_in_info, keyHandle ); - - printf("---------------------------------------------\n"); - tpm2_plugin_rsa_sign_init(keyHandle_sign, mechanism, param, len); - - printf("---------------------------------------------\n"); - tpm2_plugin_rsa_sign(keyHandle_sign, mechanism, msg, msg_len, sig, sig_len); - -} diff --git a/TPM2-Plugin/src/Makefile.am b/TPM2-Plugin/test/Makefile.am index 8cbcd68..8cbcd68 100644 --- a/TPM2-Plugin/src/Makefile.am +++ b/TPM2-Plugin/test/Makefile.am diff --git a/TPM2-Plugin/test/main.c b/TPM2-Plugin/test/main.c new file mode 100644 index 0000000..c9d15c8 --- /dev/null +++ b/TPM2-Plugin/test/main.c @@ -0,0 +1,67 @@ +/* Copyright 2018 Intel Corporation, Inc +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include <stdio.h> +#include "tpm2_plugin_api.h" +//#include "plugin_register.h" +//#include "hwpluginif.h" + +void main(void) +{ + unsigned long mechanism =1; + void *param = NULL; + size_t len = 100; + void *keyHandle_sign = NULL; + + unsigned char *msg; + int msg_len; + unsigned char *sig; + int *sig_len; + + SSHSM_HW_PLUGIN_ACTIVATE_LOAD_IN_INFO_t *activate_in_info; + activate_in_info = malloc(sizeof(SSHSM_HW_PLUGIN_ACTIVATE_LOAD_IN_INFO_t)); + SSHSM_HW_PLUGIN_ACTIVATE_LOAD_IN_INFO_t *loadkey_in_info; + loadkey_in_info = malloc(sizeof(SSHSM_HW_PLUGIN_ACTIVATE_LOAD_IN_INFO_t)); + loadkey_in_info->num_buffers = 2; + unsigned char *str ="abcde"; + //loadkey_in_info->buffer_info[0]->buffer = str; + //loadkey_in_info->buffer_info[0]->length_of_buffer = 5; + //loadkey_in_info->buffer_info[1]->buffer = str; + //loadkey_in_info->buffer_info[1]->length_of_buffer = 5; + + void **keyHandle; + + printf("---------------------------------------------\n"); + printf("Test app calling tpm2_plugin APIs\n"); + + printf("---------------------------------------------\n"); + tpm2_plugin_init(); + + printf("---------------------------------------------\n"); + tpm2_plugin_uninit(); + + printf("---------------------------------------------\n"); + tpm2_plugin_activate(activate_in_info); + + printf("---------------------------------------------\n"); + tpm2_plugin_rsa_sign_init(keyHandle_sign, mechanism, param, len); + + printf("---------------------------------------------\n"); + tpm2_plugin_load_key(loadkey_in_info, keyHandle); + + printf("---------------------------------------------\n"); + tpm2_plugin_rsa_sign(keyHandle_sign, mechanism, msg, msg_len, sig, sig_len); + +} |