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