Coverage Report

Created: 2024-07-27 06:30

/src/ibmswtpm2/src/CommandAudit.c
Line
Count
Source (jump to first uncovered line)
1
/********************************************************************************/
2
/*                    */
3
/*                  */
4
/*           Written by Ken Goldman       */
5
/*           IBM Thomas J. Watson Research Center     */
6
/*            $Id: CommandAudit.c 1047 2017-07-20 18:27:34Z kgoldman $    */
7
/*                    */
8
/*  Licenses and Notices              */
9
/*                    */
10
/*  1. Copyright Licenses:              */
11
/*                    */
12
/*  - Trusted Computing Group (TCG) grants to the user of the source code in  */
13
/*    this specification (the "Source Code") a worldwide, irrevocable,    */
14
/*    nonexclusive, royalty free, copyright license to reproduce, create  */
15
/*    derivative works, distribute, display and perform the Source Code and */
16
/*    derivative works thereof, and to grant others the rights granted herein.  */
17
/*                    */
18
/*  - The TCG grants to the user of the other parts of the specification  */
19
/*    (other than the Source Code) the rights to reproduce, distribute,   */
20
/*    display, and perform the specification solely for the purpose of    */
21
/*    developing products based on such documents.        */
22
/*                    */
23
/*  2. Source Code Distribution Conditions:         */
24
/*                    */
25
/*  - Redistributions of Source Code must retain the above copyright licenses,  */
26
/*    this list of conditions and the following disclaimers.      */
27
/*                    */
28
/*  - Redistributions in binary form must reproduce the above copyright   */
29
/*    licenses, this list of conditions and the following disclaimers in the  */
30
/*    documentation and/or other materials provided with the distribution.  */
31
/*                    */
32
/*  3. Disclaimers:               */
33
/*                    */
34
/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
35
/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
36
/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
37
/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.   */
38
/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for    */
39
/*  information on specification licensing rights available through TCG   */
40
/*  membership agreements.              */
41
/*                    */
42
/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED   */
43
/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR   */
44
/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR    */
45
/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY    */
46
/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.   */
47
/*                    */
48
/*  - Without limitation, TCG and its members and licensors disclaim all  */
49
/*    liability, including liability for infringement of any proprietary  */
50
/*    rights, relating to use of information in this specification and to the */
51
/*    implementation of this specification, and TCG disclaims all liability for */
52
/*    cost of procurement of substitute goods or services, lost profits, loss   */
53
/*    of use, loss of data or any incidental, consequential, direct, indirect,  */
54
/*    or special damages, whether under contract, tort, warranty or otherwise,  */
55
/*    arising in any way out of use or reliance upon this specification or any  */
56
/*    information herein.             */
57
/*                    */
58
/*  (c) Copyright IBM Corp. and others, 2016, 2017        */
59
/*                    */
60
/********************************************************************************/
61
62
/* 8.1 CommandAudit.c */
63
/* 8.1.1 Introduction */
64
/* This file contains the functions that support command audit. */
65
/* 8.1.2 Includes */
66
#include "Tpm.h"
67
/* 8.1.3 Functions */
68
/* 8.1.3.1 CommandAuditPreInstall_Init() */
69
/* This function initializes the command audit list. This function is simulates the behavior of
70
   manufacturing. A function is used instead of a structure definition because this is easier than
71
   figuring out the initialization value for a bit array. */
72
/* This function would not be implemented outside of a manufacturing or simulation environment. */
73
void
74
CommandAuditPreInstall_Init(
75
          void
76
          )
