/** The function returns whether or not the device is Opal Locked. TRUE means that the device is partially or fully locked. This will perform a Level 0 Discovery and parse the locking feature descriptor @param[in] OpalDev Opal object to determine if locked @param[out] BlockSidSupported Whether device support BlockSid feature. **/ BOOLEAN IsOpalDeviceLocked( OPAL_SMM_DEVICE *OpalDev, BOOLEAN *BlockSidSupported ) { OPAL_SESSION Session; OPAL_DISK_SUPPORT_ATTRIBUTE SupportedAttributes; TCG_LOCKING_FEATURE_DESCRIPTOR LockingFeature; UINT16 OpalBaseComId; TCG_RESULT Ret; Session.Sscp = &OpalDev->Sscp; Session.MediaId = 0; Ret = OpalGetSupportedAttributesInfo (&Session, &SupportedAttributes, &OpalBaseComId); if (Ret != TcgResultSuccess) { return FALSE; } OpalDev->OpalBaseComId = OpalBaseComId; Session.OpalBaseComId = OpalBaseComId; *BlockSidSupported = SupportedAttributes.BlockSid == 1 ? TRUE : FALSE; Ret = OpalGetLockingInfo(&Session, &LockingFeature); if (Ret != TcgResultSuccess) { return FALSE; } return OpalDeviceLocked (&SupportedAttributes, &LockingFeature); }
/** Check whether enable feature or not. @retval Return the disk number. **/ UINT8 HiiGetNumConfigRequiredOpalDisksCB( VOID ) { UINT8 NumDisks; UINT8 NumLockedOpalDisks; OPAL_DISK *OpalDisk; UINT8 Index; NumLockedOpalDisks = 0; NumDisks = GetDeviceCount(); for (Index = 0; Index < NumDisks; Index++) { OpalDisk = HiiGetOpalDiskCB(Index); if (OpalDisk != NULL) { if (!OpalFeatureEnabled (&OpalDisk->SupportedAttributes, &OpalDisk->LockingFeature)) { DEBUG ((DEBUG_INFO, "Ignoring disk %u because feature is disabled or health has already been inspected\n", Index)); } else if (OpalDeviceLocked (&OpalDisk->SupportedAttributes, &OpalDisk->LockingFeature)) { NumLockedOpalDisks++; } } } return NumLockedOpalDisks; }
/** Check if disk is locked, show popup window and ask for password if it is @param[in] Dev The device which need to be unlock. **/ VOID OpalDriverRequestPassword ( OPAL_DRIVER_DEVICE *Dev ) { UINT8 Count; BOOLEAN IsEnabled; CHAR8 *Password; UINT32 PasswordLen; TCG_RESULT Ret; EFI_INPUT_KEY Key; OPAL_SESSION Session; BOOLEAN PressEsc; BOOLEAN Locked; if (Dev == NULL) { return; } Count = 0; IsEnabled = OpalFeatureEnabled (&Dev->OpalDisk.SupportedAttributes, &Dev->OpalDisk.LockingFeature); if (IsEnabled) { ZeroMem(&Session, sizeof(Session)); Session.Sscp = Dev->OpalDisk.Sscp; Session.MediaId = Dev->OpalDisk.MediaId; Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId; Locked = OpalDeviceLocked (&Dev->OpalDisk.SupportedAttributes, &Dev->OpalDisk.LockingFeature); while (Count < MAX_PASSWORD_TRY_COUNT) { Password = OpalDriverPopUpHddPassword (Dev, &PressEsc); if (PressEsc) { if (Locked) { // // Current device in the lock status and // User not input password and press ESC, // keep device in lock status and continue boot. // do { CreatePopUp ( EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Press ENTER to skip password, Press ESC to input password", NULL ); } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN)); if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) { gST->ConOut->ClearScreen(gST->ConOut); // // Keep lock and continue boot. // return; } else { // // Let user input password again. // continue; } } else { // // Current device in the unlock status and // User not input password and press ESC, // Shutdown the device. // do { CreatePopUp ( EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Press ENTER to shutdown, Press ESC to input password", NULL ); } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN)); if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) { gRT->ResetSystem (EfiResetShutdown, EFI_SUCCESS, 0, NULL); } else { // // Let user input password again. // continue; } } } if (Password == NULL) { Count ++; continue; } PasswordLen = (UINT32) AsciiStrLen(Password); if (Locked) { Ret = OpalSupportUnlock(&Session, Password, PasswordLen, Dev->OpalDevicePath); } else { Ret = OpalSupportLock(&Session, Password, PasswordLen, Dev->OpalDevicePath); if (Ret == TcgResultSuccess) { Ret = OpalSupportUnlock(&Session, Password, PasswordLen, Dev->OpalDevicePath); } } if (Password != NULL) { ZeroMem (Password, PasswordLen); FreePool (Password); } if (Ret == TcgResultSuccess) { break; } Count++; do { CreatePopUp ( EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid password.", L"Press ENTER to retry", NULL ); } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN); } if (Count >= MAX_PASSWORD_TRY_COUNT) { do { CreatePopUp ( EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Opal password retry count exceeds the limit. Must shutdown!", L"Press ENTER to shutdown", NULL ); } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN); gRT->ResetSystem (EfiResetShutdown, EFI_SUCCESS, 0, NULL); } } }