• 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      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 //
48 void
DAStartup(STARTUP_TYPE type)49 DAStartup(
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 //
86 void
DARegisterFailure(TPM_HANDLE handle)87 DARegisterFailure(
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 //
107 void
DASelfHeal(void)108 DASelfHeal(
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 }
168