2 * This file is part of the OpenPTS project.
4 * The Initial Developer of the Original Code is International
5 * Business Machines Corporation. Portions created by IBM
6 * Corporation are Copyright (C) 2010 International Business
7 * Machines Corporation. All Rights Reserved.
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the Common Public License as published by
11 * IBM Corporation; either version 1 of the License, or (at your option)
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * Common Public License for more details.
19 * You should have received a copy of the Common Public License
20 * along with this program; if not, a copy can be viewed at
21 * http://www.opensource.org/licenses/cpl1.0.php.
26 * \brief Generate Integrity Report from IML
27 * @author Seiji Munetoh <munetoh@users.sourceforge.jp>
29 * cleanup 2011-07-06 SM
31 * TSS Event Struct -> IR
32 * IML and PCR may not match, since the read them is not an atmic operation
36 * Event-> XML, calc PCR(c)
43 * if PCR(t) is old, ignore new events
57 #include <libxml/encoding.h>
58 #include <libxml/xmlwriter.h>
59 #include <libxml/parser.h>
65 TEXT_WRITER_START_ELEMENT,
66 TEXT_WRITER_WRITE_ATTR,
67 TEXT_WRITER_WRITE_FORMAT_ELEMENT,
68 TEXT_WRITER_END_ELEMENT,
69 TEXT_WRITER_WRITE_BASE64,
70 TEXT_WRITER_START_DOC,
76 void displayXmlError(int errorIndex, int rc) {
77 char *xmlFuncStrings[XML_FUNC_END] = {
78 "xmlTextWriterStartElement",
79 "xmlTextWriterWriteAttribute",
80 "xmlTextWriterWriteFormatElement",
81 "xmlTextWriterEndElement",
82 "xmlTextWriterWriteBase64",
83 "xmlTextWriterStartDocument",
85 "xmlTextWriterEndDocument",
89 if (errorIndex >= XML_FUNC_END) {
90 LOG(LOG_ERR, "errorIndex(%d) > XML_FUNC_END(%d)",errorIndex, XML_FUNC_END);
95 LOG(LOG_ERR, "XML function '%s' returned '%d'\n", xmlFuncStrings[errorIndex], rc);
104 int freeAllFsm(OPENPTS_CONTEXT *ctx) {
105 OPENPTS_SNAPSHOT *ss;
108 DEBUG_CAL("resetFsm\n");
112 LOG(LOG_ERR, "null input");
116 if (ctx->ss_table == NULL) {
117 // DEBUG("resetFsm() - no SS table\n");
122 for (i = 0; i < MAX_PCRNUM; i++) {
123 for (j = 0; j < MAX_SSLEVEL; j++) {
125 ss = getSnapshotFromTable(ctx->ss_table, i, j);
128 /* free event wrapper chain */
129 if (ss->start != NULL) {
130 freeEventWrapperChain(ss->start);
134 if (ss->fsm_behavior != NULL) {
135 // DEBUG("free pcr %d, level 0, BHV-FSM\n",i);
136 freeFsmContext(ss->fsm_behavior);
137 ss->fsm_behavior = NULL;
139 if (ss->fsm_binary != NULL) {
140 // DEBUG("free pcr %d, level 0, BIN-FSM\n",i);
141 freeFsmContext(ss->fsm_binary);
142 ss->fsm_binary = NULL;
146 memset(ss->curr_pcr, 0, SHA1_DIGEST_SIZE);
147 memset(ss->tpm_pcr, 0, SHA1_DIGEST_SIZE);
153 setActiveSnapshotLevel(ctx->ss_table, i, 0);
163 * pointer to OPENPTS_IR_CONTEXT OR NULL
166 OPENPTS_IR_CONTEXT *newIrContext() {
167 OPENPTS_IR_CONTEXT *ctx;
169 ctx = (OPENPTS_IR_CONTEXT *) xmalloc(sizeof(OPENPTS_IR_CONTEXT));
171 LOG(LOG_ERR, "no memory");
174 memset(ctx, 0, sizeof(OPENPTS_IR_CONTEXT));
176 ctx->buf = xmalloc(EVENTDATA_BUF_SIZE);
177 if (ctx->buf == NULL) {
178 LOG(LOG_ERR, "no memory");
182 memset(ctx->buf, 0, EVENTDATA_BUF_SIZE);
193 void freeIrContext(OPENPTS_IR_CONTEXT *ctx) {
196 LOG(LOG_ERR, "null input");
201 if (ctx->buf != NULL) {
210 * write ComponentID by PCR.
212 * This code does not support stacked components by IR
213 * To supports stacked component, we need FSM model to parse the IML.
214 * But, if we use the FSM model, verifier can validate the IML without stacked component
216 * @retval PTS_SUCCESS
217 * @retval PTS_INTERNAL_ERROR
221 int writeComponentID(
222 xmlTextWriterPtr writer,
223 PTS_ComponentId * cid,
225 int rc = PTS_INTERNAL_ERROR;
230 LOG(LOG_ERR, "null input");
235 BYTE *simpleName = snmalloc2(cid->dataBlock.dataBlock,
236 cid->simpleName.offset,
237 cid->simpleName.length);
239 BYTE *vendor = snmalloc2(cid->dataBlock.dataBlock,
243 BYTE *versionString = snmalloc2(cid->dataBlock.dataBlock,
244 cid->versionString.offset,
245 cid->versionString.length);
247 /* element "core:ComponentID" */
248 rc = xmlTextWriterStartElement(writer, BAD_CAST "core:ComponentID");
250 displayXmlError(TEXT_WRITER_START_ELEMENT, rc);
254 /* Add an attribute with name "Id" */
255 snprintf(id, sizeof(id), "CID_%d", pcrIndex);
256 rc = xmlTextWriterWriteAttribute(
261 displayXmlError(TEXT_WRITER_WRITE_ATTR, rc);
265 /* Add an attribute with name "ModelSystemClass" */
266 rc = xmlTextWriterWriteAttribute(
268 BAD_CAST "ModelSystemClass",
269 BAD_CAST "TBD"); // TODO(munetoh)
271 displayXmlError(TEXT_WRITER_WRITE_ATTR, rc);
275 /* Add an attribute with name "SimpleName" */
276 rc = xmlTextWriterWriteAttribute(
278 BAD_CAST "SimpleName",
279 BAD_CAST simpleName);
281 displayXmlError(TEXT_WRITER_WRITE_ATTR, rc);
285 /* Add an attribute with name "VersionBuild" */
286 rc = xmlTextWriterWriteAttribute(
288 BAD_CAST "VersionBuild",
289 BAD_CAST "1250694000000"); // TODO(munetoh)
291 displayXmlError(TEXT_WRITER_WRITE_ATTR, rc);
295 /* Add an attribute with name "VersionString" */
297 rc = xmlTextWriterWriteAttribute(
299 BAD_CAST "VersionString",
300 BAD_CAST versionString);
302 displayXmlError(TEXT_WRITER_WRITE_ATTR, rc);
306 /* Start an element named "core:VendorID" as child of "core:ComponentID". */
307 rc = xmlTextWriterStartElement(
309 BAD_CAST "core:VendorID");
311 displayXmlError(TEXT_WRITER_START_ELEMENT, rc);
315 /* Add an attribute with name "Name" */
316 rc = xmlTextWriterWriteAttribute(
321 displayXmlError(TEXT_WRITER_WRITE_ATTR, rc);
326 /* element "core:SmiVendorId" */
327 rc = xmlTextWriterWriteFormatElement(
329 BAD_CAST "core:SmiVendorId", "%d", 0);
331 displayXmlError(TEXT_WRITER_WRITE_FORMAT_ELEMENT, rc);
336 /* element "core:TcgVendorId" */
337 rc = xmlTextWriterWriteFormatElement(
339 BAD_CAST "core:TcgVendorId", "%s", "DEMO"); // TODO(munetoh)
341 displayXmlError(TEXT_WRITER_WRITE_FORMAT_ELEMENT, rc);
345 /* Close the element "core:VendorID". */
346 rc = xmlTextWriterEndElement(writer);
348 displayXmlError(TEXT_WRITER_END_ELEMENT, rc);
352 /* Close the element"core:ComponentID". */
353 rc = xmlTextWriterEndElement(writer);
355 displayXmlError(TEXT_WRITER_END_ELEMENT, rc);
363 rc = PTS_INTERNAL_ERROR;
366 if (simpleName != NULL)
370 if (versionString != NULL)
371 xfree(versionString);
377 * write core:DigestMethod
379 * @retval PTS_SUCCESS
380 * @retval PTS_INTERNAL_ERROR
383 int writeDigestMethod(xmlTextWriterPtr writer) {
386 /* Start element "core:DigestMethod" */
387 rc = xmlTextWriterStartElement(
389 BAD_CAST "core:DigestMethod");
391 displayXmlError(TEXT_WRITER_START_ELEMENT, rc);
392 return PTS_INTERNAL_ERROR;
395 /* Add an attribute with name "Algorithm" */
396 rc = xmlTextWriterWriteAttribute(
398 BAD_CAST "Algorithm",
401 displayXmlError(TEXT_WRITER_WRITE_ATTR, rc);
402 return PTS_INTERNAL_ERROR;
405 /* Add an attribute with name "Id" */
406 rc = xmlTextWriterWriteAttribute(
411 displayXmlError(TEXT_WRITER_WRITE_ATTR, rc);
412 return PTS_INTERNAL_ERROR;
415 /* Close the element named "core:DigestMethod". */
416 rc = xmlTextWriterEndElement(writer);
418 displayXmlError(TEXT_WRITER_END_ELEMENT, rc);
419 return PTS_INTERNAL_ERROR;
427 * write stuff:Objects
428 * this is a single event.
436 * @retval PTS_SUCCESS
437 * @retval PTS_INTERNAL_ERROR
441 int writeStuffObjects(
442 xmlTextWriterPtr writer,
443 TSS_PCR_EVENT * event,
447 char id[256]; // TODO(munetoh)
452 LOG(LOG_ERR, "null input");
457 snprintf(id, sizeof(id), "PCR_%d_LV%d_%d_%d_EVENT",
458 event->ulPcrIndex, ss_level, event->eventType, eventindex);
460 DEBUG_XML("addStuffObjects - pcr %d,id %s\n", event->ulPcrIndex, id);
462 /* start "stuff:Objects" */
463 rc = xmlTextWriterStartElement(
465 BAD_CAST "stuff:Objects");
467 displayXmlError(TEXT_WRITER_START_ELEMENT, rc);
471 /* start "stuff:Hash" */
472 rc = xmlTextWriterStartElement(
474 BAD_CAST "stuff:Hash");
476 displayXmlError(TEXT_WRITER_START_ELEMENT, rc);
480 /* Add an attribute with name "AlgRef" */
481 rc = xmlTextWriterWriteAttribute(
484 // BAD_CAST ALG_NAME[algtype]) < 0)
485 BAD_CAST getAlgString(algtype));
487 displayXmlError(TEXT_WRITER_WRITE_ATTR, rc);
491 /* Add an attribute with name "Id" */
492 rc = xmlTextWriterWriteAttribute(
497 displayXmlError(TEXT_WRITER_WRITE_ATTR, rc);
502 rc = xmlTextWriterWriteBase64(
504 (const char *) event->rgbPcrValue,
506 event->ulPcrValueLength);
508 displayXmlError(TEXT_WRITER_WRITE_BASE64, rc);
512 /* Close the element named "stuff:Hash". */
513 rc = xmlTextWriterEndElement(writer);
515 displayXmlError(TEXT_WRITER_END_ELEMENT, rc);
519 /* Write an element named "pcrindex" */
520 rc = xmlTextWriterWriteFormatElement(
523 "%d", event->ulPcrIndex);
525 displayXmlError(TEXT_WRITER_WRITE_FORMAT_ELEMENT, rc);
529 /* Write an element named "eventtype" */
530 rc = xmlTextWriterWriteFormatElement(
532 BAD_CAST "eventtype",
533 "%d", event->eventType);
535 displayXmlError(TEXT_WRITER_WRITE_FORMAT_ELEMENT, rc);
539 if (event->ulEventLength > 0) {
540 /* Start an element named "eventdata" as child of "eventdata". */
541 rc = xmlTextWriterStartElement(
543 BAD_CAST "eventdata");
545 displayXmlError(TEXT_WRITER_START_ELEMENT, rc);
550 rc = xmlTextWriterWriteBase64(
552 (const char *) event->rgbEvent,
554 event->ulEventLength);
556 displayXmlError(TEXT_WRITER_WRITE_BASE64, rc);
560 /* Close the element named "eventdata". */
561 rc = xmlTextWriterEndElement(writer);
563 displayXmlError(TEXT_WRITER_END_ELEMENT, rc);
570 /* Close the element named "stuff:Objects". */
571 rc = xmlTextWriterEndElement(writer);
573 displayXmlError(TEXT_WRITER_END_ELEMENT, rc);
580 LOG(LOG_ERR, "writeStuffObjects() XML ERROR\n");
581 return PTS_INTERNAL_ERROR;
587 <PcrHash AlgRef="sha1"
588 Id="_06bd159d-365c-4d80-b968-9c2fe12c4d66_pcrhash"
591 StartHash="AAAAAAAAAAAAAAAAAAAAAAAAAAA=">
592 j7/z7OqcVMjRxCz+qT1r8BvzQFs=
595 * @retval PTS_SUCCESS
596 * @retval PTS_INTERNAL_ERROR
601 xmlTextWriterPtr writer,
607 // int rc = PTS_SUCCESS;
608 char id[256]; // TODO(munetoh) 11+1+1 = 12?
611 DEBUG_CAL("writePcrHash - PCR[%d] level %d \n", pcrIndex, ss_level);
614 if (startHash == NULL) {
615 LOG(LOG_ERR, "null input");
619 LOG(LOG_ERR, "null input");
624 snprintf(id, sizeof(id), "PCR_%d_LV%d_HASH", pcrIndex, ss_level);
626 /* Start an element named "eventdata" as child of "PcrHash". */
627 rc = xmlTextWriterStartElement(writer, BAD_CAST "PcrHash");
629 displayXmlError(TEXT_WRITER_START_ELEMENT, rc);
633 /* Add an attribute with name "AlgRef" */
634 rc = xmlTextWriterWriteAttribute(
637 // BAD_CAST ALG_NAME[algtype]) < 0)
638 BAD_CAST getAlgString(algtype));
640 displayXmlError(TEXT_WRITER_WRITE_ATTR, rc);
644 /* Add an attribute with name "Id" */
645 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "Id", BAD_CAST id);
647 displayXmlError(TEXT_WRITER_WRITE_ATTR, rc);
651 /* Add an attribute with name "IsResetable" */
652 rc = xmlTextWriterWriteAttribute(
654 BAD_CAST "IsResetable",
657 displayXmlError(TEXT_WRITER_WRITE_ATTR, rc);
661 /* Add an attribute with name "Number" */
662 snprintf(id, sizeof(id), "%d", pcrIndex);
663 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "Number", BAD_CAST id);
665 displayXmlError(TEXT_WRITER_WRITE_ATTR, rc);
669 /* Add an attribute with name "StartHash" */
670 // TODO(munetoh) convert startHash to base64 string
671 rc = xmlTextWriterWriteAttribute(
673 BAD_CAST "StartHash",
674 BAD_CAST "AAAAAAAAAAAAAAAAAAAAAAAAAAA=");
676 displayXmlError(TEXT_WRITER_WRITE_ATTR, rc);
681 rc = xmlTextWriterWriteBase64(writer, (const char *) hash, 0, 20);
683 displayXmlError(TEXT_WRITER_WRITE_BASE64, rc);
687 /* Close the element named "PcrHash". */
688 rc = xmlTextWriterEndElement(writer);
690 displayXmlError(TEXT_WRITER_END_ELEMENT, rc);
697 return PTS_INTERNAL_ERROR;
703 * @retval PTS_SUCCESS
704 * @retval PTS_INTERNAL_ERROR
707 xmlTextWriterPtr writer,
708 OPENPTS_TPM_CONTEXT *tpm,
709 PTS_ComponentId *cid,
711 OPENPTS_SNAPSHOT *ss) {
712 int rc = PTS_SUCCESS;
716 char id[256]; // TODO 3 + UUID = 3 + 36 = 39
718 OPENPTS_PCR_EVENT_WRAPPER *eventWrapper;
722 LOG(LOG_ERR, "null input");
726 LOG(LOG_ERR, "null input");
730 LOG(LOG_ERR, "null input");
737 // FSM resetPCR(n) exist
738 if (ss->reset_pcr == 1) {
739 LOG(LOG_TODO, "reset PCR[%d]\n", index);
740 resetTpmPcr(tpm, index);
744 /* set initial PCR value */
745 rc = getTpmPcrValue(tpm, index, ss->start_pcr);
747 DEBUG_CAL("addSnapshot - start pcr%d snapshot level %d num %d\n",
748 index, level, ss->event_num);
750 /* Start an element named "SnapshotCollection" as child of Report. */
751 rc = xmlTextWriterStartElement(writer, BAD_CAST "SnapshotCollection");
753 displayXmlError(TEXT_WRITER_START_ELEMENT, rc);
754 rc = PTS_INTERNAL_ERROR;
760 if (ir_uuid == NULL) {
761 LOG(LOG_ERR, "UUID \n");
762 rc = PTS_INTERNAL_ERROR;
765 str_ir_uuid = getStringOfUuid(ir_uuid);
766 if (str_ir_uuid == NULL) {
767 LOG(LOG_ERR, "UUID \n");
768 rc = PTS_INTERNAL_ERROR;
773 snprintf(id, sizeof(id), "IR_%s", str_ir_uuid);
775 /* Add an attribute with name "Id" */
776 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "Id", BAD_CAST id);
778 displayXmlError(TEXT_WRITER_WRITE_ATTR, rc);
779 rc = PTS_INTERNAL_ERROR;
783 /* Add an attribute with name "UUID" */
784 rc = xmlTextWriterWriteAttribute(
785 writer, BAD_CAST "UUID", BAD_CAST str_ir_uuid);
787 displayXmlError(TEXT_WRITER_WRITE_ATTR, rc);
788 rc = PTS_INTERNAL_ERROR;
791 /* Add an attribute with name "RevLevel" */
792 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "RevLevel", BAD_CAST "0");
794 displayXmlError(TEXT_WRITER_WRITE_ATTR, rc);
795 rc = PTS_INTERNAL_ERROR;
799 rc = writeComponentID(writer, cid, index);
801 rc = writeDigestMethod(writer);
803 /* Start an element named "core:Values" as child of "SnapshotCollection". */
804 rc = xmlTextWriterStartElement(writer, BAD_CAST "core:Values");
806 displayXmlError(TEXT_WRITER_START_ELEMENT, rc);
807 rc = PTS_INTERNAL_ERROR;
811 /* Start "stuff:SimpleSnapshotObject" */
812 rc = xmlTextWriterStartElement(
813 writer, BAD_CAST "stuff:SimpleSnapshotObject");
815 displayXmlError(TEXT_WRITER_START_ELEMENT, rc);
816 rc = PTS_INTERNAL_ERROR;
820 /* Events at PCR[i] */
822 eventWrapper = ss->start;
824 if (eventWrapper == NULL) {
825 LOG(LOG_ERR, "writeSnapshot- eventWrapper is NULL\n");
830 for (j = 0; j < ss->event_num; j++) {
831 DEBUG_XML("genIr - start snapshot - event %d \n", j);
832 rc = writeStuffObjects(writer, eventWrapper->event, ALGTYPE_SHA1, level, j);
834 rc = extendTpm(tpm, eventWrapper->event);
837 eventWrapper = eventWrapper->next_pcr;
840 /* Close the element named "stuff:SimpleSnapshotObject". */
841 rc = xmlTextWriterEndElement(writer);
843 displayXmlError(TEXT_WRITER_END_ELEMENT, rc);
844 rc = PTS_INTERNAL_ERROR;
848 /* Close the element named "core:Values". */
849 rc = xmlTextWriterEndElement(writer);
851 displayXmlError(TEXT_WRITER_END_ELEMENT, rc);
852 rc = PTS_INTERNAL_ERROR;
856 /* set curr PCR value */
857 rc = getTpmPcrValue(tpm, index, ss->curr_pcr);
858 if (rc != PTS_SUCCESS) {
859 LOG(LOG_ERR, "getTpmPcrValue() fail");
860 rc = PTS_INTERNAL_ERROR;
864 /* check with TPM value if this is the last snapshot */
865 // TODO(munetoh) copy level0 tpm_pcr to level1
867 /* add PcrHash element */
868 rc = writePcrHash(writer, index, level, ss->start_pcr, ss->curr_pcr, ALGTYPE_SHA1);
869 if (rc != PTS_SUCCESS) {
870 LOG(LOG_ERR, "writePcrHash() fail");
871 rc = PTS_INTERNAL_ERROR;
875 /* Close the element named "SnapshotCollection". */
876 rc = xmlTextWriterEndElement(writer);
878 displayXmlError(TEXT_WRITER_END_ELEMENT, rc);
879 rc = PTS_INTERNAL_ERROR;
890 DEBUG_CAL("addSnapshot - done, rc=%d\n", rc);
899 * @retval PTS_SUCCESS
900 * @retval PTS_INTERNAL_ERROR
904 <QuoteData ID="XXXX">
907 <PcrSelection SizeOfSelect="3" PcrSelect="AAM1BQA="/>
908 <ValueSize>120</ValueSize>
909 <PcrValue PcrNumber="0">lavylWbp6wz29tPTGu8uXQgBXZY=</PcrValue>
910 <PcrValue PcrNumber="2">4skssUfiCqP4sq8brID5lh/UHqA=</PcrValue>
911 <PcrValue PcrNumber="4">ooe0hpRSNq7AF5p8flBBNCigU14=</PcrValue>
912 <PcrValue PcrNumber="5">aNAgqKiy8qF8rUilK2GP/ny0TsE=</PcrValue>
913 <PcrValue PcrNumber="8">Mx3F5PbzeH/a/iBof4NKEyPlLPw=</PcrValue>
914 <PcrValue PcrNumber="10">OpUxai7OgR6KNabQ1ftXoArHFqU=</PcrValue>
916 <QuoteInfo VersionMajor="1" VersionMinor="1" VersionRevMajor="0" VersionRevMinor="0" Fixed="QUOT" DigestValue="tZ87wnYe8mAVW8ByvTjHjWzqCgY=" ExternalData="+saVas74wMg9V9N8rpe4gcP1uCo="/>
919 <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
920 <SignatureValue>x3rjafy577XLUw+7Guam3XTPojTWeVe9CD2E/9B0ZxdiWuLF2Kv34qDCDiAmHpE7a9fiawEhLntQ1Lmqsev/NKoKlL57/vJiJuON4/nRow0FBGHcsrZnOSl9WWL+Eob/rAZPglcL4O8SMM2sqvaIK6XBLJhF2P7+fxWRWnH27w/w+lnWV6J3ItxYLhk9Bs1NWAeI+z4barv6RxmYH1/91hlbByWUA1XAX6t1NC3lBgwLRrUqu2aQAPikle+2SxjpW3squT/LICVE8Qzcd9s6G+D1jfmmPBkxoRQE4NTjsVxJJitnL2ADnuVheEHTd3+heJEb6n+n/aKq93M6VnKjhg==</SignatureValue>
922 <KeyValue>AMxWrZm0Aiq3F/1U9xbA5vqWejd18zT195sB6uTAUR96hNkJg/+Q2ffUXRdzIYdVgMddZDJtEz2Dzyg3lllwL7ssHi+vusEgrhgDmpQrwQNySFWC0ce64ckosC+HG4xjNeoAEFOWGqDvIFAsmT6T2kFgZnYs1GiKbg+qpmw0xY4qQPXiMP58w4JlTBM6cClnen60+A01aSSjiCioeYOy+4AItVYINrretBcrDmbPhGqWT32HpqpmNu3lQBg0aUtHMG5X+FhG0Mu9zemXT0nHxLljEDCRgkdzY9oXGjG08Wxn5OzOX9JVoDuMnLgeuAIlqSXIOEFhFJfvBLeGnriLktM=</KeyValue>
928 xmlTextWriterPtr writer,
929 OPENPTS_CONTEXT *ctx) {
934 int size_of_select = 0;
936 BYTE select_byte[3]; // TODO TPM1.2, 24PCRs => 3 bytes
941 LOG(LOG_ERR, "null input");
944 if (ctx->pcrs == NULL) {
945 LOG(LOG_TODO, "writeQuote - OPENPTS_PCRS is NULL, SKIP QuoteData\n");
948 if (ctx->validation_data == NULL) {
949 LOG(LOG_TODO, "writeQuote - TSS_VALIDATION is NULL, SKIP QuoteData\n");
953 /* Start an element named "QuoteData" as child of Report. */
954 rc = xmlTextWriterStartElement(writer, BAD_CAST "QuoteData");
956 displayXmlError(TEXT_WRITER_START_ELEMENT, rc);
957 return PTS_INTERNAL_ERROR;
960 /* Add an attribute with name "ID" */
961 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "ID", BAD_CAST "TBD");
963 displayXmlError(TEXT_WRITER_WRITE_ATTR, rc);
964 return PTS_INTERNAL_ERROR;
967 /* Start an element named "Quote" as child of QuoteData. */
968 rc = xmlTextWriterStartElement(writer, BAD_CAST "Quote");
970 displayXmlError(TEXT_WRITER_START_ELEMENT, rc);
971 return PTS_INTERNAL_ERROR;
974 /* Start an element named "PcrComposit" as child of Quote. */
975 rc = xmlTextWriterStartElement(writer, BAD_CAST "PcrComposit");
977 displayXmlError(TEXT_WRITER_START_ELEMENT, rc);
978 return PTS_INTERNAL_ERROR;
982 // is 2 if call TPM_Quote
983 // TODO gen pcrselect bit map
985 if (ctx->pcrs->pcr_num == 24) {
988 ctx->pcrs->value_size = 0;
989 for (i = 0; i< ctx->pcrs->pcr_num; i++) {
990 if (ctx->pcrs->pcr_select[i] == 1) {
991 select_int = select_int | 1;
992 ctx->pcrs->value_size += 20; // TODO digest size
994 select_int = select_int << 1;
996 select_int = select_int >> 1; // TODO
997 // DEBUG("PCR SELECT %x\n", select_int);
998 select_byte[0] = (select_int & 0xFF0000) >> 16;
999 select_byte[1] = (select_int & 0xFF00) >> 8;
1000 select_byte[2] = select_int & 0xFF;
1003 LOG(LOG_ERR, " PCR NUM != 24\n");
1006 /* Start an element named "PcrSelection" as child of PcrComposit. */
1007 rc = xmlTextWriterStartElement(writer, BAD_CAST "PcrSelection");
1009 displayXmlError(TEXT_WRITER_START_ELEMENT, rc);
1010 return PTS_INTERNAL_ERROR;
1013 /* Add an attribute with name "SizeOfSelect", int */
1014 snprintf(tagbuf, sizeof(tagbuf), "%d", size_of_select);
1015 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "SizeOfSelect", BAD_CAST tagbuf);
1017 displayXmlError(TEXT_WRITER_WRITE_ATTR, rc);
1018 return PTS_INTERNAL_ERROR;
1021 /* Add an attribute with name "PcrSelect", base64 */
1022 b64buf = (char *)encodeBase64(
1023 (unsigned char *)select_byte,
1026 if (b64buf == NULL) {
1027 LOG(LOG_ERR, "encodeBase64 fail"); // TODO ERROR => displayXmlError
1028 return PTS_INTERNAL_ERROR;
1030 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "PcrSelect", BAD_CAST b64buf);
1032 // LOG(LOG_ERR, "Error at xmlTextWriterWriteAttribute\n");
1033 displayXmlError(TEXT_WRITER_WRITE_ATTR, rc);
1034 return PTS_INTERNAL_ERROR;
1039 /* Close the element named "PcrSelection". */
1040 rc = xmlTextWriterEndElement(writer);
1042 // LOG(LOG_ERR, "Error at xmlTextWriterEndElement\n");
1043 displayXmlError(TEXT_WRITER_END_ELEMENT, rc);
1044 return PTS_INTERNAL_ERROR;
1049 /* Write an element named "ValueSize" as child of PcrComposit */
1050 rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "ValueSize", "%d", ctx->pcrs->value_size);
1052 displayXmlError(TEXT_WRITER_WRITE_FORMAT_ELEMENT, rc);
1053 return PTS_INTERNAL_ERROR;
1056 /* PcrValue, loop */
1058 for (i = 0; i < ctx->pcrs->pcr_num; i ++) {
1059 if (ctx->pcrs->pcr_select[i] == 1) {
1060 /* Start an element named "PcrValue" as child of PcrComposit. */
1061 rc = xmlTextWriterStartElement(writer, BAD_CAST "PcrValue");
1063 displayXmlError(TEXT_WRITER_START_ELEMENT, rc);
1064 return PTS_INTERNAL_ERROR;
1066 /* Add an attribute with name "PcrNumber", int */
1067 snprintf(tagbuf, sizeof(tagbuf), "%d", i);
1068 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "PcrNumber", BAD_CAST tagbuf);
1069 // rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "PcrNumber", BAD_CAST "0");
1071 displayXmlError(TEXT_WRITER_WRITE_ATTR, rc);
1072 return PTS_INTERNAL_ERROR;
1075 /* Write a text, PCR, base64 */
1076 rc = xmlTextWriterWriteBase64(
1078 (const char *) ctx->pcrs->pcr[i],
1080 20); // TODO add length to OPENPTS_PCRS
1082 displayXmlError(TEXT_WRITER_WRITE_BASE64, rc);
1083 return PTS_INTERNAL_ERROR;
1086 /* Close the element named "PcrValue" */
1087 rc = xmlTextWriterEndElement(writer);
1089 displayXmlError(TEXT_WRITER_END_ELEMENT, rc);
1090 return PTS_INTERNAL_ERROR;
1095 /* Close the element named "PcrComposit". */
1096 rc = xmlTextWriterEndElement(writer);
1098 displayXmlError(TEXT_WRITER_END_ELEMENT, rc);
1099 return PTS_INTERNAL_ERROR;
1103 /* Start an element named "QuoteInfo" as child of Quote. */
1104 rc = xmlTextWriterStartElement(writer, BAD_CAST "QuoteInfo");
1106 displayXmlError(TEXT_WRITER_START_ELEMENT, rc);
1107 return PTS_INTERNAL_ERROR;
1110 /* Add an attribute with name "VersionMajor", int */
1111 snprintf(tagbuf, sizeof(tagbuf), "%d", ctx->validation_data->versionInfo.bMajor);
1112 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "VersionMajor", BAD_CAST tagbuf);
1114 // LOG(LOG_ERR, "Error at xmlTextWriterWriteAttribute\n");
1115 displayXmlError(TEXT_WRITER_WRITE_ATTR, rc);
1116 return PTS_INTERNAL_ERROR;
1118 /* Add an attribute with name "VersionMinor", int */
1119 snprintf(tagbuf, sizeof(tagbuf), "%d", ctx->validation_data->versionInfo.bMinor);
1120 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "VersionMinor", BAD_CAST tagbuf);
1122 // LOG(LOG_ERR, "Error at xmlTextWriterWriteAttribute\n");
1123 displayXmlError(TEXT_WRITER_WRITE_ATTR, rc);
1124 return PTS_INTERNAL_ERROR;
1126 /* Add an attribute with name "VersionRevMajor", int */
1127 snprintf(tagbuf, sizeof(tagbuf), "%d", ctx->validation_data->versionInfo.bRevMajor);
1128 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "VersionRevMajor", BAD_CAST tagbuf);
1130 // LOG(LOG_ERR, "Error at xmlTextWriterWriteAttribute\n");
1131 displayXmlError(TEXT_WRITER_WRITE_ATTR, rc);
1132 return PTS_INTERNAL_ERROR;
1135 /* Add an attribute with name "VersionRevMinor", int */
1136 snprintf(tagbuf, sizeof(tagbuf), "%d", ctx->validation_data->versionInfo.bRevMinor);
1137 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "VersionRevMinor", BAD_CAST tagbuf);
1139 // LOG(LOG_ERR, "Error at xmlTextWriterWriteAttribute\n");
1140 displayXmlError(TEXT_WRITER_WRITE_ATTR, rc);
1141 return PTS_INTERNAL_ERROR;
1144 /* Add an attribute with name "Fixed", int */
1145 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "Fixed", BAD_CAST "QUOT");
1147 // LOG(LOG_ERR, "Error at xmlTextWriterWriteAttribute\n");
1148 displayXmlError(TEXT_WRITER_WRITE_ATTR, rc);
1152 /* Add an attribute with name "DigestValue", base64 */
1153 b64buf = encodeBase64(
1154 (unsigned char *)&ctx->validation_data->rgbData[8], // skip 01010000 51554f54
1156 &b64buf_len); // ctx->validation_data->ulDataLength);
1157 if (b64buf == NULL) {
1158 LOG(LOG_ERR, "encodeBase64() fail");
1159 return PTS_INTERNAL_ERROR;
1161 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "DigestValue", BAD_CAST b64buf);
1163 displayXmlError(TEXT_WRITER_WRITE_ATTR, rc);
1164 return PTS_INTERNAL_ERROR;
1169 // TODO we used DH-nonce exchange but here, we put plain nonce:-P
1170 // TODO is this option attribute? can we suppress?
1171 /* Add an attribute with name "ExternalData", base64 */
1172 b64buf = encodeBase64(
1173 (unsigned char *)ctx->validation_data->rgbExternalData,
1174 ctx->validation_data->ulExternalDataLength,
1176 if (b64buf == NULL) {
1177 LOG(LOG_ERR, "encodeBase64() fail");
1178 return PTS_INTERNAL_ERROR;
1180 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "ExternalData", BAD_CAST b64buf);
1182 // LOG(LOG_ERR, "Error at xmlTextWriterWriteAttribute\n");
1183 displayXmlError(TEXT_WRITER_WRITE_ATTR, rc);
1184 return PTS_INTERNAL_ERROR;
1189 /* Close the element named "QuoteInfo". */
1190 rc = xmlTextWriterEndElement(writer);
1192 // LOG(LOG_ERR, "Error at xmlTextWriterEndElement\n");
1193 displayXmlError(TEXT_WRITER_END_ELEMENT, rc);
1194 return PTS_INTERNAL_ERROR;
1197 /* Close the element named "Quote". */
1198 rc = xmlTextWriterEndElement(writer);
1200 // LOG(LOG_ERR, "Error at xmlTextWriterEndElement\n");
1201 displayXmlError(TEXT_WRITER_END_ELEMENT, rc);
1202 return PTS_INTERNAL_ERROR;
1205 /* TpmSignature ------------------------------------ */
1207 /* Start an element named "TpmSignature" as child of QuoteData. */
1208 rc = xmlTextWriterStartElement(writer, BAD_CAST "TpmSignature");
1210 displayXmlError(TEXT_WRITER_START_ELEMENT, rc);
1211 return PTS_INTERNAL_ERROR;
1214 /* SignatureMethod */
1216 /* Start an element named "SignatureMethod" as child of TpmSignature. */
1217 rc = xmlTextWriterStartElement(writer, BAD_CAST "SignatureMethod");
1219 displayXmlError(TEXT_WRITER_START_ELEMENT, rc);
1220 return PTS_INTERNAL_ERROR;
1222 /* Add an attribute with name "Algorithm", string */
1223 rc = xmlTextWriterWriteAttribute(writer,
1224 BAD_CAST "Algorithm",
1225 BAD_CAST "http://www.w3.org/2000/09/xmldsig#rsa-sha1"); // TODO
1227 displayXmlError(TEXT_WRITER_WRITE_ATTR, rc);
1228 return PTS_INTERNAL_ERROR;
1230 /* Close the element named "SignatureMethod". */
1231 rc = xmlTextWriterEndElement(writer);
1233 displayXmlError(TEXT_WRITER_END_ELEMENT, rc);
1234 return PTS_INTERNAL_ERROR;
1237 /* SignatureValue */
1239 /* Start an element named "SignatureValue" as child of TpmSignature. */
1240 rc = xmlTextWriterStartElement(writer, BAD_CAST "SignatureValue");
1242 displayXmlError(TEXT_WRITER_START_ELEMENT, rc);
1243 return PTS_INTERNAL_ERROR;
1245 /* Write a text, signature, base64 */
1246 rc = xmlTextWriterWriteBase64(
1248 (const char *) ctx->validation_data->rgbValidationData,
1250 ctx->validation_data->ulValidationDataLength);
1252 displayXmlError(TEXT_WRITER_WRITE_BASE64, rc);
1253 return PTS_INTERNAL_ERROR;
1255 /* Close the element named "SignatureValue". */
1256 rc = xmlTextWriterEndElement(writer);
1258 displayXmlError(TEXT_WRITER_END_ELEMENT, rc);
1259 return PTS_INTERNAL_ERROR;
1262 /* Close the element named "TpmSignature". */
1263 rc = xmlTextWriterEndElement(writer);
1265 displayXmlError(TEXT_WRITER_END_ELEMENT, rc);
1266 return PTS_INTERNAL_ERROR;
1269 /* Close the element named "QuoteData". */
1270 rc = xmlTextWriterEndElement(writer);
1272 displayXmlError(TEXT_WRITER_END_ELEMENT, rc);
1273 return PTS_INTERNAL_ERROR;
1286 * Tag - unsignedShort
1288 * ExtendedData - base64
1290 * CapVersioninfoType
1292 * @retval PTS_SUCCESS
1293 * @retval PTS_INTERNAL_ERROR
1296 xmlTextWriterPtr writer,
1297 OPENPTS_CONTEXT *ctx) {
1300 char *b64buf = NULL;
1302 int size_of_select = 0;
1303 BYTE select_byte[3];
1307 BYTE *composite_hash;
1308 char tagbuf[128]; // Quote tag
1312 LOG(LOG_ERR, "null input");
1315 if (ctx->pcrs == NULL) {
1316 LOG(LOG_TODO, "writeQuote2 - OPENPTS_PCRS is NULL, SKIP QuoteData\n");
1319 if (ctx->validation_data == NULL) {
1320 LOG(LOG_TODO, "writeQuote2 - TSS_VALIDATION is NULL, SKIP QuoteData\n");
1324 /* Quote2 - tag [0:1] */
1325 tag = ctx->validation_data->rgbData[0];
1327 tag += ctx->validation_data->rgbData[1];
1329 /* Quote2 - Fixed [2:5] */
1330 memcpy(fixed, &ctx->validation_data->rgbData[2], 4);
1334 /* Quote2 - Nonce [6:25] */
1335 // external_data = &ctx->validation_data->rgbData[6];
1337 /* Quote2 - PcrSelection [26:27] */
1338 size_of_select = ctx->validation_data->rgbData[27];
1340 /* Quote2 - Selection [28:30] */
1342 select_byte[0] = ctx->validation_data->rgbData[28];
1343 select_byte[1] = ctx->validation_data->rgbData[29];
1344 select_byte[2] = ctx->validation_data->rgbData[30];
1346 /* Quote2 - locallity [31] */
1347 locality = ctx->validation_data->rgbData[31];
1349 /* Quote2 - CompositHash [32:51] */
1350 composite_hash = &ctx->validation_data->rgbData[32];
1352 /* QuoteData - start */
1353 rc = xmlTextWriterStartElement(writer, BAD_CAST "QuoteData");
1355 displayXmlError(TEXT_WRITER_START_ELEMENT, rc);
1356 return PTS_INTERNAL_ERROR;
1358 /* Add an attribute with name "ID" */
1359 // TODO Set UUID based on now
1360 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "ID", BAD_CAST "TBD");
1362 displayXmlError(TEXT_WRITER_WRITE_ATTR, rc);
1363 return PTS_INTERNAL_ERROR;
1366 /* Quote2 - start */
1367 rc = xmlTextWriterStartElement(writer, BAD_CAST "Quote2");
1369 displayXmlError(TEXT_WRITER_START_ELEMENT, rc);
1370 return PTS_INTERNAL_ERROR;
1373 /* QuoteInfo2 - start */
1374 rc = xmlTextWriterStartElement(writer, BAD_CAST "QuoteInfo2");
1376 displayXmlError(TEXT_WRITER_START_ELEMENT, rc);
1377 return PTS_INTERNAL_ERROR;
1380 /* QuoteInfo2 - attribute - Tag */
1381 snprintf(tagbuf, sizeof(tagbuf), "%d", tag);
1382 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "Tag", BAD_CAST tagbuf);
1384 displayXmlError(TEXT_WRITER_WRITE_ATTR, rc);
1385 return PTS_INTERNAL_ERROR;
1387 /* QuoteInfo2 - attribute - Fixed - char */
1388 DEBUG("fixed : %s", fixed);
1389 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "Fixed", BAD_CAST fixed);
1391 displayXmlError(TEXT_WRITER_WRITE_ATTR, rc);
1392 return PTS_INTERNAL_ERROR;
1394 /* QuoteInfo2 - attribute - ExternalData - base64 */
1395 b64buf = encodeBase64(
1396 (unsigned char *)ctx->validation_data->rgbExternalData,
1397 ctx->validation_data->ulExternalDataLength,
1399 if (b64buf == NULL) {
1400 LOG(LOG_ERR, "encodeBase64 fail");
1401 return PTS_INTERNAL_ERROR;
1403 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "ExternalData", BAD_CAST b64buf);
1406 // LOG(LOG_ERR, "Error at xmlTextWriterWriteAttribute\n");
1407 displayXmlError(TEXT_WRITER_WRITE_ATTR, rc);
1408 return PTS_INTERNAL_ERROR;
1411 /* PcrInfoShort - start */
1412 rc = xmlTextWriterStartElement(writer, BAD_CAST "PcrInfoShort");
1414 // LOG(LOG_ERR, "Error at xmlTextWriterStartElement\n");
1415 displayXmlError(TEXT_WRITER_START_ELEMENT, rc);
1416 return PTS_INTERNAL_ERROR;
1419 /* PcrSelection - start */
1420 rc = xmlTextWriterStartElement(writer, BAD_CAST "PcrSelection");
1422 // LOG(LOG_ERR, "Error at xmlTextWriterStartElement\n");
1423 displayXmlError(TEXT_WRITER_START_ELEMENT, rc);
1424 return PTS_INTERNAL_ERROR;
1426 /* Add an attribute with name "SizeOfSelect", int */
1427 snprintf(tagbuf, sizeof(tagbuf), "%d", size_of_select);
1428 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "SizeOfSelect", BAD_CAST tagbuf);
1430 // LOG(LOG_ERR, "Error at xmlTextWriterWriteAttribute\n");
1431 displayXmlError(TEXT_WRITER_WRITE_ATTR, rc);
1432 return PTS_INTERNAL_ERROR;
1434 /* Add an attribute with name "PcrSelect", base64 */
1435 b64buf = encodeBase64(
1436 (unsigned char *)select_byte,
1439 if (b64buf == NULL) {
1440 LOG(LOG_ERR, "encodeBase64 fail");
1441 return PTS_INTERNAL_ERROR;
1443 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "PcrSelect", BAD_CAST b64buf);
1446 displayXmlError(TEXT_WRITER_WRITE_ATTR, rc);
1447 return PTS_INTERNAL_ERROR;
1449 /* PcrSelection - end */
1450 rc = xmlTextWriterEndElement(writer);
1452 displayXmlError(TEXT_WRITER_END_ELEMENT, rc);
1453 return PTS_INTERNAL_ERROR;
1457 /* LocalityAtRelease - element */
1458 rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "LocalityAtRelease", "%d", locality);
1460 displayXmlError(TEXT_WRITER_WRITE_FORMAT_ELEMENT, rc);
1461 return PTS_INTERNAL_ERROR;
1464 /* CompositeHash - element */
1465 b64buf = encodeBase64(
1466 (unsigned char *)composite_hash,
1469 if (b64buf == NULL) {
1470 LOG(LOG_ERR, "encodeBase64 fail");
1471 return PTS_INTERNAL_ERROR;
1473 rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "CompositeHash", "%s", b64buf);
1476 displayXmlError(TEXT_WRITER_WRITE_FORMAT_ELEMENT, rc);
1477 return PTS_INTERNAL_ERROR;
1481 /* PcrComposite - start */
1482 rc = xmlTextWriterStartElement(writer, BAD_CAST "PcrComposit");
1484 // LOG(LOG_ERR, "Error at xmlTextWriterStartElement\n");
1485 displayXmlError(TEXT_WRITER_START_ELEMENT, rc);
1486 return PTS_INTERNAL_ERROR;
1489 /* PcrSelection - start */
1490 rc = xmlTextWriterStartElement(writer, BAD_CAST "PcrSelection");
1492 // LOG(LOG_ERR, "Error at xmlTextWriterStartElement\n");
1493 displayXmlError(TEXT_WRITER_START_ELEMENT, rc);
1494 return PTS_INTERNAL_ERROR;
1496 /* Add an attribute with name "SizeOfSelect", int */
1497 snprintf(tagbuf, sizeof(tagbuf), "%d", size_of_select);
1498 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "SizeOfSelect", BAD_CAST tagbuf);
1500 // LOG(LOG_ERR, "Error at xmlTextWriterWriteAttribute\n");
1501 displayXmlError(TEXT_WRITER_WRITE_ATTR, rc);
1502 return PTS_INTERNAL_ERROR;
1504 /* Add an attribute with name "PcrSelect", base64 */
1505 b64buf = encodeBase64(
1506 (unsigned char *)select_byte,
1509 if (b64buf == NULL) {
1510 LOG(LOG_ERR, "encodeBase64 fail");
1511 return PTS_INTERNAL_ERROR;
1513 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "PcrSelect", BAD_CAST b64buf);
1516 displayXmlError(TEXT_WRITER_WRITE_ATTR, rc);
1517 return PTS_INTERNAL_ERROR;
1519 /* PcrSelection - end */
1520 rc = xmlTextWriterEndElement(writer);
1522 displayXmlError(TEXT_WRITER_END_ELEMENT, rc);
1523 return PTS_INTERNAL_ERROR;
1525 /* ValueSize - element */
1526 rc = xmlTextWriterWriteFormatElement(writer, BAD_CAST "ValueSize", "%d", ctx->pcrs->value_size);
1528 displayXmlError(TEXT_WRITER_WRITE_FORMAT_ELEMENT, rc);
1529 return PTS_INTERNAL_ERROR;
1531 /* PcrValue, loop */
1532 for (i = 0; i < ctx->pcrs->pcr_num; i ++) {
1533 if (ctx->pcrs->pcr_select[i] == 1) {
1534 /* PcrValue - start */
1535 rc = xmlTextWriterStartElement(writer, BAD_CAST "PcrValue");
1537 // LOG(LOG_ERR, "Error at xmlTextWriterStartElement\n");
1538 displayXmlError(TEXT_WRITER_START_ELEMENT, rc);
1539 return PTS_INTERNAL_ERROR;
1541 /* Add an attribute - PcrNumber - int */
1542 snprintf(tagbuf, sizeof(tagbuf), "%d", i);
1543 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "PcrNumber", BAD_CAST tagbuf);
1545 // LOG(LOG_ERR, "Error at xmlTextWriterWriteAttribute\n");
1546 displayXmlError(TEXT_WRITER_WRITE_ATTR, rc);
1547 return PTS_INTERNAL_ERROR;
1551 /* Write a text, PCR, base64 */
1552 rc = xmlTextWriterWriteBase64(
1554 (const char *) ctx->pcrs->pcr[i],
1556 20); // TODO add length to OPENPTS_PCRS
1558 displayXmlError(TEXT_WRITER_WRITE_BASE64, rc);
1559 return PTS_INTERNAL_ERROR;
1562 /* PcrValue - end */
1563 rc = xmlTextWriterEndElement(writer);
1565 displayXmlError(TEXT_WRITER_END_ELEMENT, rc);
1566 return PTS_INTERNAL_ERROR;
1570 /* PcrComposite - end */
1571 rc = xmlTextWriterEndElement(writer);
1573 displayXmlError(TEXT_WRITER_END_ELEMENT, rc);
1574 return PTS_INTERNAL_ERROR;
1577 /* PcrInfoShort - end */
1578 rc = xmlTextWriterEndElement(writer);
1580 displayXmlError(TEXT_WRITER_END_ELEMENT, rc);
1581 return PTS_INTERNAL_ERROR;
1584 /* QuoteInfo2 - end */
1585 rc = xmlTextWriterEndElement(writer);
1587 displayXmlError(TEXT_WRITER_END_ELEMENT, rc);
1588 return PTS_INTERNAL_ERROR;
1592 rc = xmlTextWriterEndElement(writer);
1594 displayXmlError(TEXT_WRITER_END_ELEMENT, rc);
1595 return PTS_INTERNAL_ERROR;
1598 /* TpmSignature ------------------------------------ */
1600 /* Start an element named "TpmSignature" as child of QuoteData. */
1601 rc = xmlTextWriterStartElement(writer, BAD_CAST "TpmSignature");
1603 displayXmlError(TEXT_WRITER_START_ELEMENT, rc);
1604 return PTS_INTERNAL_ERROR;
1607 /* SignatureMethod */
1609 /* Start an element named "SignatureMethod" as child of TpmSignature. */
1610 rc = xmlTextWriterStartElement(writer, BAD_CAST "SignatureMethod");
1612 displayXmlError(TEXT_WRITER_START_ELEMENT, rc);
1613 return PTS_INTERNAL_ERROR;
1615 /* Add an attribute with name "Algorithm", string */
1616 rc = xmlTextWriterWriteAttribute(writer,
1617 BAD_CAST "Algorithm",
1618 BAD_CAST "http://www.w3.org/2000/09/xmldsig#rsa-sha1"); // TODO
1620 displayXmlError(TEXT_WRITER_WRITE_ATTR, rc);
1621 return PTS_INTERNAL_ERROR;
1623 /* Close the element named "SignatureMethod". */
1624 rc = xmlTextWriterEndElement(writer);
1626 displayXmlError(TEXT_WRITER_END_ELEMENT, rc);
1627 return PTS_INTERNAL_ERROR;
1630 /* SignatureValue */
1632 /* Start an element named "SignatureValue" as child of TpmSignature. */
1633 rc = xmlTextWriterStartElement(writer, BAD_CAST "SignatureValue");
1635 displayXmlError(TEXT_WRITER_START_ELEMENT, rc);
1636 return PTS_INTERNAL_ERROR;
1638 /* Write a text, signature, base64 */
1639 rc = xmlTextWriterWriteBase64(
1641 (const char *) ctx->validation_data->rgbValidationData,
1643 ctx->validation_data->ulValidationDataLength);
1645 displayXmlError(TEXT_WRITER_WRITE_BASE64, rc);
1646 return PTS_INTERNAL_ERROR;
1648 /* Close the element named "SignatureValue". */
1649 rc = xmlTextWriterEndElement(writer);
1651 displayXmlError(TEXT_WRITER_END_ELEMENT, rc);
1652 return PTS_INTERNAL_ERROR;
1655 /* Close the element named "TpmSignature". */
1656 rc = xmlTextWriterEndElement(writer);
1658 displayXmlError(TEXT_WRITER_END_ELEMENT, rc);
1659 return PTS_INTERNAL_ERROR;
1662 /* Close the element named "QuoteData". */
1663 rc = xmlTextWriterEndElement(writer);
1665 displayXmlError(TEXT_WRITER_END_ELEMENT, rc);
1666 return PTS_INTERNAL_ERROR;
1674 * generate IR in XML (common)
1676 * @param file - filename of generated IR
1677 * @param XX PCR select
1678 * @param XX AIK auth
1681 * return 0:success, -1:error
1682 * TODO PTS_SUCCESS PTS_XXX
1684 * @retval PTS_SUCCESS
1685 * @retval PTS_INTERNAL_ERROR
1690 OPENPTS_CONTEXT *ctx,
1691 const char *filenameDP, // in (set ctx->conf->ir_filename in normal operation)
1692 int *savedFd) // out
1694 int rc = PTS_SUCCESS;
1698 xmlTextWriterPtr writer;
1699 xmlBufferPtr xmlbuf;
1700 PTS_ComponentId cid;
1701 OPENPTS_TPM_CONTEXT tpm; // to calc snapshot PCR
1704 char *filename = NULL;
1706 PTS_Byte smbios[12] = { 0x4A, 0x4A, 0x4A, 0x4A, 0x4A,
1707 0x4A, 0x4A, 0x4A, 0x4A, 0x4A,
1711 OPENPTS_SNAPSHOT *ss;
1713 DEBUG_CAL("writeIr - start\n");
1717 LOG(LOG_ERR, "null input");
1722 // TODO(munetoh) dummy data
1723 cid.vendor.offset = 0;
1724 cid.vendor.length = 2;
1725 cid.simpleName.offset = 0;
1726 cid.simpleName.length = 2;
1727 cid.modelName.offset = 0;
1728 cid.modelName.length = 2;
1729 cid.modelNumber.offset = 0;
1730 cid.modelNumber.length = 2;
1731 cid.modelSerialNumber.offset = 0;
1732 cid.modelSerialNumber.length = 2;
1733 cid.modelSystemClass.offset = 0;
1734 cid.modelSystemClass.length = 2;
1736 cid.majorVersion = 0;
1737 cid.minorVersion = 1;
1738 cid.buildNumber = 0;
1740 cid.versionString.offset = 0;
1741 cid.versionString.length = 2;
1742 cid.patchLevel.offset = 0;
1743 cid.patchLevel.length = 2;
1744 cid.discretePatches.offset = 0;
1745 cid.discretePatches.length = 2;
1747 cid.buildDate.sec = 0;
1748 cid.buildDate.min = 0;
1749 cid.buildDate.hour = 0;
1750 cid.buildDate.mday = 0;
1751 cid.buildDate.mon = 0;
1752 cid.buildDate.wday = 0;
1753 cid.buildDate.yday = 0;
1754 cid.buildDate.isDst = 0;
1756 cid.dataBlock.blockSize = 0;
1757 cid.dataBlock.dataBlock = smbios;
1760 resetTpm(&tpm, ctx->drtm);
1762 /* Create a new XML buffer */
1763 xmlbuf = xmlBufferCreate();
1764 if (xmlbuf == NULL) {
1765 LOG(LOG_ERR, "creating the xml buffer fail\n");
1766 rc = PTS_INTERNAL_ERROR;
1770 /* Create a new XmlWriter for memory */
1771 writer = xmlNewTextWriterMemory(xmlbuf, 0);
1772 if (writer == NULL) {
1773 LOG(LOG_ERR, "creating the xml writer fail\n");
1774 rc = PTS_INTERNAL_ERROR;
1778 /* Start the document */
1779 rc = xmlTextWriterStartDocument(writer, "1.0", XML_ENCODING, "no");
1781 displayXmlError(TEXT_WRITER_START_DOC, rc);
1782 rc = PTS_INTERNAL_ERROR;
1786 /* Start an element named "Report", the root element of the document. */
1787 rc = xmlTextWriterStartElement(writer, BAD_CAST "Report");
1789 displayXmlError(TEXT_WRITER_START_ELEMENT, rc);
1790 rc = PTS_INTERNAL_ERROR;
1794 DEBUG_CAL("genIr - uuid done\n");
1796 /* Add an attribute of Schemas */
1797 rc = xmlTextWriterWriteAttribute(
1799 BAD_CAST "xmlns:core",
1800 BAD_CAST XMLNS_CORE);
1802 displayXmlError(TEXT_WRITER_WRITE_ATTR, rc);
1803 rc = PTS_INTERNAL_ERROR;
1807 rc = xmlTextWriterWriteAttribute(
1809 BAD_CAST "xmlns:stuff",
1810 BAD_CAST XMLNS_STUFF);
1812 displayXmlError(TEXT_WRITER_WRITE_ATTR, rc);
1813 rc = PTS_INTERNAL_ERROR;
1818 rc = xmlTextWriterWriteAttribute(
1820 BAD_CAST "xmlns:xsi",
1821 BAD_CAST "http://www.w3.org/2001/XMLSchema-instance");
1823 displayXmlError(TEXT_WRITER_WRITE_ATTR, rc);
1824 rc = PTS_INTERNAL_ERROR;
1828 rc = xmlTextWriterWriteAttribute(
1833 displayXmlError(TEXT_WRITER_WRITE_ATTR, rc);
1834 rc = PTS_INTERNAL_ERROR;
1839 ir_uuid = newUuid();
1840 if (ir_uuid == NULL) {
1841 LOG(LOG_ERR, "fail UUID generation\n");
1842 rc = PTS_INTERNAL_ERROR;
1846 str_ir_uuid = getStringOfUuid(ir_uuid);
1847 if (str_ir_uuid == NULL) {
1848 LOG(LOG_ERR, "fail UUID generation\n");
1849 rc = PTS_INTERNAL_ERROR;
1854 /* Add an attribute with name Document ID */
1855 snprintf(id, sizeof(id), "IR_%s", str_ir_uuid);
1857 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "ID", BAD_CAST id);
1859 displayXmlError(TEXT_WRITER_WRITE_ATTR, rc);
1860 rc = PTS_INTERNAL_ERROR;
1864 /* Add an attribute with name UUID */
1865 rc = xmlTextWriterWriteAttribute(
1866 writer, BAD_CAST "UUID", BAD_CAST str_ir_uuid);
1868 displayXmlError(TEXT_WRITER_WRITE_ATTR, rc);
1869 rc = PTS_INTERNAL_ERROR;
1872 // TODO(munetoh) SnapshotCollection Loop by selected PCR
1875 if (ctx->conf->iml_mode == 0) {
1876 if (ctx->conf->ir_without_quote == 1) {
1877 LOG(LOG_TODO, "skip TPM_Quote\n");
1879 if (ctx->conf->tpm_quote_type == 1) {
1881 rc = writeQuote(writer, ctx);
1883 LOG(LOG_ERR, "writeIr - writeQuote() rc = %d\n", rc);
1884 rc = PTS_INTERNAL_ERROR;
1889 rc = writeQuote2(writer, ctx);
1891 LOG(LOG_ERR, "writeIr - writeQuote2() rc = %d\n", rc);
1892 rc = PTS_INTERNAL_ERROR;
1898 // DEBUG("iml.mode!=tss, skip writeQuote()\n");
1902 DEBUG_CAL("genIr - start snapshot\n");
1904 for (i = 0; i < MAX_PCRNUM; i++) {
1905 /* level 0, platform */
1906 ss = getSnapshotFromTable(ctx->ss_table, i, 0);
1908 if (ss->event_num > 0) {
1910 // LOG(LOG_ERR, "writeIr PCR[%d] LV0 num=%d\n", i,ss->event_num);
1911 writeSnapshot(writer, &tpm, &cid, i, ss);
1915 /* level 1, runtime */
1916 ss = getSnapshotFromTable(ctx->ss_table, i, 1);
1918 if (ss->event_num > 0) {
1919 // LOG(LOG_ERR, "writeIr PCR[%d] LV1 num=%d\n", i,ss->event_num);
1920 // writeSnapshot(writer, &tpm, &cid, i, ss);
1921 if (i == OPENPTS_PCR_INDEX) {
1922 DEBUG("genIr - Not writing snapshot for OPENPTS_PCR_INDEX (%d)\n",
1925 writeSnapshot(writer, &tpm, &cid, i, ss);
1931 /* Close all elements */
1932 rc = xmlTextWriterEndDocument(writer);
1934 displayXmlError(TEXT_WRITER_END_DOC, rc);
1935 rc = PTS_INTERNAL_ERROR;
1939 rc = xmlTextWriterFlush(writer);
1941 // LOG(LOG_ERR, "writeRm: Error at xmlTextWriterFlush\n");
1942 displayXmlError(TEXT_WRITER_FLUSH, rc);
1943 rc = PTS_INTERNAL_ERROR;
1947 /* Close all elements */
1948 rc = xmlTextWriterEndDocument(writer);
1950 LOG(LOG_ERR, "testXmlwriterMemory: Error at xmlTextWriterEndDocument\n");
1951 rc = PTS_INTERNAL_ERROR;
1957 /* check filename */
1958 if (filenameDP != NULL) {
1959 /* use given filename for the Unit Test*/
1961 /* create new IR filename, save to ctx->ir_filename */
1963 /* use default filename */
1964 if (ctx->conf->ir_dir == NULL) {
1965 LOG(LOG_ERR, "Set ir.dir in %s.\n", ctx->conf->config_file);
1966 ctx->conf->ir_dir = smalloc("/tmp/.ptsc");
1968 snprintf(buf, sizeof(buf), "%s_%s.xml",
1972 ctx->ir_filename = getFullpathName(ctx->conf->ir_dir, buf);
1973 filenameDP = ctx->ir_filename;
1976 //filename = ctx->ir_filename;
1977 DEBUG("Write Integrity Report (IR) : %s\n", filenameDP); //filename);
1980 xmlFreeTextWriter(writer);
1982 irFd = open(filenameDP, O_CREAT | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR);
1984 LOG(LOG_ERR, "Failed to open ir file '%s' for writing, errno = %d\n", filename, errno);
1985 rc = PTS_INTERNAL_ERROR;
1989 /* If savedFd is not NULL, the user wanted a little bit extra security
1990 by not leaving the file lying around on the filesystem to be read/hacked/etc.
1991 This is most useful during verification when running "ptsc -m". Anyway,
1992 serious hackers probably wouldn't be deterred by this ... */
1993 if (NULL != savedFd &&
1994 -1 == unlink(filenameDP)) {
1995 LOG(LOG_ERR, "Failed to unlink file '%s', errno = %d\n", filename, errno);
1998 lengthOfIrFile = xmlbuf->use;
2000 int writeRc = write(irFd, xmlbuf->content, lengthOfIrFile);
2001 if ( lengthOfIrFile != writeRc ) {
2002 LOG(LOG_ERR, "Failed to write contents to IR file - rc %d, errno %d\n", writeRc, errno);
2003 rc = PTS_INTERNAL_ERROR;
2006 rc = PTS_SUCCESS; // 0
2007 if (NULL != savedFd) {
2009 /* keep the file open - the caller will close it later */
2021 xmlBufferFree(xmlbuf);
2024 DEBUG_CAL("writeIr - done\n");
2031 <Report xmlns:core="http://www.trustedcomputinggroup.org/XML/SCHEMA/1_0_1/core_integrity#" xmlns:stuff="http://www.trustedcomputinggroup.org/XML/SCHEMA/1_0/simple_object#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.trustedcomputinggroup.org/XML/SCHEMA/1_0/integrity_report#" ID="IR_24868831-1b3c-4eb5-8e15-83b74f54d033" UUID="24868831-1b3c-4eb5-8e15-83b74f54d033">
2032 <SnapshotCollection Id="IR_1bd0ac8f-d091-4a14-af05-651386f312a1" UUID="1bd0ac8f-d091-4a14-af05-651386f312a1" RevLevel="0">
2033 <core:ComponentID Id="CID_0" ModelSystemClass="745749J" SimpleName="JJ" VersionBuild="1250694000000" VersionString="JJ">
2034 <core:VendorID Name="JJ">
2035 <core:SmiVendorId>0</core:SmiVendorId>
2036 <core:TcgVendorId>DEMO</core:TcgVendorId>
2039 <core:DigestMethod Algorithm="unknown" Id="sha1"/>
2041 <stuff:SimpleSnapshotObject>
2043 <stuff:Hash AlgRef="sha1" Id="PCR_0_LV0_8_0_EVENT">VnKCP/hHGXIdJtuXyR1gR7HnqXs=</stuff:Hash>
2044 <pcrindex>0</pcrindex>
2045 <eventtype>8</eventtype>
2046 <eventdata>CAD+//////8FAAAA</eventdata>
2050 <PcrHash AlgRef="sha1" Id="PCR_0_LV0_HASH" IsResetable="false" Number="0" StartHash="AAAAAAAAAAAAAAAAAAAAAAAAAAA=">j7/z7OqcVMjRxCz+qT1r8BvzQFs=</Pc
2052 </SnapshotCollection>
2057 #define IR_SAX_BUFFER_SIZE 2048
2062 void irStartDocument(void * ctx) {
2063 OPENPTS_CONTEXT * pctx = (OPENPTS_CONTEXT *)ctx;
2064 OPENPTS_IR_CONTEXT * ir_ctx = pctx->ir_ctx;
2068 LOG(LOG_ERR, "null input");
2072 ir_ctx->sax_error = 0;
2073 ir_ctx->event_index = 0;
2082 void irEndDocument(void * ctx) {
2085 LOG(LOG_ERR, "null input");
2090 /* This prevents real world buffer over-run attacks using malformed IRs
2091 where pcr is basically an index onto the heap or stack. It has been
2092 already been demonstrated that this type of attack could fool the verifier
2093 wrongly into presenting a valid attestation of a compromised system. */
2094 static int getPcrIndexFromIR(char *value) {
2095 unsigned int index = atoi(value);
2098 if (value == NULL) {
2099 LOG(LOG_ERR, "null input");
2103 index = atoi(value);
2104 if ( index > MAX_PCRNUM ) {
2112 * SAX parser - Start of Element
2114 void irStartElement(void* ctx, const xmlChar* name, const xmlChar** atts) {
2115 OPENPTS_CONTEXT * pctx;
2116 OPENPTS_IR_CONTEXT * ir_ctx;
2117 TSS_VALIDATION *validation_data;
2119 BYTE *b64buf = NULL;
2127 LOG(LOG_ERR, "null input");
2130 pctx = (OPENPTS_CONTEXT *)ctx;
2131 ir_ctx = pctx->ir_ctx;
2132 if (ir_ctx == NULL) {
2133 LOG(LOG_ERR, "null input");
2138 LOG(LOG_ERR, "null input");
2142 LOG(LOG_ERR, "null input");
2145 validation_data = pctx->validation_data; // ckeck later
2148 ir_ctx->char_size = 0;
2150 if (!strcmp((char *)name, "Report")) {
2152 } else if (!strcmp((char *)name, "SnapshotCollection")) {
2154 } else if (!strcmp((char *)name, "core:ComponentID")) {
2156 } else if (!strcmp((char *)name, "core:VendorID")) {
2158 } else if (!strcmp((char *)name, "core:TcgVendorId")) {
2160 } else if (!strcmp((char *)name, "core:SmiVendorId")) {
2162 } else if (!strcmp((char *)name, "core:DigestMethod")) {
2164 } else if (!strcmp((char *)name, "core:Values")) {
2166 } else if (!strcmp((char *)name, "stuff:SimpleSnapshotObject")) {
2168 } else if (!strcmp((char *)name, "pcrindex")) {
2169 /* stuff:Hash -> PCR value (base64) */
2170 // DEBUG("START ELEMENT [%s] <<<< HASH HASH \n",name);
2171 // ir_ctx->sax_state = IR_SAX_STATE_PCR_INDEX;
2173 } else if (!strcmp((char *)name, "eventtype")) {
2174 // DEBUG("START ELEMENT [%s] <<<< HASH HASH \n",name);
2175 // ir_ctx->sax_state = IR_SAX_STATE_EVENT_TYPE;
2177 } else if (!strcmp((char *)name, "stuff:Hash")) {
2178 // DEBUG("START ELEMENT [%s] <<<< DIGEST \n",name);
2179 // ir_ctx->sax_state = IR_SAX_STATE_DIGEST;
2181 } else if (!strcmp((char *)name, "eventdata")) {
2182 // DEBUG("START ELEMENT [%s] <<<< EVENT_DATA\n",name);
2183 // ir_ctx->sax_state = IR_SAX_STATE_EVENT_DATA;
2185 } else if (!strcmp((char *)name, "PcrHash")) {
2186 // DEBUG("START ELEMENT [%s] <<<< EVENT_DATA\n",name);
2187 // ir_ctx->sax_state = IR_SAX_STATE_PCR;
2189 /* get Number =pcrindex) attribute ( */
2191 for (i = 0;(atts[i] != NULL);i++) {
2192 type = (char *)atts[i++];
2193 if (atts[i] != NULL) {
2194 value= (char *)atts[i];
2195 if (!strcmp(type, "Number")) {
2196 ir_ctx->pcr_index = getPcrIndexFromIR(value);
2201 } else if (!strcmp((char *)name, "stuff:Objects")) {
2204 ir_ctx->event = (TSS_PCR_EVENT *) xmalloc(sizeof(TSS_PCR_EVENT));
2205 if (ir_ctx->event == NULL) {
2208 memset(ir_ctx->event, 0, sizeof(TSS_PCR_EVENT));
2210 } else if (!strcmp((char *)name, "QuoteData")) {
2212 // <QuoteData ID="TBD">...
2215 pcrs = xmalloc_assert(sizeof(OPENPTS_PCRS));
2217 memset(pcrs, 0, sizeof(OPENPTS_PCRS));
2219 // DEBUG("malloc OPENPTS_PCRS %p\n", pcrs);
2221 if (validation_data == NULL) {
2222 validation_data = xmalloc_assert(sizeof(TSS_VALIDATION));
2224 memset(validation_data, 0, sizeof(TSS_VALIDATION));
2225 pctx->validation_data = validation_data;
2226 // DEBUG("malloc TSS_VALIDATION %p\n", validation_data);
2228 } else if (!strcmp((char *)name, "Quote")) {
2230 } else if (!strcmp((char *)name, "Quote2")) {
2232 } else if (!strcmp((char *)name, "PcrComposit")) {
2234 } else if (!strcmp((char *)name, "PcrSelection")) {
2236 // <PcrSelection SizeOfSelect="3" PcrSelect="/6AA"/>
2237 // SizeOfSelect => ctx->pcrs->pcr_select_size
2238 // PcrSelect => ctx->pcrs->pcr_select
2239 // note) PcrSelection is not used to verify the quote. - 20101125 SM
2241 for (i = 0;(atts[i] != NULL);i++) {
2242 type = (char *)atts[i++];
2243 if (atts[i] != NULL) {
2244 value= (char *)atts[i];
2245 if (!strcmp(type, "SizeOfSelect")) {
2246 /* TPM1.2 - 24 PCRS -> 3 */
2247 pcrs->pcr_select_size = atoi(value);
2249 // DEBUG("SizeOfSelect = %d\n", ir_ctx->pcr_select_size);
2251 if (!strcmp(type, "PcrSelect")) {
2253 if (b64buf != NULL) {
2254 LOG(LOG_ERR, "bad memory management");
2257 b64buf = (BYTE *) decodeBase64(
2262 // DEBUG("PcrSelect = 0x%02x %02x %02x \n", buf[0],buf[1],buf[2]);
2263 if (b64buf == NULL) {
2264 LOG(LOG_ERR, "Failed to decode base64 string\n");
2265 ir_ctx->sax_error++;
2266 pcrs->pcr_select_size = 0;
2274 /* set pcr_select */
2275 // if (pcrs->pcr_select_size > 0) {
2276 if (attr_cnt == 2) {
2277 // ir_ctx->pcrs->pcr_select_byte
2278 if (pcrs->pcr_select_byte != NULL) {
2279 xfree(pcrs->pcr_select_byte);
2281 pcrs->pcr_select_byte = xmalloc(pcrs->pcr_select_size);
2282 if (pcrs->pcr_select_byte != NULL) {
2283 if (b64buf != NULL) {
2284 memcpy(pcrs->pcr_select_byte, b64buf, pcrs->pcr_select_size);
2286 LOG(LOG_ERR, "pcr_select_byte is missing");
2289 LOG(LOG_ERR, "no memory\n");
2293 LOG(LOG_ERR, "BAD IR SizeOfSelect or PcrSelect are missing\n");
2295 /* free Base64 buffer */
2296 if (b64buf != NULL) {
2300 } else if (!strcmp((char *)name, "ValueSize")) {
2301 // <ValueSize>200</ValueSize>
2302 // Text => ctx->pcrs->value_size - irEndElement()
2303 } else if (!strcmp((char *)name, "PcrValue")) {
2304 // <PcrValue PcrNumber="0">j7/z7OqcVMjRxCz+qT1r8BvzQFs=</PcrValue>
2305 // PcrNumber => ir_ctx->pcr_index
2306 // Text => ir_ctx->pcr
2308 for (i = 0;(atts[i] != NULL);i++) {
2309 type = (char *)atts[i++];
2310 if (atts[i] != NULL) {
2311 value= (char *)atts[i];
2312 if (!strcmp(type, "PcrNumber")) {
2313 ir_ctx->pcr_index = getPcrIndexFromIR(value);
2318 } else if (!strcmp((char *)name, "QuoteInfo")) {
2319 // <QuoteInfo VersionMajor="1" VersionMinor="2" VersionRevMajor="0" VersionRevMinor="0" Fixed="QUOT"
2320 // DigestValue="AQEAAFFVT1RjiS4FS/WTFp0ynrVBQKD559YRGnM9C4gDMct9ZZo5kd8yf2tW46Qs"
2321 // ExternalData="cz0LiAMxy31lmjmR3zJ/a1bjpCw="/>
2323 // DEBUG("QuoteInfo attribute\n");
2324 // DigestValue=base64,
2325 // ExternalData=base64
2327 for (i = 0;(atts[i] != NULL);i++) {
2328 type = (char *)atts[i++];
2330 if (validation_data == NULL) {
2331 LOG(LOG_ERR, "validation_data == NULL");
2334 if (validation_data->rgbData == NULL) {
2336 validation_data->ulDataLength = 48;
2337 validation_data->rgbData = xmalloc_assert(48);
2340 if (atts[i] != NULL) {
2341 value= (char *)atts[i];
2342 if (!strcmp(type, "VersionMajor")) {
2343 validation_data->versionInfo.bMajor = atoi(value);
2344 validation_data->rgbData[0] = atoi(value);
2346 if (!strcmp(type, "VersionMinor")) {
2347 validation_data->versionInfo.bMinor = atoi(value);
2348 validation_data->rgbData[1] = atoi(value);
2350 if (!strcmp(type, "VersionRevMajor")) {
2351 validation_data->versionInfo.bRevMajor = atoi(value);
2352 validation_data->rgbData[2] = atoi(value);
2354 if (!strcmp(type, "VersionRevMinor")) {
2355 validation_data->versionInfo.bRevMinor = atoi(value);
2356 validation_data->rgbData[3] = atoi(value);
2358 if (!strcmp(type, "Fixed")) {
2360 validation_data->rgbData[4] = value[0];
2361 validation_data->rgbData[5] = value[1];
2362 validation_data->rgbData[6] = value[2];
2363 validation_data->rgbData[7] = value[3];
2365 if (!strcmp(type, "DigestValue")) {
2366 // TODO check buf len
2367 b64buf = decodeBase64(
2371 if (b64buf == NULL) {
2372 LOG(LOG_ERR, "decodeBase64 fail");
2373 ir_ctx->sax_error++;
2374 return; // TODO return?
2376 if (b64buf_len == 20) {
2377 memcpy(&validation_data->rgbData[8], b64buf, 20);
2379 LOG(LOG_ERR, "size of decodeBase64 out is not 20 but %d", b64buf_len);
2380 ir_ctx->sax_error++;
2386 if (!strcmp(type, "ExternalData")) {
2387 b64buf = decodeBase64(
2391 if (b64buf == NULL) {
2392 LOG(LOG_ERR, "decodeBase64 fail");
2393 ir_ctx->sax_error++;
2396 if (b64buf_len == 20) {
2397 validation_data->ulExternalDataLength = b64buf_len;
2398 if (validation_data->rgbExternalData != NULL) {
2399 free(validation_data->rgbExternalData);
2401 validation_data->rgbExternalData = b64buf;
2403 // memcpy(validation_data->rgbExternalData, buf, rc);
2404 memcpy(&validation_data->rgbData[28], b64buf, 20);
2406 LOG(LOG_ERR, "Failed to decode base64 string, len = %d not 20\n", b64buf_len);
2407 ir_ctx->sax_error++;
2414 } else if (!strcmp((char *)name, "QuoteInfo2")) {
2415 // <QuoteInfo2 Tag="54" Fixed="QUT2" ExternalData="WlpaWlpaWlpaWlpaWlpaWlpaWlo=">
2417 for (i = 0;(atts[i] != NULL);i++) {
2418 type = (char *)atts[i++];
2420 if (validation_data == NULL) {
2421 LOG(LOG_ERR, "validation_data == NULL");
2424 if (validation_data->rgbData == NULL) {
2426 validation_data->ulDataLength = 52;
2427 validation_data->rgbData = xmalloc_assert(52);
2430 if (atts[i] != NULL) {
2431 value= (char *)atts[i];
2432 if (!strcmp(type, "Tag")) {
2433 int tag = atoi(value);
2434 validation_data->rgbData[0] = (tag >> 8) & 0xFF;
2435 validation_data->rgbData[1] = tag & 0xFF;
2437 if (!strcmp(type, "Fixed")) {
2439 validation_data->rgbData[2] = value[0];
2440 validation_data->rgbData[3] = value[1];
2441 validation_data->rgbData[4] = value[2];
2442 validation_data->rgbData[5] = value[3];
2444 if (!strcmp(type, "ExternalData")) {
2445 b64buf = decodeBase64(
2449 if (b64buf == NULL) {
2450 LOG(LOG_ERR, "decodeBase64 fail");
2451 ir_ctx->sax_error++;
2454 if (b64buf_len == 20) {
2455 validation_data->ulExternalDataLength = b64buf_len;
2456 validation_data->rgbExternalData = b64buf;
2457 // memcpy(validation_data->rgbExternalData, b64buf, rc);
2458 memcpy(&validation_data->rgbData[6], b64buf, 20);
2460 LOG(LOG_ERR, "Failed to decode base64 string, len = %d not 20\n", b64buf_len);
2461 ir_ctx->sax_error++;
2468 } else if (!strcmp((char *)name, "PcrInfoShort")) {
2470 } else if (!strcmp((char *)name, "LocalityAtRelease")) {
2472 } else if (!strcmp((char *)name, "CompositeHash")) {
2474 } else if (!strcmp((char *)name, "TpmSignature")) {
2476 } else if (!strcmp((char *)name, "SignatureMethod")) {
2478 } else if (!strcmp((char *)name, "SignatureValue")) {
2479 // DONE LOG(LOG_TODO, "get value(base64)\n");
2480 } else if (!strcmp((char *)name, "KeyInfo")) {
2482 } else if (!strcmp((char *)name, "KeyValue")) {
2483 // DONE LOG(LOG_TODO, "get value(base64)\n");
2484 } else { /* Else? */
2485 LOG(LOG_ERR, "START ELEMENT [%s] \n", name);
2486 ir_ctx->sax_state = IR_SAX_STATE_IDOL;
2491 * SAX parser - End of Element
2493 void irEndElement(void * ctx, const xmlChar * name) {
2494 OPENPTS_CONTEXT * pctx;
2495 OPENPTS_IR_CONTEXT * ir_ctx;
2496 TSS_VALIDATION *validation_data;
2499 BYTE *b64buf = NULL;
2504 LOG(LOG_ERR, "null input");
2507 pctx = (OPENPTS_CONTEXT *)ctx;
2508 ir_ctx = pctx->ir_ctx;
2509 if (ir_ctx == NULL) {
2510 LOG(LOG_ERR, "null input");
2515 LOG(LOG_ERR, "null input");
2519 LOG(LOG_ERR, "null input");
2522 validation_data = pctx->validation_data; // ckeck later
2525 if (!strcmp((char *)name, "stuff:Objects")) {
2528 BYTE* digest = NULL;
2530 /* Event finish, let's get into our structure */
2531 ir_ctx->event_index++;
2533 /* Add new event wrapper and update the chain */
2534 ir_ctx->ew_last = ir_ctx->ew_new;
2536 ir_ctx->ew_new = (OPENPTS_PCR_EVENT_WRAPPER *)
2537 xmalloc(sizeof(OPENPTS_PCR_EVENT_WRAPPER));
2538 if (ir_ctx->ew_new == NULL) {
2539 ir_ctx->sax_error++;
2542 memset(ir_ctx->ew_new, 0, sizeof(OPENPTS_PCR_EVENT_WRAPPER));
2544 /* set the event structure */
2545 if (ir_ctx->event == NULL) {
2546 LOG(LOG_ERR, "internal error\n");
2547 ir_ctx->ew_new->event = NULL;
2548 ir_ctx->sax_error++;
2550 /* TPM extend - after FSM push */
2552 pcr_index = ir_ctx->event->ulPcrIndex;
2553 digest = ir_ctx->event->rgbPcrValue;
2555 /* move to the EW chain */
2556 ir_ctx->ew_new->event = ir_ctx->event;
2557 ir_ctx->event = NULL;
2560 /* map to the snapshot, push FSM */
2561 rc = addEventToSnapshotBin(pctx, ir_ctx->ew_new); // iml.c
2562 if (rc != PTS_SUCCESS) {
2563 // LOG(LOG_ERR, "validateIr:irStartElement - addEventToSnapshotBin rc = %d\n", rc);
2564 ir_ctx->integrity = OPENPTS_RESULT_INVALID;
2567 /* extend after FSM push. after execution of Action() in FSM */
2576 } else if (!strcmp((char *)name, "SnapshotCollection")) {
2577 /* snapshot finish */
2578 /* Push FSM until Final state to run actions */
2580 rc = flashSnapshot(pctx, ir_ctx->pcr_index); // iml.c
2581 if (rc == PTS_INVALID_SNAPSHOT) {
2582 DEBUG_FSM("irEndElement() -- SS has validation error\n");
2583 ir_ctx->fsm_error_count++;
2584 } else if (rc != PTS_SUCCESS) {
2585 LOG(LOG_ERR, "SnapshotCollection -> FSM flash was fail\n");
2586 ir_ctx->sax_error++;
2589 } else if (!strcmp((char *)name, "pcrindex")) {
2590 ir_ctx->buf[ir_ctx->char_size] = 0;
2591 // ir_ctx->event->ulPcrIndex = atoi(ir_ctx->buf);
2592 ir_ctx->event->ulPcrIndex = getPcrIndexFromIR(ir_ctx->buf);
2593 } else if (!strcmp((char *)name, "stuff:Hash")) {
2594 ir_ctx->buf[ir_ctx->char_size] = 0;
2595 /* base64 -> plain */
2596 ir_ctx->event->rgbPcrValue = decodeBase64(
2597 (char *)ir_ctx->buf,
2600 if (ir_ctx->event->rgbPcrValue == NULL) {
2601 LOG(LOG_ERR, "decodeBase64 fail");
2602 ir_ctx->sax_error++;
2605 ir_ctx->event->ulPcrValueLength = b64buf_len;
2607 } else if (!strcmp((char *)name, "eventtype")) {
2608 ir_ctx->buf[ir_ctx->char_size] = 0;
2609 ir_ctx->event->eventType = atoi(ir_ctx->buf);
2610 } else if (!strcmp((char *)name, "eventdata")) {
2611 ir_ctx->buf[ir_ctx->char_size] = 0; // null terminate
2612 /* base64 -> plain */
2613 ir_ctx->event->rgbEvent = decodeBase64(
2614 (char *)ir_ctx->buf,
2617 if (ir_ctx->event->rgbEvent == NULL) {
2618 LOG(LOG_ERR, "decodeBase64 fail");
2619 ir_ctx->sax_error++;
2622 ir_ctx->event->ulEventLength = b64buf_len;
2624 } else if (!strcmp((char *)name, "PcrHash")) {
2626 ir_ctx->buf[ir_ctx->char_size] = 0; // null terminate
2627 /* base64 -> plain */
2628 b64buf = decodeBase64(
2629 (char *)ir_ctx->buf,
2632 if (b64buf == NULL) {
2633 LOG(LOG_ERR, "decodeBase64 fail");
2634 ir_ctx->sax_error++;
2637 if (b64buf_len > MAX_DIGEST_SIZE) {
2638 LOG(LOG_ERR, "decodeBase64 out is too latge, %d > %d",
2639 b64buf_len, MAX_DIGEST_SIZE);
2640 ir_ctx->sax_error++;
2643 memcpy(ir_ctx->pcr, b64buf, b64buf_len);
2646 /* Check with PCR in TPM */
2647 rc = checkTpmPcr2(&pctx->tpm, ir_ctx->pcr_index, ir_ctx->pcr);
2648 if (rc != PTS_SUCCESS) {
2649 LOG(LOG_ERR, "ERROR PCR[%d] != IML\n", ir_ctx->pcr_index);
2650 ir_ctx->sax_error = 1;
2651 // verbose = DEBUG_FLAG | DEBUG_TPM_FLAG; // switch DEBUG MODE
2652 if (isDebugFlagSet(DEBUG_FLAG)) {
2654 DEBUG("PCR[%d]\n", ir_ctx->pcr_index);
2655 getTpmPcrValue(&pctx->tpm, ir_ctx->pcr_index, pcr);
2656 debugHex("", pcr, 20, " (emulated)\n");
2657 debugHex("", ir_ctx->pcr, 20, " (IR)\n");
2660 /* IML and PCR are consistent :-) */
2661 DEBUG_FSM("PCR[%d] == IML\n", ir_ctx->pcr_index);
2662 // TODO(munetoh) add property? tpm.pcr.N.snapshot.N.integrity=valid
2664 /* update pcrs, used by validatePcrCompositeV11 */
2665 if (pctx->conf->iml_mode == 0) {
2667 /* malloc OPENPTS_PCRS */
2668 // LOG(LOG_ERR, "PCR is not intialized - No QuoteData element\n");
2669 pcrs = xmalloc(sizeof(OPENPTS_PCRS));
2671 LOG(LOG_ERR, "no memory\n");
2674 memset(pcrs, 0, sizeof(OPENPTS_PCRS));
2677 // TODO PcrValue and PcrHash
2678 // pcrs->pcr_select[ir_ctx->pcr_index] = 1;
2679 // memcpy(pcrs->pcr[ir_ctx->pcr_index], ir_ctx->pcr, 20); // TODO pcr size
2682 // DEBUG("iml.mode!=tss, skip pcr copy to PCRS\n");
2685 } else if (!strcmp((char *)name, "LocalityAtRelease")) {
2687 if (validation_data == NULL) {
2688 LOG(LOG_ERR, "validation_data == NULL");
2691 validation_data->rgbData[31] = atoi(ir_ctx->buf);
2692 } else if (!strcmp((char *)name, "CompositeHash")) {
2693 // DEBUG("CompositeHash %s", ir_ctx->buf);
2694 if (validation_data == NULL) {
2695 LOG(LOG_ERR, "validation_data == NULL");
2698 b64buf = decodeBase64(
2699 (char *)ir_ctx->buf,
2702 if (b64buf == NULL) {
2703 LOG(LOG_ERR, "decodeBase64 fail");
2704 ir_ctx->sax_error++;
2707 memcpy(&validation_data->rgbData[32], b64buf, 20);
2709 } else if (!strcmp((char *)name, "ValueSize")) {
2710 // <ValueSize>200</ValueSize>
2711 // Text => ctx->pcrs->value_size
2712 ir_ctx->buf[ir_ctx->char_size] = 0; // end of string
2713 pcrs->value_size = atoi(ir_ctx->buf);
2714 } else if (!strcmp((char *)name, "PcrValue")) {
2715 // <PcrValue PcrNumber="0">j7/z7OqcVMjRxCz+qT1r8BvzQFs=</PcrValue>
2716 // Text => ctx->pcrs->pcr[0]
2717 ir_ctx->buf[ir_ctx->char_size] = 0;
2718 b64buf = decodeBase64(
2719 (char *)ir_ctx->buf,
2722 if (b64buf == NULL) {
2723 LOG(LOG_ERR, "decodeBase64 fail");
2724 ir_ctx->sax_error++;
2727 if (b64buf_len < SHA1_DIGEST_SIZE) {
2728 LOG(LOG_ERR, "decodeBase64 outout is too small, %d < %d", b64buf_len, SHA1_DIGEST_SIZE);
2729 ir_ctx->sax_error++;
2732 if (b64buf_len > MAX_DIGEST_SIZE) {
2733 LOG(LOG_ERR, "decodeBase64 outout is too large, %d < %d", b64buf_len, MAX_DIGEST_SIZE);
2734 ir_ctx->sax_error++;
2738 memcpy(pcrs->pcr[ir_ctx->pcr_index], b64buf, b64buf_len);
2741 pcrs->pcr_select[ir_ctx->pcr_index] = 1;
2743 // DEBUG("PCR[%d] base64=%s\n", ir_ctx->pcr_index,ir_ctx->buf);
2744 // printHex("", (BYTE *)pcrs->pcr[ir_ctx->pcr_index], 20, "\n");
2746 // DEBUG("set reference PCR values\n");
2748 // tpm.quote.pcr.0=base64
2749 // note) Do not use PCR10(IMA) as policy
2751 snprintf(name, sizeof(name), "disable.quote.pcr.%d", ir_ctx->pcr_index);
2752 if (NULL != getProperty(ctx, name)) {
2753 DEBUG("Found disabled quote property '%s'\n", name);
2754 snprintf(name, sizeof(name), "# tpm.quote.pcr.%d", ir_ctx->pcr_index);
2756 snprintf(name, sizeof(name), "tpm.quote.pcr.%d", ir_ctx->pcr_index);
2758 addProperty(ctx, name, ir_ctx->buf);
2761 // snprintf(buf2, sizeof(buf2), "tpm.quote.pcr.%d", ir_ctx->pcr_index);
2762 // addProperty(ctx, buf2, ir_ctx->buf);
2764 } else if (!strcmp((char *)name, "QuoteInfo2")) {
2765 /* pcr select => validation_data */
2766 if (pcrs->pcr_select_byte == NULL) {
2767 LOG(LOG_ERR, "pcrs->pcr_select_byte is null");
2769 if (validation_data == NULL) {
2770 LOG(LOG_ERR, "validation_data == NULL");
2773 validation_data->rgbData[26] = 0;
2774 validation_data->rgbData[27] = pcrs->pcr_select_size;
2775 validation_data->rgbData[28] = pcrs->pcr_select_byte[0];
2776 validation_data->rgbData[29] = pcrs->pcr_select_byte[1];
2777 validation_data->rgbData[30] = pcrs->pcr_select_byte[2];
2779 } else if (!strcmp((char *)name, "SignatureValue")) {
2780 ir_ctx->buf[ir_ctx->char_size] = 0;
2781 if (ir_ctx->char_size > IR_SAX_BUFFER_SIZE) { // TODO check buf size
2782 LOG(LOG_ERR, "buf is small %d \n", ir_ctx->char_size);
2783 ir_ctx->sax_error++;
2785 if (validation_data == NULL) {
2786 LOG(LOG_ERR, "validation_data == NULL");
2789 if (validation_data->rgbValidationData != NULL) {
2790 xfree(validation_data->rgbValidationData);
2792 /* base64 -> plain */
2793 validation_data->rgbValidationData = decodeBase64(
2794 (char *)ir_ctx->buf,
2797 if (validation_data->rgbValidationData == NULL) {
2798 LOG(LOG_ERR, "decodeBase64 fail");
2799 ir_ctx->sax_error++;
2802 validation_data->ulValidationDataLength = b64buf_len;
2804 } else if (!strcmp((char *)name, "KeyValue")) {
2805 ir_ctx->buf[ir_ctx->char_size] = 0;
2806 if (ir_ctx->char_size > IR_SAX_BUFFER_SIZE) { // TODO check buf size
2807 LOG(LOG_ERR, "buf is small %d \n", ir_ctx->char_size);
2809 pcrs->pubkey = decodeBase64(
2810 (char *)ir_ctx->buf,
2813 if (pcrs->pubkey == NULL) {
2814 LOG(LOG_ERR, "decodeBase64 fail");
2815 ir_ctx->sax_error++;
2818 pcrs->pubkey_length = b64buf_len;
2820 } else if (!strcmp((char *)name, "QuoteData")) {
2822 /* Validate QuoteData */
2824 if ( ir_ctx->sax_error > 0 ) {
2825 LOG(LOG_ERR, "Unable to validate quote data due to %d SAX parse errors\n", ir_ctx->sax_error);
2827 rc = validateQuoteData(pcrs, validation_data);
2828 // DEBUG("validateQuoteData = %d\n", rc);
2829 if (rc != PTS_SUCCESS) {
2830 LOG(LOG_ERR, "---------------------------------------------------------------------------\n");
2831 LOG(LOG_ERR, "BAD QUOTE DATA!!! BAD QUOTE DATA!!! BAD QUOTE DATA!!! BAD QUOTE DATA!!!\n");
2832 LOG(LOG_ERR, "---------------------------------------------------------------------------\n");
2833 addProperty(pctx, "tpm.quote.signature", "invalid");
2835 ir_ctx->bad_quote = 1;
2838 LOG(LOG_TODO, "---------------------------------------------------------------------------\n");
2839 LOG(LOG_TODO, "GOOD QUOTE DATA!!! GOOD QUOTE DATA!!! GOOD QUOTE DATA!!! GOOD QUOTE DATA!!!\n");
2840 LOG(LOG_TODO, "---------------------------------------------------------------------------\n");
2842 addProperty(pctx, "tpm.quote.signature", "valid");
2846 pctx->conf->ir_without_quote = 0;
2851 ir_ctx->sax_state = IR_SAX_STATE_IDOL;
2855 * SAX parser - Text of Element
2857 * This called multiple time:-(
2860 void irCharacters(void* ctx, const xmlChar * ch, int len) {
2861 OPENPTS_CONTEXT * pctx;
2862 OPENPTS_IR_CONTEXT * ir_ctx;
2866 LOG(LOG_ERR, "null input");
2869 pctx = (OPENPTS_CONTEXT *)ctx;
2870 ir_ctx = pctx->ir_ctx;
2871 if (ir_ctx == NULL) {
2872 LOG(LOG_ERR, "null input");
2876 // LOG(LOG_ERR, "null input");
2881 /* copy to buf at ir_ctx, but check length first, ensuring additional space
2882 for NULL terminator */
2883 if ((ir_ctx->char_size + len + 1) > EVENTDATA_BUF_SIZE) {
2884 LOG(LOG_ERR, "Buffer for EVENTDATA is too small, %d + %d > %d\n", ir_ctx->char_size, len, EVENTDATA_BUF_SIZE);
2887 memcpy(&ir_ctx->buf[ir_ctx->char_size], ch, len);
2888 ir_ctx->char_size += len;
2892 * Validate Integrity Report (IR) by using SAX parser
2893 * @param ctx PTS_CONTEXT
2894 * @param filename IR file
2896 * @retval OPENPTS_RESULT_VALID
2897 * @retval OPENPTS_RESULT_INVALID
2898 * @retval OPENPTS_RESULT_UNKNOWN
2902 * Capability is Limited at this moment.
2903 * - check the consistency between IML and PCR
2906 * - validate quote signature
2907 * - validate with Reference Manifest
2908 * - validate with Integrity Database
2913 * 20100522 move global variable to ir_ctx
2914 * *** glibc detected *** ./check_fsm: double free or corruption (!prev): 0x090d5420 ***
2916 * export MALLOC_CHECK_=0
2918 * valgrind --leak-check=full --show-reachable=yes -v tests/check_fsm
2921 // int validateIr(OPENPTS_CONTEXT *ctx, const char *filenameNG) {
2922 int validateIr(OPENPTS_CONTEXT *ctx) {
2923 xmlSAXHandler sax_handler;
2924 int rc = PTS_VERIFY_FAILED; // guilty until proven innocent
2925 OPENPTS_CONFIG *conf;
2929 DEBUG("validateIr - start\n");
2933 LOG(LOG_ERR, "null input");
2936 if (ctx->target_conf == NULL) {
2937 LOG(LOG_ERR, "null input");
2940 if (ctx->ir_filename == NULL) {
2941 LOG(LOG_ERR, "null input");
2944 conf = ctx->target_conf;
2946 LOG(LOG_ERR, "null input");
2951 if (ctx->pcrs == NULL) {
2952 /* malloc OPENPTS_PCRS */
2953 ctx->pcrs = xmalloc(sizeof(OPENPTS_PCRS));
2954 if (ctx->pcrs == NULL) {
2958 memset(ctx->pcrs, 0, sizeof(OPENPTS_PCRS));
2961 pcrs->pubkey_length = conf->pubkey_length;
2962 pcrs->pubkey = conf->pubkey;
2965 if (ctx->ir_ctx == NULL) {
2966 ctx->ir_ctx = newIrContext();
2967 if (ctx->ir_ctx == NULL) {
2973 memset(&sax_handler, 0, sizeof(xmlSAXHandler));
2975 /* setup handlers */
2976 sax_handler.startDocument = irStartDocument;
2977 sax_handler.endDocument = irEndDocument;
2978 sax_handler.startElement = irStartElement;
2979 sax_handler.endElement = irEndElement;
2980 sax_handler.characters = irCharacters;
2984 if (conf->ima_validation_mode == OPENPTS_VALIDATION_MODE_AIDE) {
2985 if (ctx->aide_ctx == NULL) {
2986 /* setup AIDE as IIDB*/
2987 ctx->aide_ctx = newAideContext();
2989 #ifdef CONFIG_SQLITE
2990 // DEBUG("loadSQLiteDatabaseFile %s\n", ctx->conf->aide_sqlite_filename);
2991 rc = loadSQLiteDatabaseFile(ctx->aide_ctx, conf->aide_sqlite_filename);
2992 if (rc != PTS_SUCCESS) {
2993 LOG(LOG_ERR, "loadSQLiteDatabaseFile fail\n");
2998 rc = loadAideDatabaseFile(ctx->aide_ctx, conf->aide_database_filename);
3002 // pre loaded (see iml2aide.c)
3003 LOG(LOG_TODO, "AIDE DB pre loaded\n");
3006 if (ctx->conf->aide_ignorelist_filename != NULL) {
3007 rc = readAideIgnoreNameFile(ctx->aide_ctx, conf->aide_ignorelist_filename);
3013 /* Apply Validation Policy */
3014 // set policy as a property (e.g. name=unknown)
3015 // addProperty(ctx,"hoge", "unknown");
3017 /* default conf is missing QuoteData */
3018 // conf->ir_without_quote = 1;
3020 /* read IR, IR -> IML SAX */
3022 DEBUG("validateIr - Validate IR : %s\n", ctx->ir_filename);
3024 // http://xmlsoft.org/html/libxml-parser.html#xmlSAXUserParseFile
3025 if ((rc = xmlSAXUserParseFile(&sax_handler, (void *)ctx, ctx->ir_filename)) != 0) {
3027 DEBUG("validateIr() - SAX parse error rc=%d\n", rc);
3028 rc = PTS_INTERNAL_ERROR;
3031 rc = ctx->ir_ctx->sax_error;
3032 DEBUG("validateIr() - SAX parse : PASS (rc=%d)\n", rc);
3035 // DEBUG("validatePcrComposite, ctx->conf->ir_without_quote %d\n", ctx->conf->ir_without_quote);
3036 // LOG(LOG_ERR, "conf->pubkey_length %d\n",conf->pubkey_length);
3038 /* validate PCR values by QuoteData */
3039 if ((conf->iml_mode == 0) && (conf->ir_without_quote == 0)) {
3040 // DEBUG("validate PCR values by QuoteData\n");
3042 if (ctx->validation_data == NULL) {
3043 // TODO set properties
3044 // DEBUG("Without QUote?\n");
3045 addProperty(ctx, "tpm.quote.pcrs", "unknown"); // check by policy
3046 } else if (conf->pubkey_length > 0) {
3048 ctx->pcrs->pubkey_length = conf->pubkey_length;
3049 ctx->pcrs->pubkey = conf->pubkey;
3051 if (ctx->conf->tpm_quote_type == 1) {
3053 rc = validatePcrCompositeV11(ctx->pcrs, ctx->validation_data); // tss.c
3056 rc = validatePcrCompositeV12(ctx->pcrs, ctx->validation_data);
3059 DEBUG("validateIr() - validatePcrComposite, set rc=%d\n", rc);
3060 // DBEUG("validatePcrCompositeV11 = %d\n",rc);
3061 if (rc == PTS_SUCCESS) {
3062 addProperty(ctx, "tpm.quote.pcrs", "valid");
3063 } else if (rc == PTS_VERIFY_FAILED) {
3064 // ptsc - if FSM config in ptsc.conf is wrong this happen
3065 addReason(ctx, -1, NLS(MS_OPENPTS, OPENPTS_IR_PCR_COMPOSITE_VERIFY_FAILED,
3066 "[QUOTE] verification of PCR Composite has failed, "
3067 "(tscd - bad FSM configuration in /etc/ptsc.conf)"));
3068 addProperty(ctx, "tpm.quote.pcrs", "invalid");
3070 addReason(ctx, -1, NLS(MS_OPENPTS, OPENPTS_IR_PCR_COMPOSITE_VERIFY_FAILED,
3071 "[QUOTE] verification of PCR Composite has failed"));
3072 addProperty(ctx, "tpm.quote.pcrs", "invalid");
3075 LOG(LOG_ERR, "PUBKEY is missing\n");
3076 addProperty(ctx, "tpm.quote.pcrs", "unknown");
3079 DEBUG("validateIr() - skip validatePcrCompositeV11 conf->iml_mode=%d conf->ir_without_quote=%d\n",
3080 conf->iml_mode, conf->ir_without_quote);
3083 // TODO use policy or not
3085 /* Check Properties by Policy (if exist) */
3086 if (ctx->policy_start != NULL) {
3087 rc = checkPolicy(ctx);
3088 DEBUG("validateIr() - checkPolicy : rc=%d\n", rc);
3090 /* Use the result by IR validation by RM(FSM) */
3091 if (ctx->ir_ctx->sax_error > 0) {
3092 DEBUG("validateIr() - ctx->ir_ctx->sax_error > %d => rc = OPENPTS_RESULT_INVALID\n",
3093 ctx->ir_ctx->sax_error);
3094 rc = OPENPTS_RESULT_INVALID;
3096 if (ctx->ir_ctx->fsm_error_count > 0) {
3097 DEBUG("validateIr() - ctx->ir_ctx->fsm_error_count > %d => rc = OPENPTS_RESULT_INVALID\n",
3098 ctx->ir_ctx->fsm_error_count);
3099 rc = OPENPTS_RESULT_INVALID;
3103 if (ctx->ima_unknown > 0) {
3104 if (conf->ima_validation_unknown == 1) {
3105 DEBUG("ctx->ima_unknown = %d, result is INVALID\n", ctx->ima_unknown);
3106 addReason(ctx, -1, NLS(MS_OPENPTS, OPENPTS_IR_SEVERAL_UNKNOWN_IMA,
3107 "[LINUX-IMA] There are several unknown IMA measurements. "
3108 "Please check and update your AIDE ignore list."));
3109 rc = OPENPTS_RESULT_UNKNOWN;
3113 if (ctx->ir_ctx->bad_quote == 1) {
3114 addReason(ctx, -1, NLS(MS_OPENPTS, OPENPTS_IR_QUOTE_VERIFY_FAILED,
3115 "[QUOTE] verification of quote signature has failed."));
3116 rc = OPENPTS_RESULT_INVALID;
3124 if (ctx->aide_ctx != NULL) {
3125 freeAideContext(ctx->aide_ctx);
3129 if (ctx->pcrs != NULL) {
3135 if (ctx->ir_ctx != NULL) {
3136 if (ctx->ir_ctx->buf != NULL) {
3137 xfree(ctx->ir_ctx->buf);
3143 DEBUG("validateIr - done\n");
3150 * gen IR from Securityfs
3152 * @retval PTS_SUCCESS
3153 * @retval PTS_INTERNAL_ERROR
3155 int genIrFromSecurityfs(
3156 OPENPTS_CONTEXT *ctx,
3157 int *savedFd /* out*/ ) {
3159 /* get IML via securityfs */
3162 #ifdef CONFIG_NO_TSS
3163 DEBUG("Build with --without-tss. skip TPM_quote\n");
3165 DEBUG("TPM Quote not work with config option iml.mode=securityfs\n");
3170 LOG(LOG_ERR, "null input");
3175 resetTpm(&ctx->tpm, ctx->drtm);
3178 rc = freeAllFsm(ctx);
3181 rc = readFsmFromPropFile(ctx, ctx->conf->config_file);
3182 if (rc != PTS_SUCCESS) {
3183 LOG(LOG_ERR, "readFsmFromPropFile %s failed\n", ctx->conf->config_file);
3184 return PTS_INTERNAL_ERROR;
3188 rc = readBiosImlFile(ctx, ctx->conf->bios_iml_filename, ctx->conf->iml_endian);
3189 if (rc != PTS_SUCCESS) {
3190 LOG(LOG_ERR, "fail to load BIOS IML, rc = %d\n", rc);
3191 return PTS_INTERNAL_ERROR;
3194 if (ctx->conf->runtime_iml_filename != NULL) {
3196 /* read Runtime IML */
3197 rc = readImaImlFile(ctx, ctx->conf->runtime_iml_filename,
3198 ctx->conf->runtime_iml_type, 0, &count); // TODO endian?
3199 if (rc != PTS_SUCCESS) {
3200 LOG(LOG_ERR, "fail to load IMA IML, rc = %d\n", rc);
3201 return PTS_INTERNAL_ERROR;
3206 rc = getPcrBySysfsFile(ctx, ctx->conf->pcrs_filename);
3208 LOG(LOG_ERR, "fail to load PCR, rc = %d -- (pcr file is missing)\n", rc);
3209 LOG(LOG_TODO, "Get or Create PCR file for this testcase\n");
3213 // do not use tempnum,
3214 // if (ctx->conf->ir_filename != NULL) {
3215 // LOG(LOG_ERR, "Redefining the IR file location %s", ctx->conf->ir_filename);
3217 // ctx->conf->ir_filename = tempnam(NULL, "ir_");
3219 /* save IR (new file in tmp dir) */
3220 rc = writeIr(ctx, NULL, savedFd);
3221 // rc = writeIr(ctx, ctx->ir_filename, savedFd);
3223 LOG(LOG_ERR, "fail to write IR, rc = %d\n", rc);
3224 return PTS_INTERNAL_ERROR;
3232 * gen IR from Securityfs
3234 * @retval PTS_SUCCESS
3235 * @retval PTS_INTERNAL_ERROR
3238 OPENPTS_CONTEXT *ctx,
3239 int *savedFd /* out */ ) {
3244 LOG(LOG_ERR, "null input");
3248 /* get IML via securityfs */
3251 resetTpm(&ctx->tpm, ctx->drtm);
3254 rc = freeAllFsm(ctx);
3256 /* reset OPENPTS_PCRS */
3257 if (ctx->pcrs == NULL) {
3258 ctx->pcrs = xmalloc_assert(sizeof(OPENPTS_PCRS)); // TODO NULL check, or gen at newCtx
3261 memset(ctx->pcrs, 0, sizeof(OPENPTS_PCRS));
3264 // pcrSelect is set at PCR with FSM
3265 rc = readFsmFromPropFile(ctx, ctx->conf->config_file); // fsm.c
3266 if (rc != PTS_SUCCESS) {
3267 LOG(LOG_ERR, "read FSM failed\n");
3268 return PTS_INTERNAL_ERROR;
3271 /* TSS_VALIDATION */
3272 if (ctx->validation_data == NULL) {
3273 ctx->validation_data = xmalloc_assert(sizeof(TSS_VALIDATION));
3277 if (ctx->nonce->nonce_length > 0) {
3278 ctx->validation_data->ulExternalDataLength = ctx->nonce->nonce_length;
3279 // NG ctx->validation_data->rgbExternalData= ctx->nonce->nonce;
3281 ctx->validation_data->rgbExternalData = malloc(ctx->nonce->nonce_length);
3282 if (ctx->validation_data->rgbExternalData == NULL) {
3283 LOG(LOG_ERR, "no memory");
3287 ctx->validation_data->rgbExternalData,
3289 ctx->nonce->nonce_length);
3291 LOG(LOG_ERR, "genIrFromTss - nonce is missing, DH-nonce? \n");
3292 ctx->validation_data->ulExternalDataLength = 0;
3293 ctx->validation_data->rgbExternalData = NULL;
3296 ctx->validation_data->ulDataLength = 0;
3297 ctx->validation_data->rgbData= NULL; // ptr
3299 ctx->validation_data->ulValidationDataLength = 0;
3300 ctx->validation_data->rgbValidationData = NULL; // ptr
3303 if (ctx->conf->ir_without_quote == 1) {
3304 LOG(LOG_TODO, "skip TPM_Quote\n");
3306 /* TPM Quote or TPM Quote2 */
3307 if (ctx->conf->tpm_quote_type == 1) {
3309 ctx->conf->uuid->uuid,
3310 ctx->conf->aik_storage_type,
3311 ctx->conf->srk_password_mode,
3312 ctx->conf->aik_storage_filename,
3313 ctx->conf->aik_auth_type,
3316 ctx->validation_data); // tss.c
3319 ctx->conf->uuid->uuid,
3320 ctx->conf->aik_storage_type,
3321 ctx->conf->srk_password_mode,
3322 ctx->conf->aik_storage_filename,
3323 ctx->conf->aik_auth_type,
3326 ctx->validation_data); // tss.c
3329 LOG(LOG_ERR, "quoteTss fail, rc = 0x%04d\n", rc);
3330 return PTS_INTERNAL_ERROR;
3334 /* set PCR to snapshot */
3335 rc = setPcrsToSnapshot(ctx, ctx->pcrs); // TODO
3337 LOG(LOG_ERR, "fail to load PCR, rc = %d\n", rc);
3338 return PTS_INTERNAL_ERROR;
3341 /* get BIOS/IMA IML */
3342 rc = getIml(ctx, 0);
3344 LOG(LOG_ERR, "fail to load BIOS IML, rc = %d\n", rc);
3345 return PTS_INTERNAL_ERROR;
3348 if (ctx->conf->ir_filename != NULL) {
3349 LOG(LOG_ERR, "Redefining the IR file location %s", ctx->conf->ir_filename);
3351 //ctx->conf->ir_filename = tempnam(NULL, "ir_");
3352 //DEBUG("ctx->conf->ir_filename : %s\n", ctx->conf->ir_filename);
3354 /* save IR (new file in tmp dir) */
3355 rc = writeIr(ctx, NULL, savedFd);
3356 // rc = writeIr(ctx, ctx->ir_filename, savedFd); // ir.c
3358 LOG(LOG_ERR, "fail to write IR, rc = %d\n", rc);
3359 return PTS_INTERNAL_ERROR;
3369 * @retval PTS_SUCCESS
3370 * @retval PTS_INTERNAL_ERROR
3373 OPENPTS_CONTEXT *ctx,
3374 int *savedFd /* out */) {
3375 int rc = PTS_INTERNAL_ERROR;
3379 LOG(LOG_ERR, "null input");
3385 if (ctx->conf->iml_mode == 1) {
3386 rc = genIrFromSecurityfs(ctx, savedFd);
3387 if (rc != PTS_SUCCESS) {
3388 LOG(LOG_ERR, "writePtsTlvToSock - gen IR failed\n");
3392 #ifdef CONFIG_NO_TSS
3393 LOG(LOG_TODO, "OpenPTS was build with --without-tss and config option iml.mode=tssand, skip IR gen.\n");
3395 // DEBUG("get IML/PCR via TSS is not ready\n");
3396 rc = genIrFromTss(ctx, savedFd);
3397 if (rc != PTS_SUCCESS) {
3398 LOG(LOG_ERR, "gen IR failed\n");