From: Star Zeng <star.zeng@intel.com>
To: edk2-devel@lists.01.org
Cc: Star Zeng <star.zeng@intel.com>,
Jiewen Yao <jiewen.yao@intel.com>,
Eric Dong <eric.dong@intel.com>,
Chao Zhang <chao.b.zhang@intel.com>
Subject: [PATCH 6/7] SecurityPkg OpalPasswordSupportLib: Remove it
Date: Tue, 6 Mar 2018 22:27:59 +0800 [thread overview]
Message-ID: <1520346480-65348-7-git-send-email-star.zeng@intel.com> (raw)
In-Reply-To: <1520346480-65348-1-git-send-email-star.zeng@intel.com>
Remove OpalPasswordSupportLib as it is not been used
anymore.
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Chao Zhang <chao.b.zhang@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Star Zeng <star.zeng@intel.com>
---
.../Include/Library/OpalPasswordSupportLib.h | 289 --------
.../OpalPasswordSupportLib.c | 781 ---------------------
.../OpalPasswordSupportLib.inf | 55 --
.../OpalPasswordSupportNotify.h | 55 --
SecurityPkg/SecurityPkg.dec | 4 -
SecurityPkg/SecurityPkg.dsc | 2 -
6 files changed, 1186 deletions(-)
delete mode 100644 SecurityPkg/Include/Library/OpalPasswordSupportLib.h
delete mode 100644 SecurityPkg/Library/OpalPasswordSupportLib/OpalPasswordSupportLib.c
delete mode 100644 SecurityPkg/Library/OpalPasswordSupportLib/OpalPasswordSupportLib.inf
delete mode 100644 SecurityPkg/Library/OpalPasswordSupportLib/OpalPasswordSupportNotify.h
diff --git a/SecurityPkg/Include/Library/OpalPasswordSupportLib.h b/SecurityPkg/Include/Library/OpalPasswordSupportLib.h
deleted file mode 100644
index e616c763f05c..000000000000
--- a/SecurityPkg/Include/Library/OpalPasswordSupportLib.h
+++ /dev/null
@@ -1,289 +0,0 @@
-/** @file
- Header file of Opal password support library.
-
-Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
-This program and the accompanying materials
-are licensed and made available under the terms and conditions of the BSD License
-which accompanies this distribution. The full text of the license may be found at
-http://opensource.org/licenses/bsd-license.php
-
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-
-
-#ifndef _OPAL_PASSWORD_SUPPORT_LIB_H_
-#define _OPAL_PASSWORD_SUPPORT_LIB_H_
-
-#include <Protocol/DevicePath.h>
-#include <Library/TcgStorageOpalLib.h>
-
-
-#pragma pack(1)
-
-//
-// Structure that is used to represent the available actions for an OpalDisk.
-// The data can then be utilized to expose/hide certain actions available to an end user
-// by the consumer of this library.
-//
-typedef struct {
- //
- // Indicates if the disk can support PSID Revert action. should verify disk supports PSID authority
- //
- UINT16 PsidRevert : 1;
-
- //
- // Indicates if the disk can support Revert action
- //
- UINT16 Revert : 1;
-
- //
- // Indicates if the user must keep data for revert action. It is true if no media encryption is supported.
- //
- UINT16 RevertKeepDataForced : 1;
-
- //
- // Indicates if the disk can support set Admin password
- //
- UINT16 AdminPass : 1;
-
- //
- // Indicates if the disk can support set User password. This action requires that a user
- // password is first enabled.
- //
- UINT16 UserPass : 1;
-
- //
- // Indicates if unlock action is available. Requires disk to be currently locked.
- //
- UINT16 Unlock : 1;
-
- //
- // Indicates if Secure Erase action is available. Action requires admin credentials and media encryption support.
- //
- UINT16 SecureErase : 1;
-
- //
- // Indicates if Disable User action is available. Action requires admin credentials.
- //
- UINT16 DisableUser : 1;
-} OPAL_DISK_ACTIONS;
-
-//
-// Structure that is used to represent the Opal device with password info.
-//
-typedef struct {
- LIST_ENTRY Link;
-
- UINT8 Password[32];
- UINT8 PasswordLength;
-
- EFI_DEVICE_PATH_PROTOCOL OpalDevicePath;
-} OPAL_DISK_AND_PASSWORD_INFO;
-
-#pragma pack()
-
-/**
-
- The function performs determines the available actions for the OPAL_DISK provided.
-
- @param[in] SupportedAttributes The support attribute for the device.
- @param[in] LockingFeature The locking status for the device.
- @param[in] OwnerShip The ownership for the device.
- @param[out] AvalDiskActions Pointer to fill-out with appropriate disk actions.
-
-**/
-TCG_RESULT
-EFIAPI
-OpalSupportGetAvailableActions(
- IN OPAL_DISK_SUPPORT_ATTRIBUTE *SupportedAttributes,
- IN TCG_LOCKING_FEATURE_DESCRIPTOR *LockingFeature,
- IN UINT16 OwnerShip,
- OUT OPAL_DISK_ACTIONS *AvalDiskActions
- );
-
-/**
- Enable Opal Feature for the input device.
-
- @param[in] Session The opal session for the opal device.
- @param[in] Msid Msid
- @param[in] MsidLength Msid Length
- @param[in] Password Admin password
- @param[in] PassLength Length of password in bytes
- @param[in] DevicePath The device path for the opal devcie.
-
-**/
-TCG_RESULT
-EFIAPI
-OpalSupportEnableOpalFeature(
- IN OPAL_SESSION *Session,
- IN VOID *Msid,
- IN UINT32 MsidLength,
- IN VOID *Password,
- IN UINT32 PassLength,
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
- );
-
-/**
- Creates a session with OPAL_UID_ADMIN_SP as OPAL_ADMIN_SP_PSID_AUTHORITY, then reverts device using Admin SP Revert method.
-
- @param[in] Session The opal session for the opal device.
- @param[in] Psid PSID of device to revert.
- @param[in] PsidLength Length of PSID in bytes.
- @param[in] DevicePath The device path for the opal devcie.
-
-**/
-TCG_RESULT
-EFIAPI
-OpalSupportPsidRevert(
- IN OPAL_SESSION *Session,
- IN VOID *Psid,
- IN UINT32 PsidLength,
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
- );
-
-/**
- Opens a session with OPAL_UID_ADMIN_SP as OPAL_ADMIN_SP_PSID_AUTHORITY, then reverts the device using the RevertSP method.
-
- @param[in] Session The opal session for the opal device.
- @param[in] KeepUserData TRUE to keep existing Data on the disk, or FALSE to erase it
- @param[in] Password Admin password
- @param[in] PasswordLength Length of password in bytes
- @param[in] Msid Msid
- @param[in] MsidLength Msid Length
- @param[out] PasswordFailed indicates if password failed (start session didn't work)
- @param[in] DevicePath The device path for the opal devcie.
-
-**/
-TCG_RESULT
-EFIAPI
-OpalSupportRevert(
- IN OPAL_SESSION *Session,
- IN BOOLEAN KeepUserData,
- IN VOID *Password,
- IN UINT32 PasswordLength,
- IN VOID *Msid,
- IN UINT32 MsidLength,
- OUT BOOLEAN *PasswordFailed,
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
- );
-
-/**
- Set new password.
-
- @param[in] Session The opal session for the opal device.
- @param[in] OldPassword Current admin password
- @param[in] OldPasswordLength Length of current admin password in bytes
- @param[in] NewPassword New admin password to set
- @param[in] NewPasswordLength Length of new password in bytes
- @param[in] DevicePath The device path for the opal devcie.
- @param[in] SetAdmin Whether set admin password or user password.
- TRUE for admin, FALSE for user.
-
-**/
-TCG_RESULT
-EFIAPI
-OpalSupportSetPassword(
- IN OPAL_SESSION *Session,
- IN VOID *OldPassword,
- IN UINT32 OldPasswordLength,
- IN VOID *NewPassword,
- IN UINT32 NewPasswordLength,
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
- IN BOOLEAN SetAdmin
- );
-
-/**
- Starts a session with OPAL_UID_LOCKING_SP as OPAL_LOCKING_SP_ADMIN1_AUTHORITY and disables the User1 authority.
-
- @param[in] Session The opal session for the opal device.
- @param[in] Password Admin password
- @param[in] PasswordLength Length of password in bytes
- @param[out] PasswordFailed Indicates if password failed (start session didn't work)
- @param[in] DevicePath The device path for the opal devcie.
-
-**/
-TCG_RESULT
-EFIAPI
-OpalSupportDisableUser(
- IN OPAL_SESSION *Session,
- IN VOID *Password,
- IN UINT32 PasswordLength,
- OUT BOOLEAN *PasswordFailed,
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
- );
-
-/**
- Starts a session with OPAL_UID_LOCKING_SP as OPAL_LOCKING_SP_USER1_AUTHORITY or OPAL_LOCKING_SP_ADMIN1_AUTHORITY
- and updates the global locking range ReadLocked and WriteLocked columns to FALSE.
-
- @param[in] Session The opal session for the opal device.
- @param[in] Password Admin or user password
- @param[in] PasswordLength Length of password in bytes
- @param[in] DevicePath The device path for the opal devcie.
-
-**/
-TCG_RESULT
-EFIAPI
-OpalSupportUnlock(
- IN OPAL_SESSION *Session,
- IN VOID *Password,
- IN UINT32 PasswordLength,
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
- );
-
-/**
- Starts a session with OPAL_UID_LOCKING_SP as OPAL_LOCKING_SP_USER1_AUTHORITY or OPAL_LOCKING_SP_ADMIN1_AUTHORITY
- and updates the global locking range ReadLocked and WriteLocked columns to TRUE.
-
- @param[in] Session The opal session for the opal device.
- @param[in] Password Admin or user password
- @param[in] PasswordLength Length of password in bytes
- @param[in] DevicePath The device path for the opal devcie.
-
-**/
-TCG_RESULT
-EFIAPI
-OpalSupportLock(
- IN OPAL_SESSION *Session,
- IN VOID *Password,
- IN UINT32 PasswordLength,
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
- );
-
-/**
- Check if the password is full zero.
-
- @param[in] Password Points to the Data Buffer
-
- @retval TRUE This password string is full zero.
- @retval FALSE This password string is not full zero.
-
-**/
-LIST_ENTRY *
-EFIAPI
-OpalSupportGetOpalDeviceList (
- VOID
- );
-
-/**
- Transfer the password to the smm driver.
-
- @param[in] DevicePath The device path for the opal devcie.
- @param PasswordLen The input password length.
- @param Password Input password buffer.
-
- @retval EFI_SUCCESS Do the required action success.
- @retval Others Error occured.
-
-**/
-EFI_STATUS
-EFIAPI
-OpalSupportSendPasword(
- EFI_DEVICE_PATH_PROTOCOL *DevicePath,
- UINTN PasswordLen,
- VOID *Password
- );
-
-#endif // _OPAL_CORE_H_
diff --git a/SecurityPkg/Library/OpalPasswordSupportLib/OpalPasswordSupportLib.c b/SecurityPkg/Library/OpalPasswordSupportLib/OpalPasswordSupportLib.c
deleted file mode 100644
index 837582359e4f..000000000000
--- a/SecurityPkg/Library/OpalPasswordSupportLib/OpalPasswordSupportLib.c
+++ /dev/null
@@ -1,781 +0,0 @@
-/** @file
- Implementation of Opal password support library.
-
-Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
-This program and the accompanying materials
-are licensed and made available under the terms and conditions of the BSD License
-which accompanies this distribution. The full text of the license may be found at
-http://opensource.org/licenses/bsd-license.php
-
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-
-#include "OpalPasswordSupportNotify.h"
-
-#define OPAL_PASSWORD_MAX_LENGTH 32
-
-LIST_ENTRY mDeviceList = INITIALIZE_LIST_HEAD_VARIABLE (mDeviceList);
-BOOLEAN gInSmm = FALSE;
-EFI_GUID gOpalPasswordNotifyProtocolGuid = OPAL_PASSWORD_NOTIFY_PROTOCOL_GUID;
-
-/**
-
- The function performs determines the available actions for the OPAL_DISK provided.
-
- @param[in] SupportedAttributes The support attribute for the device.
- @param[in] LockingFeature The locking status for the device.
- @param[in] OwnerShip The ownership for the device.
- @param[out] AvalDiskActions Pointer to fill-out with appropriate disk actions.
-
-**/
-TCG_RESULT
-EFIAPI
-OpalSupportGetAvailableActions(
- IN OPAL_DISK_SUPPORT_ATTRIBUTE *SupportedAttributes,
- IN TCG_LOCKING_FEATURE_DESCRIPTOR *LockingFeature,
- IN UINT16 OwnerShip,
- OUT OPAL_DISK_ACTIONS *AvalDiskActions
- )
-{
- BOOLEAN ExistingPassword;
-
- NULL_CHECK(AvalDiskActions);
-
- AvalDiskActions->AdminPass = 1;
- AvalDiskActions->UserPass = 0;
- AvalDiskActions->DisableUser = 0;
- AvalDiskActions->Unlock = 0;
-
- //
- // Revert is performed on locking sp, so only allow if locking sp is enabled
- //
- if (LockingFeature->LockingEnabled) {
- AvalDiskActions->Revert = 1;
- }
-
- //
- // Psid revert is available for any device with media encryption support
- // Revert is allowed for any device with media encryption support, however it requires
- //
- if (SupportedAttributes->MediaEncryption) {
-
- //
- // Only allow psid revert if media encryption is enabled.
- // Otherwise, someone who steals a disk can psid revert the disk and the user Data is still
- // intact and accessible
- //
- AvalDiskActions->PsidRevert = 1;
- AvalDiskActions->RevertKeepDataForced = 0;
-
- //
- // Secure erase is performed by generating a new encryption key
- // this is only available is encryption is supported
- //
- AvalDiskActions->SecureErase = 1;
- } else {
- AvalDiskActions->PsidRevert = 0;
- AvalDiskActions->SecureErase = 0;
-
- //
- // If no media encryption is supported, then a revert (using password) will not
- // erase the Data (since you can't generate a new encryption key)
- //
- AvalDiskActions->RevertKeepDataForced = 1;
- }
-
- if (LockingFeature->Locked) {
- AvalDiskActions->Unlock = 1;
- } else {
- AvalDiskActions->Unlock = 0;
- }
-
- //
- // Only allow user to set password if an admin password exists
- //
- ExistingPassword = OpalUtilAdminPasswordExists(OwnerShip, LockingFeature);
- AvalDiskActions->UserPass = ExistingPassword;
-
- //
- // This will still show up even if there isn't a user, which is fine
- //
- AvalDiskActions->DisableUser = ExistingPassword;
-
- return TcgResultSuccess;
-}
-
-/**
- Creates a session with OPAL_UID_ADMIN_SP as OPAL_ADMIN_SP_PSID_AUTHORITY, then reverts device using Admin SP Revert method.
-
- @param[in] Session The opal session for the opal device.
- @param[in] Psid PSID of device to revert.
- @param[in] PsidLength Length of PSID in bytes.
- @param[in] DevicePath The device path for the opal devcie.
-
-**/
-TCG_RESULT
-EFIAPI
-OpalSupportPsidRevert(
- IN OPAL_SESSION *Session,
- IN VOID *Psid,
- IN UINT32 PsidLength,
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
- )
-{
- TCG_RESULT Ret;
-
- NULL_CHECK(Session);
- NULL_CHECK(Psid);
-
- Ret = OpalUtilPsidRevert (Session, Psid, PsidLength);
- if (Ret == TcgResultSuccess && !gInSmm) {
- OpalSupportSendPasword (DevicePath, 0, NULL);
- }
-
- return Ret;
-}
-
-/**
- Opens a session with OPAL_UID_ADMIN_SP as OPAL_ADMIN_SP_SID_AUTHORITY,
- sets OPAL_UID_ADMIN_SP_C_PIN_SID with the new password,
- and sets OPAL_LOCKING_SP_C_PIN_ADMIN1 with the new password.
-
- @param[in] Session The opal session for the opal device.
- @param[in] OldPassword Current admin password
- @param[in] OldPasswordLength Length of current admin password in bytes
- @param[in] NewPassword New admin password to set
- @param[in] NewPasswordLength Length of new password in bytes
- @param[in] DevicePath The device path for the opal devcie.
- @param[in] SetAdmin Whether set admin password or user password.
- TRUE for admin, FALSE for user.
-
-**/
-TCG_RESULT
-EFIAPI
-OpalSupportSetPassword(
- IN OPAL_SESSION *Session,
- IN VOID *OldPassword,
- IN UINT32 OldPasswordLength,
- IN VOID *NewPassword,
- IN UINT32 NewPasswordLength,
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
- IN BOOLEAN SetAdmin
- )
-{
- TCG_RESULT Ret;
-
- NULL_CHECK(Session);
- NULL_CHECK(OldPassword);
- NULL_CHECK(NewPassword);
-
- if (SetAdmin) {
- Ret = OpalUtilSetAdminPassword(Session, OldPassword, OldPasswordLength, NewPassword, NewPasswordLength);
- } else {
- Ret = OpalUtilSetUserPassword(Session, OldPassword, OldPasswordLength, NewPassword, NewPasswordLength);
- }
- if (Ret == TcgResultSuccess && !gInSmm) {
- OpalSupportSendPasword (DevicePath, NewPasswordLength, NewPassword);
- }
-
- return Ret;
-}
-
-/**
- Starts a session with OPAL_UID_LOCKING_SP as OPAL_LOCKING_SP_ADMIN1_AUTHORITY and disables the User1 authority.
-
- @param[in] Session The opal session for the opal device.
- @param[in] Password Admin password
- @param[in] PasswordLength Length of password in bytes
- @param[out] PasswordFailed Indicates if password failed (start session didn't work)
- @param[in] DevicePath The device path for the opal devcie.
-
-**/
-TCG_RESULT
-EFIAPI
-OpalSupportDisableUser(
- IN OPAL_SESSION *Session,
- IN VOID *Password,
- IN UINT32 PasswordLength,
- OUT BOOLEAN *PasswordFailed,
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
- )
-{
- TCG_RESULT Ret;
-
- NULL_CHECK(Session);
- NULL_CHECK(Password);
- NULL_CHECK(PasswordFailed);
-
- Ret = OpalUtilDisableUser(Session, Password, PasswordLength, PasswordFailed);
- if (Ret == TcgResultSuccess && !gInSmm) {
- OpalSupportSendPasword (DevicePath, PasswordLength, Password);
- }
-
- return Ret;
-}
-
-/**
- Enable Opal Feature for the input device.
-
- @param[in] Session The opal session for the opal device.
- @param[in] Msid Msid
- @param[in] MsidLength Msid Length
- @param[in] Password Admin password
- @param[in] PassLength Length of password in bytes
- @param[in] DevicePath The device path for the opal devcie.
-
-**/
-TCG_RESULT
-EFIAPI
-OpalSupportEnableOpalFeature (
- IN OPAL_SESSION *Session,
- IN VOID *Msid,
- IN UINT32 MsidLength,
- IN VOID *Password,
- IN UINT32 PassLength,
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
- )
-{
- TCG_RESULT Ret;
-
- NULL_CHECK(Session);
- NULL_CHECK(Msid);
- NULL_CHECK(Password);
-
- Ret = OpalUtilSetAdminPasswordAsSid(
- Session,
- Msid,
- MsidLength,
- Password,
- PassLength
- );
- if (Ret == TcgResultSuccess) {
- //
- // Enable global locking range
- //
- Ret = OpalUtilSetOpalLockingRange(
- Session,
- Password,
- PassLength,
- OPAL_LOCKING_SP_LOCKING_GLOBALRANGE,
- 0,
- 0,
- TRUE,
- TRUE,
- FALSE,
- FALSE
- );
- }
-
- if (Ret == TcgResultSuccess && !gInSmm) {
- OpalSupportSendPasword (DevicePath, PassLength, Password);
- }
-
- return Ret;
-}
-
-/**
- Opens a session with OPAL_UID_ADMIN_SP as OPAL_ADMIN_SP_PSID_AUTHORITY, then reverts the device using the RevertSP method.
-
- @param[in] Session The opal session for the opal device.
- @param[in] KeepUserData TRUE to keep existing Data on the disk, or FALSE to erase it
- @param[in] Password Admin password
- @param[in] PasswordLength Length of password in bytes
- @param[in] Msid Msid
- @param[in] MsidLength Msid Length
- @param[out] PasswordFailed indicates if password failed (start session didn't work)
- @param[in] DevicePath The device path for the opal devcie.
-
-**/
-TCG_RESULT
-EFIAPI
-OpalSupportRevert(
- IN OPAL_SESSION *Session,
- IN BOOLEAN KeepUserData,
- IN VOID *Password,
- IN UINT32 PasswordLength,
- IN VOID *Msid,
- IN UINT32 MsidLength,
- OUT BOOLEAN *PasswordFailed,
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
- )
-{
- TCG_RESULT Ret;
-
- NULL_CHECK(Session);
- NULL_CHECK(Password);
- NULL_CHECK(Msid);
- NULL_CHECK(PasswordFailed);
-
- Ret = OpalUtilRevert(Session, KeepUserData, Password, PasswordLength, PasswordFailed, Msid, MsidLength);
- if (Ret == TcgResultSuccess && !gInSmm) {
- OpalSupportSendPasword (DevicePath, 0, NULL);
- }
-
- return Ret;
-}
-
-/**
- Starts a session with OPAL_UID_LOCKING_SP as OPAL_LOCKING_SP_USER1_AUTHORITY or OPAL_LOCKING_SP_ADMIN1_AUTHORITY
- and updates the global locking range ReadLocked and WriteLocked columns to FALSE.
-
- @param[in] Session The opal session for the opal device.
- @param[in] Password Admin or user password
- @param[in] PasswordLength Length of password in bytes
- @param[in] DevicePath The device path for the opal devcie.
-
-**/
-TCG_RESULT
-EFIAPI
-OpalSupportUnlock(
- IN OPAL_SESSION *Session,
- IN VOID *Password,
- IN UINT32 PasswordLength,
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
- )
-{
- TCG_RESULT Ret;
-
- NULL_CHECK(Session);
- NULL_CHECK(Password);
-
- Ret = OpalUtilUpdateGlobalLockingRange(Session, Password, PasswordLength, FALSE, FALSE);
- if (Ret == TcgResultSuccess && !gInSmm) {
- OpalSupportSendPasword (DevicePath, PasswordLength, Password);
- }
-
- return Ret;
-}
-
-/**
- Starts a session with OPAL_UID_LOCKING_SP as OPAL_LOCKING_SP_USER1_AUTHORITY or OPAL_LOCKING_SP_ADMIN1_AUTHORITY
- and updates the global locking range ReadLocked and WriteLocked columns to TRUE.
-
- @param[in] Session The opal session for the opal device.
- @param[in] Password Admin or user password
- @param[in] PasswordLength Length of password in bytes
- @param[in] DevicePath The device path for the opal devcie.
-
-**/
-TCG_RESULT
-EFIAPI
-OpalSupportLock(
- IN OPAL_SESSION *Session,
- IN VOID *Password,
- IN UINT32 PasswordLength,
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
- )
-{
- TCG_RESULT Ret;
-
- NULL_CHECK(Session);
- NULL_CHECK(Password);
-
- Ret = OpalUtilUpdateGlobalLockingRange(Session, Password, PasswordLength, TRUE, TRUE);
- if (Ret == TcgResultSuccess && !gInSmm) {
- OpalSupportSendPasword (DevicePath, PasswordLength, Password);
- }
-
- return Ret;
-}
-
-/**
- Initialize the communicate Buffer using DataSize and Function.
-
- @param[out] DataPtr Points to the Data in the communicate Buffer.
- @param[in] DataSize The Data Size to send to SMM.
- @param[in] Function The function number to initialize the communicate Header.
-
- @retval EFI_INVALID_PARAMETER The Data Size is too big.
- @retval EFI_SUCCESS Find the specified variable.
-
-**/
-VOID*
-OpalInitCommunicateBuffer (
- OUT VOID **DataPtr OPTIONAL,
- IN UINTN DataSize,
- IN UINTN Function
- )
-{
- EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader;
- OPAL_SMM_COMMUNICATE_HEADER *SmmFunctionHeader;
- VOID *Buffer;
- EDKII_PI_SMM_COMMUNICATION_REGION_TABLE *SmmCommRegionTable;
- EFI_MEMORY_DESCRIPTOR *SmmCommMemRegion;
- UINTN Index;
- UINTN Size;
- EFI_STATUS Status;
-
- Buffer = NULL;
- Status = EfiGetSystemConfigurationTable (
- &gEdkiiPiSmmCommunicationRegionTableGuid,
- (VOID **) &SmmCommRegionTable
- );
- if (EFI_ERROR (Status)) {
- return NULL;
- }
-
- ASSERT (SmmCommRegionTable != NULL);
- SmmCommMemRegion = (EFI_MEMORY_DESCRIPTOR *) (SmmCommRegionTable + 1);
- Size = 0;
- for (Index = 0; Index < SmmCommRegionTable->NumberOfEntries; Index++) {
- if (SmmCommMemRegion->Type == EfiConventionalMemory) {
- Size = EFI_PAGES_TO_SIZE ((UINTN) SmmCommMemRegion->NumberOfPages);
- if (Size >= (DataSize + OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data) + OFFSET_OF (OPAL_SMM_COMMUNICATE_HEADER, Data))) {
- break;
- }
- }
- SmmCommMemRegion = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) SmmCommMemRegion + SmmCommRegionTable->DescriptorSize);
- }
- ASSERT (Index < SmmCommRegionTable->NumberOfEntries);
-
- Buffer = (VOID*)(UINTN)SmmCommMemRegion->PhysicalStart;
- ASSERT (Buffer != NULL);
-
- SmmCommunicateHeader = (EFI_SMM_COMMUNICATE_HEADER *) Buffer;
- CopyGuid (&SmmCommunicateHeader->HeaderGuid, &gOpalPasswordNotifyProtocolGuid);
- SmmCommunicateHeader->MessageLength = DataSize + OFFSET_OF (OPAL_SMM_COMMUNICATE_HEADER, Data);
-
- SmmFunctionHeader = (OPAL_SMM_COMMUNICATE_HEADER *) SmmCommunicateHeader->Data;
- SmmFunctionHeader->Function = Function;
- if (DataPtr != NULL) {
- *DataPtr = SmmFunctionHeader->Data;
- }
-
- return Buffer;
-}
-
-/**
- Send the Data in communicate Buffer to SMM.
-
- @param[in] Buffer Points to the Data in the communicate Buffer.
- @param[in] DataSize This Size of the function Header and the Data.
-
- @retval EFI_SUCCESS Success is returned from the functin in SMM.
- @retval Others Failure is returned from the function in SMM.
-
-**/
-EFI_STATUS
-OpalSendCommunicateBuffer (
- IN VOID *Buffer,
- IN UINTN DataSize
- )
-{
- EFI_STATUS Status;
- UINTN CommSize;
- EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader;
- OPAL_SMM_COMMUNICATE_HEADER *SmmFunctionHeader;
- EFI_SMM_COMMUNICATION_PROTOCOL *SmmCommunication;
-
- Status = gBS->LocateProtocol (&gEfiSmmCommunicationProtocolGuid, NULL, (VOID **) &SmmCommunication);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- CommSize = DataSize + OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data) + OFFSET_OF (OPAL_SMM_COMMUNICATE_HEADER, Data);
- Status = SmmCommunication->Communicate (SmmCommunication, Buffer, &CommSize);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- SmmCommunicateHeader = (EFI_SMM_COMMUNICATE_HEADER *) Buffer;
- SmmFunctionHeader = (OPAL_SMM_COMMUNICATE_HEADER *)SmmCommunicateHeader->Data;
-
- return SmmFunctionHeader->ReturnStatus;
-}
-
-/**
- Transfer the password to the smm driver.
-
- @param[in] DevicePath The device path for the opal devcie.
- @param PasswordLen The input password length.
- @param Password Input password buffer.
-
- @retval EFI_SUCCESS Do the required action success.
- @retval Others Error occured.
-
-**/
-EFI_STATUS
-EFIAPI
-OpalSupportSendPasword(
- EFI_DEVICE_PATH_PROTOCOL *DevicePath,
- UINTN PasswordLen,
- VOID *Password
- )
-{
- OPAL_COMM_DEVICE_LIST *Parameter;
- VOID *Buffer;
- UINTN Length;
- EFI_STATUS Status;
- UINTN DevicePathLen;
-
- Parameter = NULL;
- Buffer = NULL;
-
- if (DevicePath == NULL) {
- //
- // Assume DevicePath == NULL only when library used by SMM driver
- // and should not run to here, just return success.
- //
- return EFI_SUCCESS;
- }
-
- DevicePathLen = GetDevicePathSize (DevicePath);
- Length = OFFSET_OF (OPAL_COMM_DEVICE_LIST, OpalDevicePath) + DevicePathLen;
- Buffer = OpalInitCommunicateBuffer((VOID**)&Parameter, Length, SMM_FUNCTION_SET_OPAL_PASSWORD);
- if (Buffer == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- if (Password != NULL) {
- CopyMem((VOID*)Parameter->Password, Password, PasswordLen);
- Parameter->PasswordLength = (UINT8)PasswordLen;
- }
- CopyMem (&Parameter->OpalDevicePath, DevicePath, DevicePathLen);
-
- Status = OpalSendCommunicateBuffer(Buffer, Length);
- if (EFI_ERROR(Status)) {
- goto EXIT;
- }
-
-EXIT:
- ZeroMem(Parameter, Length);
- return Status;
-}
-
-/**
- Get saved Opal device list.
-
- @retval return opal device list.
-
-**/
-LIST_ENTRY*
-EFIAPI
-OpalSupportGetOpalDeviceList (
- VOID
- )
-{
- return &mDeviceList;
-}
-
-/**
- Check if the password is full zero.
-
- @param[in] Password Points to the Data Buffer
-
- @retval TRUE This password string is full zero.
- @retval FALSE This password string is not full zero.
-
-**/
-BOOLEAN
-OpalPasswordIsFullZero (
- IN UINT8 *Password
- )
-{
- UINTN Index;
-
- for (Index = 0; Index < OPAL_PASSWORD_MAX_LENGTH; Index++) {
- if (Password[Index] != 0) {
- return FALSE;
- }
- }
-
- return TRUE;
-}
-
-/**
- Save hdd password to SMM.
-
- @param[in] DevicePath Input device path info for the device.
- @param[in] Password The hdd password of attached ATA device.
- @param[in] PasswordLength The hdd password length.
-
- @retval EFI_OUT_OF_RESOURCES Insufficient resources to create database record
- @retval EFI_SUCCESS The function has been successfully executed.
-
-**/
-EFI_STATUS
-OpalSavePasswordToSmm (
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
- IN UINT8 *Password,
- IN UINT8 PasswordLength
- )
-{
- OPAL_DISK_AND_PASSWORD_INFO *List;
- OPAL_DISK_AND_PASSWORD_INFO *Dev;
- LIST_ENTRY *Entry;
- UINTN DevicePathLen;
-
- DevicePathLen = GetDevicePathSize (DevicePath);
-
- for (Entry = mDeviceList.ForwardLink; Entry != &mDeviceList; Entry = Entry->ForwardLink) {
- List = BASE_CR (Entry, OPAL_DISK_AND_PASSWORD_INFO, Link);
- if (CompareMem (&List->OpalDevicePath, DevicePath, DevicePathLen) == 0) {
- CopyMem(List->Password, Password, OPAL_PASSWORD_MAX_LENGTH);
- return EFI_SUCCESS;
- }
- }
-
- Dev = AllocateZeroPool (OFFSET_OF (OPAL_DISK_AND_PASSWORD_INFO, OpalDevicePath) + DevicePathLen);
- if (Dev == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- Dev->PasswordLength = PasswordLength;
- CopyMem(&(Dev->Password), Password, OPAL_PASSWORD_MAX_LENGTH);
- CopyMem(&(Dev->OpalDevicePath), DevicePath, DevicePathLen);
-
- InsertHeadList (&mDeviceList, &Dev->Link);
-
- return EFI_SUCCESS;
-}
-
-/**
- Communication service SMI Handler entry.
-
- This SMI handler provides services for saving HDD password and saving S3 boot script when ready to boot.
-
- @param[in] DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().
- @param[in] RegisterContext Points to an optional handler context which was specified when the
- handler was registered.
- @param[in, out] CommBuffer A pointer to a collection of Data in memory that will
- be conveyed from a non-SMM environment into an SMM environment.
- @param[in, out] CommBufferSize The Size of the CommBuffer.
-
- @retval EFI_SUCCESS The interrupt was handled and quiesced. No other handlers
- should still be called.
- @retval EFI_WARN_INTERRUPT_SOURCE_QUIESCED The interrupt has been quiesced but other handlers should
- still be called.
- @retval EFI_WARN_INTERRUPT_SOURCE_PENDING The interrupt is still pending and other handlers should still
- be called.
- @retval EFI_INTERRUPT_PENDING The interrupt could not be quiesced.
-**/
-EFI_STATUS
-EFIAPI
-SmmOpalPasswordHandler (
- IN EFI_HANDLE DispatchHandle,
- IN CONST VOID *RegisterContext,
- IN OUT VOID *CommBuffer,
- IN OUT UINTN *CommBufferSize
- )
-{
- EFI_STATUS Status;
- OPAL_SMM_COMMUNICATE_HEADER *SmmFunctionHeader;
- UINTN TempCommBufferSize;
- UINT8 *NewPassword;
- UINT8 PasswordLength;
- EFI_DEVICE_PATH_PROTOCOL *DevicePath;
-
- if (CommBuffer == NULL || CommBufferSize == NULL) {
- return EFI_SUCCESS;
- }
-
- TempCommBufferSize = *CommBufferSize;
- if (TempCommBufferSize < OFFSET_OF (OPAL_SMM_COMMUNICATE_HEADER, Data)) {
- return EFI_SUCCESS;
- }
-
- Status = EFI_SUCCESS;
- SmmFunctionHeader = (OPAL_SMM_COMMUNICATE_HEADER *)CommBuffer;
-
- DevicePath = &((OPAL_COMM_DEVICE_LIST*)(SmmFunctionHeader->Data))->OpalDevicePath;
- PasswordLength = ((OPAL_COMM_DEVICE_LIST*)(SmmFunctionHeader->Data))->PasswordLength;
- NewPassword = ((OPAL_COMM_DEVICE_LIST*)(SmmFunctionHeader->Data))->Password;
-
- switch (SmmFunctionHeader->Function) {
- case SMM_FUNCTION_SET_OPAL_PASSWORD:
- if (OpalPasswordIsFullZero (NewPassword) || PasswordLength == 0) {
- Status = EFI_INVALID_PARAMETER;
- goto EXIT;
- }
-
- Status = OpalSavePasswordToSmm (DevicePath, NewPassword, PasswordLength);
- break;
-
- default:
- Status = EFI_UNSUPPORTED;
- break;
- }
-
-EXIT:
- SmmFunctionHeader->ReturnStatus = Status;
-
- //
- // Return EFI_SUCCESS cause only one handler can be trigged.
- // so return EFI_WARN_INTERRUPT_SOURCE_PENDING to make all handler can be trigged.
- //
- return EFI_WARN_INTERRUPT_SOURCE_PENDING;
-}
-
-/**
- The constructor function.
-
- Register SMI handler when link to SMM driver.
-
- @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
-
-**/
-EFI_STATUS
-EFIAPI
-OpalPasswordSupportLibConstructor (
- VOID
- )
-{
- EFI_SMM_BASE2_PROTOCOL *SmmBase2;
- EFI_SMM_SYSTEM_TABLE2 *Smst;
- EFI_HANDLE SmmHandle;
- EFI_STATUS Status;
-
- Status = gBS->LocateProtocol (&gEfiSmmBase2ProtocolGuid, NULL, (VOID**) &SmmBase2);
- if (EFI_ERROR (Status)) {
- return RETURN_SUCCESS;
- }
- Status = SmmBase2->InSmm (SmmBase2, &gInSmm);
- if (EFI_ERROR (Status)) {
- return RETURN_SUCCESS;
- }
- if (!gInSmm) {
- return RETURN_SUCCESS;
- }
-
- //
- // Good, we are in SMM
- //
- Status = SmmBase2->GetSmstLocation (SmmBase2, &Smst);
- if (EFI_ERROR (Status)) {
- return RETURN_SUCCESS;
- }
-
- SmmHandle = NULL;
- Status = Smst->SmiHandlerRegister (SmmOpalPasswordHandler, &gOpalPasswordNotifyProtocolGuid, &SmmHandle);
- ASSERT_EFI_ERROR (Status);
-
- return EFI_SUCCESS;
-}
-
-/**
- The Destructor function.
-
- Clean the saved opal device list.
-
- @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
-
-**/
-EFI_STATUS
-EFIAPI
-OpalPasswordSupportLibDestructor (
- VOID
- )
-{
- OPAL_DISK_AND_PASSWORD_INFO *Device;
-
- while (!IsListEmpty (&mDeviceList)) {
- Device = BASE_CR (mDeviceList.ForwardLink, OPAL_DISK_AND_PASSWORD_INFO, Link);
-
- RemoveEntryList (&Device->Link);
- FreePool (Device);
- }
-
- return EFI_SUCCESS;
-}
diff --git a/SecurityPkg/Library/OpalPasswordSupportLib/OpalPasswordSupportLib.inf b/SecurityPkg/Library/OpalPasswordSupportLib/OpalPasswordSupportLib.inf
deleted file mode 100644
index b7831356e5dd..000000000000
--- a/SecurityPkg/Library/OpalPasswordSupportLib/OpalPasswordSupportLib.inf
+++ /dev/null
@@ -1,55 +0,0 @@
-## @file
-# This is a OpalPassword support library.
-#
-# This module is used to provide API used by Opal password solution.
-#
-# Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
-# This program and the accompanying materials
-# are licensed and made available under the terms and conditions of the BSD License
-# which accompanies this distribution. The full text of the license may be found at
-# http://opensource.org/licenses/bsd-license.php
-# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-#
-##
-[Defines]
- INF_VERSION = 0x00010017
- BASE_NAME = OpalPasswordSupportLib
- FILE_GUID = 00F93D8C-00A6-42D0-9327-11CE309B944A
- VERSION_STRING = 1.0
- MODULE_TYPE = BASE
- LIBRARY_CLASS = OpalPasswordSupportLib|DXE_DRIVER DXE_CORE DXE_SMM_DRIVER
-
- CONSTRUCTOR = OpalPasswordSupportLibConstructor
- DESTRUCTOR = OpalPasswordSupportLibDestructor
-#
-# The following information is for reference only and not required by the build tools.
-#
-# VALID_ARCHITECTURES = IA32 X64
-#
-
-[Sources]
- OpalPasswordSupportLib.c
- OpalPasswordSupportNotify.h
-
-[LibraryClasses]
- BaseLib
- BaseMemoryLib
- PrintLib
- DebugLib
- TimerLib
- TcgStorageOpalLib
- UefiLib
-
-[Packages]
- MdePkg/MdePkg.dec
- MdeModulePkg/MdeModulePkg.dec
- SecurityPkg/SecurityPkg.dec
-
-[Protocols]
- gEfiStorageSecurityCommandProtocolGuid ## CONSUMES
- gEfiSmmCommunicationProtocolGuid ## CONSUMES
- gEfiSmmBase2ProtocolGuid ## CONSUMES # only for SMM version
-
-[Guids]
- gEdkiiPiSmmCommunicationRegionTableGuid ## CONSUMES ## SystemTable
diff --git a/SecurityPkg/Library/OpalPasswordSupportLib/OpalPasswordSupportNotify.h b/SecurityPkg/Library/OpalPasswordSupportLib/OpalPasswordSupportNotify.h
deleted file mode 100644
index a2115b738653..000000000000
--- a/SecurityPkg/Library/OpalPasswordSupportLib/OpalPasswordSupportNotify.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/** @file
- Implementation of Opal password support library.
-
-Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.<BR>
-This program and the accompanying materials
-are licensed and made available under the terms and conditions of the BSD License
-which accompanies this distribution. The full text of the license may be found at
-http://opensource.org/licenses/bsd-license.php
-
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-
-#ifndef _DXE_OPAL_NOTIFY_H_
-#define _DXE_OPAL_NOTIFY_H_
-
-#include <PiDxe.h>
-#include <PiSmm.h>
-
-#include <Guid/PiSmmCommunicationRegionTable.h>
-#include <Library/DebugLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/UefiLib.h>
-#include <Library/OpalPasswordSupportLib.h>
-#include <Library/DevicePathLib.h>
-#include <Library/MemoryAllocationLib.h>
-
-#include <Protocol/SmmCommunication.h>
-#include <Protocol/SmmBase2.h>
-
-
-#pragma pack(1)
-
-typedef struct {
- UINTN Function;
- EFI_STATUS ReturnStatus;
- UINT8 Data[1];
-} OPAL_SMM_COMMUNICATE_HEADER;
-
-typedef struct {
- UINT8 Password[32];
- UINT8 PasswordLength;
-
- EFI_DEVICE_PATH_PROTOCOL OpalDevicePath;
-} OPAL_COMM_DEVICE_LIST;
-
-#pragma pack()
-
-#define SMM_FUNCTION_SET_OPAL_PASSWORD 1
-
-#define OPAL_PASSWORD_NOTIFY_PROTOCOL_GUID {0x0ff2ddd0, 0xefc9, 0x4f49, { 0x99, 0x7a, 0xcb, 0x59, 0x44, 0xe6, 0x97, 0xd3 } }
-
-#endif
diff --git a/SecurityPkg/SecurityPkg.dec b/SecurityPkg/SecurityPkg.dec
index 71963eb750d5..77d6b073d401 100644
--- a/SecurityPkg/SecurityPkg.dec
+++ b/SecurityPkg/SecurityPkg.dec
@@ -90,10 +90,6 @@ [LibraryClasses]
#
TcgStorageOpalLib|Include/Library/TcgStorageOpalLib.h
- ## @libraryclass Provides interfaces about Opal commond special for Opal password solution.
- #
- OpalPasswordSupportLib|Include/Library/OpalPasswordSupportLib.h
-
[Guids]
## Security package token space guid.
# Include/Guid/SecurityPkgTokenSpace.h
diff --git a/SecurityPkg/SecurityPkg.dsc b/SecurityPkg/SecurityPkg.dsc
index 9be484877cc2..ed47fb2fa05b 100644
--- a/SecurityPkg/SecurityPkg.dsc
+++ b/SecurityPkg/SecurityPkg.dsc
@@ -73,7 +73,6 @@ [LibraryClasses]
PciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf
TcgStorageCoreLib|SecurityPkg/Library/TcgStorageCoreLib/TcgStorageCoreLib.inf
TcgStorageOpalLib|SecurityPkg/Library/TcgStorageOpalLib/TcgStorageOpalLib.inf
- OpalPasswordSupportLib|SecurityPkg/Library/OpalPasswordSupportLib/OpalPasswordSupportLib.inf
ResetSystemLib|MdeModulePkg/Library/BaseResetSystemLibNull/BaseResetSystemLibNull.inf
[LibraryClasses.common.PEIM]
@@ -204,7 +203,6 @@ [Components]
#
SecurityPkg/Library/TcgStorageCoreLib/TcgStorageCoreLib.inf
SecurityPkg/Library/TcgStorageOpalLib/TcgStorageOpalLib.inf
- SecurityPkg/Library/OpalPasswordSupportLib/OpalPasswordSupportLib.inf
#
# Other
--
2.7.0.windows.1
next prev parent reply other threads:[~2018-03-06 14:22 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-03-06 14:27 [PATCH 0/7] OpalPassword: New solution without SMM device code Star Zeng
2018-03-06 14:27 ` [PATCH 1/7] MdeModulePkg LockBoxLib: Support LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY Star Zeng
2018-03-07 6:44 ` Yao, Jiewen
2018-03-06 14:27 ` [PATCH 2/7] SecurityPkg TcgStorageOpalLib: Make it be base type really Star Zeng
2018-03-07 6:45 ` Yao, Jiewen
2018-03-06 14:27 ` [PATCH 3/7] SecurityPkg TcgStorageCoreLib: " Star Zeng
2018-03-07 6:46 ` Yao, Jiewen
2018-03-06 14:27 ` [PATCH 4/7] SecurityPkg OpalPassword: Add solution without SMM device code Star Zeng
2018-03-07 7:06 ` Yao, Jiewen
2018-03-07 13:21 ` Zeng, Star
2018-03-06 14:27 ` [PATCH 5/7] SecurityPkg OpalPassword: Remove old solution Star Zeng
2018-03-07 6:55 ` Yao, Jiewen
2018-03-06 14:27 ` Star Zeng [this message]
2018-03-07 6:55 ` [PATCH 6/7] SecurityPkg OpalPasswordSupportLib: Remove it Yao, Jiewen
2018-03-06 14:28 ` [PATCH 7/7] SecurityPkg OpalPasswordExtraInfoVariable.h: " Star Zeng
2018-03-07 6:55 ` Yao, Jiewen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1520346480-65348-7-git-send-email-star.zeng@intel.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox