From 2ac563372735668ac9687c57e35e39c3e4553ff0 Mon Sep 17 00:00:00 2001 From: Arun kumar Sekar Date: Fri, 30 Mar 2018 11:20:30 -0700 Subject: Utility to Import external RSA pem key into TPM Duplicate tool - Takes RSA private key in pem format as input and generates TPM structured buffers as expected by tpm Import Import tool - Takes input buffers from Duplicate tool and results in pub/priv blobs which can be used to load the key in tpm storage heirarchy's as child to primary key Change-Id: I0af6676895ce0cc22c70e5546908e905b78bb71e Issue-ID: AAF-207 Signed-off-by: Arun kumar Sekar --- tpm-util/import/include/tpm_wrapper.h | 60 +++++++++ tpm-util/import/include/util.h | 25 ++++ tpm-util/import/main.c | 244 ++++++++++++++++++++++++++++++++++ tpm-util/import/sampleMakefile | 38 ++++++ tpm-util/import/tpm_wrapper.c | 213 +++++++++++++++++++++++++++++ tpm-util/import/util.c | 104 +++++++++++++++ 6 files changed, 684 insertions(+) create mode 100644 tpm-util/import/include/tpm_wrapper.h create mode 100644 tpm-util/import/include/util.h create mode 100644 tpm-util/import/main.c create mode 100644 tpm-util/import/sampleMakefile create mode 100644 tpm-util/import/tpm_wrapper.c create mode 100644 tpm-util/import/util.c (limited to 'tpm-util/import') diff --git a/tpm-util/import/include/tpm_wrapper.h b/tpm-util/import/include/tpm_wrapper.h new file mode 100644 index 0000000..4d1639d --- /dev/null +++ b/tpm-util/import/include/tpm_wrapper.h @@ -0,0 +1,60 @@ +/* + * Copyright 2018 Intel Corporation + * + * 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. + */ +// Author: Arun Kumar Sekar + +#ifndef __TPM_WRAPPER_H__ +#define __TPM_WRAPPER_H__ + +#include +#include +#include +#include +#include +#include + +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define INIT_SIMPLE_TPM2B_SIZE( type ) (type).t.size = sizeof( type ) - 2; + +TSS2_TCTI_CONTEXT* tpm_tcti_tabrmd_init (void); + +TSS2_SYS_CONTEXT* sys_ctx_init (TSS2_TCTI_CONTEXT *tcti_ctx); + +TSS2_RC TeardownTctiContext( TSS2_TCTI_CONTEXT *tctiContext ); + +void TeardownSysContext( TSS2_SYS_CONTEXT **sysContext ); + +TSS2_RC swKeyTpmImport( + /* IN */ + TSS2_SYS_CONTEXT *sysContext, + TPM_HANDLE parentKeyHandle, + TPM2B_DATA* encryptionKey, TPM2B_PUBLIC* swKeyPublic, TPM2B_PRIVATE* swKeyPrivate, TPM2B_ENCRYPTED_SECRET* encSymSeed, + unsigned char* tpm_pwd, int tpm_pwd_len, + /* OUT */ + TPM2B_PRIVATE *importPrivate); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/tpm-util/import/include/util.h b/tpm-util/import/include/util.h new file mode 100644 index 0000000..5d89376 --- /dev/null +++ b/tpm-util/import/include/util.h @@ -0,0 +1,25 @@ +/* + * Copyright 2018 Intel Corporation + * + * 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. + */ +// Author: Arun Kumar Sekar + +#ifndef __UTIL_H__ +#define __UTIL_H__ + +int saveDataToFile(const char *fileName, UINT8 *buf, UINT16 size); + +int loadDataFromFile(const char *fileName, UINT8 *buf, UINT16 *size); + +#endif diff --git a/tpm-util/import/main.c b/tpm-util/import/main.c new file mode 100644 index 0000000..c498f6c --- /dev/null +++ b/tpm-util/import/main.c @@ -0,0 +1,244 @@ +/* + * Copyright 2018 Intel Corporation + * + * 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. + */ +// +// main.c : Tool to import Openssl RSA key into TPM +// Author: Arun Kumar Sekar +// + +#include +#include +#include +#include + +#include + +#include "tpm_wrapper.h" +#include "util.h" + +char* tpm_pwd = ""; +int tpm_pwd_len = 0; + +void PrintHelp(); +char version[] = "0.1"; + +void PrintHelp() +{ + printf( + "OSSL key to tpm import tool, Version %s\nUsage:" + "./ossl_tpm_import " + "[-dupPub out_dupPubFile] [-dupPriv out_dupPrivFile] [-dupSymSeed out_dupSymSeedFile] [-dupEncKey out_dupEncKeyFile]" + "[-pub out_keyPub] [-priv out_KeyPriv]\n" + "\n" + , version); +} + +int main(int argc, char* argv[]) +{ + TPM_RC rval = 0; + int count=0; + TSS2_TCTI_CONTEXT *tcti_ctx = 0; + TSS2_SYS_CONTEXT *sysContext = 0; + + // SW Key Duplicate O/P variables + char dupPub_Filename[256]; + int dupPub_flag = 0; + char dupPriv_Filename[256]; + int dupPriv_flag = 0; + char dupSymSeed_Filename[256]; + int dupSymSeed_flag = 0; + char dupEncKey_Filename[256]; + int dupEncKey_flag = 0; + TPM2B_DATA encryptionKey; + TPM2B_PUBLIC swKeyPublic; + TPM2B_PRIVATE swKeyPrivate; + TPM2B_ENCRYPTED_SECRET encSymSeed; + + // SW Key Import O/P variables + char pub_Filename[256]; + int pub_flag = 0; + char priv_Filename[256]; + int priv_flag = 0; + unsigned short file_size = 0; + + TPM_HANDLE primaryKeyHandle = 0; + int H_flag = 0; + + TPM2B_PUBLIC parentKeyPublicPortion; + int pubKeysize = 0; + + setbuf(stdout, NULL); + setvbuf (stdout, NULL, _IONBF, BUFSIZ); + if( (argc < 2) ) + { + printf("Arguments count does not match \n"); + PrintHelp(); + return 1; + } + else + { + /* Get the argument values and evaluate it */ + for( count = 1; count < argc; count++ ) + { + if( 0 == strcmp( argv[count], "-dupPub" ) ) { + count++; + if( (1 != sscanf( argv[count], "%s", dupPub_Filename )) ) + { + PrintHelp(); + return 1; + } + dupPub_flag = 1; + } + else if( 0 == strcmp( argv[count], "-dupPriv" ) ) { + count++; + if( (1 != sscanf( argv[count], "%s", dupPriv_Filename )) ) + { + PrintHelp(); + return 1; + } + dupPriv_flag = 1; + } + else if( 0 == strcmp( argv[count], "-dupSymSeed" ) ) { + count++; + if( (1 != sscanf( argv[count], "%s", dupSymSeed_Filename )) ) + { + PrintHelp(); + return 1; + } + dupSymSeed_flag = 1; + } + else if( 0 == strcmp( argv[count], "-dupEncKey" ) ) { + count++; + if( (1 != sscanf( argv[count], "%s", dupEncKey_Filename )) ) + { + PrintHelp(); + return 1; + } + dupEncKey_flag = 1; + } + else if( 0 == strcmp( argv[count], "-pub" ) ) { + count++; + if( (1 != sscanf( argv[count], "%s", pub_Filename )) ) + { + PrintHelp(); + return 1; + } + pub_flag = 1; + } + else if( 0 == strcmp( argv[count], "-priv" ) ) { + count++; + if( (1 != sscanf( argv[count], "%s", priv_Filename )) ) + { + PrintHelp(); + return 1; + } + priv_flag = 1; + } + else if( 0 == strcmp( argv[count], "-H" ) ) { + count++; + primaryKeyHandle = strtoul(argv[count], NULL, 16); + printf("Primary Key handle Given: 0x%x \n", primaryKeyHandle); + H_flag = 1; + } + else if( 0 == strcmp( argv[count], "--help" ) ) { + PrintHelp(); + exit(1); + } + else { + PrintHelp(); + exit(1); + } + } + } + + if((!H_flag)) { + printf("Parent handle should be passed for TPM import operation \n"); + return -1; + } + + // For TPM Import functionality, check all input params are present + if( (!dupPub_flag) || + (!dupPriv_flag) || + (!dupSymSeed_flag) || + (!dupEncKey_flag) || + (!pub_flag) || + (!priv_flag) + ) { + printf("Error: One or more Inputs for TPM import functionality is missing ! \n"); + return -1; + } + + /* SW Key TPM Import operation started */ + if(rval == 0) { + file_size = sizeof(TPM2B_PUBLIC); + rval = loadDataFromFile(dupPub_Filename, (UINT8 *) &swKeyPublic, &file_size); + if ( rval == 0 ) { + file_size = sizeof(TPM2B_PRIVATE); + rval = loadDataFromFile(dupPriv_Filename, (UINT8 *) &swKeyPrivate, &file_size); + } + if ( rval == 0 ) { + file_size = sizeof(TPM2B_ENCRYPTED_SECRET); + rval = loadDataFromFile(dupSymSeed_Filename, (UINT8 *) &encSymSeed, &file_size); + } + if ( rval == 0 ) { + file_size = sizeof(TPM2B_DATA); + rval = loadDataFromFile(dupEncKey_Filename, (UINT8 *) &encryptionKey, &file_size); + } + + if ( rval == 0 ) { + /* Initialize TCTI and sapi context */ + tcti_ctx = tpm_tcti_tabrmd_init(); + if(tcti_ctx == NULL) { + printf("Creation of TCTI context with TABRMD failed ! \n"); + goto end; + } + + sysContext = sys_ctx_init(tcti_ctx); + if(sysContext == NULL) { + printf("Creation of SAPI context with TABRMD failed ! \n"); + goto end; + } + printf("\nInitializing TPM context success: 0x%x ! \n", rval); + } + + TPM2B_PRIVATE importPrivate; + INIT_SIMPLE_TPM2B_SIZE(importPrivate); + rval = swKeyTpmImport(sysContext, primaryKeyHandle, + &encryptionKey, &swKeyPublic, &swKeyPrivate, &encSymSeed, + tpm_pwd, tpm_pwd_len, + &importPrivate); + if(rval != 0) { + printf("\nswKeyTpmImport failed: 0x%x ! \n", rval); + goto end; + } + else { + printf("\nswKeyImport success: 0x%x ! \n", rval); + saveDataToFile(pub_Filename, (UINT8 *) &swKeyPublic, sizeof(TPM2B_PUBLIC)); + saveDataToFile(priv_Filename, (UINT8 *) &importPrivate, sizeof(TPM2B_PRIVATE)); + printf("\nOutput files are written successfully ! \n"); + } + } + +end: + if(sysContext) { + TeardownSysContext(&sysContext); + } + if(tcti_ctx) { + TeardownTctiContext(tcti_ctx); + } + + return rval; +} + diff --git a/tpm-util/import/sampleMakefile b/tpm-util/import/sampleMakefile new file mode 100644 index 0000000..55c180a --- /dev/null +++ b/tpm-util/import/sampleMakefile @@ -0,0 +1,38 @@ + +CC = gcc +#CC = g++ +LD = ld +AR = ar +LDDFLAGS += -fPIC +ARFLAGS = -rc + +TSS_DIR?=/home/pramod/tpm2-tss + +OUTPUT=ossl_tpm_import + +OBJS= util.o \ + tpm_wrapper.o \ + main.o + + +CFLAGS += -g -fPIC -I./include -I${TSS_DIR}/include/ -I$(TSS_DIR)/sysapi/include + +LDFLAGS += -ldl -L/usr/local/lib/ -lsapi -ltcti-device -ltcti-tabrmd + +LIBS = -lpthread -lcrypto -lssl + +%.o : %.c + $(CC) -c $(CFLAGS) $< -o $@ + + +$(OUTPUT): $(OBJS) + $(CC) $(OBJS) $(LDFLAGS) ${LIBS} -o $(OUTPUT) + +.PHONY: all +all: $(OUTPUT) + +install: + @set -e; for i in $(OUTPUT); do mv $$i ../../bin/$$i ; done + +clean: + rm -f *.o $(OUTPUT) *.so diff --git a/tpm-util/import/tpm_wrapper.c b/tpm-util/import/tpm_wrapper.c new file mode 100644 index 0000000..5f4ab2a --- /dev/null +++ b/tpm-util/import/tpm_wrapper.c @@ -0,0 +1,213 @@ +/* + * Copyright 2018 Intel Corporation + * + * 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. + */ +// +// Author: Arun Kumar Sekar +// + +#include "tpm_wrapper.h" +#include "util.h" + +#include + +#include +#include +#include +#include "tcti_util.h" + +TSS2_RC swKeyTpmImport( + /* IN */ + TSS2_SYS_CONTEXT *sysContext, + TPM_HANDLE parentKeyHandle, + TPM2B_DATA* encryptionKey, TPM2B_PUBLIC* swKeyPublic, TPM2B_PRIVATE* swKeyPrivate, TPM2B_ENCRYPTED_SECRET* encSymSeed, + unsigned char* tpm_pwd, int tpm_pwd_len, + /* OUT */ + TPM2B_PRIVATE *importPrivate) +{ + TPM_RC rval = TPM_RC_SUCCESS; + TPM2B_NAME name = { { sizeof( TPM2B_NAME ) - 2, } }; + + TPM_HANDLE wrapperKeyHandle; + + TSS2_SYS_CMD_AUTHS npsessionsData; + TSS2_SYS_RSP_AUTHS npsessionsDataOut; + TPMS_AUTH_COMMAND npsessionData; + TPMS_AUTH_RESPONSE npsessionDataOut; + + if(NULL == tpm_pwd) { + printf("TPM password pinter is NULL \n"); + return -1; + } + + *((UINT8 *)((void *)&npsessionData.sessionAttributes)) = 0; + npsessionData.sessionHandle = TPM_RS_PW; + npsessionData.nonce.t.size = 0; + npsessionData.hmac.t.size = 0; + + npsessionData.hmac.t.size = tpm_pwd_len; + if(tpm_pwd_len > 0) + { + memcpy(npsessionData.hmac.t.buffer, tpm_pwd, npsessionData.hmac.t.size); + } + + TPMS_AUTH_COMMAND *npsessionDataArray[1]; + TPMS_AUTH_RESPONSE *npsessionDataOutArray[1]; + TPMT_SYM_DEF_OBJECT symmetricAlg; + + npsessionDataArray[0] = &npsessionData; + npsessionDataOutArray[0] = &npsessionDataOut; + npsessionsData.cmdAuthsCount = 1; + npsessionsData.cmdAuths = &npsessionDataArray[0]; + npsessionsDataOut.rspAuthsCount = 1; + npsessionsDataOut.rspAuths = &npsessionDataOutArray[0]; + + symmetricAlg.algorithm = TPM_ALG_AES; + symmetricAlg.keyBits.aes = 128; + symmetricAlg.mode.aes = TPM_ALG_CFB; + + rval = Tss2_Sys_Import( sysContext, + parentKeyHandle, + &npsessionsData, + encryptionKey, + swKeyPublic, + swKeyPrivate, + encSymSeed, + &symmetricAlg, + importPrivate, + &npsessionsDataOut + ); + printf("The return value of sys import: 0x%x \n", rval); + +#if 0 + if(rval == TSS2_RC_SUCCESS) + { + rval = Tss2_Sys_Load (sysContext, parentKeyHandle, &npsessionsData, importPrivate, swKeyPublic, + &wrapperKeyHandle, &name, &npsessionsDataOut); + printf("\n Load Imported Handle: 0x%x | rval 0x%x \n", wrapperKeyHandle, rval); + } + if(rval == TSS2_RC_SUCCESS) + { + rval = Tss2_Sys_FlushContext( sysContext, wrapperKeyHandle); + printf("\n Flush Loaded key Handle : 0x%8.8x| rval 0x%x \n", wrapperKeyHandle, rval); + } +#endif + + // Nullify TPM password + memset(tpm_pwd, 0, tpm_pwd_len); + + return rval; +} + +TSS2_TCTI_CONTEXT* tpm_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; +} + +TSS2_SYS_CONTEXT* sys_ctx_init (TSS2_TCTI_CONTEXT *tcti_ctx) +{ + TSS2_SYS_CONTEXT *sys_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); + sys_ctx = (TSS2_SYS_CONTEXT*)calloc (1, size); + if (sys_ctx == NULL) { + fprintf (stderr, + "Failed to allocate 0x%zx bytes for the SAPI context\n", + size); + return NULL; + } + rc = Tss2_Sys_Initialize (sys_ctx, size, tcti_ctx, &abi_version); + if (rc != TSS2_RC_SUCCESS) { + fprintf (stderr, "Failed to initialize SAPI context: 0x%x\n", rc); + free (sys_ctx); + return NULL; + } + + return sys_ctx; +} + +TSS2_RC TeardownTctiContext( TSS2_TCTI_CONTEXT *tctiContext ) +{ + ((TSS2_TCTI_CONTEXT_INTEL *)tctiContext)->finalize( tctiContext ); + free (tctiContext); + tctiContext = NULL; + return TSS2_RC_SUCCESS; +} + +void TeardownSysContext( TSS2_SYS_CONTEXT **sysContext ) +{ + if( *sysContext != 0 ) { + Tss2_Sys_Finalize(*sysContext); + free(*sysContext); + *sysContext = 0; + } +} + +/* helper functions */ +#if 0 +TSS2_RC TPM2ReadPublicPortion(TSS2_SYS_CONTEXT *sysContext, TPM_HANDLE objectHandle, TPM2B_PUBLIC *publicPortion ) +{ + TPM_RC rval = TPM_RC_SUCCESS; + TPM2B_NAME qualifiedName; + TPM2B_NAME name; + INIT_SIMPLE_TPM2B_SIZE( name ); + INIT_SIMPLE_TPM2B_SIZE( qualifiedName ); + + if(publicPortion == NULL) { + printf("Input reference for TPM2B_PUBLIC structure is NULL"); + return TPM_RC_FAILURE; + } + + publicPortion->t.size = 0; + rval = Tss2_Sys_ReadPublic( sysContext, objectHandle , 0, publicPortion, &name, &qualifiedName, 0 ); + if(rval != TPM_RC_SUCCESS) + { + printf("\n Tss2_Sys_ReadPublic failed: 0x%x ! for TPM handle: 0x%x \n", rval, objectHandle); + } + + return rval; +} +#endif + diff --git a/tpm-util/import/util.c b/tpm-util/import/util.c new file mode 100644 index 0000000..a0038a5 --- /dev/null +++ b/tpm-util/import/util.c @@ -0,0 +1,104 @@ +/* + * Copyright 2018 Intel Corporation + * + * 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. + */ +// Author: Arun Kumar Sekar + + +#include "tpm_wrapper.h" + +int saveDataToFile(const char *fileName, UINT8 *buf, UINT16 size) +{ + FILE *f; + UINT16 count = 1; + if( fileName == NULL || buf == NULL || size == 0 ) + return -1; + + f = fopen(fileName, "wb+"); + if( f == NULL ) { + printf("File(%s) open error.\n", fileName); + return -2; + } + + while( size > 0 && count > 0 ) { + count = fwrite(buf, 1, size, f); + size -= count; + buf += count; + } + + if( size > 0 ) { + printf("File write error\n"); + fclose(f); + return -3; + } + + fclose(f); + return 0; +} + +int loadDataFromFile(const char *fileName, UINT8 *buf, UINT16 *size) +{ + UINT16 count = 1, left; + FILE *f; + if ( size == NULL || buf == NULL || fileName == NULL ) + return -1; + + f = fopen(fileName, "rb+"); + if( f == NULL ) { + printf("File(%s) open error.\n", fileName); + return -2; + } + + left = *size; + *size = 0; + while( left > 0 && count > 0 ) { + count = fread(buf, 1, left, f); + *size += count; + left -= count; + buf += count; + } + + if( *size == 0 ) { + printf("File read error\n"); + fclose(f); + return -3; + } + fclose(f); + return 0; +} + +void hex_log(UINT8 *pData, UINT32 numBytes, const char* caption) +{ + int i = 0; + + if(NULL == pData) + { + return; + } + if(caption != NULL) + { + printf("\n=== %s ===\n", caption); + } + printf("size: %d \n", numBytes); + + for(i = 0; i < numBytes; i++) + { + printf("%02X ", pData[i]); + + if (!((i + 1) % 16)) + printf("\n"); + } + printf("\n"); +} + -- cgit 1.2.3-korg