Created
April 16, 2020 21:27
-
-
Save williamcroberts/a3966e2131ba7e0adbf3ea757d36f15d to your computer and use it in GitHub Desktop.
poor example of safe multithreaded sharing of ESYS_CONTEXT and ESYS_TR's
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <string.h> | |
#include <pthread.h> | |
#include <unistd.h> | |
#include <tss2/tss2_esys.h> | |
static ESYS_CONTEXT *ectx; | |
static ESYS_TR objectHandle; | |
pthread_t t1, t2; | |
static void *t1_task_create(void *arg) { | |
printf("t1: starting\n"); | |
TPM2B_PUBLIC pub_templ = { | |
.size = 0, | |
.publicArea = { | |
.type = TPM2_ALG_RSA, | |
.nameAlg = TPM2_ALG_SHA1, | |
.objectAttributes = (TPMA_OBJECT_USERWITHAUTH | | |
TPMA_OBJECT_SIGN_ENCRYPT | | |
TPMA_OBJECT_FIXEDTPM | | |
TPMA_OBJECT_FIXEDPARENT | | |
TPMA_OBJECT_SENSITIVEDATAORIGIN), | |
.authPolicy = { | |
.size = 0, | |
}, | |
.parameters.rsaDetail = { | |
.symmetric = { | |
.algorithm = TPM2_ALG_NULL, | |
.keyBits.aes = 128, | |
.mode.aes = TPM2_ALG_CFB}, | |
.scheme = { | |
.scheme = TPM2_ALG_RSAPSS, | |
.details = { | |
.rsapss = { .hashAlg = TPM2_ALG_SHA1 } | |
} | |
}, | |
.keyBits = 2048, | |
.exponent = 0, | |
}, | |
.unique.rsa = { | |
.size = 0, | |
.buffer = {}, | |
}, | |
}, | |
}; | |
TPM2B_DATA outsideInfo = { | |
.size = 0, | |
.buffer = {} | |
, | |
}; | |
TPML_PCR_SELECTION creationPCR = { | |
.count = 0, | |
}; | |
TPM2B_SENSITIVE_CREATE inSensitive = { | |
.size = 0, | |
.sensitive = { | |
.userAuth = { | |
.size = 0, | |
.buffer = {0} | |
, | |
}, | |
.data = { | |
.size = 0, | |
.buffer = {0} | |
} | |
} | |
}; | |
TPM2B_PUBLIC *outPublic = NULL; | |
TPM2B_CREATION_DATA *creationData = NULL; | |
TPM2B_DIGEST *creationHash = NULL; | |
TPMT_TK_CREATION *creationTicket = NULL; | |
printf("t1: creating key\n"); | |
TSS2_RC rv = Esys_CreatePrimary(ectx, ESYS_TR_RH_OWNER, ESYS_TR_PASSWORD, | |
ESYS_TR_NONE, ESYS_TR_NONE, &inSensitive, &pub_templ, | |
&outsideInfo, &creationPCR, &objectHandle, | |
&outPublic, &creationData, &creationHash, | |
&creationTicket); | |
if (rv != TSS2_RC_SUCCESS) { | |
fprintf(stderr, "t1: Esys_CreatePrimary: 0x%x\n", rv); | |
return NULL; | |
} | |
printf("t1: key created - done\n"); | |
return NULL; | |
} | |
static void *t2_task_sign(void *arg) { | |
printf("t2: starting\n"); | |
printf("t2: joining on t1\n"); | |
void *retval = NULL; | |
int rx = pthread_join(t1, &retval); | |
if (rx) { | |
fprintf(stderr, "T2 pthread_join: 0x%x\n", rx); | |
return NULL; | |
} | |
TPMT_SIG_SCHEME inScheme = { .scheme = TPM2_ALG_NULL }; | |
TPMT_TK_HASHCHECK hash_validation = { | |
.tag = TPM2_ST_HASHCHECK, | |
.hierarchy = TPM2_RH_OWNER, | |
.digest = {0} | |
}; | |
/* SHA1 digest for PCR register with zeros */ | |
TPM2B_DIGEST pcr_digest_zero = { | |
.size = 20, | |
.buffer = { 0x67, 0x68, 0x03, 0x3e, 0x21, 0x64, 0x68, 0x24, 0x7b, 0xd0, | |
0x31, 0xa0, 0xa2, 0xd9, 0x87, 0x6d, 0x79, 0x81, 0x8f, 0x8f } | |
}; | |
TPMT_SIGNATURE *signature = NULL; | |
printf("t2: signing\n"); | |
TSS2_RC rv = Esys_Sign( | |
ectx, | |
objectHandle, | |
ESYS_TR_PASSWORD, | |
ESYS_TR_NONE, | |
ESYS_TR_NONE, | |
&pcr_digest_zero, | |
&inScheme, | |
&hash_validation, | |
&signature); | |
if (rv != TSS2_RC_SUCCESS) { | |
fprintf(stderr, "t2: Esys_Sign: 0x%x\n", rv); | |
return NULL; | |
} | |
printf("t2: done success\n"); | |
return NULL; | |
} | |
int main(int argc, char *argv[]) { | |
/* | |
* create a connection to the TPM letting ESAPI choose how to get there. | |
* If you need more control, you can use tcti and tcti-ldr libraries to | |
* get a TCTI pointer to use for the tcti argument of Esys_Initialize. | |
*/ | |
printf("main: initializing esys\n"); | |
TSS2_RC rv = Esys_Initialize(&ectx, | |
NULL, /* let it find the TCTI */ | |
NULL);/* Use whatever ABI */ | |
if (rv != TSS2_RC_SUCCESS) { | |
fprintf(stderr, "Esys_Initialize: 0x%x\n", rv); | |
return 1; | |
} | |
printf("main: spawning create thread 1\n"); | |
int rx = pthread_create(&t1, NULL, t1_task_create, NULL); | |
if (rx != 0) { | |
fprintf(stderr, "pthread_create: 0x%x\n", rx); | |
return 1; | |
} | |
/* do some stuff */ | |
printf("main: doing stuff\n"); | |
sleep(1); | |
printf("main: signing with thread 2\n"); | |
rx = pthread_create(&t2, NULL, t2_task_sign, NULL); | |
if (rx != 0) { | |
fprintf(stderr, "pthread_create: 0x%x\n", rx); | |
return 1; | |
} | |
printf("main: joining with thread 2\n"); | |
void *retval = NULL; | |
rx = pthread_join(t2, &retval); | |
if (rx) { | |
fprintf(stderr, "pthread_create: 0x%x\n", rx); | |
return 1; | |
} | |
Esys_Finalize(&ectx); | |
printf("main: done\n"); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment