You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@camel.apache.org by "Andrea Cosentino (Jira)" <ji...@apache.org> on 2026/10/19 08:57:00 UTC
[jira] [Assigned] (CAMEL-25800) camel-pqc - the hybrid KEM always uses P-256, so ECDH_P384, ECDH_P521 and X448 cannot work
[ https://issues.apache.org/jira/browse/CAMEL-25800?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Andrea Cosentino reassigned CAMEL-25800:
----------------------------------------
Assignee: Andrea Cosentino
> camel-pqc - the hybrid KEM always uses P-256, so ECDH_P384, ECDH_P521 and X448 cannot work
> ------------------------------------------------------------------------------------------
>
> Key: CAMEL-25800
> URL: https://issues.apache.org/jira/browse/CAMEL-25800
> Project: Camel
> Issue Type: Bug
> Components: camel-pqc
> Reporter: Andrea Cosentino
> Assignee: Andrea Cosentino
> Priority: Major
>
> {{HybridKEM.encapsulate()}} derives the ephemeral classical key from the *key's own* algorithm string rather than from the configured {{classicalKEMAlgorithm}}, and hardcodes secp256r1 for every EC key.
> {{HybridKEM.java:287-305}}:
> {code:java}
> private static KeyPair generateEphemeralKeyPair(String algorithm) throws Exception {
> KeyPairGenerator kpg;
> if ("EC".equals(algorithm)) {
> kpg = KeyPairGenerator.getInstance("EC");
> // Default to P-256
> kpg.initialize(new ECGenParameterSpec("secp256r1"), SecureRandomHelper.getSecureRandom());
> } else if ("X25519".equals(algorithm) || "XDH".equals(algorithm)) {
> {code}
> {{classicalPublicKey.getAlgorithm()}} returns just {{"EC"}} for every curve, so the ephemeral key is always P-256. With a P-384 or P-521 static key, {{classicalKA.doPhase(classicalPublicKey, true)}} ({{HybridKEM.java:97}}) fails on mismatched domain parameters. The {{X448}} branch exists at {{:298-299}} but nothing can select it, because the branch keys off the key's own algorithm string rather than the configuration.
> h3. The option is advertised
> {{PQCConfiguration.java:85}}:
> {code:java}
> @UriParam(enums = "ECDH_P256,ECDH_P384,ECDH_P521,X25519,X448", ...)
> {code}
> and {{src/main/docs/pqc-hybrid.adoc:120-123}} documents {{ECDH_P384}}, {{ECDH_P521}} and {{X448}} as supported.
> h3. The enum already has everything needed, unused
> {{PQCClassicalKEMAlgorithms.getCurveSpec()}}, {{getSharedSecretSize()}} and {{isECDH()}} have *zero callers* anywhere in {{src/main}} — verified by grep. Only {{getKeyAlgorithm()}} is used, at {{PQCProducer.java:478-479}}. That is precisely why this went unnoticed.
> h3. Suggested fix
> Thread the configured {{PQCClassicalKEMAlgorithms}} into {{HybridKEM.encapsulate()}} and use {{getCurveSpec()}} to initialise the ephemeral generator. Alternatively derive the curve from the static key's {{ECParameterSpec}} instead of hardcoding one.
> h3. Related: the hybrid KDF silently downgrades on an unrecognised name
> {{HybridKEM.java:278-284}}:
> {code:java}
> private static HKDFBytesGenerator createHKDF(String algorithm) {
> return switch (algorithm) {
> case "HKDF-SHA256" -> new HKDFBytesGenerator(new SHA256Digest());
> case "HKDF-SHA384" -> new HKDFBytesGenerator(new SHA384Digest());
> case "HKDF-SHA512" -> new HKDFBytesGenerator(new SHA512Digest());
> default -> new HKDFBytesGenerator(new SHA256Digest());
> };
> {code}
> {{hybridKdfAlgorithm}} is a free-form {{String}} ({{PQCConfiguration.java:105}}) validated only by catalog metadata, never at runtime. A typo such as {{HKDF-SHA-512}} silently yields SHA-256 instead of failing. It should throw {{IllegalArgumentException}}.
> h3. Test gap
> No test anywhere in {{src/test}} references {{ECDH_P384}}, {{ECDH_P521}} or {{X448}} — only {{ECDH_P256}} ({{PQCHybridKEMECDHMLKEMTest.java:68}}) and {{X25519}} ({{PQCHybridKEMX25519MLKEMTest.java:68}}).
> ----
> _Reported by Claude Code (AI agent) on behalf of [~oscerd]. Every code reference was verified against commit {{7aae27315946}} on {{main}}._
--
This message was sent by Atlassian Jira
(v8.20.10#820010)