diff --git a/CMakeLists.txt b/CMakeLists.txt index 604297d..c07d468 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,6 +23,8 @@ target_include_directories(ecdaa_member_tpm PUBLIC ) target_link_libraries(ecdaa_member_tpm /usr/lib/x86_64-linux-gnu/libecdaa.so) target_link_libraries(ecdaa_member_tpm /usr/lib/x86_64-linux-gnu/libecdaa-tpm.so) +target_link_libraries(ecdaa_member_tpm /usr/lib/x86_64-linux-gnu/libtss2-tcti-device.so) +target_link_libraries(ecdaa_member_tpm /usr/lib/x86_64-linux-gnu/libtss2-sys.so) add_executable(ecdaa_verifier verifier.c common.h common.c server.h server.c client.h client.c) target_include_directories(ecdaa_verifier PUBLIC @@ -30,9 +32,26 @@ target_include_directories(ecdaa_verifier PUBLIC ) target_link_libraries(ecdaa_verifier /usr/lib/x86_64-linux-gnu/libecdaa.so) -add_executable(ecdaa_test daa-test.c common.h common.c client.h client.c server.h server.c) +add_executable(ecdaa_test daa-test.c daa-test.h common.h common.c client.h client.c server.h server.c) target_include_directories(ecdaa_test PUBLIC ${ECDAA_AMCL} ) target_link_libraries(ecdaa_test /usr/lib/x86_64-linux-gnu/libecdaa.so) -target_link_libraries(ecdaa_test /usr/lib/x86_64-linux-gnu/libecdaa-tpm.so) + +add_executable(ecdaa_test_tpm daa-test-tpm.c daa-test-tpm.h common.h common.c client.h client.c server.h server.c) +target_include_directories(ecdaa_test_tpm PUBLIC + ${ECDAA_AMCL} + ) +target_link_libraries(ecdaa_test_tpm /usr/lib/x86_64-linux-gnu/libecdaa.so) +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) +target_include_directories(create_tpm_key PUBLIC + ${ECDAA_AMCL} + ) +target_link_libraries(create_tpm_key /usr/lib/x86_64-linux-gnu/libecdaa.so) +target_link_libraries(create_tpm_key /usr/lib/x86_64-linux-gnu/libecdaa-tpm.so) +target_link_libraries(create_tpm_key /usr/lib/x86_64-linux-gnu/libtss2-tcti-device.so) +target_link_libraries(create_tpm_key /usr/lib/x86_64-linux-gnu/libtss2-sys.so) diff --git a/create_tpm_key b/create_tpm_key new file mode 100755 index 0000000..bf6d1c8 Binary files /dev/null and b/create_tpm_key differ diff --git a/create_tpm_key-util.c b/create_tpm_key-util.c new file mode 100644 index 0000000..0c8c4f4 --- /dev/null +++ b/create_tpm_key-util.c @@ -0,0 +1,402 @@ +/****************************************************************************** + * + * Copyright 2020 Xaptum, 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 "daa-test-tpm.h" + +static TPMA_SESSION empty_session_attributes = {0}; // attributes for password either can't be set or don't make sense +const char *pub_key_filename = "pub_key.txt"; +const char *handle_filename = "handle.txt"; + +void parse_cmd_args(int argc, char *argv[]) { + if (3 != argc) { + printf("usage: %s \n", argv[0]); + exit(1); + } + + pub_key_filename = argv[1]; + handle_filename = argv[2]; + printf("Saving public key to %s and handle to %s\n", pub_key_filename, 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]; + +}; + +static void initialize(struct test_context *ctx); +static void cleanup(struct test_context *ctx); + +static void create_key(const char* pub_key_filename, const char* handle_filename); +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[]) +{ + // Included in the utils header, but we don't need them. +// (void)tpm_initialize; +// (void)tpm_cleanup; + +// parse_cmd_args(argc, argv); + + printf("Saving public key to %s and handle to %s\n", pub_key_filename, handle_filename); + create_key(pub_key_filename, handle_filename); +} + +void initialize(struct test_context *ctx) +{ + const char *device_conf = "/dev/tpm0"; + + 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; + + size_t size; + 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); + } +} + +void 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); +} + +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, "%02X", ctx->out_public.publicArea.unique.ecc.x.buffer[i]) != 2) { + 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, "%02X", ctx->out_public.publicArea.unique.ecc.y.buffer[i]) != 2) { + 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/daa-test-tpm.c b/daa-test-tpm.c index 2ed9e77..5dcfc9b 100644 --- a/daa-test-tpm.c +++ b/daa-test-tpm.c @@ -1,8 +1,30 @@ #include "daa-test-tpm.h" +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]; +}test_context; + +static TPMA_SESSION empty_session_attributes = {0}; + int test1(); -int test2(); -int test3(); +//int test2(); +//int test3(); +void initialize(struct test_context *ctx); +void create_key(const char* pub_key_filename, const char* handle_filename); +int clear(struct test_context *ctx); +int create_primary(struct test_context *ctx); +int create(struct test_context *ctx); +int load(struct test_context *ctx); +int save_public_key_info(const struct test_context* ctx, const char* pub_key_filename, const char* handle_filename); +int evict_control(struct test_context *ctx); +void cleanup(struct test_context *ctx); int main(int argc, char **argv) { if(0 != test1()) { @@ -10,11 +32,336 @@ int main(int argc, char **argv) { return 0; } else { printf("test1 succeeded\n"); + } } int test1() { const char *pub_key_filename = "pub_key.txt"; const char *handle_filename = "handle.txt"; + struct test_context ctx; + initialize(&ctx); + + int ret = 0; + ret = clear(&ctx); + if(ret != TSS2_RC_SUCCESS) { + printf("TPM Clear failed: %x\n",ret); + return ret; + } + ret = create_primary(&ctx); + if(ret != TSS2_RC_SUCCESS) { + printf("TPM Create Primary failed: %x\n",ret); + return ret; + } + ret = create(&ctx); + if(ret != TSS2_RC_SUCCESS) { + printf("TPM Create failed: %x\n",ret); + return ret; + } + ret = evict_control(&ctx); + if(ret != TSS2_RC_SUCCESS) { + printf("TPM Evict Control failed: %x\n",ret); + return 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); + return ret; + } + cleanup(&ctx); return 0; } + +void initialize(struct test_context *ctx) +{ + const char *device_conf = "/dev/tpm0"; + + 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; + size_t size; + 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; +} + +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; + + //default attributes in tpm2-tools https://github.com/tpm2-software/tpm2-tools/blob/master/tools/tpm2_createprimary.c + 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; +} + +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, "%02X", ctx->out_public.publicArea.unique.ecc.x.buffer[i]) != 2) { + 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, "%02X", ctx->out_public.publicArea.unique.ecc.y.buffer[i]) != 2) { + 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; +} + +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); + } +} + diff --git a/daa-test-tpm.h b/daa-test-tpm.h index 4e07370..d7477da 100644 --- a/daa-test-tpm.h +++ b/daa-test-tpm.h @@ -6,8 +6,10 @@ #include "client.h" #include "common.h" #include +#include #include #include #include #include +#endif diff --git a/ecdaa_issuer b/ecdaa_issuer index 7b8f186..ac835e2 100755 Binary files a/ecdaa_issuer and b/ecdaa_issuer differ diff --git a/ecdaa_member b/ecdaa_member index 5e0d903..5932b66 100755 Binary files a/ecdaa_member and b/ecdaa_member differ diff --git a/ecdaa_member_tpm b/ecdaa_member_tpm new file mode 100755 index 0000000..08cad58 Binary files /dev/null and b/ecdaa_member_tpm differ diff --git a/ecdaa_test b/ecdaa_test index f23a4d2..31180c6 100755 Binary files a/ecdaa_test and b/ecdaa_test differ diff --git a/ecdaa_test_tpm b/ecdaa_test_tpm new file mode 100755 index 0000000..7a566a7 Binary files /dev/null and b/ecdaa_test_tpm differ diff --git a/ecdaa_verifier b/ecdaa_verifier index 491cb2c..672d031 100755 Binary files a/ecdaa_verifier and b/ecdaa_verifier differ diff --git a/member-tpm.c b/member-tpm.c index d37cf87..0dd72e8 100644 --- a/member-tpm.c +++ b/member-tpm.c @@ -19,52 +19,147 @@ typedef struct member { uint8_t bsn[MAX_BSNSIZE]; size_t bsn_len; struct ecdaa_tpm_context ctx; + TPM2_HANDLE pk_handle; + unsigned char pk_in[ECP_FP256BN_LENGTH]; + unsigned char tcti_buffer[256]; } member_t; member_t member; +uint8_t msg[MAX_MSGSIZE]; +size_t msg_len; +const char *pub_key_filename = "pub_key.txt"; +const char *handle_filename = "handle.txt"; int init_tpm(); int free_tpm(); +static int read_public_key_from_files(uint8_t *public_key, TPM2_HANDLE *key_handle, const char *pub_key_filename, const char *handle_filename); int member_join(char *buffer); -int member_attest(char *buffer); +int member_verifymsg(char *buffer); int member_publish(char *buffer); -int member_getpublic(char *buffer); int member_joinappend(char *buffer); int member_joinfinish(char *buffer); -int main() { - - init_tpm(); - if (2 != server_start(&process_member, MEMBERPORT)) { - printf("server failed\n"); +int main(int argc, char *argv[]) { + char buffer[MAX_BUFSIZE]; + char *remote_ip = argv[2]; + int ret = 0; + TPM2_HANDLE sk_handle = 0; + + //strncpy(member.bsn, "mybasename", 10); + //member.bsn_len = strlen(member.bsn); + 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, pub_key_filename, handle_filename)) { + printf("Error: error reading in public key files '%s' and '%s'\n", pub_key_filename, handle_filename); + return 1; + } + member.state = ON; + ret = client_connect(&member_join, remote_ip, ISSUERPORT); + if (0 >= ret || JOINED != member.state) { + printf("Join process failed!\n"); + return 1; + } else { + printf("Join process was successful\n"); + } + } else { + printf("2 arguments but not join\n"); + } + break; + case 4: + if( 0 == strncasecmp("--send", argv[1], 6) || 0 == strncasecmp("-s", argv[1], 2)) { + msg_len = ecdaa_read_from_file(msg, MAX_MSGSIZE, argv[3]); + if (msg_len < 0) { + printf("Could not open message file %s\n", argv[3]); + return 1; + } + if (0 != read_public_key_from_files(member.pk_in, &sk_handle, pub_key_filename, handle_filename)) { + printf("Error: error reading in public key files '%s' and '%s'\n", pub_key_filename, handle_filename); + return 1; + } + if (0 > ecdaa_read_from_file(member.nonce, NONCE_SIZE, member_nonce_file) || + 0 != ecdaa_member_public_key_FP256BN_deserialize_file(&member.mpk, member_public_key_file, member.nonce, NONCE_SIZE) || + 0 != ecdaa_credential_FP256BN_deserialize_file(&member.cred, member_credential_file)) { + printf("Could not import key files. importing from %s, %s or %s was not successful\n", + member_nonce_file, member_public_key_file, member_credential_file); + return 1; + } + member.state = JOINED; + ret = client_connect(&member_verifymsg, remote_ip, VERIFIERPORT); + if (0 >= ret || JOINED != member.state) { + printf("connection to verifier failed\n"); + } + } else { + printf("3 arguments but not send\n"); + } + break; + default: + printf("Usage: \n Join an issuer's group: %s --join \n", argv[0]); + printf("Send a signed message to the verifier: %s --send \n", argv[0]); + printf("Before sending a DAA-signed message, the member must join a DAA group\n"); + break; } - free_tpm(); return 0; } -int init_tpm() { - TSS2_TCTI_CONTEXT *tctiContext = NULL; - TPM2_HANDLE handle = 0; - const char* passwd = "1234"; - uint16_t passwdlen = strlen(passwd); - TSS2_RC retval = 0; - size_t bufsize = tss2_tcti_getsize_device(); - uint8_t tctiBuffer[bufsize]; - bzero(tctiBuffer, bufsize); - const char* devicePath = "/dev/tpm0"; - - tctiContext = tctiBuffer; - retval = tss2_tcti_init_device(devicePath, strlen(devicePath), tctiContext); - switch (retval & 0xFF) { - case TSS2_RC_SUCCESS: - printf("tcti context established\n"); - break; - default: - printf("tcti context failed\n"); - break; +//int init_tpm() { +// TSS2_TCTI_CONTEXT *tctiContext = NULL; +// member.pk_handle = 0x81010000; +// const char* passwd = NULL; +// uint16_t passwdlen = 0; +// TSS2_RC retval = 0; +// size_t bufsize = tss2_tcti_getsize_device(); +// uint8_t tctiBuffer[bufsize]; +// bzero(tctiBuffer, bufsize); +// const char* devicePath = "/dev/tpm0"; +// +// tctiContext = tctiBuffer; +// retval = tss2_tcti_init_device(devicePath, strlen(devicePath), tctiContext); +// switch (retval & 0xFF) { +// case TSS2_RC_SUCCESS: +// printf("tcti context established\n"); +// break; +// default: +// printf("tcti context failed\n"); +// break; +// } +// //initialize ecdaa tpm context +// if(0 != ecdaa_tpm_context_init(&member.ctx, handle, passwd, passwdlen, tctiContext)) { +// printf("\necdaa context failed\n"); +// return -1; +// } +// printf("\necdaa context initialized\n"); +// return 0; +//} + +int init_tpm() +{ + const char *device_conf = "/dev/tpm0"; + + int init_ret; + + memset(member.tcti_buffer, 0, sizeof(member.tcti_buffer)); + + TSS2_TCTI_CONTEXT *tcti_ctx = (TSS2_TCTI_CONTEXT*)member.tcti_buffer; + + size_t size; + 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"); + return -1; + } + if (size > sizeof(member.tcti_buffer)) { + printf("Error: device TCTI context size larger than pre-allocated buffer\n"); + return -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"); + return -1; } + //initialize ecdaa tpm context - if(0 != ecdaa_tpm_context_init(&member.ctx, handle, NULL, 0, tctiContext)) { + if(0 != ecdaa_tpm_context_init(&member.ctx, member.pk_handle, NULL, 0, tcti_ctx)) { printf("\necdaa context failed\n"); return -1; } @@ -77,108 +172,9 @@ int free_tpm() { return 0; } -int process_member(char *buffer) { - int ret = 0; - - bzero(member.bsn, MAX_BSNSIZE); - strncpy((char *) member.bsn, "Biometric Sensor", 16); - member.bsn_len = 16; - - printf("> MEMBER: %s\n", buffer); - - if (member.state == JOINED && 0 == strncasecmp("ATTEST", buffer, 6)) { - bzero(buffer, MAX_BUFSIZE); - strncpy(buffer, "ATTEST ", 7); - member_attest(buffer); - } else if (member.state == ON && 0 == strncasecmp("GETPUBLIC", buffer, 9)) { - bzero(buffer, MAX_BUFSIZE); - ret = client_connect(&member_getpublic, ISSUERIP, ISSUERPORT); - if (0 >= ret || RCVPUBLIC != member.state) { - printf("process_member: issuer connection failed\n"); - bzero(buffer, MAX_BUFSIZE); - strncpy(buffer, "ERR\n", 4); - } else { - bzero(buffer, MAX_BUFSIZE); - strncpy(buffer, "OK\n", 3); - } - ret = 0; - } else if (0 == strncasecmp("PUBLISH", buffer, 7)) { - bzero(buffer, MAX_BUFSIZE); - member_publish(buffer); - } else if (member.state == RCVPUBLIC && 0 == strncasecmp("JOIN", buffer, 4)) { - member.state = JOIN; - ret = client_connect(&member_join, ISSUERIP, ISSUERPORT); - if (0 >= ret || JOINED != member.state) { - printf("process_member: issuer connection failed\n"); - bzero(buffer, MAX_BUFSIZE); - strncpy(buffer, "ERR\n", 4); - } else { - bzero(buffer, MAX_BUFSIZE); - strncpy(buffer, "OK\n", 3); - } - ret = 0; - } else if (0 == strncasecmp("EXIT", buffer, 4)) { - bzero(buffer, MAX_BUFSIZE); - strncpy(buffer, "OK\n", 3); - ret = 1; - } else if (0 == strncasecmp("SHUTDOWN", buffer, 8)) { - bzero(buffer, MAX_BUFSIZE); - strncpy(buffer, "OK\n", 3); - ret = 2; - } else { - bzero(buffer, MAX_BUFSIZE); - strncpy(buffer, "ERR\n", 4); - ret = 0; - } - - printf("< MEMBER: %s\n", buffer); - return ret; -} - int member_join(char *buffer) { int ret = 0; - switch (member.state) { - case JOIN: - bzero(buffer, MAX_BUFSIZE); - strncpy(buffer, "JOIN\n", 5); - member.state = APPEND; - break; - case APPEND: - if (0 == strncasecmp("JOINSTART", buffer, 9)) { - printf("ISSUER > MEMBER: %s", buffer); - member_joinappend(buffer); - member.state = JOINPROCEED; - } else { - printf("member_join: did not get nonce from issuer\n"); - member.state = RCVPUBLIC; - ret = -1; - } - break; - case JOINPROCEED: - if (0 == strncasecmp("JOINPROCEED", buffer, 11)) { - printf("ISSUER > MEMBER: %s", buffer); - member_joinfinish(buffer); - member.state = JOINED; - ret = 1; - } else { - printf("member_getpublic: did not get credentials from issuer\n"); - member.state = RCVPUBLIC; - ret = -1; - } - break; - default: - ret = -1; - } - if (0 == ret) { - printf("ISSUER < MEMBER: %s", buffer); - } - return ret; -} - -int member_getpublic(char *buffer) { - int ret = 0; - switch (member.state) { case ON: bzero(buffer, MAX_BUFSIZE); @@ -190,7 +186,7 @@ int member_getpublic(char *buffer) { printf("ISSUER > MEMBER: %s", buffer); uint8_t binbuf[MAX_BUFSIZE]; char *current = &buffer[8]; - ecdaa_hextobin(current, binbuf, ECDAA_ISSUER_PUBLIC_KEY_FP256BN_LENGTH); + ecdaa_decode(current, binbuf, ECDAA_ISSUER_PUBLIC_KEY_FP256BN_LENGTH); ret = ecdaa_issuer_public_key_FP256BN_deserialize(&member.ipk, binbuf); if (-1 == ret) { printf("member_getpublic: issuer public key is malformed!\n"); @@ -199,8 +195,10 @@ int member_getpublic(char *buffer) { printf("member_getpublic: signature of issuer public key is invalid\n"); ret = -1; } else { - member.state = RCVPUBLIC; - ret = 1; + bzero(buffer, MAX_BUFSIZE); + strncpy(buffer, "JOIN\n", 5); + member.state = APPEND; + ret = 0; } } else { printf("member_getpublic: did not get public key from issuer\n"); @@ -208,11 +206,31 @@ int member_getpublic(char *buffer) { ret = -1; } break; + case APPEND: + if (0 == strncasecmp("JOINSTART", buffer, 9)) { + printf("ISSUER > MEMBER: %s", buffer); + member_joinappend(buffer); + member.state = JOINPROCEED; + } else { + printf("member_join: did not get nonce from issuer\n"); + member.state = RCVPUBLIC; + ret = -1; + } + break; + case JOINPROCEED: + if (0 == strncasecmp("JOINPROCEED", buffer, 11)) { + printf("ISSUER > MEMBER: %s", buffer); + member_joinfinish(buffer); + member.state = JOINED; + ret = 1; + } else { + printf("member_getpublic: did not get credentials from issuer\n"); + member.state = RCVPUBLIC; + ret = -1; + } + break; default: - printf("member_getpublic: did not get public key from issuer\n"); - member.state = ON; ret = -1; - break; } if (0 == ret) { printf("ISSUER < MEMBER: %s", buffer); @@ -220,39 +238,60 @@ int member_getpublic(char *buffer) { return ret; } -//"ATTEST" > "ATTEST " -int member_attest(char *buffer) { +//"VERIFYMSG" > "VERIFYMSG " +int member_verifymsg(char *buffer) { char *current = buffer; uint8_t binbuf[MAX_BUFSIZE]; - uint8_t msg[MAX_MSGSIZE] = "I am the real host"; - size_t msg_len = strlen((char*)msg); - uint8_t has_nym = member.bsn_len != 0 ? 1 : 0; + uint8_t has_nym = member.bsn_len > 0 ? 1 : 0; struct ecdaa_signature_FP256BN sig; - size_t sig_len = has_nym ? ECDAA_SIGNATURE_FP256BN_WITH_NYM_LENGTH : ECDAA_SIGNATURE_FP256BN_LENGTH; + size_t sig_len = has_nym ? ecdaa_signature_FP256BN_with_nym_length() : ecdaa_signature_FP256BN_length(); + int ret = 0; + + if (0 == strncasecmp("OK", buffer, 2)) { + return 1; + } else if (0 == strncasecmp("ERR", buffer, 3)) { + printf("member_verifymsg: Verifier refused signature\n"); + return 1; + } - ecdaa_signature_TPM_FP256BN_sign(&sig, msg, msg_len, member.bsn, member.bsn_len, &member.cred, ecdaa_rand, &member.ctx); bzero(buffer, MAX_BUFSIZE); - bzero(binbuf, MAX_BUFSIZE); - strncpy(current, "ATTEST ", 7); - current = ¤t[7]; + strncpy(current, "VERIFYMSG ", 10); + current = ¤t[10]; - strncpy(current, (char*) msg, MAX_MSGSIZE); - current[MAX_MSGSIZE] = has_nym == 1 ? '1' : '0'; - current = ¤t[MAX_MSGSIZE + 1]; + ret = ecdaa_encode(msg, current, msg_len); + current = ¤t[2 * MAX_MSGSIZE]; if(has_nym) { + if (0 != ecdaa_signature_TPM_FP256BN_sign(&sig, msg, msg_len, member.bsn, member.bsn_len, &member.cred, ecdaa_rand, &member.ctx)) { + printf("member_verifymsg: Signing message failed\n"); + } + current[0] = '1'; + current = ¤t[1]; strncpy(current, (char *)member.bsn, MAX_BSNSIZE); current = ¤t[MAX_BSNSIZE]; + } else { + if (0 != ecdaa_signature_TPM_FP256BN_sign(&sig, msg, msg_len, NULL, 0, &member.cred, ecdaa_rand, &member.ctx)) { + printf("member_verifymsg: Signing message failed\n"); + } + current[0] = '0'; + current = ¤t[1]; } + bzero(binbuf, MAX_BUFSIZE); ecdaa_signature_FP256BN_serialize(binbuf, &sig, has_nym); - ecdaa_bintohex(binbuf, sig_len, current); - current[2 * sig_len] = '\n'; + ret = ecdaa_encode(binbuf, current, sig_len); + printf("member_verifymsg: has_nym: %u, sig_len: %lu\n",has_nym, sig_len); + printf("member_verifymsg: msg: %s, len: %lu\n",msg, msg_len); + printf("member_verifymsg: bsn: %s, len: %lu\n",(char *)member.bsn, strlen((char *)member.bsn)); + printf("member_verifymsg: sig: %s, len: %lu\n", current, sig_len); + + current[ret] = '\n'; return 0; } //"PUBLISH" > "PUBLISH " int member_publish(char *buffer) { char *current; + int ret = 0; uint8_t binbuf[MAX_BUFSIZE]; bzero(buffer, MAX_BUFSIZE); @@ -261,9 +300,9 @@ int member_publish(char *buffer) { current = &buffer[8]; bzero(binbuf, MAX_BUFSIZE); ecdaa_member_public_key_FP256BN_serialize(binbuf, &member.mpk); - ecdaa_bintohex(binbuf, ECDAA_MEMBER_PUBLIC_KEY_FP256BN_LENGTH, current); + ret = ecdaa_encode(binbuf, current, ECDAA_MEMBER_PUBLIC_KEY_FP256BN_LENGTH); - current[2 * ECDAA_MEMBER_PUBLIC_KEY_FP256BN_LENGTH] = '\n'; + current[ret] = '\n'; return 0; } @@ -272,13 +311,9 @@ int member_publish(char *buffer) { int member_joinappend(char *buffer) { char *current = &buffer[10]; uint8_t binbuf[MAX_BUFSIZE]; - ecdaa_hextobin(current, member.nonce, NONCE_SIZE); - - uint8_t serial_gpk[ECDAA_GROUP_PUBLIC_KEY_FP256BN_LENGTH]; - bzero(serial_gpk, ECDAA_GROUP_PUBLIC_KEY_FP256BN_LENGTH); - ecdaa_issuer_public_key_FP256BN_serialize(serial_gpk, &member.ipk); - - if (0 != ecdaa_member_key_pair_TPM_FP256BN_generate(&member.mpk, serial_gpk, member.nonce, NONCE_SIZE, &member.ctx)) { + int ret = ecdaa_decode(current, member.nonce, NONCE_SIZE); + ecdaa_write_buffer_to_file(member_nonce_file, member.nonce, NONCE_SIZE); + if (0 != ecdaa_member_key_pair_TPM_FP256BN_generate(&member.mpk, member.pk_in, member.nonce, NONCE_SIZE, &member.ctx)) { fprintf(stderr, "Error generating member key-pair\n"); return -1; } @@ -288,8 +323,8 @@ int member_joinappend(char *buffer) { current = &buffer[7]; bzero(binbuf, MAX_BUFSIZE); ecdaa_member_public_key_FP256BN_serialize(binbuf, &member.mpk); - ecdaa_bintohex(binbuf, ECDAA_MEMBER_PUBLIC_KEY_FP256BN_LENGTH, current); - current[2 * ECDAA_MEMBER_PUBLIC_KEY_FP256BN_LENGTH] = '\n'; + ret = ecdaa_encode(binbuf, current, ECDAA_MEMBER_PUBLIC_KEY_FP256BN_LENGTH); + current[ret] = '\n'; return 0; } @@ -300,19 +335,66 @@ int member_joinfinish(char *buffer) { uint8_t binbuf[MAX_BUFSIZE]; int ret = 0; bzero(binbuf, MAX_BUFSIZE); - ecdaa_hextobin(current, binbuf, ECDAA_CREDENTIAL_FP256BN_LENGTH); + ret = ecdaa_decode(current, binbuf, ECDAA_CREDENTIAL_FP256BN_LENGTH); - current = &buffer[12 + 2 * ECDAA_CREDENTIAL_FP256BN_LENGTH + 1]; + current = ¤t[ret]; bincur = &binbuf[ECDAA_CREDENTIAL_FP256BN_LENGTH]; - ecdaa_hextobin(current, bincur, ECDAA_CREDENTIAL_FP256BN_SIGNATURE_LENGTH); + ecdaa_decode(current, bincur, ECDAA_CREDENTIAL_FP256BN_SIGNATURE_LENGTH); ret = ecdaa_credential_FP256BN_deserialize_with_signature(&member.cred, &member.mpk, &member.ipk.gpk, binbuf, bincur); if(-1 == ret) { printf("member_joinfinish: credential is malformed!\n"); ret = -1; } else if(-2 == ret) { - printf("member_joinfinish: siganture of credential is invalid"); + printf("member_joinfinish: siganture of credential is invalid\n"); ret = -1; } + printf("member_joinfinish: writing key-pair and credential to disk\n"); + if(0 != ecdaa_member_public_key_FP256BN_serialize_file(member_public_key_file, &member.mpk) || + 0 != ecdaa_credential_FP256BN_serialize_file(member_credential_file, &member.cred)) { + printf("issuer_setup: Error saving key-pair or credential to disk\n"); + return -1; + } + + return ret; +} + +int read_public_key_from_files(uint8_t *public_key, TPM2_HANDLE *key_handle, const char *pub_key_filename, const char *handle_filename) +{ + int ret = 0; + + FILE *pub_key_file_ptr = fopen(pub_key_filename, "r"); + if (NULL == pub_key_file_ptr) + return -1; + do { + for (unsigned i=0; i < ECP_FP256BN_LENGTH; i++) { + unsigned byt; + if (fscanf(pub_key_file_ptr, "%02X", &byt) != 1) { + ret = -1; + break; + } + public_key[i] = (uint8_t)byt; + } + } while(0); + (void)fclose(pub_key_file_ptr); + if (0 != ret) + return -1; + + FILE *handle_file_ptr = fopen(handle_filename, "r"); + if (NULL == handle_file_ptr) + return -1; + do { + for (int i=(sizeof(TPM2_HANDLE)-1); i >= 0; i--) { + unsigned byt; + if (fscanf(handle_file_ptr, "%02X", &byt) != 1) { + ret = -1; + break; + } + *key_handle += byt<<(i*8); + } + if (0 != ret) + break; + } while(0); + (void)fclose(handle_file_ptr); return ret; } diff --git a/member-tpm.h b/member-tpm.h index f497280..f136025 100644 --- a/member-tpm.h +++ b/member-tpm.h @@ -2,8 +2,8 @@ // Created by root on 11/5/19. // -#ifndef ECDAA_ISSUER_MEMBER_H -#define ECDAA_ISSUER_MEMBER_H +#ifndef ECDAA_MEMBER_TPM_H +#define ECDAA_MEMBER_TPM_H #include #include #include @@ -13,6 +13,12 @@ #include "client.h" #include "common.h" +#define ECP_FP256BN_LENGTH 130 + int process_member(char *buffer); -#endif //ECDAA_ISSUER_ISSUER_H +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