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