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