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.
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)
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.
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.
23 * \file src/iml2text.c
24 * \brief Convert binary IML file to plaintext
25 * @author Seiji Munetoh <munetoh@users.sourceforge.jp>
27 * cleanup 2011-08-17 SM
29 * show eventlog (get though TSS)
33 * show eventlog (binary eventlog file)
35 * ./src/iml2text -i tests/data/ThinkpadX200_Fedora12/binary_bios_measurements
37 * show BE(big-endian) event on LE host
39 * ./src/iml2text -E -i tests/data/XXX/example_event_log
45 * [1] BIOS https://www.trustedcomputinggroup.org/specs/PCClient/
46 * Ref PC Spec v1.2, p74
50 * UINT32 eventDataSize
53 * [2] GRUB-IMA, see BIOS format
57 * boot aggregate = sha1(PCR[0],PCR[1],,,PCR[7])
59 * /sys/kernel/security/ima/binary_runtime_measurements
61 * BYTE template_hash[20]
66 * CHAR filename[filename_len]
70 * CHAR filename[filename_len]
72 * template_hash = SHA1(ima_data) = SHA1(digest + filename)
85 #ifndef __STDC_FORMAT_MACROS
86 #define __STDC_FORMAT_MACROS
90 #include <openssl/sha.h>
95 #include <openpts_tboot.h>
107 // -v 1 show event data contents
114 // Check the consistence of IML and PCRs
126 int hex2bin(void *dest, const void *src, size_t n);
127 void printhex(char *str, unsigned char *buf, int len);
139 typedef UINT64 EFI_PHISICAL_ADDRESS;
140 typedef UINT64 UINTN;
141 typedef wchar_t CHAR16;
145 typedef BYTE EFI_DEVICE_PATH; // TODO
154 typedef struct tdEFI_PLATFORM_FIRMWARE_BLOB {
155 EFI_PHISICAL_ADDRESS BlobBase;
157 } EFI_PLATFORM_FIRMWARE_BLOB;
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;
168 typedef struct tdEFI_CONFIGULATION_TABLE {
171 } EFI_CONFIGULATION_TABLE;
173 typedef struct tdEFI_HANDOFF_TABLE_POINTERS {
174 UINTN NumberOfTables;
175 EFI_CONFIGULATION_TABLE TableEntry[1];
176 } EFI_HANDOFF_TABLE_POINTERS;
179 typedef struct tdEFI_VARIABLE_DATA {
180 EFI_GUID ValiableName;
181 UINTN UnicodeNameLength;
182 UINTN VariableDataLength;
183 CHAR16 UnicodeName[1];
184 INT8 VariableData[1];
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]);
202 void fprintBin(FILE* fp, BYTE* data, UINT32 len) {
204 for (i = 0; i < (int)len; i++) {
209 void fprintHex(FILE* fp, BYTE* data, UINT32 len) {
211 for (i = 0; i < (int)len; i++) {
212 fprintf(fp, "%02x", data[i]);
217 void fprintChar(FILE* fp, BYTE* data, UINT32 len) {
219 for (i = 0; i < (int)len; i++) {
220 if ((0x20 <= data[i]) && (data[i] < 0x7e)) {
221 fprintf(fp, "%c", data[i]);
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) {
234 for (i = 0; i< len*2;i+=2) {
235 fprintf(fp, "%c", u8[i]);
242 void SHA1_UpdateUint32(SHA_CTX *c, UINT32 data) {
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);
253 * TODO(munetoh) move to iml.c and be common
255 void fprintEventData(
258 UINT32 len, // event length
263 char *b64buf; //[BUFSIZE];
268 memcpy(buf, data, len);
269 buf[len]=0; // terminate
271 memcpy(buf, data, BUFSIZE);
272 buf[BUFSIZE-1] = 0; // terminate
276 if (pcrindex == 10) { // Linux-IMA
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) {
285 RHEL6 - Kernel 2.6.32
286 --------------------------------------------------------------------------------
288 98 0a 38 ef 63 42 a5 d6 37 cf 96 47 b5 34 45 ac 13 98 d5 c7
291 0c d0 a1 73 28 b3 e0 93 a0 51 15 c1 44 23 eb 62 45 df 3b 32
293 62 6f 6f 74 5f 61 67 67 72 65 67 61 74 65 | boot_aggregate|
294 --------------------------------------------------------------------------------
296 c8 7f 4d ea 27 e3 3e 3c 6b 88 71 d7 fb bf ed e2 0f f1 78 7a
299 ac 63 ec 16 2b 60 31 3a 88 96 e4 1a 57 0c 64 da bf 3b 16 ec
301 2f 69 6e 69 74 |./init|
302 --------------------------------------------------------------------------------
304 IML->TSS(Fix the format)->
307 BYTE[len-20] filename
309 fprintf(fp, "[IMA:sha1(");
310 fprintBin(fp, &data[20], len-20);
312 fprintHex(fp, data, 20);
316 fprintf(fp, "[IMA:(TBD)] ");
318 } else if ((type & 0xFFFF) == 4) {
319 fprintf(fp, "[IMA-USR,0x%04x:%s] ", (type >> 16), buf);
321 fprintf(fp, "[???:%s] ", buf);
323 } else if (pcrindex <= 8) { // BIOS + Grub
326 fprintf(fp, "[BIOS:EV_PREBOOT_CERT(EV_CODE_CERT)]");
329 fprintf(fp, "[BIOS:EV_POST_CODE(EV_CODE_NOCERT)]");
332 fprintf(fp, "[BIOS:EV_UNUSED(EV_XML_CONFIG)]");
335 fprintf(fp, "[BIOS:EV_NO_ACTION]");
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]);
351 fprintf(fp, "[BIOS:EV_SEPARATOR, %s]", buf);
355 if ((pcr5_grub > 0) && (pcrindex == 5)) {
356 fprintf(fp, "[GRUB:EV_ACTION, %s]", buf);
358 fprintf(fp, "[BIOS:EV_ACTION, %s]", buf);
362 if ((pcr4_grub > 1) && (pcrindex == 4)) {
363 fprintf(fp, "[GRUB: measure MBR again]");
365 fprintf(fp, "[BIOS:EV_EVENT_TAG(EV_PLATFORM_SPECIFIC)]");
369 fprintf(fp, "[BIOS:EV_S_CRTM_CONTENTS]");
372 fprintf(fp, "[BIOS:EV_S_CRTM_VERSION]");
377 SHA1_Update(&ctx, data, len);
378 SHA1_Final(digest2, &ctx);
380 fprintHex(fp, digest2, 20);
381 fprintf(fp, " <= SHA1(Version[%d])", len);
383 if (verbose_cnt > 0) {
385 fprintf(fp, "%sVersion(hex) : ", indent);
386 fprintHex(fp, data, len);
387 fprintf(fp, "\n%sVersion(char): ", indent);
388 fprintChar(fp, data, len);
392 fprintf(fp, "[BIOS:EV_CPU_MICROCODE]");
395 fprintf(fp, "[BIOS:EV_PLATFORM_CONFIG_FLAG)]");
398 fprintf(fp, "[BIOS:EV_TABLE_OF_CONTENTS)]");
401 fprintf(fp, "[BIOS:EV_COMPACT_HASH]");
404 if (pcr4_grub == 0) {
406 fprintf(fp, "[BIOS:EV_IPL]");
408 } else if (pcr4_grub == 1) {
410 fprintf(fp, "[GRUB:EV_IPL, Stage1(MBR)]");
412 } else if (pcr4_grub == 2) {
414 fprintf(fp, "[GRUB:EV_IPL, Stage1.5]");
416 } else if (pcr4_grub == 3) {
418 fprintf(fp, "[GRUB:EV_IPL, Stage1.5(filesystem)]");
422 fprintf(fp, "[GRUB:EV_IPL]");
426 if (pcr5_grub == 0) {
427 fprintf(fp, "[BIOS:EV_IPL_PERTITION_DATA]");
430 fprintf(fp, "[GRUB:grub.conf]");
434 fprintf(fp, "[BIOS:EV_NOHOST_CODE)]");
437 fprintf(fp, "[BIOS:EV_NOHOST_CONFIG]");
440 fprintf(fp, "[BIOS:EV_NOHOST_INFO]");
443 fprintf(fp, "[BIOS:EV_SPECIFICATION_IDENTIFIER 0x");
444 for (i = 0; i < (int)len; i++) {
445 fprintf(fp, "%02x", (BYTE)buf[i]);
450 case 0x80000001: // EFI
451 fprintf(fp, "[BIOS:EV_EFI_VARIABLE_DRIVER_CONFIG,");
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);
461 case 0x80000002: // EFI
462 fprintf(fp, "[BIOS:EV_EFI_VARIABLE_BOOT,");
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);
472 case 0x80000003: // EFI
473 fprintf(fp, "[BIOS:EV_EFI_BOOT_SERVICES_APPLICATION,");
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);
482 case 0x80000004: // EFI
483 fprintf(fp, "[BIOS:EV_EFI_BOOT_SERVICES_DRIVER,");
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);
492 case 0x80000005: // EFI
493 fprintf(fp, "[BIOS:EV_EFI_RUNTIME_SERVICES_DRIVER,");
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);
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]);
509 case 0x80000007: // EFI
510 fprintf(fp, "[BIOS:EV_EFI_ACTION, %s]", buf);
512 case 0x80000008: // EFI
513 fprintf(fp, "[BIOS:EV_EFI_PLATFORM_FIRMWARE_BLOB,");
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);
520 case 0x80000009: // EFI
521 fprintf(fp, "[BIOS:EV_EFI_HANDOFF_TABLE,");
523 EFI_HANDOFF_TABLE_POINTERS *p = (EFI_HANDOFF_TABLE_POINTERS *)buf;
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);
532 // 0100000000000000 312d9deb882dd3119a160090273fc14d 00a06b7f 00000000
537 fprintf(fp, "[GRUB:ACTION, %s]", buf);
540 fprintf(fp, "[GRUB:KERNEL_OPT %s]", buf);
543 fprintf(fp, "[GRUB:KERNEL %s]", buf);
546 fprintf(fp, "[GRUB:INITRD %s]", buf);
549 fprintf(fp, "[GRUB:MODULE %s]", buf);
553 fprintf(fp, "[Unknown BIOS Event:size=%d] ", len);
559 case EV_COLLECTOR_START:
560 fprintf(fp, "[OpenPTS:EV_COLLECTOR_START[%d]]", len);
562 if (verbose_cnt > 0) {
563 fprintf(fp, "%sUUID");
564 for (i = 0; i < (int)len; i++) {
565 fprintf(fp, "%02x", (BYTE)buf[i]);
568 (unsigned char *)b64buf,
569 (unsigned char *)buf, len);
570 fprintf(fp, ", base64(%s)", b64buf);
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 */
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);
590 case EV_FILE_SCAN_TSS:
591 fprintf(fp, "[OpenPTS:EV_FILE_SCAN_TSS]");
597 SHA1_UpdateUint32(&ctx, pcrindex);
598 SHA1_UpdateUint32(&ctx, type);
599 SHA1_Update(&ctx, (BYTE *) data, len);
600 SHA1_Final(digest2, &ctx);
602 fprintHex(fp, digest2, 20);
603 fprintf(fp, " <= SHA1(%d(pcrindex) || %d(eventtype) || eventdata[%d])",
604 pcrindex, type, len);
606 if (verbose_cnt > 0) {
607 OPENPTS_EVENT_FILE_SCAN *fscan;
608 fscan = (OPENPTS_EVENT_FILE_SCAN *) buf;
609 /* show event data */
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);
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 */
628 fprintf(fp, "%ssinit_hash : ", indent);
629 fprintHex(fp, ed->sinit_hash, 20);
631 fprintf(fp, "%sedx_senter_flags : ", indent);
632 fprintHex(fp, ed->edx_senter_flags, 4);
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 */
642 fprintf(fp, "%ssinit_hash : ", indent);
643 fprintHex(fp, ed->sinit_hash, 32);
645 fprintf(fp, "%sedx_senter_flags : ", indent);
646 fprintHex(fp, ed->edx_senter_flags, 4);
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 */
656 fprintf(fp, "%sbios_acm_id : ", indent);
657 fprintHex(fp, ed->bios_acm_id, 20);
659 fprintf(fp, "%smseg_valid : ", indent);
660 fprintHex(fp, ed->mseg_valid, 8);
663 case EV_TBOOT_MLE_HASH:
664 fprintf(fp, "[tboot:mle_hash]");
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 */
673 fprintf(fp, "%spolict_control : ", indent);
674 fprintHex(fp, pc->pol_control, 4);
676 fprintf(fp, "%spolicy_hash : ", indent);
677 fprintHex(fp, pc->pol_hash, 20);
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;
687 /* show event data */
690 fprintf(fp, "%scommand_hash : ", indent);
691 fprintHex(fp, ed->command_hash, 20);
694 fprintf(fp, "%sfile_hash : ", indent);
695 fprintHex(fp, ed->file_hash, 20);
699 ptr = (BYTE *)&buf[40];
700 size = *(UINT32*) ptr;
702 fprintf(fp, "%scommand : ", indent);
703 fprintChar(fp, (BYTE *)ptr, size);
707 size = *(UINT32*) ptr;
709 fprintf(fp, "%sfilename : ", indent);
710 fprintChar(fp, (BYTE *)ptr, size);
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]);
721 b64buf = encodeBase64(
722 //(unsigned char *)b64buf,
723 (unsigned char *)buf,
726 if (b64buf == NULL) {
727 ERROR("encodeBase64 fail");
729 fprintf(fp, ", base64(%s)", b64buf);
734 fprintf(fp, "[Unknown Event:size=%d] ", len);
744 void extend(int index, BYTE* digest) {
748 SHA1_Update(&ctx, &pcr[index][0], 20);
749 SHA1_Update(&ctx, digest, 20);
750 SHA1_Final(&pcr[index][0], &ctx);
754 void ima_boot_aggregate(BYTE* digest) {
757 BYTE buf2[256]; // note) this is FIXED size
759 char *filename = "boot_aggregate";
762 for (i = 0; i < 8; i++) {
763 SHA1_Update(&ctx, &pcr[i][0], 20);
765 SHA1_Final(buf1, &ctx);
767 memset(buf2, 0, 256);
768 memcpy(buf2, filename, 14);
772 SHA1_Update(&ctx, buf1, 20);
773 SHA1_Update(&ctx, buf2, 256);
774 SHA1_Final(digest, &ctx);
778 * get IML from file (TCG binary format)
780 * Step 1. read event -> EVENT_WRAPPER chain
781 * Step 2. EVENT_WRAPPER -> TSS_PCR_EVENT
782 * Step 3. free EVENT_WRAPPER
785 TSS_RESULT getEventLog(char *filename, int endian, int aligned, UINT32 *event_num, TSS_PCR_EVENT **pcr_events) {
793 UINT32 aligned_length;
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;
802 DEBUG("getEventLog() - %s, ensian = %d, aligned = %d\n", filename, endian, aligned);
805 if (filename == NULL) {
806 ERROR("filename is NULL\n");
807 return TSS_E_INTERNAL_ERROR;
811 if ((fp = fopen(filename, "rb")) == NULL) {
812 ERROR("%s missing", filename);
813 return TSS_E_INTERNAL_ERROR;
816 /* STEP 1, Read IML, add to Snapshot */
818 DEBUG("--- event %d ------------\n", i);
820 size = fread(&pcrIndex, 1, 4, fp);
825 size = fread(&eventType, 1, 4, fp);
830 ew = (OPENPTS_PCR_EVENT_WRAPPER *)malloc(sizeof(OPENPTS_PCR_EVENT_WRAPPER));
832 ERROR("no memory\n");
833 rc = TSS_E_INTERNAL_ERROR;
836 memset(ew, 0, sizeof(OPENPTS_PCR_EVENT_WRAPPER));
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;
845 memset((void*)ew->event, 0, sizeof(TSS_PCR_EVENT));
848 ew->event->ulPcrIndex = pcrIndex;
849 ew->event->eventType = eventType;
852 ew->event->ulPcrIndex = b2l(pcrIndex);
853 ew->event->eventType = b2l(eventType);
856 DEBUG("\tpcr index = 0x%x\n", ew->event->ulPcrIndex);
857 DEBUG("\tevent type = 0x%x\n", ew->event->eventType);
860 ew->event->ulPcrValueLength = SHA1_DIGEST_SIZE;
861 if ((ew->event->rgbPcrValue = (BYTE *) malloc(SHA1_DIGEST_SIZE)) == NULL) {
863 rc = TSS_E_INTERNAL_ERROR;
866 size = fread(ew->event->rgbPcrValue, 1, SHA1_DIGEST_SIZE, fp);
867 if (size != SHA1_DIGEST_SIZE) { // TODO(munetoh) SHA1 only
869 rc = TSS_E_INTERNAL_ERROR;
873 if (verbose == DEBUG_FLAG) {
875 printHex("\t\t\t\t", ew->event->rgbPcrValue, 20, "\n");
879 size = fread(&eventLength, 1, 4, fp);
882 rc = TSS_E_INTERNAL_ERROR;
887 ew->event->ulEventLength = eventLength;
889 ew->event->ulEventLength = b2l(eventLength);
892 /* adjust read data length */
893 aligned_length = ew->event->ulEventLength;
895 if ((ew->event->ulEventLength & 0x03) != 0) {
896 aligned_length = (ew->event->ulEventLength & 0xFFFFFFFC) + 0x04;
900 DEBUG("\tevent size = 0x%x (%d)\n", ew->event->ulEventLength, ew->event->ulEventLength);
903 if ((ew->event->rgbEvent = malloc(aligned_length)) == NULL) {
905 rc = TSS_E_INTERNAL_ERROR;
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",
912 (unsigned int) ew->event->ulEventLength,
914 rc = TSS_E_INTERNAL_ERROR;
918 if (verbose == DEBUG_FLAG) {
920 printHex("\tevent data", ew->event->rgbEvent, ew->event->ulEventLength, "\n");
923 /* move to EW chain */
929 ew_last->next_all = ew;
936 /* done, clear last event & ew */
942 /* STEP 2, generate TSS_PCR_EVENT**, ew chain -> TSS_PCR_EVENT** */
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;
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));
956 ew = ew->next_all; // next
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);
970 if (fclose(fp) == EOF) {
971 // TODO(munetoh) SYSLOG ERROR?
972 rc = TSS_E_INTERNAL_ERROR;
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);
984 return rc; // TSS_E_INTERNAL_ERROR;
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");
1007 int main(int argc, char *argv[]) {
1008 TSS_RESULT result = 0;
1009 TSS_HCONTEXT hContext;
1011 TSS_PCR_EVENT * PcrEvents;
1012 UINT32 ulEventNumber = 0;
1016 BYTE boot_aggregate[20];
1019 int gmode = 0; // 0:TSS,1,file
1020 char *filename = NULL;
1023 int endian = 0; // 0:normal 1:convert
1031 memset(zero, 0, 20);
1032 memset(fox, 0xff, 20);
1033 memset(boot_aggregate, 0xff, 20);
1036 while ((c = getopt(argc, argv, "i:p:I:EAvVDh")) != EOF) {
1043 pcrindex = atoi(optarg);
1046 ima_mode = atoi(optarg);
1048 case 'E': /* Enable Endian Conversion */
1049 DEBUG("enable endian conversion\n");
1052 case 'A': /* four byte aligned event data */
1055 case 'v': /* DEBUG */
1058 case 'V': /* verify */
1061 case 'D': /* drtm */
1068 fprintf(stderr, "bad option '%c'\n", c);
1076 for (i = 0; i < 16; i++) {
1077 for (j = 0; j < 20; j++) {
1081 for (i = 16; i < 24; i++) {
1083 for (j = 0; j < 20; j++) {
1084 if (drtm == 1) pcr[i][j] = 0x00;
1085 else pcr[i][j] = 0xff;
1089 if (verbose_cnt > 1) {
1090 verbose = DEBUG_FLAG;
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",
1103 result = Tspi_Context_Connect(hContext, SERVER);
1104 if (result != TSS_SUCCESS) {
1105 printf("ERROR: Tspi_Context_Connect failed rc=0x%x\n",
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",
1121 /* Get EventLog via TSS */
1122 result = Tspi_TPM_GetEventLog(
1126 if (result != TSS_SUCCESS) { // ERROR
1127 printf("ERROR: Tspi_TPM_GetEventLog failed rc=0x%x\n",
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",
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]);
1156 PcrEvents[i].rgbEvent,
1157 PcrEvents[i].ulEventLength,
1158 PcrEvents[i].ulPcrIndex,
1159 PcrEvents[i].eventType,
1160 PcrEvents[i].rgbPcrValue);
1165 if (PcrEvents[i].ulPcrIndex == 10) { // IMA log
1166 if (memcmp(PcrEvents[i].rgbPcrValue, zero, 20) == 0) { // zero
1167 extend(PcrEvents[i].ulPcrIndex, fox);
1169 extend(PcrEvents[i].ulPcrIndex, PcrEvents[i].rgbPcrValue);
1171 // TODO get boot aggregate
1172 if (memcmp(PcrEvents[i].rgbEvent, "boot_aggregate", 14) == 0) {
1173 memcpy(boot_aggregate, PcrEvents[i].rgbPcrValue, 20);
1177 extend(PcrEvents[i].ulPcrIndex, PcrEvents[i].rgbPcrValue);
1180 if (PcrEvents[i].ulPcrIndex == 10) {
1189 fprintf(fp, "Verify IML :-)\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);
1197 for (j = 0; j < 20; j++) {
1198 fprintf(fp, "%02x", pcr[i][j]);
1201 result = Tspi_TPM_PcrRead(hTPM, i, &blobLength, &blob);
1202 if (result != TSS_SUCCESS) { // ERROR
1203 ERROR("PrcRead failed rc=0x%x\n",
1208 if (memcmp(&pcr[i][0], blob, 20) == 0) {
1209 fprintf(fp, " == ");
1211 fprintf(fp, " != ");
1214 for (j = 0; j < 20; j++) {
1215 fprintf(fp, "%02x", blob[j]);
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]);
1232 for (j = 0; j < 20; j++) {
1233 fprintf(fp, "%02x", boot_aggregate[j]);
1241 result = Tspi_Context_FreeMemory(hContext, (BYTE *)PcrEvents);
1242 Tspi_Context_FreeMemory(hContext, NULL);
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);
1255 Tspi_Context_Close(hContext);