This patch adds 5 tools for accessing and managing 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.
-v2:
- tpm_nvdefine: changed the 'd' short parameter to an 'a'
- added --list-only parameter to tpm_nvinfo to only display the defined NVRAM
areas' indices
- removed initialization values from all static variables
- converted parameters and functions from 'int' to 'unsigned int' since no
negative values are needed
- fixes to functions parsing values
- tpm_nvread -i <index> now displays all the content of the NVRAM area
without having to give a size
Signed-off-by: Stefan Berger <[email protected]>
---
include/tpm_tspi.h | 15 +
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 | 317 +++++++++++++++++++++++++++++++++++++
src/tpm_mgmt/tpm_nvcommon.h | 66 +++++++
src/tpm_mgmt/tpm_nvdefine.c | 288 ++++++++++++++++++++++++++++++++++
src/tpm_mgmt/tpm_nvinfo.c | 208 ++++++++++++++++++++++++
src/tpm_mgmt/tpm_nvread.c | 307 ++++++++++++++++++++++++++++++++++++
src/tpm_mgmt/tpm_nvrelease.c | 178 +++++++++++++++++++++
src/tpm_mgmt/tpm_nvwrite.c | 359 +++++++++++++++++++++++++++++++++++++++++++
12 files changed, 1832 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,288 @@
+/*
+ * 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 unsigned int nvindex;
+static unsigned int nvperm;
+static unsigned int nvsize;
+static const char *ownerpass;
+static BOOL ownerWellKnown;
+static BOOL askOwnerPass;
+static const char *datapass;
+static BOOL dataWellKnown;
+static BOOL askDataPass;
+static int end;
+
+TSS_HCONTEXT hContext = 0;
+
+
+static int parse(const int aOpt, const char *aArg)
+{
+ switch (aOpt) {
+ case 'i':
+ if (parseHexOrDecimal(aArg, &nvindex, 0, UINT_MAX,
+ "NVRAM index") != 0)
+ return -1;
+ break;
+
+ case 'p':
+ if (!strcmp(aArg, "?")) {
+ displayStringsAndValues(permvalues, "");
+ end = 1;
+ return 0;
+ }
+ if (parseStringWithValues(aArg, permvalues, &nvperm, UINT_MAX,
+ "NVRAM permission") != 0)
+ return -1;
+ break;
+
+ case 's':
+ if (parseHexOrDecimal(aArg, &nvsize, 0, 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'},
+ {"data-well-known" , no_argument, NULL, 'z'},
+ {"owner-well-known", no_argument, NULL, 'y'},
+ {NULL , no_argument, NULL, 0},
+ };
+
+ initIntlSys();
+
+ if (genericOptHandler
+ (argc, argv, "i:s:p:o:a: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 area.\n"));
+ goto out;
+ }
+
+ if (nvperm == 0 && (UINT32)nvindex != 0xffffffff) {
+ logError(_("You must provide permission bits for the NVRAM
area.\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 area 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,21 @@ 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 unsigned int nvindex;
+static const char *ownerpass;
+static BOOL ownerWellKnown;
+static BOOL askOwnerPass;
+TSS_HCONTEXT hContext = 0;
+
+
+static int parse(const int aOpt, const char *aArg)
+{
+
+ switch (aOpt) {
+ case 'i':
+ if (parseHexOrDecimal(aArg, &nvindex, 0, 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"));
+ logOwnerPassCmdOption();
+ logNVIndexCmdOption();
+}
+
+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'},
+ {"owner-well-known", no_argument, NULL, 'y'},
+ {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 area.\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 area 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,307 @@
+/*
+ * 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 unsigned int nvindex;
+static unsigned int offset;
+static unsigned int length;
+static BOOL length_set;
+static const char *filename;
+static BOOL passWellKnown;
+static const char *password;
+static BOOL askPassword;
+
+TSS_HCONTEXT hContext = 0;
+
+
+static int parse(const int aOpt, const char *aArg)
+{
+
+ switch (aOpt) {
+ case 'i':
+ if (parseHexOrDecimal(aArg, &nvindex, 0, UINT_MAX,
+ "NVRAM index") != 0)
+ return -1;
+ break;
+
+ case 'n':
+ if (parseHexOrDecimal(aArg, &offset, 0, UINT_MAX,
+ "read offset") != 0)
+ return -1;
+ break;
+
+ case 's':
+ if (parseHexOrDecimal(aArg, &length, 0, UINT_MAX,
+ "length of data") != 0)
+ return -1;
+ length_set = TRUE;
+ 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'},
+ {"well-known" , no_argument, NULL, 'z'},
+ {NULL , no_argument, NULL, 0},
+ };
+ int fd = -1;
+
+ initIntlSys();
+
+ if (genericOptHandler
+ (argc, argv, "i:s:n: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 area.\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 (!length_set)
+ ulDataLength = nvpub->dataSize;
+
+ 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 data from NVRAM area 0x%x (%u) "
+ "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,359 @@
+/*
+ * 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 BOOL nvindex_set;
+static unsigned int nvindex;
+static unsigned int offset;
+static unsigned int length;
+static int fillvalue = -1;
+static const char *filename;
+static BOOL passWellKnown;
+static BOOL askPassword;
+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, 0, UINT_MAX,
+ "NVRAM index") != 0)
+ return -1;
+
+ nvindex_set = 1;
+
+ break;
+
+ case 's':
+ if (parseHexOrDecimal(aArg, &length, 0, UINT_MAX,
+ "length of data") != 0)
+ return -1;
+ break;
+
+ case 'n':
+ if (parseHexOrDecimal(aArg, &offset, 0, 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, (unsigned int *)&fillvalue,
+ 0, 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"));
+ logCmdOption("-m, --fill-value",
+ _("The byte to fill the NVRAM area with"));
+}
+
+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'},
+ {"well-known" , no_argument, NULL, 'z'},
+ {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 area.\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,208 @@
+/*
+ * 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 BOOL nvindex_set;
+static unsigned int nvindex;
+static BOOL list_only;
+TSS_HCONTEXT hContext = 0;
+
+static int parse(const int aOpt, const char *aArg)
+{
+
+ switch (aOpt) {
+ case 'i':
+ if (parseHexOrDecimal(aArg, &nvindex, 0, UINT_MAX,
+ "NVRAM index") != 0)
+ return -1;
+
+ nvindex_set = TRUE;
+ list_only = FALSE;
+
+ break;
+
+ case 'n':
+ list_only = TRUE;
+ nvindex_set = FALSE;
+ break;
+
+ default:
+ return -1;
+ }
+ return 0;
+}
+
+
+static void help(const char* aCmd)
+{
+ logCmdHelp(aCmd);
+ logNVIndexCmdOption();
+ logCmdOption("-n, --list-only",
+ _("Only list the defined NVRAM areas' indices."));
+}
+
+
+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;
+ UINT32 ulResultLen;
+ BYTE *pResult = NULL;
+ int iRc = -1;
+ unsigned int i;
+ struct option hOpts[] = {
+ {"index" , required_argument, NULL, 'i'},
+ {"list-only", no_argument, NULL, 'n'},
+ {NULL , no_argument, NULL, 0},
+ };
+
+ initIntlSys();
+
+ if (genericOptHandler
+ (argc, argv, "i:o:n", 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;
+
+
+ if (getCapability(hTpm, TSS_TPMCAP_NV_LIST, 0, NULL,
+ &ulResultLen, &pResult) != TSS_SUCCESS) {
+ goto out_close;
+ }
+
+ if (list_only) {
+ logMsg(_("The following NVRAM areas have been defined:\n"));
+ }
+
+ for (i = 0; i < ulResultLen/sizeof(UINT32); i++) {
+ UINT32 nvi;
+ nvi = Decode_UINT32(pResult + i * sizeof(UINT32));
+
+ if (list_only) {
+ logMsg("0x%08x (%d)\n", nvi, nvi);
+ } else {
+ 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,317 @@
+/*
+ * 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 "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 NVRAM area authorization"),
+ },
+ {
+ .name = "AUTHWRITE",
+ .value = TPM_NV_PER_AUTHWRITE,
+ .desc = _("writing requires NVRAM area 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,
+ unsigned int *x, unsigned 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;
+
+ while (isspace(*(aArg + offset)))
+ offset++;
+
+ 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;
+ }
+ }
+
+ while (!found) {
+ if (!isdigit(*(aArg+offset)))
+ break;
+
+ 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: %s.\n"),
+ name, 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);
+ char printbuf[30];
+ 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) {
+ snprintf(printbuf, sizeof(printbuf), "%s0x%x",
+ c ? "|" : "",
+ value);
+ len = strlen(printbuf);
+ if (len + strlen(buffer) + 1 > buffer_size) {
+ buffer_size += 1024;
+ buffer = realloc(buffer,
+ buffer_size);
+ if (!buffer)
+ return NULL;
+ }
+ if (c)
+ strcat(buffer, printbuf);
+ }
+ return buffer;
+}
+
+
+int parseHexOrDecimal(const char *aArg, unsigned int *x,
+ unsigned int minimum, unsigned int maximum,
+ const char *name)
+{
+ while (isspace(*aArg))
+ aArg++;
+
+ if (strncmp(aArg, "0x", 2) == 0) {
+ if (sscanf(aArg, "%x", x) != 1) {
+ return -1;
+ }
+ } else {
+ if (!isdigit(*aArg)) {
+ fprintf(stderr,
+ "%s must be a positive integer.\n", name);
+ return -1;
+ }
+
+ if (sscanf(aArg, "%u", x) != 1) {
+ return -1;
+ }
+ }
+
+ if ((*x > maximum) || (*x < minimum)) {
+ fprintf(stderr, "%s is out of valid range [%u, %u]\n",
+ name, minimum, maximum);
+ 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,66 @@
+/*
+ * 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,
+ unsigned int *x, unsigned int maximum,
+ const char *name);
+
+char *printValueAsStrings(unsigned int value,
+ const struct strings_with_values *svals);
+
+int parseHexOrDecimal(const char *aArg, unsigned int *x,
+ unsigned int minimum, unsigned 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 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