At present tpm_sealdata only allows one to seal to current PCR values.
This patch extends the interface and functionality to support sealing to
specified PCR values.  This is useful for sealing to a known platform
state before booting the new platform configuration, e.g. for system
updates.  

The interface extension is simple; if the user specifies an equal sign
(=) followed by a hex string after the PCR index in the -p option, then
the hex string is used as the desired PCR value rather then current
value of that PCR.  For example, the following command:
$ tpm_sealdata -p 0 -p 12=71591395285927F96413B48D1049A4AEAF178BB6 -p 14
means to seal to the current values of PCRs 0 and 14 but to the
specified value for PCR 12.

Signed-off-by:  Stephen Smalley <[email protected]>

---

 src/cmds/tpm_sealdata.c |   50 +++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 47 insertions(+), 3 deletions(-)

diff --git a/src/cmds/tpm_sealdata.c b/src/cmds/tpm_sealdata.c
index 80b005f..59d826d 100644
--- a/src/cmds/tpm_sealdata.c
+++ b/src/cmds/tpm_sealdata.c
@@ -20,6 +20,8 @@
  */
 #include <openssl/evp.h>
 #include <limits.h>
+#include <stdlib.h>
+#include <string.h>
 #include "tpm_tspi.h"
 #include "tpm_utils.h"
 #include "tpm_seal.h"
@@ -44,7 +46,11 @@ static void help(const char *aCmd)
 static char in_filename[PATH_MAX] = "", out_filename[PATH_MAX] = "";
 static TSS_HPCRS hPcrs = NULL_HPCRS;
 static TSS_HTPM hTpm;
-static UINT32 selectedPcrs[24];
+#define NPCRS 24
+#define PCRSIZE 20
+static UINT32 selectedPcrs[NPCRS];
+static BYTE PcrValues[NPCRS][PCRSIZE];
+static BOOL PcrValueSet[NPCRS];
 static UINT32 selectedPcrsLen = 0;
 static BOOL passUnicode = FALSE;
 static BOOL isWellKnown = FALSE;
@@ -69,7 +75,42 @@ static int parse(const int aOpt, const char *aArg)
                break;
        case 'p':
                if (aArg) {
-                       selectedPcrs[selectedPcrsLen++] = atoi(aArg);
+                       UINT32 idx; 
+                       char *val;
+                       unsigned int i;
+
+                       if (selectedPcrsLen >= NPCRS) {
+                               logError(_("Too many PCRs specified\n"));
+                               return -1;
+                       }
+                       idx = atoi(aArg);
+                       for (i = 0; i < selectedPcrsLen; i++) {
+                               if (selectedPcrs[i] == idx) {
+                                       logError(_("PCR %u specified more than 
once\n"), idx);
+                                       return -1;
+                               }
+                       }
+
+                       selectedPcrs[selectedPcrsLen] = idx;
+                       val = strchr(aArg, '=');
+                       if (val) {
+                               int i;
+                               val++;
+                               if (strlen(val) < PCRSIZE*2) {
+                                       logError(_("Hex string for PCR %u is 
too short\n"), idx);
+                                       return -1;
+                               }
+                               for (i = 0; i < PCRSIZE; val+=2, i++) {
+                                       unsigned int byte;
+                                       if (sscanf(val, "%2x", &byte) != 1) {
+                                               logError(_("Could not parse hex 
string for PCR %u\n"), idx);
+                                               return -1;
+                                       }
+                                       PcrValues[selectedPcrsLen][i] = (BYTE) 
byte;
+                               }
+                               PcrValueSet[selectedPcrsLen] = 1;
+                       }
+                       selectedPcrsLen++;
                        rc = 0;
                }
                break;
@@ -177,7 +218,10 @@ int main(int argc, char **argv)
                        goto out_close;
 
                for (i = 0; i < selectedPcrsLen; i++) {
-                       if (tpmPcrRead(hTpm, selectedPcrs[i], &pcrSize, 
&pcrValue) != TSS_SUCCESS)
+                       if (PcrValueSet[i]) {
+                               pcrSize = PCRSIZE;
+                               pcrValue = PcrValues[i];
+                       } else if (tpmPcrRead(hTpm, selectedPcrs[i], &pcrSize, 
&pcrValue) != TSS_SUCCESS)
                                goto out_close;
 
                        if (pcrcompositeSetPcrValue(hPcrs, selectedPcrs[i], 
pcrSize, pcrValue)


-- 
Stephen Smalley
National Security Agency


------------------------------------------------------------------------------
The ultimate all-in-one performance toolkit: Intel(R) Parallel Studio XE:
Pinpoint memory and threading errors before they happen.
Find and fix more than 250 security defects in the development cycle.
Locate bottlenecks in serial and parallel code that limit performance.
http://p.sf.net/sfu/intel-dev2devfeb
_______________________________________________
TrouSerS-tech mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/trousers-tech

Reply via email to