]> git.proxmox.com Git - mirror_edk2.git/blame - SecurityPkg/Tcg/Opal/OpalPassword/OpalDriver.c
UefiCpuPkg/MpInitLib: Decrease NumApsExecuting only for ApInitConfig
[mirror_edk2.git] / SecurityPkg / Tcg / Opal / OpalPassword / OpalDriver.c
CommitLineData
112e584b
SZ
1/** @file\r
2 Entrypoint of Opal UEFI Driver and contains all the logic to\r
3 register for new Opal device instances.\r
4\r
d72d8561 5Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.<BR>\r
289b714b 6SPDX-License-Identifier: BSD-2-Clause-Patent\r
112e584b
SZ
7\r
8**/\r
9\r
10// This UEFI driver consumes EFI_STORAGE_SECURITY_PROTOCOL instances and installs an\r
11// HII GUI to manage Opal features if the device is Opal capable\r
12// If the Opal device is being managed by the UEFI Driver, it shall provide a popup\r
13// window during boot requesting a user password\r
14\r
15#include "OpalDriver.h"\r
16#include "OpalHii.h"\r
17\r
a3efbc29 18EFI_GUID mOpalDeviceLockBoxGuid = OPAL_DEVICE_LOCKBOX_GUID;\r
112e584b
SZ
19\r
20BOOLEAN mOpalEndOfDxe = FALSE;\r
21OPAL_REQUEST_VARIABLE *mOpalRequestVariable = NULL;\r
22UINTN mOpalRequestVariableSize = 0;\r
aa085730 23CHAR16 mPopUpString[100];\r
112e584b 24\r
112e584b
SZ
25OPAL_DRIVER mOpalDriver;\r
26\r
27//\r
28// Globals\r
29//\r
30EFI_DRIVER_BINDING_PROTOCOL gOpalDriverBinding = {\r
31 OpalEfiDriverBindingSupported,\r
32 OpalEfiDriverBindingStart,\r
33 OpalEfiDriverBindingStop,\r
34 0x1b,\r
35 NULL,\r
36 NULL\r
37};\r
38\r
39/**\r
40\r
41 The function determines the available actions for the OPAL_DISK provided.\r
42\r
43 @param[in] SupportedAttributes The supported attributes for the device.\r
44 @param[in] LockingFeature The locking status for the device.\r
45 @param[in] OwnerShip The ownership for the device.\r
46 @param[out] AvalDiskActions Pointer to fill-out with appropriate disk actions.\r
47\r
48**/\r
49TCG_RESULT\r
50EFIAPI\r
51OpalSupportGetAvailableActions(\r
52 IN OPAL_DISK_SUPPORT_ATTRIBUTE *SupportedAttributes,\r
53 IN TCG_LOCKING_FEATURE_DESCRIPTOR *LockingFeature,\r
54 IN UINT16 OwnerShip,\r
55 OUT OPAL_DISK_ACTIONS *AvalDiskActions\r
56 )\r
57{\r
58 BOOLEAN ExistingPassword;\r
59\r
60 NULL_CHECK(AvalDiskActions);\r
61\r
62 AvalDiskActions->AdminPass = 1;\r
63 AvalDiskActions->UserPass = 0;\r
64 AvalDiskActions->DisableUser = 0;\r
65 AvalDiskActions->Unlock = 0;\r
66\r
67 //\r
68 // Revert is performed on locking sp, so only allow if locking sp is enabled\r
69 //\r
70 if (LockingFeature->LockingEnabled) {\r
71 AvalDiskActions->Revert = 1;\r
72 }\r
73\r
74 //\r
40d32e79 75 // Psid revert is available for any device with media encryption support or pyrite 2.0 type support.\r
112e584b 76 //\r
40d32e79 77 if (SupportedAttributes->PyriteSscV2 || SupportedAttributes->MediaEncryption) {\r
112e584b
SZ
78\r
79 //\r
40d32e79 80 // Only allow psid revert if media encryption is enabled or pyrite 2.0 type support..\r
112e584b
SZ
81 // Otherwise, someone who steals a disk can psid revert the disk and the user Data is still\r
82 // intact and accessible\r
83 //\r
84 AvalDiskActions->PsidRevert = 1;\r
85 AvalDiskActions->RevertKeepDataForced = 0;\r
86\r
87 //\r
88 // Secure erase is performed by generating a new encryption key\r
89 // this is only available if encryption is supported\r
90 //\r
91 AvalDiskActions->SecureErase = 1;\r
92 } else {\r
93 AvalDiskActions->PsidRevert = 0;\r
94 AvalDiskActions->SecureErase = 0;\r
95\r
96 //\r
97 // If no media encryption is supported, then a revert (using password) will not\r
98 // erase the Data (since you can't generate a new encryption key)\r
99 //\r
100 AvalDiskActions->RevertKeepDataForced = 1;\r
101 }\r
102\r
103 if (LockingFeature->Locked) {\r
104 AvalDiskActions->Unlock = 1;\r
105 } else {\r
106 AvalDiskActions->Unlock = 0;\r
107 }\r
108\r
109 //\r
110 // Only allow user to set password if an admin password exists\r
111 //\r
112 ExistingPassword = OpalUtilAdminPasswordExists(OwnerShip, LockingFeature);\r
113 AvalDiskActions->UserPass = ExistingPassword;\r
114\r
115 //\r
116 // This will still show up even if there isn't a user, which is fine\r
117 //\r
118 AvalDiskActions->DisableUser = ExistingPassword;\r
119\r
120 return TcgResultSuccess;\r
121}\r
122\r
123/**\r
124 Enable Opal Feature for the input device.\r
125\r
126 @param[in] Session The opal session for the opal device.\r
127 @param[in] Msid Msid\r
128 @param[in] MsidLength Msid Length\r
129 @param[in] Password Admin password\r
130 @param[in] PassLength Length of password in bytes\r
131\r
132**/\r
133TCG_RESULT\r
134EFIAPI\r
135OpalSupportEnableOpalFeature (\r
136 IN OPAL_SESSION *Session,\r
137 IN VOID *Msid,\r
138 IN UINT32 MsidLength,\r
139 IN VOID *Password,\r
140 IN UINT32 PassLength\r
141 )\r
142{\r
143 TCG_RESULT Ret;\r
144\r
145 NULL_CHECK(Session);\r
146 NULL_CHECK(Msid);\r
147 NULL_CHECK(Password);\r
148\r
149 Ret = OpalUtilSetAdminPasswordAsSid(\r
150 Session,\r
151 Msid,\r
152 MsidLength,\r
153 Password,\r
154 PassLength\r
155 );\r
156 if (Ret == TcgResultSuccess) {\r
157 //\r
158 // Enable global locking range\r
159 //\r
160 Ret = OpalUtilSetOpalLockingRange(\r
161 Session,\r
162 Password,\r
163 PassLength,\r
164 OPAL_LOCKING_SP_LOCKING_GLOBALRANGE,\r
165 0,\r
166 0,\r
167 TRUE,\r
168 TRUE,\r
169 FALSE,\r
170 FALSE\r
171 );\r
172 }\r
173\r
174 return Ret;\r
175}\r
176\r
177/**\r
178 Update password for the Opal disk.\r
179\r
180 @param[in, out] OpalDisk The disk to update password.\r
181 @param[in] Password The input password.\r
182 @param[in] PasswordLength The input password length.\r
183\r
184**/\r
185VOID\r
186OpalSupportUpdatePassword (\r
187 IN OUT OPAL_DISK *OpalDisk,\r
188 IN VOID *Password,\r
189 IN UINT32 PasswordLength\r
190 )\r
191{\r
192 CopyMem (OpalDisk->Password, Password, PasswordLength);\r
193 OpalDisk->PasswordLength = (UINT8) PasswordLength;\r
194}\r
195\r
196/**\r
197 Extract device info from the device path.\r
198\r
199 @param[in] DevicePath Device path info for the device.\r
200 @param[out] DevInfoLength Device information length needed.\r
201 @param[out] DevInfo Device information extracted.\r
202\r
112e584b 203**/\r
a3efbc29 204VOID\r
112e584b
SZ
205ExtractDeviceInfoFromDevicePath (\r
206 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
a3efbc29
HW
207 OUT UINT32 *DevInfoLength,\r
208 OUT OPAL_DEVICE_LOCKBOX_DATA *DevInfo OPTIONAL\r
112e584b
SZ
209 )\r
210{\r
211 EFI_DEVICE_PATH_PROTOCOL *TmpDevPath;\r
212 EFI_DEVICE_PATH_PROTOCOL *TmpDevPath2;\r
213 PCI_DEVICE_PATH *PciDevPath;\r
214 UINT8 DeviceType;\r
215 UINT8 BusNum;\r
216 OPAL_PCI_DEVICE *PciDevice;\r
112e584b
SZ
217\r
218 ASSERT (DevicePath != NULL);\r
219 ASSERT (DevInfoLength != NULL);\r
220\r
221 DeviceType = OPAL_DEVICE_TYPE_UNKNOWN;\r
222 *DevInfoLength = 0;\r
223\r
224 TmpDevPath = DevicePath;\r
225\r
226 //\r
227 // Get device type.\r
228 //\r
229 while (!IsDevicePathEnd (TmpDevPath)) {\r
a3efbc29
HW
230 if ((TmpDevPath->Type == MESSAGING_DEVICE_PATH) &&\r
231 (TmpDevPath->SubType == MSG_SATA_DP || TmpDevPath->SubType == MSG_NVME_NAMESPACE_DP)) {\r
112e584b 232 if (DevInfo != NULL) {\r
a3efbc29
HW
233 DevInfo->DevicePathLength = (UINT32) GetDevicePathSize (DevicePath);\r
234 CopyMem (DevInfo->DevicePath, DevicePath, DevInfo->DevicePathLength);\r
112e584b 235 }\r
a3efbc29
HW
236\r
237 DeviceType = (TmpDevPath->SubType == MSG_SATA_DP) ? OPAL_DEVICE_TYPE_ATA : OPAL_DEVICE_TYPE_NVME;\r
238 *DevInfoLength = sizeof (OPAL_DEVICE_LOCKBOX_DATA) + (UINT32) GetDevicePathSize (DevicePath);\r
112e584b
SZ
239 break;\r
240 }\r
241 TmpDevPath = NextDevicePathNode (TmpDevPath);\r
242 }\r
243\r
244 //\r
245 // Get device info.\r
246 //\r
247 BusNum = 0;\r
248 TmpDevPath = DevicePath;\r
249 TmpDevPath2 = NextDevicePathNode (DevicePath);\r
250 while (!IsDevicePathEnd (TmpDevPath2)) {\r
251 if (TmpDevPath->Type == HARDWARE_DEVICE_PATH && TmpDevPath->SubType == HW_PCI_DP) {\r
252 PciDevPath = (PCI_DEVICE_PATH *) TmpDevPath;\r
a3efbc29
HW
253 if ((TmpDevPath2->Type == MESSAGING_DEVICE_PATH) &&\r
254 (TmpDevPath2->SubType == MSG_SATA_DP || TmpDevPath2->SubType == MSG_NVME_NAMESPACE_DP)) {\r
112e584b
SZ
255 if (DevInfo != NULL) {\r
256 PciDevice = &DevInfo->Device;\r
257 PciDevice->Segment = 0;\r
258 PciDevice->Bus = BusNum;\r
259 PciDevice->Device = PciDevPath->Device;\r
260 PciDevice->Function = PciDevPath->Function;\r
261 }\r
262 } else {\r
112e584b
SZ
263 if (TmpDevPath2->Type == HARDWARE_DEVICE_PATH && TmpDevPath2->SubType == HW_PCI_DP) {\r
264 BusNum = PciRead8 (PCI_LIB_ADDRESS (BusNum, PciDevPath->Device, PciDevPath->Function, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET));\r
265 }\r
266 }\r
267 }\r
268\r
269 TmpDevPath = NextDevicePathNode (TmpDevPath);\r
270 TmpDevPath2 = NextDevicePathNode (TmpDevPath2);\r
271 }\r
272\r
273 ASSERT (DeviceType != OPAL_DEVICE_TYPE_UNKNOWN);\r
a3efbc29 274 return;\r
112e584b
SZ
275}\r
276\r
277/**\r
a3efbc29 278 Build OPAL device info and save them to LockBox.\r
112e584b
SZ
279\r
280 **/\r
281VOID\r
a3efbc29
HW
282BuildOpalDeviceInfo (\r
283 VOID\r
112e584b
SZ
284 )\r
285{\r
a3efbc29
HW
286 EFI_STATUS Status;\r
287 OPAL_DEVICE_LOCKBOX_DATA *DevInfo;\r
288 OPAL_DEVICE_LOCKBOX_DATA *TempDevInfo;\r
289 UINTN TotalDevInfoLength;\r
290 UINT32 DevInfoLength;\r
291 OPAL_DRIVER_DEVICE *TmpDev;\r
292 UINT8 DummyData;\r
293 BOOLEAN S3InitDevicesExist;\r
294 UINTN S3InitDevicesLength;\r
295 EFI_DEVICE_PATH_PROTOCOL *S3InitDevices;\r
296 EFI_DEVICE_PATH_PROTOCOL *S3InitDevicesBak;\r
112e584b
SZ
297\r
298 //\r
a3efbc29 299 // Build OPAL device info and save them to LockBox.\r
112e584b 300 //\r
a3efbc29 301 TotalDevInfoLength = 0;\r
112e584b
SZ
302 TmpDev = mOpalDriver.DeviceList;\r
303 while (TmpDev != NULL) {\r
a3efbc29
HW
304 ExtractDeviceInfoFromDevicePath (\r
305 TmpDev->OpalDisk.OpalDevicePath,\r
306 &DevInfoLength,\r
307 NULL\r
308 );\r
309 TotalDevInfoLength += DevInfoLength;\r
112e584b
SZ
310 TmpDev = TmpDev->Next;\r
311 }\r
312\r
a3efbc29 313 if (TotalDevInfoLength == 0) {\r
112e584b
SZ
314 return;\r
315 }\r
316\r
a3efbc29
HW
317 S3InitDevicesLength = sizeof (DummyData);\r
318 Status = RestoreLockBox (\r
319 &gS3StorageDeviceInitListGuid,\r
320 &DummyData,\r
321 &S3InitDevicesLength\r
112e584b 322 );\r
a3efbc29
HW
323 ASSERT ((Status == EFI_NOT_FOUND) || (Status == EFI_BUFFER_TOO_SMALL));\r
324 if (Status == EFI_NOT_FOUND) {\r
325 S3InitDevices = NULL;\r
326 S3InitDevicesExist = FALSE;\r
327 } else if (Status == EFI_BUFFER_TOO_SMALL) {\r
328 S3InitDevices = AllocatePool (S3InitDevicesLength);\r
329 ASSERT (S3InitDevices != NULL);\r
330 if (S3InitDevices == NULL) {\r
331 return;\r
112e584b
SZ
332 }\r
333\r
a3efbc29
HW
334 Status = RestoreLockBox (\r
335 &gS3StorageDeviceInitListGuid,\r
336 S3InitDevices,\r
337 &S3InitDevicesLength\r
338 );\r
339 ASSERT_EFI_ERROR (Status);\r
340 S3InitDevicesExist = TRUE;\r
341 } else {\r
112e584b
SZ
342 return;\r
343 }\r
344\r
a3efbc29
HW
345 DevInfo = AllocateZeroPool (TotalDevInfoLength);\r
346 ASSERT (DevInfo != NULL);\r
347 if (DevInfo == NULL) {\r
d72d8561
ED
348 return;\r
349 }\r
112e584b 350\r
a3efbc29
HW
351 TempDevInfo = DevInfo;\r
352 TmpDev = mOpalDriver.DeviceList;\r
112e584b 353 while (TmpDev != NULL) {\r
a3efbc29
HW
354 ExtractDeviceInfoFromDevicePath (\r
355 TmpDev->OpalDisk.OpalDevicePath,\r
356 &DevInfoLength,\r
357 TempDevInfo\r
358 );\r
359 TempDevInfo->Length = DevInfoLength;\r
360 TempDevInfo->OpalBaseComId = TmpDev->OpalDisk.OpalBaseComId;\r
361 CopyMem (\r
362 TempDevInfo->Password,\r
363 TmpDev->OpalDisk.Password,\r
364 TmpDev->OpalDisk.PasswordLength\r
365 );\r
366 TempDevInfo->PasswordLength = TmpDev->OpalDisk.PasswordLength;\r
367\r
368 S3InitDevicesBak = S3InitDevices;\r
369 S3InitDevices = AppendDevicePathInstance (\r
370 S3InitDevicesBak,\r
371 TmpDev->OpalDisk.OpalDevicePath\r
372 );\r
373 if (S3InitDevicesBak != NULL) {\r
374 FreePool (S3InitDevicesBak);\r
375 }\r
376 ASSERT (S3InitDevices != NULL);\r
377 if (S3InitDevices == NULL) {\r
378 return;\r
112e584b
SZ
379 }\r
380\r
a3efbc29 381 TempDevInfo = (OPAL_DEVICE_LOCKBOX_DATA *) ((UINTN) TempDevInfo + DevInfoLength);\r
112e584b
SZ
382 TmpDev = TmpDev->Next;\r
383 }\r
384\r
385 Status = SaveLockBox (\r
a3efbc29
HW
386 &mOpalDeviceLockBoxGuid,\r
387 DevInfo,\r
388 TotalDevInfoLength\r
112e584b
SZ
389 );\r
390 ASSERT_EFI_ERROR (Status);\r
391\r
392 Status = SetLockBoxAttributes (\r
a3efbc29 393 &mOpalDeviceLockBoxGuid,\r
112e584b
SZ
394 LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY\r
395 );\r
396 ASSERT_EFI_ERROR (Status);\r
397\r
a3efbc29
HW
398 S3InitDevicesLength = GetDevicePathSize (S3InitDevices);\r
399 if (S3InitDevicesExist) {\r
400 Status = UpdateLockBox (\r
401 &gS3StorageDeviceInitListGuid,\r
402 0,\r
403 S3InitDevices,\r
404 S3InitDevicesLength\r
405 );\r
406 ASSERT_EFI_ERROR (Status);\r
407 } else {\r
408 Status = SaveLockBox (\r
409 &gS3StorageDeviceInitListGuid,\r
410 S3InitDevices,\r
411 S3InitDevicesLength\r
412 );\r
413 ASSERT_EFI_ERROR (Status);\r
414\r
415 Status = SetLockBoxAttributes (\r
416 &gS3StorageDeviceInitListGuid,\r
417 LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY\r
418 );\r
419 ASSERT_EFI_ERROR (Status);\r
420 }\r
421\r
422 ZeroMem (DevInfo, TotalDevInfoLength);\r
423 FreePool (DevInfo);\r
424 FreePool (S3InitDevices);\r
112e584b
SZ
425}\r
426\r
539a6c93
ED
427/**\r
428\r
429 Send BlockSid command if needed.\r
430\r
431**/\r
432VOID\r
433SendBlockSidCommand (\r
434 VOID\r
435 )\r
436{\r
437 OPAL_DRIVER_DEVICE *Itr;\r
438 TCG_RESULT Result;\r
439 OPAL_SESSION Session;\r
440 UINT32 PpStorageFlag;\r
441\r
442 PpStorageFlag = Tcg2PhysicalPresenceLibGetManagementFlags ();\r
443 if ((PpStorageFlag & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_ENABLE_BLOCK_SID) != 0) {\r
444 //\r
445 // Send BlockSID command to each Opal disk\r
446 //\r
447 Itr = mOpalDriver.DeviceList;\r
448 while (Itr != NULL) {\r
449 if (Itr->OpalDisk.SupportedAttributes.BlockSid) {\r
450 ZeroMem(&Session, sizeof(Session));\r
451 Session.Sscp = Itr->OpalDisk.Sscp;\r
452 Session.MediaId = Itr->OpalDisk.MediaId;\r
453 Session.OpalBaseComId = Itr->OpalDisk.OpalBaseComId;\r
454\r
455 DEBUG ((DEBUG_INFO, "OpalPassword: EndOfDxe point, send BlockSid command to device!\n"));\r
456 Result = OpalBlockSid (&Session, TRUE); // HardwareReset must always be TRUE\r
457 if (Result != TcgResultSuccess) {\r
458 DEBUG ((DEBUG_ERROR, "OpalBlockSid fail\n"));\r
459 break;\r
460 }\r
46e69608
ED
461\r
462 //\r
463 // Record BlockSID command has been sent.\r
464 //\r
465 Itr->OpalDisk.SentBlockSID = TRUE;\r
539a6c93
ED
466 }\r
467\r
468 Itr = Itr->Next;\r
469 }\r
470 }\r
471}\r
472\r
112e584b
SZ
473/**\r
474 Notification function of EFI_END_OF_DXE_EVENT_GROUP_GUID event group.\r
475\r
476 This is a notification function registered on EFI_END_OF_DXE_EVENT_GROUP_GUID event group.\r
477\r
478 @param Event Event whose notification function is being invoked.\r
479 @param Context Pointer to the notification function's context.\r
480\r
481**/\r
482VOID\r
483EFIAPI\r
484OpalEndOfDxeEventNotify (\r
485 EFI_EVENT Event,\r
486 VOID *Context\r
487 )\r
488{\r
112e584b
SZ
489 OPAL_DRIVER_DEVICE *TmpDev;\r
490\r
491 DEBUG ((DEBUG_INFO, "%a() - enter\n", __FUNCTION__));\r
492\r
493 mOpalEndOfDxe = TRUE;\r
494\r
495 if (mOpalRequestVariable != NULL) {\r
496 //\r
497 // Free the OPAL request variable buffer here\r
498 // as the OPAL requests should have been processed.\r
499 //\r
500 FreePool (mOpalRequestVariable);\r
501 mOpalRequestVariable = NULL;\r
502 mOpalRequestVariableSize = 0;\r
503 }\r
504\r
fbe1328a
SZ
505 //\r
506 // If no any device, return directly.\r
507 //\r
508 if (mOpalDriver.DeviceList == NULL) {\r
509 gBS->CloseEvent (Event);\r
510 return;\r
511 }\r
512\r
a3efbc29 513 BuildOpalDeviceInfo ();\r
112e584b
SZ
514\r
515 //\r
516 // Zero passsword.\r
517 //\r
518 TmpDev = mOpalDriver.DeviceList;\r
519 while (TmpDev != NULL) {\r
520 ZeroMem (TmpDev->OpalDisk.Password, TmpDev->OpalDisk.PasswordLength);\r
521 TmpDev = TmpDev->Next;\r
522 }\r
523\r
539a6c93
ED
524 //\r
525 // Send BlockSid command if needed.\r
526 //\r
527 SendBlockSidCommand ();\r
528\r
112e584b
SZ
529 DEBUG ((DEBUG_INFO, "%a() - exit\n", __FUNCTION__));\r
530\r
531 gBS->CloseEvent (Event);\r
532}\r
533\r
534/**\r
535 Get Psid input from the popup window.\r
536\r
537 @param[in] Dev The device which need Psid to process Psid Revert\r
538 OPAL request.\r
539 @param[in] PopUpString Pop up string.\r
40d32e79 540 @param[in] PopUpString2 Pop up string in line 2.\r
f5245a1d 541 @param[in] PopUpString3 Pop up string in line 3.\r
40d32e79 542\r
112e584b
SZ
543 @param[out] PressEsc Whether user escape function through Press ESC.\r
544\r
aa085730 545 @retval Psid string if success. NULL if failed.\r
112e584b
SZ
546\r
547**/\r
548CHAR8 *\r
549OpalDriverPopUpPsidInput (\r
550 IN OPAL_DRIVER_DEVICE *Dev,\r
551 IN CHAR16 *PopUpString,\r
40d32e79 552 IN CHAR16 *PopUpString2,\r
f5245a1d 553 IN CHAR16 *PopUpString3,\r
112e584b
SZ
554 OUT BOOLEAN *PressEsc\r
555 )\r
556{\r
557 EFI_INPUT_KEY InputKey;\r
558 UINTN InputLength;\r
559 CHAR16 Mask[PSID_CHARACTER_LENGTH + 1];\r
560 CHAR16 Unicode[PSID_CHARACTER_LENGTH + 1];\r
561 CHAR8 *Ascii;\r
562\r
563 ZeroMem(Unicode, sizeof(Unicode));\r
564 ZeroMem(Mask, sizeof(Mask));\r
565\r
566 *PressEsc = FALSE;\r
567\r
568 gST->ConOut->ClearScreen(gST->ConOut);\r
569\r
570 InputLength = 0;\r
571 while (TRUE) {\r
572 Mask[InputLength] = L'_';\r
63c76537
ED
573 if (PopUpString2 == NULL) {\r
574 CreatePopUp (\r
575 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
576 &InputKey,\r
577 PopUpString,\r
578 L"---------------------",\r
579 Mask,\r
580 NULL\r
581 );\r
582 } else {\r
f5245a1d
CM
583 if (PopUpString3 == NULL) {\r
584 CreatePopUp (\r
585 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
586 &InputKey,\r
587 PopUpString,\r
588 PopUpString2,\r
589 L"---------------------",\r
590 Mask,\r
591 NULL\r
592 );\r
593 } else {\r
594 CreatePopUp (\r
595 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
596 &InputKey,\r
597 PopUpString,\r
598 PopUpString2,\r
599 PopUpString3,\r
600 L"---------------------",\r
601 Mask,\r
602 NULL\r
603 );\r
604 }\r
63c76537 605 }\r
112e584b
SZ
606\r
607 //\r
608 // Check key.\r
609 //\r
610 if (InputKey.ScanCode == SCAN_NULL) {\r
611 //\r
612 // password finished\r
613 //\r
614 if (InputKey.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
615 //\r
616 // Add the null terminator.\r
617 //\r
618 Unicode[InputLength] = 0;\r
619 Mask[InputLength] = 0;\r
620 break;\r
621 } else if ((InputKey.UnicodeChar == CHAR_NULL) ||\r
622 (InputKey.UnicodeChar == CHAR_TAB) ||\r
623 (InputKey.UnicodeChar == CHAR_LINEFEED)\r
624 ) {\r
625 continue;\r
626 } else {\r
627 //\r
628 // delete last key entered\r
629 //\r
630 if (InputKey.UnicodeChar == CHAR_BACKSPACE) {\r
631 if (InputLength > 0) {\r
632 Unicode[InputLength] = 0;\r
633 Mask[InputLength] = 0;\r
634 InputLength--;\r
635 }\r
636 } else {\r
637 //\r
638 // add Next key entry\r
639 //\r
640 Unicode[InputLength] = InputKey.UnicodeChar;\r
641 Mask[InputLength] = InputKey.UnicodeChar;\r
642 InputLength++;\r
643 if (InputLength == PSID_CHARACTER_LENGTH) {\r
644 //\r
645 // Add the null terminator.\r
646 //\r
647 Unicode[InputLength] = 0;\r
648 Mask[InputLength] = 0;\r
649 break;\r
650 }\r
651 }\r
652 }\r
653 }\r
654\r
655 //\r
656 // exit on ESC\r
657 //\r
658 if (InputKey.ScanCode == SCAN_ESC) {\r
659 *PressEsc = TRUE;\r
660 break;\r
661 }\r
662 }\r
663\r
664 gST->ConOut->ClearScreen(gST->ConOut);\r
665\r
666 if (InputLength == 0 || InputKey.ScanCode == SCAN_ESC) {\r
667 ZeroMem (Unicode, sizeof (Unicode));\r
668 ZeroMem (Mask, sizeof (Mask));\r
669 return NULL;\r
670 }\r
671\r
672 Ascii = AllocateZeroPool (PSID_CHARACTER_LENGTH + 1);\r
673 if (Ascii == NULL) {\r
674 ZeroMem (Unicode, sizeof (Unicode));\r
675 ZeroMem (Mask, sizeof (Mask));\r
676 return NULL;\r
677 }\r
678\r
679 UnicodeStrToAsciiStrS (Unicode, Ascii, PSID_CHARACTER_LENGTH + 1);\r
680 ZeroMem (Unicode, sizeof (Unicode));\r
681 ZeroMem (Mask, sizeof (Mask));\r
682\r
683 return Ascii;\r
684}\r
685\r
686\r
687/**\r
688 Get password input from the popup window.\r
689\r
690 @param[in] Dev The device which need password to unlock or\r
691 process OPAL request.\r
692 @param[in] PopUpString1 Pop up string 1.\r
693 @param[in] PopUpString2 Pop up string 2.\r
f5245a1d 694 @param[in] PopUpString3 Pop up string 3.\r
112e584b
SZ
695 @param[out] PressEsc Whether user escape function through Press ESC.\r
696\r
697 @retval Password string if success. NULL if failed.\r
698\r
699**/\r
700CHAR8 *\r
701OpalDriverPopUpPasswordInput (\r
702 IN OPAL_DRIVER_DEVICE *Dev,\r
703 IN CHAR16 *PopUpString1,\r
704 IN CHAR16 *PopUpString2,\r
f5245a1d 705 IN CHAR16 *PopUpString3,\r
112e584b
SZ
706 OUT BOOLEAN *PressEsc\r
707 )\r
708{\r
709 EFI_INPUT_KEY InputKey;\r
710 UINTN InputLength;\r
711 CHAR16 Mask[OPAL_MAX_PASSWORD_SIZE + 1];\r
712 CHAR16 Unicode[OPAL_MAX_PASSWORD_SIZE + 1];\r
713 CHAR8 *Ascii;\r
714\r
715 ZeroMem(Unicode, sizeof(Unicode));\r
716 ZeroMem(Mask, sizeof(Mask));\r
717\r
718 *PressEsc = FALSE;\r
719\r
720 gST->ConOut->ClearScreen(gST->ConOut);\r
721\r
722 InputLength = 0;\r
723 while (TRUE) {\r
724 Mask[InputLength] = L'_';\r
725 if (PopUpString2 == NULL) {\r
726 CreatePopUp (\r
727 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
728 &InputKey,\r
729 PopUpString1,\r
730 L"---------------------",\r
731 Mask,\r
732 NULL\r
733 );\r
734 } else {\r
f5245a1d
CM
735 if (PopUpString3 == NULL) {\r
736 CreatePopUp (\r
737 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
738 &InputKey,\r
739 PopUpString1,\r
740 PopUpString2,\r
741 L"---------------------",\r
742 Mask,\r
743 NULL\r
744 );\r
745 } else {\r
746 CreatePopUp (\r
747 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
748 &InputKey,\r
749 PopUpString1,\r
750 PopUpString2,\r
751 PopUpString3,\r
752 L"---------------------",\r
753 Mask,\r
754 NULL\r
755 );\r
756 }\r
112e584b
SZ
757 }\r
758\r
759 //\r
760 // Check key.\r
761 //\r
762 if (InputKey.ScanCode == SCAN_NULL) {\r
763 //\r
764 // password finished\r
765 //\r
766 if (InputKey.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
767 //\r
768 // Add the null terminator.\r
769 //\r
770 Unicode[InputLength] = 0;\r
771 Mask[InputLength] = 0;\r
772 break;\r
773 } else if ((InputKey.UnicodeChar == CHAR_NULL) ||\r
774 (InputKey.UnicodeChar == CHAR_TAB) ||\r
775 (InputKey.UnicodeChar == CHAR_LINEFEED)\r
776 ) {\r
777 continue;\r
778 } else {\r
779 //\r
780 // delete last key entered\r
781 //\r
782 if (InputKey.UnicodeChar == CHAR_BACKSPACE) {\r
783 if (InputLength > 0) {\r
784 Unicode[InputLength] = 0;\r
785 Mask[InputLength] = 0;\r
786 InputLength--;\r
787 }\r
788 } else {\r
789 //\r
790 // add Next key entry\r
791 //\r
792 Unicode[InputLength] = InputKey.UnicodeChar;\r
793 Mask[InputLength] = L'*';\r
794 InputLength++;\r
795 if (InputLength == OPAL_MAX_PASSWORD_SIZE) {\r
796 //\r
797 // Add the null terminator.\r
798 //\r
799 Unicode[InputLength] = 0;\r
800 Mask[InputLength] = 0;\r
801 break;\r
802 }\r
803 }\r
804 }\r
805 }\r
806\r
807 //\r
808 // exit on ESC\r
809 //\r
810 if (InputKey.ScanCode == SCAN_ESC) {\r
811 *PressEsc = TRUE;\r
812 break;\r
813 }\r
814 }\r
815\r
816 gST->ConOut->ClearScreen(gST->ConOut);\r
817\r
818 if (InputLength == 0 || InputKey.ScanCode == SCAN_ESC) {\r
819 ZeroMem (Unicode, sizeof (Unicode));\r
820 return NULL;\r
821 }\r
822\r
823 Ascii = AllocateZeroPool (OPAL_MAX_PASSWORD_SIZE + 1);\r
824 if (Ascii == NULL) {\r
825 ZeroMem (Unicode, sizeof (Unicode));\r
826 return NULL;\r
827 }\r
828\r
829 UnicodeStrToAsciiStrS (Unicode, Ascii, OPAL_MAX_PASSWORD_SIZE + 1);\r
830 ZeroMem (Unicode, sizeof (Unicode));\r
831\r
832 return Ascii;\r
833}\r
834\r
835/**\r
aa085730 836 Get pop up string.\r
112e584b 837\r
aa085730 838 @param[in] Dev The OPAL device.\r
112e584b
SZ
839 @param[in] RequestString Request string.\r
840\r
aa085730
SZ
841 @return Pop up string.\r
842\r
112e584b
SZ
843**/\r
844CHAR16 *\r
845OpalGetPopUpString (\r
846 IN OPAL_DRIVER_DEVICE *Dev,\r
847 IN CHAR16 *RequestString\r
848 )\r
849{\r
112e584b 850 if (Dev->Name16 == NULL) {\r
aa085730 851 UnicodeSPrint (mPopUpString, sizeof (mPopUpString), L"%s Disk", RequestString);\r
112e584b 852 } else {\r
aa085730 853 UnicodeSPrint (mPopUpString, sizeof (mPopUpString), L"%s %s", RequestString, Dev->Name16);\r
112e584b
SZ
854 }\r
855\r
856 return mPopUpString;\r
857}\r
858\r
859/**\r
860 Check if disk is locked, show popup window and ask for password if it is.\r
861\r
862 @param[in] Dev The device which need to be unlocked.\r
863 @param[in] RequestString Request string.\r
864\r
865**/\r
866VOID\r
867OpalDriverRequestPassword (\r
868 IN OPAL_DRIVER_DEVICE *Dev,\r
869 IN CHAR16 *RequestString\r
870 )\r
871{\r
872 UINT8 Count;\r
873 BOOLEAN IsEnabled;\r
874 BOOLEAN IsLocked;\r
875 CHAR8 *Password;\r
876 UINT32 PasswordLen;\r
877 OPAL_SESSION Session;\r
878 BOOLEAN PressEsc;\r
879 EFI_INPUT_KEY Key;\r
880 TCG_RESULT Ret;\r
881 CHAR16 *PopUpString;\r
882\r
883 if (Dev == NULL) {\r
884 return;\r
885 }\r
886\r
887 DEBUG ((DEBUG_INFO, "%a()\n", __FUNCTION__));\r
888\r
889 PopUpString = OpalGetPopUpString (Dev, RequestString);\r
890\r
891 Count = 0;\r
892\r
893 IsEnabled = OpalFeatureEnabled (&Dev->OpalDisk.SupportedAttributes, &Dev->OpalDisk.LockingFeature);\r
894 if (IsEnabled) {\r
895 ZeroMem(&Session, sizeof(Session));\r
896 Session.Sscp = Dev->OpalDisk.Sscp;\r
897 Session.MediaId = Dev->OpalDisk.MediaId;\r
898 Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;\r
899\r
900 IsLocked = OpalDeviceLocked (&Dev->OpalDisk.SupportedAttributes, &Dev->OpalDisk.LockingFeature);\r
901\r
8a9301cd
CM
902 if (IsLocked && PcdGetBool (PcdSkipOpalDxeUnlock)) {\r
903 return;\r
904 }\r
905\r
112e584b 906 while (Count < MAX_PASSWORD_TRY_COUNT) {\r
f5245a1d 907 Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, NULL, NULL, &PressEsc);\r
112e584b
SZ
908 if (PressEsc) {\r
909 if (IsLocked) {\r
910 //\r
911 // Current device in the lock status and\r
912 // User not input password and press ESC,\r
913 // keep device in lock status and continue boot.\r
914 //\r
915 do {\r
916 CreatePopUp (\r
917 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
918 &Key,\r
919 L"Press ENTER to skip the request and continue boot,",\r
920 L"Press ESC to input password again",\r
921 NULL\r
922 );\r
923 } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));\r
924\r
925 if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
926 gST->ConOut->ClearScreen(gST->ConOut);\r
927 //\r
928 // Keep lock and continue boot.\r
929 //\r
930 return;\r
931 } else {\r
932 //\r
933 // Let user input password again.\r
934 //\r
935 continue;\r
936 }\r
937 } else {\r
938 //\r
939 // Current device in the unlock status and\r
940 // User not input password and press ESC,\r
941 // Shutdown the device.\r
942 //\r
943 do {\r
944 CreatePopUp (\r
945 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
946 &Key,\r
947 L"Press ENTER to shutdown, Press ESC to input password again",\r
948 NULL\r
949 );\r
950 } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));\r
951\r
952 if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
953 gRT->ResetSystem (EfiResetShutdown, EFI_SUCCESS, 0, NULL);\r
954 } else {\r
955 //\r
956 // Let user input password again.\r
957 //\r
958 continue;\r
959 }\r
960 }\r
961 }\r
962\r
963 if (Password == NULL) {\r
964 Count ++;\r
965 continue;\r
966 }\r
967 PasswordLen = (UINT32) AsciiStrLen(Password);\r
968\r
969 if (IsLocked) {\r
970 Ret = OpalUtilUpdateGlobalLockingRange(&Session, Password, PasswordLen, FALSE, FALSE);\r
971 } else {\r
972 Ret = OpalUtilUpdateGlobalLockingRange(&Session, Password, PasswordLen, TRUE, TRUE);\r
973 if (Ret == TcgResultSuccess) {\r
974 Ret = OpalUtilUpdateGlobalLockingRange(&Session, Password, PasswordLen, FALSE, FALSE);\r
975 }\r
976 }\r
977\r
978 if (Ret == TcgResultSuccess) {\r
979 OpalSupportUpdatePassword (&Dev->OpalDisk, Password, PasswordLen);\r
980 DEBUG ((DEBUG_INFO, "%s Success\n", RequestString));\r
981 } else {\r
982 DEBUG ((DEBUG_INFO, "%s Failure\n", RequestString));\r
983 }\r
984\r
985 if (Password != NULL) {\r
986 ZeroMem (Password, PasswordLen);\r
987 FreePool (Password);\r
988 }\r
989\r
990 if (Ret == TcgResultSuccess) {\r
991 break;\r
992 }\r
993\r
e4e314b1
ED
994 //\r
995 // Check whether opal device's Tries value has reach the TryLimit value, if yes, force a shutdown\r
996 // before accept new password.\r
997 //\r
998 if (Ret == TcgResultFailureInvalidType) {\r
999 Count = MAX_PASSWORD_TRY_COUNT;\r
1000 break;\r
1001 }\r
1002\r
112e584b
SZ
1003 Count++;\r
1004\r
1005 do {\r
1006 CreatePopUp (\r
1007 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1008 &Key,\r
1009 L"Invalid password.",\r
1010 L"Press ENTER to retry",\r
1011 NULL\r
1012 );\r
1013 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
1014 }\r
1015\r
1016 if (Count >= MAX_PASSWORD_TRY_COUNT) {\r
1017 do {\r
1018 CreatePopUp (\r
1019 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1020 &Key,\r
1021 L"Opal password retry count exceeds the limit. Must shutdown!",\r
1022 L"Press ENTER to shutdown",\r
1023 NULL\r
1024 );\r
1025 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
1026\r
1027 gRT->ResetSystem (EfiResetShutdown, EFI_SUCCESS, 0, NULL);\r
1028 }\r
1029 }\r
1030}\r
1031\r
1032/**\r
1033 Process Enable Feature OPAL request.\r
1034\r
1035 @param[in] Dev The device which has Enable Feature OPAL request.\r
1036 @param[in] RequestString Request string.\r
1037\r
1038**/\r
1039VOID\r
1040ProcessOpalRequestEnableFeature (\r
1041 IN OPAL_DRIVER_DEVICE *Dev,\r
1042 IN CHAR16 *RequestString\r
1043 )\r
1044{\r
1045 UINT8 Count;\r
1046 CHAR8 *Password;\r
1047 UINT32 PasswordLen;\r
1048 CHAR8 *PasswordConfirm;\r
1049 UINT32 PasswordLenConfirm;\r
1050 OPAL_SESSION Session;\r
1051 BOOLEAN PressEsc;\r
1052 EFI_INPUT_KEY Key;\r
1053 TCG_RESULT Ret;\r
1054 CHAR16 *PopUpString;\r
1055\r
1056 if (Dev == NULL) {\r
1057 return;\r
1058 }\r
1059\r
1060 DEBUG ((DEBUG_INFO, "%a()\n", __FUNCTION__));\r
1061\r
1062 PopUpString = OpalGetPopUpString (Dev, RequestString);\r
1063\r
1064 Count = 0;\r
1065\r
1066 ZeroMem(&Session, sizeof(Session));\r
1067 Session.Sscp = Dev->OpalDisk.Sscp;\r
1068 Session.MediaId = Dev->OpalDisk.MediaId;\r
1069 Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;\r
1070\r
1071 while (Count < MAX_PASSWORD_TRY_COUNT) {\r
f5245a1d 1072 Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please type in your new password", NULL, &PressEsc);\r
112e584b
SZ
1073 if (PressEsc) {\r
1074 do {\r
1075 CreatePopUp (\r
1076 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1077 &Key,\r
1078 L"Press ENTER to skip the request and continue boot,",\r
1079 L"Press ESC to input password again",\r
1080 NULL\r
1081 );\r
1082 } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));\r
1083\r
1084 if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
1085 gST->ConOut->ClearScreen(gST->ConOut);\r
1086 return;\r
1087 } else {\r
1088 //\r
1089 // Let user input password again.\r
1090 //\r
1091 continue;\r
1092 }\r
1093 }\r
1094\r
1095 if (Password == NULL) {\r
1096 Count ++;\r
1097 continue;\r
1098 }\r
1099 PasswordLen = (UINT32) AsciiStrLen(Password);\r
1100\r
f5245a1d 1101 PasswordConfirm = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please confirm your new password", NULL, &PressEsc);\r
112e584b
SZ
1102 if (PasswordConfirm == NULL) {\r
1103 ZeroMem (Password, PasswordLen);\r
1104 FreePool (Password);\r
1105 Count ++;\r
1106 continue;\r
1107 }\r
1108 PasswordLenConfirm = (UINT32) AsciiStrLen(PasswordConfirm);\r
1109 if ((PasswordLen != PasswordLenConfirm) ||\r
1110 (CompareMem (Password, PasswordConfirm, PasswordLen) != 0)) {\r
1111 ZeroMem (Password, PasswordLen);\r
1112 FreePool (Password);\r
1113 ZeroMem (PasswordConfirm, PasswordLenConfirm);\r
1114 FreePool (PasswordConfirm);\r
1115 do {\r
1116 CreatePopUp (\r
1117 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1118 &Key,\r
1119 L"Passwords are not the same.",\r
1120 L"Press ENTER to retry",\r
1121 NULL\r
1122 );\r
1123 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
1124 Count ++;\r
1125 continue;\r
1126 }\r
1127\r
1128 if (PasswordConfirm != NULL) {\r
1129 ZeroMem (PasswordConfirm, PasswordLenConfirm);\r
1130 FreePool (PasswordConfirm);\r
1131 }\r
1132\r
1133 Ret = OpalSupportEnableOpalFeature (&Session, Dev->OpalDisk.Msid, Dev->OpalDisk.MsidLength, Password, PasswordLen);\r
1134 if (Ret == TcgResultSuccess) {\r
1135 OpalSupportUpdatePassword (&Dev->OpalDisk, Password, PasswordLen);\r
1136 DEBUG ((DEBUG_INFO, "%s Success\n", RequestString));\r
1137 } else {\r
1138 DEBUG ((DEBUG_INFO, "%s Failure\n", RequestString));\r
1139 }\r
1140\r
1141 if (Password != NULL) {\r
1142 ZeroMem (Password, PasswordLen);\r
1143 FreePool (Password);\r
1144 }\r
1145\r
1146 if (Ret == TcgResultSuccess) {\r
1147 break;\r
1148 }\r
1149\r
1150 Count++;\r
1151\r
1152 do {\r
1153 CreatePopUp (\r
1154 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1155 &Key,\r
1156 L"Request failed.",\r
1157 L"Press ENTER to retry",\r
1158 NULL\r
1159 );\r
1160 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
1161 }\r
1162\r
1163 if (Count >= MAX_PASSWORD_TRY_COUNT) {\r
1164 do {\r
1165 CreatePopUp (\r
1166 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1167 &Key,\r
1168 L"Opal password retry count exceeds the limit.",\r
1169 L"Press ENTER to skip the request and continue boot",\r
1170 NULL\r
1171 );\r
1172 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
1173 gST->ConOut->ClearScreen(gST->ConOut);\r
1174 }\r
1175}\r
1176\r
1177/**\r
1178 Process Disable User OPAL request.\r
1179\r
1180 @param[in] Dev The device which has Disable User OPAL request.\r
1181 @param[in] RequestString Request string.\r
1182\r
1183**/\r
1184VOID\r
1185ProcessOpalRequestDisableUser (\r
1186 IN OPAL_DRIVER_DEVICE *Dev,\r
1187 IN CHAR16 *RequestString\r
1188 )\r
1189{\r
1190 UINT8 Count;\r
1191 CHAR8 *Password;\r
1192 UINT32 PasswordLen;\r
1193 OPAL_SESSION Session;\r
1194 BOOLEAN PressEsc;\r
1195 EFI_INPUT_KEY Key;\r
1196 TCG_RESULT Ret;\r
1197 BOOLEAN PasswordFailed;\r
1198 CHAR16 *PopUpString;\r
1199\r
1200 if (Dev == NULL) {\r
1201 return;\r
1202 }\r
1203\r
1204 DEBUG ((DEBUG_INFO, "%a()\n", __FUNCTION__));\r
1205\r
1206 PopUpString = OpalGetPopUpString (Dev, RequestString);\r
1207\r
1208 Count = 0;\r
1209\r
1210 ZeroMem(&Session, sizeof(Session));\r
1211 Session.Sscp = Dev->OpalDisk.Sscp;\r
1212 Session.MediaId = Dev->OpalDisk.MediaId;\r
1213 Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;\r
1214\r
1215 while (Count < MAX_PASSWORD_TRY_COUNT) {\r
f5245a1d 1216 Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, NULL, NULL, &PressEsc);\r
112e584b
SZ
1217 if (PressEsc) {\r
1218 do {\r
1219 CreatePopUp (\r
1220 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1221 &Key,\r
1222 L"Press ENTER to skip the request and continue boot,",\r
1223 L"Press ESC to input password again",\r
1224 NULL\r
1225 );\r
1226 } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));\r
1227\r
1228 if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
1229 gST->ConOut->ClearScreen(gST->ConOut);\r
1230 return;\r
1231 } else {\r
1232 //\r
1233 // Let user input password again.\r
1234 //\r
1235 continue;\r
1236 }\r
1237 }\r
1238\r
1239 if (Password == NULL) {\r
1240 Count ++;\r
1241 continue;\r
1242 }\r
1243 PasswordLen = (UINT32) AsciiStrLen(Password);\r
1244\r
1245 Ret = OpalUtilDisableUser(&Session, Password, PasswordLen, &PasswordFailed);\r
1246 if (Ret == TcgResultSuccess) {\r
1247 OpalSupportUpdatePassword (&Dev->OpalDisk, Password, PasswordLen);\r
1248 DEBUG ((DEBUG_INFO, "%s Success\n", RequestString));\r
1249 } else {\r
1250 DEBUG ((DEBUG_INFO, "%s Failure\n", RequestString));\r
1251 }\r
1252\r
1253 if (Password != NULL) {\r
1254 ZeroMem (Password, PasswordLen);\r
1255 FreePool (Password);\r
1256 }\r
1257\r
1258 if (Ret == TcgResultSuccess) {\r
1259 break;\r
1260 }\r
1261\r
1262 Count++;\r
1263\r
1264 do {\r
1265 CreatePopUp (\r
1266 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1267 &Key,\r
1268 L"Invalid password, request failed.",\r
1269 L"Press ENTER to retry",\r
1270 NULL\r
1271 );\r
1272 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
1273 }\r
1274\r
1275 if (Count >= MAX_PASSWORD_TRY_COUNT) {\r
1276 do {\r
1277 CreatePopUp (\r
1278 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1279 &Key,\r
1280 L"Opal password retry count exceeds the limit.",\r
1281 L"Press ENTER to skip the request and continue boot",\r
1282 NULL\r
1283 );\r
1284 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
1285 gST->ConOut->ClearScreen(gST->ConOut);\r
1286 }\r
1287}\r
1288\r
1289/**\r
1290 Process Psid Revert OPAL request.\r
1291\r
1292 @param[in] Dev The device which has Psid Revert OPAL request.\r
1293 @param[in] RequestString Request string.\r
1294\r
1295**/\r
1296VOID\r
1297ProcessOpalRequestPsidRevert (\r
1298 IN OPAL_DRIVER_DEVICE *Dev,\r
1299 IN CHAR16 *RequestString\r
1300 )\r
1301{\r
1302 UINT8 Count;\r
1303 CHAR8 *Psid;\r
1304 UINT32 PsidLen;\r
1305 OPAL_SESSION Session;\r
1306 BOOLEAN PressEsc;\r
1307 EFI_INPUT_KEY Key;\r
1308 TCG_RESULT Ret;\r
1309 CHAR16 *PopUpString;\r
40d32e79 1310 CHAR16 *PopUpString2;\r
f5245a1d 1311 CHAR16 *PopUpString3;\r
40d32e79 1312 UINTN BufferSize;\r
112e584b
SZ
1313\r
1314 if (Dev == NULL) {\r
1315 return;\r
1316 }\r
1317\r
1318 DEBUG ((DEBUG_INFO, "%a()\n", __FUNCTION__));\r
1319\r
1320 PopUpString = OpalGetPopUpString (Dev, RequestString);\r
1321\r
40d32e79 1322 if (Dev->OpalDisk.EstimateTimeCost > MAX_ACCEPTABLE_REVERTING_TIME) {\r
f5245a1d 1323 BufferSize = StrSize (L"Warning: Revert action will take about ####### seconds");\r
40d32e79
ED
1324 PopUpString2 = AllocateZeroPool (BufferSize);\r
1325 ASSERT (PopUpString2 != NULL);\r
1326 UnicodeSPrint (\r
1327 PopUpString2,\r
1328 BufferSize,\r
f5245a1d 1329 L"WARNING: Revert action will take about %d seconds",\r
40d32e79
ED
1330 Dev->OpalDisk.EstimateTimeCost\r
1331 );\r
f5245a1d 1332 PopUpString3 = L"DO NOT power off system during the revert action!";\r
40d32e79
ED
1333 } else {\r
1334 PopUpString2 = NULL;\r
f5245a1d 1335 PopUpString3 = NULL;\r
40d32e79
ED
1336 }\r
1337\r
112e584b
SZ
1338 Count = 0;\r
1339\r
1340 ZeroMem(&Session, sizeof(Session));\r
1341 Session.Sscp = Dev->OpalDisk.Sscp;\r
1342 Session.MediaId = Dev->OpalDisk.MediaId;\r
1343 Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;\r
1344\r
1345 while (Count < MAX_PSID_TRY_COUNT) {\r
f5245a1d 1346 Psid = OpalDriverPopUpPsidInput (Dev, PopUpString, PopUpString2, PopUpString3, &PressEsc);\r
112e584b
SZ
1347 if (PressEsc) {\r
1348 do {\r
1349 CreatePopUp (\r
1350 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1351 &Key,\r
1352 L"Press ENTER to skip the request and continue boot,",\r
1353 L"Press ESC to input Psid again",\r
1354 NULL\r
1355 );\r
1356 } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));\r
1357\r
1358 if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
1359 gST->ConOut->ClearScreen(gST->ConOut);\r
40d32e79 1360 goto Done;\r
112e584b
SZ
1361 } else {\r
1362 //\r
1363 // Let user input Psid again.\r
1364 //\r
1365 continue;\r
1366 }\r
1367 }\r
1368\r
1369 if (Psid == NULL) {\r
1370 Count ++;\r
1371 continue;\r
1372 }\r
1373 PsidLen = (UINT32) AsciiStrLen(Psid);\r
1374\r
1375 Ret = OpalUtilPsidRevert(&Session, Psid, PsidLen);\r
1376 if (Ret == TcgResultSuccess) {\r
1377 DEBUG ((DEBUG_INFO, "%s Success\n", RequestString));\r
1378 } else {\r
1379 DEBUG ((DEBUG_INFO, "%s Failure\n", RequestString));\r
1380 }\r
1381\r
1382 if (Psid != NULL) {\r
1383 ZeroMem (Psid, PsidLen);\r
1384 FreePool (Psid);\r
1385 }\r
1386\r
1387 if (Ret == TcgResultSuccess) {\r
1388 break;\r
1389 }\r
1390\r
1391 Count++;\r
1392\r
1393 do {\r
1394 CreatePopUp (\r
1395 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1396 &Key,\r
1397 L"Invalid Psid, request failed.",\r
1398 L"Press ENTER to retry",\r
1399 NULL\r
1400 );\r
1401 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
1402 }\r
1403\r
1404 if (Count >= MAX_PSID_TRY_COUNT) {\r
1405 do {\r
1406 CreatePopUp (\r
1407 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1408 &Key,\r
1409 L"Opal Psid retry count exceeds the limit.",\r
1410 L"Press ENTER to skip the request and continue boot",\r
1411 NULL\r
1412 );\r
1413 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
1414 gST->ConOut->ClearScreen(gST->ConOut);\r
1415 }\r
40d32e79
ED
1416\r
1417Done:\r
1418 if (PopUpString2 != NULL) {\r
1419 FreePool (PopUpString2);\r
1420 }\r
112e584b
SZ
1421}\r
1422\r
1423/**\r
1424 Process Admin Revert OPAL request.\r
1425\r
1426 @param[in] Dev The device which has Revert OPAL request.\r
1427 @param[in] KeepUserData Whether to keep user data or not.\r
1428 @param[in] RequestString Request string.\r
1429\r
1430**/\r
1431VOID\r
1432ProcessOpalRequestRevert (\r
1433 IN OPAL_DRIVER_DEVICE *Dev,\r
1434 IN BOOLEAN KeepUserData,\r
1435 IN CHAR16 *RequestString\r
1436 )\r
1437{\r
1438 UINT8 Count;\r
1439 CHAR8 *Password;\r
1440 UINT32 PasswordLen;\r
1441 OPAL_SESSION Session;\r
1442 BOOLEAN PressEsc;\r
1443 EFI_INPUT_KEY Key;\r
1444 TCG_RESULT Ret;\r
1445 BOOLEAN PasswordFailed;\r
1446 CHAR16 *PopUpString;\r
40d32e79 1447 CHAR16 *PopUpString2;\r
f5245a1d 1448 CHAR16 *PopUpString3;\r
40d32e79 1449 UINTN BufferSize;\r
112e584b
SZ
1450\r
1451 if (Dev == NULL) {\r
1452 return;\r
1453 }\r
1454\r
1455 DEBUG ((DEBUG_INFO, "%a()\n", __FUNCTION__));\r
1456\r
1457 PopUpString = OpalGetPopUpString (Dev, RequestString);\r
1458\r
4ec00f82
CM
1459 if ((!KeepUserData) &&\r
1460 (Dev->OpalDisk.EstimateTimeCost > MAX_ACCEPTABLE_REVERTING_TIME)) {\r
f5245a1d 1461 BufferSize = StrSize (L"Warning: Revert action will take about ####### seconds");\r
40d32e79
ED
1462 PopUpString2 = AllocateZeroPool (BufferSize);\r
1463 ASSERT (PopUpString2 != NULL);\r
1464 UnicodeSPrint (\r
1465 PopUpString2,\r
1466 BufferSize,\r
f5245a1d 1467 L"WARNING: Revert action will take about %d seconds",\r
40d32e79
ED
1468 Dev->OpalDisk.EstimateTimeCost\r
1469 );\r
f5245a1d 1470 PopUpString3 = L"DO NOT power off system during the revert action!";\r
40d32e79
ED
1471 } else {\r
1472 PopUpString2 = NULL;\r
f5245a1d 1473 PopUpString3 = NULL;\r
40d32e79
ED
1474 }\r
1475\r
112e584b
SZ
1476 Count = 0;\r
1477\r
1478 ZeroMem(&Session, sizeof(Session));\r
1479 Session.Sscp = Dev->OpalDisk.Sscp;\r
1480 Session.MediaId = Dev->OpalDisk.MediaId;\r
1481 Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;\r
1482\r
1483 while (Count < MAX_PASSWORD_TRY_COUNT) {\r
f5245a1d 1484 Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, PopUpString2, PopUpString3, &PressEsc);\r
112e584b
SZ
1485 if (PressEsc) {\r
1486 do {\r
1487 CreatePopUp (\r
1488 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1489 &Key,\r
1490 L"Press ENTER to skip the request and continue boot,",\r
1491 L"Press ESC to input password again",\r
1492 NULL\r
1493 );\r
1494 } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));\r
1495\r
1496 if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
1497 gST->ConOut->ClearScreen(gST->ConOut);\r
40d32e79 1498 goto Done;\r
112e584b
SZ
1499 } else {\r
1500 //\r
1501 // Let user input password again.\r
1502 //\r
1503 continue;\r
1504 }\r
1505 }\r
1506\r
1507 if (Password == NULL) {\r
1508 Count ++;\r
1509 continue;\r
1510 }\r
1511 PasswordLen = (UINT32) AsciiStrLen(Password);\r
1512\r
1513 if ((Dev->OpalDisk.SupportedAttributes.PyriteSsc == 1) &&\r
1514 (Dev->OpalDisk.LockingFeature.MediaEncryption == 0)) {\r
1515 //\r
1516 // For pyrite type device which does not support media encryption,\r
1517 // it does not accept "Keep User Data" parameter.\r
1518 // So here hardcode a FALSE for this case.\r
1519 //\r
1520 Ret = OpalUtilRevert(\r
1521 &Session,\r
1522 FALSE,\r
1523 Password,\r
1524 PasswordLen,\r
1525 &PasswordFailed,\r
1526 Dev->OpalDisk.Msid,\r
1527 Dev->OpalDisk.MsidLength\r
1528 );\r
1529 } else {\r
1530 Ret = OpalUtilRevert(\r
1531 &Session,\r
1532 KeepUserData,\r
1533 Password,\r
1534 PasswordLen,\r
1535 &PasswordFailed,\r
1536 Dev->OpalDisk.Msid,\r
1537 Dev->OpalDisk.MsidLength\r
1538 );\r
1539 }\r
1540 if (Ret == TcgResultSuccess) {\r
1541 OpalSupportUpdatePassword (&Dev->OpalDisk, Password, PasswordLen);\r
1542 DEBUG ((DEBUG_INFO, "%s Success\n", RequestString));\r
1543 } else {\r
1544 DEBUG ((DEBUG_INFO, "%s Failure\n", RequestString));\r
1545 }\r
1546\r
1547 if (Password != NULL) {\r
1548 ZeroMem (Password, PasswordLen);\r
1549 FreePool (Password);\r
1550 }\r
1551\r
1552 if (Ret == TcgResultSuccess) {\r
1553 break;\r
1554 }\r
1555\r
1556 Count++;\r
1557\r
1558 do {\r
1559 CreatePopUp (\r
1560 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1561 &Key,\r
1562 L"Invalid password, request failed.",\r
1563 L"Press ENTER to retry",\r
1564 NULL\r
1565 );\r
1566 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
1567 }\r
1568\r
1569 if (Count >= MAX_PASSWORD_TRY_COUNT) {\r
1570 do {\r
1571 CreatePopUp (\r
1572 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1573 &Key,\r
1574 L"Opal password retry count exceeds the limit.",\r
1575 L"Press ENTER to skip the request and continue boot",\r
1576 NULL\r
1577 );\r
1578 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
1579 gST->ConOut->ClearScreen(gST->ConOut);\r
1580 }\r
40d32e79
ED
1581\r
1582Done:\r
1583 if (PopUpString2 != NULL) {\r
1584 FreePool (PopUpString2);\r
1585 }\r
112e584b
SZ
1586}\r
1587\r
1588/**\r
1589 Process Secure Erase OPAL request.\r
1590\r
1591 @param[in] Dev The device which has Secure Erase OPAL request.\r
1592 @param[in] RequestString Request string.\r
1593\r
1594**/\r
1595VOID\r
1596ProcessOpalRequestSecureErase (\r
1597 IN OPAL_DRIVER_DEVICE *Dev,\r
1598 IN CHAR16 *RequestString\r
1599 )\r
1600{\r
1601 UINT8 Count;\r
1602 CHAR8 *Password;\r
1603 UINT32 PasswordLen;\r
1604 OPAL_SESSION Session;\r
1605 BOOLEAN PressEsc;\r
1606 EFI_INPUT_KEY Key;\r
1607 TCG_RESULT Ret;\r
1608 BOOLEAN PasswordFailed;\r
1609 CHAR16 *PopUpString;\r
f5245a1d
CM
1610 CHAR16 *PopUpString2;\r
1611 CHAR16 *PopUpString3;\r
1612 UINTN BufferSize;\r
112e584b
SZ
1613\r
1614 if (Dev == NULL) {\r
1615 return;\r
1616 }\r
1617\r
1618 DEBUG ((DEBUG_INFO, "%a()\n", __FUNCTION__));\r
1619\r
1620 PopUpString = OpalGetPopUpString (Dev, RequestString);\r
1621\r
f5245a1d
CM
1622 if (Dev->OpalDisk.EstimateTimeCost > MAX_ACCEPTABLE_REVERTING_TIME) {\r
1623 BufferSize = StrSize (L"Warning: Secure erase action will take about ####### seconds");\r
1624 PopUpString2 = AllocateZeroPool (BufferSize);\r
1625 ASSERT (PopUpString2 != NULL);\r
1626 UnicodeSPrint (\r
1627 PopUpString2,\r
1628 BufferSize,\r
1629 L"WARNING: Secure erase action will take about %d seconds",\r
1630 Dev->OpalDisk.EstimateTimeCost\r
1631 );\r
1632 PopUpString3 = L"DO NOT power off system during the action!";\r
1633 } else {\r
1634 PopUpString2 = NULL;\r
1635 PopUpString3 = NULL;\r
1636 }\r
112e584b
SZ
1637 Count = 0;\r
1638\r
1639 ZeroMem(&Session, sizeof(Session));\r
1640 Session.Sscp = Dev->OpalDisk.Sscp;\r
1641 Session.MediaId = Dev->OpalDisk.MediaId;\r
1642 Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;\r
1643\r
1644 while (Count < MAX_PASSWORD_TRY_COUNT) {\r
f5245a1d 1645 Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, PopUpString2, PopUpString3, &PressEsc);\r
112e584b
SZ
1646 if (PressEsc) {\r
1647 do {\r
1648 CreatePopUp (\r
1649 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1650 &Key,\r
1651 L"Press ENTER to skip the request and continue boot,",\r
1652 L"Press ESC to input password again",\r
1653 NULL\r
1654 );\r
1655 } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));\r
1656\r
1657 if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
1658 gST->ConOut->ClearScreen(gST->ConOut);\r
f5245a1d 1659 goto Done;\r
112e584b
SZ
1660 } else {\r
1661 //\r
1662 // Let user input password again.\r
1663 //\r
1664 continue;\r
1665 }\r
1666 }\r
1667\r
1668 if (Password == NULL) {\r
1669 Count ++;\r
1670 continue;\r
1671 }\r
1672 PasswordLen = (UINT32) AsciiStrLen(Password);\r
1673\r
1674 Ret = OpalUtilSecureErase(&Session, Password, PasswordLen, &PasswordFailed);\r
1675 if (Ret == TcgResultSuccess) {\r
1676 OpalSupportUpdatePassword (&Dev->OpalDisk, Password, PasswordLen);\r
1677 DEBUG ((DEBUG_INFO, "%s Success\n", RequestString));\r
1678 } else {\r
1679 DEBUG ((DEBUG_INFO, "%s Failure\n", RequestString));\r
1680 }\r
1681\r
1682 if (Password != NULL) {\r
1683 ZeroMem (Password, PasswordLen);\r
1684 FreePool (Password);\r
1685 }\r
1686\r
1687 if (Ret == TcgResultSuccess) {\r
1688 break;\r
1689 }\r
1690\r
1691 Count++;\r
1692\r
1693 do {\r
1694 CreatePopUp (\r
1695 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1696 &Key,\r
1697 L"Invalid password, request failed.",\r
1698 L"Press ENTER to retry",\r
1699 NULL\r
1700 );\r
1701 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
1702 }\r
1703\r
1704 if (Count >= MAX_PASSWORD_TRY_COUNT) {\r
1705 do {\r
1706 CreatePopUp (\r
1707 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1708 &Key,\r
1709 L"Opal password retry count exceeds the limit.",\r
1710 L"Press ENTER to skip the request and continue boot",\r
1711 NULL\r
1712 );\r
1713 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
1714 gST->ConOut->ClearScreen(gST->ConOut);\r
1715 }\r
f5245a1d
CM
1716\r
1717Done:\r
1718 if (PopUpString2 != NULL) {\r
1719 FreePool (PopUpString2);\r
1720 }\r
112e584b
SZ
1721}\r
1722\r
1723/**\r
1724 Process Set Admin Pwd OPAL request.\r
1725\r
1726 @param[in] Dev The device which has Set Admin Pwd Feature OPAL request.\r
1727 @param[in] RequestString Request string.\r
1728\r
1729**/\r
1730VOID\r
1731ProcessOpalRequestSetUserPwd (\r
1732 IN OPAL_DRIVER_DEVICE *Dev,\r
1733 IN CHAR16 *RequestString\r
1734 )\r
1735{\r
1736 UINT8 Count;\r
1737 CHAR8 *OldPassword;\r
1738 UINT32 OldPasswordLen;\r
1739 CHAR8 *Password;\r
1740 UINT32 PasswordLen;\r
1741 CHAR8 *PasswordConfirm;\r
1742 UINT32 PasswordLenConfirm;\r
1743 OPAL_SESSION Session;\r
1744 BOOLEAN PressEsc;\r
1745 EFI_INPUT_KEY Key;\r
1746 TCG_RESULT Ret;\r
1747 CHAR16 *PopUpString;\r
1748\r
1749 if (Dev == NULL) {\r
1750 return;\r
1751 }\r
1752\r
1753 DEBUG ((DEBUG_INFO, "%a()\n", __FUNCTION__));\r
1754\r
1755 PopUpString = OpalGetPopUpString (Dev, RequestString);\r
1756\r
1757 Count = 0;\r
1758\r
1759 while (Count < MAX_PASSWORD_TRY_COUNT) {\r
f5245a1d 1760 OldPassword = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please type in your password", NULL, &PressEsc);\r
112e584b
SZ
1761 if (PressEsc) {\r
1762 do {\r
1763 CreatePopUp (\r
1764 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1765 &Key,\r
1766 L"Press ENTER to skip the request and continue boot,",\r
1767 L"Press ESC to input password again",\r
1768 NULL\r
1769 );\r
1770 } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));\r
1771\r
1772 if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
1773 gST->ConOut->ClearScreen(gST->ConOut);\r
1774 return;\r
1775 } else {\r
1776 //\r
1777 // Let user input password again.\r
1778 //\r
1779 continue;\r
1780 }\r
1781 }\r
1782\r
1783 if (OldPassword == NULL) {\r
1784 Count ++;\r
1785 continue;\r
1786 }\r
1787 OldPasswordLen = (UINT32) AsciiStrLen(OldPassword);\r
1788\r
1789 ZeroMem(&Session, sizeof(Session));\r
1790 Session.Sscp = Dev->OpalDisk.Sscp;\r
1791 Session.MediaId = Dev->OpalDisk.MediaId;\r
1792 Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;\r
1793 Ret = OpalUtilVerifyPassword (&Session, OldPassword, OldPasswordLen, OPAL_LOCKING_SP_USER1_AUTHORITY);\r
1794 if (Ret == TcgResultSuccess) {\r
1795 DEBUG ((DEBUG_INFO, "Verify with USER1 authority : Success\n"));\r
1796 } else {\r
1797 Ret = OpalUtilVerifyPassword (&Session, OldPassword, OldPasswordLen, OPAL_LOCKING_SP_ADMIN1_AUTHORITY);\r
1798 if (Ret == TcgResultSuccess) {\r
1799 DEBUG ((DEBUG_INFO, "Verify with ADMIN1 authority: Success\n"));\r
1800 } else {\r
1801 ZeroMem (OldPassword, OldPasswordLen);\r
1802 FreePool (OldPassword);\r
1803 DEBUG ((DEBUG_INFO, "Verify: Failure\n"));\r
1804 do {\r
1805 CreatePopUp (\r
1806 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1807 &Key,\r
1808 L"Incorrect password.",\r
1809 L"Press ENTER to retry",\r
1810 NULL\r
1811 );\r
1812 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
1813 Count ++;\r
1814 continue;\r
1815 }\r
1816 }\r
1817\r
f5245a1d 1818 Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please type in your new password", NULL, &PressEsc);\r
112e584b
SZ
1819 if (Password == NULL) {\r
1820 ZeroMem (OldPassword, OldPasswordLen);\r
1821 FreePool (OldPassword);\r
1822 Count ++;\r
1823 continue;\r
1824 }\r
1825 PasswordLen = (UINT32) AsciiStrLen(Password);\r
1826\r
f5245a1d 1827 PasswordConfirm = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please confirm your new password", NULL, &PressEsc);\r
112e584b
SZ
1828 if (PasswordConfirm == NULL) {\r
1829 ZeroMem (OldPassword, OldPasswordLen);\r
1830 FreePool (OldPassword);\r
1831 ZeroMem (Password, PasswordLen);\r
1832 FreePool (Password);\r
1833 Count ++;\r
1834 continue;\r
1835 }\r
1836 PasswordLenConfirm = (UINT32) AsciiStrLen(PasswordConfirm);\r
1837 if ((PasswordLen != PasswordLenConfirm) ||\r
1838 (CompareMem (Password, PasswordConfirm, PasswordLen) != 0)) {\r
1839 ZeroMem (OldPassword, OldPasswordLen);\r
1840 FreePool (OldPassword);\r
1841 ZeroMem (Password, PasswordLen);\r
1842 FreePool (Password);\r
1843 ZeroMem (PasswordConfirm, PasswordLenConfirm);\r
1844 FreePool (PasswordConfirm);\r
1845 do {\r
1846 CreatePopUp (\r
1847 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1848 &Key,\r
1849 L"Passwords are not the same.",\r
1850 L"Press ENTER to retry",\r
1851 NULL\r
1852 );\r
1853 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
1854 Count ++;\r
1855 continue;\r
1856 }\r
1857\r
1858 if (PasswordConfirm != NULL) {\r
1859 ZeroMem (PasswordConfirm, PasswordLenConfirm);\r
1860 FreePool (PasswordConfirm);\r
1861 }\r
1862\r
1863 ZeroMem(&Session, sizeof(Session));\r
1864 Session.Sscp = Dev->OpalDisk.Sscp;\r
1865 Session.MediaId = Dev->OpalDisk.MediaId;\r
1866 Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;\r
1867 Ret = OpalUtilSetUserPassword(\r
1868 &Session,\r
1869 OldPassword,\r
1870 OldPasswordLen,\r
1871 Password,\r
1872 PasswordLen\r
1873 );\r
1874 if (Ret == TcgResultSuccess) {\r
1875 OpalSupportUpdatePassword (&Dev->OpalDisk, Password, PasswordLen);\r
1876 DEBUG ((DEBUG_INFO, "%s Success\n", RequestString));\r
1877 } else {\r
1878 DEBUG ((DEBUG_INFO, "%s Failure\n", RequestString));\r
1879 }\r
1880\r
1881 if (OldPassword != NULL) {\r
1882 ZeroMem (OldPassword, OldPasswordLen);\r
1883 FreePool (OldPassword);\r
1884 }\r
1885\r
1886 if (Password != NULL) {\r
1887 ZeroMem (Password, PasswordLen);\r
1888 FreePool (Password);\r
1889 }\r
1890\r
1891 if (Ret == TcgResultSuccess) {\r
1892 break;\r
1893 }\r
1894\r
1895 Count++;\r
1896\r
1897 do {\r
1898 CreatePopUp (\r
1899 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1900 &Key,\r
1901 L"Request failed.",\r
1902 L"Press ENTER to retry",\r
1903 NULL\r
1904 );\r
1905 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
1906 }\r
1907\r
1908 if (Count >= MAX_PASSWORD_TRY_COUNT) {\r
1909 do {\r
1910 CreatePopUp (\r
1911 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1912 &Key,\r
1913 L"Opal password retry count exceeds the limit.",\r
1914 L"Press ENTER to skip the request and continue boot",\r
1915 NULL\r
1916 );\r
1917 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
1918 gST->ConOut->ClearScreen(gST->ConOut);\r
1919 }\r
1920}\r
1921\r
1922/**\r
1923 Process Set Admin Pwd OPAL request.\r
1924\r
1925 @param[in] Dev The device which has Set Admin Pwd Feature OPAL request.\r
1926 @param[in] RequestString Request string.\r
1927\r
1928**/\r
1929VOID\r
1930ProcessOpalRequestSetAdminPwd (\r
1931 IN OPAL_DRIVER_DEVICE *Dev,\r
1932 IN CHAR16 *RequestString\r
1933 )\r
1934{\r
1935 UINT8 Count;\r
1936 CHAR8 *OldPassword;\r
1937 UINT32 OldPasswordLen;\r
1938 CHAR8 *Password;\r
1939 UINT32 PasswordLen;\r
1940 CHAR8 *PasswordConfirm;\r
1941 UINT32 PasswordLenConfirm;\r
1942 OPAL_SESSION Session;\r
1943 BOOLEAN PressEsc;\r
1944 EFI_INPUT_KEY Key;\r
1945 TCG_RESULT Ret;\r
1946 CHAR16 *PopUpString;\r
1947\r
1948 if (Dev == NULL) {\r
1949 return;\r
1950 }\r
1951\r
1952 DEBUG ((DEBUG_INFO, "%a()\n", __FUNCTION__));\r
1953\r
1954 PopUpString = OpalGetPopUpString (Dev, RequestString);\r
1955\r
1956 Count = 0;\r
1957\r
1958 while (Count < MAX_PASSWORD_TRY_COUNT) {\r
f5245a1d 1959 OldPassword = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please type in your password", NULL, &PressEsc);\r
112e584b
SZ
1960 if (PressEsc) {\r
1961 do {\r
1962 CreatePopUp (\r
1963 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1964 &Key,\r
1965 L"Press ENTER to skip the request and continue boot,",\r
1966 L"Press ESC to input password again",\r
1967 NULL\r
1968 );\r
1969 } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));\r
1970\r
1971 if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
1972 gST->ConOut->ClearScreen(gST->ConOut);\r
1973 return;\r
1974 } else {\r
1975 //\r
1976 // Let user input password again.\r
1977 //\r
1978 continue;\r
1979 }\r
1980 }\r
1981\r
1982 if (OldPassword == NULL) {\r
1983 Count ++;\r
1984 continue;\r
1985 }\r
1986 OldPasswordLen = (UINT32) AsciiStrLen(OldPassword);\r
1987\r
1988 ZeroMem(&Session, sizeof(Session));\r
1989 Session.Sscp = Dev->OpalDisk.Sscp;\r
1990 Session.MediaId = Dev->OpalDisk.MediaId;\r
1991 Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;\r
1992 Ret = OpalUtilVerifyPassword (&Session, OldPassword, OldPasswordLen, OPAL_LOCKING_SP_ADMIN1_AUTHORITY);\r
1993 if (Ret == TcgResultSuccess) {\r
1994 DEBUG ((DEBUG_INFO, "Verify: Success\n"));\r
1995 } else {\r
1996 ZeroMem (OldPassword, OldPasswordLen);\r
1997 FreePool (OldPassword);\r
1998 DEBUG ((DEBUG_INFO, "Verify: Failure\n"));\r
1999 do {\r
2000 CreatePopUp (\r
2001 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
2002 &Key,\r
2003 L"Incorrect password.",\r
2004 L"Press ENTER to retry",\r
2005 NULL\r
2006 );\r
2007 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
2008 Count ++;\r
2009 continue;\r
2010 }\r
2011\r
f5245a1d 2012 Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please type in your new password", NULL, &PressEsc);\r
112e584b
SZ
2013 if (Password == NULL) {\r
2014 ZeroMem (OldPassword, OldPasswordLen);\r
2015 FreePool (OldPassword);\r
2016 Count ++;\r
2017 continue;\r
2018 }\r
2019 PasswordLen = (UINT32) AsciiStrLen(Password);\r
2020\r
f5245a1d 2021 PasswordConfirm = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please confirm your new password", NULL, &PressEsc);\r
112e584b
SZ
2022 if (PasswordConfirm == NULL) {\r
2023 ZeroMem (OldPassword, OldPasswordLen);\r
2024 FreePool (OldPassword);\r
2025 ZeroMem (Password, PasswordLen);\r
2026 FreePool (Password);\r
2027 Count ++;\r
2028 continue;\r
2029 }\r
2030 PasswordLenConfirm = (UINT32) AsciiStrLen(PasswordConfirm);\r
2031 if ((PasswordLen != PasswordLenConfirm) ||\r
2032 (CompareMem (Password, PasswordConfirm, PasswordLen) != 0)) {\r
2033 ZeroMem (OldPassword, OldPasswordLen);\r
2034 FreePool (OldPassword);\r
2035 ZeroMem (Password, PasswordLen);\r
2036 FreePool (Password);\r
2037 ZeroMem (PasswordConfirm, PasswordLenConfirm);\r
2038 FreePool (PasswordConfirm);\r
2039 do {\r
2040 CreatePopUp (\r
2041 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
2042 &Key,\r
2043 L"Passwords are not the same.",\r
2044 L"Press ENTER to retry",\r
2045 NULL\r
2046 );\r
2047 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
2048 Count ++;\r
2049 continue;\r
2050 }\r
2051\r
2052 if (PasswordConfirm != NULL) {\r
2053 ZeroMem (PasswordConfirm, PasswordLenConfirm);\r
2054 FreePool (PasswordConfirm);\r
2055 }\r
2056\r
2057\r
2058 ZeroMem(&Session, sizeof(Session));\r
2059 Session.Sscp = Dev->OpalDisk.Sscp;\r
2060 Session.MediaId = Dev->OpalDisk.MediaId;\r
2061 Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;\r
2062 Ret = OpalUtilSetAdminPassword(\r
2063 &Session,\r
2064 OldPassword,\r
2065 OldPasswordLen,\r
2066 Password,\r
2067 PasswordLen\r
2068 );\r
2069 if (Ret == TcgResultSuccess) {\r
2070 OpalSupportUpdatePassword (&Dev->OpalDisk, Password, PasswordLen);\r
2071 DEBUG ((DEBUG_INFO, "%s Success\n", RequestString));\r
2072 } else {\r
2073 DEBUG ((DEBUG_INFO, "%s Failure\n", RequestString));\r
2074 }\r
2075\r
2076 if (OldPassword != NULL) {\r
2077 ZeroMem (OldPassword, OldPasswordLen);\r
2078 FreePool (OldPassword);\r
2079 }\r
2080\r
2081 if (Password != NULL) {\r
2082 ZeroMem (Password, PasswordLen);\r
2083 FreePool (Password);\r
2084 }\r
2085\r
2086 if (Ret == TcgResultSuccess) {\r
2087 break;\r
2088 }\r
2089\r
2090 Count++;\r
2091\r
2092 do {\r
2093 CreatePopUp (\r
2094 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
2095 &Key,\r
2096 L"Request failed.",\r
2097 L"Press ENTER to retry",\r
2098 NULL\r
2099 );\r
2100 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
2101 }\r
2102\r
2103 if (Count >= MAX_PASSWORD_TRY_COUNT) {\r
2104 do {\r
2105 CreatePopUp (\r
2106 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
2107 &Key,\r
2108 L"Opal password retry count exceeds the limit.",\r
2109 L"Press ENTER to skip the request and continue boot",\r
2110 NULL\r
2111 );\r
2112 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
2113 gST->ConOut->ClearScreen(gST->ConOut);\r
2114 }\r
2115}\r
2116\r
2117/**\r
2118 Process OPAL request.\r
2119\r
2120 @param[in] Dev The device which has OPAL request.\r
2121\r
2122**/\r
2123VOID\r
2124ProcessOpalRequest (\r
2125 IN OPAL_DRIVER_DEVICE *Dev\r
2126 )\r
2127{\r
2128 EFI_STATUS Status;\r
2129 OPAL_REQUEST_VARIABLE *TempVariable;\r
2130 OPAL_REQUEST_VARIABLE *Variable;\r
2131 UINTN VariableSize;\r
2132 EFI_DEVICE_PATH_PROTOCOL *DevicePathInVariable;\r
2133 UINTN DevicePathSizeInVariable;\r
2134 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
2135 UINTN DevicePathSize;\r
2136 BOOLEAN KeepUserData;\r
2137\r
2138 DEBUG ((DEBUG_INFO, "%a() - enter\n", __FUNCTION__));\r
2139\r
2140 if (mOpalRequestVariable == NULL) {\r
2141 Status = GetVariable2 (\r
2142 OPAL_REQUEST_VARIABLE_NAME,\r
2143 &gHiiSetupVariableGuid,\r
2144 (VOID **) &Variable,\r
2145 &VariableSize\r
2146 );\r
2147 if (EFI_ERROR (Status) || (Variable == NULL)) {\r
2148 return;\r
2149 }\r
2150 mOpalRequestVariable = Variable;\r
2151 mOpalRequestVariableSize = VariableSize;\r
2152\r
2153 //\r
2154 // Delete the OPAL request variable.\r
2155 //\r
2156 Status = gRT->SetVariable (\r
2157 OPAL_REQUEST_VARIABLE_NAME,\r
2158 (EFI_GUID *) &gHiiSetupVariableGuid,\r
2159 0,\r
2160 0,\r
2161 NULL\r
2162 );\r
2163 ASSERT_EFI_ERROR (Status);\r
2164 } else {\r
2165 Variable = mOpalRequestVariable;\r
2166 VariableSize = mOpalRequestVariableSize;\r
2167 }\r
2168\r
2169 //\r
2170 // Process the OPAL requests.\r
2171 //\r
2172 TempVariable = Variable;\r
2173 while ((VariableSize > sizeof (OPAL_REQUEST_VARIABLE)) &&\r
2174 (VariableSize >= TempVariable->Length) &&\r
2175 (TempVariable->Length > sizeof (OPAL_REQUEST_VARIABLE))) {\r
2176 DevicePathInVariable = (EFI_DEVICE_PATH_PROTOCOL *) ((UINTN) TempVariable + sizeof (OPAL_REQUEST_VARIABLE));\r
2177 DevicePathSizeInVariable = GetDevicePathSize (DevicePathInVariable);\r
2178 DevicePath = Dev->OpalDisk.OpalDevicePath;\r
2179 DevicePathSize = GetDevicePathSize (DevicePath);\r
2180 if ((DevicePathSize == DevicePathSizeInVariable) &&\r
2181 (CompareMem (DevicePath, DevicePathInVariable, DevicePathSize) == 0)) {\r
2182 //\r
2183 // Found the node for the OPAL device.\r
2184 //\r
2185 if (TempVariable->OpalRequest.SetAdminPwd != 0) {\r
2186 ProcessOpalRequestSetAdminPwd (Dev, L"Update Admin Pwd:");\r
2187 }\r
2188 if (TempVariable->OpalRequest.SetUserPwd != 0) {\r
2189 ProcessOpalRequestSetUserPwd (Dev, L"Set User Pwd:");\r
2190 }\r
2191 if (TempVariable->OpalRequest.SecureErase!= 0) {\r
2192 ProcessOpalRequestSecureErase (Dev, L"Secure Erase:");\r
2193 }\r
2194 if (TempVariable->OpalRequest.Revert != 0) {\r
2195 KeepUserData = (BOOLEAN) TempVariable->OpalRequest.KeepUserData;\r
2196 ProcessOpalRequestRevert (\r
2197 Dev,\r
2198 KeepUserData,\r
2199 KeepUserData ? L"Admin Revert(keep):" : L"Admin Revert:"\r
2200 );\r
2201 }\r
2202 if (TempVariable->OpalRequest.PsidRevert != 0) {\r
2203 ProcessOpalRequestPsidRevert (Dev, L"Psid Revert:");\r
2204 }\r
2205 if (TempVariable->OpalRequest.DisableUser != 0) {\r
2206 ProcessOpalRequestDisableUser (Dev, L"Disable User:");\r
2207 }\r
2208 if (TempVariable->OpalRequest.EnableFeature != 0) {\r
2209 ProcessOpalRequestEnableFeature (Dev, L"Enable Feature:");\r
2210 }\r
2211\r
46e69608
ED
2212 //\r
2213 // Update Device ownership.\r
2214 // Later BlockSID command may block the update.\r
2215 //\r
2216 OpalDiskUpdateOwnerShip (&Dev->OpalDisk);\r
2217\r
112e584b
SZ
2218 break;\r
2219 }\r
2220\r
2221 VariableSize -= TempVariable->Length;\r
2222 TempVariable = (OPAL_REQUEST_VARIABLE *) ((UINTN) TempVariable + TempVariable->Length);\r
2223 }\r
2224\r
2225 DEBUG ((DEBUG_INFO, "%a() - exit\n", __FUNCTION__));\r
2226}\r
2227\r
2228/**\r
2229 Add new device to the global device list.\r
2230\r
2231 @param Dev New create device.\r
2232\r
2233**/\r
2234VOID\r
2235AddDeviceToTail(\r
2236 IN OPAL_DRIVER_DEVICE *Dev\r
2237 )\r
2238{\r
2239 OPAL_DRIVER_DEVICE *TmpDev;\r
2240\r
2241 if (mOpalDriver.DeviceList == NULL) {\r
2242 mOpalDriver.DeviceList = Dev;\r
2243 } else {\r
2244 TmpDev = mOpalDriver.DeviceList;\r
2245 while (TmpDev->Next != NULL) {\r
2246 TmpDev = TmpDev->Next;\r
2247 }\r
2248\r
2249 TmpDev->Next = Dev;\r
2250 }\r
2251}\r
2252\r
2253/**\r
2254 Remove one device in the global device list.\r
2255\r
2256 @param Dev The device need to be removed.\r
2257\r
2258**/\r
2259VOID\r
2260RemoveDevice (\r
2261 IN OPAL_DRIVER_DEVICE *Dev\r
2262 )\r
2263{\r
2264 OPAL_DRIVER_DEVICE *TmpDev;\r
2265\r
2266 if (mOpalDriver.DeviceList == NULL) {\r
2267 return;\r
2268 }\r
2269\r
2270 if (mOpalDriver.DeviceList == Dev) {\r
2271 mOpalDriver.DeviceList = NULL;\r
2272 return;\r
2273 }\r
2274\r
2275 TmpDev = mOpalDriver.DeviceList;\r
2276 while (TmpDev->Next != NULL) {\r
2277 if (TmpDev->Next == Dev) {\r
2278 TmpDev->Next = Dev->Next;\r
2279 break;\r
2280 }\r
2281 }\r
2282}\r
2283\r
2284/**\r
2285 Get current device count.\r
2286\r
2287 @retval return the current created device count.\r
2288\r
2289**/\r
2290UINT8\r
2291GetDeviceCount (\r
2292 VOID\r
2293 )\r
2294{\r
2295 UINT8 Count;\r
2296 OPAL_DRIVER_DEVICE *TmpDev;\r
2297\r
2298 Count = 0;\r
2299 TmpDev = mOpalDriver.DeviceList;\r
2300\r
2301 while (TmpDev != NULL) {\r
2302 Count++;\r
2303 TmpDev = TmpDev->Next;\r
2304 }\r
2305\r
2306 return Count;\r
2307}\r
2308\r
2309/**\r
2310 Get devcie list info.\r
2311\r
2312 @retval return the device list pointer.\r
2313**/\r
2314OPAL_DRIVER_DEVICE*\r
2315OpalDriverGetDeviceList(\r
2316 VOID\r
2317 )\r
2318{\r
2319 return mOpalDriver.DeviceList;\r
2320}\r
2321\r
112e584b
SZ
2322/**\r
2323 Stop this Controller.\r
2324\r
2325 @param Dev The device need to be stopped.\r
2326\r
2327**/\r
2328VOID\r
2329OpalDriverStopDevice (\r
2330 OPAL_DRIVER_DEVICE *Dev\r
2331 )\r
2332{\r
2333 //\r
2334 // free each name\r
2335 //\r
2336 FreePool(Dev->Name16);\r
2337\r
2338 //\r
2339 // remove OPAL_DRIVER_DEVICE from the list\r
2340 // it updates the controllerList pointer\r
2341 //\r
2342 RemoveDevice(Dev);\r
2343\r
2344 //\r
2345 // close protocols that were opened\r
2346 //\r
2347 gBS->CloseProtocol(\r
2348 Dev->Handle,\r
2349 &gEfiStorageSecurityCommandProtocolGuid,\r
2350 gOpalDriverBinding.DriverBindingHandle,\r
2351 Dev->Handle\r
2352 );\r
2353\r
2354 gBS->CloseProtocol(\r
2355 Dev->Handle,\r
2356 &gEfiBlockIoProtocolGuid,\r
2357 gOpalDriverBinding.DriverBindingHandle,\r
2358 Dev->Handle\r
2359 );\r
2360\r
2361 FreePool(Dev);\r
2362}\r
2363\r
2364/**\r
2365 Get devcie name through the component name protocol.\r
2366\r
2367 @param[in] AllHandlesBuffer The handle buffer for current system.\r
2368 @param[in] NumAllHandles The number of handles for the handle buffer.\r
2369 @param[in] Dev The device which need to get name.\r
2370 @param[in] UseComp1 Whether use component name or name2 protocol.\r
2371\r
2372 @retval TRUE Find the name for this device.\r
2373 @retval FALSE Not found the name for this device.\r
2374**/\r
2375BOOLEAN\r
2376OpalDriverGetDeviceNameByProtocol(\r
2377 EFI_HANDLE *AllHandlesBuffer,\r
2378 UINTN NumAllHandles,\r
2379 OPAL_DRIVER_DEVICE *Dev,\r
2380 BOOLEAN UseComp1\r
2381 )\r
2382{\r
2383 EFI_HANDLE* ProtocolHandlesBuffer;\r
2384 UINTN NumProtocolHandles;\r
2385 EFI_STATUS Status;\r
2386 EFI_COMPONENT_NAME2_PROTOCOL* Cnp1_2; // efi component name and componentName2 have same layout\r
2387 EFI_GUID Protocol;\r
2388 UINTN StrLength;\r
2389 EFI_DEVICE_PATH_PROTOCOL* TmpDevPath;\r
2390 UINTN Index1;\r
2391 UINTN Index2;\r
2392 EFI_HANDLE TmpHandle;\r
2393 CHAR16 *DevName;\r
2394\r
2395 if (Dev == NULL || AllHandlesBuffer == NULL || NumAllHandles == 0) {\r
2396 return FALSE;\r
2397 }\r
2398\r
2399 Protocol = UseComp1 ? gEfiComponentNameProtocolGuid : gEfiComponentName2ProtocolGuid;\r
2400\r
2401 //\r
2402 // Find all EFI_HANDLES with protocol\r
2403 //\r
2404 Status = gBS->LocateHandleBuffer(\r
2405 ByProtocol,\r
2406 &Protocol,\r
2407 NULL,\r
2408 &NumProtocolHandles,\r
2409 &ProtocolHandlesBuffer\r
2410 );\r
2411 if (EFI_ERROR(Status)) {\r
2412 return FALSE;\r
2413 }\r
2414\r
2415\r
2416 //\r
2417 // Exit early if no supported devices\r
2418 //\r
2419 if (NumProtocolHandles == 0) {\r
2420 return FALSE;\r
2421 }\r
2422\r
2423 //\r
2424 // Get printable name by iterating through all protocols\r
2425 // using the handle as the child, and iterate through all handles for the controller\r
2426 // exit loop early once found, if not found, then delete device\r
2427 // storage security protocol instances already exist, add them to internal list\r
2428 //\r
2429 Status = EFI_DEVICE_ERROR;\r
2430 for (Index1 = 0; Index1 < NumProtocolHandles; Index1++) {\r
2431 DevName = NULL;\r
2432\r
2433 if (Dev->Name16 != NULL) {\r
2434 return TRUE;\r
2435 }\r
2436\r
2437 TmpHandle = ProtocolHandlesBuffer[Index1];\r
2438\r
2439 Status = gBS->OpenProtocol(\r
2440 TmpHandle,\r
2441 &Protocol,\r
2442 (VOID**)&Cnp1_2,\r
2443 gImageHandle,\r
2444 NULL,\r
2445 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
2446 );\r
2447 if (EFI_ERROR(Status) || Cnp1_2 == NULL) {\r
2448 continue;\r
2449 }\r
2450\r
2451 //\r
2452 // Use all handles array as controller handle\r
2453 //\r
2454 for (Index2 = 0; Index2 < NumAllHandles; Index2++) {\r
2455 Status = Cnp1_2->GetControllerName(\r
2456 Cnp1_2,\r
2457 AllHandlesBuffer[Index2],\r
2458 Dev->Handle,\r
2459 LANGUAGE_ISO_639_2_ENGLISH,\r
2460 &DevName\r
2461 );\r
2462 if (EFI_ERROR(Status)) {\r
2463 Status = Cnp1_2->GetControllerName(\r
2464 Cnp1_2,\r
2465 AllHandlesBuffer[Index2],\r
2466 Dev->Handle,\r
2467 LANGUAGE_RFC_3066_ENGLISH,\r
2468 &DevName\r
2469 );\r
2470 }\r
2471 if (!EFI_ERROR(Status) && DevName != NULL) {\r
2472 StrLength = StrLen(DevName) + 1; // Add one for NULL terminator\r
2473 Dev->Name16 = AllocateZeroPool(StrLength * sizeof (CHAR16));\r
2474 ASSERT (Dev->Name16 != NULL);\r
2475 StrCpyS (Dev->Name16, StrLength, DevName);\r
2476 Dev->NameZ = (CHAR8*)AllocateZeroPool(StrLength);\r
2477 UnicodeStrToAsciiStrS (DevName, Dev->NameZ, StrLength);\r
2478\r
2479 //\r
2480 // Retrieve bridge BDF info and port number or namespace depending on type\r
2481 //\r
2482 TmpDevPath = NULL;\r
2483 Status = gBS->OpenProtocol(\r
2484 Dev->Handle,\r
2485 &gEfiDevicePathProtocolGuid,\r
2486 (VOID**)&TmpDevPath,\r
2487 gImageHandle,\r
2488 NULL,\r
2489 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
2490 );\r
2491 if (!EFI_ERROR(Status)) {\r
2492 Dev->OpalDevicePath = DuplicateDevicePath (TmpDevPath);\r
2493 return TRUE;\r
2494 }\r
2495\r
2496 if (Dev->Name16 != NULL) {\r
2497 FreePool(Dev->Name16);\r
2498 Dev->Name16 = NULL;\r
2499 }\r
2500 if (Dev->NameZ != NULL) {\r
2501 FreePool(Dev->NameZ);\r
2502 Dev->NameZ = NULL;\r
2503 }\r
2504 }\r
2505 }\r
2506 }\r
2507\r
2508 return FALSE;\r
2509}\r
2510\r
2511/**\r
2512 Get devcie name through the component name protocol.\r
2513\r
2514 @param[in] Dev The device which need to get name.\r
2515\r
2516 @retval TRUE Find the name for this device.\r
2517 @retval FALSE Not found the name for this device.\r
2518**/\r
2519BOOLEAN\r
2520OpalDriverGetDriverDeviceName(\r
2521 OPAL_DRIVER_DEVICE *Dev\r
2522 )\r
2523{\r
2524 EFI_HANDLE* AllHandlesBuffer;\r
2525 UINTN NumAllHandles;\r
2526 EFI_STATUS Status;\r
2527\r
2528 if (Dev == NULL) {\r
2529 DEBUG((DEBUG_ERROR | DEBUG_INIT, "OpalDriverGetDriverDeviceName Exiting, Dev=NULL\n"));\r
2530 return FALSE;\r
2531 }\r
2532\r
2533 //\r
2534 // Iterate through ComponentName2 handles to get name, if fails, try ComponentName\r
2535 //\r
2536 if (Dev->Name16 == NULL) {\r
2537 DEBUG((DEBUG_ERROR | DEBUG_INIT, "Name is null, update it\n"));\r
2538 //\r
2539 // Find all EFI_HANDLES\r
2540 //\r
2541 Status = gBS->LocateHandleBuffer(\r
2542 AllHandles,\r
2543 NULL,\r
2544 NULL,\r
2545 &NumAllHandles,\r
2546 &AllHandlesBuffer\r
2547 );\r
2548 if (EFI_ERROR(Status)) {\r
2549 DEBUG ((DEBUG_INFO, "LocateHandleBuffer for AllHandles failed %r\n", Status ));\r
2550 return FALSE;\r
2551 }\r
2552\r
2553 //\r
2554 // Try component Name2\r
2555 //\r
2556 if (!OpalDriverGetDeviceNameByProtocol(AllHandlesBuffer, NumAllHandles, Dev, FALSE)) {\r
2557 DEBUG((DEBUG_ERROR | DEBUG_INIT, "ComponentName2 failed to get device name, try ComponentName\n"));\r
2558 if (!OpalDriverGetDeviceNameByProtocol(AllHandlesBuffer, NumAllHandles, Dev, TRUE)) {\r
2559 DEBUG((DEBUG_ERROR | DEBUG_INIT, "ComponentName failed to get device name, skip device\n"));\r
2560 return FALSE;\r
2561 }\r
2562 }\r
2563 }\r
2564\r
2565 return TRUE;\r
2566}\r
2567\r
2568/**\r
2569 Main entry for this driver.\r
2570\r
2571 @param ImageHandle Image Handle this driver.\r
2572 @param SystemTable Pointer to SystemTable.\r
2573\r
2574 @retval EFI_SUCESS This function always complete successfully.\r
2575**/\r
2576EFI_STATUS\r
2577EFIAPI\r
2578EfiDriverEntryPoint(\r
2579 IN EFI_HANDLE ImageHandle,\r
2580 IN EFI_SYSTEM_TABLE* SystemTable\r
2581 )\r
2582{\r
2583 EFI_STATUS Status;\r
112e584b
SZ
2584 EFI_EVENT EndOfDxeEvent;\r
2585\r
2586 Status = EfiLibInstallDriverBindingComponentName2 (\r
2587 ImageHandle,\r
2588 SystemTable,\r
2589 &gOpalDriverBinding,\r
2590 ImageHandle,\r
2591 &gOpalComponentName,\r
2592 &gOpalComponentName2\r
2593 );\r
2594\r
2595 if (EFI_ERROR(Status)) {\r
2596 DEBUG((DEBUG_ERROR, "Install protocols to Opal driver Handle failed\n"));\r
2597 return Status ;\r
2598 }\r
2599\r
2600 //\r
2601 // Initialize Driver object\r
2602 //\r
2603 ZeroMem(&mOpalDriver, sizeof(mOpalDriver));\r
2604 mOpalDriver.Handle = ImageHandle;\r
2605\r
2606 Status = gBS->CreateEventEx (\r
2607 EVT_NOTIFY_SIGNAL,\r
2608 TPL_CALLBACK,\r
2609 OpalEndOfDxeEventNotify,\r
2610 NULL,\r
2611 &gEfiEndOfDxeEventGroupGuid,\r
2612 &EndOfDxeEvent\r
2613 );\r
2614 ASSERT_EFI_ERROR (Status);\r
2615\r
112e584b
SZ
2616 //\r
2617 // Install Hii packages.\r
2618 //\r
2619 HiiInstall();\r
2620\r
2621 return Status;\r
2622}\r
2623\r
2624/**\r
2625 Tests to see if this driver supports a given controller.\r
2626\r
2627 This function checks to see if the controller contains an instance of the\r
2628 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL and the EFI_BLOCK_IO_PROTOCL\r
2629 and returns EFI_SUCCESS if it does.\r
2630\r
2631 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
2632 @param[in] ControllerHandle The Handle of the controller to test. This Handle\r
2633 must support a protocol interface that supplies\r
2634 an I/O abstraction to the driver.\r
2635 @param[in] RemainingDevicePath This parameter is ignored.\r
2636\r
2637 @retval EFI_SUCCESS The device contains required protocols\r
2638 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and\r
2639 RemainingDevicePath is already being managed by the driver\r
2640 specified by This.\r
2641 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and\r
2642 RemainingDevicePath is already being managed by a different\r
2643 driver or an application that requires exclusive access.\r
2644 Currently not implemented.\r
2645 @retval EFI_UNSUPPORTED The device does not contain requires protocols\r
2646\r
2647**/\r
2648EFI_STATUS\r
2649EFIAPI\r
2650OpalEfiDriverBindingSupported(\r
2651 IN EFI_DRIVER_BINDING_PROTOCOL* This,\r
2652 IN EFI_HANDLE Controller,\r
2653 IN EFI_DEVICE_PATH_PROTOCOL* RemainingDevicePath\r
2654 )\r
2655{\r
2656 EFI_STATUS Status;\r
2657 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL* SecurityCommand;\r
2658 EFI_BLOCK_IO_PROTOCOL* BlkIo;\r
2659\r
2660 if (mOpalEndOfDxe) {\r
2661 return EFI_UNSUPPORTED;\r
2662 }\r
2663\r
2664 //\r
2665 // Test EFI_STORAGE_SECURITY_COMMAND_PROTOCOL on controller Handle.\r
2666 //\r
2667 Status = gBS->OpenProtocol(\r
2668 Controller,\r
2669 &gEfiStorageSecurityCommandProtocolGuid,\r
2670 ( VOID ** )&SecurityCommand,\r
2671 This->DriverBindingHandle,\r
2672 Controller,\r
2673 EFI_OPEN_PROTOCOL_BY_DRIVER\r
2674 );\r
2675\r
2676 if (Status == EFI_ALREADY_STARTED) {\r
2677 return EFI_SUCCESS;\r
2678 }\r
2679\r
2680 if (EFI_ERROR(Status)) {\r
2681 return Status;\r
2682 }\r
2683\r
2684 //\r
2685 // Close protocol and reopen in Start call\r
2686 //\r
2687 gBS->CloseProtocol(\r
2688 Controller,\r
2689 &gEfiStorageSecurityCommandProtocolGuid,\r
2690 This->DriverBindingHandle,\r
2691 Controller\r
2692 );\r
2693\r
2694 //\r
2695 // Test EFI_BLOCK_IO_PROTOCOL on controller Handle, required by EFI_STORAGE_SECURITY_COMMAND_PROTOCOL\r
2696 // function APIs\r
2697 //\r
2698 Status = gBS->OpenProtocol(\r
2699 Controller,\r
2700 &gEfiBlockIoProtocolGuid,\r
2701 (VOID **)&BlkIo,\r
2702 This->DriverBindingHandle,\r
2703 Controller,\r
2704 EFI_OPEN_PROTOCOL_BY_DRIVER\r
2705 );\r
2706\r
2707 if (EFI_ERROR(Status)) {\r
2708 DEBUG((DEBUG_INFO, "No EFI_BLOCK_IO_PROTOCOL on controller\n"));\r
2709 return Status;\r
2710 }\r
2711\r
2712 //\r
2713 // Close protocol and reopen in Start call\r
2714 //\r
2715 gBS->CloseProtocol(\r
2716 Controller,\r
2717 &gEfiBlockIoProtocolGuid,\r
2718 This->DriverBindingHandle,\r
2719 Controller\r
2720 );\r
2721\r
2722 return EFI_SUCCESS;\r
2723}\r
2724\r
2725/**\r
2726 Enables Opal Management on a supported device if available.\r
2727\r
2728 The start function is designed to be called after the Opal UEFI Driver has confirmed the\r
2729 "controller", which is a child Handle, contains the EF_STORAGE_SECURITY_COMMAND protocols.\r
2730 This function will complete the other necessary checks, such as verifying the device supports\r
2731 the correct version of Opal. Upon verification, it will add the device to the\r
2732 Opal HII list in order to expose Opal managmeent options.\r
2733\r
2734 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
2735 @param[in] ControllerHandle The Handle of the controller to start. This Handle\r
2736 must support a protocol interface that supplies\r
2737 an I/O abstraction to the driver.\r
2738 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This\r
2739 parameter is ignored by device drivers, and is optional for bus\r
2740 drivers. For a bus driver, if this parameter is NULL, then handles\r
2741 for all the children of Controller are created by this driver.\r
2742 If this parameter is not NULL and the first Device Path Node is\r
2743 not the End of Device Path Node, then only the Handle for the\r
2744 child device specified by the first Device Path Node of\r
2745 RemainingDevicePath is created by this driver.\r
2746 If the first Device Path Node of RemainingDevicePath is\r
2747 the End of Device Path Node, no child Handle is created by this\r
2748 driver.\r
2749\r
2750 @retval EFI_SUCCESS Opal management was enabled.\r
2751 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.\r
2752 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
2753 @retval Others The driver failed to start the device.\r
2754\r
2755**/\r
2756EFI_STATUS\r
2757EFIAPI\r
2758OpalEfiDriverBindingStart(\r
2759 IN EFI_DRIVER_BINDING_PROTOCOL* This,\r
2760 IN EFI_HANDLE Controller,\r
2761 IN EFI_DEVICE_PATH_PROTOCOL* RemainingDevicePath\r
2762 )\r
2763{\r
2764 EFI_STATUS Status;\r
2765 EFI_BLOCK_IO_PROTOCOL *BlkIo;\r
2766 OPAL_DRIVER_DEVICE *Dev;\r
2767 OPAL_DRIVER_DEVICE *Itr;\r
2768 BOOLEAN Result;\r
2769\r
2770 Itr = mOpalDriver.DeviceList;\r
2771 while (Itr != NULL) {\r
2772 if (Controller == Itr->Handle) {\r
2773 return EFI_SUCCESS;\r
2774 }\r
2775 Itr = Itr->Next;\r
2776 }\r
2777\r
2778 //\r
2779 // Create internal device for tracking. This allows all disks to be tracked\r
2780 // by same HII form\r
2781 //\r
2782 Dev = (OPAL_DRIVER_DEVICE*)AllocateZeroPool(sizeof(OPAL_DRIVER_DEVICE));\r
2783 if (Dev == NULL) {\r
2784 return EFI_OUT_OF_RESOURCES;\r
2785 }\r
2786 Dev->Handle = Controller;\r
2787\r
2788 //\r
2789 // Open EFI_STORAGE_SECURITY_COMMAND_PROTOCOL to perform Opal supported checks\r
2790 //\r
2791 Status = gBS->OpenProtocol(\r
2792 Controller,\r
2793 &gEfiStorageSecurityCommandProtocolGuid,\r
2794 (VOID **)&Dev->Sscp,\r
2795 This->DriverBindingHandle,\r
2796 Controller,\r
2797 EFI_OPEN_PROTOCOL_BY_DRIVER\r
2798 );\r
2799 if (EFI_ERROR(Status)) {\r
2800 FreePool(Dev);\r
2801 return Status;\r
2802 }\r
2803\r
2804 //\r
2805 // Open EFI_BLOCK_IO_PROTOCOL on controller Handle, required by EFI_STORAGE_SECURITY_COMMAND_PROTOCOL\r
2806 // function APIs\r
2807 //\r
2808 Status = gBS->OpenProtocol(\r
2809 Controller,\r
2810 &gEfiBlockIoProtocolGuid,\r
2811 (VOID **)&BlkIo,\r
2812 This->DriverBindingHandle,\r
2813 Controller,\r
2814 EFI_OPEN_PROTOCOL_BY_DRIVER\r
2815 );\r
2816 if (EFI_ERROR(Status)) {\r
2817 //\r
2818 // Close storage security that was opened\r
2819 //\r
2820 gBS->CloseProtocol(\r
2821 Controller,\r
2822 &gEfiStorageSecurityCommandProtocolGuid,\r
2823 This->DriverBindingHandle,\r
2824 Controller\r
2825 );\r
2826\r
2827 FreePool(Dev);\r
2828 return Status;\r
2829 }\r
2830\r
2831 //\r
2832 // Save mediaId\r
2833 //\r
2834 Dev->MediaId = BlkIo->Media->MediaId;\r
2835\r
2836 gBS->CloseProtocol(\r
2837 Controller,\r
2838 &gEfiBlockIoProtocolGuid,\r
2839 This->DriverBindingHandle,\r
2840 Controller\r
2841 );\r
2842\r
2843 //\r
2844 // Acquire Ascii printable name of child, if not found, then ignore device\r
2845 //\r
2846 Result = OpalDriverGetDriverDeviceName (Dev);\r
2847 if (!Result) {\r
2848 goto Done;\r
2849 }\r
2850\r
2851 Status = OpalDiskInitialize (Dev);\r
2852 if (EFI_ERROR (Status)) {\r
2853 goto Done;\r
2854 }\r
2855\r
2856 AddDeviceToTail(Dev);\r
2857\r
2858 //\r
2859 // Check if device is locked and prompt for password.\r
2860 //\r
2861 OpalDriverRequestPassword (Dev, L"Unlock:");\r
2862\r
2863 //\r
2864 // Process OPAL request from last boot.\r
2865 //\r
2866 ProcessOpalRequest (Dev);\r
2867\r
2868 return EFI_SUCCESS;\r
2869\r
2870Done:\r
2871 //\r
2872 // free device, close protocols and exit\r
2873 //\r
2874 gBS->CloseProtocol(\r
2875 Controller,\r
2876 &gEfiStorageSecurityCommandProtocolGuid,\r
2877 This->DriverBindingHandle,\r
2878 Controller\r
2879 );\r
2880\r
2881 FreePool(Dev);\r
2882\r
2883 return EFI_DEVICE_ERROR;\r
2884}\r
2885\r
2886/**\r
2887 Stop this driver on Controller.\r
2888\r
2889 @param This Protocol instance pointer.\r
2890 @param Controller Handle of device to stop driver on\r
2891 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of\r
2892 children is zero stop the entire bus driver.\r
2893 @param ChildHandleBuffer List of Child Handles to Stop.\r
2894\r
2895 @retval EFI_SUCCESS This driver is removed Controller.\r
2896 @retval other This driver could not be removed from this device.\r
2897\r
2898**/\r
2899EFI_STATUS\r
2900EFIAPI\r
2901OpalEfiDriverBindingStop(\r
2902 EFI_DRIVER_BINDING_PROTOCOL* This,\r
2903 EFI_HANDLE Controller,\r
2904 UINTN NumberOfChildren,\r
2905 EFI_HANDLE* ChildHandleBuffer\r
2906 )\r
2907{\r
2908 OPAL_DRIVER_DEVICE* Itr;\r
2909\r
2910 Itr = mOpalDriver.DeviceList;\r
2911\r
2912 //\r
2913 // does Controller match any of the devices we are managing for Opal\r
2914 //\r
2915 while (Itr != NULL) {\r
2916 if (Itr->Handle == Controller) {\r
2917 OpalDriverStopDevice (Itr);\r
2918 return EFI_SUCCESS;\r
2919 }\r
2920\r
2921 Itr = Itr->Next;\r
2922 }\r
2923\r
2924 return EFI_NOT_FOUND;\r
2925}\r
2926\r
2927\r
2928/**\r
2929 Unloads UEFI Driver. Very useful for debugging and testing.\r
2930\r
2931 @param ImageHandle Image Handle this driver.\r
2932\r
2933 @retval EFI_SUCCESS This function always complete successfully.\r
2934 @retval EFI_INVALID_PARAMETER The input ImageHandle is not valid.\r
2935**/\r
2936EFI_STATUS\r
2937EFIAPI\r
2938OpalEfiDriverUnload (\r
2939 IN EFI_HANDLE ImageHandle\r
2940 )\r
2941{\r
2942 EFI_STATUS Status;\r
2943 OPAL_DRIVER_DEVICE *Itr;\r
2944\r
2945 Status = EFI_SUCCESS;\r
2946\r
2947 if (ImageHandle != gImageHandle) {\r
2948 return (EFI_INVALID_PARAMETER);\r
2949 }\r
2950\r
2951 //\r
2952 // Uninstall any interface added to each device by us\r
2953 //\r
2954 while (mOpalDriver.DeviceList) {\r
2955 Itr = mOpalDriver.DeviceList;\r
2956 //\r
2957 // Remove OPAL_DRIVER_DEVICE from the list\r
2958 // it updates the controllerList pointer\r
2959 //\r
2960 OpalDriverStopDevice(Itr);\r
2961 }\r
2962\r
2963 //\r
2964 // Uninstall the HII capability\r
2965 //\r
2966 Status = HiiUninstall();\r
2967\r
2968 return Status;\r
2969}\r
2970\r