Created
April 21, 2020 17:35
-
-
Save williamcroberts/66a7dab3adfb973fbae3219954535009 to your computer and use it in GitHub Desktop.
poor example of creating a TPM2 AES Key and using it
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 <stdlib.h> | |
#include <string.h> | |
#include <unistd.h> | |
#include <tss2/tss2_esys.h> | |
void create_primary(ESYS_CONTEXT *ectx, ESYS_TR *parent) { | |
TPM2B_PUBLIC pub_templ = { | |
.publicArea = { | |
.type = TPM2_ALG_RSA, | |
.nameAlg = TPM2_ALG_SHA256, | |
.objectAttributes = (TPMA_OBJECT_USERWITHAUTH | | |
TPMA_OBJECT_RESTRICTED | | |
TPMA_OBJECT_DECRYPT | | |
TPMA_OBJECT_FIXEDTPM | | |
TPMA_OBJECT_FIXEDPARENT | | |
TPMA_OBJECT_SENSITIVEDATAORIGIN), | |
.authPolicy = { | |
.size = 0, | |
}, | |
.parameters.rsaDetail = { | |
.symmetric = { | |
.algorithm = TPM2_ALG_AES, | |
.keyBits.aes = 128, | |
.mode.aes = TPM2_ALG_CFB}, | |
.scheme = { | |
.scheme = TPM2_ALG_NULL | |
}, | |
.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; | |
TSS2_RC rv = Esys_CreatePrimary(ectx, ESYS_TR_RH_OWNER, ESYS_TR_PASSWORD, | |
ESYS_TR_NONE, ESYS_TR_NONE, &inSensitive, &pub_templ, | |
&outsideInfo, &creationPCR, parent, | |
&outPublic, &creationData, &creationHash, | |
&creationTicket); | |
if (rv != TSS2_RC_SUCCESS) { | |
fprintf(stderr, "t1: Esys_CreatePrimary: 0x%x\n", rv); | |
exit(1); | |
} | |
} | |
void create_and_load_aes_key(ESYS_CONTEXT *ectx, ESYS_TR parent, ESYS_TR *aes_key) { | |
TPM2B_PUBLIC pub_templ = { | |
.size = 0, | |
.publicArea = { | |
.type = TPM2_ALG_SYMCIPHER, | |
.nameAlg = TPM2_ALG_SHA256, | |
.objectAttributes = (TPMA_OBJECT_USERWITHAUTH | | |
TPMA_OBJECT_SIGN_ENCRYPT | | |
TPMA_OBJECT_DECRYPT | | |
TPMA_OBJECT_FIXEDTPM | | |
TPMA_OBJECT_FIXEDPARENT | | |
TPMA_OBJECT_SENSITIVEDATAORIGIN), | |
.parameters = { | |
.symDetail = { | |
.sym = { | |
.algorithm = TPM2_ALG_AES, | |
.keyBits = { .aes = 128 }, | |
.mode = { .aes = TPM2_ALG_NULL } | |
}, | |
}, | |
}, | |
.authPolicy = { | |
.size = 0, | |
}, | |
}, | |
}; | |
TPM2B_DATA outsideInfo = { | |
.size = 0, | |
}; | |
TPML_PCR_SELECTION creationPCR = { | |
.count = 0, | |
}; | |
TPM2B_SENSITIVE_CREATE inSensitive = { | |
.size = 0, | |
.sensitive = { | |
.userAuth = { | |
/* TODO: Set this to a non-hard coded password, or better yet use a policy */ | |
.size = 8, | |
.buffer = "password" | |
, | |
}, | |
.data = { | |
.size = 0, | |
.buffer = {0} | |
} | |
} | |
}; | |
TPM2B_PRIVATE *outPrivate = NULL; | |
TPM2B_PUBLIC *outPublic = NULL; | |
TPM2B_CREATION_DATA *creationData = NULL; | |
TPM2B_DIGEST *creationHash = NULL; | |
TPMT_TK_CREATION *creationTicket = NULL; | |
TSS2_RC rv = Esys_Create( | |
ectx, | |
parent, | |
ESYS_TR_PASSWORD, | |
ESYS_TR_NONE, | |
ESYS_TR_NONE, | |
&inSensitive, | |
&pub_templ, | |
&outsideInfo, | |
&creationPCR, | |
&outPrivate, | |
&outPublic, | |
&creationData, | |
&creationHash, | |
&creationTicket); | |
if (rv != TSS2_RC_SUCCESS) { | |
fprintf(stderr, "Esys_Create: 0x%x\n", rv); | |
exit(1); | |
} | |
/* if you want this key again, save the TPM2B_PUBLIC and TPM2B_PRIVATE for | |
* future use. You just need to call load again. | |
*/ | |
rv = Esys_Load(ectx, | |
parent, | |
ESYS_TR_PASSWORD, | |
ESYS_TR_NONE, | |
ESYS_TR_NONE, | |
outPrivate, | |
outPublic, | |
aes_key); | |
if (rv != TSS2_RC_SUCCESS) { | |
fprintf(stderr, "Esys_Load: 0x%x\n", rv); | |
exit(1); | |
} | |
} | |
void enc_dec(ESYS_CONTEXT *ectx, | |
TPMI_YES_NO decrypt, | |
ESYS_TR aes_key, | |
TPM2B_MAX_BUFFER *in, | |
TPM2B_MAX_BUFFER **out) { | |
const TPM2B_AUTH authValue = { | |
.size = 8, | |
.buffer = "password", | |
}; | |
TSS2_RC rv = | |
Esys_TR_SetAuth(ectx, aes_key, &authValue); | |
if (rv != TSS2_RC_SUCCESS) { | |
fprintf(stderr, "Esys_TR_SetAuth: 0x%x\n", rv); | |
exit(1); | |
} | |
/* initialize to GOOD random values */ | |
TPM2B_IV iv_in = { | |
.size = 16, | |
.buffer = { 0 }, | |
}; | |
/* iv for next block */ | |
TPM2B_IV *iv_out = NULL; | |
/* better to use the EncryptDecrypt2 call if your TPM supports it */ | |
rv = Esys_EncryptDecrypt(ectx, | |
aes_key, | |
ESYS_TR_PASSWORD, | |
ESYS_TR_NONE, | |
ESYS_TR_NONE, | |
decrypt, | |
TPM2_ALG_CBC, | |
&iv_in, | |
in, | |
out, | |
&iv_out); | |
if (rv != TSS2_RC_SUCCESS) { | |
fprintf(stderr, "Esys_EncryptDecrypt: 0x%x\n", rv); | |
exit(1); | |
} | |
} | |
void encrypt(ESYS_CONTEXT *ectx, ESYS_TR aes_key, | |
TPM2B_MAX_BUFFER *ptext, | |
TPM2B_MAX_BUFFER **ctext) { | |
enc_dec(ectx, TPM2_NO, aes_key, | |
ptext, ctext); | |
} | |
void decrypt(ESYS_CONTEXT *ectx, ESYS_TR aes_key, | |
TPM2B_MAX_BUFFER *ctext, | |
TPM2B_MAX_BUFFER **ptext) { | |
enc_dec(ectx, TPM2_YES, aes_key, | |
ctext, ptext); | |
} | |
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. | |
*/ | |
fprintf(stderr, "****************************\n"); | |
fprintf(stderr, "* DO NOT USE IN PRODUCTION *\n"); | |
fprintf(stderr, "****************************\n"); | |
printf("main: initializing esys\n"); | |
ESYS_CONTEXT *ectx = NULL; | |
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; | |
} | |
ESYS_TR parent = ESYS_TR_NONE; | |
create_primary(ectx, &parent); | |
ESYS_TR aes_key = ESYS_TR_NONE; | |
create_and_load_aes_key(ectx, parent, &aes_key); | |
TPM2B_MAX_BUFFER ptext = { | |
.size = 16, | |
.buffer = "hello world" | |
}; | |
TPM2B_MAX_BUFFER *ctext = NULL; | |
printf("Encrypting Ciphertext\n"); | |
encrypt(ectx, aes_key, | |
&ptext, | |
&ctext); | |
printf("Decrypting: \"hello world\"\n"); | |
TPM2B_MAX_BUFFER *ptext2 = NULL; | |
decrypt(ectx, aes_key, | |
ctext, | |
&ptext2); | |
printf("Decrypted data: %.*s\n", ptext2->size, ptext2->buffer); | |
Esys_Finalize(&ectx); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment