[
https://issues.apache.org/jira/browse/CAMEL-25802?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Claus Ibsen updated CAMEL-25802:
--------------------------------
Fix Version/s: 4.24.0
> 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)