Home | History | Annotate | Download | only in tpm2
      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