From 8a5b33a9ba846d785d244e29bc29a46f7be34928 Mon Sep 17 00:00:00 2001 From: NingSun Date: Tue, 27 Mar 2018 10:42:51 -0700 Subject: Add more codes in tpm2-plugin Implement tpm2_plugin_load_key() and tpm2_plugin_rsa_sign() APIs Issue-ID: AAF-94 Change-Id: I5f4329fdf973e52264d9e0e8aabc864c5fbdeebf Signed-off-by: NingSun --- TPM2-Plugin/Makefile.am | 2 +- TPM2-Plugin/lib/Makefile.am | 5 +- TPM2-Plugin/lib/files.c | 8 +- TPM2-Plugin/lib/include/files.h | 34 ++- TPM2-Plugin/lib/include/log.h | 2 +- TPM2-Plugin/lib/include/plugin_register.h | 45 +++- TPM2-Plugin/lib/include/tpm2_alg_util.h | 2 +- TPM2-Plugin/lib/include/tpm2_attr_util.h | 2 +- TPM2-Plugin/lib/include/tpm2_convert.h | 99 +++++++++ TPM2-Plugin/lib/include/tpm2_error.h | 2 +- TPM2-Plugin/lib/include/tpm2_hash.h | 2 +- TPM2-Plugin/lib/include/tpm2_options.h | 208 ++++++++++++++++++ TPM2-Plugin/lib/include/tpm2_plugin_api.h | 26 ++- TPM2-Plugin/lib/include/tpm2_tcti_ldr.h | 16 +- TPM2-Plugin/lib/include/tpm2_tool.h | 86 ++++++++ TPM2-Plugin/lib/include/tpm2_util.h | 47 +--- TPM2-Plugin/lib/tpm2_alg_util.c | 2 +- TPM2-Plugin/lib/tpm2_attr_util.c | 48 ++--- TPM2-Plugin/lib/tpm2_convert.c | 216 +++++++++++++++++++ TPM2-Plugin/lib/tpm2_error.c | 3 +- TPM2-Plugin/lib/tpm2_hash.c | 2 +- TPM2-Plugin/lib/tpm2_plugin_api.c | 341 ++++++++++++++++++++++++++++-- TPM2-Plugin/lib/tpm2_plugin_init.c | 26 +-- TPM2-Plugin/lib/tpm2_tcti_ldr.c | 19 +- TPM2-Plugin/lib/tpm2_util.c | 67 +----- TPM2-Plugin/src/main.c | 31 ++- 26 files changed, 1154 insertions(+), 187 deletions(-) create mode 100644 TPM2-Plugin/lib/include/tpm2_convert.h create mode 100644 TPM2-Plugin/lib/include/tpm2_options.h create mode 100644 TPM2-Plugin/lib/include/tpm2_tool.h create mode 100644 TPM2-Plugin/lib/tpm2_convert.c diff --git a/TPM2-Plugin/Makefile.am b/TPM2-Plugin/Makefile.am index e932e6e..38afb93 100644 --- a/TPM2-Plugin/Makefile.am +++ b/TPM2-Plugin/Makefile.am @@ -1,2 +1,2 @@ -SUBDIRS = lib src +SUBDIRS = lib src ACLOCAL_AMFLAGS = -I m4 diff --git a/TPM2-Plugin/lib/Makefile.am b/TPM2-Plugin/lib/Makefile.am index c82cf86..26689a7 100644 --- a/TPM2-Plugin/lib/Makefile.am +++ b/TPM2-Plugin/lib/Makefile.am @@ -1,4 +1,5 @@ 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 plugin_register.c files.c tpm2_attr_util.c tpm2_alg_util.c tpm2_hash.c -libtpm2_plugin_la_LDFLAGS = -version-info @VERSION_INFO@ -lsapi -ltcti-socket -ltcti-device -lcrypto -lssl -ldl +libtpm2_plugin_la_SOURCES = tpm2_error.c tpm2_plugin_api.c tpm2_plugin_init.c tpm2_tcti_ldr.c tpm2_util.c log.c plugin_register.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 -ltcti-socket -ltcti-device -lcrypto -lssl -ldl +libtpm2_plugin_la_LDFLAGS = -version-info @VERSION_INFO@ -lsapi -ltss2-mu -ltcti-socket -ltcti-device -lcrypto -lssl -ldl diff --git a/TPM2-Plugin/lib/files.c b/TPM2-Plugin/lib/files.c index e2e41f4..b28a225 100644 --- a/TPM2-Plugin/lib/files.c +++ b/TPM2-Plugin/lib/files.c @@ -32,9 +32,10 @@ #include #include #include +#include -#include -#include +#include +#include #include "files.h" #include "log.h" @@ -634,3 +635,6 @@ 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 index 164e308..a4befc8 100644 --- a/TPM2-Plugin/lib/include/files.h +++ b/TPM2-Plugin/lib/include/files.h @@ -34,7 +34,7 @@ #include #include -#include +#include /** * Reads a series of bytes from a file as a byte array. This is similar to files_read_bytes(), @@ -213,6 +213,16 @@ bool files_load_ticket(const char *path, TPMT_TK_VERIFIED *ticket); */ 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 @@ -235,6 +245,28 @@ bool files_save_validation(TPMT_TK_HASHCHECK *validation, const char *path); */ 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 diff --git a/TPM2-Plugin/lib/include/log.h b/TPM2-Plugin/lib/include/log.h index c4ae0bd..a93c1c2 100644 --- a/TPM2-Plugin/lib/include/log.h +++ b/TPM2-Plugin/lib/include/log.h @@ -34,7 +34,7 @@ #include #include -#include +#include #include "tpm2_error.h" #include "tpm2_util.h" diff --git a/TPM2-Plugin/lib/include/plugin_register.h b/TPM2-Plugin/lib/include/plugin_register.h index a154a24..2bb118d 100644 --- a/TPM2-Plugin/lib/include/plugin_register.h +++ b/TPM2-Plugin/lib/include/plugin_register.h @@ -36,17 +36,51 @@ extern "C" { #endif +#define MAX_ID_LENGTH (32) + +typedef struct buffer_info_s{ + char id[MAX_ID_LENGTH+1]; + int length_of_buffer; + unsigned char *buffer; +}buffer_info_t; + + +typedef struct sshsm_hw_plugin_activate_in_info_s { + int num_buffers; + buffer_info_t *buffer_info; +}SSHSM_HW_PLUGIN_ACTIVATE_IN_INFO_t; + +typedef struct sshsm_hw_plugin_load_key_in_info_s { + int num_buffers; + buffer_info_t buffer_info[]; +}SSHSM_HW_PLUGIN_LOAD_KEY_IN_INFO_t; + + +//typedef int (*sshsm_hw_plugin_load_key)(SSHSM_HW_PLUGIN_LOAD_KEY_IN_INFO_t *loadkey_in_info, void **keyHandle); + +//typedef int (*sshsm_hw_plugin_activate)(SSHSM_HW_PLUGIN_ACTIVATE_IN_INFO_t *activate_in_info); + /* * Callback function definitions */ +typedef int (*fp_crypto_hw_plugin_init) ( ); +typedef int (*fp_crypto_hw_plugin_uninit) ( ); +typedef int (*fp_crypto_hw_plugin_activate)( + SSHSM_HW_PLUGIN_ACTIVATE_IN_INFO_t *activate_in_info + ); + +typedef int (*fp_crypto_hw_plugin_load_key)( + SSHSM_HW_PLUGIN_LOAD_KEY_IN_INFO_t *loadkey_in_info, + void **keyHandle + ); typedef int (*fp_crypto_rsa_decrypt_init) ( /* IN */ unsigned long mechanism, /* PKCS#11 Mechanism */ void *param, /* PKCS#11 Paramter */ unsigned long param_len, /* PKCS#11 Parameter len */ /* OUT */ - void *cb /* Address of pointer to store context block */ + void *cb /* Address of pointer to store context block */ ); typedef int (*fp_crypto_rsa_decrypt) ( @@ -167,10 +201,13 @@ typedef int (*fp_crypto_ecdsa_delete_object) ( ); -typedef struct +typedef struct { - fp_crypto_rsa_decrypt_init cb_crypto_rsa_decrypt_init; - fp_crypto_rsa_decrypt cb_crypto_rsa_decrypt; + fp_crypto_hw_plugin_init cb_crypto_hw_plugin_init; + fp_crypto_hw_plugin_uninit cb_crypto_hw_plugin_uninit; + fp_crypto_hw_plugin_activate cb_crypto_hw_plugin_activate; + fp_crypto_hw_plugin_load_key cb_crypto_hw_plugin_load_key; + fp_crypto_rsa_decrypt cb_crypto_rsa_decrypt; fp_crypto_rsa_sign_init cb_crypto_rsa_sign_init; fp_crypto_rsa_sign_update cb_crypto_rsa_sign_update; fp_crypto_rsa_sign_final cb_crypto_rsa_sign_final; diff --git a/TPM2-Plugin/lib/include/tpm2_alg_util.h b/TPM2-Plugin/lib/include/tpm2_alg_util.h index ce4083c..b9511dc 100644 --- a/TPM2-Plugin/lib/include/tpm2_alg_util.h +++ b/TPM2-Plugin/lib/include/tpm2_alg_util.h @@ -33,7 +33,7 @@ #include -#include +#include /** * Iterator callback routine for iterating over known algorithm name and value diff --git a/TPM2-Plugin/lib/include/tpm2_attr_util.h b/TPM2-Plugin/lib/include/tpm2_attr_util.h index 2487982..5964174 100644 --- a/TPM2-Plugin/lib/include/tpm2_attr_util.h +++ b/TPM2-Plugin/lib/include/tpm2_attr_util.h @@ -33,7 +33,7 @@ #include -#include +#include /** * Converts a list of | (pipe) separated attributes as defined in tavle 204 diff --git a/TPM2-Plugin/lib/include/tpm2_convert.h b/TPM2-Plugin/lib/include/tpm2_convert.h new file mode 100644 index 0000000..275d96a --- /dev/null +++ b/TPM2-Plugin/lib/include/tpm2_convert.h @@ -0,0 +1,99 @@ +//**********************************************************************; +// 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 + +#include + +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 index 0549edc..01ec043 100644 --- a/TPM2-Plugin/lib/include/tpm2_error.h +++ b/TPM2-Plugin/lib/include/tpm2_error.h @@ -30,7 +30,7 @@ #include -#include +#include /** * Number of error layers diff --git a/TPM2-Plugin/lib/include/tpm2_hash.h b/TPM2-Plugin/lib/include/tpm2_hash.h index 7fab882..627a95a 100644 --- a/TPM2-Plugin/lib/include/tpm2_hash.h +++ b/TPM2-Plugin/lib/include/tpm2_hash.h @@ -33,7 +33,7 @@ #include -#include +#include /** * Hashes a BYTE array via the tpm. diff --git a/TPM2-Plugin/lib/include/tpm2_options.h b/TPM2-Plugin/lib/include/tpm2_options.h new file mode 100644 index 0000000..860d9b0 --- /dev/null +++ b/TPM2-Plugin/lib/include/tpm2_options.h @@ -0,0 +1,208 @@ +/* + * 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 +#include +#include + +#include + +#include + +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 238af99..4c3ad63 100644 --- a/TPM2-Plugin/lib/include/tpm2_plugin_api.h +++ b/TPM2-Plugin/lib/include/tpm2_plugin_api.h @@ -35,7 +35,7 @@ #include #include -#include +#include #include "plugin_register.h" @@ -90,6 +90,14 @@ void TeardownSysContext( TSS2_SYS_CONTEXT **sysContext ); TSS2_RC TeardownTctiResMgrContext( TSS2_TCTI_CONTEXT *tctiContext ); +int tpm2_plugin_init(); +int tpm2_plugin_uninit(); +int tpm2_plugin_activate(SSHSM_HW_PLUGIN_ACTIVATE_IN_INFO_t *activate_in_info); +int tpm2_plugin_load_key( + SSHSM_HW_PLUGIN_LOAD_KEY_IN_INFO_t *loadkey_in_info, + void **keyHandle + ); + int tpm2_rsa_create_object( unsigned long appHandle, //DhsmWPKRSAFormat* wpk, @@ -104,13 +112,13 @@ int tpm2_rsa_create_object( int tpm2_rsa_delete_object( void *cb_object); -int tpm2_rsa_sign_init( +int tpm2_plugin_rsa_sign_init( unsigned long mechanish, void *param, size_t len, void *ctx); -int tpm2_rsa_sign( +int tpm2_plugin_rsa_sign( void *ctx, unsigned char *msg, int msg_len, @@ -119,12 +127,12 @@ int tpm2_rsa_sign( int tpm2_import_object( - unsigned long appHandle, - unsigned char* tlvbuffer, - int buflen, - unsigned char* iv, - int iv_len, - unsigned char* tpm_pwd, + unsigned long appHandle, + unsigned char* tlvbuffer, + int buflen, + unsigned char* iv, + int iv_len, + unsigned char* tpm_pwd, int tpm_pwd_len); diff --git a/TPM2-Plugin/lib/include/tpm2_tcti_ldr.h b/TPM2-Plugin/lib/include/tpm2_tcti_ldr.h index 1e20d3d..684e5e2 100644 --- a/TPM2-Plugin/lib/include/tpm2_tcti_ldr.h +++ b/TPM2-Plugin/lib/include/tpm2_tcti_ldr.h @@ -25,7 +25,7 @@ // THE POSSIBILITY OF SUCH DAMAGE. //**********************************************************************; -#include +#include #ifndef LIB_TPM2_TCTI_LDR_H_ #define LIB_TPM2_TCTI_LDR_H_ @@ -34,8 +34,8 @@ * Loads a TCTI from a friendly name, library name, or path. * For example * friendly: path = tabrmd - * library name: path = libtcti-socket.so - * full path: path = /home/user/lib/libtcti-custom.so + * 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 @@ -54,6 +54,16 @@ TSS2_TCTI_CONTEXT *tpm2_tcti_ldr_load(const char *path, const char *opts); */ 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(); */ diff --git a/TPM2-Plugin/lib/include/tpm2_tool.h b/TPM2-Plugin/lib/include/tpm2_tool.h new file mode 100644 index 0000000..f24be38 --- /dev/null +++ b/TPM2-Plugin/lib/include/tpm2_tool.h @@ -0,0 +1,86 @@ +/* + * 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 +#include + +#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 index edc759d..de02777 100644 --- a/TPM2-Plugin/lib/include/tpm2_util.h +++ b/TPM2-Plugin/lib/include/tpm2_util.h @@ -35,7 +35,7 @@ #include #include -#include +#include #include "tpm2_error.h" @@ -118,20 +118,10 @@ __result; \ }) -/** - * 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) +typedef struct { + UINT16 size; + BYTE buffer[0]; +} TPM2B; int tpm2_util_hex_to_byte_structure(const char *inStr, UINT16 *byteLenth, BYTE *byteBuffer); @@ -176,28 +166,23 @@ bool tpm2_util_string_to_uint16(const char *str, uint16_t *value); * The data to print. * @param len * The length of the data. - * @param plain - * true for a plain hex string false for an xxd compatable - * dump. */ -void tpm2_util_hexdump(const BYTE *data, size_t len, bool plain); +void tpm2_util_hexdump(const BYTE *data, size_t len); /** - * Prints an xxd compatible hexdump to stdout if output is enabled, + * 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. - * @param plain - * true for a plain hex string false for an xxd compatable - * dump. * @return * true if len bytes were successfully read and printed, * false otherwise */ -bool tpm2_util_hexdump_file(FILE *fd, size_t len, bool plain); +bool tpm2_util_hexdump_file(FILE *fd, size_t len); /** * Prints a TPM2B as a hex dump. @@ -205,7 +190,7 @@ bool tpm2_util_hexdump_file(FILE *fd, size_t len, bool plain); */ static inline void tpm2_util_print_tpm2b(TPM2B *buffer) { - return tpm2_util_hexdump(buffer->buffer, buffer->size, true); + return tpm2_util_hexdump(buffer->buffer, buffer->size); } /** @@ -215,18 +200,6 @@ static inline void tpm2_util_print_tpm2b(TPM2B *buffer) { */ bool tpm2_util_print_tpm2b_file(FILE *fd); -/** - * Copies a tpm2b from dest to src and clears dest if src is NULL. - * If src is NULL, it is a NOP. - * @param dest - * The destination TPM2B - * @param src - * The source TPM2B - * @return - * The number of bytes copied. - */ -UINT16 tpm2_util_copy_tpm2b(TPM2B *dest, TPM2B *src); - /** * Checks if the host is big endian * @return diff --git a/TPM2-Plugin/lib/tpm2_alg_util.c b/TPM2-Plugin/lib/tpm2_alg_util.c index 975f4ae..3683b6e 100644 --- a/TPM2-Plugin/lib/tpm2_alg_util.c +++ b/TPM2-Plugin/lib/tpm2_alg_util.c @@ -32,7 +32,7 @@ #include #include -#include +#include #include "files.h" #include "log.h" diff --git a/TPM2-Plugin/lib/tpm2_attr_util.c b/TPM2-Plugin/lib/tpm2_attr_util.c index 03ce2d5..b21141d 100644 --- a/TPM2-Plugin/lib/tpm2_attr_util.c +++ b/TPM2-Plugin/lib/tpm2_attr_util.c @@ -32,7 +32,7 @@ #include #include -#include +#include #include "log.h" #include "tpm2_attr_util.h" @@ -66,147 +66,147 @@ struct dispatch_table { static bool authread(TPMA_NV *nv, char *arg) { UNUSED(arg); - *nv |= TPMA_NV_TPMA_NV_AUTHREAD; + *nv |= TPMA_NV_AUTHREAD; return true; } static bool authwrite(TPMA_NV *nv, char *arg) { UNUSED(arg); - *nv |= TPMA_NV_TPMA_NV_AUTHWRITE; + *nv |= TPMA_NV_AUTHWRITE; return true; } static bool clear_stclear(TPMA_NV *nv, char *arg) { UNUSED(arg); - *nv |= TPMA_NV_TPMA_NV_CLEAR_STCLEAR; + *nv |= TPMA_NV_CLEAR_STCLEAR; return true; } static bool globallock(TPMA_NV *nv, char *arg) { UNUSED(arg); - *nv |= TPMA_NV_TPMA_NV_GLOBALLOCK; + *nv |= TPMA_NV_GLOBALLOCK; return true; } static bool no_da(TPMA_NV *nv, char *arg) { UNUSED(arg); - *nv |= TPMA_NV_TPMA_NV_NO_DA; + *nv |= TPMA_NV_NO_DA; return true; } static bool orderly(TPMA_NV *nv, char *arg) { UNUSED(arg); - *nv |= TPMA_NV_TPMA_NV_ORDERLY; + *nv |= TPMA_NV_ORDERLY; return true; } static bool ownerread(TPMA_NV *nv, char *arg) { UNUSED(arg); - *nv |= TPMA_NV_TPMA_NV_OWNERREAD; + *nv |= TPMA_NV_OWNERREAD; return true; } static bool ownerwrite(TPMA_NV *nv, char *arg) { UNUSED(arg); - *nv |= TPMA_NV_TPMA_NV_OWNERWRITE; + *nv |= TPMA_NV_OWNERWRITE; return true; } static bool platformcreate(TPMA_NV *nv, char *arg) { UNUSED(arg); - *nv |= TPMA_NV_TPMA_NV_PLATFORMCREATE; + *nv |= TPMA_NV_PLATFORMCREATE; return true; } static bool policyread(TPMA_NV *nv, char *arg) { UNUSED(arg); - *nv |= TPMA_NV_TPMA_NV_POLICYREAD; + *nv |= TPMA_NV_POLICYREAD; return true; } static bool policywrite(TPMA_NV *nv, char *arg) { UNUSED(arg); - *nv |= TPMA_NV_TPMA_NV_POLICYWRITE; + *nv |= TPMA_NV_POLICYWRITE; return true; } static bool policydelete(TPMA_NV *nv, char *arg) { UNUSED(arg); - *nv |= TPMA_NV_TPMA_NV_POLICY_DELETE; + *nv |= TPMA_NV_POLICY_DELETE; return true; } static bool ppread(TPMA_NV *nv, char *arg) { UNUSED(arg); - *nv |= TPMA_NV_TPMA_NV_PPREAD; + *nv |= TPMA_NV_PPREAD; return true; } static bool ppwrite(TPMA_NV *nv, char *arg) { UNUSED(arg); - *nv |= TPMA_NV_TPMA_NV_PPWRITE; + *nv |= TPMA_NV_PPWRITE; return true; } static bool readlocked(TPMA_NV *nv, char *arg) { UNUSED(arg); - *nv |= TPMA_NV_TPMA_NV_READLOCKED; + *nv |= TPMA_NV_READLOCKED; return true; } static bool read_stclear(TPMA_NV *nv, char *arg) { UNUSED(arg); - *nv |= TPMA_NV_TPMA_NV_READ_STCLEAR; + *nv |= TPMA_NV_READ_STCLEAR; return true; } static bool writeall(TPMA_NV *nv, char *arg) { UNUSED(arg); - *nv |= TPMA_NV_TPMA_NV_WRITEALL; + *nv |= TPMA_NV_WRITEALL; return true; } static bool writedefine(TPMA_NV *nv, char *arg) { UNUSED(arg); - *nv |= TPMA_NV_TPMA_NV_WRITEDEFINE; + *nv |= TPMA_NV_WRITEDEFINE; return true; } static bool writelocked(TPMA_NV *nv, char *arg) { UNUSED(arg); - *nv |= TPMA_NV_TPMA_NV_WRITELOCKED; + *nv |= TPMA_NV_WRITELOCKED; return true; } static bool write_stclear(TPMA_NV *nv, char *arg) { UNUSED(arg); - *nv |= TPMA_NV_TPMA_NV_WRITE_STCLEAR; + *nv |= TPMA_NV_WRITE_STCLEAR; return true; } static bool written(TPMA_NV *nv, char *arg) { UNUSED(arg); - *nv |= TPMA_NV_TPMA_NV_WRITTEN; + *nv |= TPMA_NV_WRITTEN; return true; } @@ -226,7 +226,7 @@ static bool nt(TPMA_NV *nv, char *arg) { return false; } - *nv &= ~TPMA_NV_TPM2_NT; + *nv &= ~TPMA_NV_TPM2_NT_MASK; *nv |= value << 4; return true; } @@ -348,7 +348,7 @@ static bool decrypt(TPMA_OBJECT *obj, char *arg) { static bool sign(TPMA_OBJECT *obj, char *arg) { UNUSED(arg); - *obj |= TPMA_OBJECT_SIGN; + *obj |= TPMA_OBJECT_SIGN_ENCRYPT; return true; } diff --git a/TPM2-Plugin/lib/tpm2_convert.c b/TPM2-Plugin/lib/tpm2_convert.c new file mode 100644 index 0000000..9b09c81 --- /dev/null +++ b/TPM2-Plugin/lib/tpm2_convert.c @@ -0,0 +1,216 @@ +//**********************************************************************; +// 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 +#include + +#include +#include +#include +#include + +#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 index 7bc024d..32eeb41 100644 --- a/TPM2-Plugin/lib/tpm2_error.c +++ b/TPM2-Plugin/lib/tpm2_error.c @@ -28,8 +28,9 @@ #include #include #include +#include -#include +#include #include "tpm2_error.h" #include "tpm2_util.h" diff --git a/TPM2-Plugin/lib/tpm2_hash.c b/TPM2-Plugin/lib/tpm2_hash.c index ecf3a72..5ea7400 100644 --- a/TPM2-Plugin/lib/tpm2_hash.c +++ b/TPM2-Plugin/lib/tpm2_hash.c @@ -31,7 +31,7 @@ #include #include -#include +#include #include "log.h" #include "files.h" diff --git a/TPM2-Plugin/lib/tpm2_plugin_api.c b/TPM2-Plugin/lib/tpm2_plugin_api.c index adc8cf7..7e9a7a8 100644 --- a/TPM2-Plugin/lib/tpm2_plugin_api.c +++ b/TPM2-Plugin/lib/tpm2_plugin_api.c @@ -29,15 +29,21 @@ // THE POSSIBILITY OF SUCH DAMAGE. //**********************************************************************; -#include +#include #include #include #include "tpm2_plugin_api.h" -#include "log.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" +bool output_enabled = true; -const char *tcti_path="libtcti-device.so"; +const char *tcti_path="libtss2-tcti-device.so"; static void tcti_teardown (TSS2_TCTI_CONTEXT *tcti_context) { @@ -68,15 +74,18 @@ static void sapi_teardown_full (TSS2_SYS_CONTEXT *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 = { - .tssCreator = TSSWG_INTEROP, - .tssFamily = TSS_SAPI_FIRST_FAMILY, - .tssLevel = TSS_SAPI_FIRST_LEVEL, - .tssVersion = TSS_SAPI_FIRST_VERSION, - }; + 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); @@ -95,22 +104,325 @@ static TSS2_SYS_CONTEXT* sapi_ctx_init(TSS2_TCTI_CONTEXT *tcti_ctx) return sapi_ctx; } -int tpm2_rsa_sign_init( + + +int tpm2_plugin_init() +{ + printf("Init API done for TPM plugin ! \n"); + return 0; +} + +int tpm2_plugin_uninit() +{ + printf("UnInit API done for TPM plugin ! \n"); + return 0; +} + +int tpm2_plugin_activate(SSHSM_HW_PLUGIN_ACTIVATE_IN_INFO_t *activate_in_info) +{ + + printf("Activate API done for TPM plugin ! \n"); + 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; +}; + +static tpm_load_ctx ctx_load = { + .session_data = { + .sessionHandle = TPM2_RS_PW, + .nonce = TPM2B_EMPTY_INIT, + .hmac = TPM2B_EMPTY_INIT, + .sessionAttributes = 0 + } +}; + +int load (TSS2_SYS_CONTEXT *sapi_context) { + UINT32 rval; + TSS2L_SYS_AUTH_COMMAND sessionsData; + TSS2L_SYS_AUTH_RESPONSE sessionsDataOut; + + 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) + { + LOG_PERR(Tss2_Sys_Load, rval); + 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; + } + } + + return 0; +} + +int tpm2_tool_load_key(TSS2_SYS_CONTEXT *sapi_context) +{ + + 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; + } + + 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; + } + } + + returnVal = load(sapi_context); + if (returnVal) { + return 1; + } + + 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; + } + } + + return 0; +} + +int tpm2_plugin_load_key( + SSHSM_HW_PLUGIN_LOAD_KEY_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); + return -1; + } + + TSS2_SYS_CONTEXT *sapi_context = NULL; + if (tcti) { + sapi_context = sapi_ctx_init(tcti); + if (!sapi_context) { + goto free_tcti; + } + } + + ret = tpm2_tool_load_key(sapi_context); + if (ret != 0) { + LOG_ERR("Unable to run tpm2_tool_iload_key"); + sapi_teardown_full(sapi_context); + +free_tcti: + tpm2_tcti_ldr_unload(); + return ret; + } + + printf("Load key API done for TPM plugin ! \n"); + return 0; + +} + +typedef struct tpm_sign_ctx tpm_sign_ctx; +struct tpm_sign_ctx { + TPMT_TK_HASHCHECK validation; + TPMS_AUTH_COMMAND sessionData; + TPMI_DH_OBJECT keyHandle; + TPMI_ALG_HASH halg; + TPM2B_DIGEST digest; + char *outFilePath; + 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), +}; + + +int tpm2_plugin_rsa_sign_init( unsigned long mechanish, void *param, size_t len, void *ctx) { - printf("executing tpm2_rsa_sign_init in tpm2_plugin... \n"); + printf("rsa_sign_init API done for tpm2_plugin... \n"); return 0; } +static bool init_sign(TSS2_SYS_CONTEXT *sapi_context) { + + 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; + } + + if (ctx_sign.flags.D && (ctx_sign.flags.t || ctx_sign.flags.m)) { + LOG_WARN("Option D provided, options m and t are ignored."); + } + + 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)); + } + + /* + * 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; + } + } + + /* + * 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; + } + } + + return true; +} + + +static bool sign_and_save(TSS2_SYS_CONTEXT *sapi_context) { + + TPMT_SIG_SCHEME in_scheme; + TPMT_SIGNATURE signature; + + TSS2L_SYS_AUTH_COMMAND sessions_data = { 1, { ctx_sign.sessionData }}; + TSS2L_SYS_AUTH_RESPONSE sessions_data_out; + + 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; + } + } + + bool result = get_signature_scheme(sapi_context, ctx_sign.keyHandle, ctx_sign.halg, &in_scheme); + 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); + return false; + } + + return tpm2_convert_sig(&signature, ctx_sign.sig_format, ctx_sign.outFilePath); +} + + int tpm2_tool_sign(TSS2_SYS_CONTEXT *sapi_context) { - return 0; + + bool result = init_sign(sapi_context); + if (!result) { + return 1; + } + + result = sign_and_save(sapi_context); + + free(ctx_sign.msg); + + return result != true; } -int tpm2_rsa_sign( + +int tpm2_plugin_rsa_sign( void *ctx, unsigned char *msg, int msg_len, @@ -141,7 +453,8 @@ int tpm2_rsa_sign( free_tcti: tpm2_tcti_ldr_unload(); return ret; -} + } + printf("rsa_sign API done for tpm2_plugin... \n"); } int tpm2_rsa_create_object( diff --git a/TPM2-Plugin/lib/tpm2_plugin_init.c b/TPM2-Plugin/lib/tpm2_plugin_init.c index 5ef0fce..d73b230 100644 --- a/TPM2-Plugin/lib/tpm2_plugin_init.c +++ b/TPM2-Plugin/lib/tpm2_plugin_init.c @@ -35,31 +35,17 @@ #include "tpm2_plugin_api.h" -int __plugin_init(char* configPath) -{ -// if tpm_plugin, do this - printf("Init module done for TPM plug-in mode ! \n"); -// if SGX_plugin, do this - - return 0; -} - -int __plugin_finialize() -{ -// if tpm_plugin, do this - printf("Finalize module done for SW mode ! \n"); -// if SGX_plugin, do this - - return 0; -} int __plugin_functions_mapping(plugin_register *plugin_fp) { printf("%s(): Assigning Function pointers for TPM (dTPM or PTT) mode \n", __func__); - plugin_fp->cb_crypto_rsa_decrypt_init = NULL; + plugin_fp->cb_crypto_hw_plugin_init = &tpm2_plugin_init; + plugin_fp->cb_crypto_hw_plugin_uninit = &tpm2_plugin_uninit; + plugin_fp->cb_crypto_hw_plugin_activate = &tpm2_plugin_activate; + plugin_fp->cb_crypto_hw_plugin_load_key = &tpm2_plugin_load_key; plugin_fp->cb_crypto_rsa_decrypt = NULL; - plugin_fp->cb_crypto_rsa_sign_init = &tpm2_rsa_sign_init; - plugin_fp->cb_crypto_rsa_sign = &tpm2_rsa_sign; + plugin_fp->cb_crypto_rsa_sign_init = &tpm2_plugin_rsa_sign_init; + plugin_fp->cb_crypto_rsa_sign = &tpm2_plugin_rsa_sign; plugin_fp->cb_crypto_rsa_sign_update = NULL; plugin_fp->cb_crypto_rsa_sign_final = NULL; plugin_fp->cb_crypto_ecdsa_sign = NULL; diff --git a/TPM2-Plugin/lib/tpm2_tcti_ldr.c b/TPM2-Plugin/lib/tpm2_tcti_ldr.c index 9f25188..5b827a9 100644 --- a/TPM2-Plugin/lib/tpm2_tcti_ldr.c +++ b/TPM2-Plugin/lib/tpm2_tcti_ldr.c @@ -30,7 +30,7 @@ #include #include -#include +#include #include "log.h" #include "tpm2_tcti_ldr.h" @@ -52,6 +52,19 @@ 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; @@ -63,13 +76,13 @@ TSS2_TCTI_CONTEXT *tpm2_tcti_ldr_load(const char *path, const char *opts) { /* * Try what they gave us, if it doesn't load up, try - * libtcti-xxx.so replacing xxx with what they gave us. + * 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), "libtcti-%s.so", path); + 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); diff --git a/TPM2-Plugin/lib/tpm2_util.c b/TPM2-Plugin/lib/tpm2_util.c index 7a42df7..c0a6cc4 100644 --- a/TPM2-Plugin/lib/tpm2_util.c +++ b/TPM2-Plugin/lib/tpm2_util.c @@ -31,13 +31,16 @@ #include #include #include +#include +#include #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 output_enabled; + bool tpm2_util_concat_buffer(TPM2B_MAX_BUFFER *result, TPM2B *append) { if (!result || !append) { @@ -131,45 +134,19 @@ int tpm2_util_hex_to_byte_structure(const char *inStr, UINT16 *byteLength, return 0; } -void tpm2_util_hexdump(const BYTE *data, size_t len, bool plain) { +void tpm2_util_hexdump(const BYTE *data, size_t len) { if (!output_enabled) { return; } - if (plain) { - size_t i; - for (i=0; i < len; i++) { - printf("%02x", data[i]); - } - return; - } - size_t i; - size_t j; - for (i = 0; i < len; i += 16) { - printf("%06zx: ", i); - - for (j = 0; j < 16; j++) { - if (i + j < len) { - printf("%02x ", data[i + j]); - } else { - printf(" "); - } - } - - printf(" "); - - for (j = 0; j < 16; j++) { - if (i + j < len) { - printf("%c", isprint(data[i + j]) ? data[i + j] : '.'); - } - } - printf("\n"); + for (i=0; i < len; i++) { + printf("%02x", data[i]); } } -bool tpm2_util_hexdump_file(FILE *fd, size_t len, bool plain) { +bool tpm2_util_hexdump_file(FILE *fd, size_t len) { BYTE* buff = (BYTE*)malloc(len); if (!buff) { LOG_ERR("malloc() failed"); @@ -183,7 +160,7 @@ bool tpm2_util_hexdump_file(FILE *fd, size_t len, bool plain) { return false; } - tpm2_util_hexdump(buff, len, plain); + tpm2_util_hexdump(buff, len); free(buff); return true; @@ -197,29 +174,7 @@ bool tpm2_util_print_tpm2b_file(FILE *fd) LOG_ERR("File read failed"); return false; } - return tpm2_util_hexdump_file(fd, len, true); -} - -/* TODO OPTIMIZE ME */ -UINT16 tpm2_util_copy_tpm2b(TPM2B *dest, TPM2B *src) { - int i; - UINT16 rval = 0; - - if (dest != 0) { - if (src == 0) { - dest->size = 0; - rval = 0; - } else { - dest->size = src->size; - for (i = 0; i < src->size; i++) - dest->buffer[i] = src->buffer[i]; - rval = (sizeof(UINT16) + src->size); - } - } else { - rval = 0; - } - - return rval; + return tpm2_util_hexdump_file(fd, len); } bool tpm2_util_is_big_endian(void) { @@ -386,7 +341,7 @@ void tpm2_util_public_to_yaml(TPM2B_PUBLIC *public) { if (public->publicArea.authPolicy.size) { tpm2_tool_output("authorization policy: "); tpm2_util_hexdump(public->publicArea.authPolicy.buffer, - public->publicArea.authPolicy.size, true); + public->publicArea.authPolicy.size); tpm2_tool_output("\n"); } } diff --git a/TPM2-Plugin/src/main.c b/TPM2-Plugin/src/main.c index 69bb29f..6fc54a4 100644 --- a/TPM2-Plugin/src/main.c +++ b/TPM2-Plugin/src/main.c @@ -31,6 +31,7 @@ #include #include "tpm2_plugin_api.h" +#include "plugin_register.h" void main(void) { @@ -38,11 +39,35 @@ void main(void) void *param = NULL; size_t len = 100; void *ctx = NULL; + + unsigned char *msg; + int msg_len; + unsigned char *sig; + int *sig_len; - printf("test app calling tpm2_rsa_sign_init in tpm2_plugin \n"); + SSHSM_HW_PLUGIN_ACTIVATE_IN_INFO_t *activate_in_info; + SSHSM_HW_PLUGIN_LOAD_KEY_IN_INFO_t *loadkey_in_info; + void **keyHandle; - tpm2_rsa_sign_init(mechanish, param, len, ctx); + printf("---------------------------------------------\n"); + printf("Test app calling tpm2_plugin APIs\n"); - printf("tpm2_rsa_sign_init was returned from tpm2_plugin, test app will exit... \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(mechanish, param, len, ctx); + + printf("---------------------------------------------\n"); + tpm2_plugin_rsa_sign(ctx, msg, msg_len, sig, sig_len); } -- cgit 1.2.3-korg