aboutsummaryrefslogtreecommitdiff
path: root/DA.c
blob: 6d82716712c71da1b2df37fb4c9f2dc2c8006be5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
// This file was extracted from the TCG Published
// Trusted Platform Module Library
// Part 4: Supporting Routines
// Family "2.0"
// Level 00 Revision 01.16
// October 30, 2014

#define DA_C
#include "InternalRoutines.h"
//
//
//           Functions
//
//            DAPreInstall_Init()
//
//      This function initializes the DA parameters to their manufacturer-default values. The default values are
//      determined by a platform-specific specification.
//      This function should not be called outside of a manufacturing or simulation environment.
//      The DA parameters will be restored to these initial values by TPM2_Clear().
//
void
DAPreInstall_Init(
     void
     )
{
     gp.failedTries = 0;
     // TODO(vbendeb): consider finer tuning of this value (crosbug.com/p/55708)
     gp.maxTries = 200;
     gp.recoveryTime = 1000;                  // in seconds (~16.67 minutes)
     gp.lockoutRecovery = 1000;               // in seconds
     gp.lockOutAuthEnabled = TRUE;            // Use of lockoutAuth is enabled
     // Record persistent DA parameter changes to NV
     NvWriteReserved(NV_FAILED_TRIES, &gp.failedTries);
     NvWriteReserved(NV_MAX_TRIES, &gp.maxTries);
     NvWriteReserved(NV_RECOVERY_TIME, &gp.recoveryTime);
     NvWriteReserved(NV_LOCKOUT_RECOVERY, &gp.lockoutRecovery);
     NvWriteReserved(NV_LOCKOUT_AUTH_ENABLED, &gp.lockOutAuthEnabled);
    return;
}
//
//
//          DAStartup()
//
//     This function is called by TPM2_Startup() to initialize the DA parameters. In the case of Startup(CLEAR),
//     use of lockoutAuth will be enabled if the lockout recovery time is 0. Otherwise, lockoutAuth will not be
//     enabled until the TPM has been continuously powered for the lockoutRecovery time.
//     This function requires that NV be available and not rate limiting.
//
void
DAStartup(
    STARTUP_TYPE         type               // IN: startup type
    )
{
    // For TPM Reset, if lockoutRecovery is 0, enable use of lockoutAuth.
    if(type == SU_RESET)
    {
        if(gp.lockoutRecovery == 0)
        {
            gp.lockOutAuthEnabled = TRUE;
            // Record the changes to NV
            NvWriteReserved(NV_LOCKOUT_AUTH_ENABLED, &gp.lockOutAuthEnabled);
        }
    }
    // If DA has not been disabled and the previous shutdown is not orderly
    // failedTries is not already at its maximum then increment 'failedTries'
    if(    gp.recoveryTime != 0
        && g_prevOrderlyState == SHUTDOWN_NONE
        && gp.failedTries < gp.maxTries)
    {
        gp.failedTries++;
        // Record the change to NV
        NvWriteReserved(NV_FAILED_TRIES, &gp.failedTries);
    }
    // Reset self healing timers
    s_selfHealTimer = g_time;
    s_lockoutTimer = g_time;
    return;
}
//
//
//          DARegisterFailure()
//
//     This function is called when a authorization failure occurs on an entity that is subject to dictionary-attack
//     protection. When a DA failure is triggered, register the failure by resetting the relevant self-healing timer
//     to the current time.
//
void
DARegisterFailure(
    TPM_HANDLE           handle             // IN: handle for failure
    )
{
    // Reset the timer associated with lockout if the handle is the lockout auth.
    if(handle == TPM_RH_LOCKOUT)
         s_lockoutTimer = g_time;
    else
         s_selfHealTimer = g_time;
//
   return;
}
//
//
//             DASelfHeal()
//
//      This function is called to check if sufficient time has passed to allow decrement of failedTries or to re-
//      enable use of lockoutAuth.
//      This function should be called when the time interval is updated.
//
void
DASelfHeal(
   void
   )
{
   // Regular auth self healing logic
   // If no failed authorization tries, do nothing. Otherwise, try to
   // decrease failedTries
   if(gp.failedTries != 0)
   {
       // if recovery time is 0, DA logic has been disabled. Clear failed tries
       // immediately
       if(gp.recoveryTime == 0)
       {
            gp.failedTries = 0;
            // Update NV record
            NvWriteReserved(NV_FAILED_TRIES, &gp.failedTries);
       }
       else
       {
            UINT64          decreaseCount;
               // In the unlikely event that failedTries should become larger than
               // maxTries
               if(gp.failedTries > gp.maxTries)
                   gp.failedTries = gp.maxTries;
               // How much can failedTried be decreased
               decreaseCount = ((g_time - s_selfHealTimer) / 1000) / gp.recoveryTime;
               if(gp.failedTries <= (UINT32) decreaseCount)
                   // should not set failedTries below zero
                   gp.failedTries = 0;
               else
                   gp.failedTries -= (UINT32) decreaseCount;
               // the cast prevents overflow of the product
               s_selfHealTimer += (decreaseCount * (UINT64)gp.recoveryTime) * 1000;
               if(decreaseCount != 0)
                   // If there was a change to the failedTries, record the changes
                   // to NV
                   NvWriteReserved(NV_FAILED_TRIES, &gp.failedTries);
         }
   }
   // LockoutAuth self healing logic
   // If lockoutAuth is enabled, do nothing. Otherwise, try to see if we
   // may enable it
   if(!gp.lockOutAuthEnabled)
   {
       // if lockout authorization recovery time is 0, a reboot is required to
       // re-enable use of lockout authorization. Self-healing would not
       // apply in this case.
       if(gp.lockoutRecovery != 0)
//
           {
                 if(((g_time - s_lockoutTimer)/1000) >= gp.lockoutRecovery)
                 {
                     gp.lockOutAuthEnabled = TRUE;
                     // Record the changes to NV
                     NvWriteReserved(NV_LOCKOUT_AUTH_ENABLED, &gp.lockOutAuthEnabled);
                 }
           }
     }
     return;
}