• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

stefanberger / libtpms / #2063

11 Feb 2026 02:58PM UTC coverage: 77.18% (-0.02%) from 77.195%
#2063

push

travis-ci

web-flow
Merge c175b6f1e into c2a8109f8

1174 of 1370 new or added lines in 95 files covered. (85.69%)

2190 existing lines in 89 files now uncovered.

36347 of 47094 relevant lines covered (77.18%)

125164.35 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

71.88
/src/tpm2/TPMCmd/tpm/src/command/ClockTimer/ACT_spt.c
1
// SPDX-License-Identifier: BSD-2-Clause
2

3
//** Introduction
4
// This code implements the ACT update code. It does not use a mutex. This code uses
5
// a platform service (_plat__ACT_UpdateCounter()) that returns 'false' if the update
6
// is not accepted. If this occurs, then TPM_RC_RETRY should be sent to the caller so
7
// that they can retry the operation later. The implementation of this is platform
8
// dependent but the reference uses a simple flag to indicate that an update is
9
// pending and the only process that can clear that flag is the process that does the
10
// actual update.
11

12
//** Includes
13
#include "Tpm.h"
14
#include "ACT_spt_fp.h"
15
// TODO_RENAME_INC_FOLDER:platform_interface refers to the TPM_CoreLib platform interface
16
#include <platform_interface/tpm_to_platform_interface.h>
17

18
//** Functions
19

20
#if 1 // ACT_SUPPORT                        // libtpms: FIXME
21

22
//*** _ActResume()
23
// This function does the resume processing for an ACT. It updates the saved count
24
// and turns signaling back on if necessary.
25
#ifndef __ACT_DISABLED        // libtpms added
26
static void _ActResume(UINT32     act,     //IN: the act number
27
                       ACT_STATE* actData  //IN: pointer to the saved ACT data
28
)
29
{
30
    // If the act was non-zero, then restore the counter value.
31
    if(actData->remaining > 0)
32
        _plat__ACT_UpdateCounter(act, actData->remaining);
33
    // if the counter was zero and the ACT signaling, enable the signaling.
34
    else if(go.signaledACT & (1 << act))
35
        _plat__ACT_SetSignaled(act, TRUE);
36
}
37
#endif                        // libtpms added
38

39
//*** ActStartup()
40
// This function is called by TPM2_Startup() to initialize the ACT counter values.
41
BOOL ActStartup(STARTUP_TYPE type)
4,251✔
42
{
43
    // Reset all the ACT hardware
44
    _plat__ACT_Initialize();
4,251✔
45

46
    // If this not a cold start, copy all the current 'signaled' settings to
47
    // 'preservedSignaled'.
48
#ifndef __ACT_DISABLED        // libtpms added
49
    if(g_powerWasLost)
50
        go.preservedSignaled = 0;
51
    else
52
        go.preservedSignaled |= go.signaledACT;
53
#endif                        // libtpms added
54

55
    // For TPM_RESET or TPM_RESTART, the ACTs will all be disabled and the output
56
    // de-asserted.
57
    if(type != SU_RESUME)
4,251✔
58
    {
59
#ifndef __ACT_DISABLED        // libtpms added
60
        go.signaledACT = 0;
61
#endif                        // libtpms added
62
#  define CLEAR_ACT_POLICY(N)                      \
63
      go.ACT_##N.hashAlg           = TPM_ALG_NULL; \
64
      go.ACT_##N.authPolicy.b.size = 0;
65
        FOR_EACH_ACT(CLEAR_ACT_POLICY)
66
    }
67
    else
68
    {
69
        // Resume each of the implemented ACT
70
#  define RESUME_ACT(N) _ActResume(0x##N, &go.ACT_##N);
71

72
        FOR_EACH_ACT(RESUME_ACT)
73
    }
4,251✔
74
    // set no ACT updated since last startup. This is to enable the halving of the
75
    // timeout value
76
    s_ActUpdated = 0;
4,251✔
77
    _plat__ACT_EnableTicks(TRUE);
4,251✔
78
    return TRUE;
4,251✔
79
}
80

