OSDN Git Service

import v0.2.5
[openpts/openpts.git] / src / iml.c
1 /*
2  * This file is part of the OpenPTS project.
3  *
4  * The Initial Developer of the Original Code is International
5  * Business Machines Corporation. Portions created by IBM
6  * Corporation are Copyright (C) 2010 International Business
7  * Machines Corporation. All Rights Reserved.
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the Common Public License as published by
11  * IBM Corporation; either version 1 of the License, or (at your option)
12  * any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * Common Public License for more details.
18  *
19  * You should have received a copy of the Common Public License
20  * along with this program; if not, a copy can be viewed at
21  * http://www.opensource.org/licenses/cpl1.0.php.
22  */
23
24 /**
25  * \file src/iml.c
26  * \brief Load TCG Integrity Measurement Log (IML)
27  * @author Seiji Munetoh <munetoh@users.sourceforge.jp>
28  * @date 2010-04-01
29  * cleanup 2011-07-06 SM
30  *
31  * get IML/PCRS from filesystem
32  * get IML/PCRS vis TSS
33  * create Snapshots with IML
34  */
35
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <openssl/sha.h>
40 #include <openpts.h>
41
42
43 void printEventWrapper(OPENPTS_PCR_EVENT_WRAPPER *eventWrapper);
44
45
46 /**
47  * reset snapshot array
48  *
49  * TODO use ctx,
50  * TODO reset level1 too
51  */
52 // TODO move to snapshot?
53 int resetSnapshot(OPENPTS_SNAPSHOT * snapshots) {
54     int i, j;
55     OPENPTS_SNAPSHOT *ss;
56
57     TSS_PCR_EVENT *event;
58     OPENPTS_PCR_EVENT_WRAPPER *eventWrapper;
59     OPENPTS_PCR_EVENT_WRAPPER *eventWrapper_next;
60
61     for (i = 0; i < MAX_PCRNUM; i++) {
62         ss = &snapshots[i];
63         eventWrapper = ss->start;
64         for (j = 0; j < ss->event_num; j++) {
65             event = eventWrapper->event;
66             if (event != NULL) {
67                 if (event->rgbPcrValue != NULL)
68                     free(event->rgbPcrValue);
69                 if (event->rgbEvent != NULL)
70                     free(event->rgbEvent);
71                 free(event);
72             } else {
73                 ERROR("resetSnapshot - NULL event\n");  // TODO(munetoh)
74             }
75             eventWrapper_next = eventWrapper->next_pcr;
76             free(eventWrapper);
77             eventWrapper = eventWrapper_next;
78         }
79         // if (iml[i].eventList != NULL) free(iml[i].eventList);
80         ss->pcrIndex = i;
81         ss->event_num = 0;
82         ss->level = 0;
83     }
84
85
86     return 0;  // TODO(munetoh)
87 }
88
89
90 /**
91  *  new 
92  */
93 OPENPTS_PCR_EVENT_WRAPPER * newEventWrapper() {
94     OPENPTS_PCR_EVENT_WRAPPER *ew;
95
96     ew = (OPENPTS_PCR_EVENT_WRAPPER *)malloc(sizeof(OPENPTS_PCR_EVENT_WRAPPER));
97     if (ew == NULL) {
98         ERROR("newEventWrapper() - no memory\n");
99         return NULL;
100     }
101
102     memset(ew, 0, sizeof(OPENPTS_PCR_EVENT_WRAPPER));
103
104     return ew;
105 }
106
107 /**
108  *  free 
109  */
110 void freeEventWrapper(OPENPTS_PCR_EVENT_WRAPPER * ew) {
111     // TODO
112     free(ew);
113 }
114
115 /**
116  * 
117  */
118 void freeEventWrapperChain(OPENPTS_PCR_EVENT_WRAPPER * ew) {
119     TSS_PCR_EVENT *event;
120
121     if (ew == NULL) {
122         ERROR("OPENPTS_PCR_EVENT_WRAPPE is NULL\n");
123         return;
124     }
125
126     if (ew->next_pcr != NULL) {
127         freeEventWrapperChain(ew->next_pcr);
128     }
129
130     event = ew->event;
131     if (event != NULL) {
132         // {
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);
136         // }
137         if (event->rgbPcrValue != NULL)
138             free(event->rgbPcrValue);
139         if (event->rgbEvent != NULL)
140             free(event->rgbEvent);
141         free(event);
142     } else {
143         ERROR("freeSnapshot - NULL event\n");  // TODO(munetoh)
144     }
145     free(ew);
146     ew = NULL;
147 }
148
149
150 #define OPENPTS_FSM_NO_LEVEL1  10
151
152 /**
153  * add Event to Snapshopt
154  * IML-> IR, check with Behavir FSM
155  * IML-> RM, check with Behavir FSM
156  *
157  * Return
158  *   PTS_SUCCESS            OK
159  *   PTS_INVALID_SNAPSHOT   bad event (FSM fail)
160  *   PTS_INTERNAL_ERROR     else
161  *
162  *   OPENPTS_FSM_TRANSIT        => transit to next level of FSM
163  *   OPENPTS_FSM_FINISH_WO_HIT  => transit to next level of FSM
164  *
165  *  OLD
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
170  *
171  */
172 int addEventToSnapshotBhv(
173         OPENPTS_CONTEXT * ctx,
174         OPENPTS_PCR_EVENT_WRAPPER * eventWrapper) {
175     int index;
176     int active_level;
177     OPENPTS_SNAPSHOT *ss;
178     int rc;
179
180     DEBUG_CAL("addEventToSnapshot - start\n");
181
182     if (eventWrapper == NULL) {
183         ERROR("null eventWrapper\n");
184         return PTS_INTERNAL_ERROR;  // OPENPTS_FSM_ERROR;
185     }
186
187     index = eventWrapper->event->ulPcrIndex;
188
189
190     DEBUG_FSM("[PCR%02d] addEventToSnapshotBhv()\n", index);
191
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];
196     }
197
198     /* Get Snapshot */
199     /* 
200         Snapshot by PCR, by Level
201
202         Active FSM(LV0)  FSM(LV1)        level
203         ----------------------------------------
204            0      OK        -         =>  0
205            0      NULL      OK        =>  1
206            1      -         OK        =>  1
207         
208     */
209
210     active_level = getActiveSnapshotLevel(ctx->ss_table, index);
211
212     if (active_level == 0) {
213         /* use level 0 snapshot */
214         ss = getSnapshotFromTable(ctx->ss_table, index, 0);
215
216         if (ss == NULL) {
217             /* level 0 SS is null => check Level 1 SS */
218             ss = getSnapshotFromTable(ctx->ss_table, index, 1);
219             if (ss == NULL) {
220                 addReason(ctx, "[PCR%02d] Snapshot(FSM) is missing for PCR%d. Please check the configuration file '%s'",
221                     index,
222                     index, ctx->conf->config_file);
223                 ctx->ss_table->error[index] = PTS_INTERNAL_ERROR;
224                 return PTS_INTERNAL_ERROR;
225             }
226
227             /* check FSM */
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);
231                 active_level = 1;
232                 // DEBUG_FSM("pcr%d SKIP to level 1\n", index);
233                 DEBUG_FSM("[PCR%02d] RM0 -> RM1 (RM0 is missing)\n");
234             } else {
235                 /* FSM is missing */
236                 addReason(ctx,
237                     "[RM01-PCR%02d] FSM is missing for PCR%d, Level 1. Please check the configuration file '%s'",
238                     index,
239                     index, ctx->conf->config_file);
240                 ctx->ss_table->error[index] = PTS_INTERNAL_ERROR;
241                 return PTS_INTERNAL_ERROR;
242             }
243         }
244
245
246         /* check FSM */
247         if (ss->fsm_behavior == NULL) {
248             /* no BHV-FSM => check the next level, 1 */
249
250             /* check level 1 SS */
251             ss = getSnapshotFromTable(ctx->ss_table, index, 1);
252             if (ss == NULL) {
253                 /* SS is missing */
254                 addReason(ctx,
255                     "[PCR%02d] Snapshot is missing for PCR%d for Level 0 and 1. "
256                     "Please check the configuration file '%s'",
257                     index,
258                     index,
259                     ctx->conf->config_file);
260                 ctx->ss_table->error[index] = PTS_INTERNAL_ERROR;
261                 return PTS_INTERNAL_ERROR;
262             }
263
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);
269                 active_level = 1;
270             } else {
271                 /* FSM is missing*/
272                 addReason(ctx,
273                     "[RM01-PCR%02d] FSM is missing for PCR%d, Level 1. Please check the configuration file '%s'",
274                     index,
275                     index, ctx->conf->config_file);
276                 ctx->ss_table->error[index] = PTS_INTERNAL_ERROR;
277                 return PTS_INTERNAL_ERROR;  // OPENPTS_FSM_ERROR;
278             }
279         }
280     } else if (active_level == 1) {
281         /* active level is 1, check the level 1 */
282         ss = getSnapshotFromTable(ctx->ss_table, index, 1);
283         if (ss == NULL) {
284             /* SS is missing */
285             DEBUG("ss == NULL  =>  Reason\n");
286             addReason(ctx,
287                 "[RM%02d-PCR%02d] Snapshot is missing for PCR%d, Level %d. Please check the configuration file '%s'",
288                 active_level,
289                 index,
290                 index,
291                 active_level, ctx->conf->config_file);
292             ctx->ss_table->error[index] = PTS_INTERNAL_ERROR;
293             return PTS_INTERNAL_ERROR;
294         }
295
296         /* check FSM */
297         if (ss->fsm_behavior == NULL) {
298             /* FSm is missing */
299             DEBUG("ss->fsm_behavior == NULL  =>  Reason\n");
300             addReason(ctx,
301                 "[RM%02d-PCR%02d] FSM is missing for PCR%d, Level %d. Please check the configuration file '%s'",
302                 active_level,
303                 index,
304                 active_level,
305                 index, ctx->conf->config_file);
306             ctx->ss_table->error[index] = PTS_INTERNAL_ERROR;
307             return PTS_INTERNAL_ERROR;
308         }
309
310         /* OK, the BHV-FSM exists at Level 1*/
311
312     } else {
313         ERROR("level >1 is TBD, pcr=%d level=%d\n", index, active_level);
314         return PTS_INTERNAL_ERROR;
315     }
316
317     /* set sw->ss link */
318     eventWrapper->snapshot = ss;
319     eventWrapper->index = ss->event_num;  // ID for EV_ACTION
320
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'",
328             active_level,
329             index,
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;
337         rc = PTS_SUCCESS;
338
339         /* Move to next level (0->1) */
340         incActiveSnapshotLevel(ctx->ss_table, index);
341     } else if (rc == OPENPTS_FSM_SUCCESS) {
342         /* OK */
343         rc = PTS_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;
348
349         /* Move to next level (0->1) */
350         incActiveSnapshotLevel(ctx->ss_table, index);
351         goto end;
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;
356
357         /* Move to next level (0->1) */
358         incActiveSnapshotLevel(ctx->ss_table, index);
359         goto end;
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) */
362         goto end;
363     } else {
364         ERROR("updateFsm rc=%d\n", rc);
365     }
366
367
368     /* update SS chain */
369     if (ss->event_num == 0) {
370         /* First event */
371         ss->start = eventWrapper;
372         ss->end = eventWrapper;
373     } else {
374         /* else - last */
375         ss->end->next_pcr = eventWrapper;
376         ss->end = eventWrapper;
377     }
378     ss->event_num++;
379
380   end:
381     DEBUG_CAL("addEventToSnapshot - done\n");
382     return rc;
383 }
384
385 /**
386  * add Event to Snapshopt
387  * IR-> check with Binary FSM (RM)
388  *
389  * return
390  *   PTS_SUCCESS            OK
391  *   PTS_INVALID_SNAPSHOT   bad event (FSM fail)
392  *   PTS_INTERNAL_ERROR     else
393  *
394  *
395  */
396 int addEventToSnapshotBin(
397         OPENPTS_CONTEXT * ctx,
398         OPENPTS_PCR_EVENT_WRAPPER * eventWrapper) {
399     int index;
400     int active_level;
401     OPENPTS_SNAPSHOT *ss;
402     int rc;
403
404     DEBUG_CAL("addEventToSnapshotBin - start\n");
405
406     /* check */
407     if (eventWrapper == NULL) {
408         ERROR("null eventWrapper\n");
409         return PTS_INTERNAL_ERROR;
410     }
411
412     index = eventWrapper->event->ulPcrIndex;
413
414     /* Get active snapshot level of this PCR */
415     active_level = getActiveSnapshotLevel(ctx->ss_table, index);
416
417     /* Get Snapshot */
418     ss = getSnapshotFromTable(ctx->ss_table, index, active_level);
419     if (ss == NULL) {
420         /* check the next level */
421         active_level++;
422         ss = getSnapshotFromTable(ctx->ss_table, index, active_level);
423
424         /* check next level (1) */
425         if (ss == NULL) {
426             // ERROR("addEventToSnapshotBin() - pcr=%d Level=%d snapshots is missing\n",index, active_level);
427             addReason(ctx, "[PCR%02d] Snapshot(FSM) is missing",
428                 index);
429             ctx->ss_table->error[index] = PTS_INTERNAL_ERROR;
430             return PTS_INTERNAL_ERROR;
431         } else {
432             /* Exist use this level as active */
433             incActiveSnapshotLevel(ctx->ss_table, index);
434         }
435     }
436
437
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];
442     }
443
444     /* link between Snapshot - event wrapper */
445     eventWrapper->snapshot = ss;
446     eventWrapper->index = ss->event_num;
447
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) {
453             /* 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",
459                     active_level,
460                     index);
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",
464                     active_level,
465                     index);
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",
469                     active_level,
470                     index);
471             } else {
472                 addReason(ctx,  "[RM%02d-PCR%02d-%s] IR validation by RM was faild",
473                     active_level,
474                     index,
475                     ss->fsm_binary->curr_state->name);
476             }
477             ctx->ss_table->error[index] = PTS_INVALID_SNAPSHOT;
478             return PTS_INVALID_SNAPSHOT;
479         }
480         /* return RC */
481     } else {
482         /* no binary FSM */
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);
486             if (ss == NULL) {
487                 // ERROR("no BIN-FSM at level 0,  no SS at level 1\n");
488                 addReason(ctx,  "[PCR%02d] Snapshot(FSM) is missing",
489                     index);
490                 ctx->ss_table->error[index] = PTS_INTERNAL_ERROR;
491                 return PTS_INTERNAL_ERROR;
492             }
493
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
501                 if (ss == NULL) {
502                     ERROR("getSnapshotFromTable(%d,%d) is NULL\n", index, 1);
503                     return PTS_INTERNAL_ERROR;
504                 } else {
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",
511                             active_level + 1,
512                             index,
513                             ss->fsm_binary->curr_state->name);
514                         ctx->ss_table->error[index] = PTS_INVALID_SNAPSHOT;
515                         return PTS_INVALID_SNAPSHOT;
516                     }
517                 }
518             } else {
519                 ERROR("no BIN-FSM at level 0,  no BIN-FSM at level 1\n");
520                 addReason(ctx, "[PCR%02d] Snapshot(FSM) is missing",
521                     index);
522                 ctx->ss_table->error[index] = PTS_INTERNAL_ERROR;
523                 return PTS_INTERNAL_ERROR;
524             }
525         }
526     }
527
528     /* update SS chain */
529
530     if (ss->event_num == 0) {
531         /* First event */
532         ss->start = eventWrapper;
533         ss->end = eventWrapper;
534     } else {
535         /* else - last */
536         ss->end->next_pcr = eventWrapper;
537         ss->end = eventWrapper;
538     }
539     ss->event_num++;
540
541     return PTS_SUCCESS;
542 }
543
544
545 /**
546  * flash Snapshot -> FSM -> Final
547  *
548  * Return
549  *  PTS_SUCCESS
550  *  PTS_INVALID_SNAPSHOT
551  *  PTS_INTERNAL_ERROR
552  */
553 int flashSnapshot(
554         OPENPTS_CONTEXT * ctx,
555         int index) {
556     int active_level;
557     OPENPTS_SNAPSHOT *ss;
558     OPENPTS_SNAPSHOT *ss_lv0 = NULL;
559     int rc;
560
561     DEBUG_CAL("flashSnapshot - start\n");
562
563     /*
564         Active FSM(LV0)  FSM(LV1)        new level
565         ----------------------------------------
566            0      OK        -         =>  0
567            0      NULL      OK        =>  1
568            1      -         OK        =>  1
569         
570     */
571
572     /* which level now ? */
573     active_level = getActiveSnapshotLevel(ctx->ss_table, index);
574
575     /* Get Snapshot */
576     ss = getSnapshotFromTable(ctx->ss_table, index, active_level);
577     if (ss == NULL) {
578         ERROR("No Snapshot at PCR[%d]. level %d\n", index, active_level);
579         // return PTS_INTERNAL_ERROR;
580         // TODO 2011-05-02
581         active_level++;
582         ss = getSnapshotFromTable(ctx->ss_table, index, active_level);
583         if (ss == NULL) {
584             ERROR("No Snapshot at PCR[%d], level %d\n", index, active_level);
585             return PTS_INTERNAL_ERROR;
586         } else {
587             DEBUG("Skip Null SS level. level = %d\n", active_level);
588         }
589     }
590
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 */
595             ss_lv0 = ss;
596             ss = getSnapshotFromTable(ctx->ss_table, index, 1);
597             if (ss == NULL) {
598                 ERROR("PCR[%d] level 1 SS is null\n", index);
599                 return PTS_INTERNAL_ERROR;
600             }
601
602             if (ss->fsm_binary != NULL) {
603                 /* skip level 1 */
604                 DEBUG("PCR[%d] SKIP to level 1\n", index);
605                 setActiveSnapshotLevel(ctx->ss_table, index, 1);
606                 active_level = 1;
607             } else {
608                 ERROR("level 1 BHV-FSM is null\n");
609                 return PTS_INTERNAL_ERROR;
610             }
611         }
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;
619         }
620     } else {
621         ERROR("level %d is not supported yet\n", active_level);
622         return PTS_INTERNAL_ERROR;
623     }
624
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;
629     }
630
631     /* Parse Event by BIN-FSM Model, Do validation by RM */
632
633     DEBUG_FSM("flashSnapshot - PCR[%d] BIN-FSM exist\n", index);
634
635     /* drive FSM */
636     rc = updateFsm(ctx, ss->fsm_binary, NULL);
637
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) {
655         //  OK, HIT
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) {
661         // IMA's last
662         // DEBUG("flashSnapshot - updateFsm looped - end of the IMA IML, rc = %d\n", rc);
663     } else {
664         ERROR("flashSnapshot - updateFsm rc=%d\n", rc);
665     }
666
667     DEBUG_CAL("flashSnapshot - done\n");
668
669     return PTS_SUCCESS;
670 }
671
672
673 /**
674  * \brief  read IML via TSS, get whole IML
675  * option
676  * 0: simple snapshot
677  * 1: stacked snapshot (by FSM)
678  *
679  *  IML->TSS->snapshot(BHV-FSM)->RM
680  *  IML->TSS->snapshot(BHV-FSM)->IR
681  */
682
683 #define SERVER    NULL
684
685 #ifdef CONFIG_NO_TSS
686 int getIml(OPENPTS_CONTEXT * ctx, int option) {
687     /* dummy */
688     return 0;
689 }
690 #else  // CONFIG_NO_TSS
691 int getIml(OPENPTS_CONTEXT * ctx, int option) {
692     int rc = 0;
693     TSS_RESULT result;
694     TSS_HCONTEXT hContext;
695     TSS_HTPM hTPM;
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;
700     int i;
701     int error = 0;
702
703     DEBUG_CAL("getIml - start\n");
704
705     /* clean up TPM */
706     resetTpm(&ctx->tpm, 0);  // reset TPM DRTM=off
707
708     /* check SS table */
709     if (ctx->ss_table == NULL) {
710         ERROR("SS table is null\n");
711         return PTS_INTERNAL_ERROR;
712     }
713
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);
718         goto close;
719     }
720
721     result = Tspi_Context_Connect(hContext, SERVER);
722     if (result != TSS_SUCCESS) {
723         ERROR("ERROR: Tspi_Context_Connect failed rc=0x%x\n", result);
724         goto close;
725     }
726
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);
731         goto close;
732     }
733
734
735     /* Get Log */
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);
739         goto close;
740     }
741
742     DEBUG("IML(via TSS)                : %d events\n", ulEventNumber);
743
744     ctx->ss_table->event_num = ulEventNumber;
745
746     /* map to the snapshot  */
747     if (option == 0) {  // simple, snapshot[i] hold all events on PCR[i]
748         TSS_PCR_EVENT *tpe_tss;
749         TSS_PCR_EVENT *tpe;
750         // int index;
751
752         for (i = 0; i < (int) ulEventNumber; i++) {
753             tpe_tss = &pcrEvents[i];
754
755             /* copy event to local */
756             tpe = (TSS_PCR_EVENT *) malloc(sizeof(TSS_PCR_EVENT));
757             if (tpe == NULL) {
758                 return -1;  // TODO(munetoh)
759             }
760             memcpy(tpe, tpe_tss, sizeof(TSS_PCR_EVENT));
761             // index = tpe->ulPcrIndex;
762
763             /* copy digest */
764             tpe->rgbPcrValue = (BYTE *) malloc(tpe->ulPcrValueLength);
765             if (tpe->rgbPcrValue == NULL) {
766                 return -1;  // TODO(munetoh)
767             }
768             memcpy(tpe->rgbPcrValue,
769                    tpe_tss->rgbPcrValue,
770                    tpe->ulPcrValueLength);
771
772             if (tpe->ulEventLength > 0) {
773                 /* copy eventdata */
774                 tpe->rgbEvent = (BYTE *) malloc(tpe->ulEventLength);
775                 if (tpe->rgbEvent == NULL) {
776                     return -1;  // TODO(munetoh)
777                 }
778                 memcpy(tpe->rgbEvent,
779                        tpe_tss->rgbEvent,
780                        tpe->ulEventLength);
781             } else {
782                 tpe->rgbEvent = NULL;
783             }
784
785             /* create wrapper */
786             // ew_last = ew_new;
787             ew_new = (OPENPTS_PCR_EVENT_WRAPPER *)
788                 malloc(sizeof(OPENPTS_PCR_EVENT_WRAPPER));
789             if (ew_new == NULL) {
790                 ERROR("no memory\n");
791                 return -1;
792             }
793             memset(ew_new, 0, sizeof(OPENPTS_PCR_EVENT_WRAPPER));
794             ew_new->event = tpe;
795
796             /* map to the snapshot (BHV-FSM) */
797             rc = addEventToSnapshotBhv(ctx, ew_new);  // iml.c
798
799             if (rc == PTS_SUCCESS) {
800                 /* OK */
801             } else if (rc == PTS_INVALID_SNAPSHOT) {  // OPENPTS_FSM_ERROR) {
802                 /* ERROR but continue the verification of rest of IML */
803                 error++;
804             } else if (rc == PTS_INTERNAL_ERROR) {  // 58
805                 /* SKIP */
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
812             } else {
813                 /* Unknwon error */
814                 ERROR("getIml - addEventToSnapshotBhv rc = %d\n", rc);
815             }
816
817             /* TPM Extend */
818             rc = extendTpm(&ctx->tpm, ew_new->event);
819             if (rc < 0) {
820                 ERROR("getIml - extendTpm fail\n");
821                 goto free;
822             }
823         }
824     } else if (option == 1) {
825         //  stacked snapshot with FSM
826     } else {
827         // NA
828     }
829
830     /* done */
831     rc = (int) ulEventNumber;
832
833   free:
834
835     // Keep IML data? we have to free by ourselves
836     result = Tspi_Context_FreeMemory(hContext, (BYTE *) pcrEvents);
837     Tspi_Context_FreeMemory(hContext, NULL);
838
839     /* Close TSS/TPM */
840   close:
841     Tspi_Context_Close(hContext);
842
843     if (error > 0) {
844         char buf[BUF_SIZE];
845         snprintf(buf, BUF_SIZE, "[IML] Load IML (via TSS) was faild");
846         addReason(ctx, buf);
847         return PTS_INVALID_SNAPSHOT;
848     }
849
850
851     DEBUG_CAL("getIml - end\n");
852
853     return rc;
854 }
855 #endif  // CONFIG_NO_TSS
856
857 /**
858  * fread + endian conv
859  * Return
860  *   0xFFFFFFFF Error
861  */
862 UINT32 freadUint32(FILE * stream, int endian) {
863     size_t size;
864     UINT32 data;
865     UINT32 in;
866     UINT32 out;
867
868     size = fread(&data, 1, 4, stream);
869
870     if (size != 4) {
871         // This is EOF ERROR("\n");
872         return 0xFFFFFFFF;  // TODO
873     }
874
875     if (endian == 0) {
876         return data;
877     } else {
878         in = data;
879         out = in & 0xff;
880         in = in >> 8;
881         out = out << 8;
882         out += in & 0xff;
883         in = in >> 8;
884         out = out << 8;
885         out += in & 0xff;
886         in = in >> 8;
887         out = out << 8;
888         out += in & 0xff;
889         // DEBUG(" %08x -> %08x\n", data ,out);
890         return out;
891     }
892 }
893
894
895 /**
896  * \brief  read BIOS IML file
897  *
898  * PCR0-7   - BIOS  => Level 0
899  * PCR4,5,8 - GRUB  => Level 1
900  * 
901  * SHA1 only
902  *
903  * \param filename -- TODO unicode? or url?
904  * \param mode 
905  *        0:use BHV-FSM, 
906  *        1:use BIN-FSM
907  *        2:use BHV-FSM + Endian Conv (for PPC Test on X86 ) + 4-byte aligned
908  *
909  * event num => ctx->ss_table->event_num
910  *
911  * return
912  *   PTS_SUCCESS
913  *   PTS_INVALID_SNAPSHOT
914  *   PTS_INTERNAL_ERROR
915  *
916  */
917 // TODO rename readBiosImlFile()
918 int readBiosImlFile(OPENPTS_CONTEXT * ctx, const char *filename, int mode) {
919     int rc = PTS_SUCCESS;
920     int result;
921     int i = 0;
922     size_t size;
923     FILE *fp = NULL;
924     UINT32 pcrIndex;
925     UINT32 eventType;
926     UINT32 eventLength;
927     int endian = 0;
928     int aligned = 0;
929
930     TSS_PCR_EVENT *event = NULL;
931     OPENPTS_PCR_EVENT_WRAPPER *ew_new = NULL;
932     // OPENPTS_PCR_EVENT_WRAPPER *ew_last = NULL;
933     int error = 0;
934
935     DEBUG_CAL("getBiosImlFile - start\n");
936     // DEBUG("read BIOS IML, file %s\n", filename);
937
938     /* check */
939     if (ctx == NULL) {
940         ERROR("ERROR\n");  // TODO(munetoh)
941         return PTS_INTERNAL_ERROR;
942     }
943     if (filename == NULL) {
944         ERROR("ERROR\n");  // TODO(munetoh)
945         return PTS_INTERNAL_ERROR;
946     }
947
948     /* open file */
949     if ((fp = fopen(filename, "rb")) == NULL) {
950         ERROR("%s missing", filename);
951         return PTS_INTERNAL_ERROR;
952     }
953
954     // TODO
955     if (mode == USE_BHV_FSM_EC) {
956         mode = USE_BHV_FSM;
957         endian = 1;  // TODO conf->iml_endian?
958         aligned = 4;  // TODO conf->iml_aligned?
959     }
960
961     /* Read IML, add to Snapshot */
962     while (1) {
963         /* PCR index */
964         pcrIndex = freadUint32(fp, endian);
965         if (pcrIndex == 0xFFFFFFFF) {
966             /* end of data */
967             break;
968         }
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;
973             goto close;
974         }
975
976         /* Event type */
977         eventType = freadUint32(fp, endian);
978         event = (TSS_PCR_EVENT *) malloc(sizeof(TSS_PCR_EVENT));
979         if (event == NULL) {
980             ERROR("no memory\n");
981             rc = PTS_FATAL;
982             goto close;
983         }
984         memset(event, 0, sizeof(TSS_PCR_EVENT));
985
986         // event->versionInfo = 0;  // TODO(munetoh)
987         event->ulPcrIndex = pcrIndex;
988         event->eventType = eventType;
989
990         /* Digest */
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");
995             rc = PTS_FATAL;
996             goto close;
997         }
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;
1003             goto close;
1004         }
1005
1006         /* EventData len */
1007         eventLength = freadUint32(fp, endian);
1008         event->ulEventLength = eventLength;
1009         /* adjust read data length */
1010         if (aligned == 4) {
1011             if ((eventLength & 0x03) != 0) {
1012                 // DEBUG("FIX alignement\n");
1013                 eventLength = (eventLength & 0xFFFFFFFC) + 0x04;
1014             }
1015         }
1016         /* malloc EventData */
1017         if ((event->rgbEvent = malloc(eventLength)) == NULL) {
1018             ERROR("no memory\n");
1019             rc = PTS_FATAL;
1020             goto close;
1021         }
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;
1028             goto close;
1029         }
1030
1031 #if 0
1032         // DEBUG SMBIOS
1033         if (eventLength > 2000) {
1034             TODO("eventLength = %d\n", eventLength);
1035             printHex("", event->rgbEvent, eventLength, "\n");
1036         }
1037 #endif
1038
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");
1044             rc = PTS_FATAL;
1045             goto close;
1046         }
1047         memset(ew_new, 0, sizeof(OPENPTS_PCR_EVENT_WRAPPER));
1048         ew_new->event = event;
1049
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
1054
1055             if (result == PTS_SUCCESS) {
1056                 /* OK */
1057             } else if (result == PTS_INVALID_SNAPSHOT) {  // OPENPTS_FSM_ERROR) {
1058                 /* ERROR but continue the verification of rest of IML */
1059                 error++;
1060             } else if (result == PTS_INTERNAL_ERROR) {  // 58
1061                 /* SKIP */
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) {
1069                 /* SKIP */
1070             } else {
1071                 /* Unknwon error */
1072                 ERROR("getBiosImlFile - addEventToSnapshotBhv rc = %d\n", rc);
1073             }
1074         } else {  // USE_BIN_FSM
1075             /* BIN-FSM - map to the snapshot */
1076             result = addEventToSnapshotBin(ctx, ew_new);  // iml.c
1077
1078             if (result == OPENPTS_FSM_SUCCESS) {
1079                 /* OK */
1080             } else if (result == PTS_INVALID_SNAPSHOT) {
1081                 /* Keep */
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);
1087                 }
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);
1093                 }
1094             } else {
1095                 /* Unknwon error */
1096                 ERROR("getBiosImlFile - addEventToSnapshotBin rc = %d\n", rc);
1097             }
1098         }
1099
1100         /* TPM Extend */
1101         result = extendTpm(&ctx->tpm, ew_new->event);
1102         if (result !=0) {
1103             ERROR("extend TPM fail\n");
1104             rc = PTS_INTERNAL_ERROR;
1105             goto close;
1106         }
1107
1108         /* moved to the snapshot */
1109         event = NULL;
1110         ew_new = NULL;
1111
1112         /* inc */
1113         ctx->ss_table->event_num++;
1114         i++;
1115     }  // while loop
1116
1117
1118   close:
1119     if (fclose(fp) == EOF) {
1120         ERROR("BIOS IML File %s, read fail\n", filename);
1121         rc = PTS_INTERNAL_ERROR;
1122     }
1123     DEBUG("read BIOS IML, file %s => %d events\n", filename, ctx->ss_table->event_num);
1124
1125     if (error > 0) {
1126         addReason(ctx, "[IML] Load IML(file:%s) was faild",
1127             filename);
1128         rc = PTS_INVALID_SNAPSHOT;
1129     }
1130
1131     /* free (for ERROR) */
1132     if (event != NULL) {
1133         if (event->rgbPcrValue != NULL) free(event->rgbPcrValue);
1134         if (event->rgbEvent != NULL) free(event->rgbEvent);
1135         free(event);
1136     }
1137     if (ew_new != NULL) free(ew_new);
1138
1139     DEBUG_CAL("iml.c - getBiosImlFile - done\n");
1140
1141     return rc;
1142 }
1143
1144
1145
1146 #define TEMPLATE_TYPE_SIZE 16
1147
1148 /**
1149  * \brief  read Runtime(Linux-IMA) IML file
1150  *
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)
1156  *
1157  * Snapshot - PCR10, Level 1
1158  *
1159  * \param filename -- TODO unicode? or url?
1160  * \param mode 0:use BHV-FSM, 1:use BIN-FSM
1161  *
1162 <PRE>
1163 BINARY_IML_TYPE_IMA_ORIGINAL( Kernel 2.6.18 - Kernel 2.6.29)
1164
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
1170
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
1176
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
1181
1182
1183 BINARY_IML_TYPE_IMA_31 
1184   Fedora12(Kernel 2.6.31, 2.6.32)
1185
1186 0a 00 00 00                                                 | pcr index
1187 00 00 00 00                                                 | type?
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
1192
1193 0a 00 00 00                                                 | pcr index
1194 00 00 00 00                                                 | type?
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
1199
1200 BINARY_IML_TYPE_IMA 
1201   Fedora12 2.6.32.12-115.fc12.x86_64 2010-06-30
1202
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
1206 69 6d 61                                                     | ima
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
1210
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
1214 69 6d 61                                                     | ima
1215 4c 65 02 10 71 e8 e6 21 40 65 1b 3f 1b 62 ac ed 31 93 5d da  | SHA1(/init)
1216 05 00 00 00                                                  | len=5
1217 2f 69 6e 69 74                                               | /init
1218
1219
1220 BINARY_IML_TYPE_IMA new
1221
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
1227 0e 00 00 00                                                 | len
1228 62 6f 6f 74 5f 61 67 67 72 65 67 61 74 65                   | boot_aggregate
1229
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
1237
1238 IMA              TSS_PCR_EVENT
1239 pcrindex      => ulPcrIndex
1240 digest        => rgbPcrValue
1241 template type => eventType = BINARY_IML_TYPE_IMA
1242
1243
1244 BINARY_IML_TYPE_IMA_NG new
1245
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)
1248 06 00 00 00                                                 |
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
1255
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 |
1258 06 00 00 00                                                 |
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
1265
1266
1267 BINARY_IML_TYPE_IMA_NGLONG new
1268
1269 0a 00 00 00 
1270 09 bb 7f 01 03 4d 43 b9 d1 4f 3a 1d fd 2a b4 2b 5f 08 01 e8  
1271 0a 00 00 00 
1272 69 6d 61 2d 6e 67 6c 6f 6e 67                               | ima-nglong
1273 48 00 00 00 
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 
1279
1280 0a 00 00 00 
1281 43 27 a6 14 2a 9e 78 10 be d8 29 2b 3a 47 f6 a3 eb a1  30 d9 
1282 0a 00 00 00 
1283 69 6d 61 2d 6e 67 6c 6f 6e 67  
1284 50 00 00 00 
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 
1290 0a 00 00 00 
1291 75 6e 6c 61 62 65 6c 65 64 00 00  |unlabeled|
1292 07 00 00 00 
1293 6b 65 72 6e  65 6c 00 00   |kernel |
1294
1295 0a 00 00 00 
1296 d2 a1 0c 44 d7 d5 5a 41 48 75 2a 7d 01 cd 8c b3 fe 14 78 06 
1297 0a 00 00 00  
1298 69 6d 61 2d 6e 67 6c 6f 6e 67  |.ima-nglo|
1299 50 00 00 00 
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
1307 00                                                          | ??
1308 07 00 00 00                                                 | len = 7
1309 6b 65 72 6e 65 6c 00                                        | kernel
1310 00                                                          | ??
1311
1312 </PRE>
1313 */
1314 int readImaImlFile(OPENPTS_CONTEXT * ctx, const char *filename, int type, int mode, int *count) {
1315     int rc = PTS_SUCCESS;
1316     int result;
1317     int i = 0;
1318     size_t size;
1319     FILE *fp = NULL;
1320     UINT32 pcr_index;
1321     UINT32 event_type;
1322     UINT32 template_len;
1323     UINT32 template_type_len;
1324     UINT32 filename_len;
1325     char buf[TEMPLATE_TYPE_SIZE];
1326     int event_num = 0;
1327
1328     TSS_PCR_EVENT *event = NULL;
1329     OPENPTS_PCR_EVENT_WRAPPER *ew = NULL;
1330     OPENPTS_PCR_EVENT_WRAPPER *ew_last = NULL;
1331
1332     DEBUG_CAL("readImaImlFile - start\n");
1333
1334     /* check */
1335     if (ctx == NULL) {
1336         ERROR("readImaImlFile - ctx is NULL\n");  // TODO(munetoh)
1337         return -1;
1338     }
1339     if (filename == NULL) {
1340         ERROR("readImaImlFile - no filename\n");  // TODO(munetoh)
1341         return -1;
1342     }
1343
1344     /* open file */
1345     if ((fp = fopen(filename, "rb")) == NULL) {
1346         ERROR("readImaImlFile - file open was failed, [%s]\n", filename);
1347         return -1;
1348     }
1349
1350     /* 
1351      * PCR10 snapshot
1352      *   level 0 <= nothing,  num=0
1353      *   level 1 <= IMA
1354      */
1355
1356     /* pass one - check the IML size */
1357     while (1) {
1358         /* read PCR index */
1359         size = fread(&pcr_index, 1, 4, fp);
1360         if (size != 4) {
1361             /* end of event? => exit */
1362             break;
1363         }
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;
1368             goto close;
1369         }
1370
1371         /* alloc event structure */
1372         event = (TSS_PCR_EVENT *) malloc(sizeof(TSS_PCR_EVENT));
1373         if (event == NULL) {
1374             ERROR("no memory\n");
1375             rc = PTS_FATAL;
1376             goto close;
1377         }
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)
1384
1385         /* many formats :-( */
1386         if (type == BINARY_IML_TYPE_IMA_ORIGINAL) {  // 2.6.29
1387             /* read type */
1388             size = fread(&event->eventType, 1, 4, fp);
1389             if (size != 4) {
1390                 ERROR("Linux-IMA(ORIGINAL) IML File %s, bad eventType at %d event\n",
1391                     filename, i);
1392                 rc = PTS_INTERNAL_ERROR;
1393                 goto close;
1394             }
1395
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");
1401                 rc = PTS_FATAL;
1402                 goto close;
1403             }
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",
1407                     filename, size, i);
1408                 rc = PTS_INTERNAL_ERROR;
1409                 goto close;
1410             }
1411
1412             /* read eventdata length */
1413             size = fread(&event->ulEventLength, 1, 4, fp);
1414             if (size != 4) {
1415                 ERROR("Linux-IMA(ORIGINAL) IML File %s, bad event length size %d at %d event\n",
1416                     filename, size, i);
1417                 rc = PTS_INTERNAL_ERROR;
1418                 goto close;
1419             }
1420             /* alloc eventdata */
1421             event->rgbEvent = malloc(event->ulEventLength);
1422             if (event->rgbEvent == NULL) {
1423                 ERROR("no memory\n");
1424                 rc = PTS_FATAL;
1425                 goto close;
1426             }
1427             // memset(event->rgbEvent,0,event->ulEventLength);
1428
1429             /* read filename */
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",
1433                     filename, size, i);
1434                 rc = PTS_INTERNAL_ERROR;
1435                 goto close;
1436             }
1437         } else if (type == BINARY_IML_TYPE_IMA_31) {  // 2.6.30-32
1438             // DEBUG("getImaImlFile - BINARY_IML_TYPE_IMA_31\n");
1439             /* read type */
1440             size = fread(&event_type, 1, 4, fp);
1441             if (size != 4) {
1442                 ERROR("Linux-IMA(IMA_31) IML File %s, bad eventType at %d event\n",
1443                     filename, i);
1444                 rc = PTS_INTERNAL_ERROR;
1445                 goto close;
1446             }
1447
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");
1453                 rc = PTS_FATAL;
1454                 goto close;
1455             }
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",
1459                     filename, size, i);
1460                 rc = PTS_INTERNAL_ERROR;
1461                 goto close;
1462             }
1463
1464             /* read Template length */
1465             size = fread(&template_len, 1, 4, fp);
1466             if (size != 4) {
1467                 ERROR("Linux-IMA(IMA_31) IML File %s, bad template size %d at %d event\n",
1468                     filename, size, i);
1469                 rc = PTS_INTERNAL_ERROR;
1470                 goto close;
1471             }
1472             filename_len = template_len - 20;
1473
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");
1479                 rc = PTS_FATAL;
1480                 goto close;
1481             }
1482             memset(event->rgbEvent, 0, event->ulEventLength);
1483
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",
1488                     filename, size, i);
1489                 rc = PTS_INTERNAL_ERROR;
1490                 goto close;
1491             }
1492
1493             // DEBUG("getImaImlFile - filename_len %d\n", filename_len);
1494
1495             /* read filename */
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;
1501                 goto close;
1502             }
1503         } else {
1504             /* read Digest (SHA1) */
1505             event->ulPcrValueLength = SHA1_DIGEST_SIZE;
1506             event->rgbPcrValue = (BYTE *) malloc(SHA1_DIGEST_SIZE);
1507
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",
1511                     filename, size, i);
1512                 rc = PTS_INTERNAL_ERROR;
1513                 goto close;
1514             }
1515
1516             /* read Template type length */
1517             size = fread(&template_type_len, 1, 4, fp);
1518             if (size != 4) {
1519                 ERROR("Linux-IMA() IML File %s, bad template size %d at %d event\n",
1520                     filename, size, i);
1521                 rc = PTS_INTERNAL_ERROR;
1522                 goto close;
1523             }
1524
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;
1528                 goto close;
1529             }
1530             // DEBUG("getImaImlFile - template_type_len %d\n",template_type_len);
1531
1532             /* read Template type */
1533             size = fread(&buf, 1, template_type_len, fp);
1534             if (size != template_type_len) {
1535                 ERROR("missing\n");
1536                 rc = PTS_INTERNAL_ERROR;
1537                 goto close;
1538             }
1539             // TODO accessing beyond memory
1540             buf[template_type_len] = 0;
1541
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
1546
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");
1552                     rc = PTS_FATAL;
1553                     goto close;
1554                 }
1555                 memset(event->rgbEvent, 0, event->ulEventLength);
1556
1557                 /* read Template digest */
1558                 size = fread(event->rgbEvent, 1, SHA1_DIGEST_SIZE, fp);
1559                 if (size != SHA1_DIGEST_SIZE) {
1560                     ERROR("missing\n");
1561                     rc = PTS_INTERNAL_ERROR;
1562                     goto close;
1563                 }
1564
1565                 /* read filename len */
1566                 size = fread(&filename_len, 1, 4, fp);
1567                 if (size != 4) {
1568                     ERROR("missing\n");
1569                     rc = PTS_INTERNAL_ERROR;
1570                     goto close;
1571                 }
1572
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;
1576                     goto close;
1577                 }
1578
1579                 DEBUG_CAL("readImaImlFile - filename_len %d\n", filename_len);
1580
1581                 /* read filename */
1582                 size = fread(&event->rgbEvent[20], 1, filename_len, fp);
1583                 if (size != filename_len) {
1584                     ERROR("missing\n");
1585                     rc = PTS_INTERNAL_ERROR;
1586                     goto close;
1587                 }
1588
1589             } else {
1590                 ERROR("Unknown template [%s]\n", buf);
1591                 rc = PTS_INTERNAL_ERROR;
1592                 goto close;
1593             }
1594         }
1595
1596         /* create wrapper */
1597         // ew_last = ew_new;  // TODO
1598         ew = (OPENPTS_PCR_EVENT_WRAPPER *)
1599             malloc(sizeof(OPENPTS_PCR_EVENT_WRAPPER));
1600         if (ew == NULL) {
1601             ERROR("no memory\n");
1602             rc = PTS_FATAL;
1603             goto close;
1604         }
1605         memset(ew, 0, sizeof(OPENPTS_PCR_EVENT_WRAPPER));
1606         ew->event = event;
1607
1608         if (event_num == 0) {
1609             ew_last = ew;
1610         } else {
1611             ew->index = event_num;
1612             ew_last->next_all = ew;
1613             ew_last = ew;
1614         }
1615
1616         /* to snapshot */
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;
1623                 goto close;
1624             }
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;
1631                 goto close;
1632             }
1633         }
1634
1635         DEBUG_CAL("readImaImlFile - TPM_extend\n");
1636
1637         /* TPM Extend */
1638         result = extendTpm(&ctx->tpm, ew_last->event);
1639         if (result !=0) {
1640             ERROR("extend TPM fail\n");
1641             rc = PTS_INTERNAL_ERROR;
1642             goto close;
1643         }
1644
1645         /* moved to the snapshot */
1646         event = NULL;
1647         ew    = NULL;
1648
1649         event_num++;
1650         i++;
1651     }  // while
1652
1653     ctx->ss_table->event_num += event_num;
1654
1655   close:
1656     fclose(fp);
1657
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);
1662
1663     *count = 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);
1668         free(event);
1669     }
1670     if (ew  != NULL) free(ew);
1671
1672     return rc;
1673 }
1674
1675 /**
1676  * set OPENPTS_PCRS to SNAPSHOT
1677  *
1678  *
1679  * called from ifm.c
1680  *
1681  */
1682 int setPcrsToSnapshot(OPENPTS_CONTEXT *ctx, OPENPTS_PCRS *pcrs) {
1683     BYTE *pcr;
1684     int i;
1685
1686     DEBUG_CAL("setPcrsToSnapshot\n");
1687
1688     /* snapshots */
1689     for (i = 0; i < pcrs->pcr_num; i++) {
1690         int j;
1691         OPENPTS_SNAPSHOT *ss0;
1692         OPENPTS_SNAPSHOT *ss1;
1693
1694         pcr = pcrs->pcr[i];
1695
1696         // TODO ss0->tpm_pcr is wrong
1697         ss0 = getSnapshotFromTable(ctx->ss_table, i, 0);
1698         ss1 = getSnapshotFromTable(ctx->ss_table, i, 1);
1699
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];
1706             }
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];
1712             }
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];
1718             }
1719         }
1720     }
1721
1722     return 0;
1723 }
1724
1725
1726 #ifdef CONFIG_NO_TSS
1727 int getPcr(OPENPTS_CONTEXT * ctx) {
1728     /* dummy */
1729     return 0;
1730 }
1731 #else  // CONFIG_NO_TSS
1732 /**
1733  * get PCR value from TSS
1734  * 
1735  * PCR values are also taken at quoteTss time.
1736  */
1737 int getPcr(OPENPTS_CONTEXT * ctx) {
1738     TSS_RESULT result;
1739     TSS_HCONTEXT hContext;
1740     TSS_HTPM hTPM;
1741     BYTE *blob;
1742     UINT32 blobLength;
1743     UINT32 subCap;
1744
1745     // DEBUG("getPcr is deprecated\n");
1746
1747     int i;
1748     int pcrNum = 16;
1749
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);
1754         goto close;
1755     }
1756
1757     result = Tspi_Context_Connect(hContext, SERVER);
1758     if (result != TSS_SUCCESS) {
1759         ERROR("ERROR: Tspi_Context_Connect failed rc=0x%x\n", result);
1760         goto close;
1761     }
1762
1763
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);
1768         goto close;
1769     }
1770
1771     /* get PCR num */
1772     subCap = TSS_TPMCAP_PROP_PCR;
1773     result = Tspi_TPM_GetCapability(
1774                 hTPM,
1775                 TSS_TPMCAP_PROPERTY,
1776                 sizeof(UINT32),
1777                 (BYTE *) & subCap,
1778                 &blobLength,
1779                 &blob);
1780     if (result != TSS_SUCCESS) {
1781         ERROR("ERROR: Tspi_TPM_GetCapability failed rc=0x%x\n", result);
1782         goto free;
1783     }
1784
1785     // pcrNum = (UINT32) * blob;  // TODO(munetoh) Endian
1786     pcrNum = * (UINT32 *) blob;
1787
1788     /* Read PCRs */
1789     for (i = 0; i < pcrNum; i++) {
1790         result = Tspi_TPM_PcrRead(hTPM, i, &blobLength, &blob);
1791
1792         if (result != TSS_SUCCESS) {
1793             ERROR("ERROR: Tspi_TPM_PcrRead failed rc=0x%x\n", result);
1794             goto free;
1795         }
1796
1797         if (blobLength != SHA1_DIGEST_SIZE) {
1798             Tspi_Context_FreeMemory(hContext, blob);
1799             goto free;
1800         }
1801
1802         {
1803             int j;
1804             OPENPTS_SNAPSHOT *ss0;
1805             OPENPTS_SNAPSHOT *ss1;
1806
1807             // TODO ss0->tpm_pcr is wrong
1808             ss0 = getSnapshotFromTable(ctx->ss_table, i, 0);
1809             ss1 = getSnapshotFromTable(ctx->ss_table, i, 1);
1810
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];
1817                 }
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];
1823                 }
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];
1829                 }
1830             }
1831         }
1832         Tspi_Context_FreeMemory(hContext, blob);
1833     }  // for
1834
1835   free:
1836     Tspi_Context_FreeMemory(hContext, NULL);
1837
1838     /* Close TSS/TPM */
1839   close:
1840     Tspi_Context_Close(hContext);
1841
1842     return pcrNum;
1843 }
1844 #endif  // CONFIG_NO_TSS
1845
1846 /**
1847  * HEX string to BYTE[0]
1848  */
1849 BYTE hex2byte(char *buf, int offset) {
1850     UINT32 tmp;
1851     char *e;
1852
1853     tmp = strtol(&buf[offset], &e, 16);
1854
1855     return (BYTE) (0xFF & tmp);
1856 }
1857
1858 /**
1859  * read PCRS
1860  *
1861  * PCR-00: 8F BF F3 EC EA 9C 54 C8 D1 C4 2C FE A9 3D 6B F0 1B F3 40 5B
1862  *
1863  * Return 
1864  *    number of PCR
1865  *   -1 Error
1866  */
1867 int getPcrBySysfsFile(OPENPTS_CONTEXT * ctx, const char *filename) {
1868     FILE *fp;
1869     char buf[256];  // TODO(munetoh)
1870     char *ptr;
1871     int count = 0;
1872     int j;
1873     OPENPTS_SNAPSHOT *ss0;
1874     OPENPTS_SNAPSHOT *ss1;
1875
1876     /* check */
1877
1878     /* open */
1879     if ((fp = fopen(filename, "r")) == NULL) {
1880         TODO("getPcrBySysfsFile - pcr file is %s missing  -- ignore in test\n", filename);
1881         return -1;  // TODO
1882     }
1883
1884     while (1) {
1885         /*read line */
1886         ptr = fgets(buf, 256, fp);
1887         if (ptr == NULL) {
1888             break;
1889         }
1890
1891         // TODO ss0->tpm_pcr is wrong
1892         ss0 = getSnapshotFromTable(ctx->ss_table, count, 0);
1893         ss1 = getSnapshotFromTable(ctx->ss_table, count, 1);
1894
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);
1901             }
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);
1907             }
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);
1913             }
1914         }
1915
1916         count++;
1917     }
1918
1919     fclose(fp);
1920     ctx->pcr_num = count;
1921
1922     return count;
1923 }
1924
1925 /**
1926  *
1927  * cat /sys/class/misc/tpm0/device/pcrs
1928  */
1929 int validatePcr(OPENPTS_CONTEXT * ctx) {
1930     int rc = 0;
1931     int i, j;
1932     OPENPTS_TPM_CONTEXT *tpm;
1933     OPENPTS_SNAPSHOT *ss;
1934
1935     tpm = &ctx->tpm;
1936
1937     DEBUG("validatePcr - start, Iml->PCR vs TPM\n");
1938
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);
1942         if (ss != NULL) {
1943             for (j = 0; j < SHA1_DIGEST_SIZE; j++) {
1944                 if (tpm->pcr[i][j] != ss->tpm_pcr[j]) {
1945                     rc++;
1946                 }
1947             }
1948         }
1949     }
1950
1951     DEBUG("validatePcr - done, rc=%d\n", rc);
1952
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);
1957             if (ss != NULL) {
1958                 for (j = 0; j < SHA1_DIGEST_SIZE; j++) {
1959                     printf("%02x-%02x ", tpm->pcr[i][j], ss->tpm_pcr[j]);
1960                 }
1961             } else {
1962                 for (j = 0; j < SHA1_DIGEST_SIZE; j++) {
1963                     printf("%02x-   ", tpm->pcr[i][j]);
1964                 }
1965             }
1966             printf("\n");
1967         }
1968     }
1969
1970     return rc;
1971 }
1972
1973 /**
1974  * print OPENPTS_PCR_EVENT_WRAPPER
1975  *
1976  */
1977 void printEventWrapper(OPENPTS_PCR_EVENT_WRAPPER *eventWrapper) {
1978     int j;
1979     TSS_PCR_EVENT *event;
1980
1981     event = eventWrapper->event;
1982
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]);
1988         }
1989         printf("eventdata[%4d]\n", event->ulEventLength);
1990     } else {
1991         ERROR("NULL event\n");  // TODO(munetoh)
1992     }
1993 }
1994
1995
1996 /**
1997  * \brief print event of selected PCR index
1998  * \return num of event
1999  */
2000 int printImlByPcr(
2001         OPENPTS_CONTEXT * ctx,
2002         UINT32 index,
2003         UINT32 offset) {
2004     int i, j;
2005     OPENPTS_SNAPSHOT *ss;
2006     OPENPTS_PCR_EVENT_WRAPPER *eventWrapper;
2007     char buf[SHA1_BASE64_DIGEST_SIZE + 1];
2008     // int len;
2009
2010     /* snapshot */
2011     ss = getSnapshotFromTable(ctx->ss_table, index, 0);
2012     if (ss == NULL) {
2013         ERROR("printImlByPcr() - no ss at pcr=%d, level=0\n", index);
2014         return -1;
2015     }
2016
2017     eventWrapper = ss->start;
2018
2019     printf("PCR[%d]\n", index);
2020
2021     for (i = 0; i < ctx->ss_table->event_num; i++) {
2022         printf(" %3d %3d %08x ",
2023             offset + i,
2024             eventWrapper->event->ulPcrIndex,
2025             eventWrapper->event->eventType);
2026         /* hex */
2027         for (j = 0; j < 20; j++) {
2028             printf("%02x", eventWrapper->event->rgbPcrValue[j]);
2029         }
2030
2031         /* base64 */
2032         // len = encodeBase64(
2033         //     (unsigned char *)buf,
2034         //     (unsigned char *)eventWrapper->event->rgbPcrValue,
2035          //   20);
2036
2037         printf(" (%s) \n", buf);
2038         eventWrapper = eventWrapper->next_pcr;
2039         if (eventWrapper == NULL) break;
2040     }
2041
2042
2043     return i;
2044 }
2045
2046 /**
2047  * \brief print all events
2048  */
2049 int printIml(OPENPTS_CONTEXT * ctx) {
2050     int i;
2051     int rc = 0;
2052
2053     for (i = 0; i < MAX_PCRNUM; i++) {
2054         rc += printImlByPcr(ctx, i, rc);
2055     }
2056
2057     return rc;
2058 }
2059
2060 #if 0
2061 // TODO REMOVE
2062 /**
2063  * print TSS_PCR_EVENT
2064  *
2065  * TODO(munetoh) use fprintEventData in iml2text.c
2066  */
2067 void printEvent(TSS_PCR_EVENT *event) {
2068     int i;
2069
2070     if (event != NULL) {
2071         int index = (int) event->ulPcrIndex;
2072         int type  = event->eventType;
2073         int len = event->ulEventLength;
2074         int pcr4_grub = 0;
2075         int pcr5_grub = 0;
2076         char buf[256];
2077
2078         printf("%4d ", index);
2079         printf("%8x ", type);
2080         for (i = 0; i < (int)event->ulPcrValueLength; i++) {
2081             printf("%02x", event->rgbPcrValue[i]);
2082         }
2083         printf(" eventdata[%4d] ", event->ulEventLength);
2084
2085         if (len < 256) {
2086             memcpy(buf, event->rgbEvent, event->ulEventLength);
2087             buf[event->ulEventLength] = 0;
2088         } else {
2089             memcpy(buf, event->rgbEvent, 255);
2090             buf[255] = 0;
2091         }
2092
2093         if (index == 10) {  // Linux-IMA
2094             if (type == 2) {
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);
2100                 printf("[IMA] ");
2101             } else if ((type & 0xFFFF) == 4) {
2102                 printf("[IMA-USR,0x%04x:%s] ", (type >> 16), buf);
2103             } else {
2104                 printf("[???:%s] ", buf);
2105             }
2106         } else if (index <= 8) {  // BIOS + Grub
2107             switch (type) {
2108                 case 0:
2109                     printf("[BIOS:EV_PREBOOT_CERT(EV_CODE_CERT)]");
2110                     break;
2111                 case 1:
2112                     printf("[BIOS:EV_POST_CODE(EV_CODE_NOCERT)]");
2113                     break;
2114                 case 2:
2115                     printf("[BIOS:EV_UNUSED(EV_XML_CONFIG)]");
2116                     break;
2117                 case 3:
2118                     printf("[BIOS:EV_NO_ACTION]");
2119                     break;
2120                 case 4:
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]);
2133                     } else {
2134                             printf("[BIOS:EV_SEPARATOR, %s]", buf);
2135                     }
2136                     break;
2137                 case 5:
2138                     if ((pcr5_grub > 0) && (index == 5)) {
2139                             printf("[GRUB:EV_ACTION, %s]", buf);
2140                     } else {
2141                             printf("[BIOS:EV_ACTION, %s]", buf);
2142                     }
2143                     break;
2144                 case 6:
2145                     if ((pcr4_grub > 1) && (index == 4)) {
2146                             printf("[GRUB: measure MBR again]");
2147                     } else {
2148                             printf("[BIOS:EV_EVENT_TAG(EV_PLATFORM_SPECIFIC)]");
2149                     }
2150                     break;
2151                 case 7:
2152                     printf("[BIOS:EV_S_CRTM_CONTENTS]");
2153                     break;
2154                 case 8:
2155                     printf("[BIOS:EV_S_CRTM_VERSION]");
2156                     break;
2157                 case 9:
2158                     printf("[BIOS:EV_CPU_MICROCODE]");
2159                     break;
2160                 case 0x0a:
2161                     printf("[BIOS:EV_PLATFORM_CONFIG_FLAG)]");
2162                     break;
2163                 case 0x0b:
2164                     printf("[BIOS:EV_TABLE_OF_CONTENTS)]");
2165                     break;
2166                 case 0x0c:
2167                     printf("[BIOS:EV_COMPACT_HASH]");
2168                     break;
2169                 case 0x0d:
2170                     if (pcr4_grub == 0) {
2171                         // BIOS
2172                         printf("[BIOS:EV_IPL]");
2173                         pcr4_grub = 1;
2174                     } else if (pcr4_grub == 1) {
2175                         // GRUB
2176                         printf("[GRUB:EV_IPL, Stage1(MBR)]");
2177                         pcr4_grub = 2;
2178                     } else if (pcr4_grub == 2) {
2179                         // GRUB
2180                         printf("[GRUB:EV_IPL, Stage1.5]");
2181                         pcr4_grub = 3;
2182                     } else if (pcr4_grub == 3) {
2183                         // GRUB
2184                         printf("[GRUB:EV_IPL, Stage1.5(filesystem)]");
2185                         pcr4_grub = 4;
2186                     } else {
2187                         // GRUB
2188                         printf("[GRUB:EV_IPL]");
2189                     }
2190                     break;
2191                 case 0x0e:
2192                     if (pcr5_grub == 0) {
2193                         printf("[BIOS:EV_IPL_PERTITION_DATA]");
2194                         pcr5_grub = 1;
2195                     } else {
2196                         printf("[GRUB:grub.conf]");
2197                     }
2198                     break;
2199                 case 0x0f:
2200                     printf("[BIOS:EV_NOHOST_CODE)]");
2201                     break;
2202                 case 0x10:
2203                     printf("[BIOS:EV_NOHOST_CONFIG]");
2204                     break;
2205                 case 0x11:
2206                     printf("[BIOS:EV_NOHOST_INFO]");
2207                     break;
2208                 case 0x12:
2209                     printf("[BIOS:EV_SPECIFICATION_IDENTIFIER 0x");
2210                     for (i = 0; i < len; i++) {
2211                         printf("%02x", (unsigned char)buf[i]);
2212                     }
2213                     printf("]");
2214                     break;
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]);
2219                     }
2220                     printf("]");
2221                     break;
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]);
2226                     }
2227                     printf("]");
2228                     break;
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]);
2233                     }
2234                     printf("]");
2235                     break;
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]);
2240                     }
2241                     printf("]");
2242                     break;
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]);
2247                     }
2248                     printf("]");
2249                     break;
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]);
2254                     }
2255                     printf("]");
2256                     break;
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]);
2261                     }
2262                     printf("]");
2263                     break;
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]);
2268                     }
2269                     printf("]");
2270                     break;
2271                 // GRUB-IMA
2272                 case 0x1005:
2273                     printf("[GRUB:ACTION, %s]", buf);
2274                     break;
2275                 case 0x1105:
2276                     printf("[GRUB:KERNEL_OPT %s]", buf);
2277                     break;
2278                 case 0x1205:
2279                     printf("[GRUB:KERNEL %s]", buf);
2280                     break;
2281                 case 0x1305:
2282                     printf("[GRUB:INITRD %s]", buf);
2283                     break;
2284                 case 0x1405:
2285                     printf("[GRUB:MODULE %s]", buf);
2286                     break;
2287                 default:
2288                     printf("[Unknown BIOS Event:size=%d]", len);
2289                     break;
2290             }
2291         }
2292
2293         encodeBase64((unsigned char *)buf, (unsigned char *)event->rgbPcrValue, event->ulPcrValueLength);
2294         printf(" b64(%s)\n", buf);
2295
2296     } else {
2297         ERROR("NULL event\n");  // TODO(munetoh)
2298     }
2299 }
2300 #endif
2301
2302 #if 0
2303 /**
2304  * print OPENPTS_SNAPSHOT
2305  */
2306 void printSnapshot(OPENPTS_SNAPSHOT * ss) {
2307     int i;
2308     TSS_PCR_EVENT *event;
2309     OPENPTS_PCR_EVENT_WRAPPER *eventWrapper;
2310
2311     eventWrapper = ss->start;
2312     // OR while()
2313     for (i = 0; i < ss->event_num; i++) {
2314         event = eventWrapper->event;
2315         printEvent(event);
2316         eventWrapper = eventWrapper->next_pcr;
2317     }
2318 }
2319 #endif
2320
2321 #if 0
2322 // TODO REMOVE
2323 /**
2324  * print events in each snapshot 
2325  */ 
2326 void printSnapshots(OPENPTS_CONTEXT * ctx) {
2327     int i;
2328     OPENPTS_SNAPSHOT *ss;
2329     int level0_num = 0;
2330     int level1_num = 0;
2331
2332     printf("events\n");
2333     printf(" \n");
2334     for (i = 0; i < MAX_PCRNUM; i++) {
2335         ss = getSnapshotFromTable(ctx->ss_table, i, 0);
2336         if (ss != NULL) {
2337             if (ss->event_num > 0) {
2338                 printf("PCR[%2d] - ", i);
2339                 printf("%d events at level 0\n", ss->event_num);
2340             }
2341             level0_num += ss->event_num;
2342             printSnapshot(ss);
2343         }
2344
2345         // if (ss->next != NULL) {
2346         //     ss = ss->next;
2347         /* level 1 */
2348         ss = getSnapshotFromTable(ctx->ss_table, i, 1);
2349         if (ss != NULL) {
2350             if (ss->event_num > 0) {
2351                 printf("PCR[%2d] - ", i);
2352                 printf("%d events at level 1\n", ss->event_num);
2353             }
2354             level1_num += ss->event_num;
2355             if (ss->level != 1) ERROR("bad level %d\n", ss->level);
2356             printSnapshot(ss);
2357         }
2358     }
2359     printf("---------------------------\n");
2360     printf("level 0 total = %d\n", level0_num);
2361     printf("level 1 total = %d\n", level1_num);
2362     printf("---------------------------\n");
2363 }
2364 #endif
2365
2366 /**
2367  *  print event number of each snapshot
2368  */ 
2369 void printSnapshotsInfo(OPENPTS_CONTEXT * ctx) {
2370     int i;
2371     OPENPTS_SNAPSHOT *ss;
2372     // TODO support valiable levels
2373     int level0_num = 0;
2374     int level1_num = 0;
2375
2376     printf("Number of event\n");
2377     printf(" \n");
2378     printf("PCR Level0 Level1 \n");
2379     printf("--------------------------\n");
2380
2381     for (i = 0; i < MAX_PCRNUM; i++) {
2382         /* level 0 */
2383         ss = getSnapshotFromTable(ctx->ss_table, i, 0);
2384         if (ss != NULL) {
2385             printf("%2d ", i);
2386             printf("%6d", ss->event_num);
2387             level0_num += ss->event_num;
2388         } else {
2389             printf("        ");
2390         }
2391
2392         /* level 1 */
2393         ss = getSnapshotFromTable(ctx->ss_table, i, 1);
2394         if (ss != NULL) {
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);
2398         } else {
2399             printf("\n");
2400         }
2401     }
2402     printf("---------------------------\n");
2403     printf("level 0 total = %d\n", level0_num);
2404     printf("level 1 total = %d\n", level1_num);
2405     printf("---------------------------\n");
2406 }
2407