mirror of https://github.com/acidanthera/audk.git
1. Check input PK/KEK variable data to make sure it is a valid EFI_SIGNATURE_LIST.
Signed-off-by: sfu5 Reviewed-by: gdong1 Reviewed-by : czhan46 git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12765 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
e1982d4ca9
commit
d912bad783
|
@ -48,6 +48,23 @@ VOID *mStorageArea = NULL;
|
|||
//
|
||||
UINT8 *mSerializationRuntimeBuffer = NULL;
|
||||
|
||||
//
|
||||
// Requirement for different signature type which have been defined in UEFI spec.
|
||||
// These data are used to peform SignatureList format check while setting PK/KEK variable.
|
||||
//
|
||||
EFI_SIGNATURE_ITEM mSupportSigItem[] = {
|
||||
//{SigType, SigHeaderSize, SigDataSize }
|
||||
{EFI_CERT_SHA256_GUID, 0, 32 },
|
||||
{EFI_CERT_RSA2048_GUID, 0, 256 },
|
||||
{EFI_CERT_RSA2048_SHA256_GUID, 0, 256 },
|
||||
{EFI_CERT_SHA1_GUID, 0, 20 },
|
||||
{EFI_CERT_RSA2048_SHA1_GUID, 0, 256 },
|
||||
{EFI_CERT_X509_GUID, 0, ((UINT32) ~0)},
|
||||
{EFI_CERT_SHA224_GUID, 0, 28 },
|
||||
{EFI_CERT_SHA384_GUID, 0, 48 },
|
||||
{EFI_CERT_SHA512_GUID, 0, 64 }
|
||||
};
|
||||
|
||||
/**
|
||||
Internal function to delete a Variable given its name and GUID, no authentication
|
||||
required.
|
||||
|
@ -652,6 +669,100 @@ UpdatePlatformMode (
|
|||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Check input data form to make sure it is a valid EFI_SIGNATURE_LIST for PK/KEK variable.
|
||||
|
||||
@param[in] VariableName Name of Variable to be check.
|
||||
@param[in] VendorGuid Variable vendor GUID.
|
||||
@param[in] Data Point to the variable data to be checked.
|
||||
@param[in] DataSize Size of Data.
|
||||
|
||||
@return EFI_INVALID_PARAMETER Invalid signature list format.
|
||||
@return EFI_SUCCESS Passed signature list format check successfully.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
CheckSignatureListFormat(
|
||||
IN CHAR16 *VariableName,
|
||||
IN EFI_GUID *VendorGuid,
|
||||
IN VOID *Data,
|
||||
IN UINTN DataSize
|
||||
)
|
||||
{
|
||||
EFI_SIGNATURE_LIST *SigList;
|
||||
UINTN SigDataSize;
|
||||
UINT32 Index;
|
||||
UINT32 SigCount;
|
||||
BOOLEAN IsPk;
|
||||
|
||||
if (DataSize == 0) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
ASSERT (VariableName != NULL && VendorGuid != NULL && Data != NULL);
|
||||
|
||||
if (CompareGuid (VendorGuid, &gEfiGlobalVariableGuid) && (StrCmp (VariableName, EFI_PLATFORM_KEY_NAME) == 0)){
|
||||
IsPk = TRUE;
|
||||
} else if (CompareGuid (VendorGuid, &gEfiGlobalVariableGuid) && (StrCmp (VariableName, EFI_KEY_EXCHANGE_KEY_NAME) == 0)) {
|
||||
IsPk = FALSE;
|
||||
} else {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
SigCount = 0;
|
||||
SigList = (EFI_SIGNATURE_LIST *) Data;
|
||||
SigDataSize = DataSize;
|
||||
|
||||
//
|
||||
// Walk throuth the input signature list and check the data format.
|
||||
// If any signature is incorrectly formed, the whole check will fail.
|
||||
//
|
||||
while ((SigDataSize > 0) && (SigDataSize >= SigList->SignatureListSize)) {
|
||||
for (Index = 0; Index < (sizeof (mSupportSigItem) / sizeof (EFI_SIGNATURE_ITEM)); Index++ ) {
|
||||
if (CompareGuid (&SigList->SignatureType, &mSupportSigItem[Index].SigType)) {
|
||||
//
|
||||
// The value of SignatureSize should always be 16 (size of SignatureOwner
|
||||
// component) add the data length according to signature type.
|
||||
//
|
||||
if (mSupportSigItem[Index].SigDataSize != ((UINT32) ~0) &&
|
||||
(SigList->SignatureSize - sizeof (EFI_GUID)) != mSupportSigItem[Index].SigDataSize) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
if (mSupportSigItem[Index].SigHeaderSize != ((UINTN) ~0) &&
|
||||
SigList->SignatureHeaderSize != mSupportSigItem[Index].SigHeaderSize) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (Index == (sizeof (mSupportSigItem) / sizeof (EFI_SIGNATURE_ITEM))) {
|
||||
//
|
||||
// Undefined signature type.
|
||||
//
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if ((SigList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - SigList->SignatureHeaderSize) % SigList->SignatureSize != 0) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
SigCount += (SigList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - SigList->SignatureHeaderSize) / SigList->SignatureSize;
|
||||
|
||||
SigDataSize -= SigList->SignatureListSize;
|
||||
SigList = (EFI_SIGNATURE_LIST *) ((UINT8 *) SigList + SigList->SignatureListSize);
|
||||
}
|
||||
|
||||
if (((UINTN) SigList - (UINTN) Data) != DataSize) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (IsPk && SigCount > 1) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Process variable with platform key for verification.
|
||||
|
||||
|
@ -757,6 +868,15 @@ ProcessVarWithPk (
|
|||
OldPkData = (EFI_SIGNATURE_DATA *) ((UINT8 *) OldPkList + sizeof (EFI_SIGNATURE_LIST) + OldPkList->SignatureHeaderSize);
|
||||
Status = VerifyCounterBasedPayload (Data, DataSize, OldPkData->SignatureData);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
Status = CheckSignatureListFormat(
|
||||
VariableName,
|
||||
VendorGuid,
|
||||
(UINT8*)Data + AUTHINFO_SIZE,
|
||||
DataSize - AUTHINFO_SIZE);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = UpdateVariable (
|
||||
VariableName,
|
||||
VendorGuid,
|
||||
|
@ -809,6 +929,11 @@ ProcessVarWithPk (
|
|||
PayloadSize = DataSize;
|
||||
}
|
||||
|
||||
Status = CheckSignatureListFormat(VariableName, VendorGuid, Payload, PayloadSize);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = UpdateVariable (
|
||||
VariableName,
|
||||
VendorGuid,
|
||||
|
@ -1496,6 +1621,11 @@ Exit:
|
|||
return EFI_SECURITY_VIOLATION;
|
||||
}
|
||||
|
||||
Status = CheckSignatureListFormat(VariableName, VendorGuid, PayloadPtr, PayloadSize);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
if ((PayloadSize == 0) && (VarDel != NULL)) {
|
||||
*VarDel = TRUE;
|
||||
}
|
||||
|
|
|
@ -49,6 +49,17 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||
///
|
||||
#define SIGSUPPORT_NUM 2
|
||||
|
||||
///
|
||||
/// Struct to record signature requirement defined by UEFI spec.
|
||||
/// For SigHeaderSize and SigDataSize, ((UINT32) ~0) means NO exact length requirement for this field.
|
||||
///
|
||||
typedef struct {
|
||||
EFI_GUID SigType;
|
||||
// Expected SignatureHeader size in Bytes.
|
||||
UINT32 SigHeaderSize;
|
||||
// Expected SignatureData size in Bytes.
|
||||
UINT32 SigDataSize;
|
||||
} EFI_SIGNATURE_ITEM;
|
||||
|
||||
/**
|
||||
Process variable with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS/EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS set.
|
||||
|
@ -116,6 +127,26 @@ CryptLibraryInitialize (
|
|||
VOID
|
||||
);
|
||||
|
||||
/**
|
||||
Check input data form to make sure it is a valid EFI_SIGNATURE_LIST for PK/KEK variable.
|
||||
|
||||
@param[in] VariableName Name of Variable to be check.
|
||||
@param[in] VendorGuid Variable vendor GUID.
|
||||
@param[in] Data Point to the variable data to be checked.
|
||||
@param[in] DataSize Size of Data.
|
||||
|
||||
@return EFI_INVALID_PARAMETER Invalid signature list format.
|
||||
@return EFI_SUCCESS Passed signature list format check successfully.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
CheckSignatureListFormat(
|
||||
IN CHAR16 *VariableName,
|
||||
IN EFI_GUID *VendorGuid,
|
||||
IN VOID *Data,
|
||||
IN UINTN DataSize
|
||||
);
|
||||
|
||||
/**
|
||||
Process variable with platform key for verification.
|
||||
|
||||
|
|
Loading…
Reference in New Issue