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 "Shutdown_fp.h"
     10 //
     11 //
     12 //     Error Returns                   Meaning
     13 //
     14 //     TPM_RC_TYPE                     if PCR bank has been re-configured, a CLEAR StateSave() is
     15 //                                     required
     16 //
     17 TPM_RC
     18 TPM2_Shutdown(
     19    Shutdown_In       *in               // IN: input parameter list
     20    )
     21 {
     22    TPM_RC            result;
     23 
     24    // The command needs NV update. Check if NV is available.
     25    // A TPM_RC_NV_UNAVAILABLE or TPM_RC_NV_RATE error may be returned at
     26    // this point
     27    result = NvIsAvailable();
     28    if(result != TPM_RC_SUCCESS) return result;
     29 
     30 // Input Validation
     31 
     32    // If PCR bank has been reconfigured, a CLEAR state save is required
     33    if(g_pcrReConfig && in->shutdownType == TPM_SU_STATE)
     34        return TPM_RC_TYPE + RC_Shutdown_shutdownType;
     35 
     36 // Internal Data Update
     37 
     38    // PCR private date state save
     39    PCRStateSave(in->shutdownType);
     40 
     41    // Get DRBG state
     42    CryptDrbgGetPutState(GET_STATE);
     43 
     44    // Save all orderly data
     45    NvWriteReserved(NV_ORDERLY_DATA, &go);
     46 
     47    // Save RAM backed NV index data
     48    NvStateSave();
     49 
     50    if(in->shutdownType == TPM_SU_STATE)
     51    {
     52        // Save STATE_RESET and STATE_CLEAR data
     53        NvWriteReserved(NV_STATE_CLEAR, &gc);
     54        NvWriteReserved(NV_STATE_RESET, &gr);
     55    }
     56    else if(in->shutdownType == TPM_SU_CLEAR)
     57    {
     58        // Save STATE_RESET data
     59        NvWriteReserved(NV_STATE_RESET, &gr);
     60    }
     61 
     62    // Write orderly shut down state
     63    if(in->shutdownType == TPM_SU_CLEAR)
     64        gp.orderlyState = TPM_SU_CLEAR;
     65    else if(in->shutdownType == TPM_SU_STATE)
     66    {
     67        gp.orderlyState = TPM_SU_STATE;
     68        // Hack for the H-CRTM and Startup locality settings
     69          if(g_DrtmPreStartup)
     70              gp.orderlyState |= PRE_STARTUP_FLAG;
     71          else if(g_StartupLocality3)
     72              gp.orderlyState |= STARTUP_LOCALITY_3;
     73    }
     74    else
     75        pAssert(FALSE);
     76 
     77    NvWriteReserved(NV_ORDERLY, &gp.orderlyState);
     78 
     79    //   If PRE_STARTUP_FLAG was SET, then it will stay set in gp.orderlyState even
     80    //   if the TPM isn't actually shut down. This is OK because all other checks
     81    //   of gp.orderlyState are to see if it is SHUTDOWN_NONE. So, having
     82    //   gp.orderlyState set to another value that is also not SHUTDOWN_NONE, is not
     83    //   an issue. This must be the case, otherwise, it would be impossible to add
     84    //   an additional shutdown type without major changes to the code.
     85 
     86    return TPM_RC_SUCCESS;
     87 }
     88