Coverage Report

Created: 2025-08-28 06:05

/src/tpm2/CommandAudit.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
#include "InternalRoutines.h"
9
//
10
//
11
//           Functions
12
//
13
//
14
//      GetBitPosForCC()
15
//
16
//      Helper function returning a bit offset in command audit bitmap for
17
//      the given command code or extended command code.
18
//
19
//      Return Value                 Meaning
20
//
21
//        UINT32                     bit-offset in command audit bitmap
22
static UINT32 GetBitPosForCC(TPM_CC commandCode)
23
710
{
24
710
    if (commandCode & TPM_CCE_BIT_MASK)
25
0
        return MAX_CAP_CC + commandCode - TPM_CCE_FIRST;
26
710
    return commandCode - TPM_CC_FIRST;
27
710
}
28
//
29
//           CommandAuditPreInstall_Init()
30
//
31
//     This function initializes the command audit list. This function is simulates the behavior of manufacturing. A
32
//     function is used instead of a structure definition because this is easier than figuring out the initialization
33
//     value for a bit array.
34
//     This function would not be implemented outside of a manufacturing or simulation environment.
35
//
36
void
37
CommandAuditPreInstall_Init(
38
     void
39
     )
40
251
{
41
     // Clear all the audit commands
42
251
     MemorySet(gp.auditComands, 0x00, sizeof(gp.auditComands));
43
44
     // TPM_CC_SetCommandCodeAuditStatus always being audited
45
251
     if(CommandIsImplemented(TPM_CC_SetCommandCodeAuditStatus))
46
0
         CommandAuditSet(TPM_CC_SetCommandCodeAuditStatus);
47
     // Set initial command audit hash algorithm to be context integrity hash
48
     // algorithm
49
251
     gp.auditHashAlg = CONTEXT_INTEGRITY_HASH_ALG;
50
     // Set up audit counter to be 0
51
251
     gp.auditCounter = 0;
52
     // Write command audit persistent data to NV
53
251
     NvWriteReserved(NV_AUDIT_COMMANDS, &gp.auditComands);
54
251
     NvWriteReserved(NV_AUDIT_HASH_ALG, &gp.auditHashAlg);
55
251
     NvWriteReserved(NV_AUDIT_COUNTER, &gp.auditCounter);
56
251
     return;
57
251
}
58
//
59
//
60
//           CommandAuditStartup()
61
//
62
//     This function clears the command audit digest on a TPM Reset.
63
//
64
void
65
CommandAuditStartup(
66
     STARTUP_TYPE        type               // IN: start up type
67
     )
68
251
{
69
251
   if(type == SU_RESET)
70
251
   {
71
       // Reset the digest size to initialize the digest
72
251
       gr.commandAuditDigest.t.size = 0;
73
251
   }
74
251
}
75
//
76
//
77
//         CommandAuditSet()
78
//
79
//     This function will SET the audit flag for a command. This function will not SET the audit flag for a
80
//     command that is not implemented. This ensures that the audit status is not SET when
81
//     TPM2_GetCapability() is used to read the list of audited commands.
82
//     This function is only used by TPM2_SetCommandCodeAuditStatus().
83
//     The actions in TPM2_SetCommandCodeAuditStatus() are expected to cause the changes to be saved to
84
//     NV after it is setting and clearing bits.
85
//
86
//     Return Value                      Meaning
87
//
88
//     TRUE                              the command code audit status was changed
89
//     FALSE                             the command code audit status was not changed
90
//
91
BOOL
92
CommandAuditSet(
93
   TPM_CC              commandCode          // IN: command code
94
   )
95
0
{
96
0
   UINT32         bitPos = GetBitPosForCC(commandCode);
97
   // Only SET a bit if the corresponding command is implemented
98
0
   if(CommandIsImplemented(commandCode))
99
0
   {
100
       // Can't audit shutdown
101
0
       if(commandCode != TPM_CC_Shutdown)
102
0
       {
103
0
           if(!BitIsSet(bitPos, &gp.auditComands[0], sizeof(gp.auditComands)))
104
0
           {
105
               // Set bit
106
0
               BitSet(bitPos, &gp.auditComands[0], sizeof(gp.auditComands));
107
0
               return TRUE;
108
0
           }
109
0
       }
110
0
   }
111
   // No change
112
0
   return FALSE;
113
0
}
114
//
115
//
116
//         CommandAuditClear()
117
//
118
//     This function will CLEAR the audit flag for a command. It will not CLEAR the audit flag for
119
//     TPM_CC_SetCommandCodeAuditStatus().
120
//     This function is only used by TPM2_SetCommandCodeAuditStatus().
121
//     The actions in TPM2_SetCommandCodeAuditStatus() are expected to cause the changes to be saved to
122
//     NV after it is setting and clearing bits.
123
//
124
//
125
//
126
//      Return Value                     Meaning
127
//
128
//      TRUE                             the command code audit status was changed
129
//      FALSE                            the command code audit status was not changed
130
//
131
BOOL
132
CommandAuditClear(
133
    TPM_CC               commandCode        // IN: command code
134
    )
