Skip to content

DxeImageVerification Support - #260

Draft
Flickdm wants to merge 19 commits into
microsoft:mainfrom
Flickdm:feat/dxe-image-verification-support
Draft

DxeImageVerification Support#260
Flickdm wants to merge 19 commits into
microsoft:mainfrom
Flickdm:feat/dxe-image-verification-support

Conversation

@Flickdm

@Flickdm Flickdm commented Jun 10, 2026

Copy link
Copy Markdown
Member

Add the OneCrypto v1.1 GetAuthenticodeHash() implementation that computes a PE/COFF Authenticode-style image hash. The implementation parses and validates the PE/COFF headers, hashes the image header up to and excluding the CheckSum and Cert Directory entry, hashes the sections in PointerToRawData order, and hashes any trailing bytes between the end of the last section and the start of the certificate table.

The hashing primitives are taken from BaseCryptLib (Sha1/Sha256/ Sha384/Sha512), so the same source compiles in both the OpensslPkg and MbedTlsPkg backends. The digest algorithm is selected by GUID (gEfiCertSha1Guid, gEfiCertSha256Guid, gEfiCertSha384Guid, gEfiCertSha512Guid). A separate CryptAuthenticodeHashNull.c stub is added for the PEI / Runtime / SEC / SMM phase library instances that do not provide the implementation.

OneCryptoBin is updated to publish the new function pointer in the v1.1 ONE_CRYPTO_PROTOCOL.

Caution: The PE/COFF image is treated as untrusted input. All header fields are bounds-checked against FileSize before use to avoid out-of-bounds reads.

Description

<Include a description of the change and why this change was made.>

For details on how to complete these options and their meaning refer to CONTRIBUTING.md.

  • Impacts functionality?
  • Impacts security?
  • Breaking change?
  • Includes tests?
  • Includes documentation?

How This Was Tested

<Describe the test(s) that were run to verify the changes.>

Integration Instructions

<Describe how these changes should be integrated. Use N/A if nothing is required.>

@mu-automation mu-automation Bot added the impact:non-functional Does not have a functional impact label Jun 10, 2026
@Flickdm
Flickdm force-pushed the feat/dxe-image-verification-support branch 2 times, most recently from 46bf199 to 33da9f3 Compare June 11, 2026 15:33
@mu-automation mu-automation Bot added the language:python Pull requests that update Python code label Jun 11, 2026
@Flickdm Flickdm added this to the v1.1.0-OneCrypto milestone Jun 11, 2026
@Flickdm
Flickdm force-pushed the feat/dxe-image-verification-support branch from fb2ae9f to 43cb38f Compare July 1, 2026 23:10
@Flickdm
Flickdm force-pushed the feat/dxe-image-verification-support branch 6 times, most recently from 0183ef5 to 0cc577b Compare July 22, 2026 21:46
@Flickdm Flickdm linked an issue Jul 24, 2026 that may be closed by this pull request
@Flickdm
Flickdm force-pushed the feat/dxe-image-verification-support branch 4 times, most recently from ad22c72 to 105ccc1 Compare July 29, 2026 22:52
Flickdm added 11 commits July 29, 2026 16:01
Implement AllocateCopyPool in MemoryAllocationLibOnOneCrypto using
the supported OneCryptoAllocatePool and CopyMem primitives. The
function was previously stubbed to ASSERT and return NULL, which
broke GetTrustAnchorX509FromAuthData in the trust-anchor path when
running in the OneCrypto environment.

Signed-off-by: Doug Flick <dougflick@microsoft.com>
Add the OneCrypto v1.1 GetAuthenticodeHash() implementation in the
OpensslPkg BaseCryptLib instance. The function computes a PE/COFF
Authenticode-style image hash: it parses and validates the PE/COFF
headers, hashes the image header up to and excluding the CheckSum
and Cert Directory entry, hashes the sections in PointerToRawData
order, and hashes any trailing bytes between the end of the last
section and the start of the certificate table.