77
656
{
78
    // Clear all the audit commands
79
656
    MemorySet(gp.auditCommands, 0x00, sizeof(gp.auditCommands));
80
    // TPM_CC_SetCommandCodeAuditStatus always being audited
81
656
    CommandAuditSet(TPM_CC_SetCommandCodeAuditStatus);
82
    // Set initial command audit hash algorithm to be context integrity hash
83
    // algorithm
84
656
    gp.auditHashAlg = CONTEXT_INTEGRITY_HASH_ALG;
85
    // Set up audit counter to be 0
86
656
    gp.auditCounter = 0;
87
    // Write command audit persistent data to NV
88
656
    NV_SYNC_PERSISTENT(auditCommands);
89
656
    NV_SYNC_PERSISTENT(auditHashAlg);
90
656
    NV_SYNC_PERSISTENT(auditCounter);
91
656
    return;
92
656
}
93
/* 8.1.3.2 CommandAuditStartup() */
94
/* This function clears the command audit digest on a TPM Reset. */
95
void
96
CommandAuditStartup(
97
        STARTUP_TYPE     type           // IN: start up type
98
        )
99
0
{
100
0
    if((type != SU_RESTART) && (type != SU_RESUME))
101
0
  {
102
      // Reset the digest size to initialize the digest
103
0
      gr.commandAuditDigest.t.size = 0;
104
0
  }
105
0
}
106
/* 8.1.3.3 CommandAuditSet() */
107
/* This function will SET the audit flag for a command. This function will not SET the audit flag
108
   for a command that is not implemented. This ensures that the audit status is not SET when
109
   TPM2_GetCapability() is used to read the list of audited commands. */
110
/* This function is only used by TPM2_SetCommandCodeAuditStatus(). */
111
/* The actions in TPM2_SetCommandCodeAuditStatus() are expected to cause the changes to be saved to
112
   NV after it is setting and clearing bits. */
113
/* Return Values Meaning */
114
/* TRUE the command code audit status was changed */
115
/* FALSE the command code audit status was not changed */
116
BOOL
117
CommandAuditSet(
118
    TPM_CC           commandCode    // IN: command code
119
    )
120
656
{
121
656
    COMMAND_INDEX        commandIndex = CommandCodeToCommandIndex(commandCode);
122
    // Only SET a bit if the corresponding command is implemented
123
656
    if(commandIndex != UNIMPLEMENTED_COMMAND_INDEX)
124
656
  {
125
      // Can't audit shutdown
126
656
      if(commandCode != TPM_CC_Shutdown)
127
656
    {
128
656
        if(!TEST_BIT(commandIndex, gp.auditCommands))
129
656
      {
130
          // Set bit
131
656
          SET_BIT(commandIndex, gp.auditCommands);
132
656
          return TRUE;
133
656
      }
134
656
    }
135
656
  }
136
    // No change
137
0
    return FALSE;
138
656
}
139
/* 8.1.3.4 CommandAuditClear() */
140
/* This function will CLEAR the audit flag for a command. It will not CLEAR the audit flag for
141
   TPM_CC_SetCommandCodeAuditStatus(). */
142
/* This function is only used by TPM2_SetCommandCodeAuditStatus(). */
143
/* The actions in TPM2_SetCommandCodeAuditStatus() are expected to cause the changes to be saved to
144
   NV after it is setting and clearing bits. */
145
/* Return Values Meaning */
146
/* TRUE the command code audit status was changed */
147
/* FALSE the command code audit status was not changed */
148
BOOL
149
CommandAuditClear(
150
      TPM_CC           commandCode    // IN: command code
151
      )
152
0
{
153
0
    COMMAND_INDEX       commandIndex = CommandCodeToCommandIndex(commandCode);
154
    // Do nothing if the command is not implemented
155
0
    if(commandIndex != UNIMPLEMENTED_COMMAND_INDEX)
156
0
  {
157
      // The bit associated with TPM_CC_SetCommandCodeAuditStatus() cannot be
158
      // cleared
159
0
      if(commandCode != TPM_CC_SetCommandCodeAuditStatus)
160
0
    {
161
0
        if(TEST_BIT(commandIndex, gp.auditCommands))
162
0
      {
163
          // Clear bit
164
0
          CLEAR_BIT(commandIndex, gp.auditCommands);
165
0
          return TRUE;
166
0
      }
167
0
    }
168
0
  }
169
    // No change
170
0
    return FALSE;
171
0
}
172
/* 8.1.3.5 CommandAuditIsRequired() */
173
/* This function indicates if the audit flag is SET for a command. */
174
/* Return Values Meaning */
175
/* TRUE if command is audited */
176
/* FALSE if command is not audited */
177
BOOL
178
CommandAuditIsRequired(
179
           COMMAND_INDEX    commandIndex   // IN: command index
180
           )
