]> git.proxmox.com Git - mirror_edk2.git/blame - SecurityPkg/Tcg/Opal/OpalPassword/OpalDriver.c
SecurityPkg: Fix spelling errors
[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
6cbed0e3
CM
902 //\r
903 // Add PcdSkipOpalPasswordPrompt to determin whether to skip password prompt.\r
904 // Due to board design, device may not power off during system warm boot, which result in\r
905 // security status remain unlocked status, hence we add device security status check here.\r
906 //\r
907 // If device is in the locked status, device keeps locked and system continues booting.\r
908 // If device is in the unlocked status, system is forced shutdown to support security requirement.\r
909 //\r
910 if (PcdGetBool (PcdSkipOpalPasswordPrompt)) {\r
911 if (IsLocked) {\r
912 return;\r
913 } else {\r
914 gRT->ResetSystem (EfiResetShutdown, EFI_SUCCESS, 0, NULL);\r
915 }\r
8a9301cd
CM
916 }\r
917\r
112e584b 918 while (Count < MAX_PASSWORD_TRY_COUNT) {\r
f5245a1d 919 Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, NULL, NULL, &PressEsc);\r
112e584b
SZ
920 if (PressEsc) {\r
921 if (IsLocked) {\r
922 //\r
923 // Current device in the lock status and\r
924 // User not input password and press ESC,\r
925 // keep device in lock status and continue boot.\r
926 //\r
927 do {\r
928 CreatePopUp (\r
929 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
930 &Key,\r
931 L"Press ENTER to skip the request and continue boot,",\r
932 L"Press ESC to input password again",\r
933 NULL\r
934 );\r
935 } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));\r
936\r
937 if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
938 gST->ConOut->ClearScreen(gST->ConOut);\r
939 //\r
940 // Keep lock and continue boot.\r
941 //\r
942 return;\r
943 } else {\r
944 //\r
945 // Let user input password again.\r
946 //\r
947 continue;\r
948 }\r
949 } else {\r
950 //\r
951 // Current device in the unlock status and\r
952 // User not input password and press ESC,\r
953 // Shutdown the device.\r
954 //\r
955 do {\r
956 CreatePopUp (\r
957 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
958 &Key,\r
959 L"Press ENTER to shutdown, Press ESC to input password again",\r
960 NULL\r
961 );\r
962 } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));\r
963\r
964 if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
965 gRT->ResetSystem (EfiResetShutdown, EFI_SUCCESS, 0, NULL);\r
966 } else {\r
967 //\r
968 // Let user input password again.\r
969 //\r
970 continue;\r
971 }\r
972 }\r
973 }\r
974\r
975 if (Password == NULL) {\r
976 Count ++;\r
977 continue;\r
978 }\r
979 PasswordLen = (UINT32) AsciiStrLen(Password);\r
980\r
981 if (IsLocked) {\r
982 Ret = OpalUtilUpdateGlobalLockingRange(&Session, Password, PasswordLen, FALSE, FALSE);\r
983 } else {\r
984 Ret = OpalUtilUpdateGlobalLockingRange(&Session, Password, PasswordLen, TRUE, TRUE);\r
985 if (Ret == TcgResultSuccess) {\r
986 Ret = OpalUtilUpdateGlobalLockingRange(&Session, Password, PasswordLen, FALSE, FALSE);\r
987 }\r
988 }\r
989\r
990 if (Ret == TcgResultSuccess) {\r
991 OpalSupportUpdatePassword (&Dev->OpalDisk, Password, PasswordLen);\r
992 DEBUG ((DEBUG_INFO, "%s Success\n", RequestString));\r
993 } else {\r
994 DEBUG ((DEBUG_INFO, "%s Failure\n", RequestString));\r
995 }\r
996\r
997 if (Password != NULL) {\r
998 ZeroMem (Password, PasswordLen);\r
999 FreePool (Password);\r
1000 }\r
1001\r
1002 if (Ret == TcgResultSuccess) {\r
1003 break;\r
1004 }\r
1005\r
e4e314b1
ED
1006 //\r
1007 // Check whether opal device's Tries value has reach the TryLimit value, if yes, force a shutdown\r
1008 // before accept new password.\r
1009 //\r
1010 if (Ret == TcgResultFailureInvalidType) {\r
1011 Count = MAX_PASSWORD_TRY_COUNT;\r
1012 break;\r
1013 }\r
1014\r
112e584b
SZ
1015 Count++;\r
1016\r
1017 do {\r
1018 CreatePopUp (\r
1019 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1020 &Key,\r
1021 L"Invalid password.",\r
1022 L"Press ENTER to retry",\r
1023 NULL\r
1024 );\r
1025 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
1026 }\r
1027\r
1028 if (Count >= MAX_PASSWORD_TRY_COUNT) {\r
1029 do {\r
1030 CreatePopUp (\r
1031 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1032 &Key,\r
1033 L"Opal password retry count exceeds the limit. Must shutdown!",\r
1034 L"Press ENTER to shutdown",\r
1035 NULL\r
1036 );\r
1037 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
1038\r
1039 gRT->ResetSystem (EfiResetShutdown, EFI_SUCCESS, 0, NULL);\r
1040 }\r
1041 }\r
1042}\r
1043\r
1044/**\r
1045 Process Enable Feature OPAL request.\r
1046\r
1047 @param[in] Dev The device which has Enable Feature OPAL request.\r
1048 @param[in] RequestString Request string.\r
1049\r
1050**/\r
1051VOID\r
1052ProcessOpalRequestEnableFeature (\r
1053 IN OPAL_DRIVER_DEVICE *Dev,\r
1054 IN CHAR16 *RequestString\r
1055 )\r
1056{\r
1057 UINT8 Count;\r
1058 CHAR8 *Password;\r
1059 UINT32 PasswordLen;\r
1060 CHAR8 *PasswordConfirm;\r
1061 UINT32 PasswordLenConfirm;\r
1062 OPAL_SESSION Session;\r
1063 BOOLEAN PressEsc;\r
1064 EFI_INPUT_KEY Key;\r
1065 TCG_RESULT Ret;\r
1066 CHAR16 *PopUpString;\r
1067\r
1068 if (Dev == NULL) {\r
1069 return;\r
1070 }\r
1071\r
1072 DEBUG ((DEBUG_INFO, "%a()\n", __FUNCTION__));\r
1073\r
1074 PopUpString = OpalGetPopUpString (Dev, RequestString);\r
1075\r
1076 Count = 0;\r
1077\r
1078 ZeroMem(&Session, sizeof(Session));\r
1079 Session.Sscp = Dev->OpalDisk.Sscp;\r
1080 Session.MediaId = Dev->OpalDisk.MediaId;\r
1081 Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;\r
1082\r
1083 while (Count < MAX_PASSWORD_TRY_COUNT) {\r
f5245a1d 1084 Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please type in your new password", NULL, &PressEsc);\r
112e584b
SZ
1085 if (PressEsc) {\r
1086 do {\r
1087 CreatePopUp (\r
1088 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1089 &Key,\r
1090 L"Press ENTER to skip the request and continue boot,",\r
1091 L"Press ESC to input password again",\r
1092 NULL\r
1093 );\r
1094 } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));\r
1095\r
1096 if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
1097 gST->ConOut->ClearScreen(gST->ConOut);\r
1098 return;\r
1099 } else {\r
1100 //\r
1101 // Let user input password again.\r
1102 //\r
1103 continue;\r
1104 }\r
1105 }\r
1106\r
1107 if (Password == NULL) {\r
1108 Count ++;\r
1109 continue;\r
1110 }\r
1111 PasswordLen = (UINT32) AsciiStrLen(Password);\r
1112\r
f5245a1d 1113 PasswordConfirm = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please confirm your new password", NULL, &PressEsc);\r
112e584b
SZ
1114 if (PasswordConfirm == NULL) {\r
1115 ZeroMem (Password, PasswordLen);\r
1116 FreePool (Password);\r
1117 Count ++;\r
1118 continue;\r
1119 }\r
1120 PasswordLenConfirm = (UINT32) AsciiStrLen(PasswordConfirm);\r
1121 if ((PasswordLen != PasswordLenConfirm) ||\r
1122 (CompareMem (Password, PasswordConfirm, PasswordLen) != 0)) {\r
1123 ZeroMem (Password, PasswordLen);\r
1124 FreePool (Password);\r
1125 ZeroMem (PasswordConfirm, PasswordLenConfirm);\r
1126 FreePool (PasswordConfirm);\r
1127 do {\r
1128 CreatePopUp (\r
1129 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1130 &Key,\r
1131 L"Passwords are not the same.",\r
1132 L"Press ENTER to retry",\r
1133 NULL\r
1134 );\r
1135 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
1136 Count ++;\r
1137 continue;\r
1138 }\r
1139\r
1140 if (PasswordConfirm != NULL) {\r
1141 ZeroMem (PasswordConfirm, PasswordLenConfirm);\r
1142 FreePool (PasswordConfirm);\r
1143 }\r
1144\r
1145 Ret = OpalSupportEnableOpalFeature (&Session, Dev->OpalDisk.Msid, Dev->OpalDisk.MsidLength, Password, PasswordLen);\r
1146 if (Ret == TcgResultSuccess) {\r
1147 OpalSupportUpdatePassword (&Dev->OpalDisk, Password, PasswordLen);\r
1148 DEBUG ((DEBUG_INFO, "%s Success\n", RequestString));\r
1149 } else {\r
1150 DEBUG ((DEBUG_INFO, "%s Failure\n", RequestString));\r
1151 }\r
1152\r
1153 if (Password != NULL) {\r
1154 ZeroMem (Password, PasswordLen);\r
1155 FreePool (Password);\r
1156 }\r
1157\r
1158 if (Ret == TcgResultSuccess) {\r
1159 break;\r
1160 }\r
1161\r
1162 Count++;\r
1163\r
1164 do {\r
1165 CreatePopUp (\r
1166 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1167 &Key,\r
1168 L"Request failed.",\r
1169 L"Press ENTER to retry",\r
1170 NULL\r
1171 );\r
1172 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
1173 }\r
1174\r
1175 if (Count >= MAX_PASSWORD_TRY_COUNT) {\r
1176 do {\r
1177 CreatePopUp (\r
1178 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1179 &Key,\r
1180 L"Opal password retry count exceeds the limit.",\r
1181 L"Press ENTER to skip the request and continue boot",\r
1182 NULL\r
1183 );\r
1184 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
1185 gST->ConOut->ClearScreen(gST->ConOut);\r
1186 }\r
1187}\r
1188\r
1189/**\r
1190 Process Disable User OPAL request.\r
1191\r
1192 @param[in] Dev The device which has Disable User OPAL request.\r
1193 @param[in] RequestString Request string.\r
1194\r
1195**/\r
1196VOID\r
1197ProcessOpalRequestDisableUser (\r
1198 IN OPAL_DRIVER_DEVICE *Dev,\r
1199 IN CHAR16 *RequestString\r
1200 )\r
1201{\r
1202 UINT8 Count;\r
1203 CHAR8 *Password;\r
1204 UINT32 PasswordLen;\r
1205 OPAL_SESSION Session;\r
1206 BOOLEAN PressEsc;\r
1207 EFI_INPUT_KEY Key;\r
1208 TCG_RESULT Ret;\r
1209 BOOLEAN PasswordFailed;\r
1210 CHAR16 *PopUpString;\r
1211\r
1212 if (Dev == NULL) {\r
1213 return;\r
1214 }\r
1215\r
1216 DEBUG ((DEBUG_INFO, "%a()\n", __FUNCTION__));\r
1217\r
1218 PopUpString = OpalGetPopUpString (Dev, RequestString);\r
1219\r
1220 Count = 0;\r
1221\r
1222 ZeroMem(&Session, sizeof(Session));\r
1223 Session.Sscp = Dev->OpalDisk.Sscp;\r
1224 Session.MediaId = Dev->OpalDisk.MediaId;\r
1225 Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;\r
1226\r
1227 while (Count < MAX_PASSWORD_TRY_COUNT) {\r
f5245a1d 1228 Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, NULL, NULL, &PressEsc);\r
112e584b
SZ
1229 if (PressEsc) {\r
1230 do {\r
1231 CreatePopUp (\r
1232 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1233 &Key,\r
1234 L"Press ENTER to skip the request and continue boot,",\r
1235 L"Press ESC to input password again",\r
1236 NULL\r
1237 );\r
1238 } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));\r
1239\r
1240 if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
1241 gST->ConOut->ClearScreen(gST->ConOut);\r
1242 return;\r
1243 } else {\r
1244 //\r
1245 // Let user input password again.\r
1246 //\r
1247 continue;\r
1248 }\r
1249 }\r
1250\r
1251 if (Password == NULL) {\r
1252 Count ++;\r
1253 continue;\r
1254 }\r
1255 PasswordLen = (UINT32) AsciiStrLen(Password);\r
1256\r
1257 Ret = OpalUtilDisableUser(&Session, Password, PasswordLen, &PasswordFailed);\r
1258 if (Ret == TcgResultSuccess) {\r
1259 OpalSupportUpdatePassword (&Dev->OpalDisk, Password, PasswordLen);\r
1260 DEBUG ((DEBUG_INFO, "%s Success\n", RequestString));\r
1261 } else {\r
1262 DEBUG ((DEBUG_INFO, "%s Failure\n", RequestString));\r
1263 }\r
1264\r
1265 if (Password != NULL) {\r
1266 ZeroMem (Password, PasswordLen);\r
1267 FreePool (Password);\r
1268 }\r
1269\r
1270 if (Ret == TcgResultSuccess) {\r
1271 break;\r
1272 }\r
1273\r
1274 Count++;\r
1275\r
1276 do {\r
1277 CreatePopUp (\r
1278 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1279 &Key,\r
1280 L"Invalid password, request failed.",\r
1281 L"Press ENTER to retry",\r
1282 NULL\r
1283 );\r
1284 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
1285 }\r
1286\r
1287 if (Count >= MAX_PASSWORD_TRY_COUNT) {\r
1288 do {\r
1289 CreatePopUp (\r
1290 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1291 &Key,\r
1292 L"Opal password retry count exceeds the limit.",\r
1293 L"Press ENTER to skip the request and continue boot",\r
1294 NULL\r
1295 );\r
1296 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
1297 gST->ConOut->ClearScreen(gST->ConOut);\r
1298 }\r
1299}\r
1300\r
1301/**\r
1302 Process Psid Revert OPAL request.\r
1303\r
1304 @param[in] Dev The device which has Psid Revert OPAL request.\r
1305 @param[in] RequestString Request string.\r
1306\r
1307**/\r
1308VOID\r
1309ProcessOpalRequestPsidRevert (\r
1310 IN OPAL_DRIVER_DEVICE *Dev,\r
1311 IN CHAR16 *RequestString\r
1312 )\r
1313{\r
1314 UINT8 Count;\r
1315 CHAR8 *Psid;\r
1316 UINT32 PsidLen;\r
1317 OPAL_SESSION Session;\r
1318 BOOLEAN PressEsc;\r
1319 EFI_INPUT_KEY Key;\r
1320 TCG_RESULT Ret;\r
1321 CHAR16 *PopUpString;\r
40d32e79 1322 CHAR16 *PopUpString2;\r
f5245a1d 1323 CHAR16 *PopUpString3;\r
40d32e79 1324 UINTN BufferSize;\r
112e584b
SZ
1325\r
1326 if (Dev == NULL) {\r
1327 return;\r
1328 }\r
1329\r
1330 DEBUG ((DEBUG_INFO, "%a()\n", __FUNCTION__));\r
1331\r
1332 PopUpString = OpalGetPopUpString (Dev, RequestString);\r
1333\r
40d32e79 1334 if (Dev->OpalDisk.EstimateTimeCost > MAX_ACCEPTABLE_REVERTING_TIME) {\r
f5245a1d 1335 BufferSize = StrSize (L"Warning: Revert action will take about ####### seconds");\r
40d32e79
ED
1336 PopUpString2 = AllocateZeroPool (BufferSize);\r
1337 ASSERT (PopUpString2 != NULL);\r
1338 UnicodeSPrint (\r
1339 PopUpString2,\r
1340 BufferSize,\r
f5245a1d 1341 L"WARNING: Revert action will take about %d seconds",\r
40d32e79
ED
1342 Dev->OpalDisk.EstimateTimeCost\r
1343 );\r
f5245a1d 1344 PopUpString3 = L"DO NOT power off system during the revert action!";\r
40d32e79
ED
1345 } else {\r
1346 PopUpString2 = NULL;\r
f5245a1d 1347 PopUpString3 = NULL;\r
40d32e79
ED
1348 }\r
1349\r
112e584b
SZ
1350 Count = 0;\r
1351\r
1352 ZeroMem(&Session, sizeof(Session));\r
1353 Session.Sscp = Dev->OpalDisk.Sscp;\r
1354 Session.MediaId = Dev->OpalDisk.MediaId;\r
1355 Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;\r
1356\r
1357 while (Count < MAX_PSID_TRY_COUNT) {\r
f5245a1d 1358 Psid = OpalDriverPopUpPsidInput (Dev, PopUpString, PopUpString2, PopUpString3, &PressEsc);\r
112e584b
SZ
1359 if (PressEsc) {\r
1360 do {\r
1361 CreatePopUp (\r
1362 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1363 &Key,\r
1364 L"Press ENTER to skip the request and continue boot,",\r
1365 L"Press ESC to input Psid again",\r
1366 NULL\r
1367 );\r
1368 } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));\r
1369\r
1370 if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
1371 gST->ConOut->ClearScreen(gST->ConOut);\r
40d32e79 1372 goto Done;\r
112e584b
SZ
1373 } else {\r
1374 //\r
1375 // Let user input Psid again.\r
1376 //\r
1377 continue;\r
1378 }\r
1379 }\r
1380\r
1381 if (Psid == NULL) {\r
1382 Count ++;\r
1383 continue;\r
1384 }\r
1385 PsidLen = (UINT32) AsciiStrLen(Psid);\r
1386\r
1387 Ret = OpalUtilPsidRevert(&Session, Psid, PsidLen);\r
1388 if (Ret == TcgResultSuccess) {\r
1389 DEBUG ((DEBUG_INFO, "%s Success\n", RequestString));\r
1390 } else {\r
1391 DEBUG ((DEBUG_INFO, "%s Failure\n", RequestString));\r
1392 }\r
1393\r
1394 if (Psid != NULL) {\r
1395 ZeroMem (Psid, PsidLen);\r
1396 FreePool (Psid);\r
1397 }\r
1398\r
1399 if (Ret == TcgResultSuccess) {\r
1400 break;\r
1401 }\r
1402\r
1403 Count++;\r
1404\r
1405 do {\r
1406 CreatePopUp (\r
1407 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1408 &Key,\r
1409 L"Invalid Psid, request failed.",\r
1410 L"Press ENTER to retry",\r
1411 NULL\r
1412 );\r
1413 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
1414 }\r
1415\r
1416 if (Count >= MAX_PSID_TRY_COUNT) {\r
1417 do {\r
1418 CreatePopUp (\r
1419 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1420 &Key,\r
1421 L"Opal Psid retry count exceeds the limit.",\r
1422 L"Press ENTER to skip the request and continue boot",\r
1423 NULL\r
1424 );\r
1425 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
1426 gST->ConOut->ClearScreen(gST->ConOut);\r
1427 }\r
40d32e79
ED
1428\r
1429Done:\r
1430 if (PopUpString2 != NULL) {\r
1431 FreePool (PopUpString2);\r
1432 }\r
112e584b
SZ
1433}\r
1434\r
1435/**\r
1436 Process Admin Revert OPAL request.\r
1437\r
1438 @param[in] Dev The device which has Revert OPAL request.\r
1439 @param[in] KeepUserData Whether to keep user data or not.\r
1440 @param[in] RequestString Request string.\r
1441\r
1442**/\r
1443VOID\r
1444ProcessOpalRequestRevert (\r
1445 IN OPAL_DRIVER_DEVICE *Dev,\r
1446 IN BOOLEAN KeepUserData,\r
1447 IN CHAR16 *RequestString\r
1448 )\r
1449{\r
1450 UINT8 Count;\r
1451 CHAR8 *Password;\r
1452 UINT32 PasswordLen;\r
1453 OPAL_SESSION Session;\r
1454 BOOLEAN PressEsc;\r
1455 EFI_INPUT_KEY Key;\r
1456 TCG_RESULT Ret;\r
1457 BOOLEAN PasswordFailed;\r
1458 CHAR16 *PopUpString;\r
40d32e79 1459 CHAR16 *PopUpString2;\r
f5245a1d 1460 CHAR16 *PopUpString3;\r
40d32e79 1461 UINTN BufferSize;\r
112e584b
SZ
1462\r
1463 if (Dev == NULL) {\r
1464 return;\r
1465 }\r
1466\r
1467 DEBUG ((DEBUG_INFO, "%a()\n", __FUNCTION__));\r
1468\r
1469 PopUpString = OpalGetPopUpString (Dev, RequestString);\r
1470\r
4ec00f82
CM
1471 if ((!KeepUserData) &&\r
1472 (Dev->OpalDisk.EstimateTimeCost > MAX_ACCEPTABLE_REVERTING_TIME)) {\r
f5245a1d 1473 BufferSize = StrSize (L"Warning: Revert action will take about ####### seconds");\r
40d32e79
ED
1474 PopUpString2 = AllocateZeroPool (BufferSize);\r
1475 ASSERT (PopUpString2 != NULL);\r
1476 UnicodeSPrint (\r
1477 PopUpString2,\r
1478 BufferSize,\r
f5245a1d 1479 L"WARNING: Revert action will take about %d seconds",\r
40d32e79
ED
1480 Dev->OpalDisk.EstimateTimeCost\r
1481 );\r
f5245a1d 1482 PopUpString3 = L"DO NOT power off system during the revert action!";\r
40d32e79
ED
1483 } else {\r
1484 PopUpString2 = NULL;\r
f5245a1d 1485 PopUpString3 = NULL;\r
40d32e79
ED
1486 }\r
1487\r
112e584b
SZ
1488 Count = 0;\r
1489\r
1490 ZeroMem(&Session, sizeof(Session));\r
1491 Session.Sscp = Dev->OpalDisk.Sscp;\r
1492 Session.MediaId = Dev->OpalDisk.MediaId;\r
1493 Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;\r
1494\r
1495 while (Count < MAX_PASSWORD_TRY_COUNT) {\r
f5245a1d 1496 Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, PopUpString2, PopUpString3, &PressEsc);\r
112e584b
SZ
1497 if (PressEsc) {\r
1498 do {\r
1499 CreatePopUp (\r
1500 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1501 &Key,\r
1502 L"Press ENTER to skip the request and continue boot,",\r
1503 L"Press ESC to input password again",\r
1504 NULL\r
1505 );\r
1506 } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));\r
1507\r
1508 if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
1509 gST->ConOut->ClearScreen(gST->ConOut);\r
40d32e79 1510 goto Done;\r
112e584b
SZ
1511 } else {\r
1512 //\r
1513 // Let user input password again.\r
1514 //\r
1515 continue;\r
1516 }\r
1517 }\r
1518\r
1519 if (Password == NULL) {\r
1520 Count ++;\r
1521 continue;\r
1522 }\r
1523 PasswordLen = (UINT32) AsciiStrLen(Password);\r
1524\r
1525 if ((Dev->OpalDisk.SupportedAttributes.PyriteSsc == 1) &&\r
1526 (Dev->OpalDisk.LockingFeature.MediaEncryption == 0)) {\r
1527 //\r
1528 // For pyrite type device which does not support media encryption,\r
1529 // it does not accept "Keep User Data" parameter.\r
1530 // So here hardcode a FALSE for this case.\r
1531 //\r
1532 Ret = OpalUtilRevert(\r
1533 &Session,\r
1534 FALSE,\r
1535 Password,\r
1536 PasswordLen,\r
1537 &PasswordFailed,\r
1538 Dev->OpalDisk.Msid,\r
1539 Dev->OpalDisk.MsidLength\r
1540 );\r
1541 } else {\r
1542 Ret = OpalUtilRevert(\r
1543 &Session,\r
1544 KeepUserData,\r
1545 Password,\r
1546 PasswordLen,\r
1547 &PasswordFailed,\r
1548 Dev->OpalDisk.Msid,\r
1549 Dev->OpalDisk.MsidLength\r
1550 );\r
1551 }\r
1552 if (Ret == TcgResultSuccess) {\r
1553 OpalSupportUpdatePassword (&Dev->OpalDisk, Password, PasswordLen);\r
1554 DEBUG ((DEBUG_INFO, "%s Success\n", RequestString));\r
1555 } else {\r
1556 DEBUG ((DEBUG_INFO, "%s Failure\n", RequestString));\r
1557 }\r
1558\r
1559 if (Password != NULL) {\r
1560 ZeroMem (Password, PasswordLen);\r
1561 FreePool (Password);\r
1562 }\r
1563\r
1564 if (Ret == TcgResultSuccess) {\r
1565 break;\r
1566 }\r
1567\r
1568 Count++;\r
1569\r
1570 do {\r
1571 CreatePopUp (\r
1572 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1573 &Key,\r
1574 L"Invalid password, request failed.",\r
1575 L"Press ENTER to retry",\r
1576 NULL\r
1577 );\r
1578 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
1579 }\r
1580\r
1581 if (Count >= MAX_PASSWORD_TRY_COUNT) {\r
1582 do {\r
1583 CreatePopUp (\r
1584 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1585 &Key,\r
1586 L"Opal password retry count exceeds the limit.",\r
1587 L"Press ENTER to skip the request and continue boot",\r
1588 NULL\r
1589 );\r
1590 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
1591 gST->ConOut->ClearScreen(gST->ConOut);\r
1592 }\r
40d32e79
ED
1593\r
1594Done:\r
1595 if (PopUpString2 != NULL) {\r
1596 FreePool (PopUpString2);\r
1597 }\r
112e584b
SZ
1598}\r
1599\r
1600/**\r
1601 Process Secure Erase OPAL request.\r
1602\r
1603 @param[in] Dev The device which has Secure Erase OPAL request.\r
1604 @param[in] RequestString Request string.\r
1605\r
1606**/\r
1607VOID\r
1608ProcessOpalRequestSecureErase (\r
1609 IN OPAL_DRIVER_DEVICE *Dev,\r
1610 IN CHAR16 *RequestString\r
1611 )\r
1612{\r
1613 UINT8 Count;\r
1614 CHAR8 *Password;\r
1615 UINT32 PasswordLen;\r
1616 OPAL_SESSION Session;\r
1617 BOOLEAN PressEsc;\r
1618 EFI_INPUT_KEY Key;\r
1619 TCG_RESULT Ret;\r
1620 BOOLEAN PasswordFailed;\r
1621 CHAR16 *PopUpString;\r
f5245a1d
CM
1622 CHAR16 *PopUpString2;\r
1623 CHAR16 *PopUpString3;\r
1624 UINTN BufferSize;\r
112e584b
SZ
1625\r
1626 if (Dev == NULL) {\r
1627 return;\r
1628 }\r
1629\r
1630 DEBUG ((DEBUG_INFO, "%a()\n", __FUNCTION__));\r
1631\r
1632 PopUpString = OpalGetPopUpString (Dev, RequestString);\r
1633\r
f5245a1d
CM
1634 if (Dev->OpalDisk.EstimateTimeCost > MAX_ACCEPTABLE_REVERTING_TIME) {\r
1635 BufferSize = StrSize (L"Warning: Secure erase action will take about ####### seconds");\r
1636 PopUpString2 = AllocateZeroPool (BufferSize);\r
1637 ASSERT (PopUpString2 != NULL);\r
1638 UnicodeSPrint (\r
1639 PopUpString2,\r
1640 BufferSize,\r
1641 L"WARNING: Secure erase action will take about %d seconds",\r
1642 Dev->OpalDisk.EstimateTimeCost\r
1643 );\r
1644 PopUpString3 = L"DO NOT power off system during the action!";\r
1645 } else {\r
1646 PopUpString2 = NULL;\r
1647 PopUpString3 = NULL;\r
1648 }\r
112e584b
SZ
1649 Count = 0;\r
1650\r
1651 ZeroMem(&Session, sizeof(Session));\r
1652 Session.Sscp = Dev->OpalDisk.Sscp;\r
1653 Session.MediaId = Dev->OpalDisk.MediaId;\r
1654 Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;\r
1655\r
1656 while (Count < MAX_PASSWORD_TRY_COUNT) {\r
f5245a1d 1657 Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, PopUpString2, PopUpString3, &PressEsc);\r
112e584b
SZ
1658 if (PressEsc) {\r
1659 do {\r
1660 CreatePopUp (\r
1661 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1662 &Key,\r
1663 L"Press ENTER to skip the request and continue boot,",\r
1664 L"Press ESC to input password again",\r
1665 NULL\r
1666 );\r
1667 } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));\r
1668\r
1669 if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
1670 gST->ConOut->ClearScreen(gST->ConOut);\r
f5245a1d 1671 goto Done;\r
112e584b
SZ
1672 } else {\r
1673 //\r
1674 // Let user input password again.\r
1675 //\r
1676 continue;\r
1677 }\r
1678 }\r
1679\r
1680 if (Password == NULL) {\r
1681 Count ++;\r
1682 continue;\r
1683 }\r
1684 PasswordLen = (UINT32) AsciiStrLen(Password);\r
1685\r
1686 Ret = OpalUtilSecureErase(&Session, Password, PasswordLen, &PasswordFailed);\r
1687 if (Ret == TcgResultSuccess) {\r
1688 OpalSupportUpdatePassword (&Dev->OpalDisk, Password, PasswordLen);\r
1689 DEBUG ((DEBUG_INFO, "%s Success\n", RequestString));\r
1690 } else {\r
1691 DEBUG ((DEBUG_INFO, "%s Failure\n", RequestString));\r
1692 }\r
1693\r
1694 if (Password != NULL) {\r
1695 ZeroMem (Password, PasswordLen);\r
1696 FreePool (Password);\r
1697 }\r
1698\r
1699 if (Ret == TcgResultSuccess) {\r
1700 break;\r
1701 }\r
1702\r
1703 Count++;\r
1704\r
1705 do {\r
1706 CreatePopUp (\r
1707 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1708 &Key,\r
1709 L"Invalid password, request failed.",\r
1710 L"Press ENTER to retry",\r
1711 NULL\r
1712 );\r
1713 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
1714 }\r
1715\r
1716 if (Count >= MAX_PASSWORD_TRY_COUNT) {\r
1717 do {\r
1718 CreatePopUp (\r
1719 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1720 &Key,\r
1721 L"Opal password retry count exceeds the limit.",\r
1722 L"Press ENTER to skip the request and continue boot",\r
1723 NULL\r
1724 );\r
1725 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
1726 gST->ConOut->ClearScreen(gST->ConOut);\r
1727 }\r
f5245a1d
CM
1728\r
1729Done:\r
1730 if (PopUpString2 != NULL) {\r
1731 FreePool (PopUpString2);\r
1732 }\r
112e584b
SZ
1733}\r
1734\r
1735/**\r
1736 Process Set Admin Pwd OPAL request.\r
1737\r
1738 @param[in] Dev The device which has Set Admin Pwd Feature OPAL request.\r
1739 @param[in] RequestString Request string.\r
1740\r
1741**/\r
1742VOID\r
1743ProcessOpalRequestSetUserPwd (\r
1744 IN OPAL_DRIVER_DEVICE *Dev,\r
1745 IN CHAR16 *RequestString\r
1746 )\r
1747{\r
1748 UINT8 Count;\r
1749 CHAR8 *OldPassword;\r
1750 UINT32 OldPasswordLen;\r
1751 CHAR8 *Password;\r
1752 UINT32 PasswordLen;\r
1753 CHAR8 *PasswordConfirm;\r
1754 UINT32 PasswordLenConfirm;\r
1755 OPAL_SESSION Session;\r
1756 BOOLEAN PressEsc;\r
1757 EFI_INPUT_KEY Key;\r
1758 TCG_RESULT Ret;\r
1759 CHAR16 *PopUpString;\r
1760\r
1761 if (Dev == NULL) {\r
1762 return;\r
1763 }\r
1764\r
1765 DEBUG ((DEBUG_INFO, "%a()\n", __FUNCTION__));\r
1766\r
1767 PopUpString = OpalGetPopUpString (Dev, RequestString);\r
1768\r
1769 Count = 0;\r
1770\r
1771 while (Count < MAX_PASSWORD_TRY_COUNT) {\r
f5245a1d 1772 OldPassword = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please type in your password", NULL, &PressEsc);\r
112e584b
SZ
1773 if (PressEsc) {\r
1774 do {\r
1775 CreatePopUp (\r
1776 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1777 &Key,\r
1778 L"Press ENTER to skip the request and continue boot,",\r
1779 L"Press ESC to input password again",\r
1780 NULL\r
1781 );\r
1782 } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));\r
1783\r
1784 if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
1785 gST->ConOut->ClearScreen(gST->ConOut);\r
1786 return;\r
1787 } else {\r
1788 //\r
1789 // Let user input password again.\r
1790 //\r
1791 continue;\r
1792 }\r
1793 }\r
1794\r
1795 if (OldPassword == NULL) {\r
1796 Count ++;\r
1797 continue;\r
1798 }\r
1799 OldPasswordLen = (UINT32) AsciiStrLen(OldPassword);\r
1800\r
1801 ZeroMem(&Session, sizeof(Session));\r
1802 Session.Sscp = Dev->OpalDisk.Sscp;\r
1803 Session.MediaId = Dev->OpalDisk.MediaId;\r
1804 Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;\r
1805 Ret = OpalUtilVerifyPassword (&Session, OldPassword, OldPasswordLen, OPAL_LOCKING_SP_USER1_AUTHORITY);\r
1806 if (Ret == TcgResultSuccess) {\r
1807 DEBUG ((DEBUG_INFO, "Verify with USER1 authority : Success\n"));\r
1808 } else {\r
1809 Ret = OpalUtilVerifyPassword (&Session, OldPassword, OldPasswordLen, OPAL_LOCKING_SP_ADMIN1_AUTHORITY);\r
1810 if (Ret == TcgResultSuccess) {\r
1811 DEBUG ((DEBUG_INFO, "Verify with ADMIN1 authority: Success\n"));\r
1812 } else {\r
1813 ZeroMem (OldPassword, OldPasswordLen);\r
1814 FreePool (OldPassword);\r
1815 DEBUG ((DEBUG_INFO, "Verify: Failure\n"));\r
1816 do {\r
1817 CreatePopUp (\r
1818 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1819 &Key,\r
1820 L"Incorrect password.",\r
1821 L"Press ENTER to retry",\r
1822 NULL\r
1823 );\r
1824 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
1825 Count ++;\r
1826 continue;\r
1827 }\r
1828 }\r
1829\r
f5245a1d 1830 Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please type in your new password", NULL, &PressEsc);\r
112e584b
SZ
1831 if (Password == NULL) {\r
1832 ZeroMem (OldPassword, OldPasswordLen);\r
1833 FreePool (OldPassword);\r
1834 Count ++;\r
1835 continue;\r
1836 }\r
1837 PasswordLen = (UINT32) AsciiStrLen(Password);\r
1838\r
f5245a1d 1839 PasswordConfirm = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please confirm your new password", NULL, &PressEsc);\r
112e584b
SZ
1840 if (PasswordConfirm == NULL) {\r
1841 ZeroMem (OldPassword, OldPasswordLen);\r
1842 FreePool (OldPassword);\r
1843 ZeroMem (Password, PasswordLen);\r
1844 FreePool (Password);\r
1845 Count ++;\r
1846 continue;\r
1847 }\r
1848 PasswordLenConfirm = (UINT32) AsciiStrLen(PasswordConfirm);\r
1849 if ((PasswordLen != PasswordLenConfirm) ||\r
1850 (CompareMem (Password, PasswordConfirm, PasswordLen) != 0)) {\r
1851 ZeroMem (OldPassword, OldPasswordLen);\r
1852 FreePool (OldPassword);\r
1853 ZeroMem (Password, PasswordLen);\r
1854 FreePool (Password);\r
1855 ZeroMem (PasswordConfirm, PasswordLenConfirm);\r
1856 FreePool (PasswordConfirm);\r
1857 do {\r
1858 CreatePopUp (\r
1859 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1860 &Key,\r
1861 L"Passwords are not the same.",\r
1862 L"Press ENTER to retry",\r
1863 NULL\r
1864 );\r
1865 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
1866 Count ++;\r
1867 continue;\r
1868 }\r
1869\r
1870 if (PasswordConfirm != NULL) {\r
1871 ZeroMem (PasswordConfirm, PasswordLenConfirm);\r
1872 FreePool (PasswordConfirm);\r
1873 }\r
1874\r
1875 ZeroMem(&Session, sizeof(Session));\r
1876 Session.Sscp = Dev->OpalDisk.Sscp;\r
1877 Session.MediaId = Dev->OpalDisk.MediaId;\r
1878 Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;\r
1879 Ret = OpalUtilSetUserPassword(\r
1880 &Session,\r
1881 OldPassword,\r
1882 OldPasswordLen,\r
1883 Password,\r
1884 PasswordLen\r
1885 );\r
1886 if (Ret == TcgResultSuccess) {\r
1887 OpalSupportUpdatePassword (&Dev->OpalDisk, Password, PasswordLen);\r
1888 DEBUG ((DEBUG_INFO, "%s Success\n", RequestString));\r
1889 } else {\r
1890 DEBUG ((DEBUG_INFO, "%s Failure\n", RequestString));\r
1891 }\r
1892\r
1893 if (OldPassword != NULL) {\r
1894 ZeroMem (OldPassword, OldPasswordLen);\r
1895 FreePool (OldPassword);\r
1896 }\r
1897\r
1898 if (Password != NULL) {\r
1899 ZeroMem (Password, PasswordLen);\r
1900 FreePool (Password);\r
1901 }\r
1902\r
1903 if (Ret == TcgResultSuccess) {\r
1904 break;\r
1905 }\r
1906\r
1907 Count++;\r
1908\r
1909 do {\r
1910 CreatePopUp (\r
1911 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1912 &Key,\r
1913 L"Request failed.",\r
1914 L"Press ENTER to retry",\r
1915 NULL\r
1916 );\r
1917 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
1918 }\r
1919\r
1920 if (Count >= MAX_PASSWORD_TRY_COUNT) {\r
1921 do {\r
1922 CreatePopUp (\r
1923 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1924 &Key,\r
1925 L"Opal password retry count exceeds the limit.",\r
1926 L"Press ENTER to skip the request and continue boot",\r
1927 NULL\r
1928 );\r
1929 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
1930 gST->ConOut->ClearScreen(gST->ConOut);\r
1931 }\r
1932}\r
1933\r
1934/**\r
1935 Process Set Admin Pwd OPAL request.\r
1936\r
1937 @param[in] Dev The device which has Set Admin Pwd Feature OPAL request.\r
1938 @param[in] RequestString Request string.\r
1939\r
1940**/\r
1941VOID\r
1942ProcessOpalRequestSetAdminPwd (\r
1943 IN OPAL_DRIVER_DEVICE *Dev,\r
1944 IN CHAR16 *RequestString\r
1945 )\r
1946{\r
1947 UINT8 Count;\r
1948 CHAR8 *OldPassword;\r
1949 UINT32 OldPasswordLen;\r
1950 CHAR8 *Password;\r
1951 UINT32 PasswordLen;\r
1952 CHAR8 *PasswordConfirm;\r
1953 UINT32 PasswordLenConfirm;\r
1954 OPAL_SESSION Session;\r
1955 BOOLEAN PressEsc;\r
1956 EFI_INPUT_KEY Key;\r
1957 TCG_RESULT Ret;\r
1958 CHAR16 *PopUpString;\r
1959\r
1960 if (Dev == NULL) {\r
1961 return;\r
1962 }\r
1963\r
1964 DEBUG ((DEBUG_INFO, "%a()\n", __FUNCTION__));\r
1965\r
1966 PopUpString = OpalGetPopUpString (Dev, RequestString);\r
1967\r
1968 Count = 0;\r
1969\r
1970 while (Count < MAX_PASSWORD_TRY_COUNT) {\r
f5245a1d 1971 OldPassword = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please type in your password", NULL, &PressEsc);\r
112e584b
SZ
1972 if (PressEsc) {\r
1973 do {\r
1974 CreatePopUp (\r
1975 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1976 &Key,\r
1977 L"Press ENTER to skip the request and continue boot,",\r
1978 L"Press ESC to input password again",\r
1979 NULL\r
1980 );\r
1981 } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));\r
1982\r
1983 if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
1984 gST->ConOut->ClearScreen(gST->ConOut);\r
1985 return;\r
1986 } else {\r
1987 //\r
1988 // Let user input password again.\r
1989 //\r
1990 continue;\r
1991 }\r
1992 }\r
1993\r
1994 if (OldPassword == NULL) {\r
1995 Count ++;\r
1996 continue;\r
1997 }\r
1998 OldPasswordLen = (UINT32) AsciiStrLen(OldPassword);\r
1999\r
2000 ZeroMem(&Session, sizeof(Session));\r
2001 Session.Sscp = Dev->OpalDisk.Sscp;\r
2002 Session.MediaId = Dev->OpalDisk.MediaId;\r
2003 Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;\r
2004 Ret = OpalUtilVerifyPassword (&Session, OldPassword, OldPasswordLen, OPAL_LOCKING_SP_ADMIN1_AUTHORITY);\r
2005 if (Ret == TcgResultSuccess) {\r
2006 DEBUG ((DEBUG_INFO, "Verify: Success\n"));\r
2007 } else {\r
2008 ZeroMem (OldPassword, OldPasswordLen);\r
2009 FreePool (OldPassword);\r
2010 DEBUG ((DEBUG_INFO, "Verify: Failure\n"));\r
2011 do {\r
2012 CreatePopUp (\r
2013 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
2014 &Key,\r
2015 L"Incorrect password.",\r
2016 L"Press ENTER to retry",\r
2017 NULL\r
2018 );\r
2019 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
2020 Count ++;\r
2021 continue;\r
2022 }\r
2023\r
f5245a1d 2024 Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please type in your new password", NULL, &PressEsc);\r
112e584b
SZ
2025 if (Password == NULL) {\r
2026 ZeroMem (OldPassword, OldPasswordLen);\r
2027 FreePool (OldPassword);\r
2028 Count ++;\r
2029 continue;\r
2030 }\r
2031 PasswordLen = (UINT32) AsciiStrLen(Password);\r
2032\r
f5245a1d 2033 PasswordConfirm = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please confirm your new password", NULL, &PressEsc);\r
112e584b
SZ
2034 if (PasswordConfirm == NULL) {\r
2035 ZeroMem (OldPassword, OldPasswordLen);\r
2036 FreePool (OldPassword);\r
2037 ZeroMem (Password, PasswordLen);\r
2038 FreePool (Password);\r
2039 Count ++;\r
2040 continue;\r
2041 }\r
2042 PasswordLenConfirm = (UINT32) AsciiStrLen(PasswordConfirm);\r
2043 if ((PasswordLen != PasswordLenConfirm) ||\r
2044 (CompareMem (Password, PasswordConfirm, PasswordLen) != 0)) {\r
2045 ZeroMem (OldPassword, OldPasswordLen);\r
2046 FreePool (OldPassword);\r
2047 ZeroMem (Password, PasswordLen);\r
2048 FreePool (Password);\r
2049 ZeroMem (PasswordConfirm, PasswordLenConfirm);\r
2050 FreePool (PasswordConfirm);\r
2051 do {\r
2052 CreatePopUp (\r
2053 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
2054 &Key,\r
2055 L"Passwords are not the same.",\r
2056 L"Press ENTER to retry",\r
2057 NULL\r
2058 );\r
2059 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
2060 Count ++;\r
2061 continue;\r
2062 }\r
2063\r
2064 if (PasswordConfirm != NULL) {\r
2065 ZeroMem (PasswordConfirm, PasswordLenConfirm);\r
2066 FreePool (PasswordConfirm);\r
2067 }\r
2068\r
2069\r
2070 ZeroMem(&Session, sizeof(Session));\r
2071 Session.Sscp = Dev->OpalDisk.Sscp;\r
2072 Session.MediaId = Dev->OpalDisk.MediaId;\r
2073 Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;\r
2074 Ret = OpalUtilSetAdminPassword(\r
2075 &Session,\r
2076 OldPassword,\r
2077 OldPasswordLen,\r
2078 Password,\r
2079 PasswordLen\r
2080 );\r
2081 if (Ret == TcgResultSuccess) {\r
2082 OpalSupportUpdatePassword (&Dev->OpalDisk, Password, PasswordLen);\r
2083 DEBUG ((DEBUG_INFO, "%s Success\n", RequestString));\r
2084 } else {\r
2085 DEBUG ((DEBUG_INFO, "%s Failure\n", RequestString));\r
2086 }\r
2087\r
2088 if (OldPassword != NULL) {\r
2089 ZeroMem (OldPassword, OldPasswordLen);\r
2090 FreePool (OldPassword);\r
2091 }\r
2092\r
2093 if (Password != NULL) {\r
2094 ZeroMem (Password, PasswordLen);\r
2095 FreePool (Password);\r
2096 }\r
2097\r
2098 if (Ret == TcgResultSuccess) {\r
2099 break;\r
2100 }\r
2101\r
2102 Count++;\r
2103\r
2104 do {\r
2105 CreatePopUp (\r
2106 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
2107 &Key,\r
2108 L"Request failed.",\r
2109 L"Press ENTER to retry",\r
2110 NULL\r
2111 );\r
2112 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
2113 }\r
2114\r
2115 if (Count >= MAX_PASSWORD_TRY_COUNT) {\r
2116 do {\r
2117 CreatePopUp (\r
2118 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
2119 &Key,\r
2120 L"Opal password retry count exceeds the limit.",\r
2121 L"Press ENTER to skip the request and continue boot",\r
2122 NULL\r
2123 );\r
2124 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
2125 gST->ConOut->ClearScreen(gST->ConOut);\r
2126 }\r
2127}\r
2128\r
2129/**\r
2130 Process OPAL request.\r
2131\r
2132 @param[in] Dev The device which has OPAL request.\r
2133\r
2134**/\r
2135VOID\r
2136ProcessOpalRequest (\r
2137 IN OPAL_DRIVER_DEVICE *Dev\r
2138 )\r
2139{\r
2140 EFI_STATUS Status;\r
2141 OPAL_REQUEST_VARIABLE *TempVariable;\r
2142 OPAL_REQUEST_VARIABLE *Variable;\r
2143 UINTN VariableSize;\r
2144 EFI_DEVICE_PATH_PROTOCOL *DevicePathInVariable;\r
2145 UINTN DevicePathSizeInVariable;\r
2146 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
2147 UINTN DevicePathSize;\r
2148 BOOLEAN KeepUserData;\r
2149\r
2150 DEBUG ((DEBUG_INFO, "%a() - enter\n", __FUNCTION__));\r
2151\r
2152 if (mOpalRequestVariable == NULL) {\r
2153 Status = GetVariable2 (\r
2154 OPAL_REQUEST_VARIABLE_NAME,\r
2155 &gHiiSetupVariableGuid,\r
2156 (VOID **) &Variable,\r
2157 &VariableSize\r
2158 );\r
2159 if (EFI_ERROR (Status) || (Variable == NULL)) {\r
2160 return;\r
2161 }\r
2162 mOpalRequestVariable = Variable;\r
2163 mOpalRequestVariableSize = VariableSize;\r
2164\r
2165 //\r
2166 // Delete the OPAL request variable.\r
2167 //\r
2168 Status = gRT->SetVariable (\r
2169 OPAL_REQUEST_VARIABLE_NAME,\r
2170 (EFI_GUID *) &gHiiSetupVariableGuid,\r
2171 0,\r
2172 0,\r
2173 NULL\r
2174 );\r
2175 ASSERT_EFI_ERROR (Status);\r
2176 } else {\r
2177 Variable = mOpalRequestVariable;\r
2178 VariableSize = mOpalRequestVariableSize;\r
2179 }\r
2180\r
2181 //\r
2182 // Process the OPAL requests.\r
2183 //\r
2184 TempVariable = Variable;\r
2185 while ((VariableSize > sizeof (OPAL_REQUEST_VARIABLE)) &&\r
2186 (VariableSize >= TempVariable->Length) &&\r
2187 (TempVariable->Length > sizeof (OPAL_REQUEST_VARIABLE))) {\r
2188 DevicePathInVariable = (EFI_DEVICE_PATH_PROTOCOL *) ((UINTN) TempVariable + sizeof (OPAL_REQUEST_VARIABLE));\r
2189 DevicePathSizeInVariable = GetDevicePathSize (DevicePathInVariable);\r
2190 DevicePath = Dev->OpalDisk.OpalDevicePath;\r
2191 DevicePathSize = GetDevicePathSize (DevicePath);\r
2192 if ((DevicePathSize == DevicePathSizeInVariable) &&\r
2193 (CompareMem (DevicePath, DevicePathInVariable, DevicePathSize) == 0)) {\r
2194 //\r
2195 // Found the node for the OPAL device.\r
2196 //\r
2197 if (TempVariable->OpalRequest.SetAdminPwd != 0) {\r
2198 ProcessOpalRequestSetAdminPwd (Dev, L"Update Admin Pwd:");\r
2199 }\r
2200 if (TempVariable->OpalRequest.SetUserPwd != 0) {\r
2201 ProcessOpalRequestSetUserPwd (Dev, L"Set User Pwd:");\r
2202 }\r
2203 if (TempVariable->OpalRequest.SecureErase!= 0) {\r
2204 ProcessOpalRequestSecureErase (Dev, L"Secure Erase:");\r
2205 }\r
2206 if (TempVariable->OpalRequest.Revert != 0) {\r
2207 KeepUserData = (BOOLEAN) TempVariable->OpalRequest.KeepUserData;\r
2208 ProcessOpalRequestRevert (\r
2209 Dev,\r
2210 KeepUserData,\r
2211 KeepUserData ? L"Admin Revert(keep):" : L"Admin Revert:"\r
2212 );\r
2213 }\r
2214 if (TempVariable->OpalRequest.PsidRevert != 0) {\r
2215 ProcessOpalRequestPsidRevert (Dev, L"Psid Revert:");\r
2216 }\r
2217 if (TempVariable->OpalRequest.DisableUser != 0) {\r
2218 ProcessOpalRequestDisableUser (Dev, L"Disable User:");\r
2219 }\r
2220 if (TempVariable->OpalRequest.EnableFeature != 0) {\r
2221 ProcessOpalRequestEnableFeature (Dev, L"Enable Feature:");\r
2222 }\r
2223\r
46e69608
ED
2224 //\r
2225 // Update Device ownership.\r
2226 // Later BlockSID command may block the update.\r
2227 //\r
2228 OpalDiskUpdateOwnerShip (&Dev->OpalDisk);\r
2229\r
112e584b
SZ
2230 break;\r
2231 }\r
2232\r
2233 VariableSize -= TempVariable->Length;\r
2234 TempVariable = (OPAL_REQUEST_VARIABLE *) ((UINTN) TempVariable + TempVariable->Length);\r
2235 }\r
2236\r
2237 DEBUG ((DEBUG_INFO, "%a() - exit\n", __FUNCTION__));\r
2238}\r
2239\r
2240/**\r
2241 Add new device to the global device list.\r
2242\r
2243 @param Dev New create device.\r
2244\r
2245**/\r
2246VOID\r
2247AddDeviceToTail(\r
2248 IN OPAL_DRIVER_DEVICE *Dev\r
2249 )\r
2250{\r
2251 OPAL_DRIVER_DEVICE *TmpDev;\r
2252\r
2253 if (mOpalDriver.DeviceList == NULL) {\r
2254 mOpalDriver.DeviceList = Dev;\r
2255 } else {\r
2256 TmpDev = mOpalDriver.DeviceList;\r
2257 while (TmpDev->Next != NULL) {\r
2258 TmpDev = TmpDev->Next;\r
2259 }\r
2260\r
2261 TmpDev->Next = Dev;\r
2262 }\r
2263}\r
2264\r
2265/**\r
2266 Remove one device in the global device list.\r
2267\r
2268 @param Dev The device need to be removed.\r
2269\r
2270**/\r
2271VOID\r
2272RemoveDevice (\r
2273 IN OPAL_DRIVER_DEVICE *Dev\r
2274 )\r
2275{\r
2276 OPAL_DRIVER_DEVICE *TmpDev;\r
2277\r
2278 if (mOpalDriver.DeviceList == NULL) {\r
2279 return;\r
2280 }\r
2281\r
2282 if (mOpalDriver.DeviceList == Dev) {\r
2283 mOpalDriver.DeviceList = NULL;\r
2284 return;\r
2285 }\r
2286\r
2287 TmpDev = mOpalDriver.DeviceList;\r
2288 while (TmpDev->Next != NULL) {\r
2289 if (TmpDev->Next == Dev) {\r
2290 TmpDev->Next = Dev->Next;\r
2291 break;\r
2292 }\r
2293 }\r
2294}\r
2295\r
2296/**\r
2297 Get current device count.\r
2298\r
2299 @retval return the current created device count.\r
2300\r
2301**/\r
2302UINT8\r
2303GetDeviceCount (\r
2304 VOID\r
2305 )\r
2306{\r
2307 UINT8 Count;\r
2308 OPAL_DRIVER_DEVICE *TmpDev;\r
2309\r
2310 Count = 0;\r
2311 TmpDev = mOpalDriver.DeviceList;\r
2312\r
2313 while (TmpDev != NULL) {\r
2314 Count++;\r
2315 TmpDev = TmpDev->Next;\r
2316 }\r
2317\r
2318 return Count;\r
2319}\r
2320\r
2321/**\r
2322 Get devcie list info.\r
2323\r
2324 @retval return the device list pointer.\r
2325**/\r
2326OPAL_DRIVER_DEVICE*\r
2327OpalDriverGetDeviceList(\r
2328 VOID\r
2329 )\r
2330{\r
2331 return mOpalDriver.DeviceList;\r
2332}\r
2333\r
112e584b
SZ
2334/**\r
2335 Stop this Controller.\r
2336\r
2337 @param Dev The device need to be stopped.\r
2338\r
2339**/\r
2340VOID\r
2341OpalDriverStopDevice (\r
2342 OPAL_DRIVER_DEVICE *Dev\r
2343 )\r
2344{\r
2345 //\r
2346 // free each name\r
2347 //\r
2348 FreePool(Dev->Name16);\r
2349\r
2350 //\r
2351 // remove OPAL_DRIVER_DEVICE from the list\r
2352 // it updates the controllerList pointer\r
2353 //\r
2354 RemoveDevice(Dev);\r
2355\r
2356 //\r
2357 // close protocols that were opened\r
2358 //\r
2359 gBS->CloseProtocol(\r
2360 Dev->Handle,\r
2361 &gEfiStorageSecurityCommandProtocolGuid,\r
2362 gOpalDriverBinding.DriverBindingHandle,\r
2363 Dev->Handle\r
2364 );\r
2365\r
2366 gBS->CloseProtocol(\r
2367 Dev->Handle,\r
2368 &gEfiBlockIoProtocolGuid,\r
2369 gOpalDriverBinding.DriverBindingHandle,\r
2370 Dev->Handle\r
2371 );\r
2372\r
2373 FreePool(Dev);\r
2374}\r
2375\r
2376/**\r
2377 Get devcie name through the component name protocol.\r
2378\r
2379 @param[in] AllHandlesBuffer The handle buffer for current system.\r
2380 @param[in] NumAllHandles The number of handles for the handle buffer.\r
2381 @param[in] Dev The device which need to get name.\r
2382 @param[in] UseComp1 Whether use component name or name2 protocol.\r
2383\r
2384 @retval TRUE Find the name for this device.\r
2385 @retval FALSE Not found the name for this device.\r
2386**/\r
2387BOOLEAN\r
2388OpalDriverGetDeviceNameByProtocol(\r
2389 EFI_HANDLE *AllHandlesBuffer,\r
2390 UINTN NumAllHandles,\r
2391 OPAL_DRIVER_DEVICE *Dev,\r
2392 BOOLEAN UseComp1\r
2393 )\r
2394{\r
2395 EFI_HANDLE* ProtocolHandlesBuffer;\r
2396 UINTN NumProtocolHandles;\r
2397 EFI_STATUS Status;\r
2398 EFI_COMPONENT_NAME2_PROTOCOL* Cnp1_2; // efi component name and componentName2 have same layout\r
2399 EFI_GUID Protocol;\r
2400 UINTN StrLength;\r
2401 EFI_DEVICE_PATH_PROTOCOL* TmpDevPath;\r
2402 UINTN Index1;\r
2403 UINTN Index2;\r
2404 EFI_HANDLE TmpHandle;\r
2405 CHAR16 *DevName;\r
2406\r
2407 if (Dev == NULL || AllHandlesBuffer == NULL || NumAllHandles == 0) {\r
2408 return FALSE;\r
2409 }\r
2410\r
2411 Protocol = UseComp1 ? gEfiComponentNameProtocolGuid : gEfiComponentName2ProtocolGuid;\r
2412\r
2413 //\r
2414 // Find all EFI_HANDLES with protocol\r
2415 //\r
2416 Status = gBS->LocateHandleBuffer(\r
2417 ByProtocol,\r
2418 &Protocol,\r
2419 NULL,\r
2420 &NumProtocolHandles,\r
2421 &ProtocolHandlesBuffer\r
2422 );\r
2423 if (EFI_ERROR(Status)) {\r
2424 return FALSE;\r
2425 }\r
2426\r
2427\r
2428 //\r
2429 // Exit early if no supported devices\r
2430 //\r
2431 if (NumProtocolHandles == 0) {\r
2432 return FALSE;\r
2433 }\r
2434\r
2435 //\r
2436 // Get printable name by iterating through all protocols\r
2437 // using the handle as the child, and iterate through all handles for the controller\r
2438 // exit loop early once found, if not found, then delete device\r
2439 // storage security protocol instances already exist, add them to internal list\r
2440 //\r
2441 Status = EFI_DEVICE_ERROR;\r
2442 for (Index1 = 0; Index1 < NumProtocolHandles; Index1++) {\r
2443 DevName = NULL;\r
2444\r
2445 if (Dev->Name16 != NULL) {\r
2446 return TRUE;\r
2447 }\r
2448\r
2449 TmpHandle = ProtocolHandlesBuffer[Index1];\r
2450\r
2451 Status = gBS->OpenProtocol(\r
2452 TmpHandle,\r
2453 &Protocol,\r
2454 (VOID**)&Cnp1_2,\r
2455 gImageHandle,\r
2456 NULL,\r
2457 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
2458 );\r
2459 if (EFI_ERROR(Status) || Cnp1_2 == NULL) {\r
2460 continue;\r
2461 }\r
2462\r
2463 //\r
2464 // Use all handles array as controller handle\r
2465 //\r
2466 for (Index2 = 0; Index2 < NumAllHandles; Index2++) {\r
2467 Status = Cnp1_2->GetControllerName(\r
2468 Cnp1_2,\r
2469 AllHandlesBuffer[Index2],\r
2470 Dev->Handle,\r
2471 LANGUAGE_ISO_639_2_ENGLISH,\r
2472 &DevName\r
2473 );\r
2474 if (EFI_ERROR(Status)) {\r
2475 Status = Cnp1_2->GetControllerName(\r
2476 Cnp1_2,\r
2477 AllHandlesBuffer[Index2],\r
2478 Dev->Handle,\r
2479 LANGUAGE_RFC_3066_ENGLISH,\r
2480 &DevName\r
2481 );\r
2482 }\r
2483 if (!EFI_ERROR(Status) && DevName != NULL) {\r
2484 StrLength = StrLen(DevName) + 1; // Add one for NULL terminator\r
2485 Dev->Name16 = AllocateZeroPool(StrLength * sizeof (CHAR16));\r
2486 ASSERT (Dev->Name16 != NULL);\r
2487 StrCpyS (Dev->Name16, StrLength, DevName);\r
2488 Dev->NameZ = (CHAR8*)AllocateZeroPool(StrLength);\r
2489 UnicodeStrToAsciiStrS (DevName, Dev->NameZ, StrLength);\r
2490\r
2491 //\r
2492 // Retrieve bridge BDF info and port number or namespace depending on type\r
2493 //\r
2494 TmpDevPath = NULL;\r
2495 Status = gBS->OpenProtocol(\r
2496 Dev->Handle,\r
2497 &gEfiDevicePathProtocolGuid,\r
2498 (VOID**)&TmpDevPath,\r
2499 gImageHandle,\r
2500 NULL,\r
2501 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
2502 );\r
2503 if (!EFI_ERROR(Status)) {\r
2504 Dev->OpalDevicePath = DuplicateDevicePath (TmpDevPath);\r
2505 return TRUE;\r
2506 }\r
2507\r
2508 if (Dev->Name16 != NULL) {\r
2509 FreePool(Dev->Name16);\r
2510 Dev->Name16 = NULL;\r
2511 }\r
2512 if (Dev->NameZ != NULL) {\r
2513 FreePool(Dev->NameZ);\r
2514 Dev->NameZ = NULL;\r
2515 }\r
2516 }\r
2517 }\r
2518 }\r
2519\r
2520 return FALSE;\r
2521}\r
2522\r
2523/**\r
2524 Get devcie name through the component name protocol.\r
2525\r
2526 @param[in] Dev The device which need to get name.\r
2527\r
2528 @retval TRUE Find the name for this device.\r
2529 @retval FALSE Not found the name for this device.\r
2530**/\r
2531BOOLEAN\r
2532OpalDriverGetDriverDeviceName(\r
2533 OPAL_DRIVER_DEVICE *Dev\r
2534 )\r
2535{\r
2536 EFI_HANDLE* AllHandlesBuffer;\r
2537 UINTN NumAllHandles;\r
2538 EFI_STATUS Status;\r
2539\r
2540 if (Dev == NULL) {\r
2541 DEBUG((DEBUG_ERROR | DEBUG_INIT, "OpalDriverGetDriverDeviceName Exiting, Dev=NULL\n"));\r
2542 return FALSE;\r
2543 }\r
2544\r
2545 //\r
2546 // Iterate through ComponentName2 handles to get name, if fails, try ComponentName\r
2547 //\r
2548 if (Dev->Name16 == NULL) {\r
2549 DEBUG((DEBUG_ERROR | DEBUG_INIT, "Name is null, update it\n"));\r
2550 //\r
2551 // Find all EFI_HANDLES\r
2552 //\r
2553 Status = gBS->LocateHandleBuffer(\r
2554 AllHandles,\r
2555 NULL,\r
2556 NULL,\r
2557 &NumAllHandles,\r
2558 &AllHandlesBuffer\r
2559 );\r
2560 if (EFI_ERROR(Status)) {\r
2561 DEBUG ((DEBUG_INFO, "LocateHandleBuffer for AllHandles failed %r\n", Status ));\r
2562 return FALSE;\r
2563 }\r
2564\r
2565 //\r
2566 // Try component Name2\r
2567 //\r
2568 if (!OpalDriverGetDeviceNameByProtocol(AllHandlesBuffer, NumAllHandles, Dev, FALSE)) {\r
2569 DEBUG((DEBUG_ERROR | DEBUG_INIT, "ComponentName2 failed to get device name, try ComponentName\n"));\r
2570 if (!OpalDriverGetDeviceNameByProtocol(AllHandlesBuffer, NumAllHandles, Dev, TRUE)) {\r
2571 DEBUG((DEBUG_ERROR | DEBUG_INIT, "ComponentName failed to get device name, skip device\n"));\r
2572 return FALSE;\r
2573 }\r
2574 }\r
2575 }\r
2576\r
2577 return TRUE;\r
2578}\r
2579\r
2580/**\r
2581 Main entry for this driver.\r
2582\r
2583 @param ImageHandle Image Handle this driver.\r
2584 @param SystemTable Pointer to SystemTable.\r
2585\r
d6b926e7 2586 @retval EFI_SUCCESS This function always complete successfully.\r
112e584b
SZ
2587**/\r
2588EFI_STATUS\r
2589EFIAPI\r
2590EfiDriverEntryPoint(\r
2591 IN EFI_HANDLE ImageHandle,\r
2592 IN EFI_SYSTEM_TABLE* SystemTable\r
2593 )\r
2594{\r
2595 EFI_STATUS Status;\r
112e584b
SZ
2596 EFI_EVENT EndOfDxeEvent;\r
2597\r
2598 Status = EfiLibInstallDriverBindingComponentName2 (\r
2599 ImageHandle,\r
2600 SystemTable,\r
2601 &gOpalDriverBinding,\r
2602 ImageHandle,\r
2603 &gOpalComponentName,\r
2604 &gOpalComponentName2\r
2605 );\r
2606\r
2607 if (EFI_ERROR(Status)) {\r
2608 DEBUG((DEBUG_ERROR, "Install protocols to Opal driver Handle failed\n"));\r
2609 return Status ;\r
2610 }\r
2611\r
2612 //\r
2613 // Initialize Driver object\r
2614 //\r
2615 ZeroMem(&mOpalDriver, sizeof(mOpalDriver));\r
2616 mOpalDriver.Handle = ImageHandle;\r
2617\r
2618 Status = gBS->CreateEventEx (\r
2619 EVT_NOTIFY_SIGNAL,\r
2620 TPL_CALLBACK,\r
2621 OpalEndOfDxeEventNotify,\r
2622 NULL,\r
2623 &gEfiEndOfDxeEventGroupGuid,\r
2624 &EndOfDxeEvent\r
2625 );\r
2626 ASSERT_EFI_ERROR (Status);\r
2627\r
112e584b
SZ
2628 //\r
2629 // Install Hii packages.\r
2630 //\r
2631 HiiInstall();\r
2632\r
2633 return Status;\r
2634}\r
2635\r
2636/**\r
2637 Tests to see if this driver supports a given controller.\r
2638\r
2639 This function checks to see if the controller contains an instance of the\r
d6b926e7 2640 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL and the EFI_BLOCK_IO_PROTOCOL\r
112e584b
SZ
2641 and returns EFI_SUCCESS if it does.\r
2642\r
2643 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
2644 @param[in] ControllerHandle The Handle of the controller to test. This Handle\r
2645 must support a protocol interface that supplies\r
2646 an I/O abstraction to the driver.\r
2647 @param[in] RemainingDevicePath This parameter is ignored.\r
2648\r
2649 @retval EFI_SUCCESS The device contains required protocols\r
2650 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and\r
2651 RemainingDevicePath is already being managed by the driver\r
2652 specified by This.\r
2653 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and\r
2654 RemainingDevicePath is already being managed by a different\r
2655 driver or an application that requires exclusive access.\r
2656 Currently not implemented.\r
2657 @retval EFI_UNSUPPORTED The device does not contain requires protocols\r
2658\r
2659**/\r
2660EFI_STATUS\r
2661EFIAPI\r
2662OpalEfiDriverBindingSupported(\r
2663 IN EFI_DRIVER_BINDING_PROTOCOL* This,\r
2664 IN EFI_HANDLE Controller,\r
2665 IN EFI_DEVICE_PATH_PROTOCOL* RemainingDevicePath\r
2666 )\r
2667{\r
2668 EFI_STATUS Status;\r
2669 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL* SecurityCommand;\r
2670 EFI_BLOCK_IO_PROTOCOL* BlkIo;\r
2671\r
2672 if (mOpalEndOfDxe) {\r
2673 return EFI_UNSUPPORTED;\r
2674 }\r
2675\r
2676 //\r
2677 // Test EFI_STORAGE_SECURITY_COMMAND_PROTOCOL on controller Handle.\r
2678 //\r
2679 Status = gBS->OpenProtocol(\r
2680 Controller,\r
2681 &gEfiStorageSecurityCommandProtocolGuid,\r
2682 ( VOID ** )&SecurityCommand,\r
2683 This->DriverBindingHandle,\r
2684 Controller,\r
2685 EFI_OPEN_PROTOCOL_BY_DRIVER\r
2686 );\r
2687\r
2688 if (Status == EFI_ALREADY_STARTED) {\r
2689 return EFI_SUCCESS;\r
2690 }\r
2691\r
2692 if (EFI_ERROR(Status)) {\r
2693 return Status;\r
2694 }\r
2695\r
2696 //\r
2697 // Close protocol and reopen in Start call\r
2698 //\r
2699 gBS->CloseProtocol(\r
2700 Controller,\r
2701 &gEfiStorageSecurityCommandProtocolGuid,\r
2702 This->DriverBindingHandle,\r
2703 Controller\r
2704 );\r
2705\r
2706 //\r
2707 // Test EFI_BLOCK_IO_PROTOCOL on controller Handle, required by EFI_STORAGE_SECURITY_COMMAND_PROTOCOL\r
2708 // function APIs\r
2709 //\r
2710 Status = gBS->OpenProtocol(\r
2711 Controller,\r
2712 &gEfiBlockIoProtocolGuid,\r
2713 (VOID **)&BlkIo,\r
2714 This->DriverBindingHandle,\r
2715 Controller,\r
2716 EFI_OPEN_PROTOCOL_BY_DRIVER\r
2717 );\r
2718\r
2719 if (EFI_ERROR(Status)) {\r
2720 DEBUG((DEBUG_INFO, "No EFI_BLOCK_IO_PROTOCOL on controller\n"));\r
2721 return Status;\r
2722 }\r
2723\r
2724 //\r
2725 // Close protocol and reopen in Start call\r
2726 //\r
2727 gBS->CloseProtocol(\r
2728 Controller,\r
2729 &gEfiBlockIoProtocolGuid,\r
2730 This->DriverBindingHandle,\r
2731 Controller\r
2732 );\r
2733\r
2734 return EFI_SUCCESS;\r
2735}\r
2736\r
2737/**\r
2738 Enables Opal Management on a supported device if available.\r
2739\r
2740 The start function is designed to be called after the Opal UEFI Driver has confirmed the\r
2741 "controller", which is a child Handle, contains the EF_STORAGE_SECURITY_COMMAND protocols.\r
2742 This function will complete the other necessary checks, such as verifying the device supports\r
2743 the correct version of Opal. Upon verification, it will add the device to the\r
d6b926e7 2744 Opal HII list in order to expose Opal management options.\r
112e584b
SZ
2745\r
2746 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
2747 @param[in] ControllerHandle The Handle of the controller to start. This Handle\r
2748 must support a protocol interface that supplies\r
2749 an I/O abstraction to the driver.\r
2750 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This\r
2751 parameter is ignored by device drivers, and is optional for bus\r
2752 drivers. For a bus driver, if this parameter is NULL, then handles\r
2753 for all the children of Controller are created by this driver.\r
2754 If this parameter is not NULL and the first Device Path Node is\r
2755 not the End of Device Path Node, then only the Handle for the\r
2756 child device specified by the first Device Path Node of\r
2757 RemainingDevicePath is created by this driver.\r
2758 If the first Device Path Node of RemainingDevicePath is\r
2759 the End of Device Path Node, no child Handle is created by this\r
2760 driver.\r
2761\r
2762 @retval EFI_SUCCESS Opal management was enabled.\r
2763 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.\r
2764 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
2765 @retval Others The driver failed to start the device.\r
2766\r
2767**/\r
2768EFI_STATUS\r
2769EFIAPI\r
2770OpalEfiDriverBindingStart(\r
2771 IN EFI_DRIVER_BINDING_PROTOCOL* This,\r
2772 IN EFI_HANDLE Controller,\r
2773 IN EFI_DEVICE_PATH_PROTOCOL* RemainingDevicePath\r
2774 )\r
2775{\r
2776 EFI_STATUS Status;\r
2777 EFI_BLOCK_IO_PROTOCOL *BlkIo;\r
2778 OPAL_DRIVER_DEVICE *Dev;\r
2779 OPAL_DRIVER_DEVICE *Itr;\r
2780 BOOLEAN Result;\r
2781\r
2782 Itr = mOpalDriver.DeviceList;\r
2783 while (Itr != NULL) {\r
2784 if (Controller == Itr->Handle) {\r
2785 return EFI_SUCCESS;\r
2786 }\r
2787 Itr = Itr->Next;\r
2788 }\r
2789\r
2790 //\r
2791 // Create internal device for tracking. This allows all disks to be tracked\r
2792 // by same HII form\r
2793 //\r
2794 Dev = (OPAL_DRIVER_DEVICE*)AllocateZeroPool(sizeof(OPAL_DRIVER_DEVICE));\r
2795 if (Dev == NULL) {\r
2796 return EFI_OUT_OF_RESOURCES;\r
2797 }\r
2798 Dev->Handle = Controller;\r
2799\r
2800 //\r
2801 // Open EFI_STORAGE_SECURITY_COMMAND_PROTOCOL to perform Opal supported checks\r
2802 //\r
2803 Status = gBS->OpenProtocol(\r
2804 Controller,\r
2805 &gEfiStorageSecurityCommandProtocolGuid,\r
2806 (VOID **)&Dev->Sscp,\r
2807 This->DriverBindingHandle,\r
2808 Controller,\r
2809 EFI_OPEN_PROTOCOL_BY_DRIVER\r
2810 );\r
2811 if (EFI_ERROR(Status)) {\r
2812 FreePool(Dev);\r
2813 return Status;\r
2814 }\r
2815\r
2816 //\r
2817 // Open EFI_BLOCK_IO_PROTOCOL on controller Handle, required by EFI_STORAGE_SECURITY_COMMAND_PROTOCOL\r
2818 // function APIs\r
2819 //\r
2820 Status = gBS->OpenProtocol(\r
2821 Controller,\r
2822 &gEfiBlockIoProtocolGuid,\r
2823 (VOID **)&BlkIo,\r
2824 This->DriverBindingHandle,\r
2825 Controller,\r
2826 EFI_OPEN_PROTOCOL_BY_DRIVER\r
2827 );\r
2828 if (EFI_ERROR(Status)) {\r
2829 //\r
2830 // Close storage security that was opened\r
2831 //\r
2832 gBS->CloseProtocol(\r
2833 Controller,\r
2834 &gEfiStorageSecurityCommandProtocolGuid,\r
2835 This->DriverBindingHandle,\r
2836 Controller\r
2837 );\r
2838\r
2839 FreePool(Dev);\r
2840 return Status;\r
2841 }\r
2842\r
2843 //\r
2844 // Save mediaId\r
2845 //\r
2846 Dev->MediaId = BlkIo->Media->MediaId;\r
2847\r
2848 gBS->CloseProtocol(\r
2849 Controller,\r
2850 &gEfiBlockIoProtocolGuid,\r
2851 This->DriverBindingHandle,\r
2852 Controller\r
2853 );\r
2854\r
2855 //\r
2856 // Acquire Ascii printable name of child, if not found, then ignore device\r
2857 //\r
2858 Result = OpalDriverGetDriverDeviceName (Dev);\r
2859 if (!Result) {\r
2860 goto Done;\r
2861 }\r
2862\r
2863 Status = OpalDiskInitialize (Dev);\r
2864 if (EFI_ERROR (Status)) {\r
2865 goto Done;\r
2866 }\r
2867\r
2868 AddDeviceToTail(Dev);\r
2869\r
2870 //\r
2871 // Check if device is locked and prompt for password.\r
2872 //\r
2873 OpalDriverRequestPassword (Dev, L"Unlock:");\r
2874\r
2875 //\r
2876 // Process OPAL request from last boot.\r
2877 //\r
2878 ProcessOpalRequest (Dev);\r
2879\r
2880 return EFI_SUCCESS;\r
2881\r
2882Done:\r
2883 //\r
2884 // free device, close protocols and exit\r
2885 //\r
2886 gBS->CloseProtocol(\r
2887 Controller,\r
2888 &gEfiStorageSecurityCommandProtocolGuid,\r
2889 This->DriverBindingHandle,\r
2890 Controller\r
2891 );\r
2892\r
2893 FreePool(Dev);\r
2894\r
2895 return EFI_DEVICE_ERROR;\r
2896}\r
2897\r
2898/**\r
2899 Stop this driver on Controller.\r
2900\r
2901 @param This Protocol instance pointer.\r
2902 @param Controller Handle of device to stop driver on\r
2903 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of\r
2904 children is zero stop the entire bus driver.\r
2905 @param ChildHandleBuffer List of Child Handles to Stop.\r
2906\r
2907 @retval EFI_SUCCESS This driver is removed Controller.\r
2908 @retval other This driver could not be removed from this device.\r
2909\r
2910**/\r
2911EFI_STATUS\r
2912EFIAPI\r
2913OpalEfiDriverBindingStop(\r
2914 EFI_DRIVER_BINDING_PROTOCOL* This,\r
2915 EFI_HANDLE Controller,\r
2916 UINTN NumberOfChildren,\r
2917 EFI_HANDLE* ChildHandleBuffer\r
2918 )\r
2919{\r
2920 OPAL_DRIVER_DEVICE* Itr;\r
2921\r
2922 Itr = mOpalDriver.DeviceList;\r
2923\r
2924 //\r
2925 // does Controller match any of the devices we are managing for Opal\r
2926 //\r
2927 while (Itr != NULL) {\r
2928 if (Itr->Handle == Controller) {\r
2929 OpalDriverStopDevice (Itr);\r
2930 return EFI_SUCCESS;\r
2931 }\r
2932\r
2933 Itr = Itr->Next;\r
2934 }\r
2935\r
2936 return EFI_NOT_FOUND;\r
2937}\r
2938\r
2939\r
2940/**\r
2941 Unloads UEFI Driver. Very useful for debugging and testing.\r
2942\r
2943 @param ImageHandle Image Handle this driver.\r
2944\r
2945 @retval EFI_SUCCESS This function always complete successfully.\r
2946 @retval EFI_INVALID_PARAMETER The input ImageHandle is not valid.\r
2947**/\r
2948EFI_STATUS\r
2949EFIAPI\r
2950OpalEfiDriverUnload (\r
2951 IN EFI_HANDLE ImageHandle\r
2952 )\r
2953{\r
2954 EFI_STATUS Status;\r
2955 OPAL_DRIVER_DEVICE *Itr;\r
2956\r
2957 Status = EFI_SUCCESS;\r
2958\r
2959 if (ImageHandle != gImageHandle) {\r
2960 return (EFI_INVALID_PARAMETER);\r
2961 }\r
2962\r
2963 //\r
2964 // Uninstall any interface added to each device by us\r
2965 //\r
2966 while (mOpalDriver.DeviceList) {\r
2967 Itr = mOpalDriver.DeviceList;\r
2968 //\r
2969 // Remove OPAL_DRIVER_DEVICE from the list\r
2970 // it updates the controllerList pointer\r
2971 //\r
2972 OpalDriverStopDevice(Itr);\r
2973 }\r
2974\r
2975 //\r
2976 // Uninstall the HII capability\r
2977 //\r
2978 Status = HiiUninstall();\r
2979\r
2980 return Status;\r
2981}\r
2982\r