tss: add support for getting the names of objects (including NV objects)

This is a precursor to supporting TPM2_PolicySecret.  The essential
component of this policy is the name of the object being used for
authorization.  The most common elements for names are persistent and
NV objects.  In each case the hash is that of the public area, but the
NV object also has to have a special call to retrieve the public area
(TPM2_NV_ReadPublic instead of TPM2_ReadPublic).  Add a name option to
tpm2_ReadPublic to allow it to retrieve the name and add
tpm2_NV_ReadPublic to retrieve the name of and NV index.

Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
diff --git a/src/engine/e_tpm2.c b/src/engine/e_tpm2.c
index 9f55647..9057aef 100644
--- a/src/engine/e_tpm2.c
+++ b/src/engine/e_tpm2.c
@@ -177,7 +177,8 @@
 
 		rc = tpm2_get_bound_handle(tssContext, &session, key, NULL);
 		if (rc == TPM_RC_SUCCESS) {
-			rc = tpm2_ReadPublic(tssContext, key, NULL, session);
+			rc = tpm2_ReadPublic(tssContext, key, NULL, session,
+					     NULL);
 			if (rc)
 				tpm2_flush_handle(tssContext, session);
 		}
diff --git a/src/include/ibm-tss.h b/src/include/ibm-tss.h
index 5bb685d..4d7d1c0 100644
--- a/src/include/ibm-tss.h
+++ b/src/include/ibm-tss.h
@@ -163,7 +163,7 @@
 
 static inline TPM_RC
 tpm2_ReadPublic(TSS_CONTEXT *tssContext, TPM_HANDLE objectHandle,
-		TPMT_PUBLIC *pub, TPM_HANDLE auth)
+		TPMT_PUBLIC *pub, TPM_HANDLE auth, NAME_2B *name)
 {
 	ReadPublic_In rin;
 	ReadPublic_Out rout;
@@ -190,6 +190,35 @@
 
 	if (pub)
 		*pub = rout.outPublic.publicArea;
+	if (name)
+		*name = rout.name.t;
+
+	return rc;
+}
+
+static inline TPM_RC
+tpm2_NV_ReadPublic(TSS_CONTEXT *tssContext, TPM_HANDLE nvIndex,
+		   NAME_2B *nvName)
+{
+	TPM_RC rc;
+	NV_ReadPublic_In in;
+	NV_ReadPublic_Out out;
+
+	in.nvIndex = nvIndex;
+	rc = TSS_Execute (tssContext,
+			  (RESPONSE_PARAMETERS *)&out,
+			  (COMMAND_PARAMETERS *)&in,
+			  NULL,
+			  TPM_CC_NV_ReadPublic,
+			  TPM_RH_NULL, NULL, 0);
+
+	if (rc) {
+		tpm2_error(rc, "TPM2_NV_ReadPublic");
+		return rc;
+	}
+
+	if (nvName)
+		*nvName = out.nvName.t;
 
 	return rc;
 }
@@ -379,7 +408,7 @@
 		 * access to the public part.  It does this by keeping
 		 * key files, but request the public part just to make
 		 * sure*/
-		tpm2_ReadPublic(tssContext, tpmKey,  NULL, TPM_RH_NULL);
+		tpm2_ReadPublic(tssContext, tpmKey,  NULL, TPM_RH_NULL, NULL);
 		/* don't care what rout returns, the purpose of the
 		 * operation was to get the public key parameters into
 		 * the tss so it can construct the salt */
diff --git a/src/include/intel-tss.h b/src/include/intel-tss.h
index 2356874..d989e33 100644
--- a/src/include/intel-tss.h
+++ b/src/include/intel-tss.h
@@ -79,6 +79,7 @@
 #define TPM_RH_ENDORSEMENT	ESYS_TR_RH_ENDORSEMENT
 #define TPM_RH_NULL		ESYS_TR_NONE
 
+#define TPM_HT_NV_INDEX		TPM2_HT_NV_INDEX
 #define TPM_HT_PERMANENT	TPM2_HT_PERMANENT
 #define TPM_HT_TRANSIENT	TPM2_HT_TRANSIENT
 #define TPM_HT_PERSISTENT	TPM2_HT_PERSISTENT
@@ -184,6 +185,7 @@
 TSS_CONVERT_MARSHAL(TPMT_SENSITIVE, )
 TSS_CONVERT_MARSHAL(TPM2B_ECC_POINT, )
 TSS_CONVERT_MARSHAL(TPM2B_DIGEST, )
