1 /*
2 * Copyright (c) 2007, 2016, 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 /*
25 * @test
26 * @bug 4898484 6604496 8001284
27 * @summary basic test for symmetric ciphers with no padding
28 * @author Valerie Peng
29 * @library ..
30 * @key randomness
31 * @modules jdk.crypto.token
32 * @run main/othervm TestSymmCiphersNoPad
33 * @run main/othervm TestSymmCiphersNoPad sm
34 */
35
36 import java.io.ByteArrayInputStream;
37 import java.io.ByteArrayOutputStream;
38 import java.io.InputStream;
39 import java.nio.ByteBuffer;
40 import java.security.AlgorithmParameters;
41 import java.security.NoSuchAlgorithmException;
42 import java.security.Provider;
43 import java.util.Random;
44 import javax.crypto.Cipher;
45 import javax.crypto.CipherInputStream;
46 import javax.crypto.KeyGenerator;
47 import javax.crypto.SecretKey;
48
49 public class TestSymmCiphersNoPad extends PKCS11Test {
50
51 private static class CI { // class for holding Cipher Information
52 String transformation;
53 String keyAlgo;
54 int dataSize;
55
56 CI(String transformation, String keyAlgo, int dataSize) {
57 this.transformation = transformation;
58 this.keyAlgo = keyAlgo;
59 this.dataSize = dataSize;
60 }
61 }
62
63 private static final CI TEST_LIST[] = {
64 new CI("ARCFOUR", "ARCFOUR", 400),
65 new CI("RC4", "RC4", 401),
66 new CI("DES/CBC/NoPadding", "DES", 400),
67 new CI("DESede/CBC/NoPadding", "DESede", 160),
68 new CI("AES/CBC/NoPadding", "AES", 4800),
69 new CI("Blowfish/CBC/NoPadding", "Blowfish", 24),
70 new CI("AES/CTR/NoPadding", "AES", 1600),
71 new CI("AES/CTR/NoPadding", "AES", 65)
72 };
73
74 private static StringBuffer debugBuf;
75
76 @Override
77 public void main(Provider p) throws Exception {
78 boolean status = true;
79 Random random = new Random();
80 try {
81 for (int i = 0; i < TEST_LIST.length; i++) {
82 CI currTest = TEST_LIST[i];
83 System.out.println("===" + currTest.transformation + "===");
84 try {
85 KeyGenerator kg =
86 KeyGenerator.getInstance(currTest.keyAlgo, p);
87 SecretKey key = kg.generateKey();
88 Cipher c1 = Cipher.getInstance(currTest.transformation, p);
89 Cipher c2 = Cipher.getInstance(currTest.transformation,
90 "SunJCE");
91
92 byte[] plainTxt = new byte[currTest.dataSize];
93 random.nextBytes(plainTxt);
94 System.out.println("Testing inLen = " + plainTxt.length);
95
96 c2.init(Cipher.ENCRYPT_MODE, key);
97 AlgorithmParameters params = c2.getParameters();
98 byte[] answer = c2.doFinal(plainTxt);
99 test(c1, Cipher.ENCRYPT_MODE, key, params,
100 plainTxt, answer);
101 System.out.println("Encryption tests: DONE");
102 c2.init(Cipher.DECRYPT_MODE, key, params);
103 byte[] answer2 = c2.doFinal(answer);
104 test(c1, Cipher.DECRYPT_MODE, key, params,
105 answer, answer2);
106 System.out.println("Decryption tests: DONE");
107 } catch (NoSuchAlgorithmException nsae) {
108 System.out.println("Skipping unsupported algorithm: " +
109 nsae);
110 }
111 }
112 } catch (Exception ex) {
113 // print out debug info when exception is encountered
114 if (debugBuf != null) {
115 System.out.println(debugBuf.toString());
116 }
117 throw ex;
118 }
119 }
120
121 private static void test(Cipher cipher, int mode, SecretKey key,
122 AlgorithmParameters params,
123 byte[] in, byte[] answer) throws Exception {
124 // test setup
125 debugBuf = new StringBuffer();
126 cipher.init(mode, key, params);
127 int outLen = cipher.getOutputSize(in.length);
128 debugBuf.append("Estimated output size = " + outLen + "\n");
129
130 // test data preparation
131 ByteBuffer inBuf = ByteBuffer.allocate(in.length);
132 inBuf.put(in);
133 inBuf.position(0);
134 ByteBuffer inDirectBuf = ByteBuffer.allocateDirect(in.length);
135 inDirectBuf.put(in);
136 inDirectBuf.position(0);
137 ByteBuffer outBuf = ByteBuffer.allocate(outLen);
138 ByteBuffer outDirectBuf = ByteBuffer.allocateDirect(outLen);
139
140 // test#1: byte[] in + byte[] out
141 debugBuf.append("Test#1:\n");
142 ByteArrayOutputStream baos = new ByteArrayOutputStream();
143 byte[] testOut1 = cipher.update(in, 0, 16);
144 if (testOut1 != null) baos.write(testOut1, 0, testOut1.length);
145 testOut1 = cipher.doFinal(in, 16, in.length-16);
146 if (testOut1 != null) baos.write(testOut1, 0, testOut1.length);
147 testOut1 = baos.toByteArray();
148 match(testOut1, answer);
149
150 // test#2: Non-direct Buffer in + non-direct Buffer out
151 debugBuf.append("Test#2:\n");
152 debugBuf.append("inputBuf: " + inBuf + "\n");
153 debugBuf.append("outputBuf: " + outBuf + "\n");
154 cipher.update(inBuf, outBuf);
155 cipher.doFinal(inBuf, outBuf);
156 match(outBuf, answer);
157
158 // test#3: Direct Buffer in + direc Buffer out
159 debugBuf.append("Test#3:\n");
160 debugBuf.append("(pre) inputBuf: " + inDirectBuf + "\n");
161 debugBuf.append("(pre) outputBuf: " + outDirectBuf + "\n");
162 cipher.update(inDirectBuf, outDirectBuf);
163 cipher.doFinal(inDirectBuf, outDirectBuf);
164
165 debugBuf.append("(post) inputBuf: " + inDirectBuf + "\n");
166 debugBuf.append("(post) outputBuf: " + outDirectBuf + "\n");
167 match(outDirectBuf, answer);
168
169 // test#4: Direct Buffer in + non-direct Buffer out
170 debugBuf.append("Test#4:\n");
171 inDirectBuf.position(0);
172 outBuf.position(0);
173 debugBuf.append("inputBuf: " + inDirectBuf + "\n");
174 debugBuf.append("outputBuf: " + outBuf + "\n");
175 cipher.update(inDirectBuf, outBuf);
176 cipher.doFinal(inDirectBuf, outBuf);
177 match(outBuf, answer);
178
179 // test#5: Non-direct Buffer in + direct Buffer out
180 debugBuf.append("Test#5:\n");
181 inBuf.position(0);
182 outDirectBuf.position(0);
183
184 debugBuf.append("(pre) inputBuf: " + inBuf + "\n");
185 debugBuf.append("(pre) outputBuf: " + outDirectBuf + "\n");
186
187 cipher.update(inBuf, outDirectBuf);
188 cipher.doFinal(inBuf, outDirectBuf);
189
190 debugBuf.append("(post) inputBuf: " + inBuf + "\n");
191 debugBuf.append("(post) outputBuf: " + outDirectBuf + "\n");
192 match(outDirectBuf, answer);
193
194 // test#6: Streams
195 debugBuf.append("Test#6: Streaming\n");
196 outBuf.position(0);
197 InputStream stream =
198 new CipherInputStream(new ByteArrayInputStream(in), cipher);
199 byte[] data = new byte[1024];
200 int bytesRead = 0;
201 try {
202 while (bytesRead >= 0) {
203 bytesRead = stream.read(data);
204 if (bytesRead == -1)
205 break;
206 debugBuf.append("bytesRead: " + bytesRead);
207 debugBuf.append("\toutBuf.position(): " + outBuf.position() +
208 "\n");
209 outBuf.put(data, 0 , bytesRead);
210 }
211 } catch (Exception ex) {
212 debugBuf.append("Caught Exception during stream reading\n");
213 throw ex;
214 }
215 match(outBuf, answer);
216
217 debugBuf = null;
218 }
219
220 private static void match(byte[] b1, byte[] b2) throws Exception {
221 if (b1.length != b2.length) {
222 debugBuf.append("got len : " + b1.length + "\n");
223 debugBuf.append("expect len: " + b2.length + "\n");
224 throw new Exception("mismatch - different length!\n");
225 } else {
226 for (int i = 0; i < b1.length; i++) {
227 if (b1[i] != b2[i]) {
228 debugBuf.append("got : " + toString(b1) + "\n");
229 debugBuf.append("expect: " + toString(b2) + "\n");
230 throw new Exception("mismatch");
231 }
232 }
233 }
234 }
235
236 private static void match(ByteBuffer bb, byte[] answer) throws Exception {
237 byte[] bbTemp = new byte[bb.position()];
238 bb.position(0);
239 bb.get(bbTemp, 0, bbTemp.length);
240 match(bbTemp, answer);
241 }
242
243 public static void main(String[] args) throws Exception {
244 main(new TestSymmCiphersNoPad(), args);
245 }
246 }