The hashing primitives are the BaseCryptLib Sha1 / Sha256 / Sha384 /
Sha512 routines, so this source is independent of the underlying
provider library. The digest algorithm is selected by GUID
(gEfiCertSha1Guid, gEfiCertSha256Guid, gEfiCertSha384Guid,
gEfiCertSha512Guid). A separate CryptAuthenticodeHashNull.c stub is
added for the PEI / Runtime / SEC / SMM phase library instances that
do not provide the implementation.

Caution: The PE/COFF image is treated as untrusted input. All header
fields are bounds-checked against FileSize before use to avoid
out-of-bounds reads.

Signed-off-by: Doug Flick <dougflick@microsoft.com>
Add the OneCrypto v1.1 GetAuthenticodeHash() implementation in the
MbedTlsPkg BaseCryptLib instance. The function computes a PE/COFF
Authenticode-style image hash: it parses and validates the PE/COFF
headers, hashes the image header up to and excluding the CheckSum
and Cert Directory entry, hashes the sections in PointerToRawData
order, and hashes any trailing bytes between the end of the last
section and the start of the certificate table.

The hashing primitives are the BaseCryptLib Sha1 / Sha256 / Sha384 /
Sha512 routines, so this source is independent of the underlying
provider library. The digest algorithm is selected by GUID
(gEfiCertSha1Guid, gEfiCertSha256Guid, gEfiCertSha384Guid,
gEfiCertSha512Guid). A separate CryptAuthenticodeHashNull.c stub is
added for the PEI / Runtime / SEC / SMM phase library instances that
do not provide the implementation.

Caution: The PE/COFF image is treated as untrusted input. All header
fields are bounds-checked against FileSize before use to avoid
out-of-bounds reads.

Signed-off-by: Doug Flick <dougflick@microsoft.com>
Wire the GetAuthenticodeHash function pointer into the OneCryptoBin
ONE_CRYPTO_PROTOCOL

Signed-off-by: Doug Flick <dougflick@microsoft.com>
Add the OneCrypto v1.1 GetTrustAnchorX509FromAuthData() and
FreeTrustAnchorX509Cache() implementation in the OpensslPkg
BaseCryptLib instance. The function walks a PKCS#7 SignedData blob,
hashes each embedded X.509 certificate's TBSCertificate, and returns
the certificate whose digest matches the caller-supplied hash.

The PKCS#7 ASN.1 DER is parsed in-place with bounds-checked length
decoding; both the bare SignedData and the ContentInfo wrapper forms
are accepted. The certificates [0] IMPLICIT field is enumerated and
each Certificate SEQUENCE is matched on its TBSCertificate digest.
The hash algorithm is selected by the caller-supplied hash size
(20=SHA-1, 32=SHA-256, 48=SHA-384, 64=SHA-512). The hashing
primitives are taken from BaseCryptLib so the source is independent
of the underlying provider library.

The optional caller-managed cache stores up to 64 entries; each entry
holds a copy of the certificate DER bytes and lazily-computed TBS
digests under each algorithm. A separate CryptTrustAnchorNull.c stub
is added for the PEI / Runtime / SEC / SMM phase library instances
that do not provide the implementation.

Caution: AuthData is treated as untrusted input. All ASN.1 length
fields are bounds-checked against the remaining input before the
parser advances.

Signed-off-by: Doug Flick <dougflick@microsoft.com>
Add the OneCrypto v1.1 GetTrustAnchorX509FromAuthData() and
FreeTrustAnchorX509Cache() implementation in the MbedTlsPkg
BaseCryptLib instance. The implementation walks a PKCS#7 SignedData
blob, hashes each embedded X.509 certificate's TBSCertificate, and
returns the certificate whose digest matches the caller-supplied
hash.

The source is shared with OpensslPkg: the parser uses only ASN.1 DER
primitives and the BaseCryptLib hash API, so it does not depend on
the underlying provider library. This is required because the
MbedTlsPkg PKCS#7 helper Pkcs7GetCertificatesList() is currently
ASSERT(FALSE)-stubbed and cannot be used for certificate
enumeration.

A CryptTrustAnchorNull.c stub is added for the PEI / Runtime / SEC /
SMM phase library instances.

Caution: AuthData is treated as untrusted input. All ASN.1 length
fields are bounds-checked against the remaining input before the
parser advances.

