Line | Count | Source (jump to first uncovered line) |
1 | | // 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 | | // |
21 | | void |
22 | | DAPreInstall_Init( |
23 | | void |
24 | | ) |
25 | 444 | { |
26 | 444 | gp.failedTries = 0; |
27 | | // TODO(vbendeb): consider finer tuning of this value (crosbug.com/p/55708) |
28 | 444 | gp.maxTries = 200; |
29 | | |
30 | | // Disable DA mitigation mechanism. |
31 | 444 | gp.recoveryTime = 0; |
32 | 444 | gp.lockoutRecovery = 0; |
33 | | |
34 | 444 | gp.lockOutAuthEnabled = TRUE; // Use of lockoutAuth is enabled |
35 | | // Record persistent DA parameter changes to NV |
36 | 444 | NvWriteReserved(NV_FAILED_TRIES, &gp.failedTries); |
37 | 444 | NvWriteReserved(NV_MAX_TRIES, &gp.maxTries); |
38 | 444 | NvWriteReserved(NV_RECOVERY_TIME, &gp.recoveryTime); |
39 | 444 | NvWriteReserved(NV_LOCKOUT_RECOVERY, &gp.lockoutRecovery); |
40 | 444 | NvWriteReserved(NV_LOCKOUT_AUTH_ENABLED, &gp.lockOutAuthEnabled); |
41 | 444 | return; |
42 | 444 | } |
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 | | // |
52 | | void |
53 | | DAStartup( |
54 | | STARTUP_TYPE type // IN: startup type |
55 | | ) |
56 | 444 | { |
57 | | // For TPM Reset, if lockoutRecovery is 0, enable use of lockoutAuth. |
58 | 444 | if(type == SU_RESET) |
59 | 444 | { |
60 | 444 | if(gp.lockoutRecovery == 0) |
61 | 444 | { |
62 | 444 | gp.lockOutAuthEnabled = TRUE; |
63 | | // Record the changes to NV |
64 | 444 | NvWriteReserved(NV_LOCKOUT_AUTH_ENABLED, &gp.lockOutAuthEnabled); |
65 | 444 | } |
66 | 444 | } |
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 | 444 | if( gp.recoveryTime != 0 |
70 | 444 | && g_prevOrderlyState == SHUTDOWN_NONE |
71 | 444 | && gp.failedTries < gp.maxTries) |
72 | 0 | { |
73 | 0 | gp.failedTries++; |
74 | | // Record the change to NV |
75 | 0 | NvWriteReserved(NV_FAILED_TRIES, &gp.failedTries); |
76 | 0 | } |
77 | | // Reset self healing timers |
78 | 444 | s_selfHealTimer = g_time; |
79 | 444 | s_lockoutTimer = g_time; |
80 | 444 | return; |
81 | 444 | } |
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 | | // |
90 | | void |
91 | | DARegisterFailure( |
92 | | TPM_HANDLE handle // IN: handle for failure |
93 | | ) |
94 | 0 | { |
95 | | // Reset the timer associated with lockout if the handle is the lockout auth. |
96 | 0 | if(handle == TPM_RH_LOCKOUT) |
97 | 0 | s_lockoutTimer = g_time; |
98 | 0 | else |
99 | 0 | s_selfHealTimer = g_time; |
100 | | // |
101 | 0 | return; |
102 | 0 | } |
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 | | // |
111 | | void |
112 | | DASelfHeal( |
113 | | void |
114 | | ) |
115 | 888 | { |
116 | | // Regular auth self healing logic |
117 | | // If no failed authorization tries, do nothing. Otherwise, try to |
118 | | // decrease failedTries |
119 | 888 | if(gp.failedTries != 0) |
120 | 0 | { |
121 | | // if recovery time is 0, DA logic has been disabled. Clear failed tries |
122 | | // immediately |
123 | 0 | if(gp.recoveryTime == 0) |
124 | 0 | { |
125 | 0 | gp.failedTries = 0; |
126 | | // Update NV record |
127 | 0 | NvWriteReserved(NV_FAILED_TRIES, &gp.failedTries); |
128 | 0 | } |
129 | 0 | else |
130 | 0 | { |
131 | 0 | UINT64 decreaseCount; |
132 | | // In the unlikely event that failedTries should become larger than |
133 | | // maxTries |
134 | 0 | if(gp.failedTries > gp.maxTries) |
135 | 0 | gp.failedTries = gp.maxTries; |
136 | | // How much can failedTried be decreased |
137 | 0 | decreaseCount = ((g_time - s_selfHealTimer) / 1000) / gp.recoveryTime; |
138 | 0 | if(gp.failedTries <= (UINT32) decreaseCount) |
139 | | // should not set failedTries below zero |
140 | 0 | gp.failedTries = 0; |
141 | 0 | else |
142 | 0 | gp.failedTries -= (UINT32) decreaseCount; |
143 | | // the cast prevents overflow of the product |
144 | 0 | s_selfHealTimer += (decreaseCount * (UINT64)gp.recoveryTime) * 1000; |
145 | 0 | if(decreaseCount != 0) |
146 | | // If there was a change to the failedTries, record the changes |
147 | | // to NV |
148 | 0 | NvWriteReserved(NV_FAILED_TRIES, &gp.failedTries); |
149 | 0 | } |
150 | 0 | } |
151 | | // LockoutAuth self healing logic |
152 | | // If lockoutAuth is enabled, do nothing. Otherwise, try to see if we |
153 | | // may enable it |
154 | 888 | if(!gp.lockOutAuthEnabled) |
155 | 0 | { |
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 | 0 | if(gp.lockoutRecovery != 0) |
160 | | // |
161 | 0 | { |
162 | 0 | if(((g_time - s_lockoutTimer)/1000) >= gp.lockoutRecovery) |
163 | 0 | { |
164 | 0 | gp.lockOutAuthEnabled = TRUE; |
165 | | // Record the changes to NV |
166 | 0 | NvWriteReserved(NV_LOCKOUT_AUTH_ENABLED, &gp.lockOutAuthEnabled); |
167 | 0 | } |
168 | 0 | } |
169 | 0 | } |
170 | 888 | return; |
171 | 888 | } |