• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
CheckResetButtonState(VOID)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
UserPhysicalPresent(VOID)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
PlatformSecureLibInitialize(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)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