diff --git a/MdeModulePkg/Include/Library/LockBoxLib.h b/MdeModulePkg/Include/Library/LockBoxLib.h index db7fd05def..80beb4d0f8 100644 --- a/MdeModulePkg/Include/Library/LockBoxLib.h +++ b/MdeModulePkg/Include/Library/LockBoxLib.h @@ -2,7 +2,7 @@ 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. -Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.
+Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.
This program and the accompanying materials 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. diff --git a/MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxDxeLib.c b/MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxDxeLib.c index b75f81e69e..9b6f0bedbd 100644 --- a/MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxDxeLib.c +++ b/MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxDxeLib.c @@ -1,6 +1,6 @@ /** @file -Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved.
+Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions @@ -241,7 +241,7 @@ SetLockBoxAttributes ( // Basic check // 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; } diff --git a/MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxSmmLib.c b/MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxSmmLib.c index 4960df7555..32a57b6a76 100644 --- a/MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxSmmLib.c +++ b/MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxSmmLib.c @@ -1,6 +1,6 @@ /** @file -Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.
+Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.
This program and the accompanying materials 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 #include #include +#include +#include +#include +#include #include "SmmLockBoxLibPrivate.h" @@ -31,6 +35,11 @@ SMM_LOCK_BOX_CONTEXT mSmmLockBoxContext; LIST_ENTRY mLockBoxQueue = INITIALIZE_LIST_HEAD_VARIABLE (mLockBoxQueue); 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. @@ -63,6 +72,128 @@ InternalGetSmmLockBoxContext ( 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. 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")); + // + // 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 // @@ -158,6 +319,40 @@ SmmLockBoxSmmDestructor ( 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; } @@ -354,11 +549,19 @@ SetLockBoxAttributes ( // Basic check // 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)); 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 // @@ -368,6 +571,16 @@ SetLockBoxAttributes ( 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 // @@ -496,6 +709,16 @@ RestoreLockBox ( 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 // diff --git a/MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxSmmLib.inf b/MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxSmmLib.inf index eb7ba0bb2e..426af4cccf 100644 --- a/MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxSmmLib.inf +++ b/MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxSmmLib.inf @@ -1,7 +1,7 @@ ## @file # SMM LockBox library instance. # -# Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.
+# Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.
# # This program and the accompanying materials # are licensed and made available under the terms and conditions @@ -44,7 +44,15 @@ BaseLib DebugLib +[Protocols] + gEfiSmmReadyToLockProtocolGuid ## NOTIFY + gEfiSmmEndOfDxeProtocolGuid ## NOTIFY + gEfiSmmSxDispatch2ProtocolGuid ## NOTIFY + [Guids] ## SOMETIMES_CONSUMES ## UNDEFINED # SmmSystemTable ## SOMETIMES_PRODUCES ## UNDEFINED # SmmSystemTable gEfiSmmLockBoxCommunicationGuid + ## CONSUMES ## UNDEFINED # Protocol notify + gEdkiiEndOfS3ResumeGuid +