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_WriteLock_fp.h"
10#include "NV_spt_fp.h"
11//
12//
13//     Error Returns                    Meaning
14//
15//     TPM_RC_ATTRIBUTES                neither TPMA_NV_WRITEDEFINE nor
16//                                      TPMA_NV_WRITE_STCLEAR is SET in Index referenced by
17//                                      nvIndex
18//     TPM_RC_NV_AUTHORIZATION          the authorization was valid but the authorizing entity (authHandle) is
19//                                      not allowed to write to the Index referenced by nvIndex
20//
21TPM_RC
22TPM2_NV_WriteLock(
23   NV_WriteLock_In       *in                  // IN: input parameter list
24   )
25{
26   TPM_RC            result;
27   NV_INDEX          nvIndex;
28
29// Input Validation:
30
31   // Common write access checks, a TPM_RC_NV_AUTHORIZATION or TPM_RC_NV_LOCKED
32   // error may be returned at this point
33   result = NvWriteAccessChecks(in->authHandle, in->nvIndex);
34   if(result != TPM_RC_SUCCESS)
35   {
36       if(result == TPM_RC_NV_AUTHORIZATION)
37           return TPM_RC_NV_AUTHORIZATION;
38       // If write access failed because the index is already locked, then it is
39       // no error.
40       return TPM_RC_SUCCESS;
41   }
42
43   // Get NV index info
44   NvGetIndexInfo(in->nvIndex, &nvIndex);
45
46   // if neither TPMA_NV_WRITEDEFINE nor TPMA_NV_WRITE_STCLEAR is set, the index
47   // can not be write-locked
48   if(   nvIndex.publicArea.attributes.TPMA_NV_WRITEDEFINE == CLEAR
49      && nvIndex.publicArea.attributes.TPMA_NV_WRITE_STCLEAR == CLEAR)
50       return TPM_RC_ATTRIBUTES + RC_NV_WriteLock_nvIndex;
51
52// Internal Data Update
53
54   // The command needs NV update. Check if NV is available.
55   // A TPM_RC_NV_UNAVAILABLE or TPM_RC_NV_RATE error may be returned at
56   // this point
57   result = NvIsAvailable();
58   if(result != TPM_RC_SUCCESS)
59       return result;
60
61   // Set the WRITELOCK attribute.
62   // Note: if TPMA_NV_WRITELOCKED were already SET, then the write access check
63   // above would have failed and this code isn't executed.
64   nvIndex.publicArea.attributes.TPMA_NV_WRITELOCKED = SET;
65
66   // Write index info back
67   NvWriteIndexInfo(in->nvIndex, &nvIndex);
68
69   return TPM_RC_SUCCESS;
70}
71