@@ -46,7 +46,7 @@ public void testKDF()
4646 byte [] okm = Hex .decode ("2124ffb29fac4e0fbbc7d5d87492bff3" );
4747 byte [] genOkm ;
4848 HKDFParameterSpec .ExtractThenExpand hkdfParams1 = HKDFParameterSpec .ofExtract ().addIKM (ikm )
49- .addSalt (salt ).thenExpand (info , okm .length );
49+ .addSalt (salt ).thenExpand (info , okm .length );
5050
5151 genOkm = kdfHkdf .deriveData (hkdfParams1 );
5252
@@ -77,12 +77,13 @@ public void testKDF()
7777 //kdf.init(new KDFParameter(new SHA1Digest()));
7878 //kdf.deriveData(hkdfParams);
7979 }
80+
8081 private boolean doComparison (String algorithm , byte [] ikm , byte [] salt , byte [] info )
8182 throws Exception
8283 {
8384 KDF kdf = KDF .getInstance (algorithm , "BC" );
8485 HKDFParameterSpec .ExtractThenExpand spec = HKDFParameterSpec .ofExtract ().addIKM (ikm )
85- .addSalt (salt ).thenExpand (info , ikm .length );
86+ .addSalt (salt ).thenExpand (info , ikm .length );
8687
8788 org .bouncycastle .jcajce .spec .HKDFParameterSpec pre25spec = new org .bouncycastle .jcajce .spec .HKDFParameterSpec (ikm , salt , info , ikm .length );
8889 byte [] kdfSecret = kdf .deriveData (spec );
@@ -97,7 +98,7 @@ public void testSecretKeyFactoryComparison()
9798 throws Exception
9899 {
99100 setUp ();
100- String [] algorithms = new String [] {
101+ String [] algorithms = new String []{
101102 "HKDF-SHA256" ,
102103 "HKDF-SHA384" ,
103104 "HKDF-SHA512" ,
@@ -106,12 +107,12 @@ public void testSecretKeyFactoryComparison()
106107 byte [] salt = new byte [16 ];
107108 byte [] info = new byte [16 ];
108109 SecureRandom random = new SecureRandom ();
109- for (String algorithm : algorithms )
110+ for (String algorithm : algorithms )
110111 {
111112 random .nextBytes (ikm );
112113 random .nextBytes (salt );
113114 random .nextBytes (info );
114- if (!doComparison (algorithm , ikm , salt , info ))
115+ if (!doComparison (algorithm , ikm , salt , info ))
115116 {
116117 fail ("failed to generate same secret using kdf and secret key factory for: " + algorithm );
117118 }
@@ -183,6 +184,79 @@ public void testExceptionHandling()
183184// }
184185 }
185186
187+ public void testExtractWithConcatenatedIKMAndSalts ()
188+ throws Exception
189+ {
190+ setUp ();
191+ KDF kdfHkdf = KDF .getInstance ("HKDF-SHA256" , "BC" );
192+
193+ byte [][] ikms = new byte [][]
194+ {
195+ Hex .decode ("000102030405060708090a0b0c0d0e0f" ),
196+ Hex .decode ("101112131415161718191a1b1c1d1e1f" ),
197+ Hex .decode ("202122232425262728292a2b2c2d2e2f" ),
198+ Hex .decode ("303132333435363738393a3b3c3d3e3f" ),
199+ Hex .decode ("404142434445464748494a4b4c4d4e4f" ),
200+ };
201+
202+ byte [][] salts = new byte [][]
203+ {
204+ Hex .decode ("606162636465666768696a6b6c6d6e6f" ),
205+ Hex .decode ("707172737475767778797a7b7c7d7e7f" ),
206+ Hex .decode ("808182838485868788898a8b8c8d8e8f" ),
207+ Hex .decode ("909192939495969798999a9b9c9d9e9f" ),
208+ Hex .decode ("a0a1a2a3a4a5a6a7a8a9aaabacadaeaf" ),
209+ };
210+ byte [] info = Hex .decode ("b0b1b2b3b4b5b6b7b8b9babbbcbdbebf"
211+ + "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf"
212+ + "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf"
213+ + "e0e1e2e3e4e5e6e7e8e9eaebecedeeef"
214+ + "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff" );
215+ byte [] okm = Hex .decode (
216+ "b11e398dc80327a1c8e7f78c596a4934" +
217+ "4f012eda2d4efad8a050cc4c19afa97c" +
218+ "59045a99cac7827271cb41c65e590e09" +
219+ "da3275600c2f09b8367793a9aca3db71" +
220+ "cc30c58179ec3e87c14c01d5c1f3434f" +
221+ "1d87" );
222+
223+ HKDFParameterSpec .ExtractThenExpand hkdfParams1 = HKDFParameterSpec .ofExtract ()
224+ .addIKM (ikms [0 ]).addIKM (ikms [1 ]).addIKM (ikms [2 ]).addIKM (ikms [3 ]).addIKM (ikms [4 ])
225+ .addSalt (salts [0 ]).addSalt (salts [1 ]).addSalt (salts [2 ]).addSalt (salts [3 ]).addSalt (salts [4 ])
226+ .thenExpand (info , okm .length );
227+
228+ byte [] genOkm = kdfHkdf .deriveData (hkdfParams1 );
229+
230+ if (!areEqual (genOkm , okm ))
231+ {
232+ fail ("HKDF failed for multiple ikms/salts" );
233+ }
234+
235+ HKDFParameterSpec .Extract hkdfParams2 = HKDFParameterSpec .ofExtract ()
236+ .addIKM (ikms [0 ]).addIKM (ikms [1 ]).addIKM (ikms [2 ]).addIKM (ikms [3 ]).addIKM (ikms [4 ])
237+ .addSalt (salts [0 ]).addSalt (salts [1 ]).addSalt (salts [2 ]).addSalt (salts [3 ]).addSalt (salts [4 ])
238+ .extractOnly ();
239+
240+ okm = Hex .decode ("06a6b88c5853361a06104c9ceb35b45cef760014904671014a193f40c15fc244" );
241+ genOkm = kdfHkdf .deriveData (hkdfParams2 );
242+
243+ if (!areEqual (genOkm , okm ))
244+ {
245+ fail ("HKDF failed for multiple ikms/salts" );
246+ }
247+ }
248+
249+ /**
250+ * Helper method to concatenate two byte arrays.
251+ */
252+ private byte [] concatenate (byte [] first , byte [] second )
253+ {
254+ byte [] result = new byte [first .length + second .length ];
255+ System .arraycopy (first , 0 , result , 0 , first .length );
256+ System .arraycopy (second , 0 , result , first .length , second .length );
257+ return result ;
258+ }
259+
186260 private static class InvalidKDFParameters
187261 implements KDFParameters
188262 {
0 commit comments