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