diff --git a/CMakeLists.txt b/CMakeLists.txt index 6903e8b..d3f9491 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,7 +17,7 @@ target_include_directories(ecdaa_member PUBLIC target_link_libraries(ecdaa_member /usr/lib/x86_64-linux-gnu/libecdaa.so) target_link_libraries(ecdaa_member /usr/lib/x86_64-linux-gnu/libecdaa-tpm.so) -add_executable(ecdaa_member_tpm member-tpm.c common.h common.c client.h client.c server.h server.c amcl-extensions/ecp_FP256BN.c amcl/big_256_56.c amcl/rom_curve_FP256BN.c amcl/ecp_FP256BN.c amcl/fp_FP256BN.c amcl/rom_field_FP256BN.c amcl/rand.c amcl/hash.c) +add_executable(ecdaa_member_tpm member-tpm.c common.h common.c client.h client.c server.h server.c amcl-extensions/ecp_FP256BN.c amcl/big_256_56.c amcl/rom_curve_FP256BN.c amcl/ecp_FP256BN.c amcl/fp_FP256BN.c amcl/rom_field_FP256BN.c amcl/rand.c amcl/hash.c member-tpm-key.c) target_include_directories(ecdaa_member_tpm PUBLIC ${ECDAA_AMCL} ) @@ -47,7 +47,7 @@ target_link_libraries(ecdaa_test_tpm /usr/lib/x86_64-linux-gnu/libecdaa-tpm.so) target_link_libraries(ecdaa_test_tpm /usr/lib/x86_64-linux-gnu/libtss2-tcti-device.so) target_link_libraries(ecdaa_test_tpm /usr/lib/x86_64-linux-gnu/libtss2-sys.so) -add_executable(create_tpm_key create_tpm_key-util.c) +add_executable(create_tpm_key member-tpm-key.c) target_include_directories(create_tpm_key PUBLIC ${ECDAA_AMCL} ) diff --git a/common.h b/common.h index 9f6411d..f6584a2 100644 --- a/common.h +++ b/common.h @@ -12,15 +12,25 @@ #define VERIFIERPORT 6592 #define MAX_CLIENTS 10 -#define MAX_MSGSIZE 4096 +#define MAX_MSGSIZE 15000 #define MAX_CHKSUMSIZE 1024 #define MAX_BUFSIZE (((MAX_MSGSIZE + 2) / 3) * 4) + (((MAX_CHKSUMSIZE + 2) / 3) * 4) + 1536 /* #define MAX_MSGSIZE ((MAX_BUFSIZE - 1536) / 2) - MAX_CHKSUMSIZE //for bin to hex*/ /* #define MAX_MSGSIZE ((MAX_BUFSIZE - 1536) / 4 * 3) - MAX_CHKSUMSIZE //for base64 */ #define MAX_BSNSIZE 128 #define NONCE_SIZE 384 -#define MSGFILE "msg.txt" -#define CHKSUMFILE "chksum.txt" + +const char* issuer_public_key_file = "ipk.bin"; +const char* issuer_secret_key_file = "isk.bin"; +const char* member_tpm_handle_file = "tpmhndl.bin"; //Handle to access tpm key +const char* member_tpm_key_file = "tpmpk.bin"; //public key to access TPM key (!= mpk) +const char* member_secret_key_file = "msk.bin"; //for TPM less members only +const char* member_public_key_file = "mpk.bin"; +const char* member_credential_file = "mcred.bin"; +const char* member_nonce_file = "mnonce.bin"; +const char* verifier_ipk_file = "ipk.bin"; +const char* message_file = "msg.txt"; //Checksum of message in chksum.txt +const char* checksum_file = "chksum.txt"; //Only this file is signed due to 1024 bytes size limit typedef int (*conn_handler)(char *buffer); diff --git a/issuer.h b/issuer.h index e0f9adc..e95cb25 100644 --- a/issuer.h +++ b/issuer.h @@ -10,7 +10,5 @@ #include "common.h" int process_issuer(char *buffer); -const char* issuer_public_key_file = "ipk.bin"; -const char* issuer_secret_key_file = "isk.bin"; #endif //ECDAA_ISSUER_H diff --git a/member-tpm-key.c b/member-tpm-key.c new file mode 100644 index 0000000..7d59667 --- /dev/null +++ b/member-tpm-key.c @@ -0,0 +1,382 @@ +#include "member-tpm-key.h" + +static TPMA_SESSION empty_session_attributes = {0}; // attributes for password either can't be set or don't make sense + +struct command_line_args { + char *pub_key_filename; + char *handle_filename; +} + +struct test_context { + TSS2_SYS_CONTEXT *sapi_ctx; + TPM2_HANDLE primary_key_handle; + TPM2_HANDLE signing_key_handle; + TPM2_HANDLE persistent_key_handle; + TPM2B_PUBLIC out_public; + TPM2B_PRIVATE out_private; + unsigned char tcti_buffer[256]; + unsigned char sapi_buffer[4200]; + +}; + +void parse_cmd_args(struct command_line_args *args_out, int argc, char *argv[]) { + if (3 != argc) { + printf("usage: %s pub_key_filename = argv[1]; + args_out->handle_filename = argv[2]; + printf("Saving public key to %s and handle to %s\n", pub_key_filename, handle_filename); +} + +static void initialize(struct test_context *ctx); +static void cleanup(struct test_context *ctx); + +static int clear(struct test_context *ctx); +static int create_primary(struct test_context *ctx); +static int create(struct test_context *ctx); +static int load(struct test_context *ctx); +static int save_public_key_info(const struct test_context* ctx, const char* pub_key_filename, const char* handle_filename); +static int evict_control(struct test_context *ctx); + +int main(int argc, char *argv[]) +{ + struct command_line_args args; + parse_cmd_args(&args, argc, argv); + + create_key(pub_key_filename, handle_filename); +} + +void initialize(struct test_context *ctx) +{ + const char *device_conf = "/dev/tpm0"; + size_t size; + int init_ret; + + memset(ctx->tcti_buffer, 0, sizeof(ctx->tcti_buffer)); + memset(ctx->sapi_buffer, 0, sizeof(ctx->sapi_buffer)); + + TSS2_TCTI_CONTEXT *tcti_ctx = (TSS2_TCTI_CONTEXT*)ctx->tcti_buffer; + + init_ret = Tss2_Tcti_Device_Init(NULL, &size, device_conf); + if (TSS2_RC_SUCCESS != init_ret) { + printf("Failed to get allocation size for tcti context\n"); + exit(1); + } + if (size > sizeof(ctx->tcti_buffer)) { + printf("Error: device TCTI context size larger than pre-allocated buffer\n"); + exit(1); + } + init_ret = Tss2_Tcti_Device_Init(tcti_ctx, &size, device_conf); + if (TSS2_RC_SUCCESS != init_ret) { + printf("Error: Unable to initialize device TCTI context\n"); + exit(1); + } + + ctx->sapi_ctx = (TSS2_SYS_CONTEXT*)ctx->sapi_buffer; + size_t sapi_ctx_size = Tss2_Sys_GetContextSize(0); + + TSS2_ABI_VERSION abi_version = TSS2_ABI_VERSION_CURRENT; + init_ret = Tss2_Sys_Initialize(ctx->sapi_ctx, + sapi_ctx_size, + tcti_ctx, + &abi_version); + ctx->out_public.size = 0; + ctx->out_private.size = 0; +} + +void cleanup(struct test_context *ctx) +{ + TSS2_TCTI_CONTEXT *tcti_context = NULL; + TSS2_RC rc; + + if (ctx->sapi_ctx != NULL) { + rc = Tss2_Sys_GetTctiContext(ctx->sapi_ctx, &tcti_context); + + Tss2_Tcti_Finalize(tcti_context); + + Tss2_Sys_Finalize(ctx->sapi_ctx); + } +} + +int create_key(const char* pub_key_filename, const char* handle_filename) +{ + struct test_context ctx; + initialize(&ctx); + + int ret = 0; + + ret = clear(&ctx); + if(ret != TSS2_RC_SUCCESS) { + printf("TPM Clear failed: %x\n",ret); + } + + ret = create_primary(&ctx); + if(ret != TSS2_RC_SUCCESS) { + printf("TPM Create Primary failed: %x\n",ret); + } + + ret = create(&ctx); + if(ret != TSS2_RC_SUCCESS) { + printf("TPM Create failed: %x\n",ret); + } + + ret = load(&ctx); + if(ret != TSS2_RC_SUCCESS) { + printf("TPM Load failed: %x\n",ret); + } + + ret = evict_control(&ctx); + if(ret != TSS2_RC_SUCCESS) { + printf("TPM Evict Control failed: %x\n",ret); + } + + ret = save_public_key_info(&ctx, pub_key_filename, handle_filename); + if(ret != TSS2_RC_SUCCESS) { + printf("Save Public Key Info failed: %x\n",ret); + } + + cleanup(&ctx); + return ret; +} + +int save_public_key_info(const struct test_context *ctx, const char* pub_key_filename, const char* handle_filename) +{ + int write_ret = 0; + + FILE *pub_key_file_ptr = fopen(pub_key_filename, "w"); + + if (NULL == pub_key_file_ptr) + return -1; + do { + if (fprintf(pub_key_file_ptr, "%02X", 4) != 2) + break; + + for (unsigned i=0; i < ctx->out_public.publicArea.unique.ecc.x.size; i++) { + if (fprintf(pub_key_file_ptr, "%c", ctx->out_public.publicArea.unique.ecc.x.buffer[i]) != 1) { + write_ret = -1; + break; + } + } + if (0 != write_ret) + break; + + for (unsigned i=0; i < ctx->out_public.publicArea.unique.ecc.y.size; i++) { + if (fprintf(pub_key_file_ptr, "%c", ctx->out_public.publicArea.unique.ecc.y.buffer[i]) != 1) { + write_ret = -1; + break; + } + } + if (0 != write_ret) + break; + } while(0); + (void)fclose(pub_key_file_ptr); + + (void)handle_filename; + FILE *handle_file_ptr = fopen(handle_filename, "w"); + if (NULL == handle_file_ptr) + return -1; + write_ret = 0; + do { + for (int i=(sizeof(ctx->persistent_key_handle)-1); i >= 0; i--) { + if (fprintf(handle_file_ptr, "%02X", (ctx->persistent_key_handle >> i*8) & 0xFF) != 2) { + write_ret = -1; + break; + } + } + if (0 != write_ret) + break; + } while(0); + (void)fclose(handle_file_ptr); + + return write_ret; +} + +int clear(struct test_context *ctx) +{ + TPMI_RH_CLEAR auth_handle = TPM2_RH_LOCKOUT; + + TSS2L_SYS_AUTH_COMMAND sessionsData = {}; + sessionsData.auths[0].sessionHandle = TPM2_RS_PW; + sessionsData.auths[0].sessionAttributes = empty_session_attributes; + sessionsData.count = 1; + + TSS2L_SYS_AUTH_RESPONSE sessionsDataOut = {}; + sessionsDataOut.count = 1; + + TSS2_RC ret = Tss2_Sys_Clear(ctx->sapi_ctx, + auth_handle, + &sessionsData, + &sessionsDataOut); + + printf("Clear ret=%#X\n", ret); + + return ret; +} + +int create_primary(struct test_context *ctx) +{ + TPMI_RH_HIERARCHY hierarchy = TPM2_RH_ENDORSEMENT; + + TSS2L_SYS_AUTH_COMMAND sessionsData = {}; + sessionsData.auths[0].sessionHandle = TPM2_RS_PW; + sessionsData.auths[0].sessionAttributes = empty_session_attributes; + sessionsData.count = 1; + + TSS2L_SYS_AUTH_RESPONSE sessionsDataOut = {}; + sessionsDataOut.count = 1; + + TPM2B_SENSITIVE_CREATE inSensitive = {}; + + TPM2B_PUBLIC in_public = {}; + in_public.publicArea.type = TPM2_ALG_ECC; + in_public.publicArea.nameAlg = TPM2_ALG_SHA256; + in_public.publicArea.objectAttributes = TPMA_OBJECT_FIXEDTPM | + TPMA_OBJECT_FIXEDPARENT | + TPMA_OBJECT_SENSITIVEDATAORIGIN | + TPMA_OBJECT_USERWITHAUTH | + TPMA_OBJECT_DECRYPT | + TPMA_OBJECT_RESTRICTED; + in_public.publicArea.parameters.eccDetail.symmetric.algorithm = TPM2_ALG_AES; + in_public.publicArea.parameters.eccDetail.symmetric.keyBits.aes = 128; + in_public.publicArea.parameters.eccDetail.symmetric.mode.sym = TPM2_ALG_CFB; + in_public.publicArea.parameters.eccDetail.scheme.scheme = TPM2_ALG_NULL; + in_public.publicArea.parameters.eccDetail.curveID = TPM2_ECC_NIST_P256; + in_public.publicArea.parameters.eccDetail.kdf.scheme = TPM2_ALG_NULL; + + TPM2B_DATA outsideInfo = {}; + + TPML_PCR_SELECTION creationPCR = {}; + + TPM2B_CREATION_DATA creationData = {}; + TPM2B_DIGEST creationHash = {}; + TPMT_TK_CREATION creationTicket = {}; + + TPM2B_NAME name = {}; + + TPM2B_PUBLIC public_key = {}; + + TSS2_RC ret = Tss2_Sys_CreatePrimary(ctx->sapi_ctx, + hierarchy, + &sessionsData, + &inSensitive, + &in_public, + &outsideInfo, + &creationPCR, + &ctx->primary_key_handle, + &public_key, + &creationData, + &creationHash, + &creationTicket, + &name, + &sessionsDataOut); + + printf("CreatePrimary ret=%#X\n", ret); + + return ret; +} + +int create(struct test_context *ctx) +{ + TSS2L_SYS_AUTH_COMMAND sessionsData = {}; + sessionsData.auths[0].sessionHandle = TPM2_RS_PW; + sessionsData.auths[0].sessionAttributes = empty_session_attributes; + sessionsData.count = 1; + + TSS2L_SYS_AUTH_RESPONSE sessionsDataOut = {}; + sessionsDataOut.count = 1; + + TPM2B_SENSITIVE_CREATE inSensitive = {}; + + TPM2B_PUBLIC in_public = {}; + in_public.publicArea.type = TPM2_ALG_ECC; + in_public.publicArea.nameAlg = TPM2_ALG_SHA256; + in_public.publicArea.objectAttributes = TPMA_OBJECT_FIXEDTPM | + TPMA_OBJECT_FIXEDPARENT | + TPMA_OBJECT_SENSITIVEDATAORIGIN | + TPMA_OBJECT_USERWITHAUTH | + TPMA_OBJECT_SIGN_ENCRYPT; + in_public.publicArea.parameters.eccDetail.symmetric.algorithm = TPM2_ALG_NULL; + in_public.publicArea.parameters.eccDetail.scheme.scheme = TPM2_ALG_ECDAA; + in_public.publicArea.parameters.eccDetail.scheme.details.ecdaa.hashAlg = TPM2_ALG_SHA256; + in_public.publicArea.parameters.eccDetail.scheme.details.ecdaa.count = 1; + in_public.publicArea.parameters.eccDetail.curveID = TPM2_ECC_BN_P256; + in_public.publicArea.parameters.eccDetail.kdf.scheme = TPM2_ALG_NULL; + + TPM2B_DATA outsideInfo = {}; + + TPML_PCR_SELECTION creationPCR = {}; + + TPM2B_CREATION_DATA creationData = {}; + TPM2B_DIGEST creationHash = {}; + TPMT_TK_CREATION creationTicket = {}; + + TSS2_RC ret = Tss2_Sys_Create(ctx->sapi_ctx, + ctx->primary_key_handle, + &sessionsData, + &inSensitive, + &in_public, + &outsideInfo, + &creationPCR, + &ctx->out_private, + &ctx->out_public, + &creationData, + &creationHash, + &creationTicket, + &sessionsDataOut); + + printf("Create ret=%#X\n", ret); + + return ret; +} + +int load(struct test_context *ctx) +{ + TSS2L_SYS_AUTH_COMMAND sessionsData = {}; + sessionsData.auths[0].sessionHandle = TPM2_RS_PW; + sessionsData.auths[0].sessionAttributes = empty_session_attributes; + sessionsData.count = 1; + + TSS2L_SYS_AUTH_RESPONSE sessionsDataOut = {}; + sessionsDataOut.count = 1; + + TPM2B_NAME name = {}; + + int ret = Tss2_Sys_Load(ctx->sapi_ctx, + ctx->primary_key_handle, + &sessionsData, + &ctx->out_private, + &ctx->out_public, + &ctx->signing_key_handle, + &name, + &sessionsDataOut); + + printf("Load ret=%#X\n", ret); + + return ret; +} + +int evict_control(struct test_context *ctx) +{ + TSS2L_SYS_AUTH_COMMAND sessionsData = {}; + sessionsData.auths[0].sessionHandle = TPM2_RS_PW; + sessionsData.auths[0].sessionAttributes = empty_session_attributes; + sessionsData.count = 1; + + TSS2L_SYS_AUTH_RESPONSE sessionsDataOut = {}; + sessionsDataOut.count = 1; + + ctx->persistent_key_handle = 0x81010000; + + TSS2_RC ret = Tss2_Sys_EvictControl(ctx->sapi_ctx, + TPM2_RH_OWNER, + ctx->signing_key_handle, + &sessionsData, + ctx->persistent_key_handle, + &sessionsDataOut); + + printf("EvictControl ret=%#X\n", ret); + + return ret; +} diff --git a/member-tpm-key.h b/member-tpm-key.h new file mode 100644 index 0000000..c0cb065 --- /dev/null +++ b/member-tpm-key.h @@ -0,0 +1,8 @@ +#ifndef ECDAA_MEMBER_TPM_KEY_H +#define ECDAA_MEMBER_TPM_KEY_H +#include "common.h" +#include "member-tpm.h" + +static int create_key(const char* pub_key_filename, const char* handle_filename); + +#endif //ECDAA_MEMBER_TPM_KEY_H diff --git a/member-tpm.c b/member-tpm.c index 04d9216..7fbe224 100644 --- a/member-tpm.c +++ b/member-tpm.c @@ -20,7 +20,6 @@ typedef struct member { size_t bsn_len; struct ecdaa_tpm_context ctx; TPM2_HANDLE pk_handle; - //ECP_FP256BN public_key; unsigned char pk_in[ECP_FP256BN_LENGTH]; unsigned char tcti_buffer[256]; } member_t; @@ -57,11 +56,18 @@ int main(int argc, char *argv[]) { switch(argc) { case 3: if(0 == strncasecmp("--join", argv[1], 6) || 0 == strncasecmp("-j", argv[1], 2)) { - if (0 != read_public_key_from_files(member.pk_in, &sk_handle, tpm_key_file, tpm_handle_file)) { - printf("Error: error reading in public key files '%s' and '%s'\n", tpm_key_file, tpm_handle_file); - return 1; + if (0 != read_public_key_from_files(member.pk_in, &sk_handle, member_tpm_key_file, member_tpm_handle_file)) { + printf("Could not load TPM key with '%s' and '%s', trying to create a new key...\n", member_tpm_key_file, member_tpm_handle_file); + if (0 != create_key(member_tpm_key_file, member_tpm_handle_file) || 0 != read_public_key_from_files(member.pk_in, &sk_handle, member_tpm_key_file, member_tpm_handle_file)) { + printf("Error: Creating or Loading TPM key with '%s' and '%s' failed. Exiting\n", member_tpm_key_file, member_tpm_handle_file); + return 1; + } } - printf("Loaded pubkey and handle\n"); + if (0 != init_tpm()) { + printf("Error: Failed to initialize TPM. Exiting\n"); + return 1; + } + printf("Initialized TPM with pubkey and handle\n"); member.state = ON; remote_ip = argv[2]; ret = client_connect(&member_join, remote_ip, ISSUERPORT); @@ -71,11 +77,15 @@ int main(int argc, char *argv[]) { } printf("Join process was successful\n"); } else if (0 == strncasecmp("--send", argv[1], 6) || 0 == strncasecmp("-s", argv[1], 2)) { - if (0 != read_public_key_from_files(member.pk_in, &sk_handle, tpm_key_file, tpm_handle_file)) { - printf("Error: reading in public key files '%s' and '%s' failed\n", tpm_key_file, tpm_handle_file); + if (0 != read_public_key_from_files(member.pk_in, &sk_handle, member_tpm_key_file, member_tpm_handle_file)) { + printf("Error: reading in public key files '%s' and '%s' failed\n", member_tpm_key_file, member_tpm_handle_file); return 1; } - printf("Loaded pubkey and handle\n"); + if (0 != init_tpm()) { + printf("Error: Failed to initialize TPM. Exiting\n"); + return 1; + } + printf("Initialized TPM with pubkey and handle\n"); msg_len = ecdaa_read_from_file(msg, MAX_MSGSIZE, MSGFILE); if (msg_len < 0) { printf("Could not open message file %s\n", MSGFILE); @@ -118,10 +128,12 @@ int init_tpm() { const char *device_conf = "/dev/tpm0"; - int init_ret; + int ret = 0; memset(member.tcti_buffer, 0, sizeof(member.tcti_buffer)); + TPM2_HANDLE key_handle = 0; + TSS2_TCTI_CONTEXT *tcti_ctx = (TSS2_TCTI_CONTEXT*)member.tcti_buffer; size_t size; @@ -340,11 +352,8 @@ int read_public_key_from_files(uint8_t *public_key, TPM2_HANDLE *key_handle, con } do { for (unsigned i=0; i < ECP_FP256BN_LENGTH; i++) { - unsigned char byt; - int ret=0; - //if (ret = fscanf(pub_key_file_ptr, "%02X", &byt) != 1) { - if (ret = fscanf(pub_key_file_ptr, "%c", &byt) != 1) { - printf("read_public_key: i=%d, len=%d, returnvalue=%d\n", i, ECP_FP256BN_LENGTH, ret); + unsigned byt; + if (ret = fscanf(pub_key_file_ptr, "%02X", &byt) != 1) { ret = -1; break; } @@ -365,9 +374,8 @@ int read_public_key_from_files(uint8_t *public_key, TPM2_HANDLE *key_handle, con do { for (int i=(sizeof(TPM2_HANDLE)-1); i >= 0; i--) { - unsigned char byt; - //if (fscanf(handle_file_ptr, "%02X", &byt) != 1) { - if (fscanf(handle_file_ptr, "%c", &byt) != 1) { + unsigned byt; + if (fscanf(handle_file_ptr, "%02X", &byt) != 1) { ret = -1; break; } @@ -384,3 +392,4 @@ int read_public_key_from_files(uint8_t *public_key, TPM2_HANDLE *key_handle, con } return ret; } + diff --git a/member-tpm.h b/member-tpm.h index b068e2d..9324d8e 100644 --- a/member-tpm.h +++ b/member-tpm.h @@ -10,13 +10,8 @@ #include "server.h" #include "client.h" #include "common.h" +#include "member-tpm-key.h" int process_member(char *buffer); -const char* tpm_handle_file = "handle.txt"; -const char* tpm_key_file = "pub_key.txt"; -const char* member_public_key_file = "mpk.bin"; -const char* member_credential_file = "mcred.bin"; -const char* member_nonce_file = "mnonce.bin"; - #endif //ECDAA_MEMBER_TPM_H diff --git a/member.h b/member.h index bb75daf..14b2f49 100644 --- a/member.h +++ b/member.h @@ -9,9 +9,4 @@ /* int process_member(char *buffer); */ -const char* member_public_key_file = "mpk.bin"; -const char* member_secret_key_file = "msk.bin"; -const char* member_credential_file = "mcred.bin"; -const char* member_nonce_file = "mnonce.bin"; - #endif //ECDAA_ISSUER_H diff --git a/verifier.h b/verifier.h index c939c9c..5bf25f5 100644 --- a/verifier.h +++ b/verifier.h @@ -9,6 +9,4 @@ int process_verifier(char *buffer); -const char* verifier_ipk_file = "ipk.bin"; - #endif //ECDAA_VERIFIER_H