Skip to content

Commit 7ba916e

Browse files
committed
added length check for decryption payload for ML-KEM.
added tests for the same. added PBMAC1 support to PKCS12StoreParameter
1 parent f7d8a42 commit 7ba916e

File tree

3 files changed

+178
-0
lines changed

3 files changed

+178
-0
lines changed

core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMExtractor.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ public MLKEMExtractor(MLKEMPrivateKeyParameters privateKey)
2121

2222
public byte[] extractSecret(byte[] encapsulation)
2323
{
24+
if (encapsulation.length != this.getEncapsulationLength())
25+
{
26+
throw new IllegalArgumentException("encapsulation wrong length");
27+
}
2428
return engine.kemDecrypt(privateKey, encapsulation);
2529
}
2630

core/src/test/java/org/bouncycastle/pqc/crypto/test/MLKEMTest.java

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import java.util.HashMap;
99
import java.util.Map;
1010

11+
import junit.framework.Assert;
1112
import junit.framework.TestCase;
1213
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
1314
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
@@ -75,6 +76,41 @@ public void testKeys()
7576
}
7677
}
7778

79+
public void testInputs()
80+
throws Exception
81+
{
82+
MLKEMKeyPairGenerator kpGen = new MLKEMKeyPairGenerator();
83+
MLKEMKeyGenerationParameters genParam = new MLKEMKeyGenerationParameters(new SecureRandom(), MLKEMParameters.ml_kem_512);
84+
85+
//
86+
// Generate keys and test.
87+
//
88+
kpGen.init(genParam);
89+
AsymmetricCipherKeyPair kp = kpGen.generateKeyPair();
90+
91+
MLKEMExtractor kEx = new MLKEMExtractor((MLKEMPrivateKeyParameters)kp.getPrivate());
92+
93+
try
94+
{
95+
kEx.extractSecret(new byte[2000]);
96+
Assert.fail();
97+
}
98+
catch (IllegalArgumentException e)
99+
{
100+
assertEquals("encapsulation wrong length", e.getMessage());
101+
}
102+
103+
try
104+
{
105+
kEx.extractSecret(new byte[600]);
106+
Assert.fail();
107+
}
108+
catch (IllegalArgumentException e)
109+
{
110+
assertEquals("encapsulation wrong length", e.getMessage());
111+
}
112+
}
113+
78114
public void testKeyGen() throws IOException
79115
{
80116
MLKEMParameters[] params = new MLKEMParameters[]{

prov/src/main/java/org/bouncycastle/jcajce/PKCS12StoreParameter.java

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,15 @@
55
import java.security.KeyStore.LoadStoreParameter;
66
import java.security.KeyStore.ProtectionParameter;
77

8+
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
9+
import org.bouncycastle.asn1.DERNull;
10+
import org.bouncycastle.asn1.pkcs.PBKDF2Params;
11+
import org.bouncycastle.asn1.pkcs.PBMAC1Params;
12+
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
13+
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
14+
import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers;
15+
import org.bouncycastle.util.Arrays;
16+
817
/**
918
* LoadStoreParameter to allow for additional config with PKCS12 files.
1019
* <p>
@@ -18,6 +27,123 @@ public class PKCS12StoreParameter
1827
private final ProtectionParameter protectionParameter;
1928
private final boolean forDEREncoding;
2029
private final boolean overwriteFriendlyName;
30+
private final AlgorithmIdentifier macAlgorithm;
31+
32+
public static class PBMAC1WithPBKDF2Builder
33+
{
34+
private int iterationCount = 16384;
35+
private byte[] salt = null;
36+
private int keySizeinBits = 256;
37+
private ASN1ObjectIdentifier prf = PKCSObjectIdentifiers.id_hmacWithSHA256;
38+
private ASN1ObjectIdentifier mac = PKCSObjectIdentifiers.id_hmacWithSHA512;
39+
40+
PBMAC1WithPBKDF2Builder()
41+
{
42+
43+
}
44+
45+
public PBMAC1WithPBKDF2Builder setIterationCount(int iterationCount)
46+
{
47+
this.iterationCount = iterationCount;
48+
49+
return this;
50+
}
51+
52+
public PBMAC1WithPBKDF2Builder setSalt(byte[] salt)
53+
{
54+
this.salt = Arrays.clone(salt);
55+
56+
return this;
57+
}
58+
59+
public PBMAC1WithPBKDF2Builder setKeySize(int keySizeinBits)
60+
{
61+
this.keySizeinBits = keySizeinBits;
62+
63+
return this;
64+
}
65+
66+
public PBMAC1WithPBKDF2Builder setPrf(ASN1ObjectIdentifier prf)
67+
{
68+
this.prf = prf;
69+
70+
return this;
71+
}
72+
73+
public PBMAC1WithPBKDF2Builder setMac(ASN1ObjectIdentifier mac)
74+
{
75+
this.mac = mac;
76+
77+
return this;
78+
}
79+
80+
public AlgorithmIdentifier build()
81+
{
82+
if (salt != null)
83+
{
84+
throw new IllegalStateException("salt must be non-null");
85+
}
86+
87+
return new AlgorithmIdentifier(PKCSObjectIdentifiers.id_PBMAC1, new PBMAC1Params(new AlgorithmIdentifier(PKCSObjectIdentifiers.id_PBKDF2, new PBKDF2Params(salt, iterationCount, keySizeinBits, new AlgorithmIdentifier(prf))),
88+
new AlgorithmIdentifier(mac)));
89+
}
90+
}
91+
92+
public static PBMAC1WithPBKDF2Builder pbmac1WithPBKDF2Builder()
93+
{
94+
return new PBMAC1WithPBKDF2Builder();
95+
}
96+
97+
public static class Builder
98+
{
99+
private final OutputStream out;
100+
private final ProtectionParameter protectionParameter;
101+
private boolean forDEREncoding = true;
102+
private boolean overwriteFriendlyName = true;
103+
private AlgorithmIdentifier macAlgorithm = new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE);
104+
105+
private Builder(OutputStream out, ProtectionParameter protectionParameter)
106+
{
107+
this.out = out;
108+
this.protectionParameter = protectionParameter;
109+
}
110+
111+
public Builder setDEREncoding(boolean enable)
112+
{
113+
this.forDEREncoding = enable;
114+
115+
return this;
116+
}
117+
118+
public Builder setOverwriteFriendlyName(boolean enable)
119+
{
120+
this.overwriteFriendlyName = enable;
121+
122+
return this;
123+
}
124+
125+
public Builder setMacAlgorithm(AlgorithmIdentifier macAlgorithm)
126+
{
127+
this.macAlgorithm = macAlgorithm;
128+
129+
return this;
130+
}
131+
132+
public PKCS12StoreParameter build()
133+
{
134+
return new PKCS12StoreParameter(out, protectionParameter, forDEREncoding, overwriteFriendlyName, macAlgorithm);
135+
}
136+
}
137+
138+
public static Builder builder(OutputStream out, char[] password)
139+
{
140+
return builder(out, new KeyStore.PasswordProtection(password));
141+
}
142+
143+
public static Builder builder(OutputStream out, ProtectionParameter protectionParameter)
144+
{
145+
return new Builder(out, protectionParameter);
146+
}
21147

22148
public PKCS12StoreParameter(OutputStream out, char[] password)
23149
{
@@ -33,6 +159,7 @@ public PKCS12StoreParameter(OutputStream out, char[] password, boolean forDEREnc
33159
{
34160
this(out, new KeyStore.PasswordProtection(password), forDEREncoding, true);
35161
}
162+
36163
public PKCS12StoreParameter(OutputStream out, ProtectionParameter protectionParameter, boolean forDEREncoding)
37164
{
38165
this(out, protectionParameter, forDEREncoding, true);
@@ -44,11 +171,17 @@ public PKCS12StoreParameter(OutputStream out, char[] password, boolean forDEREnc
44171
}
45172

46173
public PKCS12StoreParameter(OutputStream out, ProtectionParameter protectionParameter, boolean forDEREncoding, boolean overwriteFriendlyName)
174+
{
175+
this(out, protectionParameter, forDEREncoding, overwriteFriendlyName, new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE));
176+
}
177+
178+
private PKCS12StoreParameter(OutputStream out, ProtectionParameter protectionParameter, boolean forDEREncoding, boolean overwriteFriendlyName, AlgorithmIdentifier macAlgorithm)
47179
{
48180
this.out = out;
49181
this.protectionParameter = protectionParameter;
50182
this.forDEREncoding = forDEREncoding;
51183
this.overwriteFriendlyName = overwriteFriendlyName;
184+
this.macAlgorithm = macAlgorithm;
52185
}
53186

54187
public OutputStream getOutputStream()
@@ -81,4 +214,9 @@ public boolean isOverwriteFriendlyName()
81214
{
82215
return overwriteFriendlyName;
83216
}
217+
218+
public AlgorithmIdentifier getMacAlgorithm()
219+
{
220+
return macAlgorithm;
221+
}
84222
}

0 commit comments

Comments
 (0)