/*
** Copyright (C) 2020 Johannes Kepler University Linz, Institute of Networks and Security
** Copyright (C) 2020 CDL Digidow
**
** Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
** the European Commission - subsequent versions of the EUPL (the "Licence").
** You may not use this work except in compliance with the Licence.
**
** You should have received a copy of the European Union Public License along
** with this program. If not, you may obtain a copy of the Licence at:
**
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the Licence is distributed on an "AS IS" basis,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the Licence for the specific language governing permissions and
** limitations under the Licence.
**
*/
#include
#include
#include
#include
#include
#define ECP_FP256BN_LENGTH 65
const char *pub_key_filename = "pub_key.txt";
const char *handle_filename = "handle.txt";
struct tpm_context {
struct ecdaa_tpm_context tpm_ctx;
uint8_t serialized_public_key[ECP_FP256BN_LENGTH];
ECP_FP256BN public_key;
unsigned char tcti_buffer[256];
TSS2_TCTI_CONTEXT *tcti_context;
};
static void tpm_cleanup(struct tpm_context *ctx);
static int tpm_initialize(struct tpm_context *ctx, const char *pub_key_filename, const char *handle_filename);
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");
printf("Reading: %s\n",pub_key_filename);
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;
printf("i=%d, fscanf did not read a byte\n",i);
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");
printf("Reading: %s\n",handle_filename);
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;
}
static int tpm_initialize(struct tpm_context *ctx, const char *pub_key_filename, const char *handle_filename)
{
const char *device_conf = "/dev/tpm0";
memset(ctx->tcti_buffer, 0, sizeof(ctx->tcti_buffer));
int ret = 0;
TPM2_HANDLE key_handle = 0;
if (0 != read_public_key_from_files(ctx->serialized_public_key, &key_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;
}
ctx->tcti_context = (TSS2_TCTI_CONTEXT*)ctx->tcti_buffer;
size_t size;
ret = Tss2_Tcti_Device_Init(NULL, &size, device_conf);
if (TSS2_RC_SUCCESS != ret) {
printf("Failed to get allocation size for tcti context\n");
return -1;
}
if (size > sizeof(ctx->tcti_buffer)) {
printf("Error: device TCTI context size larger than pre-allocated buffer\n");
return -1;
}
ret = Tss2_Tcti_Device_Init(ctx->tcti_context, &size, device_conf);
if (TSS2_RC_SUCCESS != ret) {
printf("Error: Unable to initialize device TCTI context\n");
return -1;
}
ret = ecdaa_tpm_context_init(&ctx->tpm_ctx, key_handle, NULL, 0, ctx->tcti_context);
if (0 != ret) {
printf("Error: ecdaa_tpm_context_init failed: 0x%x\n", ret);
return -1;
}
return 0;
}
static void tpm_cleanup(struct tpm_context *ctx)
{
ecdaa_tpm_context_free(&ctx->tpm_ctx);
if (NULL != ctx->tcti_context) {
Tss2_Tcti_Finalize(ctx->tcti_context);
}
}