Skip to content

Commit 22794e1

Browse files
committed
Further KDF work.
1 parent 75eb3fb commit 22794e1

File tree

11 files changed

+784
-144
lines changed

11 files changed

+784
-144
lines changed
Lines changed: 60 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,106 +1,107 @@
11
package org.bouncycastle.jcajce.provider.symmetric;
22

3+
import java.security.InvalidAlgorithmParameterException;
4+
import java.security.spec.InvalidKeySpecException;
5+
import java.security.spec.KeySpec;
6+
7+
import javax.crypto.SecretKey;
8+
9+
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
10+
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
311
import org.bouncycastle.crypto.CipherParameters;
4-
import org.bouncycastle.crypto.DerivationFunction;
512
import org.bouncycastle.crypto.Digest;
613
import org.bouncycastle.crypto.digests.SHA256Digest;
714
import org.bouncycastle.crypto.digests.SHA384Digest;
815
import org.bouncycastle.crypto.digests.SHA512Digest;
916
import org.bouncycastle.crypto.generators.HKDFBytesGenerator;
1017
import org.bouncycastle.crypto.params.HKDFParameters;
1118
import org.bouncycastle.crypto.params.KeyParameter;
12-
import org.bouncycastle.internal.asn1.misc.MiscObjectIdentifiers;
1319
import org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
1420
import org.bouncycastle.jcajce.provider.symmetric.util.BCPBEKey;
21+
import org.bouncycastle.jcajce.provider.symmetric.util.BaseSecretKeyFactory;
1522
import org.bouncycastle.jcajce.provider.util.AlgorithmProvider;
23+
import org.bouncycastle.jcajce.spec.HKDFParameterSpec;
1624

17-
import javax.crypto.SecretKey;
18-
import javax.crypto.SecretKeyFactorySpi;
19-
import java.security.InvalidAlgorithmParameterException;
20-
import java.security.InvalidKeyException;
21-
import java.security.spec.InvalidKeySpecException;
22-
import java.security.spec.KeySpec;
23-
24-
public class HKDF extends SecretKeyFactorySpi
25+
public class HKDF
2526
{
26-
protected String algName;
27-
protected HKDFBytesGenerator hkdf;
28-
29-
30-
private HKDF(String algName, Digest digest)
27+
private HKDF()
3128
{
32-
this.algName = algName;
33-
this.hkdf = new HKDFBytesGenerator(digest);
29+
3430
}
3531

36-
@Override
37-
protected SecretKey engineGenerateSecret(KeySpec keySpec) throws InvalidKeySpecException
32+
public static class HKDFBase
33+
extends BaseSecretKeyFactory
3834
{
39-
HKDFParameters hkdfParameters = (HKDFParameters) keySpec;
40-
int derivedDataLength = hkdfParameters.getIKM().length;
41-
hkdf.init(hkdfParameters);
35+
protected String algName;
36+
protected HKDFBytesGenerator hkdf;
4237

43-
byte[] derivedData = new byte[derivedDataLength];
44-
hkdf.generateBytes(derivedData, 0, derivedDataLength);
4538

46-
CipherParameters param = new KeyParameter(derivedData);
39+
public HKDFBase(String algName, Digest digest, ASN1ObjectIdentifier oid)
40+
{
41+
super(algName, oid);
42+
this.algName = algName;
43+
this.hkdf = new HKDFBytesGenerator(digest);
44+
}
4745

48-
return new BCPBEKey(this.algName, param) ;
49-
}
46+
@Override
47+
protected SecretKey engineGenerateSecret(KeySpec keySpec)
48+
throws InvalidKeySpecException
49+
{
50+
HKDFParameterSpec spec = (HKDFParameterSpec)keySpec;
51+
int derivedDataLength = spec.getOutputLength();
52+
hkdf.init(new HKDFParameters(spec.getIKM(), spec.getSalt(), spec.getInfo()));
53+
54+
byte[] derivedData = new byte[derivedDataLength];
55+
hkdf.generateBytes(derivedData, 0, derivedDataLength);
5056

57+
CipherParameters param = new KeyParameter(derivedData);
5158

52-
@Override
53-
protected KeySpec engineGetKeySpec(SecretKey key, Class<?> keySpec) throws InvalidKeySpecException
59+
return new BCPBEKey(this.algName, param);
60+
}
61+
}
62+
63+
public static class HKDFwithSHA256
64+
extends HKDFBase
5465
{
55-
return null;
66+
public HKDFwithSHA256() throws InvalidAlgorithmParameterException
67+
{
68+
super("HKDF-SHA256", new SHA256Digest(), PKCSObjectIdentifiers.id_alg_hkdf_with_sha256);
69+
}
5670
}
5771

58-
@Override
59-
protected SecretKey engineTranslateKey(SecretKey key) throws InvalidKeyException
72+
public static class HKDFwithSHA384
73+
extends HKDFBase
6074
{
61-
return null;
75+
public HKDFwithSHA384() throws InvalidAlgorithmParameterException
76+
{
77+
super("HKDF-SHA384", new SHA384Digest(), PKCSObjectIdentifiers.id_alg_hkdf_with_sha384);
78+
}
6279
}
6380

81+
public static class HKDFwithSHA512
82+
extends HKDFBase
83+
{
84+
85+
public HKDFwithSHA512() throws InvalidAlgorithmParameterException
86+
{
87+
super("HKDF-SHA512", new SHA512Digest(), PKCSObjectIdentifiers.id_alg_hkdf_with_sha512);
88+
}
89+
}
6490

