blob: 6d82716712c71da1b2df37fb4c9f2dc2c8006be5 [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;
Vadim Bendebury56797522015-05-20 10:32:25 -070029 gp.recoveryTime = 1000; // in seconds (~16.67 minutes)
30 gp.lockoutRecovery = 1000; // in seconds
31 gp.lockOutAuthEnabled = TRUE; // Use of lockoutAuth is enabled
32 // Record persistent DA parameter changes to NV
33 NvWriteReserved(NV_FAILED_TRIES, &gp.failedTries);
34 NvWriteReserved(NV_MAX_TRIES, &gp.maxTries);
35 NvWriteReserved(NV_RECOVERY_TIME, &gp.recoveryTime);
36 NvWriteReserved(NV_LOCKOUT_RECOVERY, &gp.lockoutRecovery);
37 NvWriteReserved(NV_LOCKOUT_AUTH_ENABLED, &gp.lockOutAuthEnabled);
38 return;
39}
40//
41//
42// DAStartup()
43//
44// This function is called by TPM2_Startup() to initialize the DA parameters. In the case of Startup(CLEAR),
45// use of lockoutAuth will be enabled if the lockout recovery time is 0. Otherwise, lockoutAuth will not be
46// enabled until the TPM has been continuously powered for the lockoutRecovery time.
47// This function requires that NV be available and not rate limiting.
48//
49void
50DAStartup(
51 STARTUP_TYPE type // IN: startup type
52 )
53{
54 // For TPM Reset, if lockoutRecovery is 0, enable use of lockoutAuth.
55 if(type == SU_RESET)
56 {
57 if(gp.lockoutRecovery == 0)
58 {
59 gp.lockOutAuthEnabled = TRUE;
60 // Record the changes to NV
61 NvWriteReserved(NV_LOCKOUT_AUTH_ENABLED, &gp.lockOutAuthEnabled);
62 }
63 }
64 // If DA has not been disabled and the previous shutdown is not orderly
65 // failedTries is not already at its maximum then increment 'failedTries'
66 if( gp.recoveryTime != 0
67 && g_prevOrderlyState == SHUTDOWN_NONE
68 && gp.failedTries < gp.maxTries)
69 {
70 gp.failedTries++;
71 // Record the change to NV
72 NvWriteReserved(NV_FAILED_TRIES, &gp.failedTries);
73 }
74 // Reset self healing timers
75 s_selfHealTimer = g_time;
76 s_lockoutTimer = g_time;
77 return;
78}
79//
80//
81// DARegisterFailure()
82//
83// This function is called when a authorization failure occurs on an entity that is subject to dictionary-attack
84// protection. When a DA failure is triggered, register the failure by resetting the relevant self-healing timer
85// to the current time.
86//
87void
88DARegisterFailure(
89 TPM_HANDLE handle // IN: handle for failure
90 )
91{
92 // Reset the timer associated with lockout if the handle is the lockout auth.
93 if(handle == TPM_RH_LOCKOUT)
94 s_lockoutTimer = g_time;
95 else
96 s_selfHealTimer = g_time;
97//
98 return;
99}
100//
101//
102// DASelfHeal()
103//
104// This function is called to check if sufficient time has passed to allow decrement of failedTries or to re-
105// enable use of lockoutAuth.
106// This function should be called when the time interval is updated.
107//
108void
109DASelfHeal(
110 void
111 )
112{
113 // Regular auth self healing logic
114 // If no failed authorization tries, do nothing. Otherwise, try to
115 // decrease failedTries
116 if(gp.failedTries != 0)
117 {
118 // if recovery time is 0, DA logic has been disabled. Clear failed tries
119 // immediately
120 if(gp.recoveryTime == 0)
121 {
122 gp.failedTries = 0;
123 // Update NV record
124 NvWriteReserved(NV_FAILED_TRIES, &gp.failedTries);
125 }
126 else
127 {
128 UINT64 decreaseCount;
129 // In the unlikely event that failedTries should become larger than
130 // maxTries
131 if(gp.failedTries > gp.maxTries)
132 gp.failedTries = gp.maxTries;
133 // How much can failedTried be decreased
134 decreaseCount = ((g_time - s_selfHealTimer) / 1000) / gp.recoveryTime;
135 if(gp.failedTries <= (UINT32) decreaseCount)
136 // should not set failedTries below zero
137 gp.failedTries = 0;
138 else
139 gp.failedTries -= (UINT32) decreaseCount;
140 // the cast prevents overflow of the product
141 s_selfHealTimer += (decreaseCount * (UINT64)gp.recoveryTime) * 1000;
142 if(decreaseCount != 0)
143 // If there was a change to the failedTries, record the changes
144 // to NV
145 NvWriteReserved(NV_FAILED_TRIES, &gp.failedTries);
146 }
147 }
148 // LockoutAuth self healing logic
149 // If lockoutAuth is enabled, do nothing. Otherwise, try to see if we
150 // may enable it
151 if(!gp.lockOutAuthEnabled)
152 {
153 // if lockout authorization recovery time is 0, a reboot is required to
154 // re-enable use of lockout authorization. Self-healing would not
155 // apply in this case.
156 if(gp.lockoutRecovery != 0)
157//
158 {
159 if(((g_time - s_lockoutTimer)/1000) >= gp.lockoutRecovery)
160 {
161 gp.lockOutAuthEnabled = TRUE;
162 // Record the changes to NV
163 NvWriteReserved(NV_LOCKOUT_AUTH_ENABLED, &gp.lockOutAuthEnabled);
164 }
165 }
166 }
167 return;
168}