+TSS_CONVERT_MARSHAL(TPM2B_NAME, )
 TSS_CONVERT_MARSHAL(TPM2B_PUBLIC, )
 TSS_CONVERT_MARSHAL(TPM2B_PRIVATE, )
 TSS_CONVERT_MARSHAL(TPML_PCR_SELECTION, )
@@ -198,6 +200,7 @@
 TSS_CONVERT_UNMARSHAL(UINT16, )
 TSS_CONVERT_UNMARSHAL(UINT32, )
 TSS_CONVERT_UNMARSHAL(TPM2B_DIGEST, )
+TSS_CONVERT_UNMARSHAL(TPM2B_NAME, )
 TSS_CONVERT_UNMARSHAL(TPMT_SIGNATURE, X)
 
 #define ARRAY_SIZE(A) (sizeof(A)/sizeof(A[0]))
@@ -798,27 +801,50 @@
 
 static inline TPM_RC
 tpm2_ReadPublic(TSS_CONTEXT *tssContext, TPM_HANDLE objectHandle,
-		TPMT_PUBLIC *pub, TPM_HANDLE auth)
+		TPMT_PUBLIC *pub, TPM_HANDLE auth, NAME_2B *name)
 {
 	TPM2B_PUBLIC *out;
+	NAME_2B *out_name;
 	TPM_RC rc;
 
 	if (auth != TPM_RH_NULL)
 		intel_sess_helper(tssContext, auth, TPMA_SESSION_ENCRYPT);
 
 	rc = Esys_ReadPublic(tssContext, objectHandle, auth, ESYS_TR_NONE,
-			     ESYS_TR_NONE, &out, NULL, NULL);
+			     ESYS_TR_NONE, &out, &out_name, NULL);
 	if (rc)
 		return rc;
 
 	if (pub)
 		*pub = out->publicArea;
+	if (name)
+		*name = *out_name;
 	free(out);
 
 	return rc;
 }
 
 static inline TPM_RC
+tpm2_NV_ReadPublic(TSS_CONTEXT *tssContext, TPM_HANDLE nvIndex,
+		   NAME_2B *nvName)
+{
+	TPM_RC rc;
+	NAME_2B *name;
+
+	rc = Esys_NV_ReadPublic(tssContext, nvIndex, ESYS_TR_NONE, ESYS_TR_NONE,
+				ESYS_TR_NONE, NULL, &name);
+
+	if (rc)
+		return rc;
+
+	if (nvName)
+		*nvName = *name;
+	free(name);
+
+	return rc;
+}
+
+static inline TPM_RC
 tpm2_RSA_Decrypt(TSS_CONTEXT *tssContext, TPM_HANDLE keyHandle,
 		 PUBLIC_KEY_RSA_2B *cipherText, TPMT_RSA_DECRYPT *inScheme,
 		 PUBLIC_KEY_RSA_2B *message,
diff --git a/src/libcommon/tpm2-common.c b/src/libcommon/tpm2-common.c
index 2822414..11c4f88 100644
--- a/src/libcommon/tpm2-common.c
+++ b/src/libcommon/tpm2-common.c
@@ -984,7 +984,7 @@
 TPM_RC tpm2_readpublic(TSS_CONTEXT *tssContext, TPM_HANDLE handle,
 		       TPMT_PUBLIC *pub)
 {
-	return tpm2_ReadPublic(tssContext, handle, pub, TPM_RH_NULL);
+	return tpm2_ReadPublic(tssContext, handle, pub, TPM_RH_NULL, NULL);
 }
 
 TPM_RC tpm2_get_bound_handle(TSS_CONTEXT *tssContext, TPM_HANDLE *handle,
@@ -1443,6 +1443,10 @@
 	unlink(keyfile);
 	snprintf(keyfile, sizeof(keyfile), "%s/hp%08x.bin", dir, key);
 	unlink(keyfile);
+	if ((key >> 24) == TPM_HT_NV_INDEX) {
+		snprintf(keyfile, sizeof(keyfile), "%s/nvp%08x.bin", dir, key);
+		unlink(keyfile);
+	}
 }
 
 void tpm2_rm_tssdir(const char *dir)
diff --git a/src/provider/store.c b/src/provider/store.c
index 56a39e0..d42e731 100644
--- a/src/provider/store.c
+++ b/src/provider/store.c
@@ -85,7 +85,8 @@
 
 			rc = tpm2_get_bound_handle(tssContext, &session, key, NULL);
 			if (rc == TPM_RC_SUCCESS) {
-				rc = tpm2_ReadPublic(tssContext, key, NULL, session);
+				rc = tpm2_ReadPublic(tssContext, key, NULL,
+						     session, NULL);
 				if (rc)
 					tpm2_flush_handle(tssContext, session);
 		}