OSDN Git Service

e80742dcd530a5914b17bc69ba6de70748fa3315
[openpts/openpts.git] / src / tss.c
1 /*
2  * This file is part of the OpenPTS project.
3  *
4  * The Initial Developer of the Original Code is International
5  * Business Machines Corporation. Portions created by IBM
6  * Corporation are Copyright (C) 2007, 2010 International Business
7  * Machines Corporation. All Rights Reserved.
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the Common Public License as published by
11  * IBM Corporation; either version 1 of the License, or (at your option)
12  * any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * Common Public License for more details.
18  *
19  * You should have received a copy of the Common Public License
20  * along with this program; if not, a copy can be viewed at
21  * http://www.opensource.org/licenses/cpl1.0.php.
22  */
23
24 /**
25  * \file src/tss.c
26  * \brief TSS wrapper
27  * @author Seiji Munetoh <munetoh@users.sourceforge.jp>
28  * @date 2010-08-18
29  * refactoring 2011-02-15 SM
30  * cleanup 2011-10-07 SM
31  *
32  * Create Sign Key
33  * Create AIK
34  * Quote
35  *
36  * UUID
37  *   uuit_t    uuid/uuid.h       typedef unsigned char uuid_t[16];
38  *   TSS_UUID  tss/tss_structs.h 16-bytes struct
39  *
40  * return is TSS_XXX
41  *
42  */
43
44 #include <stdio.h>
45 #include <stdlib.h>
46 #include <string.h>
47
48 #ifndef CONFIG_NO_TSS
49 #ifdef AIX
50 #include <trousers/tss.h>
51 #else
52 #include <platform.h>
53 #include <tss_defines.h>
54 #include <tss_typedef.h>
55 #include <tss_structs.h>
56 #include <tss_error.h>
57 #include <tspi.h>
58 #endif
59 #endif
60
61 #include <openssl/sha.h>
62 #include <openssl/rsa.h>
63 #include <openssl/bn.h>
64 #include <openssl/objects.h>
65 #include <openssl/err.h>
66
67 #include <openpts.h>
68
69 // Local TCSD
70 #define SERVER    NULL
71
72 #define TSS_PS_TYPE_BLOB   (0)   // not defined by TSS
73
74 // TODO common secret
75 #define TPMSIGKEY_SECRET "password"
76
77 #ifdef CONFIG_NO_TSS
78 /* ONLY for verifier side */
79 int printTssKeyList(int ps_type) {
80     /* dummy */
81     return TSS_SUCCESS;
82 }
83
84 int createTssSignKey(PTS_UUID *uuid, int ps_type, char *filename, int force, int srk_password_mode) {
85     /* dummy */
86     return TSS_SUCCESS;
87 }
88
89 int deleteTssKey(PTS_UUID *uuid, int ps_type) {
90     /* dummy */
91     return TSS_SUCCESS;
92 }
93
94 int getTpmVersion(TSS_VERSION *version) {
95     /* dummy */
96     return TSS_SUCCESS;
97 }
98
99 int createAIK() {
100     /* dummy */
101     TODO("createAIK - TBD\n");
102     return TSS_E_FAIL;
103 }
104
105 int getTssPubKey(
106     PTS_UUID *uuid,
107     int ps_type, int srk_password_mode,
108     int resetdalock, char *filename, int *pubkey_length, BYTE **pubkey) {
109     /* dummy */
110     return TSS_SUCCESS;
111 }
112
113 int quoteTss(
114         /* Key */
115         PTS_UUID *uuid,
116         int ps_type,
117         int srk_password_mode,
118         char *filename,
119         /* Nonce */
120         BYTE *nonce,
121         /* PCR selection */
122         OPENPTS_PCRS *pcrs,
123         /* Output */
124         TSS_VALIDATION *validationData) {
125     /* dummy */
126     return TSS_SUCCESS;
127 }
128
129 int quote2Tss(
130         /* Key */
131         PTS_UUID *uuid,
132         int ps_type,
133         int srk_password_mode,
134         char *filename,
135         /* Nonce */
136         BYTE *nonce,
137         /* PCR selection */
138         OPENPTS_PCRS *pcrs,
139         /* Output */
140         TSS_VALIDATION *validationData) {
141     /* dummy */
142     return TSS_SUCCESS;
143 }
144
145 int getRandom(BYTE *out, int size) {
146     int i;
147     unsigned int seed;
148
149     for (i = 0; i < size; i++) {
150         out[i] = rand_r(&seed);  // TODO use rand_r
151     }
152
153     return TSS_SUCCESS;
154 }
155
156 int extendEvent(TSS_PCR_EVENT* event) {
157     /* Skip */
158     return TSS_SUCCESS;
159 }
160
161 int readPcr(int pcr_index, BYTE *pcr) {
162     /* Skip */
163     return TSS_SUCCESS;
164 }
165
166 #else  // CONFIG_NO_TSS
167 /* TSS - Collector side */
168
169 BYTE null_srk_auth[1] = {0};  // ""
170 BYTE known_srk_auth[20] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
171                            0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
172
173 /**
174  * get TPM status 
175  */
176 int getTpmStatus(TSS_FLAG flag, TSS_BOOL *value, int tpm_password_mode) {
177     TSS_RESULT result;
178     TSS_HCONTEXT hContext;
179     TSS_HTPM hTPM;
180     TSS_HPOLICY hTPMPolicy;
181     UINT32 tpm_auth_mode = TSS_SECRET_MODE_PLAIN;
182     BYTE *tpm_auth;
183     int tpm_auth_len = 0;
184
185     /* Connect to TCSD */
186     result = Tspi_Context_Create(&hContext);
187     if (result != TSS_SUCCESS) {
188         ERROR("Tspi_Context_Create failed rc=0x%x\n",
189                result);
190         if (result == 0x3011) {
191             OUTPUT(NLS(MS_OPENPTS, OPENPTS_TPM_TSS_COMMS_FAILURE, "TSS communications failure. Is tcsd running?\n"));
192         }
193         goto close;
194     }
195
196     result = Tspi_Context_Connect(hContext, SERVER);
197     if (result != TSS_SUCCESS) {
198         ERROR("Tspi_Context_Connect failed rc=0x%x\n",
199                result);
200         goto close;
201     }
202
203     /* Get TPM handle */
204     result = Tspi_Context_GetTpmObject(hContext, &hTPM);
205     if (result != TSS_SUCCESS) {
206         ERROR("Tspi_Context_GetTpmObject failed rc=0x%x\n",
207                result);
208         goto close;
209     }
210
211     /* Get TPM policy */
212     result = Tspi_GetPolicyObject(hTPM, TSS_POLICY_USAGE, &hTPMPolicy);
213     if (result != TSS_SUCCESS) {
214         ERROR("Tspi_GetPolicyObject failed rc=0x%x\n",
215                result);
216         goto close;
217     }
218
219     /* Set TPM secret */
220     if (tpm_password_mode == 1) {
221         tpm_auth_mode = TSS_SECRET_MODE_SHA1;
222         tpm_auth = known_srk_auth;
223         tpm_auth_len = 20;
224     } else if (tpm_password_mode == 0) {
225         tpm_auth_mode = TSS_SECRET_MODE_PLAIN;
226         tpm_auth = null_srk_auth;
227         tpm_auth_len = 0;
228     } else {
229         ERROR("TPM secret\n");
230         result = PTS_INTERNAL_ERROR;  // TODO
231         goto close;
232     }
233     result = Tspi_Policy_SetSecret(
234                 hTPMPolicy,
235                 tpm_auth_mode,
236                 tpm_auth_len,
237                 tpm_auth);
238     if (result != TSS_SUCCESS) {
239         ERROR("Tspi_Policy_SetSecret failed rc=0x%x\n",
240                result);
241         goto close;
242     }
243
244
245     /* Set TPM status */
246     result = Tspi_TPM_GetStatus(
247                 hTPM,
248                 flag,
249                 value);
250     if (result != TSS_SUCCESS) {
251         ERROR("Tspi_TPM_GetStatus failed rc=0x%x\n",
252                result);
253         goto close;
254     }
255
256   close:
257     /* Close TSS/TPM */
258     Tspi_Context_Close(hContext);
259     return result;
260 }
261
262 /**
263  * reset TPM DA lock flag 
264  * to avoid 0x803 Error
265  * TODO resetTpmLock -> setTpmStatus
266  */
267 int setTpmStatus(TSS_FLAG flag, TSS_BOOL value, int tpm_password_mode) {
268     TSS_RESULT result;
269     TSS_HCONTEXT hContext;
270     TSS_HTPM hTPM;
271     TSS_HPOLICY hTPMPolicy;
272     UINT32 tpm_auth_mode = TSS_SECRET_MODE_PLAIN;
273     BYTE *tpm_auth;
274     int tpm_auth_len = 0;
275
276     /* Connect to TCSD */
277     result = Tspi_Context_Create(&hContext);
278     if (result != TSS_SUCCESS) {
279         ERROR("Tspi_Context_Create failed rc=0x%x\n",
280                result);
281         if (result == 0x3011) {
282             OUTPUT(NLS(MS_OPENPTS, OPENPTS_TPM_TSS_COMMS_FAILURE, "TSS communications failure. Is tcsd running?\n"));
283         }
284         goto close;
285     }
286
287     result = Tspi_Context_Connect(hContext, SERVER);
288     if (result != TSS_SUCCESS) {
289         ERROR("Tspi_Context_Connect failed rc=0x%x\n",
290                result);
291         goto close;
292     }
293
294     /* Get TPM handle */
295     result = Tspi_Context_GetTpmObject(hContext, &hTPM);
296     if (result != TSS_SUCCESS) {
297         ERROR("Tspi_Context_GetTpmObject failed rc=0x%x\n",
298                result);
299         goto close;
300     }
301
302     /* Get TPM policy */
303     result = Tspi_GetPolicyObject(hTPM, TSS_POLICY_USAGE, &hTPMPolicy);
304     if (result != TSS_SUCCESS) {
305         ERROR("Tspi_GetPolicyObject failed rc=0x%x\n",
306                result);
307         goto close;
308     }
309
310     /* Set TPM secret */
311     if (tpm_password_mode == 1) {
312         tpm_auth_mode = TSS_SECRET_MODE_SHA1;
313         tpm_auth = known_srk_auth;
314         tpm_auth_len = 20;
315     } else if (tpm_password_mode == 0) {
316         tpm_auth_mode = TSS_SECRET_MODE_PLAIN;
317         tpm_auth = null_srk_auth;
318         tpm_auth_len = 0;
319     } else {
320         ERROR("TPM secret\n");
321         result = PTS_INTERNAL_ERROR;  // TODO
322         goto close;
323     }
324     result = Tspi_Policy_SetSecret(
325                 hTPMPolicy,
326                 tpm_auth_mode,
327                 tpm_auth_len,
328                 tpm_auth);
329     if (result != TSS_SUCCESS) {
330         ERROR("Tspi_Policy_SetSecret failed rc=0x%x\n",
331                result);
332         goto close;
333     }
334
335
336     /* Set TPM status */
337     result = Tspi_TPM_SetStatus(
338                 hTPM,
339                 flag,  // TSS_TPMSTATUS_RESETLOCK,
340                 value);
341     if (result != TSS_SUCCESS) {
342         ERROR("Tspi_Policy_SetSecret failed rc=0x%x\n",
343                result);
344         goto close;
345     }
346
347   close:
348     /* Close TSS/TPM */
349     Tspi_Context_Close(hContext);
350     return result;
351 }
352
353
354 /**
355  * List Keys
356  */
357 int printTssKeyList(int ps_type) {
358     TSS_RESULT result = 0;
359     TSS_HCONTEXT hContext;
360     UINT32 ulKeyHierarchySize;
361     // BYTE *buf;
362     TSS_UUID SRK_UUID = TSS_UUID_SRK;
363     int i;
364     TSS_KM_KEYINFO *info = NULL;
365
366     /* Open TSS */
367     result = Tspi_Context_Create(&hContext);
368     if (result != TSS_SUCCESS) {
369         ERROR("Tspi_Context_Create failed rc=0x%x\n",
370                result);
371         goto close;
372     }
373
374     result = Tspi_Context_Connect(hContext, SERVER);
375     if (result != TSS_SUCCESS) {
376         ERROR("Tspi_Context_Connect failed rc=0x%x\n",
377                result);
378         goto close;
379     }
380
381     /* List */
382     // buf = (BYTE *) & SRK_UUID;
383     // printhex("SRK uuid: ", buf, 16);
384
385     result = Tspi_Context_GetRegisteredKeysByUUID(
386                 hContext,
387                 (UINT32) ps_type,  // TSS_PS_TYPE_SYSTEM,
388                 &SRK_UUID,
389                 &ulKeyHierarchySize,
390                 &info);
391     if (result != TSS_SUCCESS) {
392         ERROR("Tspi_Context_GetRegisteredKeysByUUID failed rc=0x%x\n",
393             result);
394         goto close;
395     }
396
397     OUTPUT(NLS(MS_OPENPTS, OPENPTS_TPM_TSS_KEY_NUM, "Key number: %d\n"), ulKeyHierarchySize);
398     for (i = 0; i < (int)ulKeyHierarchySize; i++) {
399         OUTPUT(NLS(MS_OPENPTS, OPENPTS_TPM_TSS_KEY, "Key %d\n"), i);
400         info = info + 1;
401     }
402
403   close:
404     /* Close TSS/TPM */
405     Tspi_Context_Close(hContext);
406
407     return result;
408 }
409
410 /**
411  * Create Sign Key
412  *
413  * Key Storage : PS
414  * UUID        : uuid of ptscd
415  * Auth        : no
416  *
417  * srk_password_mode   0: SHA1("")  1: 0x00 x 20
418  * 
419  * TODO return PUBKEY blog
420  */
421 int createTssSignKey(
422     PTS_UUID *uuid,
423     int key_storage_type,
424     char *filename,
425     int auth_type,
426     int force,
427     int srk_password_mode)
428 {
429     TSS_RESULT result = 0;
430     TSS_HCONTEXT hContext;
431     TSS_HTPM hTPM;
432     TSS_UUID SRK_UUID = TSS_UUID_SRK;
433     TSS_HKEY hSRK;
434     TSS_HPOLICY hSRKPolicy;
435     UINT32 srk_auth_mode = TSS_SECRET_MODE_PLAIN;
436     BYTE *srk_auth;
437     int srk_auth_len = 0;
438     TSS_HKEY hKey;
439     UINT32 keyLength;
440     BYTE *keyBlob;
441     TSS_HPOLICY hKeyPolicy;
442     int i;
443     TSS_UUID tss_uuid;
444
445     /* Open TSS */
446     result = Tspi_Context_Create(&hContext);
447     if (result != TSS_SUCCESS) {
448         ERROR("Tspi_Context_Create failed rc=0x%x\n",
449                result);
450         goto close;
451     }
452
453     result = Tspi_Context_Connect(hContext, SERVER);
454     if (result != TSS_SUCCESS) {
455         ERROR("Tspi_Context_Connect failed rc=0x%x\n",
456                result);
457         goto close;
458     }
459
460     /* get TPM handles */
461     result = Tspi_Context_GetTpmObject(hContext, &hTPM);
462     if (result != TSS_SUCCESS) {
463         ERROR("Tspi_Context_GetTpmObject failed rc=0x%x\n",
464                result);
465         goto close;
466     }
467
468     /* load SRK */
469     result = Tspi_Context_LoadKeyByUUID(hContext,
470                                         TSS_PS_TYPE_SYSTEM, SRK_UUID,
471                                         &hSRK);
472     if (result != TSS_SUCCESS) {
473         ERROR("Tspi_Context_LoadKeyByUUID (SRK) failed rc=0x%x\n",
474          result);
475         if (result == 0x2020) {
476             ERROR("Your key storage of tcsd is damaged or missing. \n");
477         }
478         goto close;
479     }
480
481     /* SRK Policy objects */
482     result = Tspi_GetPolicyObject(hSRK, TSS_POLICY_USAGE, &hSRKPolicy);
483     if (result != TSS_SUCCESS) {
484         ERROR("Tspi_GetPolicyObject failed rc=0x%x\n",
485                result);
486         goto close;
487     }
488
489     /* SRK Auth Secret */
490     if (srk_password_mode == 1) {
491         srk_auth_mode = TSS_SECRET_MODE_SHA1;
492         srk_auth = known_srk_auth;
493         srk_auth_len = 20;
494     } else {
495         srk_auth_mode = TSS_SECRET_MODE_PLAIN;
496         srk_auth = null_srk_auth;
497         srk_auth_len = 0;
498     }
499
500     result = Tspi_Policy_SetSecret(
501                 hSRKPolicy,
502                 srk_auth_mode,
503                 srk_auth_len,
504                 srk_auth);
505     if (result != TSS_SUCCESS) {
506         ERROR("Tspi_Policy_SetSecret failed rc=0x%x\n",
507                result);
508         goto close;
509     }
510
511     /* UUID */
512     memcpy(&tss_uuid, uuid, sizeof(TSS_UUID));
513
514
515
516     if (auth_type == OPENPTS_AIK_AUTH_TYPE_COMMON) {
517 TODO("auth_type == OPENPTS_AIK_AUTH_TYPE_COMMON");
518         /* Create New Key object */
519         result = Tspi_Context_CreateObject(
520                     hContext,
521                     TSS_OBJECT_TYPE_RSAKEY,
522                     TSS_KEY_AUTHORIZATION | TSS_KEY_SIZE_2048 | TSS_KEY_TYPE_SIGNING,
523                     &hKey);
524         if (result != TSS_SUCCESS) {
525             ERROR("Tspi_Context_CreateObject failed rc=0x%x\n",
526                    result);
527             goto close;
528         }
529
530         // Noauth => uses Dummy Auth secret
531         result = Tspi_Context_CreateObject(
532                     hContext,
533                     TSS_OBJECT_TYPE_POLICY,
534                     TSS_POLICY_USAGE,
535                     &hKeyPolicy);
536         if (result != TSS_SUCCESS) {
537             printf
538             ("ERROR: Tspi_Context_CreateObject failed rc=0x%x\n",
539              result);
540             goto close;
541         }
542
543         result = Tspi_Policy_SetSecret(
544                     hKeyPolicy,
545                     TSS_SECRET_MODE_PLAIN,
546                     strlen(TPMSIGKEY_SECRET),
547                     (BYTE *)TPMSIGKEY_SECRET);
548         if (result != TSS_SUCCESS) {
549             printf
550             ("ERROR: Tspi_Policy_SetSecret failed rc=0x%x\n",
551              result);
552             goto close;
553         }
554
555         result = Tspi_Policy_AssignToObject(hKeyPolicy, hKey);
556
557         if (result != TSS_SUCCESS) {
558             printf
559             ("ERROR: Tspi_Policy_SetSecret failed rc=0x%x\n",
560              result);
561             goto close;
562         }
563     } else {
564         /* Create New Key object */
565 TODO("auth_type != OPENPTS_AIK_AUTH_TYPE_COMMON");
566         result = Tspi_Context_CreateObject(
567                     hContext,
568                     TSS_OBJECT_TYPE_RSAKEY,
569                     TSS_KEY_SIZE_2048 | TSS_KEY_TYPE_SIGNING,
570                     &hKey);
571         if (result != TSS_SUCCESS) {
572             ERROR("Tspi_Context_CreateObject failed rc=0x%x\n",
573                    result);
574             goto close;
575         }
576     }
577
578     /* create Key */
579     result = Tspi_Key_CreateKey(hKey, hSRK, 0);
580     if (result != TSS_SUCCESS) {
581         ERROR("Tspi_Key_CreateKey failed rc=0x%04x\n",
582                result);
583         if (result == 0x12) {
584             ERROR("TPM_NOSRK error, take the TPM ownership before initialize ptsc");
585         }
586         goto close;
587     }
588
589     /* RegisterKey */
590     if (key_storage_type == OPENPTS_AIK_STORAGE_TYPE_BLOB) {
591         /* save as blob */
592         FILE *fp;
593
594         if (filename == NULL) {
595             ERROR("key blob filename is NULL\n");
596             result = TSS_E_KEY_NOT_LOADED;
597             goto close;
598         }
599
600         fp = fopen(filename, "w");
601         if (fp==NULL) {
602             ERROR("file open fail, key blob file is %s",filename);
603             result = TSS_E_KEY_NOT_LOADED;
604             goto close;
605         }
606
607         result = Tspi_GetAttribData(
608                      hKey,
609                      TSS_TSPATTRIB_KEY_BLOB,
610                      TSS_TSPATTRIB_KEYBLOB_BLOB,
611                      &keyLength,
612                      &keyBlob);
613         if (result != TSS_SUCCESS) {
614             ERROR("Tspi_GetAttribData failed rc=0x%04x\n",
615                    result);
616             fclose(fp);
617             goto close;
618         }
619
620         for (i = 0; i< (int)keyLength; i++) {
621             fprintf(fp, "%c", keyBlob[i]);
622         }
623
624         fclose(fp);
625
626     } else {
627         /* managed by TSS  */
628   regkey:
629         result = Tspi_Context_RegisterKey(hContext,
630                                           hKey,
631                                           TSS_PS_TYPE_SYSTEM,
632                                           tss_uuid,
633                                           TSS_PS_TYPE_SYSTEM,
634                                           SRK_UUID);
635
636         if (result != TSS_SUCCESS) {
637             if (result == 0x2008) {
638                 // key is already registerd
639                 if (force == 1) {
640                     /* delete key */
641                     TSS_HKEY hKey;
642                     result =
643                         Tspi_Context_UnregisterKey(hContext,
644                                                    TSS_PS_TYPE_SYSTEM,
645                                                    tss_uuid,
646                                                    &hKey);
647                     if (result != TSS_SUCCESS) {
648                         ERROR("Tspi_Context_UnregisterKey failed rc=0x%x\n",
649                          result);
650                     } else {
651                         /* try regkey again */
652                         goto regkey;
653                     }
654                 } else {
655                     ERROR("Tspi_Context_RegisterKey failed rc=0x%x\n",
656                      result);
657                     ERROR("       TSS_E_KEY_ALREADY_REGISTERED\n");
658                 }
659             } else {
660                 ERROR("spi_Context_RegisterKey failed rc=0x%x\n",
661                  result);
662                 // 0x3003 TEE_E_BAD_PARAMETOR
663             }
664             goto close;
665         } else {
666             // OK
667         }
668     }  // ps_type
669
670   close:
671     /* Close TSS/TPM */
672     Tspi_Context_Close(hContext);
673
674     return result;
675 }
676
677 /**
678  * Create AIK
679  */
680 int createAIK() {
681     TODO("createAIK - TBD\n");
682     return -1;
683 }
684
685 /**
686  * delete TSS key
687  */
688 int deleteTssKey(PTS_UUID *uuid, int ps_type) {
689     TSS_RESULT result = 0;
690     TSS_HCONTEXT hContext;
691     TSS_HKEY hKey;
692     TSS_UUID tss_uuid;
693
694     /* Open TSS */
695     result = Tspi_Context_Create(&hContext);
696     if (result != TSS_SUCCESS) {
697         ERROR("Tspi_Context_Create failed rc=0x%x\n",
698                result);
699         goto close;
700     }
701
702     result = Tspi_Context_Connect(hContext, SERVER);
703     if (result != TSS_SUCCESS) {
704         ERROR("Tspi_Context_Connect failed rc=0x%x\n",
705                result);
706         goto close;
707     }
708
709     /* UUID */
710     memcpy(&tss_uuid, uuid, sizeof(TSS_UUID));
711
712     /* delete key */
713     result =
714         Tspi_Context_UnregisterKey(hContext,
715                                    (UINT32) ps_type,  // TSS_PS_TYPE_SYSTEM,
716                                    tss_uuid,
717                                    &hKey);
718     if (result != TSS_SUCCESS) {
719         ERROR("Tspi_Context_UnregisterKey failed rc=0x%x\n",
720          result);
721     }
722
723   close:
724     /* Close TSS/TPM */
725     Tspi_Context_Close(hContext);
726
727     return result;
728 }
729
730
731 #define KEY_BLOB_SIZE 1024
732
733 /**
734  * get Pubkey
735  *
736  * conf->pubkey_length
737  * conf->pubkey
738  */
739 int getTssPubKey(
740     PTS_UUID *uuid,
741     int ps_type,
742     int srk_password_mode,
743     int resetdalock,
744     char *filename,
745     int auth_type,
746     int *pubkey_length, BYTE **pubkey) {
747     TSS_RESULT result = 0;
748     TSS_HCONTEXT hContext;
749     TSS_HKEY hKey;
750     TSS_UUID tss_uuid;
751     BYTE *buf;  // TODO for pubkey
752     TSS_HKEY hSRK;
753     TSS_HPOLICY hSRKPolicy;
754     TSS_UUID SRK_UUID = TSS_UUID_SRK;
755     UINT32 srk_auth_mode = TSS_SECRET_MODE_PLAIN;
756     BYTE *srk_auth;
757     int srk_auth_len = 0;
758     TSS_HPOLICY hKeyPolicy;
759
760     if (resetdalock == 1) {
761         // 2011-03-03 SM WEC TPM locks well.
762         // TSS_TPMSTATUS_RESETLOCK is read only. no way to get this FLAG before 0x803 Error? :-(
763         // Thus, control by ptsc.conf
764         DEBUG("TSS_TPMSTATUS_RESETLOCK\n");
765         setTpmStatus(TSS_TPMSTATUS_RESETLOCK, TRUE, srk_password_mode);
766     }
767
768
769     /* Open TSS */
770     result = Tspi_Context_Create(&hContext);
771     if (result != TSS_SUCCESS) {
772         ERROR("Tspi_Context_Create failed rc=0x%x\n",
773                result);
774         goto close;
775     }
776
777     result = Tspi_Context_Connect(hContext, SERVER);
778     if (result != TSS_SUCCESS) {
779         ERROR("Tspi_Context_Connect failed rc=0x%x\n",
780                result);
781         goto close;
782     }
783
784     /* UUID */
785     memcpy(&tss_uuid, uuid, sizeof(TSS_UUID));
786
787     /* load key */
788     /* Get SRK handles */
789     result = Tspi_Context_LoadKeyByUUID(
790                 hContext,
791                 TSS_PS_TYPE_SYSTEM,
792                 SRK_UUID,
793                 &hSRK);
794     if (result != TSS_SUCCESS) {
795         ERROR("Tspi_Context_LoadKeyByUUID (SRK) failed rc=0x%x\n",
796          result);
797         if (result == 0x2020) {
798             ERROR(" TSS_E_PS_KEY_NOT_FOUND.\n");
799             fprintf(stderr, NLS(MS_OPENPTS, OPENPTS_TSS_CHECK_SETTING,
800                 "Please check your system_ps_file setting in /etc/security/tss/tcsd.conf. "
801                 "(The default is /var/tss/lib/tpm/system.data)\n"
802                 "If system_ps_file size is zero then it does not contain the SRK info\n"));
803         }
804
805         goto close;
806     }
807
808
809     /* SRK Policy objects */
810     result = Tspi_GetPolicyObject(hSRK, TSS_POLICY_USAGE, &hSRKPolicy);
811     if (result != TSS_SUCCESS) {
812         ERROR("Tspi_GetPolicyObject failed rc=0x%x\n",
813                result);
814         goto close;
815     }
816
817     /* SRK Auth Secret */
818     if (srk_password_mode == 1) {
819         srk_auth_mode = TSS_SECRET_MODE_SHA1;
820         srk_auth = known_srk_auth;
821         srk_auth_len = 20;
822     } else {
823         srk_auth_mode = TSS_SECRET_MODE_PLAIN;
824         srk_auth = null_srk_auth;
825         srk_auth_len = 0;
826     }
827
828     /* SRK secret */
829     result = Tspi_Policy_SetSecret(
830                 hSRKPolicy,
831                 srk_auth_mode,
832                 srk_auth_len,
833                 srk_auth);
834     if (result != TSS_SUCCESS) {
835         ERROR("Tspi_Policy_SetSecret failed rc=0x%x\n",
836                result);
837         goto close;
838     }
839
840     // TODO resetDaLock
841
842     /* Load AIK or Sign key */
843     if (ps_type == OPENPTS_AIK_STORAGE_TYPE_BLOB) {
844         /* Blob file */
845         FILE *fp;
846         BYTE blob[KEY_BLOB_SIZE];
847         int len;
848
849         fp = fopen(filename, "r");
850         if (fp==NULL) {
851             ERROR("file open fail, key blob file is %s",filename);
852             result = TSS_E_KEY_NOT_LOADED;
853             goto close;
854         }
855         len = fread(blob, 1, KEY_BLOB_SIZE, fp);
856         fclose(fp);
857
858         /* Load */
859         result = Tspi_Context_LoadKeyByBlob(
860                     hContext,
861                     hSRK,
862                     len,
863                     blob,
864                     &hKey);
865         if (result != TSS_SUCCESS) {
866             ERROR("Tspi_Context_LoadKeyByBlob (Key) failed rc=0x%x\n",
867              result);
868             goto close;
869         }
870     } else {
871         /* TSS PS*/
872         result = Tspi_Context_LoadKeyByUUID(
873                     hContext,
874                     (UINT32) ps_type,  // TSS_PS_TYPE_SYSTEM,
875                     tss_uuid,
876                     &hKey);
877         if (result == 0x803) {
878             fprintf(stderr, NLS(MS_OPENPTS, OPENPTS_TSS_TPM_LOCKED,
879                         "The TPM is locked. Please use the 'tpm_resetdalock' command to clear the lock\n"
880                         "For the ptscd daemon please set the flag 'tpm.resetdalock=on' in /etc/ptsc.conf\n"));
881             goto close;
882         } else if (result != TSS_SUCCESS) {
883             ERROR("Tspi_Context_LoadKeyByUUID (Key) failed rc=0x%x\n", result);
884             debugHex("\t\tUUID", (BYTE*)&tss_uuid, 16, "\n");
885
886             goto close;
887         }
888     }
889
890     /* Policy Object*/
891     result = Tspi_GetPolicyObject(hKey, TSS_POLICY_USAGE, &hKeyPolicy);
892     if (result != TSS_SUCCESS) {
893         ERROR("Tspi_GetPolicyObject failed rc=0x%x\n",
894                result);
895         goto close;
896     }
897
898 //<<<<<<< HEAD
899 //
900 //    /* Set Policy */
901 //    result = Tspi_Policy_SetSecret(
902 //                hKeyPolicy,
903 //                TSS_SECRET_MODE_PLAIN,
904 //                0,  // ""
905 //                key_auth);
906 //    if (result != TSS_SUCCESS) {
907 //        ERROR("Tspi_Policy_SetSecret failed rc=0x%x\n",
908 //               result);
909 //        goto close;
910 //=======
911     if (auth_type == OPENPTS_AIK_AUTH_TYPE_COMMON) {
912         /* Set Policy - Dummy Secret */
913         // 2011-11-26 Munetoh - This fail with Infineon TPM(v1.2)
914         result = Tspi_Policy_SetSecret(
915                     hKeyPolicy,
916                     TSS_SECRET_MODE_PLAIN,
917                     strlen(TPMSIGKEY_SECRET),
918                     (BYTE *)TPMSIGKEY_SECRET);
919         if (result != TSS_SUCCESS) {
920             printf("ERROR: Tspi_Policy_SetSecret failed rc=0x%x\n",
921                    result);
922             goto close;
923         }
924     } else {
925         /* Set Policy - Null Secret */
926         // Atmel, Winbond, STM
927         BYTE key_auth[1] = {0};
928
929         result = Tspi_Policy_SetSecret(
930                     hKeyPolicy,
931                     TSS_SECRET_MODE_PLAIN,
932                     0,
933                     key_auth);
934         if (result != TSS_SUCCESS) {
935             printf("ERROR: Tspi_Policy_SetSecret failed rc=0x%x\n",
936                    result);
937             goto close;
938         }
939 //>>>>>>> 042e40b0979f3e44e75200271e4d1282ce08f72c
940     }
941
942     /* get pubkey */
943     /* PubKey */
944     // TODO shared at enroll phase
945     result = Tspi_GetAttribData(hKey,
946                                 TSS_TSPATTRIB_KEY_BLOB,
947                                 TSS_TSPATTRIB_KEYBLOB_PUBLIC_KEY,
948                                 // (UINT32 *) &conf->pubkey_length,
949                                 (UINT32 *) pubkey_length,
950                                 &buf);
951     if (result != TSS_SUCCESS) {
952         ERROR("Tspi_GetAttribData failed rc=0x%x\n",
953                result);
954         goto free;
955     }
956     /* copy to local */
957     if (*pubkey != NULL) {
958         // DEBUG("realloc conf->pubkey\n");  // TODO realloc happen
959         xfree(*pubkey);
960     }
961     *pubkey = xmalloc_assert(*pubkey_length);
962     memcpy(*pubkey, buf, *pubkey_length);
963
964
965   free:
966     Tspi_Context_FreeMemory(hContext, NULL);
967     Tspi_Context_CloseObject(hContext, hKey);
968     Tspi_Context_CloseObject(hContext, hSRK);
969
970   close:
971     /* Close TSS/TPM */
972     Tspi_Context_Close(hContext);
973
974     return result;
975 }
976
977 /**
978  * get TPM version
979  */
980 int getTpmVersion(TSS_VERSION *version) {
981     int rc = TSS_SUCCESS;
982     TSS_RESULT result;
983     TSS_HCONTEXT hContext;
984     TSS_HTPM hTPM;
985     UINT32 data_len;
986     BYTE *data;
987
988     /* Connect to TCSD */
989     result = Tspi_Context_Create(&hContext);
990     if (result != TSS_SUCCESS) {
991         ERROR("Tspi_Context_Create failed rc=0x%x\n",
992                result);
993         if (result == 0x3011) {
994             OUTPUT(NLS(MS_OPENPTS, OPENPTS_TPM_TSS_COMMS_FAILURE, "TSS communications failure. Is tcsd running?\n"));
995         }
996         rc = (int)result;
997         goto close;
998     }
999
1000     result = Tspi_Context_Connect(hContext, SERVER);
1001     if (result != TSS_SUCCESS) {
1002         ERROR("Tspi_Context_Connect failed rc=0x%x\n",
1003                result);
1004         rc = (int)result;
1005         goto close;
1006     }
1007
1008     /* Get TPM handle */
1009     result = Tspi_Context_GetTpmObject(hContext, &hTPM);
1010     if (result != TSS_SUCCESS) {
1011         ERROR("Tspi_Context_GetTpmObject failed rc=0x%x\n",
1012                result);
1013         rc = (int)result;
1014         goto close;
1015     }
1016
1017     /* Get TPM Version via Capability */
1018     // 1.2
1019     result = Tspi_TPM_GetCapability(
1020                 hTPM,
1021                 TSS_TPMCAP_VERSION,
1022                 0,
1023                 NULL,
1024                 &data_len,
1025                 &data);
1026     if (result != TSS_SUCCESS) {
1027         ERROR("Tspi_TPM_GetCapability failed rc=0x%x\n",
1028                result);
1029         rc = (int)result;
1030         goto close;
1031     }
1032
1033     if (data_len != 4) {
1034         ERROR("bad TPM version\n");
1035         rc = TSS_E_FAIL;
1036         goto close;
1037     }
1038
1039     // 1.1.0.0
1040     version->bMajor = data[0];
1041     version->bMinor = data[1];
1042     version->bRevMajor = data[2];
1043     version->bRevMinor = data[3];
1044
1045     /* Close TSS/TPM */
1046   close:
1047     Tspi_Context_Close(hContext);
1048
1049     return rc;
1050 }
1051
1052
1053 /**
1054  * Get Quote Signature
1055  *
1056  */
1057 int quoteTss(
1058         /* Key */
1059         PTS_UUID *uuid,
1060         int ps_type,
1061         int srk_password_mode,
1062         char *filename,
1063         int auth_type,
1064         /* Nonce */
1065         BYTE *nonce,
1066         /* PCR selection */
1067         OPENPTS_PCRS *pcrs,
1068         /* Output */
1069         TSS_VALIDATION *validationData) {
1070     TSS_RESULT result;
1071     TSS_HCONTEXT hContext;
1072     TSS_HTPM hTPM;
1073     TSS_HKEY hSRK;
1074     TSS_HPOLICY hSRKPolicy;
1075     TSS_UUID SRK_UUID = TSS_UUID_SRK;
1076     UINT32 srk_auth_mode = TSS_SECRET_MODE_PLAIN;
1077     BYTE *srk_auth = NULL;
1078     int srk_auth_len = 0;
1079
1080     TSS_HKEY hKey;
1081     TSS_HPOLICY hKeyPolicy;
1082     TSS_UUID tss_uuid;
1083     TSS_HPCRS hPcrComposite;
1084     TSS_VALIDATION validation_data;  // local
1085     int i;
1086     UINT32 ulSubCapLength;
1087     UINT32 rgbSubCap;
1088     UINT32 pulRespDataLength;
1089     BYTE *prgbRespData;
1090     UINT32 pcrnum;
1091
1092     int pcrSelectCount = 0;
1093
1094     /* UUID */
1095     memcpy(&tss_uuid, uuid, sizeof(TSS_UUID));
1096
1097     /* Connect to TCSD */
1098     result = Tspi_Context_Create(&hContext);
1099     if (result != TSS_SUCCESS) {
1100         ERROR("Tspi_Context_Create failed rc=0x%x\n",
1101                result);
1102         if (result == 0x3011) {
1103             OUTPUT(NLS(MS_OPENPTS, OPENPTS_TPM_TSS_COMMS_FAILURE, "TSS communications failure. Is tcsd running?\n"));
1104         }
1105
1106         goto close;
1107     }
1108
1109     result = Tspi_Context_Connect(hContext, SERVER);
1110     if (result != TSS_SUCCESS) {
1111         ERROR("Tspi_Context_Connect failed rc=0x%x\n",
1112                result);
1113         goto close;
1114     }
1115
1116     /* Get TPM handle */
1117     result = Tspi_Context_GetTpmObject(hContext, &hTPM);
1118     if (result != TSS_SUCCESS) {
1119         ERROR("Tspi_Context_GetTpmObject failed rc=0x%x\n",
1120                result);
1121         goto close;
1122     }
1123
1124     /* Get PCR Num */
1125     ulSubCapLength = sizeof(UINT32);
1126     rgbSubCap = TSS_TPMCAP_PROP_PCR;
1127
1128     result = Tspi_TPM_GetCapability(hTPM,
1129                                     TSS_TPMCAP_PROPERTY,
1130                                     ulSubCapLength,
1131                                     (BYTE *) & rgbSubCap,
1132                                     &pulRespDataLength, &prgbRespData);
1133
1134     if (result != TSS_SUCCESS) {
1135         ERROR("Tspi_TPM_GetCapability failed rc=0x%x\n",
1136                result);
1137         goto close;
1138     }
1139
1140     pcrnum = (UINT32) *prgbRespData;
1141     pcrnum = * (UINT32 *)prgbRespData;
1142     pcrs->pcr_num = pcrnum;  // TODO
1143
1144
1145     /* PCR Composite - Object */
1146     result = Tspi_Context_CreateObject(
1147                 hContext,
1148                 TSS_OBJECT_TYPE_PCRS,
1149                 0,
1150                 &hPcrComposite);
1151     if (result != TSS_SUCCESS) {
1152         ERROR("Tspi_Context_CreateObject failed rc=0x%x\n",
1153                result);
1154         goto close;
1155     }
1156
1157     /* PCR Composite - SelectPcrIndex */
1158     for (i = 0; i < (int)pcrnum; i++) {
1159         if (pcrs->pcr_select[i] == 1) {
1160             result = Tspi_PcrComposite_SelectPcrIndex(
1161                         hPcrComposite,
1162                         i);
1163             if (result != TSS_SUCCESS) {
1164                     ERROR("failed rc=0x%x\n", result);
1165                     goto close;
1166             }
1167             pcrSelectCount++;
1168         }
1169     }
1170
1171     /* check PCR */
1172     if (pcrSelectCount == 0) {
1173         ERROR("No PCR is selected for quote\n");
1174         goto close;
1175     }
1176
1177     /* Get SRK handles */
1178     result = Tspi_Context_LoadKeyByUUID(
1179                 hContext,
1180                 TSS_PS_TYPE_SYSTEM,
1181                 SRK_UUID,
1182                 &hSRK);
1183     if (result != TSS_SUCCESS) {
1184         ERROR("Tspi_Context_LoadKeyByUUID (SRK) failed rc=0x%x\n",
1185          result);
1186         if (result == 0x2020) {
1187             ERROR(" TSS_E_PS_KEY_NOT_FOUND.\n");
1188             fprintf(stderr, NLS(MS_OPENPTS, OPENPTS_TSS_CHECK_SETTING,
1189                 "Please check your system_ps_file setting in /etc/tcsd.conf. "
1190                 "(The default is /var/lib/tpm/system.data)\n"
1191                 "If system_ps_file size is zero then it does not contains the SRK info\n"));
1192         }
1193
1194         goto close;
1195     }
1196
1197
1198     /* Get SRK Policy objects */
1199     result = Tspi_GetPolicyObject(hSRK, TSS_POLICY_USAGE, &hSRKPolicy);
1200     if (result != TSS_SUCCESS) {
1201         ERROR("Tspi_GetPolicyObject failed rc=0x%x\n",
1202                result);
1203         goto close;
1204     }
1205
1206
1207     /* SRK Auth Secret */
1208     if (srk_password_mode == 1) {
1209         srk_auth_mode = TSS_SECRET_MODE_SHA1;
1210         srk_auth = known_srk_auth;
1211         srk_auth_len = 20;
1212     } else {
1213         srk_auth_mode = TSS_SECRET_MODE_PLAIN;
1214         srk_auth = null_srk_auth;
1215         srk_auth_len = 0;
1216     }
1217
1218     /* Set SRK Credential */
1219     result = Tspi_Policy_SetSecret(
1220                 hSRKPolicy,
1221                 srk_auth_mode,
1222                 srk_auth_len,
1223                 srk_auth);
1224     if (result != TSS_SUCCESS) {
1225         ERROR("Tspi_Policy_SetSecret failed rc=0x%x\n",
1226                result);
1227         goto close;
1228     }
1229
1230
1231     /* Load AIK or Sign key */
1232     if (ps_type == OPENPTS_AIK_STORAGE_TYPE_BLOB) {
1233         /* Blob file */
1234         FILE *fp;
1235         BYTE blob[KEY_BLOB_SIZE];
1236         int len;
1237
1238         fp = fopen(filename, "r");
1239         if (fp==NULL) {
1240             ERROR("file open fail, key blob file is %s",filename);
1241             result = TSS_E_KEY_NOT_LOADED;
1242             goto close;
1243         }
1244
1245         len = fread(blob, 1, KEY_BLOB_SIZE, fp);
1246         fclose(fp);
1247
1248         /* Load */
1249         result = Tspi_Context_LoadKeyByBlob(
1250                      hContext,
1251                      hSRK,
1252                      len,
1253                      blob,
1254                      &hKey);
1255         if (result != TSS_SUCCESS) {
1256             ERROR("Tspi_Context_LoadKeyByBlob (Key) failed rc=0x%x\n",
1257              result);
1258             goto close;
1259         }
1260     } else {
1261         /* load from TSS's PS */
1262         result = Tspi_Context_LoadKeyByUUID(hContext,
1263                                             (UINT32) ps_type,  // TSS_PS_TYPE_SYSTEM,
1264                                             tss_uuid,
1265                                             &hKey);
1266         if (result != TSS_SUCCESS) {
1267             ERROR("Tspi_Context_LoadKeyByUUID (Key) failed rc=0x%x\n", result);
1268             debugHex("\t\tUUID", (BYTE*)&tss_uuid, 16, "\n");
1269
1270             goto close;
1271         }
1272     }
1273
1274     /* get Policy Object of Sign key */
1275     result = Tspi_GetPolicyObject(hKey, TSS_POLICY_USAGE, &hKeyPolicy);
1276     if (result != TSS_SUCCESS) {
1277         ERROR("Tspi_GetPolicyObject failed rc=0x%x\n",
1278               result);
1279         goto close;
1280     }
1281
1282 //<<<<<<< HEAD
1283 //    /* Set Policy */
1284 //    result = Tspi_Policy_SetSecret(
1285 //                hKeyPolicy,
1286 //                TSS_SECRET_MODE_PLAIN,
1287 //                0,  // ""
1288 //                key_auth);
1289 //    if (result != TSS_SUCCESS) {
1290 //        ERROR("Tspi_Policy_SetSecret failed rc=0x%x\n",
1291 //               result);
1292 //        goto close;
1293 //=======
1294     if (auth_type == OPENPTS_AIK_AUTH_TYPE_COMMON) {
1295         /* Set Policy - Dummy Secret */
1296         // 2011-11-26 Munetoh - This fail with Infineon TPM(v1.2)
1297         result = Tspi_Policy_SetSecret(
1298                     hKeyPolicy,
1299                     TSS_SECRET_MODE_PLAIN,
1300                     strlen(TPMSIGKEY_SECRET),
1301                     (BYTE *)TPMSIGKEY_SECRET);
1302         if (result != TSS_SUCCESS) {
1303             printf("ERROR: Tspi_Policy_SetSecret failed rc=0x%x\n",
1304                    result);
1305             goto close;
1306         }
1307     } else {
1308         /* Set Policy - Null Secret */
1309         // Atmel, Winbond, STM
1310         BYTE key_auth[] = "";
1311
1312         result = Tspi_Policy_SetSecret(
1313                     hKeyPolicy,
1314                     TSS_SECRET_MODE_PLAIN,
1315                     0,
1316                     key_auth);
1317         if (result != TSS_SUCCESS) {
1318             printf("ERROR: Tspi_Policy_SetSecret failed rc=0x%x\n",
1319                    result);
1320             goto close;
1321         }
1322 //>>>>>>> 042e40b0979f3e44e75200271e4d1282ce08f72c
1323     }
1324
1325     /* Setup (copy) Validation Data Structure */
1326     validation_data.versionInfo.bMajor = validationData->versionInfo.bMajor;
1327     validation_data.versionInfo.bMinor = validationData->versionInfo.bMinor;
1328     validation_data.versionInfo.bRevMajor = validationData->versionInfo.bRevMajor;
1329     validation_data.versionInfo.bRevMinor = validationData->versionInfo.bRevMinor;
1330
1331     /* Nonce -> rgbExternalData */
1332     validation_data.ulExternalDataLength = validationData->ulExternalDataLength;
1333     validation_data.rgbExternalData = validationData->rgbExternalData;
1334
1335
1336     /* Issue TPM_Quote */
1337     result = Tspi_TPM_Quote(hTPM,
1338                             hKey, hPcrComposite, &validation_data);
1339     if (result != TSS_SUCCESS) {
1340         if (result == 0x01) {
1341             ERROR("Tspi_TPM_Quote failed rc=0x%04x\n",
1342                    result);
1343             ERROR("       Authorization faild, needs valid password\n");
1344         } else {
1345             ERROR("Tspi_TPM_Quote failed rc=0x%04x\n",
1346                    result);
1347         }
1348         goto free;
1349     }
1350
1351     /* Store Validation Data Structure */
1352 #if 1
1353     /* rgbData */
1354     //   version
1355     //   QUOTE
1356     //   SHA1(PCRs)
1357     //   NONCE[20]
1358     // total 48-bytes
1359     validationData->ulDataLength = validation_data.ulDataLength;
1360     validationData->rgbData = xmalloc(validation_data.ulDataLength);
1361     if (validationData->rgbData == NULL) {
1362         result = PTS_FATAL;
1363         goto free;
1364     }
1365     memcpy(
1366         validationData->rgbData,
1367         validation_data.rgbData,
1368         validation_data.ulDataLength);
1369 #else
1370     // rgbData stores digest only
1371     // 2011-02-09 SM bad approach
1372     /* rgbData */
1373     validationData->ulDataLength = 20;
1374     validationData->rgbData = xmalloc(20);
1375     if (validationData->rgbData == NULL) {
1376         result = PTS_FATAL;
1377         goto free;
1378     }
1379     memcpy(
1380         validationData->rgbData,
1381         &validation_data.rgbData[8],
1382         20);
1383 #endif
1384
1385
1386     /* rgbValidationData */
1387     validationData->ulValidationDataLength = validation_data.ulValidationDataLength;
1388     validationData->rgbValidationData = xmalloc(validation_data.ulValidationDataLength);
1389     if (validationData->rgbValidationData == NULL) {
1390         result = PTS_FATAL;
1391         goto free;
1392     }
1393     memcpy(
1394         validationData->rgbValidationData,
1395         validation_data.rgbValidationData,
1396         validation_data.ulValidationDataLength);
1397
1398     /* version */
1399     validationData->versionInfo.bMajor    = validationData->rgbData[0];
1400     validationData->versionInfo.bMinor    = validationData->rgbData[1];
1401     validationData->versionInfo.bRevMajor = validationData->rgbData[2];
1402     validationData->versionInfo.bRevMinor = validationData->rgbData[3];
1403
1404
1405     if (isDebugFlagSet(DEBUG_FLAG)) {
1406         DEBUG("TPM_Quote\n");
1407         debugHex("   validationData :",
1408             validationData->rgbData,
1409             validationData->ulDataLength, "\n");
1410     }
1411
1412
1413     /* Get PCR values used by Quote */
1414     // TODO
1415     for (i = 0; i < (int) pcrnum; i++) {  // TODO pcrs->pcr_num
1416         if (pcrs->pcr_select[i] == 1) {
1417             UINT32 length;
1418             BYTE *data;
1419             result = Tspi_PcrComposite_GetPcrValue(
1420                         hPcrComposite, i,
1421                         &length, &data);
1422             if (result != TSS_SUCCESS) {
1423                 ERROR("Tspi_PcrComposite_GetPcrValue failed rc=0x%x\n",
1424                         result);
1425                 goto free;
1426             }
1427
1428             // fprintf(fp, "pcr.%d=", i);
1429             // fprinthex(fp, "", data, length);
1430             if (length < MAX_DIGEST_SIZE) {
1431                 memcpy(&pcrs->pcr[i], data, length);
1432                 if (isDebugFlagSet(DEBUG_FLAG)) {
1433                     // DEBUG("PCR[%d]", i);
1434                     debugHex("             : ", data, length, "\n");
1435                 }
1436             } else {
1437                 ERROR("pcr size is too big %d >  %d\n", length, MAX_DIGEST_SIZE);
1438             }
1439
1440             Tspi_Context_FreeMemory(hContext, data);
1441         }
1442     }
1443
1444     /* Validation */
1445     // TODO
1446
1447   free:
1448     Tspi_Context_FreeMemory(hContext, NULL);
1449     Tspi_Context_CloseObject(hContext, hPcrComposite);
1450     Tspi_Context_CloseObject(hContext, hKeyPolicy);
1451     Tspi_Context_CloseObject(hContext, hKey);
1452     Tspi_Context_CloseObject(hContext, hSRKPolicy);
1453     Tspi_Context_CloseObject(hContext, hSRK);
1454     Tspi_Context_CloseObject(hContext, hTPM);
1455
1456     /* Close TSS/TPM */
1457   close:
1458     Tspi_Context_Close(hContext);
1459
1460     return result;
1461 }
1462
1463 /**
1464  * Get Quote2 Signature
1465  *
1466  */
1467 int quote2Tss(
1468         /* Key */
1469         PTS_UUID *uuid,
1470         int ps_type,
1471         int srk_password_mode,
1472         char *filename,
1473         int auth_type,
1474         /* Nonce */
1475         BYTE *nonce,
1476         /* PCR selection */
1477         OPENPTS_PCRS *pcrs,
1478         /* Output */
1479         TSS_VALIDATION *validationData) {
1480     TSS_RESULT result;
1481     TSS_HCONTEXT hContext;
1482     TSS_HTPM hTPM;
1483     TSS_HKEY hSRK;
1484     TSS_HPOLICY hSRKPolicy;
1485     TSS_UUID SRK_UUID = TSS_UUID_SRK;
1486
1487     UINT32 srk_auth_mode = TSS_SECRET_MODE_PLAIN;
1488     BYTE *srk_auth;
1489     int srk_auth_len = 0;
1490
1491     TSS_HKEY hKey;
1492     TSS_HPOLICY hKeyPolicy;
1493     TSS_UUID tss_uuid;
1494     TSS_HPCRS hPcrComposite;
1495     TSS_VALIDATION validation_data;  // local
1496     int i;
1497     UINT32 ulSubCapLength;
1498     UINT32 rgbSubCap;
1499     UINT32 pulRespDataLength;
1500     BYTE *prgbRespData;
1501     UINT32 pcrnum;
1502
1503     UINT32  versionInfoSize;
1504     BYTE*   versionInfo;
1505
1506     int pcrSelectCount = 0;
1507
1508     /* UUID */
1509     // uuit_t -> TSS_UUID
1510     memcpy(&tss_uuid, uuid, sizeof(TSS_UUID));
1511
1512     /* Connect to TCSD */
1513     result = Tspi_Context_Create(&hContext);
1514     if (result != TSS_SUCCESS) {
1515         ERROR("Tspi_Context_Create failed rc=0x%x\n",
1516                result);
1517         if (result == 0x3011) {
1518             OUTPUT(NLS(MS_OPENPTS, OPENPTS_TPM_TSS_COMMS_FAILURE, "TSS communications failure. Is tcsd running?\n"));
1519         }
1520
1521         goto close;
1522     }
1523
1524     result = Tspi_Context_Connect(hContext, SERVER);
1525     if (result != TSS_SUCCESS) {
1526         ERROR("Tspi_Context_Connect failed rc=0x%x\n",
1527                result);
1528         goto close;
1529     }
1530
1531     /* Get TPM handle */
1532     result = Tspi_Context_GetTpmObject(hContext, &hTPM);
1533     if (result != TSS_SUCCESS) {
1534         ERROR("Tspi_Context_GetTpmObject failed rc=0x%x\n",
1535                result);
1536         goto close;
1537     }
1538
1539     /* Get PCR Num */
1540     ulSubCapLength = sizeof(UINT32);
1541     rgbSubCap = TSS_TPMCAP_PROP_PCR;
1542
1543     result = Tspi_TPM_GetCapability(
1544                 hTPM,
1545                 TSS_TPMCAP_PROPERTY,
1546                 ulSubCapLength,
1547                 (BYTE *) & rgbSubCap,
1548                 &pulRespDataLength, &prgbRespData);
1549
1550     if (result != TSS_SUCCESS) {
1551         ERROR("Tspi_TPM_GetCapability failed rc=0x%x\n",
1552                result);
1553         goto close;
1554     }
1555
1556     pcrnum = (UINT32) *prgbRespData;
1557     pcrnum = * (UINT32 *)prgbRespData;
1558     pcrs->pcr_num = pcrnum;  // TODO
1559
1560
1561     /* PCR Composite - Object */
1562     result = Tspi_Context_CreateObject(
1563                 hContext,
1564                 TSS_OBJECT_TYPE_PCRS,
1565                 TSS_PCRS_STRUCT_INFO_SHORT,
1566                 &hPcrComposite);
1567     if (result != TSS_SUCCESS) {
1568         ERROR("Tspi_Context_CreateObject failed rc=0x%x\n",
1569                result);
1570         goto close;
1571     }
1572
1573     /* PCR Composite - SelectPcrIndex */
1574     for (i = 0; i < (int)pcrnum; i++) {
1575         if (pcrs->pcr_select[i] == 1) {
1576             result = Tspi_PcrComposite_SelectPcrIndexEx(
1577                         hPcrComposite,
1578                         i,
1579                         TSS_PCRS_DIRECTION_RELEASE);
1580             if (result != TSS_SUCCESS) {
1581                     ERROR("failed rc=0x%x\n", result);
1582                     goto close;
1583             }
1584             pcrSelectCount++;
1585         }
1586     }
1587
1588     /* check PCR */
1589     if (pcrSelectCount == 0) {
1590         ERROR("No PCR is selected for quote\n");
1591         goto close;
1592     }
1593
1594     /* Get SRK handles */
1595     result = Tspi_Context_LoadKeyByUUID(
1596                 hContext,
1597                 TSS_PS_TYPE_SYSTEM,
1598                 SRK_UUID,
1599                 &hSRK);
1600     if (result != TSS_SUCCESS) {
1601         ERROR("Tspi_Context_LoadKeyByUUID (SRK) failed rc=0x%x\n",
1602          result);
1603         if (result == 0x2020) {
1604             ERROR(" TSS_E_PS_KEY_NOT_FOUND.\n");
1605             fprintf(stderr, NLS(MS_OPENPTS, OPENPTS_TSS_CHECK_SETTING,
1606                 "Please check your system_ps_file setting in /etc/tcsd.conf. "
1607                 "(The default is /var/lib/tpm/system.data)\n"
1608                 "If system_ps_file size is zero then it does not contains the SRK info\n"));
1609         }
1610
1611         goto close;
1612     }
1613
1614
1615     /* Get SRK Policy objects */
1616     result = Tspi_GetPolicyObject(hSRK, TSS_POLICY_USAGE, &hSRKPolicy);
1617     if (result != TSS_SUCCESS) {
1618         ERROR("Tspi_GetPolicyObject failed rc=0x%x\n",
1619                result);
1620         goto close;
1621     }
1622
1623     /* SRK Auth Secret */
1624     if (srk_password_mode == 1) {
1625         srk_auth_mode = TSS_SECRET_MODE_SHA1;
1626         srk_auth = known_srk_auth;
1627         srk_auth_len = 20;
1628     } else {
1629         srk_auth_mode = TSS_SECRET_MODE_PLAIN;
1630         srk_auth = null_srk_auth;
1631         srk_auth_len = 0;
1632     }
1633
1634     /* Set SRK Credential (must be NULL) */
1635     result = Tspi_Policy_SetSecret(
1636                 hSRKPolicy,
1637                 srk_auth_mode,
1638                 srk_auth_len,
1639                 srk_auth);
1640     if (result != TSS_SUCCESS) {
1641         ERROR("Tspi_Policy_SetSecret failed rc=0x%x\n",
1642                result);
1643         goto close;
1644     }
1645
1646
1647     /* Load AIK or Sign key */
1648     if (ps_type == OPENPTS_AIK_STORAGE_TYPE_BLOB) {
1649         /* Blob file */
1650         FILE *fp;
1651         BYTE blob[KEY_BLOB_SIZE];
1652         int len;
1653
1654         fp = fopen(filename, "r");
1655         if (fp==NULL) {
1656             ERROR("file open fail, key blob file is %s",filename);
1657             result = TSS_E_KEY_NOT_LOADED;
1658             goto close;
1659         }
1660
1661
1662         len = fread(blob, 1, KEY_BLOB_SIZE, fp);
1663         fclose(fp);
1664
1665         /* Load */
1666         result = Tspi_Context_LoadKeyByBlob(
1667                      hContext,
1668                      hSRK,
1669                      len,
1670                      blob,
1671                      &hKey);
1672         if (result != TSS_SUCCESS) {
1673             ERROR("Tspi_Context_LoadKeyByBlob (Key) failed rc=0x%x\n",
1674              result);
1675             goto close;
1676         }
1677     } else {
1678         /* load from TSS's PS */
1679         result = Tspi_Context_LoadKeyByUUID(hContext,
1680                                             (UINT32) ps_type,  // TSS_PS_TYPE_SYSTEM,
1681                                             tss_uuid,
1682                                             &hKey);
1683         if (result != TSS_SUCCESS) {
1684             ERROR("Tspi_Context_LoadKeyByUUID (Key) failed rc=0x%x\n", result);
1685             debugHex("\t\tUUID", (BYTE*)&tss_uuid, 16, "\n");
1686
1687             goto close;
1688         }
1689     }
1690
1691     /* get Policy Object of Sign key */
1692     result = Tspi_GetPolicyObject(hKey, TSS_POLICY_USAGE, &hKeyPolicy);
1693     if (result != TSS_SUCCESS) {
1694         ERROR("Tspi_GetPolicyObject failed rc=0x%x\n",
1695                result);
1696         goto close;
1697     }
1698
1699 //<<<<<<< HEAD
1700 //    /* Set Policy */
1701 //    result = Tspi_Policy_SetSecret(
1702 //                hKeyPolicy,
1703 //                TSS_SECRET_MODE_PLAIN,
1704 //                0,
1705 //                key_auth);
1706 //    if (result != TSS_SUCCESS) {
1707 //        ERROR("Tspi_Policy_SetSecret failed rc=0x%x\n",
1708 //               result);
1709 //        goto close;
1710 //=======
1711     if (auth_type == OPENPTS_AIK_AUTH_TYPE_COMMON) {
1712         /* Set Policy - Dummy Secret */
1713         // 2011-11-26 Munetoh - This fail with Infineon TPM(v1.2)
1714         result = Tspi_Policy_SetSecret(
1715                     hKeyPolicy,
1716                     TSS_SECRET_MODE_PLAIN,
1717                     strlen(TPMSIGKEY_SECRET),
1718                     (BYTE *)TPMSIGKEY_SECRET);
1719         if (result != TSS_SUCCESS) {
1720             printf("ERROR: Tspi_Policy_SetSecret failed rc=0x%x\n",
1721                    result);
1722             goto close;
1723         }
1724     } else {
1725         /* Set Policy - Null Secret */
1726         // Atmel, Winbond, STM
1727         BYTE key_auth[] = "";
1728
1729         result = Tspi_Policy_SetSecret(
1730                     hKeyPolicy,
1731                     TSS_SECRET_MODE_PLAIN,
1732                     0,
1733                     key_auth);
1734         if (result != TSS_SUCCESS) {
1735             printf("ERROR: Tspi_Policy_SetSecret failed rc=0x%x\n",
1736                    result);
1737             goto close;
1738         }
1739 //>>>>>>> 042e40b0979f3e44e75200271e4d1282ce08f72c
1740     }
1741
1742     /* Nonce -> rgbExternalData */
1743     validation_data.ulExternalDataLength = validationData->ulExternalDataLength;
1744     validation_data.rgbExternalData = validationData->rgbExternalData;
1745
1746     /* Issue TPM_Quote */
1747     result = Tspi_TPM_Quote2(
1748                 hTPM,
1749                 hKey,
1750                 FALSE,  // or TRUE, add version info
1751                 hPcrComposite,
1752                 &validation_data,
1753                 &versionInfoSize,
1754                 &versionInfo);
1755     if (result != TSS_SUCCESS) {
1756         if (result == 0x01) {
1757             ERROR("Tspi_TPM_Quote failed rc=0x%04x\n", result);
1758             fprintf(stderr, NLS(MS_OPENPTS, OPENPTS_TSS_AUTH_FAILED, "Authorization failed, needs valid password\n"));
1759         } else {
1760             ERROR("Tspi_TPM_Quote failed rc=0x%04x\n", result);
1761         }
1762         goto free;
1763     }
1764
1765     if (isDebugFlagSet(DEBUG_FLAG)) {
1766         DEBUG("TPM_Quote2\n");
1767         debugHex(NLS(MS_OPENPTS, OPENPTS_TSS_EXT_DATA, "External Data:"),
1768             validation_data.rgbExternalData,
1769             validation_data.ulExternalDataLength, "\n");
1770         debugHex(NLS(MS_OPENPTS, OPENPTS_TSS_DATA, "Data:"),
1771             validation_data.rgbData,
1772             validation_data.ulDataLength, "\n");
1773         debugHex(NLS(MS_OPENPTS, OPENPTS_TSS_VALIDATION_DATA, "Validation Data:"),
1774             validation_data.rgbValidationData,
1775             validation_data.ulValidationDataLength, "\n");
1776         if (versionInfoSize > 0) {
1777             debugHex(NLS(MS_OPENPTS, OPENPTS_TSS_VERSION_INFO, "Version Info:"),
1778                 versionInfo,
1779                 versionInfoSize, "\n");
1780         }
1781     }
1782
1783     /* Get PCR values used by Quote */
1784     for (i = 0; i < (int) pcrnum; i++) {  // TODO pcrs->pcr_num
1785         if (pcrs->pcr_select[i] == 1) {
1786             UINT32 length;
1787             BYTE *data;
1788 #if 0
1789             // 2011-02-15 SM can not get the PCR values, TSS bug?
1790             result = Tspi_PcrComposite_GetPcrValue(
1791                         hPcrComposite, i,
1792                         &length, &data);
1793             if (result != TSS_SUCCESS) {
1794                 ERROR("Tspi_PcrComposite_GetPcrValue failed rc=0x%x\n",
1795                         result);
1796                 goto free;
1797             }
1798 #else
1799             // 2011-02-15 SM  read Pcr value from TPM
1800             result = Tspi_TPM_PcrRead(
1801                 hTPM, i, &length, &data);
1802             if (result != TSS_SUCCESS) {
1803                 ERROR("Tspi_TPM_PcrRead failed rc=0x%x\n", result);
1804                 goto free;
1805             }
1806 #endif
1807
1808             if (length < MAX_DIGEST_SIZE) {
1809                 memcpy(&pcrs->pcr[i], data, length);
1810                 if (isDebugFlagSet(DEBUG_FLAG)) {
1811                     // DEBUG("PCR[%d]", i);
1812                     debugHex("             : ", data, length, "\n");
1813                 }
1814             } else {
1815                 fprintf(stderr, NLS(MS_OPENPTS, OPENPTS_TSS_PCR_SIZE_TOO_BIG,
1816                     "PCR size is too big %d > %d\n"), length, MAX_DIGEST_SIZE);
1817             }
1818
1819             Tspi_Context_FreeMemory(hContext, data);
1820         }
1821     }
1822
1823
1824
1825     /* Store Validation Data Structure */
1826     //    TPM_QUOTE_INFO2 structure
1827     //  0:1  TAG       00 36  = TPM_TAG_QUOTE_INFO2
1828     //  2:5  BYTE[4]   51 55 54 32  QUOT2
1829     //  6:25 TPM_NONCE 5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A
1830     //       TPM_PCR_INFO_SHORT
1831     // 26:30   TPM_PCR_SELECTION 0003 FF 00 00
1832     // 31      LOCALITY          01
1833     // 32:51   COPMPOSIT_HASH    A57A3A1E62C3D391E015CCB9167453D5FBBC9E53
1834     //     ???                  0030 01 02 04 00 000202494E544300080004000000030464
1835     //       TPM_CAP_VERSION_INFO  0030 01 02 04 00 000202494E544300080004000000030464
1836     //         TPM_STRUCTURE_TAG   0030         tag;
1837     //         TPM_VERSION         01 02 04 00  version;
1838     //         UINT16              0002   specLevel;
1839     //         BYTE                02     errataRev;
1840     //         BYTE                49 4E 54 43     tpmVendorID[4];
1841     //         UINT16              0008        vendorSpecificSize;
1842     //         SIZEIS(vendorSpecificSize)
1843     //           BYTE              0004 0000 0003 0464 *vendorSpecific;
1844     //
1845     // 2+4+20+5+1+20 = 52
1846     // total 75-bytes???
1847     validationData->ulDataLength = validation_data.ulDataLength;
1848     validationData->rgbData = xmalloc(validation_data.ulDataLength);
1849     if (validationData->rgbData == NULL) {
1850         result = PTS_FATAL;
1851         goto free;
1852     }
1853     memcpy(
1854         validationData->rgbData,
1855         validation_data.rgbData,
1856         validation_data.ulDataLength);
1857
1858
1859     /* rgbValidationData */
1860     validationData->ulValidationDataLength = validation_data.ulValidationDataLength;
1861     validationData->rgbValidationData = xmalloc(validation_data.ulValidationDataLength);
1862     if (validationData->rgbValidationData == NULL) {
1863         result = PTS_FATAL;
1864         goto free;
1865     }
1866     memcpy(
1867         validationData->rgbValidationData,
1868         validation_data.rgbValidationData,
1869         validation_data.ulValidationDataLength);
1870
1871     /* version */
1872     // get from validationData->rgbData (used by Quote)
1873     // validationData->versionInfo.bMajor    = validationData->rgbData[0];
1874     // validationData->versionInfo.bMinor    = validationData->rgbData[1];
1875     // validationData->versionInfo.bRevMajor = validationData->rgbData[2];
1876     // validationData->versionInfo.bRevMinor = validationData->rgbData[3];
1877
1878     /* Validation */
1879     // TODO
1880
1881   free:
1882     Tspi_Context_FreeMemory(hContext, NULL);
1883     Tspi_Context_CloseObject(hContext, hPcrComposite);
1884     Tspi_Context_CloseObject(hContext, hKey);
1885
1886     /* Close TSS/TPM */
1887   close:
1888     Tspi_Context_Close(hContext);
1889
1890     return result;
1891 }
1892
1893 /**
1894  * get ramdom value from TPM
1895  *
1896  * Return
1897  *   TSS_SUCCESS
1898  *
1899  * TODO if TPM/TSS is missing, use pseudo ramdom -- added
1900  *
1901  * UnitTest: check_tss.c / test_getRandom
1902  */
1903 int getRandom(BYTE *out, int size) {
1904     TSS_RESULT result;
1905     TSS_HCONTEXT hContext;
1906     TSS_HTPM hTPM;
1907     BYTE *buf;
1908
1909     /* Connect to TCSD */
1910     result = Tspi_Context_Create(&hContext);
1911     if (result != TSS_SUCCESS) {
1912         ERROR("Tspi_Context_Create failed rc=0x%x\n", result);
1913         if (result == 0x3011) {
1914             OUTPUT(NLS(MS_OPENPTS, OPENPTS_TPM_TSS_COMMS_FAILURE, "TSS communications failure. Is tcsd running?\n"));
1915         }
1916         goto close;
1917     }
1918
1919     result = Tspi_Context_Connect(hContext, SERVER);
1920     if (result != TSS_SUCCESS) {
1921         ERROR("Tspi_Context_Connect failed rc=0x%x\n", result);
1922         goto close;
1923     }
1924
1925     /* Get TPM handle */
1926     result = Tspi_Context_GetTpmObject(hContext, &hTPM);
1927     if (result != TSS_SUCCESS) {
1928         ERROR("Tspi_Context_GetTpmObject failed rc=0x%x\n", result);
1929         goto close;
1930     }
1931
1932
1933     /* get Random*/
1934     result = Tspi_TPM_GetRandom(hTPM, size, &buf);
1935     if (result != TSS_SUCCESS) {
1936             ERROR
1937                 ("Tspi_TPM_GetRandom failed rc=0x%x\n",
1938                  result);
1939             Tspi_Context_FreeMemory(hContext, NULL);
1940             goto free;
1941     }
1942     memcpy(out, buf, size);
1943
1944     DEBUG("Get ramdom data from TPM");
1945     if (isDebugFlagSet(DEBUG_FLAG)) {
1946         debugHex(" - random:", buf, size, "\n");
1947     }
1948
1949   free:
1950     Tspi_Context_FreeMemory(hContext, buf);
1951
1952   close:
1953     /* Close TSS/TPM */
1954     Tspi_Context_Close(hContext);
1955     return result;
1956 }
1957
1958 /**
1959  * Extend Event
1960  *
1961  */
1962 int extendEvent(TSS_PCR_EVENT* event) {
1963     TSS_RESULT result;
1964     TSS_HCONTEXT hContext;
1965     TSS_HTPM hTPM;
1966     BYTE *pcr0 = NULL;
1967     UINT32  pcr_len = 0;
1968     BYTE*   pcr = NULL;
1969
1970
1971     /* Connect to TCSD */
1972     result = Tspi_Context_Create(&hContext);
1973     if (result != TSS_SUCCESS) {
1974         ERROR("Tspi_Context_Create failed rc=0x%x\n", result);
1975         if (result == 0x3011) {
1976             OUTPUT(NLS(MS_OPENPTS, OPENPTS_TPM_TSS_COMMS_FAILURE, "TSS communications failure. Is tcsd running?\n"));
1977         }
1978         goto close;
1979     }
1980
1981     result = Tspi_Context_Connect(hContext, SERVER);
1982     if (result != TSS_SUCCESS) {
1983         ERROR("Tspi_Context_Connect failed rc=0x%x\n", result);
1984         goto close;
1985     }
1986
1987     /* Get TPM handle */
1988     result = Tspi_Context_GetTpmObject(hContext, &hTPM);
1989     if (result != TSS_SUCCESS) {
1990         ERROR("Tspi_Context_GetTpmObject failed rc=0x%x\n", result);
1991         goto close;
1992     }
1993
1994     // 2011-02-21 SM pcr0=NULL -> 0x3003 BAD_PARAMETOR error
1995     pcr0 = xmalloc_assert(20);
1996     memset(pcr0, 0, 20);
1997
1998     /* Extend */
1999     result = Tspi_TPM_PcrExtend(
2000                 hTPM,
2001                 event->ulPcrIndex,
2002                 20,
2003                 pcr0,  // TODO ??
2004                 event,
2005                 &pcr_len,
2006                 &pcr);
2007     if (result != TSS_SUCCESS) {
2008             ERROR
2009                 ("Tspi_TPM_PcrExtend failed rc=0x%x\n",
2010                  result);
2011             // Tspi_Context_FreeMemory(hContext, NULL);
2012             goto close;
2013     }
2014
2015     // TODO free some?
2016     xfree(pcr0);
2017
2018   close:
2019     /* Close TSS/TPM */
2020     Tspi_Context_Close(hContext);
2021     return result;
2022 }
2023
2024 /**
2025  * read PCR
2026  * call must prepare the buffer for pcr
2027  */
2028 int readPcr(int pcr_index, BYTE *pcr) {
2029     TSS_RESULT result;
2030     TSS_HCONTEXT hContext;
2031     TSS_HTPM hTPM;
2032     UINT32  data_len = 0;
2033     BYTE*   data = NULL;
2034
2035
2036     /* Connect to TCSD */
2037     result = Tspi_Context_Create(&hContext);
2038     if (result != TSS_SUCCESS) {
2039         ERROR("Tspi_Context_Create failed rc=0x%x\n", result);
2040         if (result == 0x3011) {
2041             OUTPUT(NLS(MS_OPENPTS, OPENPTS_TPM_TSS_COMMS_FAILURE, "TSS communications failure. Is tcsd running?\n"));
2042         }
2043         goto close;
2044     }
2045
2046     result = Tspi_Context_Connect(hContext, SERVER);
2047     if (result != TSS_SUCCESS) {
2048         ERROR("Tspi_Context_Connect failed rc=0x%x\n", result);
2049         goto close;
2050     }
2051
2052     /* Get TPM handle */
2053     result = Tspi_Context_GetTpmObject(hContext, &hTPM);
2054     if (result != TSS_SUCCESS) {
2055         ERROR("Tspi_Context_GetTpmObject failed rc=0x%x\n", result);
2056         goto close;
2057     }
2058
2059     result = Tspi_TPM_PcrRead(
2060         hTPM, pcr_index, &data_len, &data);
2061     if (result != TSS_SUCCESS) {
2062         ERROR("Tspi_TPM_PcrRead failed rc=0x%x\n", result);
2063         goto close;
2064     }
2065     if (data_len != SHA1_DIGEST_SIZE) {
2066         ERROR("Bad PCR size %d\n", data_len);
2067         result = PTS_INTERNAL_ERROR;
2068     } else {
2069         memcpy(pcr, data, SHA1_DIGEST_SIZE);
2070     }
2071
2072   close:
2073     /* Close TSS/TPM */
2074     Tspi_Context_Close(hContext);
2075     return result;
2076 }
2077 #endif  // !CONFIG_NO_TSS
2078
2079
2080 /* Verifier side */
2081
2082
2083 /**
2084  * validate QuoteData
2085  *
2086  * - TPM_SS_RSASSAPKCS1v15_SHA1 ONLY
2087  * - TPM_Quote
2088  * - TPM_Quote2
2089  *
2090  *  Return
2091  *    PTS_SUCCESS
2092  *    PTS_VERIFY_FAILED
2093  *    PTS_INTERNAL_ERROR
2094  *
2095  *  OLD return 1: OK
2096  */
2097 int validateQuoteData(OPENPTS_PCRS *pcrs, TSS_VALIDATION *validationData) {
2098     int rc = PTS_VERIFY_FAILED;
2099     int message_length;
2100     BYTE *message;
2101     SHA_CTX ctx;
2102     int hash_length;
2103     BYTE *hash;
2104     int signature_length;
2105     BYTE *signature;
2106     int pubkey_length;
2107     BYTE *pubkey;
2108     RSA *rsa = NULL;
2109     BIGNUM *rsa_e = NULL;
2110     BIGNUM *rsa_n = NULL;
2111     BYTE exp[4] = {0x00, 0x01, 0x00, 0x01};
2112
2113     /* check */
2114     if (pcrs == NULL) {
2115         ERROR("validateQuoteData - pcrs is NULL\n");
2116         return PTS_INTERNAL_ERROR;
2117     }
2118     if (pcrs->pubkey_length == 0) {
2119         ERROR("validateQuoteData - pcrs->pubkey_length is ZERO\n");
2120         return PTS_INTERNAL_ERROR;
2121     }
2122     if (pcrs->pubkey == NULL) {
2123         ERROR("validateQuoteData - pcrs->pubkey is NULL\n");
2124         return PTS_INTERNAL_ERROR;
2125     }
2126
2127     /* message */
2128     if (validationData->ulDataLength == 48) {
2129         DEBUG("Quote\n");
2130     } else if (validationData->ulDataLength == 52) {
2131         DEBUG("Quote2\n");
2132     } else {
2133         ERROR("validationData->ulDataLength != 48/52, but %d\n",
2134             validationData->ulDataLength);
2135         return PTS_INTERNAL_ERROR;
2136     }
2137
2138     if (validationData->ulExternalDataLength != 20) {
2139         ERROR("validationData->ulExternalDataLength != 20, but %d\n",
2140             validationData->ulExternalDataLength);
2141         return PTS_INTERNAL_ERROR;
2142     }
2143
2144     message_length = validationData->ulDataLength;
2145     message = validationData->rgbData;
2146
2147     /* hash */
2148     hash_length = 20;  // TODO
2149     hash = xmalloc_assert(20);
2150     SHA1_Init(&ctx);
2151     SHA1_Update(&ctx, message, message_length);
2152     SHA1_Final(hash, &ctx);
2153
2154     /* signature */
2155     signature_length = validationData->ulValidationDataLength;
2156     signature = validationData->rgbValidationData;
2157
2158     /* pubkey */
2159     /*
2160     PUB KEY BLOB    
2161
2162     [284 = 28 + 256 ]
2163     00000001  TPM_ALGORITHM_ID  algorithmID << TPM_KEY_PARMS     algorithmParms;
2164     0001      TPM_ENC_SCHEME    encScheme; 0001 => TPM_ES_NONE 
2165     0002      TPM_SIG_SCHEME    sigScheme; 0002 => TPM_SS_RSASSAPKCS1v15_SHA1 
2166     0000000C  UINT32            parmSize = 12
2167     00000800
2168     00000002
2169     00000000
2170
2171     00000100  UINT32    keyLength = 256 
2172     734AA85F2DDFD5D7AC09081681537D...
2173
2174     */
2175
2176     // TODO 2048 bit key only
2177     pubkey_length = 256;  // TODO
2178     pubkey = &pcrs->pubkey[28];  // TODO use struct
2179
2180     // pubkey_length = 257;
2181     // pubkey = malloc(pubkey_length);
2182     // pubkey[0] = 0;
2183     // memcpy(&pubkey[1],&pcrs->pubkey[28], 256);
2184
2185 #if 0
2186     TODO("\n");
2187     printHex("message   :", message, message_length, "\n");
2188     printHex("hash      :", hash, hash_length, "\n");
2189     printHex("signature :", signature, signature_length, "\n");
2190     printHex("pubkey    :", pubkey, pubkey_length, "\n");
2191 #endif
2192
2193     /* setup RSA key */
2194     rsa = RSA_new();
2195
2196     /* exp */
2197     rsa_e = BN_new();
2198     BN_bin2bn(exp, 4, rsa_e);
2199
2200     /* n */
2201     rsa_n = BN_new();
2202     BN_bin2bn(pubkey, pubkey_length, rsa_n);
2203
2204     BN_hex2bn(&(rsa->n), BN_bn2hex(rsa_n));
2205     BN_hex2bn(&(rsa->e), BN_bn2hex(rsa_e));
2206
2207     // DEBUG("RSA_verify\n");
2208     /* RSA verify  1: success, 0:otherwise */
2209     rc = RSA_verify(
2210             NID_sha1,  // hash type,
2211             hash,
2212             hash_length,
2213             signature,
2214             signature_length,
2215             rsa);
2216
2217     /* free RSA key */
2218     RSA_free(rsa);
2219     BN_free(rsa_e);
2220     BN_free(rsa_n);
2221
2222     if (hash != NULL) {
2223         xfree(hash);
2224     }
2225
2226     /* DEBUG */
2227     if (isDebugFlagSet(DEBUG_FLAG)) {
2228         DEBUG("validateQuoteData - rc = %d (1:success)\n", rc);
2229         debugHex(NLS(MS_OPENPTS, OPENPTS_TSS_PUBKEY, "pubkey: "), pubkey, pubkey_length, "\n");
2230         debugHex(NLS(MS_OPENPTS, OPENPTS_TSS_MSG, "message: "), message, message_length, "\n");
2231         debugHex(NLS(MS_OPENPTS, OPENPTS_TSS_SIGNATURE, "signature: "), signature, signature_length, "\n");
2232     }
2233
2234     /**/
2235     // xfree(message);
2236
2237     if (rc == 1) {
2238         /* RSA verify - success */
2239         return PTS_SUCCESS;
2240     } else {
2241         /* RSA verify - fail */
2242         UINT32 e;  // unsigned long
2243         ERR_load_crypto_strings();
2244         e = ERR_get_error();
2245         ERROR("RSA_verify failed, %s\n", ERR_error_string(e, NULL));
2246         ERROR("   %s\n", ERR_lib_error_string(e));
2247         ERROR("   %s\n", ERR_func_error_string(e));
2248         ERROR("   %s\n", ERR_reason_error_string(e));
2249         ERR_free_strings();
2250         return PTS_VERIFY_FAILED;
2251     }
2252 }
2253
2254 /**
2255  *  Validate PCR Composite (TPM/TSS v1.1 PCR[0-15])
2256  *
2257  *  Return
2258  *    PTS_SUCCESS
2259  *    PTS_VERIFY_FAILED
2260  *    PTS_INTERNAL_ERROR
2261  */
2262 int validatePcrCompositeV11(OPENPTS_PCRS *pcrs, TSS_VALIDATION *validationData) {
2263     int rc = PTS_VERIFY_FAILED;
2264     int i;
2265     int buf_len;
2266     BYTE *buf;
2267     BYTE *ptr;
2268     SHA_CTX ctx;
2269     BYTE digest[20];
2270     UINT16 mask = 0;
2271     int count = 0;
2272     int value_size;
2273
2274     /* check */
2275     if (validationData == NULL) {
2276         ERROR("validationData == NULL\n");
2277         return PTS_INTERNAL_ERROR;
2278     }
2279
2280     if (validationData->rgbData == NULL) {
2281         ERROR("validationData->rgbData == NULL\n");
2282         return PTS_INTERNAL_ERROR;
2283     }
2284     if (validationData->ulDataLength != 48) {
2285         ERROR("validationData->ulDataLength != 48, but %d\n",
2286             validationData->ulDataLength);
2287         return PTS_INTERNAL_ERROR;
2288     }
2289
2290
2291     /* setup PCR composite */
2292     // PCR Select is confusing
2293     // PCR 0,1,2,3,4,5,6,7,8,10 => FF 05
2294     for (i = 15; i > 0; i--) {  // 15-1
2295         if (pcrs->pcr_select[i] == 1) {
2296             mask += 1;
2297             count++;
2298             DEBUG("validatePcrCompositeV11() - PCR[%d] - selected\n", i);
2299         }
2300         mask = mask << 1;
2301     }
2302     if (pcrs->pcr_select[i] == 1) {  // 0
2303         mask = mask + 1;
2304         count++;
2305         DEBUG("validatePcrCompositeV11() - PCR[%d] - selected\n", i);
2306     }
2307
2308     /* set ValueSize */
2309     value_size = 20 * count;
2310     buf_len = 2 + 2 + 4 + value_size;
2311     buf = xmalloc(buf_len);
2312     if (buf == NULL) {
2313         return PTS_INTERNAL_ERROR;
2314     }
2315     memset(buf, 0, buf_len);
2316
2317     /* PCR select size, UINT16 */
2318     buf[0] = 0;
2319     buf[1] = 2;
2320
2321     /* select, 2 bytes*/
2322     buf[2] = mask & 0xFF;
2323     buf[3] = (mask >> 8) & 0xFF;
2324
2325     /* Value Size, UINT32 */
2326     buf[4] = 0;
2327     buf[5] = 0;
2328     buf[6] = (value_size >> 8)& 0xFF;
2329     buf[7] = value_size & 0xFF;
2330
2331     /* PCR values */
2332     ptr = &buf[8];
2333     for (i = 0; i < 16; i++) {
2334         if (pcrs->pcr_select[i] == 1) {
2335             memcpy(ptr, pcrs->pcr[i], 20);
2336             ptr += 20;
2337         }
2338     }
2339
2340     /* calc hash */
2341     SHA1_Init(&ctx);
2342     SHA1_Update(&ctx, buf, buf_len);
2343     SHA1_Final(digest, &ctx);
2344
2345     if (isDebugFlagSet(DEBUG_FLAG)) {
2346         DEBUG("pcr composite\n");
2347         debugHex(NLS(MS_OPENPTS, OPENPTS_TSS_BUF, "   buf:"), buf, buf_len, "\n");
2348         debugHex(NLS(MS_OPENPTS, OPENPTS_TSS_DIGEST, "   digest:"), digest, 20, "\n");
2349         DEBUG("select size : %d\n", 2);
2350         DEBUG("select      : 0x%X\n", mask);
2351     }
2352
2353 #if 0
2354     printHex(
2355         "Digest  :", digest, 20, "\n");
2356     printHex(
2357         "rgbData :",
2358         &validationData->rgbData[8],
2359         20, "\n");
2360 #endif
2361
2362     /* check */
2363     if (memcmp(digest, &validationData->rgbData[8], 20) == 0) {
2364     // if (memcmp(digest, validationData->rgbData, 20) == 0) {
2365         /* HIT valid composit */
2366         rc = PTS_SUCCESS;
2367     } else {
2368         DEBUG("validatePcrCompositeV11() - bad digest\n");
2369     }
2370
2371     if (rc != PTS_SUCCESS) {
2372         /* why? */
2373         DEBUG("validatePcrCompositeV11() - validation fail, rc = %d\n", rc);
2374     }
2375
2376
2377     /* free */
2378     xfree(buf);
2379
2380     return rc;
2381 }
2382
2383 /**
2384  *  Validate PCR Composite (TPM/TSS v1.2 PCR[0-23])
2385  *
2386  *  Return
2387  *    PTS_SUCCESS
2388  *    PTS_VERIFY_FAILED
2389  *    PTS_INTERNAL_ERROR
2390  */
2391 int validatePcrCompositeV12(OPENPTS_PCRS *pcrs, TSS_VALIDATION *validationData) {
2392     int rc = PTS_VERIFY_FAILED;
2393     int i;
2394     int buf_len;
2395     BYTE *buf;
2396     BYTE *ptr;
2397     SHA_CTX ctx;
2398     BYTE digest[20];
2399     UINT32 mask = 0;
2400     int count = 0;
2401     int value_size;
2402     int pcrsel_size;
2403     int loc = 0;
2404     BYTE *composit_hash;
2405
2406     /* check */
2407     if (validationData == NULL) {
2408         ERROR("validationData == NULL\n");
2409         return PTS_INTERNAL_ERROR;
2410     }
2411
2412     if (validationData->rgbData == NULL) {
2413         ERROR("validationData->rgbData == NULL\n");
2414         return PTS_INTERNAL_ERROR;
2415     }
2416
2417     // TODO identify Quote/Quote2 not using the data length
2418     if (validationData->ulDataLength == 48) {
2419         // Quote
2420         pcrsel_size = 2;
2421         composit_hash = &validationData->rgbData[8];
2422     } else if (validationData->ulDataLength == 52) {
2423         // Quote2
2424         pcrsel_size = 3;
2425         composit_hash = &validationData->rgbData[32];
2426     } else  {
2427         ERROR("validationData->ulDataLength != 48 or 52, but %d\n",
2428             validationData->ulDataLength);
2429         return PTS_INTERNAL_ERROR;
2430     }
2431
2432
2433     /* setup PCR composite */
2434     // PCR Select is confusing
2435     // PCR 0,1,2,3,4,5,6,7,8,10 => FF 05
2436     for (i = 23; i > 0; i--) {  // 23-1
2437         if (pcrs->pcr_select[i] == 1) {
2438             mask += 1;
2439             count++;
2440             DEBUG("validatePcrCompositeV12() - PCR[%d] - selected\n", i);
2441         }
2442         mask = mask << 1;
2443     }
2444     if (pcrs->pcr_select[i] == 1) {  // 0
2445         mask = mask + 1;
2446         count++;
2447         DEBUG("validatePcrCompositeV12() - PCR[%d] - selected\n", i);
2448     }
2449
2450     /* pcr sel size */
2451     // TODO ?
2452 #if 0
2453     if (((mask >> 16) & 0xFF) != 0) {
2454         pcrsel_size = 3;
2455     } else if (((mask >> 8) & 0xFF) != 0) {
2456         pcrsel_size = 2;
2457     } else {
2458         pcrsel_size = 1;
2459     }
2460 #endif
2461
2462     /* set ValueSize */
2463     value_size = 20 * count;
2464     buf_len = 2 + pcrsel_size + 4 + value_size;
2465     buf = xmalloc(buf_len);
2466     if (buf == NULL) {
2467         return PTS_INTERNAL_ERROR;
2468     }
2469     memset(buf, 0, buf_len);
2470
2471     /* PCR select size, UINT16 */
2472     buf[0] = 0;
2473     buf[1] = pcrsel_size;
2474
2475     /* select, 3 bytes*/
2476     loc = 2;
2477     buf[loc] = mask & 0xFF;
2478     buf[loc + 1] = (mask >> 8) & 0xFF;
2479     buf[loc + 2] = (mask >> 16) & 0xFF;
2480     loc += pcrsel_size;
2481
2482     /* Value Size, UINT32 */
2483     buf[loc] = 0;
2484     buf[loc + 1] = 0;
2485     buf[loc + 2] = (value_size >> 8)& 0xFF;
2486     buf[loc + 3] = value_size & 0xFF;
2487     loc += 4;
2488     /* PCR values */
2489     ptr = &buf[loc];
2490     for (i = 0; i < MAX_PCRNUM; i++) {
2491         if (pcrs->pcr_select[i] == 1) {
2492             memcpy(ptr, pcrs->pcr[i], 20);
2493             ptr += 20;
2494         }
2495     }
2496
2497     /* calc hash */
2498     SHA1_Init(&ctx);
2499     SHA1_Update(&ctx, buf, buf_len);
2500     SHA1_Final(digest, &ctx);
2501
2502     if (isDebugFlagSet(DEBUG_FLAG)) {
2503         DEBUG("PcrComposit\n");
2504         debugHex(NLS(MS_OPENPTS, OPENPTS_TSS_BUF, "   buf:"), buf, buf_len, "\n");
2505         debugHex(NLS(MS_OPENPTS, OPENPTS_TSS_DIGEST, "   digest:"), digest, 20, "\n");
2506         DEBUG("PcrComposit - select size   : %d\n", pcrsel_size);
2507         DEBUG("PcrComposit - bit mask      : 0x%08X\n", mask);
2508     }
2509
2510     /* check */
2511     if (memcmp(digest, composit_hash , 20) == 0) {
2512     // if (memcmp(digest, validationData->rgbData, 20) == 0) {
2513         /* HIT valid composit */
2514         rc = PTS_SUCCESS;
2515     } else {
2516         DEBUG("validatePcrCompositeV12() - bad digest\n");
2517         if (isDebugFlagSet(DEBUG_FLAG)) {
2518             debugHex("  calc    :", digest, 20, "\n");
2519             debugHex("  given   :", composit_hash, 20, "\n");
2520         }
2521     }
2522
2523     if (rc != PTS_SUCCESS) {
2524         /* why? */
2525         DEBUG("validatePcrCompositeV12() - validation fail, rc = %d\n", rc);
2526         // 34 PTS_VERIFY_FAILED
2527     }
2528
2529     /* free */
2530     xfree(buf);
2531
2532     return rc;
2533 }
2534
2535