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 24import java.nio.ByteBuffer; 25import java.security.AlgorithmParameters; 26import java.security.Provider; 27import java.security.Security; 28import java.util.ArrayList; 29import java.util.Arrays; 30import java.util.List; 31import javax.crypto.SecretKey; 32import javax.crypto.Cipher; 33import 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 */ 85public 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} 754