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 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