TianoCore EDK2 master
Loading...
Searching...
No Matches
HddPasswordPei.c
Go to the documentation of this file.
1
10#include "HddPasswordPei.h"
11
12EFI_GUID mHddPasswordDeviceInfoGuid = HDD_PASSWORD_DEVICE_INFO_GUID;
13
32 IN UINT16 Port,
33 IN UINT16 PortMultiplierPort,
34 IN CHAR8 Identifier,
35 IN CHAR8 *Password
36 )
37{
38 EFI_STATUS Status;
42 UINT8 Buffer[HDD_PAYLOAD];
43
44 if ((AtaPassThru == NULL) || (Password == NULL)) {
45 return EFI_INVALID_PARAMETER;
46 }
47
48 //
49 // The 'Asb' field (a pointer to the EFI_ATA_STATUS_BLOCK structure) in
50 // EFI_ATA_PASS_THRU_COMMAND_PACKET is required to be aligned specified by
51 // the 'IoAlign' field in the EFI_ATA_PASS_THRU_MODE structure. Meanwhile,
52 // the structure EFI_ATA_STATUS_BLOCK is composed of only UINT8 fields, so it
53 // may not be aligned when allocated on stack for some compilers. Hence, we
54 // use the API AllocateAlignedPages to ensure this structure is properly
55 // aligned.
56 //
59 AtaPassThru->Mode->IoAlign
60 );
61 if (Asb == NULL) {
62 return EFI_OUT_OF_RESOURCES;
63 }
64
65 //
66 // Prepare for ATA command block.
67 //
68 ZeroMem (&Acb, sizeof (Acb));
69 ZeroMem (Asb, sizeof (EFI_ATA_STATUS_BLOCK));
70 Acb.AtaCommand = ATA_SECURITY_UNLOCK_CMD;
71 Acb.AtaDeviceHead = (UINT8)(PortMultiplierPort == 0xFFFF ? 0 : (PortMultiplierPort << 4));
72
73 //
74 // Prepare for ATA pass through packet.
75 //
76 ZeroMem (&Packet, sizeof (Packet));
77 Packet.Protocol = EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_OUT;
78 Packet.Length = EFI_ATA_PASS_THRU_LENGTH_BYTES;
79 Packet.Asb = Asb;
80 Packet.Acb = &Acb;
81
82 ((CHAR16 *)Buffer)[0] = Identifier & BIT0;
83 CopyMem (&((CHAR16 *)Buffer)[1], Password, HDD_PASSWORD_MAX_LENGTH);
84
85 Packet.OutDataBuffer = Buffer;
86 Packet.OutTransferLength = sizeof (Buffer);
87 Packet.Timeout = ATA_TIMEOUT;
88
89 Status = AtaPassThru->PassThru (
90 AtaPassThru,
91 Port,
92 PortMultiplierPort,
93 &Packet
94 );
95 if (!EFI_ERROR (Status) &&
96 ((Asb->AtaStatus & ATA_STSREG_ERR) != 0) &&
97 ((Asb->AtaError & ATA_ERRREG_ABRT) != 0))
98 {
99 Status = EFI_DEVICE_ERROR;
100 }
101
103
104 ZeroMem (Buffer, sizeof (Buffer));
105
106 DEBUG ((DEBUG_INFO, "%a() - %r\n", __func__, Status));
107 return Status;
108}
109
125 IN EDKII_PEI_ATA_PASS_THRU_PPI *AtaPassThru,
126 IN UINT16 Port,
127 IN UINT16 PortMultiplierPort
128 )
129{
130 EFI_STATUS Status;
134
135 if (AtaPassThru == NULL) {
136 return EFI_INVALID_PARAMETER;
137 }
138
139 //
140 // The 'Asb' field (a pointer to the EFI_ATA_STATUS_BLOCK structure) in
141 // EFI_ATA_PASS_THRU_COMMAND_PACKET is required to be aligned specified by
142 // the 'IoAlign' field in the EFI_ATA_PASS_THRU_MODE structure. Meanwhile,
143 // the structure EFI_ATA_STATUS_BLOCK is composed of only UINT8 fields, so it
144 // may not be aligned when allocated on stack for some compilers. Hence, we
145 // use the API AllocateAlignedPages to ensure this structure is properly
146 // aligned.
147 //
150 AtaPassThru->Mode->IoAlign
151 );
152 if (Asb == NULL) {
153 return EFI_OUT_OF_RESOURCES;
154 }
155
156 //
157 // Prepare for ATA command block.
158 //
159 ZeroMem (&Acb, sizeof (Acb));
160 ZeroMem (Asb, sizeof (EFI_ATA_STATUS_BLOCK));
161 Acb.AtaCommand = ATA_SECURITY_FREEZE_LOCK_CMD;
162 Acb.AtaDeviceHead = (UINT8)(PortMultiplierPort == 0xFFFF ? 0 : (PortMultiplierPort << 4));
163
164 //
165 // Prepare for ATA pass through packet.
166 //
167 ZeroMem (&Packet, sizeof (Packet));
168 Packet.Protocol = EFI_ATA_PASS_THRU_PROTOCOL_ATA_NON_DATA;
169 Packet.Length = EFI_ATA_PASS_THRU_LENGTH_NO_DATA_TRANSFER;
170 Packet.Asb = Asb;
171 Packet.Acb = &Acb;
172 Packet.Timeout = ATA_TIMEOUT;
173
174 Status = AtaPassThru->PassThru (
175 AtaPassThru,
176 Port,
177 PortMultiplierPort,
178 &Packet
179 );
180 if (!EFI_ERROR (Status) &&
181 ((Asb->AtaStatus & ATA_STSREG_ERR) != 0) &&
182 ((Asb->AtaError & ATA_ERRREG_ABRT) != 0))
183 {
184 Status = EFI_DEVICE_ERROR;
185 }
186
188
189 DEBUG ((DEBUG_INFO, "%a() - %r\n", __func__, Status));
190 return Status;
191}
192
199VOID
201 IN EDKII_PEI_ATA_PASS_THRU_PPI *AtaPassThruPpi
202 )
203{
204 EFI_STATUS Status;
205 VOID *Buffer;
206 UINTN Length;
207 UINT8 DummyData;
209 UINT16 Port;
210 UINT16 PortMultiplierPort;
211 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
212 UINTN DevicePathLength;
213
214 //
215 // Get HDD password device info from LockBox.
216 //
217 Buffer = (VOID *)&DummyData;
218 Length = sizeof (DummyData);
219 Status = RestoreLockBox (&mHddPasswordDeviceInfoGuid, Buffer, &Length);
220 if (Status == EFI_BUFFER_TOO_SMALL) {
221 Buffer = AllocatePages (EFI_SIZE_TO_PAGES (Length));
222 if (Buffer != NULL) {
223 Status = RestoreLockBox (&mHddPasswordDeviceInfoGuid, Buffer, &Length);
224 }
225 }
226
227 if ((Buffer == NULL) || (Buffer == (VOID *)&DummyData)) {
228 return;
229 } else if (EFI_ERROR (Status)) {
230 FreePages (Buffer, EFI_SIZE_TO_PAGES (Length));
231 return;
232 }
233
234 Status = AtaPassThruPpi->GetDevicePath (AtaPassThruPpi, &DevicePathLength, &DevicePath);
235 if (EFI_ERROR (Status) || (DevicePathLength <= sizeof (EFI_DEVICE_PATH_PROTOCOL))) {
236 goto Exit;
237 }
238
239 //
240 // Go through all the devices managed by the AtaPassThru PPI instance.
241 //
242 Port = 0xFFFF;
243 while (TRUE) {
244 Status = AtaPassThruPpi->GetNextPort (AtaPassThruPpi, &Port);
245 if (EFI_ERROR (Status)) {
246 //
247 // We cannot find more legal port then we are done.
248 //
249 break;
250 }
251
252 PortMultiplierPort = 0xFFFF;
253 while (TRUE) {
254 Status = AtaPassThruPpi->GetNextDevice (AtaPassThruPpi, Port, &PortMultiplierPort);
255 if (EFI_ERROR (Status)) {
256 //
257 // We cannot find more legal port multiplier port number for ATA device
258 // on the port, then we are done.
259 //
260 break;
261 }
262
263 //
264 // Search the device in the restored LockBox.
265 //
266 DevInfo = (HDD_PASSWORD_DEVICE_INFO *)Buffer;
267 while ((UINTN)DevInfo < ((UINTN)Buffer + Length)) {
268 //
269 // Find the matching device.
270 //
271 if ((DevInfo->Device.Port == Port) &&
272 (DevInfo->Device.PortMultiplierPort == PortMultiplierPort) &&
273 (DevInfo->DevicePathLength >= DevicePathLength) &&
274 (CompareMem (
275 DevInfo->DevicePath,
276 DevicePath,
277 DevicePathLength - sizeof (EFI_DEVICE_PATH_PROTOCOL)
278 ) == 0))
279 {
280 //
281 // If device locked, unlock first.
282 //
283 if (!IsZeroBuffer (DevInfo->Password, HDD_PASSWORD_MAX_LENGTH)) {
284 UnlockDevice (AtaPassThruPpi, Port, PortMultiplierPort, 0, DevInfo->Password);
285 }
286
287 //
288 // Freeze lock the device.
289 //
290 FreezeLockDevice (AtaPassThruPpi, Port, PortMultiplierPort);
291 break;
292 }
293
294 DevInfo = (HDD_PASSWORD_DEVICE_INFO *)
295 ((UINTN)DevInfo + sizeof (HDD_PASSWORD_DEVICE_INFO) + DevInfo->DevicePathLength);
296 }
297 }
298 }
299
300Exit:
301 ZeroMem (Buffer, Length);
302 FreePages (Buffer, EFI_SIZE_TO_PAGES (Length));
303}
304
317EFIAPI
319 IN EFI_PEI_SERVICES **PeiServices,
320 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,
321 IN VOID *Ppi
322 )
323{
324 DEBUG ((DEBUG_INFO, "%a() - enter at S3 resume\n", __func__));
325
327
328 DEBUG ((DEBUG_INFO, "%a() - exit at S3 resume\n", __func__));
329
330 return EFI_SUCCESS;
331}
332
333EFI_PEI_NOTIFY_DESCRIPTOR mHddPasswordAtaPassThruPpiNotifyDesc = {
334 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
335 &gEdkiiPeiAtaPassThruPpiGuid,
337};
338
349EFIAPI
351 IN EFI_PEI_FILE_HANDLE FileHandle,
352 IN CONST EFI_PEI_SERVICES **PeiServices
353 )
354{
355 EFI_STATUS Status;
356 EFI_BOOT_MODE BootMode;
357
358 Status = PeiServicesGetBootMode (&BootMode);
359 if ((EFI_ERROR (Status)) || (BootMode != BOOT_ON_S3_RESUME)) {
360 return EFI_UNSUPPORTED;
361 }
362
363 DEBUG ((DEBUG_INFO, "%a: Enters in S3 path.\n", __func__));
364
365 Status = PeiServicesNotifyPpi (&mHddPasswordAtaPassThruPpiNotifyDesc);
366 ASSERT_EFI_ERROR (Status);
367 return Status;
368}
UINT64 UINTN
#define ATA_ERRREG_ABRT
Aborted Command defined from ATA-1.
Definition: Atapi.h:826
#define ATA_STSREG_ERR
Error defined from ATA-1.
Definition: Atapi.h:841
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
BOOLEAN EFIAPI IsZeroBuffer(IN CONST VOID *Buffer, IN UINTN Length)
VOID EFIAPI FreePages(IN VOID *Buffer, IN UINTN Pages)
VOID EFIAPI FreeAlignedPages(IN VOID *Buffer, IN UINTN Pages)
EFI_STATUS EFIAPI PeiServicesGetBootMode(OUT EFI_BOOT_MODE *BootMode)
EFI_STATUS EFIAPI PeiServicesNotifyPpi(IN CONST EFI_PEI_NOTIFY_DESCRIPTOR *NotifyList)
EFI_STATUS UnlockDevice(IN EDKII_PEI_ATA_PASS_THRU_PPI *AtaPassThru, IN UINT16 Port, IN UINT16 PortMultiplierPort, IN CHAR8 Identifier, IN CHAR8 *Password)
EFI_STATUS EFIAPI HddPasswordAtaPassThruNotify(IN EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc, IN VOID *Ppi)
EFI_STATUS EFIAPI HddPasswordPeiInit(IN EFI_PEI_FILE_HANDLE FileHandle, IN CONST EFI_PEI_SERVICES **PeiServices)
VOID UnlockHddPassword(IN EDKII_PEI_ATA_PASS_THRU_PPI *AtaPassThruPpi)
EFI_STATUS FreezeLockDevice(IN EDKII_PEI_ATA_PASS_THRU_PPI *AtaPassThru, IN UINT16 Port, IN UINT16 PortMultiplierPort)
RETURN_STATUS EFIAPI RestoreLockBox(IN GUID *Guid, IN VOID *Buffer OPTIONAL, IN OUT UINTN *Length OPTIONAL)
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define TRUE
Definition: Base.h:301
#define IN
Definition: Base.h:279
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG(Expression)
Definition: DebugLib.h:434
UINT32 EFI_BOOT_MODE
Definition: PiBootMode.h:18
VOID * EFI_PEI_FILE_HANDLE
Definition: PiPeiCis.h:26
VOID *EFIAPI AllocateAlignedPages(IN UINTN Pages, IN UINTN Alignment)
VOID *EFIAPI AllocatePages(IN UINTN Pages)
VOID EFIAPI Exit(IN EFI_STATUS Status)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SIZE_TO_PAGES(Size)
Definition: UefiBaseType.h:200
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_ATA_STATUS_BLOCK * Asb
Definition: AtaPassThru.h:114
EFI_ATA_PASS_THRU_LENGTH Length
Definition: AtaPassThru.h:167
EFI_ATA_PASS_THRU_CMD_PROTOCOL Protocol
Definition: AtaPassThru.h:163
EFI_ATA_COMMAND_BLOCK * Acb
Definition: AtaPassThru.h:119
Definition: Base.h:213