From 15c1a9a310645ceb958587fe000d5f60ed3bc4bd Mon Sep 17 00:00:00 2001 From: Gary Lin Date: Wed, 5 Jun 2024 15:31:04 +0800 Subject: Implement the CodeSign EKU check to fulfill the requirements of NIAP OS_PP. Also modify the ModSign EKU check to use VerifyEKUsInPkcs7Signature() to check the signer certificate instead of the certificate directly from the key database. This commit supersedes the PR#232 and PR#661 (Apply the EKU checks) so that author's original codes can be quite independent of other modification. To answer the question in PR#232, author also changed the conditional statement to EFI_Status != EFI_SUCCESS right after VerifyEKUsInPkcs7Signature() in Cryptlib/Pk/CryptPkcs7Verify.c Signed-off-by: Dennis Tseng Signed-off-by: Gary Lin --- Cryptlib/Library/BaseCryptLib.h | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'Cryptlib/Library/BaseCryptLib.h') diff --git a/Cryptlib/Library/BaseCryptLib.h b/Cryptlib/Library/BaseCryptLib.h index 2df8bd2f..ed482d3f 100644 --- a/Cryptlib/Library/BaseCryptLib.h +++ b/Cryptlib/Library/BaseCryptLib.h @@ -2403,6 +2403,46 @@ Pkcs7Verify ( IN UINTN DataLength ); +/** + This function receives a PKCS#7 formatted signature blob, + looks for the EKU SEQUENCE blob, and if found then looks + for all the required EKUs. This function was created so that + the Surface team can cut down on the number of Certificate + Authorities (CA's) by checking EKU's on leaf signers for + a specific product. This prevents one product's certificate + from signing another product's firmware or unlock blobs. + + Note that this function does not validate the certificate chain. + That needs to be done before using this function. + + @param[in] Pkcs7Signature The PKCS#7 signed information content block. An array + containing the content block with both the signature, + the signer's certificate, and any necessary intermediate + certificates. + @param[in] Pkcs7SignatureSize Number of bytes in Pkcs7Signature. + @param[in] RequiredEKUs Array of null-terminated strings listing OIDs of + required EKUs that must be present in the signature. + @param[in] RequiredEKUsSize Number of elements in the RequiredEKUs string array. + @param[in] RequireAllPresent If this is TRUE, then all of the specified EKU's + must be present in the leaf signer. If it is + FALSE, then we will succeed if we find any + of the specified EKU's. + + @retval EFI_SUCCESS The required EKUs were found in the signature. + @retval EFI_INVALID_PARAMETER A parameter was invalid. + @retval EFI_NOT_FOUND One or more EKU's were not found in the signature. + +**/ +EFI_STATUS +EFIAPI +VerifyEKUsInPkcs7Signature ( + IN CONST UINT8 *Pkcs7Signature, + IN CONST UINT32 SignatureSize, + IN CONST CHAR8 *RequiredEKUs[], + IN CONST UINT32 RequiredEKUsSize, + IN BOOLEAN RequireAllPresent + ); + /** Extracts the attached content from a PKCS#7 signed data if existed. The input signed data could be wrapped in a ContentInfo structure. -- cgit v1.2.3 From eb02afc6f822576b73b7added3966ad7e72fd342 Mon Sep 17 00:00:00 2001 From: Dennis Tseng Date: Wed, 5 Jun 2024 22:33:06 +0800 Subject: Optionally enabling codesign EKU check in compiling time. This commit also supersedes PR#232 which was closed on Jul 1, 2021. So that original codesign EKU codes cannot be bothered. To enable the codesign check, ENABLE_CODESIGN_EKU can be set to 1. To disable the codesign check, ENABLE_CODESIGN_EKU can be set to 0 or just omit this flag. For example: make xxxx ENABLE_CODESIGN_EKU=1 xxxx shim.efi Signed-off-by: Dennis Tseng --- Cryptlib/InternalCryptLib.h | 3 ++- Cryptlib/Library/BaseCryptLib.h | 2 ++ Cryptlib/Makefile | 8 +++++++- Cryptlib/Pk/CryptPkcs7Verify.c | 8 ++++++++ 4 files changed, 19 insertions(+), 2 deletions(-) (limited to 'Cryptlib/Library/BaseCryptLib.h') diff --git a/Cryptlib/InternalCryptLib.h b/Cryptlib/InternalCryptLib.h index b713ed1c..0ad2ef70 100644 --- a/Cryptlib/InternalCryptLib.h +++ b/Cryptlib/InternalCryptLib.h @@ -32,6 +32,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #define OBJ_length(o) ((o)->length) #endif +#if defined(ENABLE_CODESIGN_EKU) /** Check input P7Data is a wrapped ContentInfo structure or not. If not construct a new structure to wrap P7Data. @@ -65,4 +66,4 @@ WrapPkcs7Data ( ); #endif - +#endif diff --git a/Cryptlib/Library/BaseCryptLib.h b/Cryptlib/Library/BaseCryptLib.h index ed482d3f..439f0516 100644 --- a/Cryptlib/Library/BaseCryptLib.h +++ b/Cryptlib/Library/BaseCryptLib.h @@ -2403,6 +2403,7 @@ Pkcs7Verify ( IN UINTN DataLength ); +#if defined(ENABLE_CODESIGN_EKU) /** This function receives a PKCS#7 formatted signature blob, looks for the EKU SEQUENCE blob, and if found then looks @@ -2442,6 +2443,7 @@ VerifyEKUsInPkcs7Signature ( IN CONST UINT32 RequiredEKUsSize, IN BOOLEAN RequireAllPresent ); +#endif /** Extracts the attached content from a PKCS#7 signed data if existed. The input signed diff --git a/Cryptlib/Makefile b/Cryptlib/Makefile index 023da637..68a9395e 100644 --- a/Cryptlib/Makefile +++ b/Cryptlib/Makefile @@ -40,6 +40,9 @@ endif ifeq ($(ARCH),arm) DEFINES += -DMDE_CPU_ARM endif +ifeq ($(ENABLE_CODESIGN_EKU),1) +DEFINES += -DENABLE_CODESIGN_EKU +endif LDFLAGS = -nostdlib -znocombreloc @@ -60,7 +63,6 @@ OBJS = Hash/CryptMd4Null.o \ Pk/CryptRsaExtNull.o \ Pk/CryptPkcs7SignNull.o \ Pk/CryptPkcs7Verify.o \ - Pk/CryptPkcs7VerifyEku.o \ Pk/CryptDhNull.o \ Pk/CryptTs.o \ Pk/CryptX509.o \ @@ -71,6 +73,10 @@ OBJS = Hash/CryptMd4Null.o \ SysCall/BaseMemAllocation.o \ SysCall/BaseStrings.o +ifeq ($(ENABLE_CODESIGN_EKU),1) + OBJS += Pk/CryptPkcs7VerifyEku.o +endif + all: $(TARGET) libcryptlib.a: $(OBJS) diff --git a/Cryptlib/Pk/CryptPkcs7Verify.c b/Cryptlib/Pk/CryptPkcs7Verify.c index fd523c59..640b01d0 100644 --- a/Cryptlib/Pk/CryptPkcs7Verify.c +++ b/Cryptlib/Pk/CryptPkcs7Verify.c @@ -29,8 +29,10 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include UINT8 mOidValue[9] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x02 }; +#if defined(ENABLE_CODESIGN_EKU) /* EKU CodeSign */ CHAR8 mOidCodeSign[] = "1.3.6.1.5.5.7.3.3"; +#endif #if 1 #if OPENSSL_VERSION_NUMBER < 0x10100000L @@ -848,8 +850,10 @@ Pkcs7Verify ( CONST UINT8 *Temp; UINTN SignedDataSize; BOOLEAN Wrapped; +#if defined(ENABLE_CODESIGN_EKU) CONST CHAR8 *Ekus[1]; EFI_STATUS EFI_Status; +#endif // // Check input parameters. @@ -863,7 +867,9 @@ Pkcs7Verify ( DataBio = NULL; Cert = NULL; CertStore = NULL; +#if defined(ENABLE_CODESIGN_EKU) Ekus[0] = mOidCodeSign; +#endif // // Register & Initialize necessary digest algorithms for PKCS#7 Handling @@ -963,10 +969,12 @@ Pkcs7Verify ( // X509_STORE_set_purpose (CertStore, X509_PURPOSE_ANY); +#if defined(ENABLE_CODESIGN_EKU) EFI_Status = VerifyEKUsInPkcs7Signature(P7Data, P7Length, Ekus, 1, TRUE); if (EFI_Status != EFI_SUCCESS) { goto _Exit; } +#endif // // Verifies the PKCS#7 signedData structure -- cgit v1.2.3