Skip to content

Feature: Enable PQC#252

Draft
Flickdm wants to merge 19 commits into
microsoft:mainfrom
Flickdm:feat/pqc-tls-support
Draft

Feature: Enable PQC#252
Flickdm wants to merge 19 commits into
microsoft:mainfrom
Flickdm:feat/pqc-tls-support

Conversation

@Flickdm
Copy link
Copy Markdown
Member

@Flickdm Flickdm commented May 6, 2026

Description

microsoft/mu_basecore#1799

<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

Test Results:

PQC Tests

INFO - ---------------------------------------------------------
INFO - RUNNING TEST SUITE: PQC verify tests
INFO - ---------------------------------------------------------
INFO - /__w/mu_crypto_release/mu_crypto_release/MU_BASECORE/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/PqcTests.c:58 UT_ASSERT_TRUE(Status:1)
INFO - UnitTest: CryptoPkg.BaseCryptLib.Pqc - ML-DSA-44 CMS signature verification
INFO - Log Output Start
INFO - [INFO]        ML-DSA-44 CMS verification: PASSED
INFO - Log Output End
INFO - /__w/mu_crypto_release/mu_crypto_release/MU_BASECORE/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/PqcTests.c:58 UT_ASSERT_TRUE(Status:1)
INFO - UnitTest: CryptoPkg.BaseCryptLib.Pqc - ML-DSA-65 CMS signature verification
INFO - Log Output Start
INFO - [INFO]        ML-DSA-65 CMS verification: PASSED
INFO - Log Output End
INFO - /__w/mu_crypto_release/mu_crypto_release/MU_BASECORE/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/PqcTests.c:58 UT_ASSERT_TRUE(Status:1)
INFO - UnitTest: CryptoPkg.BaseCryptLib.Pqc - ML-DSA-87 CMS signature verification
INFO - Log Output Start
INFO - [INFO]        ML-DSA-87 CMS verification: PASSED
INFO - Log Output End
INFO - CMS_verify failed: 0x1700006D
INFO - UnitTest: CryptoPkg.BaseCryptLib.Pqc - ML-DSA-87 rejects tampered data
INFO - Log Output Start
INFO - [INFO]        ML-DSA-87 tampered data rejection: PASSED
INFO - Log Output End
INFO - CMS_verify failed: 0x17000064
INFO - UnitTest: CryptoPkg.BaseCryptLib.Pqc - ML-DSA-87 rejects wrong certificate
INFO - Log Output Start
INFO - [INFO]        ML-DSA-87 wrong cert rejection: PASSED

TLS 1.3 + PQC

[TLS 1.3 Support Report]
  TLS 1.3 context creation .. SUPPORTED
  TLS_AES_128_GCM_SHA256              (0x1301) .. SUPPORTED
  TLS_AES_256_GCM_SHA384              (0x1302) .. SUPPORTED
  TLS_CHACHA20_POLY1305_SHA256        (0x1303) .. SUPPORTED
  TLS_AES_128_CCM_SHA256              (0x1304) .. SUPPORTED
  TLS 1.3 ciphers supported: 4 / 4
[PQC Hybrid Key Exchange Group Report]
  X25519MLKEM768            .... SUPPORTED
  SecP256r1MLKEM768         .... SUPPORTED
  SecP384r1MLKEM1024        .... SUPPORTED
  PQC groups supported: 3 / 3
