Coverage Report

Created: 2025-07-18 06:04

/src/tpm2/NV_Extend.c
Line
Count
Source (jump to first uncovered line)
1
// This file was extracted from the TCG Published
2
// Trusted Platform Module Library
3
// Part 3: Commands
4
// Family "2.0"
5
// Level 00 Revision 01.16
6
// October 30, 2014
7
8
#include "InternalRoutines.h"
9
#include "NV_Extend_fp.h"
10
#include "NV_spt_fp.h"
11
//
12
//
13
//     Error Returns               Meaning
14
//
15
//     TPM_RC_ATTRIBUTES           the TPMA_NV_EXTEND attribute is not SET in the Index referenced
16
//                                 by nvIndex
17
//     TPM_RC_NV_AUTHORIZATION     the authorization was valid but the authorizing entity (authHandle) is
18
//                                 not allowed to write to the Index referenced by nvIndex
19
//     TPM_RC_NV_LOCKED            the Index referenced by nvIndex is locked for writing
20
//
21
TPM_RC
22
TPM2_NV_Extend(
23
   NV_Extend_In      *in            // IN: input parameter list
24
   )
25
0
{
26
0
   TPM_RC                  result;
27
0
   NV_INDEX                nvIndex;
28
29
0
   TPM2B_DIGEST            oldDigest;
30
0
   TPM2B_DIGEST            newDigest;
31
0
   HASH_STATE              hashState;
32
33
// Input Validation
34
35
   // Common access checks, NvWriteAccessCheck() may return TPM_RC_NV_AUTHORIZATION
36
   // or TPM_RC_NV_LOCKED
37
0
   result = NvWriteAccessChecks(in->authHandle, in->nvIndex);
38
0
   if(result != TPM_RC_SUCCESS)
39
0
       return result;
40
41
   // Check if there are platform-specific reasons to prohibit updating this
42
   // index.
43
0
   if (!_plat__NvUpdateAllowed(in->nvIndex))
44
0
       return TPM_RC_NV_AUTHORIZATION;
45
46
   // Get NV index info
47
0
   NvGetIndexInfo(in->nvIndex, &nvIndex);
48
49
   // Make sure that this is an extend index
50
0
   if(nvIndex.publicArea.attributes.TPMA_NV_EXTEND != SET)
51
0
       return TPM_RC_ATTRIBUTES + RC_NV_Extend_nvIndex;
52
53
   // If the Index is not-orderly, or if this is the first write, NV will
54
   // need to be updated.
55
0
   if(   nvIndex.publicArea.attributes.TPMA_NV_ORDERLY == CLEAR
56
0
      || nvIndex.publicArea.attributes.TPMA_NV_WRITTEN == CLEAR)
57
0
   {
58
       // Check if NV is available. NvIsAvailable may return TPM_RC_NV_UNAVAILABLE
59
       // TPM_RC_NV_RATE or TPM_RC_SUCCESS.
60
0
       result = NvIsAvailable();
61
0
       if(result != TPM_RC_SUCCESS)
62
0
           return result;
63
0
   }
64
65
// Internal Data Update
66
67
   // Perform the write.
68
0
   oldDigest.t.size = CryptGetHashDigestSize(nvIndex.publicArea.nameAlg);
69
0
   pAssert(oldDigest.t.size <= sizeof(oldDigest.t.buffer));
70
0
   if(nvIndex.publicArea.attributes.TPMA_NV_WRITTEN == SET)
71
0
   {
72
0
       NvGetIndexData(in->nvIndex, &nvIndex, 0,
73
0
                      oldDigest.t.size, oldDigest.t.buffer);
74
0
   }
75
0
   else
76
0
   {
77
0
       MemorySet(oldDigest.t.buffer, 0, oldDigest.t.size);
78
0
   }
79
   // Start hash
80
0
   newDigest.t.size = CryptStartHash(nvIndex.publicArea.nameAlg, &hashState);
81
82
   // Adding old digest
83
0
   CryptUpdateDigest2B(&hashState, &oldDigest.b);
84
85
   // Adding new data
86
0
   CryptUpdateDigest2B(&hashState, &in->data.b);
87
88
   // Complete hash
89
0
   CryptCompleteHash2B(&hashState, &newDigest.b);
90
91
   // Write extended hash back.
92
   // Note, this routine will SET the TPMA_NV_WRITTEN attribute if necessary
93
0
   return NvWriteIndexData(in->nvIndex, &nvIndex, 0,
94
0
                           newDigest.t.size, newDigest.t.buffer);
95
0
}