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

Claus Ibsen resolved CAMEL-25802.
---------------------------------
    Resolution: Fixed

> camel-pqc - align the key material classes on SecureRandom, provider names 
> and documented defaults
> --------------------------------------------------------------------------------------------------
>
>                 Key: CAMEL-25802
>                 URL: https://issues.apache.org/jira/browse/CAMEL-25802
>             Project: Camel
>          Issue Type: Improvement
>          Components: camel-pqc
>            Reporter: Andrea Cosentino
>            Assignee: Andrea Cosentino
>            Priority: Minor
>             Fix For: 4.24.0
>
>
> The twenty-one {{PQCDefault*Material}} classes were written by cloning each 
> other and have drifted. None of the items below is individually serious; 
> together they make the module's security-relevant defaults unpredictable and 
> undocumented.
> h3. 1. Only 6 of 11 signature materials seed with {{SecureRandomHelper}}
> Seeded: MLDSA, DILITHIUM, SLHDSA, SPHINCSPLUS, XMSS, XMSSMT. Not seeded — 
> Falcon, MAYO, SNOVA, LMS, HSS fall back to the provider default RNG. 
> {{PQCDefaultFalconMaterial.java:50-52}}:
> {code:java}
>         KeyPairGenerator kpGen = 
> KeyPairGenerator.getInstance(PQCSignatureAlgorithms.FALCON.getAlgorithm(),
>                 PQCSignatureAlgorithms.FALCON.getBcProvider());
>         kpGen.initialize(FalconParameterSpec.falcon_1024);
> {code}
> Same at {{PQCDefaultHSSMaterial.java:59}}, {{PQCDefaultLMSMaterial.java:54}}, 
> {{PQCDefaultMAYOMaterial.java:52}}, {{PQCDefaultSNOVAMaterial.java:52}}. All 
> ten KEM materials do seed. {{SecureRandomHelper}} exists precisely to 
> centralise this choice. Note that {{PQCComponent.resolveKeyPair}} ({{:264}}) 
> always seeds, so the same algorithm gets a different RNG depending on whether 
> {{parameterSpec}} was set.
> h3. 2. Aliases of the same algorithm default to different security levels
> {{MLKEM("ML-KEM", "BC")}} and {{KYBER("ML-KEM", "BC")}} are the same JCE 
> algorithm, yet {{PQCDefaultMLKEMMaterial.java:55}} uses 
> {{MLKEMParameterSpec.ml_kem_512}} (NIST level 1) while 
> {{PQCDefaultKYBERMaterial.java:55}} uses {{ml_kem_1024}} (level 5), and the 
> hybrid materials independently pick {{ml_kem_768}}. The production autowired 
> default for the flagship standardised KEM is therefore the weakest of the 
> three. The same split exists for {{MLDSA}} ({{ml_dsa_65}}) versus 
> {{DILITHIUM}} ({{ml_dsa_87}}). None of these levels is documented anywhere.
> Related drift across the family with no stated rationale: 
> {{CMCEParameterSpec.mceliece8192128f}} (highest), 
> {{SABERParameterSpec.lightsaberkem256r3}} and 
> {{NTRUParameterSpec.ntruhps2048509}} (lowest), versus {{bike192}} / 
> {{hqc192}} / {{frodokem976aes}} (middle). {{PQCDefaultLMSMaterial}} uses 
> {{LMOtsParameters.sha256_n32_w1}} while {{PQCDefaultHSSMaterial.java:56}} 
> uses {{w2}} for the same underlying scheme, and the LMS default 
> {{lms_sha256_n32_h5}} is a height-5 tree, i.e. *32 signatures* before 
> permanent exhaustion.
> h3. 3. Residual {{BCPQC}} provider strings
> Twelve enum constants still name {{"BCPQC"}} — 
> {{PQCSignatureAlgorithms.java:26-27}}:
> {code:java}
>     XMSS("XMSS", "BCPQC"),
>     XMSSMT("XMSSMT", "BCPQC"),
> {code}
> plus FALCON/SNOVA/MAYO and six KEM constants — mixed with {{"BC"}} for the 
> rest, with no principle distinguishing them. (They resolve identically in 
> Bouncy Castle 1.86, so this is cosmetic, but it is arbitrary.) There are also 
> six hardcoded {{"BC"}} literals in the hybrid materials, and 
> {{HybridKEM.java:293}} / {{PQCProducer.java:452,481}} resolve classical 
> primitives with no provider at all, so one hybrid exchange can mix 
> SunEC-produced keys with BC objects. No shared provider constant exists in 
> {{PQCConstants}}.
> h3. 4. {{DILITHIUM}} and {{SPHINCSPLUS}} get a factually wrong warning
> {{PQCProducer.java:96-103}} puts both in {{NON_FIPS_PQ_SIGNATURES}}, which 
> drives {{PQCProducer.java:1280}}:
> {code:java}
>                 LOG.warn("PQC signature algorithm {} is not part of NIST FIPS 
> 204/205. Consider using "
>                          + "ML-DSA (FIPS 204) or SLH-DSA (FIPS 205) for 
> production hybrid deployments.",
> {code}
> But {{PQCSignatureAlgorithms.java:28,34}} are {{DILITHIUM("ML-DSA", "BC")}} 
> and {{SPHINCSPLUS("SLH-DSA", "BC")}} — they already *are* the FIPS 204/205 
> algorithms the warning recommends. The module knows this: 
> {{PQCParameterSpecResolver.java:117}} says "DILITHIUM and SPHINCSPLUS 
> generate ML-DSA and SLH-DSA keys". Either drop them from the set or warn that 
> the name is a deprecated alias.
> h3. 5. {{parameterSpec}} is refused for MAYO and SNOVA on a premise that is 
> not true for BC 1.86
> {{PQCParameterSpecResolver.java:43-45}}:
> {code:java}
>  * algorithms (XMSS, XMSSMT, LMS, HSS) and MAYO/SNOVA have no 
> name-addressable BouncyCastle parameter spec and are
>  * therefore not supported here
> {code}
> Verified against {{bcprov-jdk18on-1.86.jar}}: both {{MayoParameterSpec}} and 
> {{SnovaParameterSpec}} declare {{public static ... 
> fromName(java.lang.String)}}. The claim is correct for XMSS/XMSSMT/LMS/HSS 
> ({{XMSSParameterSpec}} has no {{fromName}}) but wrong for MAYO/SNOVA, which 
> are not stateful. {{PQCParameterSpecResolverTest.java:115}} enshrines the 
> wrong premise with 
> {{assertFalse(PQCParameterSpecResolver.isSupported("MAYO"));}}.
> h3. 6. {{label}} is a required URI path option that can never be bound
> {{PQCConfiguration.java:36-38}}:
> {code:java}
>     @UriPath(description = "Logical name")
>     @Metadata(required = true)
>     private String label;
> {code}
> There is no {{getLabel}} or {{setLabel}} anywhere in the module, and 
> {{PQCComponent.createEndpoint}} ({{:85-89}}) never uses its {{remaining}} 
> argument. The generated {{pqc.json}} emits it as {{"kind": "path", 
> "required": true}} and {{PQCEndpointUriFactory}} builds it, but nothing ever 
> reads it.
> h3. 7. Observability and Javadoc gaps
> {{PQCProducer.java:233}} is the only {{recordOperation}} call site in the 
> module; {{PQCDataFormat}}, {{KeyRotationScheduler}} and all five 
> {{KeyLifecycleManager}} implementations have no metrics at all, so key 
> generation, rotation and storage are unobserved. Twenty-three public classes 
> have no class-level Javadoc (all 21 material classes, {{PQCConfiguration}}, 
> {{KeyMetadataCodec}}) while every hybrid class, enum and lifecycle manager is 
> documented.
> h3. Suggested direction
> Most of this collapses if the clone-and-tweak material classes are replaced 
> by one parameterised factory driven by {{PQCParameterSpecResolver}}: that 
> removes the SecureRandom split, the undocumented level drift and the missing 
> Javadoc in one change, and it makes the "add a new algorithm" path a single 
> registration instead of a new file plus two switch arms.
> ----
> _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