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