2 * This file is part of the OpenPTS project.
4 * The Initial Developer of the Original Code is International
5 * Business Machines Corporation. Portions created by IBM
6 * Corporation are Copyright (C) 2010 International Business
7 * Machines Corporation. All Rights Reserved.
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)
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.
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.
26 * \brief Load TCG Integrity Measurement Log (IML)
27 * @author Seiji Munetoh <munetoh@users.sourceforge.jp>
29 * cleanup 2011-07-06 SM
31 * get IML/PCRS from filesystem
32 * get IML/PCRS vis TSS
33 * create Snapshots with IML
39 #include <openssl/sha.h>
43 void printEventWrapper(OPENPTS_PCR_EVENT_WRAPPER *eventWrapper);
47 * reset snapshot array
50 * TODO reset level1 too
52 // TODO move to snapshot?
53 int resetSnapshot(OPENPTS_SNAPSHOT * snapshots) {
58 OPENPTS_PCR_EVENT_WRAPPER *eventWrapper;
59 OPENPTS_PCR_EVENT_WRAPPER *eventWrapper_next;
61 for (i = 0; i < MAX_PCRNUM; i++) {
63 eventWrapper = ss->start;
64 for (j = 0; j < ss->event_num; j++) {
65 event = eventWrapper->event;
67 if (event->rgbPcrValue != NULL)
68 free(event->rgbPcrValue);
69 if (event->rgbEvent != NULL)
70 free(event->rgbEvent);
73 ERROR("resetSnapshot - NULL event\n"); // TODO(munetoh)
75 eventWrapper_next = eventWrapper->next_pcr;
77 eventWrapper = eventWrapper_next;
79 // if (iml[i].eventList != NULL) free(iml[i].eventList);
86 return 0; // TODO(munetoh)
93 OPENPTS_PCR_EVENT_WRAPPER * newEventWrapper() {
94 OPENPTS_PCR_EVENT_WRAPPER *ew;
96 ew = (OPENPTS_PCR_EVENT_WRAPPER *)malloc(sizeof(OPENPTS_PCR_EVENT_WRAPPER));
98 ERROR("newEventWrapper() - no memory\n");
102 memset(ew, 0, sizeof(OPENPTS_PCR_EVENT_WRAPPER));
110 void freeEventWrapper(OPENPTS_PCR_EVENT_WRAPPER * ew) {
118 void freeEventWrapperChain(OPENPTS_PCR_EVENT_WRAPPER * ew) {
119 TSS_PCR_EVENT *event;
122 ERROR("OPENPTS_PCR_EVENT_WRAPPE is NULL\n");
126 if (ew->next_pcr != NULL) {
127 freeEventWrapperChain(ew->next_pcr);
133 // OPENPTS_SNAPSHOT *ss = ew->snapshot;
134 // DEBUG("freeEventWrapperChain() - free event index=%3d pcr=%2d level =%d type=0x%04x\n",
135 // ew->index, event->ulPcrIndex, ss->level, event->eventType);
137 if (event->rgbPcrValue != NULL)
138 free(event->rgbPcrValue);
139 if (event->rgbEvent != NULL)
140 free(event->rgbEvent);
143 ERROR("freeSnapshot - NULL event\n"); // TODO(munetoh)
150 #define OPENPTS_FSM_NO_LEVEL1 10
153 * add Event to Snapshopt
154 * IML-> IR, check with Behavir FSM
155 * IML-> RM, check with Behavir FSM
159 * PTS_INVALID_SNAPSHOT bad event (FSM fail)
160 * PTS_INTERNAL_ERROR else
162 * OPENPTS_FSM_TRANSIT => transit to next level of FSM
163 * OPENPTS_FSM_FINISH_WO_HIT => transit to next level of FSM
166 * OPENPTS_FSM_SUCCESS => PTS_SUCCESS
167 * OPENPTS_FSM_FINISH => PTS_SUCCESS
168 * OPENPTS_FSM_ERROR => PTS_INVALID_SNAPSHOT + reason << BAD IML
169 * OPENPTS_FSM_NO_LEVEL1 => PTS_INTERNAL_ERROR + reason
172 int addEventToSnapshotBhv(
173 OPENPTS_CONTEXT * ctx,
174 OPENPTS_PCR_EVENT_WRAPPER * eventWrapper) {
177 OPENPTS_SNAPSHOT *ss;
180 DEBUG_CAL("addEventToSnapshot - start\n");
182 if (eventWrapper == NULL) {
183 ERROR("null eventWrapper\n");
184 return PTS_INTERNAL_ERROR; // OPENPTS_FSM_ERROR;
187 index = eventWrapper->event->ulPcrIndex;
190 DEBUG_FSM("[PCR%02d] addEventToSnapshotBhv()\n", index);
192 /* skip Bad Snapshot/PCR[n] */
193 // 20101124 SM use common SS error flag par pcr_index
194 if (ctx->ss_table->error[index] != PTS_SUCCESS) {
195 return ctx->ss_table->error[index];
200 Snapshot by PCR, by Level
202 Active FSM(LV0) FSM(LV1) level
203 ----------------------------------------
210 active_level = getActiveSnapshotLevel(ctx->ss_table, index);
212 if (active_level == 0) {
213 /* use level 0 snapshot */
214 ss = getSnapshotFromTable(ctx->ss_table, index, 0);
217 /* level 0 SS is null => check Level 1 SS */
218 ss = getSnapshotFromTable(ctx->ss_table, index, 1);
220 addReason(ctx, "[PCR%02d] Snapshot(FSM) is missing for PCR%d. Please check the configuration file '%s'",
222 index, ctx->conf->config_file);
223 ctx->ss_table->error[index] = PTS_INTERNAL_ERROR;
224 return PTS_INTERNAL_ERROR;
228 if (ss->fsm_behavior != NULL) {
229 /* OK, BHV-FSM exist at level 1 => chenge the active Level to 1 */
230 setActiveSnapshotLevel(ctx->ss_table, index, 1);
232 // DEBUG_FSM("pcr%d SKIP to level 1\n", index);
233 DEBUG_FSM("[PCR%02d] RM0 -> RM1 (RM0 is missing)\n");
237 "[RM01-PCR%02d] FSM is missing for PCR%d, Level 1. Please check the configuration file '%s'",
239 index, ctx->conf->config_file);
240 ctx->ss_table->error[index] = PTS_INTERNAL_ERROR;
241 return PTS_INTERNAL_ERROR;
247 if (ss->fsm_behavior == NULL) {
248 /* no BHV-FSM => check the next level, 1 */
250 /* check level 1 SS */
251 ss = getSnapshotFromTable(ctx->ss_table, index, 1);
255 "[PCR%02d] Snapshot is missing for PCR%d for Level 0 and 1. "
256 "Please check the configuration file '%s'",
259 ctx->conf->config_file);
260 ctx->ss_table->error[index] = PTS_INTERNAL_ERROR;
261 return PTS_INTERNAL_ERROR;
264 /* check FSM at level 1 */
265 if (ss->fsm_behavior != NULL) {
266 /* BHV-FSM lexist at level 1 << Active Level */
267 DEBUG_FSM("pcr%d SKIP to level 1\n", index);
268 setActiveSnapshotLevel(ctx->ss_table, index, 1);
273 "[RM01-PCR%02d] FSM is missing for PCR%d, Level 1. Please check the configuration file '%s'",
275 index, ctx->conf->config_file);
276 ctx->ss_table->error[index] = PTS_INTERNAL_ERROR;
277 return PTS_INTERNAL_ERROR; // OPENPTS_FSM_ERROR;
280 } else if (active_level == 1) {
281 /* active level is 1, check the level 1 */
282 ss = getSnapshotFromTable(ctx->ss_table, index, 1);
285 DEBUG("ss == NULL => Reason\n");
287 "[RM%02d-PCR%02d] Snapshot is missing for PCR%d, Level %d. Please check the configuration file '%s'",
291 active_level, ctx->conf->config_file);
292 ctx->ss_table->error[index] = PTS_INTERNAL_ERROR;
293 return PTS_INTERNAL_ERROR;
297 if (ss->fsm_behavior == NULL) {
299 DEBUG("ss->fsm_behavior == NULL => Reason\n");
301 "[RM%02d-PCR%02d] FSM is missing for PCR%d, Level %d. Please check the configuration file '%s'",
305 index, ctx->conf->config_file);
306 ctx->ss_table->error[index] = PTS_INTERNAL_ERROR;
307 return PTS_INTERNAL_ERROR;
310 /* OK, the BHV-FSM exists at Level 1*/
313 ERROR("level >1 is TBD, pcr=%d level=%d\n", index, active_level);
314 return PTS_INTERNAL_ERROR;
317 /* set sw->ss link */
318 eventWrapper->snapshot = ss;
319 eventWrapper->index = ss->event_num; // ID for EV_ACTION
321 /* Parse Event by BHV-FSM Model */
322 rc = updateFsm(ctx, ss->fsm_behavior, eventWrapper);
323 if (rc == OPENPTS_FSM_ERROR) {
324 /* FSM detect invalid IML, or bad FSM for this IML */
325 DEBUG("[RM%02d-PCR%02d] updateFsm() => OPENPTS_FSM_ERROR ===> rc=PTS_INVALID_SNAPSHOT, added Reason\n",
326 active_level, index);
327 addReason(ctx, "[RM%02d-PCR%02d] IML validation by FSM was faild. State='%s' at the FSM is '%s'",
330 ss->fsm_behavior->curr_state->name,
331 ss->fsm_behavior->uml_file);
332 ctx->ss_table->error[index] = PTS_INVALID_SNAPSHOT;
333 rc = PTS_INVALID_SNAPSHOT;
334 } else if (rc == OPENPTS_FSM_FINISH) {
335 /* OK, FSM finish successfly */
336 ss->fsm_behavior->status = OPENPTS_FSM_FINISH;
339 /* Move to next level (0->1) */
340 incActiveSnapshotLevel(ctx->ss_table, index);
341 } else if (rc == OPENPTS_FSM_SUCCESS) {
344 } else if (rc == OPENPTS_FSM_TRANSIT) {
345 // TRANSIT, Skip update SS chain
346 // TODO set by updateFsm
347 ss->fsm_behavior->status = OPENPTS_FSM_FINISH;
349 /* Move to next level (0->1) */
350 incActiveSnapshotLevel(ctx->ss_table, index);
352 } else if (rc == OPENPTS_FSM_FINISH_WO_HIT) {
353 // TRANSIT, Skip update SS chain
354 // TODO set by updateFsm
355 ss->fsm_behavior->status = OPENPTS_FSM_FINISH;
357 /* Move to next level (0->1) */
358 incActiveSnapshotLevel(ctx->ss_table, index);
360 } else if (rc == OPENPTS_FSM_MIGRATE_EVENT) {
361 /* this event is migrated to target PCR, remove from this SS (did not put the EW chain) */
364 ERROR("updateFsm rc=%d\n", rc);
368 /* update SS chain */
369 if (ss->event_num == 0) {
371 ss->start = eventWrapper;
372 ss->end = eventWrapper;
375 ss->end->next_pcr = eventWrapper;
376 ss->end = eventWrapper;
381 DEBUG_CAL("addEventToSnapshot - done\n");
386 * add Event to Snapshopt
387 * IR-> check with Binary FSM (RM)
391 * PTS_INVALID_SNAPSHOT bad event (FSM fail)
392 * PTS_INTERNAL_ERROR else
396 int addEventToSnapshotBin(
397 OPENPTS_CONTEXT * ctx,
398 OPENPTS_PCR_EVENT_WRAPPER * eventWrapper) {
401 OPENPTS_SNAPSHOT *ss;
404 DEBUG_CAL("addEventToSnapshotBin - start\n");
407 if (eventWrapper == NULL) {
408 ERROR("null eventWrapper\n");
409 return PTS_INTERNAL_ERROR;
412 index = eventWrapper->event->ulPcrIndex;
414 /* Get active snapshot level of this PCR */
415 active_level = getActiveSnapshotLevel(ctx->ss_table, index);
418 ss = getSnapshotFromTable(ctx->ss_table, index, active_level);
420 /* check the next level */
422 ss = getSnapshotFromTable(ctx->ss_table, index, active_level);
424 /* check next level (1) */
426 // ERROR("addEventToSnapshotBin() - pcr=%d Level=%d snapshots is missing\n",index, active_level);
427 addReason(ctx, "[PCR%02d] Snapshot(FSM) is missing",
429 ctx->ss_table->error[index] = PTS_INTERNAL_ERROR;
430 return PTS_INTERNAL_ERROR;
432 /* Exist use this level as active */
433 incActiveSnapshotLevel(ctx->ss_table, index);
438 /* skip Bad Snapshot/PCR[n] */
439 // 20101124 SM use common SS error flag par pcr_index
440 if (ctx->ss_table->error[index] != PTS_SUCCESS) {
441 return ctx->ss_table->error[index];
444 /* link between Snapshot - event wrapper */
445 eventWrapper->snapshot = ss;
446 eventWrapper->index = ss->event_num;
448 /* Checked by BIN-FSM Model, Do validation by RM */
449 if (ss->fsm_binary != NULL) {
450 /* OK, drive the FSM */
451 rc = updateFsm(ctx, ss->fsm_binary, eventWrapper); // fsm.c
452 if (rc == OPENPTS_FSM_ERROR) {
454 DEBUG_FSM("addEventToSnapshotBin() - No trans, return PTS_INVALID_SNAPSHOT\n");
455 // TODO Broken FSM - 20110115 SM under ARU test
456 if (ss->fsm_binary == NULL) {
457 ERROR("ss->fsm_binary == NULLn");
458 addReason(ctx, "[RM%02d-PCR%02d-MissingFSM] IR validation by RM was faild",
461 } else if (ss->fsm_binary->curr_state == NULL) {
462 ERROR("ss->fsm_binary->curr_state == NULL\n");
463 addReason(ctx, "[RM%02d-PCR%02d-MissingState] IR validation by RM was faild",
466 } else if (ss->fsm_binary->curr_state->name[0] == 0) { // TODO malloc the name
467 ERROR("ss->fsm_binary->curr_state->name == NULL\n");
468 addReason(ctx, "[RM%02d-PCR%02d-MissingStateName] IR validation by RM was faild",
472 addReason(ctx, "[RM%02d-PCR%02d-%s] IR validation by RM was faild",
475 ss->fsm_binary->curr_state->name);
477 ctx->ss_table->error[index] = PTS_INVALID_SNAPSHOT;
478 return PTS_INVALID_SNAPSHOT;
483 if (active_level == 0) { // TODO here, the level is 0 or 1
484 /* check the next level */
485 ss = getSnapshotFromTable(ctx->ss_table, index, 1);
487 // ERROR("no BIN-FSM at level 0, no SS at level 1\n");
488 addReason(ctx, "[PCR%02d] Snapshot(FSM) is missing",
490 ctx->ss_table->error[index] = PTS_INTERNAL_ERROR;
491 return PTS_INTERNAL_ERROR;
494 if (ss->fsm_binary != NULL) {
495 // DEBUG("addEventToSnapshot - level 0 BIN-FSM is null, move to Level 1 FSM\n");
496 /* move to next the level */
497 incActiveSnapshotLevel(ctx->ss_table, index);
498 DEBUG_FSM("move to level %d\n", getActiveSnapshotLevel(ctx->ss_table, index));
499 /* Update with new SS */
500 ss = getSnapshotFromTable(ctx->ss_table, index, 1); // TODO new func for next
502 ERROR("getSnapshotFromTable(%d,%d) is NULL\n", index, 1);
503 return PTS_INTERNAL_ERROR;
505 eventWrapper->snapshot = ss;
506 rc = updateFsm(ctx, ss->fsm_binary, eventWrapper);
507 if (rc == OPENPTS_FSM_ERROR) {
508 DEBUG_FSM("No trans, return PTS_INVALID_SNAPSHOT at %s\n", ss->fsm_binary->curr_state->name);
509 DEBUG("updateFsm fail\n");
510 addReason(ctx, "[RM%02d-PCR%02d-%s] IR validation by RM was faild",
513 ss->fsm_binary->curr_state->name);
514 ctx->ss_table->error[index] = PTS_INVALID_SNAPSHOT;
515 return PTS_INVALID_SNAPSHOT;
519 ERROR("no BIN-FSM at level 0, no BIN-FSM at level 1\n");
520 addReason(ctx, "[PCR%02d] Snapshot(FSM) is missing",
522 ctx->ss_table->error[index] = PTS_INTERNAL_ERROR;
523 return PTS_INTERNAL_ERROR;
528 /* update SS chain */
530 if (ss->event_num == 0) {
532 ss->start = eventWrapper;
533 ss->end = eventWrapper;
536 ss->end->next_pcr = eventWrapper;
537 ss->end = eventWrapper;
546 * flash Snapshot -> FSM -> Final
550 * PTS_INVALID_SNAPSHOT
554 OPENPTS_CONTEXT * ctx,
557 OPENPTS_SNAPSHOT *ss;
558 OPENPTS_SNAPSHOT *ss_lv0 = NULL;
561 DEBUG_CAL("flashSnapshot - start\n");
564 Active FSM(LV0) FSM(LV1) new level
565 ----------------------------------------
572 /* which level now ? */
573 active_level = getActiveSnapshotLevel(ctx->ss_table, index);
576 ss = getSnapshotFromTable(ctx->ss_table, index, active_level);
578 ERROR("No Snapshot at PCR[%d]. level %d\n", index, active_level);
579 // return PTS_INTERNAL_ERROR;
582 ss = getSnapshotFromTable(ctx->ss_table, index, active_level);
584 ERROR("No Snapshot at PCR[%d], level %d\n", index, active_level);
585 return PTS_INTERNAL_ERROR;
587 DEBUG("Skip Null SS level. level = %d\n", active_level);
591 if (active_level == 0) {
592 /* use level 0 snapshot, but */
593 if (ss->fsm_binary == NULL) {
594 /* FSM is missing at level 0, move to level 1 */
596 ss = getSnapshotFromTable(ctx->ss_table, index, 1);
598 ERROR("PCR[%d] level 1 SS is null\n", index);
599 return PTS_INTERNAL_ERROR;
602 if (ss->fsm_binary != NULL) {
604 DEBUG("PCR[%d] SKIP to level 1\n", index);
605 setActiveSnapshotLevel(ctx->ss_table, index, 1);
608 ERROR("level 1 BHV-FSM is null\n");
609 return PTS_INTERNAL_ERROR;
612 } else if (active_level == 1) {
613 /* use level 1 snapshot */
614 if (ss->fsm_binary == NULL) {
615 ERROR("Missing BIB-FSM pcr=%d,level=%d, ss=%p -> %p\n",
616 index, active_level, ss_lv0, ss);
617 // printeventWrapper(eventWrapper);
618 return PTS_INTERNAL_ERROR;
621 ERROR("level %d is not supported yet\n", active_level);
622 return PTS_INTERNAL_ERROR;
625 /* if SS has been got error skip the flash operation */
626 if (ctx->ss_table->error[index] == PTS_INVALID_SNAPSHOT) {
627 DEBUG_FSM("skip flashSnapshot since SS has PTS_INVALID_SNAPSHOT error\n");
628 return PTS_INVALID_SNAPSHOT;
631 /* Parse Event by BIN-FSM Model, Do validation by RM */
633 DEBUG_FSM("flashSnapshot - PCR[%d] BIN-FSM exist\n", index);
636 rc = updateFsm(ctx, ss->fsm_binary, NULL);
638 if (rc == OPENPTS_FSM_FINISH_WO_HIT) {
639 // OK, reach Final state, but event is not consumed
640 setActiveSnapshotLevel(ctx->ss_table, index, 1);
641 DEBUG_FSM("updateFsm, OPENPTS_FSM_FINISH_WO_HIT => PCR[%d] level => %d\n",
642 index, getActiveSnapshotLevel(ctx->ss_table, index));
643 } else if (rc == OPENPTS_FSM_FINISH) {
644 // OK, reach Final state,
645 setActiveSnapshotLevel(ctx->ss_table, index, 1);
646 // TODO check_rm > ERROR:iml.c:620 updateFsm, OPENPTS_FSM_FINISH => PCR[5] level => 1
647 DEBUG_FSM("updateFsm, OPENPTS_FSM_FINISH => PCR[%d] level => %d\n",
648 index, getActiveSnapshotLevel(ctx->ss_table, index));
649 } else if (rc == OPENPTS_FSM_TRANSIT) {
650 // OK, reach Final state
651 setActiveSnapshotLevel(ctx->ss_table, index, 1);
652 DEBUG_FSM("updateFsm, OPENPTS_FSM_TRANSIT => PCR[%d] level => %d\n",
653 index, getActiveSnapshotLevel(ctx->ss_table, index));
654 } else if (rc == OPENPTS_FSM_SUCCESS) {
656 DEBUG_FSM("updateFsm, OPENPTS_FSM_SUCCESS => PCR[%d] level == %d\n",
657 index, getActiveSnapshotLevel(ctx->ss_table, index));
658 } else if (rc == OPENPTS_FSM_ERROR) {
659 ERROR("flashSnapshot - updateFsm fail, rc = %d\n", rc);
660 } else if (rc == OPENPTS_FSM_ERROR_LOOP) {
662 // DEBUG("flashSnapshot - updateFsm looped - end of the IMA IML, rc = %d\n", rc);
664 ERROR("flashSnapshot - updateFsm rc=%d\n", rc);
667 DEBUG_CAL("flashSnapshot - done\n");
674 * \brief read IML via TSS, get whole IML
677 * 1: stacked snapshot (by FSM)
679 * IML->TSS->snapshot(BHV-FSM)->RM
680 * IML->TSS->snapshot(BHV-FSM)->IR
686 int getIml(OPENPTS_CONTEXT * ctx, int option) {
690 #else // CONFIG_NO_TSS
691 int getIml(OPENPTS_CONTEXT * ctx, int option) {
694 TSS_HCONTEXT hContext;
696 TSS_PCR_EVENT *pcrEvents;
697 UINT32 ulEventNumber = 0;
698 OPENPTS_PCR_EVENT_WRAPPER *ew_new = NULL;
699 // OPENPTS_PCR_EVENT_WRAPPER *ew_last = NULL;
703 DEBUG_CAL("getIml - start\n");
706 resetTpm(&ctx->tpm, 0); // reset TPM DRTM=off
709 if (ctx->ss_table == NULL) {
710 ERROR("SS table is null\n");
711 return PTS_INTERNAL_ERROR;
714 /* Connect to TCSD */
715 result = Tspi_Context_Create(&hContext);
716 if (result != TSS_SUCCESS) {
717 ERROR("ERROR: Tspi_Context_Create failed rc=0x%x\n", result);
721 result = Tspi_Context_Connect(hContext, SERVER);
722 if (result != TSS_SUCCESS) {
723 ERROR("ERROR: Tspi_Context_Connect failed rc=0x%x\n", result);
727 /* Get TPM handles */
728 result = Tspi_Context_GetTpmObject(hContext, &hTPM);
729 if (result != TSS_SUCCESS) {
730 ERROR("ERROR: Tspi_Context_GetTpmObject failed rc=0x%x\n", result);
736 result = Tspi_TPM_GetEventLog(hTPM, &ulEventNumber, &pcrEvents);
737 if (result != TSS_SUCCESS) { // ERROR
738 ERROR("ERROR: Tspi_TPM_GetEventLog failed rc=0x%x\n", result);
742 DEBUG("IML(via TSS) : %d events\n", ulEventNumber);
744 ctx->ss_table->event_num = ulEventNumber;
746 /* map to the snapshot */
747 if (option == 0) { // simple, snapshot[i] hold all events on PCR[i]
748 TSS_PCR_EVENT *tpe_tss;
752 for (i = 0; i < (int) ulEventNumber; i++) {
753 tpe_tss = &pcrEvents[i];
755 /* copy event to local */
756 tpe = (TSS_PCR_EVENT *) malloc(sizeof(TSS_PCR_EVENT));
758 return -1; // TODO(munetoh)
760 memcpy(tpe, tpe_tss, sizeof(TSS_PCR_EVENT));
761 // index = tpe->ulPcrIndex;
764 tpe->rgbPcrValue = (BYTE *) malloc(tpe->ulPcrValueLength);
765 if (tpe->rgbPcrValue == NULL) {
766 return -1; // TODO(munetoh)
768 memcpy(tpe->rgbPcrValue,
769 tpe_tss->rgbPcrValue,
770 tpe->ulPcrValueLength);
772 if (tpe->ulEventLength > 0) {
774 tpe->rgbEvent = (BYTE *) malloc(tpe->ulEventLength);
775 if (tpe->rgbEvent == NULL) {
776 return -1; // TODO(munetoh)
778 memcpy(tpe->rgbEvent,
782 tpe->rgbEvent = NULL;
787 ew_new = (OPENPTS_PCR_EVENT_WRAPPER *)
788 malloc(sizeof(OPENPTS_PCR_EVENT_WRAPPER));
789 if (ew_new == NULL) {
790 ERROR("no memory\n");
793 memset(ew_new, 0, sizeof(OPENPTS_PCR_EVENT_WRAPPER));
796 /* map to the snapshot (BHV-FSM) */
797 rc = addEventToSnapshotBhv(ctx, ew_new); // iml.c
799 if (rc == PTS_SUCCESS) {
801 } else if (rc == PTS_INVALID_SNAPSHOT) { // OPENPTS_FSM_ERROR) {
802 /* ERROR but continue the verification of rest of IML */
804 } else if (rc == PTS_INTERNAL_ERROR) { // 58
806 } else if (rc == OPENPTS_FSM_TRANSIT) {
807 DEBUG_FSM("\tTransit to next FSM ======================================\n");
808 rc = addEventToSnapshotBhv(ctx, ew_new); // iml.c
809 } else if (rc == OPENPTS_FSM_FINISH_WO_HIT) {
810 DEBUG_FSM("\tTransit to next FSM ======================================\n");
811 rc = addEventToSnapshotBhv(ctx, ew_new); // iml.c
814 ERROR("getIml - addEventToSnapshotBhv rc = %d\n", rc);
818 rc = extendTpm(&ctx->tpm, ew_new->event);
820 ERROR("getIml - extendTpm fail\n");
824 } else if (option == 1) {
825 // stacked snapshot with FSM
831 rc = (int) ulEventNumber;
835 // Keep IML data? we have to free by ourselves
836 result = Tspi_Context_FreeMemory(hContext, (BYTE *) pcrEvents);
837 Tspi_Context_FreeMemory(hContext, NULL);
841 Tspi_Context_Close(hContext);
845 snprintf(buf, BUF_SIZE, "[IML] Load IML (via TSS) was faild");
847 return PTS_INVALID_SNAPSHOT;
851 DEBUG_CAL("getIml - end\n");
855 #endif // CONFIG_NO_TSS
858 * fread + endian conv
862 UINT32 freadUint32(FILE * stream, int endian) {
868 size = fread(&data, 1, 4, stream);
871 // This is EOF ERROR("\n");
872 return 0xFFFFFFFF; // TODO
889 // DEBUG(" %08x -> %08x\n", data ,out);
896 * \brief read BIOS IML file
898 * PCR0-7 - BIOS => Level 0
899 * PCR4,5,8 - GRUB => Level 1
903 * \param filename -- TODO unicode? or url?
907 * 2:use BHV-FSM + Endian Conv (for PPC Test on X86 ) + 4-byte aligned
909 * event num => ctx->ss_table->event_num
913 * PTS_INVALID_SNAPSHOT
917 // TODO rename readBiosImlFile()
918 int readBiosImlFile(OPENPTS_CONTEXT * ctx, const char *filename, int mode) {
919 int rc = PTS_SUCCESS;
930 TSS_PCR_EVENT *event = NULL;
931 OPENPTS_PCR_EVENT_WRAPPER *ew_new = NULL;
932 // OPENPTS_PCR_EVENT_WRAPPER *ew_last = NULL;
935 DEBUG_CAL("getBiosImlFile - start\n");
936 // DEBUG("read BIOS IML, file %s\n", filename);
940 ERROR("ERROR\n"); // TODO(munetoh)
941 return PTS_INTERNAL_ERROR;
943 if (filename == NULL) {
944 ERROR("ERROR\n"); // TODO(munetoh)
945 return PTS_INTERNAL_ERROR;
949 if ((fp = fopen(filename, "rb")) == NULL) {
950 ERROR("%s missing", filename);
951 return PTS_INTERNAL_ERROR;
955 if (mode == USE_BHV_FSM_EC) {
957 endian = 1; // TODO conf->iml_endian?
958 aligned = 4; // TODO conf->iml_aligned?
961 /* Read IML, add to Snapshot */
964 pcrIndex = freadUint32(fp, endian);
965 if (pcrIndex == 0xFFFFFFFF) {
969 if (pcrIndex > MAX_PCRNUM) {
970 ERROR("BIOS IML File %s, bad pcr index value %d at %d event\n",
971 filename, pcrIndex, i);
972 rc = PTS_INTERNAL_ERROR;
977 eventType = freadUint32(fp, endian);
978 event = (TSS_PCR_EVENT *) malloc(sizeof(TSS_PCR_EVENT));
980 ERROR("no memory\n");
984 memset(event, 0, sizeof(TSS_PCR_EVENT));
986 // event->versionInfo = 0; // TODO(munetoh)
987 event->ulPcrIndex = pcrIndex;
988 event->eventType = eventType;
991 event->ulPcrValueLength = SHA1_DIGEST_SIZE;
992 event->rgbPcrValue = (BYTE *) malloc(SHA1_DIGEST_SIZE); // leaked
993 if (event->rgbPcrValue == NULL) {
994 ERROR("no memory\n");
998 size = fread(event->rgbPcrValue, 1, SHA1_DIGEST_SIZE, fp);
999 if (size != SHA1_DIGEST_SIZE) { // TODO(munetoh) SHA1 only
1000 ERROR("BIOS IML File %s, bad pcr size %d at %d event\n",
1001 filename, (int)size, i);
1002 rc = PTS_INTERNAL_ERROR;
1007 eventLength = freadUint32(fp, endian);
1008 event->ulEventLength = eventLength;
1009 /* adjust read data length */
1011 if ((eventLength & 0x03) != 0) {
1012 // DEBUG("FIX alignement\n");
1013 eventLength = (eventLength & 0xFFFFFFFC) + 0x04;
1016 /* malloc EventData */
1017 if ((event->rgbEvent = malloc(eventLength)) == NULL) {
1018 ERROR("no memory\n");
1022 // TODO if rgbevent is huge 0x4000000 #=> check the endian
1023 size = fread(event->rgbEvent, 1, eventLength, fp);
1024 if (size != eventLength) {
1025 ERROR("BIOS IML File %s, bad eventdata size 0x%x != 0x%xat %d event\n",
1026 filename, (int)size, (int)eventLength, i);
1027 rc = PTS_INTERNAL_ERROR;
1033 if (eventLength > 2000) {
1034 TODO("eventLength = %d\n", eventLength);
1035 printHex("", event->rgbEvent, eventLength, "\n");
1039 /* create event wrapper */
1040 ew_new = (OPENPTS_PCR_EVENT_WRAPPER *)
1041 malloc(sizeof(OPENPTS_PCR_EVENT_WRAPPER));
1042 if (ew_new == NULL) {
1043 ERROR("no memory\n");
1047 memset(ew_new, 0, sizeof(OPENPTS_PCR_EVENT_WRAPPER));
1048 ew_new->event = event;
1050 /* add to the snapshot */
1051 if (mode == USE_BHV_FSM) {
1052 /* BHV-FSM - map to the snapshot */
1053 result = addEventToSnapshotBhv(ctx, ew_new); // iml.c
1055 if (result == PTS_SUCCESS) {
1057 } else if (result == PTS_INVALID_SNAPSHOT) { // OPENPTS_FSM_ERROR) {
1058 /* ERROR but continue the verification of rest of IML */
1060 } else if (result == PTS_INTERNAL_ERROR) { // 58
1062 } else if (result == OPENPTS_FSM_TRANSIT) {
1063 DEBUG_FSM("\tTransit to next FSM ======================================\n");
1064 rc = addEventToSnapshotBhv(ctx, ew_new); // iml.c
1065 } else if (result == OPENPTS_FSM_FINISH_WO_HIT) {
1066 DEBUG_FSM("\tTransit to next FSM ======================================\n");
1067 result = addEventToSnapshotBhv(ctx, ew_new); // iml.c
1068 } else if (result == OPENPTS_FSM_MIGRATE_EVENT) {
1072 ERROR("getBiosImlFile - addEventToSnapshotBhv rc = %d\n", rc);
1074 } else { // USE_BIN_FSM
1075 /* BIN-FSM - map to the snapshot */
1076 result = addEventToSnapshotBin(ctx, ew_new); // iml.c
1078 if (result == OPENPTS_FSM_SUCCESS) {
1080 } else if (result == PTS_INVALID_SNAPSHOT) {
1082 } else if (result == OPENPTS_FSM_TRANSIT) {
1083 DEBUG_FSM("\tTransit to next FSM ======================================\n");
1084 result = addEventToSnapshotBin(ctx, ew_new); // iml.c
1085 if (result < 0) { // TODO
1086 TODO("getBiosImlFile - addEventToSnapshotBin rc = %d\n", rc);
1088 } else if (result == OPENPTS_FSM_FINISH_WO_HIT) {
1089 DEBUG_FSM("\tTransit to next FSM ======================================\n");
1090 result = addEventToSnapshotBin(ctx, ew_new); // iml.c
1091 if (result < 0) { // TODO
1092 TODO("getBiosImlFile - addEventToSnapshotBin rc = %d\n", rc);
1096 ERROR("getBiosImlFile - addEventToSnapshotBin rc = %d\n", rc);
1101 result = extendTpm(&ctx->tpm, ew_new->event);
1103 ERROR("extend TPM fail\n");
1104 rc = PTS_INTERNAL_ERROR;
1108 /* moved to the snapshot */
1113 ctx->ss_table->event_num++;
1119 if (fclose(fp) == EOF) {
1120 ERROR("BIOS IML File %s, read fail\n", filename);
1121 rc = PTS_INTERNAL_ERROR;
1123 DEBUG("read BIOS IML, file %s => %d events\n", filename, ctx->ss_table->event_num);
1126 addReason(ctx, "[IML] Load IML(file:%s) was faild",
1128 rc = PTS_INVALID_SNAPSHOT;
1131 /* free (for ERROR) */
1132 if (event != NULL) {
1133 if (event->rgbPcrValue != NULL) free(event->rgbPcrValue);
1134 if (event->rgbEvent != NULL) free(event->rgbEvent);
1137 if (ew_new != NULL) free(ew_new);
1139 DEBUG_CAL("iml.c - getBiosImlFile - done\n");
1146 #define TEMPLATE_TYPE_SIZE 16
1149 * \brief read Runtime(Linux-IMA) IML file
1151 * there are many binary format types :-(
1152 * 1 BINARY_IML_TYPE_IMA_ORIGINAL ima (before kernel 2.6.30, patch set)
1153 * 2 BINARY_IML_TYPE_IMA ima (after kernel 2.6.31, mainline)
1154 * 3 BINARY_IML_TYPE_IMA_NG ima-ng (after kernel 2.6.3X, mainline)
1155 * 4 BINARY_IML_TYPE_IMA_NGLONG ima-ng-long (after kernel 2.6.3X, mainline)
1157 * Snapshot - PCR10, Level 1
1159 * \param filename -- TODO unicode? or url?
1160 * \param mode 0:use BHV-FSM, 1:use BIN-FSM
1163 BINARY_IML_TYPE_IMA_ORIGINAL( Kernel 2.6.18 - Kernel 2.6.29)
1165 0a 00 00 00 | pcr index
1166 00 00 00 00 | type = 0
1167 9e 59 5e bf c6 46 af 46 9c 4b b1 30 00 30 f0 a0 34 bb 4a fe | digest
1168 0e 00 00 00 | length
1169 62 6f 6f 74 5f 61 67 67 72 65 67 61 74 65 | boot_aggregate
1171 0a 00 00 00 | pcr index
1172 01 00 00 00 | type = 1
1173 4c d4 10 cb d7 76 6b 06 72 df eb 0b 73 75 6c 49 0c 12 62 b6 | digest
1174 0b 00 00 00 | length
1175 2f 73 74 61 74 69 63 2f 61 73 68 | /static/ash
1177 0a 00 00 00 | pcr index
1178 01 00 00 00 | type = 1
1179 44 9c 07 6c 8b bd e6 38 c3 7e 07 5d 63 cc d7 a6 ac 66 02 a0 | digest
1180 0e 00 00 00 2f 73 74 61 74 69 63 2f 69 6e 73 6d 6f 64 | /static/insmod
1183 BINARY_IML_TYPE_IMA_31
1184 Fedora12(Kernel 2.6.31, 2.6.32)
1186 0a 00 00 00 | pcr index
1188 97 6c 6c d4 28 ca bb 21 ec a2 ac e6 e6 ac b0 c9 f3 97 ed bb | digest
1189 22 00 00 00 | len = 34 = 20+14
1190 36 b6 36 92 6c fd e5 e6 9c 62 6b 93 ca 39 b8 88 df 7b 00 04 | sha1(PCR0-8)
1191 62 6f 6f 74 5f 61 67 67 72 65 67 61 74 65 | boot_aggregate
1193 0a 00 00 00 | pcr index
1195 5c bd bf 4d de 8f 6c 07 37 fc 4a c1 41 fc 7c 55 d1 7a e4 a8 | digest
1196 19 00 00 00 | len = 25 = 20+5
1197 61 a6 44 44 de db 3d fa 89 e0 65 4c 4c e2 d8 c5 5f c7 c9 7b | sha1(/init)
1198 2f 69 6e 69 74 | /init
1201 Fedora12 2.6.32.12-115.fc12.x86_64 2010-06-30
1203 0a 00 00 00 | pcr index
1204 13 39 da 6c 77 98 a9 c2 b4 4f 1b 0d 87 58 5f d7 3f 7c 22 ce | digest
1205 03 00 00 00 | len = 3
1207 54 6c 57 74 80 74 91 68 a8 c5 d2 b9 03 b0 a9 60 59 96 54 0d | sha1(PCR0-8)
1208 0e 00 00 00 | len = 14
1209 62 6f 6f 74 5f 61 67 67 72 65 67 61 74 65 | boot_aggregate
1211 0a 00 00 00 | pcr index
1212 c7 b9 c2 03 94 48 3a 14 02 e1 e5 d4 51 50 a4 eb f4 6d 5a 16 | digest
1213 03 00 00 00 | len = 3
1215 4c 65 02 10 71 e8 e6 21 40 65 1b 3f 1b 62 ac ed 31 93 5d da | SHA1(/init)
1217 2f 69 6e 69 74 | /init
1220 BINARY_IML_TYPE_IMA new
1222 0a 00 00 00 | pcrindex = 10
1223 e5 07 75 aa a7 9f c4 0a 82 59 75 53 3b 13 f8 ab e5 15 26 6c | digest
1224 03 00 00 00 | len = 3
1225 69 6d 61 | type = ima
1226 54 72 86 ec a8 ea 52 96 1b 3d 46 09 a6 2a ff 34 b1 46 c8 46 | template digest
1228 62 6f 6f 74 5f 61 67 67 72 65 67 61 74 65 | boot_aggregate
1230 0a 00 00 00 | pcrindex = 10
1231 5c bd bf 4d de 8f 6c 07 37 fc 4a c1 41 fc 7c 55 d1 7a e4 a8 | digest
1232 03 00 00 00 | len = 3
1233 69 6d 61 | type = ima
1234 61 a6 44 44 de db 3d fa 89 e0 65 4c 4c e2 d8 c5 5f c7 c9 7b | template digest
1235 05 00 00 00 | len = 5
1236 2f 69 6e 69 74 | /init
1239 pcrindex => ulPcrIndex
1240 digest => rgbPcrValue
1241 template type => eventType = BINARY_IML_TYPE_IMA
1244 BINARY_IML_TYPE_IMA_NG new
1246 0a 00 00 00 | pcr index
1247 62 a5 b7 e8 43 7d 21 b9 a4 81 3c 1d 56 02 93 d5 48 ea 51 2f | SHA1(template)
1249 69 6d 61 2d 6e 67 | ima-ng
1250 36 00 00 00 | template size = 0x36
1251 73 68 61 32 35 36 00 | sha256
1252 06 85 35 49 b8 8d 5c 3d 8e 3d 5d d4 3f b9 88 02 | SHA256()
1253 b4 cb 5a b7 a5 0f e5 17 fd 40 eb 2a 71 f6 d5 49 | SHA256()
1254 62 6f 6f 74 5f 61 67 67 72 65 67 61 74 65 00 | boot_aggregate
1256 0a 00 00 00 | pcr index
1257 b6 d6 07 01 ff a9 e8 27 0b 85 f2 72 ec 6f 5e 65 1a 95 6c ab |
1259 69 6d 61 2d 6e 67 | ima-ng
1260 2d 00 00 00 | template size = 0x36
1261 73 68 61 32 35 36 00 | sha256
1262 7f 58 cc 2a 7f c1 b3 ae 7d 2a 6d 84 ce fb 79 c2 | SHA256()
1263 ea 13 09 82 66 f6 56 a1 9f c4 15 dc 7f 32 b3 0a | SHA256()
1264 2f 69 6e 69 74 00 | /init
1267 BINARY_IML_TYPE_IMA_NGLONG new
1270 09 bb 7f 01 03 4d 43 b9 d1 4f 3a 1d fd 2a b4 2b 5f 08 01 e8
1272 69 6d 61 2d 6e 67 6c 6f 6e 67 | ima-nglong
1274 73 68 61 32 35 36 00 |sha256|
1275 06 85 35 49 b8 8d 5c 3d 8e 3d 5d d4 3f b9 88 02
1276 b4 cb 5a b7 a5 0f e5 17 fd 40 eb 2a 71 f6 d5 49
1277 62 6f 6f 74 5f 61 67 67 72 65 67 61 74 65 00 | boot_aggregate|
1278 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1281 43 27 a6 14 2a 9e 78 10 be d8 29 2b 3a 47 f6 a3 eb a1 30 d9
1283 69 6d 61 2d 6e 67 6c 6f 6e 67
1285 73 68 61 32 35 36 00
1286 7f 58 cc 2a 7f c1 b3 ae 7d 2a 6d 84 ce fb 79 c2
1287 ea 13 09 82 66 f6 56 a1 9f c4 15 dc 7f 32 b3 0a
1288 2f 69 6e 69 74 00 | /init
1289 00 00 00 00 00 00 00 00
1291 75 6e 6c 61 62 65 6c 65 64 00 00 |unlabeled|
1293 6b 65 72 6e 65 6c 00 00 |kernel |
1296 d2 a1 0c 44 d7 d5 5a 41 48 75 2a 7d 01 cd 8c b3 fe 14 78 06
1298 69 6d 61 2d 6e 67 6c 6f 6e 67 |.ima-nglo|
1300 73 68 61 32 35 36 00
1301 0c 63 8b 44 75 d5 25 12 6d 2c ea 9f 35 8b de a9 |
1302 9e d0 f5 d2 a3 f9 5b 88 b3 30 da fb c9 0d 28 c9 |
1303 2f 69 6e 69 74 00 | /init + \0
1304 00 00 00 00 00 00 00 00 | ????
1305 0a 00 00 00 | len = 10
1306 75 6e 6c 61 62 65 6c 65 64 00 | unlabeled
1308 07 00 00 00 | len = 7
1309 6b 65 72 6e 65 6c 00 | kernel
1314 int readImaImlFile(OPENPTS_CONTEXT * ctx, const char *filename, int type, int mode, int *count) {
1315 int rc = PTS_SUCCESS;
1322 UINT32 template_len;
1323 UINT32 template_type_len;
1324 UINT32 filename_len;
1325 char buf[TEMPLATE_TYPE_SIZE];
1328 TSS_PCR_EVENT *event = NULL;
1329 OPENPTS_PCR_EVENT_WRAPPER *ew = NULL;
1330 OPENPTS_PCR_EVENT_WRAPPER *ew_last = NULL;
1332 DEBUG_CAL("readImaImlFile - start\n");
1336 ERROR("readImaImlFile - ctx is NULL\n"); // TODO(munetoh)
1339 if (filename == NULL) {
1340 ERROR("readImaImlFile - no filename\n"); // TODO(munetoh)
1345 if ((fp = fopen(filename, "rb")) == NULL) {
1346 ERROR("readImaImlFile - file open was failed, [%s]\n", filename);
1352 * level 0 <= nothing, num=0
1356 /* pass one - check the IML size */
1358 /* read PCR index */
1359 size = fread(&pcr_index, 1, 4, fp);
1361 /* end of event? => exit */
1364 if (pcr_index > MAX_PCRNUM) {
1365 ERROR("Linux-IMA IML File %s, bad pcr index value %d at %d event\n",
1366 filename, pcr_index, i);
1367 rc = PTS_INTERNAL_ERROR;
1371 /* alloc event structure */
1372 event = (TSS_PCR_EVENT *) malloc(sizeof(TSS_PCR_EVENT));
1373 if (event == NULL) {
1374 ERROR("no memory\n");
1378 memset(event, 0, sizeof(TSS_PCR_EVENT));
1379 event->ulPcrIndex = pcr_index;
1380 event->eventType = 0; // TODO
1381 event->ulPcrValueLength = 0;
1382 event->ulEventLength = 0;
1383 // event->versionInfo = 0; // TODO(munetoh)
1385 /* many formats :-( */
1386 if (type == BINARY_IML_TYPE_IMA_ORIGINAL) { // 2.6.29
1388 size = fread(&event->eventType, 1, 4, fp);
1390 ERROR("Linux-IMA(ORIGINAL) IML File %s, bad eventType at %d event\n",
1392 rc = PTS_INTERNAL_ERROR;
1396 /* read Digest (SHA1) */
1397 event->ulPcrValueLength = SHA1_DIGEST_SIZE;
1398 event->rgbPcrValue = (BYTE *) malloc(SHA1_DIGEST_SIZE);
1399 if (event->rgbPcrValue == NULL) {
1400 ERROR("no memory\n");
1404 size = fread(event->rgbPcrValue, 1, SHA1_DIGEST_SIZE, fp);
1405 if (size != SHA1_DIGEST_SIZE) {
1406 ERROR("Linux-IMA(ORIGINAL) IML File %s, bad pcr size %d at %d event\n",
1408 rc = PTS_INTERNAL_ERROR;
1412 /* read eventdata length */
1413 size = fread(&event->ulEventLength, 1, 4, fp);
1415 ERROR("Linux-IMA(ORIGINAL) IML File %s, bad event length size %d at %d event\n",
1417 rc = PTS_INTERNAL_ERROR;
1420 /* alloc eventdata */
1421 event->rgbEvent = malloc(event->ulEventLength);
1422 if (event->rgbEvent == NULL) {
1423 ERROR("no memory\n");
1427 // memset(event->rgbEvent,0,event->ulEventLength);
1430 size = fread(event->rgbEvent, 1, event->ulEventLength, fp);
1431 if (size != event->ulEventLength) {
1432 ERROR("Linux-IMA(ORIGINAL) IML File %s, bad event size %d at %d event\n",
1434 rc = PTS_INTERNAL_ERROR;
1437 } else if (type == BINARY_IML_TYPE_IMA_31) { // 2.6.30-32
1438 // DEBUG("getImaImlFile - BINARY_IML_TYPE_IMA_31\n");
1440 size = fread(&event_type, 1, 4, fp);
1442 ERROR("Linux-IMA(IMA_31) IML File %s, bad eventType at %d event\n",
1444 rc = PTS_INTERNAL_ERROR;
1448 /* read Digest (SHA1) */
1449 event->ulPcrValueLength = SHA1_DIGEST_SIZE;
1450 event->rgbPcrValue = (BYTE *) malloc(SHA1_DIGEST_SIZE);
1451 if (event->rgbPcrValue == NULL) {
1452 ERROR("no memory\n");
1456 size = fread(event->rgbPcrValue, 1, SHA1_DIGEST_SIZE, fp);
1457 if (size != SHA1_DIGEST_SIZE) {
1458 ERROR("Linux-IMA(IMA_31) IML File %s, bad pcr size %d at %d event\n",
1460 rc = PTS_INTERNAL_ERROR;
1464 /* read Template length */
1465 size = fread(&template_len, 1, 4, fp);
1467 ERROR("Linux-IMA(IMA_31) IML File %s, bad template size %d at %d event\n",
1469 rc = PTS_INTERNAL_ERROR;
1472 filename_len = template_len - 20;
1474 /* alloc template (=event data) */
1475 event->ulEventLength = 20 + 256; // TODO(munetoh)
1476 event->rgbEvent = malloc(event->ulEventLength);
1477 if (event->rgbEvent == NULL) {
1478 ERROR("no memory\n");
1482 memset(event->rgbEvent, 0, event->ulEventLength);
1484 /* read Template digest */
1485 size = fread(event->rgbEvent, 1, SHA1_DIGEST_SIZE, fp);
1486 if (size != SHA1_DIGEST_SIZE) {
1487 ERROR("Linux-IMA(IMA_31) IML File %s, bad event size %d at %d event\n",
1489 rc = PTS_INTERNAL_ERROR;
1493 // DEBUG("getImaImlFile - filename_len %d\n", filename_len);
1496 size = fread(&event->rgbEvent[20], 1, filename_len, fp);
1497 if (size != filename_len) {
1498 ERROR("Linux-IMA(IMA_31) IML File %s, bad event size %d != %dat %d event\n",
1499 filename, (int)size, (int)filename_len, i);
1500 rc = PTS_INTERNAL_ERROR;
1504 /* read Digest (SHA1) */
1505 event->ulPcrValueLength = SHA1_DIGEST_SIZE;
1506 event->rgbPcrValue = (BYTE *) malloc(SHA1_DIGEST_SIZE);
1508 size = fread(event->rgbPcrValue, 1, SHA1_DIGEST_SIZE, fp);
1509 if (size != SHA1_DIGEST_SIZE) {
1510 ERROR("Linux-IMA() IML File %s, bad pcr size %d at %d event\n",
1512 rc = PTS_INTERNAL_ERROR;
1516 /* read Template type length */
1517 size = fread(&template_type_len, 1, 4, fp);
1519 ERROR("Linux-IMA() IML File %s, bad template size %d at %d event\n",
1521 rc = PTS_INTERNAL_ERROR;
1525 if (template_type_len >= TEMPLATE_TYPE_SIZE) {
1526 ERROR("template_type_len %d(0x%x) is too big\n", template_type_len, template_type_len);
1527 rc = PTS_INTERNAL_ERROR;
1530 // DEBUG("getImaImlFile - template_type_len %d\n",template_type_len);
1532 /* read Template type */
1533 size = fread(&buf, 1, template_type_len, fp);
1534 if (size != template_type_len) {
1536 rc = PTS_INTERNAL_ERROR;
1539 // TODO accessing beyond memory
1540 buf[template_type_len] = 0;
1542 if (!strcmp(buf, "ima")) {
1543 // DEBUG("getImaImlFile - BINARY_IML_TYPE_IMA\n");
1544 event->eventType = 0; // BINARY_IML_TYPE_IMA;
1545 // TODO(munetoh) check with type
1547 /* alloc template (=event data) */
1548 event->ulEventLength = 20 + 256; // TODO(munetoh)
1549 event->rgbEvent = malloc(event->ulEventLength);
1550 if (event->rgbEvent == NULL) {
1551 ERROR("no memory\n");
1555 memset(event->rgbEvent, 0, event->ulEventLength);
1557 /* read Template digest */
1558 size = fread(event->rgbEvent, 1, SHA1_DIGEST_SIZE, fp);
1559 if (size != SHA1_DIGEST_SIZE) {
1561 rc = PTS_INTERNAL_ERROR;
1565 /* read filename len */
1566 size = fread(&filename_len, 1, 4, fp);
1569 rc = PTS_INTERNAL_ERROR;
1573 if (filename_len > 255) {
1574 ERROR("filename_len is too big, %d, 0x%x\n", filename_len, filename_len);
1575 rc = PTS_INTERNAL_ERROR;
1579 DEBUG_CAL("readImaImlFile - filename_len %d\n", filename_len);
1582 size = fread(&event->rgbEvent[20], 1, filename_len, fp);
1583 if (size != filename_len) {
1585 rc = PTS_INTERNAL_ERROR;
1590 ERROR("Unknown template [%s]\n", buf);
1591 rc = PTS_INTERNAL_ERROR;
1596 /* create wrapper */
1597 // ew_last = ew_new; // TODO
1598 ew = (OPENPTS_PCR_EVENT_WRAPPER *)
1599 malloc(sizeof(OPENPTS_PCR_EVENT_WRAPPER));
1601 ERROR("no memory\n");
1605 memset(ew, 0, sizeof(OPENPTS_PCR_EVENT_WRAPPER));
1608 if (event_num == 0) {
1611 ew->index = event_num;
1612 ew_last->next_all = ew;
1617 if (mode == USE_BHV_FSM) {
1618 /* map to the snapshot */
1619 result = addEventToSnapshotBhv(ctx, ew_last); // iml.c
1620 if (result != PTS_SUCCESS) {
1621 ERROR("readImaImlFile - addEventToSnapshotBhv fail, rc = %d\n", rc);
1622 rc = PTS_INTERNAL_ERROR;
1625 } else { // USE_BIN_FSM
1626 /* map to the snapshot */
1627 result = addEventToSnapshotBin(ctx, ew_last); // iml.c
1628 if (result != PTS_SUCCESS) {
1629 ERROR("readImaImlFile - addEventToSnapshotBin fail\n");
1630 rc = PTS_INTERNAL_ERROR;
1635 DEBUG_CAL("readImaImlFile - TPM_extend\n");
1638 result = extendTpm(&ctx->tpm, ew_last->event);
1640 ERROR("extend TPM fail\n");
1641 rc = PTS_INTERNAL_ERROR;
1645 /* moved to the snapshot */
1653 ctx->ss_table->event_num += event_num;
1658 // DEBUG("iml.c - getBiosImlFile - done, %d events\n", event_num);
1659 // ERROR("SS LEVEL %d == 1?, ss->event_num =%d\n",ss->level,ss->event_num );
1660 DEBUG("read IMA IML, file %s => %d events\n", filename, event_num);
1661 DEBUG_CAL("readImaImlFile - done, %d events\n", event_num);
1664 /* free (for error) */
1665 if (event != NULL) {
1666 if (event->rgbPcrValue != NULL) free(event->rgbPcrValue);
1667 if (event->rgbEvent != NULL) free(event->rgbEvent);
1670 if (ew != NULL) free(ew);
1676 * set OPENPTS_PCRS to SNAPSHOT
1682 int setPcrsToSnapshot(OPENPTS_CONTEXT *ctx, OPENPTS_PCRS *pcrs) {
1686 DEBUG_CAL("setPcrsToSnapshot\n");
1689 for (i = 0; i < pcrs->pcr_num; i++) {
1691 OPENPTS_SNAPSHOT *ss0;
1692 OPENPTS_SNAPSHOT *ss1;
1696 // TODO ss0->tpm_pcr is wrong
1697 ss0 = getSnapshotFromTable(ctx->ss_table, i, 0);
1698 ss1 = getSnapshotFromTable(ctx->ss_table, i, 1);
1700 if ((ss0 != NULL) && (ss1 != NULL)) {
1701 /* exist level 0 and 1 */
1702 for (j = 0; j < SHA1_DIGEST_SIZE; j++) {
1703 ss0->start_pcr[j] = 0;
1704 ss0->tpm_pcr[j] = pcr[j]; // TODO(munetoh)
1705 ss1->tpm_pcr[j] = pcr[j];
1707 } else if ((ss0 != NULL) && (ss1 == NULL)) {
1708 /* exist level 0 only */
1709 for (j = 0; j < SHA1_DIGEST_SIZE; j++) {
1710 ss0->start_pcr[j] = 0;
1711 ss0->tpm_pcr[j] = pcr[j];
1713 } else if ((ss0 == NULL) && (ss1 != NULL)) {
1714 /* exist level 1 only */
1715 for (j = 0; j < SHA1_DIGEST_SIZE; j++) {
1716 ss1->start_pcr[j] = 0;
1717 ss1->tpm_pcr[j] = pcr[j];
1726 #ifdef CONFIG_NO_TSS
1727 int getPcr(OPENPTS_CONTEXT * ctx) {
1731 #else // CONFIG_NO_TSS
1733 * get PCR value from TSS
1735 * PCR values are also taken at quoteTss time.
1737 int getPcr(OPENPTS_CONTEXT * ctx) {
1739 TSS_HCONTEXT hContext;
1745 // DEBUG("getPcr is deprecated\n");
1750 /* Connect to TCSD */
1751 result = Tspi_Context_Create(&hContext);
1752 if (result != TSS_SUCCESS) {
1753 ERROR("ERROR: Tspi_Context_Create failed rc=0x%x\n", result);
1757 result = Tspi_Context_Connect(hContext, SERVER);
1758 if (result != TSS_SUCCESS) {
1759 ERROR("ERROR: Tspi_Context_Connect failed rc=0x%x\n", result);
1764 /* Get TPM handles */
1765 result = Tspi_Context_GetTpmObject(hContext, &hTPM);
1766 if (result != TSS_SUCCESS) {
1767 ERROR("ERROR: Tspi_Context_GetTpmObject failed rc=0x%x\n", result);
1772 subCap = TSS_TPMCAP_PROP_PCR;
1773 result = Tspi_TPM_GetCapability(
1775 TSS_TPMCAP_PROPERTY,
1780 if (result != TSS_SUCCESS) {
1781 ERROR("ERROR: Tspi_TPM_GetCapability failed rc=0x%x\n", result);
1785 // pcrNum = (UINT32) * blob; // TODO(munetoh) Endian
1786 pcrNum = * (UINT32 *) blob;
1789 for (i = 0; i < pcrNum; i++) {
1790 result = Tspi_TPM_PcrRead(hTPM, i, &blobLength, &blob);
1792 if (result != TSS_SUCCESS) {
1793 ERROR("ERROR: Tspi_TPM_PcrRead failed rc=0x%x\n", result);
1797 if (blobLength != SHA1_DIGEST_SIZE) {
1798 Tspi_Context_FreeMemory(hContext, blob);
1804 OPENPTS_SNAPSHOT *ss0;
1805 OPENPTS_SNAPSHOT *ss1;
1807 // TODO ss0->tpm_pcr is wrong
1808 ss0 = getSnapshotFromTable(ctx->ss_table, i, 0);
1809 ss1 = getSnapshotFromTable(ctx->ss_table, i, 1);
1811 if ((ss0 != NULL) && (ss1 != NULL)) {
1812 /* exist level 0 and 1 */
1813 for (j = 0; j < SHA1_DIGEST_SIZE; j++) {
1814 ss0->start_pcr[j] = 0;
1815 ss0->tpm_pcr[j] = blob[j]; // TODO(munetoh)
1816 ss1->tpm_pcr[j] = blob[j];
1818 } else if ((ss0 != NULL) && (ss1 == NULL)) {
1819 /* exist level 0 only */
1820 for (j = 0; j < SHA1_DIGEST_SIZE; j++) {
1821 ss0->start_pcr[j] = 0;
1822 ss0->tpm_pcr[j] = blob[j];
1824 } else if ((ss0 == NULL) && (ss1 != NULL)) {
1825 /* exist level 1 only */
1826 for (j = 0; j < SHA1_DIGEST_SIZE; j++) {
1827 ss1->start_pcr[j] = 0;
1828 ss1->tpm_pcr[j] = blob[j];
1832 Tspi_Context_FreeMemory(hContext, blob);
1836 Tspi_Context_FreeMemory(hContext, NULL);
1840 Tspi_Context_Close(hContext);
1844 #endif // CONFIG_NO_TSS
1847 * HEX string to BYTE[0]
1849 BYTE hex2byte(char *buf, int offset) {
1853 tmp = strtol(&buf[offset], &e, 16);
1855 return (BYTE) (0xFF & tmp);
1861 * PCR-00: 8F BF F3 EC EA 9C 54 C8 D1 C4 2C FE A9 3D 6B F0 1B F3 40 5B
1867 int getPcrBySysfsFile(OPENPTS_CONTEXT * ctx, const char *filename) {
1869 char buf[256]; // TODO(munetoh)
1873 OPENPTS_SNAPSHOT *ss0;
1874 OPENPTS_SNAPSHOT *ss1;
1879 if ((fp = fopen(filename, "r")) == NULL) {
1880 TODO("getPcrBySysfsFile - pcr file is %s missing -- ignore in test\n", filename);
1886 ptr = fgets(buf, 256, fp);
1891 // TODO ss0->tpm_pcr is wrong
1892 ss0 = getSnapshotFromTable(ctx->ss_table, count, 0);
1893 ss1 = getSnapshotFromTable(ctx->ss_table, count, 1);
1895 if ((ss0 != NULL) && (ss1 != NULL)) {
1896 /* exist level 0 and 1 */
1897 for (j = 0; j < SHA1_DIGEST_SIZE; j++) {
1898 ss0->start_pcr[j] = 0;
1899 ss0->tpm_pcr[j] = hex2byte(buf, 8 + j * 3);
1900 ss1->tpm_pcr[j] = hex2byte(buf, 8 + j * 3);
1902 } else if ((ss0 != NULL) && (ss1 == NULL)) {
1903 /* exist level 0 only */
1904 for (j = 0; j < SHA1_DIGEST_SIZE; j++) {
1905 ss0->start_pcr[j] = 0;
1906 ss0->tpm_pcr[j] = hex2byte(buf, 8 + j * 3);
1908 } else if ((ss0 == NULL) && (ss1 != NULL)) {
1909 /* exist level 1 only */
1910 for (j = 0; j < SHA1_DIGEST_SIZE; j++) {
1911 ss1->start_pcr[j] = 0;
1912 ss1->tpm_pcr[j] = hex2byte(buf, 8 + j * 3);
1920 ctx->pcr_num = count;
1927 * cat /sys/class/misc/tpm0/device/pcrs
1929 int validatePcr(OPENPTS_CONTEXT * ctx) {
1932 OPENPTS_TPM_CONTEXT *tpm;
1933 OPENPTS_SNAPSHOT *ss;
1937 DEBUG("validatePcr - start, Iml->PCR vs TPM\n");
1939 for (i = 0; i < ctx->pcr_num; i++) {
1940 // TODO this check level 0 only, support stacked PCR
1941 ss = getActiveSnapshotFromTable(ctx->ss_table, i);
1943 for (j = 0; j < SHA1_DIGEST_SIZE; j++) {
1944 if (tpm->pcr[i][j] != ss->tpm_pcr[j]) {
1951 DEBUG("validatePcr - done, rc=%d\n", rc);
1953 if (verbose & DEBUG_FLAG) {
1954 for (i = 0; i < ctx->pcr_num; i++) {
1955 printf("PCR %2d ", i);
1956 ss = getActiveSnapshotFromTable(ctx->ss_table, i);
1958 for (j = 0; j < SHA1_DIGEST_SIZE; j++) {
1959 printf("%02x-%02x ", tpm->pcr[i][j], ss->tpm_pcr[j]);
1962 for (j = 0; j < SHA1_DIGEST_SIZE; j++) {
1963 printf("%02x- ", tpm->pcr[i][j]);
1974 * print OPENPTS_PCR_EVENT_WRAPPER
1977 void printEventWrapper(OPENPTS_PCR_EVENT_WRAPPER *eventWrapper) {
1979 TSS_PCR_EVENT *event;
1981 event = eventWrapper->event;
1983 if (event != NULL) {
1984 printf("%4d ", (int)event->ulPcrIndex);
1985 printf("%8x ", event->eventType);
1986 for (j = 0; j < (int)event->ulPcrValueLength; j++) {
1987 printf("%02x", event->rgbPcrValue[j]);
1989 printf("eventdata[%4d]\n", event->ulEventLength);
1991 ERROR("NULL event\n"); // TODO(munetoh)
1997 * \brief print event of selected PCR index
1998 * \return num of event
2001 OPENPTS_CONTEXT * ctx,
2005 OPENPTS_SNAPSHOT *ss;
2006 OPENPTS_PCR_EVENT_WRAPPER *eventWrapper;
2007 char buf[SHA1_BASE64_DIGEST_SIZE + 1];
2011 ss = getSnapshotFromTable(ctx->ss_table, index, 0);
2013 ERROR("printImlByPcr() - no ss at pcr=%d, level=0\n", index);
2017 eventWrapper = ss->start;
2019 printf("PCR[%d]\n", index);
2021 for (i = 0; i < ctx->ss_table->event_num; i++) {
2022 printf(" %3d %3d %08x ",
2024 eventWrapper->event->ulPcrIndex,
2025 eventWrapper->event->eventType);
2027 for (j = 0; j < 20; j++) {
2028 printf("%02x", eventWrapper->event->rgbPcrValue[j]);
2032 // len = encodeBase64(
2033 // (unsigned char *)buf,
2034 // (unsigned char *)eventWrapper->event->rgbPcrValue,
2037 printf(" (%s) \n", buf);
2038 eventWrapper = eventWrapper->next_pcr;
2039 if (eventWrapper == NULL) break;
2047 * \brief print all events
2049 int printIml(OPENPTS_CONTEXT * ctx) {
2053 for (i = 0; i < MAX_PCRNUM; i++) {
2054 rc += printImlByPcr(ctx, i, rc);
2063 * print TSS_PCR_EVENT
2065 * TODO(munetoh) use fprintEventData in iml2text.c
2067 void printEvent(TSS_PCR_EVENT *event) {
2070 if (event != NULL) {
2071 int index = (int) event->ulPcrIndex;
2072 int type = event->eventType;
2073 int len = event->ulEventLength;
2078 printf("%4d ", index);
2079 printf("%8x ", type);
2080 for (i = 0; i < (int)event->ulPcrValueLength; i++) {
2081 printf("%02x", event->rgbPcrValue[i]);
2083 printf(" eventdata[%4d] ", event->ulEventLength);
2086 memcpy(buf, event->rgbEvent, event->ulEventLength);
2087 buf[event->ulEventLength] = 0;
2089 memcpy(buf, event->rgbEvent, 255);
2093 if (index == 10) { // Linux-IMA
2095 printf("[IMA-LKM:%s] ", buf);
2096 } else if (type == 1) {
2097 printf("[IMA-EXE:%s] ", buf);
2098 } else if (type == 0) {
2099 // printf("[IMA:%s] ", buf);
2101 } else if ((type & 0xFFFF) == 4) {
2102 printf("[IMA-USR,0x%04x:%s] ", (type >> 16), buf);
2104 printf("[???:%s] ", buf);
2106 } else if (index <= 8) { // BIOS + Grub
2109 printf("[BIOS:EV_PREBOOT_CERT(EV_CODE_CERT)]");
2112 printf("[BIOS:EV_POST_CODE(EV_CODE_NOCERT)]");
2115 printf("[BIOS:EV_UNUSED(EV_XML_CONFIG)]");
2118 printf("[BIOS:EV_NO_ACTION]");
2121 if ((pcr4_grub > 1) && (index == 4)) {
2122 printf("[GRUB:EV_SEPARATOR, %s]", buf);
2123 } else if ((pcr5_grub > 0) && (index == 5)) {
2124 printf("[GRUB:EV_SEPARATOR, %s]", buf);
2125 } else if (index == 8) {
2126 printf("[GRUB:EV_SEPARATOR, %s]", buf);
2127 } else if (len == 4) { // V1.2
2128 printf("[BIOS:EV_SEPARATOR, %02x%02x%02x%02x]",
2129 (unsigned char) buf[0],
2130 (unsigned char) buf[1],
2131 (unsigned char) buf[2],
2132 (unsigned char) buf[3]);
2134 printf("[BIOS:EV_SEPARATOR, %s]", buf);
2138 if ((pcr5_grub > 0) && (index == 5)) {
2139 printf("[GRUB:EV_ACTION, %s]", buf);
2141 printf("[BIOS:EV_ACTION, %s]", buf);
2145 if ((pcr4_grub > 1) && (index == 4)) {
2146 printf("[GRUB: measure MBR again]");
2148 printf("[BIOS:EV_EVENT_TAG(EV_PLATFORM_SPECIFIC)]");
2152 printf("[BIOS:EV_S_CRTM_CONTENTS]");
2155 printf("[BIOS:EV_S_CRTM_VERSION]");
2158 printf("[BIOS:EV_CPU_MICROCODE]");
2161 printf("[BIOS:EV_PLATFORM_CONFIG_FLAG)]");
2164 printf("[BIOS:EV_TABLE_OF_CONTENTS)]");
2167 printf("[BIOS:EV_COMPACT_HASH]");
2170 if (pcr4_grub == 0) {
2172 printf("[BIOS:EV_IPL]");
2174 } else if (pcr4_grub == 1) {
2176 printf("[GRUB:EV_IPL, Stage1(MBR)]");
2178 } else if (pcr4_grub == 2) {
2180 printf("[GRUB:EV_IPL, Stage1.5]");
2182 } else if (pcr4_grub == 3) {
2184 printf("[GRUB:EV_IPL, Stage1.5(filesystem)]");
2188 printf("[GRUB:EV_IPL]");
2192 if (pcr5_grub == 0) {
2193 printf("[BIOS:EV_IPL_PERTITION_DATA]");
2196 printf("[GRUB:grub.conf]");
2200 printf("[BIOS:EV_NOHOST_CODE)]");
2203 printf("[BIOS:EV_NOHOST_CONFIG]");
2206 printf("[BIOS:EV_NOHOST_INFO]");
2209 printf("[BIOS:EV_SPECIFICATION_IDENTIFIER 0x");
2210 for (i = 0; i < len; i++) {
2211 printf("%02x", (unsigned char)buf[i]);
2215 case 0x80000001: // EFI
2216 printf("[BIOS:EV_EFI_VARIABLE_DRIVER_CONFIG len=%d,", len);
2217 for (i = 0; i < len; i++) {
2218 printf("%02x", (unsigned char)buf[i]);
2222 case 0x80000002: // EFI
2223 printf("[BIOS:EV_EFI_VARIABLE_BOOT len=%d,", len);
2224 for (i = 0; i < len; i++) {
2225 printf("%02x", (unsigned char)buf[i]);
2229 case 0x80000003: // EFI
2230 printf("[BIOS:EV_EFI_BOOT_SERVICES_APPLICATION len=%d,", len);
2231 for (i = 0; i < len; i++) {
2232 printf("%02x", (unsigned char)buf[i]);
2236 case 0x80000004: // EFI
2237 printf("[BIOS:EV_EFI_BOOT_SERVICES_DRIVER len=%d,", len);
2238 for (i = 0; i < len; i++) {
2239 printf("%02x", (unsigned char)buf[i]);
2243 case 0x80000005: // EFI
2244 printf("[BIOS:EV_EFI_RUNTIME_SERVICES_DRIVER len=%d,", len);
2245 for (i = 0; i < len; i++) {
2246 printf("%02x", (unsigned char)buf[i]);
2250 case 0x80000006: // EFI
2251 printf("[BIOS:EV_EFI_GPT_EVENT len=%d,", len);
2252 for (i = 0; i < len; i++) {
2253 printf("%02x", (unsigned char)buf[i]);
2257 case 0x80000007: // EFI
2258 printf("[BIOS:EV_EFI_ACTION len=%d,", len);
2259 for (i = 0; i < len; i++) {
2260 printf("%02x", (unsigned char)buf[i]);
2264 case 0x80000009: // EFI
2265 printf("[BIOS:EV_EFI_HANDOFF_TABLES len=%d,", len);
2266 for (i = 0; i < len; i++) {
2267 printf("%02x", (unsigned char)buf[i]);
2273 printf("[GRUB:ACTION, %s]", buf);
2276 printf("[GRUB:KERNEL_OPT %s]", buf);
2279 printf("[GRUB:KERNEL %s]", buf);
2282 printf("[GRUB:INITRD %s]", buf);
2285 printf("[GRUB:MODULE %s]", buf);
2288 printf("[Unknown BIOS Event:size=%d]", len);
2293 encodeBase64((unsigned char *)buf, (unsigned char *)event->rgbPcrValue, event->ulPcrValueLength);
2294 printf(" b64(%s)\n", buf);
2297 ERROR("NULL event\n"); // TODO(munetoh)
2304 * print OPENPTS_SNAPSHOT
2306 void printSnapshot(OPENPTS_SNAPSHOT * ss) {
2308 TSS_PCR_EVENT *event;
2309 OPENPTS_PCR_EVENT_WRAPPER *eventWrapper;
2311 eventWrapper = ss->start;
2313 for (i = 0; i < ss->event_num; i++) {
2314 event = eventWrapper->event;
2316 eventWrapper = eventWrapper->next_pcr;
2324 * print events in each snapshot
2326 void printSnapshots(OPENPTS_CONTEXT * ctx) {
2328 OPENPTS_SNAPSHOT *ss;
2334 for (i = 0; i < MAX_PCRNUM; i++) {
2335 ss = getSnapshotFromTable(ctx->ss_table, i, 0);
2337 if (ss->event_num > 0) {
2338 printf("PCR[%2d] - ", i);
2339 printf("%d events at level 0\n", ss->event_num);
2341 level0_num += ss->event_num;
2345 // if (ss->next != NULL) {
2348 ss = getSnapshotFromTable(ctx->ss_table, i, 1);
2350 if (ss->event_num > 0) {
2351 printf("PCR[%2d] - ", i);
2352 printf("%d events at level 1\n", ss->event_num);
2354 level1_num += ss->event_num;
2355 if (ss->level != 1) ERROR("bad level %d\n", ss->level);
2359 printf("---------------------------\n");
2360 printf("level 0 total = %d\n", level0_num);
2361 printf("level 1 total = %d\n", level1_num);
2362 printf("---------------------------\n");
2367 * print event number of each snapshot
2369 void printSnapshotsInfo(OPENPTS_CONTEXT * ctx) {
2371 OPENPTS_SNAPSHOT *ss;
2372 // TODO support valiable levels
2376 printf("Number of event\n");
2378 printf("PCR Level0 Level1 \n");
2379 printf("--------------------------\n");
2381 for (i = 0; i < MAX_PCRNUM; i++) {
2383 ss = getSnapshotFromTable(ctx->ss_table, i, 0);
2386 printf("%6d", ss->event_num);
2387 level0_num += ss->event_num;
2393 ss = getSnapshotFromTable(ctx->ss_table, i, 1);
2395 printf(" %6d\n", ss->event_num);
2396 level1_num += ss->event_num;
2397 if (ss->level != 1) ERROR("bad level %d\n", ss->level);
2402 printf("---------------------------\n");
2403 printf("level 0 total = %d\n", level0_num);
2404 printf("level 1 total = %d\n", level1_num);
2405 printf("---------------------------\n");