]> git.proxmox.com Git - mirror_edk2.git/blob - SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalHii.c
e3bde4275dfa73a9be861fb41fe6e5e653b7a7d5
[mirror_edk2.git] / SecurityPkg / Tcg / Opal / OpalPasswordDxe / OpalHii.c
1 /** @file
2 Implementation of the HII for the Opal UEFI Driver.
3
4 Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include "OpalHii.h"
16 #include "OpalDriver.h"
17 #include "OpalHiiPrivate.h"
18
19 //
20 // This is the generated IFR binary Data for each formset defined in VFR.
21 // This Data array is ready to be used as input of HiiAddPackages() to
22 // create a packagelist (which contains Form packages, String packages, etc).
23 //
24 extern UINT8 OpalPasswordFormBin[];
25
26 //
27 // This is the generated String package Data for all .UNI files.
28 // This Data array is ready to be used as input of HiiAddPackages() to
29 // create a packagelist (which contains Form packages, String packages, etc).
30 //
31 extern UINT8 OpalPasswordDxeStrings[];
32
33 CHAR16 OpalPasswordStorageName[] = L"OpalHiiConfig";
34
35 EFI_HII_CONFIG_ACCESS_PROTOCOL gHiiConfigAccessProtocol;
36
37 //
38 // Handle to the list of HII packages (forms and strings) for this driver
39 //
40 EFI_HII_HANDLE gHiiPackageListHandle = NULL;
41
42 //
43 // Package List GUID containing all form and string packages
44 //
45 const EFI_GUID gHiiPackageListGuid = PACKAGE_LIST_GUID;
46 const EFI_GUID gHiiSetupVariableGuid = SETUP_VARIABLE_GUID;
47
48 //
49 // Structure that contains state of the HII
50 // This structure is updated by Hii.cpp and its contents
51 // is rendered in the HII.
52 //
53 OPAL_HII_CONFIGURATION gHiiConfiguration;
54
55 CHAR8 gHiiOldPassword[MAX_PASSWORD_CHARACTER_LENGTH] = {0};
56 UINT32 gHiiOldPasswordLength = 0;
57
58 //
59 // The device path containing the VENDOR_DEVICE_PATH and EFI_DEVICE_PATH_PROTOCOL
60 //
61 HII_VENDOR_DEVICE_PATH gHiiVendorDevicePath = {
62 {
63 {
64 HARDWARE_DEVICE_PATH,
65 HW_VENDOR_DP,
66 {
67 (UINT8)(sizeof(VENDOR_DEVICE_PATH)),
68 (UINT8)((sizeof(VENDOR_DEVICE_PATH)) >> 8)
69 }
70 },
71 OPAL_PASSWORD_CONFIG_GUID
72 },
73 {
74 END_DEVICE_PATH_TYPE,
75 END_ENTIRE_DEVICE_PATH_SUBTYPE,
76 {
77 (UINT8)(END_DEVICE_PATH_LENGTH),
78 (UINT8)((END_DEVICE_PATH_LENGTH) >> 8)
79 }
80 }
81 };
82
83
84 /**
85 Sets the current system state of global config variables.
86
87 **/
88 VOID
89 HiiSetCurrentConfiguration(
90 VOID
91 )
92 {
93 UINT32 PpStorageFlag;
94 EFI_STRING NewString;
95
96 gHiiConfiguration.NumDisks = GetDeviceCount();
97
98 //
99 // Update the BlockSID status string.
100 //
101 PpStorageFlag = Tcg2PhysicalPresenceLibGetManagementFlags ();
102
103 if ((PpStorageFlag & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_ENABLE_BLOCK_SID) != 0) {
104 NewString = HiiGetString (gHiiPackageListHandle, STRING_TOKEN(STR_ENABLED), NULL);
105 if (NewString == NULL) {
106 DEBUG ((DEBUG_INFO, "HiiSetCurrentConfiguration: HiiGetString( ) failed\n"));
107 return;
108 }
109 } else {
110 NewString = HiiGetString (gHiiPackageListHandle, STRING_TOKEN(STR_DISABLED), NULL);
111 if (NewString == NULL) {
112 DEBUG ((DEBUG_INFO, "HiiSetCurrentConfiguration: HiiGetString( ) failed\n"));
113 return;
114 }
115 }
116 HiiSetString(gHiiPackageListHandle, STRING_TOKEN(STR_BLOCKSID_STATUS1), NewString, NULL);
117 FreePool (NewString);
118
119 if ((PpStorageFlag & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_ENABLE_BLOCK_SID) != 0) {
120 NewString = HiiGetString (gHiiPackageListHandle, STRING_TOKEN(STR_DISK_INFO_ENABLE_BLOCKSID_TRUE), NULL);
121 if (NewString == NULL) {
122 DEBUG ((DEBUG_INFO, "HiiSetCurrentConfiguration: HiiGetString( ) failed\n"));
123 return;
124 }
125 } else {
126 NewString = HiiGetString (gHiiPackageListHandle, STRING_TOKEN(STR_DISK_INFO_ENABLE_BLOCKSID_FALSE), NULL);
127 if (NewString == NULL) {
128 DEBUG ((DEBUG_INFO, "HiiSetCurrentConfiguration: HiiGetString( ) failed\n"));
129 return;
130 }
131 }
132 HiiSetString(gHiiPackageListHandle, STRING_TOKEN(STR_BLOCKSID_STATUS2), NewString, NULL);
133 FreePool (NewString);
134
135 if ((PpStorageFlag & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_DISABLE_BLOCK_SID) != 0) {
136 NewString = HiiGetString (gHiiPackageListHandle, STRING_TOKEN(STR_DISK_INFO_DISABLE_BLOCKSID_TRUE), NULL);
137 if (NewString == NULL) {
138 DEBUG ((DEBUG_INFO, "HiiSetCurrentConfiguration: HiiGetString( ) failed\n"));
139 return;
140 }
141 } else {
142 NewString = HiiGetString (gHiiPackageListHandle, STRING_TOKEN(STR_DISK_INFO_DISABLE_BLOCKSID_FALSE), NULL);
143 if (NewString == NULL) {
144 DEBUG ((DEBUG_INFO, "HiiSetCurrentConfiguration: HiiGetString( ) failed\n"));
145 return;
146 }
147 }
148 HiiSetString(gHiiPackageListHandle, STRING_TOKEN(STR_BLOCKSID_STATUS3), NewString, NULL);
149 FreePool (NewString);
150 }
151
152 /**
153 Install the HII related resources.
154
155 @retval EFI_SUCCESS Install all the resources success.
156 @retval other Error occur when install the resources.
157 **/
158 EFI_STATUS
159 HiiInstall(
160 VOID
161 )
162 {
163 EFI_STATUS Status;
164 EFI_HANDLE DriverHandle;
165
166 //
167 // Clear the global configuration.
168 //
169 ZeroMem(&gHiiConfiguration, sizeof(gHiiConfiguration));
170
171 //
172 // Obtain the driver handle that the BIOS assigned us
173 //
174 DriverHandle = HiiGetDriverImageHandleCB();
175
176 //
177 // Populate the config access protocol with the three functions we are publishing
178 //
179 gHiiConfigAccessProtocol.ExtractConfig = ExtractConfig;
180 gHiiConfigAccessProtocol.RouteConfig = RouteConfig;
181 gHiiConfigAccessProtocol.Callback = DriverCallback;
182
183 //
184 // Associate the required protocols with our driver handle
185 //
186 Status = gBS->InstallMultipleProtocolInterfaces(
187 &DriverHandle,
188 &gEfiHiiConfigAccessProtocolGuid,
189 &gHiiConfigAccessProtocol, // HII callback
190 &gEfiDevicePathProtocolGuid,
191 &gHiiVendorDevicePath, // required for HII callback allow all disks to be shown in same hii
192 NULL
193 );
194
195 if (EFI_ERROR(Status)) {
196 return Status;
197 }
198
199 return OpalHiiAddPackages();
200 }
201
202 /**
203 Install the HII form and string packages.
204
205 @retval EFI_SUCCESS Install all the resources success.
206 @retval EFI_OUT_OF_RESOURCES Out of resource error.
207 **/
208 EFI_STATUS
209 OpalHiiAddPackages(
210 VOID
211 )
212 {
213 EFI_HANDLE DriverHandle;
214 CHAR16 *NewString;
215
216 DriverHandle = HiiGetDriverImageHandleCB();
217
218 //
219 // Publish the HII form and HII string packages
220 //
221 gHiiPackageListHandle = HiiAddPackages(
222 &gHiiPackageListGuid,
223 DriverHandle,
224 OpalPasswordDxeStrings,
225 OpalPasswordFormBin,
226 (VOID*)NULL
227 );
228
229 //
230 // Make sure the packages installed successfully
231 //
232 if (gHiiPackageListHandle == NULL) {
233 DEBUG ((DEBUG_INFO, "OpalHiiAddPackages failed\n"));
234 return EFI_OUT_OF_RESOURCES;
235 }
236
237 //
238 // Update Version String in main window
239 //
240 NewString = HiiGetDriverNameCB ();
241 if (HiiSetString(gHiiPackageListHandle, STRING_TOKEN(STR_MAIN_OPAL_VERSION), NewString, NULL) == 0) {
242 DEBUG ((DEBUG_INFO, "OpalHiiAddPackages: HiiSetString( ) failed\n"));
243 return EFI_OUT_OF_RESOURCES;
244 }
245
246 return EFI_SUCCESS;
247 }
248
249 /**
250 Uninstall the HII capability.
251
252 @retval EFI_SUCCESS Uninstall all the resources success.
253 @retval others Other errors occur when unistall the hii resource.
254 **/
255 EFI_STATUS
256 HiiUninstall(
257 VOID
258 )
259 {
260 EFI_STATUS Status;
261
262 //
263 // Remove the packages we've provided to the BIOS
264 //
265 HiiRemovePackages(gHiiPackageListHandle);
266
267 //
268 // Remove the protocols from our driver handle
269 //
270 Status = gBS->UninstallMultipleProtocolInterfaces(
271 HiiGetDriverImageHandleCB(),
272 &gEfiHiiConfigAccessProtocolGuid,
273 &gHiiConfigAccessProtocol, // HII callback
274 &gEfiDevicePathProtocolGuid,
275 &gHiiVendorDevicePath, // required for HII callback
276 NULL
277 );
278 if (EFI_ERROR(Status)) {
279 DEBUG ((DEBUG_INFO, "Cannot uninstall Hii Protocols: %r\n", Status));
280 }
281
282 return Status;
283 }
284
285 /**
286 Updates the main menu form.
287
288 @retval EFI_SUCCESS update the main form success.
289 **/
290 EFI_STATUS
291 HiiPopulateMainMenuForm (
292 VOID
293 )
294 {
295 UINT8 Index;
296 CHAR8 *DiskName;
297 EFI_STRING_ID DiskNameId;
298 OPAL_DISK *OpalDisk;
299
300 HiiSetCurrentConfiguration();
301
302 gHiiConfiguration.SupportedDisks = 0;
303
304 for (Index = 0; Index < gHiiConfiguration.NumDisks; Index++) {
305 OpalDisk = HiiGetOpalDiskCB (Index);
306 if ((OpalDisk != NULL) && OpalFeatureSupported (&OpalDisk->SupportedAttributes)) {
307 gHiiConfiguration.SupportedDisks |= (1 << Index);
308 DiskNameId = GetDiskNameStringId (Index);
309 DiskName = HiiDiskGetNameCB (Index);
310 if ((DiskName == NULL) || (DiskNameId == 0)) {
311 return EFI_UNSUPPORTED;
312 }
313 HiiSetFormString(DiskNameId, DiskName);
314 }
315 }
316
317 OpalHiiSetBrowserData ();
318 return EFI_SUCCESS;
319 }
320
321 /**
322 Update the disk action info.
323
324 @param ActionString
325 @param SelectedAction
326
327 @retval EFI_SUCCESS Uninstall all the resources success.
328 **/
329 EFI_STATUS
330 HiiSelectDiskAction (
331 CHAR8 *ActionString,
332 UINT8 SelectedAction
333 )
334 {
335 OPAL_DISK *OpalDisk;
336 OPAL_DISK_ACTIONS AvailActions;
337
338 OpalHiiGetBrowserData ();
339
340 HiiSetFormString(STRING_TOKEN(STR_DISK_ACTION_LBL), ActionString);
341 HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS), " ");
342
343 gHiiConfiguration.SelectedAction = SelectedAction;
344 gHiiConfiguration.AvailableFields = 0;
345
346 OpalDisk = HiiGetOpalDiskCB(gHiiConfiguration.SelectedDiskIndex);
347 if (OpalDisk == NULL) {
348 return EFI_INVALID_PARAMETER;
349 }
350
351 if (OpalSupportGetAvailableActions (&OpalDisk->SupportedAttributes, &OpalDisk->LockingFeature, OpalDisk->Owner, &AvailActions) != TcgResultSuccess) {
352 return EFI_DEVICE_ERROR;
353 }
354
355 switch (SelectedAction) {
356 case HII_KEY_ID_GOTO_LOCK:
357 case HII_KEY_ID_GOTO_UNLOCK:
358 case HII_KEY_ID_GOTO_SET_ADMIN_PWD:
359 case HII_KEY_ID_GOTO_SET_USER_PWD:
360 case HII_KEY_ID_GOTO_SECURE_ERASE:
361 case HII_KEY_ID_GOTO_DISABLE_USER:
362 case HII_KEY_ID_GOTO_ENABLE_FEATURE: // User is required to enter Password to enable Feature
363 gHiiConfiguration.AvailableFields |= HII_FIELD_PASSWORD;
364 break;
365
366 case HII_KEY_ID_GOTO_PSID_REVERT:
367 gHiiConfiguration.AvailableFields |= HII_FIELD_PSID;
368 break;
369
370 case HII_KEY_ID_GOTO_REVERT:
371 gHiiConfiguration.AvailableFields |= HII_FIELD_PASSWORD;
372 gHiiConfiguration.AvailableFields |= HII_FIELD_KEEP_USER_DATA;
373 if (AvailActions.RevertKeepDataForced) {
374 gHiiConfiguration.AvailableFields |= HII_FIELD_KEEP_USER_DATA_FORCED;
375 }
376 break;
377 }
378
379 OpalHiiSetBrowserData ();
380
381 return EFI_SUCCESS;
382 }
383
384 /**
385 Get disk name string id.
386
387 @param DiskIndex The input disk index info.
388
389 @retval The disk name string id.
390
391 **/
392 EFI_STRING_ID
393 GetDiskNameStringId(
394 UINT8 DiskIndex
395 )
396 {
397 switch (DiskIndex) {
398 case 0: return STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_0);
399 case 1: return STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_1);
400 case 2: return STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_2);
401 case 3: return STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_3);
402 case 4: return STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_4);
403 case 5: return STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_5);
404 }
405 return 0;
406 }
407
408 /**
409 This function processes the results of changes in configuration.
410
411 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
412 @param Action Specifies the type of action taken by the browser.
413 @param QuestionId A unique value which is sent to the original
414 exporting driver so that it can identify the type
415 of data to expect.
416 @param Type The type of value for the question.
417 @param Value A pointer to the data being sent to the original
418 exporting driver.
419 @param ActionRequest On return, points to the action requested by the
420 callback function.
421
422 @retval EFI_SUCCESS The callback successfully handled the action.
423 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
424 variable and its data.
425 @retval EFI_DEVICE_ERROR The variable could not be saved.
426 @retval EFI_UNSUPPORTED The specified Action is not supported by the
427 callback.
428
429 **/
430 EFI_STATUS
431 EFIAPI
432 DriverCallback(
433 CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
434 EFI_BROWSER_ACTION Action,
435 EFI_QUESTION_ID QuestionId,
436 UINT8 Type,
437 EFI_IFR_TYPE_VALUE *Value,
438 EFI_BROWSER_ACTION_REQUEST *ActionRequest
439 )
440 {
441 HII_KEY HiiKey;
442 UINT8 HiiKeyId;
443 UINT32 PpRequest;
444
445 if (ActionRequest != NULL) {
446 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
447 } else {
448 return EFI_INVALID_PARAMETER;
449 }
450
451 //
452 // If QuestionId is an auto-generated key (label, empty line, etc.), ignore it.
453 //
454 if ((QuestionId & HII_KEY_FLAG) == 0) {
455 return EFI_SUCCESS;
456 }
457
458 HiiKey.Raw = QuestionId;
459 HiiKeyId = (UINT8) HiiKey.KeyBits.Id;
460
461 if (Action == EFI_BROWSER_ACTION_FORM_OPEN) {
462 switch (HiiKeyId) {
463 case HII_KEY_ID_VAR_SUPPORTED_DISKS:
464 DEBUG ((DEBUG_INFO, "HII_KEY_ID_VAR_SUPPORTED_DISKS\n"));
465 return HiiPopulateMainMenuForm ();
466
467 case HII_KEY_ID_VAR_SELECTED_DISK_AVAILABLE_ACTIONS:
468 return HiiPopulateDiskInfoForm();
469 }
470 } else if (Action == EFI_BROWSER_ACTION_CHANGING) {
471 switch (HiiKeyId) {
472 case HII_KEY_ID_GOTO_DISK_INFO:
473 return HiiSelectDisk((UINT8)HiiKey.KeyBits.Index);
474
475 case HII_KEY_ID_GOTO_LOCK:
476 return HiiSelectDiskAction("Action: Lock", HiiKeyId);
477
478 case HII_KEY_ID_GOTO_UNLOCK:
479 return HiiSelectDiskAction("Action: Unlock", HiiKeyId);
480
481 case HII_KEY_ID_GOTO_SET_ADMIN_PWD:
482 return HiiSelectDiskAction("Action: Set Administrator Password", HiiKeyId);
483
484 case HII_KEY_ID_GOTO_SET_USER_PWD:
485 return HiiSelectDiskAction("Action: Set User Password", HiiKeyId);
486
487 case HII_KEY_ID_GOTO_SECURE_ERASE:
488 return HiiSelectDiskAction("Action: Secure Erase", HiiKeyId);
489
490 case HII_KEY_ID_GOTO_PSID_REVERT:
491 return HiiSelectDiskAction("Action: Revert to Factory Defaults with PSID", HiiKeyId);
492
493 case HII_KEY_ID_GOTO_REVERT:
494 return HiiSelectDiskAction("Action: Revert to Factory Defaults", HiiKeyId);
495
496 case HII_KEY_ID_GOTO_DISABLE_USER:
497 return HiiSelectDiskAction("Action: Disable User", HiiKeyId);
498
499 case HII_KEY_ID_GOTO_ENABLE_FEATURE:
500 return HiiSelectDiskAction("Action: Enable Feature", HiiKeyId);
501
502 case HII_KEY_ID_ENTER_PASSWORD:
503 return HiiPasswordEntered(Value->string);
504
505 case HII_KEY_ID_ENTER_PSID:
506 return HiiPsidRevert(Value->string);
507
508 }
509 } else if (Action == EFI_BROWSER_ACTION_CHANGED) {
510 switch (HiiKeyId) {
511 case HII_KEY_ID_BLOCKSID:
512 switch (Value->u8) {
513 case 0:
514 PpRequest = TCG2_PHYSICAL_PRESENCE_NO_ACTION;
515 break;
516
517 case 1:
518 PpRequest = TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID;
519 break;
520
521 case 2:
522 PpRequest = TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID;
523 break;
524
525 case 3:
526 PpRequest = TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_TRUE;
527 break;
528
529 case 4:
530 PpRequest = TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_FALSE;
531 break;
532
533 case 5:
534 PpRequest = TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_TRUE;
535 break;
536
537 case 6:
538 PpRequest = TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_FALSE;
539 break;
540
541 default:
542 PpRequest = TCG2_PHYSICAL_PRESENCE_NO_ACTION;
543 DEBUG ((DEBUG_ERROR, "Invalid value input!\n"));
544 break;
545 }
546 HiiSetBlockSidAction(PpRequest);
547
548 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
549 return EFI_SUCCESS;
550
551 default:
552 break;
553 }
554 }
555
556 return EFI_UNSUPPORTED;
557 }
558
559 /**
560 Update the global Disk index info.
561
562 @param Index The input disk index info.
563
564 @retval EFI_SUCCESS Update the disk index info success.
565
566 **/
567 EFI_STATUS
568 HiiSelectDisk(
569 UINT8 Index
570 )
571 {
572 OpalHiiGetBrowserData();
573 gHiiConfiguration.SelectedDiskIndex = Index;
574 OpalHiiSetBrowserData ();
575
576 return EFI_SUCCESS;
577 }
578
579 /**
580 Draws the disk info form.
581
582 @retval EFI_SUCCESS Draw the disk info success.
583
584 **/
585 EFI_STATUS
586 HiiPopulateDiskInfoForm(
587 VOID
588 )
589 {
590 OPAL_DISK* OpalDisk;
591 OPAL_DISK_ACTIONS AvailActions;
592 TCG_RESULT Ret;
593 CHAR8 *DiskName;
594
595 OpalHiiGetBrowserData();
596
597 DiskName = HiiDiskGetNameCB (gHiiConfiguration.SelectedDiskIndex);
598 if (DiskName == NULL) {
599 return EFI_UNSUPPORTED;
600 }
601 HiiSetFormString(STRING_TOKEN(STR_DISK_INFO_SELECTED_DISK_NAME), DiskName);
602
603 ZeroMem(gHiiConfiguration.Psid, sizeof(gHiiConfiguration.Psid));
604
605 gHiiConfiguration.SelectedDiskAvailableActions = HII_ACTION_NONE;
606
607 OpalDisk = HiiGetOpalDiskCB(gHiiConfiguration.SelectedDiskIndex);
608
609 if (OpalDisk != NULL) {
610 OpalDiskUpdateStatus (OpalDisk);
611 Ret = OpalSupportGetAvailableActions(&OpalDisk->SupportedAttributes, &OpalDisk->LockingFeature, OpalDisk->Owner, &AvailActions);
612 if (Ret == TcgResultSuccess) {
613 //
614 // Update actions, always allow PSID Revert
615 //
616 gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.PsidRevert == 1) ? HII_ACTION_PSID_REVERT : HII_ACTION_NONE;
617
618 //
619 // Always allow unlock to handle device migration
620 //
621 gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.Unlock == 1) ? HII_ACTION_UNLOCK : HII_ACTION_NONE;
622
623 if (!OpalFeatureEnabled (&OpalDisk->SupportedAttributes, &OpalDisk->LockingFeature)) {
624 if (OpalDisk->Owner == OpalOwnershipNobody) {
625 gHiiConfiguration.SelectedDiskAvailableActions |= HII_ACTION_ENABLE_FEATURE;
626
627 //
628 // Update strings
629 //
630 HiiSetFormString( STRING_TOKEN(STR_DISK_INFO_PSID_REVERT), "PSID Revert to factory default");
631 } else {
632 DEBUG ((DEBUG_INFO, "Feature disabled but ownership != nobody\n"));
633 }
634 } else {
635 gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.Revert == 1) ? HII_ACTION_REVERT : HII_ACTION_NONE;
636 gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.AdminPass == 1) ? HII_ACTION_SET_ADMIN_PWD : HII_ACTION_NONE;
637 gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.UserPass == 1) ? HII_ACTION_SET_USER_PWD : HII_ACTION_NONE;
638 gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.SecureErase == 1) ? HII_ACTION_SECURE_ERASE : HII_ACTION_NONE;
639 gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.DisableUser == 1) ? HII_ACTION_DISABLE_USER : HII_ACTION_NONE;
640
641 HiiSetFormString (STRING_TOKEN(STR_DISK_INFO_PSID_REVERT), "PSID Revert to factory default and Disable");
642
643 //
644 // Determine revert options for disk
645 // Default initialize keep user Data to be true
646 //
647 gHiiConfiguration.KeepUserData = 1;
648 }
649 }
650 }
651
652 //
653 // Pass the current configuration to the BIOS
654 //
655 OpalHiiSetBrowserData ();
656
657 return EFI_SUCCESS;
658 }
659
660 /**
661 Reverts the Opal disk to factory default.
662
663 @param PsidStringId The string id for the PSID info.
664
665 @retval EFI_SUCCESS Do the required action success.
666
667 **/
668 EFI_STATUS
669 HiiPsidRevert(
670 EFI_STRING_ID PsidStringId
671 )
672 {
673 CHAR8 Response[DEFAULT_RESPONSE_SIZE];
674 TCG_PSID Psid;
675 OPAL_DISK *OpalDisk;
676 TCG_RESULT Ret;
677 OPAL_SESSION Session;
678 CHAR16 *UnicodeStr;
679 UINT8 TmpBuf[PSID_CHARACTER_STRING_END_LENGTH];
680
681 Ret = TcgResultFailure;
682
683 UnicodeStr = HiiGetString (gHiiPackageListHandle, PsidStringId, NULL);
684 ZeroMem (TmpBuf, sizeof (TmpBuf));
685 UnicodeStrToAsciiStrS (UnicodeStr, (CHAR8*)TmpBuf, PSID_CHARACTER_STRING_END_LENGTH);
686 CopyMem (Psid.Psid, TmpBuf, PSID_CHARACTER_LENGTH);
687 HiiSetString (gHiiPackageListHandle, PsidStringId, L"", NULL);
688 ZeroMem (TmpBuf, sizeof (TmpBuf));
689 ZeroMem (UnicodeStr, StrSize (UnicodeStr));
690 FreePool (UnicodeStr);
691
692 OpalDisk = HiiGetOpalDiskCB (gHiiConfiguration.SelectedDiskIndex);
693 if (OpalDisk != NULL) {
694 ZeroMem(&Session, sizeof(Session));
695 Session.Sscp = OpalDisk->Sscp;
696 Session.MediaId = OpalDisk->MediaId;
697 Session.OpalBaseComId = OpalDisk->OpalBaseComId;
698
699 Ret = OpalSupportPsidRevert(&Session, Psid.Psid, (UINT32)sizeof(Psid.Psid), OpalDisk->OpalDevicePath);
700 }
701
702 ZeroMem (Psid.Psid, PSID_CHARACTER_LENGTH);
703
704 if (Ret == TcgResultSuccess) {
705 AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "PSID Revert: Success" );
706 } else {
707 AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "PSID Revert: Failure" );
708 }
709
710 HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS), Response);
711
712 return EFI_SUCCESS;
713 }
714
715 /**
716 Set password for the disk.
717
718 @param OpalDisk The disk need to set the password.
719 @param Password The input password.
720 @param PassLength The input password length.
721
722 @retval EFI_SUCCESS Do the required action success.
723
724 **/
725 EFI_STATUS
726 HiiSetPassword(
727 OPAL_DISK *OpalDisk,
728 VOID *Password,
729 UINT32 PassLength
730 )
731 {
732 CHAR8 Response[DEFAULT_RESPONSE_SIZE];
733 TCG_RESULT Ret;
734 BOOLEAN ExistingPassword;
735 OPAL_SESSION Session;
736
737 ExistingPassword = FALSE;
738
739 //
740 // PassLength = 0 means check whether exist old password.
741 //
742 if (PassLength == 0) {
743 ZeroMem(gHiiOldPassword, sizeof(gHiiOldPassword));
744 gHiiOldPasswordLength = 0;
745
746 if (gHiiConfiguration.SelectedAction == HII_KEY_ID_GOTO_ENABLE_FEATURE) {
747 ExistingPassword = FALSE;
748 } else if (gHiiConfiguration.SelectedAction == HII_KEY_ID_GOTO_SET_ADMIN_PWD) {
749 ExistingPassword = OpalUtilAdminPasswordExists(OpalDisk->Owner, &OpalDisk->LockingFeature);
750 } else if (gHiiConfiguration.SelectedAction == HII_KEY_ID_GOTO_SET_USER_PWD) {
751 //
752 // Set user Password option shall only be shown if an Admin Password exists
753 // so a Password is always required (Admin or Existing User Password)
754 //
755 ExistingPassword = TRUE;
756 }
757
758 //
759 // Return error if there is a previous Password
760 // see UEFI 2.4 errata B, Figure 121. Password Flowchart
761 //
762 return ExistingPassword ? EFI_DEVICE_ERROR : EFI_SUCCESS;
763 }
764
765 ZeroMem(&Session, sizeof(Session));
766 Session.Sscp = OpalDisk->Sscp;
767 Session.MediaId = OpalDisk->MediaId;
768 Session.OpalBaseComId = OpalDisk->OpalBaseComId;
769
770 AsciiSPrint(Response, DEFAULT_RESPONSE_SIZE, "%a", "Set Password: Failure");
771 //
772 // Password entered.
773 // No current Owner, so set new Password, must be admin Password
774 //
775 if (OpalDisk->Owner == OpalOwnershipNobody) {
776 Ret = OpalSupportEnableOpalFeature (&Session, OpalDisk->Msid, OpalDisk->MsidLength,Password, PassLength, OpalDisk->OpalDevicePath);
777 if (Ret == TcgResultSuccess) {
778 AsciiSPrint(Response, DEFAULT_RESPONSE_SIZE, "%a", "Set Password: Success");
779 }
780
781 HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS), Response);
782 return EFI_SUCCESS;
783 }
784
785 //
786 // 1st Password entered
787 //
788 if (OpalDisk->Owner == OpalOwnershipUnknown && gHiiOldPasswordLength == 0) {
789
790 //
791 // Unknown ownership - prompt for old Password, then new
792 // old Password is not set yet - first time through
793 // assume authority provided is admin1, overwritten if user1 authority works below
794 //
795 if (gHiiConfiguration.SelectedAction == HII_KEY_ID_GOTO_SET_USER_PWD) {
796 //
797 // First try to login as USER1 to Locking SP to see if we're simply updating its Password
798 //
799 Ret = OpalUtilVerifyPassword (&Session, Password, PassLength, OPAL_LOCKING_SP_USER1_AUTHORITY);
800 if (Ret == TcgResultSuccess) {
801 //
802 // User1 worked so authority 1 means user 1
803 //
804 CopyMem(gHiiOldPassword, Password, PassLength);
805 gHiiOldPasswordLength = PassLength;
806
807 return EFI_SUCCESS;
808 }
809 }
810
811 //
812 // Else try admin1 below
813 //
814 Ret = OpalUtilVerifyPassword (&Session, Password, PassLength, OPAL_LOCKING_SP_ADMIN1_AUTHORITY);
815 if (Ret == TcgResultSuccess) {
816 CopyMem(gHiiOldPassword, Password, PassLength);
817 gHiiOldPasswordLength = PassLength;
818
819 return EFI_SUCCESS;
820 } else {
821 DEBUG ((DEBUG_INFO, "start session with old PW failed - return EFI_NOT_READY - mistyped old PW\n"));
822 HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS), "Authentication Failure");
823
824 ZeroMem(gHiiOldPassword, sizeof(gHiiOldPassword));
825 gHiiOldPasswordLength = 0;
826
827 return EFI_NOT_READY;
828 }
829 }
830
831 //
832 // New Password entered
833 //
834 if (gHiiConfiguration.SelectedAction == HII_KEY_ID_GOTO_SET_USER_PWD) {
835 Ret = OpalSupportSetPassword(
836 &Session,
837 gHiiOldPassword,
838 gHiiOldPasswordLength,
839 Password,
840 PassLength,
841 OpalDisk->OpalDevicePath,
842 FALSE
843 );
844 } else {
845 Ret = OpalSupportSetPassword(
846 &Session,
847 gHiiOldPassword,
848 gHiiOldPasswordLength,
849 Password,
850 PassLength,
851 OpalDisk->OpalDevicePath,
852 TRUE
853 );
854 }
855
856 if (Ret == TcgResultSuccess) {
857 AsciiSPrint(Response, DEFAULT_RESPONSE_SIZE, "%a", "Set Password: Success");
858 }
859
860 //
861 // Reset old Password storage
862 //
863 ZeroMem(gHiiOldPassword, sizeof(gHiiOldPassword));
864 gHiiOldPasswordLength = 0;
865
866 HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS), Response);
867 return Ret == TcgResultSuccess ? EFI_SUCCESS : EFI_NOT_READY;
868 }
869
870 /**
871 Secure Erases Opal Disk.
872
873 @param OpalDisk The disk need to erase data.
874 @param Password The input password.
875 @param PassLength The input password length.
876
877 @retval EFI_SUCCESS Do the required action success.
878
879 **/
880 EFI_STATUS
881 HiiSecureErase(
882 OPAL_DISK *OpalDisk,
883 const VOID *Password,
884 UINT32 PassLength
885 )
886 {
887 CHAR8 Response[DEFAULT_RESPONSE_SIZE];
888 BOOLEAN PasswordFailed;
889 TCG_RESULT Ret;
890 OPAL_SESSION AdminSpSession;
891
892 if (PassLength == 0) {
893 return EFI_DEVICE_ERROR; // return error to indicate there is an existing Password
894 }
895
896 ZeroMem(&AdminSpSession, sizeof(AdminSpSession));
897 AdminSpSession.Sscp = OpalDisk->Sscp;
898 AdminSpSession.MediaId = OpalDisk->MediaId;
899 AdminSpSession.OpalBaseComId = OpalDisk->OpalBaseComId;
900
901 Ret = OpalUtilSecureErase(&AdminSpSession, Password, PassLength, &PasswordFailed);
902 if (Ret == TcgResultSuccess) {
903 AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "Secure Erase: Success" );
904 } else {
905 AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "Secure Erase: Failure" );
906 }
907 HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS), Response);
908
909 //
910 // If Password failed, return invalid passowrd
911 //
912 if (PasswordFailed) {
913 DEBUG ((DEBUG_INFO, "returning EFI_NOT_READY to indicate Password was not correct\n"));
914 return EFI_NOT_READY;
915 }
916
917 //
918 // Indicates Password was valid and is not changing to UEFI
919 // Response string will indicate action error
920 //
921 return EFI_DEVICE_ERROR;
922 }
923
924
925 /**
926 Disables User for Opal Disk.
927
928 @param OpalDisk The disk need to the action.
929 @param Password The input password.
930 @param PassLength The input password length.
931
932 @retval EFI_SUCCESS Do the required action success.
933
934 **/
935 EFI_STATUS
936 HiiDisableUser(
937 OPAL_DISK *OpalDisk,
938 VOID *Password,
939 UINT32 PassLength
940 )
941 {
942 CHAR8 Response[ DEFAULT_RESPONSE_SIZE ];
943 BOOLEAN PasswordFailed;
944 TCG_RESULT Ret;
945 OPAL_SESSION Session;
946
947 if (PassLength == 0) {
948 return EFI_DEVICE_ERROR; // return error to indicate there is an existing Password
949 }
950
951 ZeroMem(&Session, sizeof(Session));
952 Session.Sscp = OpalDisk->Sscp;
953 Session.MediaId = OpalDisk->MediaId;
954 Session.OpalBaseComId = OpalDisk->OpalBaseComId;
955
956 Ret = OpalSupportDisableUser(&Session, Password, PassLength, &PasswordFailed, OpalDisk->OpalDevicePath);
957 if (Ret == TcgResultSuccess) {
958 AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "Disable User: Success" );
959 } else {
960 AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "Disable User: Failure" );
961 }
962 HiiSetFormString (STRING_TOKEN(STR_ACTION_STATUS), Response);
963
964 //
965 // If Password failed, return invalid passowrd
966 //
967 if (PasswordFailed) {
968 DEBUG ((DEBUG_INFO, "returning EFI_NOT_READY to indicate Password was not correct\n"));
969 return EFI_NOT_READY;
970 }
971
972 //
973 // Indicates Password was valid and is not changing to UEFI
974 // Response string will indicate action error
975 //
976 return EFI_DEVICE_ERROR;
977 }
978
979 /**
980 Revert Opal Disk as Admin1.
981
982 @param OpalDisk The disk need to the action.
983 @param Password The input password.
984 @param PassLength The input password length.
985 @param KeepUserData Whether need to keey user data.
986
987 @retval EFI_SUCCESS Do the required action success.
988
989 **/
990 EFI_STATUS
991 HiiRevert(
992 OPAL_DISK *OpalDisk,
993 VOID *Password,
994 UINT32 PassLength,
995 BOOLEAN KeepUserData
996 )
997 {
998 CHAR8 Response[ DEFAULT_RESPONSE_SIZE ];
999 BOOLEAN PasswordFailed;
1000 TCG_RESULT Ret;
1001 OPAL_SESSION Session;
1002
1003 if (PassLength == 0) {
1004 DEBUG ((DEBUG_INFO, "Returning error to indicate there is an existing Password\n"));
1005 // return error to indicate there is an existing Password
1006 return EFI_DEVICE_ERROR;
1007 }
1008
1009 ZeroMem(&Session, sizeof(Session));
1010 Session.Sscp = OpalDisk->Sscp;
1011 Session.MediaId = OpalDisk->MediaId;
1012 Session.OpalBaseComId = OpalDisk->OpalBaseComId;
1013
1014 Ret = OpalSupportRevert(
1015 &Session,
1016 KeepUserData,
1017 Password,
1018 PassLength,
1019 OpalDisk->Msid,
1020 OpalDisk->MsidLength,
1021 &PasswordFailed,
1022 OpalDisk->OpalDevicePath
1023 );
1024 if (Ret == TcgResultSuccess) {
1025 AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "Revert: Success" );
1026 } else {
1027 AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "Revert: Failure" );
1028 }
1029 HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS), Response);
1030
1031 //
1032 // If Password failed, return invalid passowrd
1033 //
1034 if (PasswordFailed) {
1035 DEBUG ((DEBUG_INFO, "returning EFI_NOT_READY to indicate Password was not correct\n"));
1036 return EFI_NOT_READY;
1037 }
1038
1039 //
1040 // Indicates Password was valid and is not changing to UEFI
1041 // Response string will indicate action error
1042 //
1043 return EFI_DEVICE_ERROR;
1044 }
1045
1046 /**
1047 Unlocks Opal Disk.
1048
1049 @param OpalDisk The disk need to the action.
1050 @param Password The input password.
1051 @param PassLength The input password length.
1052
1053 @retval EFI_SUCCESS Do the required action success.
1054
1055 **/
1056 EFI_STATUS
1057 HiiUnlock(
1058 OPAL_DISK *OpalDisk,
1059 VOID *Password,
1060 UINT32 PassLength
1061 )
1062 {
1063 CHAR8 Response[DEFAULT_RESPONSE_SIZE];
1064 TCG_RESULT Ret;
1065 OPAL_SESSION Session;
1066
1067 if (PassLength == 0) {
1068 DEBUG ((DEBUG_INFO, "Returning error to indicate there is an existing Password\n"));
1069 return EFI_DEVICE_ERROR; // return error to indicate there is an existing Password
1070 }
1071
1072 ZeroMem(&Session, sizeof(Session));
1073 Session.Sscp = OpalDisk->Sscp;
1074 Session.MediaId = OpalDisk->MediaId;
1075 Session.OpalBaseComId = OpalDisk->OpalBaseComId;
1076
1077 Ret = OpalSupportUnlock(&Session, Password, PassLength, OpalDisk->OpalDevicePath);
1078 if (Ret == TcgResultSuccess) {
1079 AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "Unlock: Success" );
1080 } else {
1081 AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "Unlock: Failure" );
1082 }
1083
1084 HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS), Response);
1085
1086 if (Ret == TcgResultSuccess) {
1087 DEBUG ((DEBUG_INFO, "returning error to indicate Password was correct but is not changing\n"));
1088 return EFI_DEVICE_ERROR;
1089 } else {
1090 DEBUG ((DEBUG_INFO, "returning EFI_NOT_READY to indicate Password was not correct\n"));
1091 return EFI_NOT_READY;
1092 }
1093 }
1094
1095 /**
1096 Use the input password to do the specified action.
1097
1098 @param Str The input password saved in.
1099
1100 @retval EFI_SUCCESS Do the required action success.
1101 @retval Others Other error occur.
1102
1103 **/
1104 EFI_STATUS
1105 HiiPasswordEntered(
1106 EFI_STRING_ID Str
1107 )
1108 {
1109 OPAL_DISK* OpalDisk;
1110 CHAR8 Password[MAX_PASSWORD_CHARACTER_LENGTH + 1];
1111 CHAR16* UniStr;
1112 UINT32 PassLength;
1113 EFI_STATUS Status;
1114
1115 OpalHiiGetBrowserData();
1116
1117 OpalDisk = HiiGetOpalDiskCB(gHiiConfiguration.SelectedDiskIndex);
1118 if (OpalDisk == NULL) {
1119 DEBUG ((DEBUG_INFO, "ERROR: disk %u not found\n", gHiiConfiguration.SelectedDiskIndex));
1120 return EFI_NOT_FOUND;
1121 }
1122
1123 if (Str == 0) {
1124 DEBUG ((DEBUG_INFO, "ERROR: str=NULL\n"));
1125 return EFI_INVALID_PARAMETER;
1126 }
1127
1128 ZeroMem(Password, sizeof(Password));
1129
1130 UniStr = HiiGetString(gHiiPackageListHandle, Str, NULL);
1131 if (UniStr == NULL) {
1132 return EFI_NOT_FOUND;
1133 }
1134
1135 HiiSetString(gHiiPackageListHandle, Str, L"", NULL);
1136
1137 PassLength = (UINT32) StrLen (UniStr);
1138 if (PassLength >= sizeof(Password)) {
1139 HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS), "Password too long");
1140 ZeroMem (UniStr, StrSize (UniStr));
1141 FreePool(UniStr);
1142 return EFI_BUFFER_TOO_SMALL;
1143 }
1144
1145 UnicodeStrToAsciiStrS (UniStr, Password, sizeof (Password));
1146 ZeroMem (UniStr, StrSize (UniStr));
1147 FreePool(UniStr);
1148
1149 if (gHiiConfiguration.SelectedAction == HII_KEY_ID_GOTO_UNLOCK) {
1150 Status = HiiUnlock (OpalDisk, Password, PassLength);
1151 } else if (gHiiConfiguration.SelectedAction == HII_KEY_ID_GOTO_SECURE_ERASE) {
1152 Status = HiiSecureErase (OpalDisk, Password, PassLength);
1153 } else if (gHiiConfiguration.SelectedAction == HII_KEY_ID_GOTO_DISABLE_USER) {
1154 Status = HiiDisableUser (OpalDisk, Password, PassLength);
1155 } else if (gHiiConfiguration.SelectedAction == HII_KEY_ID_GOTO_REVERT) {
1156 if (OpalDisk->SupportedAttributes.PyriteSsc == 1 && OpalDisk->LockingFeature.MediaEncryption == 0) {
1157 //
1158 // For pyrite type device which also not supports media encryption, it not accept "Keep User Data" parameter.
1159 // So here hardcode a FALSE for this case.
1160 //
1161 Status = HiiRevert(OpalDisk, Password, PassLength, FALSE);
1162 } else {
1163 Status = HiiRevert(OpalDisk, Password, PassLength, gHiiConfiguration.KeepUserData);
1164 }
1165 } else {
1166 Status = HiiSetPassword(OpalDisk, Password, PassLength);
1167 }
1168
1169 ZeroMem (Password, sizeof (Password));
1170
1171 OpalHiiSetBrowserData ();
1172
1173 return Status;
1174 }
1175
1176 /**
1177 Send BlockSid request through TPM physical presence module.
1178
1179 @param PpRequest TPM physical presence operation request.
1180
1181 @retval EFI_SUCCESS Do the required action success.
1182 @retval Others Other error occur.
1183
1184 **/
1185 EFI_STATUS
1186 HiiSetBlockSidAction (
1187 IN UINT32 PpRequest
1188 )
1189 {
1190 UINT32 ReturnCode;
1191 EFI_STATUS Status;
1192
1193 ReturnCode = Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (PpRequest, 0);
1194 if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS) {
1195 Status = EFI_SUCCESS;
1196 } else if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE) {
1197 Status = EFI_OUT_OF_RESOURCES;
1198 } else if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED) {
1199 Status = EFI_UNSUPPORTED;
1200 } else {
1201 Status = EFI_DEVICE_ERROR;
1202 }
1203
1204 return Status;
1205 }
1206
1207 /**
1208 This function processes the results of changes in configuration.
1209
1210 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1211 @param Configuration A null-terminated Unicode string in <ConfigResp>
1212 format.
1213 @param Progress A pointer to a string filled in with the offset of
1214 the most recent '&' before the first failing
1215 name/value pair (or the beginning of the string if
1216 the failure is in the first name/value pair) or
1217 the terminating NULL if all was successful.
1218
1219 @retval EFI_SUCCESS The Results is processed successfully.
1220 @retval EFI_INVALID_PARAMETER Configuration is NULL.
1221 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
1222 driver.
1223
1224 **/
1225 EFI_STATUS
1226 EFIAPI
1227 RouteConfig(
1228 CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
1229 CONST EFI_STRING Configuration,
1230 EFI_STRING *Progress
1231 )
1232 {
1233 if (Configuration == NULL || Progress == NULL) {
1234 return (EFI_INVALID_PARAMETER);
1235 }
1236
1237 *Progress = Configuration;
1238 if (!HiiIsConfigHdrMatch (Configuration, &gHiiSetupVariableGuid, OpalPasswordStorageName)) {
1239 return EFI_NOT_FOUND;
1240 }
1241
1242 *Progress = Configuration + StrLen (Configuration);
1243
1244 return EFI_SUCCESS;
1245 }
1246
1247 /**
1248 This function allows a caller to extract the current configuration for one
1249 or more named elements from the target driver.
1250
1251 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1252 @param Request A null-terminated Unicode string in
1253 <ConfigRequest> format.
1254 @param Progress On return, points to a character in the Request
1255 string. Points to the string's null terminator if
1256 request was successful. Points to the most recent
1257 '&' before the first failing name/value pair (or
1258 the beginning of the string if the failure is in
1259 the first name/value pair) if the request was not
1260 successful.
1261 @param Results A null-terminated Unicode string in
1262 <ConfigAltResp> format which has all values filled
1263 in for the names in the Request string. String to
1264 be allocated by the called function.
1265
1266 @retval EFI_SUCCESS The Results is filled with the requested values.
1267 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
1268 @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.
1269 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
1270 driver.
1271
1272 **/
1273 EFI_STATUS
1274 EFIAPI
1275 ExtractConfig(
1276 CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
1277 CONST EFI_STRING Request,
1278 EFI_STRING *Progress,
1279 EFI_STRING *Results
1280 )
1281 {
1282 EFI_STATUS Status;
1283 EFI_STRING ConfigRequest;
1284 EFI_STRING ConfigRequestHdr;
1285 UINTN BufferSize;
1286 UINTN Size;
1287 BOOLEAN AllocatedRequest;
1288 EFI_HANDLE DriverHandle;
1289
1290 //
1291 // Check for valid parameters
1292 //
1293 if (Progress == NULL || Results == NULL) {
1294 return (EFI_INVALID_PARAMETER);
1295 }
1296
1297 *Progress = Request;
1298 if ((Request != NULL) &&
1299 !HiiIsConfigHdrMatch (Request, &gHiiSetupVariableGuid, OpalPasswordStorageName)) {
1300 return EFI_NOT_FOUND;
1301 }
1302
1303 AllocatedRequest = FALSE;
1304 BufferSize = sizeof (OPAL_HII_CONFIGURATION);
1305 ConfigRequest = Request;
1306 if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
1307 //
1308 // Request has no request element, construct full request string.
1309 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
1310 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
1311 //
1312 DriverHandle = HiiGetDriverImageHandleCB();
1313 ConfigRequestHdr = HiiConstructConfigHdr (&gHiiSetupVariableGuid, OpalPasswordStorageName, DriverHandle);
1314 Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
1315 ConfigRequest = AllocateZeroPool (Size);
1316 if (ConfigRequest == NULL) {
1317 return EFI_OUT_OF_RESOURCES;
1318 }
1319 AllocatedRequest = TRUE;
1320 UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
1321 FreePool (ConfigRequestHdr);
1322 }
1323
1324 //
1325 // Convert Buffer Data to <ConfigResp> by helper function BlockToConfig( )
1326 //
1327 Status = gHiiConfigRouting->BlockToConfig(
1328 gHiiConfigRouting,
1329 ConfigRequest,
1330 (UINT8*)&gHiiConfiguration,
1331 sizeof(OPAL_HII_CONFIGURATION),
1332 Results,
1333 Progress
1334 );
1335
1336 //
1337 // Free the allocated config request string.
1338 //
1339 if (AllocatedRequest) {
1340 FreePool (ConfigRequest);
1341 ConfigRequest = NULL;
1342 }
1343
1344 //
1345 // Set Progress string to the original request string.
1346 //
1347 if (Request == NULL) {
1348 *Progress = NULL;
1349 } else if (StrStr (Request, L"OFFSET") == NULL) {
1350 *Progress = Request + StrLen (Request);
1351 }
1352
1353 return (Status);
1354 }
1355
1356
1357 /**
1358
1359 Pass the current system state to the bios via the hii_G_Configuration.
1360
1361 **/
1362 VOID
1363 OpalHiiSetBrowserData (
1364 VOID
1365 )
1366 {
1367 HiiSetBrowserData(
1368 &gHiiSetupVariableGuid,
1369 (CHAR16*)L"OpalHiiConfig",
1370 sizeof(gHiiConfiguration),
1371 (UINT8*)&gHiiConfiguration,
1372 NULL
1373 );
1374 }
1375
1376
1377 /**
1378
1379 Populate the hii_g_Configuraton with the browser Data.
1380
1381 **/
1382 VOID
1383 OpalHiiGetBrowserData (
1384 VOID
1385 )
1386 {
1387 HiiGetBrowserData(
1388 &gHiiSetupVariableGuid,
1389 (CHAR16*)L"OpalHiiConfig",
1390 sizeof(gHiiConfiguration),
1391 (UINT8*)&gHiiConfiguration
1392 );
1393 }
1394
1395 /**
1396 Set a string Value in a form.
1397
1398 @param DestStringId The stringid which need to update.
1399 @param SrcAsciiStr The string nned to update.
1400
1401 @retval EFI_SUCCESS Do the required action success.
1402 @retval Others Other error occur.
1403
1404 **/
1405 EFI_STATUS
1406 HiiSetFormString(
1407 EFI_STRING_ID DestStringId,
1408 CHAR8 *SrcAsciiStr
1409 )
1410 {
1411 UINT32 Len;
1412 UINT32 UniSize;
1413 CHAR16* UniStr;
1414
1415 //
1416 // Determine the Length of the sting
1417 //
1418 Len = ( UINT32 )AsciiStrLen( SrcAsciiStr );
1419
1420 //
1421 // Allocate space for the unicode string, including terminator
1422 //
1423 UniSize = (Len + 1) * sizeof(CHAR16);
1424 UniStr = (CHAR16*)AllocateZeroPool(UniSize);
1425
1426 //
1427 // Copy into unicode string, then copy into string id
1428 //
1429 AsciiStrToUnicodeStrS ( SrcAsciiStr, UniStr, Len + 1);
1430
1431 //
1432 // Update the string in the form
1433 //
1434 if (HiiSetString(gHiiPackageListHandle, DestStringId, UniStr, NULL) == 0) {
1435 DEBUG ((DEBUG_INFO, "HiiSetFormString( ) failed\n"));
1436 FreePool(UniStr);
1437 return (EFI_OUT_OF_RESOURCES);
1438 }
1439
1440 //
1441 // Free the memory
1442 //
1443 FreePool(UniStr);
1444
1445 return (EFI_SUCCESS);
1446 }
1447
1448 /**
1449 Initialize the Opal disk base on the hardware info get from device.
1450
1451 @param Dev The Opal device.
1452
1453 @retval EFI_SUCESS Initialize the device success.
1454 @retval EFI_DEVICE_ERROR Get info from device failed.
1455
1456 **/
1457 EFI_STATUS
1458 OpalDiskInitialize (
1459 IN OPAL_DRIVER_DEVICE *Dev
1460 )
1461 {
1462 TCG_RESULT TcgResult;
1463 OPAL_SESSION Session;
1464
1465 ZeroMem(&Dev->OpalDisk, sizeof(OPAL_DISK));
1466 Dev->OpalDisk.Sscp = Dev->Sscp;
1467 Dev->OpalDisk.MediaId = Dev->MediaId;
1468 Dev->OpalDisk.OpalDevicePath = Dev->OpalDevicePath;
1469
1470 ZeroMem(&Session, sizeof(Session));
1471 Session.Sscp = Dev->Sscp;
1472 Session.MediaId = Dev->MediaId;
1473
1474 TcgResult = OpalGetSupportedAttributesInfo (&Session, &Dev->OpalDisk.SupportedAttributes, &Dev->OpalDisk.OpalBaseComId);
1475 if (TcgResult != TcgResultSuccess) {
1476 return EFI_DEVICE_ERROR;
1477 }
1478 Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;
1479
1480 TcgResult = OpalUtilGetMsid (&Session, Dev->OpalDisk.Msid, OPAL_MSID_LENGHT, &Dev->OpalDisk.MsidLength);
1481 if (TcgResult != TcgResultSuccess) {
1482 return EFI_DEVICE_ERROR;
1483 }
1484
1485 return OpalDiskUpdateStatus (&Dev->OpalDisk);
1486 }
1487
1488 /**
1489 Update the device info.
1490
1491 @param OpalDisk The Opal device.
1492
1493 @retval EFI_SUCESS Initialize the device success.
1494 @retval EFI_DEVICE_ERROR Get info from device failed.
1495 @retval EFI_INVALID_PARAMETER Not get Msid info before get ownership info.
1496
1497 **/
1498 EFI_STATUS
1499 OpalDiskUpdateStatus (
1500 OPAL_DISK *OpalDisk
1501 )
1502 {
1503 TCG_RESULT TcgResult;
1504 OPAL_SESSION Session;
1505
1506 ZeroMem(&Session, sizeof(Session));
1507 Session.Sscp = OpalDisk->Sscp;
1508 Session.MediaId = OpalDisk->MediaId;
1509 Session.OpalBaseComId = OpalDisk->OpalBaseComId;
1510
1511 TcgResult = OpalGetLockingInfo(&Session, &OpalDisk->LockingFeature);
1512 if (TcgResult != TcgResultSuccess) {
1513 return EFI_DEVICE_ERROR;
1514 }
1515
1516 if (OpalDisk->MsidLength == 0) {
1517 return EFI_INVALID_PARAMETER;
1518 } else {
1519 //
1520 // Base on the Msid info to get the ownership, so Msid info must get first.
1521 //
1522 OpalDisk->Owner = OpalUtilDetermineOwnership(&Session, OpalDisk->Msid, OpalDisk->MsidLength);
1523 }
1524
1525 return EFI_SUCCESS;
1526 }
1527