aboutsummaryrefslogtreecommitdiff
path: root/NV_Extend.c
diff options
context:
space:
mode:
authorVadim Bendebury <vbendeb@chromium.org>2015-05-20 10:32:25 -0700
committerVadim Bendebury <vbendeb@chromium.org>2015-05-20 22:32:05 -0700
commit5679752bf24c21135884e987c4077e2f71848971 (patch)
tree3e680dd91a7af84c45ea1170ee88225bd4ad32c8 /NV_Extend.c
downloadtpm2-5679752bf24c21135884e987c4077e2f71848971.tar.gz
Initial commit to seed TPM2.0 source code directory
LICENSE file text copied from TCG library specification. README describes the procedure used to extract source code from parts 3 and 4 of the specification. The python scripts and part{34}.txt files will be removed in the following commits. Change-Id: Ie281e6e988481831f33483053455e8aff8f3f75f Signed-off-by: Vadim Bendebury <vbendeb@chromium.org>
Diffstat (limited to 'NV_Extend.c')
-rw-r--r--NV_Extend.c90
1 files changed, 90 insertions, 0 deletions
diff --git a/NV_Extend.c b/NV_Extend.c
new file mode 100644
index 0000000..197bb1a
--- /dev/null
+++ b/NV_Extend.c
@@ -0,0 +1,90 @@
+// This file was extracted from the TCG Published
+// Trusted Platform Module Library
+// Part 3: Commands
+// Family "2.0"
+// Level 00 Revision 01.16
+// October 30, 2014
+
+#include "InternalRoutines.h"
+#include "NV_Extend_fp.h"
+#include "NV_spt_fp.h"
+//
+//
+// Error Returns Meaning
+//
+// TPM_RC_ATTRIBUTES the TPMA_NV_EXTEND attribute is not SET in the Index referenced
+// by nvIndex
+// TPM_RC_NV_AUTHORIZATION the authorization was valid but the authorizing entity (authHandle) is
+// not allowed to write to the Index referenced by nvIndex
+// TPM_RC_NV_LOCKED the Index referenced by nvIndex is locked for writing
+//
+TPM_RC
+TPM2_NV_Extend(
+ NV_Extend_In *in // IN: input parameter list
+ )
+{
+ TPM_RC result;
+ NV_INDEX nvIndex;
+
+ TPM2B_DIGEST oldDigest;
+ TPM2B_DIGEST newDigest;
+ HASH_STATE hashState;
+
+// Input Validation
+
+ // Common access checks, NvWriteAccessCheck() may return TPM_RC_NV_AUTHORIZATION
+ // or TPM_RC_NV_LOCKED
+ result = NvWriteAccessChecks(in->authHandle, in->nvIndex);
+ if(result != TPM_RC_SUCCESS)
+ return result;
+
+ // Get NV index info
+ NvGetIndexInfo(in->nvIndex, &nvIndex);
+
+ // Make sure that this is an extend index
+ if(nvIndex.publicArea.attributes.TPMA_NV_EXTEND != SET)
+ return TPM_RC_ATTRIBUTES + RC_NV_Extend_nvIndex;
+
+ // If the Index is not-orderly, or if this is the first write, NV will
+ // need to be updated.
+ if( nvIndex.publicArea.attributes.TPMA_NV_ORDERLY == CLEAR
+ || nvIndex.publicArea.attributes.TPMA_NV_WRITTEN == CLEAR)
+ {
+ // Check if NV is available. NvIsAvailable may return TPM_RC_NV_UNAVAILABLE
+ // TPM_RC_NV_RATE or TPM_RC_SUCCESS.
+ result = NvIsAvailable();
+ if(result != TPM_RC_SUCCESS)
+ return result;
+ }
+
+// Internal Data Update
+
+ // Perform the write.
+ oldDigest.t.size = CryptGetHashDigestSize(nvIndex.publicArea.nameAlg);
+ pAssert(oldDigest.t.size <= sizeof(oldDigest.t.buffer));
+ if(nvIndex.publicArea.attributes.TPMA_NV_WRITTEN == SET)
+ {
+ NvGetIndexData(in->nvIndex, &nvIndex, 0,
+ oldDigest.t.size, oldDigest.t.buffer);
+ }
+ else
+ {
+ MemorySet(oldDigest.t.buffer, 0, oldDigest.t.size);
+ }
+ // Start hash
+ newDigest.t.size = CryptStartHash(nvIndex.publicArea.nameAlg, &hashState);
+
+ // Adding old digest
+ CryptUpdateDigest2B(&hashState, &oldDigest.b);
+
+ // Adding new data
+ CryptUpdateDigest2B(&hashState, &in->data.b);
+
+ // Complete hash
+ CryptCompleteHash2B(&hashState, &newDigest.b);
+
+ // Write extended hash back.
+ // Note, this routine will SET the TPMA_NV_WRITTEN attribute if necessary
+ return NvWriteIndexData(in->nvIndex, &nvIndex, 0,
+ newDigest.t.size, newDigest.t.buffer);
+}