OSDN Git Service

1fccca327f230f2c9dd065207f97205cb517eaf4
[openpts/openpts.git] / src / iml2text.c
1 /*
2  * The Initial Developer of the Original Code is International
3  * Business Machines Corporation. Portions created by IBM
4  * Corporation are Copyright (C) 2007,2010 International Business
5  * Machines Corporation. All Rights Reserved.
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the Common Public License as published by
9  * IBM Corporation; either version 1 of the License, or (at your option)
10  * any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * Common Public License for more details.
16  *
17  * You should have received a copy of the Common Public License
18  * along with this program; if not, a copy can be viewed at
19  * http://www.opensource.org/licenses/cpl1.0.php.
20  */
21
22 /**
23  * \file src/iml2text.c
24  * \brief Convert binary IML file to plaintext
25  * @author Seiji Munetoh <munetoh@users.sourceforge.jp>
26  * @date 2010-08-25
27  * cleanup 2011-08-17 SM
28  *
29  * show eventlog (get though TSS)
30  *
31  *   ./src/iml2text
32  *
33  * show eventlog (binary eventlog file)
34  *
35  *   ./src/iml2text -i tests/data/ThinkpadX200_Fedora12/binary_bios_measurements
36  *
37  * show BE(big-endian) event on LE host
38  *
39  *   ./src/iml2text -E -i tests/data/XXX/example_event_log
40  *
41  */
42
43 /*
44  * References:
45  * [1] BIOS https://www.trustedcomputinggroup.org/specs/PCClient/
46  *     Ref PC Spec v1.2, p74
47  *       UINT32   pcrIndex
48  *       UINT32   eventType
49  *       BYTE[20] digest
50  *       UINT32   eventDataSize
51  *       BYTE[]   event
52  *
53  * [2] GRUB-IMA, see BIOS format
54  * [3] Linux-IMA
55  * [4] LIM/IMA
56  *
57  *     boot aggregate = sha1(PCR[0],PCR[1],,,PCR[7])
58  *
59  *     /sys/kernel/security/ima/binary_runtime_measurements
60  *          UINT32 pcr
61  *          BYTE   template_hash[20]
62  *          UNIT32 name_len
63  *          BYTE   name[name_len]
64  *          BYTE   digest[20]
65  *          UNIT32 filename_len
66  *          CHAR   filename[filename_len]
67  *
68  *       ima_data
69  *          BYTE   digest[20]
70  *          CHAR   filename[filename_len]
71  *
72  *       template_hash = SHA1(ima_data) = SHA1(digest + filename)
73  *
74  *     Through TSS (TBD)
75  *
76  *
77  */
78
79 #include <stdio.h>
80 #include <stdlib.h>
81 #include <string.h>
82 #include <unistd.h>
83 #include <stdint.h>
84
85 #ifndef __STDC_FORMAT_MACROS
86 #define __STDC_FORMAT_MACROS
87 #include <inttypes.h>
88 #endif
89
90 #include <openssl/sha.h>
91
92 #include <openpts.h>
93
94 #ifdef CONFIG_TBOOT
95 #include <openpts_tboot.h>
96 #endif
97
98 // Local TCSD
99 #define SERVER    NULL
100
101
102 // PCR
103 BYTE pcr[24][20];
104
105 // Verbose Counter
106 //       0 no
107 // -v    1 show event data contents
108 // -v -v 2 DEBUG
109 int verbose_cnt = 0;
110 int verbose = 0;
111
112 char *indent = "                                                              ";
113
114 // Check the consistence of IML and PCRs
115 int verify = 0;
116
117 /*
118
119  TPM PCR Read
120
121  Usage:
122   tpm_pcrread -p index
123
124  */
125
126 int hex2bin(void *dest, const void *src, size_t n);
127 void printhex(char *str, unsigned char *buf, int len);
128
129
130 #define BUFSIZE 4096
131 // State
132 int pcr4_grub = 0;
133 int pcr5_grub = 0;
134
135 #define IMA32 32
136 int ima_mode = 0;
137
138 /* EFI */
139 typedef UINT64 EFI_PHISICAL_ADDRESS;
140 typedef UINT64 UINTN;
141 typedef wchar_t CHAR16;
142 typedef BYTE UINT8;
143 typedef BYTE INT8;
144 typedef void VOID;
145 typedef BYTE EFI_DEVICE_PATH;  // TODO
146 typedef struct {
147     UINT32 Data1;
148     UINT16 Data2;
149     UINT16 Data3;
150     UINT8  Data4[8];
151 } EFI_GUID;
152
153
154 typedef struct tdEFI_PLATFORM_FIRMWARE_BLOB {
155     EFI_PHISICAL_ADDRESS    BlobBase;
156     UINTN                   BlobLength;
157 } EFI_PLATFORM_FIRMWARE_BLOB;
158
159 typedef struct tdEFI_IMAGE_LOAD_EVENT {
160     EFI_PHISICAL_ADDRESS    ImageLocationInMemory;
161     UINTN                   ImageLengthInMemory;
162     UINTN                   ImageLinkTimeAddress;
163     UINTN                   LengthOfDevicePath;
164     EFI_DEVICE_PATH         DevicePath[1];
165 } EFI_IMAGE_LOAD_EVENT;
166
167
168 typedef struct tdEFI_CONFIGULATION_TABLE {
169     EFI_GUID VendorGuid;
170     VOID    *VentorTable;
171 } EFI_CONFIGULATION_TABLE;
172
173 typedef struct tdEFI_HANDOFF_TABLE_POINTERS {
174     UINTN                   NumberOfTables;
175     EFI_CONFIGULATION_TABLE TableEntry[1];
176 } EFI_HANDOFF_TABLE_POINTERS;
177
178
179 typedef struct tdEFI_VARIABLE_DATA {
180     EFI_GUID    ValiableName;
181     UINTN       UnicodeNameLength;
182     UINTN       VariableDataLength;
183     CHAR16      UnicodeName[1];
184     INT8        VariableData[1];
185 } EFI_VARIABLE_DATA;
186
187
188 void fprintGuid(FILE *fp, EFI_GUID guid) {
189     fprintf(fp, "GUID=%08x-", guid.Data1);
190     fprintf(fp, "%04x-", guid.Data2);
191     fprintf(fp, "%04x-", guid.Data3);
192     fprintf(fp, "%02x-", guid.Data4[0]);
193     fprintf(fp, "%02x-", guid.Data4[1]);
194     fprintf(fp, "%02x-", guid.Data4[2]);
195     fprintf(fp, "%02x-", guid.Data4[3]);
196     fprintf(fp, "%02x-", guid.Data4[4]);
197     fprintf(fp, "%02x-", guid.Data4[5]);
198     fprintf(fp, "%02x-", guid.Data4[6]);
199     fprintf(fp, "%02x",  guid.Data4[7]);
200 }
201
202 void fprintBin(FILE* fp, BYTE* data, UINT32 len) {
203     int i;
204     for (i = 0; i < (int)len; i++) {
205         fputc(data[i], fp);
206     }
207 }
208
209 void fprintHex(FILE* fp, BYTE* data, UINT32 len) {
210     int i;
211     for (i = 0; i < (int)len; i++) {
212         fprintf(fp, "%02x", data[i]);
213     }
214 }
215
216
217 void fprintChar(FILE* fp, BYTE* data, UINT32 len) {
218     int i;
219     for (i = 0; i < (int)len; i++) {
220         if ((0x20 <= data[i]) && (data[i] < 0x7e)) {
221             fprintf(fp, "%c", data[i]);
222         } else {
223             fprintf(fp, ".");
224         }
225     }
226 }
227
228 // 61dfe48bca93d211aa0d00e098032b8c 0900000000000000 1a00000000000000
229 // 4200 6f00 6f00 7400 4f00 7200 6400 6500 7200 00000100020003000400050006000700080009000a000b000c00]
230 void fprintUnicode(FILE *fp, wchar_t * name, int len) {
231     int i;
232     char *u8;
233     u8 = (char *) name;
234     for (i = 0; i< len*2;i+=2) {
235         fprintf(fp, "%c", u8[i]);
236     }
237 }
238
239 /**
240  *  
241  */
242 void SHA1_UpdateUint32(SHA_CTX *c, UINT32 data) {
243     BYTE buf[4];
244     buf[0] = (data >> 24) & 0xff;
245     buf[1] = (data >> 16) & 0xff;
246     buf[2] = (data >> 8) & 0xff;
247     buf[3] = data & 0xff;
248     SHA1_Update(c, buf, 4);
249 }
250
251 /**
252  *
253  * TODO(munetoh) move to iml.c and be common 
254  */
255 void fprintEventData(
256         FILE* fp,
257         BYTE* data,  // event
258         UINT32 len,  // event length
259         UINT32 pcrindex,
260         UINT32 type,
261         BYTE*  digest) {
262     char buf[BUFSIZE];
263     char *b64buf; //[BUFSIZE];
264     int b64buf_len;
265     int i;
266
267     if (len < BUFSIZE) {
268         memcpy(buf, data, len);
269         buf[len]=0;  // terminate
270     } else {
271         memcpy(buf, data, BUFSIZE);
272         buf[BUFSIZE-1] = 0;  // terminate
273     }
274
275
276     if (pcrindex == 10) {  // Linux-IMA
277         if (type == 2) {
278             fprintf(fp, "[IMA-LKM:%s] ", buf);
279         } else if (type == 1) {
280             fprintf(fp, "[IMA-EXE:%s] ", buf);
281         } else if (type == 0) {
282             // fprintf(fp, "[IMA:%s] ", buf);
283             if (ima_mode == 32) {
284 /*
285 RHEL6 - Kernel 2.6.32
286 --------------------------------------------------------------------------------
287 0a 00 00 00
288 98 0a 38 ef 63 42 a5 d6 37 cf 96 47 b5 34 45 ac 13 98 d5 c7
289 03 00 00 00
290 69 6d 61 
291 0c d0 a1 73 28 b3 e0 93 a0 51 15 c1 44 23 eb 62 45 df 3b 32 
292 0e 00 00 00 
293 62 6f 6f 74 5f 61 67 67 72 65 67 61 74 65 | boot_aggregate|
294 --------------------------------------------------------------------------------
295 0a 00 00 00
296 c8 7f 4d ea 27 e3 3e 3c 6b 88 71 d7 fb bf ed e2 0f f1 78 7a 
297 03 00 00 00
298 69 6d 61                                  |.ima
299 ac 63 ec 16  2b 60 31 3a 88 96 e4 1a 57 0c 64 da bf 3b 16 ec
300 05 00 00 00 
301 2f 69 6e 69 74                              |./init|
302 --------------------------------------------------------------------------------
303
304 IML->TSS(Fix the format)->
305 EventData
306   BYTE[20] digest
307   BYTE[len-20] filename
308 */
309                 fprintf(fp, "[IMA:sha1(");
310                 fprintBin(fp, &data[20], len-20);
311                 fprintf(fp, ")=");
312                 fprintHex(fp, data, 20);
313                 fprintf(fp, "] ");
314
315             } else {
316                 fprintf(fp, "[IMA:(TBD)] ");
317             }
318         } else if ((type & 0xFFFF) == 4) {
319             fprintf(fp, "[IMA-USR,0x%04x:%s] ", (type >> 16), buf);
320         } else {
321             fprintf(fp, "[???:%s] ", buf);
322         }
323     } else if (pcrindex <= 8) {  // BIOS + Grub
324         switch (type) {
325         case 0:
326             fprintf(fp, "[BIOS:EV_PREBOOT_CERT(EV_CODE_CERT)]");
327             break;
328         case 1:
329             fprintf(fp, "[BIOS:EV_POST_CODE(EV_CODE_NOCERT)]");
330             break;
331         case 2:
332             fprintf(fp, "[BIOS:EV_UNUSED(EV_XML_CONFIG)]");
333             break;
334         case 3:
335             fprintf(fp, "[BIOS:EV_NO_ACTION]");
336             break;
337         case 4:
338             if ((pcr4_grub > 1) && (pcrindex == 4)) {
339                 fprintf(fp, "[GRUB:EV_SEPARATOR, %s]", buf);
340             } else if ((pcr5_grub > 0) && (pcrindex == 5)) {
341                 fprintf(fp, "[GRUB:EV_SEPARATOR, %s]", buf);
342             } else if (pcrindex == 8) {
343                 fprintf(fp, "[GRUB:EV_SEPARATOR, %s]", buf);
344             } else if (len == 4) {  // V1.2
345                 fprintf(fp, "[BIOS:EV_SEPARATOR, %02x%02x%02x%02x]",
346                         (unsigned char) buf[0],
347                         (unsigned char) buf[1],
348                         (unsigned char) buf[2],
349                         (unsigned char) buf[3]);
350             } else {
351                 fprintf(fp, "[BIOS:EV_SEPARATOR, %s]", buf);
352             }
353             break;
354         case 5:
355             if ((pcr5_grub > 0) && (pcrindex == 5)) {
356                 fprintf(fp, "[GRUB:EV_ACTION, %s]", buf);
357             } else {
358                 fprintf(fp, "[BIOS:EV_ACTION, %s]", buf);
359             }
360             break;
361         case 6:
362             if ((pcr4_grub > 1) && (pcrindex == 4)) {
363                 fprintf(fp, "[GRUB: measure MBR again]");
364             } else {
365                 fprintf(fp, "[BIOS:EV_EVENT_TAG(EV_PLATFORM_SPECIFIC)]");
366             }
367             break;
368         case 7:
369             fprintf(fp, "[BIOS:EV_S_CRTM_CONTENTS]");
370             break;
371         case 8:
372             fprintf(fp, "[BIOS:EV_S_CRTM_VERSION]");
373             if (verify == 1) {
374                 BYTE digest2[20];
375                 SHA_CTX ctx;
376                 SHA1_Init(&ctx);
377                 SHA1_Update(&ctx, data, len);
378                 SHA1_Final(digest2, &ctx);
379                 fprintf(fp, "\n                    ");
380                 fprintHex(fp, digest2, 20);
381                 fprintf(fp, " <= SHA1(Version[%d])", len);
382             }
383             if (verbose_cnt > 0) {
384                 fprintf(fp, "\n");
385                 fprintf(fp, "%sVersion(hex) : ", indent);
386                 fprintHex(fp, data, len);
387                 fprintf(fp, "\n%sVersion(char): ", indent);
388                 fprintChar(fp, data, len);
389             }
390             break;
391         case 9:
392             fprintf(fp, "[BIOS:EV_CPU_MICROCODE]");
393             break;
394         case 0x0a:
395             fprintf(fp, "[BIOS:EV_PLATFORM_CONFIG_FLAG)]");
396             break;
397         case 0x0b:
398             fprintf(fp, "[BIOS:EV_TABLE_OF_CONTENTS)]");
399             break;
400         case 0x0c:
401             fprintf(fp, "[BIOS:EV_COMPACT_HASH]");
402             break;
403         case 0x0d:
404             if (pcr4_grub == 0) {
405                 // BIOS
406                 fprintf(fp, "[BIOS:EV_IPL]");
407                 pcr4_grub = 1;
408             } else if (pcr4_grub == 1) {
409                 // GRUB
410                 fprintf(fp, "[GRUB:EV_IPL, Stage1(MBR)]");
411                 pcr4_grub = 2;
412             } else if (pcr4_grub == 2) {
413                 // GRUB
414                 fprintf(fp, "[GRUB:EV_IPL, Stage1.5]");
415                 pcr4_grub = 3;
416             } else if (pcr4_grub == 3) {
417                 // GRUB
418                 fprintf(fp, "[GRUB:EV_IPL, Stage1.5(filesystem)]");
419                 pcr4_grub = 4;
420             } else {
421                 // GRUB
422                 fprintf(fp, "[GRUB:EV_IPL]");
423             }
424             break;
425         case 0x0e:
426             if (pcr5_grub == 0) {
427                 fprintf(fp, "[BIOS:EV_IPL_PERTITION_DATA]");
428                 pcr5_grub = 1;
429             } else {
430                 fprintf(fp, "[GRUB:grub.conf]");
431             }
432             break;
433         case 0x0f:
434             fprintf(fp, "[BIOS:EV_NOHOST_CODE)]");
435             break;
436         case 0x10:
437             fprintf(fp, "[BIOS:EV_NOHOST_CONFIG]");
438             break;
439         case 0x11:
440             fprintf(fp, "[BIOS:EV_NOHOST_INFO]");
441             break;
442         case 0x12:
443             fprintf(fp, "[BIOS:EV_SPECIFICATION_IDENTIFIER 0x");
444             for (i = 0; i < (int)len; i++) {
445                 fprintf(fp, "%02x", (BYTE)buf[i]);
446             }
447             fprintf(fp, "]");
448             break;
449
450         case 0x80000001:  // EFI
451             fprintf(fp, "[BIOS:EV_EFI_VARIABLE_DRIVER_CONFIG,");
452             {
453                 EFI_VARIABLE_DATA *d = (EFI_VARIABLE_DATA *) buf;
454                 fprintGuid(fp, d->ValiableName);
455                 fprintf(fp, ",Name=");
456                 fprintUnicode(fp, d->UnicodeName, d->UnicodeNameLength);
457                 fprintf(fp, ",Valiable[0x%" PRIx64 "]", (UINT64)d->VariableDataLength);
458             }
459             fprintf(fp, "]");
460             break;
461         case 0x80000002:  // EFI
462             fprintf(fp, "[BIOS:EV_EFI_VARIABLE_BOOT,");
463             {
464                 EFI_VARIABLE_DATA *d = (EFI_VARIABLE_DATA *) buf;
465                 fprintGuid(fp, d->ValiableName);
466                 fprintf(fp, ",Name=");
467                 fprintUnicode(fp, d->UnicodeName, d->UnicodeNameLength);
468                 fprintf(fp, ",Valiable[0x%" PRIx64 "]", (UINT64)d->VariableDataLength);
469             }
470             fprintf(fp, "]");
471             break;
472         case 0x80000003:  // EFI
473             fprintf(fp, "[BIOS:EV_EFI_BOOT_SERVICES_APPLICATION,");
474             {
475                 EFI_IMAGE_LOAD_EVENT *e = (EFI_IMAGE_LOAD_EVENT *) buf;
476                 fprintf(fp, "base=0x%" PRIx64 ",", (UINT64)e->ImageLocationInMemory);
477                 fprintf(fp, "len=0x%" PRIx64 ",", (UINT64)e->ImageLengthInMemory);
478                 fprintf(fp, "len=0x%" PRIx64 ",", (UINT64)e->ImageLinkTimeAddress);
479                 fprintf(fp, "len=0x%" PRIx64 "]", (UINT64)e->LengthOfDevicePath);
480             }
481             break;
482         case 0x80000004:  // EFI
483             fprintf(fp, "[BIOS:EV_EFI_BOOT_SERVICES_DRIVER,");
484             {
485                 EFI_IMAGE_LOAD_EVENT *e = (EFI_IMAGE_LOAD_EVENT *) buf;
486                 fprintf(fp, "base=0x%" PRIx64 ",", (UINT64)e->ImageLocationInMemory);
487                 fprintf(fp, "len=0x%" PRIx64 ",", (UINT64)e->ImageLengthInMemory);
488                 fprintf(fp, "len=0x%" PRIx64 ",", (UINT64)e->ImageLinkTimeAddress);
489                 fprintf(fp, "len=0x%" PRIx64 "]", (UINT64)e->LengthOfDevicePath);
490             }
491             break;
492         case 0x80000005:  // EFI
493             fprintf(fp, "[BIOS:EV_EFI_RUNTIME_SERVICES_DRIVER,");
494             {
495                 EFI_IMAGE_LOAD_EVENT *e = (EFI_IMAGE_LOAD_EVENT *) buf;
496                 fprintf(fp, "base=0x%" PRIx64 ",", (UINT64)e->ImageLocationInMemory);
497                 fprintf(fp, "len=0x%" PRIx64 ",", (UINT64)e->ImageLengthInMemory);
498                 fprintf(fp, "len=0x%" PRIx64 ",", (UINT64)e->ImageLinkTimeAddress);
499                 fprintf(fp, "len=0x%" PRIx64 "]", (UINT64)e->LengthOfDevicePath);
500             }
501             break;
502         case 0x80000006:  // EFI TODO
503             fprintf(fp, "[BIOS:EV_EFI_GPT_EVENT len=%d,", len);
504             for (i = 0; i < (int)len; i++) {
505                 fprintf(fp, "%02x", (BYTE)buf[i]);
506             }
507             fprintf(fp, "]");
508             break;
509         case 0x80000007:  // EFI
510             fprintf(fp, "[BIOS:EV_EFI_ACTION, %s]", buf);
511             break;
512         case 0x80000008:  // EFI
513             fprintf(fp, "[BIOS:EV_EFI_PLATFORM_FIRMWARE_BLOB,");
514             {
515                 EFI_PLATFORM_FIRMWARE_BLOB *blob = (EFI_PLATFORM_FIRMWARE_BLOB *)buf;
516                 fprintf(fp, "base=0x%" PRIx64 ",", (UINT64)blob->BlobBase);
517                 fprintf(fp, "len=0x%" PRIx64 "]", (UINT64)blob->BlobLength);
518             }
519             break;
520         case 0x80000009:  // EFI
521             fprintf(fp, "[BIOS:EV_EFI_HANDOFF_TABLE,");
522             {
523                 EFI_HANDOFF_TABLE_POINTERS *p = (EFI_HANDOFF_TABLE_POINTERS *)buf;
524
525                 fprintf(fp, "num=0x%" PRIx64 ",", (UINT64)p->NumberOfTables);
526                 if (p->NumberOfTables > 0) {
527                     EFI_CONFIGULATION_TABLE *t = &p->TableEntry[0];
528                     fprintGuid(fp, t->VendorGuid);
529                     fprintf(fp, "]");
530                 }
531             }
532             // 0100000000000000 312d9deb882dd3119a160090273fc14d 00a06b7f 00000000
533             break;
534
535             // GRUB
536         case 0x1005:
537             fprintf(fp, "[GRUB:ACTION, %s]", buf);
538             break;
539         case 0x1105:
540             fprintf(fp, "[GRUB:KERNEL_OPT %s]", buf);
541             break;
542         case 0x1205:
543             fprintf(fp, "[GRUB:KERNEL %s]", buf);
544             break;
545         case 0x1305:
546             fprintf(fp, "[GRUB:INITRD %s]", buf);
547             break;
548         case 0x1405:
549             fprintf(fp, "[GRUB:MODULE %s]", buf);
550             break;
551
552         default:
553             fprintf(fp, "[Unknown BIOS Event:size=%d] ", len);
554             break;
555         }
556     } else {
557         switch (type) {
558             /* OpenPTS*/
559         case EV_COLLECTOR_START:
560             fprintf(fp, "[OpenPTS:EV_COLLECTOR_START[%d]]", len);
561 #if 0
562             if (verbose_cnt > 0) {
563                 fprintf(fp, "%sUUID");
564                 for (i = 0; i < (int)len; i++) {
565                     fprintf(fp, "%02x", (BYTE)buf[i]);
566                 }
567                 encodeBase64(
568                     (unsigned char *)b64buf,
569                     (unsigned char *)buf, len);
570                 fprintf(fp, ", base64(%s)", b64buf);
571             }
572 #endif
573             break;
574         case EV_FILE_SCAN:
575             fprintf(fp, "[OpenPTS:EV_FILE_SCAN]");
576             if (verbose_cnt > 0) {
577                 OPENPTS_EVENT_FILE_SCAN *fscan;
578                 fscan = (OPENPTS_EVENT_FILE_SCAN *) buf;
579                 /* show event data */
580                 fprintf(fp, "\n");
581                 fprintf(fp, "%sFile Mode : %o\n", indent, fscan->file_mode);
582                 fprintf(fp, "%sFile UID  : %d\n", indent, fscan->file_uid);
583                 fprintf(fp, "%sFile GID  : %d\n", indent, fscan->file_gid);
584                 fprintf(fp, "%sFile size : %d\n", indent, fscan->file_size);
585                 fprintf(fp, "%sFilename  : %s\n",   indent, fscan->filename);
586                 fprintf(fp, "%sDigest    : ",     indent);
587                 fprintHex(fp, fscan->digest, 20);
588             }
589             break;
590         case EV_FILE_SCAN_TSS:
591             fprintf(fp, "[OpenPTS:EV_FILE_SCAN_TSS]");
592             if (verify == 1) {
593                 BYTE digest2[20];
594                 SHA_CTX ctx;
595
596                 SHA1_Init(&ctx);
597                 SHA1_UpdateUint32(&ctx, pcrindex);
598                 SHA1_UpdateUint32(&ctx, type);
599                 SHA1_Update(&ctx, (BYTE *) data, len);
600                 SHA1_Final(digest2, &ctx);
601                 fprintf(fp, "\n                    ");
602                 fprintHex(fp, digest2, 20);
603                 fprintf(fp, " <= SHA1(%d(pcrindex) || %d(eventtype) || eventdata[%d])",
604                     pcrindex, type, len);
605             }
606             if (verbose_cnt > 0) {
607                 OPENPTS_EVENT_FILE_SCAN *fscan;
608                 fscan = (OPENPTS_EVENT_FILE_SCAN *) buf;
609                 /* show event data */
610                 fprintf(fp, "\n");
611                 fprintf(fp, "%sFile Mode : %o\n", indent, fscan->file_mode);
612                 fprintf(fp, "%sFile UID  : %d\n", indent, fscan->file_uid);
613                 fprintf(fp, "%sFile GID  : %d\n", indent, fscan->file_gid);
614                 fprintf(fp, "%sFile size : %d\n", indent, fscan->file_size);
615                 fprintf(fp, "%sFilename  : %s\n",   indent, fscan->filename);
616                 fprintf(fp, "%sDigest    : ",     indent);
617                 fprintHex(fp, fscan->digest, 20);
618             }
619             break;
620 #ifdef CONFIG_TBOOT
621         case EV_TBOOT_SINIT_V6:
622             fprintf(fp, "[tboot:sinit(v6)]");
623             if (verbose_cnt > 0) {
624                 OPENPTS_EVENT_TBOOT_SINIT_V6 *ed;
625                 ed = (OPENPTS_EVENT_TBOOT_SINIT_V6 *) buf;
626                 /* show event data */
627                 fprintf(fp, "\n");
628                 fprintf(fp, "%ssinit_hash       : ",     indent);
629                 fprintHex(fp, ed->sinit_hash, 20);
630                 fprintf(fp, "\n");
631                 fprintf(fp, "%sedx_senter_flags : ", indent);
632                 fprintHex(fp, ed->edx_senter_flags, 4);
633             }
634             break;
635         case EV_TBOOT_SINIT_V7:
636             fprintf(fp, "[tboot:sinit(v7)]");
637             if (verbose_cnt > 0) {
638                 OPENPTS_EVENT_TBOOT_SINIT_V7 *ed;
639                 ed = (OPENPTS_EVENT_TBOOT_SINIT_V7 *) buf;
640                 /* show event data */
641                 fprintf(fp, "\n");
642                 fprintf(fp, "%ssinit_hash       : ",     indent);
643                 fprintHex(fp, ed->sinit_hash, 32);
644                 fprintf(fp, "\n");
645                 fprintf(fp, "%sedx_senter_flags : ", indent);
646                 fprintHex(fp, ed->edx_senter_flags, 4);
647             }
648             break;
649         case EV_TBOOT_STM_V6:
650             fprintf(fp, "[tboot:stm(v6)]");
651             if (verbose_cnt > 0) {
652                 OPENPTS_EVENT_TBOOT_STM_V6 *ed;
653                 ed = (OPENPTS_EVENT_TBOOT_STM_V6 *) buf;
654                 /* show event data */
655                 fprintf(fp, "\n");
656                 fprintf(fp, "%sbios_acm_id : ",     indent);
657                 fprintHex(fp, ed->bios_acm_id, 20);
658                 fprintf(fp, "\n");
659                 fprintf(fp, "%smseg_valid  : ", indent);
660                 fprintHex(fp, ed->mseg_valid, 8);
661             }
662             break;
663         case EV_TBOOT_MLE_HASH:
664             fprintf(fp, "[tboot:mle_hash]");
665             break;
666         case EV_TBOOT_POLCTL:
667             fprintf(fp, "[tboot:tb_policy_control]");
668             if (verbose_cnt > 0) {
669                 OPENPTS_EVENT_TBOOT_POLCTL *pc;
670                 pc = (OPENPTS_EVENT_TBOOT_POLCTL *) buf;
671                 /* show event data */
672                 fprintf(fp, "\n");
673                 fprintf(fp, "%spolict_control : ", indent);
674                 fprintHex(fp, pc->pol_control, 4);
675                 fprintf(fp, "\n");
676                 fprintf(fp, "%spolicy_hash    : ", indent);
677                 fprintHex(fp, pc->pol_hash, 20);
678             }
679             break;
680         case EV_TBOOT_MODULE:
681             fprintf(fp, "[tboot:module]");
682             if (verbose_cnt > 0) {
683                 OPENPTS_EVENT_TBOOT_MODULE *ed;
684                 ed = (OPENPTS_EVENT_TBOOT_MODULE *) buf;
685                 UINT32 size;
686                 BYTE *ptr;
687                 /* show event data */
688                 fprintf(fp, "\n");
689
690                 fprintf(fp, "%scommand_hash : ",     indent);
691                 fprintHex(fp, ed->command_hash, 20);
692                 fprintf(fp, "\n");
693
694                 fprintf(fp, "%sfile_hash    : ",     indent);
695                 fprintHex(fp, ed->file_hash, 20);
696                 fprintf(fp, "\n");
697
698
699                 ptr = (BYTE *)&buf[40];
700                 size = *(UINT32*) ptr;
701                 ptr += 4;
702                 fprintf(fp, "%scommand      : ", indent);
703                 fprintChar(fp, (BYTE *)ptr, size);
704                 fprintf(fp, "\n");
705
706                 ptr += size;
707                 size = *(UINT32*) ptr;
708                 ptr += 4;
709                 fprintf(fp, "%sfilename     : ", indent);
710                 fprintChar(fp, (BYTE *)ptr, size);
711                 fprintf(fp, "\n");
712             }
713             break;
714 #endif
715         default:
716             if ((verbose) && (len < 64)) {
717                 fprintf(fp, "[Unknown Event[%d]=0x", len);
718                 for (i = 0; i < (int)len; i++) {
719                     fprintf(fp, "%02x", (BYTE)buf[i]);
720                 }
721                 b64buf = encodeBase64(
722                     //(unsigned char *)b64buf,
723                     (unsigned char *)buf,
724                     len,
725                     &b64buf_len);
726                 if (b64buf == NULL) {
727                     ERROR("encodeBase64 fail");
728                 } else {
729                     fprintf(fp, ", base64(%s)", b64buf);
730                     fprintf(fp, "]");
731                     free(b64buf);
732                 }
733             } else {
734                 fprintf(fp, "[Unknown Event:size=%d] ", len);
735             }
736             break;
737         }
738     }
739 }
740
741
742
743 // Verify
744 void extend(int index, BYTE* digest) {
745     SHA_CTX ctx;
746
747     SHA1_Init(&ctx);
748     SHA1_Update(&ctx, &pcr[index][0], 20);
749     SHA1_Update(&ctx, digest, 20);
750     SHA1_Final(&pcr[index][0], &ctx);
751 }
752
753
754 void ima_boot_aggregate(BYTE* digest) {
755     SHA_CTX ctx;
756     BYTE buf1[20];
757     BYTE buf2[256];  // note) this is FIXED size
758     int i;
759     char *filename = "boot_aggregate";
760
761     SHA1_Init(&ctx);
762     for (i = 0; i < 8; i++) {
763         SHA1_Update(&ctx, &pcr[i][0], 20);
764     }
765     SHA1_Final(buf1, &ctx);
766
767     memset(buf2, 0, 256);
768     memcpy(buf2, filename, 14);
769
770     // template
771     SHA1_Init(&ctx);
772     SHA1_Update(&ctx, buf1, 20);
773     SHA1_Update(&ctx, buf2, 256);
774     SHA1_Final(digest, &ctx);
775 }
776
777 /**
778  * get IML from file (TCG binary format)
779  *
780  * Step 1. read event -> EVENT_WRAPPER chain
781  * Step 2. EVENT_WRAPPER -> TSS_PCR_EVENT
782  * Step 3. free  EVENT_WRAPPER
783  *
784  */
785 TSS_RESULT getEventLog(char *filename, int endian, int aligned, UINT32 *event_num, TSS_PCR_EVENT **pcr_events) {
786     int rc = 0;
787     int i = 0;
788     size_t size;
789     FILE *fp;
790     UINT32 pcrIndex;
791     UINT32 eventType;
792     UINT32 eventLength;
793     UINT32 aligned_length;
794     // BYTE buf[4];
795
796     /**/
797     // TSS_PCR_EVENT *event = NULL;
798     OPENPTS_PCR_EVENT_WRAPPER *ew = NULL;
799     OPENPTS_PCR_EVENT_WRAPPER *ew_start = NULL;
800     OPENPTS_PCR_EVENT_WRAPPER *ew_last = NULL;
801
802     DEBUG("getEventLog() - %s, ensian = %d, aligned = %d\n", filename, endian, aligned);
803
804     /* check */
805     if (filename == NULL) {
806         ERROR("filename is NULL\n");
807         return TSS_E_INTERNAL_ERROR;
808     }
809
810     /* open file */
811     if ((fp = fopen(filename, "rb")) == NULL) {
812         ERROR("%s missing", filename);
813         return TSS_E_INTERNAL_ERROR;
814     }
815
816     /* STEP 1, Read IML, add to Snapshot */
817     while (1) {
818         DEBUG("--- event %d ------------\n", i);
819         /* PCR index */
820         size = fread(&pcrIndex, 1, 4, fp);
821         if (size != 4)
822             break;
823
824         /* Event type */
825         size = fread(&eventType, 1, 4, fp);
826         if (size != 4)
827             break;
828
829         /* create wrapper */
830         ew = (OPENPTS_PCR_EVENT_WRAPPER *)malloc(sizeof(OPENPTS_PCR_EVENT_WRAPPER));
831         if (ew == NULL) {
832             ERROR("no memory\n");
833             rc =  TSS_E_INTERNAL_ERROR;
834             goto close;
835         }
836         memset(ew, 0, sizeof(OPENPTS_PCR_EVENT_WRAPPER));
837
838         /* alloc new event */
839         ew->event = (TSS_PCR_EVENT *) malloc(sizeof(TSS_PCR_EVENT));
840         if (ew->event == NULL) {
841             printf("no memory\n");
842             rc =  TSS_E_INTERNAL_ERROR;
843             goto close;
844         }
845         memset((void*)ew->event, 0, sizeof(TSS_PCR_EVENT));
846
847         if (endian == 0) {
848             ew->event->ulPcrIndex = pcrIndex;
849             ew->event->eventType = eventType;
850         } else {
851             /* Big endian */
852             ew->event->ulPcrIndex = b2l(pcrIndex);
853             ew->event->eventType = b2l(eventType);
854         }
855
856         DEBUG("\tpcr index = 0x%x\n", ew->event->ulPcrIndex);
857         DEBUG("\tevent type = 0x%x\n", ew->event->eventType);
858
859         /* Digest */
860         ew->event->ulPcrValueLength = SHA1_DIGEST_SIZE;
861         if ((ew->event->rgbPcrValue = (BYTE *) malloc(SHA1_DIGEST_SIZE)) == NULL) {
862             ERROR("no memory");
863             rc =  TSS_E_INTERNAL_ERROR;
864             goto close;
865         }
866         size = fread(ew->event->rgbPcrValue, 1, SHA1_DIGEST_SIZE, fp);
867         if (size != SHA1_DIGEST_SIZE) {  // TODO(munetoh) SHA1 only
868             ERROR("SHA1 only");
869             rc =  TSS_E_INTERNAL_ERROR;
870             goto close;
871         }
872
873         if (verbose == DEBUG_FLAG) {
874             DEBUG("digest");
875             printHex("\t\t\t\t", ew->event->rgbPcrValue, 20, "\n");
876         }
877
878         /* EventData len */
879         size = fread(&eventLength, 1, 4, fp);
880         if (size != 4) {
881             ERROR("fread NG\n");
882             rc =  TSS_E_INTERNAL_ERROR;
883             goto close;
884         }
885
886         if (endian == 0) {
887             ew->event->ulEventLength = eventLength;
888         } else {
889             ew->event->ulEventLength = b2l(eventLength);
890         }
891
892         /* adjust read data length */
893         aligned_length = ew->event->ulEventLength;
894         if (aligned == 4) {
895             if ((ew->event->ulEventLength & 0x03) != 0) {
896                 aligned_length = (ew->event->ulEventLength & 0xFFFFFFFC) + 0x04;
897             }
898         }
899
900         DEBUG("\tevent size = 0x%x (%d)\n", ew->event->ulEventLength, ew->event->ulEventLength);
901
902         /* EventData  */
903         if ((ew->event->rgbEvent = malloc(aligned_length)) == NULL) {
904             ERROR("no memory");
905             rc =  TSS_E_INTERNAL_ERROR;
906             goto close;
907         }
908         size = fread(ew->event->rgbEvent, 1, aligned_length, fp);
909         if (size != aligned_length) {
910             ERROR("fread NG, size = %d != %d (@PCR[%d])\n",
911                 (unsigned int) size,
912                 (unsigned int) ew->event->ulEventLength,
913                 pcrIndex);
914             rc =  TSS_E_INTERNAL_ERROR;
915             goto close;
916         }
917
918         if (verbose == DEBUG_FLAG) {
919             DEBUG("");
920             printHex("\tevent data", ew->event->rgbEvent, ew->event->ulEventLength, "\n");
921         }
922
923         /* move to EW chain */
924         if (i == 0) {
925             /* 1st EW */
926             ew_start = ew;
927             ew_last = ew;
928         } else {
929             ew_last->next_all = ew;
930             ew_last = ew;
931         }
932
933
934         i++;
935     }
936     /* done, clear last event & ew */
937     ew = NULL;
938
939     /* event num */
940     *event_num = i;
941
942     /* STEP 2, generate TSS_PCR_EVENT**,  ew chain -> TSS_PCR_EVENT** */
943     /* maloc */
944     *pcr_events = calloc(*event_num, sizeof(TSS_PCR_EVENT));
945     if ((*pcr_events) == NULL) {
946         ERROR("no memory\n");
947         rc = TSS_E_INTERNAL_ERROR;
948         goto close;
949     }
950     /* copy events */
951     ew = ew_start;  // first EW
952     for (i = 0; i < (int)(*event_num); i++) {
953         memcpy(&((*pcr_events)[i]), ew->event, sizeof(TSS_PCR_EVENT));
954
955         ew_last = ew;
956         ew = ew->next_all;  // next
957
958         /* free event, ew (PCR.EventData are linked to pcr_events) */
959         ew_last->event->rgbPcrValue = NULL;
960         ew_last->event->rgbEvent = NULL;
961         free(ew_last->event);
962         free(ew_last);
963     }
964     ew = NULL;
965
966     /* OK */
967     rc = TSS_SUCCESS;
968
969   close:
970     if (fclose(fp) == EOF) {
971         // TODO(munetoh) SYSLOG ERROR?
972         rc = TSS_E_INTERNAL_ERROR;
973     }
974     /* free for error */
975     if (ew != NULL) {
976         if (ew->event != NULL) {
977             if (ew->event->rgbPcrValue != NULL) free(ew->event->rgbPcrValue);
978             if (ew->event->rgbEvent != NULL) free(ew->event->rgbEvent);
979             free(ew->event);
980         }
981         free(ew);
982     }
983
984     return rc;  // TSS_E_INTERNAL_ERROR;
985 }
986
987 /**
988  * Usage
989  */
990 void usage(void) {
991     fprintf(stderr, "OpenPTS command\n\n");
992     fprintf(stderr, "Usage: iml2text [options]\n\n");
993     fprintf(stderr, "Options:\n");
994     fprintf(stderr, "  -i filename           Set binary eventlog file (at securityfs)\n");
995     fprintf(stderr, "  -p pcr_index          Select pcr (TSS)\n");
996     fprintf(stderr, "  -I mode               Select IMA's log format (Kernel 2.6.32:32)\n");
997     fprintf(stderr, "  -V                    Verify\n");
998     fprintf(stderr, "  -D                    DRTM\n");
999     fprintf(stderr, "  -E                    Enable endian conversion (BE->LE or LE->BE)\n");
1000     fprintf(stderr, "  -h                    Show this help message\n");
1001     fprintf(stderr, "\n");
1002 }
1003
1004 /**
1005  * main
1006  */
1007 int main(int argc, char *argv[]) {
1008     TSS_RESULT result = 0;
1009     TSS_HCONTEXT hContext;
1010     TSS_HTPM hTPM;
1011     TSS_PCR_EVENT * PcrEvents;
1012     UINT32 ulEventNumber = 0;
1013     BYTE digest[20];
1014     BYTE zero[20];
1015     BYTE fox[20];
1016     BYTE boot_aggregate[20];
1017     int i, j;
1018     int pcrindex = -1;
1019     int gmode = 0;  // 0:TSS,1,file
1020     char *filename = NULL;
1021     FILE *fp = stdout;
1022     int c;
1023     int endian = 0;  // 0:normal 1:convert
1024     int aligned = 0;
1025     int ima_exist = 0;
1026     int drtm = 0;
1027     BYTE *blob;
1028     UINT32 blobLength;
1029
1030     /* init */
1031     memset(zero, 0, 20);
1032     memset(fox, 0xff, 20);
1033     memset(boot_aggregate, 0xff, 20);
1034
1035     /* Args */
1036     while ((c = getopt(argc, argv, "i:p:I:EAvVDh")) != EOF) {
1037         switch (c) {
1038         case 'i':
1039             filename = optarg;
1040             gmode = 1;  // file
1041             break;
1042         case 'p':
1043             pcrindex = atoi(optarg);
1044             break;
1045         case 'I':
1046             ima_mode = atoi(optarg);
1047             break;
1048         case 'E':  /* Enable Endian Conversion */
1049             DEBUG("enable endian conversion\n");
1050             endian = 1;
1051             break;
1052         case 'A':  /*  four byte aligned event data */
1053             aligned = 4;
1054             break;
1055         case 'v':  /* DEBUG */
1056             verbose_cnt++;
1057             break;
1058         case 'V':  /* verify  */
1059             verify = 1;
1060             break;
1061         case 'D':  /* drtm  */
1062             drtm = 1;
1063             break;
1064         case 'h':
1065             usage();
1066             return 0;
1067         default:
1068             fprintf(stderr, "bad option '%c'\n", c);
1069             usage();
1070             return -1;
1071         }
1072     }
1073     argc -= optind;
1074     argv += optind;
1075
1076     for (i = 0; i < 16; i++) {
1077         for (j = 0; j < 20; j++) {
1078             pcr[i][j] = 0;
1079         }
1080     }
1081     for (i = 16; i < 24; i++) {
1082         /* no DRTM */
1083         for (j = 0; j < 20; j++) {
1084             if (drtm == 1) pcr[i][j] = 0x00;
1085             else           pcr[i][j] = 0xff;
1086         }
1087     }
1088
1089     if (verbose_cnt > 1) {
1090        verbose = DEBUG_FLAG;
1091     }
1092
1093     /* TSS and Verify */
1094     if (gmode == 0 || verify) {
1095         /* in both cases, we have to connect to TCSD */
1096         result = Tspi_Context_Create(&hContext);
1097         if (result != TSS_SUCCESS) {
1098             printf("ERROR: Tspi_Context_Create failed rc=0x%x\n",
1099                    result);
1100             goto close;
1101         }
1102
1103         result = Tspi_Context_Connect(hContext, SERVER);
1104         if (result != TSS_SUCCESS) {
1105             printf("ERROR: Tspi_Context_Connect failed rc=0x%x\n",
1106                    result);
1107             goto close;
1108         }
1109
1110         /* Get TPM handles */
1111         result = Tspi_Context_GetTpmObject(hContext, &hTPM);
1112         if (result != TSS_SUCCESS) {
1113             printf("ERROR: Tspi_Context_GetTpmObject failed rc=0x%x\n",
1114                    result);
1115             goto close;
1116         }
1117     }
1118
1119     /* get IML */
1120     if (gmode == 0) {
1121         /* Get EventLog via TSS */
1122         result = Tspi_TPM_GetEventLog(
1123                     hTPM,
1124                     &ulEventNumber,
1125                     &PcrEvents);
1126         if (result != TSS_SUCCESS) {  // ERROR
1127             printf("ERROR: Tspi_TPM_GetEventLog failed rc=0x%x\n",
1128                    result);
1129             goto close;
1130         }
1131     } else {
1132         /* Get EventLog File */
1133         result = getEventLog(filename, endian, aligned, &ulEventNumber, &PcrEvents);
1134         if (result != TSS_SUCCESS) {  // ERROR
1135             ERROR("getEventLog failed rc=0x%x\n",
1136                    result);
1137             goto close;
1138         }
1139     }
1140
1141     /* Dump */
1142     fprintf(fp, " Idx PCR       Type    Digest                                EventData\n");
1143     fprintf(fp, "-----------------------------------------------------------------------\n");
1144     for (i = 0; i < (int)ulEventNumber; i++) {
1145         if ((pcrindex < 0) || (pcrindex == (int)PcrEvents[i].ulPcrIndex)) {
1146             fprintf(fp, "%4d ", i);
1147             fprintf(fp, "%3d ", PcrEvents[i].ulPcrIndex);
1148             fprintf(fp, "0x%08x ", PcrEvents[i].eventType);
1149             for (j = 0; j < (int)PcrEvents[i].ulPcrValueLength; j++)
1150                 fprintf(fp, "%02x", PcrEvents[i].rgbPcrValue[j]);
1151             fprintf(fp, " ");
1152
1153             /* event Data */
1154             fprintEventData(
1155                 fp,
1156                 PcrEvents[i].rgbEvent,
1157                 PcrEvents[i].ulEventLength,
1158                 PcrEvents[i].ulPcrIndex,
1159                 PcrEvents[i].eventType,
1160                 PcrEvents[i].rgbPcrValue);
1161
1162             fprintf(fp, "\n");
1163
1164             if (verify) {
1165                 if (PcrEvents[i].ulPcrIndex == 10) {  // IMA log
1166                     if (memcmp(PcrEvents[i].rgbPcrValue, zero, 20) == 0) {  // zero
1167                         extend(PcrEvents[i].ulPcrIndex, fox);
1168                     } else {
1169                         extend(PcrEvents[i].ulPcrIndex, PcrEvents[i].rgbPcrValue);
1170                     }
1171                     // TODO get boot aggregate
1172                     if (memcmp(PcrEvents[i].rgbEvent, "boot_aggregate", 14) == 0) {
1173                         memcpy(boot_aggregate, PcrEvents[i].rgbPcrValue, 20);
1174                     }
1175
1176                 } else {
1177                     extend(PcrEvents[i].ulPcrIndex, PcrEvents[i].rgbPcrValue);
1178                 }
1179             }
1180             if (PcrEvents[i].ulPcrIndex == 10) {
1181                 ima_exist = 1;
1182             }
1183         }
1184     }
1185
1186     /* Verify */
1187     if (verify) {
1188         fprintf(fp, "\n");
1189         fprintf(fp, "Verify IML :-)\n");
1190         fprintf(fp, "\n");
1191         fprintf(fp, "\tcalculated pcr values\t\t\t\tactual pcr values\n");
1192         fprintf(fp, "---------------------------------------------------"
1193             "---------------------------------------------------\n");
1194         for (i = 0; i < 24; i++) {
1195             fprintf(fp, "pcr.%d=\t", i);
1196             // my calc
1197             for (j = 0; j < 20; j++) {
1198                 fprintf(fp, "%02x", pcr[i][j]);
1199             }
1200             // actual
1201             result = Tspi_TPM_PcrRead(hTPM, i, &blobLength, &blob);
1202             if (result != TSS_SUCCESS) {  // ERROR
1203                 ERROR("PrcRead failed rc=0x%x\n",
1204                        result);
1205                 goto free;
1206             }
1207
1208             if (memcmp(&pcr[i][0], blob, 20) == 0) {
1209                 fprintf(fp, "  ==  ");
1210             } else {
1211                 fprintf(fp, "  !=  ");
1212             }
1213
1214             for (j = 0; j < 20; j++) {
1215                 fprintf(fp, "%02x", blob[j]);
1216             }
1217             fprintf(fp, "\n");
1218         }
1219         fprintf(fp, "\n");
1220         fprintf(fp, "\n");
1221
1222         if (ima_exist == 1) {
1223             ima_boot_aggregate(digest);
1224             fprintf(fp, "IMA boot aggregate:\n");
1225             fprintf(fp, "\tcalculated boot_aggregate\t\t\t\tactual boot_aggregate\n");
1226             fprintf(fp, "---------------------------------------------------"
1227                 "---------------------------------------------------\n");
1228             for (j = 0; j < 20; j++) {
1229                 fprintf(fp, "%02x", digest[j]);
1230             }
1231             fprintf(fp, "\t");
1232             for (j = 0; j < 20; j++) {
1233                 fprintf(fp, "%02x", boot_aggregate[j]);
1234             }
1235             fprintf(fp, "\n");
1236         }
1237     }
1238
1239   free:
1240     if (gmode == 0) {
1241         result = Tspi_Context_FreeMemory(hContext, (BYTE *)PcrEvents);
1242         Tspi_Context_FreeMemory(hContext, NULL);
1243     } else {
1244         // TODO free PcrEvents
1245         for (i = 0; i < (int)ulEventNumber; i++) {
1246             if (PcrEvents[i].rgbPcrValue != NULL) free(PcrEvents[i].rgbPcrValue);
1247             if (PcrEvents[i].rgbEvent != NULL) free(PcrEvents[i].rgbEvent);
1248         }
1249         free(PcrEvents);
1250     }
1251     /* Close TSS/TPM */
1252
1253   close:
1254     if (gmode == 0) {
1255         Tspi_Context_Close(hContext);
1256     }
1257
1258     return result;
1259 }