blob: 9aa9410ddd0a4f5776ce3e72cc3c835580d16092 [file] [log] [blame]
Vadim Bendebury56797522015-05-20 10:32:25 -07001// 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//
17TPM_RC
18TPM2_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}