181
1.08k
{
182
    // Check the bit map.  If the bit is SET, command audit is required
183
1.08k
    return(TEST_BIT(commandIndex, gp.auditCommands));
184
1.08k
}
185
/* 8.1.3.6 CommandAuditCapGetCCList() */
186
/* This function returns a list of commands that have their audit bit SET. */
187
/* The list starts at the input commandCode. */
188
/* Return Values Meaning */
189
/* YES if there are more command code available */
190
/* NO all the available command code has been returned */
191
TPMI_YES_NO
192
CommandAuditCapGetCCList(
193
       TPM_CC           commandCode,   // IN: start command code
194
       UINT32           count,         // IN: count of returned TPM_CC
195
       TPML_CC         *commandList    // OUT: list of TPM_CC
196
       )
197
0
{
198
0
    TPMI_YES_NO     more = NO;
199
0
    COMMAND_INDEX   commandIndex;
200
    // Initialize output handle list
201
0
    commandList->count = 0;
202
    // The maximum count of command we may return is MAX_CAP_CC
203
0
    if(count > MAX_CAP_CC) count = MAX_CAP_CC;
204
    // Find the implemented command that has a command code that is the same or
205
    // higher than the input
206
    // Collect audit commands
207
0
    for(commandIndex = GetClosestCommandIndex(commandCode);
208
0
  commandIndex != UNIMPLEMENTED_COMMAND_INDEX;
209
0
  commandIndex = GetNextCommandIndex(commandIndex))
210
0
  {
211
0
      if(CommandAuditIsRequired(commandIndex))
212
0
    {
213
0
        if(commandList->count < count)
214
0
      {
215
          // If we have not filled up the return list, add this command
216
          // code to its
217
0
          TPM_CC      cc = GET_ATTRIBUTE(s_ccAttr[commandIndex],
218
0
                 TPMA_CC, commandIndex);
219
0
          if(IS_ATTRIBUTE(s_ccAttr[commandIndex], TPMA_CC, V))
220
0
        cc += (1 << 29);
221
0
          commandList->commandCodes[commandList->count] = cc;
222
0
          commandList->count++;
223
0
      }
224
0
        else
225
0
      {
226
          // If the return list is full but we still have command
227
          // available, report this and stop iterating
228
0
          more = YES;
229
0
          break;
230
0
      }
231
0
    }
232
0
  }
233
0
    return more;
234
0
}
235
/* 8.1.3.7 CommandAuditGetDigest */
236
/* This command is used to create a digest of the commands being audited. The commands are processed
237
   in ascending numeric order with a list of TPM_CC being added to a hash. This operates as if all
238
   the audited command codes were concatenated and then hashed. */
239
void
240
CommandAuditGetDigest(
241
          TPM2B_DIGEST    *digest         // OUT: command digest
242
          )
243
0
{
244
0
    TPM_CC                       commandCode;
245
0
    COMMAND_INDEX                commandIndex;
246
0
    HASH_STATE                   hashState;
247
    // Start hash
248
0
    digest->t.size = CryptHashStart(&hashState, gp.auditHashAlg);
249
    // Add command code
250
0
    for(commandIndex = 0; commandIndex < COMMAND_COUNT; commandIndex++)
251
0
  {
252
0
      if(CommandAuditIsRequired(commandIndex))
253
0
    {
254
0
        commandCode = GetCommandCode(commandIndex);
255
0
        CryptDigestUpdateInt(&hashState, sizeof(commandCode), commandCode);
256
0
    }
257
0
  }
258
    // Complete hash
259
0
    CryptHashEnd2B(&hashState, &digest->b);
260
0
    return;
261
0
}