From 499325fd93041589a6e26eb6883156c7b71bc351 Mon Sep 17 00:00:00 2001 From: Dave Mihalcik Date: Thu, 25 Jun 2026 11:30:04 -0400 Subject: [PATCH 1/5] feat(xtest): Enables mlkem tests on java-sdk --- xtest/sdk/java/cli.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/xtest/sdk/java/cli.sh b/xtest/sdk/java/cli.sh index cece9630..89411744 100755 --- a/xtest/sdk/java/cli.sh +++ b/xtest/sdk/java/cli.sh @@ -96,6 +96,11 @@ if [ "$1" == "supports" ]; then exit 1 ;; + mechanism-mlkem) + set -o pipefail + java -jar "$SCRIPT_DIR"/cmdline.jar help encrypt | grep -i xwing + exit $? + ;; mechanism-rsa-4096 | mechanism-ec-curves-384-521) # rsa4096 support in >= 0.13.0 set -o pipefail From a5198a5e05a3485b605e84281cdd261fcddada89 Mon Sep 17 00:00:00 2001 From: Dave Mihalcik Date: Thu, 25 Jun 2026 16:58:07 -0400 Subject: [PATCH 2/5] fixup --- xtest/sdk/java/cli.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xtest/sdk/java/cli.sh b/xtest/sdk/java/cli.sh index 89411744..95d78ae7 100755 --- a/xtest/sdk/java/cli.sh +++ b/xtest/sdk/java/cli.sh @@ -98,7 +98,7 @@ if [ "$1" == "supports" ]; then mechanism-mlkem) set -o pipefail - java -jar "$SCRIPT_DIR"/cmdline.jar help encrypt | grep -i xwing + java -jar "$SCRIPT_DIR"/cmdline.jar help encrypt | exit $? ;; mechanism-rsa-4096 | mechanism-ec-curves-384-521) From 4ed768ee61bcadd41d103b12477278848a90aef7 Mon Sep 17 00:00:00 2001 From: Dave Mihalcik Date: Fri, 26 Jun 2026 11:02:56 -0400 Subject: [PATCH 3/5] fix(xtest): skip hybrid PQC tests for otdfctl <= v0.33.0 / new platform skew otdfctl v0.33.0 and older were built against a pre-ocrypto-0.13.0 that produces non-conformant X-Wing and secp+ML-KEM key material. When paired with a platform that has hybrid PQC support enabled (new-format KAS), both key creation and decapsulation fail with opaque errors. Add skip_pqc_hybrid_format_skew() + _otdfctl_semver() to tdfs.py and call the guard in the four hybrid test functions (xwing roundtrip, xwing+ec roundtrip, secpmlkem-3 roundtrip, secpmlkem-5 roundtrip). Pure ML-KEM tests are unaffected. --- xtest/tdfs.py | 36 ++++++++++++++++++++++++++++++++++++ xtest/test_pqc.py | 4 ++++ 2 files changed, 40 insertions(+) diff --git a/xtest/tdfs.py b/xtest/tdfs.py index 50f6e459..f42e4f01 100644 --- a/xtest/tdfs.py +++ b/xtest/tdfs.py @@ -700,6 +700,42 @@ def skip_connectrpc_skew(encrypt_sdk: SDK, decrypt_sdk: SDK, pfs: PlatformFeatur return False +def _otdfctl_semver() -> tuple[int, int, int] | None: + """Parse otdfctl version from OTDFCTL_HEADS; None if unresolvable (main, dev, etc.).""" + oh = os.environ.get("OTDFCTL_HEADS", "[]") + try: + heads = json.loads(oh) + except json.JSONDecodeError: + return None + if not heads: + return None + m = _version_re.match(str(heads[0]).lstrip("v")) + if not m: + return None + return (int(m.group(1)), int(m.group(2)), int(m.group(3))) + + +def skip_pqc_hybrid_format_skew() -> None: + """Skip if otdfctl predates the lib/ocrypto v0.13.0 hybrid-KEM format change. + + otdfctl ≤ 0.33.0 produces non-conformant X-Wing / secp+ML-KEM key material. + When the platform has hybrid PQC support enabled (new-format KAS), the mismatch + causes opaque crypto failures; skip early with a clear message instead. + """ + pfs = get_platform_features() + if ( + "mechanism-xwing" not in pfs.features + and "mechanism-secpmlkem" not in pfs.features + ): + return + otdfctl_ver = _otdfctl_semver() + if otdfctl_ver is not None and otdfctl_ver <= (0, 33, 0): + pytest.skip( + f"otdfctl v{'.'.join(map(str, otdfctl_ver))} predates lib/ocrypto v0.13.0; " + "hybrid key material format is incompatible with this platform" + ) + + def select_target_version( encrypt_sdk: SDK, decrypt_sdk: SDK ) -> container_version | None: diff --git a/xtest/test_pqc.py b/xtest/test_pqc.py index b2fe7d6d..4405531f 100644 --- a/xtest/test_pqc.py +++ b/xtest/test_pqc.py @@ -83,6 +83,7 @@ def test_xwing_roundtrip( ) tdfs.skip_connectrpc_skew(encrypt_sdk, decrypt_sdk, pfs) tdfs.skip_hexless_skew(encrypt_sdk, decrypt_sdk) + tdfs.skip_pqc_hybrid_format_skew() attr, key_ids = attribute_with_xwing_key @@ -135,6 +136,7 @@ def test_xwing_with_ec_roundtrip( ) tdfs.skip_connectrpc_skew(encrypt_sdk, decrypt_sdk, pfs) tdfs.skip_hexless_skew(encrypt_sdk, decrypt_sdk) + tdfs.skip_pqc_hybrid_format_skew() attr, key_ids = attribute_with_xwing_and_ec_keys @@ -199,6 +201,7 @@ def test_secpmlkem_3_roundtrip( ) tdfs.skip_connectrpc_skew(encrypt_sdk, decrypt_sdk, pfs) tdfs.skip_hexless_skew(encrypt_sdk, decrypt_sdk) + tdfs.skip_pqc_hybrid_format_skew() attr, key_ids = attribute_with_secpmlkem_3_key @@ -277,6 +280,7 @@ def test_secpmlkem_5_roundtrip( ) tdfs.skip_connectrpc_skew(encrypt_sdk, decrypt_sdk, pfs) tdfs.skip_hexless_skew(encrypt_sdk, decrypt_sdk) + tdfs.skip_pqc_hybrid_format_skew() attr, key_ids = attribute_with_secpmlkem_5_key From 1367bd9074dd8483d9520447779828806e7a3542 Mon Sep 17 00:00:00 2001 From: Dave Mihalcik Date: Fri, 26 Jun 2026 11:52:26 -0400 Subject: [PATCH 4/5] xtest: skip hybrid PQC tests when encrypt SDK predates ocrypto v0.13.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two independent sources of format incompatibility exist for hybrid PQC tests (X-Wing and secp+ML-KEM): - otdfctl ≤ 0.33.0: registers hybrid KAS keys in non-conformant format - go encrypt SDK ≤ 0.33.0: produces hybrid KEM ciphertexts in old format Both are built against lib/ocrypto < v0.13.0 which changed the key-material format. Either causes opaque crypto failures when paired with a platform that has hybrid PQC support enabled. Extend skip_pqc_hybrid_format_skew() to accept an encrypt_sdk parameter and check its version (when it is a released go SDK ≤ v0.33.0) in addition to the existing otdfctl version check. Pass encrypt_sdk at all four hybrid test call sites. --- xtest/tdfs.py | 42 ++++++++++++++++++++++++++++++++---------- xtest/test_pqc.py | 8 ++++---- 2 files changed, 36 insertions(+), 14 deletions(-) diff --git a/xtest/tdfs.py b/xtest/tdfs.py index f42e4f01..d09ca470 100644 --- a/xtest/tdfs.py +++ b/xtest/tdfs.py @@ -700,6 +700,14 @@ def skip_connectrpc_skew(encrypt_sdk: SDK, decrypt_sdk: SDK, pfs: PlatformFeatur return False +def _parse_semver(version: str) -> tuple[int, int, int] | None: + """Parse a version string (with optional 'v' prefix) into (major, minor, patch).""" + m = _version_re.match(version.lstrip("v")) + if not m: + return None + return (int(m.group(1)), int(m.group(2)), int(m.group(3))) + + def _otdfctl_semver() -> tuple[int, int, int] | None: """Parse otdfctl version from OTDFCTL_HEADS; None if unresolvable (main, dev, etc.).""" oh = os.environ.get("OTDFCTL_HEADS", "[]") @@ -709,18 +717,21 @@ def _otdfctl_semver() -> tuple[int, int, int] | None: return None if not heads: return None - m = _version_re.match(str(heads[0]).lstrip("v")) - if not m: - return None - return (int(m.group(1)), int(m.group(2)), int(m.group(3))) + return _parse_semver(str(heads[0])) + +# go SDK ≤ this version used pre-ocrypto-0.13.0 hybrid KEM format (non-conformant). +_PQC_HYBRID_FORMAT_CUTOFF = (0, 33, 0) -def skip_pqc_hybrid_format_skew() -> None: - """Skip if otdfctl predates the lib/ocrypto v0.13.0 hybrid-KEM format change. - otdfctl ≤ 0.33.0 produces non-conformant X-Wing / secp+ML-KEM key material. - When the platform has hybrid PQC support enabled (new-format KAS), the mismatch - causes opaque crypto failures; skip early with a clear message instead. +def skip_pqc_hybrid_format_skew(encrypt_sdk: SDK | None = None) -> None: + """Skip if the encrypt SDK or otdfctl predates the lib/ocrypto v0.13.0 hybrid-KEM format. + + Two independent sources of format incompatibility: + - otdfctl ≤ 0.33.0: registers hybrid KAS keys in old non-conformant format. + - go encrypt SDK ≤ 0.33.0: produces hybrid KEM ciphertexts (wrappedKey) in old format. + Either causes opaque crypto failures when paired with a platform that has hybrid PQC + support enabled (new-format KAS); skip early with a clear message instead. """ pfs = get_platform_features() if ( @@ -729,11 +740,22 @@ def skip_pqc_hybrid_format_skew() -> None: ): return otdfctl_ver = _otdfctl_semver() - if otdfctl_ver is not None and otdfctl_ver <= (0, 33, 0): + if otdfctl_ver is not None and otdfctl_ver <= _PQC_HYBRID_FORMAT_CUTOFF: pytest.skip( f"otdfctl v{'.'.join(map(str, otdfctl_ver))} predates lib/ocrypto v0.13.0; " "hybrid key material format is incompatible with this platform" ) + if ( + encrypt_sdk is not None + and encrypt_sdk.sdk == "go" + and encrypt_sdk.is_released() + ): + sdk_ver = _parse_semver(encrypt_sdk.version) + if sdk_ver is not None and sdk_ver <= _PQC_HYBRID_FORMAT_CUTOFF: + pytest.skip( + f"{encrypt_sdk} predates lib/ocrypto v0.13.0; " + "hybrid KEM ciphertext format is incompatible with this platform" + ) def select_target_version( diff --git a/xtest/test_pqc.py b/xtest/test_pqc.py index 4405531f..9ad25998 100644 --- a/xtest/test_pqc.py +++ b/xtest/test_pqc.py @@ -83,7 +83,7 @@ def test_xwing_roundtrip( ) tdfs.skip_connectrpc_skew(encrypt_sdk, decrypt_sdk, pfs) tdfs.skip_hexless_skew(encrypt_sdk, decrypt_sdk) - tdfs.skip_pqc_hybrid_format_skew() + tdfs.skip_pqc_hybrid_format_skew(encrypt_sdk) attr, key_ids = attribute_with_xwing_key @@ -136,7 +136,7 @@ def test_xwing_with_ec_roundtrip( ) tdfs.skip_connectrpc_skew(encrypt_sdk, decrypt_sdk, pfs) tdfs.skip_hexless_skew(encrypt_sdk, decrypt_sdk) - tdfs.skip_pqc_hybrid_format_skew() + tdfs.skip_pqc_hybrid_format_skew(encrypt_sdk) attr, key_ids = attribute_with_xwing_and_ec_keys @@ -201,7 +201,7 @@ def test_secpmlkem_3_roundtrip( ) tdfs.skip_connectrpc_skew(encrypt_sdk, decrypt_sdk, pfs) tdfs.skip_hexless_skew(encrypt_sdk, decrypt_sdk) - tdfs.skip_pqc_hybrid_format_skew() + tdfs.skip_pqc_hybrid_format_skew(encrypt_sdk) attr, key_ids = attribute_with_secpmlkem_3_key @@ -280,7 +280,7 @@ def test_secpmlkem_5_roundtrip( ) tdfs.skip_connectrpc_skew(encrypt_sdk, decrypt_sdk, pfs) tdfs.skip_hexless_skew(encrypt_sdk, decrypt_sdk) - tdfs.skip_pqc_hybrid_format_skew() + tdfs.skip_pqc_hybrid_format_skew(encrypt_sdk) attr, key_ids = attribute_with_secpmlkem_5_key From d937e09ac5a4256d0ef603b47065a969932a243d Mon Sep 17 00:00:00 2001 From: Dave Mihalcik Date: Fri, 26 Jun 2026 12:47:19 -0400 Subject: [PATCH 5/5] xtest/sdk/java: fix broken mechanism-mlkem supports check The grep command was missing, leaving a dangling pipe into exit. Add the missing grep for 'mlkem:768' to match the help output. --- xtest/sdk/java/cli.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xtest/sdk/java/cli.sh b/xtest/sdk/java/cli.sh index 95d78ae7..0a8725e0 100755 --- a/xtest/sdk/java/cli.sh +++ b/xtest/sdk/java/cli.sh @@ -98,7 +98,7 @@ if [ "$1" == "supports" ]; then mechanism-mlkem) set -o pipefail - java -jar "$SCRIPT_DIR"/cmdline.jar help encrypt | + java -jar "$SCRIPT_DIR"/cmdline.jar help encrypt | grep -i "mlkem:768" exit $? ;; mechanism-rsa-4096 | mechanism-ec-curves-384-521)