edk2/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/Pkcs7EkuTests.c
Longhaox Lee 51e2c18a53 CryptoPkg/BaseCryptLibUnitTest: Separate MbedTls UnitTest Library.
Separate Unit test functions for MbedTls.

BaseCryptLibMbedTls does not support all Crypto services
So deprecate below function for MbedTls Unit test:

TestVerifyEKUsWith3CertsInSignature()
TestVerifyEKUsWith2CertsInSignature()
TestNoEKUsInSignature()
TestVerifyRsaCertPkcs1SignVerify
TestVerifyPkcs7SignVerifyNonSelfIssued()
TestVerifyDhGenerateKey()
Pkcs1v2Decrypt
Pkcs1v2EncryptDecrypt
RsaOaepEncrypt (Interface)
RsaOaepEncrypt (NoSeed)
RsaOaepEncrypt (Seeded)
RsaOaepDecrypt
RsaOaepEncryptDecrypt
RsaOaepEncryptPkcs1v2Decrypt
Pkcs1v2EncryptRsaOaepDecrypt
RsaOaepEncrypt (MdDefaultMgf1Default)
RsaOaepDecrypt (MdDefaultMgf1Default)
RsaOaepEncryptDecrypt (MdDefaultMgf1Default)
RsaOaepEncrypt (MdSha1Bgf1Sha1
RsaOaepDecrypt (MdSha1Bgf1Sha1)
RsaOaepEncryptDecrypt (MdSha1Bgf1Sha1)
RsaOaepEncrypt (MdSha256Bgf1Sha256)
RsaOaepDecrypt (MdSha256Bgf1Sha256)
RsaOaepEncryptDecrypt (MdSha256Bgf1Sha256)
TestVerifyBn()
TestVerifyEcKey()
TestPkcs7Attached()
TestPkcs7Detached()
TestVerifyPkcs7ContentData()

REF: https://github.com/tianocore/edk2/issues/11605
Signed-off-by: Longhaox Lee <longhaox.lee@intel.com>
2025-11-24 13:10:50 +00:00

558 lines
19 KiB
C

/** @file -- Pkcs7EkuVerify.c
* Copyright (c) Microsoft Corporation.
* SPDX-License-Identifier: BSD-2-Clause-Patent
This is an test code which verifies specified
Enhanced Key Usages (EKU)'s are present in the leaf signer
of a PKCS7 formatted signature.
A typical signing certificate chain looks like this: (Could be RSA or ECC).
------------------------------------------
| | // Root of trust. ECDSA P521 curve
| TestEKUParsingRoot | // SHA 256 Key Usage: CERT_DIGITAL_SIGNATURE_KEY_USAGE
| | // CERT_KEY_CERT_SIGN_KEY_USAGE | CERT_CRL_SIGN_KEY_USAGE
------------------------------------------
^
|
------------------------------------------
| | // Policy CA. Issues subordinate CAs. ECC P384 curve.
| TestEKUParsingPolicyCA | // SHA 256 Key Usage:
| | // CERT_KEY_CERT_SIGN_KEY_USAGE | CERT_CRL_SIGN_KEY_USAGE
------------------------------------------
^
|
------------------------------------------
| | // Issues end-entity (leaf) signers. ECC P256 curve.
| TestEKUParsingIssuingCA | // SHA 256 Key Usage: CERT_DIGITAL_SIGNATURE_KEY_USAGE
| | // Enhanced Key Usage:
------------------------------------------ // 1.3.6.1.4.1.311.76.9.21.1 (Surface firmware signing)
^
|
--------------------------------------
/ TestEKUParsingLeafSigner && / // Leaf signer, ECC P256 curve.
/ TestEKUParsingLeafSignerPid12345 / // SHA 256 Key Usage: CERT_DIGITAL_SIGNATURE_KEY_USAGE
/ / // Enhanced Key usages:
-------------------------------------- // 1.3.6.1.4.1.311.76.9.21.1 (Surface firmware signing)
// 1.3.6.1.4.1.311.76.9.21.1.N, N == Product ID.
**/
#include "TestBaseCryptLib.h"
#include "Pkcs7EkuTestSignatures.h"
EFI_STATUS
EFIAPI
VerifyEKUsInPkcs7Signature (
IN CONST UINT8 *Pkcs7Signature,
IN CONST UINT32 SignatureSize,
IN CONST CHAR8 *RequiredEKUs[],
IN CONST UINT32 RequiredEKUsSize,
IN BOOLEAN RequireAllPresent
);
/// ================================================================================================
/// ================================================================================================
///
/// TEST CASES
///
/// ================================================================================================
/// ================================================================================================
CONST CHAR8 FIRMWARE_SIGNER_EKU[] = "1.3.6.1.4.1.311.76.9.21.1";
/**
TestVerifyEKUsInSignature()
Verify that "1.3.6.1.4.1.311.76.9.21.1" (Firmware signature) is in the
leaf signer certificate.
@param[in] Framework - Unit-test framework handle.
@param[in] Context - Optional context pointer for this test.
@retval UNIT_TEST_PASSED - The required EKUs were found in the signature.
@retval UNIT_TEST_ERROR_TEST_FAILED - Something failed, check the debug output.
**/
static
UNIT_TEST_STATUS
EFIAPI
TestVerifyEKUsInSignature (
IN UNIT_TEST_CONTEXT Context
)
{
EFI_STATUS Status = EFI_SUCCESS;
CONST CHAR8 *RequiredEKUs[] = { FIRMWARE_SIGNER_EKU };
Status = VerifyEKUsInPkcs7Signature (
ProductionECCSignature,
ARRAY_SIZE (ProductionECCSignature),
(CONST CHAR8 **)RequiredEKUs,
ARRAY_SIZE (RequiredEKUs),
TRUE
);
UT_ASSERT_STATUS_EQUAL (Status, EFI_SUCCESS);
return UNIT_TEST_PASSED;
}// TestVerifyEKUsInSignature()
/**
TestVerifyEKUsWith3CertsInSignature()
This PKCS7 signature has 3 certificates in it. (Policy CA, Issuing CA
and leaf signer). It has one firmware signing EKU in it.
"1.3.6.1.4.1.311.76.9.21.1"
@param[in] Framework - Unit-test framework handle.
@param[in] Context - Optional context pointer for this test.
@retval UNIT_TEST_PASSED - The required EKUs were found in the signature.
@retval UNIT_TEST_ERROR_TEST_FAILED - Something failed, check the debug output.
**/
static
UNIT_TEST_STATUS
EFIAPI
TestVerifyEKUsWith3CertsInSignature (
IN UNIT_TEST_CONTEXT Context
)
{
EFI_STATUS Status = EFI_SUCCESS;
CONST CHAR8 *RequiredEKUs[] = { FIRMWARE_SIGNER_EKU };
Status = VerifyEKUsInPkcs7Signature (
TestSignEKUsWith3CertsInSignature,
ARRAY_SIZE (TestSignEKUsWith3CertsInSignature),
(CONST CHAR8 **)RequiredEKUs,
ARRAY_SIZE (RequiredEKUs),
TRUE
);
UT_ASSERT_STATUS_EQUAL (Status, EFI_SUCCESS);
return UNIT_TEST_PASSED;
}// TestVerifyEKUsWith3CertsInSignature()
/**
TestVerifyEKUsWith2CertsInSignature()
This PKCS7 signature has 2 certificates in it. (Issuing CA and leaf signer).
It has one firmware signing EKU in it. "1.3.6.1.4.1.311.76.9.21.1"
@param[in] Framework - Unit-test framework handle.
@param[in] Context - Optional context pointer for this test.
@retval UNIT_TEST_PASSED - The required EKUs were found in the signature.
@retval UNIT_TEST_ERROR_TEST_FAILED - Something failed, check the debug output.
**/
static
UNIT_TEST_STATUS
EFIAPI
TestVerifyEKUsWith2CertsInSignature (
IN UNIT_TEST_CONTEXT Context
)
{
EFI_STATUS Status = EFI_SUCCESS;
CONST CHAR8 *RequiredEKUs[] = { FIRMWARE_SIGNER_EKU };
Status = VerifyEKUsInPkcs7Signature (
TestSignEKUsWith2CertsInSignature,
ARRAY_SIZE (TestSignEKUsWith2CertsInSignature),
(CONST CHAR8 **)RequiredEKUs,
ARRAY_SIZE (RequiredEKUs),
TRUE
);
UT_ASSERT_STATUS_EQUAL (Status, EFI_SUCCESS);
return UNIT_TEST_PASSED;
}// TestVerifyEKUsWith2CertsInSignature()
/**
TestVerifyEKUsWith1CertInSignature()
This PKCS7 signature only has the leaf signer in it.
It has one firmware signing EKU in it. "1.3.6.1.4.1.311.76.9.21.1"
@param[in] Framework - Unit-test framework handle.
@param[in] Context - Optional context pointer for this test.
@retval UNIT_TEST_PASSED - The required EKUs were found in the signature.
@retval UNIT_TEST_ERROR_TEST_FAILED - Something failed, check the debug output.
**/
static
UNIT_TEST_STATUS
EFIAPI
TestVerifyEKUsWith1CertInSignature (
IN UNIT_TEST_CONTEXT Context
)
{
EFI_STATUS Status = EFI_SUCCESS;
CONST CHAR8 *RequiredEKUs[] = { FIRMWARE_SIGNER_EKU };
Status = VerifyEKUsInPkcs7Signature (
TestSignEKUsWith1CertInSignature,
ARRAY_SIZE (TestSignEKUsWith1CertInSignature),
(CONST CHAR8 **)RequiredEKUs,
ARRAY_SIZE (RequiredEKUs),
TRUE
);
UT_ASSERT_STATUS_EQUAL (Status, EFI_SUCCESS);
return UNIT_TEST_PASSED;
}// TestVerifyEKUsWith1CertInSignature()
/**
TestVerifyEKUsWithMultipleEKUsInCert()
This signature has two EKU's in it:
"1.3.6.1.4.1.311.76.9.21.1"
"1.3.6.1.4.1.311.76.9.21.2"
We verify that both EKU's were present in the leaf signer.
@param[in] Framework - Unit-test framework handle.
@param[in] Context - Optional context pointer for this test.
@retval UNIT_TEST_PASSED - The required EKUs were found in the signature.
@retval UNIT_TEST_ERROR_TEST_FAILED - Something failed, check the debug output.
**/
static
UNIT_TEST_STATUS
EFIAPI
TestVerifyEKUsWithMultipleEKUsInCert (
IN UNIT_TEST_CONTEXT Context
)
{
EFI_STATUS Status = EFI_SUCCESS;
CONST CHAR8 *RequiredEKUs[] = {
"1.3.6.1.4.1.311.76.9.21.1",
"1.3.6.1.4.1.311.76.9.21.1.2"
};
Status = VerifyEKUsInPkcs7Signature (
TestSignedWithMultipleEKUsInCert,
ARRAY_SIZE (TestSignedWithMultipleEKUsInCert),
(CONST CHAR8 **)RequiredEKUs,
ARRAY_SIZE (RequiredEKUs),
TRUE
);
UT_ASSERT_STATUS_EQUAL (Status, EFI_SUCCESS);
return UNIT_TEST_PASSED;
}// TestVerifyEKUsWithMultipleEKUsInCert()
/**
TestEkusNotPresentInSignature()
This test verifies that if we send an EKU that is not in the signature,
that we get back an error.
@param[in] Framework - Unit-test framework handle.
@param[in] Context - Optional context pointer for this test.
@retval UNIT_TEST_PASSED - The required EKUs were found in the signature.
@retval UNIT_TEST_ERROR_TEST_FAILED - Something failed, check the debug output.
**/
static
UNIT_TEST_STATUS
EFIAPI
TestEkusNotPresentInSignature (
IN UNIT_TEST_CONTEXT Context
)
{
EFI_STATUS Status = EFI_SUCCESS;
//
// This EKU is not in the signature.
//
CONST CHAR8 *RequiredEKUs[] = { "1.3.6.1.4.1.311.76.9.21.3" };
Status = VerifyEKUsInPkcs7Signature (
TestSignedWithMultipleEKUsInCert,
ARRAY_SIZE (TestSignedWithMultipleEKUsInCert),
(CONST CHAR8 **)RequiredEKUs,
ARRAY_SIZE (RequiredEKUs),
TRUE
);
UT_ASSERT_NOT_EQUAL (Status, EFI_SUCCESS);
return UNIT_TEST_PASSED;
}// TestEkusNotPresentInSignature()
/**
TestEkusNotPresentInSignature()
This test signature has two EKU's in it: (Product ID is 10001)
"1.3.6.1.4.1.311.76.9.21.1"
"1.3.6.1.4.1.311.76.9.21.1.10001"
@param[in] Framework - Unit-test framework handle.
@param[in] Context - Optional context pointer for this test.
@retval UNIT_TEST_PASSED - The required EKUs were found in the signature.
@retval UNIT_TEST_ERROR_TEST_FAILED - Something failed, check the debug output.
**/
static
UNIT_TEST_STATUS
EFIAPI
TestProductId10001PresentInSignature (
IN UNIT_TEST_CONTEXT Context
)
{
EFI_STATUS Status = EFI_SUCCESS;
//
// These EKU's are present in the leaf signer certificate.
//
CONST CHAR8 *RequiredEKUs[] = {
"1.3.6.1.4.1.311.76.9.21.1",
"1.3.6.1.4.1.311.76.9.21.1.10001"
};
Status = VerifyEKUsInPkcs7Signature (
TestSignedWithProductId10001,
ARRAY_SIZE (TestSignedWithProductId10001),
(CONST CHAR8 **)RequiredEKUs,
ARRAY_SIZE (RequiredEKUs),
TRUE
);
UT_ASSERT_STATUS_EQUAL (Status, EFI_SUCCESS);
return UNIT_TEST_PASSED;
}// TestProductId10001PresentInSignature()
/**
TestOnlyOneEkuInListRequired()
This test will check the BOOLEAN RequireAllPresent parameter in the
call to VerifyEKUsInPkcs7Signature() behaves properly. The signature
has two EKU's in it:
"1.3.6.1.4.1.311.76.9.21.1"
"1.3.6.1.4.1.311.76.9.21.1.10001"
but we only pass in one of them, and set RequireAllPresent to FALSE.
@param[in] Framework - Unit-test framework handle.
@param[in] Context - Optional context pointer for this test.
@retval UNIT_TEST_PASSED - The required EKUs were found in the signature.
@retval UNIT_TEST_ERROR_TEST_FAILED - Something failed, check the debug output.
**/
static
UNIT_TEST_STATUS
EFIAPI
TestOnlyOneEkuInListRequired (
IN UNIT_TEST_CONTEXT Context
)
{
EFI_STATUS Status = EFI_SUCCESS;
//
// This will test the flag that specifies it is OK to succeed if
// any one of the EKU's passed in is found.
//
CONST CHAR8 *RequiredEKUs[] = { "1.3.6.1.4.1.311.76.9.21.1.10001" };
Status = VerifyEKUsInPkcs7Signature (
TestSignedWithProductId10001,
ARRAY_SIZE (TestSignedWithProductId10001),
(CONST CHAR8 **)RequiredEKUs,
ARRAY_SIZE (RequiredEKUs),
FALSE
);
UT_ASSERT_STATUS_EQUAL (Status, EFI_SUCCESS);
return UNIT_TEST_PASSED;
}// TestOnlyOneEkuInListRequired()
/**
TestNoEKUsInSignature()
This test uses a signature that was signed with a certificate that does
not contain any EKUs.
@param[in] Framework - Unit-test framework handle.
@param[in] Context - Optional context pointer for this test.
@retval UNIT_TEST_PASSED - The required EKUs were found in the signature.
@retval UNIT_TEST_ERROR_TEST_FAILED - Something failed, check the debug output.
**/
static
UNIT_TEST_STATUS
EFIAPI
TestNoEKUsInSignature (
IN UNIT_TEST_CONTEXT Context
)
{
EFI_STATUS Status = EFI_SUCCESS;
//
// This EKU is not in the certificate, so it should fail.
//
CONST CHAR8 *RequiredEKUs[] = { "1.3.6.1.4.1.311.76.9.21.1" };
Status = VerifyEKUsInPkcs7Signature (
TestSignatureWithNoEKUsPresent,
ARRAY_SIZE (TestSignatureWithNoEKUsPresent),
(CONST CHAR8 **)RequiredEKUs,
ARRAY_SIZE (RequiredEKUs),
TRUE
);
UT_ASSERT_NOT_EQUAL (Status, EFI_SUCCESS);
return UNIT_TEST_PASSED;
}// TestNoEKUsInSignature()
/**
TestInvalidParameters()
Passes the API invalid parameters, and ensures that it does not succeed.
@param[in] Framework - Unit-test framework handle.
@param[in] Context - Optional context pointer for this test.
@retval UNIT_TEST_PASSED - The required EKUs were found in the signature.
@retval UNIT_TEST_ERROR_TEST_FAILED - Something failed, check the debug output.
**/
static
UNIT_TEST_STATUS
EFIAPI
TestInvalidParameters (
IN UNIT_TEST_CONTEXT Context
)
{
EFI_STATUS Status = EFI_SUCCESS;
CONST CHAR8 *RequiredEKUs[] = { "1.3.6.1.4.1.311.76.9.21.1" };
//
// Check bad signature.
//
Status = VerifyEKUsInPkcs7Signature (
NULL,
0,
(CONST CHAR8 **)RequiredEKUs,
ARRAY_SIZE (RequiredEKUs),
TRUE
);
UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER);
//
// Check invalid EKU's
//
Status = VerifyEKUsInPkcs7Signature (
TestSignatureWithNoEKUsPresent,
ARRAY_SIZE (TestSignatureWithNoEKUsPresent),
(CONST CHAR8 **)NULL,
0,
TRUE
);
UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER);
return UNIT_TEST_PASSED;
}// TestInvalidParameters()
/**
TestEKUSubStringFails()
Pass the API a sub set and super set of an EKU and ensure that they
don't pass.
@param[in] Framework - Unit-test framework handle.
@param[in] Context - Optional context pointer for this test.
@retval UNIT_TEST_PASSED - The required EKUs were found in the signature.
@retval UNIT_TEST_ERROR_TEST_FAILED - Something failed, check the debug output.
**/
static
UNIT_TEST_STATUS
EFIAPI
TestEKUSubsetSupersetFails (
IN UNIT_TEST_CONTEXT Context
)
{
EFI_STATUS Status = EFI_SUCCESS;
//
// This signature has an EKU of:
// "1.3.6.1.4.1.311.76.9.21.1.10001"
// so ensure that
// "1.3.6.1.4.1.311.76.9.21"
// does not pass.
//
CONST CHAR8 *RequiredEKUs1[] = { "1.3.6.1.4.1.311.76.9.21" };
Status = VerifyEKUsInPkcs7Signature (
TestSignedWithProductId10001,
ARRAY_SIZE (TestSignedWithProductId10001),
(CONST CHAR8 **)RequiredEKUs1,
ARRAY_SIZE (RequiredEKUs1),
TRUE
);
UT_ASSERT_NOT_EQUAL (Status, EFI_SUCCESS);
//
// This signature has an EKU of:
// "1.3.6.1.4.1.311.76.9.21.1.10001"
// so ensure that a super set
// "1.3.6.1.4.1.311.76.9.21.1.10001.1"
// does not pass.
//
CONST CHAR8 *RequiredEKUs2[] = { "1.3.6.1.4.1.311.76.9.21.1.10001.1" };
Status = VerifyEKUsInPkcs7Signature (
TestSignedWithProductId10001,
ARRAY_SIZE (TestSignedWithProductId10001),
(CONST CHAR8 **)RequiredEKUs2,
ARRAY_SIZE (RequiredEKUs2),
TRUE
);
UT_ASSERT_NOT_EQUAL (Status, EFI_SUCCESS);
return UNIT_TEST_PASSED;
}// TestEKUSubsetSupersetFails()
TEST_DESC mPkcs7EkuTest[] = {
//
// -----Description--------------------------------Class----------------------------Function------------------------------Pre---Post--Context
//
{ "TestVerifyEKUsInSignature()", "CryptoPkg.BaseCryptLib.Eku", TestVerifyEKUsInSignature, NULL, NULL, NULL },
{ "TestVerifyEKUsWith3CertsInSignature()", "CryptoPkg.BaseCryptLib.Eku", TestVerifyEKUsWith3CertsInSignature, NULL, NULL, NULL },
{ "TestVerifyEKUsWith2CertsInSignature()", "CryptoPkg.BaseCryptLib.Eku", TestVerifyEKUsWith2CertsInSignature, NULL, NULL, NULL },
{ "TestVerifyEKUsWith1CertInSignature()", "CryptoPkg.BaseCryptLib.Eku", TestVerifyEKUsWith1CertInSignature, NULL, NULL, NULL },
{ "TestVerifyEKUsWithMultipleEKUsInCert()", "CryptoPkg.BaseCryptLib.Eku", TestVerifyEKUsWithMultipleEKUsInCert, NULL, NULL, NULL },
{ "TestEkusNotPresentInSignature()", "CryptoPkg.BaseCryptLib.Eku", TestEkusNotPresentInSignature, NULL, NULL, NULL },
{ "TestProductId10001PresentInSignature()", "CryptoPkg.BaseCryptLib.Eku", TestProductId10001PresentInSignature, NULL, NULL, NULL },
{ "TestOnlyOneEkuInListRequired()", "CryptoPkg.BaseCryptLib.Eku", TestOnlyOneEkuInListRequired, NULL, NULL, NULL },
{ "TestNoEKUsInSignature()", "CryptoPkg.BaseCryptLib.Eku", TestNoEKUsInSignature, NULL, NULL, NULL },
{ "TestInvalidParameters()", "CryptoPkg.BaseCryptLib.Eku", TestInvalidParameters, NULL, NULL, NULL },
{ "TestEKUSubsetSupersetFails()", "CryptoPkg.BaseCryptLib.Eku", TestEKUSubsetSupersetFails, NULL, NULL, NULL },
};
UINTN mPkcs7EkuTestNum = ARRAY_SIZE (mPkcs7EkuTest);
TEST_DESC mPkcs7EkuTestMbedTls[] = {
//
// -----Description--------------------------------Class----------------------------Function------------------------------Pre---Post--Context
//
{ "TestVerifyEKUsWith1CertInSignature()", "CryptoPkg.BaseCryptLib.Eku", TestVerifyEKUsWith1CertInSignature, NULL, NULL, NULL },
{ "TestVerifyEKUsWithMultipleEKUsInCert()", "CryptoPkg.BaseCryptLib.Eku", TestVerifyEKUsWithMultipleEKUsInCert, NULL, NULL, NULL },
{ "TestEkusNotPresentInSignature()", "CryptoPkg.BaseCryptLib.Eku", TestEkusNotPresentInSignature, NULL, NULL, NULL },
{ "TestProductId10001PresentInSignature()", "CryptoPkg.BaseCryptLib.Eku", TestProductId10001PresentInSignature, NULL, NULL, NULL },
{ "TestOnlyOneEkuInListRequired()", "CryptoPkg.BaseCryptLib.Eku", TestOnlyOneEkuInListRequired, NULL, NULL, NULL },
{ "TestInvalidParameters()", "CryptoPkg.BaseCryptLib.Eku", TestInvalidParameters, NULL, NULL, NULL },
{ "TestEKUSubsetSupersetFails()", "CryptoPkg.BaseCryptLib.Eku", TestEKUSubsetSupersetFails, NULL, NULL, NULL },
};
UINTN mPkcs7EkuTestMbedTlsNum = ARRAY_SIZE (mPkcs7EkuTestMbedTls);