Home | History | Annotate | Download | only in PlatformSecureLib
      1 /** @file
      2 Provides a secure platform-specific method to detect physically present user.
      3 
      4 Copyright (c) 2013 - 2016 Intel Corporation.
      5 
      6 This program and the accompanying materials
      7 are licensed and made available under the terms and conditions of the BSD License
      8 which accompanies this distribution.  The full text of the license may be found at
      9 http://opensource.org/licenses/bsd-license.php
     10 
     11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     13 
     14 **/
     15 
     16 #include <PiDxe.h>
     17 #include <Library/PlatformHelperLib.h>
     18 #include <Library/DebugLib.h>
     19 #include <Library/UefiBootServicesTableLib.h>
     20 #include <Library/I2cLib.h>
     21 
     22 #include <PlatformBoards.h>
     23 #include <Pcal9555.h>
     24 #include <QNCAccess.h>
     25 
     26 //
     27 // Global variable to cache pointer to I2C protocol.
     28 //
     29 EFI_PLATFORM_TYPE mPlatformType = TypeUnknown;
     30 
     31 BOOLEAN
     32 CheckResetButtonState (
     33   VOID
     34   )
     35 {
     36   EFI_STATUS              Status;
     37   EFI_I2C_DEVICE_ADDRESS  I2CSlaveAddress;
     38   UINTN                   Length;
     39   UINTN                   ReadLength;
     40   UINT8                   Buffer[2];
     41 
     42   DEBUG ((EFI_D_INFO, "CheckResetButtonState(): mPlatformType == %d\n", mPlatformType));
     43   if (mPlatformType == GalileoGen2) {
     44     //
     45     // Read state of Reset Button - EXP2.P1_7
     46     // This GPIO is pulled high when the button is not pressed
     47     // This GPIO reads low when button is pressed
     48     //
     49     return PlatformPcal9555GpioGetState (
     50       GALILEO_GEN2_IOEXP2_7BIT_SLAVE_ADDR,  // IO Expander 2.
     51       15                                    // P1-7.
     52       );
     53   }
     54   if (mPlatformType == Galileo) {
     55     //
     56     // Detect the I2C Slave Address of the GPIO Expander
     57     //
     58     if (PlatformLegacyGpioGetLevel (R_QNC_GPIO_RGLVL_RESUME_WELL, GALILEO_DETERMINE_IOEXP_SLA_RESUMEWELL_GPIO)) {
     59       I2CSlaveAddress.I2CDeviceAddress = GALILEO_IOEXP_J2HI_7BIT_SLAVE_ADDR;
     60     } else {
     61       I2CSlaveAddress.I2CDeviceAddress = GALILEO_IOEXP_J2LO_7BIT_SLAVE_ADDR;
     62     }
     63     DEBUG ((EFI_D_INFO, "Galileo GPIO Expender Slave Address = %02x\n", I2CSlaveAddress.I2CDeviceAddress));
     64 
     65     //
     66     // Read state of RESET_N_SHLD (GPORT5_BIT0)
     67     //
     68     Buffer[1] = 5;
     69     Length = 1;
     70     ReadLength = 1;
     71     Status = I2cReadMultipleByte (
     72                I2CSlaveAddress,
     73                EfiI2CSevenBitAddrMode,
     74                &Length,
     75                &ReadLength,
     76                &Buffer[1]
     77                );
     78     ASSERT_EFI_ERROR (Status);
     79 
     80     //
     81     // Return the state of GPORT5_BIT0
     82     //
     83     return ((Buffer[1] & BIT0) != 0);
     84   }
     85   return TRUE;
     86 }
     87 
     88 /**
     89 
     90   This function provides a platform-specific method to detect whether the platform
     91   is operating by a physically present user.
     92 
     93   Programmatic changing of platform security policy (such as disable Secure Boot,
     94   or switch between Standard/Custom Secure Boot mode) MUST NOT be possible during
     95   Boot Services or after exiting EFI Boot Services. Only a physically present user
     96   is allowed to perform these operations.
     97 
     98   NOTE THAT: This function cannot depend on any EFI Variable Service since they are
     99   not available when this function is called in AuthenticateVariable driver.
    100 
    101   @retval  TRUE       The platform is operated by a physically present user.
    102   @retval  FALSE      The platform is NOT operated by a physically present user.
    103 
    104 **/
    105 BOOLEAN
    106 EFIAPI
    107 UserPhysicalPresent (
    108   VOID
    109   )
    110 {
    111   EFI_STATUS  Status;
    112 
    113   //
    114   // If user has already been detected as present, then return TRUE
    115   //
    116   if (PcdGetBool (PcdUserIsPhysicallyPresent)) {
    117     return TRUE;
    118   }
    119 
    120   //
    121   // Check to see if user is present now
    122   //
    123   if (CheckResetButtonState ()) {
    124     //
    125     // User is still not present, then return FALSE
    126     //
    127     return FALSE;
    128   }
    129 
    130   //
    131   // User has gone from not present to present state, so set
    132   // PcdUserIsPhysicallyPresent to TRUE
    133   //
    134   Status = PcdSetBoolS (PcdUserIsPhysicallyPresent, TRUE);
    135   ASSERT_EFI_ERROR (Status);
    136 
    137   return TRUE;
    138 }
    139 
    140 /**
    141   Determines if a user is physically present by reading the reset button state.
    142 
    143   @param  ImageHandle  The image handle of this driver.
    144   @param  SystemTable  A pointer to the EFI System Table.
    145 
    146   @retval EFI_SUCCESS   Install the Secure Boot Helper Protocol successfully.
    147 
    148 **/
    149 EFI_STATUS
    150 EFIAPI
    151 PlatformSecureLibInitialize (
    152   IN EFI_HANDLE        ImageHandle,
    153   IN EFI_SYSTEM_TABLE  *SystemTable
    154   )
    155 {
    156   EFI_STATUS  Status;
    157 
    158   //
    159   // Get the platform type
    160   //
    161   mPlatformType = (EFI_PLATFORM_TYPE)PcdGet16 (PcdPlatformType);
    162 
    163   //
    164   // Read the state of the reset button when the library is initialized
    165   //
    166   Status = PcdSetBoolS (PcdUserIsPhysicallyPresent, !CheckResetButtonState ());
    167   ASSERT_EFI_ERROR (Status);
    168 
    169   return EFI_SUCCESS;
    170 }
    171