+++ /dev/null
-/** @file\r
- Header file of Opal password support library.\r
-\r
-Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-\r
-#ifndef _OPAL_PASSWORD_SUPPORT_LIB_H_\r
-#define _OPAL_PASSWORD_SUPPORT_LIB_H_\r
-\r
-#include <Protocol/DevicePath.h>\r
-#include <Library/TcgStorageOpalLib.h>\r
-\r
-\r
-#pragma pack(1)\r
-\r
-//\r
-// Structure that is used to represent the available actions for an OpalDisk.\r
-// The data can then be utilized to expose/hide certain actions available to an end user\r
-// by the consumer of this library.\r
-//\r
-typedef struct {\r
- //\r
- // Indicates if the disk can support PSID Revert action. should verify disk supports PSID authority\r
- //\r
- UINT16 PsidRevert : 1;\r
-\r
- //\r
- // Indicates if the disk can support Revert action\r
- //\r
- UINT16 Revert : 1;\r
-\r
- //\r
- // Indicates if the user must keep data for revert action. It is true if no media encryption is supported.\r
- //\r
- UINT16 RevertKeepDataForced : 1;\r
-\r
- //\r
- // Indicates if the disk can support set Admin password\r
- //\r
- UINT16 AdminPass : 1;\r
-\r
- //\r
- // Indicates if the disk can support set User password. This action requires that a user\r
- // password is first enabled.\r
- //\r
- UINT16 UserPass : 1;\r
-\r
- //\r
- // Indicates if unlock action is available. Requires disk to be currently locked.\r
- //\r
- UINT16 Unlock : 1;\r
-\r
- //\r
- // Indicates if Secure Erase action is available. Action requires admin credentials and media encryption support.\r
- //\r
- UINT16 SecureErase : 1;\r
-\r
- //\r
- // Indicates if Disable User action is available. Action requires admin credentials.\r
- //\r
- UINT16 DisableUser : 1;\r
-} OPAL_DISK_ACTIONS;\r
-\r
-//\r
-// Structure that is used to represent the Opal device with password info.\r
-//\r
-typedef struct {\r
- LIST_ENTRY Link;\r
-\r
- UINT8 Password[32];\r
- UINT8 PasswordLength;\r
-\r
- EFI_DEVICE_PATH_PROTOCOL OpalDevicePath;\r
-} OPAL_DISK_AND_PASSWORD_INFO;\r
-\r
-#pragma pack()\r
-\r
-/**\r
-\r
- The function performs determines the available actions for the OPAL_DISK provided.\r
-\r
- @param[in] SupportedAttributes The support attribute for the device.\r
- @param[in] LockingFeature The locking status for the device.\r
- @param[in] OwnerShip The ownership for the device.\r
- @param[out] AvalDiskActions Pointer to fill-out with appropriate disk actions.\r
-\r
-**/\r
-TCG_RESULT\r
-EFIAPI\r
-OpalSupportGetAvailableActions(\r
- IN OPAL_DISK_SUPPORT_ATTRIBUTE *SupportedAttributes,\r
- IN TCG_LOCKING_FEATURE_DESCRIPTOR *LockingFeature,\r
- IN UINT16 OwnerShip,\r
- OUT OPAL_DISK_ACTIONS *AvalDiskActions\r
- );\r
-\r
-/**\r
- Enable Opal Feature for the input device.\r
-\r
- @param[in] Session The opal session for the opal device.\r
- @param[in] Msid Msid\r
- @param[in] MsidLength Msid Length\r
- @param[in] Password Admin password\r
- @param[in] PassLength Length of password in bytes\r
- @param[in] DevicePath The device path for the opal devcie.\r
-\r
-**/\r
-TCG_RESULT\r
-EFIAPI\r
-OpalSupportEnableOpalFeature(\r
- IN OPAL_SESSION *Session,\r
- IN VOID *Msid,\r
- IN UINT32 MsidLength,\r
- IN VOID *Password,\r
- IN UINT32 PassLength,\r
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
- );\r
-\r
-/**\r
- Creates a session with OPAL_UID_ADMIN_SP as OPAL_ADMIN_SP_PSID_AUTHORITY, then reverts device using Admin SP Revert method.\r
-\r
- @param[in] Session The opal session for the opal device.\r
- @param[in] Psid PSID of device to revert.\r
- @param[in] PsidLength Length of PSID in bytes.\r
- @param[in] DevicePath The device path for the opal devcie.\r
-\r
-**/\r
-TCG_RESULT\r
-EFIAPI\r
-OpalSupportPsidRevert(\r
- IN OPAL_SESSION *Session,\r
- IN VOID *Psid,\r
- IN UINT32 PsidLength,\r
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
- );\r
-\r
-/**\r
- Opens a session with OPAL_UID_ADMIN_SP as OPAL_ADMIN_SP_PSID_AUTHORITY, then reverts the device using the RevertSP method.\r
-\r
- @param[in] Session The opal session for the opal device.\r
- @param[in] KeepUserData TRUE to keep existing Data on the disk, or FALSE to erase it\r
- @param[in] Password Admin password\r
- @param[in] PasswordLength Length of password in bytes\r
- @param[in] Msid Msid\r
- @param[in] MsidLength Msid Length\r
- @param[out] PasswordFailed indicates if password failed (start session didn't work)\r
- @param[in] DevicePath The device path for the opal devcie.\r
-\r
-**/\r
-TCG_RESULT\r
-EFIAPI\r
-OpalSupportRevert(\r
- IN OPAL_SESSION *Session,\r
- IN BOOLEAN KeepUserData,\r
- IN VOID *Password,\r
- IN UINT32 PasswordLength,\r
- IN VOID *Msid,\r
- IN UINT32 MsidLength,\r
- OUT BOOLEAN *PasswordFailed,\r
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
- );\r
-\r
-/**\r
- Set new password.\r
-\r
- @param[in] Session The opal session for the opal device.\r
- @param[in] OldPassword Current admin password\r
- @param[in] OldPasswordLength Length of current admin password in bytes\r
- @param[in] NewPassword New admin password to set\r
- @param[in] NewPasswordLength Length of new password in bytes\r
- @param[in] DevicePath The device path for the opal devcie.\r
- @param[in] SetAdmin Whether set admin password or user password.\r
- TRUE for admin, FALSE for user.\r
-\r
-**/\r
-TCG_RESULT\r
-EFIAPI\r
-OpalSupportSetPassword(\r
- IN OPAL_SESSION *Session,\r
- IN VOID *OldPassword,\r
- IN UINT32 OldPasswordLength,\r
- IN VOID *NewPassword,\r
- IN UINT32 NewPasswordLength,\r
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
- IN BOOLEAN SetAdmin\r
- );\r
-\r
-/**\r
- Starts a session with OPAL_UID_LOCKING_SP as OPAL_LOCKING_SP_ADMIN1_AUTHORITY and disables the User1 authority.\r
-\r
- @param[in] Session The opal session for the opal device.\r
- @param[in] Password Admin password\r
- @param[in] PasswordLength Length of password in bytes\r
- @param[out] PasswordFailed Indicates if password failed (start session didn't work)\r
- @param[in] DevicePath The device path for the opal devcie.\r
-\r
-**/\r
-TCG_RESULT\r
-EFIAPI\r
-OpalSupportDisableUser(\r
- IN OPAL_SESSION *Session,\r
- IN VOID *Password,\r
- IN UINT32 PasswordLength,\r
- OUT BOOLEAN *PasswordFailed,\r
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
- );\r
-\r
-/**\r
- Starts a session with OPAL_UID_LOCKING_SP as OPAL_LOCKING_SP_USER1_AUTHORITY or OPAL_LOCKING_SP_ADMIN1_AUTHORITY\r
- and updates the global locking range ReadLocked and WriteLocked columns to FALSE.\r
-\r
- @param[in] Session The opal session for the opal device.\r
- @param[in] Password Admin or user password\r
- @param[in] PasswordLength Length of password in bytes\r
- @param[in] DevicePath The device path for the opal devcie.\r
-\r
-**/\r
-TCG_RESULT\r
-EFIAPI\r
-OpalSupportUnlock(\r
- IN OPAL_SESSION *Session,\r
- IN VOID *Password,\r
- IN UINT32 PasswordLength,\r
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
- );\r
-\r
-/**\r
- Starts a session with OPAL_UID_LOCKING_SP as OPAL_LOCKING_SP_USER1_AUTHORITY or OPAL_LOCKING_SP_ADMIN1_AUTHORITY\r
- and updates the global locking range ReadLocked and WriteLocked columns to TRUE.\r
-\r
- @param[in] Session The opal session for the opal device.\r
- @param[in] Password Admin or user password\r
- @param[in] PasswordLength Length of password in bytes\r
- @param[in] DevicePath The device path for the opal devcie.\r
-\r
-**/\r
-TCG_RESULT\r
-EFIAPI\r
-OpalSupportLock(\r
- IN OPAL_SESSION *Session,\r
- IN VOID *Password,\r
- IN UINT32 PasswordLength,\r
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
- );\r
-\r
-/**\r
- Check if the password is full zero.\r
-\r
- @param[in] Password Points to the Data Buffer\r
-\r
- @retval TRUE This password string is full zero.\r
- @retval FALSE This password string is not full zero.\r
-\r
-**/\r
-LIST_ENTRY *\r
-EFIAPI\r
-OpalSupportGetOpalDeviceList (\r
- VOID\r
- );\r
-\r
-/**\r
- Transfer the password to the smm driver.\r
-\r
- @param[in] DevicePath The device path for the opal devcie.\r
- @param PasswordLen The input password length.\r
- @param Password Input password buffer.\r
-\r
- @retval EFI_SUCCESS Do the required action success.\r
- @retval Others Error occured.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-OpalSupportSendPasword(\r
- EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
- UINTN PasswordLen,\r
- VOID *Password\r
- );\r
-\r
-#endif // _OPAL_CORE_H_\r
+++ /dev/null
-/** @file\r
- Implementation of Opal password support library.\r
-\r
-Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-#include "OpalPasswordSupportNotify.h"\r
-\r
-#define OPAL_PASSWORD_MAX_LENGTH 32\r
-\r
-LIST_ENTRY mDeviceList = INITIALIZE_LIST_HEAD_VARIABLE (mDeviceList);\r
-BOOLEAN gInSmm = FALSE;\r
-EFI_GUID gOpalPasswordNotifyProtocolGuid = OPAL_PASSWORD_NOTIFY_PROTOCOL_GUID;\r
-\r
-/**\r
-\r
- The function performs determines the available actions for the OPAL_DISK provided.\r
-\r
- @param[in] SupportedAttributes The support attribute for the device.\r
- @param[in] LockingFeature The locking status for the device.\r
- @param[in] OwnerShip The ownership for the device.\r
- @param[out] AvalDiskActions Pointer to fill-out with appropriate disk actions.\r
-\r
-**/\r
-TCG_RESULT\r
-EFIAPI\r
-OpalSupportGetAvailableActions(\r
- IN OPAL_DISK_SUPPORT_ATTRIBUTE *SupportedAttributes,\r
- IN TCG_LOCKING_FEATURE_DESCRIPTOR *LockingFeature,\r
- IN UINT16 OwnerShip,\r
- OUT OPAL_DISK_ACTIONS *AvalDiskActions\r
- )\r
-{\r
- BOOLEAN ExistingPassword;\r
-\r
- NULL_CHECK(AvalDiskActions);\r
-\r
- AvalDiskActions->AdminPass = 1;\r
- AvalDiskActions->UserPass = 0;\r
- AvalDiskActions->DisableUser = 0;\r
- AvalDiskActions->Unlock = 0;\r
-\r
- //\r
- // Revert is performed on locking sp, so only allow if locking sp is enabled\r
- //\r
- if (LockingFeature->LockingEnabled) {\r
- AvalDiskActions->Revert = 1;\r
- }\r
-\r
- //\r
- // Psid revert is available for any device with media encryption support\r
- // Revert is allowed for any device with media encryption support, however it requires\r
- //\r
- if (SupportedAttributes->MediaEncryption) {\r
-\r
- //\r
- // Only allow psid revert if media encryption is enabled.\r
- // Otherwise, someone who steals a disk can psid revert the disk and the user Data is still\r
- // intact and accessible\r
- //\r
- AvalDiskActions->PsidRevert = 1;\r
- AvalDiskActions->RevertKeepDataForced = 0;\r
-\r
- //\r
- // Secure erase is performed by generating a new encryption key\r
- // this is only available is encryption is supported\r
- //\r
- AvalDiskActions->SecureErase = 1;\r
- } else {\r
- AvalDiskActions->PsidRevert = 0;\r
- AvalDiskActions->SecureErase = 0;\r
-\r
- //\r
- // If no media encryption is supported, then a revert (using password) will not\r
- // erase the Data (since you can't generate a new encryption key)\r
- //\r
- AvalDiskActions->RevertKeepDataForced = 1;\r
- }\r
-\r
- if (LockingFeature->Locked) {\r
- AvalDiskActions->Unlock = 1;\r
- } else {\r
- AvalDiskActions->Unlock = 0;\r
- }\r
-\r
- //\r
- // Only allow user to set password if an admin password exists\r
- //\r
- ExistingPassword = OpalUtilAdminPasswordExists(OwnerShip, LockingFeature);\r
- AvalDiskActions->UserPass = ExistingPassword;\r
-\r
- //\r
- // This will still show up even if there isn't a user, which is fine\r
- //\r
- AvalDiskActions->DisableUser = ExistingPassword;\r
-\r
- return TcgResultSuccess;\r
-}\r
-\r
-/**\r
- Creates a session with OPAL_UID_ADMIN_SP as OPAL_ADMIN_SP_PSID_AUTHORITY, then reverts device using Admin SP Revert method.\r
-\r
- @param[in] Session The opal session for the opal device.\r
- @param[in] Psid PSID of device to revert.\r
- @param[in] PsidLength Length of PSID in bytes.\r
- @param[in] DevicePath The device path for the opal devcie.\r
-\r
-**/\r
-TCG_RESULT\r
-EFIAPI\r
-OpalSupportPsidRevert(\r
- IN OPAL_SESSION *Session,\r
- IN VOID *Psid,\r
- IN UINT32 PsidLength,\r
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
- )\r
-{\r
- TCG_RESULT Ret;\r
-\r
- NULL_CHECK(Session);\r
- NULL_CHECK(Psid);\r
-\r
- Ret = OpalUtilPsidRevert (Session, Psid, PsidLength);\r
- if (Ret == TcgResultSuccess && !gInSmm) {\r
- OpalSupportSendPasword (DevicePath, 0, NULL);\r
- }\r
-\r
- return Ret;\r
-}\r
-\r
-/**\r
- Opens a session with OPAL_UID_ADMIN_SP as OPAL_ADMIN_SP_SID_AUTHORITY,\r
- sets OPAL_UID_ADMIN_SP_C_PIN_SID with the new password,\r
- and sets OPAL_LOCKING_SP_C_PIN_ADMIN1 with the new password.\r
-\r
- @param[in] Session The opal session for the opal device.\r
- @param[in] OldPassword Current admin password\r
- @param[in] OldPasswordLength Length of current admin password in bytes\r
- @param[in] NewPassword New admin password to set\r
- @param[in] NewPasswordLength Length of new password in bytes\r
- @param[in] DevicePath The device path for the opal devcie.\r
- @param[in] SetAdmin Whether set admin password or user password.\r
- TRUE for admin, FALSE for user.\r
-\r
-**/\r
-TCG_RESULT\r
-EFIAPI\r
-OpalSupportSetPassword(\r
- IN OPAL_SESSION *Session,\r
- IN VOID *OldPassword,\r
- IN UINT32 OldPasswordLength,\r
- IN VOID *NewPassword,\r
- IN UINT32 NewPasswordLength,\r
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
- IN BOOLEAN SetAdmin\r
- )\r
-{\r
- TCG_RESULT Ret;\r
-\r
- NULL_CHECK(Session);\r
- NULL_CHECK(OldPassword);\r
- NULL_CHECK(NewPassword);\r
-\r
- if (SetAdmin) {\r
- Ret = OpalUtilSetAdminPassword(Session, OldPassword, OldPasswordLength, NewPassword, NewPasswordLength);\r
- } else {\r
- Ret = OpalUtilSetUserPassword(Session, OldPassword, OldPasswordLength, NewPassword, NewPasswordLength);\r
- }\r
- if (Ret == TcgResultSuccess && !gInSmm) {\r
- OpalSupportSendPasword (DevicePath, NewPasswordLength, NewPassword);\r
- }\r
-\r
- return Ret;\r
-}\r
-\r
-/**\r
- Starts a session with OPAL_UID_LOCKING_SP as OPAL_LOCKING_SP_ADMIN1_AUTHORITY and disables the User1 authority.\r
-\r
- @param[in] Session The opal session for the opal device.\r
- @param[in] Password Admin password\r
- @param[in] PasswordLength Length of password in bytes\r
- @param[out] PasswordFailed Indicates if password failed (start session didn't work)\r
- @param[in] DevicePath The device path for the opal devcie.\r
-\r
-**/\r
-TCG_RESULT\r
-EFIAPI\r
-OpalSupportDisableUser(\r
- IN OPAL_SESSION *Session,\r
- IN VOID *Password,\r
- IN UINT32 PasswordLength,\r
- OUT BOOLEAN *PasswordFailed,\r
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
- )\r
-{\r
- TCG_RESULT Ret;\r
-\r
- NULL_CHECK(Session);\r
- NULL_CHECK(Password);\r
- NULL_CHECK(PasswordFailed);\r
-\r
- Ret = OpalUtilDisableUser(Session, Password, PasswordLength, PasswordFailed);\r
- if (Ret == TcgResultSuccess && !gInSmm) {\r
- OpalSupportSendPasword (DevicePath, PasswordLength, Password);\r
- }\r
-\r
- return Ret;\r
-}\r
-\r
-/**\r
- Enable Opal Feature for the input device.\r
-\r
- @param[in] Session The opal session for the opal device.\r
- @param[in] Msid Msid\r
- @param[in] MsidLength Msid Length\r
- @param[in] Password Admin password\r
- @param[in] PassLength Length of password in bytes\r
- @param[in] DevicePath The device path for the opal devcie.\r
-\r
-**/\r
-TCG_RESULT\r
-EFIAPI\r
-OpalSupportEnableOpalFeature (\r
- IN OPAL_SESSION *Session,\r
- IN VOID *Msid,\r
- IN UINT32 MsidLength,\r
- IN VOID *Password,\r
- IN UINT32 PassLength,\r
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
- )\r
-{\r
- TCG_RESULT Ret;\r
-\r
- NULL_CHECK(Session);\r
- NULL_CHECK(Msid);\r
- NULL_CHECK(Password);\r
-\r
- Ret = OpalUtilSetAdminPasswordAsSid(\r
- Session,\r
- Msid,\r
- MsidLength,\r
- Password,\r
- PassLength\r
- );\r
- if (Ret == TcgResultSuccess) {\r
- //\r
- // Enable global locking range\r
- //\r
- Ret = OpalUtilSetOpalLockingRange(\r
- Session,\r
- Password,\r
- PassLength,\r
- OPAL_LOCKING_SP_LOCKING_GLOBALRANGE,\r
- 0,\r
- 0,\r
- TRUE,\r
- TRUE,\r
- FALSE,\r
- FALSE\r
- );\r
- }\r
-\r
- if (Ret == TcgResultSuccess && !gInSmm) {\r
- OpalSupportSendPasword (DevicePath, PassLength, Password);\r
- }\r
-\r
- return Ret;\r
-}\r
-\r
-/**\r
- Opens a session with OPAL_UID_ADMIN_SP as OPAL_ADMIN_SP_PSID_AUTHORITY, then reverts the device using the RevertSP method.\r
-\r
- @param[in] Session The opal session for the opal device.\r
- @param[in] KeepUserData TRUE to keep existing Data on the disk, or FALSE to erase it\r
- @param[in] Password Admin password\r
- @param[in] PasswordLength Length of password in bytes\r
- @param[in] Msid Msid\r
- @param[in] MsidLength Msid Length\r
- @param[out] PasswordFailed indicates if password failed (start session didn't work)\r
- @param[in] DevicePath The device path for the opal devcie.\r
-\r
-**/\r
-TCG_RESULT\r
-EFIAPI\r
-OpalSupportRevert(\r
- IN OPAL_SESSION *Session,\r
- IN BOOLEAN KeepUserData,\r
- IN VOID *Password,\r
- IN UINT32 PasswordLength,\r
- IN VOID *Msid,\r
- IN UINT32 MsidLength,\r
- OUT BOOLEAN *PasswordFailed,\r
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
- )\r
-{\r
- TCG_RESULT Ret;\r
-\r
- NULL_CHECK(Session);\r
- NULL_CHECK(Password);\r
- NULL_CHECK(Msid);\r
- NULL_CHECK(PasswordFailed);\r
-\r
- Ret = OpalUtilRevert(Session, KeepUserData, Password, PasswordLength, PasswordFailed, Msid, MsidLength);\r
- if (Ret == TcgResultSuccess && !gInSmm) {\r
- OpalSupportSendPasword (DevicePath, 0, NULL);\r
- }\r
-\r
- return Ret;\r
-}\r
-\r
-/**\r
- Starts a session with OPAL_UID_LOCKING_SP as OPAL_LOCKING_SP_USER1_AUTHORITY or OPAL_LOCKING_SP_ADMIN1_AUTHORITY\r
- and updates the global locking range ReadLocked and WriteLocked columns to FALSE.\r
-\r
- @param[in] Session The opal session for the opal device.\r
- @param[in] Password Admin or user password\r
- @param[in] PasswordLength Length of password in bytes\r
- @param[in] DevicePath The device path for the opal devcie.\r
-\r
-**/\r
-TCG_RESULT\r
-EFIAPI\r
-OpalSupportUnlock(\r
- IN OPAL_SESSION *Session,\r
- IN VOID *Password,\r
- IN UINT32 PasswordLength,\r
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
- )\r
-{\r
- TCG_RESULT Ret;\r
-\r
- NULL_CHECK(Session);\r
- NULL_CHECK(Password);\r
-\r
- Ret = OpalUtilUpdateGlobalLockingRange(Session, Password, PasswordLength, FALSE, FALSE);\r
- if (Ret == TcgResultSuccess && !gInSmm) {\r
- OpalSupportSendPasword (DevicePath, PasswordLength, Password);\r
- }\r
-\r
- return Ret;\r
-}\r
-\r
-/**\r
- Starts a session with OPAL_UID_LOCKING_SP as OPAL_LOCKING_SP_USER1_AUTHORITY or OPAL_LOCKING_SP_ADMIN1_AUTHORITY\r
- and updates the global locking range ReadLocked and WriteLocked columns to TRUE.\r
-\r
- @param[in] Session The opal session for the opal device.\r
- @param[in] Password Admin or user password\r
- @param[in] PasswordLength Length of password in bytes\r
- @param[in] DevicePath The device path for the opal devcie.\r
-\r
-**/\r
-TCG_RESULT\r
-EFIAPI\r
-OpalSupportLock(\r
- IN OPAL_SESSION *Session,\r
- IN VOID *Password,\r
- IN UINT32 PasswordLength,\r
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
- )\r
-{\r
- TCG_RESULT Ret;\r
-\r
- NULL_CHECK(Session);\r
- NULL_CHECK(Password);\r
-\r
- Ret = OpalUtilUpdateGlobalLockingRange(Session, Password, PasswordLength, TRUE, TRUE);\r
- if (Ret == TcgResultSuccess && !gInSmm) {\r
- OpalSupportSendPasword (DevicePath, PasswordLength, Password);\r
- }\r
-\r
- return Ret;\r
-}\r
-\r
-/**\r
- Initialize the communicate Buffer using DataSize and Function.\r
-\r
- @param[out] DataPtr Points to the Data in the communicate Buffer.\r
- @param[in] DataSize The Data Size to send to SMM.\r
- @param[in] Function The function number to initialize the communicate Header.\r
-\r
- @retval EFI_INVALID_PARAMETER The Data Size is too big.\r
- @retval EFI_SUCCESS Find the specified variable.\r
-\r
-**/\r
-VOID*\r
-OpalInitCommunicateBuffer (\r
- OUT VOID **DataPtr OPTIONAL,\r
- IN UINTN DataSize,\r
- IN UINTN Function\r
- )\r
-{\r
- EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader;\r
- OPAL_SMM_COMMUNICATE_HEADER *SmmFunctionHeader;\r
- VOID *Buffer;\r
- EDKII_PI_SMM_COMMUNICATION_REGION_TABLE *SmmCommRegionTable;\r
- EFI_MEMORY_DESCRIPTOR *SmmCommMemRegion;\r
- UINTN Index;\r
- UINTN Size;\r
- EFI_STATUS Status;\r
-\r
- Buffer = NULL;\r
- Status = EfiGetSystemConfigurationTable (\r
- &gEdkiiPiSmmCommunicationRegionTableGuid,\r
- (VOID **) &SmmCommRegionTable\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return NULL;\r
- }\r
-\r
- ASSERT (SmmCommRegionTable != NULL);\r
- SmmCommMemRegion = (EFI_MEMORY_DESCRIPTOR *) (SmmCommRegionTable + 1);\r
- Size = 0;\r
- for (Index = 0; Index < SmmCommRegionTable->NumberOfEntries; Index++) {\r
- if (SmmCommMemRegion->Type == EfiConventionalMemory) {\r
- Size = EFI_PAGES_TO_SIZE ((UINTN) SmmCommMemRegion->NumberOfPages);\r
- if (Size >= (DataSize + OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data) + OFFSET_OF (OPAL_SMM_COMMUNICATE_HEADER, Data))) {\r
- break;\r
- }\r
- }\r
- SmmCommMemRegion = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) SmmCommMemRegion + SmmCommRegionTable->DescriptorSize);\r
- }\r
- ASSERT (Index < SmmCommRegionTable->NumberOfEntries);\r
-\r
- Buffer = (VOID*)(UINTN)SmmCommMemRegion->PhysicalStart;\r
- ASSERT (Buffer != NULL);\r
-\r
- SmmCommunicateHeader = (EFI_SMM_COMMUNICATE_HEADER *) Buffer;\r
- CopyGuid (&SmmCommunicateHeader->HeaderGuid, &gOpalPasswordNotifyProtocolGuid);\r
- SmmCommunicateHeader->MessageLength = DataSize + OFFSET_OF (OPAL_SMM_COMMUNICATE_HEADER, Data);\r
-\r
- SmmFunctionHeader = (OPAL_SMM_COMMUNICATE_HEADER *) SmmCommunicateHeader->Data;\r
- SmmFunctionHeader->Function = Function;\r
- if (DataPtr != NULL) {\r
- *DataPtr = SmmFunctionHeader->Data;\r
- }\r
-\r
- return Buffer;\r
-}\r
-\r
-/**\r
- Send the Data in communicate Buffer to SMM.\r
-\r
- @param[in] Buffer Points to the Data in the communicate Buffer.\r
- @param[in] DataSize This Size of the function Header and the Data.\r
-\r
- @retval EFI_SUCCESS Success is returned from the functin in SMM.\r
- @retval Others Failure is returned from the function in SMM.\r
-\r
-**/\r
-EFI_STATUS\r
-OpalSendCommunicateBuffer (\r
- IN VOID *Buffer,\r
- IN UINTN DataSize\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN CommSize;\r
- EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader;\r
- OPAL_SMM_COMMUNICATE_HEADER *SmmFunctionHeader;\r
- EFI_SMM_COMMUNICATION_PROTOCOL *SmmCommunication;\r
-\r
- Status = gBS->LocateProtocol (&gEfiSmmCommunicationProtocolGuid, NULL, (VOID **) &SmmCommunication);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- CommSize = DataSize + OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data) + OFFSET_OF (OPAL_SMM_COMMUNICATE_HEADER, Data);\r
- Status = SmmCommunication->Communicate (SmmCommunication, Buffer, &CommSize);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- SmmCommunicateHeader = (EFI_SMM_COMMUNICATE_HEADER *) Buffer;\r
- SmmFunctionHeader = (OPAL_SMM_COMMUNICATE_HEADER *)SmmCommunicateHeader->Data;\r
-\r
- return SmmFunctionHeader->ReturnStatus;\r
-}\r
-\r
-/**\r
- Transfer the password to the smm driver.\r
-\r
- @param[in] DevicePath The device path for the opal devcie.\r
- @param PasswordLen The input password length.\r
- @param Password Input password buffer.\r
-\r
- @retval EFI_SUCCESS Do the required action success.\r
- @retval Others Error occured.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-OpalSupportSendPasword(\r
- EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
- UINTN PasswordLen,\r
- VOID *Password\r
- )\r
-{\r
- OPAL_COMM_DEVICE_LIST *Parameter;\r
- VOID *Buffer;\r
- UINTN Length;\r
- EFI_STATUS Status;\r
- UINTN DevicePathLen;\r
-\r
- Parameter = NULL;\r
- Buffer = NULL;\r
-\r
- if (DevicePath == NULL) {\r
- //\r
- // Assume DevicePath == NULL only when library used by SMM driver\r
- // and should not run to here, just return success.\r
- //\r
- return EFI_SUCCESS;\r
- }\r
-\r
- DevicePathLen = GetDevicePathSize (DevicePath);\r
- Length = OFFSET_OF (OPAL_COMM_DEVICE_LIST, OpalDevicePath) + DevicePathLen;\r
- Buffer = OpalInitCommunicateBuffer((VOID**)&Parameter, Length, SMM_FUNCTION_SET_OPAL_PASSWORD);\r
- if (Buffer == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- if (Password != NULL) {\r
- CopyMem((VOID*)Parameter->Password, Password, PasswordLen);\r
- Parameter->PasswordLength = (UINT8)PasswordLen;\r
- }\r
- CopyMem (&Parameter->OpalDevicePath, DevicePath, DevicePathLen);\r
-\r
- Status = OpalSendCommunicateBuffer(Buffer, Length);\r
- if (EFI_ERROR(Status)) {\r
- goto EXIT;\r
- }\r
-\r
-EXIT:\r
- ZeroMem(Parameter, Length);\r
- return Status;\r
-}\r
-\r
-/**\r
- Get saved Opal device list.\r
-\r
- @retval return opal device list.\r
-\r
-**/\r
-LIST_ENTRY*\r
-EFIAPI\r
-OpalSupportGetOpalDeviceList (\r
- VOID\r
- )\r
-{\r
- return &mDeviceList;\r
-}\r
-\r
-/**\r
- Check if the password is full zero.\r
-\r
- @param[in] Password Points to the Data Buffer\r
-\r
- @retval TRUE This password string is full zero.\r
- @retval FALSE This password string is not full zero.\r
-\r
-**/\r
-BOOLEAN\r
-OpalPasswordIsFullZero (\r
- IN UINT8 *Password\r
- )\r
-{\r
- UINTN Index;\r
-\r
- for (Index = 0; Index < OPAL_PASSWORD_MAX_LENGTH; Index++) {\r
- if (Password[Index] != 0) {\r
- return FALSE;\r
- }\r
- }\r
-\r
- return TRUE;\r
-}\r
-\r
-/**\r
- Save hdd password to SMM.\r
-\r
- @param[in] DevicePath Input device path info for the device.\r
- @param[in] Password The hdd password of attached ATA device.\r
- @param[in] PasswordLength The hdd password length.\r
-\r
- @retval EFI_OUT_OF_RESOURCES Insufficient resources to create database record\r
- @retval EFI_SUCCESS The function has been successfully executed.\r
-\r
-**/\r
-EFI_STATUS\r
-OpalSavePasswordToSmm (\r
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
- IN UINT8 *Password,\r
- IN UINT8 PasswordLength\r
- )\r
-{\r
- OPAL_DISK_AND_PASSWORD_INFO *List;\r
- OPAL_DISK_AND_PASSWORD_INFO *Dev;\r
- LIST_ENTRY *Entry;\r
- UINTN DevicePathLen;\r
-\r
- DevicePathLen = GetDevicePathSize (DevicePath);\r
-\r
- for (Entry = mDeviceList.ForwardLink; Entry != &mDeviceList; Entry = Entry->ForwardLink) {\r
- List = BASE_CR (Entry, OPAL_DISK_AND_PASSWORD_INFO, Link);\r
- if (CompareMem (&List->OpalDevicePath, DevicePath, DevicePathLen) == 0) {\r
- CopyMem(List->Password, Password, OPAL_PASSWORD_MAX_LENGTH);\r
- return EFI_SUCCESS;\r
- }\r
- }\r
-\r
- Dev = AllocateZeroPool (OFFSET_OF (OPAL_DISK_AND_PASSWORD_INFO, OpalDevicePath) + DevicePathLen);\r
- if (Dev == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- Dev->PasswordLength = PasswordLength;\r
- CopyMem(&(Dev->Password), Password, OPAL_PASSWORD_MAX_LENGTH);\r
- CopyMem(&(Dev->OpalDevicePath), DevicePath, DevicePathLen);\r
-\r
- InsertHeadList (&mDeviceList, &Dev->Link);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Communication service SMI Handler entry.\r
-\r
- This SMI handler provides services for saving HDD password and saving S3 boot script when ready to boot.\r
-\r
- @param[in] DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().\r
- @param[in] RegisterContext Points to an optional handler context which was specified when the\r
- handler was registered.\r
- @param[in, out] CommBuffer A pointer to a collection of Data in memory that will\r
- be conveyed from a non-SMM environment into an SMM environment.\r
- @param[in, out] CommBufferSize The Size of the CommBuffer.\r
-\r
- @retval EFI_SUCCESS The interrupt was handled and quiesced. No other handlers\r
- should still be called.\r
- @retval EFI_WARN_INTERRUPT_SOURCE_QUIESCED The interrupt has been quiesced but other handlers should\r
- still be called.\r
- @retval EFI_WARN_INTERRUPT_SOURCE_PENDING The interrupt is still pending and other handlers should still\r
- be called.\r
- @retval EFI_INTERRUPT_PENDING The interrupt could not be quiesced.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-SmmOpalPasswordHandler (\r
- IN EFI_HANDLE DispatchHandle,\r
- IN CONST VOID *RegisterContext,\r
- IN OUT VOID *CommBuffer,\r
- IN OUT UINTN *CommBufferSize\r
- )\r
-{\r
- EFI_STATUS Status;\r
- OPAL_SMM_COMMUNICATE_HEADER *SmmFunctionHeader;\r
- UINTN TempCommBufferSize;\r
- UINT8 *NewPassword;\r
- UINT8 PasswordLength;\r
- EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
-\r
- if (CommBuffer == NULL || CommBufferSize == NULL) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- TempCommBufferSize = *CommBufferSize;\r
- if (TempCommBufferSize < OFFSET_OF (OPAL_SMM_COMMUNICATE_HEADER, Data)) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- Status = EFI_SUCCESS;\r
- SmmFunctionHeader = (OPAL_SMM_COMMUNICATE_HEADER *)CommBuffer;\r
-\r
- DevicePath = &((OPAL_COMM_DEVICE_LIST*)(SmmFunctionHeader->Data))->OpalDevicePath;\r
- PasswordLength = ((OPAL_COMM_DEVICE_LIST*)(SmmFunctionHeader->Data))->PasswordLength;\r
- NewPassword = ((OPAL_COMM_DEVICE_LIST*)(SmmFunctionHeader->Data))->Password;\r
-\r
- switch (SmmFunctionHeader->Function) {\r
- case SMM_FUNCTION_SET_OPAL_PASSWORD:\r
- if (OpalPasswordIsFullZero (NewPassword) || PasswordLength == 0) {\r
- Status = EFI_INVALID_PARAMETER;\r
- goto EXIT;\r
- }\r
-\r
- Status = OpalSavePasswordToSmm (DevicePath, NewPassword, PasswordLength);\r
- break;\r
-\r
- default:\r
- Status = EFI_UNSUPPORTED;\r
- break;\r
- }\r
-\r
-EXIT:\r
- SmmFunctionHeader->ReturnStatus = Status;\r
-\r
- //\r
- // Return EFI_SUCCESS cause only one handler can be trigged.\r
- // so return EFI_WARN_INTERRUPT_SOURCE_PENDING to make all handler can be trigged.\r
- //\r
- return EFI_WARN_INTERRUPT_SOURCE_PENDING;\r
-}\r
-\r
-/**\r
- The constructor function.\r
-\r
- Register SMI handler when link to SMM driver.\r
-\r
- @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-OpalPasswordSupportLibConstructor (\r
- VOID\r
- )\r
-{\r
- EFI_SMM_BASE2_PROTOCOL *SmmBase2;\r
- EFI_SMM_SYSTEM_TABLE2 *Smst;\r
- EFI_HANDLE SmmHandle;\r
- EFI_STATUS Status;\r
-\r
- Status = gBS->LocateProtocol (&gEfiSmmBase2ProtocolGuid, NULL, (VOID**) &SmmBase2);\r
- if (EFI_ERROR (Status)) {\r
- return RETURN_SUCCESS;\r
- }\r
- Status = SmmBase2->InSmm (SmmBase2, &gInSmm);\r
- if (EFI_ERROR (Status)) {\r
- return RETURN_SUCCESS;\r
- }\r
- if (!gInSmm) {\r
- return RETURN_SUCCESS;\r
- }\r
-\r
- //\r
- // Good, we are in SMM\r
- //\r
- Status = SmmBase2->GetSmstLocation (SmmBase2, &Smst);\r
- if (EFI_ERROR (Status)) {\r
- return RETURN_SUCCESS;\r
- }\r
-\r
- SmmHandle = NULL;\r
- Status = Smst->SmiHandlerRegister (SmmOpalPasswordHandler, &gOpalPasswordNotifyProtocolGuid, &SmmHandle);\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- The Destructor function.\r
-\r
- Clean the saved opal device list.\r
-\r
- @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-OpalPasswordSupportLibDestructor (\r
- VOID\r
- )\r
-{\r
- OPAL_DISK_AND_PASSWORD_INFO *Device;\r
-\r
- while (!IsListEmpty (&mDeviceList)) {\r
- Device = BASE_CR (mDeviceList.ForwardLink, OPAL_DISK_AND_PASSWORD_INFO, Link);\r
-\r
- RemoveEntryList (&Device->Link);\r
- FreePool (Device);\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r