• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
DAPreInstall_Init(void)22 DAPreInstall_Init(
23      void
24      )
25 {
26      gp.failedTries = 0;
27      // TODO(vbendeb): consider finer tuning of this value (crosbug.com/p/55708)
28      gp.maxTries = 200;
29      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 //
49 void
DAStartup(STARTUP_TYPE type)50 DAStartup(
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 //
87 void
DARegisterFailure(TPM_HANDLE handle)88 DARegisterFailure(
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 //
108 void
DASelfHeal(void)109 DASelfHeal(
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 }
169