Skip to content

Commit e7518c8

Browse files
zzambersjudovana
authored andcommitted
Add KDFTests
1 parent 097d16c commit e7518c8

File tree

2 files changed

+156
-0
lines changed

2 files changed

+156
-0
lines changed

cryptotest/CryptoTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
* cryptotest.tests.CipherTests
6363
* cryptotest.tests.ConfigurationTests
6464
* cryptotest.tests.GssApiMechanismTests
65+
* cryptotest.tests.KDFTests
6566
* cryptotest.tests.KEMTests
6667
* cryptotest.tests.KeyAgreementTests
6768
* cryptotest.tests.KeyFactoryTests

cryptotest/tests/KDFTests.java

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
/*
2+
* The MIT License
3+
*
4+
* Copyright 2025 Red Hat, Inc.
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in
14+
* all copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
* THE SOFTWARE.
23+
*/
24+
25+
/*
26+
* @test
27+
* @requires jdk.version.major >= 24
28+
* @modules java.base/java.security:open
29+
* java.base/sun.security.internal.spec
30+
* @bug 6666666
31+
* @library /
32+
* @build cryptotest.tests.KEMTests
33+
* cryptotest.Settings
34+
* cryptotest.utils.AlgorithmIgnoredException
35+
* cryptotest.utils.AlgorithmInstantiationException
36+
* cryptotest.utils.AlgorithmRunException
37+
* cryptotest.utils.AlgorithmTest
38+
* cryptotest.utils.KeysNaiveGenerator
39+
* cryptotest.utils.TestResult
40+
* @run main/othervm cryptotest.tests.KDFTests
41+
*/
42+
43+
package cryptotest.tests;
44+
45+
import cryptotest.utils.AlgorithmIgnoredException;
46+
import cryptotest.utils.AlgorithmInstantiationException;
47+
import cryptotest.utils.AlgorithmRunException;
48+
import cryptotest.utils.AlgorithmTest;
49+
import cryptotest.utils.KeysNaiveGenerator;
50+
import cryptotest.utils.TestResult;
51+
import java.security.*;
52+
import java.security.spec.*;
53+
import javax.crypto.*;
54+
import javax.crypto.spec.*;
55+
import java.lang.reflect.*;
56+
57+
public class KDFTests extends AlgorithmTest {
58+
59+
/**
60+
* @param args the command line arguments
61+
*/
62+
63+
public static void main(String[] args) {
64+
TestResult r = new KDFTests().mainLoop();
65+
System.out.println(r.getExplanation());
66+
System.out.println(r.toString());
67+
r.assertItself();
68+
}
69+
70+
public static Object _KDF_getInstance(String alias, Provider p) throws Exception {
71+
Class c = Class.forName("javax.crypto.KDF");
72+
Method m = c.getDeclaredMethod("getInstance", String.class, Provider.class);
73+
return m.invoke(null, alias, p);
74+
}
75+
76+
public static Object _HKDFParameterSpec_ofExtract() throws Exception {
77+
Class c = Class.forName("javax.crypto.spec.HKDFParameterSpec");
78+
Method m = c.getDeclaredMethod("ofExtract");
79+
return m.invoke(null);
80+
}
81+
82+
public static Object _Builder_addIKM(Object builder, byte[] ikm) throws Exception {
83+
Class c = Class.forName("javax.crypto.spec.HKDFParameterSpec$Builder");
84+
Method m = c.getDeclaredMethod("addIKM", byte[].class);
85+
return m.invoke(builder, ikm);
86+
}
87+
88+
public static Object _Builder_addSalt(Object builder, byte[] salt) throws Exception {
89+
Class c = Class.forName("javax.crypto.spec.HKDFParameterSpec$Builder");
90+
Method m = c.getDeclaredMethod("addSalt", byte[].class);
91+
return m.invoke(builder, salt);
92+
}
93+
94+
public static AlgorithmParameterSpec _Builder_thenExpand(Object builder, byte[] info, int size) throws Exception {
95+
Class c = Class.forName("javax.crypto.spec.HKDFParameterSpec$Builder");
96+
Method m = c.getDeclaredMethod("thenExpand", byte[].class, int.class);
97+
return (AlgorithmParameterSpec) m.invoke(builder, info, size);
98+
}
99+
100+
public static SecretKey _KDF_deriveKey(Object kdf, String alg, AlgorithmParameterSpec derivationSpec) throws Exception {
101+
Class c = Class.forName("javax.crypto.KDF");
102+
Method m = c.getDeclaredMethod("deriveKey", String.class, AlgorithmParameterSpec.class);
103+
return (SecretKey) m.invoke(kdf, alg, derivationSpec);
104+
}
105+
106+
@Override
107+
protected void checkAlgorithm(Provider.Service service, String alias) throws AlgorithmInstantiationException, AlgorithmRunException {
108+
try {
109+
Object kdf = _KDF_getInstance(alias, service.getProvider());
110+
AlgorithmParameterSpec derivationSpec = null;
111+
if (service.getAlgorithm().startsWith("HKDF")) {
112+
Object builder = _HKDFParameterSpec_ofExtract();
113+
builder = _Builder_addIKM(builder, new byte[]{1,2,3,4,5,6,7,8,9,10});
114+
builder = _Builder_addSalt(builder, new byte[]{1,2,1,2,1,2,1,2,1,2});
115+
derivationSpec = _Builder_thenExpand(builder, new byte[]{4,3,2,1}, 32);
116+
}
117+
if (derivationSpec == null) {
118+
throw new Exception("Failed to generate derivationSpec");
119+
}
120+
SecretKey sKey = _KDF_deriveKey(kdf, "AES", derivationSpec);
121+
if (sKey == null) {
122+
throw new Exception("Failed to generate secret key");
123+
}
124+
125+
/*
126+
127+
Code above uses reflection, so that it is buildable on all jdks,
128+
It is equivalent to following code:
129+
130+
KDF kdf = KDF.getInstance(alias, service.getProvider());
131+
AlgorithmParameterSpec derivationSpec = null;
132+
if (service.getAlgorithm().startsWith("HKDF")) {
133+
HKDFParameterSpec.Builder builder = HKDFParameterSpec.ofExtract();
134+
builder = builder.addIKM(new byte[]{1,2,3,4,5,6,7,8,9,10});
135+
builder = builder.addSalt(new byte[]{1,2,1,2,1,2,1,2,1,2});
136+
derivationSpec = builder.thenExpand(new byte[]{4,3,2,1}, 32);
137+
}
138+
if (derivationSpec == null) {
139+
throw new Exception("Failed to generate derivationSpec");
140+
}
141+
SecretKey sKey = kdf.deriveKey("AES", derivationSpec);
142+
if (sKey == null) {
143+
throw new Exception("Failed to generate secret key");
144+
}
145+
146+
*/
147+
} catch (AlgorithmIgnoredException aie) {
148+
throw aie;
149+
} catch (NoSuchAlgorithmException ex) {
150+
throw new AlgorithmInstantiationException(ex);
151+
} catch (Exception ex) {
152+
throw new AlgorithmRunException(ex);
153+
}
154+
}
155+
}

0 commit comments

Comments
 (0)