Modify TPM2 Plugin codes
[aaf/sshsm.git] / TPM2-Plugin / lib / tpm2_plugin_api.c
1 /* Copyright 2018 Intel Corporation, Inc
2 *
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
6 *
7 *       http://www.apache.org/licenses/LICENSE-2.0
8 *
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.
14 */
15
16 #include <sapi/tpm20.h>
17 #include <stdbool.h>
18 #include <errno.h>
19 #include <unistd.h>
20 #include "tpm2_plugin_api.h"
21 #ifdef HAVE_TCTI_DEV
22 #include <tcti/tcti_device.h>
23 #endif
24 #ifdef HAVE_TCTI_SOCK
25 #include <tcti/tcti_socket.h>
26 #endif
27 #ifdef HAVE_TCTI_TABRMD
28 #include <tcti/tcti-tabrmd.h>
29 #endif
30 bool output_enabled = true;
31 bool hexPasswd = false;
32 TPM_HANDLE handle2048rsa;
33 const char *tcti_path="libtss2-tcti-device.so";
34
35 static void tcti_teardown(TSS2_TCTI_CONTEXT *tcti_context)
36 {
37     if (tcti_context == NULL)
38         return;
39     tss2_tcti_finalize (tcti_context);
40     free (tcti_context);
41 }
42
43 static void sapi_teardown(TSS2_SYS_CONTEXT *sapi_context)
44 {
45     if (sapi_context == NULL)
46         return;
47     Tss2_Sys_Finalize (sapi_context);
48     free (sapi_context);
49 }
50
51 static void sapi_teardown_full (TSS2_SYS_CONTEXT *sapi_context)
52 {
53     TSS2_TCTI_CONTEXT *tcti_context = NULL;
54     TSS2_RC rc;
55
56     rc = Tss2_Sys_GetTctiContext (sapi_context, &tcti_context);
57     if (rc != TSS2_RC_SUCCESS)
58         return;
59     sapi_teardown (sapi_context);
60     tcti_teardown (tcti_context);
61 }
62
63 int tpm2_plugin_init()
64 {
65     printf("Init API done for TPM plugin ! \n");
66     return 0;
67 }
68
69 int tpm2_plugin_uninit()
70 {
71     printf("UnInit API done for TPM plugin ! \n");
72     return 0;
73 }
74
75 TPM_HANDLE srk_handle;
76 int tpm2_plugin_activate(SSHSM_HW_PLUGIN_ACTIVATE_LOAD_IN_INFO_t *activate_in_info)
77 {
78     /*
79     */
80     char *handle;
81     printf("number of buffers %d ! \n", activate_in_info->num_buffers);
82     if (activate_in_info->num_buffers!=1){
83         printf("activate failed ! \n");
84         return 1;
85     }
86     printf("number of buffers %d ! \n", activate_in_info->num_buffers);
87     handle = malloc(activate_in_info->buffer_info[0]->length_of_buffer);
88     memcpy(handle, activate_in_info->buffer_info[0]->buffer, activate_in_info->buffer_info[0]->length_of_buffer);
89     srk_handle = strtol(handle, NULL, 16);
90     printf("Activate API done for TPM plugin ! \n");
91     return 0;
92 }
93
94 TPMI_DH_OBJECT handle_load;
95
96 #ifdef HAVE_TCTI_DEV
97 TSS2_TCTI_CONTEXT*
98 tcti_device_init (char const *device_file)
99 {
100     TCTI_DEVICE_CONF conf = {
101         .device_path = device_file,
102         .logCallback = NULL,
103         .logData     = NULL,
104     };
105     size_t size;
106     TSS2_RC rc;
107     TSS2_TCTI_CONTEXT *tcti_ctx;
108
109     rc = InitDeviceTcti (NULL, &size, 0);
110     if (rc != TSS2_RC_SUCCESS) {
111         fprintf (stderr,
112                  "Failed to get allocation size for device tcti context: "
113                  "0x%x\n", rc);
114         return NULL;
115     }
116     tcti_ctx = (TSS2_TCTI_CONTEXT*)calloc (1, size);
117     if (tcti_ctx == NULL) {
118         fprintf (stderr,
119                  "Allocation for device TCTI context failed: %s\n",
120                  strerror (errno));
121         return NULL;
122     }
123     rc = InitDeviceTcti (tcti_ctx, &size, &conf);
124     if (rc != TSS2_RC_SUCCESS) {
125         fprintf (stderr,
126                  "Failed to initialize device TCTI context: 0x%x\n",
127                  rc);
128         free (tcti_ctx);
129         return NULL;
130     }
131     return tcti_ctx;
132 }
133 #endif
134
135
136 #ifdef HAVE_TCTI_SOCK
137 TSS2_TCTI_CONTEXT* tcti_socket_init (char const *address, uint16_t port)
138 {
139     TCTI_SOCKET_CONF conf = {
140         .hostname          = address,
141         .port              = port,
142         .logCallback       = NULL,
143         .logBufferCallback = NULL,
144         .logData           = NULL,
145     };
146     size_t size;
147     TSS2_RC rc;
148     TSS2_TCTI_CONTEXT *tcti_ctx;
149
150     rc = InitSocketTcti (NULL, &size, &conf, 0);
151     if (rc != TSS2_RC_SUCCESS) {
152         fprintf (stderr, "Faled to get allocation size for tcti context: "
153                  "0x%x\n", rc);
154         return NULL;
155     }
156     tcti_ctx = (TSS2_TCTI_CONTEXT*)calloc (1, size);
157     if (tcti_ctx == NULL) {
158         fprintf (stderr, "Allocation for tcti context failed: %s\n",
159                  strerror (errno));
160         return NULL;
161     }
162     rc = InitSocketTcti (tcti_ctx, &size, &conf, 0);
163     if (rc != TSS2_RC_SUCCESS) {
164         fprintf (stderr, "Failed to initialize tcti context: 0x%x\n", rc);
165         free (tcti_ctx);
166         return NULL;
167     }
168     return tcti_ctx;
169 }
170 #endif
171 #ifdef HAVE_TCTI_TABRMD
172 TSS2_TCTI_CONTEXT *tcti_tabrmd_init (void)
173 {
174     TSS2_TCTI_CONTEXT *tcti_ctx;
175     TSS2_RC rc;
176     size_t size;
177
178     rc = tss2_tcti_tabrmd_init(NULL, &size);
179     if (rc != TSS2_RC_SUCCESS) {
180         printf("Failed to get size for TABRMD TCTI context: 0x%x", rc);
181         return NULL;
182     }
183     tcti_ctx = (TSS2_TCTI_CONTEXT*)calloc (1, size);
184     if (tcti_ctx == NULL) {
185         printf("Allocation for TABRMD TCTI context failed: %s", strerror (errno));
186         return NULL;
187     }
188     rc = tss2_tcti_tabrmd_init (tcti_ctx, &size);
189     if (rc != TSS2_RC_SUCCESS) {
190         printf("Failed to initialize TABRMD TCTI context: 0x%x", rc);
191         free(tcti_ctx);
192         return NULL;
193     }
194     return tcti_ctx;
195 }
196 #endif
197 TSS2_TCTI_CONTEXT *tcti_init_from_options(common_opts_t *options)
198 {
199     switch (options->tcti_type) {
200 #ifdef HAVE_TCTI_DEV
201     case DEVICE_TCTI:
202         return tcti_device_init (options->device_file);
203 #endif
204 #ifdef HAVE_TCTI_SOCK
205     case SOCKET_TCTI:
206         return tcti_socket_init (options->socket_address,
207                                  options->socket_port);
208 #endif
209 #ifdef HAVE_TCTI_TABRMD
210     case TABRMD_TCTI:
211         return tcti_tabrmd_init ();
212 #endif
213     default:
214         return NULL;
215     }
216 }
217
218 static TSS2_SYS_CONTEXT *sapi_ctx_init (TSS2_TCTI_CONTEXT *tcti_ctx)
219 {
220     TSS2_SYS_CONTEXT *sapi_ctx;
221     TSS2_RC rc;
222     size_t size;
223     TSS2_ABI_VERSION abi_version = {
224         .tssCreator = TSSWG_INTEROP,
225         .tssFamily  = TSS_SAPI_FIRST_FAMILY,
226         .tssLevel   = TSS_SAPI_FIRST_LEVEL,
227         .tssVersion = TSS_SAPI_FIRST_VERSION,
228     };
229
230     size = Tss2_Sys_GetContextSize (0);
231     sapi_ctx = (TSS2_SYS_CONTEXT*)calloc (1, size);
232     if (sapi_ctx == NULL) {
233         fprintf (stderr,
234                  "Failed to allocate 0x%zx bytes for the SAPI context\n",
235                  size);
236         return NULL;
237     }
238     rc = Tss2_Sys_Initialize (sapi_ctx, size, tcti_ctx, &abi_version);
239     if (rc != TSS2_RC_SUCCESS) {
240         fprintf (stderr, "Failed to initialize SAPI context: 0x%x\n", rc);
241         free (sapi_ctx);
242         return NULL;
243     }
244     return sapi_ctx;
245 }
246
247 #define BUFFER_SIZE(type, field) (sizeof((((type *)NULL)->t.field)))
248 #define TPM2B_TYPE_INIT(type, field) { .t = { .size = BUFFER_SIZE(type, field), }, }
249 TPMS_AUTH_COMMAND sessionData;
250 int hex2ByteStructure(const char *inStr, UINT16 *byteLength, BYTE *byteBuffer)
251 {
252     int strLength;//if the inStr likes "1a2b...", no prefix "0x"
253     int i = 0;
254     if(inStr == NULL || byteLength == NULL || byteBuffer == NULL)
255         return -1;
256     strLength = strlen(inStr);
257     if(strLength%2)
258         return -2;
259     for(i = 0; i < strLength; i++)
260     {
261         if(!isxdigit(inStr[i]))
262             return -3;
263     }
264
265     if(*byteLength < strLength/2)
266         return -4;
267
268     *byteLength = strLength/2;
269
270     for(i = 0; i < *byteLength; i++)
271     {
272         char tmpStr[4] = {0};
273         tmpStr[0] = inStr[i*2];
274         tmpStr[1] = inStr[i*2+1];
275         byteBuffer[i] = strtol(tmpStr, NULL, 16);
276     }
277     return 0;
278 }
279 int load_key(TSS2_SYS_CONTEXT *sapi_context,
280              TPMI_DH_OBJECT    parentHandle,
281              TPM2B_PUBLIC     *inPublic,
282              TPM2B_PRIVATE    *inPrivate,
283              int               P_flag)
284 {
285     UINT32 rval;
286     TPMS_AUTH_RESPONSE sessionDataOut;
287     TSS2_SYS_CMD_AUTHS sessionsData;
288     TSS2_SYS_RSP_AUTHS sessionsDataOut;
289     TPMS_AUTH_COMMAND *sessionDataArray[1];
290     TPMS_AUTH_RESPONSE *sessionDataOutArray[1];
291
292     TPM2B_NAME nameExt = TPM2B_TYPE_INIT(TPM2B_NAME, name);
293
294     sessionDataArray[0] = &sessionData;
295     sessionDataOutArray[0] = &sessionDataOut;
296
297     sessionsDataOut.rspAuths = &sessionDataOutArray[0];
298     sessionsData.cmdAuths = &sessionDataArray[0];
299
300     sessionsDataOut.rspAuthsCount = 1;
301     sessionsData.cmdAuthsCount = 1;
302
303     sessionData.sessionHandle = TPM_RS_PW;
304     sessionData.nonce.t.size = 0;
305
306     if(P_flag == 0)
307         sessionData.hmac.t.size = 0;
308
309     *((UINT8 *)((void *)&sessionData.sessionAttributes)) = 0;
310     if (sessionData.hmac.t.size > 0 && hexPasswd)
311     {
312         sessionData.hmac.t.size = sizeof(sessionData.hmac) - 2;
313         if (hex2ByteStructure((char *)sessionData.hmac.t.buffer,
314                               &sessionData.hmac.t.size,
315                               sessionData.hmac.t.buffer) != 0)
316         {
317             printf( "Failed to convert Hex format password for parent Passwd.\n");
318             return -1;
319         }
320     }
321
322     rval = Tss2_Sys_Load (sapi_context,
323                           parentHandle,
324                           &sessionsData,
325                           inPrivate,
326                           inPublic,
327                           &handle2048rsa,
328                           &nameExt,
329                           &sessionsDataOut);
330     if(rval != TPM_RC_SUCCESS)
331     {
332         printf("\nLoad Object Failed ! ErrorCode: 0x%0x\n\n",rval);
333         return -1;
334     }
335     printf("\nLoad succ.\nLoadedHandle: 0x%08x\n\n",handle2048rsa);
336
337     return 0;
338 }
339
340 TPMS_CONTEXT loaded_key_context;
341
342 int load_key_execute(SSHSM_HW_PLUGIN_ACTIVATE_LOAD_IN_INFO_t *loadkey_in_info,
343                      void **keyHandle, TSS2_SYS_CONTEXT *sapi_context)
344 {
345
346     TPMI_DH_OBJECT parentHandle;
347     TPM2B_PUBLIC  inPublic;
348     TPM2B_PRIVATE inPrivate;
349     UINT16 size;
350     int returnVal = 0;
351
352     memset(&inPublic,0,sizeof(TPM2B_PUBLIC));
353     memset(&inPrivate,0,sizeof(TPM2B_SENSITIVE));
354
355     setbuf(stdout, NULL);
356     setvbuf (stdout, NULL, _IONBF, BUFSIZ);
357
358     //parentHandle = 0x81000011;
359     parentHandle = srk_handle;
360
361     if (loadkey_in_info->num_buffers != 2)
362         return -1;
363     memcpy(&inPublic, loadkey_in_info->buffer_info[0]->buffer,
364            loadkey_in_info->buffer_info[0]->length_of_buffer);
365     memcpy(&inPrivate, loadkey_in_info->buffer_info[1]->buffer,
366            loadkey_in_info->buffer_info[1]->length_of_buffer);
367
368         printf("we are here now\n");
369     returnVal = load_key (sapi_context,
370                           parentHandle,
371                           &inPublic,
372                           &inPrivate,
373                           0);
374
375     TPM_RC rval = Tss2_Sys_ContextSave(sapi_context, handle2048rsa, &loaded_key_context);
376     if (rval != TPM_RC_SUCCESS) {
377         printf("Tss2_Sys_ContextSave: Saving handle 0x%x context failed. TPM Error:0x%x", handle2048rsa, rval);
378         return -1;
379     }
380     *keyHandle = &handle2048rsa;
381     return 0;
382 }
383
384 int tpm2_plugin_load_key(SSHSM_HW_PLUGIN_ACTIVATE_LOAD_IN_INFO_t *loadkey_in_info,
385                          void **keyHandle)
386 {
387     int ret = 1;
388     common_opts_t opts = COMMON_OPTS_INITIALIZER;
389     TSS2_TCTI_CONTEXT *tcti_ctx;
390     tcti_ctx = tcti_init_from_options(&opts);
391     if (tcti_ctx == NULL)
392         return -1;
393
394     TSS2_SYS_CONTEXT *sapi_context = NULL;
395     if (tcti_ctx) {
396         sapi_context = sapi_ctx_init(tcti_ctx);
397         if (!sapi_context) {
398             free(tcti_ctx);
399             return -1;
400         }
401     }
402
403     ret = load_key_execute(loadkey_in_info, keyHandle, sapi_context);
404     if (ret !=0)
405         printf("Load key API failed in TPM plugin ! \n");
406
407     sapi_teardown_full(sapi_context);
408
409     printf("Load key API successful in TPM plugin ! \n");
410     return 0;
411
412 }
413
414 typedef struct tpm_sign_ctx tpm_sign_ctx;
415 struct tpm_sign_ctx {
416     TPMT_TK_HASHCHECK validation;
417     TPMS_AUTH_COMMAND sessionData;
418     TPMI_DH_OBJECT keyHandle;
419     TPMI_ALG_HASH halg;
420     char outFilePath[PATH_MAX];
421     BYTE *msg;
422     UINT16 length;
423     TSS2_SYS_CONTEXT *sapi_context;
424 };
425
426 int tpm2_plugin_rsa_sign_init(
427         void *keyHandle,
428         unsigned long mechanism,
429         void *param,
430         int len)
431 {
432     printf("rsa_sign_init API mechanism is %lx \n", mechanism);
433     printf("rsa_sign_init API done for tpm2_plugin... \n");
434     return 0;
435 }
436
437 UINT32 tpm_hash(TSS2_SYS_CONTEXT *sapi_context, TPMI_ALG_HASH hashAlg,
438         UINT16 size, BYTE *data, TPM2B_DIGEST *result) {
439     TPM2B_MAX_BUFFER dataSizedBuffer;
440
441     dataSizedBuffer.t.size = size;
442     memcpy(dataSizedBuffer.t.buffer, data, size);
443     return Tss2_Sys_Hash(sapi_context, 0, &dataSizedBuffer, hashAlg,
444             TPM_RH_NULL, result, 0, 0);
445 }
446
447 static TPM_RC hash_sequence_ex(TSS2_SYS_CONTEXT *sapi_context,
448
449     TPMI_ALG_HASH hashAlg, UINT32 numBuffers, TPM2B_MAX_BUFFER *bufferList,
450     TPM2B_DIGEST *result) {
451     TPM_RC rval;
452     TPM2B_AUTH nullAuth;
453     TPMI_DH_OBJECT sequenceHandle;
454     TPM2B emptyBuffer;
455     TPMT_TK_HASHCHECK validation;
456
457     TPMS_AUTH_COMMAND cmdAuth;
458     TPMS_AUTH_COMMAND *cmdSessionArray[1] = { &cmdAuth };
459     TSS2_SYS_CMD_AUTHS cmdAuthArray = { 1, &cmdSessionArray[0] };
460
461     nullAuth.t.size = 0;
462     emptyBuffer.size = 0;
463
464     // Set result size to 0, in case any errors occur
465     result->b.size = 0;
466
467     // Init input sessions struct
468     cmdAuth.sessionHandle = TPM_RS_PW;
469     cmdAuth.nonce.t.size = 0;
470     *((UINT8 *) ((void *) &cmdAuth.sessionAttributes)) = 0;
471     cmdAuth.hmac.t.size = 0;
472
473     rval = Tss2_Sys_HashSequenceStart(sapi_context, 0, &nullAuth, hashAlg,
474             &sequenceHandle, 0);
475     if (rval != TPM_RC_SUCCESS) {
476         return rval;
477     }
478
479     unsigned i;
480     for (i = 0; i < numBuffers; i++) {
481         rval = Tss2_Sys_SequenceUpdate(sapi_context, sequenceHandle,
482                 &cmdAuthArray, &bufferList[i], 0);
483
484         if (rval != TPM_RC_SUCCESS) {
485             return rval;
486         }
487     }
488
489     rval = Tss2_Sys_SequenceComplete(sapi_context, sequenceHandle,
490             &cmdAuthArray, (TPM2B_MAX_BUFFER *) &emptyBuffer,
491             TPM_RH_PLATFORM, result, &validation, 0);
492
493     if (rval != TPM_RC_SUCCESS) {
494         return rval;
495     }
496
497     return rval;
498 }
499
500 int tpm_hash_compute_data(TSS2_SYS_CONTEXT *sapi_context, BYTE *buffer,
501         UINT16 length, TPMI_ALG_HASH halg, TPM2B_DIGEST *result) {
502
503     if (length <= MAX_DIGEST_BUFFER) {
504         if (tpm_hash(sapi_context, halg, length, buffer,
505                 result) == TPM_RC_SUCCESS)
506             return 0;
507         else
508             return -1;
509     }
510
511     UINT8 numBuffers = (length - 1) / MAX_DIGEST_BUFFER + 1;
512
513     TPM2B_MAX_BUFFER *bufferList = (TPM2B_MAX_BUFFER *) calloc(numBuffers,
514             sizeof(TPM2B_MAX_BUFFER));
515     if (bufferList == NULL)
516         return -2;
517
518     UINT32 i;
519     for (i = 0; i < (UINT32)(numBuffers - 1); i++) {
520         bufferList[i].t.size = MAX_DIGEST_BUFFER;
521         memcpy(bufferList[i].t.buffer, buffer + i * MAX_DIGEST_BUFFER,
522                 MAX_DIGEST_BUFFER);
523     }
524     bufferList[i].t.size = length - i * MAX_DIGEST_BUFFER;
525     memcpy(bufferList[i].t.buffer, buffer + i * MAX_DIGEST_BUFFER,
526             bufferList[i].t.size);
527
528     TPM_RC rval = hash_sequence_ex(sapi_context, halg, numBuffers, bufferList, result);
529     free(bufferList);
530     return rval == TPM_RC_SUCCESS ? 0 : -3;
531 }
532
533
534 static bool get_key_type(TSS2_SYS_CONTEXT *sapi_context, TPMI_DH_OBJECT objectHandle,
535         TPMI_ALG_PUBLIC *type) {
536
537     TPMS_AUTH_RESPONSE session_data_out;
538
539     TPMS_AUTH_RESPONSE *session_data_out_array[1] = {
540             &session_data_out
541     };
542
543     TSS2_SYS_RSP_AUTHS sessions_data_out = {
544             1,
545             &session_data_out_array[0]
546     };
547
548     TPM2B_PUBLIC out_public = {
549             { 0, }
550     };
551
552     TPM2B_NAME name = TPM2B_TYPE_INIT(TPM2B_NAME, name);
553
554     TPM2B_NAME qaulified_name = TPM2B_TYPE_INIT(TPM2B_NAME, name);
555
556     TPM_RC rval = Tss2_Sys_ReadPublic(sapi_context, objectHandle, 0, &out_public, &name,
557             &qaulified_name, &sessions_data_out);
558     if (rval != TPM_RC_SUCCESS) {
559         printf("Sys_ReadPublic failed, error code: 0x%x", rval);
560         return false;
561     }
562     *type = out_public.t.publicArea.type;
563     return true;
564 }
565
566 static bool set_scheme(TSS2_SYS_CONTEXT *sapi_context, TPMI_DH_OBJECT keyHandle,
567         TPMI_ALG_HASH halg, TPMT_SIG_SCHEME *inScheme) {
568
569     TPM_ALG_ID type;
570     bool result = get_key_type(sapi_context, keyHandle, &type);
571     if (!result) {
572         return false;
573     }
574
575     switch (type) {
576     case TPM_ALG_RSA :
577         inScheme->scheme = TPM_ALG_RSASSA;
578         inScheme->details.rsassa.hashAlg = halg;
579         break;
580     case TPM_ALG_KEYEDHASH :
581         inScheme->scheme = TPM_ALG_HMAC;
582         inScheme->details.hmac.hashAlg = halg;
583         break;
584     case TPM_ALG_ECC :
585         inScheme->scheme = TPM_ALG_ECDSA;
586         inScheme->details.ecdsa.hashAlg = halg;
587         break;
588     case TPM_ALG_SYMCIPHER :
589     default:
590         printf("Unknown key type, got: 0x%x", type);
591         return false;
592     }
593
594     return true;
595 }
596 static bool sign_and_save(tpm_sign_ctx *ctx,  unsigned char *sig, int *sig_len) {
597     TPM2B_DIGEST digest = TPM2B_TYPE_INIT(TPM2B_DIGEST, buffer);
598
599     TPMT_SIG_SCHEME in_scheme;
600     TPMT_SIGNATURE signature;
601     int signature_len;
602     TSS2_SYS_CMD_AUTHS sessions_data;
603     TPMS_AUTH_RESPONSE session_data_out;
604     TSS2_SYS_RSP_AUTHS sessions_data_out;
605     TPMS_AUTH_COMMAND *session_data_array[1];
606     TPMS_AUTH_RESPONSE *session_data_out_array[1];
607
608     session_data_array[0] = &ctx->sessionData;
609     sessions_data.cmdAuths = &session_data_array[0];
610     session_data_out_array[0] = &session_data_out;
611     sessions_data_out.rspAuths = &session_data_out_array[0];
612     sessions_data_out.rspAuthsCount = 1;
613     sessions_data.cmdAuthsCount = 1;
614
615     int rc = tpm_hash_compute_data(ctx->sapi_context, ctx->msg, ctx->length, ctx->halg, &digest);
616     if (rc) {
617         printf("Compute message hash failed!");
618         return false;
619     }
620
621     bool result = set_scheme(ctx->sapi_context, ctx->keyHandle, ctx->halg, &in_scheme);
622     if (!result) {
623         return false;
624     }
625
626     TPM_RC rval = Tss2_Sys_Sign(ctx->sapi_context, ctx->keyHandle,
627                                 &sessions_data, &digest, &in_scheme,
628                                 &ctx->validation, &signature,
629                                 &sessions_data_out);
630
631     if (rval != TPM_RC_SUCCESS) {
632         printf("Sys_Sign failed, error code: 0x%x", rval);
633         return false;
634     }
635     signature_len = sizeof(signature);
636     sig_len = &signature_len;
637     sig = (unsigned char *)&signature;
638
639     return true;
640 }
641
642 int tpm2_plugin_rsa_sign(
643         void  *keyHandle,
644         unsigned long mechanism,
645         unsigned char *msg,
646         int msg_len,
647         unsigned char *sig,
648         int *sig_len)
649 {
650     TPM_RC rval;
651     common_opts_t opts = COMMON_OPTS_INITIALIZER;
652     TSS2_TCTI_CONTEXT *tcti_ctx;
653     tcti_ctx = tcti_init_from_options(&opts);
654     if (tcti_ctx == NULL)
655         return -1;
656
657     TSS2_SYS_CONTEXT *sapi_context = NULL;
658     if (tcti_ctx) {
659        sapi_context = sapi_ctx_init(tcti_ctx);
660        if (!sapi_context) {
661            free(tcti_ctx);
662            return -1;
663        }
664     }
665
666     tpm_sign_ctx ctx = {
667             .msg = NULL,
668             .sessionData = { 0 },
669             .halg = 0,
670             .keyHandle = 0,
671             .validation = { 0 },
672             .sapi_context = sapi_context
673     };
674     
675     printf("rsa_sign API mechanism is %lx \n", mechanism);
676     ctx.sessionData.sessionHandle = TPM_RS_PW;
677     ctx.validation.tag = TPM_ST_HASHCHECK;
678     ctx.validation.hierarchy = TPM_RH_NULL;
679     ctx.halg = TPM_ALG_SHA256;
680     ctx.keyHandle = *(TPMI_DH_OBJECT *)keyHandle;
681
682     rval = Tss2_Sys_ContextLoad(ctx.sapi_context, &loaded_key_context, &ctx.keyHandle);
683     if (rval != TPM_RC_SUCCESS) {
684         printf("ContextLoad Error in RSA Sign API. TPM Error:0x%x", rval);
685         goto out;
686     }
687     ctx.length = msg_len;
688     ctx.msg = msg;
689
690     if (!sign_and_save(&ctx, sig, sig_len)){
691         printf("RSA sign failed\n");
692         goto out;
693     }
694
695     printf("RSA sign API successful in TPM plugin ! \n");
696
697 out:
698     sapi_teardown_full(sapi_context);
699
700     return 0;
701
702 }
703
704