Coverage Report

Created: 2025-10-13 06:07

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/tpm2/Shutdown.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 "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
}