11package org .bouncycastle .crypto .test ;
22
3+ import java .security .SecureRandom ;
4+
35import org .bouncycastle .crypto .BlockCipher ;
46import org .bouncycastle .crypto .BufferedBlockCipher ;
57import org .bouncycastle .crypto .CipherParameters ;
1416import org .bouncycastle .crypto .modes .SICBlockCipher ;
1517import org .bouncycastle .crypto .params .KeyParameter ;
1618import org .bouncycastle .crypto .params .ParametersWithIV ;
19+ import org .bouncycastle .util .Arrays ;
1720import org .bouncycastle .util .encoders .Hex ;
1821import org .bouncycastle .util .test .SimpleTest ;
1922
2326public class CTSTest
2427 extends SimpleTest
2528{
26- static byte [] in1 = Hex .decode ("4e6f7720697320746865207420" );
27- static byte [] in2 = Hex .decode ("000102030405060708090a0b0c0d0e0fff0102030405060708090a0b0c0d0e0f0aaa" );
28- static byte [] out1 = Hex .decode ("9952f131588465033fa40e8a98" );
29- static byte [] out2 = Hex .decode ("358f84d01eb42988dc34efb994" );
30- static byte [] out3 = Hex .decode ("170171cfad3f04530c509b0c1f0be0aefbd45a8e3755a873bff5ea198504b71683c6" );
31-
29+ static byte [] in1 = Hex .decode ("4e6f7720697320746865207420" );
30+ static byte [] in2 = Hex .decode ("000102030405060708090a0b0c0d0e0fff0102030405060708090a0b0c0d0e0f0aaa" );
31+ static byte [] out1 = Hex .decode ("9952f131588465033fa40e8a98" );
32+ static byte [] out2 = Hex .decode ("358f84d01eb42988dc34efb994" );
33+ static byte [] out3 = Hex .decode ("170171cfad3f04530c509b0c1f0be0aefbd45a8e3755a873bff5ea198504b71683c6" );
34+
3235 private void testCTS (
33- int id ,
34- BlockCipher cipher ,
35- CipherParameters params ,
36- byte [] input ,
37- byte [] output )
36+ int id ,
37+ BlockCipher cipher ,
38+ CipherParameters params ,
39+ byte [] input ,
40+ byte [] output )
3841 throws Exception
3942 {
40- byte [] out = new byte [input .length ];
41- BufferedBlockCipher engine = new CTSBlockCipher (cipher );
43+ byte [] out = new byte [input .length ];
44+ BufferedBlockCipher engine = new CTSBlockCipher (cipher );
4245
4346 engine .init (true , params );
4447
@@ -64,15 +67,15 @@ private void testCTS(
6467 }
6568
6669 private void testOldCTS (
67- int id ,
68- BlockCipher cipher ,
69- CipherParameters params ,
70- byte [] input ,
71- byte [] output )
72- throws Exception
70+ int id ,
71+ BlockCipher cipher ,
72+ CipherParameters params ,
73+ byte [] input ,
74+ byte [] output )
75+ throws Exception
7376 {
74- byte [] out = new byte [input .length ];
75- BufferedBlockCipher engine = new OldCTSBlockCipher (cipher );
77+ byte [] out = new byte [input .length ];
78+ BufferedBlockCipher engine = new OldCTSBlockCipher (cipher );
7679
7780 engine .init (true , params );
7881
@@ -97,77 +100,121 @@ private void testOldCTS(
97100 }
98101 }
99102
100- private void testExceptions () throws InvalidCipherTextException
103+ private void testExceptions ()
104+ throws InvalidCipherTextException
101105 {
102106 BufferedBlockCipher engine = new CTSBlockCipher (new DESEngine ());
103107 CipherParameters params = new KeyParameter (new byte [engine .getBlockSize ()]);
104108 engine .init (true , params );
105109
106110 byte [] out = new byte [engine .getOutputSize (engine .getBlockSize ())];
107-
111+
108112 engine .processBytes (new byte [engine .getBlockSize () - 1 ], 0 , engine .getBlockSize () - 1 , out , 0 );
109- try
113+ try
110114 {
111115 engine .doFinal (out , 0 );
112116 fail ("Expected CTS encrypt error on < 1 block input" );
113- } catch (DataLengthException e )
117+ }
118+ catch (DataLengthException e )
114119 {
115120 // Expected
116121 }
117122
118123 engine .init (true , params );
119124 engine .processBytes (new byte [engine .getBlockSize ()], 0 , engine .getBlockSize (), out , 0 );
120- try
125+ try
121126 {
122127 engine .doFinal (out , 0 );
123- } catch (DataLengthException e )
128+ }
129+ catch (DataLengthException e )
124130 {
125131 fail ("Unexpected CTS encrypt error on == 1 block input" );
126132 }
127133
128134 engine .init (false , params );
129135 engine .processBytes (new byte [engine .getBlockSize () - 1 ], 0 , engine .getBlockSize () - 1 , out , 0 );
130- try
136+ try
131137 {
132138 engine .doFinal (out , 0 );
133139 fail ("Expected CTS decrypt error on < 1 block input" );
134- } catch (DataLengthException e )
140+ }
141+ catch (DataLengthException e )
135142 {
136143 // Expected
137144 }
138145
139146 engine .init (false , params );
140147 engine .processBytes (new byte [engine .getBlockSize ()], 0 , engine .getBlockSize (), out , 0 );
141- try
148+ try
142149 {
143150 engine .doFinal (out , 0 );
144- } catch (DataLengthException e )
151+ }
152+ catch (DataLengthException e )
145153 {
146154 fail ("Unexpected CTS decrypt error on == 1 block input" );
147155 }
148156
149- try
157+ try
150158 {
151159 new CTSBlockCipher (SICBlockCipher .newInstance (AESEngine .newInstance ()));
152160 fail ("Expected CTS construction error - only ECB/CBC supported." );
153- } catch (IllegalArgumentException e )
161+ }
162+ catch (IllegalArgumentException e )
154163 {
155164 // Expected
156165 }
157166
158167 }
159168
169+ private void testOverlapping ()
170+ throws Exception
171+ {
172+ //Skip the dofinal of the test
173+ CTSBlockCipher bc = new CTSBlockCipher (AESEngine .newInstance ());
174+ SecureRandom random = new SecureRandom ();
175+ byte [] keyBytes = new byte [16 ];
176+ random .nextBytes (keyBytes );
177+ KeyParameter key = new KeyParameter (keyBytes );
178+
179+ int offset = 1 + random .nextInt (bc .getBlockSize () - 1 ) + bc .getBlockSize ();
180+ byte [] data = new byte [bc .getBlockSize () * 4 + offset ];
181+ byte [] expected = new byte [bc .getOutputSize (bc .getBlockSize () * 3 )];
182+ random .nextBytes (data );
183+
184+ bc .init (true , key );
185+ int len = bc .processBytes (data , 0 , expected .length , expected , 0 );
186+ bc .doFinal (expected , len );
187+ bc .init (true , key );
188+ len = bc .processBytes (data , 0 , expected .length , data , offset );
189+ bc .doFinal (data , offset + len );
190+
191+ if (!areEqual (expected , Arrays .copyOfRange (data , offset , offset + expected .length )))
192+ {
193+ fail ("failed to overlapping of encryption" );
194+ }
195+
196+ bc .init (false , key );
197+ bc .processBytes (data , 0 , expected .length , expected , 0 );
198+ bc .init (false , key );
199+ bc .processBytes (data , 0 , expected .length , data , offset );
200+
201+ if (!areEqual (expected , Arrays .copyOfRange (data , offset , offset + expected .length )))
202+ {
203+ fail ("failed to overlapping of encryption" );
204+ }
205+ }
206+
160207 public String getName ()
161208 {
162209 return "CTS" ;
163210 }
164211
165- public void performTest ()
212+ public void performTest ()
166213 throws Exception
167214 {
168- byte [] key1 = { (byte )0x01 , (byte )0x23 , (byte )0x45 , (byte )0x67 , (byte )0x89 , (byte )0xAB , (byte )0xCD , (byte )0xEF };
169- byte [] key2 = { (byte )0x01 , (byte )0x23 , (byte )0x45 , (byte )0x67 , (byte )0x89 , (byte )0xAB , (byte )0xCD , (byte )0xEF , (byte )0xee , (byte )0xff };
170- byte [] iv = { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 };
215+ byte [] key1 = {(byte )0x01 , (byte )0x23 , (byte )0x45 , (byte )0x67 , (byte )0x89 , (byte )0xAB , (byte )0xCD , (byte )0xEF };
216+ byte [] key2 = {(byte )0x01 , (byte )0x23 , (byte )0x45 , (byte )0x67 , (byte )0x89 , (byte )0xAB , (byte )0xCD , (byte )0xEF , (byte )0xee , (byte )0xff };
217+ byte [] iv = {1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 };
171218
172219 testCTS (1 , new DESEngine (), new KeyParameter (key1 ), in1 , out1 );
173220 testCTS (2 , new CBCBlockCipher (new DESEngine ()), new ParametersWithIV (new KeyParameter (key1 ), iv ), in1 , out2 );
@@ -177,11 +224,11 @@ public void performTest()
177224 // test vectors from rfc3962
178225 //
179226 byte [] aes128 = Hex .decode ("636869636b656e207465726979616b69" );
180- byte [] aesIn1 = Hex .decode ("4920776f756c64206c696b652074686520" );
227+ byte [] aesIn1 = Hex .decode ("4920776f756c64206c696b652074686520" );
181228 byte [] aesOut1 = Hex .decode ("c6353568f2bf8cb4d8a580362da7ff7f97" );
182- byte [] aesIn2 = Hex .decode ("4920776f756c64206c696b65207468652047656e6572616c20476175277320" );
229+ byte [] aesIn2 = Hex .decode ("4920776f756c64206c696b65207468652047656e6572616c20476175277320" );
183230 byte [] aesOut2 = Hex .decode ("fc00783e0efdb2c1d445d4c8eff7ed2297687268d6ecccc0c07b25e25ecfe5" );
184- byte [] aesIn3 = Hex .decode ("4920776f756c64206c696b65207468652047656e6572616c2047617527732043" );
231+ byte [] aesIn3 = Hex .decode ("4920776f756c64206c696b65207468652047656e6572616c2047617527732043" );
185232 byte [] aesOut3 = Hex .decode ("39312523a78662d5be7fcbcc98ebf5a897687268d6ecccc0c07b25e25ecfe584" );
186233
187234 testCTS (4 , new CBCBlockCipher (AESEngine .newInstance ()), new ParametersWithIV (new KeyParameter (aes128 ), new byte [16 ]), aesIn1 , aesOut1 );
@@ -202,16 +249,17 @@ public void performTest()
202249 testOldCTS (9 , new CBCBlockCipher (AESEngine .newInstance ()), new ParametersWithIV (new KeyParameter (aes128 ), new byte [16 ]), aes1Block , preErrata );
203250
204251 byte [] aes128b = Hex .decode ("aafd12f659cae63489b479e5076ddec2f06cb58faafd12f6" );
205- byte [] aesIn1b = Hex .decode ("000102030405060708090a0b0c0d0e0fff0102030405060708090a0b0c0d0e0f" );
252+ byte [] aesIn1b = Hex .decode ("000102030405060708090a0b0c0d0e0fff0102030405060708090a0b0c0d0e0f" );
206253 byte [] aesOut1b = Hex .decode ("6db2f802d99e1ef0a5940f306079e083cf87f4d8bb9d1abb36cdd9f44ead7d04" );
207254
208255 testCTS (10 , new CBCBlockCipher (AESEngine .newInstance ()), new ParametersWithIV (new KeyParameter (aes128b ), Hex .decode ("aafd12f659cae63489b479e5076ddec2" )), aesIn1b , aesOut1b );
209256
210257 testExceptions ();
258+ testOverlapping ();
211259 }
212260
213261 public static void main (
214- String [] args )
262+ String [] args )
215263 {
216264 runTest (new CTSTest ());
217265 }
0 commit comments