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