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_SetBits_fp.h"
10 #include "NV_spt_fp.h"
11 //
12 //
13 // Error Returns Meaning
14 //
15 // TPM_RC_ATTRIBUTES the TPMA_NV_BITS attribute is not SET in the Index referenced by
16 // 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
TPM2_NV_SetBits(NV_SetBits_In * in)22 TPM2_NV_SetBits(
23 NV_SetBits_In *in // IN: input parameter list
24 )
25 {
26 TPM_RC result;
27 NV_INDEX nvIndex;
28 UINT64 oldValue;
29 UINT64 newValue;
30
31 // Input Validation
32
33 // Common access checks, NvWriteAccessCheck() may return TPM_RC_NV_AUTHORIZATION
34 // or TPM_RC_NV_LOCKED
35 // error may be returned at this point
36 result = NvWriteAccessChecks(in->authHandle, in->nvIndex);
37 if(result != TPM_RC_SUCCESS)
38 return result;
39
40 // Get NV index info
41 NvGetIndexInfo(in->nvIndex, &nvIndex);
42
43 // Make sure that this is a bit field
44 if(nvIndex.publicArea.attributes.TPMA_NV_BITS != SET)
45 return TPM_RC_ATTRIBUTES + RC_NV_SetBits_nvIndex;
46
47 // If index is not been written, initialize it
48 if(nvIndex.publicArea.attributes.TPMA_NV_WRITTEN == CLEAR)
49 oldValue = 0;
50 else
51 // Read index data
52 NvGetIntIndexData(in->nvIndex, &nvIndex, &oldValue);
53
54 // Figure out what the new value is going to be
55 newValue = oldValue | in->bits;
56
57 // If the Index is not-orderly and it has changed, or if this is the first
58 // write, NV will need to be updated.
59 if( ( nvIndex.publicArea.attributes.TPMA_NV_ORDERLY == CLEAR
60 && newValue != oldValue)
61 || nvIndex.publicArea.attributes.TPMA_NV_WRITTEN == CLEAR)
62 {
63
64 // Internal Data Update
65 // Check if NV is available. NvIsAvailable may return TPM_RC_NV_UNAVAILABLE
66 // TPM_RC_NV_RATE or TPM_RC_SUCCESS.
67 result = NvIsAvailable();
68 if(result != TPM_RC_SUCCESS)
69 return result;
70
71 // Write index data back. If necessary, this function will SET
72 // TPMA_NV_WRITTEN.
73 result = NvWriteIndexData(in->nvIndex, &nvIndex, 0, 8, &newValue);
74 }
75 return result;
76
77 }
78