INFO - RUNNING TEST SUITE: Authenticode verify tests
INFO - ---------------------------------------------------------
INFO - /__w/mu_crypto_release/mu_crypto_release/MU_BASECORE/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/AuthenticodeTests.c:506 UT_ASSERT_TRUE(Status:1)
INFO - /__w/mu_crypto_release/mu_crypto_release/MU_BASECORE/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/AuthenticodeTests.c:535 UT_ASSERT_TRUE(Status:1)
INFO - /__w/mu_crypto_release/mu_crypto_release/MU_BASECORE/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/AuthenticodeTests.c:556 UT_ASSERT_TRUE(Status:1)
INFO - /__w/mu_crypto_release/mu_crypto_release/MU_BASECORE/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/AuthenticodeTests.c:577 UT_ASSERT_TRUE(Status:1)
INFO - CMS_verify failed: 0x17000064
INFO - CMS_verify failed: 0x1700009E
506 TestVerifyAuthenticodeVerify — legacy SHA-256/RSA (AuthenticodeWithSha256 + TestRootCert2)
535 TestVerifyAuthenticodeMlDsa44
556 TestVerifyAuthenticodeMlDsa65
577 TestVerifyAuthenticodeMlDsa87

Integration Instructions

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

@mu-automation mu-automation Bot added language:python Pull requests that update Python code impact:non-functional Does not have a functional impact labels May 6, 2026
Flickdm added 8 commits May 15, 2026 16:57
Update the openssl submodule pointer to the openssl-4.0.0 tag.

Signed-off-by: Doug Flick <dougflick@microsoft.com>
Fix X64-MSFT assembly filename conversion to handle both .S and
.s extensions.

Disable SM3 assembly sources in the asm filter to work around
build issues with OpenSSL 4.0.0. SM3 support will need
to be re-evaluated in a future update.

Signed-off-by: Doug Flick <dougflick@microsoft.com>
Regenerate all intermediate files in OpensslGen including headers,
architecture-specific assembly files, DER encoding sources, and
the new .inc files generated from .inc.in templates introduced
in OpenSSL 4.0.

Signed-off-by: Doug Flick <dougflick@microsoft.com>
Update the autogenerated source file lists in all OpensslLib INF
files to reflect the new and changed source files in OpenSSL
4.0.0.

Signed-off-by: Doug Flick <dougflick@microsoft.com>
Add Library/OpensslLib/OpensslGen as a package include path in
OpensslPkg.dec. OpenSSL 4.0 introduces .inc files generated from
.inc.in templates that are included by provider source files
using paths relative to the build root. The OpensslGen directory
must be in the include search path to resolve these references.

Signed-off-by: Doug Flick <dougflick@microsoft.com>
Add va_copy, vsnprintf, INT64_C, UINT64_C, INT32_C, and UINT32_C
macros to CrtLibSupport.h. These are required by OpenSSL 4.0
source files that were not needed in previous versions.

Signed-off-by: Doug Flick <dougflick@microsoft.com>
Replace direct struct member access with OpenSSL accessor
functions for ASN1_STRING, ASN1_TYPE, and ASN1_OBJECT types.
OpenSSL 4.0 makes these struct fields opaque, requiring use of
ASN1_STRING_get0_data(), ASN1_STRING_length(),
ASN1_STRING_type(), OBJ_get0_data(), and OBJ_length().

Signed-off-by: Doug Flick <dougflick@microsoft.com>
Add null stubs for tls_parse_ctos_ech() and
tls_construct_stoc_ech() in SslExtServNull.c for the new
Encrypted Client Hello (ECH) extension in OpenSSL 4.0.

Update tls_construct_cert_status_body() signature in
SslStatServNull.c to include the new OCSP_RESPONSE parameter.

Update OSSL_STORE_SEARCH_by_name() in ossl_store.c to use
const X509_NAME parameter matching the OpenSSL 4.0 API.

Signed-off-by: Doug Flick <dougflick@microsoft.com>
@Flickdm Flickdm force-pushed the feat/pqc-tls-support branch 3 times, most recently from 55c559d to 90892f5 Compare May 19, 2026 20:14
Flickdm added 10 commits May 20, 2026 15:44
Replace the vsnprintf and sprintf macros in CrtLibSupport.h with
proper function implementations that translate standard C format
specifiers to EDK2 BasePrintLib equivalents. OpenSSL 4.0 error
reporting calls BIO_vsnprintf with C %s (ASCII string), but EDK2
BasePrintLib treats %s as Unicode, causing a segfault in the
host unit tests. The new TranslateFormatSpecifiers helper converts
C %s to EDK2 %a before calling AsciiVSPrint.

