OSDN Git Service

ce13d75b817e9056e8ac016dc67a701efc87a929
[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
41 #include <openpts.h>
42
43 void printEventWrapper(OPENPTS_PCR_EVENT_WRAPPER *eventWrapper);
44
45 /**
46  * reset snapshot array
47  *
48  * TODO use ctx,
49  * TODO reset level1 too
50  */
51 // TODO move to snapshot?
52 int resetSnapshot(OPENPTS_SNAPSHOT * snapshots) {
53     int i, j;
54     OPENPTS_SNAPSHOT *ss;
55     TSS_PCR_EVENT *event;
56     OPENPTS_PCR_EVENT_WRAPPER *eventWrapper;
57     OPENPTS_PCR_EVENT_WRAPPER *eventWrapper_next;
58
59     /* check */
60     if (snapshots == NULL) {
61         LOG(LOG_ERR, "null input");
62         return PTS_FATAL;
63     }
64
65     /* reset PCRs */
66     for (i = 0; i < MAX_PCRNUM; i++) {
67         ss = &snapshots[i];
68         eventWrapper = ss->start;
69         for (j = 0; j < ss->event_num; j++) {
70             event = eventWrapper->event;
71             if (event != NULL) {
72                 if (event->rgbPcrValue != NULL)
73                     xfree(event->rgbPcrValue);
74                 if (event->rgbEvent != NULL)
75                     xfree(event->rgbEvent);
76                 xfree(event);
77             } else {
78                 LOG(LOG_ERR, "resetSnapshot - NULL event\n");  // TODO(munetoh)
79             }
80             eventWrapper_next = eventWrapper->next_pcr;
81             xfree(eventWrapper);
82             eventWrapper = eventWrapper_next;
83         }
84         // if (iml[i].eventList != NULL) xfree(iml[i].eventList);
85         ss->pcrIndex = i;
86         ss->event_num = 0;
87         ss->level = 0;
88     }
89
90
91     return 0;  // TODO(munetoh)
92 }
93
94
95 /**
96  *  new 
97  */
98 OPENPTS_PCR_EVENT_WRAPPER * newEventWrapper() {
99     OPENPTS_PCR_EVENT_WRAPPER *ew;
100
101     ew = (OPENPTS_PCR_EVENT_WRAPPER *)xmalloc(sizeof(OPENPTS_PCR_EVENT_WRAPPER));
102     if (ew == NULL) {
103         LOG(LOG_ERR, "no memory");
104         return NULL;
105     }
106
107     memset(ew, 0, sizeof(OPENPTS_PCR_EVENT_WRAPPER));
108
109     return ew;
110 }
111
112 /**
113  *  free 
114  */
115 void freeEventWrapper(OPENPTS_PCR_EVENT_WRAPPER * ew) {
116     /* check */
117     if (ew == NULL) {
118         LOG(LOG_ERR, "null input");
119         return;
120     }
121
122     xfree(ew);
123 }
124
125 /**
126  * 
127  */
128 void freeEventWrapperChain(OPENPTS_PCR_EVENT_WRAPPER * ew) {
129     TSS_PCR_EVENT *event;
130
131     /* check */
132     if (ew == NULL) {
133         LOG(LOG_ERR, "null input");
134         return;
135     }
136
137     /* chain */
138     if (ew->next_pcr != NULL) {
139         freeEventWrapperChain(ew->next_pcr);
140     }
141
142     event = ew->event;
143     if (event != NULL) {
144         if (event->rgbPcrValue != NULL)
145             xfree(event->rgbPcrValue);
146         if (event->rgbEvent != NULL)
147             xfree(event->rgbEvent);
148         xfree(event);
149     } else {
150         LOG(LOG_ERR, "freeSnapshot - NULL event\n");  // TODO(munetoh)
151     }
152     xfree(ew);
153     ew = NULL;
154 }
155
156
157 #define OPENPTS_FSM_NO_LEVEL1  10
158
159 /**
160  * add Event to Snapshopt
161  * IML-> IR, check with Behavir FSM
162  * IML-> RM, check with Behavir FSM
163  *
164  * Return
165  *   PTS_SUCCESS            OK
166  *   PTS_INVALID_SNAPSHOT   bad event (FSM fail)
167  *   PTS_INTERNAL_ERROR     else
168  *
169  *   OPENPTS_FSM_TRANSIT        => transit to next level of FSM
170  *   OPENPTS_FSM_FINISH_WO_HIT  => transit to next level of FSM
171  *
172  *  OLD
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
177  *
178  */
179 int addEventToSnapshotBhv(
180         OPENPTS_CONTEXT * ctx,
181         OPENPTS_PCR_EVENT_WRAPPER * eventWrapper) {
182     int index;
183     int active_level;
184     OPENPTS_SNAPSHOT *ss;
185     int rc;
186
187     DEBUG_CAL("addEventToSnapshot - start\n");
188
189     /* check */
190     if (ctx == NULL) {
191         LOG(LOG_ERR, "null input");
192         return PTS_FATAL;
193     }
194     if (eventWrapper == NULL) {
195         LOG(LOG_ERR, "null input");
196         return PTS_FATAL;
197     }
198     if (eventWrapper->event == NULL) {
199         LOG(LOG_ERR, "null input");
200         return PTS_FATAL;
201     }
202
203     /* PCR index */
204     index = eventWrapper->event->ulPcrIndex;
205
206     DEBUG_FSM("[PCR%02d] addEventToSnapshotBhv()\n", index);
207
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];
212     }
213
214     /* Get Snapshot */
215     /* 
216         Snapshot by PCR, by Level
217
218         Active FSM(LV0)  FSM(LV1)        level
219         ----------------------------------------
220            0      OK        -         =>  0
221            0      NULL      OK        =>  1
222            1      -         OK        =>  1
223         
224     */
225
226     active_level = getActiveSnapshotLevel(ctx->ss_table, index);
227
228     if (active_level == 0) {
229         /* use level 0 snapshot */
230         ss = getSnapshotFromTable(ctx->ss_table, index, 0);
231
232         if (ss == NULL) {
233             /* level 0 SS is null => check Level 1 SS */
234             ss = getSnapshotFromTable(ctx->ss_table, index, 1);
235             if (ss == NULL) {
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'"),
240                     index,
241                     index, ctx->conf->config_file);
242                 ctx->ss_table->error[index] = PTS_INTERNAL_ERROR;
243                 return PTS_INTERNAL_ERROR;
244             }
245
246             /* check FSM */
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);
250                 active_level = 1;
251                 // DEBUG_FSM("pcr%d SKIP to level 1\n", index);
252                 DEBUG_FSM("[PCR%02d] RM0 -> RM1 (RM0 is missing)\n", index);
253             } else {
254                 /* FSM is missing */
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'"),
259                     index,
260                     index, ctx->conf->config_file);
261                 ctx->ss_table->error[index] = PTS_INTERNAL_ERROR;
262                 return PTS_INTERNAL_ERROR;
263             }
264         }
265
266
267         /* check FSM */
268         if (ss->fsm_behavior == NULL) {
269             /* no BHV-FSM => check the next level, 1 */
270
271             /* check level 1 SS */
272             ss = getSnapshotFromTable(ctx->ss_table, index, 1);
273             if (ss == NULL) {
274                 /* SS is missing */
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'"),
279                     index,
280                     index,
281                     ctx->conf->config_file);
282                 ctx->ss_table->error[index] = PTS_INTERNAL_ERROR;
283                 return PTS_INTERNAL_ERROR;
284             }
285
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);
291                 active_level = 1;
292             } else {
293                 /* FSM is missing*/
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'"),
297                     index,
298                     index, ctx->conf->config_file);
299                 ctx->ss_table->error[index] = PTS_INTERNAL_ERROR;
300                 return PTS_INTERNAL_ERROR;  // OPENPTS_FSM_ERROR;
301             }
302         }
303     } else if (active_level == 1) {
304         /* active level is 1, check the level 1 */
305         ss = getSnapshotFromTable(ctx->ss_table, index, 1);
306         if (ss == NULL) {
307             /* SS is missing */
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'"),
311                 active_level,
312                 index,
313                 index,
314                 active_level, ctx->conf->config_file);
315             ctx->ss_table->error[index] = PTS_INTERNAL_ERROR;
316             return PTS_INTERNAL_ERROR;
317         }
318
319         /* check FSM */
320         if (ss->fsm_behavior == NULL) {
321             /* FSm is missing */
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'"),
325                 active_level,
326                 index,
327                 active_level,
328                 index, ctx->conf->config_file);
329             ctx->ss_table->error[index] = PTS_INTERNAL_ERROR;
330             return PTS_INTERNAL_ERROR;
331         }
332
333         /* OK, the BHV-FSM exists at Level 1*/
334
335     } else {
336         LOG(LOG_ERR, "level >1 is TBD, pcr=%d level=%d\n", index, active_level);
337         return PTS_INTERNAL_ERROR;
338     }
339
340     /* set sw->ss link */
341     eventWrapper->snapshot = ss;
342     eventWrapper->index = ss->event_num;  // ID for EV_ACTION
343
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'"),
354                 active_level,
355                 index,
356                 "unknown",
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");
360             // TODO
361         } else if (ss->fsm_behavior->uml_file == NULL) {
362             LOG(LOG_ERR, "ss->fsm_behavior->uml_file == NULL");
363             // TODO
364         } else {
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'"),
368                 active_level,
369                 index,
370                 ss->fsm_behavior->curr_state->name,
371                 ss->fsm_behavior->uml_file);
372         }
373         ctx->ss_table->error[index] = PTS_INVALID_SNAPSHOT;
374         rc = PTS_INVALID_SNAPSHOT;
375         goto end;
376     } else if (rc == OPENPTS_FSM_FINISH) {
377         /* OK, FSM finish successfly */
378         ss->fsm_behavior->status = OPENPTS_FSM_FINISH;
379         rc = PTS_SUCCESS;
380
381         /* Move to next level (0->1) */
382         incActiveSnapshotLevel(ctx->ss_table, index);
383     } else if (rc == OPENPTS_FSM_SUCCESS) {
384         /* OK */
385         rc = PTS_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;
390
391         /* Move to next level (0->1) */
392         incActiveSnapshotLevel(ctx->ss_table, index);
393         goto end;
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;
398
399         /* Move to next level (0->1) */
400         incActiveSnapshotLevel(ctx->ss_table, index);
401         goto end;
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) */
404         goto end;
405     } else {
406         LOG(LOG_ERR, "updateFsm rc=%d\n", rc);
407     }
408
409
410     /* update SS chain */
411     if (ss->event_num == 0) {
412         /* First event */
413         ss->start = eventWrapper;
414         ss->end = eventWrapper;
415     } else {
416         /* else - last */
417         ss->end->next_pcr = eventWrapper;
418         ss->end = eventWrapper;
419     }
420     ss->event_num++;
421
422   end:
423     DEBUG_CAL("addEventToSnapshot - done\n");
424     return rc;
425 }
426
427 /**
428  * add Event to Snapshopt
429  * IR-> check with Binary FSM (RM)
430  *
431  * return
432  *   PTS_SUCCESS            OK
433  *   PTS_INVALID_SNAPSHOT   bad event (FSM fail)
434  *   PTS_INTERNAL_ERROR     else
435  *
436  *
437  */
438 int addEventToSnapshotBin(
439         OPENPTS_CONTEXT * ctx,
440         OPENPTS_PCR_EVENT_WRAPPER * eventWrapper) {
441     int rc;
442     int index;
443     int active_level;
444     OPENPTS_SNAPSHOT *ss;
445
446     DEBUG_CAL("addEventToSnapshotBin - start\n");
447
448     /* check */
449     if (ctx == NULL) {
450         LOG(LOG_ERR, "null input");
451         return PTS_FATAL;
452     }
453     if (eventWrapper == NULL) {
454         LOG(LOG_ERR, "null input");
455         return PTS_FATAL;
456     }
457     if (eventWrapper->event == NULL) {
458         LOG(LOG_ERR, "null input");
459         return PTS_FATAL;
460     }
461
462     /* PCR index */
463     index = eventWrapper->event->ulPcrIndex;
464
465     /* Get active snapshot level of this PCR */
466     active_level = getActiveSnapshotLevel(ctx->ss_table, index);
467
468     /* Get Snapshot */
469     ss = getSnapshotFromTable(ctx->ss_table, index, active_level);
470     if (ss == NULL) {
471         /* check the next level */
472         active_level++;
473         ss = getSnapshotFromTable(ctx->ss_table, index, active_level);
474
475         /* check next level (1) */
476         if (ss == NULL) {
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"),
479                 index);
480             ctx->ss_table->error[index] = PTS_INTERNAL_ERROR;
481             return PTS_INTERNAL_ERROR;
482         } else {
483             /* Exist use this level as active */
484             incActiveSnapshotLevel(ctx->ss_table, index);
485         }
486     }
487
488
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];
493     }
494
495     /* link between Snapshot - event wrapper */
496     eventWrapper->snapshot = ss;
497     eventWrapper->index = ss->event_num;
498
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) {
504             /* 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"),
511                     active_level,
512                     index);
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"),
517                     active_level,
518                     index);
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"),
523                     active_level,
524                     index);
525             } else {
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"),
529                     active_level,
530                     index,
531                     ss->fsm_binary->curr_state->name);
532             }
533             ctx->ss_table->error[index] = PTS_INVALID_SNAPSHOT;
534             return PTS_INVALID_SNAPSHOT;
535         }
536         /* return RC */
537     } else {
538         /* no binary FSM */
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);
542             if (ss == NULL) {
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"),
546                     index);
547                 ctx->ss_table->error[index] = PTS_INTERNAL_ERROR;
548                 return PTS_INTERNAL_ERROR;
549             }
550
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
558                 if (ss == NULL) {
559                     LOG(LOG_ERR, "getSnapshotFromTable(%d,%d) is NULL\n", index, 1);
560                     return PTS_INTERNAL_ERROR;
561                 } else {
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"),
569                                   active_level + 1,
570                                   index,
571                                   ss->fsm_binary->curr_state->name);
572                         ctx->ss_table->error[index] = PTS_INVALID_SNAPSHOT;
573                         return PTS_INVALID_SNAPSHOT;
574                     }
575                 }
576             } else {
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"),
580                           index);
581                 ctx->ss_table->error[index] = PTS_INTERNAL_ERROR;
582                 return PTS_INTERNAL_ERROR;
583             }
584         }
585     }
586
587     /* update SS chain */
588
589     if (ss->event_num == 0) {
590         /* First event */
591         ss->start = eventWrapper;
592         ss->end = eventWrapper;
593     } else {
594         /* else - last */
595         ss->end->next_pcr = eventWrapper;
596         ss->end = eventWrapper;
597     }
598     ss->event_num++;
599
600     return PTS_SUCCESS;
601 }
602
603
604 /**
605  * flash Snapshot -> FSM -> Final
606  *
607  * Return
608  *  PTS_SUCCESS
609  *  PTS_INVALID_SNAPSHOT
610  *  PTS_INTERNAL_ERROR
611  */
612 int flashSnapshot(
613         OPENPTS_CONTEXT * ctx,
614         int index) {
615     int active_level;
616     int rc;
617     OPENPTS_SNAPSHOT *ss;
618     OPENPTS_SNAPSHOT *ss_lv0 = NULL;
619
620
621     DEBUG_CAL("flashSnapshot - start\n");
622
623     /* check */
624     if (ctx == NULL) {
625         LOG(LOG_ERR, "null input");
626         return PTS_FATAL;
627     }
628
629     /*
630         Active FSM(LV0)  FSM(LV1)        new level
631         ----------------------------------------
632            0      OK        -         =>  0
633            0      NULL      OK        =>  1
634            1      -         OK        =>  1
635         
636     */
637
638     /* which level now ? */
639     active_level = getActiveSnapshotLevel(ctx->ss_table, index);
640
641     /* Get Snapshot */
642     ss = getSnapshotFromTable(ctx->ss_table, index, active_level);
643     if (ss == NULL) {
644         LOG(LOG_ERR, "No Snapshot at PCR[%d]. level %d\n", index, active_level);
645         // return PTS_INTERNAL_ERROR;
646         // TODO 2011-05-02
647         active_level++;
648         ss = getSnapshotFromTable(ctx->ss_table, index, active_level);
649         if (ss == NULL) {
650             LOG(LOG_ERR, "No Snapshot at PCR[%d], level %d\n", index, active_level);
651             return PTS_INTERNAL_ERROR;
652         } else {
653             DEBUG("Skip Null SS level. level = %d\n", active_level);
654         }
655     }
656
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 */
661             ss_lv0 = ss;
662             ss = getSnapshotFromTable(ctx->ss_table, index, 1);
663             if (ss == NULL) {
664                 LOG(LOG_ERR, "PCR[%d] level 1 SS is null\n", index);
665                 return PTS_INTERNAL_ERROR;
666             }
667
668             if (ss->fsm_binary != NULL) {
669                 /* skip level 1 */
670                 DEBUG("PCR[%d] SKIP to level 1\n", index);
671                 setActiveSnapshotLevel(ctx->ss_table, index, 1);
672                 active_level = 1;
673             } else {
674                 LOG(LOG_ERR, "level 1 BHV-FSM is null\n");
675                 return PTS_INTERNAL_ERROR;
676             }
677         }
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;
685         }
686     } else {
687         LOG(LOG_ERR, "level %d is not supported yet\n", active_level);
688         return PTS_INTERNAL_ERROR;
689     }
690
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;
695     }
696
697     /* Parse Event by BIN-FSM Model, Do validation by RM */
698
699     DEBUG_FSM("flashSnapshot - PCR[%d] BIN-FSM exist\n", index);
700
701     /* drive FSM */
702     rc = updateFsm(ctx, ss->fsm_binary, NULL);
703
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) {
721         //  OK, HIT
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) {
727         // IMA's last
728         // DEBUG("flashSnapshot - updateFsm looped - end of the IMA IML, rc = %d\n", rc);
729     } else {
730         LOG(LOG_ERR, "flashSnapshot - updateFsm rc=%d\n", rc);
731     }
732
733     DEBUG_CAL("flashSnapshot - done\n");
734
735     return PTS_SUCCESS;
736 }
737
738
739 /**
740  * \brief  read IML via TSS, get whole IML
741  * option
742  * 0: simple snapshot
743  * 1: stacked snapshot (by FSM)
744  *
745  *  IML->TSS->snapshot(BHV-FSM)->RM
746  *  IML->TSS->snapshot(BHV-FSM)->IR
747  */
748
749 #define SERVER    NULL
750
751 #ifdef CONFIG_NO_TSS
752 int getIml(OPENPTS_CONTEXT * ctx, int option) {
753     /* dummy */
754     return 0;
755 }
756 #else  // CONFIG_NO_TSS
757 int getIml(OPENPTS_CONTEXT * ctx, int option) {
758     int rc = 0;
759     int i;
760     int error = 0;
761     TSS_RESULT result;
762     TSS_HCONTEXT hContext;
763     TSS_HTPM hTPM;
764     TSS_PCR_EVENT *pcrEvents;
765     UINT32 ulEventNumber = 0;
766     OPENPTS_PCR_EVENT_WRAPPER *ew_new = NULL;
767
768     DEBUG_CAL("getIml - start\n");
769
770     /* check */
771     if (ctx == NULL) {
772         LOG(LOG_ERR, "null input");
773         return PTS_FATAL;
774     }
775
776     /* clean up TPM */
777     resetTpm(&ctx->tpm, 0);  // reset TPM DRTM=off
778
779     /* check SS table */
780     if (ctx->ss_table == NULL) {
781         LOG(LOG_ERR, "null input");
782         return PTS_FATAL;
783     }
784
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);
789         goto close;
790     }
791
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);
795         goto close;
796     }
797
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);
802         goto close;
803     }
804
805
806     /* Get Log */
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);
810         goto close;
811     }
812
813     DEBUG("IML(via TSS)                : %d events\n", ulEventNumber);
814
815     ctx->ss_table->event_num = ulEventNumber;
816
817     /* map to the snapshot  */
818     if (option == 0) {  // simple, snapshot[i] hold all events on PCR[i]
819         TSS_PCR_EVENT *tpe_tss;
820         TSS_PCR_EVENT *tpe;
821         // int index;
822
823         for (i = 0; i < (int) ulEventNumber; i++) {
824             tpe_tss = &pcrEvents[i];
825
826             /* copy event to local */
827             tpe = (TSS_PCR_EVENT *) xmalloc(sizeof(TSS_PCR_EVENT));
828             if (tpe == NULL) {
829                 return -1;  // TODO(munetoh)
830             }
831             memcpy(tpe, tpe_tss, sizeof(TSS_PCR_EVENT));
832             // index = tpe->ulPcrIndex;
833
834             /* copy digest */
835             tpe->rgbPcrValue = (BYTE *) xmalloc(tpe->ulPcrValueLength);
836             if (tpe->rgbPcrValue == NULL) {
837                 return -1;  // TODO(munetoh)
838             }
839             memcpy(tpe->rgbPcrValue,
840                    tpe_tss->rgbPcrValue,
841                    tpe->ulPcrValueLength);
842
843             if (tpe->ulEventLength > 0) {
844                 /* copy eventdata */
845                 tpe->rgbEvent = (BYTE *) xmalloc(tpe->ulEventLength);
846                 if (tpe->rgbEvent == NULL) {
847                     return -1;  // TODO(munetoh)
848                 }
849                 memcpy(tpe->rgbEvent,
850                        tpe_tss->rgbEvent,
851                        tpe->ulEventLength);
852             } else {
853                 tpe->rgbEvent = NULL;
854             }
855
856             /* create wrapper */
857             // ew_last = ew_new;
858             ew_new = (OPENPTS_PCR_EVENT_WRAPPER *)
859                 xmalloc(sizeof(OPENPTS_PCR_EVENT_WRAPPER));
860             if (ew_new == NULL) {
861                 return -1;
862             }
863             memset(ew_new, 0, sizeof(OPENPTS_PCR_EVENT_WRAPPER));
864             ew_new->event = tpe;
865
866             /* map to the snapshot (BHV-FSM) */
867             rc = addEventToSnapshotBhv(ctx, ew_new);  // iml.c
868
869             if (rc == PTS_SUCCESS) {
870                 /* OK */
871             } else if (rc == PTS_INVALID_SNAPSHOT) {  // OPENPTS_FSM_ERROR) {
872                 /* ERROR but continue the verification of rest of IML */
873                 error++;
874             } else if (rc == PTS_INTERNAL_ERROR) {  // 58
875                 /* SKIP */
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
882             } else {
883                 /* Unknwon error */
884                 LOG(LOG_ERR, "getIml - addEventToSnapshotBhv rc = %d\n", rc);
885             }
886
887             /* TPM Extend */
888             rc = extendTpm(&ctx->tpm, ew_new->event);
889             if (rc < 0) {
890                 LOG(LOG_ERR, "getIml - extendTpm fail\n");
891                 goto free;
892             }
893         }
894     } else if (option == 1) {
895         //  stacked snapshot with FSM
896     } else {
897         // NA
898     }
899
900     /* done */
901     rc = (int) ulEventNumber;
902
903   free:
904
905     // Keep IML data? we have to free by ourselves
906     result = Tspi_Context_FreeMemory(hContext, (BYTE *) pcrEvents);
907     Tspi_Context_FreeMemory(hContext, NULL);
908
909     /* Close TSS/TPM */
910   close:
911     Tspi_Context_Close(hContext);
912
913     if (error > 0) {
914         char buf[BUF_SIZE];
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;
918     }
919
920
921     DEBUG_CAL("getIml - end\n");
922
923     return rc;
924 }
925 #endif  // CONFIG_NO_TSS
926
927 /**
928  * fread + endian conv
929  * Return
930  *   0xFFFFFFFF Error
931  */
932 UINT32 freadUint32(FILE * stream, int endian) {
933     size_t size;
934     UINT32 data;
935     UINT32 in;
936     UINT32 out;
937
938     /* check */
939     if (stream == NULL) {
940         LOG(LOG_ERR, "null input");
941         return 0xFFFFFFFF;
942     }
943
944     /* read */
945     size = fread(&data, 1, 4, stream);
946
947     if (size != 4) {
948         // This is EOF LOG(LOG_ERR, "\n");
949         return 0xFFFFFFFF;  // TODO
950     }
951
952     if (endian == 0) {
953         return data;
954     } else {
955         in = data;
956         out = in & 0xff;
957         in = in >> 8;
958         out = out << 8;
959         out += in & 0xff;
960         in = in >> 8;
961         out = out << 8;
962         out += in & 0xff;
963         in = in >> 8;
964         out = out << 8;
965         out += in & 0xff;
966         // DEBUG(" %08x -> %08x\n", data ,out);
967         return out;
968     }
969 }
970
971
972 /**
973  * \brief  read BIOS IML file
974  *
975  * PCR0-7   - BIOS  => Level 0
976  * PCR4,5,8 - GRUB  => Level 1
977  * 
978  * SHA1 only
979  *
980  * \param filename -- TODO unicode? or url?
981  * \param mode 
982  *        0:use BHV-FSM, 
983  *        1:use BIN-FSM
984  *        2:use BHV-FSM + Endian Conv (for PPC Test on X86 ) + 4-byte aligned
985  *
986  * event num => ctx->ss_table->event_num
987  *
988  * return
989  *   PTS_SUCCESS
990  *   PTS_INVALID_SNAPSHOT
991  *   PTS_INTERNAL_ERROR
992  *
993  */
994 // TODO rename readBiosImlFile()
995 int readBiosImlFile(OPENPTS_CONTEXT * ctx, const char *filename, int mode) {
996     int rc = PTS_SUCCESS;
997     int result;
998     int i = 0;
999     size_t size;
1000     FILE *fp = NULL;
1001     UINT32 pcrIndex;
1002     UINT32 eventType;
1003     UINT32 eventLength;
1004     int endian = 0;
1005     int aligned = 0;
1006
1007     TSS_PCR_EVENT *event = NULL;
1008     OPENPTS_PCR_EVENT_WRAPPER *ew_new = NULL;
1009     // OPENPTS_PCR_EVENT_WRAPPER *ew_last = NULL;
1010     int error = 0;
1011
1012     DEBUG_CAL("getBiosImlFile - start\n");
1013     // DEBUG("read BIOS IML, file %s\n", filename);
1014
1015     /* check */
1016     if (ctx == NULL) {
1017         LOG(LOG_ERR, "null input");
1018         return PTS_FATAL;
1019     }
1020     if (filename == NULL) {
1021         LOG(LOG_ERR, "null input");
1022         return PTS_FATAL;
1023     }
1024
1025     /* open file */
1026     if ((fp = fopen(filename, "rb")) == NULL) {
1027         LOG(LOG_ERR, "%s missing", filename);
1028         return PTS_INTERNAL_ERROR;
1029     }
1030
1031     // TODO
1032     if (mode == USE_BHV_FSM_EC) {
1033         DEBUG("endian=1, aligned=4\n");
1034         mode = USE_BHV_FSM;
1035         endian = 1;  // TODO conf->iml_endian?
1036         aligned = 4;  // TODO conf->iml_aligned?
1037     }
1038
1039     /* Read IML, add to Snapshot */
1040     while (1) {
1041         /* PCR index */
1042         pcrIndex = freadUint32(fp, endian);
1043         if (pcrIndex == 0xFFFFFFFF) {
1044             /* end of data */
1045             break;
1046         }
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;
1051             goto close;
1052         }
1053
1054         /* Event type */
1055         eventType = freadUint32(fp, endian);
1056
1057         event = (TSS_PCR_EVENT *) xmalloc(sizeof(TSS_PCR_EVENT));
1058         if (event == NULL) {
1059             LOG(LOG_ERR, "no memory");
1060             rc = PTS_FATAL;
1061             goto close;
1062         }
1063         memset(event, 0, sizeof(TSS_PCR_EVENT));
1064
1065         // event->versionInfo = 0;  // TODO(munetoh)
1066         event->ulPcrIndex = pcrIndex;
1067         event->eventType = eventType;
1068
1069         /* Digest */
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");
1074             rc = PTS_FATAL;
1075             goto close;
1076         }
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;
1082             goto close;
1083         }
1084
1085         /* EventData len */
1086         eventLength = freadUint32(fp, endian);
1087         event->ulEventLength = eventLength;
1088         /* adjust read data length */
1089         if (aligned == 4) {
1090             if ((eventLength & 0x03) != 0) {
1091                 // DEBUG("FIX alignement\n");
1092                 eventLength = (eventLength & 0xFFFFFFFC) + 0x04;
1093             }
1094         }
1095         /* malloc EventData */
1096         if ((event->rgbEvent = xmalloc_assert(eventLength)) == NULL) {
1097             LOG(LOG_ERR, "no memory");
1098             rc = PTS_FATAL;
1099             goto close;
1100         }
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;
1107             goto close;
1108         }
1109
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");
1115             rc = PTS_FATAL;
1116             goto close;
1117         }
1118         memset(ew_new, 0, sizeof(OPENPTS_PCR_EVENT_WRAPPER));
1119         ew_new->event = event;
1120
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
1125
1126             if (result == PTS_SUCCESS) {
1127                 /* OK */
1128             } else if (result == PTS_INVALID_SNAPSHOT) {  // OPENPTS_FSM_ERROR) {
1129                 /* ERROR but continue the verification of rest of IML */
1130                 error++;
1131             } else if (result == PTS_INTERNAL_ERROR) {  // 58
1132                 /* SKIP */
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) {
1140                 /* SKIP */
1141             } else {
1142                 /* Unknwon error */
1143                 LOG(LOG_ERR, "getBiosImlFile - addEventToSnapshotBhv rc = %d\n", rc);
1144             }
1145         } else {  // USE_BIN_FSM
1146             /* BIN-FSM - map to the snapshot */
1147             result = addEventToSnapshotBin(ctx, ew_new);  // iml.c
1148
1149             if (result == OPENPTS_FSM_SUCCESS) {
1150                 /* OK */
1151             } else if (result == PTS_INVALID_SNAPSHOT) {
1152                 /* Keep */
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);
1158                 }
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);
1164                 }
1165             } else {
1166                 /* Unknwon error */
1167                 LOG(LOG_ERR, "getBiosImlFile - addEventToSnapshotBin rc = %d\n", rc);
1168             }
1169         }
1170
1171         /* TPM Extend */
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;
1176             goto close;
1177         }
1178
1179         /* moved to the snapshot */
1180         event = NULL;
1181         ew_new = NULL;
1182
1183         /* inc */
1184         ctx->ss_table->event_num++;
1185         i++;
1186     }  // while loop
1187
1188
1189   close:
1190     if (fclose(fp) == EOF) {
1191         LOG(LOG_ERR, "BIOS IML File %s, read fail\n", filename);
1192         rc = PTS_INTERNAL_ERROR;
1193     }
1194     DEBUG("read BIOS IML, file %s => %d events\n", filename, ctx->ss_table->event_num);
1195
1196     if (error > 0) {
1197         // WORK NEEDED: Needs i18n using NLS
1198         addReason(ctx, -1, "[IML] Failed to load IML(file:%s)", filename);
1199         rc = PTS_INVALID_SNAPSHOT;
1200     }
1201
1202     /* free (for ERROR) */
1203     if (event != NULL) {
1204         if (event->rgbPcrValue != NULL) {
1205             xfree(event->rgbPcrValue);
1206         }
1207         if (event->rgbEvent != NULL) {
1208             xfree(event->rgbEvent);
1209         }
1210         xfree(event);
1211     }
1212     if (ew_new != NULL) {
1213         xfree(ew_new);
1214     }
1215
1216     DEBUG_CAL("iml.c - getBiosImlFile - done\n");
1217
1218     return rc;
1219 }
1220
1221
1222
1223 #define TEMPLATE_TYPE_SIZE 16
1224
1225 /**
1226  * \brief  read Runtime(Linux-IMA) IML file
1227  *
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)
1233  *
1234  * Snapshot - PCR10, Level 1
1235  *
1236  * \param filename -- TODO unicode? or url?
1237  * \param mode 0:use BHV-FSM, 1:use BIN-FSM
1238  *
1239 <PRE>
1240 BINARY_IML_TYPE_IMA_ORIGINAL( Kernel 2.6.18 - Kernel 2.6.29)
1241
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
1247
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
1253
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
1258
1259
1260 BINARY_IML_TYPE_IMA_31 
1261   Fedora12(Kernel 2.6.31, 2.6.32)
1262
1263 0a 00 00 00                                                 | pcr index
1264 00 00 00 00                                                 | type?
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
1269
1270 0a 00 00 00                                                 | pcr index
1271 00 00 00 00                                                 | type?
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
1276
1277 BINARY_IML_TYPE_IMA 
1278   Fedora12 2.6.32.12-115.fc12.x86_64 2010-06-30
1279
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
1283 69 6d 61                                                     | ima
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
1287
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
1291 69 6d 61                                                     | ima
1292 4c 65 02 10 71 e8 e6 21 40 65 1b 3f 1b 62 ac ed 31 93 5d da  | SHA1(/init)
1293 05 00 00 00                                                  | len=5
1294 2f 69 6e 69 74                                               | /init
1295
1296
1297 BINARY_IML_TYPE_IMA new
1298
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
1304 0e 00 00 00                                                 | len
1305 62 6f 6f 74 5f 61 67 67 72 65 67 61 74 65                   | boot_aggregate
1306
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
1314
1315 IMA              TSS_PCR_EVENT
1316 pcrindex      => ulPcrIndex
1317 digest        => rgbPcrValue
1318 template type => eventType = BINARY_IML_TYPE_IMA
1319
1320
1321 BINARY_IML_TYPE_IMA_NG new
1322
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)
1325 06 00 00 00                                                 |
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
1332
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 |
1335 06 00 00 00                                                 |
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
1342
1343
1344 BINARY_IML_TYPE_IMA_NGLONG new
1345
1346 0a 00 00 00 
1347 09 bb 7f 01 03 4d 43 b9 d1 4f 3a 1d fd 2a b4 2b 5f 08 01 e8  
1348 0a 00 00 00 
1349 69 6d 61 2d 6e 67 6c 6f 6e 67                               | ima-nglong
1350 48 00 00 00 
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 
1356
1357 0a 00 00 00 
1358 43 27 a6 14 2a 9e 78 10 be d8 29 2b 3a 47 f6 a3 eb a1  30 d9 
1359 0a 00 00 00 
1360 69 6d 61 2d 6e 67 6c 6f 6e 67  
1361 50 00 00 00 
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 
1367 0a 00 00 00 
1368 75 6e 6c 61 62 65 6c 65 64 00 00  |unlabeled|
1369 07 00 00 00 
1370 6b 65 72 6e  65 6c 00 00   |kernel |
1371
1372 0a 00 00 00 
1373 d2 a1 0c 44 d7 d5 5a 41 48 75 2a 7d 01 cd 8c b3 fe 14 78 06 
1374 0a 00 00 00  
1375 69 6d 61 2d 6e 67 6c 6f 6e 67  |.ima-nglo|
1376 50 00 00 00 
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
1384 00                                                          | ??
1385 07 00 00 00                                                 | len = 7
1386 6b 65 72 6e 65 6c 00                                        | kernel
1387 00                                                          | ??
1388
1389 </PRE>
1390 */
1391 int readImaImlFile(OPENPTS_CONTEXT * ctx, const char *filename, int type, int mode, int *count) {
1392     int rc = PTS_SUCCESS;
1393     int result;
1394     int i = 0;
1395     size_t size;
1396     FILE *fp = NULL;
1397     UINT32 pcr_index;
1398     UINT32 event_type;
1399     UINT32 template_len;
1400     UINT32 template_type_len;
1401     UINT32 filename_len;
1402     char buf[TEMPLATE_TYPE_SIZE];
1403     int event_num = 0;
1404
1405     TSS_PCR_EVENT *event = NULL;
1406     OPENPTS_PCR_EVENT_WRAPPER *ew = NULL;
1407     OPENPTS_PCR_EVENT_WRAPPER *ew_last = NULL;
1408
1409     DEBUG_CAL("readImaImlFile - start\n");
1410
1411     /* check */
1412     if (ctx == NULL) {
1413         LOG(LOG_ERR, "null input");
1414         return PTS_FATAL;
1415     }
1416     if (filename == NULL) {
1417         LOG(LOG_ERR, "null input");
1418         return PTS_FATAL;
1419     }
1420
1421     /* open file */
1422     if ((fp = fopen(filename, "rb")) == NULL) {
1423         LOG(LOG_ERR, "readImaImlFile - file open was failed, [%s]\n", filename);
1424         return -1;
1425     }
1426
1427     /* 
1428      * PCR10 snapshot
1429      *   level 0 <= nothing,  num=0
1430      *   level 1 <= IMA
1431      */
1432
1433     /* pass one - check the IML size */
1434     while (1) {
1435         /* read PCR index */
1436         size = fread(&pcr_index, 1, 4, fp);
1437         if (size != 4) {
1438             /* end of event? => exit */
1439             break;
1440         }
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;
1445             goto close;
1446         }
1447
1448         /* alloc event structure */
1449         event = (TSS_PCR_EVENT *) xmalloc(sizeof(TSS_PCR_EVENT));
1450         if (event == NULL) {
1451             LOG(LOG_ERR, "no memory");
1452             rc = PTS_FATAL;
1453             goto close;
1454         }
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)
1461
1462         /* many formats :-( */
1463         if (type == BINARY_IML_TYPE_IMA_ORIGINAL) {  // 2.6.29
1464             /* read type */
1465             size = fread(&event->eventType, 1, 4, fp);
1466             if (size != 4) {
1467                 LOG(LOG_ERR, "Linux-IMA(ORIGINAL) IML File %s, bad eventType at %d event\n",
1468                     filename, i);
1469                 rc = PTS_INTERNAL_ERROR;
1470                 goto close;
1471             }
1472
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");
1478                 rc = PTS_FATAL;
1479                 goto close;
1480             }
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",
1484                     filename, size, i);
1485                 rc = PTS_INTERNAL_ERROR;
1486                 goto close;
1487             }
1488
1489             /* read eventdata length */
1490             size = fread(&event->ulEventLength, 1, 4, fp);
1491             if (size != 4) {
1492                 LOG(LOG_ERR, "Linux-IMA(ORIGINAL) IML File %s, bad event length size %d at %d event\n",
1493                     filename, size, i);
1494                 rc = PTS_INTERNAL_ERROR;
1495                 goto close;
1496             }
1497             /* alloc eventdata */
1498             if ((event->rgbEvent = xmalloc(event->ulEventLength)) == NULL) {
1499                 LOG(LOG_ERR, "no memory");
1500                 rc = PTS_FATAL;
1501                 goto close;
1502             }
1503             // memset(event->rgbEvent,0,event->ulEventLength);
1504
1505             /* read filename */
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",
1509                     filename, size, i);
1510                 rc = PTS_INTERNAL_ERROR;
1511                 goto close;
1512             }
1513         } else if (type == BINARY_IML_TYPE_IMA_31) {  // 2.6.30-32
1514             // DEBUG("getImaImlFile - BINARY_IML_TYPE_IMA_31\n");
1515             /* read type */
1516             size = fread(&event_type, 1, 4, fp);
1517             if (size != 4) {
1518                 LOG(LOG_ERR, "Linux-IMA(IMA_31) IML File %s, bad eventType at %d event\n",
1519                     filename, i);
1520                 rc = PTS_INTERNAL_ERROR;
1521                 goto close;
1522             }
1523
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");
1529                 rc = PTS_FATAL;
1530                 goto close;
1531             }
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",
1535                     filename, size, i);
1536                 rc = PTS_INTERNAL_ERROR;
1537                 goto close;
1538             }
1539
1540             /* read Template length */
1541             size = fread(&template_len, 1, 4, fp);
1542             if (size != 4) {
1543                 LOG(LOG_ERR, "Linux-IMA(IMA_31) IML File %s, bad template size %d at %d event\n",
1544                     filename, size, i);
1545                 rc = PTS_INTERNAL_ERROR;
1546                 goto close;
1547             }
1548             filename_len = template_len - 20;
1549
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");
1555                 rc = PTS_FATAL;
1556                 goto close;
1557             }
1558             memset(event->rgbEvent, 0, event->ulEventLength);
1559
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",
1564                     filename, size, i);
1565                 rc = PTS_INTERNAL_ERROR;
1566                 goto close;
1567             }
1568
1569             // DEBUG("getImaImlFile - filename_len %d\n", filename_len);
1570
1571             /* read filename */
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;
1577                 goto close;
1578             }
1579         } else {
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");
1585                 rc = PTS_FATAL;
1586                 goto close;
1587             }
1588
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",
1592                     filename, size, i);
1593                 rc = PTS_INTERNAL_ERROR;
1594                 goto close;
1595             }
1596
1597             /* read Template type length */
1598             size = fread(&template_type_len, 1, 4, fp);
1599             if (size != 4) {
1600                 LOG(LOG_ERR, "Linux-IMA() IML File %s, bad template size %d at %d event\n",
1601                     filename, size, i);
1602                 rc = PTS_INTERNAL_ERROR;
1603                 goto close;
1604             }
1605
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;
1609                 goto close;
1610             }
1611             // DEBUG("getImaImlFile - template_type_len %d\n",template_type_len);
1612
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;
1618                 goto close;
1619             }
1620             // TODO accessing beyond memory
1621             buf[template_type_len] = 0;
1622
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
1627
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");
1633                     rc = PTS_FATAL;
1634                     goto close;
1635                 }
1636                 memset(event->rgbEvent, 0, event->ulEventLength);
1637
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;
1643                     goto close;
1644                 }
1645
1646                 /* read filename len */
1647                 size = fread(&filename_len, 1, 4, fp);
1648                 if (size != 4) {
1649                     LOG(LOG_ERR, "missing\n");
1650                     rc = PTS_INTERNAL_ERROR;
1651                     goto close;
1652                 }
1653
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;
1657                     goto close;
1658                 }
1659
1660                 DEBUG_CAL("readImaImlFile - filename_len %d\n", filename_len);
1661
1662                 /* read filename */
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;
1667                     goto close;
1668                 }
1669
1670             } else {
1671                 LOG(LOG_ERR, "Unknown template [%s]\n", buf);
1672                 rc = PTS_INTERNAL_ERROR;
1673                 goto close;
1674             }
1675         }
1676
1677         /* create wrapper */
1678         // ew_last = ew_new;  // TODO
1679         ew = (OPENPTS_PCR_EVENT_WRAPPER *)
1680             xmalloc(sizeof(OPENPTS_PCR_EVENT_WRAPPER));
1681         if (ew == NULL) {
1682             LOG(LOG_ERR, "no memory");
1683             rc = PTS_FATAL;
1684             goto close;
1685         }
1686         memset(ew, 0, sizeof(OPENPTS_PCR_EVENT_WRAPPER));
1687         ew->event = event;
1688
1689         if (event_num == 0) {
1690             ew_last = ew;
1691         } else {
1692             ew->index = event_num;
1693             ew_last->next_all = ew;
1694             ew_last = ew;
1695         }
1696
1697         /* to snapshot */
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;
1704                 goto close;
1705             }
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;
1712                 goto close;
1713             }
1714         }
1715
1716         DEBUG_CAL("readImaImlFile - TPM_extend\n");
1717
1718         /* TPM Extend */
1719         result = extendTpm(&ctx->tpm, ew_last->event);
1720         if (result !=0) {
1721             LOG(LOG_ERR, "extend TPM fail\n");
1722             rc = PTS_INTERNAL_ERROR;
1723             goto close;
1724         }
1725
1726         /* moved to the snapshot */
1727         event = NULL;
1728         ew    = NULL;
1729
1730         event_num++;
1731         i++;
1732     }  // while
1733
1734     ctx->ss_table->event_num += event_num;
1735
1736   close:
1737     fclose(fp);
1738
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);
1743
1744     *count = event_num;
1745     /* free (for error) */
1746     if (event != NULL) {
1747         if (event->rgbPcrValue != NULL) {
1748             xfree(event->rgbPcrValue);
1749         }
1750         if (event->rgbEvent != NULL) {
1751             xfree(event->rgbEvent);
1752         }
1753         xfree(event);
1754     }
1755     if (ew  != NULL) {
1756         xfree(ew);
1757     }
1758
1759     return rc;
1760 }
1761
1762 /**
1763  * set OPENPTS_PCRS to SNAPSHOT
1764  *
1765  *
1766  * called from ifm.c
1767  *
1768  */
1769 int setPcrsToSnapshot(OPENPTS_CONTEXT *ctx, OPENPTS_PCRS *pcrs) {
1770     BYTE *pcr;
1771     int i;
1772
1773     DEBUG_CAL("setPcrsToSnapshot\n");
1774
1775     /* check */
1776     if (ctx == NULL) {
1777         LOG(LOG_ERR, "null input");
1778         return PTS_FATAL;
1779     }
1780     if (pcrs == NULL) {
1781         LOG(LOG_ERR, "null input");
1782         return PTS_FATAL;
1783     }
1784
1785     /* snapshots */
1786     for (i = 0; i < pcrs->pcr_num; i++) {
1787         int j;
1788         OPENPTS_SNAPSHOT *ss0;
1789         OPENPTS_SNAPSHOT *ss1;
1790
1791         pcr = pcrs->pcr[i];
1792
1793         // TODO ss0->tpm_pcr is wrong
1794         ss0 = getSnapshotFromTable(ctx->ss_table, i, 0);
1795         ss1 = getSnapshotFromTable(ctx->ss_table, i, 1);
1796
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];
1803             }
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];
1809             }
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];
1815             }
1816         }
1817     }
1818
1819     return 0;
1820 }
1821
1822
1823 #ifdef CONFIG_NO_TSS
1824 int getPcr(OPENPTS_CONTEXT * ctx) {
1825     /* dummy */
1826     return 0;
1827 }
1828 #else  // CONFIG_NO_TSS
1829 /**
1830  * get PCR value from TSS
1831  * 
1832  * PCR values are also taken at quoteTss time.
1833  */
1834 int getPcr(OPENPTS_CONTEXT * ctx) {
1835     TSS_RESULT result;
1836     TSS_HCONTEXT hContext;
1837     TSS_HTPM hTPM;
1838     BYTE *blob;
1839     UINT32 blobLength;
1840     UINT32 subCap;
1841
1842     // DEBUG("getPcr is deprecated\n");
1843
1844     int i;
1845     int pcrNum = 0;
1846
1847     /* check */
1848     if (ctx == NULL) {
1849         LOG(LOG_ERR, "null input");
1850         return PTS_FATAL;
1851     }
1852
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);
1857         goto close;
1858     }
1859
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);
1863         goto close;
1864     }
1865
1866
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);
1871         goto close;
1872     }
1873
1874     /* get PCR num */
1875     subCap = TSS_TPMCAP_PROP_PCR;
1876     result = Tspi_TPM_GetCapability(
1877                 hTPM,
1878                 TSS_TPMCAP_PROPERTY,
1879                 sizeof(UINT32),
1880                 (BYTE *) & subCap,
1881                 &blobLength,
1882                 &blob);
1883     if (result != TSS_SUCCESS) {
1884         LOG(LOG_ERR, "ERROR: Tspi_TPM_GetCapability failed rc=0x%x\n", result);
1885         goto free;
1886     }
1887
1888     // pcrNum = (UINT32) * blob;  // TODO(munetoh) Endian
1889     pcrNum = * (UINT32 *) blob;
1890
1891     /* Read PCRs */
1892     for (i = 0; i < pcrNum; i++) {
1893         result = Tspi_TPM_PcrRead(hTPM, i, &blobLength, &blob);
1894
1895         if (result != TSS_SUCCESS) {
1896             LOG(LOG_ERR, "ERROR: Tspi_TPM_PcrRead failed rc=0x%x\n", result);
1897             pcrNum = 0;
1898             goto free;
1899         }
1900
1901         if (blobLength != SHA1_DIGEST_SIZE) {
1902             Tspi_Context_FreeMemory(hContext, blob);
1903             pcrNum = 0;
1904             goto free;
1905         }
1906
1907         {
1908             int j;
1909             OPENPTS_SNAPSHOT *ss0;
1910             OPENPTS_SNAPSHOT *ss1;
1911
1912             // TODO ss0->tpm_pcr is wrong
1913             ss0 = getSnapshotFromTable(ctx->ss_table, i, 0);
1914             ss1 = getSnapshotFromTable(ctx->ss_table, i, 1);
1915
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];
1922                 }
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];
1928                 }
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];
1934                 }
1935             }
1936         }
1937         Tspi_Context_FreeMemory(hContext, blob);
1938     }  // for
1939
1940   free:
1941     Tspi_Context_FreeMemory(hContext, NULL);
1942
1943     /* Close TSS/TPM */
1944   close:
1945     Tspi_Context_Close(hContext);
1946
1947     return pcrNum;
1948 }
1949 #endif  // CONFIG_NO_TSS
1950
1951 /**
1952  * HEX string to BYTE[0]
1953  */
1954 BYTE hex2byte(char *buf, int offset) {
1955     UINT32 tmp;
1956     char *e;
1957
1958     /* check */
1959     if (buf == NULL) {
1960         LOG(LOG_ERR, "null input");
1961         return 0;
1962     }
1963
1964     tmp = strtol(&buf[offset], &e, 16);
1965
1966     return (BYTE) (0xFF & tmp);
1967 }
1968
1969 /**
1970  * read PCRS
1971  *
1972  * PCR-00: 8F BF F3 EC EA 9C 54 C8 D1 C4 2C FE A9 3D 6B F0 1B F3 40 5B
1973  *
1974  * Return 
1975  *    number of PCR
1976  *   -1 Error
1977  */
1978 int getPcrBySysfsFile(OPENPTS_CONTEXT * ctx, const char *filename) {
1979     FILE *fp;
1980     char buf[256];  // TODO(munetoh)
1981     char *ptr;
1982     int count = 0;
1983     int j;
1984     OPENPTS_SNAPSHOT *ss0;
1985     OPENPTS_SNAPSHOT *ss1;
1986
1987     /* check */
1988     if (ctx == NULL) {
1989         LOG(LOG_ERR, "null input");
1990         return PTS_FATAL;
1991     }
1992     if (filename == NULL) {
1993         LOG(LOG_ERR, "null input");
1994         return PTS_FATAL;
1995     }
1996
1997     /* open */
1998     if ((fp = fopen(filename, "r")) == NULL) {
1999         LOG(LOG_TODO, "getPcrBySysfsFile - pcr file is %s missing  -- ignore in test\n", filename);
2000         return -1;  // TODO
2001     }
2002
2003     while (1) {
2004         /*read line */
2005         ptr = fgets(buf, 256, fp);
2006         if (ptr == NULL) {
2007             break;
2008         }
2009
2010         // TODO ss0->tpm_pcr is wrong
2011         ss0 = getSnapshotFromTable(ctx->ss_table, count, 0);
2012         ss1 = getSnapshotFromTable(ctx->ss_table, count, 1);
2013
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);
2020             }
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);
2026             }
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);
2032             }
2033         }
2034
2035         count++;
2036     }
2037
2038     fclose(fp);
2039     ctx->pcr_num = count;
2040
2041     return count;
2042 }
2043
2044 /**
2045  *
2046  * cat /sys/class/misc/tpm0/device/pcrs
2047  */
2048 int validatePcr(OPENPTS_CONTEXT * ctx) {
2049     int rc = 0;
2050     int i, j;
2051     OPENPTS_TPM_CONTEXT *tpm;
2052     OPENPTS_SNAPSHOT *ss;
2053
2054     /* check */
2055     if (ctx == NULL) {
2056         LOG(LOG_ERR, "null input");
2057         return PTS_FATAL;
2058     }
2059
2060     tpm = &ctx->tpm;
2061
2062     DEBUG("validatePcr - start, Iml->PCR vs TPM\n");
2063
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);
2067         if (ss != NULL) {
2068             for (j = 0; j < SHA1_DIGEST_SIZE; j++) {
2069                 if (tpm->pcr[i][j] != ss->tpm_pcr[j]) {
2070                     rc++;
2071                 }
2072             }
2073         }
2074     }
2075
2076     DEBUG("validatePcr - done, rc=%d\n", rc);
2077
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);
2082             if (ss != NULL) {
2083                 for (j = 0; j < SHA1_DIGEST_SIZE; j++) {
2084                     OUTPUT("%02x-%02x ", tpm->pcr[i][j], ss->tpm_pcr[j]);
2085                 }
2086             } else {
2087                 for (j = 0; j < SHA1_DIGEST_SIZE; j++) {
2088                     OUTPUT("%02x-   ", tpm->pcr[i][j]);
2089                 }
2090             }
2091             OUTPUT("\n");
2092         }
2093     }
2094
2095     return rc;
2096 }
2097
2098 /**
2099  * print OPENPTS_PCR_EVENT_WRAPPER
2100  *
2101  */
2102 void printEventWrapper(OPENPTS_PCR_EVENT_WRAPPER *eventWrapper) {
2103     int j;
2104     TSS_PCR_EVENT *event;
2105
2106     /* check */
2107     if (eventWrapper == NULL) {
2108         LOG(LOG_ERR, "null input");
2109         return;
2110     }
2111
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]);
2118         }
2119         OUTPUT("eventdata[%4d]\n", event->ulEventLength);
2120     } else {
2121         LOG(LOG_ERR, "NULL event\n");  // TODO(munetoh)
2122     }
2123 }
2124
2125
2126 /**
2127  *  print event number of each snapshot
2128  */ 
2129 void printSnapshotsInfo(OPENPTS_CONTEXT * ctx) {
2130     int i;
2131     OPENPTS_SNAPSHOT *ss;
2132     int level0_num = 0;
2133     int level1_num = 0;
2134
2135     /* check */
2136     if (ctx == NULL) {
2137         LOG(LOG_ERR, "null input");
2138         return;
2139     }
2140
2141     OUTPUT(NLS(MS_OPENPTS, OPENPTS_IML_SNAPSHOT_HEADER,
2142            "Number of event\n"
2143            "PCR Level0 Level1\n"));
2144     OUTPUT("--------------------------\n");
2145
2146     for (i = 0; i < MAX_PCRNUM; i++) {
2147         /* level 0 */
2148         ss = getSnapshotFromTable(ctx->ss_table, i, 0);
2149         if (ss != NULL) {
2150             OUTPUT("%2d ", i);
2151             OUTPUT("%6d", ss->event_num);
2152             level0_num += ss->event_num;
2153         } else {
2154             OUTPUT("        ");
2155         }
2156
2157         /* level 1 */
2158         ss = getSnapshotFromTable(ctx->ss_table, i, 1);
2159         if (ss != NULL) {
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);
2163         } else {
2164             OUTPUT("\n");
2165         }
2166     }
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");
2172 }
2173