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);
46 * reset snapshot array
49 * TODO reset level1 too
51 // TODO move to snapshot?
52 int resetSnapshot(OPENPTS_SNAPSHOT * snapshots) {
56 OPENPTS_PCR_EVENT_WRAPPER *eventWrapper;
57 OPENPTS_PCR_EVENT_WRAPPER *eventWrapper_next;
60 if (snapshots == NULL) {
61 LOG(LOG_ERR, "null input");
66 for (i = 0; i < MAX_PCRNUM; i++) {
68 eventWrapper = ss->start;
69 for (j = 0; j < ss->event_num; j++) {
70 event = eventWrapper->event;
72 if (event->rgbPcrValue != NULL)
73 xfree(event->rgbPcrValue);
74 if (event->rgbEvent != NULL)
75 xfree(event->rgbEvent);
78 LOG(LOG_ERR, "resetSnapshot - NULL event\n"); // TODO(munetoh)
80 eventWrapper_next = eventWrapper->next_pcr;
82 eventWrapper = eventWrapper_next;
84 // if (iml[i].eventList != NULL) xfree(iml[i].eventList);
91 return 0; // TODO(munetoh)
98 OPENPTS_PCR_EVENT_WRAPPER * newEventWrapper() {
99 OPENPTS_PCR_EVENT_WRAPPER *ew;
101 ew = (OPENPTS_PCR_EVENT_WRAPPER *)xmalloc(sizeof(OPENPTS_PCR_EVENT_WRAPPER));
103 LOG(LOG_ERR, "no memory");
107 memset(ew, 0, sizeof(OPENPTS_PCR_EVENT_WRAPPER));
115 void freeEventWrapper(OPENPTS_PCR_EVENT_WRAPPER * ew) {
118 LOG(LOG_ERR, "null input");
128 void freeEventWrapperChain(OPENPTS_PCR_EVENT_WRAPPER * ew) {
129 TSS_PCR_EVENT *event;
133 LOG(LOG_ERR, "null input");
138 if (ew->next_pcr != NULL) {
139 freeEventWrapperChain(ew->next_pcr);
144 if (event->rgbPcrValue != NULL)
145 xfree(event->rgbPcrValue);
146 if (event->rgbEvent != NULL)
147 xfree(event->rgbEvent);
150 LOG(LOG_ERR, "freeSnapshot - NULL event\n"); // TODO(munetoh)
157 #define OPENPTS_FSM_NO_LEVEL1 10
160 * add Event to Snapshopt
161 * IML-> IR, check with Behavir FSM
162 * IML-> RM, check with Behavir FSM
166 * PTS_INVALID_SNAPSHOT bad event (FSM fail)
167 * PTS_INTERNAL_ERROR else
169 * OPENPTS_FSM_TRANSIT => transit to next level of FSM
170 * OPENPTS_FSM_FINISH_WO_HIT => transit to next level of FSM
173 * OPENPTS_FSM_SUCCESS => PTS_SUCCESS
174 * OPENPTS_FSM_FINISH => PTS_SUCCESS
175 * OPENPTS_FSM_ERROR => PTS_INVALID_SNAPSHOT + reason << BAD IML
176 * OPENPTS_FSM_NO_LEVEL1 => PTS_INTERNAL_ERROR + reason
179 int addEventToSnapshotBhv(
180 OPENPTS_CONTEXT * ctx,
181 OPENPTS_PCR_EVENT_WRAPPER * eventWrapper) {
184 OPENPTS_SNAPSHOT *ss;
187 DEBUG_CAL("addEventToSnapshot - start\n");
191 LOG(LOG_ERR, "null input");
194 if (eventWrapper == NULL) {
195 LOG(LOG_ERR, "null input");
198 if (eventWrapper->event == NULL) {
199 LOG(LOG_ERR, "null input");
204 index = eventWrapper->event->ulPcrIndex;
206 DEBUG_FSM("[PCR%02d] addEventToSnapshotBhv()\n", index);
208 /* skip Bad Snapshot/PCR[n] */
209 // 20101124 SM use common SS error flag par pcr_index
210 if (ctx->ss_table->error[index] != PTS_SUCCESS) {
211 return ctx->ss_table->error[index];
216 Snapshot by PCR, by Level
218 Active FSM(LV0) FSM(LV1) level
219 ----------------------------------------
226 active_level = getActiveSnapshotLevel(ctx->ss_table, index);
228 if (active_level == 0) {
229 /* use level 0 snapshot */
230 ss = getSnapshotFromTable(ctx->ss_table, index, 0);
233 /* level 0 SS is null => check Level 1 SS */
234 ss = getSnapshotFromTable(ctx->ss_table, index, 1);
236 LOG(LOG_ERR, "getSnapshotFromTable(%d,1) is null", index);
237 addReason(ctx, index, NLS(MS_OPENPTS, OPENPTS_IML_SNAPSHOT_MISSING,
238 "[PCR%02d] Snapshot(FSM) is missing for PCR%d. "
239 "Please check the configuration file '%s'"),
241 index, ctx->conf->config_file);
242 ctx->ss_table->error[index] = PTS_INTERNAL_ERROR;
243 return PTS_INTERNAL_ERROR;
247 if (ss->fsm_behavior != NULL) {
248 /* OK, BHV-FSM exist at level 1 => chenge the active Level to 1 */
249 setActiveSnapshotLevel(ctx->ss_table, index, 1);
251 // DEBUG_FSM("pcr%d SKIP to level 1\n", index);
252 DEBUG_FSM("[PCR%02d] RM0 -> RM1 (RM0 is missing)\n", index);
255 LOG(LOG_ERR, "getSnapshotFromTable(), FSM is null");
256 addReason(ctx, index, NLS(MS_OPENPTS, OPENPTS_IML_FSM_MISSING,
257 "[RM01-PCR%02d] FSM is missing for PCR%d, Level 1. "
258 "Please check the configuration file '%s'"),
260 index, ctx->conf->config_file);
261 ctx->ss_table->error[index] = PTS_INTERNAL_ERROR;
262 return PTS_INTERNAL_ERROR;
268 if (ss->fsm_behavior == NULL) {
269 /* no BHV-FSM => check the next level, 1 */
271 /* check level 1 SS */
272 ss = getSnapshotFromTable(ctx->ss_table, index, 1);
275 LOG(LOG_ERR, "getSnapshotFromTable(), ss is null");
276 addReason(ctx, index, NLS(MS_OPENPTS, OPENPTS_IML_SNAPSHOT_MISSING_2,
277 "[PCR%02d] Snapshot is missing for PCR%d for Level 0 and 1. "
278 "Please check the configuration file '%s'"),
281 ctx->conf->config_file);
282 ctx->ss_table->error[index] = PTS_INTERNAL_ERROR;
283 return PTS_INTERNAL_ERROR;
286 /* check FSM at level 1 */
287 if (ss->fsm_behavior != NULL) {
288 /* BHV-FSM lexist at level 1 << Active Level */
289 DEBUG_FSM("pcr%d SKIP to level 1\n", index);
290 setActiveSnapshotLevel(ctx->ss_table, index, 1);
294 LOG(LOG_ERR, "getSnapshotFromTable(), FSM is null");
295 addReason(ctx, index, NLS(MS_OPENPTS, OPENPTS_IML_FSM_MISSING_2,
296 "[RM01-PCR%02d] FSM is missing for PCR%d, Level 1. Please check the configuration file '%s'"),
298 index, ctx->conf->config_file);
299 ctx->ss_table->error[index] = PTS_INTERNAL_ERROR;
300 return PTS_INTERNAL_ERROR; // OPENPTS_FSM_ERROR;
303 } else if (active_level == 1) {
304 /* active level is 1, check the level 1 */
305 ss = getSnapshotFromTable(ctx->ss_table, index, 1);
308 LOG(LOG_ERR, "getSnapshotFromTable(), ss is null");
309 addReason(ctx, index, NLS(MS_OPENPTS, OPENPTS_IML_SNAPSHOT_MISSING_6,
310 "[RM%02d-PCR%02d] Snapshot is missing for PCR%d, Level %d. Please check the configuration file '%s'"),
314 active_level, ctx->conf->config_file);
315 ctx->ss_table->error[index] = PTS_INTERNAL_ERROR;
316 return PTS_INTERNAL_ERROR;
320 if (ss->fsm_behavior == NULL) {
322 LOG(LOG_ERR, "getSnapshotFromTable(), FSM is null");
323 addReason(ctx, index, NLS(MS_OPENPTS, OPENPTS_IML_FSM_MISSING_3,
324 "[RM%02d-PCR%02d] FSM is missing for PCR%d, Level %d. Please check the configuration file '%s'"),
328 index, ctx->conf->config_file);
329 ctx->ss_table->error[index] = PTS_INTERNAL_ERROR;
330 return PTS_INTERNAL_ERROR;
333 /* OK, the BHV-FSM exists at Level 1*/
336 LOG(LOG_ERR, "level >1 is TBD, pcr=%d level=%d\n", index, active_level);
337 return PTS_INTERNAL_ERROR;
340 /* set sw->ss link */
341 eventWrapper->snapshot = ss;
342 eventWrapper->index = ss->event_num; // ID for EV_ACTION
344 /* Parse Event by BHV-FSM Model */
345 rc = updateFsm(ctx, ss->fsm_behavior, eventWrapper);
346 if (rc == OPENPTS_FSM_ERROR) {
347 /* FSM detect invalid IML, or bad FSM for this IML */
348 DEBUG("[RM%02d-PCR%02d] updateFsm() => OPENPTS_FSM_ERROR ===> rc=PTS_INVALID_SNAPSHOT, added Reason\n",
349 active_level, index);
350 if (ss->fsm_behavior->curr_state == NULL) {
351 LOG(LOG_ERR, "ss->fsm_behavior->curr_state == NULL");
352 addReason(ctx, index, NLS(MS_OPENPTS, OPENPTS_IML_VALIDATION_FAILED,
353 "[RM%02d-PCR%02d] IML validation by FSM has failed. State='%s' at the FSM is '%s'"),
357 ss->fsm_behavior->uml_file);
358 } else if (ss->fsm_behavior->curr_state->name == NULL) {
359 LOG(LOG_ERR, "ss->fsm_behavior->curr_state->name == NULL");
361 } else if (ss->fsm_behavior->uml_file == NULL) {
362 LOG(LOG_ERR, "ss->fsm_behavior->uml_file == NULL");
365 LOG(LOG_ERR, "IML validation by FSM has failed.");
366 addReason(ctx, index, NLS(MS_OPENPTS, OPENPTS_IML_VALIDATION_FAILED,
367 "[RM%02d-PCR%02d] IML validation by FSM has failed. State='%s' at the FSM is '%s'"),
370 ss->fsm_behavior->curr_state->name,
371 ss->fsm_behavior->uml_file);
373 ctx->ss_table->error[index] = PTS_INVALID_SNAPSHOT;
374 rc = PTS_INVALID_SNAPSHOT;
376 } else if (rc == OPENPTS_FSM_FINISH) {
377 /* OK, FSM finish successfly */
378 ss->fsm_behavior->status = OPENPTS_FSM_FINISH;
381 /* Move to next level (0->1) */
382 incActiveSnapshotLevel(ctx->ss_table, index);
383 } else if (rc == OPENPTS_FSM_SUCCESS) {
386 } else if (rc == OPENPTS_FSM_TRANSIT) {
387 // TRANSIT, Skip update SS chain
388 // TODO set by updateFsm
389 ss->fsm_behavior->status = OPENPTS_FSM_FINISH;
391 /* Move to next level (0->1) */
392 incActiveSnapshotLevel(ctx->ss_table, index);
394 } else if (rc == OPENPTS_FSM_FINISH_WO_HIT) {
395 // TRANSIT, Skip update SS chain
396 // TODO set by updateFsm
397 ss->fsm_behavior->status = OPENPTS_FSM_FINISH;
399 /* Move to next level (0->1) */
400 incActiveSnapshotLevel(ctx->ss_table, index);
402 } else if (rc == OPENPTS_FSM_MIGRATE_EVENT) {
403 /* this event is migrated to target PCR, remove from this SS (did not put the EW chain) */
406 LOG(LOG_ERR, "updateFsm rc=%d\n", rc);
410 /* update SS chain */
411 if (ss->event_num == 0) {
413 ss->start = eventWrapper;
414 ss->end = eventWrapper;
417 ss->end->next_pcr = eventWrapper;
418 ss->end = eventWrapper;
423 DEBUG_CAL("addEventToSnapshot - done\n");
428 * add Event to Snapshopt
429 * IR-> check with Binary FSM (RM)
433 * PTS_INVALID_SNAPSHOT bad event (FSM fail)
434 * PTS_INTERNAL_ERROR else
438 int addEventToSnapshotBin(
439 OPENPTS_CONTEXT * ctx,
440 OPENPTS_PCR_EVENT_WRAPPER * eventWrapper) {
444 OPENPTS_SNAPSHOT *ss;
446 DEBUG_CAL("addEventToSnapshotBin - start\n");
450 LOG(LOG_ERR, "null input");
453 if (eventWrapper == NULL) {
454 LOG(LOG_ERR, "null input");
457 if (eventWrapper->event == NULL) {
458 LOG(LOG_ERR, "null input");
463 index = eventWrapper->event->ulPcrIndex;
465 /* Get active snapshot level of this PCR */
466 active_level = getActiveSnapshotLevel(ctx->ss_table, index);
469 ss = getSnapshotFromTable(ctx->ss_table, index, active_level);
471 /* check the next level */
473 ss = getSnapshotFromTable(ctx->ss_table, index, active_level);
475 /* check next level (1) */
477 LOG(LOG_ERR, "addEventToSnapshotBin() - pcr=%d Level=%d snapshots is missing\n",index, active_level);
478 addReason(ctx, index, NLS(MS_OPENPTS, OPENPTS_IML_SNAPSHOT_MISSING_3, "[PCR%02d] Snapshot(FSM) is missing"),
480 ctx->ss_table->error[index] = PTS_INTERNAL_ERROR;
481 return PTS_INTERNAL_ERROR;
483 /* Exist use this level as active */
484 incActiveSnapshotLevel(ctx->ss_table, index);
489 /* skip Bad Snapshot/PCR[n] */
490 // 20101124 SM use common SS error flag par pcr_index
491 if (ctx->ss_table->error[index] != PTS_SUCCESS) {
492 return ctx->ss_table->error[index];
495 /* link between Snapshot - event wrapper */
496 eventWrapper->snapshot = ss;
497 eventWrapper->index = ss->event_num;
499 /* Checked by BIN-FSM Model, Do validation by RM */
500 if (ss->fsm_binary != NULL) {
501 /* OK, drive the FSM */
502 rc = updateFsm(ctx, ss->fsm_binary, eventWrapper); // fsm.c
503 if (rc == OPENPTS_FSM_ERROR) {
505 DEBUG_FSM("addEventToSnapshotBin() - No trans, return PTS_INVALID_SNAPSHOT\n");
506 // TODO Broken FSM - 20110115 SM under ARU test
507 if (ss->fsm_binary == NULL) {
508 LOG(LOG_ERR, "ss->fsm_binary == NULLn");
509 addReason(ctx, index, NLS(MS_OPENPTS, OPENPTS_IML_IR_VALIDATION_FAILED_1,
510 "[RM%02d-PCR%02d-MissingFSM] IR validation by RM has failed"),
513 } else if (ss->fsm_binary->curr_state == NULL) {
514 LOG(LOG_ERR, "ss->fsm_binary->curr_state == NULL\n");
515 addReason(ctx, index, NLS(MS_OPENPTS, OPENPTS_IML_IR_VALIDATION_FAILED_2,
516 "[RM%02d-PCR%02d-MissingState] IR validation by RM has failed"),
519 } else if (ss->fsm_binary->curr_state->name == NULL) {
520 LOG(LOG_ERR, "ss->fsm_binary->curr_state->name == NULL\n");
521 addReason(ctx, index, NLS(MS_OPENPTS, OPENPTS_IML_IR_VALIDATION_FAILED_3,
522 "[RM%02d-PCR%02d-MissingStateName] IR validation by RM has failed"),
526 DEBUG("IR validation by RM has failed");
527 addReason(ctx, index, NLS(MS_OPENPTS, OPENPTS_IML_IR_VALIDATION_FAILED_4,
528 "[RM%02d-PCR%02d-%s] IR validation by RM has failed"),
531 ss->fsm_binary->curr_state->name);
533 ctx->ss_table->error[index] = PTS_INVALID_SNAPSHOT;
534 return PTS_INVALID_SNAPSHOT;
539 if (active_level == 0) { // TODO here, the level is 0 or 1
540 /* check the next level */
541 ss = getSnapshotFromTable(ctx->ss_table, index, 1);
543 LOG(LOG_ERR, "no BIN-FSM at level 0, no SS at level 1\n");
544 addReason(ctx, index, NLS(MS_OPENPTS, OPENPTS_IML_SNAPSHOT_MISSING_4,
545 "[PCR%02d] Snapshot(FSM) is missing"),
547 ctx->ss_table->error[index] = PTS_INTERNAL_ERROR;
548 return PTS_INTERNAL_ERROR;
551 if (ss->fsm_binary != NULL) {
552 // DEBUG("addEventToSnapshot - level 0 BIN-FSM is null, move to Level 1 FSM\n");
553 /* move to next the level */
554 incActiveSnapshotLevel(ctx->ss_table, index);
555 DEBUG_FSM("move to level %d\n", getActiveSnapshotLevel(ctx->ss_table, index));
556 /* Update with new SS */
557 ss = getSnapshotFromTable(ctx->ss_table, index, 1); // TODO new func for next
559 LOG(LOG_ERR, "getSnapshotFromTable(%d,%d) is NULL\n", index, 1);
560 return PTS_INTERNAL_ERROR;
562 eventWrapper->snapshot = ss;
563 rc = updateFsm(ctx, ss->fsm_binary, eventWrapper);
564 if (rc == OPENPTS_FSM_ERROR) {
565 DEBUG_FSM("No trans, return PTS_INVALID_SNAPSHOT at %s\n", ss->fsm_binary->curr_state->name);
566 LOG(LOG_ERR, "updateFsm fail\n");
567 addReason(ctx, index, NLS(MS_OPENPTS, OPENPTS_IML_IR_VALIDATION_FAILED_5,
568 "[RM%02d-PCR%02d-%s] IR validation by RM has failed"),
571 ss->fsm_binary->curr_state->name);
572 ctx->ss_table->error[index] = PTS_INVALID_SNAPSHOT;
573 return PTS_INVALID_SNAPSHOT;
577 LOG(LOG_ERR, "no BIN-FSM at level 0, no BIN-FSM at level 1\n");
578 addReason(ctx, index, NLS(MS_OPENPTS, OPENPTS_IML_SNAPSHOT_MISSING_5,
579 "[PCR%02d] Snapshot(FSM) is missing"),
581 ctx->ss_table->error[index] = PTS_INTERNAL_ERROR;
582 return PTS_INTERNAL_ERROR;
587 /* update SS chain */
589 if (ss->event_num == 0) {
591 ss->start = eventWrapper;
592 ss->end = eventWrapper;
595 ss->end->next_pcr = eventWrapper;
596 ss->end = eventWrapper;
605 * flash Snapshot -> FSM -> Final
609 * PTS_INVALID_SNAPSHOT
613 OPENPTS_CONTEXT * ctx,
617 OPENPTS_SNAPSHOT *ss;
618 OPENPTS_SNAPSHOT *ss_lv0 = NULL;
621 DEBUG_CAL("flashSnapshot - start\n");
625 LOG(LOG_ERR, "null input");
630 Active FSM(LV0) FSM(LV1) new level
631 ----------------------------------------
638 /* which level now ? */
639 active_level = getActiveSnapshotLevel(ctx->ss_table, index);
642 ss = getSnapshotFromTable(ctx->ss_table, index, active_level);
644 LOG(LOG_ERR, "No Snapshot at PCR[%d]. level %d\n", index, active_level);
645 // return PTS_INTERNAL_ERROR;
648 ss = getSnapshotFromTable(ctx->ss_table, index, active_level);
650 LOG(LOG_ERR, "No Snapshot at PCR[%d], level %d\n", index, active_level);
651 return PTS_INTERNAL_ERROR;
653 DEBUG("Skip Null SS level. level = %d\n", active_level);
657 if (active_level == 0) {
658 /* use level 0 snapshot, but */
659 if (ss->fsm_binary == NULL) {
660 /* FSM is missing at level 0, move to level 1 */
662 ss = getSnapshotFromTable(ctx->ss_table, index, 1);
664 LOG(LOG_ERR, "PCR[%d] level 1 SS is null\n", index);
665 return PTS_INTERNAL_ERROR;
668 if (ss->fsm_binary != NULL) {
670 DEBUG("PCR[%d] SKIP to level 1\n", index);
671 setActiveSnapshotLevel(ctx->ss_table, index, 1);
674 LOG(LOG_ERR, "level 1 BHV-FSM is null\n");
675 return PTS_INTERNAL_ERROR;
678 } else if (active_level == 1) {
679 /* use level 1 snapshot */
680 if (ss->fsm_binary == NULL) {
681 LOG(LOG_ERR, "Missing BIB-FSM pcr=%d,level=%d, ss=%p -> %p\n",
682 index, active_level, ss_lv0, ss);
683 // printeventWrapper(eventWrapper);
684 return PTS_INTERNAL_ERROR;
687 LOG(LOG_ERR, "level %d is not supported yet\n", active_level);
688 return PTS_INTERNAL_ERROR;
691 /* if SS has been got error skip the flash operation */
692 if (ctx->ss_table->error[index] == PTS_INVALID_SNAPSHOT) {
693 DEBUG_FSM("skip flashSnapshot since SS has PTS_INVALID_SNAPSHOT error\n");
694 return PTS_INVALID_SNAPSHOT;
697 /* Parse Event by BIN-FSM Model, Do validation by RM */
699 DEBUG_FSM("flashSnapshot - PCR[%d] BIN-FSM exist\n", index);
702 rc = updateFsm(ctx, ss->fsm_binary, NULL);
704 if (rc == OPENPTS_FSM_FINISH_WO_HIT) {
705 // OK, reach Final state, but event is not consumed
706 setActiveSnapshotLevel(ctx->ss_table, index, 1);
707 DEBUG_FSM("updateFsm, OPENPTS_FSM_FINISH_WO_HIT => PCR[%d] level => %d\n",
708 index, getActiveSnapshotLevel(ctx->ss_table, index));
709 } else if (rc == OPENPTS_FSM_FINISH) {
710 // OK, reach Final state,
711 setActiveSnapshotLevel(ctx->ss_table, index, 1);
712 // TODO check_rm > ERROR:iml.c:620 updateFsm, OPENPTS_FSM_FINISH => PCR[5] level => 1
713 DEBUG_FSM("updateFsm, OPENPTS_FSM_FINISH => PCR[%d] level => %d\n",
714 index, getActiveSnapshotLevel(ctx->ss_table, index));
715 } else if (rc == OPENPTS_FSM_TRANSIT) {
716 // OK, reach Final state
717 setActiveSnapshotLevel(ctx->ss_table, index, 1);
718 DEBUG_FSM("updateFsm, OPENPTS_FSM_TRANSIT => PCR[%d] level => %d\n",
719 index, getActiveSnapshotLevel(ctx->ss_table, index));
720 } else if (rc == OPENPTS_FSM_SUCCESS) {
722 DEBUG_FSM("updateFsm, OPENPTS_FSM_SUCCESS => PCR[%d] level == %d\n",
723 index, getActiveSnapshotLevel(ctx->ss_table, index));
724 } else if (rc == OPENPTS_FSM_ERROR) {
725 LOG(LOG_ERR, "flashSnapshot - updateFsm fail, rc = %d\n", rc);
726 } else if (rc == OPENPTS_FSM_ERROR_LOOP) {
728 // DEBUG("flashSnapshot - updateFsm looped - end of the IMA IML, rc = %d\n", rc);
730 LOG(LOG_ERR, "flashSnapshot - updateFsm rc=%d\n", rc);
733 DEBUG_CAL("flashSnapshot - done\n");
740 * \brief read IML via TSS, get whole IML
743 * 1: stacked snapshot (by FSM)
745 * IML->TSS->snapshot(BHV-FSM)->RM
746 * IML->TSS->snapshot(BHV-FSM)->IR
752 int getIml(OPENPTS_CONTEXT * ctx, int option) {
756 #else // CONFIG_NO_TSS
757 int getIml(OPENPTS_CONTEXT * ctx, int option) {
762 TSS_HCONTEXT hContext;
764 TSS_PCR_EVENT *pcrEvents;
765 UINT32 ulEventNumber = 0;
766 OPENPTS_PCR_EVENT_WRAPPER *ew_new = NULL;
768 DEBUG_CAL("getIml - start\n");
772 LOG(LOG_ERR, "null input");
777 resetTpm(&ctx->tpm, 0); // reset TPM DRTM=off
780 if (ctx->ss_table == NULL) {
781 LOG(LOG_ERR, "null input");
785 /* Connect to TCSD */
786 result = Tspi_Context_Create(&hContext);
787 if (result != TSS_SUCCESS) {
788 LOG(LOG_ERR, "ERROR: Tspi_Context_Create failed rc=0x%x\n", result);
792 result = Tspi_Context_Connect(hContext, SERVER);
793 if (result != TSS_SUCCESS) {
794 LOG(LOG_ERR, "ERROR: Tspi_Context_Connect failed rc=0x%x\n", result);
798 /* Get TPM handles */
799 result = Tspi_Context_GetTpmObject(hContext, &hTPM);
800 if (result != TSS_SUCCESS) {
801 LOG(LOG_ERR, "ERROR: Tspi_Context_GetTpmObject failed rc=0x%x\n", result);
807 result = Tspi_TPM_GetEventLog(hTPM, &ulEventNumber, &pcrEvents);
808 if (result != TSS_SUCCESS) { // ERROR
809 LOG(LOG_ERR, "ERROR: Tspi_TPM_GetEventLog failed rc=0x%x\n", result);
813 DEBUG("IML(via TSS) : %d events\n", ulEventNumber);
815 ctx->ss_table->event_num = ulEventNumber;
817 /* map to the snapshot */
818 if (option == 0) { // simple, snapshot[i] hold all events on PCR[i]
819 TSS_PCR_EVENT *tpe_tss;
823 for (i = 0; i < (int) ulEventNumber; i++) {
824 tpe_tss = &pcrEvents[i];
826 /* copy event to local */
827 tpe = (TSS_PCR_EVENT *) xmalloc(sizeof(TSS_PCR_EVENT));
829 return -1; // TODO(munetoh)
831 memcpy(tpe, tpe_tss, sizeof(TSS_PCR_EVENT));
832 // index = tpe->ulPcrIndex;
835 tpe->rgbPcrValue = (BYTE *) xmalloc(tpe->ulPcrValueLength);
836 if (tpe->rgbPcrValue == NULL) {
837 return -1; // TODO(munetoh)
839 memcpy(tpe->rgbPcrValue,
840 tpe_tss->rgbPcrValue,
841 tpe->ulPcrValueLength);
843 if (tpe->ulEventLength > 0) {
845 tpe->rgbEvent = (BYTE *) xmalloc(tpe->ulEventLength);
846 if (tpe->rgbEvent == NULL) {
847 return -1; // TODO(munetoh)
849 memcpy(tpe->rgbEvent,
853 tpe->rgbEvent = NULL;
858 ew_new = (OPENPTS_PCR_EVENT_WRAPPER *)
859 xmalloc(sizeof(OPENPTS_PCR_EVENT_WRAPPER));
860 if (ew_new == NULL) {
863 memset(ew_new, 0, sizeof(OPENPTS_PCR_EVENT_WRAPPER));
866 /* map to the snapshot (BHV-FSM) */
867 rc = addEventToSnapshotBhv(ctx, ew_new); // iml.c
869 if (rc == PTS_SUCCESS) {
871 } else if (rc == PTS_INVALID_SNAPSHOT) { // OPENPTS_FSM_ERROR) {
872 /* ERROR but continue the verification of rest of IML */
874 } else if (rc == PTS_INTERNAL_ERROR) { // 58
876 } else if (rc == OPENPTS_FSM_TRANSIT) {
877 DEBUG_FSM("\tTransit to next FSM ======================================\n");
878 rc = addEventToSnapshotBhv(ctx, ew_new); // iml.c
879 } else if (rc == OPENPTS_FSM_FINISH_WO_HIT) {
880 DEBUG_FSM("\tTransit to next FSM ======================================\n");
881 rc = addEventToSnapshotBhv(ctx, ew_new); // iml.c
884 LOG(LOG_ERR, "getIml - addEventToSnapshotBhv rc = %d\n", rc);
888 rc = extendTpm(&ctx->tpm, ew_new->event);
890 LOG(LOG_ERR, "getIml - extendTpm fail\n");
894 } else if (option == 1) {
895 // stacked snapshot with FSM
901 rc = (int) ulEventNumber;
905 // Keep IML data? we have to free by ourselves
906 result = Tspi_Context_FreeMemory(hContext, (BYTE *) pcrEvents);
907 Tspi_Context_FreeMemory(hContext, NULL);
911 Tspi_Context_Close(hContext);
915 snprintf(buf, BUF_SIZE, NLS(MS_OPENPTS, OPENPTS_IML_LOAD_FAILED, "[IML] Load IML (via TSS) has failed"));
916 addReason(ctx, -1, buf);
917 return PTS_INVALID_SNAPSHOT;
921 DEBUG_CAL("getIml - end\n");
925 #endif // CONFIG_NO_TSS
928 * fread + endian conv
932 UINT32 freadUint32(FILE * stream, int endian) {
939 if (stream == NULL) {
940 LOG(LOG_ERR, "null input");
945 size = fread(&data, 1, 4, stream);
948 // This is EOF LOG(LOG_ERR, "\n");
949 return 0xFFFFFFFF; // TODO
966 // DEBUG(" %08x -> %08x\n", data ,out);
973 * \brief read BIOS IML file
975 * PCR0-7 - BIOS => Level 0
976 * PCR4,5,8 - GRUB => Level 1
980 * \param filename -- TODO unicode? or url?
984 * 2:use BHV-FSM + Endian Conv (for PPC Test on X86 ) + 4-byte aligned
986 * event num => ctx->ss_table->event_num
990 * PTS_INVALID_SNAPSHOT
994 // TODO rename readBiosImlFile()
995 int readBiosImlFile(OPENPTS_CONTEXT * ctx, const char *filename, int mode) {
996 int rc = PTS_SUCCESS;
1007 TSS_PCR_EVENT *event = NULL;
1008 OPENPTS_PCR_EVENT_WRAPPER *ew_new = NULL;
1009 // OPENPTS_PCR_EVENT_WRAPPER *ew_last = NULL;
1012 DEBUG_CAL("getBiosImlFile - start\n");
1013 // DEBUG("read BIOS IML, file %s\n", filename);
1017 LOG(LOG_ERR, "null input");
1020 if (filename == NULL) {
1021 LOG(LOG_ERR, "null input");
1026 if ((fp = fopen(filename, "rb")) == NULL) {
1027 LOG(LOG_ERR, "%s missing", filename);
1028 return PTS_INTERNAL_ERROR;
1032 if (mode == USE_BHV_FSM_EC) {
1033 DEBUG("endian=1, aligned=4\n");
1035 endian = 1; // TODO conf->iml_endian?
1036 aligned = 4; // TODO conf->iml_aligned?
1039 /* Read IML, add to Snapshot */
1042 pcrIndex = freadUint32(fp, endian);
1043 if (pcrIndex == 0xFFFFFFFF) {
1047 if (pcrIndex > MAX_PCRNUM) {
1048 DEBUG("BIOS IML File %s, bad pcr index value %d at %d event\n",
1049 filename, pcrIndex, i);
1050 rc = PTS_INTERNAL_ERROR;
1055 eventType = freadUint32(fp, endian);
1057 event = (TSS_PCR_EVENT *) xmalloc(sizeof(TSS_PCR_EVENT));
1058 if (event == NULL) {
1059 LOG(LOG_ERR, "no memory");
1063 memset(event, 0, sizeof(TSS_PCR_EVENT));
1065 // event->versionInfo = 0; // TODO(munetoh)
1066 event->ulPcrIndex = pcrIndex;
1067 event->eventType = eventType;
1070 event->ulPcrValueLength = SHA1_DIGEST_SIZE;
1071 event->rgbPcrValue = (BYTE *) xmalloc(SHA1_DIGEST_SIZE); // leaked
1072 if (event->rgbPcrValue == NULL) {
1073 LOG(LOG_ERR, "no memory");
1077 size = fread(event->rgbPcrValue, 1, SHA1_DIGEST_SIZE, fp);
1078 if (size != SHA1_DIGEST_SIZE) { // TODO(munetoh) SHA1 only
1079 LOG(LOG_ERR, "BIOS IML File %s, bad pcr size %d at %d event\n",
1080 filename, (int)size, i);
1081 rc = PTS_INTERNAL_ERROR;
1086 eventLength = freadUint32(fp, endian);
1087 event->ulEventLength = eventLength;
1088 /* adjust read data length */
1090 if ((eventLength & 0x03) != 0) {
1091 // DEBUG("FIX alignement\n");
1092 eventLength = (eventLength & 0xFFFFFFFC) + 0x04;
1095 /* malloc EventData */
1096 if ((event->rgbEvent = xmalloc_assert(eventLength)) == NULL) {
1097 LOG(LOG_ERR, "no memory");
1101 // TODO if rgbevent is huge 0x4000000 #=> check the endian
1102 size = fread(event->rgbEvent, 1, eventLength, fp);
1103 if (size != eventLength) {
1104 LOG(LOG_ERR, "BIOS IML File %s, bad eventdata size 0x%x != 0x%x at %d event\n",
1105 filename, (int)size, (int)eventLength, i);
1106 rc = PTS_INTERNAL_ERROR;
1110 /* create event wrapper */
1111 ew_new = (OPENPTS_PCR_EVENT_WRAPPER *)
1112 xmalloc(sizeof(OPENPTS_PCR_EVENT_WRAPPER));
1113 if (ew_new == NULL) {
1114 LOG(LOG_ERR, "no memory");
1118 memset(ew_new, 0, sizeof(OPENPTS_PCR_EVENT_WRAPPER));
1119 ew_new->event = event;
1121 /* add to the snapshot */
1122 if (mode == USE_BHV_FSM) {
1123 /* BHV-FSM - map to the snapshot */
1124 result = addEventToSnapshotBhv(ctx, ew_new); // iml.c
1126 if (result == PTS_SUCCESS) {
1128 } else if (result == PTS_INVALID_SNAPSHOT) { // OPENPTS_FSM_ERROR) {
1129 /* ERROR but continue the verification of rest of IML */
1131 } else if (result == PTS_INTERNAL_ERROR) { // 58
1133 } else if (result == OPENPTS_FSM_TRANSIT) {
1134 DEBUG_FSM("\tTransit to next FSM ======================================\n");
1135 rc = addEventToSnapshotBhv(ctx, ew_new); // iml.c
1136 } else if (result == OPENPTS_FSM_FINISH_WO_HIT) {
1137 DEBUG_FSM("\tTransit to next FSM ======================================\n");
1138 result = addEventToSnapshotBhv(ctx, ew_new); // iml.c
1139 } else if (result == OPENPTS_FSM_MIGRATE_EVENT) {
1143 LOG(LOG_ERR, "getBiosImlFile - addEventToSnapshotBhv rc = %d\n", rc);
1145 } else { // USE_BIN_FSM
1146 /* BIN-FSM - map to the snapshot */
1147 result = addEventToSnapshotBin(ctx, ew_new); // iml.c
1149 if (result == OPENPTS_FSM_SUCCESS) {
1151 } else if (result == PTS_INVALID_SNAPSHOT) {
1153 } else if (result == OPENPTS_FSM_TRANSIT) {
1154 DEBUG_FSM("\tTransit to next FSM ======================================\n");
1155 result = addEventToSnapshotBin(ctx, ew_new); // iml.c
1156 if (result < 0) { // TODO
1157 LOG(LOG_TODO, "getBiosImlFile - addEventToSnapshotBin rc = %d\n", rc);
1159 } else if (result == OPENPTS_FSM_FINISH_WO_HIT) {
1160 DEBUG_FSM("\tTransit to next FSM ======================================\n");
1161 result = addEventToSnapshotBin(ctx, ew_new); // iml.c
1162 if (result < 0) { // TODO
1163 LOG(LOG_TODO, "getBiosImlFile - addEventToSnapshotBin rc = %d\n", rc);
1167 LOG(LOG_ERR, "getBiosImlFile - addEventToSnapshotBin rc = %d\n", rc);
1172 result = extendTpm(&ctx->tpm, ew_new->event);
1173 if (result != PTS_SUCCESS) {
1174 LOG(LOG_ERR, "extend TPM fail\n");
1175 rc = PTS_INTERNAL_ERROR;
1179 /* moved to the snapshot */
1184 ctx->ss_table->event_num++;
1190 if (fclose(fp) == EOF) {
1191 LOG(LOG_ERR, "BIOS IML File %s, read fail\n", filename);
1192 rc = PTS_INTERNAL_ERROR;
1194 DEBUG("read BIOS IML, file %s => %d events\n", filename, ctx->ss_table->event_num);
1197 // WORK NEEDED: Needs i18n using NLS
1198 addReason(ctx, -1, "[IML] Failed to load IML(file:%s)", filename);
1199 rc = PTS_INVALID_SNAPSHOT;
1202 /* free (for ERROR) */
1203 if (event != NULL) {
1204 if (event->rgbPcrValue != NULL) {
1205 xfree(event->rgbPcrValue);
1207 if (event->rgbEvent != NULL) {
1208 xfree(event->rgbEvent);
1212 if (ew_new != NULL) {
1216 DEBUG_CAL("iml.c - getBiosImlFile - done\n");
1223 #define TEMPLATE_TYPE_SIZE 16
1226 * \brief read Runtime(Linux-IMA) IML file
1228 * there are many binary format types :-(
1229 * 1 BINARY_IML_TYPE_IMA_ORIGINAL ima (before kernel 2.6.30, patch set)
1230 * 2 BINARY_IML_TYPE_IMA ima (after kernel 2.6.31, mainline)
1231 * 3 BINARY_IML_TYPE_IMA_NG ima-ng (after kernel 2.6.3X, mainline)
1232 * 4 BINARY_IML_TYPE_IMA_NGLONG ima-ng-long (after kernel 2.6.3X, mainline)
1234 * Snapshot - PCR10, Level 1
1236 * \param filename -- TODO unicode? or url?
1237 * \param mode 0:use BHV-FSM, 1:use BIN-FSM
1240 BINARY_IML_TYPE_IMA_ORIGINAL( Kernel 2.6.18 - Kernel 2.6.29)
1242 0a 00 00 00 | pcr index
1243 00 00 00 00 | type = 0
1244 9e 59 5e bf c6 46 af 46 9c 4b b1 30 00 30 f0 a0 34 bb 4a fe | digest
1245 0e 00 00 00 | length
1246 62 6f 6f 74 5f 61 67 67 72 65 67 61 74 65 | boot_aggregate
1248 0a 00 00 00 | pcr index
1249 01 00 00 00 | type = 1
1250 4c d4 10 cb d7 76 6b 06 72 df eb 0b 73 75 6c 49 0c 12 62 b6 | digest
1251 0b 00 00 00 | length
1252 2f 73 74 61 74 69 63 2f 61 73 68 | /static/ash
1254 0a 00 00 00 | pcr index
1255 01 00 00 00 | type = 1
1256 44 9c 07 6c 8b bd e6 38 c3 7e 07 5d 63 cc d7 a6 ac 66 02 a0 | digest
1257 0e 00 00 00 2f 73 74 61 74 69 63 2f 69 6e 73 6d 6f 64 | /static/insmod
1260 BINARY_IML_TYPE_IMA_31
1261 Fedora12(Kernel 2.6.31, 2.6.32)
1263 0a 00 00 00 | pcr index
1265 97 6c 6c d4 28 ca bb 21 ec a2 ac e6 e6 ac b0 c9 f3 97 ed bb | digest
1266 22 00 00 00 | len = 34 = 20+14
1267 36 b6 36 92 6c fd e5 e6 9c 62 6b 93 ca 39 b8 88 df 7b 00 04 | sha1(PCR0-8)
1268 62 6f 6f 74 5f 61 67 67 72 65 67 61 74 65 | boot_aggregate
1270 0a 00 00 00 | pcr index
1272 5c bd bf 4d de 8f 6c 07 37 fc 4a c1 41 fc 7c 55 d1 7a e4 a8 | digest
1273 19 00 00 00 | len = 25 = 20+5
1274 61 a6 44 44 de db 3d fa 89 e0 65 4c 4c e2 d8 c5 5f c7 c9 7b | sha1(/init)
1275 2f 69 6e 69 74 | /init
1278 Fedora12 2.6.32.12-115.fc12.x86_64 2010-06-30
1280 0a 00 00 00 | pcr index
1281 13 39 da 6c 77 98 a9 c2 b4 4f 1b 0d 87 58 5f d7 3f 7c 22 ce | digest
1282 03 00 00 00 | len = 3
1284 54 6c 57 74 80 74 91 68 a8 c5 d2 b9 03 b0 a9 60 59 96 54 0d | sha1(PCR0-8)
1285 0e 00 00 00 | len = 14
1286 62 6f 6f 74 5f 61 67 67 72 65 67 61 74 65 | boot_aggregate
1288 0a 00 00 00 | pcr index
1289 c7 b9 c2 03 94 48 3a 14 02 e1 e5 d4 51 50 a4 eb f4 6d 5a 16 | digest
1290 03 00 00 00 | len = 3
1292 4c 65 02 10 71 e8 e6 21 40 65 1b 3f 1b 62 ac ed 31 93 5d da | SHA1(/init)
1294 2f 69 6e 69 74 | /init
1297 BINARY_IML_TYPE_IMA new
1299 0a 00 00 00 | pcrindex = 10
1300 e5 07 75 aa a7 9f c4 0a 82 59 75 53 3b 13 f8 ab e5 15 26 6c | digest
1301 03 00 00 00 | len = 3
1302 69 6d 61 | type = ima
1303 54 72 86 ec a8 ea 52 96 1b 3d 46 09 a6 2a ff 34 b1 46 c8 46 | template digest
1305 62 6f 6f 74 5f 61 67 67 72 65 67 61 74 65 | boot_aggregate
1307 0a 00 00 00 | pcrindex = 10
1308 5c bd bf 4d de 8f 6c 07 37 fc 4a c1 41 fc 7c 55 d1 7a e4 a8 | digest
1309 03 00 00 00 | len = 3
1310 69 6d 61 | type = ima
1311 61 a6 44 44 de db 3d fa 89 e0 65 4c 4c e2 d8 c5 5f c7 c9 7b | template digest
1312 05 00 00 00 | len = 5
1313 2f 69 6e 69 74 | /init
1316 pcrindex => ulPcrIndex
1317 digest => rgbPcrValue
1318 template type => eventType = BINARY_IML_TYPE_IMA
1321 BINARY_IML_TYPE_IMA_NG new
1323 0a 00 00 00 | pcr index
1324 62 a5 b7 e8 43 7d 21 b9 a4 81 3c 1d 56 02 93 d5 48 ea 51 2f | SHA1(template)
1326 69 6d 61 2d 6e 67 | ima-ng
1327 36 00 00 00 | template size = 0x36
1328 73 68 61 32 35 36 00 | sha256
1329 06 85 35 49 b8 8d 5c 3d 8e 3d 5d d4 3f b9 88 02 | SHA256()
1330 b4 cb 5a b7 a5 0f e5 17 fd 40 eb 2a 71 f6 d5 49 | SHA256()
1331 62 6f 6f 74 5f 61 67 67 72 65 67 61 74 65 00 | boot_aggregate
1333 0a 00 00 00 | pcr index
1334 b6 d6 07 01 ff a9 e8 27 0b 85 f2 72 ec 6f 5e 65 1a 95 6c ab |
1336 69 6d 61 2d 6e 67 | ima-ng
1337 2d 00 00 00 | template size = 0x36
1338 73 68 61 32 35 36 00 | sha256
1339 7f 58 cc 2a 7f c1 b3 ae 7d 2a 6d 84 ce fb 79 c2 | SHA256()
1340 ea 13 09 82 66 f6 56 a1 9f c4 15 dc 7f 32 b3 0a | SHA256()
1341 2f 69 6e 69 74 00 | /init
1344 BINARY_IML_TYPE_IMA_NGLONG new
1347 09 bb 7f 01 03 4d 43 b9 d1 4f 3a 1d fd 2a b4 2b 5f 08 01 e8
1349 69 6d 61 2d 6e 67 6c 6f 6e 67 | ima-nglong
1351 73 68 61 32 35 36 00 |sha256|
1352 06 85 35 49 b8 8d 5c 3d 8e 3d 5d d4 3f b9 88 02
1353 b4 cb 5a b7 a5 0f e5 17 fd 40 eb 2a 71 f6 d5 49
1354 62 6f 6f 74 5f 61 67 67 72 65 67 61 74 65 00 | boot_aggregate|
1355 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1358 43 27 a6 14 2a 9e 78 10 be d8 29 2b 3a 47 f6 a3 eb a1 30 d9
1360 69 6d 61 2d 6e 67 6c 6f 6e 67
1362 73 68 61 32 35 36 00
1363 7f 58 cc 2a 7f c1 b3 ae 7d 2a 6d 84 ce fb 79 c2
1364 ea 13 09 82 66 f6 56 a1 9f c4 15 dc 7f 32 b3 0a
1365 2f 69 6e 69 74 00 | /init
1366 00 00 00 00 00 00 00 00
1368 75 6e 6c 61 62 65 6c 65 64 00 00 |unlabeled|
1370 6b 65 72 6e 65 6c 00 00 |kernel |
1373 d2 a1 0c 44 d7 d5 5a 41 48 75 2a 7d 01 cd 8c b3 fe 14 78 06
1375 69 6d 61 2d 6e 67 6c 6f 6e 67 |.ima-nglo|
1377 73 68 61 32 35 36 00
1378 0c 63 8b 44 75 d5 25 12 6d 2c ea 9f 35 8b de a9 |
1379 9e d0 f5 d2 a3 f9 5b 88 b3 30 da fb c9 0d 28 c9 |
1380 2f 69 6e 69 74 00 | /init + \0
1381 00 00 00 00 00 00 00 00 | ????
1382 0a 00 00 00 | len = 10
1383 75 6e 6c 61 62 65 6c 65 64 00 | unlabeled
1385 07 00 00 00 | len = 7
1386 6b 65 72 6e 65 6c 00 | kernel
1391 int readImaImlFile(OPENPTS_CONTEXT * ctx, const char *filename, int type, int mode, int *count) {
1392 int rc = PTS_SUCCESS;
1399 UINT32 template_len;
1400 UINT32 template_type_len;
1401 UINT32 filename_len;
1402 char buf[TEMPLATE_TYPE_SIZE];
1405 TSS_PCR_EVENT *event = NULL;
1406 OPENPTS_PCR_EVENT_WRAPPER *ew = NULL;
1407 OPENPTS_PCR_EVENT_WRAPPER *ew_last = NULL;
1409 DEBUG_CAL("readImaImlFile - start\n");
1413 LOG(LOG_ERR, "null input");
1416 if (filename == NULL) {
1417 LOG(LOG_ERR, "null input");
1422 if ((fp = fopen(filename, "rb")) == NULL) {
1423 LOG(LOG_ERR, "readImaImlFile - file open was failed, [%s]\n", filename);
1429 * level 0 <= nothing, num=0
1433 /* pass one - check the IML size */
1435 /* read PCR index */
1436 size = fread(&pcr_index, 1, 4, fp);
1438 /* end of event? => exit */
1441 if (pcr_index > MAX_PCRNUM) {
1442 LOG(LOG_ERR, "Linux-IMA IML File %s, bad pcr index value %d at %d event\n",
1443 filename, pcr_index, i);
1444 rc = PTS_INTERNAL_ERROR;
1448 /* alloc event structure */
1449 event = (TSS_PCR_EVENT *) xmalloc(sizeof(TSS_PCR_EVENT));
1450 if (event == NULL) {
1451 LOG(LOG_ERR, "no memory");
1455 memset(event, 0, sizeof(TSS_PCR_EVENT));
1456 event->ulPcrIndex = pcr_index;
1457 event->eventType = 0; // TODO
1458 event->ulPcrValueLength = 0;
1459 event->ulEventLength = 0;
1460 // event->versionInfo = 0; // TODO(munetoh)
1462 /* many formats :-( */
1463 if (type == BINARY_IML_TYPE_IMA_ORIGINAL) { // 2.6.29
1465 size = fread(&event->eventType, 1, 4, fp);
1467 LOG(LOG_ERR, "Linux-IMA(ORIGINAL) IML File %s, bad eventType at %d event\n",
1469 rc = PTS_INTERNAL_ERROR;
1473 /* read Digest (SHA1) */
1474 event->ulPcrValueLength = SHA1_DIGEST_SIZE;
1475 event->rgbPcrValue = (BYTE *) xmalloc(SHA1_DIGEST_SIZE);
1476 if (event->rgbPcrValue == NULL) {
1477 LOG(LOG_ERR, "no memory");
1481 size = fread(event->rgbPcrValue, 1, SHA1_DIGEST_SIZE, fp);
1482 if (size != SHA1_DIGEST_SIZE) {
1483 LOG(LOG_ERR, "Linux-IMA(ORIGINAL) IML File %s, bad pcr size %d at %d event\n",
1485 rc = PTS_INTERNAL_ERROR;
1489 /* read eventdata length */
1490 size = fread(&event->ulEventLength, 1, 4, fp);
1492 LOG(LOG_ERR, "Linux-IMA(ORIGINAL) IML File %s, bad event length size %d at %d event\n",
1494 rc = PTS_INTERNAL_ERROR;
1497 /* alloc eventdata */
1498 if ((event->rgbEvent = xmalloc(event->ulEventLength)) == NULL) {
1499 LOG(LOG_ERR, "no memory");
1503 // memset(event->rgbEvent,0,event->ulEventLength);
1506 size = fread(event->rgbEvent, 1, event->ulEventLength, fp);
1507 if (size != event->ulEventLength) {
1508 LOG(LOG_ERR, "Linux-IMA(ORIGINAL) IML File %s, bad event size %d at %d event\n",
1510 rc = PTS_INTERNAL_ERROR;
1513 } else if (type == BINARY_IML_TYPE_IMA_31) { // 2.6.30-32
1514 // DEBUG("getImaImlFile - BINARY_IML_TYPE_IMA_31\n");
1516 size = fread(&event_type, 1, 4, fp);
1518 LOG(LOG_ERR, "Linux-IMA(IMA_31) IML File %s, bad eventType at %d event\n",
1520 rc = PTS_INTERNAL_ERROR;
1524 /* read Digest (SHA1) */
1525 event->ulPcrValueLength = SHA1_DIGEST_SIZE;
1526 event->rgbPcrValue = (BYTE *) xmalloc(SHA1_DIGEST_SIZE);
1527 if (event->rgbPcrValue == NULL) {
1528 LOG(LOG_ERR, "no memory");
1532 size = fread(event->rgbPcrValue, 1, SHA1_DIGEST_SIZE, fp);
1533 if (size != SHA1_DIGEST_SIZE) {
1534 LOG(LOG_ERR, "Linux-IMA(IMA_31) IML File %s, bad pcr size %d at %d event\n",
1536 rc = PTS_INTERNAL_ERROR;
1540 /* read Template length */
1541 size = fread(&template_len, 1, 4, fp);
1543 LOG(LOG_ERR, "Linux-IMA(IMA_31) IML File %s, bad template size %d at %d event\n",
1545 rc = PTS_INTERNAL_ERROR;
1548 filename_len = template_len - 20;
1550 /* alloc template (=event data) */
1551 event->ulEventLength = 20 + 256; // TODO(munetoh)
1552 event->rgbEvent = xmalloc(event->ulEventLength);
1553 if (event->rgbEvent == NULL) {
1554 LOG(LOG_ERR, "no memory");
1558 memset(event->rgbEvent, 0, event->ulEventLength);
1560 /* read Template digest */
1561 size = fread(event->rgbEvent, 1, SHA1_DIGEST_SIZE, fp);
1562 if (size != SHA1_DIGEST_SIZE) {
1563 LOG(LOG_ERR, "Linux-IMA(IMA_31) IML File %s, bad event size %d at %d event\n",
1565 rc = PTS_INTERNAL_ERROR;
1569 // DEBUG("getImaImlFile - filename_len %d\n", filename_len);
1572 size = fread(&event->rgbEvent[20], 1, filename_len, fp);
1573 if (size != filename_len) {
1574 LOG(LOG_ERR, "Linux-IMA(IMA_31) IML File %s, bad event size %d != %dat %d event\n",
1575 filename, (int)size, (int)filename_len, i);
1576 rc = PTS_INTERNAL_ERROR;
1580 /* read Digest (SHA1) */
1581 event->ulPcrValueLength = SHA1_DIGEST_SIZE;
1582 event->rgbPcrValue = (BYTE *) xmalloc_assert(SHA1_DIGEST_SIZE);
1583 if (event->rgbPcrValue == NULL) {
1584 LOG(LOG_ERR, "no memory");
1589 size = fread(event->rgbPcrValue, 1, SHA1_DIGEST_SIZE, fp);
1590 if (size != SHA1_DIGEST_SIZE) {
1591 LOG(LOG_ERR, "Linux-IMA() IML File %s, bad pcr size %d at %d event\n",
1593 rc = PTS_INTERNAL_ERROR;
1597 /* read Template type length */
1598 size = fread(&template_type_len, 1, 4, fp);
1600 LOG(LOG_ERR, "Linux-IMA() IML File %s, bad template size %d at %d event\n",
1602 rc = PTS_INTERNAL_ERROR;
1606 if (template_type_len >= TEMPLATE_TYPE_SIZE) {
1607 LOG(LOG_ERR, "template_type_len %d(0x%x) is too big\n", template_type_len, template_type_len);
1608 rc = PTS_INTERNAL_ERROR;
1611 // DEBUG("getImaImlFile - template_type_len %d\n",template_type_len);
1613 /* read Template type */
1614 size = fread(&buf, 1, template_type_len, fp);
1615 if (size != template_type_len) {
1616 LOG(LOG_ERR, "missing\n");
1617 rc = PTS_INTERNAL_ERROR;
1620 // TODO accessing beyond memory
1621 buf[template_type_len] = 0;
1623 if (!strcmp(buf, "ima")) {
1624 // DEBUG("getImaImlFile - BINARY_IML_TYPE_IMA\n");
1625 event->eventType = 0; // BINARY_IML_TYPE_IMA;
1626 // TODO(munetoh) check with type
1628 /* alloc template (=event data) */
1629 event->ulEventLength = 20 + 256; // TODO(munetoh)
1630 event->rgbEvent = xmalloc(event->ulEventLength);
1631 if (event->rgbEvent == NULL) {
1632 LOG(LOG_ERR, "no memory");
1636 memset(event->rgbEvent, 0, event->ulEventLength);
1638 /* read Template digest */
1639 size = fread(event->rgbEvent, 1, SHA1_DIGEST_SIZE, fp);
1640 if (size != SHA1_DIGEST_SIZE) {
1641 LOG(LOG_ERR, "missing\n");
1642 rc = PTS_INTERNAL_ERROR;
1646 /* read filename len */
1647 size = fread(&filename_len, 1, 4, fp);
1649 LOG(LOG_ERR, "missing\n");
1650 rc = PTS_INTERNAL_ERROR;
1654 if (filename_len > 255) {
1655 LOG(LOG_ERR, "filename_len is too big, %d, 0x%x\n", filename_len, filename_len);
1656 rc = PTS_INTERNAL_ERROR;
1660 DEBUG_CAL("readImaImlFile - filename_len %d\n", filename_len);
1663 size = fread(&event->rgbEvent[20], 1, filename_len, fp);
1664 if (size != filename_len) {
1665 LOG(LOG_ERR, "missing\n");
1666 rc = PTS_INTERNAL_ERROR;
1671 LOG(LOG_ERR, "Unknown template [%s]\n", buf);
1672 rc = PTS_INTERNAL_ERROR;
1677 /* create wrapper */
1678 // ew_last = ew_new; // TODO
1679 ew = (OPENPTS_PCR_EVENT_WRAPPER *)
1680 xmalloc(sizeof(OPENPTS_PCR_EVENT_WRAPPER));
1682 LOG(LOG_ERR, "no memory");
1686 memset(ew, 0, sizeof(OPENPTS_PCR_EVENT_WRAPPER));
1689 if (event_num == 0) {
1692 ew->index = event_num;
1693 ew_last->next_all = ew;
1698 if (mode == USE_BHV_FSM) {
1699 /* map to the snapshot */
1700 result = addEventToSnapshotBhv(ctx, ew_last); // iml.c
1701 if (result != PTS_SUCCESS) {
1702 LOG(LOG_ERR, "readImaImlFile - addEventToSnapshotBhv fail, rc = %d\n", rc);
1703 rc = PTS_INTERNAL_ERROR;
1706 } else { // USE_BIN_FSM
1707 /* map to the snapshot */
1708 result = addEventToSnapshotBin(ctx, ew_last); // iml.c
1709 if (result != PTS_SUCCESS) {
1710 LOG(LOG_ERR, "readImaImlFile - addEventToSnapshotBin fail\n");
1711 rc = PTS_INTERNAL_ERROR;
1716 DEBUG_CAL("readImaImlFile - TPM_extend\n");
1719 result = extendTpm(&ctx->tpm, ew_last->event);
1721 LOG(LOG_ERR, "extend TPM fail\n");
1722 rc = PTS_INTERNAL_ERROR;
1726 /* moved to the snapshot */
1734 ctx->ss_table->event_num += event_num;
1739 // DEBUG("iml.c - getBiosImlFile - done, %d events\n", event_num);
1740 // LOG(LOG_ERR, "SS LEVEL %d == 1?, ss->event_num =%d\n",ss->level,ss->event_num );
1741 DEBUG("read IMA IML, file %s => %d events\n", filename, event_num);
1742 DEBUG_CAL("readImaImlFile - done, %d events\n", event_num);
1745 /* free (for error) */
1746 if (event != NULL) {
1747 if (event->rgbPcrValue != NULL) {
1748 xfree(event->rgbPcrValue);
1750 if (event->rgbEvent != NULL) {
1751 xfree(event->rgbEvent);
1763 * set OPENPTS_PCRS to SNAPSHOT
1769 int setPcrsToSnapshot(OPENPTS_CONTEXT *ctx, OPENPTS_PCRS *pcrs) {
1773 DEBUG_CAL("setPcrsToSnapshot\n");
1777 LOG(LOG_ERR, "null input");
1781 LOG(LOG_ERR, "null input");
1786 for (i = 0; i < pcrs->pcr_num; i++) {
1788 OPENPTS_SNAPSHOT *ss0;
1789 OPENPTS_SNAPSHOT *ss1;
1793 // TODO ss0->tpm_pcr is wrong
1794 ss0 = getSnapshotFromTable(ctx->ss_table, i, 0);
1795 ss1 = getSnapshotFromTable(ctx->ss_table, i, 1);
1797 if ((ss0 != NULL) && (ss1 != NULL)) {
1798 /* exist level 0 and 1 */
1799 for (j = 0; j < SHA1_DIGEST_SIZE; j++) {
1800 ss0->start_pcr[j] = 0;
1801 ss0->tpm_pcr[j] = pcr[j]; // TODO(munetoh)
1802 ss1->tpm_pcr[j] = pcr[j];
1804 } else if ((ss0 != NULL) && (ss1 == NULL)) {
1805 /* exist level 0 only */
1806 for (j = 0; j < SHA1_DIGEST_SIZE; j++) {
1807 ss0->start_pcr[j] = 0;
1808 ss0->tpm_pcr[j] = pcr[j];
1810 } else if ((ss0 == NULL) && (ss1 != NULL)) {
1811 /* exist level 1 only */
1812 for (j = 0; j < SHA1_DIGEST_SIZE; j++) {
1813 ss1->start_pcr[j] = 0;
1814 ss1->tpm_pcr[j] = pcr[j];
1823 #ifdef CONFIG_NO_TSS
1824 int getPcr(OPENPTS_CONTEXT * ctx) {
1828 #else // CONFIG_NO_TSS
1830 * get PCR value from TSS
1832 * PCR values are also taken at quoteTss time.
1834 int getPcr(OPENPTS_CONTEXT * ctx) {
1836 TSS_HCONTEXT hContext;
1842 // DEBUG("getPcr is deprecated\n");
1849 LOG(LOG_ERR, "null input");
1853 /* Connect to TCSD */
1854 result = Tspi_Context_Create(&hContext);
1855 if (result != TSS_SUCCESS) {
1856 LOG(LOG_ERR, "ERROR: Tspi_Context_Create failed rc=0x%x\n", result);
1860 result = Tspi_Context_Connect(hContext, SERVER);
1861 if (result != TSS_SUCCESS) {
1862 LOG(LOG_ERR, "ERROR: Tspi_Context_Connect failed rc=0x%x\n", result);
1867 /* Get TPM handles */
1868 result = Tspi_Context_GetTpmObject(hContext, &hTPM);
1869 if (result != TSS_SUCCESS) {
1870 LOG(LOG_ERR, "ERROR: Tspi_Context_GetTpmObject failed rc=0x%x\n", result);
1875 subCap = TSS_TPMCAP_PROP_PCR;
1876 result = Tspi_TPM_GetCapability(
1878 TSS_TPMCAP_PROPERTY,
1883 if (result != TSS_SUCCESS) {
1884 LOG(LOG_ERR, "ERROR: Tspi_TPM_GetCapability failed rc=0x%x\n", result);
1888 // pcrNum = (UINT32) * blob; // TODO(munetoh) Endian
1889 pcrNum = * (UINT32 *) blob;
1892 for (i = 0; i < pcrNum; i++) {
1893 result = Tspi_TPM_PcrRead(hTPM, i, &blobLength, &blob);
1895 if (result != TSS_SUCCESS) {
1896 LOG(LOG_ERR, "ERROR: Tspi_TPM_PcrRead failed rc=0x%x\n", result);
1901 if (blobLength != SHA1_DIGEST_SIZE) {
1902 Tspi_Context_FreeMemory(hContext, blob);
1909 OPENPTS_SNAPSHOT *ss0;
1910 OPENPTS_SNAPSHOT *ss1;
1912 // TODO ss0->tpm_pcr is wrong
1913 ss0 = getSnapshotFromTable(ctx->ss_table, i, 0);
1914 ss1 = getSnapshotFromTable(ctx->ss_table, i, 1);
1916 if ((ss0 != NULL) && (ss1 != NULL)) {
1917 /* exist level 0 and 1 */
1918 for (j = 0; j < SHA1_DIGEST_SIZE; j++) {
1919 ss0->start_pcr[j] = 0;
1920 ss0->tpm_pcr[j] = blob[j]; // TODO(munetoh)
1921 ss1->tpm_pcr[j] = blob[j];
1923 } else if ((ss0 != NULL) && (ss1 == NULL)) {
1924 /* exist level 0 only */
1925 for (j = 0; j < SHA1_DIGEST_SIZE; j++) {
1926 ss0->start_pcr[j] = 0;
1927 ss0->tpm_pcr[j] = blob[j];
1929 } else if ((ss0 == NULL) && (ss1 != NULL)) {
1930 /* exist level 1 only */
1931 for (j = 0; j < SHA1_DIGEST_SIZE; j++) {
1932 ss1->start_pcr[j] = 0;
1933 ss1->tpm_pcr[j] = blob[j];
1937 Tspi_Context_FreeMemory(hContext, blob);
1941 Tspi_Context_FreeMemory(hContext, NULL);
1945 Tspi_Context_Close(hContext);
1949 #endif // CONFIG_NO_TSS
1952 * HEX string to BYTE[0]
1954 BYTE hex2byte(char *buf, int offset) {
1960 LOG(LOG_ERR, "null input");
1964 tmp = strtol(&buf[offset], &e, 16);
1966 return (BYTE) (0xFF & tmp);
1972 * PCR-00: 8F BF F3 EC EA 9C 54 C8 D1 C4 2C FE A9 3D 6B F0 1B F3 40 5B
1978 int getPcrBySysfsFile(OPENPTS_CONTEXT * ctx, const char *filename) {
1980 char buf[256]; // TODO(munetoh)
1984 OPENPTS_SNAPSHOT *ss0;
1985 OPENPTS_SNAPSHOT *ss1;
1989 LOG(LOG_ERR, "null input");
1992 if (filename == NULL) {
1993 LOG(LOG_ERR, "null input");
1998 if ((fp = fopen(filename, "r")) == NULL) {
1999 LOG(LOG_TODO, "getPcrBySysfsFile - pcr file is %s missing -- ignore in test\n", filename);
2005 ptr = fgets(buf, 256, fp);
2010 // TODO ss0->tpm_pcr is wrong
2011 ss0 = getSnapshotFromTable(ctx->ss_table, count, 0);
2012 ss1 = getSnapshotFromTable(ctx->ss_table, count, 1);
2014 if ((ss0 != NULL) && (ss1 != NULL)) {
2015 /* exist level 0 and 1 */
2016 for (j = 0; j < SHA1_DIGEST_SIZE; j++) {
2017 ss0->start_pcr[j] = 0;
2018 ss0->tpm_pcr[j] = hex2byte(buf, 8 + j * 3);
2019 ss1->tpm_pcr[j] = hex2byte(buf, 8 + j * 3);
2021 } else if ((ss0 != NULL) && (ss1 == NULL)) {
2022 /* exist level 0 only */
2023 for (j = 0; j < SHA1_DIGEST_SIZE; j++) {
2024 ss0->start_pcr[j] = 0;
2025 ss0->tpm_pcr[j] = hex2byte(buf, 8 + j * 3);
2027 } else if ((ss0 == NULL) && (ss1 != NULL)) {
2028 /* exist level 1 only */
2029 for (j = 0; j < SHA1_DIGEST_SIZE; j++) {
2030 ss1->start_pcr[j] = 0;
2031 ss1->tpm_pcr[j] = hex2byte(buf, 8 + j * 3);
2039 ctx->pcr_num = count;
2046 * cat /sys/class/misc/tpm0/device/pcrs
2048 int validatePcr(OPENPTS_CONTEXT * ctx) {
2051 OPENPTS_TPM_CONTEXT *tpm;
2052 OPENPTS_SNAPSHOT *ss;
2056 LOG(LOG_ERR, "null input");
2062 DEBUG("validatePcr - start, Iml->PCR vs TPM\n");
2064 for (i = 0; i < ctx->pcr_num; i++) {
2065 // TODO this check level 0 only, support stacked PCR
2066 ss = getActiveSnapshotFromTable(ctx->ss_table, i);
2068 for (j = 0; j < SHA1_DIGEST_SIZE; j++) {
2069 if (tpm->pcr[i][j] != ss->tpm_pcr[j]) {
2076 DEBUG("validatePcr - done, rc=%d\n", rc);
2078 if (isDebugFlagSet(DEBUG_FLAG)) {
2079 for (i = 0; i < ctx->pcr_num; i++) {
2080 OUTPUT("PCR %2d ", i);
2081 ss = getActiveSnapshotFromTable(ctx->ss_table, i);
2083 for (j = 0; j < SHA1_DIGEST_SIZE; j++) {
2084 OUTPUT("%02x-%02x ", tpm->pcr[i][j], ss->tpm_pcr[j]);
2087 for (j = 0; j < SHA1_DIGEST_SIZE; j++) {
2088 OUTPUT("%02x- ", tpm->pcr[i][j]);
2099 * print OPENPTS_PCR_EVENT_WRAPPER
2102 void printEventWrapper(OPENPTS_PCR_EVENT_WRAPPER *eventWrapper) {
2104 TSS_PCR_EVENT *event;
2107 if (eventWrapper == NULL) {
2108 LOG(LOG_ERR, "null input");
2112 event = eventWrapper->event;
2113 if (event != NULL) {
2114 OUTPUT("%4d ", (int)event->ulPcrIndex);
2115 OUTPUT("%8x ", event->eventType);
2116 for (j = 0; j < (int)event->ulPcrValueLength; j++) {
2117 OUTPUT("%02x", event->rgbPcrValue[j]);
2119 OUTPUT("eventdata[%4d]\n", event->ulEventLength);
2121 LOG(LOG_ERR, "NULL event\n"); // TODO(munetoh)
2127 * print event number of each snapshot
2129 void printSnapshotsInfo(OPENPTS_CONTEXT * ctx) {
2131 OPENPTS_SNAPSHOT *ss;
2137 LOG(LOG_ERR, "null input");
2141 OUTPUT(NLS(MS_OPENPTS, OPENPTS_IML_SNAPSHOT_HEADER,
2143 "PCR Level0 Level1\n"));
2144 OUTPUT("--------------------------\n");
2146 for (i = 0; i < MAX_PCRNUM; i++) {
2148 ss = getSnapshotFromTable(ctx->ss_table, i, 0);
2151 OUTPUT("%6d", ss->event_num);
2152 level0_num += ss->event_num;
2158 ss = getSnapshotFromTable(ctx->ss_table, i, 1);
2160 OUTPUT(" %6d\n", ss->event_num);
2161 level1_num += ss->event_num;
2162 if (ss->level != 1) LOG(LOG_ERR, "bad level %d\n", ss->level);
2167 OUTPUT("---------------------------\n");
2168 OUTPUT(NLS(MS_OPENPTS, OPENPTS_IML_SNAPSHOT_LEVEL_TOTALS,
2169 "level 0 total = %d\n"
2170 "level 1 total = %d\n"), level0_num, level1_num);
2171 OUTPUT("---------------------------\n");