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

Reply via email to