1*5c591343SA. Cody Schuffelen /* Microsoft Reference Implementation for TPM 2.0
2*5c591343SA. Cody Schuffelen *
3*5c591343SA. Cody Schuffelen * The copyright in this software is being made available under the BSD License,
4*5c591343SA. Cody Schuffelen * included below. This software may be subject to other third party and
5*5c591343SA. Cody Schuffelen * contributor rights, including patent rights, and no such rights are granted
6*5c591343SA. Cody Schuffelen * under this license.
7*5c591343SA. Cody Schuffelen *
8*5c591343SA. Cody Schuffelen * Copyright (c) Microsoft Corporation
9*5c591343SA. Cody Schuffelen *
10*5c591343SA. Cody Schuffelen * All rights reserved.
11*5c591343SA. Cody Schuffelen *
12*5c591343SA. Cody Schuffelen * BSD License
13*5c591343SA. Cody Schuffelen *
14*5c591343SA. Cody Schuffelen * Redistribution and use in source and binary forms, with or without modification,
15*5c591343SA. Cody Schuffelen * are permitted provided that the following conditions are met:
16*5c591343SA. Cody Schuffelen *
17*5c591343SA. Cody Schuffelen * Redistributions of source code must retain the above copyright notice, this list
18*5c591343SA. Cody Schuffelen * of conditions and the following disclaimer.
19*5c591343SA. Cody Schuffelen *
20*5c591343SA. Cody Schuffelen * Redistributions in binary form must reproduce the above copyright notice, this
21*5c591343SA. Cody Schuffelen * list of conditions and the following disclaimer in the documentation and/or
22*5c591343SA. Cody Schuffelen * other materials provided with the distribution.
23*5c591343SA. Cody Schuffelen *
24*5c591343SA. Cody Schuffelen * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ""AS IS""
25*5c591343SA. Cody Schuffelen * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26*5c591343SA. Cody Schuffelen * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27*5c591343SA. Cody Schuffelen * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
28*5c591343SA. Cody Schuffelen * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29*5c591343SA. Cody Schuffelen * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30*5c591343SA. Cody Schuffelen * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
31*5c591343SA. Cody Schuffelen * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32*5c591343SA. Cody Schuffelen * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33*5c591343SA. Cody Schuffelen * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34*5c591343SA. Cody Schuffelen */
35*5c591343SA. Cody Schuffelen //** Introduction
36*5c591343SA. Cody Schuffelen // This file contains the functions and data definitions relating to the
37*5c591343SA. Cody Schuffelen // dictionary attack logic.
38*5c591343SA. Cody Schuffelen
39*5c591343SA. Cody Schuffelen //** Includes and Data Definitions
40*5c591343SA. Cody Schuffelen #define DA_C
41*5c591343SA. Cody Schuffelen #include "Tpm.h"
42*5c591343SA. Cody Schuffelen
43*5c591343SA. Cody Schuffelen //** Functions
44*5c591343SA. Cody Schuffelen
45*5c591343SA. Cody Schuffelen //*** DAPreInstall_Init()
46*5c591343SA. Cody Schuffelen // This function initializes the DA parameters to their manufacturer-default
47*5c591343SA. Cody Schuffelen // values. The default values are determined by a platform-specific specification.
48*5c591343SA. Cody Schuffelen //
49*5c591343SA. Cody Schuffelen // This function should not be called outside of a manufacturing or simulation
50*5c591343SA. Cody Schuffelen // environment.
51*5c591343SA. Cody Schuffelen //
52*5c591343SA. Cody Schuffelen // The DA parameters will be restored to these initial values by TPM2_Clear().
53*5c591343SA. Cody Schuffelen void
DAPreInstall_Init(void)54*5c591343SA. Cody Schuffelen DAPreInstall_Init(
55*5c591343SA. Cody Schuffelen void
56*5c591343SA. Cody Schuffelen )
57*5c591343SA. Cody Schuffelen {
58*5c591343SA. Cody Schuffelen gp.failedTries = 0;
59*5c591343SA. Cody Schuffelen gp.maxTries = 3;
60*5c591343SA. Cody Schuffelen gp.recoveryTime = 1000; // in seconds (~16.67 minutes)
61*5c591343SA. Cody Schuffelen gp.lockoutRecovery = 1000; // in seconds
62*5c591343SA. Cody Schuffelen gp.lockOutAuthEnabled = TRUE; // Use of lockoutAuth is enabled
63*5c591343SA. Cody Schuffelen
64*5c591343SA. Cody Schuffelen // Record persistent DA parameter changes to NV
65*5c591343SA. Cody Schuffelen NV_SYNC_PERSISTENT(failedTries);
66*5c591343SA. Cody Schuffelen NV_SYNC_PERSISTENT(maxTries);
67*5c591343SA. Cody Schuffelen NV_SYNC_PERSISTENT(recoveryTime);
68*5c591343SA. Cody Schuffelen NV_SYNC_PERSISTENT(lockoutRecovery);
69*5c591343SA. Cody Schuffelen NV_SYNC_PERSISTENT(lockOutAuthEnabled);
70*5c591343SA. Cody Schuffelen
71*5c591343SA. Cody Schuffelen return;
72*5c591343SA. Cody Schuffelen }
73*5c591343SA. Cody Schuffelen
74*5c591343SA. Cody Schuffelen
75*5c591343SA. Cody Schuffelen //*** DAStartup()
76*5c591343SA. Cody Schuffelen // This function is called by TPM2_Startup() to initialize the DA parameters.
77*5c591343SA. Cody Schuffelen // In the case of Startup(CLEAR), use of lockoutAuth will be enabled if the
78*5c591343SA. Cody Schuffelen // lockout recovery time is 0. Otherwise, lockoutAuth will not be enabled until
79*5c591343SA. Cody Schuffelen // the TPM has been continuously powered for the lockoutRecovery time.
80*5c591343SA. Cody Schuffelen //
81*5c591343SA. Cody Schuffelen // This function requires that NV be available and not rate limiting.
82*5c591343SA. Cody Schuffelen BOOL
DAStartup(STARTUP_TYPE type)83*5c591343SA. Cody Schuffelen DAStartup(
84*5c591343SA. Cody Schuffelen STARTUP_TYPE type // IN: startup type
85*5c591343SA. Cody Schuffelen )
86*5c591343SA. Cody Schuffelen {
87*5c591343SA. Cody Schuffelen NOT_REFERENCED(type);
88*5c591343SA. Cody Schuffelen #if !ACCUMULATE_SELF_HEAL_TIMER
89*5c591343SA. Cody Schuffelen _plat__TimerWasReset();
90*5c591343SA. Cody Schuffelen s_selfHealTimer = 0;
91*5c591343SA. Cody Schuffelen s_lockoutTimer = 0;
92*5c591343SA. Cody Schuffelen #else
93*5c591343SA. Cody Schuffelen if(_plat__TimerWasReset())
94*5c591343SA. Cody Schuffelen {
95*5c591343SA. Cody Schuffelen if(!NV_IS_ORDERLY)
96*5c591343SA. Cody Schuffelen {
97*5c591343SA. Cody Schuffelen // If shutdown was not orderly, then don't really know if go.time has
98*5c591343SA. Cody Schuffelen // any useful value so reset the timer to 0. This is what the tick
99*5c591343SA. Cody Schuffelen // was reset to
100*5c591343SA. Cody Schuffelen s_selfHealTimer = 0;
101*5c591343SA. Cody Schuffelen s_lockoutTimer = 0;
102*5c591343SA. Cody Schuffelen }
103*5c591343SA. Cody Schuffelen else
104*5c591343SA. Cody Schuffelen {
105*5c591343SA. Cody Schuffelen // If we know how much time was accumulated at the last orderly shutdown
106*5c591343SA. Cody Schuffelen // subtract that from the saved timer values so that they effectively
107*5c591343SA. Cody Schuffelen // have the accumulated values
108*5c591343SA. Cody Schuffelen s_selfHealTimer -= go.time;
109*5c591343SA. Cody Schuffelen s_lockoutTimer -= go.time;
110*5c591343SA. Cody Schuffelen }
111*5c591343SA. Cody Schuffelen }
112*5c591343SA. Cody Schuffelen #endif
113*5c591343SA. Cody Schuffelen
114*5c591343SA. Cody Schuffelen // For any Startup(), if lockoutRecovery is 0, enable use of lockoutAuth.
115*5c591343SA. Cody Schuffelen if(gp.lockoutRecovery == 0)
116*5c591343SA. Cody Schuffelen {
117*5c591343SA. Cody Schuffelen gp.lockOutAuthEnabled = TRUE;
118*5c591343SA. Cody Schuffelen // Record the changes to NV
119*5c591343SA. Cody Schuffelen NV_SYNC_PERSISTENT(lockOutAuthEnabled);
120*5c591343SA. Cody Schuffelen }
121*5c591343SA. Cody Schuffelen
122*5c591343SA. Cody Schuffelen // If DA has not been disabled and the previous shutdown is not orderly
123*5c591343SA. Cody Schuffelen // failedTries is not already at its maximum then increment 'failedTries'
124*5c591343SA. Cody Schuffelen if(gp.recoveryTime != 0
125*5c591343SA. Cody Schuffelen && gp.failedTries < gp.maxTries
126*5c591343SA. Cody Schuffelen && !IS_ORDERLY(g_prevOrderlyState))
127*5c591343SA. Cody Schuffelen {
128*5c591343SA. Cody Schuffelen #if USE_DA_USED
129*5c591343SA. Cody Schuffelen gp.failedTries += g_daUsed;
130*5c591343SA. Cody Schuffelen g_daUsed = FALSE;
131*5c591343SA. Cody Schuffelen #else
132*5c591343SA. Cody Schuffelen gp.failedTries++;
133*5c591343SA. Cody Schuffelen #endif
134*5c591343SA. Cody Schuffelen // Record the change to NV
135*5c591343SA. Cody Schuffelen NV_SYNC_PERSISTENT(failedTries);
136*5c591343SA. Cody Schuffelen }
137*5c591343SA. Cody Schuffelen // Before Startup, the TPM will not do clock updates. At startup, need to
138*5c591343SA. Cody Schuffelen // do a time update which will do the DA update.
139*5c591343SA. Cody Schuffelen TimeUpdate();
140*5c591343SA. Cody Schuffelen
141*5c591343SA. Cody Schuffelen return TRUE;
142*5c591343SA. Cody Schuffelen }
143*5c591343SA. Cody Schuffelen
144*5c591343SA. Cody Schuffelen //*** DARegisterFailure()
145*5c591343SA. Cody Schuffelen // This function is called when an authorization failure occurs on an entity
146*5c591343SA. Cody Schuffelen // that is subject to dictionary-attack protection. When a DA failure is
147*5c591343SA. Cody Schuffelen // triggered, register the failure by resetting the relevant self-healing
148*5c591343SA. Cody Schuffelen // timer to the current time.
149*5c591343SA. Cody Schuffelen void
DARegisterFailure(TPM_HANDLE handle)150*5c591343SA. Cody Schuffelen DARegisterFailure(
151*5c591343SA. Cody Schuffelen TPM_HANDLE handle // IN: handle for failure
152*5c591343SA. Cody Schuffelen )
153*5c591343SA. Cody Schuffelen {
154*5c591343SA. Cody Schuffelen // Reset the timer associated with lockout if the handle is the lockoutAuth.
155*5c591343SA. Cody Schuffelen if(handle == TPM_RH_LOCKOUT)
156*5c591343SA. Cody Schuffelen s_lockoutTimer = g_time;
157*5c591343SA. Cody Schuffelen else
158*5c591343SA. Cody Schuffelen s_selfHealTimer = g_time;
159*5c591343SA. Cody Schuffelen return;
160*5c591343SA. Cody Schuffelen }
161*5c591343SA. Cody Schuffelen
162*5c591343SA. Cody Schuffelen //*** DASelfHeal()
163*5c591343SA. Cody Schuffelen // This function is called to check if sufficient time has passed to allow
164*5c591343SA. Cody Schuffelen // decrement of failedTries or to re-enable use of lockoutAuth.
165*5c591343SA. Cody Schuffelen //
166*5c591343SA. Cody Schuffelen // This function should be called when the time interval is updated.
167*5c591343SA. Cody Schuffelen void
DASelfHeal(void)168*5c591343SA. Cody Schuffelen DASelfHeal(
169*5c591343SA. Cody Schuffelen void
170*5c591343SA. Cody Schuffelen )
171*5c591343SA. Cody Schuffelen {
172*5c591343SA. Cody Schuffelen // Regular authorization self healing logic
173*5c591343SA. Cody Schuffelen // If no failed authorization tries, do nothing. Otherwise, try to
174*5c591343SA. Cody Schuffelen // decrease failedTries
175*5c591343SA. Cody Schuffelen if(gp.failedTries != 0)
176*5c591343SA. Cody Schuffelen {
177*5c591343SA. Cody Schuffelen // if recovery time is 0, DA logic has been disabled. Clear failed tries
178*5c591343SA. Cody Schuffelen // immediately
179*5c591343SA. Cody Schuffelen if(gp.recoveryTime == 0)
180*5c591343SA. Cody Schuffelen {
181*5c591343SA. Cody Schuffelen gp.failedTries = 0;
182*5c591343SA. Cody Schuffelen // Update NV record
183*5c591343SA. Cody Schuffelen NV_SYNC_PERSISTENT(failedTries);
184*5c591343SA. Cody Schuffelen }
185*5c591343SA. Cody Schuffelen else
186*5c591343SA. Cody Schuffelen {
187*5c591343SA. Cody Schuffelen UINT64 decreaseCount;
188*5c591343SA. Cody Schuffelen #if 0 // Errata eliminates this code
189*5c591343SA. Cody Schuffelen // In the unlikely event that failedTries should become larger than
190*5c591343SA. Cody Schuffelen // maxTries
191*5c591343SA. Cody Schuffelen if(gp.failedTries > gp.maxTries)
192*5c591343SA. Cody Schuffelen gp.failedTries = gp.maxTries;
193*5c591343SA. Cody Schuffelen #endif
194*5c591343SA. Cody Schuffelen // How much can failedTries be decreased
195*5c591343SA. Cody Schuffelen
196*5c591343SA. Cody Schuffelen // Cast s_selfHealTimer to an int in case it became negative at
197*5c591343SA. Cody Schuffelen // startup
198*5c591343SA. Cody Schuffelen decreaseCount = ((g_time - (INT64)s_selfHealTimer) / 1000)
199*5c591343SA. Cody Schuffelen / gp.recoveryTime;
200*5c591343SA. Cody Schuffelen
201*5c591343SA. Cody Schuffelen if(gp.failedTries <= (UINT32)decreaseCount)
202*5c591343SA. Cody Schuffelen // should not set failedTries below zero
203*5c591343SA. Cody Schuffelen gp.failedTries = 0;
204*5c591343SA. Cody Schuffelen else
205*5c591343SA. Cody Schuffelen gp.failedTries -= (UINT32)decreaseCount;
206*5c591343SA. Cody Schuffelen
207*5c591343SA. Cody Schuffelen // the cast prevents overflow of the product
208*5c591343SA. Cody Schuffelen s_selfHealTimer += (decreaseCount * (UINT64)gp.recoveryTime) * 1000;
209*5c591343SA. Cody Schuffelen if(decreaseCount != 0)
210*5c591343SA. Cody Schuffelen // If there was a change to the failedTries, record the changes
211*5c591343SA. Cody Schuffelen // to NV
212*5c591343SA. Cody Schuffelen NV_SYNC_PERSISTENT(failedTries);
213*5c591343SA. Cody Schuffelen }
214*5c591343SA. Cody Schuffelen }
215*5c591343SA. Cody Schuffelen
216*5c591343SA. Cody Schuffelen // LockoutAuth self healing logic
217*5c591343SA. Cody Schuffelen // If lockoutAuth is enabled, do nothing. Otherwise, try to see if we
218*5c591343SA. Cody Schuffelen // may enable it
219*5c591343SA. Cody Schuffelen if(!gp.lockOutAuthEnabled)
220*5c591343SA. Cody Schuffelen {
221*5c591343SA. Cody Schuffelen // if lockout authorization recovery time is 0, a reboot is required to
222*5c591343SA. Cody Schuffelen // re-enable use of lockout authorization. Self-healing would not
223*5c591343SA. Cody Schuffelen // apply in this case.
224*5c591343SA. Cody Schuffelen if(gp.lockoutRecovery != 0)
225*5c591343SA. Cody Schuffelen {
226*5c591343SA. Cody Schuffelen if(((g_time - (INT64)s_lockoutTimer) / 1000) >= gp.lockoutRecovery)
227*5c591343SA. Cody Schuffelen {
228*5c591343SA. Cody Schuffelen gp.lockOutAuthEnabled = TRUE;
229*5c591343SA. Cody Schuffelen // Record the changes to NV
230*5c591343SA. Cody Schuffelen NV_SYNC_PERSISTENT(lockOutAuthEnabled);
231*5c591343SA. Cody Schuffelen }
232*5c591343SA. Cody Schuffelen }
233*5c591343SA. Cody Schuffelen }
234*5c591343SA. Cody Schuffelen return;
235*5c591343SA. Cody Schuffelen }