#include <tss2/tss2_esys.h>
#include <tss2/tss2_mu.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void check_rc(TSS2_RC rc, const char *msg) {
if (rc != TSS2_RC_SUCCESS) {
fprintf(stderr, "错误: %s (0x%x)\n", msg, rc);
exit(EXIT_FAILURE);
}
}
void printhex( unsigned char * str, int len){
int i = 0;
printf("hex %d \n", len);
if(!str)
return;
for(i = 0; i < len; i++){
if(i%4==0)
printf(" ");
printf("%02x", str[i]);
}
printf("\n");
}
int main() {
ESYS_CONTEXT *ctx = NULL;
ESYS_TR primaryHandle = ESYS_TR_NONE;
ESYS_TR keyHandle = ESYS_TR_NONE;
TPM2B_PUBLIC inPublic = {0};
TPM2B_SENSITIVE_CREATE inSensitive = {0};
TPM2B_PUBLIC *primPublic = NULL;
TPM2B_PUBLIC *outPublic = NULL;
TPM2B_PRIVATE *outPrivate = NULL;
const char *message = "Hello TPM2.0!";
TSS2_ABI_VERSION ver = TSS2_ABI_VERSION_CURRENT;
check_rc(Esys_Initialize(&ctx, NULL, &ver), "Esys_Initialize");
inPublic.size = sizeof(TPMT_PUBLIC);
inPublic.publicArea.type = TPM2_ALG_ECC;
inPublic.publicArea.nameAlg = TPM2_ALG_SM3_256;
inPublic.publicArea.objectAttributes = TPMA_OBJECT_FIXEDTPM | TPMA_OBJECT_USERWITHAUTH | TPMA_OBJECT_FIXEDPARENT | TPMA_OBJECT_SENSITIVEDATAORIGIN | TPMA_OBJECT_RESTRICTED | TPMA_OBJECT_DECRYPT;
inPublic.publicArea.parameters.eccDetail.symmetric.algorithm = TPM2_ALG_SM4;
inPublic.publicArea.parameters.eccDetail.symmetric.keyBits.sm4 = 0x80;
inPublic.publicArea.parameters.eccDetail.symmetric.mode.sm4 = 0x43;
inPublic.publicArea.parameters.eccDetail.scheme.scheme = TPM2_ALG_NULL;
inPublic.publicArea.parameters.eccDetail.kdf.scheme = TPM2_ALG_NULL;
inPublic.publicArea.parameters.eccDetail.curveID = TPM2_ECC_SM2_P256;
TPM2B_CREATION_DATA *creationData = NULL;
TPM2B_DIGEST *creationHash = NULL;
TPMT_TK_CREATION *creationTicket = NULL;
TPM2B_DATA outsideInfo = {
.size = 0,
.buffer = {},
};
TPML_PCR_SELECTION creationPCR = {
.count = 0,
};
TPM2B_AUTH authValue = {
.size = 0,
.buffer = {}
};
TPM2B_AUTH authValuePrimary = {
.size = 5,
.buffer = {1, 2, 3, 4, 5}
};
TPM2B_SENSITIVE_CREATE inSensitivePrimary = {
.size = 0,
.sensitive = {
.userAuth = authValuePrimary,
.data = {
.size = 0,
.buffer = {0},
},
},
};
check_rc(Esys_CreatePrimary(ctx, ESYS_TR_RH_OWNER, ESYS_TR_PASSWORD,
ESYS_TR_NONE, ESYS_TR_NONE, &inSensitivePrimary, &inPublic, &outsideInfo, &creationPCR,
&primaryHandle, &primPublic, &creationData, &creationHash, &creationTicket), "Esys_CreatePrimary");
TPM2B_PUBLIC subKeyPublic = {0};
TPM2B_SENSITIVE_CREATE subKeySensitive = {0};
subKeyPublic.publicArea.type = TPM2_ALG_ECC;
subKeyPublic.publicArea.nameAlg = TPM2_ALG_SM3_256;
subKeyPublic.publicArea.objectAttributes = TPMA_OBJECT_FIXEDTPM | TPMA_OBJECT_USERWITHAUTH | TPMA_OBJECT_FIXEDPARENT | TPMA_OBJECT_SENSITIVEDATAORIGIN | TPMA_OBJECT_SIGN_ENCRYPT;
subKeyPublic.publicArea.parameters.eccDetail.symmetric.algorithm = TPM2_ALG_NULL;
subKeyPublic.publicArea.parameters.eccDetail.scheme.scheme = TPM2_ALG_SM2;
subKeyPublic.publicArea.parameters.eccDetail.scheme.details.sm2.hashAlg = TPM2_ALG_SM3_256;
subKeyPublic.publicArea.parameters.eccDetail.kdf.scheme = TPM2_ALG_NULL;
subKeyPublic.publicArea.parameters.eccDetail.curveID = TPM2_ECC_SM2_P256;
check_rc(Esys_Create(ctx, primaryHandle, ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE,
&subKeySensitive, &subKeyPublic, &outsideInfo, &creationPCR,
&outPrivate, &outPublic, &creationData, &creationHash, &creationTicket), "Esys_Create");
ESYS_TR loadedKeyHandle = ESYS_TR_PCR0;
TPM2B_NAME *name = NULL;
printf( "create public symmetric.algorithm %x \n",
outPublic->publicArea.parameters.eccDetail.symmetric.algorithm );
printf( "create public scheme.scheme %x \n",
outPublic->publicArea.parameters.eccDetail.scheme.scheme);
printf( "create public sm2.hashAlg %x \n",
outPublic->publicArea.parameters.eccDetail.scheme.details.sm2.hashAlg );
printf( "create public kdf.scheme %x \n",
outPublic->publicArea.parameters.eccDetail.kdf.scheme );
printf( "create public eccDetail.curveID %x \n",
outPublic->publicArea.parameters.eccDetail.curveID);
check_rc(Esys_Load(ctx, primaryHandle, ESYS_TR_PASSWORD, ESYS_TR_NONE,
ESYS_TR_NONE, outPrivate, outPublic, &loadedKeyHandle), "Esys_Load");
TPM2B_DIGEST *digest = NULL;
TPMT_TK_HASHCHECK *validation = NULL;
TPM2B_MAX_BUFFER input = {
.size = sizeof(message)
};
memcpy(input.buffer, message, input.size);
TSS2_RC rc = Esys_Hash(
ctx, ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
&input, TPM2_ALG_SM3_256, ESYS_TR_RH_OWNER, &digest, &validation
);
check_rc(rc, "Esys_Hash失败");
printf("hash generate \n");
printhex( digest->buffer, digest->size );
TPMT_SIGNATURE *signature = NULL;
TPMT_SIG_SCHEME inScheme = {
.scheme = TPM2_ALG_SM2,
.details = {.sm2 = {.hashAlg = TPM2_ALG_SM3_256}}
};
check_rc(Esys_Sign(ctx, loadedKeyHandle, ESYS_TR_PASSWORD, ESYS_TR_NONE,
ESYS_TR_NONE, digest, &inScheme, validation, &signature), "Esys_Sign");
printf("signature \n");
printhex((unsigned char *)signature->signature.sm2.signatureR.buffer,
signature->signature.sm2.signatureR.size);
printhex((unsigned char *)signature->signature.sm2.signatureS.buffer,
signature->signature.sm2.signatureS.size);
TPMT_TK_VERIFIED *verification = NULL;
check_rc(Esys_VerifySignature(ctx, loadedKeyHandle, ESYS_TR_NONE,
ESYS_TR_NONE, ESYS_TR_NONE, digest,
signature, &verification), "Esys_VerifySignature");
printf("verify success \n");
Esys_Free(outPublic);
Esys_Free(outPrivate);
Esys_Free(name);
Esys_Free(signature);
Esys_Free(verification);
Esys_Finalize(&ctx);
return 0;
}