81
#ifndef __ACT_DISABLED // libtpms added
82
//*** _ActSaveState()
83
// Get the counter state and the signaled state for an ACT. If the ACT has not been
84
// updated since the last time it was saved, then divide the count by 2.
85
static void _ActSaveState(UINT32 act, P_ACT_STATE actData)
86
{
87
    actData->remaining = _plat__ACT_GetRemaining(act);
88
    // If the ACT hasn't been updated since the last startup, then it should be
89
    // be halved.
90
    if((s_ActUpdated & (1 << act)) == 0)
91
    {
92
        // Don't halve if the count is set to max or if halving would make it zero
93
        if((actData->remaining != UINT32_MAX) && (actData->remaining > 1))
94
            actData->remaining /= 2;
95
    }
96
    if(_plat__ACT_GetSignaled(act))
97
        go.signaledACT |= (1 << act);
98
}
99

100
//*** ActGetSignaled()
101
// This function returns the state of the signaled flag associated with an ACT.
102
BOOL ActGetSignaled(TPM_RH actHandle)
103
{
104
    UINT32 act = actHandle - TPM_RH_ACT_0;
105
    //
106
    return _plat__ACT_GetSignaled(act);
107
}
108
#endif                        // libtpms added
109

110
//***ActShutdown()
111
// This function saves the current state of the counters
112
BOOL ActShutdown(TPM_SU state  //IN: the type of the shutdown.
350✔
113
)
114
{
115
    // if this is not shutdown state, then the only type of startup is TPM_RESTART
116
    // so the timer values will be cleared. If this is shutdown state, get the current
117
    // countdown and signaled values. Plus, if the counter has not been updated
118
    // since the last restart, divide the time by 2 so that there is no attack on the
119
    // countdown by saving the countdown state early and then not using the TPM.
120
    if(state == TPM_SU_STATE)
350✔
121
    {
122
        // This will be populated as each of the ACT is queried
123
#ifndef __ACT_DISABLED                // libtpms added
124
        go.signaledACT = 0;
125
#endif                                // libtpms added
126
        // Get the current count and the signaled state
127
#  define SAVE_ACT_STATE(N) _ActSaveState(0x##N, &go.ACT_##N);
128

129
        FOR_EACH_ACT(SAVE_ACT_STATE);
350✔
130
    }
131
    return TRUE;
350✔
132
}
133

134
//*** ActIsImplemented()
135
// This function determines if an ACT is implemented in both the TPM and the platform
136
// code.
137
BOOL ActIsImplemented(UINT32 act)
16✔
138
{
139
    // This switch accounts for the TPM implemented values.
140
    switch(act)
16✔
141
    {
142
#ifndef __ACT_DISABLED        // libtpms added
143
        FOR_EACH_ACT(CASE_ACT_NUMBER)
144
        // This ensures that the platform implements the values implemented by
145
        // the TPM
146
        return _plat__ACT_GetImplemented(act);
147
#endif                        // libtpms added
148
        default:
149
            break;
16✔
150
    }
151
    return FALSE;
16✔
152
}
153

154
#if CC_ACT_SetTimeout        // libtpms added
155
//***ActCounterUpdate()
156
// This function updates the ACT counter. If the counter already has a pending update,
157
// it returns TPM_RC_RETRY so that the update can be tried again later.
158
TPM_RC
159
ActCounterUpdate(TPM_RH handle,   //IN: the handle of the act
160
                 UINT32 newValue  //IN: the value to set in the ACT
161
)
162
{
163
    UINT32 act;
164
    TPM_RC result;
165
    //
166
    act = handle - TPM_RH_ACT_0;
167
    // This should never fail, but...
168
    if(!_plat__ACT_GetImplemented(act))
169
        result = TPM_RC_VALUE;
170
    else
171
    {
172
        // Will need to clear orderly so fail if we are orderly and NV is
173
        // not available
174
        if(NV_IS_ORDERLY)
175
            RETURN_IF_NV_IS_NOT_AVAILABLE;
176
        // if the attempt to update the counter fails, it means that there is an
177
        // update pending so wait until it has occurred and then do an update.
178
        if(!_plat__ACT_UpdateCounter(act, newValue))
179
            result = TPM_RC_RETRY;
180
        else
181
        {
182
            // Indicate that the ACT has been updated since last TPM2_Startup().
183
            s_ActUpdated |= (UINT16)(1 << act);
184

185
            // Clear the preservedSignaled attribute.
186
            go.preservedSignaled &= ~((UINT16)(1 << act));
187

188
            // Need to clear the orderly flag
189
            g_clearOrderly = TRUE;
190

191
            result         = TPM_RC_SUCCESS;
192
        }
193
    }
194
    return result;
195
}
196
#endif                // libtpms added
197

