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 #include "PP_fp.h"
     10 
     11 //
     12 //
     13 //             Functions
     14 //
     15 //             PhysicalPresencePreInstall_Init()
     16 //
     17 //       This function is used to initialize the array of commands that require confirmation with physical presence.
     18 //       The array is an array of bits that has a correspondence with the command code.
     19 //       This command should only ever be executable in a manufacturing setting or in a simulation.
     20 //
     21 void
     22 PhysicalPresencePreInstall_Init(
     23      void
     24      )
     25 {
     26      // Clear all the PP commands
     27      MemorySet(&gp.ppList, 0,
     28 //
     29                 ((TPM_CC_PP_LAST - TPM_CC_PP_FIRST + 1) + 7) / 8);
     30    // TPM_CC_PP_Commands always requires PP
     31    if(CommandIsImplemented(TPM_CC_PP_Commands))
     32        PhysicalPresenceCommandSet(TPM_CC_PP_Commands);
     33    // Write PP list to NV
     34    NvWriteReserved(NV_PP_LIST, &gp.ppList);
     35    return;
     36 }
     37 //
     38 //
     39 //          PhysicalPresenceCommandSet()
     40 //
     41 //     This function is used to indicate a command that requires PP confirmation.
     42 //
     43 void
     44 PhysicalPresenceCommandSet(
     45    TPM_CC               commandCode       // IN: command code
     46    )
     47 {
     48    UINT32         bitPos;
     49    // Assume command is implemented. It should be checked before this
     50    // function is called
     51    pAssert(CommandIsImplemented(commandCode));
     52    // If the command is not a PP command, ignore it
     53    if(commandCode < TPM_CC_PP_FIRST || commandCode > TPM_CC_PP_LAST)
     54        return;
     55    bitPos = commandCode - TPM_CC_PP_FIRST;
     56    // Set bit
     57    gp.ppList[bitPos/8] |= 1 << (bitPos % 8);
     58    return;
     59 }
     60 //
     61 //
     62 //          PhysicalPresenceCommandClear()
     63 //
     64 //     This function is used to indicate a command that no longer requires PP confirmation.
     65 //
     66 void
     67 PhysicalPresenceCommandClear(
     68    TPM_CC               commandCode       // IN: command code
     69    )
     70 {
     71    UINT32         bitPos;
     72    // Assume command is implemented. It should be checked before this
     73    // function is called
     74    pAssert(CommandIsImplemented(commandCode));
     75    // If the command is not a PP command, ignore it
     76    if(commandCode < TPM_CC_PP_FIRST || commandCode > TPM_CC_PP_LAST)
     77        return;
     78    // if the input code is TPM_CC_PP_Commands, it can not be cleared
     79    if(commandCode == TPM_CC_PP_Commands)
     80        return;
     81    bitPos = commandCode - TPM_CC_PP_FIRST;
     82      // Set bit
     83      gp.ppList[bitPos/8] |= (1 << (bitPos % 8));
     84      // Flip it to off
     85      gp.ppList[bitPos/8] ^= (1 << (bitPos % 8));
     86      return;
     87 }
     88 //
     89 //
     90 //           PhysicalPresenceIsRequired()
     91 //
     92 //      This function indicates if PP confirmation is required for a command.
     93 //
     94 //      Return Value                      Meaning
     95 //
     96 //      TRUE                              if physical presence is required
     97 //      FALSE                             if physical presence is not required
     98 //
     99 BOOL
    100 PhysicalPresenceIsRequired(
    101      TPM_CC             commandCode           // IN: command code
    102      )
    103 {
    104      UINT32        bitPos;
    105      // if the input commandCode is not a PP command, return FALSE
    106      if(commandCode < TPM_CC_PP_FIRST || commandCode > TPM_CC_PP_LAST)
    107          return FALSE;
    108      bitPos = commandCode - TPM_CC_PP_FIRST;
    109      // Check the bit map. If the bit is SET, PP authorization is required
    110      return ((gp.ppList[bitPos/8] & (1 << (bitPos % 8))) != 0);
    111 }
    112 //
    113 //
    114 //           PhysicalPresenceCapGetCCList()
    115 //
    116 //      This function returns a list of commands that require PP confirmation. The list starts from the first
    117 //      implemented command that has a command code that the same or greater than commandCode.
    118 //
    119 //      Return Value                      Meaning
    120 //
    121 //      YES                               if there are more command codes available
    122 //      NO                                all the available command codes have been returned
    123 //
    124 TPMI_YES_NO
    125 PhysicalPresenceCapGetCCList(
    126      TPM_CC             commandCode,          // IN: start command code
    127      UINT32             count,                // IN: count of returned TPM_CC
    128      TPML_CC           *commandList           // OUT: list of TPM_CC
    129      )
    130 {
    131      TPMI_YES_NO       more = NO;
    132      UINT32            i;
    133      // Initialize output handle list
    134      commandList->count = 0;
    135      // The maximum count of command we may return is MAX_CAP_CC
    136      if(count > MAX_CAP_CC) count = MAX_CAP_CC;
    137      // Collect PP commands
    138      for(i = commandCode; i <= TPM_CC_PP_LAST; i++)
    139      {
    140          if(PhysicalPresenceIsRequired(i))
    141          {
    142              if(commandList->count < count)
    143              {
    144                  // If we have not filled up the return list, add this command
    145                  // code to it
    146                  commandList->commandCodes[commandList->count] = i;
    147                  commandList->count++;
    148              }
    149              else
    150              {
    151                  // If the return list is full but we still have PP command
    152                  // available, report this and stop iterating
    153                  more = YES;
    154                  break;
    155              }
    156          }
    157      }
    158      return more;
    159 }
    160