Path: blob/master/test/jdk/com/sun/crypto/provider/Cipher/AEAD/Encrypt.java
66649 views
/*1* Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223import java.nio.ByteBuffer;24import java.security.AlgorithmParameters;25import java.security.Provider;26import java.security.Security;27import java.util.ArrayList;28import java.util.Arrays;29import java.util.HexFormat;30import java.util.List;31import javax.crypto.SecretKey;32import javax.crypto.Cipher;33import javax.crypto.KeyGenerator;3435/*36* @test37* @bug 804859638* @summary AEAD encryption/decryption test39*/4041/*42* The test does the following:43* - create an input text and additional data44* - generate a secret key45* - instantiate a cipher according to the GCM transformation46* - generate an outputText using a single-part encryption/decryption47* in AEAD mode48* - perform 16 different combinations of multiple-part encryption/decryption49* operation in AEAD mode (in encryption mode new Cipher object is created50* and initialized with the same secret key and parameters)51* - check that all 17 results are equal52*53* Combinations:54*55* combination #156* updateAAD(byte[] src)57* update(byte[], int, int)58* doFinal(byte[], int, int)59*60* combination #261* updateAAD(byte[] src)62* update(byte[], int, int)63* doFinal(byte[], int, int, byte[], int)64*65* combination #366* updateAAD(byte[] src)67* update(byte[], int, int, byte[], int)68* doFinal(byte[], int, int)69*70* combination #471* 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 allocated82* ByteBuffer and update(ByteBuffer input, ByteBuffer output)83*84*/85public class Encrypt {8687private static final String ALGORITHMS[] = { "AES" };88private static final int KEY_STRENGTHS[] = { 128, 192, 256 };89private static final int TEXT_LENGTHS[] = { 0, 256, 1024 };90private static final int AAD_LENGTHS[] = { 0, 8, 128, 256, 1024 };91private static final int ARRAY_OFFSET = 8;9293private final String transformation;94private final Provider provider;95private final SecretKey key;96private final int textLength;97private final int AADLength;9899/**100* @param provider Security provider101* @param algorithm Security algorithm to test102* @param mode The mode (GCM is only expected)103* @param padding Algorithm padding104* @param keyStrength key length105* @param textLength Plain text length106* @param AADLength Additional data length107*/108public Encrypt(Provider provider, String algorithm, String mode,109String padding, int keyStrength, int textLength, int AADLength)110throws Exception {111112// init a secret Key113KeyGenerator kg = KeyGenerator.getInstance(algorithm, provider);114kg.init(keyStrength);115key = kg.generateKey();116117this.provider = provider;118this.transformation = algorithm + "/" + mode + "/" + padding;119this.textLength = textLength;120this.AADLength = AADLength;121}122123public static void main(String[] args) throws Exception {124Provider p = Security.getProvider("SunJCE");125for (String alg : ALGORITHMS) {126for (int keyStrength : KEY_STRENGTHS) {127if (keyStrength > Cipher.getMaxAllowedKeyLength(alg)) {128// skip this if this key length is larger than what's129// configured in the JCE jurisdiction policy files130continue;131}132for (int textLength : TEXT_LENGTHS) {133for (int AADLength : AAD_LENGTHS) {134Encrypt test = new Encrypt(p, alg,135"GCM", "NoPadding", keyStrength, textLength,136AADLength);137Cipher cipher = test.createCipher(Cipher.ENCRYPT_MODE,138null);139AlgorithmParameters params = cipher.getParameters();140test.doTest(params);141System.out.println("Test " + alg + ":"142+ keyStrength + ":" + textLength + ":"143+ AADLength + " passed");144}145}146}147}148}149150public void doTest(AlgorithmParameters params) throws Exception {151System.out.println("Test transformation = " + transformation152+ ", textLength = " + textLength153+ ", AADLength = " + AADLength);154byte[] input = Helper.generateBytes(textLength);155byte[] AAD = Helper.generateBytes(AADLength);156byte[] result = execute(Cipher.ENCRYPT_MODE, AAD, input, params);157result = execute(Cipher.DECRYPT_MODE, AAD, result, params);158if (!Arrays.equals(input, result)) {159throw new RuntimeException("Test failed");160}161System.out.println("Test passed");162}163164/**165* Create a Cipher object for the requested encryption/decryption mode.166*167* @param mode encryption or decryption mode168* @return Cipher object initiated to perform requested mode operation169*/170private Cipher createCipher(int mode, AlgorithmParameters params)171throws Exception {172Cipher ci;173if (Cipher.ENCRYPT_MODE == mode) {174// create a new Cipher object for encryption175ci = Cipher.getInstance(transformation, provider);176177// initiate it with the saved parameters178if (params != null) {179ci.init(Cipher.ENCRYPT_MODE, key, params);180} else {181// initiate the cipher without parameters182ci.init(Cipher.ENCRYPT_MODE, key);183}184} else {185// it is expected that parameters already generated186// before decryption187ci = Cipher.getInstance(transformation, provider);188ci.init(Cipher.DECRYPT_MODE, key, params);189}190191return ci;192}193194/**195* Test AEAD combinations196*197* @param mode decryption or encryption198* @param AAD additional data for AEAD operations199* @param inputText plain text to decrypt/encrypt200* @return output text after encrypt/decrypt201*/202public byte[] execute(int mode, byte[] AAD, byte[] inputText,203AlgorithmParameters params) throws Exception {204205Cipher cipher = createCipher(mode, params);206207// results of each combination will be saved in the outputTexts208List<byte[]> outputTexts = new ArrayList<>();209210// generate a standard outputText using a single-part en/de-cryption211cipher.updateAAD(AAD);212byte[] output = cipher.doFinal(inputText);213214// execute multiple-part encryption/decryption combinations215combination_1(outputTexts, mode, AAD, inputText, params);216combination_2(outputTexts, mode, AAD, inputText, params);217combination_3(outputTexts, mode, AAD, inputText, params);218combination_4(outputTexts, mode, AAD, inputText, params);219combination_5(outputTexts, mode, AAD, inputText, params);220combination_6(outputTexts, mode, AAD, inputText, params);221combination_7(outputTexts, mode, AAD, inputText, params);222combination_8(outputTexts, mode, AAD, inputText, params);223combination_9(outputTexts, mode, AAD, inputText, params);224combination_10(outputTexts, mode, AAD, inputText, params);225combination_11(outputTexts, mode, AAD, inputText, params);226combination_12(outputTexts, mode, AAD, inputText, params);227combination_13(outputTexts, mode, AAD, inputText, params);228combination_14(outputTexts, mode, AAD, inputText, params);229combination_15(outputTexts, mode, AAD, inputText, params);230combination_16(outputTexts, mode, AAD, inputText, params);231232for (int k = 0; k < outputTexts.size(); k++) {233HexFormat hex = HexFormat.of().withUpperCase();234if (!Arrays.equals(output, outputTexts.get(k))) {235System.out.println("Combination #" + (k + 1) + "\nresult " +236hex.formatHex(outputTexts.get(k)) +237"\nexpected: " + hex.formatHex(output));238throw new RuntimeException("Combination #" + (k + 1) + " failed");239}240}241return output;242}243244/*245* Execute multiple-part encryption/decryption combination #1:246* updateAAD(byte[] src)247* update(byte[], int, int)248* doFinal(byte[], int, int)249*/250private void combination_1(List<byte[]> results, int mode, byte[] AAD,251byte[] plainText, AlgorithmParameters params) throws Exception {252Cipher c = createCipher(mode, params);253c.updateAAD(AAD);254byte[] part11 = c.update(plainText, 0, plainText.length);255int part11_length = part11 == null ? 0 : part11.length;256byte[] part12 = c.doFinal();257byte[] outputText1 = new byte[part11_length + part12.length];258if (part11 != null) {259System.arraycopy(part11, 0, outputText1, 0, part11_length);260}261System.arraycopy(part12, 0, outputText1, part11_length, part12.length);262results.add(outputText1);263}264265/*266* Execute multiple-part encryption/decryption combination #2:267* updateAAD(byte[] src)268* update(byte[], int, int)269* doFinal(byte[], int, int, byte[], int)270*/271private void combination_2(List<byte[]> results, int mode, byte[] AAD,272byte[] plainText, AlgorithmParameters params) throws Exception {273Cipher c = createCipher(mode, params);274c.updateAAD(AAD);275int t = 0;276int offset = 0;277if (plainText.length > ARRAY_OFFSET) {278t = plainText.length - ARRAY_OFFSET;279offset = ARRAY_OFFSET;280}281byte[] part21 = c.update(plainText, 0, t);282byte[] part22 = new byte[c.getOutputSize(plainText.length)];283int len2 = c.doFinal(plainText, t, offset, part22, 0);284int part21Length = part21 != null ? part21.length : 0;285byte[] outputText2 = new byte[part21Length + len2];286if (part21 != null) {287System.arraycopy(part21, 0, outputText2, 0, part21Length);288}289System.arraycopy(part22, 0, outputText2, part21Length, len2);290results.add(outputText2);291}292293/*294* Execute multiple-part encryption/decryption combination #3295* updateAAD(byte[] src)296* update(byte[], int, int, byte[], int)297* doFinal(byte[], int, int)298*/299private void combination_3(List<byte[]> results, int mode, byte[] AAD,300byte[] plainText, AlgorithmParameters params) throws Exception {301Cipher ci = createCipher(mode, params);302ci.updateAAD(AAD);303byte[] part31 = new byte[ci.getOutputSize(plainText.length)];304int offset = plainText.length > ARRAY_OFFSET ? ARRAY_OFFSET : 0;305int len = ci.update(plainText, 0, plainText.length - offset, part31, 0);306byte[] part32 = ci.doFinal(plainText, plainText.length - offset,307offset);308byte[] outputText3 = new byte[len + part32.length];309System.arraycopy(part31, 0, outputText3, 0, len);310System.arraycopy(part32, 0, outputText3, len, part32.length);311results.add(outputText3);312}313314/*315* Execute multiple-part encryption/decryption combination #4:316* updateAAD(byte[] src)317* update(byte[], int, int, byte[], int)318* doFinal(byte[], int, int, byte[], int)319*/320private void combination_4(List<byte[]> results, int mode, byte[] AAD,321byte[] plainText, AlgorithmParameters params) throws Exception {322Cipher ci = createCipher(mode, params);323ci.updateAAD(AAD);324byte[] part41 = new byte[ci.getOutputSize(plainText.length)];325int offset = plainText.length > ARRAY_OFFSET ? ARRAY_OFFSET : 0;326int len = ci.update(plainText, 0, plainText.length - offset, part41, 0);327int rest4 = ci.doFinal(plainText, plainText.length - offset, offset,328part41, len);329byte[] outputText4 = new byte[len + rest4];330System.arraycopy(part41, 0, outputText4, 0, outputText4.length);331results.add(outputText4);332}333334/*335* Execute multiple-part encryption/decryption combination #5:336* updateAAD(byte[] src, int offset, int len)337* update(byte[], int, int)338* doFinal(byte[], int, int)339*/340private void combination_5(List<byte[]> results, int mode, byte[] AAD,341byte[] plainText, AlgorithmParameters params) throws Exception {342Cipher c = createCipher(mode, params);343c.updateAAD(AAD, 0, AAD.length);344byte[] part51 = c.update(plainText, 0, plainText.length);345byte[] part52 = c.doFinal();346int part51Length = part51 != null ? part51.length : 0;347byte[] outputText5 = new byte[part51Length + part52.length];348if (part51 != null) {349System.arraycopy(part51, 0, outputText5, 0, part51Length);350}351System.arraycopy(part52, 0, outputText5, part51Length, part52.length);352results.add(outputText5);353}354355/*356* Execute multiple-part encryption/decryption combination #6:357* updateAAD(byte[] src, int offset, int len)358* updateAAD(byte[] src, int offset, int len)359* update(byte[], int, int) doFinal(byte[], int, int, byte[], int)360*/361private void combination_6(List<byte[]> results, int mode, byte[] AAD,362byte[] plainText, AlgorithmParameters params) throws Exception {363Cipher c = createCipher(mode, params);364c.updateAAD(AAD, 0, AAD.length / 2);365c.updateAAD(AAD, AAD.length / 2, AAD.length - AAD.length / 2);366int t = 0;367int offset = 0;368if (plainText.length > ARRAY_OFFSET) {369t = plainText.length - ARRAY_OFFSET;370offset = ARRAY_OFFSET;371}372byte[] part61 = c.update(plainText, 0, t);373byte[] part62 = new byte[c.getOutputSize(plainText.length)];374int len = c.doFinal(plainText, t, offset, part62, 0);375int part61Length = part61 != null ? part61.length : 0;376byte[] outputText6 = new byte[part61Length + len];377if (part61 != null) {378System.arraycopy(part61, 0, outputText6, 0, part61Length);379}380System.arraycopy(part62, 0, outputText6, part61Length, len);381results.add(outputText6);382}383384/*385* Execute multiple-part encryption/decryption combination #7386* updateAAD(byte[] src, int offset, int len)387* updateAAD(byte[] src, src.length, 0)388* update(byte[], int, int, byte[], int) doFinal(byte[],int, int)389*/390private void combination_7(List<byte[]> results, int mode, byte[] AAD,391byte[] plainText, AlgorithmParameters params) throws Exception {392Cipher ci = createCipher(mode, params);393ci.updateAAD(AAD, 0, AAD.length);394ci.updateAAD(AAD, AAD.length, 0);395byte[] part71 = new byte[ci.getOutputSize(plainText.length)];396int offset = plainText.length > ARRAY_OFFSET ? ARRAY_OFFSET : 0;397int len = ci.update(plainText, 0, plainText.length - offset, part71, 0);398byte[] part72 = ci.doFinal(plainText, plainText.length - offset, offset);399byte[] outputText7 = new byte[len + part72.length];400System.arraycopy(part71, 0, outputText7, 0, len);401System.arraycopy(part72, 0, outputText7, len, part72.length);402results.add(outputText7);403}404405/*406* Execute multiple-part encryption/decryption combination #8:407* updateAAD(byte[] src, 0, 0)408* updateAAD(byte[] src, 0, src.length)409* update(byte[], int, int, byte[], int)410* doFinal(byte[], int, int, byte[], int)411*/412private void combination_8(List<byte[]> results, int mode, byte[] AAD,413byte[] plainText, AlgorithmParameters params) throws Exception {414Cipher ci = createCipher(mode, params);415ci.updateAAD(AAD, 0, 0);416ci.updateAAD(AAD, 0, AAD.length);417byte[] part81 = new byte[ci.getOutputSize(plainText.length)];418int offset = plainText.length > ARRAY_OFFSET ? ARRAY_OFFSET : 0;419int len = ci.update(plainText, 0, plainText.length - offset, part81, 0);420int rest = ci.doFinal(plainText, plainText.length - offset, offset,421part81, len);422byte[] outputText8 = new byte[len + rest];423System.arraycopy(part81, 0, outputText8, 0, outputText8.length);424results.add(outputText8);425}426427/*428* Execute multiple-part encryption/decryption combination #9:429* updateAAD(ByteBuffer src)430* update(byte[], int, int) doFinal(byte[], int, int)431*/432private void combination_9(List<byte[]> results, int mode, byte[] AAD,433byte[] plainText, AlgorithmParameters params) throws Exception {434435// prepare ByteBuffer to test436ByteBuffer buf = ByteBuffer.allocate(AAD.length);437buf.put(AAD);438buf.position(0);439buf.limit(AAD.length);440441// Get Cipher object and do the combination442Cipher c = createCipher(mode, params);443c.updateAAD(buf);444byte[] part91 = c.update(plainText, 0, plainText.length);445int part91_length = part91 == null ? 0 : part91.length;446byte[] part92 = c.doFinal();447byte[] outputText9 = new byte[part91_length + part92.length];448449// form result of the combination450if (part91 != null) {451System.arraycopy(part91, 0, outputText9, 0, part91_length);452}453System.arraycopy(part92, 0, outputText9, part91_length, part92.length);454results.add(outputText9);455}456457/*458* Execute multiple-part encryption/decryption combination #10:459* updateAAD(ByteBuffer src)460* updateAAD(ByteBuffer src) update(byte[], int, int)461* doFinal(byte[], int, int, byte[], int)462*/463private void combination_10(List<byte[]> results, int mode, byte[] AAD,464byte[] plainText, AlgorithmParameters params) throws Exception {465466// prepare ByteBuffer to test467ByteBuffer buf = ByteBuffer.allocate(AAD.length);468buf.put(AAD);469buf.position(0);470buf.limit(AAD.length / 2);471472// get a Cipher object and do the combination473Cipher c = createCipher(mode, params);474475// process the first half of AAD data476c.updateAAD(buf);477478// process the rest of AAD data479buf.limit(AAD.length);480c.updateAAD(buf);481482// prapare variables for the combination483int t = 0;484int offset = 0;485if (plainText.length > ARRAY_OFFSET) {486t = plainText.length - ARRAY_OFFSET;487offset = ARRAY_OFFSET;488}489490// encrypt the text491byte[] part10_1 = c.update(plainText, 0, t);492int part10_1_Length = part10_1 != null ? part10_1.length : 0;493byte[] part10_2 = new byte[c.getOutputSize(plainText.length)];494int len2 = c.doFinal(plainText, t, offset, part10_2, 0);495496// form the combination's result497byte[] outputText10 = new byte[part10_1_Length + len2];498if (part10_1 != null) {499System.arraycopy(part10_1, 0, outputText10, 0, part10_1_Length);500}501System.arraycopy(part10_2, 0, outputText10, part10_1_Length, len2);502results.add(outputText10);503}504505/*506* Execute multiple-part encryption/decryption combination #11507* updateAAD(ByteBuffer src1)508* updateAAD(ByteBuffer src2)509* update(byte[],int, int, byte[], int)510* doFinal(byte[], int, int)511*/512private void combination_11(List<byte[]> results, int mode, byte[] AAD,513byte[] plainText, AlgorithmParameters params) throws Exception {514515// prepare ByteBuffer1 to test516ByteBuffer buf1 = ByteBuffer.allocate(AAD.length / 2);517buf1.put(AAD, 0, AAD.length / 2);518buf1.position(0);519buf1.limit(AAD.length / 2);520521// get a Cipher object and do combination522Cipher ci = createCipher(mode, params);523524// process the first half of AAD data525ci.updateAAD(buf1);526527// prepare ByteBuffer2 to test528ByteBuffer buf2 = ByteBuffer.allocate(AAD.length - AAD.length / 2);529buf2.put(AAD, AAD.length / 2, AAD.length - AAD.length / 2);530buf2.position(0);531buf2.limit(AAD.length - AAD.length / 2);532533// process the rest of AAD data534ci.updateAAD(buf2);535536// encrypt plain text537byte[] part11_1 = new byte[ci.getOutputSize(plainText.length)];538int offset = plainText.length > ARRAY_OFFSET ? ARRAY_OFFSET : 0;539int len_11 = ci.update(plainText, 0, plainText.length - offset,540part11_1, 0);541byte[] part11_2 = ci.doFinal(plainText, plainText.length - offset,542offset);543byte[] outputText11 = new byte[len_11 + part11_2.length];544System.arraycopy(part11_1, 0, outputText11, 0, len_11);545System.arraycopy(part11_2, 0, outputText11, len_11, part11_2.length);546results.add(outputText11);547}548549/*550* Execute multiple-part encryption/decryption combination #12:551* updateAAD(ByteBuffer src)552* updateAAD(ByteBuffer emptyByteBuffer)553* update(byte[], int, int, byte[], int)554* doFinal(byte[], int, int, byte[], int)555*/556private void combination_12(List<byte[]> results, int mode, byte[] AAD,557byte[] plainText, AlgorithmParameters params) throws Exception {558559// prepare ByteBuffer to test560ByteBuffer buf = ByteBuffer.allocate(AAD.length);561buf.put(AAD);562buf.position(0);563buf.limit(AAD.length);564Cipher ci = createCipher(mode, params);565ci.updateAAD(buf);566567// prepare an empty ByteBuffer568ByteBuffer emptyBuf = ByteBuffer.allocate(0);569emptyBuf.put(new byte[0]);570ci.updateAAD(emptyBuf);571byte[] part12_1 = new byte[ci.getOutputSize(plainText.length)];572int offset = plainText.length > ARRAY_OFFSET ? ARRAY_OFFSET : 0;573int len12 = ci.update(plainText, 0, plainText.length - offset,574part12_1, 0);575int rest12 = ci.doFinal(plainText, plainText.length - offset, offset,576part12_1, len12);577byte[] outputText12 = new byte[len12 + rest12];578System.arraycopy(part12_1, 0, outputText12, 0, outputText12.length);579results.add(outputText12);580}581582/*583* Execute multiple-part encryption/decryption combination #13:584* updateAAD(ByteBuffer src), where src is directly allocated585* update(ByteBuffer input, ByteBuffer out)586* doFinal(ByteBuffer input, ByteBuffer out)587*/588private void combination_13(List<byte[]> results, int mode, byte[] AAD,589byte[] plainText, AlgorithmParameters params) throws Exception {590Cipher c = createCipher(mode, params);591592// prepare ByteBuffer to test593ByteBuffer buf = ByteBuffer.allocateDirect(AAD.length);594buf.put(AAD);595buf.position(0);596buf.limit(AAD.length);597c.updateAAD(buf);598599// prepare buffers to encrypt/decrypt600ByteBuffer in = ByteBuffer.allocateDirect(plainText.length);601in.put(plainText);602in.position(0);603in.limit(plainText.length);604ByteBuffer output = ByteBuffer.allocateDirect(605c.getOutputSize(in.limit()));606output.position(0);607output.limit(c.getOutputSize(in.limit()));608609// process input text610c.update(in, output);611c.doFinal(in, output);612int resultSize = output.position();613byte[] result13 = new byte[resultSize];614output.position(0);615output.limit(resultSize);616output.get(result13, 0, resultSize);617results.add(result13);618}619620/*621* Execute multiple-part encryption/decryption combination #14:622* updateAAD(ByteBuffer src) updateAAD(ByteBuffer src),623* where src is directly allocated624* update(ByteBuffer input, ByteBuffer out)625* doFinal(ByteBuffer input, ByteBuffer out)626*/627private void combination_14(List<byte[]> results, int mode, byte[] AAD,628byte[] plainText, AlgorithmParameters params) throws Exception {629Cipher c = createCipher(mode, params);630// prepare ByteBuffer to test631ByteBuffer buf = ByteBuffer.allocateDirect(AAD.length);632buf.put(AAD);633634// process the first half of AAD data635buf.position(0);636buf.limit(AAD.length / 2);637c.updateAAD(buf);638639// process the rest of AAD data640buf.limit(AAD.length);641c.updateAAD(buf);642643// prepare buffers to encrypt/decrypt644ByteBuffer in = ByteBuffer.allocate(plainText.length);645in.put(plainText);646in.position(0);647in.limit(plainText.length);648ByteBuffer out = ByteBuffer.allocate(c.getOutputSize(in.limit()));649out.position(0);650out.limit(c.getOutputSize(in.limit()));651652// process input text653c.update(in, out);654c.doFinal(in, out);655int resultSize = out.position();656byte[] result14 = new byte[resultSize];657out.position(0);658out.limit(resultSize);659out.get(result14, 0, resultSize);660results.add(result14);661}662663/*664* Execute multiple-part encryption/decryption combination #15665* updateAAD(ByteBuffer src1), where src1 is directly allocated666* updateAAD(ByteBuffer src2), where src2 is directly allocated667* doFinal(ByteBuffer input, ByteBuffer out)668*/669private void combination_15(List<byte[]> results, int mode, byte[] AAD,670byte[] plainText, AlgorithmParameters params) throws Exception {671Cipher c = createCipher(mode, params);672673// prepare ByteBuffer1 to test674ByteBuffer buf1 = ByteBuffer.allocateDirect(AAD.length / 2);675buf1.put(AAD, 0, AAD.length / 2);676buf1.position(0);677buf1.limit(AAD.length / 2);678679// process the first half of AAD data680c.updateAAD(buf1);681682// prepare ByteBuffer2 to test683ByteBuffer buf2 = ByteBuffer.allocateDirect(684AAD.length - AAD.length / 2);685buf2.put(AAD, AAD.length / 2, AAD.length - AAD.length / 2);686buf2.position(0);687buf2.limit(AAD.length - AAD.length / 2);688689// process the rest of AAD data690c.updateAAD(buf2);691692// prepare buffers to encrypt/decrypt693ByteBuffer in = ByteBuffer.allocateDirect(plainText.length);694in.put(plainText);695in.position(0);696in.limit(plainText.length);697ByteBuffer output = ByteBuffer.allocateDirect(698c.getOutputSize(in.limit()));699output.position(0);700output.limit(c.getOutputSize(in.limit()));701702// process input text703c.doFinal(in, output);704int resultSize = output.position();705byte[] result15 = new byte[resultSize];706output.position(0);707output.limit(resultSize);708output.get(result15, 0, resultSize);709results.add(result15);710}711712/*713* Execute multiple-part encryption/decryption combination #16:714* updateAAD(ByteBuffer src)715* updateAAD(ByteBuffer emptyByteBuffer)716* update(ByteBuffer input, ByteBuffer out)717* doFinal(EmptyByteBuffer, ByteBuffer out)718*/719private void combination_16(List<byte[]> results, int mode, byte[] AAD,720byte[] plainText, AlgorithmParameters params) throws Exception {721Cipher c = createCipher(mode, params);722723// prepare ByteBuffer to test724ByteBuffer buf = ByteBuffer.allocateDirect(AAD.length);725buf.put(AAD);726buf.position(0);727buf.limit(AAD.length);728c.updateAAD(buf);729730// prepare empty ByteBuffer731ByteBuffer emptyBuf = ByteBuffer.allocateDirect(0);732emptyBuf.put(new byte[0]);733c.updateAAD(emptyBuf);734735// prepare buffers to encrypt/decrypt736ByteBuffer in = ByteBuffer.allocateDirect(plainText.length);737in.put(plainText);738in.position(0);739in.limit(plainText.length);740ByteBuffer output = ByteBuffer.allocateDirect(741c.getOutputSize(in.limit()));742output.position(0);743output.limit(c.getOutputSize(in.limit()));744745// process input text with an empty buffer746c.update(in, output);747ByteBuffer emptyBuf2 = ByteBuffer.allocate(0);748emptyBuf2.put(new byte[0]);749c.doFinal(emptyBuf2, output);750int resultSize = output.position();751byte[] result16 = new byte[resultSize];752output.position(0);753output.limit(resultSize);754output.get(result16, 0, resultSize);755results.add(result16);756}757}758759760