198
//*** ActGetCapabilityData()
199
// This function returns the list of ACT data
200
//  Return Type: TPMI_YES_NO
201
//      YES             if more ACT data is available
202
//      NO              if no more ACT data to
203
TPMI_YES_NO
204
ActGetCapabilityData(TPM_HANDLE     actHandle,  // IN: the handle for the starting ACT
1✔
205
                     UINT32         maxCount,   // IN: maximum allowed return values
206
                     TPML_ACT_DATA* actList     // OUT: ACT data list
207
)
208
{
209
    // Initialize output property list
210
    actList->count = 0;
1✔
211

212
    // Make sure that the starting handle value is in range (again)
213
    if((actHandle < TPM_RH_ACT_0) || (actHandle > TPM_RH_ACT_F))
1✔
214
        return FALSE;
215
    // The maximum count of curves we may return is MAX_ECC_CURVES
216
    if(maxCount > MAX_ACT_DATA)
1✔
217
        maxCount = MAX_ACT_DATA;
218
    // Scan the ACT data from the starting ACT
219
    for(; actHandle <= TPM_RH_ACT_F; actHandle++)
17✔
220
    {
221
        UINT32 act = actHandle - TPM_RH_ACT_0;
16✔
222
        if(actList->count < maxCount)
16✔
223
        {
224
            if(ActIsImplemented(act))
16✔
225
            {
UNCOV
226
                TPMS_ACT_DATA* actData = &actList->actData[actList->count];
×
227
                //
UNCOV
228
                memset(&actData->attributes, 0, sizeof(actData->attributes));
×
UNCOV
229
                actData->handle  = actHandle;
×
UNCOV
230
                actData->timeout = _plat__ACT_GetRemaining(act);
×
UNCOV
231
                if(_plat__ACT_GetSignaled(act))
×
UNCOV
232
                    SET_ATTRIBUTE(actData->attributes, TPMA_ACT, signaled);
×
233
                else
UNCOV
234
                    CLEAR_ATTRIBUTE(actData->attributes, TPMA_ACT, signaled);
×
235
#ifndef __ACT_DISABLED        // libtpms added
236
                if(go.preservedSignaled & (1 << act))
237
                    SET_ATTRIBUTE(actData->attributes, TPMA_ACT, preserveSignaled);
238
#endif                        // libtpms added
UNCOV
239
                actList->count++;
×
240
            }
241
        }
242
        else
243
        {
UNCOV
244
            if(_plat__ACT_GetImplemented(act))
×
245
                return YES;
246
        }
247
    }
248
    // If we get here, either all of the ACT values were put in the list, or the list
249
    // was filled and there are no more ACT values to return
250
    return NO;
251
}
252

253
#ifndef __ACT_DISABLED                // libtpms: added
254
//*** ActGetOneCapability()
255
// This function returns an ACT's capability, if present.
256
BOOL ActGetOneCapability(TPM_HANDLE     actHandle,  // IN: the handle for the ACT
257
                         TPMS_ACT_DATA* actData     // OUT: ACT data
258
)
259
{
260
    UINT32 act = actHandle - TPM_RH_ACT_0;
261

262
    if(ActIsImplemented(actHandle - TPM_RH_ACT_0))
263
    {
264
        memset(&actData->attributes, 0, sizeof(actData->attributes));
265
        actData->handle  = actHandle;
266
        actData->timeout = _plat__ACT_GetRemaining(act);
267
        if(_plat__ACT_GetSignaled(act))
268
            SET_ATTRIBUTE(actData->attributes, TPMA_ACT, signaled);
269
        else
270
            CLEAR_ATTRIBUTE(actData->attributes, TPMA_ACT, signaled);
271
        if(go.preservedSignaled & (1 << act))
272
            SET_ATTRIBUTE(actData->attributes, TPMA_ACT, preserveSignaled);
273
        return TRUE;
274
    }
275
    return FALSE;
276
}
277
#endif                                // libtpms: added
278

279
#endif  // ACT_SUPPORT
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc