Home | History | Annotate | Download | only in TcgPei
      1 /** @file
      2   Utility functions used by TPM PEI driver.
      3 
      4 Copyright (c) 2005 - 2015, Intel Corporation. All rights reserved.<BR>
      5 This program and the accompanying materials
      6 are licensed and made available under the terms and conditions of the BSD License
      7 which accompanies this distribution.  The full text of the license may be found at
      8 http://opensource.org/licenses/bsd-license.php
      9 
     10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 
     13 **/
     14 
     15 #include "TpmComm.h"
     16 
     17 /**
     18   Send a command to TPM for execution and return response data.
     19 
     20   @param[in]      PeiServices   Describes the list of possible PEI Services.
     21   @param[in]      TisReg        TPM register space base address.
     22   @param[in]      BufferIn      Buffer for command data.
     23   @param[in]      SizeIn        Size of command data.
     24   @param[in, out] BufferOut     Buffer for response data.
     25   @param[in, out] SizeOut       size of response data.
     26 
     27   @retval EFI_SUCCESS           Operation completed successfully.
     28   @retval EFI_TIMEOUT           The register can't run into the expected status in time.
     29   @retval EFI_BUFFER_TOO_SMALL  Response data buffer is too small.
     30   @retval EFI_DEVICE_ERROR      Unexpected device behavior.
     31 
     32 **/
     33 EFI_STATUS
     34 TisTpmCommand (
     35   IN     EFI_PEI_SERVICES           **PeiServices,
     36   IN     TIS_PC_REGISTERS_PTR       TisReg,
     37   IN     UINT8                      *BufferIn,
     38   IN     UINT32                     SizeIn,
     39   IN OUT UINT8                      *BufferOut,
     40   IN OUT UINT32                     *SizeOut
     41   );
     42 
     43 /**
     44   Send TPM_Startup command to TPM.
     45 
     46   @param[in] PeiServices        Describes the list of possible PEI Services.
     47   @param[in] TpmHandle          TPM handle.
     48   @param[in] BootMode           Boot mode.
     49 
     50   @retval EFI_SUCCESS           Operation completed successfully.
     51   @retval EFI_TIMEOUT           The register can't run into the expected status in time.
     52   @retval EFI_BUFFER_TOO_SMALL  Response data buffer is too small.
     53   @retval EFI_DEVICE_ERROR      Unexpected device behavior.
     54 
     55 **/
     56 EFI_STATUS
     57 TpmCommStartup (
     58   IN      EFI_PEI_SERVICES          **PeiServices,
     59   IN      TIS_TPM_HANDLE            TpmHandle,
     60   IN      EFI_BOOT_MODE             BootMode
     61   )
     62 {
     63   EFI_STATUS                        Status;
     64   TPM_STARTUP_TYPE                  TpmSt;
     65   UINT32                            TpmRecvSize;
     66   UINT32                            TpmSendSize;
     67   TPM_CMD_START_UP                  SendBuffer;
     68   UINT8                             RecvBuffer[20];
     69 
     70   TpmSt = TPM_ST_CLEAR;
     71   if (BootMode == BOOT_ON_S3_RESUME) {
     72     TpmSt = TPM_ST_STATE;
     73   }
     74   //
     75   // send Tpm command TPM_ORD_Startup
     76   //
     77   TpmRecvSize               = 20;
     78   TpmSendSize               = sizeof (TPM_CMD_START_UP);
     79   SendBuffer.Hdr.tag        = SwapBytes16 (TPM_TAG_RQU_COMMAND);
     80   SendBuffer.Hdr.paramSize  = SwapBytes32 (TpmSendSize);
     81   SendBuffer.Hdr.ordinal    = SwapBytes32 (TPM_ORD_Startup);
     82   SendBuffer.TpmSt          = SwapBytes16 (TpmSt);
     83   Status = TisTpmCommand (PeiServices, TpmHandle, (UINT8 *)&SendBuffer, TpmSendSize, RecvBuffer, &TpmRecvSize);
     84   return Status;
     85 }
     86 
     87 /**
     88   Send TPM_ContinueSelfTest command to TPM.
     89 
     90   @param[in] PeiServices        Describes the list of possible PEI Services.
     91   @param[in] TpmHandle          TPM handle.
     92 
     93   @retval EFI_SUCCESS           Operation completed successfully.
     94   @retval EFI_TIMEOUT           The register can't run into the expected status in time.
     95   @retval EFI_BUFFER_TOO_SMALL  Response data buffer is too small.
     96   @retval EFI_DEVICE_ERROR      Unexpected device behavior.
     97 
     98 **/
     99 EFI_STATUS
    100 TpmCommContinueSelfTest (
    101   IN      EFI_PEI_SERVICES          **PeiServices,
    102   IN      TIS_TPM_HANDLE            TpmHandle
    103   )
    104 {
    105   EFI_STATUS                        Status;
    106   UINT32                            TpmRecvSize;
    107   UINT32                            TpmSendSize;
    108   TPM_CMD_SELF_TEST                 SendBuffer;
    109   UINT8                             RecvBuffer[20];
    110 
    111   //
    112   // send Tpm command TPM_ORD_ContinueSelfTest
    113   //
    114   TpmRecvSize               = 20;
    115   TpmSendSize               = sizeof (TPM_CMD_SELF_TEST);
    116   SendBuffer.Hdr.tag        = SwapBytes16 (TPM_TAG_RQU_COMMAND);
    117   SendBuffer.Hdr.paramSize  = SwapBytes32 (TpmSendSize);
    118   SendBuffer.Hdr.ordinal    = SwapBytes32 (TPM_ORD_ContinueSelfTest);
    119   Status = TisTpmCommand (PeiServices, TpmHandle, (UINT8 *)&SendBuffer, TpmSendSize, RecvBuffer, &TpmRecvSize);
    120   return Status;
    121 }
    122 
    123 /**
    124   Get TPM capability flags.
    125 
    126   @param[in]  PeiServices       Describes the list of possible PEI Services.
    127   @param[in]  TpmHandle         TPM handle.
    128   @param[out] Deactivated       Returns deactivated flag.
    129   @param[out] LifetimeLock      Returns physicalPresenceLifetimeLock permanent flag.
    130   @param[out] CmdEnable         Returns physicalPresenceCMDEnable permanent flag.
    131 
    132   @retval EFI_SUCCESS           Operation completed successfully.
    133   @retval EFI_TIMEOUT           The register can't run into the expected status in time.
    134   @retval EFI_BUFFER_TOO_SMALL  Response data buffer is too small.
    135   @retval EFI_DEVICE_ERROR      Unexpected device behavior.
    136 
    137 **/
    138 EFI_STATUS
    139 TpmCommGetCapability (
    140   IN      EFI_PEI_SERVICES          **PeiServices,
    141   IN      TIS_TPM_HANDLE            TpmHandle,
    142      OUT  BOOLEAN                   *Deactivated, OPTIONAL
    143      OUT  BOOLEAN                   *LifetimeLock, OPTIONAL
    144      OUT  BOOLEAN                   *CmdEnable OPTIONAL
    145   )
    146 {
    147   EFI_STATUS                        Status;
    148   UINT32                            TpmRecvSize;
    149   UINT32                            TpmSendSize;
    150   TPM_CMD_GET_CAPABILITY            SendBuffer;
    151   UINT8                             RecvBuffer[40];
    152   TPM_PERMANENT_FLAGS               *TpmPermanentFlags;
    153 
    154   //
    155   // send Tpm command TPM_ORD_GetCapability
    156   //
    157   TpmRecvSize                   = 40;
    158   TpmSendSize                   = sizeof (TPM_CMD_GET_CAPABILITY);
    159   SendBuffer.Hdr.tag            = SwapBytes16 (TPM_TAG_RQU_COMMAND);
    160   SendBuffer.Hdr.paramSize      = SwapBytes32 (TpmSendSize);
    161   SendBuffer.Hdr.ordinal        = SwapBytes32 (TPM_ORD_GetCapability);
    162   SendBuffer.Capability         = SwapBytes32 (TPM_CAP_FLAG);
    163   SendBuffer.CapabilityFlagSize = SwapBytes32 (sizeof (TPM_CAP_FLAG_PERMANENT));
    164   SendBuffer.CapabilityFlag     = SwapBytes32 (TPM_CAP_FLAG_PERMANENT);
    165   Status = TisTpmCommand (PeiServices, TpmHandle, (UINT8 *)&SendBuffer, TpmSendSize, RecvBuffer, &TpmRecvSize);
    166   if (EFI_ERROR (Status)) {
    167     return Status;
    168   }
    169   TpmPermanentFlags = (TPM_PERMANENT_FLAGS *)&RecvBuffer[sizeof (TPM_RSP_COMMAND_HDR) + sizeof (UINT32)];
    170   if (Deactivated != NULL) {
    171     *Deactivated      = TpmPermanentFlags->deactivated;
    172   }
    173 
    174   if (LifetimeLock != NULL) {
    175     *LifetimeLock = TpmPermanentFlags->physicalPresenceLifetimeLock;
    176   }
    177 
    178   if (CmdEnable != NULL) {
    179     *CmdEnable = TpmPermanentFlags->physicalPresenceCMDEnable;
    180   }
    181   return Status;
    182 }
    183 
    184 /**
    185   Extend a TPM PCR.
    186 
    187   @param[in]  PeiServices       Describes the list of possible PEI Services.
    188   @param[in]  TpmHandle         TPM handle.
    189   @param[in]  DigestToExtend    The 160 bit value representing the event to be recorded.
    190   @param[in]  PcrIndex          The PCR to be updated.
    191   @param[out] NewPcrValue       New PCR value after extend.
    192 
    193   @retval EFI_SUCCESS           Operation completed successfully.
    194   @retval EFI_TIMEOUT           The register can't run into the expected status in time.
    195   @retval EFI_BUFFER_TOO_SMALL  Response data buffer is too small.
    196   @retval EFI_DEVICE_ERROR      Unexpected device behavior.
    197 
    198 **/
    199 EFI_STATUS
    200 TpmCommExtend (
    201   IN      EFI_PEI_SERVICES          **PeiServices,
    202   IN      TIS_TPM_HANDLE            TpmHandle,
    203   IN      TPM_DIGEST                *DigestToExtend,
    204   IN      TPM_PCRINDEX              PcrIndex,
    205      OUT  TPM_DIGEST                *NewPcrValue
    206   )
    207 {
    208   EFI_STATUS                        Status;
    209   UINT32                            TpmSendSize;
    210   UINT32                            TpmRecvSize;
    211   TPM_CMD_EXTEND                    SendBuffer;
    212   UINT8                             RecvBuffer[10 + sizeof(TPM_DIGEST)];
    213 
    214   //
    215   // send Tpm command TPM_ORD_Extend
    216   //
    217   TpmRecvSize               = sizeof (TPM_RSP_COMMAND_HDR) + sizeof (TPM_DIGEST);
    218   TpmSendSize               = sizeof (TPM_CMD_EXTEND);
    219   SendBuffer.Hdr.tag        = SwapBytes16 (TPM_TAG_RQU_COMMAND);
    220   SendBuffer.Hdr.paramSize  = SwapBytes32 (TpmSendSize);
    221   SendBuffer.Hdr.ordinal    = SwapBytes32 (TPM_ORD_Extend);
    222   SendBuffer.PcrIndex       = SwapBytes32 (PcrIndex);
    223   CopyMem (&SendBuffer.TpmDigest, (UINT8 *)DigestToExtend, sizeof (TPM_DIGEST));
    224   Status = TisTpmCommand (PeiServices, TpmHandle, (UINT8 *)&SendBuffer, TpmSendSize, RecvBuffer, &TpmRecvSize);
    225   if (EFI_ERROR (Status)) {
    226     return Status;
    227   }
    228 
    229   if(NewPcrValue != NULL) {
    230     CopyMem ((UINT8*)NewPcrValue, &RecvBuffer[10], sizeof (TPM_DIGEST));
    231   }
    232 
    233   return Status;
    234 }
    235 
    236 
    237 /**
    238   Send TSC_PhysicalPresence command to TPM.
    239 
    240   @param[in] PeiServices        Describes the list of possible PEI Services.
    241   @param[in] TpmHandle          TPM handle.
    242   @param[in] PhysicalPresence   The state to set the TPMs Physical Presence flags.
    243 
    244   @retval EFI_SUCCESS           Operation completed successfully.
    245   @retval EFI_TIMEOUT           The register can't run into the expected status in time.
    246   @retval EFI_BUFFER_TOO_SMALL  Response data buffer is too small.
    247   @retval EFI_DEVICE_ERROR      Unexpected device behavior.
    248 
    249 **/
    250 EFI_STATUS
    251 TpmCommPhysicalPresence (
    252   IN      EFI_PEI_SERVICES          **PeiServices,
    253   IN      TIS_TPM_HANDLE            TpmHandle,
    254   IN      TPM_PHYSICAL_PRESENCE     PhysicalPresence
    255   )
    256 {
    257   EFI_STATUS                        Status;
    258   UINT32                            TpmSendSize;
    259   UINT32                            TpmRecvSize;
    260   TPM_CMD_PHYSICAL_PRESENCE         SendBuffer;
    261   UINT8                             RecvBuffer[10];
    262 
    263   //
    264   // send Tpm command TSC_ORD_PhysicalPresence
    265   //
    266   TpmRecvSize                 = 10;
    267   TpmSendSize                 = sizeof (TPM_CMD_PHYSICAL_PRESENCE);
    268   SendBuffer.Hdr.tag          = SwapBytes16 (TPM_TAG_RQU_COMMAND);
    269   SendBuffer.Hdr.paramSize    = SwapBytes32 (TpmSendSize);
    270   SendBuffer.Hdr.ordinal      = SwapBytes32 (TSC_ORD_PhysicalPresence);
    271   SendBuffer.PhysicalPresence = SwapBytes16 (PhysicalPresence);
    272   Status = TisTpmCommand (PeiServices, TpmHandle, (UINT8 *)&SendBuffer, TpmSendSize, RecvBuffer, &TpmRecvSize);
    273   return Status;
    274 }
    275