Line | Count | Source |
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 | 0 | { |
22 | 0 | 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 | 0 | result = NvIsAvailable(); |
28 | 0 | 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 | 0 | if(g_pcrReConfig && in->shutdownType == TPM_SU_STATE) |
34 | 0 | return TPM_RC_TYPE + RC_Shutdown_shutdownType; |
35 | | |
36 | | // Internal Data Update |
37 | | |
38 | | // PCR private date state save |
39 | 0 | PCRStateSave(in->shutdownType); |
40 | | |
41 | | // Get DRBG state |
42 | 0 | CryptDrbgGetPutState(GET_STATE); |
43 | | |
44 | | // Save all orderly data |
45 | 0 | NvWriteReserved(NV_ORDERLY_DATA, &go); |
46 | | |
47 | | // Save RAM backed NV index data |
48 | 0 | NvStateSave(); |
49 | |
|
50 | 0 | if(in->shutdownType == TPM_SU_STATE) |
51 | 0 | { |
52 | | // Save STATE_RESET and STATE_CLEAR data |
53 | 0 | NvWriteReserved(NV_STATE_CLEAR, &gc); |
54 | 0 | NvWriteReserved(NV_STATE_RESET, &gr); |
55 | 0 | } |
56 | 0 | else if(in->shutdownType == TPM_SU_CLEAR) |
57 | 0 | { |
58 | | // Save STATE_RESET data |
59 | 0 | NvWriteReserved(NV_STATE_RESET, &gr); |
60 | 0 | } |
61 | | |
62 | | // Write orderly shut down state |
63 | 0 | if(in->shutdownType == TPM_SU_CLEAR) |
64 | 0 | gp.orderlyState = TPM_SU_CLEAR; |
65 | 0 | else if(in->shutdownType == TPM_SU_STATE) |
66 | 0 | { |
67 | 0 | gp.orderlyState = TPM_SU_STATE; |
68 | | // Hack for the H-CRTM and Startup locality settings |
69 | 0 | if(g_DrtmPreStartup) |
70 | 0 | gp.orderlyState |= PRE_STARTUP_FLAG; |
71 | 0 | else if(g_StartupLocality3) |
72 | 0 | gp.orderlyState |= STARTUP_LOCALITY_3; |
73 | 0 | } |
74 | 0 | else |
75 | 0 | pAssert(FALSE); |
76 | |
|
77 | 0 | 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 | 0 | return TPM_RC_SUCCESS; |
87 | 0 | } |