1 /* Copyright 2018 Intel Corporation, Inc
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
16 #include <tss2/tss2_common.h>
17 #include <tss2/tss2_esys.h>
18 #include <tss2/tss2_mu.h>
19 #include <tss2/tss2_tcti_device.h>
20 #include <tss2/tss2_tcti_mssim.h>
21 #include <tss2/tss2_tpm2_types.h>
26 #ifndef TSS2_API_VERSION_1_2_1_108
27 #error Version mismatch among TSS2 header files.
28 #endif /* TSS2_API_VERSION_1_2_1_108 */
34 /* SAPI context blob */
35 typedef struct _TSS2_SYS_OPAQUE_CONTEXT_BLOB TSS2_SYS_CONTEXT;
40 #include "tpm2_plugin_api.h"
42 #include <tss2/tss2_tcti.h>
45 #include <tss2/tss2-tcti-tabrmd.h>
47 #ifdef HAVE_TCTI_TABRMD
48 #include <tss2/tss2-tcti-tabrmd.h>
50 #define ARRAY_LEN(x) (sizeof(x)/sizeof(x[0]))
51 #define TSSWG_INTEROP 1
52 #define TSS_SAPI_FIRST_FAMILY 2
53 #define TSS_SAPI_FIRST_LEVEL 1
54 #define TSS_SAPI_FIRST_VERSION 108
56 bool output_enabled = true;
57 bool hexPasswd = false;
58 TPM2_HANDLE handle2048rsa;
59 const char *tcti_path="libtss2-tcti-device.so";
61 static void tcti_teardown(TSS2_TCTI_CONTEXT *tcticontext)
63 if (tcticontext == NULL)
65 Tss2_Tcti_Finalize (tcticontext);
69 static void sapi_teardown(TSS2_SYS_CONTEXT *sysContext)
71 if (sysContext == NULL)
73 Tss2_Sys_Finalize (sysContext);
77 static void sapi_teardown_full (TSS2_SYS_CONTEXT *sysContext)
79 TSS2_TCTI_CONTEXT *tcticontext = NULL;
82 rc = Tss2_Sys_GetTctiContext (sysContext, &tcticontext);
83 if (rc != TSS2_RC_SUCCESS)
85 sapi_teardown (sysContext);
86 tcti_teardown (tcticontext);
89 int tpm2_plugin_init()
91 printf("Init API done for TPM plugin ! \n");
95 int tpm2_plugin_uninit()
97 printf("UnInit API done for TPM plugin ! \n");
101 TPM2_HANDLE srk_handle;
102 int tpm2_plugin_activate(SSHSM_HW_PLUGIN_ACTIVATE_LOAD_IN_INFO_t *activate_in_info)
107 printf("number of buffers %d ! \n", activate_in_info->num_buffers);
108 if (activate_in_info->num_buffers!=1){
109 printf("activate failed ! \n");
112 printf("number of buffers %d ! \n", activate_in_info->num_buffers);
113 handle = malloc(activate_in_info->buffer_info[0]->length_of_buffer);
114 memcpy(handle, activate_in_info->buffer_info[0]->buffer, activate_in_info->buffer_info[0]->length_of_buffer);
115 srk_handle = strtol(handle, NULL, 16);
116 printf("Activate API done for TPM plugin ! \n");
120 TPMI_DH_OBJECT handle_load;
124 tcti_device_init (char const *device_file)
126 TCTI_DEVICE_CONF conf = {
127 .device_path = device_file,
133 TSS2_TCTI_CONTEXT *tcti_ctx;
135 rc = InitDeviceTcti (NULL, &size, 0);
136 if (rc != TSS2_RC_SUCCESS) {
138 "Failed to get allocation size for device tcti context: "
142 tcti_ctx = (TSS2_TCTI_CONTEXT*)calloc (1, size);
143 if (tcti_ctx == NULL) {
145 "Allocation for device TCTI context failed: %s\n",
149 rc = InitDeviceTcti (tcti_ctx, &size, &conf);
150 if (rc != TSS2_RC_SUCCESS) {
152 "Failed to initialize device TCTI context: 0x%x\n",
161 #ifdef HAVE_TCTI_SOCK
162 TSS2_TCTI_CONTEXT* tcti_socket_init (char const *address, uint16_t port)
164 TCTI_SOCKET_CONF conf = {
168 .logBufferCallback = NULL,
173 TSS2_TCTI_CONTEXT *tcti_ctx;
175 rc = InitSocketTcti (NULL, &size, &conf, 0);
176 if (rc != TSS2_RC_SUCCESS) {
177 fprintf (stderr, "Faled to get allocation size for tcti context: "
181 tcti_ctx = (TSS2_TCTI_CONTEXT*)calloc (1, size);
182 if (tcti_ctx == NULL) {
183 fprintf (stderr, "Allocation for tcti context failed: %s\n",
187 rc = InitSocketTcti (tcti_ctx, &size, &conf, 0);
188 if (rc != TSS2_RC_SUCCESS) {
189 fprintf (stderr, "Failed to initialize tcti context: 0x%x\n", rc);
196 #ifdef HAVE_TCTI_TABRMD
197 TSS2_TCTI_CONTEXT *tcti_tabrmd_init (void)
199 TSS2_TCTI_CONTEXT *tcti_ctx;
203 //rc = tss2_tcti_tabrmd_init(NULL, &size);
204 rc = Tss2_Tcti_Tabrmd_Init(NULL, &size, NULL);
205 if (rc != TSS2_RC_SUCCESS) {
206 printf("Failed to get size for TABRMD TCTI context: 0x%x", rc);
209 tcti_ctx = (TSS2_TCTI_CONTEXT*)calloc (1, size);
210 if (tcti_ctx == NULL) {
211 printf("Allocation for TABRMD TCTI context failed: %s", strerror (errno));
214 rc = Tss2_Tcti_Tabrmd_Init (tcti_ctx, &size, NULL);
215 if (rc != TSS2_RC_SUCCESS) {
216 printf("Failed to initialize TABRMD TCTI context: 0x%x", rc);
223 TSS2_TCTI_CONTEXT *tcti_init_from_options(common_opts_t *options)
225 switch (options->tcti_type) {
228 return tcti_device_init (options->device_file);
230 #ifdef HAVE_TCTI_SOCK
232 return tcti_socket_init (options->socket_address,
233 options->socket_port);
235 #ifdef HAVE_TCTI_TABRMD
237 return tcti_tabrmd_init ();
244 static TSS2_SYS_CONTEXT *sapi_ctx_init (TSS2_TCTI_CONTEXT *tcti_ctx)
246 TSS2_SYS_CONTEXT *sysContext;
249 TSS2_ABI_VERSION abi_version = {
250 .tssCreator = TSSWG_INTEROP,
251 .tssFamily = TSS_SAPI_FIRST_FAMILY,
252 .tssLevel = TSS_SAPI_FIRST_LEVEL,
253 .tssVersion = TSS_SAPI_FIRST_VERSION,
256 size = Tss2_Sys_GetContextSize (0);
257 sysContext = (TSS2_SYS_CONTEXT*)calloc (1, size);
258 if (sysContext == NULL) {
260 "Failed to allocate 0x%zx bytes for the SAPI context\n",
264 rc = Tss2_Sys_Initialize (sysContext, size, tcti_ctx, &abi_version);
265 if (rc != TSS2_RC_SUCCESS) {
266 fprintf (stderr, "Failed to initialize SAPI context: 0x%x\n", rc);
273 #define BUFFER_SIZE(type, field) (sizeof((((type *)NULL)->field)))
274 #define TPM2B_TYPE_INIT(type, field) { .size = BUFFER_SIZE(type, field), }
276 int hex2ByteStructure(const char *inStr, UINT16 *byteLength, BYTE *byteBuffer)
278 int strLength;//if the inStr likes "1a2b...", no prefix "0x"
280 if(inStr == NULL || byteLength == NULL || byteBuffer == NULL)
282 strLength = strlen(inStr);
285 for(i = 0; i < strLength; i++)
287 if(!isxdigit(inStr[i]))
291 if(*byteLength < strLength/2)
294 *byteLength = strLength/2;
296 for(i = 0; i < *byteLength; i++)
298 char tmpStr[4] = {0};
299 tmpStr[0] = inStr[i*2];
300 tmpStr[1] = inStr[i*2+1];
301 byteBuffer[i] = strtol(tmpStr, NULL, 16);
305 int load_key(TSS2_SYS_CONTEXT *sysContext,
306 TSS2L_SYS_AUTH_COMMAND sessionData,
307 TPMI_DH_OBJECT parentHandle,
308 TPM2B_PUBLIC *inPublic,
309 TPM2B_PRIVATE *inPrivate)
312 TSS2L_SYS_AUTH_RESPONSE sessionsDataOut;
313 TPM2B_NAME nameExt = TPM2B_TYPE_INIT(TPM2B_NAME, name);
315 TSS2L_SYS_AUTH_COMMAND sessionsData = { .count = 1, .auths = {{
316 .sessionHandle = TPM2_RS_PW,
317 .sessionAttributes = 0,
318 .nonce = {.size = 0},
319 .hmac = {.size = 0}}}};
321 if (sessionsData.auths[0].hmac.size > 0 && hexPasswd)
323 sessionsData.auths[0].hmac.size = sizeof(sessionsData.auths[0].hmac) - 2;
324 if (hex2ByteStructure((char *)sessionsData.auths[0].hmac.buffer,
325 &sessionsData.auths[0].hmac.size,
326 sessionsData.auths[0].hmac.buffer) != 0)
328 printf( "Failed to convert Hex format password for parent Passwd.\n");
333 rval = Tss2_Sys_Load (sysContext,
341 if(rval != TPM2_RC_SUCCESS)
343 printf("\nLoad Object Failed ! ErrorCode: 0x%0x\n\n",rval);
346 printf("\nLoad succ.\nLoadedHandle: 0x%08x\n\n",handle2048rsa);
351 int read_public(TSS2_SYS_CONTEXT *sysContext,
353 SSHSM_HW_PLUGIN_IMPORT_PUBLIC_KEY_INFO_t *importkey_info)
355 TSS2L_SYS_AUTH_RESPONSE sessionsDataOut;
357 TPM2B_PUBLIC public = {
361 TPM2B_NAME name = TPM2B_TYPE_INIT(TPM2B_NAME, name);
363 TPM2B_NAME qualified_name = TPM2B_TYPE_INIT(TPM2B_NAME, name);
365 TPM2_RC rval = Tss2_Sys_ReadPublic(sysContext, handle, 0,
366 &public, &name, &qualified_name, &sessionsDataOut);
367 if (rval != TPM2_RC_SUCCESS) {
368 printf("TPM2_ReadPublic error: rval = 0x%0x", rval);
372 printf("\nTPM2_ReadPublic OutPut: \n");
375 for (i = 0; i < name.size; i++)
376 printf("%02x ", name.name[i]);
379 printf("qualified_name: \n");
380 for (i = 0; i < qualified_name.size; i++)
381 printf("%02x ", qualified_name.name[i]);
384 printf("public.publicArea.parameters.rsaDetail.keyBits = %d \n", public.publicArea.parameters.rsaDetail.keyBits);
385 printf("public.publicArea.parameters.rsaDetail.exponent = %d \n", public.publicArea.parameters.rsaDetail.exponent);
387 importkey_info->modulus_size = public.publicArea.unique.rsa.size;
388 printf("importkey_info->modulus_size = %ld \n", importkey_info->modulus_size);
389 importkey_info->modulus = (unsigned char *) malloc(importkey_info->modulus_size);
390 if (importkey_info->modulus != NULL) {
391 memcpy(importkey_info->modulus, &public.publicArea.unique.rsa.buffer, importkey_info->modulus_size);
394 importkey_info->exponent_size = sizeof(public.publicArea.parameters.rsaDetail.exponent);
395 printf("importkey_info->exponent_size = %ld \n", importkey_info->exponent_size);
396 importkey_info->exponent = (unsigned int *) malloc(importkey_info->exponent_size);
397 if (importkey_info->exponent != NULL) {
398 memcpy(importkey_info->exponent, &public.publicArea.parameters.rsaDetail.exponent, importkey_info->exponent_size);
401 //*importkey_info->exponent = public.publicArea.parameters.rsaDetail.exponent;
407 Reads the PRK_PASSWORD Environment variable
408 and populates that information into the
409 provided sessionData variable
411 int readPassword(TSS2L_SYS_AUTH_COMMAND *sessionData)
415 prk_passwd = getenv("TPM_PRK_PASSWORD");
416 if (prk_passwd != NULL) {
417 sessionData->auths[0].hmac.size = strlen(prk_passwd);
418 if (sessionData->auths[0].hmac.size > sizeof(sessionData->auths[0].hmac.buffer)) {
421 memcpy(sessionData->auths[0].hmac.buffer, prk_passwd, sessionData->auths[0].hmac.size);
427 TPMS_CONTEXT loaded_key_context;
429 int load_key_execute(SSHSM_HW_PLUGIN_ACTIVATE_LOAD_IN_INFO_t *loadkey_in_info,
430 void **keyHandle, TSS2_SYS_CONTEXT *sysContext,
431 SSHSM_HW_PLUGIN_IMPORT_PUBLIC_KEY_INFO_t *importkey_info)
434 TPMI_DH_OBJECT parentHandle;
435 TPM2B_PUBLIC inPublic;
436 TPM2B_PRIVATE inPrivate;
437 TSS2L_SYS_AUTH_COMMAND sessionData;
442 Initializing the sessionData structure to the 0 values
443 sessionAttributes is a union and the following assignment
444 is based on the method used in other tpm2 tools.
446 TSS2L_SYS_AUTH_COMMAND sessionsData = { .count = 1, .auths = {{
447 .sessionHandle = TPM2_RS_PW,
448 .sessionAttributes = 0,
449 .nonce = {.size = 0},
450 .hmac = {.size = 0}}}};
451 memset(&inPublic,0,sizeof(TPM2B_PUBLIC));
452 memset(&inPrivate,0,sizeof(TPM2B_PRIVATE));
454 setbuf(stdout, NULL);
455 setvbuf (stdout, NULL, _IONBF, BUFSIZ);
457 parentHandle = srk_handle;
459 if (loadkey_in_info->num_buffers != 2)
463 Identify which buffer is public vs which is private
464 TPM2B_PUBLIC should be 360 bytes
465 TPM2B_PRIVATE should be 912 bytes
468 for (int i=0; i<2; i++) {
469 if (loadkey_in_info->buffer_info[i]->length_of_buffer == sizeof(TPM2B_PUBLIC)) {
470 memcpy(&inPublic, loadkey_in_info->buffer_info[i]->buffer,
471 loadkey_in_info->buffer_info[i]->length_of_buffer);
474 if (loadkey_in_info->buffer_info[i]->length_of_buffer == sizeof(TPM2B_PRIVATE)) {
475 memcpy(&inPrivate, loadkey_in_info->buffer_info[i]->buffer,
476 loadkey_in_info->buffer_info[i]->length_of_buffer);
481 // Read TPM_PRK_PASSWORD and setup sessionsData appropriately
482 if (readPassword(&sessionData) != 0) {
483 // Password read failure
487 returnVal = load_key (sysContext,
492 returnVal = read_public(sysContext,
496 TPM2_RC rval = Tss2_Sys_ContextSave(sysContext, handle2048rsa, &loaded_key_context);
497 if (rval != TPM2_RC_SUCCESS) {
498 printf("Tss2_Sys_ContextSave: Saving handle 0x%x context failed. TPM Error:0x%x", handle2048rsa, rval);
501 *keyHandle = &handle2048rsa;
505 int tpm2_plugin_load_key(SSHSM_HW_PLUGIN_ACTIVATE_LOAD_IN_INFO_t *loadkey_in_info,
507 SSHSM_HW_PLUGIN_IMPORT_PUBLIC_KEY_INFO_t *importkey_info)
510 common_opts_t opts = COMMON_OPTS_INITIALIZER;
511 TSS2_TCTI_CONTEXT *tcti_ctx;
512 tcti_ctx = tcti_init_from_options(&opts);
513 if (tcti_ctx == NULL)
516 TSS2_SYS_CONTEXT *sysContext = NULL;
518 sysContext = sapi_ctx_init(tcti_ctx);
525 ret = load_key_execute(loadkey_in_info, keyHandle, sysContext, importkey_info);
527 printf("Load key API failed in TPM plugin ! \n");
529 sapi_teardown_full(sysContext);
531 printf("Load key API successful in TPM plugin ! \n");
536 typedef struct tpm_sign_ctx tpm_sign_ctx;
537 struct tpm_sign_ctx {
538 TPMT_TK_HASHCHECK validation;
539 TPMS_AUTH_COMMAND sessionData;
540 TPMI_DH_OBJECT keyHandle;
542 char outFilePath[PATH_MAX];
545 TSS2_SYS_CONTEXT *sysContext;
548 //create a table to consolidate all parts of data from multiple SignUpdate from sessions
549 CONCATENATE_DATA_SIGNUPDATE_t data_signupdate_session[MAX_SESSIONS];
550 unsigned long sign_sequence_id = 0;
551 int tpm2_plugin_rsa_sign_init(
553 unsigned long mechanism,
556 void **plugin_data_ref
559 printf("rsa_sign_init API mechanism is %ld \n", mechanism);
560 printf("rsa_sign_init API len is %d \n", len);
564 unsigned long hSession = sign_sequence_id;
566 for (i = 0; i < MAX_SESSIONS; i++){
567 if (data_signupdate_session[i].session_handle == 0){
568 data_signupdate_session[i].session_handle = hSession;
569 for (j = 0; j < MAX_DATA_SIGNUPDATE; j++ )
570 data_signupdate_session[i].data_signupdate[j] = 0;
571 data_signupdate_session[i].data_length = 0;
574 *plugin_data_ref = (void *)hSession;
576 printf("rsa_sign_init API done for tpm2_plugin... \n");
580 /** This function is called by SSHSM only if there sign_final function is not called.
581 If sign_final function is called, it is assumed that plugin would have cleaned this up.
584 int tpm2_plugin_rsa_sign_cleanup(
586 unsigned long mechnaism,
587 void *plugin_data_ref
591 unsigned long hSession = (unsigned long)plugin_data_ref;
592 for (i = 0; i < MAX_SESSIONS; i++) {
593 if (data_signupdate_session[i].session_handle == hSession){
594 data_signupdate_session[i].session_handle = 0;
595 for (j =0; j < MAX_DATA_SIGNUPDATE; j++ )
596 data_signupdate_session[i].data_signupdate[j] =0;
597 data_signupdate_session[i].data_length = 0;
601 if (sign_sequence_id>0xfffffffe)
607 UINT32 tpm_hash(TSS2_SYS_CONTEXT *sysContext, TPMI_ALG_HASH hashAlg,
608 UINT16 size, BYTE *data, TPM2B_DIGEST *result) {
609 TPM2B_MAX_BUFFER dataSizedBuffer;
611 dataSizedBuffer.size = size;
612 memcpy(dataSizedBuffer.buffer, data, size);
613 return Tss2_Sys_Hash(sysContext, 0, &dataSizedBuffer, hashAlg,
614 TPM2_RH_NULL, result, 0, 0);
617 static TPM2_RC hash_sequence_ex(TSS2_SYS_CONTEXT *sysContext,
619 TPMI_ALG_HASH hashAlg, UINT32 numBuffers, TPM2B_MAX_BUFFER *bufferList,
620 TPM2B_DIGEST *result) {
623 TPMI_DH_OBJECT sequenceHandle;
624 TPM2B_MAX_BUFFER emptyBuffer;
625 TPMT_TK_HASHCHECK validation;
627 TPMS_AUTH_COMMAND cmdAuth;
628 TPMS_AUTH_COMMAND *cmdSessionArray[1] = { &cmdAuth };
629 TSS2L_SYS_AUTH_COMMAND cmdAuthArray = { .count = 1, .auths = {{
630 .sessionHandle = TPM2_RS_PW,
631 .sessionAttributes = 0,
632 .nonce = {.size = 0},
633 .hmac = {.size = 0}}}};
636 emptyBuffer.size = 0;
638 // Set result size to 0, in case any errors occur
641 // Init input sessions struct
642 cmdAuth.sessionHandle = TPM2_RS_PW;
643 cmdAuth.nonce.size = 0;
644 *((UINT8 *) ((void *) &cmdAuth.sessionAttributes)) = 0;
645 cmdAuth.hmac.size = 0;
647 rval = Tss2_Sys_HashSequenceStart(sysContext, 0, &nullAuth, hashAlg,
649 if (rval != TPM2_RC_SUCCESS) {
654 for (i = 0; i < numBuffers; i++) {
655 rval = Tss2_Sys_SequenceUpdate(sysContext, sequenceHandle,
656 &cmdAuthArray, &bufferList[i], 0);
658 if (rval != TPM2_RC_SUCCESS) {
663 rval = Tss2_Sys_SequenceComplete(sysContext, sequenceHandle,
664 &cmdAuthArray, (TPM2B_MAX_BUFFER *) &emptyBuffer,
665 TPM2_RH_PLATFORM, result, &validation, 0);
667 if (rval != TPM2_RC_SUCCESS) {
674 int tpm_hash_compute_data(TSS2_SYS_CONTEXT *sysContext, BYTE *buffer,
675 UINT16 length, TPMI_ALG_HASH halg, TPM2B_DIGEST *result) {
677 if (length <= TPM2_MAX_DIGEST_BUFFER) {
678 if (tpm_hash(sysContext, halg, length, buffer,
679 result) == TPM2_RC_SUCCESS){
680 printf("Single hash result size: %d\n", result->size);
687 UINT8 numBuffers = (length - 1) / TPM2_MAX_DIGEST_BUFFER + 1;
689 TPM2B_MAX_BUFFER *bufferList = (TPM2B_MAX_BUFFER *) calloc(numBuffers,
690 sizeof(TPM2B_MAX_BUFFER));
691 if (bufferList == NULL)
695 for (i = 0; i < (UINT32)(numBuffers - 1); i++) {
696 bufferList[i].size = TPM2_MAX_DIGEST_BUFFER;
697 memcpy(bufferList[i].buffer, buffer + i * TPM2_MAX_DIGEST_BUFFER,
698 TPM2_MAX_DIGEST_BUFFER);
700 bufferList[i].size = length - i * TPM2_MAX_DIGEST_BUFFER;
701 memcpy(bufferList[i].buffer, buffer + i * TPM2_MAX_DIGEST_BUFFER,
704 TPM2_RC rval = hash_sequence_ex(sysContext, halg, numBuffers, bufferList, result);
706 printf("Sequence hash result size: %d\n", result->size);
707 return rval == TPM2_RC_SUCCESS ? 0 : -3;
711 static bool get_key_type(TSS2_SYS_CONTEXT *sysContext, TPMI_DH_OBJECT objectHandle,
712 TPMI_ALG_PUBLIC *type) {
714 TSS2L_SYS_AUTH_RESPONSE sessions_data_out;
716 TPM2B_PUBLIC out_public = {
720 TPM2B_NAME name = TPM2B_TYPE_INIT(TPM2B_NAME, name);
722 TPM2B_NAME qaulified_name = TPM2B_TYPE_INIT(TPM2B_NAME, name);
724 TPM2_RC rval = Tss2_Sys_ReadPublic(sysContext, objectHandle, 0, &out_public, &name,
725 &qaulified_name, &sessions_data_out);
726 if (rval != TPM2_RC_SUCCESS) {
727 printf("Sys_ReadPublic failed, error code: 0x%x", rval);
730 *type = out_public.publicArea.type;
734 static bool set_scheme(TSS2_SYS_CONTEXT *sysContext, TPMI_DH_OBJECT keyHandle,
735 TPMI_ALG_HASH halg, TPMT_SIG_SCHEME *inScheme) {
738 bool result = get_key_type(sysContext, keyHandle, &type);
745 inScheme->scheme = TPM2_ALG_RSASSA;
746 inScheme->details.rsassa.hashAlg = halg;
748 case TPM2_ALG_KEYEDHASH :
749 inScheme->scheme = TPM2_ALG_HMAC;
750 inScheme->details.hmac.hashAlg = halg;
753 inScheme->scheme = TPM2_ALG_ECDSA;
754 inScheme->details.ecdsa.hashAlg = halg;
756 case TPM2_ALG_SYMCIPHER :
758 printf("Unknown key type, got: 0x%x", type);
764 static bool sign_and_save(tpm_sign_ctx *ctx, TPMT_SIGNATURE *sig) {
765 TPM2B_DIGEST digest = TPM2B_TYPE_INIT(TPM2B_DIGEST, buffer);
767 TPMT_SIG_SCHEME in_scheme;
768 TSS2L_SYS_AUTH_RESPONSE sessions_data_out;
770 TSS2L_SYS_AUTH_COMMAND sessions_data = { .count = 1, .auths = {{
771 .sessionHandle = TPM2_RS_PW,
772 .sessionAttributes = 0,
773 .nonce = {.size = 0},
774 .hmac = {.size = 0}}}};
776 int rc = tpm_hash_compute_data(ctx->sysContext, ctx->msg, ctx->length, ctx->halg, &digest);
778 printf("Compute message hash failed!");
782 printf("Compute message hash digest size : %d \n", digest.size);
784 bool result = set_scheme(ctx->sysContext, ctx->keyHandle, ctx->halg, &in_scheme);
789 TPM2_RC rval = Tss2_Sys_Sign(ctx->sysContext, ctx->keyHandle,
790 &sessions_data, &digest, &in_scheme,
791 &ctx->validation, sig,
794 if (rval != TPM2_RC_SUCCESS) {
795 printf("Sys_Sign failed, error code: 0x%x", rval);
801 int tpm2_plugin_rsa_sign(
803 unsigned long mechanism,
806 void *plugin_data_ref,
811 common_opts_t opts = COMMON_OPTS_INITIALIZER;
812 TPMT_SIGNATURE signature;
813 TSS2_TCTI_CONTEXT *tcti_ctx;
814 tcti_ctx = tcti_init_from_options(&opts);
815 if (tcti_ctx == NULL)
818 TSS2_SYS_CONTEXT *sysContext = NULL;
820 sysContext = sapi_ctx_init(tcti_ctx);
829 .sessionData = { 0 },
833 .sysContext = sysContext
836 printf("rsa_sign API mechanism is %lx \n", mechanism);
837 ctx.sessionData.sessionHandle = TPM2_RS_PW;
838 ctx.validation.tag = TPM2_ST_HASHCHECK;
839 ctx.validation.hierarchy = TPM2_RH_NULL;
841 ctx.halg = TPM2_ALG_SHA256;
843 printf("mechanism not supported! \n");
844 ctx.keyHandle = *(TPMI_DH_OBJECT *)keyHandle;
846 rval = Tss2_Sys_ContextLoad(ctx.sysContext, &loaded_key_context, &ctx.keyHandle);
847 if (rval != TPM2_RC_SUCCESS) {
848 printf("ContextLoad Error in RSA Sign API. TPM Error:0x%x", rval);
851 ctx.length = msg_len;
854 if (!sign_and_save(&ctx, &signature)){
855 printf("RSA sign failed\n");
859 *sig_len = (int)signature.signature.rsassa.sig.size;
860 printf("signature length: %d \n", *sig_len);
861 memcpy(sig, signature.signature.rsassa.sig.buffer, *sig_len);
862 printf("signature buffer size: %ld \n", sizeof(signature.signature.rsassa.sig.buffer));
863 printf("RSA sign API successful in TPM plugin ! \n");
866 sapi_teardown_full(sysContext);
872 int tpm2_plugin_rsa_sign_update(
874 unsigned long mechanism,
877 void *plugin_data_ref
881 unsigned long hSession = (unsigned long)plugin_data_ref;
882 for (i = 0; i < MAX_SESSIONS; i++){
883 if (data_signupdate_session[i].session_handle == hSession){
884 n = data_signupdate_session[i].data_length;
885 for (j =0; j < msg_len; j++ )
886 data_signupdate_session[i].data_signupdate[n + j] = msg[j];
887 data_signupdate_session[i].data_length += msg_len;
894 int tpm2_plugin_rsa_sign_final(
896 unsigned long mechanism,
897 void *plugin_data_ref,
898 unsigned char *outsig,
903 unsigned long hSession = (unsigned long)plugin_data_ref;
906 for (i = 0; i < MAX_SESSIONS; i++){
907 if (data_signupdate_session[i].session_handle == hSession){
908 msg = data_signupdate_session[i].data_signupdate;
909 msg_len = data_signupdate_session[i].data_length;
910 tpm2_plugin_rsa_sign(keyHandle, mechanism, msg, msg_len, plugin_data_ref, outsig, outsiglen);
911 tpm2_plugin_rsa_sign_cleanup(keyHandle, mechanism, plugin_data_ref);