135
0
{
136
0
    UINT32         bitPos = GetBitPosForCC(commandCode);
137
    // Do nothing if the command is not implemented
138
0
    if(CommandIsImplemented(commandCode))
139
0
    {
140
        // The bit associated with TPM_CC_SetCommandCodeAuditStatus() cannot be
141
        // cleared
142
0
        if(commandCode != TPM_CC_SetCommandCodeAuditStatus)
143
0
        {
144
0
            if(BitIsSet(bitPos, &gp.auditComands[0], sizeof(gp.auditComands)))
145
0
            {
146
                // Clear bit
147
0
                BitClear(bitPos, &gp.auditComands[0], sizeof(gp.auditComands));
148
0
                return TRUE;
149
0
            }
150
0
        }
151
0
    }
152
    // No change
153
0
    return FALSE;
154
0
}
155
//
156
//
157
//           CommandAuditIsRequired()
158
//
159
//      This function indicates if the audit flag is SET for a command.
160
//
161
//      Return Value                     Meaning
162
//
163
//      TRUE                             if command is audited
164
//      FALSE                            if command is not audited
165
//
166
BOOL
167
CommandAuditIsRequired(
168
    TPM_CC               commandCode        // IN: command code
169
    )
170
710
{
171
710
    UINT32         bitPos = GetBitPosForCC(commandCode);
172
    // Check the bit map. If the bit is SET, command audit is required
173
710
    if((gp.auditComands[bitPos/8] & (1 << (bitPos % 8))) != 0)
174
0
        return TRUE;
175
710
    else
176
710
        return FALSE;
177
710
}
178
//
179
//
180
//           CommandAuditCapGetCCList()
181
//
182
//      This function returns a list of commands that have their audit bit SET.
183
//      Family "2.0"                                 TCG Published                                        Page 111
184
//      Level 00 Revision 01.16              Copyright © TCG 2006-2014                           October 30, 2014
185
//      Trusted Platform Module Library                                                  Part 4: Supporting Routines
186
//
187
//
188
//      The list starts at the input commandCode.
189
//
190
//      Return Value                      Meaning
191
//
192
//      YES                               if there are more command code available
193
//      NO                                all the available command code has been returned
194
//
195
TPMI_YES_NO
196
CommandAuditCapGetCCList(
197
     TPM_CC            commandCode,          // IN: start command code
198
     UINT32            count,                // IN: count of returned TPM_CC
199
     TPML_CC          *commandList           // OUT: list of TPM_CC
200
     )
201
0
{
202
0
     TPMI_YES_NO      more = NO;
203
0
     UINT32           i;
204
     // Initialize output handle list
205
0
     commandList->count = 0;
206
     // The maximum count of commands we may return is MAX_CAP_CC_ALL.
207
0
     if(count > MAX_CAP_CC_ALL) count = MAX_CAP_CC_ALL;
208
     // If the command code is smaller than TPM_CC_FIRST, start from TPM_CC_FIRST
209
0
     if(commandCode < TPM_CC_FIRST) commandCode = TPM_CC_FIRST;
210
     // Collect audit commands
211
0
     for(i = commandCode; i <= TPM_CCE_LAST; i++)
212
0
     {
213
0
         if (i > TPM_CC_LAST && i < TPM_CCE_FIRST)
214
0
         {
215
0
             i = TPM_CCE_FIRST;
216
0
         }
217
0
         if(CommandAuditIsRequired(i))
218
0
         {
219
0
             if(commandList->count < count)
220
0
             {
221
                 // If we have not filled up the return list, add this command
222
                 // code to it
223
0
                 commandList->commandCodes[commandList->count] = i;
224
0
                 commandList->count++;
225
0
             }
226
0
             else
227
0
             {
228
                 // If the return list is full but we still have command
229
                 // available, report this and stop iterating
230
0
                 more = YES;
231
0
                 break;
232
0
             }
233
0
         }
234
0
     }
235
0
     return more;
236
0
}
237
//
238
//
239
//          CommandAuditGetDigest
240
//
241
//      This command is used to create a digest of the commands being audited. The commands are processed
242
//      in ascending numeric order with a list of TPM_CC being added to a hash. This operates as if all the
243
//      audited command codes were concatenated and then hashed.
244
//
245
void
246
CommandAuditGetDigest(
247
     TPM2B_DIGEST     *digest                // OUT: command digest
248
     )
249
0
{
250
0
     TPM_CC                               i;
251
0
     HASH_STATE                           hashState;
252
     // Start hash
253
0
     digest->t.size = CryptStartHash(gp.auditHashAlg, &hashState);
254
     // Add command code
255
0
     for(i = TPM_CC_FIRST; i <= TPM_CCE_LAST; i++)
256
0
     {
257
0
         if (i > TPM_CC_LAST && i < TPM_CCE_FIRST)
258
0
         {
259
0
             i = TPM_CCE_FIRST;
260
0
         }
261
0
         if(CommandAuditIsRequired(i))
262
0
         {
263
0
             CryptUpdateDigestInt(&hashState, sizeof(i), &i);
264
0
         }
265
0
     }
266
     // Complete hash
267
0
     CryptCompleteHash2B(&hashState, &digest->b);
268
0
     return;
269
0
}