6591
public static class Mappings
6692
extends AlgorithmProvider
6793
{
68-
private static final String PREFIX = SCRYPT.class.getName();
94+
private static final String PREFIX = HKDF.class.getName();
6995

7096
public Mappings()
7197
{
7298
}
7399

74100
public void configure(ConfigurableProvider provider)
75101
{
76-
provider.addAlgorithm("SecretKeyFactory.HKDF", PREFIX + "HKDF");
77102
provider.addAlgorithm("SecretKeyFactory.HKDF-SHA256", PREFIX + "$HKDFwithSHA256");
78103
provider.addAlgorithm("SecretKeyFactory.HKDF-SHA384", PREFIX + "$HKDFwithSHA384");
79104
provider.addAlgorithm("SecretKeyFactory.HKDF-SHA512", PREFIX + "$HKDFwithSHA512");
80-
81-
}
82-
}
83-
public static class HKDFwithSHA256 extends HKDF
84-
{
85-
public HKDFwithSHA256() throws InvalidAlgorithmParameterException
86-
{
87-
super("HKDF-SHA256", new SHA256Digest());
88-
}
89-
}
90-
public static class HKDFwithSHA384 extends HKDF
91-
{
92-
public HKDFwithSHA384() throws InvalidAlgorithmParameterException
93-
{
94-
super("HKDF-SHA384", new SHA384Digest());
95-
}
96-
}
97-
public static class HKDFwithSHA512 extends HKDF
98-
{
99-
100-
public HKDFwithSHA512() throws InvalidAlgorithmParameterException
101-
{
102-
super("HKDF-SHA512", new SHA512Digest());
103105
}
104106
}
105-
106107
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package org.bouncycastle.jcajce.spec;
2+
3+
import java.security.spec.AlgorithmParameterSpec;
4+
import java.security.spec.KeySpec;
5+
6+
import org.bouncycastle.crypto.params.HKDFParameters;
7+
8+
public class HKDFParameterSpec
9+
implements KeySpec, AlgorithmParameterSpec
10+
{
11+
private final HKDFParameters hkdfParameters;
12+
private final int outputLength;
13+
14+
public HKDFParameterSpec(byte[] ikm, byte[] salt, byte[] info, int outputLength)
15+
{
16+
this.hkdfParameters = new HKDFParameters(ikm, salt, info);
17+
this.outputLength = outputLength;
18+
}
19+
20+
/**
21+
* Returns the input keying material or seed.
22+
*
23+
* @return the keying material
24+
*/
25+
public byte[] getIKM()
26+
{
27+
return hkdfParameters.getIKM();
28+
}
29+
30+
/**
31+
* Returns if step 1: extract has to be skipped or not
32+
*
33+
* @return true for skipping, false for no skipping of step 1
34+
*/
35+
public boolean skipExtract()
36+
{
37+
return hkdfParameters.skipExtract();
38+
}
39+
40+
/**
41+
* Returns the salt, or null if the salt should be generated as a byte array
42+
* of HashLen zeros.
43+
*
44+
* @return the salt, or null
45+
*/
46+
public byte[] getSalt()
47+
{
48+
return hkdfParameters.getSalt();
49+
}
50+
51+
/**
52+
* Returns the info field, which may be empty (null is converted to empty).
53+
*
54+
* @return the info field, never null
55+
*/
56+
public byte[] getInfo()
57+
{
58+
return hkdfParameters.getInfo();
59+
}
60+
61+
/**
62+
* Returns the length (in bytes) of the output resulting from these parameters.
63+
*
64+
* @return output length, in bytes.
65+
*/
66+
public int getOutputLength()
67+
{
68+
return outputLength;
69+
}
70+
}

prov/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProvider.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ public final class BouncyCastleProvider extends Provider
9595

9696
private static final String[] SYMMETRIC_GENERIC =
9797
{
98-
"PBEPBKDF1", "PBEPBKDF2", "PBEPKCS12", "TLSKDF", "SCRYPT"
98+
"PBEPBKDF1", "PBEPBKDF2", "PBEPKCS12", "TLSKDF", "SCRYPT", "HKDF"
9999
};
100100

101101
private static final String[] SYMMETRIC_MACS =

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public void configure(ConfigurableProvider provider)
1919
{
2020
// provider.addAlgorithm("AlgorithmParameters.PBKDF2", PREFIX + "PBEPBKDF2Spi$AlgParams");
2121
// provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + PKCSObjectIdentifiers.id_PBKDF2, "PBKDF2");
22-
provider.addAlgorithm("KDF.PBEPBKDF2", PREFIX + "PBEPBKDF2Spi$PBKDF2withUTF8");
22+
provider.addAlgorithm("KDF.PBKDF2", PREFIX + "PBEPBKDF2Spi$PBKDF2withUTF8");
2323
provider.addAlgorithm("Alg.Alias.KDF.PBKDF2WITHHMACSHA1", "PBKDF2");
2424
provider.addAlgorithm("Alg.Alias.KDF.PBKDF2WITHHMACSHA1ANDUTF8", "PBKDF2");
2525
provider.addAlgorithm("Alg.Alias.KDF." + PKCSObjectIdentifiers.id_PBKDF2, "PBKDF2");

0 commit comments

Comments
 (0)