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