[ 
https://issues.apache.org/jira/browse/CAMEL-25803?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Andrea Cosentino reassigned CAMEL-25803:
----------------------------------------

    Assignee: Andrea Cosentino

> camel-pqc - the hybrid wire format v2 is documented but not implemented
> -----------------------------------------------------------------------
>
>                 Key: CAMEL-25803
>                 URL: https://issues.apache.org/jira/browse/CAMEL-25803
>             Project: Camel
>          Issue Type: Bug
>          Components: camel-pqc
>            Reporter: Andrea Cosentino
>            Assignee: Andrea Cosentino
>            Priority: Major
>
> {{src/main/docs/pqc-hybrid.adoc}} documents a self-describing "wire format 
> v2" for hybrid signatures and encapsulations, in a dedicated hundred-line 
> section. The code implements only v1.
> h3. What the documentation claims
> {{pqc-hybrid.adoc:104}}:
> {noformat}
> Since Camel 4.19, hybrid signatures use wire format v2 which includes magic 
> bytes, version, and algorithm identifiers (see <<Wire Format v2 and Algorithm 
> Identification>>). The v1 format `[4 bytes: classical sig length][classical 
> sig][pqc sig]` is still accepted on input for backward compatibility.
> {noformat}
> The same sentence appears for encapsulations at {{:217}}, with the format 
> laid out under {{== Wire Format v2 and Algorithm Identification}} ({{:289}}) 
> and {{=== Wire Format v2 Layout}} ({{:364}}).
> h3. What the code does
> {{HybridSignature.java:73-74}}:
> {code:java}
>         // Combine: [4 bytes length][classical sig][pqc sig]
>         return combineSignatures(classicalSignature, pqcSignature);
> {code}
> That is the v1 format. {{HybridKEM}} is the same. There are no magic bytes, 
> no version byte and no algorithm identifiers anywhere in either class.
> h3. {{PQCAlgorithmId}} is public, documented and referenced by nothing
> {{PQCAlgorithmId.java:36}} declares a public enum of about fifty constants 
> whose Javadoc says it is "used in the wire format header to make hybrid 
> cryptographic outputs self-describing". A repository-wide grep finds *zero* 
> references outside its own file — no production caller, no test, only the 
> adoc. It is untested public API surface.
> It is also internally inconsistent with the algorithm enums, so 
> {{fromJcaName()}} returns {{UNKNOWN}} for the real JCE names. 
> {{PQCAlgorithmId.java:77}}:
> {code:java}
>     FRODO(0x0406, "FRODO"),
> {code}
> versus {{PQCKeyEncapsulationAlgorithms.java:29}}:
> {code:java}
>     FRODO("FrodoKEM", "BC"),
> {code}
> Same for {{KYBER}} ({{"KYBER"}} vs {{"ML-KEM"}}), {{DILITHIUM}} and 
> {{SPHINCSPLUS}}. The enum is also missing HSS and seven 
> {{PQCSymmetricAlgorithms}} constants, and carries a {{PICNIC}} constant that 
> exists in no other enum (Picnic was removed from Bouncy Castle).
> h3. The documented API does not compile
> {{pqc-hybrid.adoc:357}}:
> {code:java}
> PQCAlgorithmId classical = components.classicalAlgorithmId(); // e.g. 
> SHA256_WITH_ECDSA
> {code}
> {{HybridSignature.java:216}}:
> {code:java}
>     public record HybridSignatureComponents(byte[] classicalSignature, byte[] 
> pqcSignature) {
> {code}
> There is no {{classicalAlgorithmId()}} accessor. A user following the 
> published snippet gets a compile error.
> h3. Decision needed
> Either implement v2 — magic bytes, version, algorithm ids, with v1 still 
> accepted on input as the docs already promise — and give 
> {{HybridSignatureComponents}} the documented accessors; or delete 
> {{PQCAlgorithmId}} and the entire v2 section of the documentation and 
> describe the v1 format that actually ships. Shipping a documented format that 
> does not exist is worse than either.
> If v2 is implemented, it would also be the natural place to fix the related 
> gap in {{PQCDataFormat}} ({{:182-185}}), whose output carries neither the 
> symmetric algorithm nor the key length even though both can be overridden per 
> message via {{CamelPQCSymmetricAlgorithm}} — a mismatch currently surfaces as 
> a misleading "may have been tampered with" at {{:240-243}}.
> h3. Note on the combiner itself
> For the record, the hybrid construction is sound in kind and should not 
> change as part of this: both secrets are fed through HKDF 
> ({{HybridKEM.java:260-266}}, not XOR and not single-secret), 
> {{HybridSignature.verify}} correctly uses {{&&}} ({{:118}}), and the v1 wire 
> format is length-prefixed and bounds-checked on parse. Two smaller hardening 
> items worth folding in: the HKDF {{salt}} is {{null}} and {{info}} is only 
> the cipher name, where the established combiners also bind the PQ ciphertext 
> and the public keys; and {{info.getBytes()}} uses the platform default 
> charset inside a key derivation.
> h3. Test gap
> The only negative hybrid-signature test tampers with the data, which 
> invalidates *both* signatures — it would pass identically if the verification 
> operator were {{||}}. A test that forges exactly one half (valid classical 
> signature spliced onto a garbage PQC signature) is the highest-value missing 
> test in this area.
> ----
> _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)

Reply via email to