Signed-off-by: Doug Flick <dougflick@microsoft.com>
Remove no-ml-dsa, no-ml-kem, and no-tls1_3 from configure.py
to enable Post-Quantum Cryptography support in OpenSSL 4.0.0.

Regenerated configuration headers and INF files with:
- ML-KEM (FIPS 203) key encapsulation sources
- ML-DSA (FIPS 204) digital signature sources
- MLX hybrid key exchange sources
- TLS 1.3 protocol support (required for PQC key exchange)

OpenSSL 4.0.0 has native PQC support - no external provider
(oqsprovider) needed.

Note: Build is blocked by pre-existing missing decoders.inc
in uefiprov.c (not related to this change).

Signed-off-by: Doug Flick <dougflick@microsoft.com>
Rewrite TlsSetEcCurve to use SSL_set1_groups_list with string
group names, replacing the deprecated EC_KEY_new_by_curve_name
and SSL_set_tmp_ecdh APIs. This enables P-256 (previously
rejected), X25519, X448, and PQC hybrid key exchange groups
(X25519MLKEM768, SecP256r1MLKEM768, SecP384r1MLKEM1024).

Add TLS 1.3 cipher suite support to TlsSetCipherList by
detecting IANA IDs in the 0x1300 range and routing them
through SSL_set_ciphersuites instead of SSL_set_cipher_list.

Signed-off-by: Doug Flick <dougflick@microsoft.com>
Enable OpenSSL CMS module by removing OPENSSL_NO_CMS from
configuration-ec.h and configuration-noec.h, and adding 19
CMS source files to OpensslLibFull.inf and OpensslLibAccel.inf.

Register ML-DSA-44/65/87 signature and keymgmt providers, plus
SHAKE-128/256 and ML-DSA-MU digest providers in the UEFI
OpenSSL provider (uefiprov.c). Without these registrations,
the EVP provider framework cannot locate the ML-DSA algorithms.

