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:46:00 UTC
[jira] [Created] (CAMEL-25800) camel-pqc - the hybrid KEM always uses P-256, so ECDH_P384, ECDH_P521 and X448 cannot work
Andrea Cosentino created CAMEL-25800:
----------------------------------------
Summary: 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
{{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)