Coverage Report

Created: 2025-07-09 06:07

/src/tpm2/DA.c
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
}