|
1 /* |
|
2 * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved. |
|
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
|
4 * |
|
5 * This code is free software; you can redistribute it and/or modify it |
|
6 * under the terms of the GNU General Public License version 2 only, as |
|
7 * published by the Free Software Foundation. |
|
8 * |
|
9 * This code is distributed in the hope that it will be useful, but WITHOUT |
|
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
12 * version 2 for more details (a copy is included in the LICENSE file that |
|
13 * accompanied this code). |
|
14 * |
|
15 * You should have received a copy of the GNU General Public License version |
|
16 * 2 along with this work; if not, write to the Free Software Foundation, |
|
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
18 * |
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
|
20 * or visit www.oracle.com if you need additional information or have any |
|
21 * questions. |
|
22 */ |
|
23 |
|
24 import java.nio.ByteBuffer; |
|
25 import java.security.AlgorithmParameters; |
|
26 import java.security.Provider; |
|
27 import java.security.Security; |
|
28 import java.util.ArrayList; |
|
29 import java.util.Arrays; |
|
30 import java.util.List; |
|
31 import javax.crypto.SecretKey; |
|
32 import javax.crypto.Cipher; |
|
33 import javax.crypto.KeyGenerator; |
|
34 |
|
35 /* |
|
36 * @test |
|
37 * @bug 8048596 |
|
38 * @summary AEAD encryption/decryption test |
|
39 */ |
|
40 |
|
41 /* |
|
42 * The test does the following: |
|
43 * - create an input text and additional data |
|
44 * - generate a secret key |
|
45 * - instantiate a cipher according to the GCM transformation |
|
46 * - generate an outputText using a single-part encryption/decryption |
|
47 * in AEAD mode |
|
48 * - perform 16 different combinations of multiple-part encryption/decryption |
|
49 * operation in AEAD mode (in encryption mode new Cipher object is created |
|
50 * and initialized with the same secret key and parameters) |
|
51 * - check that all 17 results are equal |
|
52 * |
|
53 * Combinations: |
|
54 * |
|
55 * combination #1 |
|
56 * updateAAD(byte[] src) |
|
57 * update(byte[], int, int) |
|
58 * doFinal(byte[], int, int) |
|
59 * |
|
60 * combination #2 |
|
61 * updateAAD(byte[] src) |
|
62 * update(byte[], int, int) |
|
63 * doFinal(byte[], int, int, byte[], int) |
|
64 * |
|
65 * combination #3 |
|
66 * updateAAD(byte[] src) |
|
67 * update(byte[], int, int, byte[], int) |
|
68 * doFinal(byte[], int, int) |
|
69 * |
|
70 * combination #4 |
|
71 * updateAAD(byte[] src) |
|
72 * update(byte[], int, int, byte[], int) |
|
73 * doFinal(byte[], int, int, byte[], int) |
|
74 * |
|
75 * combination #5 - #8 are similar to #1 -#4, |
|
76 * but with updateAAD(byte[] src, int offset, int len) |
|
77 * |
|
78 * combination #9 - #12 are similar to #1 - #4, |
|
79 * but with updateAAD(ByteBuffer src) |
|
80 * |
|
81 * combination #13 - #16 are similar to #9 - #12 but with directly allocated |
|
82 * ByteBuffer and update(ByteBuffer input, ByteBuffer output) |
|
83 * |
|
84 */ |
|
85 public class Encrypt { |
|
86 |
|
87 private static final String ALGORITHMS[] = { "AES", "Rijndael" }; |
|
88 private static final int KEY_STRENGTHS[] = { 128, 192, 256 }; |
|
89 private static final int TEXT_LENGTHS[] = { 0, 256, 1024 }; |
|
90 private static final int AAD_LENGTHS[] = { 0, 8, 128, 256, 1024 }; |
|
91 private static final int ARRAY_OFFSET = 8; |
|
92 |
|
93 private final String transformation; |
|
94 private final Provider provider; |
|
95 private final SecretKey key; |
|
96 private final int textLength; |
|
97 private final int AADLength; |
|
98 |
|
99 /** |
|
100 * @param provider Security provider |
|
101 * @param algorithm Security algorithm to test |
|
102 * @param mode The mode (GCM is only expected) |
|
103 * @param padding Algorithm padding |
|
104 * @param keyStrength key length |
|
105 * @param textLength Plain text length |
|
106 * @param AADLength Additional data length |
|
107 */ |
|
108 public Encrypt(Provider provider, String algorithm, String mode, |
|
109 String padding, int keyStrength, int textLength, int AADLength) |
|
110 throws Exception { |
|
111 |
|
112 // init a secret Key |
|
113 KeyGenerator kg = KeyGenerator.getInstance(algorithm, provider); |
|
114 kg.init(keyStrength); |
|
115 key = kg.generateKey(); |
|
116 |
|
117 this.provider = provider; |
|
118 this.transformation = algorithm + "/" + mode + "/" + padding; |
|
119 this.textLength = textLength; |
|
120 this.AADLength = AADLength; |
|
121 } |
|
122 |
|
123 public static void main(String[] args) throws Exception { |
|
124 Provider p = Security.getProvider("SunJCE"); |
|
125 for (String alg : ALGORITHMS) { |
|
126 for (int keyStrength : KEY_STRENGTHS) { |
|
127 if (keyStrength > Cipher.getMaxAllowedKeyLength(alg)) { |
|
128 // skip this if this key length is larger than what's |
|
129 // configured in the JCE jurisdiction policy files |
|
130 continue; |
|
131 } |
|
132 for (int textLength : TEXT_LENGTHS) { |
|
133 for (int AADLength : AAD_LENGTHS) { |
|
134 Encrypt test = new Encrypt(p, alg, |
|
135 "GCM", "NoPadding", keyStrength, textLength, |
|
136 AADLength); |
|
137 Cipher cipher = test.createCipher(Cipher.ENCRYPT_MODE, |
|
138 null); |
|
139 AlgorithmParameters params = cipher.getParameters(); |
|
140 test.doTest(params); |
|
141 System.out.println("Test " + alg + ":" |
|
142 + keyStrength + ":" + textLength + ":" |
|
143 + AADLength + " passed"); |
|
144 } |
|
145 } |
|
146 } |
|
147 } |
|
148 } |
|
149 |
|
150 public void doTest(AlgorithmParameters params) throws Exception { |
|
151 System.out.println("Test transformation = " + transformation |
|
152 + ", textLength = " + textLength |
|
153 + ", AADLength = " + AADLength); |
|
154 byte[] input = Helper.generateBytes(textLength); |
|
155 byte[] AAD = Helper.generateBytes(AADLength); |
|
156 byte[] result = execute(Cipher.ENCRYPT_MODE, AAD, input, params); |
|
157 result = execute(Cipher.DECRYPT_MODE, AAD, result, params); |
|
158 if (!Arrays.equals(input, result)) { |
|
159 throw new RuntimeException("Test failed"); |
|
160 } |
|
161 System.out.println("Test passed"); |
|
162 } |
|
163 |
|
164 /** |
|
165 * Create a Cipher object for the requested encryption/decryption mode. |
|
166 * |
|
167 * @param mode encryption or decryption mode |
|
168 * @return Cipher object initiated to perform requested mode operation |
|
169 */ |
|
170 private Cipher createCipher(int mode, AlgorithmParameters params) |
|
171 throws Exception { |
|
172 Cipher ci; |
|
173 if (Cipher.ENCRYPT_MODE == mode) { |
|
174 // create a new Cipher object for encryption |
|
175 ci = Cipher.getInstance(transformation, provider); |
|
176 |
|
177 // initiate it with the saved parameters |
|
178 if (params != null) { |
|
179 ci.init(Cipher.ENCRYPT_MODE, key, params); |
|
180 } else { |
|
181 // initiate the cipher without parameters |
|
182 ci.init(Cipher.ENCRYPT_MODE, key); |
|
183 } |
|
184 } else { |
|
185 // it is expected that parameters already generated |
|
186 // before decryption |
|
187 ci = Cipher.getInstance(transformation, provider); |
|
188 ci.init(Cipher.DECRYPT_MODE, key, params); |
|
189 } |
|
190 |
|
191 return ci; |
|
192 } |
|
193 |
|
194 /** |
|
195 * Test AEAD combinations |
|
196 * |
|
197 * @param mode decryption or encryption |
|
198 * @param AAD additional data for AEAD operations |
|
199 * @param inputText plain text to decrypt/encrypt |
|
200 * @return output text after encrypt/decrypt |
|
201 */ |
|
202 public byte[] execute(int mode, byte[] AAD, byte[] inputText, |
|
203 AlgorithmParameters params) throws Exception { |
|
204 |
|
205 Cipher cipher = createCipher(mode, params); |
|
206 |
|
207 // results of each combination will be saved in the outputTexts |
|
208 List<byte[]> outputTexts = new ArrayList<>(); |
|
209 |
|
210 // generate a standard outputText using a single-part en/de-cryption |
|
211 cipher.updateAAD(AAD); |
|
212 byte[] output = cipher.doFinal(inputText); |
|
213 |
|
214 // execute multiple-part encryption/decryption combinations |
|
215 combination_1(outputTexts, mode, AAD, inputText, params); |
|
216 combination_2(outputTexts, mode, AAD, inputText, params); |
|
217 combination_3(outputTexts, mode, AAD, inputText, params); |
|
218 combination_4(outputTexts, mode, AAD, inputText, params); |
|
219 combination_5(outputTexts, mode, AAD, inputText, params); |
|
220 combination_6(outputTexts, mode, AAD, inputText, params); |
|
221 combination_7(outputTexts, mode, AAD, inputText, params); |
|
222 combination_8(outputTexts, mode, AAD, inputText, params); |
|
223 combination_9(outputTexts, mode, AAD, inputText, params); |
|
224 combination_10(outputTexts, mode, AAD, inputText, params); |
|
225 combination_11(outputTexts, mode, AAD, inputText, params); |
|
226 combination_12(outputTexts, mode, AAD, inputText, params); |
|
227 combination_13(outputTexts, mode, AAD, inputText, params); |
|
228 combination_14(outputTexts, mode, AAD, inputText, params); |
|
229 combination_15(outputTexts, mode, AAD, inputText, params); |
|
230 combination_16(outputTexts, mode, AAD, inputText, params); |
|
231 |
|
232 for (int k = 0; k < outputTexts.size(); k++) { |
|
233 if (!Arrays.equals(output, outputTexts.get(k))) { |
|
234 throw new RuntimeException("Combination #" + k + " failed"); |
|
235 } |
|
236 } |
|
237 return output; |
|
238 } |
|
239 |
|
240 /* |
|
241 * Execute multiple-part encryption/decryption combination #1: |
|
242 * updateAAD(byte[] src) |
|
243 * update(byte[], int, int) |
|
244 * doFinal(byte[], int, int) |
|
245 */ |
|
246 private void combination_1(List<byte[]> results, int mode, byte[] AAD, |
|
247 byte[] plainText, AlgorithmParameters params) throws Exception { |
|
248 Cipher c = createCipher(mode, params); |
|
249 c.updateAAD(AAD); |
|
250 byte[] part11 = c.update(plainText, 0, plainText.length); |
|
251 int part11_length = part11 == null ? 0 : part11.length; |
|
252 byte[] part12 = c.doFinal(); |
|
253 byte[] outputText1 = new byte[part11_length + part12.length]; |
|
254 if (part11 != null) { |
|
255 System.arraycopy(part11, 0, outputText1, 0, part11_length); |
|
256 } |
|
257 System.arraycopy(part12, 0, outputText1, part11_length, part12.length); |
|
258 results.add(outputText1); |
|
259 } |
|
260 |
|
261 /* |
|
262 * Execute multiple-part encryption/decryption combination #2: |
|
263 * updateAAD(byte[] src) |
|
264 * update(byte[], int, int) |
|
265 * doFinal(byte[], int, int, byte[], int) |
|
266 */ |
|
267 private void combination_2(List<byte[]> results, int mode, byte[] AAD, |
|
268 byte[] plainText, AlgorithmParameters params) throws Exception { |
|
269 Cipher c = createCipher(mode, params); |
|
270 c.updateAAD(AAD); |
|
271 int t = 0; |
|
272 int offset = 0; |
|
273 if (plainText.length > ARRAY_OFFSET) { |
|
274 t = plainText.length - ARRAY_OFFSET; |
|
275 offset = ARRAY_OFFSET; |
|
276 } |
|
277 byte[] part21 = c.update(plainText, 0, t); |
|
278 byte[] part22 = new byte[c.getOutputSize(plainText.length)]; |
|
279 int len2 = c.doFinal(plainText, t, offset, part22, 0); |
|
280 int part21Length = part21 != null ? part21.length : 0; |
|
281 byte[] outputText2 = new byte[part21Length + len2]; |
|
282 if (part21 != null) { |
|
283 System.arraycopy(part21, 0, outputText2, 0, part21Length); |
|
284 } |
|
285 System.arraycopy(part22, 0, outputText2, part21Length, len2); |
|
286 results.add(outputText2); |
|
287 } |
|
288 |
|
289 /* |
|
290 * Execute multiple-part encryption/decryption combination #3 |
|
291 * updateAAD(byte[] src) |
|
292 * update(byte[], int, int, byte[], int) |
|
293 * doFinal(byte[], int, int) |
|
294 */ |
|
295 private void combination_3(List<byte[]> results, int mode, byte[] AAD, |
|
296 byte[] plainText, AlgorithmParameters params) throws Exception { |
|
297 Cipher ci = createCipher(mode, params); |
|
298 ci.updateAAD(AAD); |
|
299 byte[] part31 = new byte[ci.getOutputSize(plainText.length)]; |
|
300 int offset = plainText.length > ARRAY_OFFSET ? ARRAY_OFFSET : 0; |
|
301 int len = ci.update(plainText, 0, plainText.length - offset, part31, 0); |
|
302 byte[] part32 = ci.doFinal(plainText, plainText.length - offset, |
|
303 offset); |
|
304 byte[] outputText3 = new byte[len + part32.length]; |
|
305 System.arraycopy(part31, 0, outputText3, 0, len); |
|
306 System.arraycopy(part32, 0, outputText3, len, part32.length); |
|
307 results.add(outputText3); |
|
308 } |
|
309 |
|
310 /* |
|
311 * Execute multiple-part encryption/decryption combination #4: |
|
312 * updateAAD(byte[] src) |
|
313 * update(byte[], int, int, byte[], int) |
|
314 * doFinal(byte[], int, int, byte[], int) |
|
315 */ |
|
316 private void combination_4(List<byte[]> results, int mode, byte[] AAD, |
|
317 byte[] plainText, AlgorithmParameters params) throws Exception { |
|
318 Cipher ci = createCipher(mode, params); |
|
319 ci.updateAAD(AAD); |
|
320 byte[] part41 = new byte[ci.getOutputSize(plainText.length)]; |
|
321 int offset = plainText.length > ARRAY_OFFSET ? ARRAY_OFFSET : 0; |
|
322 int len = ci.update(plainText, 0, plainText.length - offset, part41, 0); |
|
323 int rest4 = ci.doFinal(plainText, plainText.length - offset, offset, |
|
324 part41, len); |
|
325 byte[] outputText4 = new byte[len + rest4]; |
|
326 System.arraycopy(part41, 0, outputText4, 0, outputText4.length); |
|
327 results.add(outputText4); |
|
328 } |
|
329 |
|
330 /* |
|
331 * Execute multiple-part encryption/decryption combination #5: |
|
332 * updateAAD(byte[] src, int offset, int len) |
|
333 * update(byte[], int, int) |
|
334 * doFinal(byte[], int, int) |
|
335 */ |
|
336 private void combination_5(List<byte[]> results, int mode, byte[] AAD, |
|
337 byte[] plainText, AlgorithmParameters params) throws Exception { |
|
338 Cipher c = createCipher(mode, params); |
|
339 c.updateAAD(AAD, 0, AAD.length); |
|
340 byte[] part51 = c.update(plainText, 0, plainText.length); |
|
341 byte[] part52 = c.doFinal(); |
|
342 int part51Length = part51 != null ? part51.length : 0; |
|
343 byte[] outputText5 = new byte[part51Length + part52.length]; |
|
344 if (part51 != null) { |
|
345 System.arraycopy(part51, 0, outputText5, 0, part51Length); |
|
346 } |
|
347 System.arraycopy(part52, 0, outputText5, part51Length, part52.length); |
|
348 results.add(outputText5); |
|
349 } |
|
350 |
|
351 /* |
|
352 * Execute multiple-part encryption/decryption combination #6: |
|
353 * updateAAD(byte[] src, int offset, int len) |
|
354 * updateAAD(byte[] src, int offset, int len) |
|
355 * update(byte[], int, int) doFinal(byte[], int, int, byte[], int) |
|
356 */ |
|
357 private void combination_6(List<byte[]> results, int mode, byte[] AAD, |
|
358 byte[] plainText, AlgorithmParameters params) throws Exception { |
|
359 Cipher c = createCipher(mode, params); |
|
360 c.updateAAD(AAD, 0, AAD.length / 2); |
|
361 c.updateAAD(AAD, AAD.length / 2, AAD.length - AAD.length / 2); |
|
362 int t = 0; |
|
363 int offset = 0; |
|
364 if (plainText.length > ARRAY_OFFSET) { |
|
365 t = plainText.length - ARRAY_OFFSET; |
|
366 offset = ARRAY_OFFSET; |
|
367 } |
|
368 byte[] part61 = c.update(plainText, 0, t); |
|
369 byte[] part62 = new byte[c.getOutputSize(plainText.length)]; |
|
370 int len = c.doFinal(plainText, t, offset, part62, 0); |
|
371 int part61Length = part61 != null ? part61.length : 0; |
|
372 byte[] outputText6 = new byte[part61Length + len]; |
|
373 if (part61 != null) { |
|
374 System.arraycopy(part61, 0, outputText6, 0, part61Length); |
|
375 } |
|
376 System.arraycopy(part62, 0, outputText6, part61Length, len); |
|
377 results.add(outputText6); |
|
378 } |
|
379 |
|
380 /* |
|
381 * Execute multiple-part encryption/decryption combination #7 |
|
382 * updateAAD(byte[] src, int offset, int len) |
|
383 * updateAAD(byte[] src, src.length, 0) |
|
384 * update(byte[], int, int, byte[], int) doFinal(byte[],int, int) |
|
385 */ |
|
386 private void combination_7(List<byte[]> results, int mode, byte[] AAD, |
|
387 byte[] plainText, AlgorithmParameters params) throws Exception { |
|
388 Cipher ci = createCipher(mode, params); |
|
389 ci.updateAAD(AAD, 0, AAD.length); |
|
390 ci.updateAAD(AAD, AAD.length, 0); |
|
391 byte[] part71 = new byte[ci.getOutputSize(plainText.length)]; |
|
392 int offset = plainText.length > ARRAY_OFFSET ? ARRAY_OFFSET : 0; |
|
393 int len = ci.update(plainText, 0, plainText.length - offset, part71, 0); |
|
394 byte[] part72 = ci.doFinal(plainText, plainText.length - offset, offset); |
|
395 byte[] outputText7 = new byte[len + part72.length]; |
|
396 System.arraycopy(part71, 0, outputText7, 0, len); |
|
397 System.arraycopy(part72, 0, outputText7, len, part72.length); |
|
398 results.add(outputText7); |
|
399 } |
|
400 |
|
401 /* |
|
402 * Execute multiple-part encryption/decryption combination #8: |
|
403 * updateAAD(byte[] src, 0, 0) |
|
404 * updateAAD(byte[] src, 0, src.length) |
|
405 * update(byte[], int, int, byte[], int) |
|
406 * doFinal(byte[], int, int, byte[], int) |
|
407 */ |
|
408 private void combination_8(List<byte[]> results, int mode, byte[] AAD, |
|
409 byte[] plainText, AlgorithmParameters params) throws Exception { |
|
410 Cipher ci = createCipher(mode, params); |
|
411 ci.updateAAD(AAD, 0, 0); |
|
412 ci.updateAAD(AAD, 0, AAD.length); |
|
413 byte[] part81 = new byte[ci.getOutputSize(plainText.length)]; |
|
414 int offset = plainText.length > ARRAY_OFFSET ? ARRAY_OFFSET : 0; |
|
415 int len = ci.update(plainText, 0, plainText.length - offset, part81, 0); |
|
416 int rest = ci.doFinal(plainText, plainText.length - offset, offset, |
|
417 part81, len); |
|
418 byte[] outputText8 = new byte[len + rest]; |
|
419 System.arraycopy(part81, 0, outputText8, 0, outputText8.length); |
|
420 results.add(outputText8); |
|
421 } |
|
422 |
|
423 /* |
|
424 * Execute multiple-part encryption/decryption combination #9: |
|
425 * updateAAD(ByteBuffer src) |
|
426 * update(byte[], int, int) doFinal(byte[], int, int) |
|
427 */ |
|
428 private void combination_9(List<byte[]> results, int mode, byte[] AAD, |
|
429 byte[] plainText, AlgorithmParameters params) throws Exception { |
|
430 |
|
431 // prepare ByteBuffer to test |
|
432 ByteBuffer buf = ByteBuffer.allocate(AAD.length); |
|
433 buf.put(AAD); |
|
434 buf.position(0); |
|
435 buf.limit(AAD.length); |
|
436 |
|
437 // Get Cipher object and do the combination |
|
438 Cipher c = createCipher(mode, params); |
|
439 c.updateAAD(buf); |
|
440 byte[] part91 = c.update(plainText, 0, plainText.length); |
|
441 int part91_length = part91 == null ? 0 : part91.length; |
|
442 byte[] part92 = c.doFinal(); |
|
443 byte[] outputText9 = new byte[part91_length + part92.length]; |
|
444 |
|
445 // form result of the combination |
|
446 if (part91 != null) { |
|
447 System.arraycopy(part91, 0, outputText9, 0, part91_length); |
|
448 } |
|
449 System.arraycopy(part92, 0, outputText9, part91_length, part92.length); |
|
450 results.add(outputText9); |
|
451 } |
|
452 |
|
453 /* |
|
454 * Execute multiple-part encryption/decryption combination #10: |
|
455 * updateAAD(ByteBuffer src) |
|
456 * updateAAD(ByteBuffer src) update(byte[], int, int) |
|
457 * doFinal(byte[], int, int, byte[], int) |
|
458 */ |
|
459 private void combination_10(List<byte[]> results, int mode, byte[] AAD, |
|
460 byte[] plainText, AlgorithmParameters params) throws Exception { |
|
461 |
|
462 // prepare ByteBuffer to test |
|
463 ByteBuffer buf = ByteBuffer.allocate(AAD.length); |
|
464 buf.put(AAD); |
|
465 buf.position(0); |
|
466 buf.limit(AAD.length / 2); |
|
467 |
|
468 // get a Cipher object and do the combination |
|
469 Cipher c = createCipher(mode, params); |
|
470 |
|
471 // process the first half of AAD data |
|
472 c.updateAAD(buf); |
|
473 |
|
474 // process the rest of AAD data |
|
475 buf.limit(AAD.length); |
|
476 c.updateAAD(buf); |
|
477 |
|
478 // prapare variables for the combination |
|
479 int t = 0; |
|
480 int offset = 0; |
|
481 if (plainText.length > ARRAY_OFFSET) { |
|
482 t = plainText.length - ARRAY_OFFSET; |
|
483 offset = ARRAY_OFFSET; |
|
484 } |
|
485 |
|
486 // encrypt the text |
|
487 byte[] part10_1 = c.update(plainText, 0, t); |
|
488 int part10_1_Length = part10_1 != null ? part10_1.length : 0; |
|
489 byte[] part10_2 = new byte[c.getOutputSize(plainText.length)]; |
|
490 int len2 = c.doFinal(plainText, t, offset, part10_2, 0); |
|
491 |
|
492 // form the combination's result |
|
493 byte[] outputText10 = new byte[part10_1_Length + len2]; |
|
494 if (part10_1 != null) { |
|
495 System.arraycopy(part10_1, 0, outputText10, 0, part10_1_Length); |
|
496 } |
|
497 System.arraycopy(part10_2, 0, outputText10, part10_1_Length, len2); |
|
498 results.add(outputText10); |
|
499 } |
|
500 |
|
501 /* |
|
502 * Execute multiple-part encryption/decryption combination #11 |
|
503 * updateAAD(ByteBuffer src1) |
|
504 * updateAAD(ByteBuffer src2) |
|
505 * update(byte[],int, int, byte[], int) |
|
506 * doFinal(byte[], int, int) |
|
507 */ |
|
508 private void combination_11(List<byte[]> results, int mode, byte[] AAD, |
|
509 byte[] plainText, AlgorithmParameters params) throws Exception { |
|
510 |
|
511 // prepare ByteBuffer1 to test |
|
512 ByteBuffer buf1 = ByteBuffer.allocate(AAD.length / 2); |
|
513 buf1.put(AAD, 0, AAD.length / 2); |
|
514 buf1.position(0); |
|
515 buf1.limit(AAD.length / 2); |
|
516 |
|
517 // get a Cipher object and do combination |
|
518 Cipher ci = createCipher(mode, params); |
|
519 |
|
520 // process the first half of AAD data |
|
521 ci.updateAAD(buf1); |
|
522 |
|
523 // prepare ByteBuffer2 to test |
|
524 ByteBuffer buf2 = ByteBuffer.allocate(AAD.length - AAD.length / 2); |
|
525 buf2.put(AAD, AAD.length / 2, AAD.length - AAD.length / 2); |
|
526 buf2.position(0); |
|
527 buf2.limit(AAD.length - AAD.length / 2); |
|
528 |
|
529 // process the rest of AAD data |
|
530 ci.updateAAD(buf2); |
|
531 |
|
532 // encrypt plain text |
|
533 byte[] part11_1 = new byte[ci.getOutputSize(plainText.length)]; |
|
534 int offset = plainText.length > ARRAY_OFFSET ? ARRAY_OFFSET : 0; |
|
535 int len_11 = ci.update(plainText, 0, plainText.length - offset, |
|
536 part11_1, 0); |
|
537 byte[] part11_2 = ci.doFinal(plainText, plainText.length - offset, |
|
538 offset); |
|
539 byte[] outputText11 = new byte[len_11 + part11_2.length]; |
|
540 System.arraycopy(part11_1, 0, outputText11, 0, len_11); |
|
541 System.arraycopy(part11_2, 0, outputText11, len_11, part11_2.length); |
|
542 results.add(outputText11); |
|
543 } |
|
544 |
|
545 /* |
|
546 * Execute multiple-part encryption/decryption combination #12: |
|
547 * updateAAD(ByteBuffer src) |
|
548 * updateAAD(ByteBuffer emptyByteBuffer) |
|
549 * update(byte[], int, int, byte[], int) |
|
550 * doFinal(byte[], int, int, byte[], int) |
|
551 */ |
|
552 private void combination_12(List<byte[]> results, int mode, byte[] AAD, |
|
553 byte[] plainText, AlgorithmParameters params) throws Exception { |
|
554 |
|
555 // prepare ByteBuffer to test |
|
556 ByteBuffer buf = ByteBuffer.allocate(AAD.length); |
|
557 buf.put(AAD); |
|
558 buf.position(0); |
|
559 buf.limit(AAD.length); |
|
560 Cipher ci = createCipher(mode, params); |
|
561 ci.updateAAD(buf); |
|
562 |
|
563 // prepare an empty ByteBuffer |
|
564 ByteBuffer emptyBuf = ByteBuffer.allocate(0); |
|
565 emptyBuf.put(new byte[0]); |
|
566 ci.updateAAD(emptyBuf); |
|
567 byte[] part12_1 = new byte[ci.getOutputSize(plainText.length)]; |
|
568 int offset = plainText.length > ARRAY_OFFSET ? ARRAY_OFFSET : 0; |
|
569 int len12 = ci.update(plainText, 0, plainText.length - offset, |
|
570 part12_1, 0); |
|
571 int rest12 = ci.doFinal(plainText, plainText.length - offset, offset, |
|
572 part12_1, len12); |
|
573 byte[] outputText12 = new byte[len12 + rest12]; |
|
574 System.arraycopy(part12_1, 0, outputText12, 0, outputText12.length); |
|
575 results.add(outputText12); |
|
576 } |
|
577 |
|
578 /* |
|
579 * Execute multiple-part encryption/decryption combination #13: |
|
580 * updateAAD(ByteBuffer src), where src is directly allocated |
|
581 * update(ByteBuffer input, ByteBuffer out) |
|
582 * doFinal(ByteBuffer input, ByteBuffer out) |
|
583 */ |
|
584 private void combination_13(List<byte[]> results, int mode, byte[] AAD, |
|
585 byte[] plainText, AlgorithmParameters params) throws Exception { |
|
586 Cipher c = createCipher(mode, params); |
|
587 |
|
588 // prepare ByteBuffer to test |
|
589 ByteBuffer buf = ByteBuffer.allocateDirect(AAD.length); |
|
590 buf.put(AAD); |
|
591 buf.position(0); |
|
592 buf.limit(AAD.length); |
|
593 c.updateAAD(buf); |
|
594 |
|
595 // prepare buffers to encrypt/decrypt |
|
596 ByteBuffer in = ByteBuffer.allocateDirect(plainText.length); |
|
597 in.put(plainText); |
|
598 in.position(0); |
|
599 in.limit(plainText.length); |
|
600 ByteBuffer output = ByteBuffer.allocateDirect( |
|
601 c.getOutputSize(in.limit())); |
|
602 output.position(0); |
|
603 output.limit(c.getOutputSize(in.limit())); |
|
604 |
|
605 // process input text |
|
606 c.update(in, output); |
|
607 c.doFinal(in, output); |
|
608 int resultSize = output.position(); |
|
609 byte[] result13 = new byte[resultSize]; |
|
610 output.position(0); |
|
611 output.limit(resultSize); |
|
612 output.get(result13, 0, resultSize); |
|
613 results.add(result13); |
|
614 } |
|
615 |
|
616 /* |
|
617 * Execute multiple-part encryption/decryption combination #14: |
|
618 * updateAAD(ByteBuffer src) updateAAD(ByteBuffer src), |
|
619 * where src is directly allocated |
|
620 * update(ByteBuffer input, ByteBuffer out) |
|
621 * doFinal(ByteBuffer input, ByteBuffer out) |
|
622 */ |
|
623 private void combination_14(List<byte[]> results, int mode, byte[] AAD, |
|
624 byte[] plainText, AlgorithmParameters params) throws Exception { |
|
625 Cipher c = createCipher(mode, params); |
|
626 // prepare ByteBuffer to test |
|
627 ByteBuffer buf = ByteBuffer.allocateDirect(AAD.length); |
|
628 buf.put(AAD); |
|
629 |
|
630 // process the first half of AAD data |
|
631 buf.position(0); |
|
632 buf.limit(AAD.length / 2); |
|
633 c.updateAAD(buf); |
|
634 |
|
635 // process the rest of AAD data |
|
636 buf.limit(AAD.length); |
|
637 c.updateAAD(buf); |
|
638 |
|
639 // prepare buffers to encrypt/decrypt |
|
640 ByteBuffer in = ByteBuffer.allocate(plainText.length); |
|
641 in.put(plainText); |
|
642 in.position(0); |
|
643 in.limit(plainText.length); |
|
644 ByteBuffer out = ByteBuffer.allocate(c.getOutputSize(in.limit())); |
|
645 out.position(0); |
|
646 out.limit(c.getOutputSize(in.limit())); |
|
647 |
|
648 // process input text |
|
649 c.update(in, out); |
|
650 c.doFinal(in, out); |
|
651 int resultSize = out.position(); |
|
652 byte[] result14 = new byte[resultSize]; |
|
653 out.position(0); |
|
654 out.limit(resultSize); |
|
655 out.get(result14, 0, resultSize); |
|
656 results.add(result14); |
|
657 } |
|
658 |
|
659 /* |
|
660 * Execute multiple-part encryption/decryption combination #15 |
|
661 * updateAAD(ByteBuffer src1), where src1 is directly allocated |
|
662 * updateAAD(ByteBuffer src2), where src2 is directly allocated |
|
663 * doFinal(ByteBuffer input, ByteBuffer out) |
|
664 */ |
|
665 private void combination_15(List<byte[]> results, int mode, byte[] AAD, |
|
666 byte[] plainText, AlgorithmParameters params) throws Exception { |
|
667 Cipher c = createCipher(mode, params); |
|
668 |
|
669 // prepare ByteBuffer1 to test |
|
670 ByteBuffer buf1 = ByteBuffer.allocateDirect(AAD.length / 2); |
|
671 buf1.put(AAD, 0, AAD.length / 2); |
|
672 buf1.position(0); |
|
673 buf1.limit(AAD.length / 2); |
|
674 |
|
675 // process the first half of AAD data |
|
676 c.updateAAD(buf1); |
|
677 |
|
678 // prepare ByteBuffer2 to test |
|
679 ByteBuffer buf2 = ByteBuffer.allocateDirect( |
|
680 AAD.length - AAD.length / 2); |
|
681 buf2.put(AAD, AAD.length / 2, AAD.length - AAD.length / 2); |
|
682 buf2.position(0); |
|
683 buf2.limit(AAD.length - AAD.length / 2); |
|
684 |
|
685 // process the rest of AAD data |
|
686 c.updateAAD(buf2); |
|
687 |
|
688 // prepare buffers to encrypt/decrypt |
|
689 ByteBuffer in = ByteBuffer.allocateDirect(plainText.length); |
|
690 in.put(plainText); |
|
691 in.position(0); |
|
692 in.limit(plainText.length); |
|
693 ByteBuffer output = ByteBuffer.allocateDirect( |
|
694 c.getOutputSize(in.limit())); |
|
695 output.position(0); |
|
696 output.limit(c.getOutputSize(in.limit())); |
|
697 |
|
698 // process input text |
|
699 c.doFinal(in, output); |
|
700 int resultSize = output.position(); |
|
701 byte[] result15 = new byte[resultSize]; |
|
702 output.position(0); |
|
703 output.limit(resultSize); |
|
704 output.get(result15, 0, resultSize); |
|
705 results.add(result15); |
|
706 } |
|
707 |
|
708 /* |
|
709 * Execute multiple-part encryption/decryption combination #16: |
|
710 * updateAAD(ByteBuffer src) |
|
711 * updateAAD(ByteBuffer emptyByteBuffer) |
|
712 * update(ByteBuffer input, ByteBuffer out) |
|
713 * doFinal(EmptyByteBuffer, ByteBuffer out) |
|
714 */ |
|
715 private void combination_16(List<byte[]> results, int mode, byte[] AAD, |
|
716 byte[] plainText, AlgorithmParameters params) throws Exception { |
|
717 Cipher c = createCipher(mode, params); |
|
718 |
|
719 // prepare ByteBuffer to test |
|
720 ByteBuffer buf = ByteBuffer.allocateDirect(AAD.length); |
|
721 buf.put(AAD); |
|
722 buf.position(0); |
|
723 buf.limit(AAD.length); |
|
724 c.updateAAD(buf); |
|
725 |
|
726 // prepare empty ByteBuffer |
|
727 ByteBuffer emptyBuf = ByteBuffer.allocateDirect(0); |
|
728 emptyBuf.put(new byte[0]); |
|
729 c.updateAAD(emptyBuf); |
|
730 |
|
731 // prepare buffers to encrypt/decrypt |
|
732 ByteBuffer in = ByteBuffer.allocateDirect(plainText.length); |
|
733 in.put(plainText); |
|
734 in.position(0); |
|
735 in.limit(plainText.length); |
|
736 ByteBuffer output = ByteBuffer.allocateDirect( |
|
737 c.getOutputSize(in.limit())); |
|
738 output.position(0); |
|
739 output.limit(c.getOutputSize(in.limit())); |
|
740 |
|
741 // process input text with an empty buffer |
|
742 c.update(in, output); |
|
743 ByteBuffer emptyBuf2 = ByteBuffer.allocate(0); |
|
744 emptyBuf2.put(new byte[0]); |
|
745 c.doFinal(emptyBuf2, output); |
|
746 int resultSize = output.position(); |
|
747 byte[] result16 = new byte[resultSize]; |
|
748 output.position(0); |
|
749 output.limit(resultSize); |
|
750 output.get(result16, 0, resultSize); |
|
751 results.add(result16); |
|
752 } |
|
753 } |