2 * This file is part of the OpenPTS project.
4 * The Initial Developer of the Original Code is International
5 * Business Machines Corporation. Portions created by IBM
6 * Corporation are Copyright (C) 2011 International Business
7 * Machines Corporation. All Rights Reserved.
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the Common Public License as published by
11 * IBM Corporation; either version 1 of the License, or (at your option)
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * Common Public License for more details.
19 * You should have received a copy of the Common Public License
20 * along with this program; if not, a copy can be viewed at
21 * http://www.opensource.org/licenses/cpl1.0.php.
26 * \brief FSM action for Auto RM Update (ARU)
27 * @author Seiji Munetoh <munetoh@users.sourceforge.jp>
29 * cleanup 2011-01-22 SM
32 * ARU information is stored in conf instead of ctx since this is part of
33 * the platform information. The ctx hold volatile information for an
35 * Thus, we have to maintain the ARU info in the conf. e.g reset ARU info
36 * before used within other ctx.
39 * IML -> FSM -> ARU info -> update operation -> IML
41 * So. The test is not easy.
54 #include <search.h> // hash table
56 #include <sys/types.h>
57 #include <sys/socket.h>
59 #include <netinet/in.h>
63 #include <sys/wait.h> // Linux waitpid
65 #include <openssl/sha.h>
72 OPENPTS_UPDATE_CONTEXT *newUpdateCtx() {
73 OPENPTS_UPDATE_CONTEXT *ctx;
76 ctx = xmalloc(sizeof(OPENPTS_UPDATE_CONTEXT));
78 LOG(LOG_ERR, "no memory");
81 memset(ctx, 0, sizeof(OPENPTS_UPDATE_CONTEXT));
83 for (i = 0; i < MAX_PCRNUM; i++) {
84 for (j = 0; j < MAX_SSLEVEL; j++) {
85 ctx->snapshot[i][j] = NULL;
95 OPENPTS_UPDATE_SNAPSHOT *newUpdateSnapshot() {
96 OPENPTS_UPDATE_SNAPSHOT *uss;
98 uss = xmalloc(sizeof(OPENPTS_UPDATE_SNAPSHOT));
100 LOG(LOG_ERR, "no memory");
103 memset(uss, 0, sizeof(OPENPTS_UPDATE_SNAPSHOT));
111 void freeUpdateSnapshot(OPENPTS_UPDATE_SNAPSHOT *uss) {
118 void freeUpdateCtx(OPENPTS_UPDATE_CONTEXT* ctx) {
123 /* subset of action.c */
127 * reset FSM in snapshot for FSM update
131 int resetFsm(OPENPTS_SNAPSHOT *ss) {
134 LOG(LOG_ERR, "null input");
138 /* free event wrapper chain */
139 if (ss->start != NULL) {
140 freeEventWrapperChain(ss->start);
144 if (ss->fsm_behavior != NULL) {
145 /* just reset the FSM to initial state */
146 OPENPTS_FSM_CONTEXT *fsm_behaviour = ss->fsm_behavior;
147 OPENPTS_FSM_Transition *fsm_trans = fsm_behaviour->fsm_trans;
149 /* just reset the FSM to initial state */
150 fsm_behaviour->curr_state = NULL;
151 fsm_behaviour->status = 0;
153 while (fsm_trans != NULL) {
154 fsm_trans->event_num = 0;
155 fsm_trans = fsm_trans->next;
159 if (ss->fsm_binary != NULL) {
161 freeFsmContext(ss->fsm_binary);
162 ss->fsm_binary = NULL;
166 // TODO set to SS[n-1]
167 memset(ss->curr_pcr, 0, SHA1_DIGEST_SIZE);
168 memset(ss->tpm_pcr, 0, SHA1_DIGEST_SIZE);
177 * doAction - startUpdate
179 * allocate OPENPTS_UPDATE_SNAPSHOT
181 int startUpdate(OPENPTS_CONTEXT *ctx, OPENPTS_PCR_EVENT_WRAPPER *eventWrapper) {
182 TSS_PCR_EVENT *event;
183 OPENPTS_UPDATE_CONTEXT *update;
184 OPENPTS_UPDATE_SNAPSHOT *uss;
185 OPENPTS_CONFIG *conf;
186 OPENPTS_EVENT_UPDATE_START *start;
187 int target_pcr_index;
188 int target_snapshot_level;
193 DEBUG("startUpdate() - start\n");
197 LOG(LOG_ERR, "null input\n");
202 LOG(LOG_ERR, "null input\n");
206 if (conf->enable_aru == 0) {
211 conf->target_newrm_exist = 0;
214 if (eventWrapper == NULL) {
215 LOG(LOG_ERR, "null input");
218 event = eventWrapper->event;
220 LOG(LOG_ERR, "null input");
224 if (event->ulEventLength <= 20) { // TODO sizeof
225 LOG(LOG_ERR, "startUpdate() - bad eventdata\n");
228 if (event->rgbEvent == NULL) {
229 LOG(LOG_ERR, "null input");
232 if (conf->update == NULL) {
233 LOG(LOG_ERR, "null input");
237 update = (OPENPTS_UPDATE_CONTEXT *) conf->update;
238 start = (OPENPTS_EVENT_UPDATE_START *) event->rgbEvent;
240 // DEBUG("StartUpdate\n");
241 // printHex("UpdateEvent ", (BYTE*) start, sizeof(OPENPTS_EVENT_UPDATE_START), "\n");
243 // Convert the Endian
244 if (ctx->conf->iml_endian != 0) {
245 target_pcr_index = b2l(start->target_pcr_index);
246 target_snapshot_level = b2l(start->target_snapshot_level);
247 event_num = b2l(start->event_num);
248 update_type = b2l(start->update_type);
249 data_length = b2l(start->data_length);
251 target_pcr_index = start->target_pcr_index;
252 target_snapshot_level = start->target_snapshot_level;
253 event_num = start->event_num;
254 update_type = start->update_type;
255 data_length = start->data_length;
258 DEBUG("Update pcr=%08x level=%08x count=%d endian=%d",
260 target_snapshot_level,
262 ctx->conf->iml_endian);
264 if (target_pcr_index >= MAX_PCRNUM) {
265 LOG(LOG_ERR, "startUpdate() - Bad PCR index %d 0x%08x\n",
266 target_pcr_index, target_pcr_index);
267 return PTS_INTERNAL_ERROR;
269 if (target_snapshot_level >= MAX_SSLEVEL) {
270 LOG(LOG_ERR, "startUpdate() - Bad SS Level %d 0x%08x\n",
271 target_snapshot_level, target_snapshot_level);
272 return PTS_INTERNAL_ERROR;
275 /* set current target to OPENPTS_UPDATE_CONTEXT */
276 update->target_pcr_index = target_pcr_index;
277 update->target_snapshot_level = target_snapshot_level;
280 /* setup OPENPTS_UPDATE_SNAPSHOT */
283 [target_snapshot_level] == NULL) {
284 /* 1st update of this PCR/Level */
285 // OPENPTS_UPDATE_SNAPSHOT
286 /* malloc OPENPTS_UPDATE_SNAPSHOT */
287 // uss = xmalloc(sizeof(OPENPTS_UPDATE_SNAPSHOT));
288 uss = newUpdateSnapshot();
290 return PTS_INTERNAL_ERROR;
292 // memset(uss, 0, sizeof(OPENPTS_UPDATE_SNAPSHOT));
294 /* already exist => replace */
296 // TODO reset previous OPENPTS_UPDATE_SNAPSHOT
297 DEBUG("OPENPTS_UPDATE_SNAPSHOT exist, reset this\n");
298 uss = update->snapshot
300 [target_snapshot_level];
304 uss->event_count = 0;
306 uss->ew_start_update = eventWrapper;
310 [target_snapshot_level] = uss;
312 conf->update_exist = 1;
313 DEBUG("startUpdate() - update exit\n");
319 * doAction - deputyEvent
321 int deputyEvent(OPENPTS_CONTEXT *ctx, OPENPTS_PCR_EVENT_WRAPPER *eventWrapper) {
322 TSS_PCR_EVENT *event;
323 OPENPTS_UPDATE_CONTEXT *update;
324 int rc = PTS_SUCCESS;
325 OPENPTS_CONFIG *conf;
326 OPENPTS_UPDATE_SNAPSHOT *uss;
328 DEBUG_CAL("deputyEvent() - start\n");
332 LOG(LOG_ERR, "null input\n");
337 LOG(LOG_ERR, "null input\n");
342 if (ctx->conf->enable_aru == 0) {
348 if (eventWrapper == NULL) {
349 LOG(LOG_ERR, "null input");
352 event = eventWrapper->event;
354 LOG(LOG_ERR, "null input");
357 update = conf->update;
358 if (update == NULL) {
359 LOG(LOG_ERR, "null input");
363 /* OPENPTS_UPDATE_SNAPSHOT */
364 uss = update->snapshot
365 [update->target_pcr_index]
366 [update->target_snapshot_level];
368 LOG(LOG_ERR, "null input");
372 /* copy to update[] */
373 if (uss->event_count == 0) {
374 /* link to 1st event */
375 uss->ew_deputy_first = eventWrapper;
376 uss->ew_deputy_last = eventWrapper;
379 uss->ew_deputy_last = eventWrapper;
387 * doAction - endUpdate
389 int endUpdate(OPENPTS_CONTEXT *ctx, OPENPTS_PCR_EVENT_WRAPPER *eventWrapper) {
390 TSS_PCR_EVENT *event;
391 OPENPTS_UPDATE_CONTEXT *update;
392 OPENPTS_UPDATE_SNAPSHOT *uss;
393 OPENPTS_CONFIG *conf;
394 OPENPTS_EVENT_UPDATE_START *start;
397 DEBUG("endUpdate() - start\n");
401 LOG(LOG_ERR, "null input\n");
406 LOG(LOG_ERR, "null input\n");
411 if (conf->enable_aru == 0) {
413 DEBUG("endUpdate() - done(skip), conf->enable_aru == 0\n");
417 // TODO find the last aru event set
418 /* Set flag for Update */
419 conf->update_exist = 1;
420 DEBUG("endUpdate() - update exist\n");
423 if (eventWrapper == NULL) {
424 LOG(LOG_ERR, "null input");
427 event = eventWrapper->event;
429 LOG(LOG_ERR, "null input");
432 update = conf->update;
433 if (update == NULL) {
434 LOG(LOG_ERR, "null input");
438 uss = update->snapshot
439 [update->target_pcr_index]
440 [update->target_snapshot_level];
442 LOG(LOG_ERR, "null input");
446 /* start structure */
449 LOG(LOG_ERR, "null input");
453 // Convert the Endian
454 if (ctx->conf->iml_endian != 0) {
455 event_num = b2l(start->event_num);
457 event_num = start->event_num;
460 uss->ew_end_update = eventWrapper;
462 /* check the event num */
463 if (uss->event_count != event_num) {
464 /* actual event number is different with the number in start event */
465 LOG(LOG_ERR, "number of events (%08x) are not same with definition at start (%08x), BAD eventlog?\n",
466 uss->event_count, event_num);
467 return PTS_INVALID_SNAPSHOT;
474 * doAction - updateCollector
476 int updateCollector(OPENPTS_CONTEXT *ctx, OPENPTS_PCR_EVENT_WRAPPER *eventWrapper) {
477 // int rc = PTS_SUCCESS;
478 TSS_PCR_EVENT *event;
479 OPENPTS_EVENT_COLLECTOR_UPDATE *update = NULL;
480 OPENPTS_CONFIG *conf;
482 DEBUG("updateCollector() - start\n");
486 LOG(LOG_ERR, "null input\n");
491 LOG(LOG_ERR, "null input\n");
496 if (eventWrapper == NULL) {
497 LOG(LOG_ERR, "null input");
500 event = eventWrapper->event;
502 LOG(LOG_ERR, "null input");
506 if (event->ulEventLength != sizeof(OPENPTS_EVENT_COLLECTOR_UPDATE)) {
507 LOG(LOG_ERR, "updateCollector() - Bad eventData size %d != %d\n",
508 event->ulEventLength,
509 sizeof(OPENPTS_EVENT_COLLECTOR_UPDATE));
510 return PTS_INVALID_SNAPSHOT;
514 update = (OPENPTS_EVENT_COLLECTOR_UPDATE *)event->rgbEvent;
516 /* save RM_UUID to conf */
517 if (conf->target_newrm_uuid == NULL) {
518 conf->target_newrm_uuid = xmalloc(sizeof(PTS_UUID));
519 if (NULL == conf->target_newrm_uuid) {
520 LOG(LOG_ERR, "no memory");
524 memcpy(conf->target_newrm_uuid, &update->new_manifest_uuid, sizeof(PTS_UUID));
526 /* Already processed => Clear Update FLag */
527 conf->update_exist = 0;
529 /* Notification for Verifier side */
530 conf->target_newrm_exist = 1;
533 // TODO if TCDS was restart, the eventlog used by PTSCD was gone.
535 DEBUG("updateCollector() - done, clear update_exist flag\n");
548 * SS -> W -> W -> W - Original PCR4
550 * W -> W -> W -> W -> W - Update PCR11
555 * Delete target chain
557 * SS -> - Original PCR4
559 * W -> W -> W -> W -> W - Update PCR11
564 * Move update to target location
568 * SS -> W -> W -> W - Original PCR4
570 * W ----------------> W - Update PCR11
578 int updateSnapshot(OPENPTS_CONTEXT *ctx, OPENPTS_UPDATE_SNAPSHOT *uss, int i, int j) {
579 OPENPTS_SNAPSHOT *ss;
580 OPENPTS_PCR_EVENT_WRAPPER *eventWrapper;
581 OPENPTS_EVENT_UPDATE_START *start;
584 int target_pcr_index;
585 int target_snapshot_level;
590 DEBUG_CAL("updateSnapshot() - start, pcr=%d level=%d %d events exist!!!\n", i, j, uss->event_count);
594 LOG(LOG_ERR, "null input");
598 LOG(LOG_ERR, "null input");
603 /* start structure */
605 // Convert the Endian
606 if (ctx->conf->iml_endian != 0) {
607 target_pcr_index = b2l(start->target_pcr_index);
608 target_snapshot_level = b2l(start->target_snapshot_level);
609 event_num = b2l(start->event_num);
610 update_type = b2l(start->update_type);
611 data_length = b2l(start->data_length);
613 target_pcr_index = start->target_pcr_index;
614 target_snapshot_level = start->target_snapshot_level;
615 event_num = start->event_num;
616 update_type = start->update_type;
617 data_length = start->data_length;
620 /* update target snaposhot */
621 ss = getSnapshotFromTable(ctx->ss_table, i, j);
623 LOG(LOG_ERR, "null snapshot\n");
627 // TODO remove fillowing counters
629 ctx->ss_table->update_num[ss->level]++;
632 // DEBUG("Update by FSM %s\n", ss->fsm_behavior->uml_file);
633 // verbose |= DEBUG_FSM_FLAG;
635 // Step 1. getIml() - IML --> BHV-FSM --> SS->eventWrapper chain
636 // Step 2. writeAllCoreValue() in rm.c - SS->eventWrapper chain -> BIN-FSM is generated
638 /* reset/free target snapshot */
639 // delete EW chain, delete BIN-FSM
640 resetFsm(ss); // fsm.c
643 if (update_type == UPDATE_IPL_IMAGE) {
644 /* get iml.ipl.maxcount value from eventdata */
649 pnum = (UINT32 *)start->data;
651 if (ctx->conf->iml_endian != 0) {
655 /* WORK NEEDED: I guess that bosrenew should really pass in all IPL events including the final one */
658 LOG(LOG_INFO, "UPDATE_IPL_IMAGE iml.ipl.maxcount=%d (0x%x)\n", num, num);
659 snprintf(buf, BUF_SIZE, "%d", num);
660 setProperty(ctx, "iml.ipl.maxcount", buf);
664 eventWrapper = uss->ew_deputy_first;
665 while ((eventWrapper != NULL) && (count < uss->event_count)) {
666 /*Change PCR index */
667 eventWrapper->event->ulPcrIndex = i;
668 /* set sw->ss link */
669 rc = updateFsm(ctx, ss->fsm_behavior, eventWrapper); // TODO ignore the pcr_index
670 if (rc == OPENPTS_FSM_ERROR) {
671 /* FSM detect invalid IML, or bad FSM for this IML */
672 DEBUG("[RM%02d-PCR%02d] updateFsm() => OPENPTS_FSM_ERROR ===> rc=PTS_INVALID_SNAPSHOT, added Reason\n",
673 target_snapshot_level, target_pcr_index);
674 addReason(ctx, target_pcr_index, NLS(MS_OPENPTS, OPENPTS_ARU_IML_VALIDATION_FAILED,
675 "[RM%02d-PCR%02d] IML validation by FSM has failed. State='%s' at the FSM is '%s'"),
676 target_snapshot_level,
678 ss->fsm_behavior->curr_state->name,
679 ss->fsm_behavior->uml_file);
680 ctx->ss_table->error[start->target_pcr_index] = PTS_INVALID_SNAPSHOT;
681 rc = PTS_INVALID_SNAPSHOT;
682 } else if (rc == OPENPTS_FSM_FINISH) {
683 /* OK, FSM finish successfly */
684 ss->fsm_behavior->status = OPENPTS_FSM_FINISH;
687 /* Move to next level (0->1) */
688 incActiveSnapshotLevel(ctx->ss_table, target_pcr_index);
689 } else if (rc == OPENPTS_FSM_SUCCESS) {
692 } else if (rc == OPENPTS_FSM_TRANSIT) {
693 // TRANSIT, Skip update SS chain
694 // TODO set by updateFsm
695 ss->fsm_behavior->status = OPENPTS_FSM_FINISH;
697 /* Move to next level (0->1) */
698 incActiveSnapshotLevel(ctx->ss_table, target_pcr_index);
701 } else if (rc == OPENPTS_FSM_FINISH_WO_HIT) {
702 // TRANSIT, Skip update SS chain
703 // TODO set by updateFsm
704 ss->fsm_behavior->status = OPENPTS_FSM_FINISH;
706 /* Move to next level (0->1) */
707 incActiveSnapshotLevel(ctx->ss_table, target_pcr_index);
711 LOG(LOG_ERR, "updateFsm rc=%d\n", rc);
714 /* update SS chain */
715 if (ss->event_num == 0) {
717 ss->start = eventWrapper;
718 ss->end = eventWrapper;
721 ss->end->next_pcr = eventWrapper;
722 ss->end = eventWrapper;
726 // update->event_count++;
727 rc = OPENPTS_FSM_MIGRATE_EVENT;
729 eventWrapper = eventWrapper->next_pcr;
734 // TODO cut EW <-> event link
737 /* Target end EW -> end */
738 uss->ew_deputy_last->next_all = NULL;
739 uss->ew_deputy_last->next_pcr = NULL;
741 /* Update start->end */
742 uss->ew_start_update->next_all = uss->ew_end_update;
743 uss->ew_start_update->next_pcr = uss->ew_end_update;
745 /* Snapshot (Update, PCR11) event couner */
746 ss = uss->ew_start_update->snapshot;
747 ss->event_num = ss->event_num - count;
753 * Extend Collector Update Event
756 int extendEvCollectorUpdate(OPENPTS_CONFIG *conf) {
757 TSS_PCR_EVENT* event; // /usr/include/tss/tss_structs.h
758 OPENPTS_EVENT_COLLECTOR_UPDATE *collector_update;
759 BYTE pcr[SHA1_DIGEST_SIZE];
764 LOG(LOG_ERR, "null input\n");
767 if (conf->newrm_uuid == NULL) {
768 LOG(LOG_ERR, "null input\n");
771 if (conf->newrm_uuid->uuid == NULL) {
772 LOG(LOG_ERR, "null input\n");
776 /* malloc eventlog */
777 collector_update = xmalloc_assert(sizeof(OPENPTS_EVENT_COLLECTOR_UPDATE));
778 event = xmalloc_assert(sizeof(TSS_PCR_EVENT));
780 /* fill collector_start */
781 memcpy(&collector_update->pts_version, &conf->pts_version, 4);
782 memcpy(&collector_update->collector_uuid, conf->uuid->uuid, 16);
783 memcpy(&collector_update->new_manifest_uuid, conf->newrm_uuid->uuid, 16);
786 // memcpy(&collector_start->pcr_value;
787 // readPcr(conf->openpts_pcr_index, pcr);
794 sizeof(OPENPTS_EVENT_COLLECTOR_UPDATE));
795 SHA1_Final(pcr, &sha_ctx);
798 // event->versionInfo // set by TSP?
799 event->ulPcrIndex = conf->openpts_pcr_index; // set by TSP?
800 event->eventType = EV_COLLECTOR_UPDATE; // openpts_tpm.h
801 event->ulPcrValueLength = SHA1_DIGEST_SIZE;
802 event->rgbPcrValue = pcr;
803 event->ulEventLength = sizeof(OPENPTS_EVENT_COLLECTOR_UPDATE);
804 event->rgbEvent = (BYTE *) collector_update;
810 xfree(collector_update);
820 * Update events must be a simple event chain (atmic)
823 int updateSnapshots(OPENPTS_CONTEXT *ctx) {
825 OPENPTS_CONFIG *conf;
826 OPENPTS_UPDATE_CONTEXT *update;
827 OPENPTS_UPDATE_SNAPSHOT *uss;
830 DEBUG_CAL("updateSnapshots() - start\n");
834 LOG(LOG_ERR, "null input\n");
839 LOG(LOG_ERR, "null input\n");
844 if (conf->update_exist == 0) {
845 LOG(LOG_TODO, "updateSnapshots() - done, no update\n");
849 update = (OPENPTS_UPDATE_CONTEXT *)conf->update;
850 if (update == NULL) {
851 LOG(LOG_ERR, "null input\n");
855 for (i = 0; i < MAX_PCRNUM; i++) {
856 for (j = 0; j < MAX_SSLEVEL; j++) {
857 // DEBUG("updateSnapshots() - %d %d\n", i, j);
858 uss = update->snapshot[i][j];
860 // DEBUG("updateSnapshots() - %p\n", uss);
861 // DEBUG("updateSnapshots() - %p %d %d\n", uss, uss->event_count, uss->update_count);
862 if (uss->event_count > 0) {
863 updateSnapshot(ctx, uss, i, j);
864 DEBUG("free OPENPTS_UPDATE_SNAPSHOT\n");
866 freeUpdateSnapshot(update->snapshot[i][j]);
867 update->snapshot[i][j] = NULL;
879 * Automatically update the manifest by update events in the IML
881 * subset of collector.c, called by
884 * ptscd -u -m "OS update to X.X.X"
887 * killproc ptscd -HUP
891 OPENPTS_CONFIG *conf,
893 OPENPTS_PROPERTY *prop_start,
894 OPENPTS_PROPERTY *prop_end,
897 int rc = PTS_SUCCESS;
898 OPENPTS_CONTEXT *ctx;
900 DEBUG_CAL("update() - start\n");
904 LOG(LOG_ERR, "null input\n");
909 ctx = newPtsContext(conf);
911 LOG(LOG_ERR, "no memory");
916 if (prop_count > 0) {
918 if (prop_start == NULL) {
919 LOG(LOG_ERR, "null input\n");
922 if (prop_end == NULL) {
923 LOG(LOG_ERR, "null input\n");
926 ctx->prop_start = prop_start;
927 ctx->prop_end = prop_end;
928 ctx->prop_count = prop_count;
931 addPropertiesFromConfig(conf, ctx);
933 /* UUID of this platform */
934 OUTPUT(NLS(MS_OPENPTS, OPENPTS_UPDATE_PLATFORM_UUID,
935 "Platform UUID: %s\n"), conf->uuid->str);
936 OUTPUT(NLS(MS_OPENPTS, OPENPTS_UPDATE_RM_UUID,
937 "Reference manifest UUID: %s\n"), conf->rm_uuid->str);
938 // OUTPUT("RM UUID (for next boot) : %s\n", conf->newrm_uuid->str); // NULL
941 getRmList(conf, conf->config_dir); // uuid.c
943 OUTPUT(NLS(MS_OPENPTS, OPENPTS_UPDATE_RM_LIST,
944 "List of reference manifest sets: %d reference manifest sets in config dir\n"),
945 conf->rmsets->rmset_num);
946 printRmList(conf, " ");
950 /* delete old RM sets */
951 OUTPUT(NLS(MS_OPENPTS, OPENPTS_UPDATE_PURGE_RM, "Purge the renewed manifests\n"));
952 purgeRenewedRm(conf); // uuid.c
956 rc = readFsmFromPropFile(ctx, conf->config_file);
957 if (rc != PTS_SUCCESS) {
958 LOG(LOG_ERR, "update() - read FSM failed\n");
959 rc = PTS_INTERNAL_ERROR;
963 /* read IML to fill the BIOS binary measurement, and translate BHV->BIN FSM */
966 conf->enable_aru = 1;
967 conf->update_exist = 0;
969 if (conf->update != NULL) {
970 freeUpdateCtx((OPENPTS_UPDATE_CONTEXT*)conf->update);
972 conf->update = (void *) newUpdateCtx();
974 /* OK, now ready to read IML */
976 /* load current IML using FSMs */
977 if (conf->iml_mode == 0) { // TODO use def
979 LOG(LOG_ERR, "update() - Build with --without-tss. iml.mode=tss is not supported\n");
984 /* WORK NEEDED: The above return value could be a positive number for an error or
985 a positive number for the pcr or event number. There is no way to
986 discover success or failure. I will assume success and hope log files
987 contain some useful information! */
990 } else if (conf->iml_mode == 1) {
991 // TODO change to generic name? conf->iml_filename[0] conf->iml_filename[1]
992 /* from securityfs */
994 rc = readBiosImlFile(
996 conf->bios_iml_filename,
998 if (rc != PTS_SUCCESS) {
999 DEBUG("readBiosImlFile() was failed\n");
1000 OUTPUT(NLS(MS_OPENPTS, OPENPTS_ARU_ERROR_READING_BIOS_IML,
1001 "An error occured while reading the bios iml file.\n"));
1002 printReason(ctx, 0);
1006 /* RUNTIME IML (Linux-IMA) */
1007 if (conf->runtime_iml_filename != NULL) {
1008 /* count seems to be ignored in most places so we ignore it too */
1010 rc = readImaImlFile(
1012 conf->runtime_iml_filename,
1013 conf->runtime_iml_type, 0, &count); // TODO endian?
1015 LOG(LOG_ERR, "read IMA IML, %s has failed\n", conf->runtime_iml_filename);
1016 rc = PTS_INTERNAL_ERROR;
1021 LOG(LOG_ERR, "unknown IML mode, %d\n", conf->iml_mode);
1024 /* get SMBIOS data */
1027 // TODO change to good message
1028 if (conf->update_exist > 0) {
1031 /* Update the Manifests */
1032 rc = updateSnapshots(ctx);
1033 if (rc != PTS_SUCCESS) {
1034 LOG(LOG_ERR, "update() - updateSnapshots fail\n");
1038 /* new UUID for this RM set */
1039 if (conf->newrm_uuid == NULL) {
1040 LOG(LOG_INFO, "conf->newrm_uuid == NULL, generate new reference manifest UUID\n");
1041 conf->newrm_uuid = newOpenptsUuid(); // empty
1042 conf->newrm_uuid->filename = getFullpathName(conf->config_dir, "newrm_uuid");
1043 DEBUG("conf->newrm_uuid->filename %s\n", conf->newrm_uuid->filename);
1044 conf->newrm_uuid->status = OPENPTS_UUID_FILENAME_ONLY;
1045 rc = genOpenptsUuid(conf->newrm_uuid);
1047 // conf->str_newrm_uuid = getStringOfUuid(conf->newrm_uuid);
1048 // conf->time_newrm_uuid = getDateTimeOfUuid(conf->newrm_uuid);
1049 } else if (conf->newrm_uuid->status == OPENPTS_UUID_FILENAME_ONLY) {
1051 rc = genOpenptsUuid(conf->newrm_uuid);
1053 } else if (conf->newrm_uuid->status == OPENPTS_UUID_FILLED) {
1055 rc = genOpenptsUuid(conf->newrm_uuid);
1057 } else if (conf->newrm_uuid->status == OPENPTS_UUID_CHANGED) {
1058 /* change UUID again */
1059 rc = genOpenptsUuid(conf->newrm_uuid);
1062 LOG(LOG_ERR, "update() - conf->newrm_uuid->status %d\n", conf->newrm_uuid->status);
1063 LOG(LOG_ERR, "update() - use given reference manifest UUID %s (for test)\n", conf->rm_uuid->str);
1068 OUTPUT(NLS(MS_OPENPTS, OPENPTS_UPDATE_GENERATE_UUID,
1069 "Generate UUID (for new reference manifests): %s \n"), conf->newrm_uuid->str);
1070 OUTPUT(NLS(MS_OPENPTS, OPENPTS_UPDATE_DATE, " Date and Time: %04d-%02d-%02d-%02d:%02d:%02d\n"),
1071 conf->newrm_uuid->time->year + 1900,
1072 conf->newrm_uuid->time->mon + 1,
1073 conf->newrm_uuid->time->mday,
1074 conf->newrm_uuid->time->hour,
1075 conf->newrm_uuid->time->min,
1076 conf->newrm_uuid->time->sec);
1079 rc = makeNewRmSetDir(conf);
1080 if (rc != PTS_SUCCESS) {
1081 LOG(LOG_ERR, "mkdir of RM set dir was failed\n");
1085 /* save UUID for next boot */
1086 DEBUG("writeOpenptsUuidFile %s %s\n", conf->newrm_uuid->str, conf->newrm_uuid->filename);
1087 rc = writeOpenptsUuidFile(conf->newrm_uuid, 1); // overwrite
1091 /* check the snapshot level to be updated */
1092 for (i= 0;i < conf->newrm_num; i++) {
1093 /* check each RM level */
1094 if (ctx->ss_table->update_num[i] > 0) {
1096 for (j = 0; j < MAX_PCRNUM; j++) {
1097 OPENPTS_SNAPSHOT *ss;
1098 ss = getSnapshotFromTable(
1103 if (ss->update_num > 0) {
1104 OUTPUT(NLS(MS_OPENPTS, OPENPTS_UPDATE_RM_DETAIL,
1105 "Update RM%02d-PCR%02d (%d update(s) in update events)\n"), i, j, ss->update_num);
1110 DEBUG("update() - writeRm %s\n", conf->newrm_filename[i]);
1111 rc = writeRm(ctx, conf->newrm_filename[i], i);
1113 LOG(LOG_ERR, "write RM, %s was failed\n", conf->newrm_filename[i]);
1114 rc = PTS_INTERNAL_ERROR;
1118 /*no update, just copy the RM to new RM set dir*/
1120 DEBUG("update() - dowriteRm %s\n", conf->newrm_filename[i]);
1121 rc = writeRm(ctx, conf->newrm_filename[i], i);
1123 LOG(LOG_ERR, "write RM, %s was failed\n", conf->newrm_filename[i]);
1124 rc = PTS_INTERNAL_ERROR;
1130 /* Extend Collector Update event */
1131 rc = extendEvCollectorUpdate(conf);
1132 if (rc != PTS_SUCCESS) {
1133 LOG(LOG_ERR, "updateSnapshots() - extendEvCollectorUpdate fail\n");
1136 OUTPUT(NLS(MS_OPENPTS, OPENPTS_UPDATE_SUCCESS,
1137 "Successfully updated the reference manifests\n\n"));
1139 OUTPUT(NLS(MS_OPENPTS, OPENPTS_UPDATE_NONE,
1140 "There is no update.\n\n"));
1144 if ( rc != PTS_SUCCESS ) {
1145 ERROR(NLS(MS_OPENPTS, OPENPTS_UPDATE_FAILED,
1146 "Failed to update the reference manifests\n"));
1149 if ( NULL != ctx ) {
1151 freePtsContext(ctx);
1155 conf->enable_aru = 0;
1157 DEBUG("update() - done\n");
1165 static int diffFileAgainstCache(char *fileName, int len, BYTE *contents) {
1167 struct stat statBuf;
1168 int fd = open(fileName, O_RDONLY);
1171 LOG(LOG_ERR, "Failed to open '%s', errno %d\n", fileName, errno);
1172 } else if (fstat(fd, &statBuf) == -1) {
1173 LOG(LOG_ERR, "Failed to stat '%s' (fd %d), errno %d\n", fileName, fd, errno);
1174 } else if ( len != statBuf.st_size ) {
1175 DEBUG("File length for pending RM '%s' (%d) does not match cached length (%d) from collector.\n",
1176 fileName, (int)statBuf.st_size, len);
1178 int totalBytesRead = 0;
1181 ssize_t bytesRead = read(fd, page, 4096);
1182 if ( -1 == bytesRead ) {
1183 LOG(LOG_ERR, "Failed to read from fd %d, errno %d\n", fd, errno);
1185 } else if ( bytesRead == 0) {
1186 if (totalBytesRead != len) {
1187 LOG(LOG_ERR, "Finished reading from file prematurely, still expecting data.");
1193 totalBytesRead += bytesRead;
1194 if (totalBytesRead > len) {
1195 LOG(LOG_ERR, "Read more data from RM file than expected.");
1198 DEBUG("Read %ld bytes, total = %d out of %d\n", bytesRead, totalBytesRead, len);
1200 if ( 0 != memcmp(page, contents, bytesRead) ) {
1204 contents += bytesRead;
1219 int isNewRmStillValid(OPENPTS_CONTEXT *ctx, char *conf_dir) {
1223 char *str_collector_uuid;
1225 char *str_newrm_uuid;
1227 char *str_verifier_uuid;
1231 char * collector_dir;
1233 OPENPTS_CONFIG *conf;
1235 // TODO get from list
1236 OPENPTS_CONFIG *target_conf = NULL;
1240 LOG(LOG_ERR, "null input\n");
1245 LOG(LOG_ERR, "null input\n");
1253 newRmSet = conf->newRmSet;
1254 if (newRmSet == NULL) {
1255 LOG(LOG_ERR, "null input\n");
1258 target_conf = ctx->target_conf;
1259 if (target_conf == NULL) {
1260 LOG(LOG_ERR, "null input\n");
1263 if (target_conf->uuid == NULL) {
1264 LOG(LOG_ERR, "null input\n");
1267 if (target_conf->rm_uuid == NULL) {
1268 LOG(LOG_ERR, "null input\n");
1273 str_collector_uuid = target_conf->uuid->str;
1274 str_rm_uuid = target_conf->rm_uuid->str;
1275 str_verifier_uuid = conf->uuid->str;
1276 if ((str_collector_uuid == NULL) ||
1277 (str_rm_uuid == NULL) ||
1278 (str_verifier_uuid == NULL)) {
1282 DEBUG("Verifier UUID %s\n", str_verifier_uuid);
1283 DEBUG("Collector UUID %s\n", str_collector_uuid);
1284 DEBUG("Collector RM UUID %s\n", str_rm_uuid);
1286 /* Setup the dir for the collector */
1287 collector_dir = getFullpathName(conf_dir, str_collector_uuid);
1289 DEBUG("conf_dir %s\n", conf_dir);
1290 DEBUG("collector_dir %s\n", collector_dir);
1296 PTS_UUID *newrm_uuid = (PTS_UUID *)newRmSet;
1298 newRmSet += 16; // TODO
1299 str_newrm_uuid = getStringOfUuid(newrm_uuid);
1300 DEBUG("Collector new RM UUID %s\n", str_newrm_uuid);
1304 rm_dir = getFullpathName(collector_dir, str_newrm_uuid);
1306 rc = checkDir(collector_dir);
1307 if (rc != PTS_SUCCESS) {
1308 /* unknwon collector */
1309 LOG(LOG_ERR, "isNewRmStillValid() - Unknown collector, UUID= %s dir=%s\n",
1310 str_collector_uuid, collector_dir);
1311 addReason(ctx, -1, NLS(MS_OPENPTS, OPENPTS_ARU_MISSING_COLLECTOR_CONFIG,
1312 "Missing collector configuration"));
1313 addReason(ctx, -1, NLS(MS_OPENPTS, OPENPTS_ARU_COLLECTOR_UUID,
1314 "Collector UUID = %s"), str_collector_uuid);
1318 rc = checkDir(rm_dir);
1319 if (rc != PTS_SUCCESS) {
1320 DEBUG("isNewRmStillValid() - New RM doesn't exist, UUID = %s\n", str_collector_uuid);
1324 DEBUG("conf dir : %s\n", collector_dir);
1325 DEBUG("rm dir : %s\n", rm_dir);
1326 DEBUG("New RM UUID file : %s\n", target_conf->newrm_uuid->filename);
1329 num = getUint32(newRmSet);
1330 DEBUG("RM num %d\n", num);
1333 if (num > MAX_RM_NUM) {
1334 LOG(LOG_ERR, "Bad NUM %d\n", num);
1339 for (i = 0; i < num; i++) {
1341 snprintf(buf, BUF_SIZE, "%s/%s/rm%d.xml",
1345 DEBUG("RM[%d] : %s\n", i, buf);
1347 len = getUint32(newRmSet);
1348 DEBUG("RM[%d] len %d -> %s\n", i, len, buf);
1352 rc = diffFileAgainstCache(buf, len, newRmSet);
1354 DEBUG("New RM file '%s' is now invalidated\n", buf);
1357 DEBUG("New RM file '%s' matches cached contents from collector\n", buf);
1363 rc = PTS_SUCCESS; // OK
1366 xfree(str_newrm_uuid);
1374 * get target NEW RMs before reboot :-)
1379 * ----------------------------------
1382 int updateNewRm(OPENPTS_CONTEXT *ctx, char *host, char *conf_dir) {
1386 char *rm_filename[MAX_RM_NUM];
1388 char *str_collector_uuid;
1391 OPENPTS_UUID *newrm_uuid;
1393 char *str_verifier_uuid;
1397 char * collector_dir;
1399 OPENPTS_CONFIG *conf;
1401 // TODO get from list
1402 char *target_conf_filename = NULL;
1403 OPENPTS_CONFIG *target_conf = NULL;
1407 LOG(LOG_ERR, "null input\n");
1412 LOG(LOG_ERR, "null input\n");
1419 newRmSet = conf->newRmSet;
1420 if (newRmSet == NULL) {
1421 LOG(LOG_ERR, "null input\n");
1424 if (ctx->target_conf == NULL) {
1425 LOG(LOG_ERR, "null input\n");
1428 if (ctx->target_conf->uuid == NULL) {
1429 LOG(LOG_ERR, "null input\n");
1432 if (ctx->target_conf->rm_uuid == NULL) {
1433 LOG(LOG_ERR, "null input\n");
1438 str_collector_uuid = ctx->target_conf->uuid->str;
1439 str_rm_uuid = ctx->target_conf->rm_uuid->str;
1440 str_verifier_uuid = getStringOfUuid(ctx->conf->uuid->uuid);
1441 if ((str_collector_uuid == NULL) ||
1442 (str_rm_uuid == NULL) ||
1443 (str_verifier_uuid == NULL)) {
1444 rc = PTS_INTERNAL_ERROR;
1448 DEBUG("Verifier UUID %s\n", str_verifier_uuid);
1449 DEBUG("Collector UUID %s\n", str_collector_uuid);
1450 DEBUG("Collector RM UUID %s\n", str_rm_uuid);
1452 /* Setup the dir for the collector */
1453 collector_dir = getFullpathName(conf_dir, str_collector_uuid);
1455 DEBUG("conf_dir %s\n", conf_dir);
1456 DEBUG("collector_dir %s\n", collector_dir);
1459 target_conf_filename = getFullpathName(collector_dir, "target.conf");
1460 target_conf = newPtsConfig();
1462 rc = readTargetConf(target_conf, target_conf_filename);
1463 if (rc != PTS_SUCCESS) {
1464 LOG(LOG_ERR, "updateNewRm() - readTargetConf failed\n");
1474 newrm_uuid = newOpenptsUuid2((PTS_UUID *)newRmSet);
1475 newRmSet += 16; // TODO
1476 DEBUG("Collector new RM UUID %s\n", newrm_uuid->str);
1480 rm_dir = getFullpathName(collector_dir, newrm_uuid->str);
1482 rc = checkDir(collector_dir);
1483 if (rc != PTS_SUCCESS) {
1484 /* unknwon collector */
1485 LOG(LOG_ERR, "updateNewRm() - Unknown collector, UUID= %s dir=%s\n",
1486 str_collector_uuid, collector_dir);
1487 addReason(ctx, -1, NLS(MS_OPENPTS, OPENPTS_ARU_MISSING_COLLECTOR_CONFIG,
1488 "Missing collector configuration"));
1489 addReason(ctx, -1, NLS(MS_OPENPTS, OPENPTS_ARU_COLLECTOR_HOSTNAME,
1490 "Collector hostname = %s"), host);
1491 addReason(ctx, -1, NLS(MS_OPENPTS, OPENPTS_ARU_COLLECTOR_UUID,
1492 "Collector UUID = %s"), str_collector_uuid);
1493 rc = PTS_NOT_INITIALIZED;
1497 rc = checkDir(rm_dir);
1498 if (rc == PTS_SUCCESS) {
1499 /* ??? Already Exist */
1500 DEBUG("updateNewRm() - Exist RM, UUID= %s\n", str_collector_uuid);
1501 /*addReason(ctx, -1, NLS(MS_OPENPTS, OPENPTS_ARU_RM_ALREADY_EXISTS, "The Reference Manifest already exists"));
1502 addReason(ctx, -1, NLS(MS_OPENPTS, OPENPTS_ARU_COLLECTOR_HOSTNAME, "Collector hostname = %s"), host);
1503 addReason(ctx, -1, NLS(MS_OPENPTS, OPENPTS_ARU_COLLECTOR_UUID, "Collector UUID = %s"), str_collector_uuid);
1504 addReason(ctx, -1, NLS(MS_OPENPTS, OPENPTS_ARU_COLLECTOR_RM_UUID, "Collector RM UUID = %s"), str_rm_uuid);
1508 /* create new RM dir */
1509 rc = makeDir(rm_dir);
1510 if (rc != PTS_SUCCESS) {
1511 /* unknwon collector */
1512 LOG(LOG_ERR, "updateNewRm() - Create New RM dir failed, %s\n", rm_dir);
1513 rc = PTS_INTERNAL_ERROR;
1518 // TODO target.conf?
1519 // conf->property_filename = getFullpathName(collector_dir, "vr.properties");
1520 // conf->ir_filename = getFullpathName(collector_dir, "ir.xml");
1521 // conf->prop_filename = getFullpathName(collector_dir, "target.conf");
1522 // conf->newrm_uuid->filename = getFullpathName(collector_dir, "newrm_uuid");
1524 DEBUG("conf dir : %s\n", collector_dir);
1525 DEBUG("rm dir : %s\n", rm_dir);
1526 DEBUG("New RM UUID file : %s\n", target_conf->newrm_uuid->filename);
1529 num = getUint32(newRmSet);
1530 DEBUG("RM num %d\n", num);
1533 if (num > MAX_RM_NUM) {
1534 LOG(LOG_ERR, "Bad NUM %d\n", num);
1535 rc = PTS_INTERNAL_ERROR;
1540 DEBUG("get %d new RMs\n", num);
1541 target_conf->newrm_num = num;
1542 for (i = 0; i < num; i++) {
1544 snprintf(buf, BUF_SIZE, "%s/%s/rm%d.xml",
1548 rm_filename[i] = smalloc_assert(buf);
1549 DEBUG("RM[%d] : %s\n", i, rm_filename[i]);
1551 len = getUint32(newRmSet);
1552 DEBUG("RM[%d] len %d -> %s\n", i, len, rm_filename[i]);
1556 rc = saveToFile(rm_filename[i], len, newRmSet);
1557 if (rc != PTS_SUCCESS) {
1558 LOG(LOG_ERR, "updateNewRm() - save RM[%d], %s failed\n", i, rm_filename[i]);
1561 target_conf->rm_filename[i] = smalloc_assert(rm_filename[i]);
1566 /* New RM UUID file */
1567 /* save to newrm_uuid file */
1568 DEBUG("NEWRM %s => %s \n", newrm_uuid->str, target_conf->newrm_uuid->filename);
1569 newrm_uuid->filename = target_conf->newrm_uuid->filename;
1570 newrm_uuid->status = OPENPTS_UUID_FILLED;
1571 rc = writeOpenptsUuidFile(newrm_uuid, 1); // overwite
1574 /* save target conf */
1575 // TODO need to updade?
1576 // writeTargetConf(ctx->conf, collector_uuid, target_conf_filename); // ctx.c
1578 rc = PTS_SUCCESS; // OK
1582 if (target_conf_filename != NULL) xfree(target_conf_filename);
1583 if (target_conf != NULL) freePtsConfig(target_conf);
1585 // DEBUG("error at verifier\n");