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 /**
26 * @author Tom Deneau
27 */
28
29 import jdk.test.lib.Utils;
30 import java.security.AlgorithmParameters;
31 import java.util.Random;
32 import javax.crypto.Cipher;
33 import javax.crypto.SecretKey;
34 import javax.crypto.spec.GCMParameterSpec;
35 import javax.crypto.spec.IvParameterSpec;
36 import javax.crypto.spec.SecretKeySpec;
37
38 abstract public class TestAESBase {
39 int msgSize = Integer.getInteger("msgSize", 646);
40 boolean checkOutput = Boolean.getBoolean("checkOutput");
41 boolean noReinit = Boolean.getBoolean("noReinit");
42 boolean testingMisalignment;
43 private static final int ALIGN = 8;
44 int encInputOffset = Integer.getInteger("encInputOffset", 0) % ALIGN;
45 int encOutputOffset = Integer.getInteger("encOutputOffset", 0) % ALIGN;
46 int decOutputOffset = Integer.getInteger("decOutputOffset", 0) % ALIGN;
47 int lastChunkSize = Integer.getInteger("lastChunkSize", 32);
48 int keySize = Integer.getInteger("keySize", 128);
49 int inputLength;
50 int encodeLength;
51 int decodeLength;
52 int decodeMsgSize;
53 String algorithm = System.getProperty("algorithm", "AES");
54 String mode = System.getProperty("mode", "CBC");
55 String paddingStr = System.getProperty("paddingStr", "PKCS5Padding");
56 byte[] input;
57 byte[] encode;
58 byte[] expectedEncode;
59 byte[] decode;
60 byte[] expectedDecode;
61 final Random random = Utils.getRandomInstance();
62 Cipher cipher;
63 Cipher dCipher;
64 AlgorithmParameters algParams = null;
65 SecretKey key;
66 GCMParameterSpec gcm_spec;
67 byte[] aad = { 0x11, 0x22, 0x33, 0x44, 0x55 };
68 int tlen = 12;
69 byte[] iv = new byte[16];
70
71 static int numThreads = 0;
72 int threadId;
73 static synchronized int getThreadId() {
74 int id = numThreads;
75 numThreads++;
76 return id;
77 }
78
79 abstract public void run();
80
81 public void prepare() {
82 try {
83 System.out.println("\nalgorithm=" + algorithm + ", mode=" + mode + ", paddingStr=" + paddingStr +
84 ", msgSize=" + msgSize + ", keySize=" + keySize + ", noReinit=" + noReinit +
85 ", checkOutput=" + checkOutput + ", encInputOffset=" + encInputOffset + ", encOutputOffset=" +
86 encOutputOffset + ", decOutputOffset=" + decOutputOffset + ", lastChunkSize=" +lastChunkSize );
87
88 if (encInputOffset % ALIGN != 0 || encOutputOffset % ALIGN != 0 || decOutputOffset % ALIGN !=0 )
89 testingMisalignment = true;
90
91 int keyLenBytes = (keySize == 0 ? 16 : keySize/8);
92 byte keyBytes[] = new byte[keyLenBytes];
93 if (keySize == 128)
94 keyBytes = new byte[] {-8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7};
95 else
96 random.nextBytes(keyBytes);
97
98 key = new SecretKeySpec(keyBytes, algorithm);
99 if (threadId == 0) {
100 System.out.println("Algorithm: " + key.getAlgorithm() + "("
101 + key.getEncoded().length * 8 + "bit)");
102 }
103
104 cipher = Cipher.getInstance(algorithm + "/" + mode + "/" + paddingStr, "SunJCE");
105 dCipher = Cipher.getInstance(algorithm + "/" + mode + "/" + paddingStr, "SunJCE");
106
107 // CBC or CTR init
108 if (mode.equals("CBC") || mode.equals("CTR")) {
109 IvParameterSpec initVector = new IvParameterSpec(iv);
110 cipher.init(Cipher.ENCRYPT_MODE, key, initVector);
111 algParams = cipher.getParameters();
112 dCipher.init(Cipher.DECRYPT_MODE, key, initVector);
113
114 // GCM init
121 cipher.init(Cipher.ENCRYPT_MODE, key, algParams);
122 dCipher.init(Cipher.DECRYPT_MODE, key, algParams);
123 }
124
125 if (threadId == 0) {
126 childShowCipher();
127 }
128
129 inputLength = msgSize + encInputOffset;
130 if (testingMisalignment) {
131 encodeLength = cipher.getOutputSize(msgSize - lastChunkSize) + encOutputOffset;
132 encodeLength += cipher.getOutputSize(lastChunkSize);
133 decodeLength = dCipher.getOutputSize(encodeLength - lastChunkSize) + decOutputOffset;
134 decodeLength += dCipher.getOutputSize(lastChunkSize);
135 } else {
136 encodeLength = cipher.getOutputSize(msgSize) + encOutputOffset;
137 decodeLength = dCipher.getOutputSize(encodeLength) + decOutputOffset;
138 }
139
140 input = new byte[inputLength];
141 for (int i=encInputOffset, j=0; i<inputLength; i++, j++) {
142 input[i] = (byte) (j & 0xff);
143 }
144
145 // do one encode and decode in preparation
146 encode = new byte[encodeLength];
147 decode = new byte[decodeLength];
148 if (testingMisalignment) {
149 decodeMsgSize = cipher.update(input, encInputOffset, (msgSize - lastChunkSize), encode, encOutputOffset);
150 decodeMsgSize += cipher.doFinal(input, (encInputOffset + msgSize - lastChunkSize), lastChunkSize, encode, (encOutputOffset + decodeMsgSize));
151
152 int tempSize = dCipher.update(encode, encOutputOffset, (decodeMsgSize - lastChunkSize), decode, decOutputOffset);
153 dCipher.doFinal(encode, (encOutputOffset + decodeMsgSize - lastChunkSize), lastChunkSize, decode, (decOutputOffset + tempSize));
154 } else {
155 decodeMsgSize = cipher.doFinal(input, encInputOffset, msgSize, encode, encOutputOffset);
156 dCipher.doFinal(encode, encOutputOffset, decodeMsgSize, decode, decOutputOffset);
157 }
158 if (checkOutput) {
159 expectedEncode = (byte[]) encode.clone();
160 expectedDecode = (byte[]) decode.clone();
161 showArray(key.getEncoded() , "key: ");
162 showArray(input, "input: ");
163 showArray(encode, "encode: ");
164 showArray(decode, "decode: ");
165 }
166 }
167 catch (Exception e) {
168 e.printStackTrace();
169 System.exit(1);
170 }
171 }
172
173 void showArray(byte b[], String name) {
174 System.out.format("%s [%d]: ", name, b.length);
175 for (int i=0; i<Math.min(b.length, 32); i++) {
176 System.out.format("%02x ", b[i] & 0xff);
177 }
178 System.out.println();
179 }
180
181 void compareArrays(byte b[], byte exp[]) {
182 if (b.length != exp.length) {
183 System.out.format("different lengths for actual and expected output arrays\n");
184 showArray(b, "test: ");
185 showArray(exp, "exp : ");
186 System.exit(1);
187 }
188 for (int i=0; i< exp.length; i++) {
189 if (b[i] != exp[i]) {
190 System.out.format("output error at index %d: got %02x, expected %02x\n", i, b[i] & 0xff, exp[i] & 0xff);
191 showArray(b, "test: ");
192 showArray(exp, "exp : ");
193 System.exit(1);
194 }
195 }
196 }
197
198
199 void showCipher(Cipher c, String kind) {
200 System.out.println(kind + " cipher provider: " + cipher.getProvider());
201 System.out.println(kind + " cipher algorithm: " + cipher.getAlgorithm());
202 }
203
204 abstract void childShowCipher();
205
206 void gcm_init(boolean encrypt) throws Exception {
207 gcm_spec = new GCMParameterSpec(tlen * 8, iv);
208 if (encrypt) {
209 // Get a new instance everytime because of reuse IV restrictions
210 cipher = Cipher.getInstance(algorithm + "/" + mode + "/" + paddingStr, "SunJCE");
211 cipher.init(Cipher.ENCRYPT_MODE, key, gcm_spec);
212 cipher.updateAAD(aad);
213 } else {
214 dCipher.init(Cipher.DECRYPT_MODE, key, gcm_spec);
215 dCipher.updateAAD(aad);
216
217
218 }
|
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
26 package compiler.codegen.aes;
27
28 import jdk.test.lib.Utils;
29
30 import javax.crypto.Cipher;
31 import javax.crypto.SecretKey;
32 import javax.crypto.spec.GCMParameterSpec;
33 import javax.crypto.spec.IvParameterSpec;
34 import javax.crypto.spec.SecretKeySpec;
35 import java.security.AlgorithmParameters;
36 import java.util.Random;
37
38 /**
39 * @author Tom Deneau
40 */
41 public abstract class TestAESBase {
42 int msgSize = Integer.getInteger("msgSize", 646);
43 boolean checkOutput = Boolean.getBoolean("checkOutput");
44 boolean noReinit = Boolean.getBoolean("noReinit");
45 boolean testingMisalignment;
46 private static final int ALIGN = 8;
47 int encInputOffset = Integer.getInteger("encInputOffset", 0) % ALIGN;
48 int encOutputOffset = Integer.getInteger("encOutputOffset", 0) % ALIGN;
49 int decOutputOffset = Integer.getInteger("decOutputOffset", 0) % ALIGN;
50 int lastChunkSize = Integer.getInteger("lastChunkSize", 32);
51 int keySize = Integer.getInteger("keySize", 128);
52 int inputLength;
53 int encodeLength;
54 int decodeLength;
55 int decodeMsgSize;
56 String algorithm = System.getProperty("algorithm", "AES");
57 String mode = System.getProperty("mode", "CBC");
58 String paddingStr = System.getProperty("paddingStr", "PKCS5Padding");
59 byte[] input;
60 byte[] encode;
61 byte[] expectedEncode;
62 byte[] decode;
63 byte[] expectedDecode;
64 final Random random = Utils.getRandomInstance();
65 Cipher cipher;
66 Cipher dCipher;
67 AlgorithmParameters algParams = null;
68 SecretKey key;
69 GCMParameterSpec gcm_spec;
70 byte[] aad = {0x11, 0x22, 0x33, 0x44, 0x55};
71 int tlen = 12;
72 byte[] iv = new byte[16];
73
74 static int numThreads = 0;
75 int threadId;
76
77 static synchronized int getThreadId() {
78 int id = numThreads;
79 numThreads++;
80 return id;
81 }
82
83 abstract public void run();
84
85 public void prepare() {
86 try {
87 System.out.println("\nalgorithm=" + algorithm + ", mode=" + mode + ", paddingStr=" + paddingStr +
88 ", msgSize=" + msgSize + ", keySize=" + keySize + ", noReinit=" + noReinit +
89 ", checkOutput=" + checkOutput + ", encInputOffset=" + encInputOffset + ", encOutputOffset=" +
90 encOutputOffset + ", decOutputOffset=" + decOutputOffset + ", lastChunkSize=" + lastChunkSize);
91
92 if (encInputOffset % ALIGN != 0 || encOutputOffset % ALIGN != 0 || decOutputOffset % ALIGN != 0)
93 testingMisalignment = true;
94
95 int keyLenBytes = (keySize == 0 ? 16 : keySize / 8);
96 byte keyBytes[] = new byte[keyLenBytes];
97 if (keySize == 128)
98 keyBytes = new byte[]{-8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7};
99 else
100 random.nextBytes(keyBytes);
101
102 key = new SecretKeySpec(keyBytes, algorithm);
103 if (threadId == 0) {
104 System.out.println("Algorithm: " + key.getAlgorithm() + "("
105 + key.getEncoded().length * 8 + "bit)");
106 }
107
108 cipher = Cipher.getInstance(algorithm + "/" + mode + "/" + paddingStr, "SunJCE");
109 dCipher = Cipher.getInstance(algorithm + "/" + mode + "/" + paddingStr, "SunJCE");
110
111 // CBC or CTR init
112 if (mode.equals("CBC") || mode.equals("CTR")) {
113 IvParameterSpec initVector = new IvParameterSpec(iv);
114 cipher.init(Cipher.ENCRYPT_MODE, key, initVector);
115 algParams = cipher.getParameters();
116 dCipher.init(Cipher.DECRYPT_MODE, key, initVector);
117
118 // GCM init
125 cipher.init(Cipher.ENCRYPT_MODE, key, algParams);
126 dCipher.init(Cipher.DECRYPT_MODE, key, algParams);
127 }
128
129 if (threadId == 0) {
130 childShowCipher();
131 }
132
133 inputLength = msgSize + encInputOffset;
134 if (testingMisalignment) {
135 encodeLength = cipher.getOutputSize(msgSize - lastChunkSize) + encOutputOffset;
136 encodeLength += cipher.getOutputSize(lastChunkSize);
137 decodeLength = dCipher.getOutputSize(encodeLength - lastChunkSize) + decOutputOffset;
138 decodeLength += dCipher.getOutputSize(lastChunkSize);
139 } else {
140 encodeLength = cipher.getOutputSize(msgSize) + encOutputOffset;
141 decodeLength = dCipher.getOutputSize(encodeLength) + decOutputOffset;
142 }
143
144 input = new byte[inputLength];
145 for (int i = encInputOffset, j = 0; i < inputLength; i++, j++) {
146 input[i] = (byte) (j & 0xff);
147 }
148
149 // do one encode and decode in preparation
150 encode = new byte[encodeLength];
151 decode = new byte[decodeLength];
152 if (testingMisalignment) {
153 decodeMsgSize = cipher.update(input, encInputOffset, (msgSize - lastChunkSize), encode, encOutputOffset);
154 decodeMsgSize += cipher.doFinal(input, (encInputOffset + msgSize - lastChunkSize), lastChunkSize, encode, (encOutputOffset + decodeMsgSize));
155
156 int tempSize = dCipher.update(encode, encOutputOffset, (decodeMsgSize - lastChunkSize), decode, decOutputOffset);
157 dCipher.doFinal(encode, (encOutputOffset + decodeMsgSize - lastChunkSize), lastChunkSize, decode, (decOutputOffset + tempSize));
158 } else {
159 decodeMsgSize = cipher.doFinal(input, encInputOffset, msgSize, encode, encOutputOffset);
160 dCipher.doFinal(encode, encOutputOffset, decodeMsgSize, decode, decOutputOffset);
161 }
162 if (checkOutput) {
163 expectedEncode = (byte[]) encode.clone();
164 expectedDecode = (byte[]) decode.clone();
165 showArray(key.getEncoded(), "key: ");
166 showArray(input, "input: ");
167 showArray(encode, "encode: ");
168 showArray(decode, "decode: ");
169 }
170 } catch (Exception e) {
171 e.printStackTrace();
172 System.exit(1);
173 }
174 }
175
176 void showArray(byte b[], String name) {
177 System.out.format("%s [%d]: ", name, b.length);
178 for (int i = 0; i < Math.min(b.length, 32); i++) {
179 System.out.format("%02x ", b[i] & 0xff);
180 }
181 System.out.println();
182 }
183
184 void compareArrays(byte b[], byte exp[]) {
185 if (b.length != exp.length) {
186 System.out.format("different lengths for actual and expected output arrays\n");
187 showArray(b, "test: ");
188 showArray(exp, "exp : ");
189 System.exit(1);
190 }
191 for (int i = 0; i < exp.length; i++) {
192 if (b[i] != exp[i]) {
193 System.out.format("output error at index %d: got %02x, expected %02x\n", i, b[i] & 0xff, exp[i] & 0xff);
194 showArray(b, "test: ");
195 showArray(exp, "exp : ");
196 System.exit(1);
197 }
198 }
199 }
200
201 void showCipher(Cipher c, String kind) {
202 System.out.println(kind + " cipher provider: " + cipher.getProvider());
203 System.out.println(kind + " cipher algorithm: " + cipher.getAlgorithm());
204 }
205
206 abstract void childShowCipher();
207
208 void gcm_init(boolean encrypt) throws Exception {
209 gcm_spec = new GCMParameterSpec(tlen * 8, iv);
210 if (encrypt) {
211 // Get a new instance everytime because of reuse IV restrictions
212 cipher = Cipher.getInstance(algorithm + "/" + mode + "/" + paddingStr, "SunJCE");
213 cipher.init(Cipher.ENCRYPT_MODE, key, gcm_spec);
214 cipher.updateAAD(aad);
215 } else {
216 dCipher.init(Cipher.DECRYPT_MODE, key, gcm_spec);
217 dCipher.updateAAD(aad);
218
219
220 }
|