Coverage Report

Created: 2025-10-10 06:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/tpm2/Startup.c
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 "Startup_fp.h"
10
#include "Unique_fp.h"
11
//
12
//
13
//     Error Returns                     Meaning
14
//
15
//     TPM_RC_LOCALITY                   a Startup(STATE) does not have the same H-CRTM state as the
16
//                                       previous Startup() or the locality of the startup is not 0 pr 3
17
//     TPM_RC_NV_UNINITIALIZED           the saved state cannot be recovered and a Startup(CLEAR) is
18
//                                       requried.
19
//     TPM_RC_VALUE                      start up type is not compatible with previous shutdown sequence
20
//
21
TPM_RC
22
TPM2_Startup(
23
   Startup_In        *in                 // IN: input parameter list
24
   )
25
539
{
26
539
   STARTUP_TYPE            startup;
27
539
   TPM_RC                  result;
28
539
   BOOL                    prevDrtmPreStartup;
29
539
   BOOL                    prevStartupLoc3;
30
539
   BYTE                    locality = _plat__LocalityGet();
31
32
   // In the PC Client specification, only locality 0 and 3 are allowed
33
539
   if(locality != 0 && locality != 3)
34
0
       return TPM_RC_LOCALITY;
35
   // Indicate that the locality was 3 unless there was an H-CRTM
36
539
   if(g_DrtmPreStartup)
37
0
       locality = 0;
38
539
   g_StartupLocality3 = (locality == 3);
39
40
   // The command needs NV update. Check if NV is available.
41
   // A TPM_RC_NV_UNAVAILABLE or TPM_RC_NV_RATE error may be returned at
42
   // this point
43
539
   result = NvIsAvailable();
44
539
   if(result != TPM_RC_SUCCESS)
45
0
       return result;
46
// Input Validation
47
48
   // Read orderly shutdown states from previous power cycle
49
539
   NvReadReserved(NV_ORDERLY, &g_prevOrderlyState);
50
51
   // See if the orderly state indicates that state was saved
52
539
   if(     (g_prevOrderlyState & ~(PRE_STARTUP_FLAG | STARTUP_LOCALITY_3))
53
539
       == TPM_SU_STATE)
54
0
   {
55
       // If so, extrat the saved flags (HACK)
56
0
       prevDrtmPreStartup = (g_prevOrderlyState & PRE_STARTUP_FLAG) != 0;
57
0
       prevStartupLoc3 = (g_prevOrderlyState & STARTUP_LOCALITY_3) != 0;
58
0
       g_prevOrderlyState = TPM_SU_STATE;
59
0
   }
60
539
   else
61
539
   {
62
539
       prevDrtmPreStartup = 0;
63
539
       prevStartupLoc3 = 0;
64
539
   }
65
   // if this startup is a TPM Resume, then the H-CRTM states have to match.
66
539
   if(in->startupType == TPM_SU_STATE)
67
0
  {
68
0
         if(g_DrtmPreStartup != prevDrtmPreStartup)
69
0
             return TPM_RC_VALUE + RC_Startup_startupType;
70
0
         if(g_StartupLocality3 != prevStartupLoc3)
71
0
             return TPM_RC_LOCALITY;
72
0
  }
73
  // if the previous power cycle was shut down with no StateSave command, or
74
  // with StateSave command for CLEAR, or the part of NV used for TPM_SU_STATE
75
  // cannot be recovered, then this cycle can not startup up with STATE
76
539
  if(in->startupType == TPM_SU_STATE)
77
0
  {
78
0
      if(     g_prevOrderlyState == SHUTDOWN_NONE
79
0
         ||   g_prevOrderlyState == TPM_SU_CLEAR)
80
0
          return TPM_RC_VALUE + RC_Startup_startupType;
81
82
0
         if(g_nvOk == FALSE)
83
0
             return TPM_RC_NV_UNINITIALIZED;
84
0
  }
85
86
// Internal Date Update
87
88
  // Translate the TPM2_ShutDown and TPM2_Startup sequence into the startup
89
  // types. Will only be a SU_RESTART if the NV is OK
90
539
  if(     in->startupType == TPM_SU_CLEAR
91
539
      && g_prevOrderlyState == TPM_SU_STATE
92
0
      && g_nvOk == TRUE)
93
0
  {
94
0
      startup = SU_RESTART;
95
      // Read state reset data
96
0
      NvReadReserved(NV_STATE_RESET, &gr);
97
0
  }
98
  // In this check, we don't need to look at g_nvOk because that was checked
99
  // above
100
539
  else if(in->startupType == TPM_SU_STATE && g_prevOrderlyState == TPM_SU_STATE)
101
0
  {
102
      // Read state clear and state reset data
103
0
      NvReadReserved(NV_STATE_CLEAR, &gc);
104
0
      NvReadReserved(NV_STATE_RESET, &gr);
105
0
      startup = SU_RESUME;
106
0
  }
107
539
  else
108
539
  {
109
539
      startup = SU_RESET;
110
539
  }
111
112
  // Read persistent data from NV
113
539
  NvReadPersistent();
114
115
  // After reading the dictionary attack parameters, disable DA mitigation by
116
  // calling `DAPreInstall_Init()`, if necessary.
117
  // Note that this is not TPM2-compliant (b/178365982).
118
539
  if (gp.recoveryTime != 0 || gp.lockoutRecovery != 0)
119
0
    DAPreInstall_Init();
120
121
  // Crypto Startup
122
539
  CryptUtilStartup(startup);
123
124
  // Read the platform unique value that is used as VENDOR_PERMANENT auth value
125
539
  g_platformUniqueDetails.t.size = (UINT16)_plat__GetUnique(1,
126
539
                                     sizeof(g_platformUniqueDetails.t.buffer),
127
539
                                     g_platformUniqueDetails.t.buffer);
128
129
  // Start up subsystems
130
  // Start counters and timers
131
539
  TimeStartup(startup);
132
133
  // Start dictionary attack subsystem
134
539
  DAStartup(startup);
135
136
  // Enable hierarchies
137
539
  HierarchyStartup(startup);
138
139
   // Restore/Initialize PCR
140
539
   PCRStartup(startup, locality);
141
142
   // Restore/Initialize command audit information
143
539
   CommandAuditStartup(startup);
144
145
   // Object context variables
146
539
   if(startup == SU_RESET)
147
539
   {
148
       // Reset object context ID to 0
149
539
       gr.objectContextID = 0;
150
       // Reset clearCount to 0
151
539
       gr.clearCount= 0;
152
539
   }
153
154
   // Initialize session table
155
539
   SessionStartup(startup);
156
157
   // Initialize index/evict data.   This function clear read/write locks
158
   // in NV index
159
539
   NvEntityStartup(startup);
160
161
   // Initialize the orderly shut down flag for this cycle to SHUTDOWN_NONE.
162
539
   gp.orderlyState = SHUTDOWN_NONE;
163
539
   NvWriteReserved(NV_ORDERLY, &gp.orderlyState);
164
165
   // Update TPM internal states if command succeeded.
166
   // Record a TPM2_Startup command has been received.
167
539
   TPMRegisterStartup();
168
169
   // The H-CRTM state no longer matters
170
539
   g_DrtmPreStartup = FALSE;
171
172
#ifdef EMBEDDED_MODE
173
   _plat__StartupCallback((startup == SU_RESET) || (startup == SU_RESTART));
174
#endif
175
176
539
   return TPM_RC_SUCCESS;
177
539
}