Add CMS verification fallback to Pkcs7Verify. OpenSSL's
PKCS7_verify does not support ML-DSA (returns 'provider
signature not supported'). When PKCS7 verification fails,
the function now attempts CMS_verify which has explicit
ML-DSA support through the cms_sd.c key2data table.

Signed-off-by: Doug Flick <dougflick@microsoft.com>
Replace the PKCS7-first + CMS-fallback approach with a single
CMS_verify call. CMS (RFC 5652) is the successor to PKCS#7 and
is backward-compatible at the ASN.1 level. CMS_verify supports
RSA, ECDSA, Ed25519, ML-DSA, and future algorithms through the
OpenSSL EVP provider framework.

PKCS7_verify cannot verify ML-DSA signatures (returns 'provider
signature not supported'). Using CMS exclusively simplifies the
code and provides crypto-agile verification for both classical
and post-quantum algorithms.

Signed-off-by: Doug Flick <dougflick@microsoft.com>
Add 19 CMS source files to OpensslLibFullAccel.inf to resolve
linker errors when building OneCryptoPkg. The CMS module is
required for ML-DSA signature verification through Pkcs7Verify.

Signed-off-by: Doug Flick <dougflick@microsoft.com>
Switch AuthenticodeVerify() from the legacy PKCS7_verify path (via
Pkcs7Verify) to CMS_verify so the function can dispatch through the
OpenSSL EVP provider framework. This enables verification of
post-quantum signature algorithms (ML-DSA-44/65/87) in addition to
the traditional RSA and ECDSA paths.

CMS (RFC 5652) requires eContent to be an OCTET STRING, while
Authenticode (PKCS#7 v1.5) encodes SpcIndirectDataContent as a raw
SEQUENCE. To bridge this format mismatch without losing CMS-based
verification, temporarily remove eContent from the parsed PKCS#7 to
produce a detached signature, re-encode that detached form to DER,
parse it as CMS ContentInfo, and supply the original
SpcIndirectDataContent separately via a BIO to CMS_verify.

Signed-off-by: Doug Flick <dougflick@microsoft.com>
Switch the MU_BASECORE dependency in both PlatformBuild.py and
.pytool/CISettings.py from the pinned upstream commit on
microsoft/mu_basecore to the update/Pqc-BaseCryptLibUnitTests branch
on the flickdm/mu_basecore fork. This is required so the BaseCryptLib
PQC unit tests (ML-DSA-44/65/87) and the SHA-1 Authenticode test
removal are pulled in by stuart_update.

Revert to a pinned upstream commit once the PQC unit test changes are
merged into mu_basecore.

Signed-off-by: Doug Flick <dougflick@microsoft.com>
X509ConstructCertificateStackV initialized Status to FALSE and only
set it to TRUE after successfully constructing a certificate. When
the caller supplied only the NULL terminator (an empty list), the
loop exited with Status still FALSE and the function returned an
error instead of the documented success path "A NULL terminates the
list".

Set Status to TRUE when the loop reaches the NULL terminator so an
empty list yields an empty stack and TRUE, matching the function
documentation and the new TestX509ConstructCertificateStackEmptyList
host unit test. Also set Status to FALSE explicitly when CertSize
is zero so the failure indication is independent of whether a
previous iteration succeeded.

Signed-off-by: Doug Flick <dougflick@microsoft.com>
The EVP_add_digest_alias() registration mapping sha1WithRSAEncryption
to sha1WithRSA was needed for legacy OpenSSL OID handling.  OpenSSL
4.0 with the EVP provider framework resolves this alias internally;
the explicit registration is no longer required and SHA-1 with RSA is
deprecated for new signatures.

Signed-off-by: Doug Flick <dougflick@microsoft.com>
@Flickdm Flickdm force-pushed the feat/pqc-tls-support branch from 90892f5 to 033e592 Compare May 20, 2026 22:44
Extend the UEFI built-in OpenSSL provider (uefiprov.c) so that libssl
can discover the algorithms required for the post-quantum TLS 1.3 key
exchange groups defined by IANA codepoints 0x11EB (SecP256r1MLKEM768),
0x11EC (X25519MLKEM768), and 0x11ED (SecP384r1MLKEM1024), as well as
the classical X25519 / X448 groups.

The UEFI provider previously omitted ECX (X25519, X448), ML-KEM, and
the ML-KEM hybrid algorithms. Without keymgmt and KEM dispatch entries,
SSL_set1_groups_list() would reject those names and TlsSetEcCurve()
would return EFI_UNSUPPORTED for both classical and PQC groups.

Add the following entries (gated to match per-variant source coverage
in the OpensslLib*.inf files):

  * deflt_keyexch[]: X25519, X448 (gated by OPENSSL_NO_EC / OPENSSL_NO_ECX)
  * deflt_keymgmt[]: X25519, X448, ML-KEM-768/1024, X25519MLKEM768,
    SecP256r1MLKEM768, SecP384r1MLKEM1024
  * deflt_asym_kem[] (new table): RSA, EC, X25519, X448, ML-KEM-768/1024,
    and the three TLS hybrid KEMs
  * deflt_query(): dispatch OSSL_OP_KEM to the new deflt_asym_kem table

Verified against the TlsLib host unit tests: X25519 / X448 report
SUPPORTED, and all three PQC hybrid groups report SUPPORTED (3 / 3).
All 119 host unit tests continue to pass.

Signed-off-by: Doug Flick <dougflick@microsoft.com>
@Flickdm Flickdm force-pushed the feat/pqc-tls-support branch from 7bef5d9 to adc644d Compare May 21, 2026 04:38
@Flickdm Flickdm added this to the v2.0.0-OneCrypto milestone May 28, 2026
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.

1 participant