MdeModulePkg LockBoxLib: Support LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY

With this flag, the LockBox can be restored in S3 resume only.
The LockBox can not be restored after SmmReadyToLock in normal boot
and after EndOfS3Resume in S3 resume.
It can not be set together with LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE.

Cc: Jiewen Yao <jiewen.yao@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Star Zeng <star.zeng@intel.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
This commit is contained in:
Star Zeng 2018-02-11 10:01:21 +08:00
parent bc2288f59b
commit 6bd4af305d
4 changed files with 247 additions and 8 deletions

View File

@ -2,7 +2,7 @@
This library is only intended to be used by DXE modules that need save This library is only intended to be used by DXE modules that need save
confidential information to LockBox and get it by PEI modules in S3 phase. confidential information to LockBox and get it by PEI modules in S3 phase.
Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR> Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions are licensed and made available under the terms and conditions
@ -62,9 +62,17 @@ SetLockBoxAttributes (
); );
// //
// With this flag, this LockBox can be restored to this Buffer with RestoreAllLockBoxInPlace() // With this flag, this LockBox can be restored to this Buffer
// with RestoreAllLockBoxInPlace()
// //
#define LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE BIT0 #define LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE BIT0
//
// With this flag, this LockBox can be restored in S3 resume only.
// This LockBox can not be restored after SmmReadyToLock in normal boot
// and after EndOfS3Resume in S3 resume.
// It can not be set together with LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE.
//
#define LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY BIT1
/** /**
This function will update confidential information to lockbox. This function will update confidential information to lockbox.

View File

@ -1,6 +1,6 @@
/** @file /** @file
Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved.<BR> Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions are licensed and made available under the terms and conditions
@ -241,7 +241,7 @@ SetLockBoxAttributes (
// Basic check // Basic check
// //
if ((Guid == NULL) || if ((Guid == NULL) ||
((Attributes & ~LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE) != 0)) { ((Attributes & ~(LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE | LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY)) != 0)) {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }

View File

@ -1,6 +1,6 @@
/** @file /** @file
Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR> Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions are licensed and made available under the terms and conditions
@ -20,6 +20,10 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Library/LockBoxLib.h> #include <Library/LockBoxLib.h>
#include <Library/DebugLib.h> #include <Library/DebugLib.h>
#include <Guid/SmmLockBox.h> #include <Guid/SmmLockBox.h>
#include <Guid/EndOfS3Resume.h>
#include <Protocol/SmmReadyToLock.h>
#include <Protocol/SmmEndOfDxe.h>
#include <Protocol/SmmSxDispatch2.h>
#include "SmmLockBoxLibPrivate.h" #include "SmmLockBoxLibPrivate.h"
@ -31,6 +35,11 @@ SMM_LOCK_BOX_CONTEXT mSmmLockBoxContext;
LIST_ENTRY mLockBoxQueue = INITIALIZE_LIST_HEAD_VARIABLE (mLockBoxQueue); LIST_ENTRY mLockBoxQueue = INITIALIZE_LIST_HEAD_VARIABLE (mLockBoxQueue);
BOOLEAN mSmmConfigurationTableInstalled = FALSE; BOOLEAN mSmmConfigurationTableInstalled = FALSE;
VOID *mSmmLockBoxRegistrationSmmEndOfDxe = NULL;
VOID *mSmmLockBoxRegistrationSmmReadyToLock = NULL;
VOID *mSmmLockBoxRegistrationEndOfS3Resume = NULL;
BOOLEAN mSmmLockBoxSmmReadyToLock = FALSE;
BOOLEAN mSmmLockBoxDuringS3Resume = FALSE;
/** /**
This function return SmmLockBox context from SMST. This function return SmmLockBox context from SMST.
@ -63,6 +72,128 @@ InternalGetSmmLockBoxContext (
return NULL; return NULL;
} }
/**
Notification for SMM ReadyToLock protocol.
@param[in] Protocol Points to the protocol's unique identifier.
@param[in] Interface Points to the interface instance.
@param[in] Handle The handle on which the interface was installed.
@retval EFI_SUCCESS Notification runs successfully.
**/
EFI_STATUS
EFIAPI
SmmLockBoxSmmReadyToLockNotify (
IN CONST EFI_GUID *Protocol,
IN VOID *Interface,
IN EFI_HANDLE Handle
)
{
mSmmLockBoxSmmReadyToLock = TRUE;
return EFI_SUCCESS;
}
/**
Main entry point for an SMM handler dispatch or communicate-based callback.
@param[in] DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().
@param[in] Context 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
SmmLockBoxS3EntryCallBack (
IN EFI_HANDLE DispatchHandle,
IN CONST VOID *Context OPTIONAL,
IN OUT VOID *CommBuffer OPTIONAL,
IN OUT UINTN *CommBufferSize OPTIONAL
)
{
mSmmLockBoxDuringS3Resume = TRUE;
return EFI_SUCCESS;
}
/**
Notification for SMM EndOfDxe protocol.
@param[in] Protocol Points to the protocol's unique identifier.
@param[in] Interface Points to the interface instance.
@param[in] Handle The handle on which the interface was installed.
@retval EFI_SUCCESS Notification runs successfully.
**/
EFI_STATUS
EFIAPI
SmmLockBoxSmmEndOfDxeNotify (
IN CONST EFI_GUID *Protocol,
IN VOID *Interface,
IN EFI_HANDLE Handle
)
{
EFI_STATUS Status;
EFI_SMM_SX_DISPATCH2_PROTOCOL *SxDispatch;
EFI_SMM_SX_REGISTER_CONTEXT EntryRegisterContext;
EFI_HANDLE S3EntryHandle;
//
// Locate SmmSxDispatch2 protocol.
//
Status = gSmst->SmmLocateProtocol (
&gEfiSmmSxDispatch2ProtocolGuid,
NULL,
(VOID **)&SxDispatch
);
if (!EFI_ERROR (Status) && (SxDispatch != NULL)) {
//
// Register a S3 entry callback function to
// determine if it will be during S3 resume.
//
EntryRegisterContext.Type = SxS3;
EntryRegisterContext.Phase = SxEntry;
Status = SxDispatch->Register (
SxDispatch,
SmmLockBoxS3EntryCallBack,
&EntryRegisterContext,
&S3EntryHandle
);
ASSERT_EFI_ERROR (Status);
}
return EFI_SUCCESS;
}
/**
Notification for SMM EndOfS3Resume protocol.
@param[in] Protocol Points to the protocol's unique identifier.
@param[in] Interface Points to the interface instance.
@param[in] Handle The handle on which the interface was installed.
@retval EFI_SUCCESS Notification runs successfully.
**/
EFI_STATUS
EFIAPI
SmmLockBoxEndOfS3ResumeNotify (
IN CONST EFI_GUID *Protocol,
IN VOID *Interface,
IN EFI_HANDLE Handle
)
{
mSmmLockBoxDuringS3Resume = FALSE;
return EFI_SUCCESS;
}
/** /**
Constructor for SmmLockBox library. Constructor for SmmLockBox library.
This is used to set SmmLockBox context, which will be used in PEI phase in S3 boot path later. This is used to set SmmLockBox context, which will be used in PEI phase in S3 boot path later.
@ -85,6 +216,36 @@ SmmLockBoxSmmConstructor (
DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib SmmLockBoxSmmConstructor - Enter\n")); DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib SmmLockBoxSmmConstructor - Enter\n"));
//
// Register SmmReadyToLock notification.
//
Status = gSmst->SmmRegisterProtocolNotify (
&gEfiSmmReadyToLockProtocolGuid,
SmmLockBoxSmmReadyToLockNotify,
&mSmmLockBoxRegistrationSmmReadyToLock
);
ASSERT_EFI_ERROR (Status);
//
// Register SmmEndOfDxe notification.
//
Status = gSmst->SmmRegisterProtocolNotify (
&gEfiSmmEndOfDxeProtocolGuid,
SmmLockBoxSmmEndOfDxeNotify,
&mSmmLockBoxRegistrationSmmEndOfDxe
);
ASSERT_EFI_ERROR (Status);
//
// Register EndOfS3Resume notification.
//
Status = gSmst->SmmRegisterProtocolNotify (
&gEdkiiEndOfS3ResumeGuid,
SmmLockBoxEndOfS3ResumeNotify,
&mSmmLockBoxRegistrationEndOfS3Resume
);
ASSERT_EFI_ERROR (Status);
// //
// Check if gEfiSmmLockBoxCommunicationGuid is installed by someone // Check if gEfiSmmLockBoxCommunicationGuid is installed by someone
// //
@ -158,6 +319,40 @@ SmmLockBoxSmmDestructor (
DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib uninstall SmmLockBoxCommunication configuration table\n")); DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib uninstall SmmLockBoxCommunication configuration table\n"));
} }
if (mSmmLockBoxRegistrationSmmReadyToLock != NULL) {
//
// Unregister SmmReadyToLock notification.
//
Status = gSmst->SmmRegisterProtocolNotify (
&gEfiSmmReadyToLockProtocolGuid,
NULL,
&mSmmLockBoxRegistrationSmmReadyToLock
);
ASSERT_EFI_ERROR (Status);
}
if (mSmmLockBoxRegistrationSmmEndOfDxe != NULL) {
//
// Unregister SmmEndOfDxe notification.
//
Status = gSmst->SmmRegisterProtocolNotify (
&gEfiSmmEndOfDxeProtocolGuid,
NULL,
&mSmmLockBoxRegistrationSmmEndOfDxe
);
ASSERT_EFI_ERROR (Status);
}
if (mSmmLockBoxRegistrationEndOfS3Resume != NULL) {
//
// Unregister EndOfS3Resume notification.
//
Status = gSmst->SmmRegisterProtocolNotify (
&gEdkiiEndOfS3ResumeGuid,
NULL,
&mSmmLockBoxRegistrationEndOfS3Resume
);
ASSERT_EFI_ERROR (Status);
}
return EFI_SUCCESS; return EFI_SUCCESS;
} }
@ -354,11 +549,19 @@ SetLockBoxAttributes (
// Basic check // Basic check
// //
if ((Guid == NULL) || if ((Guid == NULL) ||
((Attributes & ~LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE) != 0)) { ((Attributes & ~(LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE | LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY)) != 0)) {
DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib SetLockBoxAttributes - Exit (%r)\n", EFI_INVALID_PARAMETER)); DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib SetLockBoxAttributes - Exit (%r)\n", EFI_INVALID_PARAMETER));
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
if (((Attributes & LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE) != 0) &&
((Attributes & LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY) != 0)) {
DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib SetLockBoxAttributes - Exit (%r)\n", EFI_INVALID_PARAMETER));
DEBUG ((EFI_D_INFO, " LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE and LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY\n\n"));
DEBUG ((EFI_D_INFO, " can not be set together\n"));
return EFI_INVALID_PARAMETER;
}
// //
// Find LockBox // Find LockBox
// //
@ -368,6 +571,16 @@ SetLockBoxAttributes (
return EFI_NOT_FOUND; return EFI_NOT_FOUND;
} }
if ((((Attributes & LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE) != 0) &&
((LockBox->Attributes & LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY) != 0)) ||
(((LockBox->Attributes & LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE) != 0) &&
((Attributes & LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY) != 0))) {
DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib SetLockBoxAttributes 0x%lx 0x%lx - Exit (%r)\n", LockBox->Attributes, Attributes, EFI_INVALID_PARAMETER));
DEBUG ((EFI_D_INFO, " LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE and LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY\n\n"));
DEBUG ((EFI_D_INFO, " can not be set together\n"));
return EFI_INVALID_PARAMETER;
}
// //
// Update data // Update data
// //
@ -496,6 +709,16 @@ RestoreLockBox (
return EFI_NOT_FOUND; return EFI_NOT_FOUND;
} }
if (((LockBox->Attributes & LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY) != 0) &&
mSmmLockBoxSmmReadyToLock &&
!mSmmLockBoxDuringS3Resume) {
//
// With LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY,
// this LockBox can be restored in S3 resume only.
//
return EFI_ACCESS_DENIED;
}
// //
// Set RestoreBuffer // Set RestoreBuffer
// //

View File

@ -1,7 +1,7 @@
## @file ## @file
# SMM LockBox library instance. # SMM LockBox library instance.
# #
# Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR> # Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
# #
# This program and the accompanying materials # This program and the accompanying materials
# are licensed and made available under the terms and conditions # are licensed and made available under the terms and conditions
@ -44,7 +44,15 @@
BaseLib BaseLib
DebugLib DebugLib
[Protocols]
gEfiSmmReadyToLockProtocolGuid ## NOTIFY
gEfiSmmEndOfDxeProtocolGuid ## NOTIFY
gEfiSmmSxDispatch2ProtocolGuid ## NOTIFY
[Guids] [Guids]
## SOMETIMES_CONSUMES ## UNDEFINED # SmmSystemTable ## SOMETIMES_CONSUMES ## UNDEFINED # SmmSystemTable
## SOMETIMES_PRODUCES ## UNDEFINED # SmmSystemTable ## SOMETIMES_PRODUCES ## UNDEFINED # SmmSystemTable
gEfiSmmLockBoxCommunicationGuid gEfiSmmLockBoxCommunicationGuid
## CONSUMES ## UNDEFINED # Protocol notify
gEdkiiEndOfS3ResumeGuid