blob: 9a1a3eb5978aa1c5a084a5b4a4af9b4605abe686 [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 4: Supporting Routines
4// Family "2.0"
5// Level 00 Revision 01.16
6// October 30, 2014
7
8#define DA_C
9#include "InternalRoutines.h"
10//
11//
12// Functions
13//
14// DAPreInstall_Init()
15//
16// This function initializes the DA parameters to their manufacturer-default values. The default values are
17// determined by a platform-specific specification.
18// This function should not be called outside of a manufacturing or simulation environment.
19// The DA parameters will be restored to these initial values by TPM2_Clear().
20//
21void
22DAPreInstall_Init(
23 void
24 )
25{
26 gp.failedTries = 0;
Vadim Bendebury8f3d7352016-07-28 11:59:26 -070027 // TODO(vbendeb): consider finer tuning of this value (crosbug.com/p/55708)
28 gp.maxTries = 200;
Leo Laief08cb02021-03-14 17:19:15 +080029
30 // Disable DA mitigation mechanism.
31 gp.recoveryTime = 0;
32 gp.lockoutRecovery = 0;
33
Vadim Bendebury56797522015-05-20 10:32:25 -070034 gp.lockOutAuthEnabled = TRUE; // Use of lockoutAuth is enabled
35 // Record persistent DA parameter changes to NV
36 NvWriteReserved(NV_FAILED_TRIES, &gp.failedTries);
37 NvWriteReserved(NV_MAX_TRIES, &gp.maxTries);
38 NvWriteReserved(NV_RECOVERY_TIME, &gp.recoveryTime);
39 NvWriteReserved(NV_LOCKOUT_RECOVERY, &gp.lockoutRecovery);
40 NvWriteReserved(NV_LOCKOUT_AUTH_ENABLED, &gp.lockOutAuthEnabled);
41 return;
42}
43//
44//
45// DAStartup()
46//
47// This function is called by TPM2_Startup() to initialize the DA parameters. In the case of Startup(CLEAR),
48// use of lockoutAuth will be enabled if the lockout recovery time is 0. Otherwise, lockoutAuth will not be
49// enabled until the TPM has been continuously powered for the lockoutRecovery time.
50// This function requires that NV be available and not rate limiting.
51//
52void
53DAStartup(
54 STARTUP_TYPE type // IN: startup type
55 )
56{
57 // For TPM Reset, if lockoutRecovery is 0, enable use of lockoutAuth.
58 if(type == SU_RESET)
59 {
60 if(gp.lockoutRecovery == 0)
61 {
62 gp.lockOutAuthEnabled = TRUE;
63 // Record the changes to NV
64 NvWriteReserved(NV_LOCKOUT_AUTH_ENABLED, &gp.lockOutAuthEnabled);
65 }
66 }
67 // If DA has not been disabled and the previous shutdown is not orderly
68 // failedTries is not already at its maximum then increment 'failedTries'
69 if( gp.recoveryTime != 0
70 && g_prevOrderlyState == SHUTDOWN_NONE
71 && gp.failedTries < gp.maxTries)
72 {
73 gp.failedTries++;
74 // Record the change to NV
75 NvWriteReserved(NV_FAILED_TRIES, &gp.failedTries);
76 }
77 // Reset self healing timers
78 s_selfHealTimer = g_time;
79 s_lockoutTimer = g_time;
80 return;
81}
82//
83//
84// DARegisterFailure()
85//
86// This function is called when a authorization failure occurs on an entity that is subject to dictionary-attack
87// protection. When a DA failure is triggered, register the failure by resetting the relevant self-healing timer
88// to the current time.
89//
90void
91DARegisterFailure(
92 TPM_HANDLE handle // IN: handle for failure
93 )
94{
95 // Reset the timer associated with lockout if the handle is the lockout auth.
96 if(handle == TPM_RH_LOCKOUT)
97 s_lockoutTimer = g_time;
98 else
99 s_selfHealTimer = g_time;
100//
101 return;
102}
103//
104//
105// DASelfHeal()
106//
107// This function is called to check if sufficient time has passed to allow decrement of failedTries or to re-
108// enable use of lockoutAuth.
109// This function should be called when the time interval is updated.
110//
111void
112DASelfHeal(
113 void
114 )
115{
116 // Regular auth self healing logic
117 // If no failed authorization tries, do nothing. Otherwise, try to
118 // decrease failedTries
119 if(gp.failedTries != 0)
120 {
121 // if recovery time is 0, DA logic has been disabled. Clear failed tries
122 // immediately
123 if(gp.recoveryTime == 0)
124 {
125 gp.failedTries = 0;
126 // Update NV record
127 NvWriteReserved(NV_FAILED_TRIES, &gp.failedTries);
128 }
129 else
130 {
131 UINT64 decreaseCount;
132 // In the unlikely event that failedTries should become larger than
133 // maxTries
134 if(gp.failedTries > gp.maxTries)
135 gp.failedTries = gp.maxTries;
136 // How much can failedTried be decreased
137 decreaseCount = ((g_time - s_selfHealTimer) / 1000) / gp.recoveryTime;
138 if(gp.failedTries <= (UINT32) decreaseCount)
139 // should not set failedTries below zero
140 gp.failedTries = 0;
141 else
142 gp.failedTries -= (UINT32) decreaseCount;
143 // the cast prevents overflow of the product
144 s_selfHealTimer += (decreaseCount * (UINT64)gp.recoveryTime) * 1000;
145 if(decreaseCount != 0)
146 // If there was a change to the failedTries, record the changes
147 // to NV
148 NvWriteReserved(NV_FAILED_TRIES, &gp.failedTries);
149 }
150 }
151 // LockoutAuth self healing logic
152 // If lockoutAuth is enabled, do nothing. Otherwise, try to see if we
153 // may enable it
154 if(!gp.lockOutAuthEnabled)
155 {
156 // if lockout authorization recovery time is 0, a reboot is required to
157 // re-enable use of lockout authorization. Self-healing would not
158 // apply in this case.
159 if(gp.lockoutRecovery != 0)
160//
161 {
162 if(((g_time - s_lockoutTimer)/1000) >= gp.lockoutRecovery)
163 {
164 gp.lockOutAuthEnabled = TRUE;
165 // Record the changes to NV
166 NvWriteReserved(NV_LOCKOUT_AUTH_ENABLED, &gp.lockOutAuthEnabled);
167 }
168 }
169 }
170 return;
171}