1Index: git/include/tpm_tspi.h 2=================================================================== 3--- git.orig/include/tpm_tspi.h 4+++ git/include/tpm_tspi.h 5@@ -117,6 +117,10 @@ TSS_RESULT tpmPcrRead(TSS_HTPM a_hTpm, U 6 UINT32 *a_PcrSize, BYTE **a_PcrValue); 7 TSS_RESULT pcrcompositeSetPcrValue(TSS_HPCRS a_hPcrs, UINT32 a_Idx, 8 UINT32 a_PcrSize, BYTE *a_PcrValue); 9+TSS_RESULT tpmPcrExtend(TSS_HTPM a_hTpm, UINT32 a_Idx, 10+ UINT32 a_DataSize, BYTE *a_Data, 11+ TSS_PCR_EVENT *a_Event, 12+ UINT32 *a_PcrSize, BYTE **a_PcrValue); 13 #ifdef TSS_LIB_IS_12 14 TSS_RESULT unloadVersionInfo(UINT64 *offset, BYTE *blob, TPM_CAP_VERSION_INFO *v); 15 TSS_RESULT pcrcompositeSetPcrLocality(TSS_HPCRS a_hPcrs, UINT32 localityValue); 16Index: git/lib/tpm_tspi.c 17=================================================================== 18--- git.orig/lib/tpm_tspi.c 19+++ git/lib/tpm_tspi.c 20@@ -594,6 +594,20 @@ pcrcompositeSetPcrValue(TSS_HPCRS a_hPcr 21 return result; 22 } 23 24+TSS_RESULT 25+tpmPcrExtend(TSS_HTPM a_hTpm, UINT32 a_Idx, 26+ UINT32 a_DataSize, BYTE *a_Data, 27+ TSS_PCR_EVENT *a_Event, 28+ UINT32 *a_PcrSize, BYTE **a_PcrValue) 29+{ 30+ TSS_RESULT result = 31+ Tspi_TPM_PcrExtend(a_hTpm, a_Idx, a_DataSize, a_Data, a_Event, 32+ a_PcrSize, a_PcrValue); 33+ tspiResult("Tspi_TPM_PcrExtend", result); 34+ 35+ return result; 36+} 37+ 38 #ifdef TSS_LIB_IS_12 39 /* 40 * These getPasswd functions will wrap calls to the other functions and check to see if the TSS 41Index: git/src/cmds/Makefile.am 42=================================================================== 43--- git.orig/src/cmds/Makefile.am 44+++ git/src/cmds/Makefile.am 45@@ -22,6 +22,7 @@ 46 # 47 48 bin_PROGRAMS = tpm_sealdata \ 49+ tpm_extendpcr \ 50 tpm_unsealdata 51 52 if TSS_LIB_IS_12 53@@ -33,4 +34,5 @@ endif 54 LDADD = $(top_builddir)/lib/libtpm_tspi.la -ltspi $(top_builddir)/lib/libtpm_unseal.la -ltpm_unseal -lcrypto @INTLLIBS@ 55 56 tpm_sealdata_SOURCES = tpm_sealdata.c 57+tpm_extendpcr_SOURCES = tpm_extendpcr.c 58 tpm_unsealdata_SOURCES = tpm_unsealdata.c 59Index: git/src/cmds/tpm_extendpcr.c 60=================================================================== 61--- /dev/null 62+++ git/src/cmds/tpm_extendpcr.c 63@@ -0,0 +1,181 @@ 64+/* 65+ * The Initial Developer of the Original Code is International 66+ * Business Machines Corporation. Portions created by IBM 67+ * Corporation are Copyright (C) 2005, 2006 International Business 68+ * Machines Corporation. All Rights Reserved. 69+ * 70+ * This program is free software; you can redistribute it and/or modify 71+ * it under the terms of the Common Public License as published by 72+ * IBM Corporation; either version 1 of the License, or (at your option) 73+ * any later version. 74+ * 75+ * This program is distributed in the hope that it will be useful, 76+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 77+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 78+ * Common Public License for more details. 79+ * 80+ * You should have received a copy of the Common Public License 81+ * along with this program; if not, a copy can be viewed at 82+ * http://www.opensource.org/licenses/cpl1.0.php. 83+ */ 84+#include <openssl/evp.h> 85+#include <openssl/sha.h> 86+#include <limits.h> 87+#include "tpm_tspi.h" 88+#include "tpm_utils.h" 89+#include "tpm_seal.h" 90+ 91+// #define TPM_EXTENDPCR_DEBUG 92+ 93+static void help(const char *aCmd) 94+{ 95+ logCmdHelp(aCmd); 96+ logCmdOption("-i, --infile FILE", 97+ _ 98+ ("Filename containing data to extend PCRs with. Default is STDIN.")); 99+ logCmdOption("-p, --pcr NUMBER", 100+ _("PCR to extend.")); 101+ 102+} 103+ 104+static char in_filename[PATH_MAX] = ""; 105+static TSS_HPCRS hPcrs = NULL_HPCRS; 106+static TSS_HTPM hTpm; 107+static UINT32 selectedPcrs[24]; 108+static UINT32 selectedPcrsLen = 0; 109+TSS_HCONTEXT hContext = 0; 110+ 111+static int parse(const int aOpt, const char *aArg) 112+{ 113+ int rc = -1; 114+ 115+ switch (aOpt) { 116+ case 'i': 117+ if (aArg) { 118+ strncpy(in_filename, aArg, PATH_MAX); 119+ rc = 0; 120+ } 121+ break; 122+ case 'p': 123+ if (aArg) { 124+ selectedPcrs[selectedPcrsLen++] = atoi(aArg); 125+ rc = 0; 126+ } 127+ break; 128+ default: 129+ break; 130+ } 131+ return rc; 132+ 133+} 134+ 135+int main(int argc, char **argv) 136+{ 137+ 138+ int iRc = -1; 139+ struct option opts[] = { 140+ {"infile", required_argument, NULL, 'i'}, 141+ {"pcr", required_argument, NULL, 'p'}, 142+ }; 143+ unsigned char line[EVP_MD_block_size(EVP_sha1()) * 16]; 144+ int lineLen; 145+ UINT32 i; 146+ 147+ BIO *bin = NULL; 148+ 149+ initIntlSys(); 150+ 151+ if (genericOptHandler(argc, argv, "i:p:", opts, 152+ sizeof(opts) / sizeof(struct option), parse, 153+ help) != 0) 154+ goto out; 155+ 156+ if (contextCreate(&hContext) != TSS_SUCCESS) 157+ goto out; 158+ 159+ if (contextConnect(hContext) != TSS_SUCCESS) 160+ goto out_close; 161+ 162+ if (contextGetTpm(hContext, &hTpm) != TSS_SUCCESS) 163+ goto out_close; 164+ 165+ /* Create a BIO for the input file */ 166+ if ((bin = BIO_new(BIO_s_file())) == NULL) { 167+ logError(_("Unable to open input BIO\n")); 168+ goto out_close; 169+ } 170+ 171+ /* Assign the input file to the BIO */ 172+ if (strlen(in_filename) == 0) 173+ BIO_set_fp(bin, stdin, BIO_NOCLOSE); 174+ else if (!BIO_read_filename(bin, in_filename)) { 175+ logError(_("Unable to open input file: %s\n"), 176+ in_filename); 177+ goto out_close; 178+ } 179+ 180+ /* Create the PCRs object. If any PCRs above 15 are selected, this will need to be 181+ * a 1.2 TSS/TPM */ 182+ if (selectedPcrsLen) { 183+ TSS_FLAG initFlag = 0; 184+ UINT32 pcrSize; 185+ BYTE *pcrValue; 186+ 187+ for (i = 0; i < selectedPcrsLen; i++) { 188+ if (selectedPcrs[i] > 15) { 189+#ifdef TSS_LIB_IS_12 190+ initFlag |= TSS_PCRS_STRUCT_INFO_LONG; 191+#else 192+ logError(_("This version of %s was compiled for a v1.1 TSS, which " 193+ "can only seal\n data to PCRs 0-15. PCR %u is out of range" 194+ "\n"), argv[0], selectedPcrs[i]); 195+ goto out_close; 196+#endif 197+ } 198+ } 199+ 200+ unsigned char msg[EVP_MAX_MD_SIZE]; 201+ unsigned int msglen; 202+ EVP_MD_CTX ctx; 203+ EVP_DigestInit(&ctx, EVP_sha1()); 204+ while ((lineLen = BIO_read(bin, line, sizeof(line))) > 0) 205+ EVP_DigestUpdate(&ctx, line, lineLen); 206+ EVP_DigestFinal(&ctx, msg, &msglen); 207+ 208+ if (contextCreateObject(hContext, TSS_OBJECT_TYPE_PCRS, initFlag, 209+ &hPcrs) != TSS_SUCCESS) 210+ goto out_close; 211+ 212+ for (i = 0; i < selectedPcrsLen; i++) { 213+#ifdef TPM_EXTENDPCR_DEBUG 214+ if (tpmPcrRead(hTpm, selectedPcrs[i], &pcrSize, &pcrValue) != TSS_SUCCESS) 215+ goto out_close; 216+ 217+ unsigned int j; 218+ for (j = 0; j < pcrSize; j++) 219+ printf("%02X ", pcrValue[j]); 220+ printf("\n"); 221+#endif 222+ 223+ if (tpmPcrExtend(hTpm, selectedPcrs[i], msglen, msg, NULL, &pcrSize, &pcrValue) != TSS_SUCCESS) 224+ goto out_close; 225+ 226+#ifdef TPM_EXTENDPCR_DEBUG 227+ for (j = 0; j < pcrSize; j++) 228+ printf("%02X ", pcrValue[j]); 229+ printf("\n"); 230+#endif 231+ } 232+ } 233+ 234+ iRc = 0; 235+ logSuccess(argv[0]); 236+ 237+out_close: 238+ contextClose(hContext); 239+ 240+out: 241+ if (bin) 242+ BIO_free(bin); 243+ return iRc; 244+} 245