/** @file | |
EFI PEI Core Security services | |
Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR> | |
SPDX-License-Identifier: BSD-2-Clause-Patent | |
**/ | |
#include "PeiMain.h" | |
EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList = { | |
EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, | |
&gEfiPeiSecurity2PpiGuid, | |
SecurityPpiNotifyCallback | |
}; | |
/** | |
Initialize the security services. | |
@param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. | |
@param OldCoreData Pointer to the old core data. | |
NULL if being run in non-permanent memory mode. | |
**/ | |
VOID | |
InitializeSecurityServices ( | |
IN EFI_PEI_SERVICES **PeiServices, | |
IN PEI_CORE_INSTANCE *OldCoreData | |
) | |
{ | |
if (OldCoreData == NULL) { | |
PeiServicesNotifyPpi (&mNotifyList); | |
} | |
return; | |
} | |
/** | |
Provide a callback for when the security PPI is installed. | |
This routine will cache installed security PPI into PeiCore's private data. | |
@param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. | |
@param NotifyDescriptor The descriptor for the notification event. | |
@param Ppi Pointer to the PPI in question. | |
@return Always success | |
**/ | |
EFI_STATUS | |
EFIAPI | |
SecurityPpiNotifyCallback ( | |
IN EFI_PEI_SERVICES **PeiServices, | |
IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, | |
IN VOID *Ppi | |
) | |
{ | |
PEI_CORE_INSTANCE *PrivateData; | |
// | |
// Get PEI Core private data | |
// | |
PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices); | |
// | |
// If there isn't a security PPI installed, use the one from notification | |
// | |
if (PrivateData->PrivateSecurityPpi == NULL) { | |
PrivateData->PrivateSecurityPpi = (EFI_PEI_SECURITY2_PPI *)Ppi; | |
} | |
return EFI_SUCCESS; | |
} | |
/** | |
Provide a callout to the security verification service. | |
@param PrivateData PeiCore's private data structure | |
@param VolumeHandle Handle of FV | |
@param FileHandle Handle of PEIM's FFS | |
@param AuthenticationStatus Authentication status | |
@retval EFI_SUCCESS Image is OK | |
@retval EFI_SECURITY_VIOLATION Image is illegal | |
@retval EFI_NOT_FOUND If security PPI is not installed. | |
**/ | |
EFI_STATUS | |
VerifyPeim ( | |
IN PEI_CORE_INSTANCE *PrivateData, | |
IN EFI_PEI_FV_HANDLE VolumeHandle, | |
IN EFI_PEI_FILE_HANDLE FileHandle, | |
IN UINT32 AuthenticationStatus | |
) | |
{ | |
EFI_STATUS Status; | |
BOOLEAN DeferExecution; | |
Status = EFI_NOT_FOUND; | |
if (PrivateData->PrivateSecurityPpi == NULL) { | |
// | |
// Check AuthenticationStatus first. | |
// | |
if ((AuthenticationStatus & EFI_AUTH_STATUS_IMAGE_SIGNED) != 0) { | |
if ((AuthenticationStatus & (EFI_AUTH_STATUS_TEST_FAILED | EFI_AUTH_STATUS_NOT_TESTED)) != 0) { | |
Status = EFI_SECURITY_VIOLATION; | |
} | |
} | |
} else { | |
// | |
// Check to see if the image is OK | |
// | |
Status = PrivateData->PrivateSecurityPpi->AuthenticationState ( | |
(CONST EFI_PEI_SERVICES **)&PrivateData->Ps, | |
PrivateData->PrivateSecurityPpi, | |
AuthenticationStatus, | |
VolumeHandle, | |
FileHandle, | |
&DeferExecution | |
); | |
if (DeferExecution) { | |
Status = EFI_SECURITY_VIOLATION; | |
} | |
} | |
return Status; | |
} | |
/** | |
Verify a Firmware volume. | |
@param CurrentFvAddress Pointer to the current Firmware Volume under consideration | |
@retval EFI_SUCCESS Firmware Volume is legal | |
**/ | |
EFI_STATUS | |
VerifyFv ( | |
IN EFI_FIRMWARE_VOLUME_HEADER *CurrentFvAddress | |
) | |
{ | |
// | |
// Right now just pass the test. Future can authenticate and/or check the | |
// FV-header or other metric for goodness of binary. | |
// | |
return EFI_SUCCESS; | |
} |