[
https://issues.apache.org/jira/browse/CAMEL-25603?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Work on CAMEL-25603 started by Andrea Cosentino.
------------------------------------------------
> camel-pqc - key encapsulation operations share one KeyGenerator and
> KeyAgreement instance across concurrent exchanges without synchronization
> ---------------------------------------------------------------------------------------------------------------------------------------------
>
> Key: CAMEL-25603
> URL: https://issues.apache.org/jira/browse/CAMEL-25603
> Project: Camel
> Issue Type: Bug
> Components: camel-pqc
> Reporter: Andrea Cosentino
> Assignee: Andrea Cosentino
> Priority: Major
> Fix For: 4.18.6, 4.22.2, 4.24.0
>
>
> {{PQCProducer}} holds a single {{javax.crypto.KeyGenerator}} for the KEM
> operations. It comes from the {{keyGenerator}} option (which is autowired),
> from the static {{PQCDefault*Material.keyGenerator}} instances that
> {{PQCComponent}} assigns when no key material is configured, or from
> {{doStart()}}:
> {code:java}
> private KeyGenerator keyGenerator;
> ...
> keyGenerator = getEndpoint().getConfiguration().getKeyGenerator();
> if (ObjectHelper.isEmpty(keyGenerator)) {
> keyGenerator = KeyGenerator.getInstance(kemAlg.getAlgorithm(),
> kemAlg.getBcProvider());
> }
> {code}
> {{generateEncapsulation()}} and {{extractEncapsulation()}} then run
> {{init(spec)}} followed by {{generateKey()}} on that object with no
> synchronization:
> {code:java}
> keyGenerator.init(new KEMExtractSpec(keyPair.getPrivate(),
> payload.getEncapsulation(), ...), SecureRandomHelper.getSecureRandom());
> SecretKeyWithEncapsulation secEnc2 = (SecretKeyWithEncapsulation)
> keyGenerator.generateKey();
> {code}
> The same pattern is used in:
> * {{HybridKEM.encapsulate()}} / {{HybridKEM.extract()}}: {{init}} +
> {{generateKey}} on the PQC {{KeyGenerator}}, and {{init}} / {{doPhase}} /
> {{generateSecret}} on the classical {{KeyAgreement}}. Both come from the
> configuration (autowired), from the static {{PQCDefaultX25519MLKEMMaterial}}
> / {{PQCDefaultECDHMLKEMMaterial}} instances, or are created once at producer
> start.
> * {{PQCDataFormat.marshal()}} / {{unmarshal()}}: {{doStart()}} caches one
> {{KeyGenerator}} in the {{keyGenerator}} field whenever
> {{keyEncapsulationAlgorithm}} is set (the default is MLKEM), so every marshal
> and unmarshal call on a started instance uses the same object, also when no
> KeyGenerator is configured. As a side effect a started data format ignores
> the per-message {{CamelPQCKemAlgorithm}} header.
> {{KeyGenerator}} and {{KeyAgreement}} keep the parameters passed to
> {{init()}} / {{doPhase()}} in the object until {{generateKey()}} /
> {{generateSecret()}} reads them, and they are not thread-safe, while
> producers and data formats are invoked concurrently. Interleaved calls can
> produce a result computed from another invocation's parameters, or fail with
> an exception. The docs currently recommend sharing one instance: the ML-KEM
> example registers a single KeyGenerator bean used by both the generate and
> the extract endpoint, and pqc-dataformat.adoc has a "Caching KeyGenerator"
> tip.
> Proposal, following CAMEL-24445:
> * create the {{KeyGenerator}} / {{KeyAgreement}} per invocation where Camel
> creates it (producer and data format start);
> * serialize each init-to-result sequence on a configured or otherwise shared
> instance;
> * stop assigning the static {{PQCDefault*Material}} key generators and key
> agreements to endpoint configurations;
> * update the docs, and add concurrency tests for the KEM, hybrid KEM and data
> format paths.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)