Skip to content

Commit 54d7959

Browse files
committed
Refactor provider ML-KEM code
- including more kyber name cleanup
1 parent a91ceab commit 54d7959

File tree

10 files changed

+198
-176
lines changed

10 files changed

+198
-176
lines changed

core/src/main/jdk1.1/org/bouncycastle/pqc/crypto/util/PrivateKeyFactory.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -157,10 +157,10 @@ else if (algOID.equals(NISTObjectIdentifiers.id_alg_ml_kem_512) ||
157157
algOID.equals(NISTObjectIdentifiers.id_alg_ml_kem_768) ||
158158
algOID.equals(NISTObjectIdentifiers.id_alg_ml_kem_1024))
159159
{
160-
ASN1OctetString kyberKey = ASN1OctetString.getInstance(keyInfo.parsePrivateKey());
161-
MLKEMParameters kyberParams = Utils.mlkemParamsLookup(algOID);
160+
ASN1OctetString mlkemKey = ASN1OctetString.getInstance(keyInfo.parsePrivateKey());
161+
MLKEMParameters mlkemParams = Utils.mlkemParamsLookup(algOID);
162162

163-
return new MLKEMPrivateKeyParameters(kyberParams, kyberKey.getOctets());
163+
return new MLKEMPrivateKeyParameters(mlkemParams, mlkemKey.getOctets());
164164
}
165165
else if (Utils.mldsaParams.containsKey(algOID))
166166
{

core/src/main/jdk1.1/org/bouncycastle/pqc/crypto/util/PublicKeyFactory.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -108,12 +108,12 @@ public class PublicKeyFactory
108108
converters.put(BCObjectIdentifiers.picnicl5full, new PicnicConverter());
109109
converters.put(BCObjectIdentifiers.falcon_512, new FalconConverter());
110110
converters.put(BCObjectIdentifiers.falcon_1024, new FalconConverter());
111-
converters.put(NISTObjectIdentifiers.id_alg_ml_kem_512, new KyberConverter());
112-
converters.put(NISTObjectIdentifiers.id_alg_ml_kem_768, new KyberConverter());
113-
converters.put(NISTObjectIdentifiers.id_alg_ml_kem_1024, new KyberConverter());
114-
converters.put(BCObjectIdentifiers.kyber512_aes, new KyberConverter());
115-
converters.put(BCObjectIdentifiers.kyber768_aes, new KyberConverter());
116-
converters.put(BCObjectIdentifiers.kyber1024_aes, new KyberConverter());
111+
converters.put(NISTObjectIdentifiers.id_alg_ml_kem_512, new MLKEMConverter());
112+
converters.put(NISTObjectIdentifiers.id_alg_ml_kem_768, new MLKEMConverter());
113+
converters.put(NISTObjectIdentifiers.id_alg_ml_kem_1024, new MLKEMConverter());
114+
converters.put(BCObjectIdentifiers.kyber512_aes, new MLKEMConverter());
115+
converters.put(BCObjectIdentifiers.kyber768_aes, new MLKEMConverter());
116+
converters.put(BCObjectIdentifiers.kyber1024_aes, new MLKEMConverter());
117117
converters.put(NISTObjectIdentifiers.id_ml_dsa_44, new MLDSAConverter());
118118
converters.put(NISTObjectIdentifiers.id_ml_dsa_65, new MLDSAConverter());
119119
converters.put(NISTObjectIdentifiers.id_ml_dsa_87, new MLDSAConverter());
@@ -351,16 +351,16 @@ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Obje
351351
}
352352
}
353353

354-
private static class KyberConverter
354+
private static class MLKEMConverter
355355
extends SubjectPublicKeyInfoConverter
356356
{
357357
AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams)
358358
throws IOException
359359
{
360-
MLKEMParameters kyberParameters = Utils.mlkemParamsLookup(keyInfo.getAlgorithm().getAlgorithm());
360+
MLKEMParameters mlkemParameters = Utils.mlkemParamsLookup(keyInfo.getAlgorithm().getAlgorithm());
361361

362362
// we're a raw encoding
363-
return new MLKEMPublicKeyParameters(kyberParameters, keyInfo.getPublicKeyData().getOctets());
363+
return new MLKEMPublicKeyParameters(mlkemParameters, keyInfo.getPublicKeyData().getOctets());
364364
}
365365
}
366366

prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/mlkem/MLKEMCipherSpi.java

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -32,46 +32,46 @@
3232
import org.bouncycastle.util.Arrays;
3333
import org.bouncycastle.util.Exceptions;
3434

