This patch adds 5 tools for accessing NVRAM areas: - tpm_nvdefine - tpm_nvrelease - tpm_nvread - tpm_nvwrite - tpm_nvinfo
It uses as many of the same options that have been introduced in other tools and introduces a couple of new ones for providing the owner and NVRAM area password via command line as well as the index, size and permissions of NVRAM areas. Signed-off-by: Stefan Berger <[email protected]> --- include/tpm_tspi.h | 14 + include/tpm_utils.h | 3 lib/tpm_log.c | 10 + lib/tpm_tspi.c | 67 ++++++++ src/tpm_mgmt/Makefile.am | 15 + src/tpm_mgmt/tpm_nvcommon.c | 273 +++++++++++++++++++++++++++++++++ src/tpm_mgmt/tpm_nvcommon.h | 73 ++++++++ src/tpm_mgmt/tpm_nvdefine.c | 285 ++++++++++++++++++++++++++++++++++ src/tpm_mgmt/tpm_nvinfo.c | 190 +++++++++++++++++++++++ src/tpm_mgmt/tpm_nvread.c | 299 ++++++++++++++++++++++++++++++++++++ src/tpm_mgmt/tpm_nvrelease.c | 178 +++++++++++++++++++++ src/tpm_mgmt/tpm_nvwrite.c | 355 +++++++++++++++++++++++++++++++++++++++++++ 12 files changed, 1761 insertions(+), 1 deletion(-) Index: tpm-tools/src/tpm_mgmt/Makefile.am =================================================================== --- tpm-tools.orig/src/tpm_mgmt/Makefile.am +++ tpm-tools/src/tpm_mgmt/Makefile.am @@ -39,7 +39,15 @@ sbin_PROGRAMS = tpm_changeownerauth \ tpm_selftest if TSS_LIB_IS_12 -sbin_PROGRAMS += tpm_revokeek tpm_setoperatorauth tpm_resetdalock tpm_restrictsrk +sbin_PROGRAMS += tpm_nvdefine \ + tpm_nvinfo \ + tpm_nvread \ + tpm_nvrelease \ + tpm_nvwrite \ + tpm_resetdalock \ + tpm_restrictsrk \ + tpm_revokeek \ + tpm_setoperatorauth AM_CPPFLAGS = -I$(top_srcdir)/include -D_LINUX -DTSS_LIB_IS_12 else AM_CPPFLAGS = -I$(top_srcdir)/include -D_LINUX @@ -54,6 +62,11 @@ tpm_changeownerauth_SOURCES = tpm_change tpm_clear_SOURCES = tpm_clear.c tpm_createek_SOURCES = tpm_createek.c tpm_getpubek_SOURCES = tpm_getpubek.c +tpm_nvdefine_SOURCES = tpm_nvdefine.c tpm_nvcommon.c +tpm_nvinfo_SOURCES = tpm_nvinfo.c tpm_nvcommon.c +tpm_nvrelease_SOURCES = tpm_nvrelease.c tpm_nvcommon.c +tpm_nvread_SOURCES = tpm_nvread.c tpm_nvcommon.c +tpm_nvwrite_SOURCES = tpm_nvwrite.c tpm_nvcommon.c tpm_restrictpubek_SOURCES = tpm_restrictpubek.c tpm_setactive_SOURCES = tpm_activate.c tpm_setclearable_SOURCES = tpm_clearable.c Index: tpm-tools/src/tpm_mgmt/tpm_nvdefine.c =================================================================== --- /dev/null +++ tpm-tools/src/tpm_mgmt/tpm_nvdefine.c @@ -0,0 +1,285 @@ +/* + * The Initial Developer of the Original Code is International + * Business Machines Corporation. Portions created by IBM + * Corporation are Copyright (C) 2005 International Business + * Machines Corporation. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the Common Public License as published by + * IBM Corporation; either version 1 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Common Public License for more details. + * + * You should have received a copy of the Common Public License + * along with this program; if not, a copy can be viewed at + * http://www.opensource.org/licenses/cpl1.0.php. + */ + +#include <limits.h> + +#include "tpm_tspi.h" +#include "tpm_utils.h" +#include "tpm_nvcommon.h" + +static int nvindex; +static int nvperm; +static int nvsize; +static const char *ownerpass; +static BOOL ownerWellKnown = FALSE; +static BOOL askOwnerPass = FALSE; +static const char *datapass; +static BOOL dataWellKnown = FALSE; +static BOOL askDataPass = FALSE; +static int end = 0; + +TSS_HCONTEXT hContext = 0; + + +static int parse(const int aOpt, const char *aArg) +{ + switch (aOpt) { + case 'i': + if (parseHexOrDecimal(aArg, &nvindex, UINT_MAX, + "NVRAM index") != 0) + return -1; + break; + + case 'p': + if (!strcmp(aArg, "?")) { + displayStringsAndValues(permvalues, ""); + end = 1; + return 0; + } + if (parseHexOrDecimal(aArg, &nvperm, UINT_MAX, + "NVRAM permission") != 0 && + parseStringWithValues(aArg, permvalues, &nvperm, UINT_MAX, + "NVRAM permission") != 0) + return -1; + break; + + case 's': + if (parseHexOrDecimal(aArg, &nvsize, UINT_MAX, + "NVRAM index size") != 0) + return -1; + break; + + case 'o': + ownerpass = aArg; + if (!ownerpass) + askOwnerPass = TRUE; + else + askOwnerPass = FALSE; + ownerWellKnown = FALSE; + break; + + case 'y': + ownerWellKnown = TRUE; + ownerpass = NULL; + askOwnerPass = FALSE; + break; + + case 'a': + datapass = aArg; + if (!datapass) + askDataPass = TRUE; + else + askDataPass = FALSE; + dataWellKnown = FALSE; + break; + + case 'z': + dataWellKnown = TRUE; + datapass = NULL; + askDataPass = FALSE; + break; + + case 'u': + useUnicode = TRUE; + break; + + default: + return -1; + } + return 0; +} + +static void help(const char* aCmd) +{ + logCmdHelp(aCmd); + logUnicodeCmdOption(); + logCmdOption("-y, --owner-well-known", + _("Use 20 bytes of zeros (TSS_WELL_KNOWN_SECRET) as the TPM owner secret")); + logCmdOption("-z, --data-well-known", + _("Use 20 bytes of zeros (TSS_WELL_KNOWN_SECRET) as the NVRAM area's secret")); + logOwnerPassCmdOption(); + logCmdOption("-a, --pwda", + _("NVRAM area password")); + logNVIndexCmdOption(); + logCmdOption("-s, --size", + _("Size of the NVRAM area")); + logCmdOption("-p, --permissions", + _("Permissions of the NVRAM area")); + + displayStringsAndValues(permvalues, " "); +} + +int main(int argc, char **argv) +{ + TSS_HTPM hTpm; + TSS_HNVSTORE nvObject; + TSS_FLAG fNvAttrs; + TSS_HPOLICY hTpmPolicy, hDataPolicy; + int iRc = -1; + BYTE well_known_secret[] = TSS_WELL_KNOWN_SECRET; + int opswd_len = -1; + int dpswd_len = -1; + struct option hOpts[] = { + {"index" , required_argument, NULL, 'i'}, + {"size" , required_argument, NULL, 's'}, + {"permissions" , required_argument, NULL, 'p'}, + {"pwdo" , optional_argument, NULL, 'o'}, + {"pwda" , optional_argument, NULL, 'a'}, + {"use-unicode" , no_argument, NULL, 'u'}, + {NULL , no_argument, NULL, 0}, + }; + + initIntlSys(); + + if (genericOptHandler + (argc, argv, "i:s:p:o:d:yzu", hOpts, + sizeof(hOpts) / sizeof(struct option), parse, help) != 0) + goto out; + + if (end) { + iRc = 0; + goto out; + } + + if (nvindex == 0) { + logError(_("You must provide an index (!= 0) for the NVRAM space.\n")); + goto out; + } + + if (nvperm == 0 && (UINT32)nvindex != 0xffffffff) { + logError(_("You must provide permission bits for the NVRAM space.\n")); + goto out; + } + + logDebug("permissions = 0x%08x\n", nvperm); + + if (contextCreate(&hContext) != TSS_SUCCESS) + goto out; + + if (contextConnect(hContext) != TSS_SUCCESS) + goto out_close; + + if (contextGetTpm(hContext, &hTpm) != TSS_SUCCESS) + goto out_close; + + fNvAttrs = 0; + + if (contextCreateObject(hContext, + TSS_OBJECT_TYPE_NV, + fNvAttrs, + &nvObject) != TSS_SUCCESS) + goto out_close; + + if (askOwnerPass) { + ownerpass = _GETPASSWD(_("Enter owner password: "), &opswd_len, + FALSE, useUnicode ); + if (!ownerpass) { + logError(_("Failed to get owner password\n")); + goto out_close; + } + } + + if (ownerpass || ownerWellKnown) { + if (policyGet(hTpm, &hTpmPolicy) != TSS_SUCCESS) + goto out_close; + if (ownerpass) { + if (opswd_len < 0) + opswd_len = strlen(ownerpass); + if (policySetSecret(hTpmPolicy, opswd_len, + (BYTE *)ownerpass) != TSS_SUCCESS) + goto out_close; + } else { + if (policySetSecret(hTpmPolicy, TCPA_SHA1_160_HASH_LEN, + (BYTE *)well_known_secret) != TSS_SUCCESS) + goto out_close; + } + } + + if (askDataPass) { + datapass = _GETPASSWD(_("Enter NVRAM data password: "), &dpswd_len, + FALSE, useUnicode ); + if (!datapass) { + logError(_("Failed to get NVRAM data password\n")); + goto out_close; + } + } + + if (datapass || dataWellKnown) { + if (contextCreateObject + (hContext, TSS_OBJECT_TYPE_POLICY, TSS_POLICY_USAGE, + &hDataPolicy) != TSS_SUCCESS) + goto out_close; + + if (datapass) { + if (dpswd_len < 0) + dpswd_len = strlen(datapass); + if (policySetSecret(hDataPolicy, dpswd_len, + (BYTE *)datapass) != TSS_SUCCESS) + goto out_close; + } else { + if (policySetSecret(hDataPolicy, TCPA_SHA1_160_HASH_LEN, + (BYTE *)well_known_secret) != TSS_SUCCESS) + goto out_close; + } + + if (Tspi_Policy_AssignToObject(hDataPolicy, nvObject) != + TSS_SUCCESS) + goto out_close; + } + + if (Tspi_SetAttribUint32(nvObject, + TSS_TSPATTRIB_NV_INDEX, + 0, + nvindex) != TSS_SUCCESS) + goto out_close_obj; + + if (Tspi_SetAttribUint32(nvObject, + TSS_TSPATTRIB_NV_PERMISSIONS, + 0, + nvperm) != TSS_SUCCESS) + goto out_close_obj; + + if (Tspi_SetAttribUint32(nvObject, + TSS_TSPATTRIB_NV_DATASIZE, + 0, + nvsize) != TSS_SUCCESS) + goto out_close_obj; + + if (NVDefineSpace(nvObject, (TSS_HPCRS)0, (TSS_HPCRS)0) != + TSS_SUCCESS) + goto out_close; + + logMsg(_("Successfully created NVRam space at index 0x%x (%u).\n"), + nvindex, nvindex); + + iRc = 0; + + goto out_close; + + out_close_obj: + contextCloseObject(hContext, nvObject); + + out_close: + contextClose(hContext); + + out: + return iRc; +} Index: tpm-tools/include/tpm_tspi.h =================================================================== --- tpm-tools.orig/include/tpm_tspi.h +++ tpm-tools/include/tpm_tspi.h @@ -120,6 +120,20 @@ TSS_RESULT pcrcompositeSetPcrValue(TSS_H #ifdef TSS_LIB_IS_12 TSS_RESULT unloadVersionInfo(UINT64 *offset, BYTE *blob, TPM_CAP_VERSION_INFO *v); TSS_RESULT pcrcompositeSetPcrLocality(TSS_HPCRS a_hPcrs, UINT32 localityValue); + +TSS_RESULT NVDefineSpace(TSS_HNVSTORE hNVStore, + TSS_HPCRS hReadPcrComposite , + TSS_HPCRS hWritePcrComposite); + +TSS_RESULT NVReleaseSpace(TSS_HNVSTORE hNVStore); + +TSS_RESULT NVWriteValue(TSS_HNVSTORE hNVStore, UINT32 offset, + UINT32 ulDataLength, BYTE *rgbDataToWrite); + +TSS_RESULT NVReadValue(TSS_HNVSTORE hNVStore, UINT32 offset, + UINT32 *ulDataLength, BYTE **rgbDataRead); + +TSS_RESULT unloadNVDataPublic(UINT64 *offset, BYTE *blob, UINT32 bloblen, TPM_NV_DATA_PUBLIC *v); #endif #endif Index: tpm-tools/lib/tpm_tspi.c =================================================================== --- tpm-tools.orig/lib/tpm_tspi.c +++ tpm-tools/lib/tpm_tspi.c @@ -647,4 +647,71 @@ pcrcompositeSetPcrLocality(TSS_HPCRS a_h return result; } + +TSS_RESULT +NVDefineSpace(TSS_HNVSTORE hNVStore, TSS_HPCRS hReadPcrComposite , + TSS_HPCRS hWritePcrComposite) +{ + TSS_RESULT result = + Tspi_NV_DefineSpace(hNVStore, hReadPcrComposite, + hWritePcrComposite); + + tspiResult("Tspi_NV_DefineSpace", result); + + return result; +} + +TSS_RESULT +NVReleaseSpace(TSS_HNVSTORE hNVStore) +{ + TSS_RESULT result = + Tspi_NV_ReleaseSpace(hNVStore); + + tspiResult("Tspi_NV_ReleaseSpace", result); + + return result; +} + +TSS_RESULT +NVWriteValue(TSS_HNVSTORE hNVStore, UINT32 offset, + UINT32 ulDataLength, BYTE *rgbDataToWrite) +{ + TSS_RESULT result = + Tspi_NV_WriteValue(hNVStore, offset, + ulDataLength, rgbDataToWrite); + + tspiResult("Tspi_NV_WriteValue", result); + + return result; +} + +TSS_RESULT +NVReadValue(TSS_HNVSTORE hNVStore, UINT32 offset, + UINT32 *ulDataLength, BYTE **rgbDataRead) +{ + TSS_RESULT result = + Tspi_NV_ReadValue(hNVStore, offset, + ulDataLength, rgbDataRead); + + tspiResult("Tspi_NV_ReadValue", result); + + return result; +} + +TSS_RESULT +unloadNVDataPublic(UINT64 *offset, BYTE *blob, UINT32 blob_len, TPM_NV_DATA_PUBLIC *v) +{ + UINT64 off = *offset; + TSS_RESULT result; + result = Trspi_UnloadBlob_NV_DATA_PUBLIC(&off, blob, NULL); + if (result == TSS_SUCCESS) { + if (off > blob_len) + return TSS_E_BAD_PARAMETER; + result = Trspi_UnloadBlob_NV_DATA_PUBLIC(offset, blob, v); + } + tspiResult("Trspi_UnloadBlob_NV_DATA_PUBLIC", result); + return result; +} + + #endif Index: tpm-tools/src/tpm_mgmt/tpm_nvrelease.c =================================================================== --- /dev/null +++ tpm-tools/src/tpm_mgmt/tpm_nvrelease.c @@ -0,0 +1,178 @@ +/* + * The Initial Developer of the Original Code is International + * Business Machines Corporation. Portions created by IBM + * Corporation are Copyright (C) 2005 International Business + * Machines Corporation. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the Common Public License as published by + * IBM Corporation; either version 1 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Common Public License for more details. + * + * You should have received a copy of the Common Public License + * along with this program; if not, a copy can be viewed at + * http://www.opensource.org/licenses/cpl1.0.php. + */ + +#include <limits.h> + +#include "tpm_nvcommon.h" +#include "tpm_tspi.h" +#include "tpm_utils.h" + +static int nvindex; +static const char *ownerpass; +static BOOL ownerWellKnown = FALSE; +static BOOL askOwnerPass = FALSE; +TSS_HCONTEXT hContext = 0; + + +static int parse(const int aOpt, const char *aArg) +{ + + switch (aOpt) { + case 'i': + if (parseHexOrDecimal(aArg, &nvindex, UINT_MAX, + "NVRAM index") != 0) + return -1; + break; + + case 'o': + ownerpass = aArg; + if (!ownerpass) + askOwnerPass = TRUE; + else + askOwnerPass = FALSE; + ownerWellKnown = FALSE; + break; + + case 'y': + ownerWellKnown = TRUE; + askOwnerPass = FALSE; + ownerpass = NULL; + break; + + case 'u': + useUnicode = TRUE; + break; + + default: + return -1; + } + return 0; +} + +static void help(const char* aCmd) +{ + logCmdHelp(aCmd); + logUnicodeCmdOption(); + logCmdOption("-y, --owner-well-known", + _("Use 20 bytes of zeros (TSS_WELL_KNOWN_SECRET) as the TPM owner password")); + logCmdOption("-o, --pwdo", + _("Owner password")); + logCmdOption("-i, --index", + _("Index of the NVRAM area")); +} + +int main(int argc, char **argv) +{ + TSS_RESULT res; + TSS_HTPM hTpm; + TSS_HNVSTORE nvObject; + TSS_FLAG fNvAttrs; + TSS_HPOLICY hTpmPolicy; + int iRc = -1; + int pswd_len = -1; + BYTE well_known_secret[] = TSS_WELL_KNOWN_SECRET; + struct option hOpts[] = { + {"index", required_argument, NULL, 'i'}, + {"pwdo" , optional_argument, NULL, 'o'}, + {NULL , no_argument, NULL, 0}, + }; + + initIntlSys(); + + if (genericOptHandler + (argc, argv, "i:o::y", hOpts, + sizeof(hOpts) / sizeof(struct option), parse, help) != 0) + goto out; + + if (nvindex == 0) { + logError(_("You must provide an index (!= 0) for the NVRAM space.\n")); + goto out; + } + + if (contextCreate(&hContext) != TSS_SUCCESS) + goto out; + + if (contextConnect(hContext) != TSS_SUCCESS) + goto out_close; + + if (contextGetTpm(hContext, &hTpm) != TSS_SUCCESS) + goto out_close; + + fNvAttrs = 0; + + if (askOwnerPass) { + ownerpass = _GETPASSWD(_("Enter owner password: "), &pswd_len, + FALSE, useUnicode ); + if (!ownerpass) { + logError(_("Failed to get owner password\n")); + goto out_close; + } + } + + if (ownerpass || ownerWellKnown) { + if (policyGet(hTpm, &hTpmPolicy) != TSS_SUCCESS) + goto out_close; + if (ownerpass) { + if (pswd_len < 0) + pswd_len = strlen(ownerpass); + + if (policySetSecret(hTpmPolicy, pswd_len, + (BYTE *)ownerpass) != TSS_SUCCESS) + goto out_close; + } else { + if (policySetSecret(hTpmPolicy, TCPA_SHA1_160_HASH_LEN, + (BYTE *)well_known_secret) != TSS_SUCCESS) + goto out_close; + } + } + + if (contextCreateObject(hContext, + TSS_OBJECT_TYPE_NV, + fNvAttrs, + &nvObject) != TSS_SUCCESS) + goto out_close; + + if (Tspi_SetAttribUint32(nvObject, + TSS_TSPATTRIB_NV_INDEX, + 0, + nvindex) != TSS_SUCCESS) + goto out_close_obj; + + if ((res = NVReleaseSpace(nvObject)) != TSS_SUCCESS) { + goto out_close; + } + + logMsg(_("Successfully released NVRam space at index 0x%x (%d).\n"), + nvindex, nvindex); + + iRc = 0; + + goto out_close; + + out_close_obj: + contextCloseObject(hContext, nvObject); + + out_close: + contextClose(hContext); + + out: + return iRc; +} Index: tpm-tools/src/tpm_mgmt/tpm_nvread.c =================================================================== --- /dev/null +++ tpm-tools/src/tpm_mgmt/tpm_nvread.c @@ -0,0 +1,299 @@ +/* + * The Initial Developer of the Original Code is International + * Business Machines Corporation. Portions created by IBM + * Corporation are Copyright (C) 2005 International Business + * Machines Corporation. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the Common Public License as published by + * IBM Corporation; either version 1 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Common Public License for more details. + * + * You should have received a copy of the Common Public License + * along with this program; if not, a copy can be viewed at + * http://www.opensource.org/licenses/cpl1.0.php. + */ + +#include <limits.h> +#include <ctype.h> +#include <fcntl.h> +#include <unistd.h> + +#include "tpm_nvcommon.h" +#include "tpm_tspi.h" +#include "tpm_utils.h" + +static int nvindex; +static int offset; +static int length; +static const char *filename; +static BOOL passWellKnown = FALSE; +static const char *password; +static BOOL askPassword = FALSE; + +TSS_HCONTEXT hContext = 0; + + +static int parse(const int aOpt, const char *aArg) +{ + + switch (aOpt) { + case 'i': + if (parseHexOrDecimal(aArg, &nvindex, UINT_MAX, + "NVRAM index") != 0) + return -1; + break; + + case 'n': + if (parseHexOrDecimal(aArg, &offset, UINT_MAX, + "read offset") != 0) + return -1; + break; + + case 's': + if (parseHexOrDecimal(aArg, &length, UINT_MAX, + "length of data") != 0) + return -1; + break; + + case 'f': + filename = aArg; + break; + + case 'p': + password = aArg; + if (!password) + askPassword = TRUE; + else + askPassword = FALSE; + passWellKnown = FALSE; + break; + + case 'z': + password = NULL; + passWellKnown = TRUE; + askPassword = FALSE; + break; + + case 'u': + useUnicode = TRUE; + break; + + default: + return -1; + } + return 0; +} + +static void displayData(FILE *stream, UINT32 offset, BYTE *data, UINT32 length) +{ + unsigned int len = (length + 0xf) & ~0xf; + unsigned int c; + unsigned char buf[17] = { 0, }; + + for (c = 0; c < len; c++) { + if ((c & 0xf) == 0) + printf("%08x ", c + offset); + + if (c < length) { + printf("%02x ", data[c]); + if (isgraph(data[c])) + buf[c & 0xf] = data[c]; + else + buf[c & 0xf] = ' '; + } else { + printf(" "); + buf[c & 0xf] = 0; + } + + if ((c & 0xf) == 0xf) { + printf(" %s\n", buf); + } + } +} + +static void help(const char* aCmd) +{ + logCmdHelp(aCmd); + logUnicodeCmdOption(); + logCmdOption("-z, --well-known", + _("Use 20 bytes of zeros (TSS_WELL_KNOWN_SECRET) as the TPM secret authorization data")); + logCmdOption("-p, --password", + _("Owner or NVRAM area password depending on permissions")); + logNVIndexCmdOption(); + logCmdOption("-s, --size", + _("Number of bytes to read from the NVRAM area")); + logCmdOption("-n, --offset", + _("Offset at which to start writing into the NVRAM area")); + logCmdOption("-f, --filename", + _("File to write data to.")); +} + +int main(int argc, char **argv) +{ + + TSS_HTPM hTpm; + TSS_HNVSTORE nvObject; + TSS_FLAG fNvAttrs; + TSS_HPOLICY hTpmPolicy, hDataPolicy; + int iRc = -1; + int pswd_len = -1; + BYTE well_known_secret[] = TSS_WELL_KNOWN_SECRET; + UINT32 ulDataLength; + BYTE *rgbDataRead = NULL; + TPM_NV_DATA_PUBLIC *nvpub = NULL; + struct option hOpts[] = { + {"index" , required_argument, NULL, 'i'}, + {"size" , required_argument, NULL, 's'}, + {"offset" , required_argument, NULL, 'n'}, + {"filename" , required_argument, NULL, 'f'}, + {"password" , optional_argument, NULL, 'p'}, + {"use-unicode", no_argument, NULL, 'u'}, + {NULL , no_argument, NULL, 0}, + }; + int fd = -1; + + initIntlSys(); + + if (genericOptHandler + (argc, argv, "i:n:s:f:p::zu", hOpts, + sizeof(hOpts) / sizeof(struct option), parse, help) != 0) + goto out; + + if (nvindex == 0) { + logError(_("You must provide an index (!= 0) for the NVRAM space.\n")); + goto out; + } + + ulDataLength = length; + + if (contextCreate(&hContext) != TSS_SUCCESS) + goto out; + + if (contextConnect(hContext) != TSS_SUCCESS) + goto out_close; + + if (contextGetTpm(hContext, &hTpm) != TSS_SUCCESS) + goto out_close; + + fNvAttrs = 0; + + if (contextCreateObject(hContext, + TSS_OBJECT_TYPE_NV, + fNvAttrs, + &nvObject) != TSS_SUCCESS) + goto out_close; + + if (askPassword) { + password = _GETPASSWD(_("Enter NVRAM access password: "), &pswd_len, + FALSE, useUnicode ); + if (!password) { + logError(_("Failed to get NVRAM access password\n")); + goto out_close; + } + } + + if (password || passWellKnown) { + if (policyGet(hTpm, &hTpmPolicy) != TSS_SUCCESS) + goto out_close; + + if (password) { + if (pswd_len < 0) + pswd_len = strlen(password); + if (policySetSecret(hTpmPolicy, pswd_len, + (BYTE *)password) != TSS_SUCCESS) + goto out_close; + } else { + if (policySetSecret(hTpmPolicy, TCPA_SHA1_160_HASH_LEN, + (BYTE *)well_known_secret) != TSS_SUCCESS) + goto out_close; + } + + if (contextCreateObject + (hContext, TSS_OBJECT_TYPE_POLICY, TSS_POLICY_USAGE, + &hDataPolicy) != TSS_SUCCESS) + goto out_close; + + if (password) { + if (policySetSecret(hDataPolicy, pswd_len, + (BYTE *)password) != TSS_SUCCESS) + goto out_close; + } else { + if (policySetSecret(hDataPolicy, TCPA_SHA1_160_HASH_LEN, + (BYTE *)well_known_secret) != TSS_SUCCESS) + goto out_close; + } + + if (Tspi_Policy_AssignToObject(hDataPolicy, nvObject) != + TSS_SUCCESS) + goto out_close; + } + + if (getNVDataPublic(hTpm, nvindex, &nvpub) != TSS_SUCCESS) { + logError(_("Could not get the NVRAM area's public information.\n")); + goto out_close_obj; + } + + if ((UINT32)offset > nvpub->dataSize) { + logError(_("The offset is outside the NVRAM area's size of %u bytes.\n"), + nvpub->dataSize); + goto out_close_obj; + } + + if ((UINT32)offset + ulDataLength > nvpub->dataSize) { + ulDataLength = nvpub->dataSize - (UINT32)offset; + } + + if (Tspi_SetAttribUint32(nvObject, + TSS_TSPATTRIB_NV_INDEX, + 0, + nvindex) != TSS_SUCCESS) + goto out_close_obj; + + + if (NVReadValue(nvObject, offset, &ulDataLength, &rgbDataRead) != + TSS_SUCCESS) + goto out_close_obj; + + if (filename) { + fd = open(filename, O_WRONLY|O_TRUNC|O_CREAT); + if (fd < 0) { + logError(_("Could not open file %s for writing."), + filename); + goto out_close_obj; + } + if (ulDataLength != write(fd, rgbDataRead, ulDataLength)) { + logError(_("Error while writing to file.\n")); + close(fd); + fd = -1; + goto out_close_obj; + } + close(fd); + fd = -1; + logMsg(_("Successfully wrote NVRAM's index 0x%x (%u) data " + "to file.\n"), nvindex, nvindex); + } else { + displayData(stdout, offset, rgbDataRead, ulDataLength); + } + + iRc = 0; + + goto out_close; + + out_close_obj: + contextCloseObject(hContext, nvObject); + + out_close: + contextClose(hContext); + + out: + free(rgbDataRead); + freeNVDataPublic(nvpub); + + return iRc; +} Index: tpm-tools/src/tpm_mgmt/tpm_nvwrite.c =================================================================== --- /dev/null +++ tpm-tools/src/tpm_mgmt/tpm_nvwrite.c @@ -0,0 +1,355 @@ +/* + * The Initial Developer of the Original Code is International + * Business Machines Corporation. Portions created by IBM + * Corporation are Copyright (C) 2005 International Business + * Machines Corporation. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the Common Public License as published by + * IBM Corporation; either version 1 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Common Public License for more details. + * + * You should have received a copy of the Common Public License + * along with this program; if not, a copy can be viewed at + * http://www.opensource.org/licenses/cpl1.0.php. + */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <fcntl.h> +#include <limits.h> + +#include "tpm_nvcommon.h" +#include "tpm_tspi.h" +#include "tpm_utils.h" + +static int nvindex_set; +static int nvindex; +static int offset; +static int length = -1; +static int fillvalue = -1; +static const char *filename; +static BOOL passWellKnown = FALSE; +static BOOL askPassword = FALSE; +static const char *password; +static char *data; + +TSS_HCONTEXT hContext = 0; + + +static int parse(const int aOpt, const char *aArg) +{ + + switch (aOpt) { + case 'i': + if (parseHexOrDecimal(aArg, &nvindex, UINT_MAX, + "NVRAM index") != 0) + return -1; + + nvindex_set = 1; + + break; + + case 's': + if (parseHexOrDecimal(aArg, &length, UINT_MAX, + "length of data") != 0) + return -1; + break; + + case 'n': + if (parseHexOrDecimal(aArg, &offset, UINT_MAX, + "write offset") != 0) + return -1; + break; + + case 'd': + data = strdup(aArg); + if (data == NULL) { + logError(_("Out of memory\n")); + return -1; + } + break; + + case 'f': + filename = aArg; + break; + + case 'm': + if (parseHexOrDecimal(aArg, &fillvalue, UCHAR_MAX, + "fill value") != 0) + return -1; + break; + + case 'p': + password = aArg; + if (!password) + askPassword = TRUE; + else + askPassword = FALSE; + passWellKnown = FALSE; + break; + + case 'z': + password = NULL; + passWellKnown = TRUE; + askPassword = FALSE; + break; + + case 'u': + useUnicode = TRUE; + break; + + default: + return -1; + } + return 0; +} + +static void help(const char* aCmd) +{ + logCmdHelp(aCmd); + logUnicodeCmdOption(); + logCmdOption("-z, --well-known", + _("Use 20 bytes of zeros (TSS_WELL_KNOWN_SECRET) as the TPM secret authorization data")); + logCmdOption("-p, --password", + _("Owner or NVRAM area password depending on permissions")); + logNVIndexCmdOption(); + logCmdOption("-s, --size", + _("Number of bytes to write to the NVRAM area")); + logCmdOption("-n, --offset", + _("Offset at which to start writing into the NVRAM area")); + logCmdOption("-f, --filename", + _("File whose contents to write into the NVRAM area")); + logCmdOption("-d, --data", + _("Data to write into the NVRAM area")); +} + +int main(int argc, char **argv) +{ + + TSS_HTPM hTpm; + TSS_HNVSTORE nvObject; + TSS_FLAG fNvAttrs; + UINT32 ulDataLength, bytesToWrite, off; + BYTE *rgbDataToWrite = NULL; + TSS_HPOLICY hTpmPolicy, hDataPolicy; + TPM_NV_DATA_PUBLIC *nvpub = NULL; + int iRc = -1; + BYTE well_known_secret[] = TSS_WELL_KNOWN_SECRET; + int pswd_len = -1; + struct option hOpts[] = { + {"index" , required_argument, NULL, 'i'}, + {"size" , required_argument, NULL, 's'}, + {"offset" , required_argument, NULL, 'n'}, + {"data" , required_argument, NULL, 'd'}, + {"filename" , required_argument, NULL, 'f'}, + {"fillvalue" , required_argument, NULL, 'm'}, + {"password" , optional_argument, NULL, 'p'}, + {"use-unicode", no_argument, NULL, 'u'}, + {NULL , no_argument, NULL, 0}, + }; + struct stat statbuf; + int fd = -1; + + initIntlSys(); + + if (genericOptHandler + (argc, argv, "i:s:n:d:f:m:p::zu", hOpts, + sizeof(hOpts) / sizeof(struct option), parse, help) != 0) + goto out; + + if (nvindex_set == 0) { + logError(_("You must provide an index for the NVRAM space.\n")); + goto out; + } + + if (length > 0 && data == NULL && + filename == NULL && + fillvalue == -1) { + logError(_("Either data, name of file or fill value must be " + "provided.\n")); + goto out; + } + + if (data) { + ulDataLength = strlen(data); + + if (length >= 0 && (UINT32)length < ulDataLength) + ulDataLength = length; + + rgbDataToWrite = (BYTE *)data; + data = NULL; + } else if (filename) { + if (stat(filename, &statbuf) != 0) { + logError(_("Could not access file '%s'\n"), + filename); + goto out; + } + ulDataLength = statbuf.st_size; + + if (length >= 0 && (UINT32)length < ulDataLength) + ulDataLength = length; + + rgbDataToWrite = malloc(ulDataLength); + if (rgbDataToWrite == NULL) { + logError(_("Out of memory.\n")); + return -1; + } + fd = open(filename, O_RDONLY); + if (fd < 0) { + logError(_("Could not open file %s for reading.\n")); + return -1; + } + if (ulDataLength != + read(fd, rgbDataToWrite, ulDataLength)) { + logError(_("Error while reading data.\n")); + return -1; + } + close(fd); + fd = -1; + } else if (fillvalue >= 0) { + if (length < 0) { + logError(_("Requiring size parameter.\n")); + return -1; + } + ulDataLength = length; + rgbDataToWrite = malloc(ulDataLength); + if (rgbDataToWrite == NULL) { + logError(_("Out of memory.\n")); + return -1; + } + memset(rgbDataToWrite, fillvalue, ulDataLength); + } else { + ulDataLength = 0; + } + + if (contextCreate(&hContext) != TSS_SUCCESS) + goto out; + + if (contextConnect(hContext) != TSS_SUCCESS) + goto out_close; + + if (contextGetTpm(hContext, &hTpm) != TSS_SUCCESS) + goto out_close; + + fNvAttrs = 0; + + if (contextCreateObject(hContext, + TSS_OBJECT_TYPE_NV, + fNvAttrs, + &nvObject) != TSS_SUCCESS) + goto out_close; + + + if (askPassword) { + password = _GETPASSWD(_("Enter NVRAM access password: "), &pswd_len, + FALSE, useUnicode ); + if (!password) { + logError(_("Failed to get NVRAM access password\n")); + goto out_close; + } + } + if (password || passWellKnown) { + if (policyGet(hTpm, &hTpmPolicy) != TSS_SUCCESS) + goto out_close; + + if (password) { + if (pswd_len < 0) + pswd_len = strlen(password); + if (policySetSecret(hTpmPolicy, strlen(password), + (BYTE *)password) != TSS_SUCCESS) + goto out_close; + } else { + if (policySetSecret(hTpmPolicy, TCPA_SHA1_160_HASH_LEN, + (BYTE *)well_known_secret) != TSS_SUCCESS) + goto out_close; + } + + if (contextCreateObject + (hContext, TSS_OBJECT_TYPE_POLICY, TSS_POLICY_USAGE, + &hDataPolicy) != TSS_SUCCESS) + goto out_close; + + if (password) { + if (policySetSecret(hDataPolicy, strlen(password), + (BYTE *)password) != TSS_SUCCESS) + goto out_close; + } else { + if (policySetSecret(hDataPolicy, TCPA_SHA1_160_HASH_LEN, + (BYTE *)well_known_secret) != TSS_SUCCESS) + goto out_close; + } + + if (Tspi_Policy_AssignToObject(hDataPolicy, nvObject) != + TSS_SUCCESS) + goto out_close; + } + + if (getNVDataPublic(hTpm, nvindex, &nvpub) != TSS_SUCCESS) { + logError(_("Could not get NVRAM area public information.\n")); + goto out_close_obj; + } + + if ((UINT32)offset > nvpub->dataSize) { + logError(_("The offset is outside the NVRAM area's size of %u bytes.\n"), + nvpub->dataSize); + goto out_close_obj; + } + + if ((UINT32)offset + ulDataLength > nvpub->dataSize) { + logError(_("Writing of data would go beyond the NVRAM area's size of %u bytes.\n"), + nvpub->dataSize); + goto out_close_obj; + } + + if (Tspi_SetAttribUint32(nvObject, + TSS_TSPATTRIB_NV_INDEX, + 0, + nvindex) != TSS_SUCCESS) + goto out_close_obj; + + + bytesToWrite = ulDataLength; + off = offset; + +#define WRITE_CHUNK_SIZE 1024 + while (bytesToWrite > 0) { + UINT32 chunk = (bytesToWrite > WRITE_CHUNK_SIZE) + ? WRITE_CHUNK_SIZE + : bytesToWrite; + if (NVWriteValue(nvObject, off, chunk, &rgbDataToWrite[off-offset]) != + TSS_SUCCESS) + goto out_close_obj; + + bytesToWrite -= chunk; + off += chunk; + } + + logMsg(_("Successfully wrote %d bytes at offset %d to NVRAM index " + "0x%x (%u).\n"), + ulDataLength, + offset, + nvindex, nvindex); + + iRc = 0; + + goto out_close; + + out_close_obj: + contextCloseObject(hContext, nvObject); + + out_close: + contextClose(hContext); + + out: + free(rgbDataToWrite); + freeNVDataPublic(nvpub); + + return iRc; +} Index: tpm-tools/src/tpm_mgmt/tpm_nvinfo.c =================================================================== --- /dev/null +++ tpm-tools/src/tpm_mgmt/tpm_nvinfo.c @@ -0,0 +1,190 @@ +/* + * The Initial Developer of the Original Code is International + * Business Machines Corporation. Portions created by IBM + * Corporation are Copyright (C) 2005 International Business + * Machines Corporation. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the Common Public License as published by + * IBM Corporation; either version 1 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Common Public License for more details. + * + * You should have received a copy of the Common Public License + * along with this program; if not, a copy can be viewed at + * http://www.opensource.org/licenses/cpl1.0.php. + */ + +#include <limits.h> +#include <arpa/inet.h> + +#include "tpm_tspi.h" +#include "tpm_utils.h" +#include "tpm_nvcommon.h" + + +static int nvindex_set; +static int nvindex; +TSS_HCONTEXT hContext = 0; + +static int parse(const int aOpt, const char *aArg) +{ + + switch (aOpt) { + case 'i': + if (parseHexOrDecimal(aArg, &nvindex, UINT_MAX, + "NVRAM index") != 0) + return -1; + + nvindex_set = 1; + + break; + + default: + return -1; + } + return 0; +} + + +static void help(const char* aCmd) +{ + logCmdHelp(aCmd); + logNVIndexCmdOption(); +} + + +static void pcrInfoShortDisplay(TPM_PCR_INFO_SHORT *tpis, const char *type) +{ + UINT16 i, c; + + c = 0; + + logMsg("PCR %sselection:\n", type); + + for (i = 0; i < tpis->pcrSelection.sizeOfSelect * 8; i++) { + if (tpis->pcrSelection.pcrSelect[(i / 8)] & (1 << (i & 0x7))) { + if (!c) + logMsg(" PCRs : "); + if (c) + logMsg(", "); + printf("%d", i); + c++; + } + } + + if (c) + logMsg("\n"); + + if (tpis->localityAtRelease) { + if (tpis->localityAtRelease == 0x1f) { + logMsg(" Localities : ALL\n"); + } else { + logMsg(" Localities : 0x%01x\n", tpis->localityAtRelease); + } + } + + if (c) { + logMsg(" Hash : "); + for (i = 0; i < 20; i++) + logMsg("%02x", tpis->digestAtRelease.digest[i]); + logMsg("\n"); + } +} + + +static void nvindexDisplay(TSS_HTPM hTpm, UINT32 nvindex) +{ + TSS_RESULT res; + char *buffer; + TPM_NV_DATA_PUBLIC *nvpub = NULL; + + logMsg("NVRAM index : 0x%08x (%u)\n", nvindex, nvindex); + + res = getNVDataPublic(hTpm, nvindex, &nvpub); + + if (res != TSS_SUCCESS) + goto out; + + pcrInfoShortDisplay(&nvpub->pcrInfoRead , "read "); + pcrInfoShortDisplay(&nvpub->pcrInfoWrite, "write "); + + buffer = printValueAsStrings((unsigned int)nvpub->permission.attributes, permvalues); + + logMsg("Permissions : 0x%08x (%s)\n", nvpub->permission.attributes, buffer); + free(buffer); + buffer = NULL; + + logMsg("bReadSTClear : %s\n", nvpub->bReadSTClear ? "TRUE" : "FALSE"); + logMsg("bWriteSTClear : %s\n", nvpub->bWriteSTClear ? "TRUE" : "FALSE"); + logMsg("bWriteDefine : %s\n", nvpub->bWriteDefine ? "TRUE" : "FALSE"); + + logMsg("Size : %d (0x%x)\n", nvpub->dataSize, nvpub->dataSize); + + + out: + freeNVDataPublic(nvpub); + + return; +} + + +int main(int argc, char **argv) +{ + TSS_HTPM hTpm; + TSS_FLAG fNvAttrs; + UINT32 ulResultLen; + BYTE *pResult = NULL; + int iRc = -1; + unsigned int i; + struct option hOpts[] = { + {"index", required_argument, NULL, 'i'}, + {NULL , no_argument, NULL, 0}, + }; + + initIntlSys(); + + if (genericOptHandler + (argc, argv, "i:o:", hOpts, + sizeof(hOpts) / sizeof(struct option), parse, help) != 0) + goto out; + + if (contextCreate(&hContext) != TSS_SUCCESS) + goto out; + + if (contextConnect(hContext) != TSS_SUCCESS) + goto out_close; + + if (contextGetTpm(hContext, &hTpm) != TSS_SUCCESS) + goto out_close; + + fNvAttrs = 0; + + if (getCapability(hTpm, TSS_TPMCAP_NV_LIST, 0, NULL, + &ulResultLen, &pResult) != TSS_SUCCESS) { + goto out_close; + } + + for (i = 0; i < ulResultLen/sizeof(UINT32); i++) { + UINT32 nvi; + nvi = Decode_UINT32(pResult + i * sizeof(UINT32)); + + if ((nvindex_set && nvi == (UINT32)nvindex) || !nvindex_set) { + nvindexDisplay(hTpm, nvi); + logMsg("\n"); + } + } + + iRc = 0; + + out_close: + contextClose(hContext); + + out: + + return iRc; +} Index: tpm-tools/src/tpm_mgmt/tpm_nvcommon.c =================================================================== --- /dev/null +++ tpm-tools/src/tpm_mgmt/tpm_nvcommon.c @@ -0,0 +1,273 @@ +/* + * The Initial Developer of the Original Code is International + * Business Machines Corporation. Portions created by IBM + * Corporation are Copyright (C) 2005 International Business + * Machines Corporation. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the Common Public License as published by + * IBM Corporation; either version 1 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Common Public License for more details. + * + * You should have received a copy of the Common Public License + * along with this program; if not, a copy can be viewed at + * http://www.opensource.org/licenses/cpl1.0.php. + */ + +#include <limits.h> + +#include "tpm_nvcommon.h" +#include "tpm_tspi.h" +#include "tpm_utils.h" + +const struct strings_with_values permvalues[] = { + { + .name = "AUTHREAD", + .value = TPM_NV_PER_AUTHREAD, + .desc = _("reading requires authorization"), + }, + { + .name = "AUTHWRITE", + .value = TPM_NV_PER_AUTHWRITE, + .desc = _("writing requires authorization"), + }, + { + .name = "OWNERREAD", + .value = TPM_NV_PER_OWNERREAD, + .desc = _("writing requires owner authorization"), + }, + { + .name = "OWNERWRITE", + .value = TPM_NV_PER_OWNERWRITE, + .desc = _("reading requires owner authorization"), + }, + { + .name = "PPREAD", + .value = TPM_NV_PER_PPREAD, + .desc = _("writing requires physical presence"), + }, + { + .name = "PPWRITE", + .value = TPM_NV_PER_PPWRITE, + .desc = _("reading requires physical presence"), + }, + { + .name = "GLOBALLOCK", + .value = TPM_NV_PER_GLOBALLOCK, + .desc = _("write to index 0 locks the NVRAM area until TPM_STARTUP(ST_CLEAR)"), + }, + { + .name = "READ_STCLEAR", + .value = TPM_NV_PER_READ_STCLEAR, + .desc = _("a read with size 0 to the same index prevents further reading until ST_STARTUP(ST_CLEAR)"), + }, + { + .name = "WRITE_STCLEAR", + .value = TPM_NV_PER_WRITE_STCLEAR, + .desc = _("a write with size 0 to the same index prevents further writing until ST_STARTUP(ST_CLEAR)"), + }, + { + .name = "WRITEDEFINE", + .value = TPM_NV_PER_WRITEDEFINE, + .desc = _("a write with size 0 to the same index locks the NVRAM area permanently"), + }, + { + .name = "WRITEALL", + .value = TPM_NV_PER_WRITEALL, + .desc = _("the value must be written in a single operation"), + }, + { + .name = NULL, + }, +}; + + +void displayStringsAndValues(const struct strings_with_values *svals, const char *indent) +{ + unsigned int i; + + logMsg("%sThe following strings are available:\n", indent); + for (i = 0; svals[i].name; i++) + logMsg("%s%15s : %s\n", indent, svals[i].name, svals[i].desc); +} + + +int parseStringWithValues(const char *aArg, + const struct strings_with_values *svals, + int *x, int maximum, const char *name) +{ + unsigned int offset = 0; + int i, num, numbytes; + size_t totlen = strlen(aArg); + *x = 0; + + while (offset < totlen) { + int found = 0; + for (i = 0; svals[i].name; i++) { + size_t len = strlen(svals[i].name); + if (strncmp(aArg + offset, svals[i].name, len) == 0 && + (aArg[offset+len] == '|' || + aArg[offset+len] == 0)) { + *x |= svals[i].value; + offset += len + 1; + found = 1; + break; + } + } + if (!found) { + if (strncmp(aArg + offset, "0x", 2) == 0) { + if (sscanf(aArg + offset, "%x%n", &num, &numbytes) != 1) { + logError(_("Could not parse hexadecimal number in %s.\n"), + aArg); + return -1; + } + if (!aArg[offset+numbytes] == '|' && + !aArg[offset+numbytes] == 0) { + logError(_("Illegal character following hexadecimal number in %s\n"), + aArg + offset); + return -1; + } + *x |= num; + + offset += numbytes + 1; + found = 1; + break; + } + } + if (!found) { + if (sscanf(aArg + offset, "%u%n", &num, &numbytes) != 1) { + logError(_("Could not parse data in %s.\n"), + aArg + offset); + return -1; + } + if (!aArg[offset+numbytes] == '|' && + !aArg[offset+numbytes] == 0) { + logError(_("Illegal character following decimal number in %s\n"), + aArg + offset); + return -1; + } + *x |= num; + + offset += numbytes + 1; + found = 1; + break; + } + if (!found) { + logError(_("Unknown element in %s.\n"), aArg + offset); + return -1; + } + } + + return 0; +} + + +char *printValueAsStrings(unsigned int value, + const struct strings_with_values *svals) +{ + unsigned int mask = (1 << 31), i,c; + unsigned int buffer_size = 1024; + char *buffer = calloc(1, buffer_size); + size_t len; + + c = 0; + + while (mask && value) { + if (value & mask) { + for (i = 0; svals[i].name; i++) { + if (svals[i].value == mask) { + len = strlen(svals[i].name); + if (len + strlen(buffer) + 1 > + buffer_size) { + buffer_size += 1024; + buffer = realloc(buffer, + buffer_size); + if (!buffer) + return NULL; + } + if (c) + strcat(buffer, "|"); + strcat(buffer, svals[i].name); + c ++; + value ^= mask; + break; + } + } + } + mask >>= 1; + } + if (value) { + if (c) + printf("|"); + printf("0x%x\n", value); + } + return buffer; +} + + +int parseHexOrDecimal(const char *aArg, int *x, int maximum, + const char *name) +{ + if (strncmp(aArg, "0x", 2) == 0) { + if (sscanf(aArg, "%x", x) != 1) { + return -1; + } + } else { + if (sscanf(aArg, "%u", x) != 1) { + return -1; + } + } + + if (maximum != 0 && (unsigned int)*x > (unsigned int)maximum) { + fprintf(stderr, "%s is out of range\n", + name); + return -1; + } + + return 0; +} + + +TSS_RESULT getNVDataPublic(TSS_HTPM hTpm, TPM_NV_INDEX nvindex, TPM_NV_DATA_PUBLIC **pub) +{ + TSS_RESULT res; + UINT32 ulResultLen; + BYTE *pResult; + UINT64 off = 0; + + res = getCapability(hTpm, TSS_TPMCAP_NV_INDEX, sizeof(UINT32), + (BYTE *)&nvindex, &ulResultLen, &pResult); + + if (res != TSS_SUCCESS) + return res; + + *pub = calloc(1, sizeof(TPM_NV_DATA_PUBLIC)); + if (*pub == NULL) { + res = TSS_E_OUTOFMEMORY; + goto err_exit; + } + + res = unloadNVDataPublic(&off, pResult, ulResultLen, *pub); + + if (res != TSS_SUCCESS) { + freeNVDataPublic(*pub); + *pub = NULL; + } +err_exit: + return res; +} + +void freeNVDataPublic(TPM_NV_DATA_PUBLIC *pub) +{ + if (!pub) + return; + + free(pub->pcrInfoRead.pcrSelection.pcrSelect); + free(pub->pcrInfoWrite.pcrSelection.pcrSelect); + free(pub); +} Index: tpm-tools/src/tpm_mgmt/tpm_nvcommon.h =================================================================== --- /dev/null +++ tpm-tools/src/tpm_mgmt/tpm_nvcommon.h @@ -0,0 +1,73 @@ +/* + * The Initial Developer of the Original Code is International + * Business Machines Corporation. Portions created by IBM + * Corporation are Copyright (C) 2005 International Business + * Machines Corporation. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the Common Public License as published by + * IBM Corporation; either version 1 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Common Public License for more details. + * + * You should have received a copy of the Common Public License + * along with this program; if not, a copy can be viewed at + * http://www.opensource.org/licenses/cpl1.0.php. + */ +#ifndef TPM_NVCOMMON_H +#define TPM_NVCOMMON_H + +#include "tpm_tspi.h" + + +struct strings_with_values +{ + const char *name; + UINT32 value; + const char *desc; +}; + +extern const struct strings_with_values permvalues[]; + +int parseStringWithValues(const char *aArg, + const struct strings_with_values *svals, + int *x, int maximum, const char *name); + +char *printValueAsStrings(unsigned int value, + const struct strings_with_values *svals); + +int parseHexOrDecimal(const char *aArg, int *x, int maximum, + const char *name); + +void displayStringsAndValues(const struct strings_with_values *svals, const char *indent); + +TSS_RESULT getNVDataPublic(TSS_HTPM hTpm, TPM_NV_INDEX nvindex, TPM_NV_DATA_PUBLIC **pub); +void freeNVDataPublic(TPM_NV_DATA_PUBLIC *pub); + +static inline UINT16 +Decode_UINT16(BYTE * in) +{ + UINT16 temp = 0; + temp = (in[1] & 0xFF); + temp |= (in[0] << 8); + return temp; +} + +static inline UINT32 +Decode_UINT32(BYTE * y) +{ + UINT32 x = 0; + + x = y[0]; + x = ((x << 8) | (y[1] & 0xFF)); + x = ((x << 8) | (y[2] & 0xFF)); + x = ((x << 8) | (y[3] & 0xFF)); + + return x; +} + +#endif /* TPM_NVCOMMON_H */ Index: tpm-tools/lib/tpm_log.c =================================================================== --- tpm-tools.orig/lib/tpm_log.c +++ tpm-tools/lib/tpm_log.c @@ -151,6 +151,16 @@ void logUnicodeCmdOption() logCmdOption("-u, --unicode", _("Use TSS UNICODE encoding for passwords to comply with applications using TSS popup boxes")); } +void logOwnerPassCmdOption() +{ + logCmdOption("-o, --pwdo", _("Owner password")); +} + +void logNVIndexCmdOption() +{ + logCmdOption("-i, --index", _("Index of the NVRAM area")); +} + void logCmdHelp(const char *aCmd) { logMsg(_("Usage: %s [options]\n"), aCmd); Index: tpm-tools/include/tpm_utils.h =================================================================== --- tpm-tools.orig/include/tpm_utils.h +++ tpm-tools/include/tpm_utils.h @@ -110,4 +110,7 @@ void logGenericOptions( ); void logCmdHelp( const char *a_pszCmd ); void logCmdHelpEx( const char *a_pszCmd, char *a_pszArgs[], char *a_pszArgDescs[] ); char *logBool( BOOL aValue ); +void logOwnerPassCmdOption( ); +void logNVIndexCmdOption( ); + #endif ------------------------------------------------------------------------------ All of the data generated in your IT infrastructure is seriously valuable. Why? It contains a definitive record of application performance, security threats, fraudulent activity, and more. Splunk takes this data and makes sense of it. IT sense. And common sense. http://p.sf.net/sfu/splunk-d2d-c2 _______________________________________________ TrouSerS-tech mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/trousers-tech
