Home | History | Annotate | Download | only in SmmTcg2PhysicalPresenceLib
      1 /** @file
      2   Handle TPM 2.0 physical presence requests from OS.
      3 
      4   This library will handle TPM 2.0 physical presence request from OS.
      5 
      6   Caution: This module requires additional review when modified.
      7   This driver will have external input - variable.
      8   This external input must be validated carefully to avoid security issue.
      9 
     10   Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction() and Tcg2PhysicalPresenceLibGetUserConfirmationStatusFunction()
     11   will receive untrusted input and do validation.
     12 
     13 Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
     14 This program and the accompanying materials
     15 are licensed and made available under the terms and conditions of the BSD License
     16 which accompanies this distribution.  The full text of the license may be found at
     17 http://opensource.org/licenses/bsd-license.php
     18 
     19 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     20 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     21 
     22 **/
     23 
     24 #include <PiSmm.h>
     25 
     26 #include <Guid/Tcg2PhysicalPresenceData.h>
     27 
     28 #include <Protocol/SmmVariable.h>
     29 
     30 #include <Library/DebugLib.h>
     31 #include <Library/Tcg2PpVendorLib.h>
     32 #include <Library/SmmServicesTableLib.h>
     33 
     34 EFI_SMM_VARIABLE_PROTOCOL  *mTcg2PpSmmVariable;
     35 
     36 /**
     37   The handler for TPM physical presence function:
     38   Return TPM Operation Response to OS Environment.
     39 
     40   This API should be invoked in OS runtime phase to interface with ACPI method.
     41 
     42   @param[out]     MostRecentRequest Most recent operation request.
     43   @param[out]     Response          Response to the most recent operation request.
     44 
     45   @return Return Code for Return TPM Operation Response to OS Environment.
     46 **/
     47 UINT32
     48 EFIAPI
     49 Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction (
     50   OUT UINT32                *MostRecentRequest,
     51   OUT UINT32                *Response
     52   )
     53 {
     54   EFI_STATUS                        Status;
     55   UINTN                             DataSize;
     56   EFI_TCG2_PHYSICAL_PRESENCE        PpData;
     57 
     58   DEBUG ((EFI_D_INFO, "[TPM2] ReturnOperationResponseToOsFunction\n"));
     59 
     60   //
     61   // Get the Physical Presence variable
     62   //
     63   DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
     64   Status = mTcg2PpSmmVariable->SmmGetVariable (
     65                                  TCG2_PHYSICAL_PRESENCE_VARIABLE,
     66                                  &gEfiTcg2PhysicalPresenceGuid,
     67                                  NULL,
     68                                  &DataSize,
     69                                  &PpData
     70                                  );
     71   if (EFI_ERROR (Status)) {
     72     *MostRecentRequest = 0;
     73     *Response          = 0;
     74     DEBUG ((EFI_D_ERROR, "[TPM2] Get PP variable failure! Status = %r\n", Status));
     75     return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_FAILURE;
     76   }
     77 
     78   *MostRecentRequest = PpData.LastPPRequest;
     79   *Response          = PpData.PPResponse;
     80 
     81   return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_SUCCESS;
     82 }
     83 
     84 /**
     85   The handler for TPM physical presence function:
     86   Submit TPM Operation Request to Pre-OS Environment and
     87   Submit TPM Operation Request to Pre-OS Environment 2.
     88 
     89   This API should be invoked in OS runtime phase to interface with ACPI method.
     90 
     91   Caution: This function may receive untrusted input.
     92 
     93   @param[in]      OperationRequest TPM physical presence operation request.
     94   @param[in]      RequestParameter TPM physical presence operation request parameter.
     95 
     96   @return Return Code for Submit TPM Operation Request to Pre-OS Environment and
     97           Submit TPM Operation Request to Pre-OS Environment 2.
     98 **/
     99 UINT32
    100 EFIAPI
    101 Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (
    102   IN UINT32                 OperationRequest,
    103   IN UINT32                 RequestParameter
    104   )
    105 {
    106   EFI_STATUS                        Status;
    107   UINTN                             DataSize;
    108   EFI_TCG2_PHYSICAL_PRESENCE        PpData;
    109   EFI_TCG2_PHYSICAL_PRESENCE_FLAGS  Flags;
    110 
    111   DEBUG ((EFI_D_INFO, "[TPM2] SubmitRequestToPreOSFunction, Request = %x, %x\n", OperationRequest, RequestParameter));
    112 
    113   //
    114   // Get the Physical Presence variable
    115   //
    116   DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
    117   Status = mTcg2PpSmmVariable->SmmGetVariable (
    118                                  TCG2_PHYSICAL_PRESENCE_VARIABLE,
    119                                  &gEfiTcg2PhysicalPresenceGuid,
    120                                  NULL,
    121                                  &DataSize,
    122                                  &PpData
    123                                  );
    124   if (EFI_ERROR (Status)) {
    125     DEBUG ((EFI_D_ERROR, "[TPM2] Get PP variable failure! Status = %r\n", Status));
    126     return TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE;
    127   }
    128 
    129   if ((OperationRequest > TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) &&
    130       (OperationRequest < TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) ) {
    131     //
    132     // This command requires UI to prompt user for Auth data.
    133     //
    134     return TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED;
    135   }
    136 
    137   if (PpData.PPRequest != OperationRequest) {
    138     PpData.PPRequest = (UINT8)OperationRequest;
    139     PpData.PPRequestParameter = RequestParameter;
    140     DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
    141     Status = mTcg2PpSmmVariable->SmmSetVariable (
    142                                    TCG2_PHYSICAL_PRESENCE_VARIABLE,
    143                                    &gEfiTcg2PhysicalPresenceGuid,
    144                                    EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
    145                                    DataSize,
    146                                    &PpData
    147                                    );
    148   }
    149 
    150   if (EFI_ERROR (Status)) {
    151     DEBUG ((EFI_D_ERROR, "[TPM2] Set PP variable failure! Status = %r\n", Status));
    152     return TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE;
    153   }
    154 
    155   if (OperationRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {
    156     DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS);
    157     Status = mTcg2PpSmmVariable->SmmGetVariable (
    158                                    TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,
    159                                    &gEfiTcg2PhysicalPresenceGuid,
    160                                    NULL,
    161                                    &DataSize,
    162                                    &Flags
    163                                    );
    164     if (EFI_ERROR (Status)) {
    165       Flags.PPFlags = TCG2_BIOS_TPM_MANAGEMENT_FLAG_DEFAULT;
    166     }
    167     return Tcg2PpVendorLibSubmitRequestToPreOSFunction (OperationRequest, Flags.PPFlags, RequestParameter);
    168   }
    169 
    170   return TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS;
    171 }
    172 
    173 /**
    174   The handler for TPM physical presence function:
    175   Get User Confirmation Status for Operation.
    176 
    177   This API should be invoked in OS runtime phase to interface with ACPI method.
    178 
    179   Caution: This function may receive untrusted input.
    180 
    181   @param[in]      OperationRequest TPM physical presence operation request.
    182 
    183   @return Return Code for Get User Confirmation Status for Operation.
    184 **/
    185 UINT32
    186 EFIAPI
    187 Tcg2PhysicalPresenceLibGetUserConfirmationStatusFunction (
    188   IN UINT32                 OperationRequest
    189   )
    190 {
    191   EFI_STATUS                        Status;
    192   UINTN                             DataSize;
    193   EFI_TCG2_PHYSICAL_PRESENCE        PpData;
    194   EFI_TCG2_PHYSICAL_PRESENCE_FLAGS  Flags;
    195   BOOLEAN                           RequestConfirmed;
    196 
    197   DEBUG ((EFI_D_INFO, "[TPM2] GetUserConfirmationStatusFunction, Request = %x\n", OperationRequest));
    198 
    199   //
    200   // Get the Physical Presence variable
    201   //
    202   DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
    203   Status = mTcg2PpSmmVariable->SmmGetVariable (
    204                                  TCG2_PHYSICAL_PRESENCE_VARIABLE,
    205                                  &gEfiTcg2PhysicalPresenceGuid,
    206                                  NULL,
    207                                  &DataSize,
    208                                  &PpData
    209                                  );
    210   if (EFI_ERROR (Status)) {
    211     DEBUG ((EFI_D_ERROR, "[TPM2] Get PP variable failure! Status = %r\n", Status));
    212     return TCG_PP_GET_USER_CONFIRMATION_BLOCKED_BY_BIOS_CONFIGURATION;
    213   }
    214   //
    215   // Get the Physical Presence flags
    216   //
    217   DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS);
    218   Status = mTcg2PpSmmVariable->SmmGetVariable (
    219                                  TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,
    220                                  &gEfiTcg2PhysicalPresenceGuid,
    221                                  NULL,
    222                                  &DataSize,
    223                                  &Flags
    224                                  );
    225   if (EFI_ERROR (Status)) {
    226     DEBUG ((EFI_D_ERROR, "[TPM2] Get PP flags failure! Status = %r\n", Status));
    227     return TCG_PP_GET_USER_CONFIRMATION_BLOCKED_BY_BIOS_CONFIGURATION;
    228   }
    229 
    230   RequestConfirmed = FALSE;
    231 
    232   switch (OperationRequest) {
    233     case TCG2_PHYSICAL_PRESENCE_CLEAR:
    234     case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR:
    235     case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2:
    236     case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3:
    237       if ((Flags.PPFlags & TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CLEAR) == 0) {
    238         RequestConfirmed = TRUE;
    239       }
    240       break;
    241 
    242     case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_TRUE:
    243       RequestConfirmed = TRUE;
    244       break;
    245 
    246     case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_FALSE:
    247       break;
    248 
    249     case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS:
    250       if ((Flags.PPFlags & TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CHANGE_PCRS) == 0) {
    251         RequestConfirmed = TRUE;
    252       }
    253       break;
    254 
    255     case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS:
    256       if ((Flags.PPFlags & TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CHANGE_EPS) == 0) {
    257         RequestConfirmed = TRUE;
    258       }
    259       break;
    260 
    261     case TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS:
    262       RequestConfirmed = TRUE;
    263       break;
    264 
    265     default:
    266       if (OperationRequest <= TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) {
    267         RequestConfirmed = TRUE;
    268       } else {
    269         if (OperationRequest < TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {
    270           return TCG_PP_GET_USER_CONFIRMATION_NOT_IMPLEMENTED;
    271         }
    272       }
    273       break;
    274   }
    275 
    276   if (OperationRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {
    277     return Tcg2PpVendorLibGetUserConfirmationStatusFunction (OperationRequest, Flags.PPFlags);
    278   }
    279 
    280   if (RequestConfirmed) {
    281     return TCG_PP_GET_USER_CONFIRMATION_ALLOWED_AND_PPUSER_NOT_REQUIRED;
    282   } else {
    283     return TCG_PP_GET_USER_CONFIRMATION_ALLOWED_AND_PPUSER_REQUIRED;
    284   }
    285 }
    286 
    287 /**
    288   The constructor function register UNI strings into imageHandle.
    289 
    290   It will ASSERT() if that operation fails and it will always return EFI_SUCCESS.
    291 
    292   @param  ImageHandle   The firmware allocated handle for the EFI image.
    293   @param  SystemTable   A pointer to the EFI System Table.
    294 
    295   @retval EFI_SUCCESS   The constructor successfully added string package.
    296   @retval Other value   The constructor can't add string package.
    297 **/
    298 EFI_STATUS
    299 EFIAPI
    300 Tcg2PhysicalPresenceLibConstructor (
    301   IN EFI_HANDLE        ImageHandle,
    302   IN EFI_SYSTEM_TABLE  *SystemTable
    303   )
    304 {
    305   EFI_STATUS  Status;
    306 
    307   //
    308   // Locate SmmVariableProtocol.
    309   //
    310   Status = gSmst->SmmLocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, (VOID**)&mTcg2PpSmmVariable);
    311   ASSERT_EFI_ERROR (Status);
    312 
    313   return EFI_SUCCESS;
    314 }
    315