35-
class MLKEMCipherSpi
35+
public class MLKEMCipherSpi
3636
extends CipherSpi
3737
{
38+
private final MLKEMParameters mlkemParameters;
3839
private final String algorithmName;
40+
3941
private MLKEMGenerator kemGen;
4042
private KTSParameterSpec kemParameterSpec;
4143
private BCMLKEMPublicKey wrapKey;
4244
private BCMLKEMPrivateKey unwrapKey;
4345

4446
private AlgorithmParameters engineParams;
45-
private MLKEMParameters mlkemParamters;
4647

47-
MLKEMCipherSpi(String algorithmName)
48+
public MLKEMCipherSpi(String algorithmName)
4849
{
50+
this.mlkemParameters = null;
4951
this.algorithmName = algorithmName;
50-
this.mlkemParamters = null;
5152
}
5253

53-
MLKEMCipherSpi(MLKEMParameters kyberParameters)
54+
public MLKEMCipherSpi(MLKEMParameters mlkemParameters)
5455
{
55-
this.mlkemParamters = kyberParameters;
56-
this.algorithmName = kyberParameters.getName();
56+
this.mlkemParameters = mlkemParameters;
57+
this.algorithmName = mlkemParameters.getName();
5758
}
5859

5960
@Override
6061
protected void engineSetMode(String mode)
61-
throws NoSuchAlgorithmException
62+
throws NoSuchAlgorithmException
6263
{
6364
throw new NoSuchAlgorithmException("Cannot support mode " + mode);
6465
}
6566

6667
@Override
6768
protected void engineSetPadding(String padding)
68-
throws NoSuchPaddingException
69+
throws NoSuchPaddingException
6970
{
7071
throw new NoSuchPaddingException("Padding " + padding + " unknown");
7172
}
7273

73-
protected int engineGetKeySize(
74-
Key key)
74+
protected int engineGetKeySize(Key key)
7575
{
7676
return 2048; // TODO
7777
//throw new IllegalArgumentException("not an valid key!");
@@ -176,9 +176,9 @@ else if (opmode == Cipher.UNWRAP_MODE)
176176
throw new InvalidParameterException("Cipher only valid for wrapping/unwrapping");
177177
}
178178

179-
if (mlkemParamters != null)
179+
if (mlkemParameters != null)
180180
{
181-
String canonicalAlgName = MLKEMParameterSpec.fromName(mlkemParamters.getName()).getName();
181+
String canonicalAlgName = MLKEMParameterSpec.fromName(mlkemParameters.getName()).getName();
182182
if (!canonicalAlgName.equals(key.getAlgorithm()))
183183
{
184184
throw new InvalidKeyException("cipher locked to " + canonicalAlgName);
@@ -256,11 +256,14 @@ protected byte[] engineWrap(
256256

257257
byte[] keyToWrap = key.getEncoded();
258258

259-
byte[] rv = Arrays.concatenate(encapsulation, kWrap.wrap(keyToWrap, 0, keyToWrap.length));
260-
261-
Arrays.clear(keyToWrap);
262-
263-
return rv;
259+
try
260+
{
261+
return Arrays.concatenate(encapsulation, kWrap.wrap(keyToWrap, 0, keyToWrap.length));
262+
}
263+
finally
264+
{
265+
Arrays.clear(keyToWrap);
266+
}
264267
}
265268
catch (IllegalArgumentException e)
266269
{
@@ -277,7 +280,7 @@ protected byte[] engineWrap(
277280
}
278281
catch (DestroyFailedException e)
279282
{
280-
throw new IllegalBlockSizeException("unable to destroy interim values: " + e.getMessage());
283+
// ignore
281284
}
282285
}
283286
}
@@ -293,6 +296,7 @@ protected Key engineUnwrap(
293296
{
294297
throw new InvalidKeyException("only SECRET_KEY supported");
295298
}
299+
296300
byte[] secret = null;
297301
try
298302
{
@@ -318,18 +322,14 @@ protected Key engineUnwrap(
318322
}
319323
finally
320324
{
321-
if (secret != null)
322-
{
323-
Arrays.clear(secret);
324-
}
325+
Arrays.clear(secret);
325326
}
326327
}
327328

328329
public static class Base
329-
extends MLKEMCipherSpi
330+
extends MLKEMCipherSpi
330331
{
331332
public Base()
332-
throws NoSuchAlgorithmException
333333
{
334334
super("MLKEM");
335335
}

prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/mlkem/MLKEMKeyGeneratorSpi.java

Lines changed: 35 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -21,21 +21,22 @@
2121
import org.bouncycastle.util.Arrays;
2222

2323
public class MLKEMKeyGeneratorSpi
24-
extends KeyGeneratorSpi
24+
extends KeyGeneratorSpi
2525
{
26+
private final MLKEMParameters mlkemParameters;
27+
2628
private KEMGenerateSpec genSpec;
2729
private SecureRandom random;
2830
private KEMExtractSpec extSpec;
29-
private MLKEMParameters kyberParameters;
3031

3132
public MLKEMKeyGeneratorSpi()
3233
{
3334
this(null);
3435
}
3536

36-
protected MLKEMKeyGeneratorSpi(MLKEMParameters kyberParameters)
37+
protected MLKEMKeyGeneratorSpi(MLKEMParameters mlkemParameters)
3738
{
38-
this.kyberParameters = kyberParameters;
39+
this.mlkemParameters = mlkemParameters;
3940
}
4041

4142
protected void engineInit(SecureRandom secureRandom)
@@ -51,9 +52,9 @@ protected void engineInit(AlgorithmParameterSpec algorithmParameterSpec, SecureR
5152
{
5253
this.genSpec = (KEMGenerateSpec)algorithmParameterSpec;
5354
this.extSpec = null;
54-
if (kyberParameters != null)
55+
if (mlkemParameters != null)
5556
{
56-
String canonicalAlgName = MLKEMParameterSpec.fromName(kyberParameters.getName()).getName();
57+
String canonicalAlgName = MLKEMParameterSpec.fromName(mlkemParameters.getName()).getName();
5758
if (!canonicalAlgName.equals(genSpec.getPublicKey().getAlgorithm()))
5859
{
5960
throw new InvalidAlgorithmParameterException("key generator locked to " + canonicalAlgName);
@@ -64,9 +65,9 @@ else if (algorithmParameterSpec instanceof KEMExtractSpec)
6465
{
6566
this.genSpec = null;
6667
this.extSpec = (KEMExtractSpec)algorithmParameterSpec;
67-
if (kyberParameters != null)
68+
if (mlkemParameters != null)
6869
{
69-
String canonicalAlgName = MLKEMParameterSpec.fromName(kyberParameters.getName()).getName();
70+
String canonicalAlgName = MLKEMParameterSpec.fromName(mlkemParameters.getName()).getName();
7071
if (!canonicalAlgName.equals(extSpec.getPrivateKey().getAlgorithm()))
7172
{
7273
throw new InvalidAlgorithmParameterException("key generator locked to " + canonicalAlgName);
@@ -93,41 +94,48 @@ protected SecretKey engineGenerateKey()
9394

9495
SecretWithEncapsulation secEnc = kemGen.generateEncapsulated(pubKey.getKeyParams());
9596

96-
byte[] sharedSecret = secEnc.getSecret();
97-
98-
byte[] secret = KdfUtil.makeKeyBytes(genSpec, sharedSecret);
99-
100-
Arrays.clear(sharedSecret);
101-
102-
SecretKey rv = new SecretKeyWithEncapsulation(new SecretKeySpec(secret, genSpec.getKeyAlgorithmName()), secEnc.getEncapsulation());
97+
byte[] kemSecret = secEnc.getSecret();
98+
byte[] kdfSecret = KdfUtil.makeKeyBytes(genSpec, kemSecret);
10399

104100
try
105101
{
106-
secEnc.destroy();
102+
SecretKeySpec secretKey = new SecretKeySpec(kdfSecret, genSpec.getKeyAlgorithmName());
103+
104+
return new SecretKeyWithEncapsulation(secretKey, secEnc.getEncapsulation());
107105
}
108-
catch (DestroyFailedException e)
106+
finally
109107
{
110-
throw new IllegalStateException("key cleanup failed");
108+
try
109+
{
110+
secEnc.destroy();
111+
}
112+
catch (DestroyFailedException e)
113+
{
114+
// ignore
115+
}
111116
}
112-
113-
return rv;
114117
}
115118
else
116119
{
117120
BCMLKEMPrivateKey privKey = (BCMLKEMPrivateKey)extSpec.getPrivateKey();
118121
MLKEMExtractor kemExt = new MLKEMExtractor(privKey.getKeyParams());
119122

120123
byte[] encapsulation = extSpec.getEncapsulation();
121-
byte[] sharedSecret = kemExt.extractSecret(encapsulation);
122-
byte[] secret = KdfUtil.makeKeyBytes(extSpec, sharedSecret);
123-
124-
Arrays.clear(sharedSecret);
125124

126-
SecretKey rv = new SecretKeyWithEncapsulation(new SecretKeySpec(secret, extSpec.getKeyAlgorithmName()), encapsulation);
125+
byte[] kemSecret = kemExt.extractSecret(encapsulation);
126+
byte[] kdfSecret = KdfUtil.makeKeyBytes(extSpec, kemSecret);
127127

128-
Arrays.clear(secret);
128+
try
129+
{
130+
SecretKeySpec secretKey = new SecretKeySpec(kdfSecret, extSpec.getKeyAlgorithmName());
129131

130-
return rv;
132+
// TODO Why do we return ...WithEncapsulation??
133+
return new SecretKeyWithEncapsulation(secretKey, encapsulation);
134+
}
135+
finally
136+
{
137+
Arrays.clear(kdfSecret);
138+
}
131139
}
132140
}
133141

0 commit comments

Comments
 (0)