Skip to content

Commit 72b2fd7

Browse files
committed
moved spec classes to org.bouncycastle.jcajce.spec
removed HKDFParameterSpec in favor of Java 25 one added support for extract only to HKDFSpi.
1 parent 09c9e9c commit 72b2fd7

File tree

10 files changed

+98
-54
lines changed

10 files changed

+98
-54
lines changed

prov/src/main/jdk25/org/bouncycastle/jcajce/provider/kdf/hkdf/HKDFParameterSpec.java

Lines changed: 0 additions & 15 deletions
This file was deleted.

prov/src/main/jdk25/org/bouncycastle/jcajce/provider/kdf/hkdf/HKDFSpi.java

Lines changed: 65 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,26 @@
1111
import javax.crypto.KDFSpi;
1212
import javax.crypto.SecretKey;
1313
import javax.crypto.spec.SecretKeySpec;
14+
import javax.crypto.spec.HKDFParameterSpec;
15+
1416
import java.security.InvalidAlgorithmParameterException;
1517
import java.security.NoSuchAlgorithmException;
1618
import java.security.spec.AlgorithmParameterSpec;
19+
import java.util.List;
1720

1821
class HKDFSpi
19-
extends KDFSpi
22+
extends KDFSpi
2023
{
2124
protected HKDFBytesGenerator hkdf;
25+
2226
public HKDFSpi(KDFParameters kdfParameters)
23-
throws InvalidAlgorithmParameterException
27+
throws InvalidAlgorithmParameterException
2428
{
2529
super(kdfParameters);
2630
}
2731

2832
public HKDFSpi(KDFParameters kdfParameters, Digest digest)
29-
throws InvalidAlgorithmParameterException
33+
throws InvalidAlgorithmParameterException
3034
{
3135
super(kdfParameters);
3236
this.hkdf = new HKDFBytesGenerator(digest);
@@ -53,62 +57,101 @@ protected KDFParameters engineGetParameters()
5357

5458
@Override
5559
protected SecretKey engineDeriveKey(String alg, AlgorithmParameterSpec derivationSpec)
56-
throws InvalidAlgorithmParameterException, NoSuchAlgorithmException
60+
throws InvalidAlgorithmParameterException, NoSuchAlgorithmException
5761
{
5862
byte[] derivedKey = engineDeriveData(derivationSpec);
5963

6064
return new SecretKeySpec(derivedKey, alg);
6165
}
66+
6267
@Override
6368
protected byte[] engineDeriveData(AlgorithmParameterSpec derivationSpec)
64-
throws InvalidAlgorithmParameterException
69+
throws InvalidAlgorithmParameterException
6570
{
66-
if (derivationSpec == null || !(derivationSpec instanceof HKDFParameters))
71+
if (derivationSpec == null || !(derivationSpec instanceof HKDFParameterSpec))
6772
{
68-
throw new InvalidAlgorithmParameterException("Invalid AlgorithmParameterSpec provided");
73+
throw new InvalidAlgorithmParameterException("invalid AlgorithmParameterSpec provided");
6974
}
7075

71-
HKDFParameters hkdfParameters = (HKDFParameters) derivationSpec;
72-
int derivedDataLength = hkdfParameters.getIKM().length;
76+
// TODO: deal with the multi ikm/salt thing
77+
HKDFParameters hkdfParameters = null;
78+
int derivedDataLength = 0;
79+
if (derivationSpec instanceof HKDFParameterSpec.ExtractThenExpand)
80+
{
81+
HKDFParameterSpec.ExtractThenExpand spec = (HKDFParameterSpec.ExtractThenExpand)derivationSpec;
82+
83+
List<SecretKey> ikms = spec.ikms();
84+
List<SecretKey> salts = spec.salts();
85+
86+
hkdfParameters = new HKDFParameters(ikms.get(0).getEncoded(), salts.get(0).getEncoded(), spec.info());
87+
derivedDataLength = spec.length();
7388

74-
hkdf.init(hkdfParameters);
89+
hkdf.init(hkdfParameters);
7590

76-
byte[] derivedData = new byte[derivedDataLength];
77-
hkdf.generateBytes(derivedData, 0, derivedDataLength);
91+
byte[] derivedData = new byte[derivedDataLength];
92+
hkdf.generateBytes(derivedData, 0, derivedDataLength);
7893

79-
return derivedData;
94+
return derivedData;
95+
}
96+
else if (derivationSpec instanceof HKDFParameterSpec.Extract)
97+
{
98+
HKDFParameterSpec.Extract spec = (HKDFParameterSpec.Extract)derivationSpec;
99+
100+
List<SecretKey> ikms = spec.ikms();
101+
List<SecretKey> salts = spec.salts();
102+
103+
return hkdf.extractPRK(salts.get(0).getEncoded(), ikms.get(0).getEncoded());
104+
}
105+
else
106+
{
107+
throw new InvalidAlgorithmParameterException("invalid HKDFParameterSpec provided");
108+
}
80109
}
81110

82-
public static class HKDFwithSHA256 extends HKDFSpi
111+
public static class HKDFwithSHA256
112+
extends HKDFSpi
83113
{
84-
public HKDFwithSHA256() throws InvalidAlgorithmParameterException
114+
public HKDFwithSHA256()
115+
throws InvalidAlgorithmParameterException
85116
{
86117
super(null, new SHA256Digest());
87118
}
88-
public HKDFwithSHA256(KDFParameters kdfParameters) throws InvalidAlgorithmParameterException
119+
120+
public HKDFwithSHA256(KDFParameters kdfParameters)
121+
throws InvalidAlgorithmParameterException
89122
{
90123
super(kdfParameters, new SHA256Digest());
91124
}
92125
}
93-
public static class HKDFwithSHA384 extends HKDFSpi
126+
127+
public static class HKDFwithSHA384
128+
extends HKDFSpi
94129
{
95-
public HKDFwithSHA384() throws InvalidAlgorithmParameterException
130+
public HKDFwithSHA384()
131+
throws InvalidAlgorithmParameterException
96132
{
97133
super(null, new SHA384Digest());
98134
}
99-
public HKDFwithSHA384(KDFParameters kdfParameters) throws InvalidAlgorithmParameterException
135+
136+
public HKDFwithSHA384(KDFParameters kdfParameters)
137+
throws InvalidAlgorithmParameterException
100138
{
101139
super(kdfParameters, new SHA384Digest());
102140
}
103141
}
104-
public static class HKDFwithSHA512 extends HKDFSpi
142+
143+
public static class HKDFwithSHA512
144+
extends HKDFSpi
105145
{
106146

107-
public HKDFwithSHA512() throws InvalidAlgorithmParameterException
147+
public HKDFwithSHA512()
148+
throws InvalidAlgorithmParameterException
108149
{
109150
super(null, new SHA512Digest());
110151
}
111-
public HKDFwithSHA512(KDFParameters kdfParameters) throws InvalidAlgorithmParameterException
152+
153+
public HKDFwithSHA512(KDFParameters kdfParameters)
154+
throws InvalidAlgorithmParameterException
112155
{
113156
super(kdfParameters, new SHA512Digest());
114157
}

prov/src/main/jdk25/org/bouncycastle/jcajce/provider/kdf/pbepbkdf2/PBEPBKDF2Spi.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import org.bouncycastle.crypto.digests.SM3Digest;
1212
import org.bouncycastle.crypto.generators.PKCS5S2ParametersGenerator;
1313
import org.bouncycastle.crypto.params.KeyParameter;
14+
import org.bouncycastle.jcajce.spec.PBEPBKDF2ParameterSpec;
1415
import org.bouncycastle.util.Arrays;
1516

1617
import javax.crypto.KDFParameters;

prov/src/main/jdk25/org/bouncycastle/jcajce/provider/kdf/scrypt/SCryptSpi.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import org.bouncycastle.crypto.PasswordConverter;
44
import org.bouncycastle.crypto.generators.SCrypt;
55
import org.bouncycastle.jcajce.spec.ScryptKeySpec;
6+
import org.bouncycastle.jcajce.spec.ScryptParameterSpec;
67
import org.bouncycastle.util.Arrays;
78

89
import javax.crypto.KDFParameters;
@@ -44,7 +45,7 @@ protected SecretKey engineDeriveKey(String alg, AlgorithmParameterSpec derivatio
4445
protected byte[] engineDeriveData(AlgorithmParameterSpec derivationSpec)
4546
throws InvalidAlgorithmParameterException
4647
{
47-
if (!(derivationSpec instanceof SCryptParameterSpec))
48+
if (!(derivationSpec instanceof ScryptParameterSpec))
4849
{
4950
throw new InvalidAlgorithmParameterException(
5051
"SCrypt requires an SCryptParameterSpec as derivation parameters");

prov/src/main/jdk25/org/bouncycastle/jcajce/provider/kdf/pbepbkdf2/PBEPBKDF2ParameterSpec.java renamed to prov/src/main/jdk25/org/bouncycastle/jcajce/spec/PBEPBKDF2ParameterSpec.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package org.bouncycastle.jcajce.provider.kdf.pbepbkdf2;
1+
package org.bouncycastle.jcajce.spec;
22

33
import javax.crypto.spec.PBEKeySpec;
44
import java.security.spec.AlgorithmParameterSpec;

prov/src/main/jdk25/org/bouncycastle/jcajce/provider/kdf/scrypt/SCryptParameterSpec.java renamed to prov/src/main/jdk25/org/bouncycastle/jcajce/spec/ScryptParameterSpec.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
package org.bouncycastle.jcajce.provider.kdf.scrypt;
1+
package org.bouncycastle.jcajce.spec;
22

33
import org.bouncycastle.jcajce.spec.ScryptKeySpec;
44

55
import java.security.spec.AlgorithmParameterSpec;
66

7-
public class SCryptParameterSpec
7+
public class ScryptParameterSpec
88
extends ScryptKeySpec
99
implements AlgorithmParameterSpec
1010
{
11-
public SCryptParameterSpec(char[] password, byte[] salt, int costParameter, int blockSize, int parallelizationParameter, int keySize)
11+
public ScryptParameterSpec(char[] password, byte[] salt, int costParameter, int blockSize, int parallelizationParameter, int keySize)
1212
{
1313
super(password, salt, costParameter, blockSize, parallelizationParameter, keySize);
1414
}

prov/src/test/jdk25/org/bouncycastle/jcajce/provider/kdf/test/AllTests25.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ public static Test suite()
1818
TestSuite suite = new TestSuite("JDK25 Provider Tests");
1919
suite.addTestSuite(HKDFTest.class);
2020
suite.addTestSuite(PBEPBKDF2Test.class);
21-
suite.addTestSuite(SCryptTest.class);
21+
suite.addTestSuite(ScryptTest.class);
2222
return suite;
2323
}
2424
}

prov/src/test/jdk25/org/bouncycastle/jcajce/provider/kdf/test/HKDFTest.java

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import org.bouncycastle.jce.provider.BouncyCastleProvider;
55
import org.bouncycastle.util.Strings;
66
import org.bouncycastle.util.encoders.Hex;
7-
import org.bouncycastle.jcajce.provider.kdf.hkdf.HKDFParameterSpec;
7+
import javax.crypto.spec.HKDFParameterSpec;
88

99
import javax.crypto.KDF;
1010

@@ -35,15 +35,29 @@ public void testKDF()
3535
byte[] info = Hex.decode("301b0609608648016503040106300e040c5c79058ba2f43447639d29e2");
3636
byte[] okm = Hex.decode("2124ffb29fac4e0fbbc7d5d87492bff3");
3737
byte[] genOkm;
38-
HKDFParameterSpec hkdfParams = new HKDFParameterSpec(ikm, salt, info);
38+
HKDFParameterSpec.ExtractThenExpand hkdfParams1 = HKDFParameterSpec.ofExtract().addIKM(ikm)
39+
.addSalt(salt).thenExpand(info, okm.length);
3940

40-
genOkm = kdfHkdf.deriveData(hkdfParams);
41+
genOkm = kdfHkdf.deriveData(hkdfParams1);
4142

4243
if (!areEqual(genOkm, okm))
4344
{
4445
fail("HKDF failed generator test");
4546
}
4647

48+
// Extract Only
49+
ikm = Hex.decode("c702e7d0a9e064b09ba55245fb733cf3");
50+
salt = Strings.toByteArray("The Cryptographic Message Syntax");
51+
okm = Hex.decode("4d757351dc7a354f041aacd288c8957e341ac8903ba8b4debde8e856f1b58e31");
52+
53+
HKDFParameterSpec.Extract hkdfParams2 = HKDFParameterSpec.ofExtract().addIKM(ikm).addSalt(salt).extractOnly();
54+
55+
genOkm = kdfHkdf.deriveData(hkdfParams2);
56+
57+
if (!areEqual(genOkm, okm))
58+
{
59+
fail("HKDF failed generator test");
60+
}
4761
//TODO: make test for derived keys
4862
// kdfHkdf.deriveKey("AES", hkdfParams);
4963

prov/src/test/jdk25/org/bouncycastle/jcajce/provider/kdf/test/PBEPBKDF2Test.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package org.bouncycastle.jcajce.provider.kdf.test;
22

33
import junit.framework.TestCase;
4-
import org.bouncycastle.jcajce.provider.kdf.pbepbkdf2.PBEPBKDF2ParameterSpec;
4+
import org.bouncycastle.jcajce.spec.PBEPBKDF2ParameterSpec;
55
import org.bouncycastle.jce.provider.BouncyCastleProvider;
66
import org.bouncycastle.util.encoders.Hex;
77

prov/src/test/jdk25/org/bouncycastle/jcajce/provider/kdf/test/SCryptTest.java renamed to prov/src/test/jdk25/org/bouncycastle/jcajce/provider/kdf/test/ScryptTest.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package org.bouncycastle.jcajce.provider.kdf.test;
22

33
import junit.framework.TestCase;
4-
import org.bouncycastle.jcajce.provider.kdf.scrypt.SCryptParameterSpec;
4+
import org.bouncycastle.jcajce.spec.ScryptParameterSpec;
55
import org.bouncycastle.jce.provider.BouncyCastleProvider;
66
import org.bouncycastle.util.Strings;
77
import org.bouncycastle.util.encoders.Hex;
@@ -11,7 +11,7 @@
1111

1212
import static org.bouncycastle.util.Arrays.areEqual;
1313

14-
public class SCryptTest
14+
public class ScryptTest
1515
extends TestCase
1616
{
1717
public void setUp()
@@ -26,10 +26,10 @@ public void testKDF()
2626
throws Exception
2727
{
2828
setUp();
29-
KDF kdf = KDF.getInstance("SCrypt", "BC");
29+
KDF kdf = KDF.getInstance("Scrypt", "BC");
3030

3131
byte[] expected = Hex.decode("77d6576238657b203b19ca42c18a0497f16b4844e3074ae8dfdffa3fede21442fcd0069ded0948f8326a753a0fc81f17e8d3e0fb2e0d3628cf35e20c38d18906");
32-
SCryptParameterSpec spec = new SCryptParameterSpec(
32+
ScryptParameterSpec spec = new ScryptParameterSpec(
3333
"".toCharArray(),
3434
Strings.toByteArray(""),
3535
16,
@@ -43,7 +43,7 @@ public void testKDF()
4343
}
4444

4545
expected = Hex.decode("fdbabe1c9d3472007856e7190d01e9fe7c6ad7cbc8237830e77376634b3731622eaf30d92e22a3886ff109279d9830dac727afb94a83ee6d8360cbdfa2cc0640");
46-
spec = new SCryptParameterSpec(
46+
spec = new ScryptParameterSpec(
4747
"password".toCharArray(),
4848
Strings.toByteArray("NaCl"),
4949
1024,
@@ -57,7 +57,7 @@ public void testKDF()
5757
}
5858

5959
expected = Hex.decode("7023bdcb3afd7348461c06cd81fd38ebfda8fbba904f8e3ea9b543f6545da1f2d5432955613f0fcf62d49705242a9af9e61e85dc0d651e40dfcf017b45575887");
60-
spec = new SCryptParameterSpec(
60+
spec = new ScryptParameterSpec(
6161
"pleaseletmein".toCharArray(),
6262
Strings.toByteArray("SodiumChloride"),
6363
16384,
@@ -71,7 +71,7 @@ public void testKDF()
7171
}
7272

7373
expected = Hex.decode("2101cb9b6a511aaeaddbbe09cf70f881ec568d574a2ffd4dabe5ee9820adaa478e56fd8f4ba5d09ffa1c6d927c40f4c337304049e8a952fbcbf45c6fa77a41a4");
74-
spec = new SCryptParameterSpec(
74+
spec = new ScryptParameterSpec(
7575
"pleaseletmein".toCharArray(),
7676
Strings.toByteArray("SodiumChloride"),
7777
1048576,

0 commit comments

Comments
 (0)