Signed-off-by: Doug Flick <dougflick@microsoft.com>
Wire GetTrustAnchorX509FromAuthData and FreeTrustAnchorX509Cache in
OneCryptoBin protocol

Signed-off-by: Doug Flick <dougflick@microsoft.com>
Add the GetAuthenticodeHashAlgorithm implementation and its Null
variant to the OpensslPkg BaseCryptLib instance. The provider copy
parses the Authenticode SpcIndirectDataContent with bounds-checked
ASN.1 decoding to recover the digest-algorithm GUID from untrusted
signature data, mapping the digestAlgorithm OID to the matching
signature-type GUID.

Signed-off-by: Doug Flick <dougflick@microsoft.com>
Add the GetAuthenticodeHashAlgorithm implementation and its Null
variant to the MbedTlsPkg BaseCryptLib instance. The provider copy is
byte-identical to the OpensslPkg copy and parses the Authenticode
SpcIndirectDataContent with bounds-checked ASN.1 decoding to recover
the digest-algorithm GUID from untrusted signature data, mapping the
digestAlgorithm OID to the matching signature-type GUID.

Signed-off-by: Doug Flick <dougflick@microsoft.com>
Wire GetAuthenticodeHashAlgorithm into the OneCryptoBin protocol
dispatch table

Signed-off-by: Doug Flick <dougflick@microsoft.com>
Implement X509GetTbsCertHash() for the OpenSSL BaseCryptLib instance.
The implementation reuses the existing X509GetTBSCert() to extract the
TBSCertificate byte range and the provider-independent hash dispatch
table to digest it under the caller-selected algorithm. Add the
matching BaseCryptLib null stub.

Signed-off-by: Doug Flick <dougflick@microsoft.com>
Flickdm added 2 commits July 29, 2026 16:05
Implement X509GetTbsCertHash() for the Mbed TLS BaseCryptLib instance.
The implementation reuses the existing X509GetTBSCert() to extract the
TBSCertificate byte range and the provider-independent hash dispatch
table to digest it under the caller-selected algorithm. Add the
matching BaseCryptLib null stub. The OpenSSL and Mbed TLS sources
remain byte-identical.

Signed-off-by: Doug Flick <dougflick@microsoft.com>
Wire the new X509GetTbsCertHash service into the OneCrypto protocol
binary

Signed-off-by: Doug Flick <dougflick@microsoft.com>
@Flickdm
Flickdm force-pushed the feat/dxe-image-verification-support branch from 105ccc1 to fb54ffe Compare July 29, 2026 23:06
Comment thread .pytool/CISettings.py

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DROP THIS COMMIT BEFORE MERGING

Flickdm added 4 commits July 30, 2026 09:57
Implement AuthenticodeVerifyEx() for the OpenSSL BaseCryptLib. On success
it returns the signer's cryptographically-verified certificate chain in
EFI_CERT_STACK form, captured from OpenSSL's own X509_STORE verification
via an observe-only verify callback (X509_STORE_CTX_get1_chain). The
returned chain is therefore exactly the one that was verified, so a
caller can run per-certificate revocation (dbx) checks without a second,
independent chain-building pass.

Add the internal Pkcs7VerifyEx() helper that arms the capture and the
CryptAuthenticodeNull stub.

Signed-off-by: Doug Flick <dougflick@microsoft.com>
Implement AuthenticodeVerifyEx() for the MbedTls BaseCryptLib. MbedTls
cannot expose the verifier-built certificate chain, so a chain request
returns EFI_UNSUPPORTED; when no chain is requested it behaves like
AuthenticodeVerify(). Add the CryptAuthenticodeNull stub.

Signed-off-by: Doug Flick <dougflick@microsoft.com>
Wire the AuthenticodeVerifyEx service into the OneCrypto protocol

Signed-off-by: Doug Flick <dougflick@microsoft.com>
Point the OneCrypto MU_BASECORE fork dependency

Signed-off-by: Doug Flick <dougflick@microsoft.com>
@Flickdm
Flickdm force-pushed the feat/dxe-image-verification-support branch from 1e0025e to 63f5959 Compare July 30, 2026 16:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

impact:non-functional Does not have a functional impact language:python Pull requests that update Python code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Add Pkcs7GetCertificateChain

1 participant