CipherTest.java revision 2ae508725e0b6c4dd4c23717bc1625bd745670b6
1/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package libcore.javax.crypto;
18
19import com.android.org.bouncycastle.asn1.x509.KeyUsage;
20import java.io.ByteArrayOutputStream;
21import java.io.PrintStream;
22import java.math.BigInteger;
23import java.nio.ByteBuffer;
24import java.security.AlgorithmParameters;
25import java.security.InvalidAlgorithmParameterException;
26import java.security.InvalidKeyException;
27import java.security.Key;
28import java.security.KeyFactory;
29import java.security.NoSuchAlgorithmException;
30import java.security.PrivateKey;
31import java.security.Provider;
32import java.security.PublicKey;
33import java.security.SecureRandom;
34import java.security.Security;
35import java.security.cert.Certificate;
36import java.security.spec.AlgorithmParameterSpec;
37import java.security.spec.RSAPrivateKeySpec;
38import java.security.spec.RSAPublicKeySpec;
39import java.util.ArrayList;
40import java.util.Arrays;
41import java.util.Collections;
42import java.util.HashMap;
43import java.util.HashSet;
44import java.util.List;
45import java.util.Locale;
46import java.util.Map;
47import java.util.Set;
48import javax.crypto.AEADBadTagException;
49import javax.crypto.BadPaddingException;
50import javax.crypto.Cipher;
51import javax.crypto.IllegalBlockSizeException;
52import javax.crypto.KeyGenerator;
53import javax.crypto.SecretKey;
54import javax.crypto.SecretKeyFactory;
55import javax.crypto.ShortBufferException;
56import javax.crypto.spec.GCMParameterSpec;
57import javax.crypto.spec.IvParameterSpec;
58import javax.crypto.spec.PBEKeySpec;
59import javax.crypto.spec.PBEParameterSpec;
60import javax.crypto.spec.SecretKeySpec;
61import junit.framework.TestCase;
62import libcore.java.security.StandardNames;
63import libcore.java.security.TestKeyStore;
64
65public final class CipherTest extends TestCase {
66
67    /** GCM tag size used for tests. */
68    private static final int GCM_TAG_SIZE_BITS = 96;
69
70    private static final String[] RSA_PROVIDERS = ((StandardNames.IS_RI)
71                                                   ? new String[] { "SunJCE" }
72                                                   : new String[] { "BC" , "AndroidOpenSSL" });
73
74    private static final String[] AES_PROVIDERS = ((StandardNames.IS_RI)
75                                                   ? new String[] { "SunJCE" }
76                                                   : new String[] { "BC", "AndroidOpenSSL" });
77
78    private static boolean isSupported(String algorithm, String provider) {
79        if (algorithm.equals("RC2")) {
80            return false;
81        }
82        if (algorithm.equals("PBEWITHMD5ANDRC2")) {
83            return false;
84        }
85        if (algorithm.startsWith("PBEWITHSHA1ANDRC2")) {
86            return false;
87        }
88        if (algorithm.equals("PBEWITHSHAAND40BITRC2-CBC")) {
89            return false;
90        }
91        if (algorithm.equals("PBEWITHSHAAND128BITRC2-CBC")) {
92            return false;
93        }
94        if (algorithm.equals("PBEWITHSHAANDTWOFISH-CBC")) {
95            return false;
96        }
97        if (!IS_UNLIMITED) {
98            if (algorithm.equals("PBEWITHMD5ANDTRIPLEDES")) {
99                return false;
100            }
101        }
102        // stream modes CFB, CTR, CTS, OFB with PKCS5Padding or PKCS7Padding don't really make sense
103        if (!provider.equals("AndroidOpenSSL") &&
104            (algorithm.equals("AES/CFB/PKCS5PADDING")
105             || algorithm.equals("AES/CFB/PKCS7PADDING")
106             || algorithm.equals("AES/CTR/PKCS5PADDING")
107             || algorithm.equals("AES/CTR/PKCS7PADDING")
108             || algorithm.equals("AES/CTS/PKCS5PADDING")
109             || algorithm.equals("AES/CTS/PKCS7PADDING")
110             || algorithm.equals("AES/OFB/PKCS5PADDING")
111             || algorithm.equals("AES/OFB/PKCS7PADDING"))) {
112            return false;
113        }
114        return true;
115    }
116
117    private static boolean isSupportedForWrapping(String algorithm) {
118        if (isOnlyWrappingAlgorithm(algorithm)) {
119            return true;
120        }
121        // http://b/9097343 RSA with NoPadding won't work since
122        // leading zeroes in the underlying key material are lost.
123        if (algorithm.equals("RSA/ECB/NOPADDING")) {
124            return false;
125        }
126        // AESWRAP should be used instead, fails with BC and SunJCE otherwise.
127        if (algorithm.startsWith("AES") || algorithm.startsWith("DESEDE")) {
128            return false;
129        }
130        return true;
131    }
132
133    private synchronized static int getEncryptMode(String algorithm) throws Exception {
134        if (isOnlyWrappingAlgorithm(algorithm)) {
135            return Cipher.WRAP_MODE;
136        }
137        return Cipher.ENCRYPT_MODE;
138    }
139
140    private synchronized static int getDecryptMode(String algorithm) throws Exception {
141        if (isOnlyWrappingAlgorithm(algorithm)) {
142            return Cipher.UNWRAP_MODE;
143        }
144        return Cipher.DECRYPT_MODE;
145    }
146
147    private static String getBaseAlgorithm(String algorithm) {
148        if (algorithm.equals("AESWRAP")) {
149            return "AES";
150        }
151        if (algorithm.startsWith("AES/")) {
152            return "AES";
153        }
154        if (algorithm.equals("GCM")) {
155            return "AES";
156        }
157        if (algorithm.startsWith("DESEDE/")) {
158            return "DESEDE";
159        }
160        if (algorithm.equals("PBEWITHMD5AND128BITAES-CBC-OPENSSL")) {
161            return "AES";
162        }
163        if (algorithm.equals("PBEWITHMD5AND192BITAES-CBC-OPENSSL")) {
164            return "AES";
165        }
166        if (algorithm.equals("PBEWITHMD5AND256BITAES-CBC-OPENSSL")) {
167            return "AES";
168        }
169        if (algorithm.equals("PBEWITHSHA256AND128BITAES-CBC-BC")) {
170            return "AES";
171        }
172        if (algorithm.equals("PBEWITHSHA256AND192BITAES-CBC-BC")) {
173            return "AES";
174        }
175        if (algorithm.equals("PBEWITHSHA256AND256BITAES-CBC-BC")) {
176            return "AES";
177        }
178        if (algorithm.equals("PBEWITHSHAAND128BITAES-CBC-BC")) {
179            return "AES";
180        }
181        if (algorithm.equals("PBEWITHSHAAND192BITAES-CBC-BC")) {
182            return "AES";
183        }
184        if (algorithm.equals("PBEWITHSHAAND256BITAES-CBC-BC")) {
185            return "AES";
186        }
187        if (algorithm.equals("PBEWITHMD5ANDDES")) {
188            return "DES";
189        }
190        if (algorithm.equals("PBEWITHSHA1ANDDES")) {
191            return "DES";
192        }
193        if (algorithm.equals("DESEDEWRAP")) {
194            return "DESEDE";
195        }
196        if (algorithm.equals("PBEWITHSHAAND2-KEYTRIPLEDES-CBC")) {
197            return "DESEDE";
198        }
199        if (algorithm.equals("PBEWITHSHAAND3-KEYTRIPLEDES-CBC")) {
200            return "DESEDE";
201        }
202        if (algorithm.equals("PBEWITHMD5ANDTRIPLEDES")) {
203            return "DESEDE";
204        }
205        if (algorithm.equals("PBEWITHSHA1ANDDESEDE")) {
206            return "DESEDE";
207        }
208        if (algorithm.equals("RSA/ECB/NOPADDING")) {
209            return "RSA";
210        }
211        if (algorithm.equals("RSA/ECB/PKCS1PADDING")) {
212            return "RSA";
213        }
214        if (algorithm.equals("PBEWITHSHAAND40BITRC4")) {
215            return "ARC4";
216        }
217        if (algorithm.equals("PBEWITHSHAAND128BITRC4")) {
218            return "ARC4";
219        }
220        return algorithm;
221    }
222
223    private static boolean isAsymmetric(String algorithm) {
224        return getBaseAlgorithm(algorithm).equals("RSA");
225    }
226
227    private static boolean isOnlyWrappingAlgorithm(String algorithm) {
228        return algorithm.endsWith("WRAP");
229    }
230
231    private static boolean isPBE(String algorithm) {
232        return algorithm.startsWith("PBE");
233    }
234
235    private static boolean isAEAD(String algorithm) {
236        return "GCM".equals(algorithm) || algorithm.contains("/GCM/");
237    }
238
239    private static boolean isStreamMode(String algorithm) {
240        return algorithm.contains("/CTR/") || algorithm.contains("/OFB")
241                || algorithm.contains("/CFB");
242    }
243
244    private static Map<String, Key> ENCRYPT_KEYS = new HashMap<String, Key>();
245    private synchronized static Key getEncryptKey(String algorithm) throws Exception {
246        Key key = ENCRYPT_KEYS.get(algorithm);
247        if (key != null) {
248            return key;
249        }
250        if (algorithm.startsWith("RSA")) {
251            KeyFactory kf = KeyFactory.getInstance("RSA");
252            RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
253                                                              RSA_2048_privateExponent);
254            key = kf.generatePrivate(keySpec);
255        } else if (isPBE(algorithm)) {
256            SecretKeyFactory skf = SecretKeyFactory.getInstance(algorithm);
257            key = skf.generateSecret(new PBEKeySpec("secret".toCharArray()));
258        } else {
259            KeyGenerator kg = KeyGenerator.getInstance(getBaseAlgorithm(algorithm));
260            key = kg.generateKey();
261        }
262        ENCRYPT_KEYS.put(algorithm, key);
263        return key;
264    }
265
266    private static Map<String, Key> DECRYPT_KEYS = new HashMap<String, Key>();
267    private synchronized static Key getDecryptKey(String algorithm) throws Exception {
268        Key key = DECRYPT_KEYS.get(algorithm);
269        if (key != null) {
270            return key;
271        }
272        if (algorithm.startsWith("RSA")) {
273            KeyFactory kf = KeyFactory.getInstance("RSA");
274            RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus,
275                                                            RSA_2048_publicExponent);
276            key = kf.generatePublic(keySpec);
277        } else {
278            assertFalse(algorithm, isAsymmetric(algorithm));
279            key = getEncryptKey(algorithm);
280        }
281        DECRYPT_KEYS.put(algorithm, key);
282        return key;
283    }
284
285    private static Map<String, Integer> EXPECTED_BLOCK_SIZE = new HashMap<String, Integer>();
286    static {
287        setExpectedBlockSize("AES", 16);
288        setExpectedBlockSize("AES/CBC/PKCS5PADDING", 16);
289        setExpectedBlockSize("AES/CBC/PKCS7PADDING", 16);
290        setExpectedBlockSize("AES/CBC/NOPADDING", 16);
291        setExpectedBlockSize("AES/CFB/PKCS5PADDING", 16);
292        setExpectedBlockSize("AES/CFB/PKCS7PADDING", 16);
293        setExpectedBlockSize("AES/CFB/NOPADDING", 16);
294        setExpectedBlockSize("AES/CTR/PKCS5PADDING", 16);
295        setExpectedBlockSize("AES/CTR/PKCS7PADDING", 16);
296        setExpectedBlockSize("AES/CTR/NOPADDING", 16);
297        setExpectedBlockSize("AES/CTS/PKCS5PADDING", 16);
298        setExpectedBlockSize("AES/CTS/PKCS7PADDING", 16);
299        setExpectedBlockSize("AES/CTS/NOPADDING", 16);
300        setExpectedBlockSize("AES/ECB/PKCS5PADDING", 16);
301        setExpectedBlockSize("AES/ECB/PKCS7PADDING", 16);
302        setExpectedBlockSize("AES/ECB/NOPADDING", 16);
303        setExpectedBlockSize("AES/GCM/NOPADDING", 16);
304        setExpectedBlockSize("AES/OFB/PKCS5PADDING", 16);
305        setExpectedBlockSize("AES/OFB/PKCS7PADDING", 16);
306        setExpectedBlockSize("AES/OFB/NOPADDING", 16);
307        setExpectedBlockSize("PBEWITHMD5AND128BITAES-CBC-OPENSSL", 16);
308        setExpectedBlockSize("PBEWITHMD5AND192BITAES-CBC-OPENSSL", 16);
309        setExpectedBlockSize("PBEWITHMD5AND256BITAES-CBC-OPENSSL", 16);
310        setExpectedBlockSize("PBEWITHSHA256AND128BITAES-CBC-BC", 16);
311        setExpectedBlockSize("PBEWITHSHA256AND192BITAES-CBC-BC", 16);
312        setExpectedBlockSize("PBEWITHSHA256AND256BITAES-CBC-BC", 16);
313        setExpectedBlockSize("PBEWITHSHAAND128BITAES-CBC-BC", 16);
314        setExpectedBlockSize("PBEWITHSHAAND192BITAES-CBC-BC", 16);
315        setExpectedBlockSize("PBEWITHSHAAND256BITAES-CBC-BC", 16);
316
317        if (StandardNames.IS_RI) {
318            setExpectedBlockSize("AESWRAP", 16);
319        } else {
320            setExpectedBlockSize("AESWRAP", 0);
321        }
322
323        setExpectedBlockSize("ARC4", 0);
324        setExpectedBlockSize("ARCFOUR", 0);
325        setExpectedBlockSize("PBEWITHSHAAND40BITRC4", 0);
326        setExpectedBlockSize("PBEWITHSHAAND128BITRC4", 0);
327
328        setExpectedBlockSize("BLOWFISH", 8);
329
330        setExpectedBlockSize("DES", 8);
331        setExpectedBlockSize("PBEWITHMD5ANDDES", 8);
332        setExpectedBlockSize("PBEWITHSHA1ANDDES", 8);
333
334        setExpectedBlockSize("DESEDE", 8);
335        setExpectedBlockSize("DESEDE/CBC/PKCS5PADDING", 8);
336        setExpectedBlockSize("DESEDE/CBC/PKCS7PADDING", 8);
337        setExpectedBlockSize("DESEDE/CBC/NOPADDING", 8);
338        setExpectedBlockSize("DESEDE/CFB/PKCS5PADDING", 8);
339        setExpectedBlockSize("DESEDE/CFB/PKCS7PADDING", 8);
340        setExpectedBlockSize("DESEDE/CFB/NOPADDING", 8);
341        setExpectedBlockSize("DESEDE/CTR/PKCS5PADDING", 8);
342        setExpectedBlockSize("DESEDE/CTR/PKCS7PADDING", 8);
343        setExpectedBlockSize("DESEDE/CTR/NOPADDING", 8);
344        setExpectedBlockSize("DESEDE/CTS/PKCS5PADDING", 8);
345        setExpectedBlockSize("DESEDE/CTS/PKCS7PADDING", 8);
346        setExpectedBlockSize("DESEDE/CTS/NOPADDING", 8);
347        setExpectedBlockSize("DESEDE/ECB/PKCS5PADDING", 8);
348        setExpectedBlockSize("DESEDE/ECB/PKCS7PADDING", 8);
349        setExpectedBlockSize("DESEDE/ECB/NOPADDING", 8);
350        setExpectedBlockSize("DESEDE/OFB/PKCS5PADDING", 8);
351        setExpectedBlockSize("DESEDE/OFB/PKCS7PADDING", 8);
352        setExpectedBlockSize("DESEDE/OFB/NOPADDING", 8);
353        setExpectedBlockSize("PBEWITHSHAAND2-KEYTRIPLEDES-CBC", 8);
354        setExpectedBlockSize("PBEWITHSHAAND3-KEYTRIPLEDES-CBC", 8);
355        setExpectedBlockSize("PBEWITHMD5ANDTRIPLEDES", 8);
356        setExpectedBlockSize("PBEWITHSHA1ANDDESEDE", 8);
357
358
359        if (StandardNames.IS_RI) {
360            setExpectedBlockSize("DESEDEWRAP", 8);
361        } else {
362            setExpectedBlockSize("DESEDEWRAP", 0);
363        }
364
365        if (StandardNames.IS_RI) {
366            setExpectedBlockSize("RSA", 0);
367            setExpectedBlockSize("RSA/ECB/NoPadding", 0);
368            setExpectedBlockSize("RSA/ECB/PKCS1Padding", 0);
369        } else {
370            setExpectedBlockSize("RSA", Cipher.ENCRYPT_MODE, 256);
371            setExpectedBlockSize("RSA/ECB/NoPadding", Cipher.ENCRYPT_MODE, 256);
372            setExpectedBlockSize("RSA/ECB/PKCS1Padding", Cipher.ENCRYPT_MODE, 245);
373
374            // BC strips the leading 0 for us even when NoPadding is specified
375            setExpectedBlockSize("RSA", Cipher.ENCRYPT_MODE, "BC", 255);
376            setExpectedBlockSize("RSA/ECB/NoPadding", Cipher.ENCRYPT_MODE, "BC", 255);
377
378            setExpectedBlockSize("RSA", Cipher.DECRYPT_MODE, 256);
379            setExpectedBlockSize("RSA/ECB/NoPadding", Cipher.DECRYPT_MODE, 256);
380            setExpectedBlockSize("RSA/ECB/PKCS1Padding", Cipher.DECRYPT_MODE, 256);
381        }
382    }
383
384    private static String modeKey(String algorithm, int mode) {
385        return algorithm + ":" + mode;
386    }
387
388    private static String modeProviderKey(String algorithm, int mode, String provider) {
389        return algorithm + ":" + mode + ":" + provider;
390    }
391
392    private static void setExpectedSize(Map<String, Integer> map,
393                                        String algorithm, int value) {
394        algorithm = algorithm.toUpperCase(Locale.US);
395        map.put(algorithm, value);
396    }
397
398    private static void setExpectedSize(Map<String, Integer> map,
399                                        String algorithm, int mode, int value) {
400        setExpectedSize(map, modeKey(algorithm, mode), value);
401    }
402
403    private static void setExpectedSize(Map<String, Integer> map,
404                                        String algorithm, int mode, String provider, int value) {
405        setExpectedSize(map, modeProviderKey(algorithm, mode, provider), value);
406    }
407
408    private static int getExpectedSize(Map<String, Integer> map, String algorithm, int mode, String provider) {
409        algorithm = algorithm.toUpperCase(Locale.US);
410        provider = provider.toUpperCase(Locale.US);
411        Integer expected = map.get(modeProviderKey(algorithm, mode, provider));
412        if (expected != null) {
413            return expected;
414        }
415        expected = map.get(modeKey(algorithm, mode));
416        if (expected != null) {
417            return expected;
418        }
419        expected = map.get(algorithm);
420        assertNotNull("Algorithm " + algorithm + " with mode " + mode + " and provider " + provider
421                      + " not found in " + map, expected);
422        return expected;
423    }
424
425    private static void setExpectedBlockSize(String algorithm, int value) {
426        setExpectedSize(EXPECTED_BLOCK_SIZE, algorithm, value);
427    }
428
429    private static void setExpectedBlockSize(String algorithm, int mode, int value) {
430        setExpectedSize(EXPECTED_BLOCK_SIZE, algorithm, mode, value);
431    }
432
433    private static void setExpectedBlockSize(String algorithm, int mode, String provider, int value) {
434        setExpectedSize(EXPECTED_BLOCK_SIZE, algorithm, mode, provider, value);
435    }
436
437    private static int getExpectedBlockSize(String algorithm, int mode, String provider) {
438        return getExpectedSize(EXPECTED_BLOCK_SIZE, algorithm, mode, provider);
439    }
440
441    private static Map<String, Integer> EXPECTED_OUTPUT_SIZE = new HashMap<String, Integer>();
442    static {
443        setExpectedOutputSize("AES/CBC/NOPADDING", 0);
444        setExpectedOutputSize("AES/CFB/NOPADDING", 0);
445        setExpectedOutputSize("AES/CTR/NOPADDING", 0);
446        setExpectedOutputSize("AES/CTS/NOPADDING", 0);
447        setExpectedOutputSize("AES/ECB/NOPADDING", 0);
448        setExpectedOutputSize("AES/OFB/NOPADDING", 0);
449
450        setExpectedOutputSize("AES", Cipher.ENCRYPT_MODE, 16);
451        setExpectedOutputSize("AES/CBC/PKCS5PADDING", Cipher.ENCRYPT_MODE, 16);
452        setExpectedOutputSize("AES/CBC/PKCS7PADDING", Cipher.ENCRYPT_MODE, 16);
453        setExpectedOutputSize("AES/CFB/PKCS5PADDING", Cipher.ENCRYPT_MODE, 16);
454        setExpectedOutputSize("AES/CFB/PKCS7PADDING", Cipher.ENCRYPT_MODE, 16);
455        setExpectedOutputSize("AES/CTR/PKCS5PADDING", Cipher.ENCRYPT_MODE, 16);
456        setExpectedOutputSize("AES/CTR/PKCS7PADDING", Cipher.ENCRYPT_MODE, 16);
457        setExpectedOutputSize("AES/CTS/PKCS5PADDING", Cipher.ENCRYPT_MODE, 16);
458        setExpectedOutputSize("AES/CTS/PKCS7PADDING", Cipher.ENCRYPT_MODE, 16);
459        setExpectedOutputSize("AES/ECB/PKCS5PADDING", Cipher.ENCRYPT_MODE, 16);
460        setExpectedOutputSize("AES/ECB/PKCS7PADDING", Cipher.ENCRYPT_MODE, 16);
461        setExpectedOutputSize("AES/GCM/NOPADDING", Cipher.ENCRYPT_MODE, GCM_TAG_SIZE_BITS / 8);
462        setExpectedOutputSize("AES/OFB/PKCS5PADDING", Cipher.ENCRYPT_MODE, 16);
463        setExpectedOutputSize("AES/OFB/PKCS7PADDING", Cipher.ENCRYPT_MODE, 16);
464        setExpectedOutputSize("PBEWITHMD5AND128BITAES-CBC-OPENSSL", 16);
465        setExpectedOutputSize("PBEWITHMD5AND192BITAES-CBC-OPENSSL", 16);
466        setExpectedOutputSize("PBEWITHMD5AND256BITAES-CBC-OPENSSL", 16);
467        setExpectedOutputSize("PBEWITHSHA256AND128BITAES-CBC-BC", 16);
468        setExpectedOutputSize("PBEWITHSHA256AND192BITAES-CBC-BC", 16);
469        setExpectedOutputSize("PBEWITHSHA256AND256BITAES-CBC-BC", 16);
470        setExpectedOutputSize("PBEWITHSHAAND128BITAES-CBC-BC", 16);
471        setExpectedOutputSize("PBEWITHSHAAND192BITAES-CBC-BC", 16);
472        setExpectedOutputSize("PBEWITHSHAAND256BITAES-CBC-BC", 16);
473        // AndroidOpenSSL returns zero for the non-block ciphers
474        setExpectedOutputSize("AES/CFB/PKCS5PADDING", Cipher.ENCRYPT_MODE, "AndroidOpenSSL", 0);
475        setExpectedOutputSize("AES/CFB/PKCS7PADDING", Cipher.ENCRYPT_MODE, "AndroidOpenSSL", 0);
476        setExpectedOutputSize("AES/CTR/PKCS5PADDING", Cipher.ENCRYPT_MODE, "AndroidOpenSSL", 0);
477        setExpectedOutputSize("AES/CTR/PKCS7PADDING", Cipher.ENCRYPT_MODE, "AndroidOpenSSL", 0);
478        setExpectedOutputSize("AES/CTS/PKCS5PADDING", Cipher.ENCRYPT_MODE, "AndroidOpenSSL", 0);
479        setExpectedOutputSize("AES/CTS/PKCS7PADDING", Cipher.ENCRYPT_MODE, "AndroidOpenSSL", 0);
480        setExpectedOutputSize("AES/OFB/PKCS5PADDING", Cipher.ENCRYPT_MODE, "AndroidOpenSSL", 0);
481        setExpectedOutputSize("AES/OFB/PKCS7PADDING", Cipher.ENCRYPT_MODE, "AndroidOpenSSL", 0);
482
483        setExpectedOutputSize("AES", Cipher.DECRYPT_MODE, 0);
484        setExpectedOutputSize("AES/CBC/PKCS5PADDING", Cipher.DECRYPT_MODE, 0);
485        setExpectedOutputSize("AES/CBC/PKCS7PADDING", Cipher.DECRYPT_MODE, 0);
486        setExpectedOutputSize("AES/CFB/PKCS5PADDING", Cipher.DECRYPT_MODE, 0);
487        setExpectedOutputSize("AES/CFB/PKCS7PADDING", Cipher.DECRYPT_MODE, 0);
488        setExpectedOutputSize("AES/CTR/PKCS5PADDING", Cipher.DECRYPT_MODE, 0);
489        setExpectedOutputSize("AES/CTR/PKCS7PADDING", Cipher.DECRYPT_MODE, 0);
490        setExpectedOutputSize("AES/CTS/PKCS5PADDING", Cipher.DECRYPT_MODE, 0);
491        setExpectedOutputSize("AES/CTS/PKCS7PADDING", Cipher.DECRYPT_MODE, 0);
492        setExpectedOutputSize("AES/ECB/PKCS5PADDING", Cipher.DECRYPT_MODE, 0);
493        setExpectedOutputSize("AES/ECB/PKCS7PADDING", Cipher.DECRYPT_MODE, 0);
494        setExpectedOutputSize("AES/GCM/NOPADDING", Cipher.DECRYPT_MODE, 0);
495        setExpectedOutputSize("AES/OFB/PKCS5PADDING", Cipher.DECRYPT_MODE, 0);
496        setExpectedOutputSize("AES/OFB/PKCS7PADDING", Cipher.DECRYPT_MODE, 0);
497        setExpectedOutputSize("PBEWITHMD5AND128BITAES-CBC-OPENSSL", Cipher.DECRYPT_MODE, 0);
498        setExpectedOutputSize("PBEWITHMD5AND192BITAES-CBC-OPENSSL", Cipher.DECRYPT_MODE, 0);
499        setExpectedOutputSize("PBEWITHMD5AND256BITAES-CBC-OPENSSL", Cipher.DECRYPT_MODE, 0);
500        setExpectedOutputSize("PBEWITHSHA256AND128BITAES-CBC-BC", Cipher.DECRYPT_MODE, 0);
501        setExpectedOutputSize("PBEWITHSHA256AND192BITAES-CBC-BC", Cipher.DECRYPT_MODE, 0);
502        setExpectedOutputSize("PBEWITHSHA256AND256BITAES-CBC-BC", Cipher.DECRYPT_MODE, 0);
503        setExpectedOutputSize("PBEWITHSHAAND128BITAES-CBC-BC", Cipher.DECRYPT_MODE, 0);
504        setExpectedOutputSize("PBEWITHSHAAND192BITAES-CBC-BC", Cipher.DECRYPT_MODE, 0);
505        setExpectedOutputSize("PBEWITHSHAAND256BITAES-CBC-BC", Cipher.DECRYPT_MODE, 0);
506        // AndroidOpenSSL returns the block size for the block ciphers
507        setExpectedOutputSize("AES/CBC/PKCS5PADDING", Cipher.DECRYPT_MODE, "AndroidOpenSSL", 16);
508        setExpectedOutputSize("AES/CBC/PKCS7PADDING", Cipher.DECRYPT_MODE, "AndroidOpenSSL", 16);
509        setExpectedOutputSize("AES/ECB/PKCS5PADDING", Cipher.DECRYPT_MODE, "AndroidOpenSSL", 16);
510        setExpectedOutputSize("AES/ECB/PKCS7PADDING", Cipher.DECRYPT_MODE, "AndroidOpenSSL", 16);
511        setExpectedOutputSize("DESEDE/CBC/PKCS5PADDING", Cipher.DECRYPT_MODE, "AndroidOpenSSL", 8);
512        setExpectedOutputSize("DESEDE/CBC/PKCS7PADDING", Cipher.DECRYPT_MODE, "AndroidOpenSSL", 8);
513        setExpectedOutputSize("DESEDE/ECB/PKCS5PADDING", Cipher.DECRYPT_MODE, "AndroidOpenSSL", 8);
514        setExpectedOutputSize("DESEDE/ECB/PKCS7PADDING", Cipher.DECRYPT_MODE, "AndroidOpenSSL", 8);
515
516        if (StandardNames.IS_RI) {
517            setExpectedOutputSize("AESWRAP", Cipher.WRAP_MODE, 8);
518            setExpectedOutputSize("AESWRAP", Cipher.UNWRAP_MODE, 0);
519        } else {
520            setExpectedOutputSize("AESWRAP", -1);
521        }
522
523        setExpectedOutputSize("ARC4", 0);
524        setExpectedOutputSize("ARCFOUR", 0);
525        setExpectedOutputSize("PBEWITHSHAAND40BITRC4", 0);
526        setExpectedOutputSize("PBEWITHSHAAND128BITRC4", 0);
527
528        setExpectedOutputSize("BLOWFISH", Cipher.ENCRYPT_MODE, 8);
529        setExpectedOutputSize("BLOWFISH", Cipher.DECRYPT_MODE, 0);
530
531        setExpectedOutputSize("DES", Cipher.ENCRYPT_MODE, 8);
532        setExpectedOutputSize("PBEWITHMD5ANDDES", Cipher.ENCRYPT_MODE, 8);
533        setExpectedOutputSize("PBEWITHSHA1ANDDES", Cipher.ENCRYPT_MODE, 8);
534
535        setExpectedOutputSize("DES", Cipher.DECRYPT_MODE, 0);
536        setExpectedOutputSize("PBEWITHMD5ANDDES", Cipher.DECRYPT_MODE, 0);
537        setExpectedOutputSize("PBEWITHSHA1ANDDES", Cipher.DECRYPT_MODE, 0);
538
539        setExpectedOutputSize("DESEDE/CBC/NOPADDING", 0);
540        setExpectedOutputSize("DESEDE/CFB/NOPADDING", 0);
541        setExpectedOutputSize("DESEDE/CTR/NOPADDING", 0);
542        setExpectedOutputSize("DESEDE/CTS/NOPADDING", 0);
543        setExpectedOutputSize("DESEDE/ECB/NOPADDING", 0);
544        setExpectedOutputSize("DESEDE/OFB/NOPADDING", 0);
545
546        setExpectedOutputSize("DESEDE", Cipher.ENCRYPT_MODE, 8);
547        setExpectedOutputSize("DESEDE/CBC/PKCS5PADDING", Cipher.ENCRYPT_MODE, 8);
548        setExpectedOutputSize("DESEDE/CBC/PKCS7PADDING", Cipher.ENCRYPT_MODE, 8);
549        setExpectedOutputSize("DESEDE/CFB/PKCS5PADDING", Cipher.ENCRYPT_MODE, 8);
550        setExpectedOutputSize("DESEDE/CFB/PKCS7PADDING", Cipher.ENCRYPT_MODE, 8);
551        setExpectedOutputSize("DESEDE/CTR/PKCS5PADDING", Cipher.ENCRYPT_MODE, 8);
552        setExpectedOutputSize("DESEDE/CTR/PKCS7PADDING", Cipher.ENCRYPT_MODE, 8);
553        setExpectedOutputSize("DESEDE/CTS/PKCS5PADDING", Cipher.ENCRYPT_MODE, 8);
554        setExpectedOutputSize("DESEDE/CTS/PKCS7PADDING", Cipher.ENCRYPT_MODE, 8);
555        setExpectedOutputSize("DESEDE/ECB/PKCS5PADDING", Cipher.ENCRYPT_MODE, 8);
556        setExpectedOutputSize("DESEDE/ECB/PKCS7PADDING", Cipher.ENCRYPT_MODE, 8);
557        setExpectedOutputSize("DESEDE/OFB/PKCS5PADDING", Cipher.ENCRYPT_MODE, 8);
558        setExpectedOutputSize("DESEDE/OFB/PKCS7PADDING", Cipher.ENCRYPT_MODE, 8);
559        setExpectedOutputSize("PBEWITHSHAAND2-KEYTRIPLEDES-CBC", Cipher.ENCRYPT_MODE, 8);
560        setExpectedOutputSize("PBEWITHSHAAND3-KEYTRIPLEDES-CBC", Cipher.ENCRYPT_MODE, 8);
561        setExpectedOutputSize("PBEWITHMD5ANDTRIPLEDES", Cipher.ENCRYPT_MODE, 8);
562        setExpectedOutputSize("PBEWITHSHA1ANDDESEDE", Cipher.ENCRYPT_MODE, 8);
563
564        setExpectedOutputSize("DESEDE", Cipher.DECRYPT_MODE, 0);
565        setExpectedOutputSize("DESEDE/CBC/PKCS5PADDING", Cipher.DECRYPT_MODE, 0);
566        setExpectedOutputSize("DESEDE/CBC/PKCS7PADDING", Cipher.DECRYPT_MODE, 0);
567        setExpectedOutputSize("DESEDE/CFB/PKCS5PADDING", Cipher.DECRYPT_MODE, 0);
568        setExpectedOutputSize("DESEDE/CFB/PKCS7PADDING", Cipher.DECRYPT_MODE, 0);
569        setExpectedOutputSize("DESEDE/CTR/PKCS5PADDING", Cipher.DECRYPT_MODE, 0);
570        setExpectedOutputSize("DESEDE/CTR/PKCS7PADDING", Cipher.DECRYPT_MODE, 0);
571        setExpectedOutputSize("DESEDE/CTS/PKCS5PADDING", Cipher.DECRYPT_MODE, 0);
572        setExpectedOutputSize("DESEDE/CTS/PKCS7PADDING", Cipher.DECRYPT_MODE, 0);
573        setExpectedOutputSize("DESEDE/ECB/PKCS5PADDING", Cipher.DECRYPT_MODE, 0);
574        setExpectedOutputSize("DESEDE/ECB/PKCS7PADDING", Cipher.DECRYPT_MODE, 0);
575        setExpectedOutputSize("DESEDE/OFB/PKCS5PADDING", Cipher.DECRYPT_MODE, 0);
576        setExpectedOutputSize("DESEDE/OFB/PKCS7PADDING", Cipher.DECRYPT_MODE, 0);
577        setExpectedOutputSize("PBEWITHSHAAND2-KEYTRIPLEDES-CBC", Cipher.DECRYPT_MODE, 0);
578        setExpectedOutputSize("PBEWITHSHAAND3-KEYTRIPLEDES-CBC", Cipher.DECRYPT_MODE, 0);
579        setExpectedOutputSize("PBEWITHMD5ANDTRIPLEDES", Cipher.DECRYPT_MODE, 0);
580        setExpectedOutputSize("PBEWITHSHA1ANDDESEDE", Cipher.DECRYPT_MODE, 0);
581
582        if (StandardNames.IS_RI) {
583            setExpectedOutputSize("DESEDEWRAP", Cipher.WRAP_MODE, 16);
584            setExpectedOutputSize("DESEDEWRAP", Cipher.UNWRAP_MODE, 0);
585        } else {
586            setExpectedOutputSize("DESEDEWRAP", -1);
587        }
588
589        setExpectedOutputSize("RSA", Cipher.ENCRYPT_MODE, 256);
590        setExpectedOutputSize("RSA/ECB/NoPadding", Cipher.ENCRYPT_MODE, 256);
591        setExpectedOutputSize("RSA/ECB/PKCS1Padding", Cipher.ENCRYPT_MODE, 256);
592
593        setExpectedOutputSize("RSA", Cipher.DECRYPT_MODE, 256);
594        setExpectedOutputSize("RSA/ECB/NoPadding", Cipher.DECRYPT_MODE, 256);
595        setExpectedOutputSize("RSA/ECB/PKCS1Padding", Cipher.DECRYPT_MODE, 245);
596
597        // SunJCE returns the full for size even when PKCS1Padding is specified
598        setExpectedOutputSize("RSA/ECB/PKCS1Padding", Cipher.DECRYPT_MODE, "SunJCE", 256);
599
600        // BC strips the leading 0 for us even when NoPadding is specified
601        setExpectedOutputSize("RSA", Cipher.DECRYPT_MODE, "BC", 255);
602        setExpectedOutputSize("RSA/ECB/NoPadding", Cipher.DECRYPT_MODE, "BC", 255);
603    }
604
605    private static void setExpectedOutputSize(String algorithm, int value) {
606        setExpectedSize(EXPECTED_OUTPUT_SIZE, algorithm, value);
607    }
608
609    private static void setExpectedOutputSize(String algorithm, int mode, int value) {
610        setExpectedSize(EXPECTED_OUTPUT_SIZE, algorithm, mode, value);
611    }
612
613    private static void setExpectedOutputSize(String algorithm, int mode, String provider, int value) {
614        setExpectedSize(EXPECTED_OUTPUT_SIZE, algorithm, mode, provider, value);
615    }
616
617    private static int getExpectedOutputSize(String algorithm, int mode, String provider) {
618        return getExpectedSize(EXPECTED_OUTPUT_SIZE, algorithm, mode, provider);
619    }
620
621    private static byte[] ORIGINAL_PLAIN_TEXT = new byte[] { 0x0a, 0x0b, 0x0c };
622    private static byte[] SIXTEEN_BYTE_BLOCK_PLAIN_TEXT = new byte[] { 0x0a, 0x0b, 0x0c, 0x00,
623                                                                       0x00, 0x00, 0x00, 0x00,
624                                                                       0x00, 0x00, 0x00, 0x00,
625                                                                       0x00, 0x00, 0x00, 0x00 };
626    private static byte[] EIGHT_BYTE_BLOCK_PLAIN_TEXT = new byte[] { 0x0a, 0x0b, 0x0c, 0x00,
627                                                                     0x00, 0x00, 0x00, 0x00 };
628    private static byte[] PKCS1_BLOCK_TYPE_00_PADDED_PLAIN_TEXT = new byte[] {
629        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
630        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
631        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
632        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
633        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
634        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
635        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
636        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
637        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
638        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
639        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
640        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
641        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
642        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
643        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
644        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0a, 0x0b, 0x0c
645    };
646    private static byte[] PKCS1_BLOCK_TYPE_01_PADDED_PLAIN_TEXT = new byte[] {
647        (byte) 0x00, (byte) 0x01, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
648        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
649        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
650        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
651        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
652        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
653        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
654        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
655        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
656        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
657        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
658        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
659        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
660        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
661        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
662        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
663        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
664        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
665        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
666        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
667        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
668        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
669        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
670        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
671        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
672        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
673        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
674        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
675        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
676        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
677        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
678        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x00, (byte) 0x0a, (byte) 0x0b, (byte) 0x0c
679    };
680    private static byte[] PKCS1_BLOCK_TYPE_02_PADDED_PLAIN_TEXT = new byte[] {
681        (byte) 0x00, (byte) 0x02, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
682        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
683        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
684        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
685        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
686        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
687        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
688        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
689        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
690        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
691        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
692        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
693        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
694        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
695        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
696        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
697        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
698        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
699        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
700        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
701        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
702        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
703        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
704        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
705        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
706        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
707        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
708        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
709        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
710        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
711        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
712        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x00, (byte) 0x0a, (byte) 0x0b, (byte) 0x0c
713    };
714
715
716    private static byte[] getActualPlainText(String algorithm) {
717        // Block mode AES with NoPadding needs to match underlying block size
718        if (algorithm.equals("AES")
719            || algorithm.equals("AES/CBC/NOPADDING")
720            || algorithm.equals("AES/CTS/NOPADDING")
721            || algorithm.equals("AES/ECB/NOPADDING")) {
722            return SIXTEEN_BYTE_BLOCK_PLAIN_TEXT;
723        }
724        if (algorithm.equals("DESEDE")
725            || algorithm.equals("DESEDE/CBC/NOPADDING")
726            || algorithm.equals("DESEDE/ECB/NOPADDING")) {
727            return EIGHT_BYTE_BLOCK_PLAIN_TEXT;
728        }
729        return ORIGINAL_PLAIN_TEXT;
730    }
731
732    private static byte[] getExpectedPlainText(String algorithm, String provider) {
733        // Block mode AES with NoPadding needs to match underlying block size
734        if (algorithm.equals("AES")
735            || algorithm.equals("AES/CBC/NOPADDING")
736            || algorithm.equals("AES/CTS/NOPADDING")
737            || algorithm.equals("AES/ECB/NOPADDING")) {
738            return SIXTEEN_BYTE_BLOCK_PLAIN_TEXT;
739        }
740        if (algorithm.equals("DESEDE")
741            || algorithm.equals("DESEDE/CBC/NOPADDING")
742            || algorithm.equals("DESEDE/ECB/NOPADDING")) {
743            return EIGHT_BYTE_BLOCK_PLAIN_TEXT;
744        }
745        // BC strips the leading 0 for us even when NoPadding is specified
746        if (!provider.equals("BC") && algorithm.equals("RSA/ECB/NOPADDING")) {
747            return PKCS1_BLOCK_TYPE_00_PADDED_PLAIN_TEXT;
748        }
749        return ORIGINAL_PLAIN_TEXT;
750    }
751
752    private static AlgorithmParameterSpec getEncryptAlgorithmParameterSpec(String algorithm) {
753        if (isPBE(algorithm)) {
754            final byte[] salt = new byte[8];
755            new SecureRandom().nextBytes(salt);
756            return new PBEParameterSpec(salt, 1024);
757        }
758        if (algorithm.equals("AES/GCM/NOPADDING")) {
759            final byte[] iv = new byte[12];
760            new SecureRandom().nextBytes(iv);
761            return new GCMParameterSpec(GCM_TAG_SIZE_BITS, iv);
762        }
763        if (algorithm.equals("AES/CBC/NOPADDING")
764            || algorithm.equals("AES/CBC/PKCS5PADDING")
765            || algorithm.equals("AES/CBC/PKCS7PADDING")
766            || algorithm.equals("AES/CFB/NOPADDING")
767            || algorithm.equals("AES/CTR/NOPADDING")
768            || algorithm.equals("AES/CTS/NOPADDING")
769            || algorithm.equals("AES/OFB/NOPADDING")) {
770            final byte[] iv = new byte[16];
771            new SecureRandom().nextBytes(iv);
772            return new IvParameterSpec(iv);
773        }
774        if (algorithm.equals("DESEDE/CBC/NOPADDING")
775            || algorithm.equals("DESEDE/CBC/PKCS5PADDING")
776            || algorithm.equals("DESEDE/CBC/PKCS7PADDING")
777            || algorithm.equals("DESEDE/CFB/NOPADDING")
778            || algorithm.equals("DESEDE/CTR/NOPADDING")
779            || algorithm.equals("DESEDE/CTS/NOPADDING")
780            || algorithm.equals("DESEDE/OFB/NOPADDING")) {
781            final byte[] iv = new byte[8];
782            new SecureRandom().nextBytes(iv);
783            return new IvParameterSpec(iv);
784        }
785        return null;
786    }
787
788    private static AlgorithmParameterSpec getDecryptAlgorithmParameterSpec(AlgorithmParameterSpec encryptSpec,
789                                                                           Cipher encryptCipher) {
790        String algorithm = encryptCipher.getAlgorithm().toUpperCase(Locale.US);
791        if (isPBE(algorithm)) {
792            return encryptSpec;
793        }
794        if (isOnlyWrappingAlgorithm(algorithm)) {
795            return null;
796        }
797        byte[] iv = encryptCipher.getIV();
798        if (iv != null) {
799            if ("AES/GCM/NOPADDING".equals(algorithm)) {
800                return new GCMParameterSpec(GCM_TAG_SIZE_BITS, iv);
801            }
802            return new IvParameterSpec(iv);
803        }
804        return null;
805    }
806
807    /*
808     * This must be below everything else to make sure the other static blocks
809     * have run first.
810     */
811    private static final boolean IS_UNLIMITED;
812    static {
813        boolean is_unlimited;
814        if (StandardNames.IS_RI) {
815            try {
816                String algorithm = "PBEWITHMD5ANDTRIPLEDES";
817                Cipher.getInstance(algorithm).init(getEncryptMode(algorithm),
818                                                   getEncryptKey(algorithm),
819                                                   getEncryptAlgorithmParameterSpec(algorithm));
820                is_unlimited = true;
821            } catch (Exception e) {
822                is_unlimited = false;
823                System.out.println("WARNING: Some tests disabled due to lack of "
824                                   + "'Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files'");
825            }
826        } else {
827            is_unlimited = true;
828        }
829        IS_UNLIMITED = is_unlimited;
830    }
831
832    private static abstract class MockProvider extends Provider {
833        public MockProvider(String name) {
834            super(name, 1.0, "Mock provider used for testing");
835            setup();
836        }
837
838        public abstract void setup();
839    }
840
841    public void testCipher_getInstance_SuppliedProviderNotRegistered_Success() throws Exception {
842        Provider mockProvider = new MockProvider("MockProvider") {
843            public void setup() {
844                put("Cipher.FOO", MockCipherSpi.AllKeyTypes.class.getName());
845            }
846        };
847
848        {
849            Cipher c = Cipher.getInstance("FOO", mockProvider);
850            c.init(Cipher.ENCRYPT_MODE, new MockKey());
851            assertEquals(mockProvider, c.getProvider());
852        }
853    }
854
855    public void testCipher_getInstance_DoesNotSupportKeyClass_Success() throws Exception {
856        Provider mockProvider = new MockProvider("MockProvider") {
857            public void setup() {
858                put("Cipher.FOO", MockCipherSpi.AllKeyTypes.class.getName());
859                put("Cipher.FOO SupportedKeyClasses", "None");
860            }
861        };
862
863        Security.addProvider(mockProvider);
864        try {
865            Cipher c = Cipher.getInstance("FOO", mockProvider);
866            c.init(Cipher.ENCRYPT_MODE, new MockKey());
867            assertEquals(mockProvider, c.getProvider());
868        } finally {
869            Security.removeProvider(mockProvider.getName());
870        }
871    }
872
873    public void testCipher_getInstance_SuppliedProviderNotRegistered_MultipartTransform_Success()
874            throws Exception {
875        Provider mockProvider = new MockProvider("MockProvider") {
876            public void setup() {
877                put("Cipher.FOO", MockCipherSpi.AllKeyTypes.class.getName());
878            }
879        };
880
881        {
882            Cipher c = Cipher.getInstance("FOO/FOO/FOO", mockProvider);
883            c.init(Cipher.ENCRYPT_MODE, new MockKey());
884            assertEquals(mockProvider, c.getProvider());
885        }
886    }
887
888    public void testCipher_getInstance_OnlyUsesSpecifiedProvider_SameNameAndClass_Success()
889            throws Exception {
890        Provider mockProvider = new MockProvider("MockProvider") {
891            public void setup() {
892                put("Cipher.FOO", MockCipherSpi.AllKeyTypes.class.getName());
893            }
894        };
895
896        Security.addProvider(mockProvider);
897        try {
898            {
899                Provider mockProvider2 = new MockProvider("MockProvider") {
900                    public void setup() {
901                        put("Cipher.FOO", MockCipherSpi.AllKeyTypes.class.getName());
902                    }
903                };
904                Cipher c = Cipher.getInstance("FOO", mockProvider2);
905                assertEquals(mockProvider2, c.getProvider());
906            }
907        } finally {
908            Security.removeProvider(mockProvider.getName());
909        }
910    }
911
912    public void testCipher_getInstance_DelayedInitialization_KeyType() throws Exception {
913        Provider mockProviderSpecific = new MockProvider("MockProviderSpecific") {
914            public void setup() {
915                put("Cipher.FOO", MockCipherSpi.SpecificKeyTypes.class.getName());
916                put("Cipher.FOO SupportedKeyClasses", MockKey.class.getName());
917            }
918        };
919        Provider mockProviderSpecific2 = new MockProvider("MockProviderSpecific2") {
920            public void setup() {
921                put("Cipher.FOO", MockCipherSpi.SpecificKeyTypes2.class.getName());
922                put("Cipher.FOO SupportedKeyClasses", MockKey2.class.getName());
923            }
924        };
925        Provider mockProviderAll = new MockProvider("MockProviderAll") {
926            public void setup() {
927                put("Cipher.FOO", MockCipherSpi.AllKeyTypes.class.getName());
928            }
929        };
930
931        Security.addProvider(mockProviderSpecific);
932        Security.addProvider(mockProviderSpecific2);
933        Security.addProvider(mockProviderAll);
934
935        try {
936            {
937                System.out.println(Arrays.deepToString(Security.getProviders("Cipher.FOO")));
938                Cipher c = Cipher.getInstance("FOO");
939                c.init(Cipher.ENCRYPT_MODE, new MockKey());
940                assertEquals(mockProviderSpecific, c.getProvider());
941
942                try {
943                    c.init(Cipher.ENCRYPT_MODE, new MockKey2());
944                    assertEquals(mockProviderSpecific2, c.getProvider());
945                    if (StandardNames.IS_RI) {
946                        fail("RI was broken before; fix tests now that it works!");
947                    }
948                } catch (InvalidKeyException e) {
949                    if (!StandardNames.IS_RI) {
950                        fail("Non-RI should select the right provider");
951                    }
952                }
953            }
954
955            {
956                Cipher c = Cipher.getInstance("FOO");
957                c.init(Cipher.ENCRYPT_MODE, new Key() {
958                    @Override
959                    public String getAlgorithm() {
960                        throw new UnsupportedOperationException("not implemented");
961                    }
962
963                    @Override
964                    public String getFormat() {
965                        throw new UnsupportedOperationException("not implemented");
966                    }
967
968                    @Override
969                    public byte[] getEncoded() {
970                        throw new UnsupportedOperationException("not implemented");
971                    }
972                });
973                assertEquals(mockProviderAll, c.getProvider());
974            }
975
976            {
977                Cipher c = Cipher.getInstance("FOO");
978                assertEquals(mockProviderSpecific, c.getProvider());
979            }
980        } finally {
981            Security.removeProvider(mockProviderSpecific.getName());
982            Security.removeProvider(mockProviderSpecific2.getName());
983            Security.removeProvider(mockProviderAll.getName());
984        }
985    }
986
987    public void testCipher_getInstance_WrongType_Failure() throws Exception {
988        Provider mockProviderInvalid = new MockProvider("MockProviderInvalid") {
989            public void setup() {
990                put("Cipher.FOO", Object.class.getName());
991            }
992        };
993
994        Security.addProvider(mockProviderInvalid);
995        try {
996            Cipher.getInstance("FOO");
997            fail("Should not find any matching providers");
998        } catch (NoSuchAlgorithmException expected) {
999        } finally {
1000            Security.removeProvider(mockProviderInvalid.getName());
1001        }
1002    }
1003
1004    public void test_getInstance() throws Exception {
1005        final ByteArrayOutputStream errBuffer = new ByteArrayOutputStream();
1006        PrintStream out = new PrintStream(errBuffer);
1007
1008        Set<String> seenBaseCipherNames = new HashSet<String>();
1009        Set<String> seenCiphersWithModeAndPadding = new HashSet<String>();
1010
1011        Provider[] providers = Security.getProviders();
1012        for (Provider provider : providers) {
1013            Set<Provider.Service> services = provider.getServices();
1014            for (Provider.Service service : services) {
1015                String type = service.getType();
1016                if (!type.equals("Cipher")) {
1017                    continue;
1018                }
1019
1020                String algorithm = service.getAlgorithm();
1021
1022                /*
1023                 * Any specific modes and paddings aren't tested directly here,
1024                 * but we need to make sure we see the bare algorithm from some
1025                 * provider. We will test each mode specifically when we get the
1026                 * base cipher.
1027                 */
1028                final int firstSlash = algorithm.indexOf('/');
1029                if (firstSlash == -1) {
1030                    seenBaseCipherNames.add(algorithm);
1031                } else {
1032                    final String baseCipherName = algorithm.substring(0, firstSlash);
1033                    if (!seenBaseCipherNames.contains(baseCipherName)) {
1034                        seenCiphersWithModeAndPadding.add(baseCipherName);
1035                    }
1036                    if (!"AndroidOpenSSL".equals(provider.getName())) {
1037                        continue;
1038                    }
1039                }
1040
1041                try {
1042                    test_Cipher_Algorithm(provider, algorithm);
1043                } catch (Throwable e) {
1044                    out.append("Error encountered checking " + algorithm
1045                               + " with provider " + provider.getName() + "\n");
1046                    e.printStackTrace(out);
1047                }
1048
1049                Set<String> modes = StandardNames.getModesForCipher(algorithm);
1050                if (modes != null) {
1051                    for (String mode : modes) {
1052                        Set<String> paddings = StandardNames.getPaddingsForCipher(algorithm);
1053                        if (paddings != null) {
1054                            for (String padding : paddings) {
1055                                final String algorithmName = algorithm + "/" + mode + "/" + padding;
1056                                try {
1057                                    test_Cipher_Algorithm(provider, algorithmName);
1058                                } catch (Throwable e) {
1059                                    out.append("Error encountered checking " + algorithmName
1060                                               + " with provider " + provider.getName() + "\n");
1061                                    e.printStackTrace(out);
1062                                }
1063                            }
1064                        }
1065                    }
1066                }
1067            }
1068        }
1069
1070        seenCiphersWithModeAndPadding.removeAll(seenBaseCipherNames);
1071        assertEquals("Ciphers seen with mode and padding but not base cipher",
1072                Collections.EMPTY_SET, seenCiphersWithModeAndPadding);
1073
1074        out.flush();
1075        if (errBuffer.size() > 0) {
1076            throw new Exception("Errors encountered:\n\n" + errBuffer.toString() + "\n\n");
1077        }
1078    }
1079
1080    private void test_Cipher_Algorithm(Provider provider, String algorithm) throws Exception {
1081        if (algorithm.equals("RSA") && provider.getName().equals("BC")) {
1082            // http://b/9097343 BC's Cipher.RSA defaults to NoPadding
1083            // which makes it fail the key wrapping test if the
1084            // generated AES key to wrap starts with a leading
1085            // zero. For the purposes of the test, use the same
1086            // default behavior as the RI. Real code really should
1087            // specify the exact mode and padding they need and not
1088            // rely on defaults. http://b/9097343
1089            algorithm = "RSA/ECB/PKCS1Padding";
1090        }
1091
1092        // Cipher.getInstance(String)
1093        Cipher c1 = Cipher.getInstance(algorithm);
1094        if (provider.equals(c1.getProvider())) {
1095            assertEquals(algorithm, c1.getAlgorithm());
1096            test_Cipher(c1);
1097        }
1098
1099        // Cipher.getInstance(String, Provider)
1100        Cipher c2 = Cipher.getInstance(algorithm, provider);
1101        assertEquals(algorithm, c2.getAlgorithm());
1102        assertEquals(provider, c2.getProvider());
1103        test_Cipher(c2);
1104
1105        // Cipher.getInstance(String, String)
1106        Cipher c3 = Cipher.getInstance(algorithm, provider.getName());
1107        assertEquals(algorithm, c3.getAlgorithm());
1108        assertEquals(provider, c3.getProvider());
1109        test_Cipher(c3);
1110    }
1111
1112    private void test_Cipher(Cipher c) throws Exception {
1113        String algorithm = c.getAlgorithm().toUpperCase(Locale.US);
1114        String providerName = c.getProvider().getName();
1115        if (!isSupported(algorithm, providerName)) {
1116            return;
1117        }
1118        String cipherID = algorithm + ":" + providerName;
1119
1120        try {
1121            c.getOutputSize(0);
1122        } catch (IllegalStateException expected) {
1123        }
1124
1125        // TODO: test keys from different factories (e.g. OpenSSLRSAPrivateKey vs JCERSAPrivateKey)
1126        Key encryptKey = getEncryptKey(algorithm);
1127
1128        final AlgorithmParameterSpec encryptSpec = getEncryptAlgorithmParameterSpec(algorithm);
1129        int encryptMode = getEncryptMode(algorithm);
1130
1131        // Bouncycastle doesn't return a default PBEParameterSpec
1132        if (isPBE(algorithm) && !"BC".equals(providerName)) {
1133            assertNotNull(cipherID + " getParameters()", c.getParameters());
1134            assertNotNull(c.getParameters().getParameterSpec(PBEParameterSpec.class));
1135        } else {
1136            assertNull(cipherID + " getParameters()", c.getParameters());
1137        }
1138        try {
1139            assertNull(cipherID + " getIV()", c.getIV());
1140        } catch (NullPointerException e) {
1141            // Bouncycastle apparently has a bug here with AESWRAP, et al.
1142            if (!("BC".equals(providerName) && isOnlyWrappingAlgorithm(algorithm))) {
1143                throw e;
1144            }
1145        }
1146
1147        test_Cipher_init_NullParameters(c, encryptMode, encryptKey);
1148
1149        c.init(encryptMode, encryptKey, encryptSpec);
1150        assertEquals(cipherID + " getBlockSize() encryptMode",
1151                getExpectedBlockSize(algorithm, encryptMode, providerName), c.getBlockSize());
1152        assertTrue(cipherID + " getOutputSize(0) encryptMode",
1153                getExpectedOutputSize(algorithm, encryptMode, providerName) <= c.getOutputSize(0));
1154        if ((algorithm.endsWith("/PKCS5PADDING") || algorithm.endsWith("/PKCS7PADDING"))
1155                && isStreamMode(algorithm)) {
1156            assertEquals(getExpectedOutputSize(algorithm, encryptMode, providerName),
1157                    c.doFinal(new byte[1]).length);
1158        }
1159
1160        final AlgorithmParameterSpec decryptSpec = getDecryptAlgorithmParameterSpec(encryptSpec, c);
1161        int decryptMode = getDecryptMode(algorithm);
1162
1163        test_Cipher_init_Decrypt_NullParameters(c, decryptMode, encryptKey, decryptSpec != null);
1164
1165        c.init(decryptMode, encryptKey, decryptSpec);
1166        assertEquals(cipherID + " getBlockSize() decryptMode",
1167                     getExpectedBlockSize(algorithm, decryptMode, providerName), c.getBlockSize());
1168        assertEquals(cipherID + " getOutputSize(0) decryptMode",
1169                     getExpectedOutputSize(algorithm, decryptMode, providerName), c.getOutputSize(0));
1170
1171        if (isPBE(algorithm)) {
1172            if (algorithm.endsWith("RC4")) {
1173                assertNull(cipherID + " getIV()", c.getIV());
1174            } else {
1175                assertNotNull(cipherID + " getIV()", c.getIV());
1176            }
1177        } else if (decryptSpec instanceof IvParameterSpec) {
1178            assertEquals(cipherID + " getIV()",
1179                    Arrays.toString(((IvParameterSpec) decryptSpec).getIV()),
1180                    Arrays.toString(c.getIV()));
1181        } else if (decryptSpec instanceof GCMParameterSpec) {
1182            assertNotNull(c.getIV());
1183            assertEquals(cipherID + " getIV()",
1184                    Arrays.toString(((GCMParameterSpec) decryptSpec).getIV()),
1185                    Arrays.toString(c.getIV()));
1186        } else {
1187            try {
1188                assertNull(cipherID + " getIV()", c.getIV());
1189            } catch (NullPointerException e) {
1190                // Bouncycastle apparently has a bug here with AESWRAP, et al.
1191                if (!("BC".equals(providerName) && isOnlyWrappingAlgorithm(algorithm))) {
1192                    throw e;
1193                }
1194            }
1195        }
1196
1197        AlgorithmParameters params = c.getParameters();
1198        if (decryptSpec == null) {
1199            assertNull(cipherID + " getParameters()", params);
1200        } else if (decryptSpec instanceof IvParameterSpec) {
1201            IvParameterSpec ivDecryptSpec = (IvParameterSpec) params.getParameterSpec(IvParameterSpec.class);
1202            assertEquals(cipherID + " getIV()",
1203                    Arrays.toString(((IvParameterSpec) decryptSpec).getIV()),
1204                    Arrays.toString(ivDecryptSpec.getIV()));
1205        } else if (decryptSpec instanceof PBEParameterSpec) {
1206            // Bouncycastle seems to be schizophrenic about whther it returns this or not
1207            if (!"BC".equals(providerName)) {
1208                assertNotNull(cipherID + " getParameters()", params);
1209            }
1210        }
1211
1212        assertNull(cipherID, c.getExemptionMechanism());
1213
1214        // Test wrapping a key.  Every cipher should be able to wrap. Except those that can't.
1215        /* Bouncycastle is broken for wrapping because getIV() fails. */
1216        if (isSupportedForWrapping(algorithm)
1217                && !algorithm.equals("AES/GCM/NOPADDING") && !providerName.equals("BC")) {
1218            // Generate a small SecretKey for AES.
1219            KeyGenerator kg = KeyGenerator.getInstance("AES");
1220            kg.init(128);
1221            SecretKey sk = kg.generateKey();
1222
1223            // Wrap it
1224            c.init(Cipher.WRAP_MODE, encryptKey, encryptSpec);
1225            byte[] cipherText = c.wrap(sk);
1226
1227            // Unwrap it
1228            c.init(Cipher.UNWRAP_MODE, getDecryptKey(algorithm), decryptSpec);
1229            Key decryptedKey = c.unwrap(cipherText, sk.getAlgorithm(), Cipher.SECRET_KEY);
1230
1231            assertEquals(cipherID
1232                    + " sk.getAlgorithm()=" + sk.getAlgorithm()
1233                    + " decryptedKey.getAlgorithm()=" + decryptedKey.getAlgorithm()
1234                    + " encryptKey.getEncoded()=" + Arrays.toString(sk.getEncoded())
1235                    + " decryptedKey.getEncoded()=" + Arrays.toString(decryptedKey.getEncoded()),
1236                    sk, decryptedKey);
1237        }
1238
1239        if (!isOnlyWrappingAlgorithm(algorithm)) {
1240            c.init(Cipher.ENCRYPT_MODE, encryptKey, encryptSpec);
1241            if (isAEAD(algorithm)) {
1242                c.updateAAD(new byte[24]);
1243            }
1244            byte[] cipherText = c.doFinal(getActualPlainText(algorithm));
1245            if (isAEAD(algorithm)) {
1246                c.updateAAD(new byte[24]);
1247            }
1248            byte[] cipherText2 = c.doFinal(getActualPlainText(algorithm));
1249            assertEquals(cipherID,
1250                         Arrays.toString(cipherText),
1251                         Arrays.toString(cipherText2));
1252            c.init(Cipher.DECRYPT_MODE, getDecryptKey(algorithm), decryptSpec);
1253            if (isAEAD(algorithm)) {
1254                c.updateAAD(new byte[24]);
1255            }
1256            byte[] decryptedPlainText = c.doFinal(cipherText);
1257            assertEquals(cipherID,
1258                         Arrays.toString(getExpectedPlainText(algorithm, providerName)),
1259                         Arrays.toString(decryptedPlainText));
1260            if (isAEAD(algorithm)) {
1261                c.updateAAD(new byte[24]);
1262            }
1263            byte[] decryptedPlainText2 = c.doFinal(cipherText);
1264            assertEquals(cipherID,
1265                         Arrays.toString(decryptedPlainText),
1266                         Arrays.toString(decryptedPlainText2));
1267        }
1268    }
1269
1270    /**
1271     * Try various .init(...) calls with null parameters to make sure it is
1272     * handled.
1273     */
1274    private void test_Cipher_init_NullParameters(Cipher c, int encryptMode, Key encryptKey)
1275            throws Exception {
1276        try {
1277            c.init(encryptMode, encryptKey, (AlgorithmParameterSpec) null);
1278        } catch (InvalidAlgorithmParameterException e) {
1279            if (!isPBE(c.getAlgorithm())) {
1280                throw e;
1281            }
1282        }
1283
1284        try {
1285            c.init(encryptMode, encryptKey, (AlgorithmParameterSpec) null, (SecureRandom) null);
1286        } catch (InvalidAlgorithmParameterException e) {
1287            if (!isPBE(c.getAlgorithm())) {
1288                throw e;
1289            }
1290        }
1291
1292        try {
1293            c.init(encryptMode, encryptKey, (AlgorithmParameters) null);
1294        } catch (InvalidAlgorithmParameterException e) {
1295            if (!isPBE(c.getAlgorithm())) {
1296                throw e;
1297            }
1298        }
1299
1300        try {
1301            c.init(encryptMode, encryptKey, (AlgorithmParameters) null, (SecureRandom) null);
1302        } catch (InvalidAlgorithmParameterException e) {
1303            if (!isPBE(c.getAlgorithm())) {
1304                throw e;
1305            }
1306        }
1307    }
1308
1309    private void test_Cipher_init_Decrypt_NullParameters(Cipher c, int decryptMode, Key encryptKey,
1310            boolean needsParameters) throws Exception {
1311        try {
1312            c.init(decryptMode, encryptKey, (AlgorithmParameterSpec) null);
1313            if (needsParameters) {
1314                fail("Should throw InvalidAlgorithmParameterException with null parameters");
1315            }
1316        } catch (InvalidAlgorithmParameterException e) {
1317            if (!needsParameters) {
1318                throw e;
1319            }
1320        }
1321
1322        try {
1323            c.init(decryptMode, encryptKey, (AlgorithmParameterSpec) null, (SecureRandom) null);
1324            if (needsParameters) {
1325                fail("Should throw InvalidAlgorithmParameterException with null parameters");
1326            }
1327        } catch (InvalidAlgorithmParameterException e) {
1328            if (!needsParameters) {
1329                throw e;
1330            }
1331        }
1332
1333        try {
1334            c.init(decryptMode, encryptKey, (AlgorithmParameters) null);
1335            if (needsParameters) {
1336                fail("Should throw InvalidAlgorithmParameterException with null parameters");
1337            }
1338        } catch (InvalidAlgorithmParameterException e) {
1339            if (!needsParameters) {
1340                throw e;
1341            }
1342        }
1343
1344        try {
1345            c.init(decryptMode, encryptKey, (AlgorithmParameters) null, (SecureRandom) null);
1346            if (needsParameters) {
1347                fail("Should throw InvalidAlgorithmParameterException with null parameters");
1348            }
1349        } catch (InvalidAlgorithmParameterException e) {
1350            if (!needsParameters) {
1351                throw e;
1352            }
1353        }
1354    }
1355
1356    public void testInputPKCS1Padding() throws Exception {
1357        for (String provider : RSA_PROVIDERS) {
1358            testInputPKCS1Padding(provider);
1359        }
1360    }
1361
1362    private void testInputPKCS1Padding(String provider) throws Exception {
1363        testInputPKCS1Padding(provider, PKCS1_BLOCK_TYPE_01_PADDED_PLAIN_TEXT, getEncryptKey("RSA"), getDecryptKey("RSA"));
1364        try {
1365            testInputPKCS1Padding(provider, PKCS1_BLOCK_TYPE_02_PADDED_PLAIN_TEXT, getEncryptKey("RSA"), getDecryptKey("RSA"));
1366            fail();
1367        } catch (BadPaddingException expected) {
1368        }
1369        try {
1370            testInputPKCS1Padding(provider, PKCS1_BLOCK_TYPE_01_PADDED_PLAIN_TEXT, getDecryptKey("RSA"), getEncryptKey("RSA"));
1371            fail();
1372        } catch (BadPaddingException expected) {
1373        }
1374        testInputPKCS1Padding(provider, PKCS1_BLOCK_TYPE_02_PADDED_PLAIN_TEXT, getDecryptKey("RSA"), getEncryptKey("RSA"));
1375    }
1376
1377    private void testInputPKCS1Padding(String provider, byte[] prePaddedPlainText, Key encryptKey, Key decryptKey) throws Exception {
1378        Cipher encryptCipher = Cipher.getInstance("RSA/ECB/NoPadding", provider);
1379        encryptCipher.init(Cipher.ENCRYPT_MODE, encryptKey);
1380        byte[] cipherText = encryptCipher.doFinal(prePaddedPlainText);
1381        encryptCipher.update(prePaddedPlainText);
1382        encryptCipher.init(Cipher.ENCRYPT_MODE, encryptKey);
1383        byte[] cipherText2 = encryptCipher.doFinal(prePaddedPlainText);
1384        assertEquals(Arrays.toString(cipherText),
1385                     Arrays.toString(cipherText2));
1386
1387        Cipher decryptCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", provider);
1388        decryptCipher.init(Cipher.DECRYPT_MODE, decryptKey);
1389        byte[] plainText = decryptCipher.doFinal(cipherText);
1390        assertEquals(Arrays.toString(ORIGINAL_PLAIN_TEXT),
1391                     Arrays.toString(plainText));
1392        decryptCipher.update(prePaddedPlainText);
1393        decryptCipher.init(Cipher.DECRYPT_MODE, decryptKey);
1394        byte[] plainText2 = decryptCipher.doFinal(cipherText);
1395        assertEquals(Arrays.toString(plainText),
1396                     Arrays.toString(plainText2));
1397    }
1398
1399    public void testOutputPKCS1Padding() throws Exception {
1400        for (String provider : RSA_PROVIDERS) {
1401            testOutputPKCS1Padding(provider);
1402        }
1403    }
1404
1405    private void testOutputPKCS1Padding(String provider) throws Exception {
1406       testOutputPKCS1Padding(provider, (byte) 1, getEncryptKey("RSA"), getDecryptKey("RSA"));
1407       testOutputPKCS1Padding(provider, (byte) 2, getDecryptKey("RSA"), getEncryptKey("RSA"));
1408    }
1409
1410    private void testOutputPKCS1Padding(String provider, byte expectedBlockType, Key encryptKey, Key decryptKey) throws Exception {
1411        Cipher encryptCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", provider);
1412        encryptCipher.init(Cipher.ENCRYPT_MODE, encryptKey);
1413        byte[] cipherText = encryptCipher.doFinal(ORIGINAL_PLAIN_TEXT);
1414        Cipher decryptCipher = Cipher.getInstance("RSA/ECB/NoPadding", provider);
1415        decryptCipher.init(Cipher.DECRYPT_MODE, decryptKey);
1416        byte[] plainText = decryptCipher.doFinal(cipherText);
1417        assertPadding(provider, expectedBlockType, ORIGINAL_PLAIN_TEXT, plainText);
1418    }
1419
1420    private void assertPadding(String provider, byte expectedBlockType, byte[] expectedData, byte[] actualDataWithPadding) {
1421        assertNotNull(provider, actualDataWithPadding);
1422        int expectedOutputSize = getExpectedOutputSize("RSA", Cipher.DECRYPT_MODE, provider);
1423        assertEquals(provider, expectedOutputSize, actualDataWithPadding.length);
1424        int expectedBlockTypeOffset;
1425        if (provider.equals("BC")) {
1426            // BC strips the leading 0 for us on decrypt even when NoPadding is specified...
1427            expectedBlockTypeOffset = 0;
1428        } else {
1429            expectedBlockTypeOffset = 1;
1430            assertEquals(provider, 0, actualDataWithPadding[0]);
1431        }
1432        byte actualBlockType = actualDataWithPadding[expectedBlockTypeOffset];
1433        assertEquals(provider, expectedBlockType, actualBlockType);
1434        int actualDataOffset = actualDataWithPadding.length - expectedData.length;
1435        if (actualBlockType == 1) {
1436            int expectedDataOffset = expectedBlockTypeOffset + 1;
1437            for (int i = expectedDataOffset; i < actualDataOffset - 1; i++) {
1438                assertEquals(provider, (byte) 0xFF, actualDataWithPadding[i]);
1439            }
1440        }
1441        assertEquals(provider, 0x00, actualDataWithPadding[actualDataOffset-1]);
1442        byte[] actualData = new byte[expectedData.length];
1443        System.arraycopy(actualDataWithPadding, actualDataOffset, actualData, 0, actualData.length);
1444        assertEquals(provider, Arrays.toString(expectedData), Arrays.toString(actualData));
1445    }
1446
1447    public void testCipherInitWithCertificate () throws Exception {
1448        // no key usage specified, everything is fine
1449        assertCipherInitWithKeyUsage(0,                         true,  true, true,  true);
1450
1451        // common case is that encrypt/wrap is prohibited when special usage is specified
1452        assertCipherInitWithKeyUsage(KeyUsage.digitalSignature, false, true, false, true);
1453        assertCipherInitWithKeyUsage(KeyUsage.nonRepudiation,   false, true, false, true);
1454        assertCipherInitWithKeyUsage(KeyUsage.keyAgreement,     false, true, false, true);
1455        assertCipherInitWithKeyUsage(KeyUsage.keyCertSign,      false, true, false, true);
1456        assertCipherInitWithKeyUsage(KeyUsage.cRLSign,          false, true, false, true);
1457
1458        // Note they encipherOnly/decipherOnly don't have to do with
1459        // ENCRYPT_MODE or DECRYPT_MODE, but restrict usage relative
1460        // to keyAgreement. There is not a *_MODE option that
1461        // corresponds to this in Cipher, the RI does not enforce
1462        // anything in Cipher.
1463        // http://code.google.com/p/android/issues/detail?id=12955
1464        assertCipherInitWithKeyUsage(KeyUsage.encipherOnly,     false, true, false, true);
1465        assertCipherInitWithKeyUsage(KeyUsage.decipherOnly,     false, true, false, true);
1466        assertCipherInitWithKeyUsage(KeyUsage.keyAgreement | KeyUsage.encipherOnly,
1467                                                                false, true, false, true);
1468        assertCipherInitWithKeyUsage(KeyUsage.keyAgreement | KeyUsage.decipherOnly,
1469                                                                false, true, false, true);
1470
1471        // except when wrapping a key is specifically allowed or
1472        assertCipherInitWithKeyUsage(KeyUsage.keyEncipherment,  false, true, true,  true);
1473        // except when wrapping data encryption is specifically allowed
1474        assertCipherInitWithKeyUsage(KeyUsage.dataEncipherment, true,  true, false, true);
1475    }
1476
1477    private void assertCipherInitWithKeyUsage (int keyUsage,
1478                                               boolean allowEncrypt,
1479                                               boolean allowDecrypt,
1480                                               boolean allowWrap,
1481                                               boolean allowUnwrap) throws Exception {
1482        Certificate certificate = certificateWithKeyUsage(keyUsage);
1483        assertCipherInitWithKeyUsage(certificate, allowEncrypt, Cipher.ENCRYPT_MODE);
1484        assertCipherInitWithKeyUsage(certificate, allowDecrypt, Cipher.DECRYPT_MODE);
1485        assertCipherInitWithKeyUsage(certificate, allowWrap,    Cipher.WRAP_MODE);
1486        assertCipherInitWithKeyUsage(certificate, allowUnwrap,  Cipher.UNWRAP_MODE);
1487    }
1488
1489    private void assertCipherInitWithKeyUsage(Certificate certificate,
1490                                              boolean allowMode,
1491                                              int mode) throws Exception {
1492        Cipher cipher = Cipher.getInstance("RSA");
1493        if (allowMode) {
1494            cipher.init(mode, certificate);
1495        } else {
1496            try {
1497                cipher.init(mode, certificate);
1498                String modeString;
1499                switch (mode) {
1500                    case Cipher.ENCRYPT_MODE:
1501                        modeString = "ENCRYPT_MODE";
1502                        break;
1503                    case Cipher.DECRYPT_MODE:
1504                        modeString = "DECRYPT_MODE";
1505                        break;
1506                    case Cipher.WRAP_MODE:
1507                        modeString = "WRAP_MODE";
1508                        break;
1509                    case Cipher.UNWRAP_MODE:
1510                        modeString = "UNWRAP_MODE";
1511                        break;
1512                    default:
1513                        throw new AssertionError("Unknown Cipher.*_MODE " + mode);
1514                }
1515                fail("Should have had InvalidKeyException for " + modeString
1516                     + " for " + certificate);
1517            } catch (InvalidKeyException expected) {
1518            }
1519        }
1520    }
1521
1522    private Certificate certificateWithKeyUsage(int keyUsage) throws Exception {
1523        // note the rare usage of non-zero keyUsage
1524        return new TestKeyStore.Builder()
1525                .aliasPrefix("rsa-dsa-ec")
1526                .keyUsage(keyUsage)
1527                .build()
1528                .getPrivateKey("RSA", "RSA").getCertificate();
1529    }
1530
1531    /*
1532     * Test vectors generated with this private key:
1533     *
1534     * -----BEGIN RSA PRIVATE KEY-----
1535     * MIIEpAIBAAKCAQEA4Ec+irjyKE/rnnQv+XSPoRjtmGM8kvUq63ouvg075gMpvnZq
1536     * 0Q62pRXQ0s/ZvqeTDwwwZTeJn3lYzT6FsB+IGFJNMSWEqUslHjYltUFB7b/uGYgI
1537     * 4buX/Hy0m56qr2jpyY19DtxTu8D6ADQ1bWMF+7zDxwAUBThqu8hzyw8+90JfPTPf
1538     * ezFa4DbSoLZq/UdQOxab8247UWJRW3Ff2oPeryxYrrmr+zCXw8yd2dvl7ylsF2E5
1539     * Ao6KZx5jBW1F9AGI0sQTNJCEXeUsJTTpxrJHjAe9rpKII7YtBmx3cPn2Pz26JH9T
1540     * CER0e+eqqF2FO4vSRKzsPePImrRkU6tNJMOsaQIDAQABAoIBADd4R3al8XaY9ayW
1541     * DfuDobZ1ZOZIvQWXz4q4CHGG8macJ6nsvdSA8Bl6gNBzCebGqW+SUzHlf4tKxvTU
1542     * XtpFojJpwJ/EKMB6Tm7fc4oV3sl/q9Lyu0ehTyDqcvz+TDbgGtp3vRN82NTaELsW
1543     * LpSkZilx8XX5hfoYjwVsuX7igW9Dq503R2Ekhs2owWGWwwgYqZXshdOEZ3kSZ7O/
1544     * IfJzcQppJYYldoQcW2cSwS1L0govMpmtt8E12l6VFavadufK8qO+gFUdBzt4vxFi
1545     * xIrSt/R0OgI47k0lL31efmUzzK5kzLOTYAdaL9HgNOw65c6cQIzL8OJeQRQCFoez
1546     * 3UdUroECgYEA9UGIS8Nzeyki1BGe9F4t7izUy7dfRVBaFXqlAJ+Zxzot8HJKxGAk
1547     * MGMy6omBd2NFRl3G3x4KbxQK/ztzluaomUrF2qloc0cv43dJ0U6z4HXmKdvrNYMz
1548     * im82SdCiZUp6Qv2atr+krE1IHTkLsimwZL3DEcwb4bYxidp8QM3s8rECgYEA6hp0
1549     * LduIHO23KIyH442GjdekCdFaQ/RF1Td6C1cx3b/KLa8oqOE81cCvzsM0fXSjniNa
1550     * PNljPydN4rlPkt9DgzkR2enxz1jyfeLgj/RZZMcg0+whOdx8r8kSlTzeyy81Wi4s
1551     * NaUPrXVMs7IxZkJLo7bjESoriYw4xcFe2yOGkzkCgYBRgo8exv2ZYCmQG68dfjN7
1552     * pfCvJ+mE6tiVrOYr199O5FoiQInyzBUa880XP84EdLywTzhqLNzA4ANrokGfVFeS
1553     * YtRxAL6TGYSj76Bb7PFBV03AebOpXEqD5sQ/MhTW3zLVEt4ZgIXlMeYWuD/X3Z0f
1554     * TiYHwzM9B8VdEH0dOJNYcQKBgQDbT7UPUN6O21P/NMgJMYigUShn2izKBIl3WeWH
1555     * wkQBDa+GZNWegIPRbBZHiTAfZ6nweAYNg0oq29NnV1toqKhCwrAqibPzH8zsiiL+
1556     * OVeVxcbHQitOXXSh6ajzDndZufwtY5wfFWc+hOk6XvFQb0MVODw41Fy9GxQEj0ch
1557     * 3IIyYQKBgQDYEUWTr0FfthLb8ZI3ENVNB0hiBadqO0MZSWjA3/HxHvD2GkozfV/T
1558     * dBu8lkDkR7i2tsR8OsEgQ1fTsMVbqShr2nP2KSlvX6kUbYl2NX08dR51FIaWpAt0
1559     * aFyCzjCQLWOdck/yTV4ulAfuNO3tLjtN9lqpvP623yjQe6aQPxZXaA==
1560     * -----END RSA PRIVATE KEY-----
1561     *
1562     */
1563
1564    private static final BigInteger RSA_2048_modulus = new BigInteger(new byte[] {
1565        (byte) 0x00, (byte) 0xe0, (byte) 0x47, (byte) 0x3e, (byte) 0x8a, (byte) 0xb8, (byte) 0xf2, (byte) 0x28,
1566        (byte) 0x4f, (byte) 0xeb, (byte) 0x9e, (byte) 0x74, (byte) 0x2f, (byte) 0xf9, (byte) 0x74, (byte) 0x8f,
1567        (byte) 0xa1, (byte) 0x18, (byte) 0xed, (byte) 0x98, (byte) 0x63, (byte) 0x3c, (byte) 0x92, (byte) 0xf5,
1568        (byte) 0x2a, (byte) 0xeb, (byte) 0x7a, (byte) 0x2e, (byte) 0xbe, (byte) 0x0d, (byte) 0x3b, (byte) 0xe6,
1569        (byte) 0x03, (byte) 0x29, (byte) 0xbe, (byte) 0x76, (byte) 0x6a, (byte) 0xd1, (byte) 0x0e, (byte) 0xb6,
1570        (byte) 0xa5, (byte) 0x15, (byte) 0xd0, (byte) 0xd2, (byte) 0xcf, (byte) 0xd9, (byte) 0xbe, (byte) 0xa7,
1571        (byte) 0x93, (byte) 0x0f, (byte) 0x0c, (byte) 0x30, (byte) 0x65, (byte) 0x37, (byte) 0x89, (byte) 0x9f,
1572        (byte) 0x79, (byte) 0x58, (byte) 0xcd, (byte) 0x3e, (byte) 0x85, (byte) 0xb0, (byte) 0x1f, (byte) 0x88,
1573        (byte) 0x18, (byte) 0x52, (byte) 0x4d, (byte) 0x31, (byte) 0x25, (byte) 0x84, (byte) 0xa9, (byte) 0x4b,
1574        (byte) 0x25, (byte) 0x1e, (byte) 0x36, (byte) 0x25, (byte) 0xb5, (byte) 0x41, (byte) 0x41, (byte) 0xed,
1575        (byte) 0xbf, (byte) 0xee, (byte) 0x19, (byte) 0x88, (byte) 0x08, (byte) 0xe1, (byte) 0xbb, (byte) 0x97,
1576        (byte) 0xfc, (byte) 0x7c, (byte) 0xb4, (byte) 0x9b, (byte) 0x9e, (byte) 0xaa, (byte) 0xaf, (byte) 0x68,
1577        (byte) 0xe9, (byte) 0xc9, (byte) 0x8d, (byte) 0x7d, (byte) 0x0e, (byte) 0xdc, (byte) 0x53, (byte) 0xbb,
1578        (byte) 0xc0, (byte) 0xfa, (byte) 0x00, (byte) 0x34, (byte) 0x35, (byte) 0x6d, (byte) 0x63, (byte) 0x05,
1579        (byte) 0xfb, (byte) 0xbc, (byte) 0xc3, (byte) 0xc7, (byte) 0x00, (byte) 0x14, (byte) 0x05, (byte) 0x38,
1580        (byte) 0x6a, (byte) 0xbb, (byte) 0xc8, (byte) 0x73, (byte) 0xcb, (byte) 0x0f, (byte) 0x3e, (byte) 0xf7,
1581        (byte) 0x42, (byte) 0x5f, (byte) 0x3d, (byte) 0x33, (byte) 0xdf, (byte) 0x7b, (byte) 0x31, (byte) 0x5a,
1582        (byte) 0xe0, (byte) 0x36, (byte) 0xd2, (byte) 0xa0, (byte) 0xb6, (byte) 0x6a, (byte) 0xfd, (byte) 0x47,
1583        (byte) 0x50, (byte) 0x3b, (byte) 0x16, (byte) 0x9b, (byte) 0xf3, (byte) 0x6e, (byte) 0x3b, (byte) 0x51,
1584        (byte) 0x62, (byte) 0x51, (byte) 0x5b, (byte) 0x71, (byte) 0x5f, (byte) 0xda, (byte) 0x83, (byte) 0xde,
1585        (byte) 0xaf, (byte) 0x2c, (byte) 0x58, (byte) 0xae, (byte) 0xb9, (byte) 0xab, (byte) 0xfb, (byte) 0x30,
1586        (byte) 0x97, (byte) 0xc3, (byte) 0xcc, (byte) 0x9d, (byte) 0xd9, (byte) 0xdb, (byte) 0xe5, (byte) 0xef,
1587        (byte) 0x29, (byte) 0x6c, (byte) 0x17, (byte) 0x61, (byte) 0x39, (byte) 0x02, (byte) 0x8e, (byte) 0x8a,
1588        (byte) 0x67, (byte) 0x1e, (byte) 0x63, (byte) 0x05, (byte) 0x6d, (byte) 0x45, (byte) 0xf4, (byte) 0x01,
1589        (byte) 0x88, (byte) 0xd2, (byte) 0xc4, (byte) 0x13, (byte) 0x34, (byte) 0x90, (byte) 0x84, (byte) 0x5d,
1590        (byte) 0xe5, (byte) 0x2c, (byte) 0x25, (byte) 0x34, (byte) 0xe9, (byte) 0xc6, (byte) 0xb2, (byte) 0x47,
1591        (byte) 0x8c, (byte) 0x07, (byte) 0xbd, (byte) 0xae, (byte) 0x92, (byte) 0x88, (byte) 0x23, (byte) 0xb6,
1592        (byte) 0x2d, (byte) 0x06, (byte) 0x6c, (byte) 0x77, (byte) 0x70, (byte) 0xf9, (byte) 0xf6, (byte) 0x3f,
1593        (byte) 0x3d, (byte) 0xba, (byte) 0x24, (byte) 0x7f, (byte) 0x53, (byte) 0x08, (byte) 0x44, (byte) 0x74,
1594        (byte) 0x7b, (byte) 0xe7, (byte) 0xaa, (byte) 0xa8, (byte) 0x5d, (byte) 0x85, (byte) 0x3b, (byte) 0x8b,
1595        (byte) 0xd2, (byte) 0x44, (byte) 0xac, (byte) 0xec, (byte) 0x3d, (byte) 0xe3, (byte) 0xc8, (byte) 0x9a,
1596        (byte) 0xb4, (byte) 0x64, (byte) 0x53, (byte) 0xab, (byte) 0x4d, (byte) 0x24, (byte) 0xc3, (byte) 0xac,
1597        (byte) 0x69,
1598    });
1599
1600    private static final BigInteger RSA_2048_privateExponent = new BigInteger(new byte[] {
1601        (byte) 0x37, (byte) 0x78, (byte) 0x47, (byte) 0x76, (byte) 0xa5, (byte) 0xf1, (byte) 0x76, (byte) 0x98,
1602        (byte) 0xf5, (byte) 0xac, (byte) 0x96, (byte) 0x0d, (byte) 0xfb, (byte) 0x83, (byte) 0xa1, (byte) 0xb6,
1603        (byte) 0x75, (byte) 0x64, (byte) 0xe6, (byte) 0x48, (byte) 0xbd, (byte) 0x05, (byte) 0x97, (byte) 0xcf,
1604        (byte) 0x8a, (byte) 0xb8, (byte) 0x08, (byte) 0x71, (byte) 0x86, (byte) 0xf2, (byte) 0x66, (byte) 0x9c,
1605        (byte) 0x27, (byte) 0xa9, (byte) 0xec, (byte) 0xbd, (byte) 0xd4, (byte) 0x80, (byte) 0xf0, (byte) 0x19,
1606        (byte) 0x7a, (byte) 0x80, (byte) 0xd0, (byte) 0x73, (byte) 0x09, (byte) 0xe6, (byte) 0xc6, (byte) 0xa9,
1607        (byte) 0x6f, (byte) 0x92, (byte) 0x53, (byte) 0x31, (byte) 0xe5, (byte) 0x7f, (byte) 0x8b, (byte) 0x4a,
1608        (byte) 0xc6, (byte) 0xf4, (byte) 0xd4, (byte) 0x5e, (byte) 0xda, (byte) 0x45, (byte) 0xa2, (byte) 0x32,
1609        (byte) 0x69, (byte) 0xc0, (byte) 0x9f, (byte) 0xc4, (byte) 0x28, (byte) 0xc0, (byte) 0x7a, (byte) 0x4e,
1610        (byte) 0x6e, (byte) 0xdf, (byte) 0x73, (byte) 0x8a, (byte) 0x15, (byte) 0xde, (byte) 0xc9, (byte) 0x7f,
1611        (byte) 0xab, (byte) 0xd2, (byte) 0xf2, (byte) 0xbb, (byte) 0x47, (byte) 0xa1, (byte) 0x4f, (byte) 0x20,
1612        (byte) 0xea, (byte) 0x72, (byte) 0xfc, (byte) 0xfe, (byte) 0x4c, (byte) 0x36, (byte) 0xe0, (byte) 0x1a,
1613        (byte) 0xda, (byte) 0x77, (byte) 0xbd, (byte) 0x13, (byte) 0x7c, (byte) 0xd8, (byte) 0xd4, (byte) 0xda,
1614        (byte) 0x10, (byte) 0xbb, (byte) 0x16, (byte) 0x2e, (byte) 0x94, (byte) 0xa4, (byte) 0x66, (byte) 0x29,
1615        (byte) 0x71, (byte) 0xf1, (byte) 0x75, (byte) 0xf9, (byte) 0x85, (byte) 0xfa, (byte) 0x18, (byte) 0x8f,
1616        (byte) 0x05, (byte) 0x6c, (byte) 0xb9, (byte) 0x7e, (byte) 0xe2, (byte) 0x81, (byte) 0x6f, (byte) 0x43,
1617        (byte) 0xab, (byte) 0x9d, (byte) 0x37, (byte) 0x47, (byte) 0x61, (byte) 0x24, (byte) 0x86, (byte) 0xcd,
1618        (byte) 0xa8, (byte) 0xc1, (byte) 0x61, (byte) 0x96, (byte) 0xc3, (byte) 0x08, (byte) 0x18, (byte) 0xa9,
1619        (byte) 0x95, (byte) 0xec, (byte) 0x85, (byte) 0xd3, (byte) 0x84, (byte) 0x67, (byte) 0x79, (byte) 0x12,
1620        (byte) 0x67, (byte) 0xb3, (byte) 0xbf, (byte) 0x21, (byte) 0xf2, (byte) 0x73, (byte) 0x71, (byte) 0x0a,
1621        (byte) 0x69, (byte) 0x25, (byte) 0x86, (byte) 0x25, (byte) 0x76, (byte) 0x84, (byte) 0x1c, (byte) 0x5b,
1622        (byte) 0x67, (byte) 0x12, (byte) 0xc1, (byte) 0x2d, (byte) 0x4b, (byte) 0xd2, (byte) 0x0a, (byte) 0x2f,
1623        (byte) 0x32, (byte) 0x99, (byte) 0xad, (byte) 0xb7, (byte) 0xc1, (byte) 0x35, (byte) 0xda, (byte) 0x5e,
1624        (byte) 0x95, (byte) 0x15, (byte) 0xab, (byte) 0xda, (byte) 0x76, (byte) 0xe7, (byte) 0xca, (byte) 0xf2,
1625        (byte) 0xa3, (byte) 0xbe, (byte) 0x80, (byte) 0x55, (byte) 0x1d, (byte) 0x07, (byte) 0x3b, (byte) 0x78,
1626        (byte) 0xbf, (byte) 0x11, (byte) 0x62, (byte) 0xc4, (byte) 0x8a, (byte) 0xd2, (byte) 0xb7, (byte) 0xf4,
1627        (byte) 0x74, (byte) 0x3a, (byte) 0x02, (byte) 0x38, (byte) 0xee, (byte) 0x4d, (byte) 0x25, (byte) 0x2f,
1628        (byte) 0x7d, (byte) 0x5e, (byte) 0x7e, (byte) 0x65, (byte) 0x33, (byte) 0xcc, (byte) 0xae, (byte) 0x64,
1629        (byte) 0xcc, (byte) 0xb3, (byte) 0x93, (byte) 0x60, (byte) 0x07, (byte) 0x5a, (byte) 0x2f, (byte) 0xd1,
1630        (byte) 0xe0, (byte) 0x34, (byte) 0xec, (byte) 0x3a, (byte) 0xe5, (byte) 0xce, (byte) 0x9c, (byte) 0x40,
1631        (byte) 0x8c, (byte) 0xcb, (byte) 0xf0, (byte) 0xe2, (byte) 0x5e, (byte) 0x41, (byte) 0x14, (byte) 0x02,
1632        (byte) 0x16, (byte) 0x87, (byte) 0xb3, (byte) 0xdd, (byte) 0x47, (byte) 0x54, (byte) 0xae, (byte) 0x81,
1633    });
1634
1635    private static final BigInteger RSA_2048_publicExponent = new BigInteger(new byte[] {
1636        (byte) 0x01, (byte) 0x00, (byte) 0x01,
1637    });
1638
1639    private static final BigInteger RSA_2048_primeP = new BigInteger(new byte[] {
1640        (byte) 0x00, (byte) 0xf5, (byte) 0x41, (byte) 0x88, (byte) 0x4b, (byte) 0xc3, (byte) 0x73, (byte) 0x7b,
1641        (byte) 0x29, (byte) 0x22, (byte) 0xd4, (byte) 0x11, (byte) 0x9e, (byte) 0xf4, (byte) 0x5e, (byte) 0x2d,
1642        (byte) 0xee, (byte) 0x2c, (byte) 0xd4, (byte) 0xcb, (byte) 0xb7, (byte) 0x5f, (byte) 0x45, (byte) 0x50,
1643        (byte) 0x5a, (byte) 0x15, (byte) 0x7a, (byte) 0xa5, (byte) 0x00, (byte) 0x9f, (byte) 0x99, (byte) 0xc7,
1644        (byte) 0x3a, (byte) 0x2d, (byte) 0xf0, (byte) 0x72, (byte) 0x4a, (byte) 0xc4, (byte) 0x60, (byte) 0x24,
1645        (byte) 0x30, (byte) 0x63, (byte) 0x32, (byte) 0xea, (byte) 0x89, (byte) 0x81, (byte) 0x77, (byte) 0x63,
1646        (byte) 0x45, (byte) 0x46, (byte) 0x5d, (byte) 0xc6, (byte) 0xdf, (byte) 0x1e, (byte) 0x0a, (byte) 0x6f,
1647        (byte) 0x14, (byte) 0x0a, (byte) 0xff, (byte) 0x3b, (byte) 0x73, (byte) 0x96, (byte) 0xe6, (byte) 0xa8,
1648        (byte) 0x99, (byte) 0x4a, (byte) 0xc5, (byte) 0xda, (byte) 0xa9, (byte) 0x68, (byte) 0x73, (byte) 0x47,
1649        (byte) 0x2f, (byte) 0xe3, (byte) 0x77, (byte) 0x49, (byte) 0xd1, (byte) 0x4e, (byte) 0xb3, (byte) 0xe0,
1650        (byte) 0x75, (byte) 0xe6, (byte) 0x29, (byte) 0xdb, (byte) 0xeb, (byte) 0x35, (byte) 0x83, (byte) 0x33,
1651        (byte) 0x8a, (byte) 0x6f, (byte) 0x36, (byte) 0x49, (byte) 0xd0, (byte) 0xa2, (byte) 0x65, (byte) 0x4a,
1652        (byte) 0x7a, (byte) 0x42, (byte) 0xfd, (byte) 0x9a, (byte) 0xb6, (byte) 0xbf, (byte) 0xa4, (byte) 0xac,
1653        (byte) 0x4d, (byte) 0x48, (byte) 0x1d, (byte) 0x39, (byte) 0x0b, (byte) 0xb2, (byte) 0x29, (byte) 0xb0,
1654        (byte) 0x64, (byte) 0xbd, (byte) 0xc3, (byte) 0x11, (byte) 0xcc, (byte) 0x1b, (byte) 0xe1, (byte) 0xb6,
1655        (byte) 0x31, (byte) 0x89, (byte) 0xda, (byte) 0x7c, (byte) 0x40, (byte) 0xcd, (byte) 0xec, (byte) 0xf2,
1656        (byte) 0xb1,
1657    });
1658
1659    private static final BigInteger RSA_2048_primeQ = new BigInteger(new byte[] {
1660        (byte) 0x00, (byte) 0xea, (byte) 0x1a, (byte) 0x74, (byte) 0x2d, (byte) 0xdb, (byte) 0x88, (byte) 0x1c,
1661        (byte) 0xed, (byte) 0xb7, (byte) 0x28, (byte) 0x8c, (byte) 0x87, (byte) 0xe3, (byte) 0x8d, (byte) 0x86,
1662        (byte) 0x8d, (byte) 0xd7, (byte) 0xa4, (byte) 0x09, (byte) 0xd1, (byte) 0x5a, (byte) 0x43, (byte) 0xf4,
1663        (byte) 0x45, (byte) 0xd5, (byte) 0x37, (byte) 0x7a, (byte) 0x0b, (byte) 0x57, (byte) 0x31, (byte) 0xdd,
1664        (byte) 0xbf, (byte) 0xca, (byte) 0x2d, (byte) 0xaf, (byte) 0x28, (byte) 0xa8, (byte) 0xe1, (byte) 0x3c,
1665        (byte) 0xd5, (byte) 0xc0, (byte) 0xaf, (byte) 0xce, (byte) 0xc3, (byte) 0x34, (byte) 0x7d, (byte) 0x74,
1666        (byte) 0xa3, (byte) 0x9e, (byte) 0x23, (byte) 0x5a, (byte) 0x3c, (byte) 0xd9, (byte) 0x63, (byte) 0x3f,
1667        (byte) 0x27, (byte) 0x4d, (byte) 0xe2, (byte) 0xb9, (byte) 0x4f, (byte) 0x92, (byte) 0xdf, (byte) 0x43,
1668        (byte) 0x83, (byte) 0x39, (byte) 0x11, (byte) 0xd9, (byte) 0xe9, (byte) 0xf1, (byte) 0xcf, (byte) 0x58,
1669        (byte) 0xf2, (byte) 0x7d, (byte) 0xe2, (byte) 0xe0, (byte) 0x8f, (byte) 0xf4, (byte) 0x59, (byte) 0x64,
1670        (byte) 0xc7, (byte) 0x20, (byte) 0xd3, (byte) 0xec, (byte) 0x21, (byte) 0x39, (byte) 0xdc, (byte) 0x7c,
1671        (byte) 0xaf, (byte) 0xc9, (byte) 0x12, (byte) 0x95, (byte) 0x3c, (byte) 0xde, (byte) 0xcb, (byte) 0x2f,
1672        (byte) 0x35, (byte) 0x5a, (byte) 0x2e, (byte) 0x2c, (byte) 0x35, (byte) 0xa5, (byte) 0x0f, (byte) 0xad,
1673        (byte) 0x75, (byte) 0x4c, (byte) 0xb3, (byte) 0xb2, (byte) 0x31, (byte) 0x66, (byte) 0x42, (byte) 0x4b,
1674        (byte) 0xa3, (byte) 0xb6, (byte) 0xe3, (byte) 0x11, (byte) 0x2a, (byte) 0x2b, (byte) 0x89, (byte) 0x8c,
1675        (byte) 0x38, (byte) 0xc5, (byte) 0xc1, (byte) 0x5e, (byte) 0xdb, (byte) 0x23, (byte) 0x86, (byte) 0x93,
1676        (byte) 0x39,
1677    });
1678
1679    /**
1680     * Test data is PKCS#1 padded "Android.\n" which can be generated by:
1681     * echo "Android." | openssl rsautl -inkey rsa.key -sign | openssl rsautl -inkey rsa.key -raw -verify | recode ../x1
1682     */
1683    private static final byte[] RSA_2048_Vector1 = new byte[] {
1684        (byte) 0x00, (byte) 0x01, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
1685        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
1686        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
1687        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
1688        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
1689        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
1690        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
1691        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
1692        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
1693        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
1694        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
1695        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
1696        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
1697        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
1698        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
1699        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
1700        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
1701        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
1702        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
1703        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
1704        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
1705        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
1706        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
1707        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
1708        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
1709        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
1710        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
1711        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
1712        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
1713        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
1714        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
1715        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
1716        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
1717        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
1718        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
1719        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
1720        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
1721        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
1722        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
1723        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
1724        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
1725        (byte) 0x00, (byte) 0x41, (byte) 0x6E, (byte) 0x64, (byte) 0x72, (byte) 0x6F,
1726        (byte) 0x69, (byte) 0x64, (byte) 0x2E, (byte) 0x0A,
1727    };
1728
1729    /**
1730     * This vector is simply "Android.\n" which is too short.
1731     */
1732    private static final byte[] TooShort_Vector = new byte[] {
1733        (byte) 0x41, (byte) 0x6E, (byte) 0x64, (byte) 0x72, (byte) 0x6F, (byte) 0x69,
1734        (byte) 0x64, (byte) 0x2E, (byte) 0x0A,
1735    };
1736
1737    /**
1738     * This vector is simply "Android.\n" padded with zeros.
1739     */
1740    private static final byte[] TooShort_Vector_Zero_Padded = new byte[] {
1741        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
1742        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
1743        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
1744        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
1745        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
1746        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
1747        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
1748        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
1749        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
1750        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
1751        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
1752        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
1753        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
1754        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
1755        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
1756        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
1757        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
1758        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
1759        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
1760        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
1761        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
1762        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
1763        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
1764        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
1765        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
1766        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
1767        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
1768        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
1769        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
1770        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
1771        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
1772        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
1773        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
1774        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
1775        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
1776        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
1777        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
1778        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
1779        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
1780        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
1781        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
1782        (byte) 0x00, (byte) 0x41, (byte) 0x6e, (byte) 0x64, (byte) 0x72, (byte) 0x6f,
1783        (byte) 0x69, (byte) 0x64, (byte) 0x2e, (byte) 0x0a,
1784    };
1785
1786    /**
1787     * openssl rsautl -raw -sign -inkey rsa.key | recode ../x1 | sed 's/0x/(byte) 0x/g'
1788     */
1789    private static final byte[] RSA_Vector1_Encrypt_Private = new byte[] {
1790        (byte) 0x35, (byte) 0x43, (byte) 0x38, (byte) 0x44, (byte) 0xAD, (byte) 0x3F,
1791        (byte) 0x97, (byte) 0x02, (byte) 0xFB, (byte) 0x59, (byte) 0x1F, (byte) 0x4A,
1792        (byte) 0x2B, (byte) 0xB9, (byte) 0x06, (byte) 0xEC, (byte) 0x66, (byte) 0xE6,
1793        (byte) 0xD2, (byte) 0xC5, (byte) 0x8B, (byte) 0x7B, (byte) 0xE3, (byte) 0x18,
1794        (byte) 0xBF, (byte) 0x07, (byte) 0xD6, (byte) 0x01, (byte) 0xF9, (byte) 0xD9,
1795        (byte) 0x89, (byte) 0xC4, (byte) 0xDB, (byte) 0x00, (byte) 0x68, (byte) 0xFF,
1796        (byte) 0x9B, (byte) 0x43, (byte) 0x90, (byte) 0xF2, (byte) 0xDB, (byte) 0x83,
1797        (byte) 0xF4, (byte) 0x7E, (byte) 0xC6, (byte) 0x81, (byte) 0x01, (byte) 0x3A,
1798        (byte) 0x0B, (byte) 0xE5, (byte) 0xED, (byte) 0x08, (byte) 0x73, (byte) 0x3E,
1799        (byte) 0xE1, (byte) 0x3F, (byte) 0xDF, (byte) 0x1F, (byte) 0x07, (byte) 0x6D,
1800        (byte) 0x22, (byte) 0x8D, (byte) 0xCC, (byte) 0x4E, (byte) 0xE3, (byte) 0x9A,
1801        (byte) 0xBC, (byte) 0xCC, (byte) 0x8F, (byte) 0x9E, (byte) 0x9B, (byte) 0x02,
1802        (byte) 0x48, (byte) 0x00, (byte) 0xAC, (byte) 0x9F, (byte) 0xA4, (byte) 0x8F,
1803        (byte) 0x87, (byte) 0xA1, (byte) 0xA8, (byte) 0xE6, (byte) 0x9D, (byte) 0xCD,
1804        (byte) 0x8B, (byte) 0x05, (byte) 0xE9, (byte) 0xD2, (byte) 0x05, (byte) 0x8D,
1805        (byte) 0xC9, (byte) 0x95, (byte) 0x16, (byte) 0xD0, (byte) 0xCD, (byte) 0x43,
1806        (byte) 0x25, (byte) 0x8A, (byte) 0x11, (byte) 0x46, (byte) 0xD7, (byte) 0x74,
1807        (byte) 0x4C, (byte) 0xCF, (byte) 0x58, (byte) 0xF9, (byte) 0xA1, (byte) 0x30,
1808        (byte) 0x84, (byte) 0x52, (byte) 0xC9, (byte) 0x01, (byte) 0x5F, (byte) 0x24,
1809        (byte) 0x4C, (byte) 0xB1, (byte) 0x9F, (byte) 0x7D, (byte) 0x12, (byte) 0x38,
1810        (byte) 0x27, (byte) 0x0F, (byte) 0x5E, (byte) 0xFF, (byte) 0xE0, (byte) 0x55,
1811        (byte) 0x8B, (byte) 0xA3, (byte) 0xAD, (byte) 0x60, (byte) 0x35, (byte) 0x83,
1812        (byte) 0x58, (byte) 0xAF, (byte) 0x99, (byte) 0xDE, (byte) 0x3F, (byte) 0x5D,
1813        (byte) 0x80, (byte) 0x80, (byte) 0xFF, (byte) 0x9B, (byte) 0xDE, (byte) 0x5C,
1814        (byte) 0xAB, (byte) 0x97, (byte) 0x43, (byte) 0x64, (byte) 0xD9, (byte) 0x9F,
1815        (byte) 0xFB, (byte) 0x67, (byte) 0x65, (byte) 0xA5, (byte) 0x99, (byte) 0xE7,
1816        (byte) 0xE6, (byte) 0xEB, (byte) 0x05, (byte) 0x95, (byte) 0xFC, (byte) 0x46,
1817        (byte) 0x28, (byte) 0x4B, (byte) 0xD8, (byte) 0x8C, (byte) 0xF5, (byte) 0x0A,
1818        (byte) 0xEB, (byte) 0x1F, (byte) 0x30, (byte) 0xEA, (byte) 0xE7, (byte) 0x67,
1819        (byte) 0x11, (byte) 0x25, (byte) 0xF0, (byte) 0x44, (byte) 0x75, (byte) 0x74,
1820        (byte) 0x94, (byte) 0x06, (byte) 0x78, (byte) 0xD0, (byte) 0x21, (byte) 0xF4,
1821        (byte) 0x3F, (byte) 0xC8, (byte) 0xC4, (byte) 0x4A, (byte) 0x57, (byte) 0xBE,
1822        (byte) 0x02, (byte) 0x3C, (byte) 0x93, (byte) 0xF6, (byte) 0x95, (byte) 0xFB,
1823        (byte) 0xD1, (byte) 0x77, (byte) 0x8B, (byte) 0x43, (byte) 0xF0, (byte) 0xB9,
1824        (byte) 0x7D, (byte) 0xE0, (byte) 0x32, (byte) 0xE1, (byte) 0x72, (byte) 0xB5,
1825        (byte) 0x62, (byte) 0x3F, (byte) 0x86, (byte) 0xC3, (byte) 0xD4, (byte) 0x5F,
1826        (byte) 0x5E, (byte) 0x54, (byte) 0x1B, (byte) 0x5B, (byte) 0xE6, (byte) 0x74,
1827        (byte) 0xA1, (byte) 0x0B, (byte) 0xE5, (byte) 0x18, (byte) 0xD2, (byte) 0x4F,
1828        (byte) 0x93, (byte) 0xF3, (byte) 0x09, (byte) 0x58, (byte) 0xCE, (byte) 0xF0,
1829        (byte) 0xA3, (byte) 0x61, (byte) 0xE4, (byte) 0x6E, (byte) 0x46, (byte) 0x45,
1830        (byte) 0x89, (byte) 0x50, (byte) 0xBD, (byte) 0x03, (byte) 0x3F, (byte) 0x38,
1831        (byte) 0xDA, (byte) 0x5D, (byte) 0xD0, (byte) 0x1B, (byte) 0x1F, (byte) 0xB1,
1832        (byte) 0xEE, (byte) 0x89, (byte) 0x59, (byte) 0xC5,
1833    };
1834
1835    private static final byte[] RSA_Vector1_ZeroPadded_Encrypted = new byte[] {
1836        (byte) 0x60, (byte) 0x4a, (byte) 0x12, (byte) 0xa3, (byte) 0xa7, (byte) 0x4a,
1837        (byte) 0xa4, (byte) 0xbf, (byte) 0x6c, (byte) 0x36, (byte) 0xad, (byte) 0x66,
1838        (byte) 0xdf, (byte) 0xce, (byte) 0xf1, (byte) 0xe4, (byte) 0x0f, (byte) 0xd4,
1839        (byte) 0x54, (byte) 0x5f, (byte) 0x03, (byte) 0x15, (byte) 0x4b, (byte) 0x9e,
1840        (byte) 0xeb, (byte) 0xfe, (byte) 0x9e, (byte) 0x24, (byte) 0xce, (byte) 0x8e,
1841        (byte) 0xc3, (byte) 0x36, (byte) 0xa5, (byte) 0x76, (byte) 0xf6, (byte) 0x54,
1842        (byte) 0xb7, (byte) 0x84, (byte) 0x48, (byte) 0x2f, (byte) 0xd4, (byte) 0x45,
1843        (byte) 0x74, (byte) 0x48, (byte) 0x5f, (byte) 0x08, (byte) 0x4e, (byte) 0x9c,
1844        (byte) 0x89, (byte) 0xcc, (byte) 0x34, (byte) 0x40, (byte) 0xb1, (byte) 0x5f,
1845        (byte) 0xa7, (byte) 0x0e, (byte) 0x11, (byte) 0x4b, (byte) 0xb5, (byte) 0x94,
1846        (byte) 0xbe, (byte) 0x14, (byte) 0xaa, (byte) 0xaa, (byte) 0xe0, (byte) 0x38,
1847        (byte) 0x1c, (byte) 0xce, (byte) 0x40, (byte) 0x61, (byte) 0xfc, (byte) 0x08,
1848        (byte) 0xcb, (byte) 0x14, (byte) 0x2b, (byte) 0xa6, (byte) 0x54, (byte) 0xdf,
1849        (byte) 0x05, (byte) 0x5c, (byte) 0x9b, (byte) 0x4f, (byte) 0x14, (byte) 0x93,
1850        (byte) 0xb0, (byte) 0x70, (byte) 0xd9, (byte) 0x32, (byte) 0xdc, (byte) 0x24,
1851        (byte) 0xe0, (byte) 0xae, (byte) 0x48, (byte) 0xfc, (byte) 0x53, (byte) 0xee,
1852        (byte) 0x7c, (byte) 0x9f, (byte) 0x69, (byte) 0x34, (byte) 0xf4, (byte) 0x76,
1853        (byte) 0xee, (byte) 0x67, (byte) 0xb2, (byte) 0xa7, (byte) 0x33, (byte) 0x1c,
1854        (byte) 0x47, (byte) 0xff, (byte) 0x5c, (byte) 0xf0, (byte) 0xb8, (byte) 0x04,
1855        (byte) 0x2c, (byte) 0xfd, (byte) 0xe2, (byte) 0xb1, (byte) 0x4a, (byte) 0x0a,
1856        (byte) 0x69, (byte) 0x1c, (byte) 0x80, (byte) 0x2b, (byte) 0xb4, (byte) 0x50,
1857        (byte) 0x65, (byte) 0x5c, (byte) 0x76, (byte) 0x78, (byte) 0x9a, (byte) 0x0c,
1858        (byte) 0x05, (byte) 0x62, (byte) 0xf0, (byte) 0xc4, (byte) 0x1c, (byte) 0x38,
1859        (byte) 0x15, (byte) 0xd0, (byte) 0xe2, (byte) 0x5a, (byte) 0x3d, (byte) 0xb6,
1860        (byte) 0xe0, (byte) 0x88, (byte) 0x85, (byte) 0xd1, (byte) 0x4f, (byte) 0x7e,
1861        (byte) 0xfc, (byte) 0x77, (byte) 0x0d, (byte) 0x2a, (byte) 0x45, (byte) 0xd5,
1862        (byte) 0xf8, (byte) 0x3c, (byte) 0x7b, (byte) 0x2d, (byte) 0x1b, (byte) 0x82,
1863        (byte) 0xfe, (byte) 0x58, (byte) 0x22, (byte) 0x47, (byte) 0x06, (byte) 0x58,
1864        (byte) 0x8b, (byte) 0x4f, (byte) 0xfb, (byte) 0x9b, (byte) 0x1c, (byte) 0x70,
1865        (byte) 0x36, (byte) 0x12, (byte) 0x04, (byte) 0x17, (byte) 0x47, (byte) 0x8a,
1866        (byte) 0x0a, (byte) 0xec, (byte) 0x12, (byte) 0x3b, (byte) 0xf8, (byte) 0xd2,
1867        (byte) 0xdc, (byte) 0x3c, (byte) 0xc8, (byte) 0x46, (byte) 0xc6, (byte) 0x51,
1868        (byte) 0x06, (byte) 0x06, (byte) 0xcb, (byte) 0x84, (byte) 0x67, (byte) 0xb5,
1869        (byte) 0x68, (byte) 0xd9, (byte) 0x9c, (byte) 0xd4, (byte) 0x16, (byte) 0x5c,
1870        (byte) 0xb4, (byte) 0xe2, (byte) 0x55, (byte) 0xe6, (byte) 0x3a, (byte) 0x73,
1871        (byte) 0x01, (byte) 0x1d, (byte) 0x6f, (byte) 0x30, (byte) 0x31, (byte) 0x59,
1872        (byte) 0x8b, (byte) 0x2f, (byte) 0x4c, (byte) 0xe7, (byte) 0x86, (byte) 0x4c,
1873        (byte) 0x39, (byte) 0x4e, (byte) 0x67, (byte) 0x3b, (byte) 0x22, (byte) 0x9b,
1874        (byte) 0x85, (byte) 0x5a, (byte) 0xc3, (byte) 0x29, (byte) 0xaf, (byte) 0x8c,
1875        (byte) 0x7c, (byte) 0x59, (byte) 0x4a, (byte) 0x24, (byte) 0xfa, (byte) 0xba,
1876        (byte) 0x55, (byte) 0x40, (byte) 0x13, (byte) 0x64, (byte) 0xd8, (byte) 0xcb,
1877        (byte) 0x4b, (byte) 0x98, (byte) 0x3f, (byte) 0xae, (byte) 0x20, (byte) 0xfd,
1878        (byte) 0x8a, (byte) 0x50, (byte) 0x73, (byte) 0xe4,
1879    };
1880
1881    public void testRSA_ECB_NoPadding_Private_OnlyDoFinal_Success() throws Exception {
1882        for (String provider : RSA_PROVIDERS) {
1883            testRSA_ECB_NoPadding_Private_OnlyDoFinal_Success(provider);
1884        }
1885    }
1886
1887    private void testRSA_ECB_NoPadding_Private_OnlyDoFinal_Success(String provider) throws Exception {
1888        KeyFactory kf = KeyFactory.getInstance("RSA");
1889        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
1890                RSA_2048_privateExponent);
1891
1892        final PrivateKey privKey = kf.generatePrivate(keySpec);
1893
1894        Cipher c = Cipher.getInstance("RSA/ECB/NoPadding", provider);
1895
1896        /*
1897         * You're actually decrypting with private keys, but there is no
1898         * distinction made here. It's all keyed off of what kind of key you're
1899         * using. ENCRYPT_MODE and DECRYPT_MODE are the same.
1900         */
1901        c.init(Cipher.ENCRYPT_MODE, privKey);
1902        byte[] encrypted = c.doFinal(RSA_2048_Vector1);
1903        assertTrue("Encrypted should match expected",
1904                Arrays.equals(RSA_Vector1_Encrypt_Private, encrypted));
1905
1906        c.init(Cipher.DECRYPT_MODE, privKey);
1907        encrypted = c.doFinal(RSA_2048_Vector1);
1908        assertTrue("Encrypted should match expected",
1909                Arrays.equals(RSA_Vector1_Encrypt_Private, encrypted));
1910    }
1911
1912    public void testRSA_ECB_NoPadding_Private_UpdateThenEmptyDoFinal_Success() throws Exception {
1913        for (String provider : RSA_PROVIDERS) {
1914            testRSA_ECB_NoPadding_Private_UpdateThenEmptyDoFinal_Success(provider);
1915        }
1916    }
1917
1918    private void testRSA_ECB_NoPadding_Private_UpdateThenEmptyDoFinal_Success(String provider) throws Exception {
1919        KeyFactory kf = KeyFactory.getInstance("RSA");
1920        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
1921                RSA_2048_privateExponent);
1922
1923        final PrivateKey privKey = kf.generatePrivate(keySpec);
1924
1925        Cipher c = Cipher.getInstance("RSA/ECB/NoPadding", provider);
1926
1927        /*
1928         * You're actually decrypting with private keys, but there is no
1929         * distinction made here. It's all keyed off of what kind of key you're
1930         * using. ENCRYPT_MODE and DECRYPT_MODE are the same.
1931         */
1932        c.init(Cipher.ENCRYPT_MODE, privKey);
1933        c.update(RSA_2048_Vector1);
1934        byte[] encrypted = c.doFinal();
1935        assertTrue("Encrypted should match expected",
1936                Arrays.equals(RSA_Vector1_Encrypt_Private, encrypted));
1937
1938        c.init(Cipher.DECRYPT_MODE, privKey);
1939        c.update(RSA_2048_Vector1);
1940        encrypted = c.doFinal();
1941        assertTrue("Encrypted should match expected",
1942                Arrays.equals(RSA_Vector1_Encrypt_Private, encrypted));
1943    }
1944
1945    public void testRSA_ECB_NoPadding_Private_SingleByteUpdateThenEmptyDoFinal_Success()
1946            throws Exception {
1947        for (String provider : RSA_PROVIDERS) {
1948            testRSA_ECB_NoPadding_Private_SingleByteUpdateThenEmptyDoFinal_Success(provider);
1949        }
1950    }
1951
1952    private void testRSA_ECB_NoPadding_Private_SingleByteUpdateThenEmptyDoFinal_Success(String provider)
1953            throws Exception {
1954        KeyFactory kf = KeyFactory.getInstance("RSA");
1955        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
1956                RSA_2048_privateExponent);
1957
1958        final PrivateKey privKey = kf.generatePrivate(keySpec);
1959
1960        Cipher c = Cipher.getInstance("RSA/ECB/NoPadding", provider);
1961
1962        /*
1963         * You're actually decrypting with private keys, but there is no
1964         * distinction made here. It's all keyed off of what kind of key you're
1965         * using. ENCRYPT_MODE and DECRYPT_MODE are the same.
1966         */
1967        c.init(Cipher.ENCRYPT_MODE, privKey);
1968        int i;
1969        for (i = 0; i < RSA_2048_Vector1.length / 2; i++) {
1970            c.update(RSA_2048_Vector1, i, 1);
1971        }
1972        byte[] encrypted = c.doFinal(RSA_2048_Vector1, i, RSA_2048_Vector1.length - i);
1973        assertTrue("Encrypted should match expected",
1974                Arrays.equals(RSA_Vector1_Encrypt_Private, encrypted));
1975
1976        c.init(Cipher.DECRYPT_MODE, privKey);
1977        for (i = 0; i < RSA_2048_Vector1.length / 2; i++) {
1978            c.update(RSA_2048_Vector1, i, 1);
1979        }
1980        encrypted = c.doFinal(RSA_2048_Vector1, i, RSA_2048_Vector1.length - i);
1981        assertTrue("Encrypted should match expected",
1982                Arrays.equals(RSA_Vector1_Encrypt_Private, encrypted));
1983    }
1984
1985    public void testRSA_ECB_NoPadding_Private_OnlyDoFinalWithOffset_Success() throws Exception {
1986        for (String provider : RSA_PROVIDERS) {
1987            testRSA_ECB_NoPadding_Private_OnlyDoFinalWithOffset_Success(provider);
1988        }
1989    }
1990
1991    private void testRSA_ECB_NoPadding_Private_OnlyDoFinalWithOffset_Success(String provider) throws Exception {
1992        KeyFactory kf = KeyFactory.getInstance("RSA");
1993        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
1994                RSA_2048_privateExponent);
1995        final PrivateKey privKey = kf.generatePrivate(keySpec);
1996
1997        Cipher c = Cipher.getInstance("RSA/ECB/NoPadding", provider);
1998
1999        /*
2000         * You're actually decrypting with private keys, but there is no
2001         * distinction made here. It's all keyed off of what kind of key you're
2002         * using. ENCRYPT_MODE and DECRYPT_MODE are the same.
2003         */
2004        c.init(Cipher.ENCRYPT_MODE, privKey);
2005        byte[] encrypted = new byte[RSA_Vector1_Encrypt_Private.length];
2006        final int encryptLen = c
2007                .doFinal(RSA_2048_Vector1, 0, RSA_2048_Vector1.length, encrypted, 0);
2008        assertEquals("Encrypted size should match expected", RSA_Vector1_Encrypt_Private.length,
2009                encryptLen);
2010        assertTrue("Encrypted should match expected",
2011                Arrays.equals(RSA_Vector1_Encrypt_Private, encrypted));
2012
2013        c.init(Cipher.DECRYPT_MODE, privKey);
2014        final int decryptLen = c
2015                .doFinal(RSA_2048_Vector1, 0, RSA_2048_Vector1.length, encrypted, 0);
2016        assertEquals("Encrypted size should match expected", RSA_Vector1_Encrypt_Private.length,
2017                decryptLen);
2018        assertTrue("Encrypted should match expected",
2019                Arrays.equals(RSA_Vector1_Encrypt_Private, encrypted));
2020    }
2021
2022    public void testRSA_ECB_NoPadding_Public_OnlyDoFinal_Success() throws Exception {
2023        for (String provider : RSA_PROVIDERS) {
2024            testRSA_ECB_NoPadding_Public_OnlyDoFinal_Success(provider);
2025        }
2026    }
2027
2028    private void testRSA_ECB_NoPadding_Public_OnlyDoFinal_Success(String provider) throws Exception {
2029        KeyFactory kf = KeyFactory.getInstance("RSA");
2030        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
2031
2032        final PublicKey privKey = kf.generatePublic(keySpec);
2033
2034        Cipher c = Cipher.getInstance("RSA/ECB/NoPadding", provider);
2035
2036        /*
2037         * You're actually encrypting with public keys, but there is no
2038         * distinction made here. It's all keyed off of what kind of key you're
2039         * using. ENCRYPT_MODE and DECRYPT_MODE are the same.
2040         */
2041        c.init(Cipher.ENCRYPT_MODE, privKey);
2042        byte[] encrypted = c.doFinal(RSA_Vector1_Encrypt_Private);
2043        assertEncryptedEqualsNoPadding(provider, Cipher.ENCRYPT_MODE, RSA_2048_Vector1, encrypted);
2044
2045        c.init(Cipher.DECRYPT_MODE, privKey);
2046        encrypted = c.doFinal(RSA_Vector1_Encrypt_Private);
2047        assertEncryptedEqualsNoPadding(provider, Cipher.DECRYPT_MODE, RSA_2048_Vector1, encrypted);
2048    }
2049
2050    public void testRSA_ECB_NoPadding_Public_OnlyDoFinalWithOffset_Success() throws Exception {
2051        for (String provider : RSA_PROVIDERS) {
2052            testRSA_ECB_NoPadding_Public_OnlyDoFinalWithOffset_Success(provider);
2053        }
2054    }
2055
2056    private void testRSA_ECB_NoPadding_Public_OnlyDoFinalWithOffset_Success(String provider) throws Exception {
2057        KeyFactory kf = KeyFactory.getInstance("RSA");
2058        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
2059
2060        final PublicKey pubKey = kf.generatePublic(keySpec);
2061
2062        Cipher c = Cipher.getInstance("RSA/ECB/NoPadding", provider);
2063
2064        /*
2065         * You're actually encrypting with public keys, but there is no
2066         * distinction made here. It's all keyed off of what kind of key you're
2067         * using. ENCRYPT_MODE and DECRYPT_MODE are the same.
2068         */
2069        c.init(Cipher.ENCRYPT_MODE, pubKey);
2070        byte[] encrypted = new byte[RSA_2048_Vector1.length];
2071        final int encryptLen = c.doFinal(RSA_Vector1_Encrypt_Private, 0,
2072                RSA_Vector1_Encrypt_Private.length, encrypted, 0);
2073        assertEquals("Encrypted size should match expected", RSA_2048_Vector1.length, encryptLen);
2074        assertEncryptedEqualsNoPadding(provider, Cipher.ENCRYPT_MODE, RSA_2048_Vector1, encrypted);
2075
2076        c.init(Cipher.DECRYPT_MODE, pubKey);
2077        int decryptLen = c.doFinal(RSA_Vector1_Encrypt_Private, 0,
2078                RSA_Vector1_Encrypt_Private.length, encrypted, 0);
2079        if (provider.equals("BC")) {
2080            // BC strips the leading 0 for us on decrypt even when NoPadding is specified...
2081            decryptLen++;
2082            encrypted = Arrays.copyOf(encrypted, encrypted.length - 1);
2083        }
2084        assertEquals("Encrypted size should match expected", RSA_2048_Vector1.length, decryptLen);
2085        assertEncryptedEqualsNoPadding(provider, Cipher.DECRYPT_MODE, RSA_2048_Vector1, encrypted);
2086    }
2087
2088    public void testRSA_ECB_NoPadding_Public_UpdateThenEmptyDoFinal_Success() throws Exception {
2089        for (String provider : RSA_PROVIDERS) {
2090            testRSA_ECB_NoPadding_Public_UpdateThenEmptyDoFinal_Success(provider);
2091        }
2092    }
2093
2094    private void testRSA_ECB_NoPadding_Public_UpdateThenEmptyDoFinal_Success(String provider) throws Exception {
2095        KeyFactory kf = KeyFactory.getInstance("RSA");
2096        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
2097
2098        final PublicKey privKey = kf.generatePublic(keySpec);
2099
2100        Cipher c = Cipher.getInstance("RSA/ECB/NoPadding", provider);
2101
2102        /*
2103         * You're actually encrypting with public keys, but there is no
2104         * distinction made here. It's all keyed off of what kind of key you're
2105         * using. ENCRYPT_MODE and DECRYPT_MODE are the same.
2106         */
2107        c.init(Cipher.ENCRYPT_MODE, privKey);
2108        c.update(RSA_Vector1_Encrypt_Private);
2109        byte[] encrypted = c.doFinal();
2110        assertEncryptedEqualsNoPadding(provider, Cipher.ENCRYPT_MODE, RSA_2048_Vector1, encrypted);
2111
2112        c.init(Cipher.DECRYPT_MODE, privKey);
2113        c.update(RSA_Vector1_Encrypt_Private);
2114        encrypted = c.doFinal();
2115        assertEncryptedEqualsNoPadding(provider, Cipher.DECRYPT_MODE, RSA_2048_Vector1, encrypted);
2116    }
2117
2118    public void testRSA_ECB_NoPadding_Public_SingleByteUpdateThenEmptyDoFinal_Success()
2119            throws Exception {
2120        for (String provider : RSA_PROVIDERS) {
2121            testRSA_ECB_NoPadding_Public_SingleByteUpdateThenEmptyDoFinal_Success(provider);
2122        }
2123    }
2124
2125    private void testRSA_ECB_NoPadding_Public_SingleByteUpdateThenEmptyDoFinal_Success(String provider)
2126            throws Exception {
2127        KeyFactory kf = KeyFactory.getInstance("RSA");
2128        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
2129
2130        final PublicKey privKey = kf.generatePublic(keySpec);
2131
2132        Cipher c = Cipher.getInstance("RSA/ECB/NoPadding", provider);
2133
2134        /*
2135         * You're actually encrypting with public keys, but there is no
2136         * distinction made here. It's all keyed off of what kind of key you're
2137         * using. ENCRYPT_MODE and DECRYPT_MODE are the same.
2138         */
2139        c.init(Cipher.ENCRYPT_MODE, privKey);
2140        int i;
2141        for (i = 0; i < RSA_Vector1_Encrypt_Private.length / 2; i++) {
2142            c.update(RSA_Vector1_Encrypt_Private, i, 1);
2143        }
2144        byte[] encrypted = c.doFinal(RSA_Vector1_Encrypt_Private, i, RSA_2048_Vector1.length - i);
2145        assertEncryptedEqualsNoPadding(provider, Cipher.ENCRYPT_MODE, RSA_2048_Vector1, encrypted);
2146
2147        c.init(Cipher.DECRYPT_MODE, privKey);
2148        for (i = 0; i < RSA_Vector1_Encrypt_Private.length / 2; i++) {
2149            c.update(RSA_Vector1_Encrypt_Private, i, 1);
2150        }
2151        encrypted = c.doFinal(RSA_Vector1_Encrypt_Private, i, RSA_2048_Vector1.length - i);
2152        assertEncryptedEqualsNoPadding(provider, Cipher.DECRYPT_MODE, RSA_2048_Vector1, encrypted);
2153    }
2154
2155    public void testRSA_ECB_NoPadding_Public_TooSmall_Success() throws Exception {
2156        for (String provider : RSA_PROVIDERS) {
2157            testRSA_ECB_NoPadding_Public_TooSmall_Success(provider);
2158        }
2159    }
2160
2161    private void testRSA_ECB_NoPadding_Public_TooSmall_Success(String provider) throws Exception {
2162        KeyFactory kf = KeyFactory.getInstance("RSA");
2163        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus, RSA_2048_publicExponent);
2164
2165        final PublicKey privKey = kf.generatePublic(keySpec);
2166
2167        Cipher c = Cipher.getInstance("RSA/ECB/NoPadding", provider);
2168
2169        /*
2170         * You're actually encrypting with public keys, but there is no
2171         * distinction made here. It's all keyed off of what kind of key you're
2172         * using. ENCRYPT_MODE and DECRYPT_MODE are the same.
2173         */
2174        c.init(Cipher.ENCRYPT_MODE, privKey);
2175        byte[] encrypted = c.doFinal(TooShort_Vector);
2176        assertTrue("Encrypted should match expected",
2177                Arrays.equals(RSA_Vector1_ZeroPadded_Encrypted, encrypted));
2178
2179        c.init(Cipher.DECRYPT_MODE, privKey);
2180        encrypted = c.doFinal(TooShort_Vector);
2181        assertTrue("Encrypted should match expected",
2182                Arrays.equals(RSA_Vector1_ZeroPadded_Encrypted, encrypted));
2183    }
2184
2185    public void testRSA_ECB_NoPadding_Private_TooSmall_Success() throws Exception {
2186        for (String provider : RSA_PROVIDERS) {
2187            testRSA_ECB_NoPadding_Private_TooSmall_Success(provider);
2188        }
2189    }
2190
2191    private void testRSA_ECB_NoPadding_Private_TooSmall_Success(String provider) throws Exception {
2192        KeyFactory kf = KeyFactory.getInstance("RSA");
2193        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
2194                RSA_2048_privateExponent);
2195
2196        final PrivateKey privKey = kf.generatePrivate(keySpec);
2197
2198        Cipher c = Cipher.getInstance("RSA/ECB/NoPadding", provider);
2199
2200        /*
2201         * You're actually encrypting with public keys, but there is no
2202         * distinction made here. It's all keyed off of what kind of key you're
2203         * using. ENCRYPT_MODE and DECRYPT_MODE are the same.
2204         */
2205        c.init(Cipher.ENCRYPT_MODE, privKey);
2206        byte[] encrypted = c.doFinal(RSA_Vector1_ZeroPadded_Encrypted);
2207        assertEncryptedEqualsNoPadding(provider, Cipher.ENCRYPT_MODE,
2208                                       TooShort_Vector_Zero_Padded, encrypted);
2209
2210        c.init(Cipher.DECRYPT_MODE, privKey);
2211        encrypted = c.doFinal(RSA_Vector1_ZeroPadded_Encrypted);
2212        assertEncryptedEqualsNoPadding(provider, Cipher.DECRYPT_MODE,
2213                                       TooShort_Vector_Zero_Padded, encrypted);
2214    }
2215
2216    private static void assertEncryptedEqualsNoPadding(String provider, int mode,
2217                                                       byte[] expected, byte[] actual) {
2218        if (provider.equals("BC") && mode == Cipher.DECRYPT_MODE) {
2219            // BouncyCastle does us the favor of stripping leading zeroes in DECRYPT_MODE
2220            int nonZeroOffset = 0;
2221            for (byte b : expected) {
2222                if (b != 0) {
2223                    break;
2224                }
2225                nonZeroOffset++;
2226            }
2227            expected = Arrays.copyOfRange(expected, nonZeroOffset, expected.length);
2228        }
2229        assertEquals("Encrypted should match expected",
2230                     Arrays.toString(expected), Arrays.toString(actual));
2231    }
2232
2233    public void testRSA_ECB_NoPadding_Private_CombinedUpdateAndDoFinal_TooBig_Failure()
2234            throws Exception {
2235        for (String provider : RSA_PROVIDERS) {
2236            testRSA_ECB_NoPadding_Private_CombinedUpdateAndDoFinal_TooBig_Failure(provider);
2237        }
2238    }
2239
2240    private void testRSA_ECB_NoPadding_Private_CombinedUpdateAndDoFinal_TooBig_Failure(String provider)
2241            throws Exception {
2242        KeyFactory kf = KeyFactory.getInstance("RSA");
2243        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
2244                RSA_2048_privateExponent);
2245
2246        final PrivateKey privKey = kf.generatePrivate(keySpec);
2247
2248        Cipher c = Cipher.getInstance("RSA/ECB/NoPadding", provider);
2249
2250        /*
2251         * You're actually encrypting with public keys, but there is no
2252         * distinction made here. It's all keyed off of what kind of key you're
2253         * using. ENCRYPT_MODE and DECRYPT_MODE are the same.
2254         */
2255        c.init(Cipher.ENCRYPT_MODE, privKey);
2256        c.update(RSA_Vector1_ZeroPadded_Encrypted);
2257
2258        try {
2259            c.doFinal(RSA_Vector1_ZeroPadded_Encrypted);
2260            fail("Should have error when block size is too big.");
2261        } catch (IllegalBlockSizeException success) {
2262            assertFalse(provider, "BC".equals(provider));
2263        } catch (ArrayIndexOutOfBoundsException success) {
2264            assertEquals("BC", provider);
2265        }
2266    }
2267
2268    public void testRSA_ECB_NoPadding_Private_UpdateInAndOutPlusDoFinal_TooBig_Failure()
2269            throws Exception {
2270        for (String provider : RSA_PROVIDERS) {
2271            testRSA_ECB_NoPadding_Private_UpdateInAndOutPlusDoFinal_TooBig_Failure(provider);
2272        }
2273    }
2274
2275    private void testRSA_ECB_NoPadding_Private_UpdateInAndOutPlusDoFinal_TooBig_Failure(String provider)
2276            throws Exception {
2277        KeyFactory kf = KeyFactory.getInstance("RSA");
2278        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
2279                RSA_2048_privateExponent);
2280
2281        final PrivateKey privKey = kf.generatePrivate(keySpec);
2282
2283        Cipher c = Cipher.getInstance("RSA/ECB/NoPadding", provider);
2284
2285        /*
2286         * You're actually encrypting with public keys, but there is no
2287         * distinction made here. It's all keyed off of what kind of key you're
2288         * using. ENCRYPT_MODE and DECRYPT_MODE are the same.
2289         */
2290        c.init(Cipher.ENCRYPT_MODE, privKey);
2291
2292        byte[] output = new byte[RSA_2048_Vector1.length];
2293        c.update(RSA_Vector1_ZeroPadded_Encrypted, 0, RSA_Vector1_ZeroPadded_Encrypted.length,
2294                output);
2295
2296        try {
2297            c.doFinal(RSA_Vector1_ZeroPadded_Encrypted);
2298            fail("Should have error when block size is too big.");
2299        } catch (IllegalBlockSizeException success) {
2300            assertFalse(provider, "BC".equals(provider));
2301        } catch (ArrayIndexOutOfBoundsException success) {
2302            assertEquals("BC", provider);
2303        }
2304    }
2305
2306    public void testRSA_ECB_NoPadding_Private_OnlyDoFinal_TooBig_Failure() throws Exception {
2307        for (String provider : RSA_PROVIDERS) {
2308            testRSA_ECB_NoPadding_Private_OnlyDoFinal_TooBig_Failure(provider);
2309        }
2310    }
2311
2312    private void testRSA_ECB_NoPadding_Private_OnlyDoFinal_TooBig_Failure(String provider) throws Exception {
2313        KeyFactory kf = KeyFactory.getInstance("RSA");
2314        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
2315                RSA_2048_privateExponent);
2316
2317        final PrivateKey privKey = kf.generatePrivate(keySpec);
2318
2319        Cipher c = Cipher.getInstance("RSA/ECB/NoPadding", provider);
2320
2321        /*
2322         * You're actually encrypting with public keys, but there is no
2323         * distinction made here. It's all keyed off of what kind of key you're
2324         * using. ENCRYPT_MODE and DECRYPT_MODE are the same.
2325         */
2326        c.init(Cipher.ENCRYPT_MODE, privKey);
2327
2328        byte[] tooBig_Vector = new byte[RSA_Vector1_ZeroPadded_Encrypted.length * 2];
2329        System.arraycopy(RSA_Vector1_ZeroPadded_Encrypted, 0, tooBig_Vector, 0,
2330                RSA_Vector1_ZeroPadded_Encrypted.length);
2331        System.arraycopy(RSA_Vector1_ZeroPadded_Encrypted, 0, tooBig_Vector,
2332                RSA_Vector1_ZeroPadded_Encrypted.length, RSA_Vector1_ZeroPadded_Encrypted.length);
2333
2334        try {
2335            c.doFinal(tooBig_Vector);
2336            fail("Should have error when block size is too big.");
2337        } catch (IllegalBlockSizeException success) {
2338            assertFalse(provider, "BC".equals(provider));
2339        } catch (ArrayIndexOutOfBoundsException success) {
2340            assertEquals("BC", provider);
2341        }
2342    }
2343
2344    public void testRSA_ECB_NoPadding_GetBlockSize_Success() throws Exception {
2345        for (String provider : RSA_PROVIDERS) {
2346            testRSA_ECB_NoPadding_GetBlockSize_Success(provider);
2347        }
2348    }
2349
2350    private void testRSA_ECB_NoPadding_GetBlockSize_Success(String provider) throws Exception {
2351        Cipher c = Cipher.getInstance("RSA/ECB/NoPadding", provider);
2352        if (StandardNames.IS_RI) {
2353            assertEquals(0, c.getBlockSize());
2354        } else {
2355            try {
2356                c.getBlockSize();
2357                fail();
2358            } catch (IllegalStateException expected) {
2359            }
2360        }
2361
2362        KeyFactory kf = KeyFactory.getInstance("RSA");
2363        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
2364                RSA_2048_publicExponent);
2365        final PublicKey pubKey = kf.generatePublic(pubKeySpec);
2366        c.init(Cipher.ENCRYPT_MODE, pubKey);
2367        assertEquals(getExpectedBlockSize("RSA", Cipher.ENCRYPT_MODE, provider), c.getBlockSize());
2368    }
2369
2370    public void testRSA_ECB_NoPadding_GetOutputSize_NoInit_Failure() throws Exception {
2371        for (String provider : RSA_PROVIDERS) {
2372            testRSA_ECB_NoPadding_GetOutputSize_NoInit_Failure(provider);
2373        }
2374    }
2375
2376    private void testRSA_ECB_NoPadding_GetOutputSize_NoInit_Failure(String provider) throws Exception {
2377        Cipher c = Cipher.getInstance("RSA/ECB/NoPadding", provider);
2378        try {
2379            c.getOutputSize(RSA_2048_Vector1.length);
2380            fail("Should throw IllegalStateException if getOutputSize is called before init");
2381        } catch (IllegalStateException success) {
2382        }
2383    }
2384
2385    public void testRSA_ECB_NoPadding_GetOutputSize_Success() throws Exception {
2386        for (String provider : RSA_PROVIDERS) {
2387            testRSA_ECB_NoPadding_GetOutputSize_Success(provider);
2388        }
2389    }
2390
2391    private void testRSA_ECB_NoPadding_GetOutputSize_Success(String provider) throws Exception {
2392        KeyFactory kf = KeyFactory.getInstance("RSA");
2393        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
2394                RSA_2048_publicExponent);
2395        final PublicKey pubKey = kf.generatePublic(pubKeySpec);
2396
2397        Cipher c = Cipher.getInstance("RSA/ECB/NoPadding", provider);
2398        c.init(Cipher.ENCRYPT_MODE, pubKey);
2399
2400        final int modulusInBytes = RSA_2048_modulus.bitLength() / 8;
2401        assertEquals(modulusInBytes, c.getOutputSize(RSA_2048_Vector1.length));
2402        assertEquals(modulusInBytes, c.getOutputSize(RSA_2048_Vector1.length * 2));
2403        assertEquals(modulusInBytes, c.getOutputSize(0));
2404    }
2405
2406    public void testRSA_ECB_NoPadding_GetIV_Success() throws Exception {
2407        for (String provider : RSA_PROVIDERS) {
2408            testRSA_ECB_NoPadding_GetIV_Success(provider);
2409        }
2410    }
2411
2412    private void testRSA_ECB_NoPadding_GetIV_Success(String provider) throws Exception {
2413        KeyFactory kf = KeyFactory.getInstance("RSA");
2414        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
2415                RSA_2048_publicExponent);
2416        final PublicKey pubKey = kf.generatePublic(pubKeySpec);
2417
2418        Cipher c = Cipher.getInstance("RSA/ECB/NoPadding", provider);
2419        assertNull("ECB mode has no IV and should be null", c.getIV());
2420
2421        c.init(Cipher.ENCRYPT_MODE, pubKey);
2422
2423        assertNull("ECB mode has no IV and should be null", c.getIV());
2424    }
2425
2426    public void testRSA_ECB_NoPadding_GetParameters_NoneProvided_Success() throws Exception {
2427        for (String provider : RSA_PROVIDERS) {
2428            testRSA_ECB_NoPadding_GetParameters_NoneProvided_Success(provider);
2429        }
2430    }
2431
2432    private void testRSA_ECB_NoPadding_GetParameters_NoneProvided_Success(String provider) throws Exception {
2433        KeyFactory kf = KeyFactory.getInstance("RSA");
2434        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(RSA_2048_modulus,
2435                RSA_2048_publicExponent);
2436        final PublicKey pubKey = kf.generatePublic(pubKeySpec);
2437
2438        Cipher c = Cipher.getInstance("RSA/ECB/NoPadding", provider);
2439        assertNull("Parameters should be null", c.getParameters());
2440    }
2441
2442    /*
2443     * Test vector generation:
2444     * openssl rand -hex 16
2445     * echo '3d4f8970b1f27537f40a39298a41555f' | sed 's/\(..\)/(byte) 0x\1, /g'
2446     */
2447    private static final byte[] AES_128_KEY = new byte[] {
2448            (byte) 0x3d, (byte) 0x4f, (byte) 0x89, (byte) 0x70, (byte) 0xb1, (byte) 0xf2,
2449            (byte) 0x75, (byte) 0x37, (byte) 0xf4, (byte) 0x0a, (byte) 0x39, (byte) 0x29,
2450            (byte) 0x8a, (byte) 0x41, (byte) 0x55, (byte) 0x5f,
2451    };
2452
2453    /*
2454     * Test key generation:
2455     * openssl rand -hex 24
2456     * echo '5a7a3d7e40b64ed996f7afa15f97fd595e27db6af428e342' | sed 's/\(..\)/(byte) 0x\1, /g'
2457     */
2458    private static final byte[] AES_192_KEY = new byte[] {
2459            (byte) 0x5a, (byte) 0x7a, (byte) 0x3d, (byte) 0x7e, (byte) 0x40, (byte) 0xb6,
2460            (byte) 0x4e, (byte) 0xd9, (byte) 0x96, (byte) 0xf7, (byte) 0xaf, (byte) 0xa1,
2461            (byte) 0x5f, (byte) 0x97, (byte) 0xfd, (byte) 0x59, (byte) 0x5e, (byte) 0x27,
2462            (byte) 0xdb, (byte) 0x6a, (byte) 0xf4, (byte) 0x28, (byte) 0xe3, (byte) 0x42,
2463    };
2464
2465    /*
2466     * Test key generation:
2467     * openssl rand -hex 32
2468     * echo 'ec53c6d51d2c4973585fb0b8e51cd2e39915ff07a1837872715d6121bf861935' | sed 's/\(..\)/(byte) 0x\1, /g'
2469     */
2470    private static final byte[] AES_256_KEY = new byte[] {
2471            (byte) 0xec, (byte) 0x53, (byte) 0xc6, (byte) 0xd5, (byte) 0x1d, (byte) 0x2c,
2472            (byte) 0x49, (byte) 0x73, (byte) 0x58, (byte) 0x5f, (byte) 0xb0, (byte) 0xb8,
2473            (byte) 0xe5, (byte) 0x1c, (byte) 0xd2, (byte) 0xe3, (byte) 0x99, (byte) 0x15,
2474            (byte) 0xff, (byte) 0x07, (byte) 0xa1, (byte) 0x83, (byte) 0x78, (byte) 0x72,
2475            (byte) 0x71, (byte) 0x5d, (byte) 0x61, (byte) 0x21, (byte) 0xbf, (byte) 0x86,
2476            (byte) 0x19, (byte) 0x35,
2477    };
2478
2479    private static final byte[][] AES_KEYS = new byte[][] {
2480            AES_128_KEY, AES_192_KEY, AES_256_KEY,
2481    };
2482
2483    private static final String[] AES_MODES = new String[] {
2484            "AES/ECB",
2485            "AES/CBC",
2486            "AES/CFB",
2487            "AES/CTR",
2488            "AES/OFB",
2489    };
2490
2491    /*
2492     * Test vector creation:
2493     * echo -n 'Hello, world!' | recode ../x1 | sed 's/0x/(byte) 0x/g'
2494     */
2495    private static final byte[] AES_128_ECB_PKCS5Padding_TestVector_1_Plaintext = new byte[] {
2496            (byte) 0x48, (byte) 0x65, (byte) 0x6C, (byte) 0x6C, (byte) 0x6F, (byte) 0x2C,
2497            (byte) 0x20, (byte) 0x77, (byte) 0x6F, (byte) 0x72, (byte) 0x6C, (byte) 0x64,
2498            (byte) 0x21,
2499    };
2500
2501    /*
2502     * Test vector creation:
2503     * openssl enc -aes-128-ecb -K 3d4f8970b1f27537f40a39298a41555f -in blah|openssl enc -aes-128-ecb -K 3d4f8970b1f27537f40a39298a41555f -nopad -d|recode ../x1 | sed 's/0x/(byte) 0x/g'
2504     */
2505    private static final byte[] AES_128_ECB_PKCS5Padding_TestVector_1_Plaintext_Padded = new byte[] {
2506            (byte) 0x48, (byte) 0x65, (byte) 0x6C, (byte) 0x6C, (byte) 0x6F, (byte) 0x2C,
2507            (byte) 0x20, (byte) 0x77, (byte) 0x6F, (byte) 0x72, (byte) 0x6C, (byte) 0x64,
2508            (byte) 0x21, (byte) 0x03, (byte) 0x03, (byte) 0x03
2509    };
2510
2511    /*
2512     * Test vector generation:
2513     * openssl enc -aes-128-ecb -K 3d4f8970b1f27537f40a39298a41555f -in blah|recode ../x1 | sed 's/0x/(byte) 0x/g'
2514     */
2515    private static final byte[] AES_128_ECB_PKCS5Padding_TestVector_1_Encrypted = new byte[] {
2516            (byte) 0x65, (byte) 0x3E, (byte) 0x86, (byte) 0xFB, (byte) 0x05, (byte) 0x5A,
2517            (byte) 0x52, (byte) 0xEA, (byte) 0xDD, (byte) 0x08, (byte) 0xE7, (byte) 0x48,
2518            (byte) 0x33, (byte) 0x01, (byte) 0xFC, (byte) 0x5A,
2519    };
2520
2521    /*
2522     * Taken from BoringSSL test vectors.
2523     */
2524    private static final byte[] AES_128_GCM_TestVector_1_Key = new byte[] {
2525            (byte) 0xca, (byte) 0xbd, (byte) 0xcf, (byte) 0x54, (byte) 0x1a, (byte) 0xeb,
2526            (byte) 0xf9, (byte) 0x17, (byte) 0xba, (byte) 0xc0, (byte) 0x19, (byte) 0xf1,
2527            (byte) 0x39, (byte) 0x25, (byte) 0xd2, (byte) 0x67,
2528    };
2529
2530    /*
2531     * Taken from BoringSSL test vectors.
2532     */
2533    private static final byte[] AES_128_GCM_TestVector_1_IV = new byte[] {
2534            (byte) 0x2c, (byte) 0x34, (byte) 0xc0, (byte) 0x0c, (byte) 0x42, (byte) 0xda,
2535            (byte) 0xe3, (byte) 0x82, (byte) 0x27, (byte) 0x9d, (byte) 0x79, (byte) 0x74,
2536    };
2537
2538    /*
2539     * Taken from BoringSSL test vectors.
2540     */
2541    private static final byte[] AES_128_GCM_TestVector_1_AAD = new byte[] {
2542            (byte) 0xdd, (byte) 0x10, (byte) 0xe3, (byte) 0x71, (byte) 0xb2, (byte) 0x2e,
2543            (byte) 0x15, (byte) 0x67, (byte) 0x1c, (byte) 0x31, (byte) 0xaf, (byte) 0xee,
2544            (byte) 0x55, (byte) 0x2b, (byte) 0xf1, (byte) 0xde, (byte) 0xa0, (byte) 0x7c,
2545            (byte) 0xbb, (byte) 0xf6, (byte) 0x85, (byte) 0xe2, (byte) 0xca, (byte) 0xa0,
2546            (byte) 0xe0, (byte) 0x36, (byte) 0x37, (byte) 0x16, (byte) 0xa2, (byte) 0x76,
2547            (byte) 0xe1, (byte) 0x20, (byte) 0xc6, (byte) 0xc0, (byte) 0xeb, (byte) 0x4a,
2548            (byte) 0xcb, (byte) 0x1a, (byte) 0x4d, (byte) 0x1b, (byte) 0xa7, (byte) 0x3f,
2549            (byte) 0xde, (byte) 0x66, (byte) 0x15, (byte) 0xf7, (byte) 0x08, (byte) 0xaa,
2550            (byte) 0xa4, (byte) 0x6b, (byte) 0xc7, (byte) 0x6c, (byte) 0x7f, (byte) 0xf3,
2551            (byte) 0x45, (byte) 0xa4, (byte) 0xf7, (byte) 0x6b, (byte) 0xda, (byte) 0x11,
2552            (byte) 0x7f, (byte) 0xe5, (byte) 0x6f, (byte) 0x0d, (byte) 0xc9, (byte) 0xb9,
2553            (byte) 0x39, (byte) 0x04, (byte) 0x0d, (byte) 0xdd,
2554    };
2555
2556    /*
2557     * Taken from BoringSSL test vectors.
2558     */
2559    private static final byte[] AES_128_GCM_TestVector_1_Plaintext = new byte[] {
2560            (byte) 0x88, (byte) 0xcc, (byte) 0x1e, (byte) 0x07, (byte) 0xdf, (byte) 0xde,
2561            (byte) 0x8e, (byte) 0x08, (byte) 0x08, (byte) 0x2e, (byte) 0x67, (byte) 0x66,
2562            (byte) 0xe0, (byte) 0xa8, (byte) 0x81, (byte) 0x03, (byte) 0x38, (byte) 0x47,
2563            (byte) 0x42, (byte) 0xaf, (byte) 0x37, (byte) 0x8d, (byte) 0x7b, (byte) 0x6b,
2564            (byte) 0x8a, (byte) 0x87, (byte) 0xfc, (byte) 0xe0, (byte) 0x36, (byte) 0xaf,
2565            (byte) 0x74, (byte) 0x41, (byte) 0xc1, (byte) 0x39, (byte) 0x61, (byte) 0xc2,
2566            (byte) 0x5a, (byte) 0xfe, (byte) 0xa7, (byte) 0xf6, (byte) 0xe5, (byte) 0x61,
2567            (byte) 0x93, (byte) 0xf5, (byte) 0x4b, (byte) 0xee, (byte) 0x00, (byte) 0x11,
2568            (byte) 0xcb, (byte) 0x78, (byte) 0x64, (byte) 0x2c, (byte) 0x3a, (byte) 0xb9,
2569            (byte) 0xe6, (byte) 0xd5, (byte) 0xb2, (byte) 0xe3, (byte) 0x58, (byte) 0x33,
2570            (byte) 0xec, (byte) 0x16, (byte) 0xcd, (byte) 0x35, (byte) 0x55, (byte) 0x15,
2571            (byte) 0xaf, (byte) 0x1a, (byte) 0x19, (byte) 0x0f,
2572    };
2573
2574    /*
2575     * Taken from BoringSSL test vectors.
2576     */
2577    private static final byte[] AES_128_GCM_TestVector_1_Encrypted = new byte[] {
2578            (byte) 0x04, (byte) 0x94, (byte) 0x53, (byte) 0xba, (byte) 0xf1, (byte) 0x57,
2579            (byte) 0x87, (byte) 0x87, (byte) 0xd6, (byte) 0x8e, (byte) 0xd5, (byte) 0x47,
2580            (byte) 0x87, (byte) 0x26, (byte) 0xc0, (byte) 0xb8, (byte) 0xa6, (byte) 0x36,
2581            (byte) 0x33, (byte) 0x7a, (byte) 0x0b, (byte) 0x8a, (byte) 0x82, (byte) 0xb8,
2582            (byte) 0x68, (byte) 0x36, (byte) 0xf9, (byte) 0x1c, (byte) 0xde, (byte) 0x25,
2583            (byte) 0xe6, (byte) 0xe4, (byte) 0x4c, (byte) 0x34, (byte) 0x59, (byte) 0x40,
2584            (byte) 0xe8, (byte) 0x19, (byte) 0xa0, (byte) 0xc5, (byte) 0x05, (byte) 0x75,
2585            (byte) 0x1e, (byte) 0x60, (byte) 0x3c, (byte) 0xb8, (byte) 0xf8, (byte) 0xc4,
2586            (byte) 0xfe, (byte) 0x98, (byte) 0x71, (byte) 0x91, (byte) 0x85, (byte) 0x56,
2587            (byte) 0x27, (byte) 0x94, (byte) 0xa1, (byte) 0x85, (byte) 0xe5, (byte) 0xde,
2588            (byte) 0xc4, (byte) 0x15, (byte) 0xc8, (byte) 0x1f, (byte) 0x2f, (byte) 0x16,
2589            (byte) 0x2c, (byte) 0xdc, (byte) 0xd6, (byte) 0x50, (byte) 0xdc, (byte) 0xe7,
2590            (byte) 0x19, (byte) 0x87, (byte) 0x28, (byte) 0xbf, (byte) 0xc1, (byte) 0xb5,
2591            (byte) 0xf9, (byte) 0x49, (byte) 0xb9, (byte) 0xb5, (byte) 0x37, (byte) 0x41,
2592            (byte) 0x99, (byte) 0xc6,
2593    };
2594
2595    /*
2596     * Test key generation:
2597     * openssl rand -hex 16
2598     * echo 'ceaa31952dfd3d0f5af4b2042ba06094' | sed 's/\(..\)/(byte) 0x\1, /g'
2599     */
2600    private static final byte[] AES_256_CBC_PKCS5Padding_TestVector_1_IV = new byte[] {
2601            (byte) 0xce, (byte) 0xaa, (byte) 0x31, (byte) 0x95, (byte) 0x2d, (byte) 0xfd,
2602            (byte) 0x3d, (byte) 0x0f, (byte) 0x5a, (byte) 0xf4, (byte) 0xb2, (byte) 0x04,
2603            (byte) 0x2b, (byte) 0xa0, (byte) 0x60, (byte) 0x94,
2604    };
2605
2606    /*
2607     * Test vector generation:
2608     * echo -n 'I only regret that I have but one test to write.' | recode ../x1 | sed 's/0x/(byte) 0x/g'
2609     */
2610    private static final byte[] AES_256_CBC_PKCS5Padding_TestVector_1_Plaintext = new byte[] {
2611            (byte) 0x49, (byte) 0x20, (byte) 0x6F, (byte) 0x6E, (byte) 0x6C, (byte) 0x79,
2612            (byte) 0x20, (byte) 0x72, (byte) 0x65, (byte) 0x67, (byte) 0x72, (byte) 0x65,
2613            (byte) 0x74, (byte) 0x20, (byte) 0x74, (byte) 0x68, (byte) 0x61, (byte) 0x74,
2614            (byte) 0x20, (byte) 0x49, (byte) 0x20, (byte) 0x68, (byte) 0x61, (byte) 0x76,
2615            (byte) 0x65, (byte) 0x20, (byte) 0x62, (byte) 0x75, (byte) 0x74, (byte) 0x20,
2616            (byte) 0x6F, (byte) 0x6E, (byte) 0x65, (byte) 0x20, (byte) 0x74, (byte) 0x65,
2617            (byte) 0x73, (byte) 0x74, (byte) 0x20, (byte) 0x74, (byte) 0x6F, (byte) 0x20,
2618            (byte) 0x77, (byte) 0x72, (byte) 0x69, (byte) 0x74, (byte) 0x65, (byte) 0x2E
2619    };
2620
2621    /*
2622     * Test vector generation:
2623     * echo -n 'I only regret that I have but one test to write.' | openssl enc -aes-256-cbc -K ec53c6d51d2c4973585fb0b8e51cd2e39915ff07a1837872715d6121bf861935 -iv ceaa31952dfd3d0f5af4b2042ba06094 | openssl enc -aes-256-cbc -K ec53c6d51d2c4973585fb0b8e51cd2e39915ff07a1837872715d6121bf861935 -iv ceaa31952dfd3d0f5af4b2042ba06094 -d -nopad | recode ../x1 | sed 's/0x/(byte) 0x/g'
2624     */
2625    private static final byte[] AES_256_CBC_PKCS5Padding_TestVector_1_Plaintext_Padded = new byte[] {
2626            (byte) 0x49, (byte) 0x20, (byte) 0x6F, (byte) 0x6E, (byte) 0x6C, (byte) 0x79,
2627            (byte) 0x20, (byte) 0x72, (byte) 0x65, (byte) 0x67, (byte) 0x72, (byte) 0x65,
2628            (byte) 0x74, (byte) 0x20, (byte) 0x74, (byte) 0x68, (byte) 0x61, (byte) 0x74,
2629            (byte) 0x20, (byte) 0x49, (byte) 0x20, (byte) 0x68, (byte) 0x61, (byte) 0x76,
2630            (byte) 0x65, (byte) 0x20, (byte) 0x62, (byte) 0x75, (byte) 0x74, (byte) 0x20,
2631            (byte) 0x6F, (byte) 0x6E, (byte) 0x65, (byte) 0x20, (byte) 0x74, (byte) 0x65,
2632            (byte) 0x73, (byte) 0x74, (byte) 0x20, (byte) 0x74, (byte) 0x6F, (byte) 0x20,
2633            (byte) 0x77, (byte) 0x72, (byte) 0x69, (byte) 0x74, (byte) 0x65, (byte) 0x2E,
2634            (byte) 0x10, (byte) 0x10, (byte) 0x10, (byte) 0x10, (byte) 0x10, (byte) 0x10,
2635            (byte) 0x10, (byte) 0x10, (byte) 0x10, (byte) 0x10, (byte) 0x10, (byte) 0x10,
2636            (byte) 0x10, (byte) 0x10, (byte) 0x10, (byte) 0x10
2637    };
2638
2639    /*
2640     * Test vector generation:
2641     * echo -n 'I only regret that I have but one test to write.' | openssl enc -aes-256-cbc -K ec53c6d51d2c4973585fb0b8e51cd2e39915ff07a1837872715d6121bf861935 -iv ceaa31952dfd3d0f5af4b2042ba06094 | recode ../x1 | sed 's/0x/(byte) 0x/g'
2642     */
2643    private static final byte[] AES_256_CBC_PKCS5Padding_TestVector_1_Ciphertext = new byte[] {
2644            (byte) 0x90, (byte) 0x65, (byte) 0xDD, (byte) 0xAF, (byte) 0x7A, (byte) 0xCE,
2645            (byte) 0xAE, (byte) 0xBF, (byte) 0xE8, (byte) 0xF6, (byte) 0x9E, (byte) 0xDB,
2646            (byte) 0xEA, (byte) 0x65, (byte) 0x28, (byte) 0xC4, (byte) 0x9A, (byte) 0x28,
2647            (byte) 0xEA, (byte) 0xA3, (byte) 0x95, (byte) 0x2E, (byte) 0xFF, (byte) 0xF1,
2648            (byte) 0xA0, (byte) 0xCA, (byte) 0xC2, (byte) 0xA4, (byte) 0x65, (byte) 0xCD,
2649            (byte) 0xBF, (byte) 0xCE, (byte) 0x9E, (byte) 0xF1, (byte) 0x57, (byte) 0xF6,
2650            (byte) 0x32, (byte) 0x2E, (byte) 0x8F, (byte) 0x93, (byte) 0x2E, (byte) 0xAE,
2651            (byte) 0x41, (byte) 0x33, (byte) 0x54, (byte) 0xD0, (byte) 0xEF, (byte) 0x8C,
2652            (byte) 0x52, (byte) 0x14, (byte) 0xAC, (byte) 0x2D, (byte) 0xD5, (byte) 0xA4,
2653            (byte) 0xF9, (byte) 0x20, (byte) 0x77, (byte) 0x25, (byte) 0x91, (byte) 0x3F,
2654            (byte) 0xD1, (byte) 0xB9, (byte) 0x00, (byte) 0x3E
2655    };
2656
2657    private static class CipherTestParam {
2658        public final String transformation;
2659
2660        public final byte[] key;
2661
2662        public final byte[] iv;
2663
2664        public final byte[] aad;
2665
2666        public final byte[] plaintext;
2667
2668        public final byte[] ciphertext;
2669
2670        public final byte[] plaintextPadded;
2671
2672        public CipherTestParam(String transformation, byte[] key, byte[] iv, byte[] aad,
2673                byte[] plaintext, byte[] plaintextPadded, byte[] ciphertext) {
2674            this.transformation = transformation.toUpperCase(Locale.ROOT);
2675            this.key = key;
2676            this.iv = iv;
2677            this.aad = aad;
2678            this.plaintext = plaintext;
2679            this.plaintextPadded = plaintextPadded;
2680            this.ciphertext = ciphertext;
2681        }
2682    }
2683
2684    private static List<CipherTestParam> CIPHER_TEST_PARAMS = new ArrayList<CipherTestParam>();
2685    static {
2686        CIPHER_TEST_PARAMS.add(new CipherTestParam("AES/ECB/PKCS5Padding", AES_128_KEY,
2687                null,
2688                null,
2689                AES_128_ECB_PKCS5Padding_TestVector_1_Plaintext,
2690                AES_128_ECB_PKCS5Padding_TestVector_1_Plaintext_Padded,
2691                AES_128_ECB_PKCS5Padding_TestVector_1_Encrypted));
2692        // PKCS#5 is assumed to be equivalent to PKCS#7 -- same test vectors are thus used for both.
2693        CIPHER_TEST_PARAMS.add(new CipherTestParam("AES/ECB/PKCS7Padding", AES_128_KEY,
2694                null,
2695                null,
2696                AES_128_ECB_PKCS5Padding_TestVector_1_Plaintext,
2697                AES_128_ECB_PKCS5Padding_TestVector_1_Plaintext_Padded,
2698                AES_128_ECB_PKCS5Padding_TestVector_1_Encrypted));
2699        CIPHER_TEST_PARAMS.add(new CipherTestParam("AES/GCM/NOPADDING",
2700                AES_128_GCM_TestVector_1_Key,
2701                AES_128_GCM_TestVector_1_IV,
2702                AES_128_GCM_TestVector_1_AAD,
2703                AES_128_GCM_TestVector_1_Plaintext,
2704                AES_128_GCM_TestVector_1_Plaintext,
2705                AES_128_GCM_TestVector_1_Encrypted));
2706        if (IS_UNLIMITED) {
2707            CIPHER_TEST_PARAMS.add(new CipherTestParam("AES/CBC/PKCS5Padding", AES_256_KEY,
2708                    AES_256_CBC_PKCS5Padding_TestVector_1_IV,
2709                    null,
2710                    AES_256_CBC_PKCS5Padding_TestVector_1_Plaintext,
2711                    AES_256_CBC_PKCS5Padding_TestVector_1_Plaintext_Padded,
2712                    AES_256_CBC_PKCS5Padding_TestVector_1_Ciphertext));
2713            CIPHER_TEST_PARAMS.add(new CipherTestParam("AES/CBC/PKCS7Padding", AES_256_KEY,
2714                    AES_256_CBC_PKCS5Padding_TestVector_1_IV,
2715                    null,
2716                    AES_256_CBC_PKCS5Padding_TestVector_1_Plaintext,
2717                    AES_256_CBC_PKCS5Padding_TestVector_1_Plaintext_Padded,
2718                    AES_256_CBC_PKCS5Padding_TestVector_1_Ciphertext));
2719        }
2720    }
2721
2722    public void testCipher_Success() throws Exception {
2723        for (String provider : AES_PROVIDERS) {
2724            testCipher_Success(provider);
2725        }
2726    }
2727
2728    private void testCipher_Success(String provider) throws Exception {
2729        final ByteArrayOutputStream errBuffer = new ByteArrayOutputStream();
2730        PrintStream out = new PrintStream(errBuffer);
2731        for (CipherTestParam p : CIPHER_TEST_PARAMS) {
2732            try {
2733                checkCipher(p, provider);
2734            } catch (Exception e) {
2735                out.append("Error encountered checking " + p.transformation + ", keySize="
2736                        + (p.key.length * 8)
2737                        + " with provider " + provider + "\n");
2738
2739                e.printStackTrace(out);
2740            }
2741        }
2742        out.flush();
2743        if (errBuffer.size() > 0) {
2744            throw new Exception("Errors encountered:\n\n" + errBuffer.toString() + "\n\n");
2745        }
2746    }
2747
2748    private void checkCipher(CipherTestParam p, String provider) throws Exception {
2749        SecretKey key = new SecretKeySpec(p.key, "AES");
2750        Cipher c = Cipher.getInstance(p.transformation, provider);
2751
2752        AlgorithmParameterSpec spec = null;
2753        if (p.iv != null) {
2754            if (isAEAD(p.transformation)) {
2755                spec = new GCMParameterSpec((p.ciphertext.length - p.plaintext.length) * 8, p.iv);
2756            } else {
2757                spec = new IvParameterSpec(p.iv);
2758            }
2759        }
2760
2761        c.init(Cipher.ENCRYPT_MODE, key, spec);
2762
2763        if (p.aad != null) {
2764            c.updateAAD(p.aad);
2765        }
2766        final byte[] actualCiphertext = c.doFinal(p.plaintext);
2767        assertEquals(p.transformation + " " + provider, Arrays.toString(p.ciphertext),
2768                Arrays.toString(actualCiphertext));
2769
2770        c = Cipher.getInstance(p.transformation, provider);
2771        c.init(Cipher.ENCRYPT_MODE, key, spec);
2772        byte[] emptyCipherText = c.doFinal();
2773        assertNotNull(emptyCipherText);
2774
2775        c.init(Cipher.DECRYPT_MODE, key, spec);
2776
2777        if (!isAEAD(p.transformation)) {
2778            try {
2779                c.updateAAD(new byte[8]);
2780                fail("Cipher should not support AAD");
2781            } catch (UnsupportedOperationException | IllegalStateException expected) {
2782            }
2783        }
2784
2785        try {
2786            byte[] emptyPlainText = c.doFinal(emptyCipherText);
2787            assertEquals(Arrays.toString(new byte[0]), Arrays.toString(emptyPlainText));
2788        } catch (AEADBadTagException e) {
2789            if (!"AndroidOpenSSL".equals(provider) || !isAEAD(p.transformation)) {
2790                throw e;
2791            }
2792        }
2793
2794        // empty decrypt
2795        {
2796            if (!isAEAD(p.transformation)
2797                    && (StandardNames.IS_RI || provider.equals("AndroidOpenSSL"))) {
2798                assertEquals(Arrays.toString(new byte[0]),
2799                             Arrays.toString(c.doFinal()));
2800
2801                c.update(new byte[0]);
2802                assertEquals(Arrays.toString(new byte[0]),
2803                             Arrays.toString(c.doFinal()));
2804            } else if (provider.equals("BC") || isAEAD(p.transformation)) {
2805                try {
2806                    c.doFinal();
2807                    fail();
2808                } catch (IllegalBlockSizeException maybe) {
2809                    if (isAEAD(p.transformation)) {
2810                        throw maybe;
2811                    }
2812                } catch (AEADBadTagException maybe) {
2813                    if (!isAEAD(p.transformation)) {
2814                        throw maybe;
2815                    }
2816                }
2817                try {
2818                    c.update(new byte[0]);
2819                    c.doFinal();
2820                    fail();
2821                } catch (IllegalBlockSizeException maybe) {
2822                    if (isAEAD(p.transformation)) {
2823                        throw maybe;
2824                    }
2825                } catch (AEADBadTagException maybe) {
2826                    if (!isAEAD(p.transformation)) {
2827                        throw maybe;
2828                    }
2829                }
2830            } else {
2831                throw new AssertionError("Define your behavior here for " + provider);
2832            }
2833        }
2834
2835        // Cipher might be in unspecified state from failures above.
2836        c.init(Cipher.DECRYPT_MODE, key, spec);
2837
2838        // .doFinal(input)
2839        {
2840            if (p.aad != null) {
2841                c.updateAAD(p.aad);
2842            }
2843            final byte[] actualPlaintext = c.doFinal(p.ciphertext);
2844            assertEquals(Arrays.toString(p.plaintext), Arrays.toString(actualPlaintext));
2845        }
2846
2847        // .doFinal(input, offset, len, output)
2848        {
2849            final byte[] largerThanCiphertext = new byte[p.ciphertext.length + 5];
2850            System.arraycopy(p.ciphertext, 0, largerThanCiphertext, 5, p.ciphertext.length);
2851
2852            if (p.aad != null) {
2853                final byte[] largerThanAad = new byte[p.aad.length + 100];
2854                System.arraycopy(p.aad, 0, largerThanAad, 50, p.aad.length);
2855                c.updateAAD(largerThanAad, 50, p.aad.length);
2856            }
2857
2858            final byte[] actualPlaintext = new byte[c.getOutputSize(p.ciphertext.length)];
2859            assertEquals(p.plaintext.length,
2860                    c.doFinal(largerThanCiphertext, 5, p.ciphertext.length, actualPlaintext));
2861            assertEquals(Arrays.toString(p.plaintext),
2862                    Arrays.toString(Arrays.copyOfRange(actualPlaintext, 0, p.plaintext.length)));
2863        }
2864
2865        // .doFinal(input, offset, len, output, offset)
2866        {
2867            final byte[] largerThanCiphertext = new byte[p.ciphertext.length + 10];
2868            System.arraycopy(p.ciphertext, 0, largerThanCiphertext, 5, p.ciphertext.length);
2869
2870            if (p.aad != null) {
2871                final byte[] largerThanAad = new byte[p.aad.length + 2];
2872                System.arraycopy(p.aad, 0, largerThanAad, 2, p.aad.length);
2873                c.updateAAD(largerThanAad, 2, p.aad.length);
2874            }
2875
2876            final byte[] actualPlaintext = new byte[c.getOutputSize(p.ciphertext.length) + 2];
2877            assertEquals(p.plaintext.length,
2878                    c.doFinal(largerThanCiphertext, 5, p.ciphertext.length, actualPlaintext, 1));
2879            assertEquals(Arrays.toString(p.plaintext),
2880                    Arrays.toString(Arrays.copyOfRange(actualPlaintext, 1, p.plaintext.length + 1)));
2881        }
2882
2883        if (!p.transformation.endsWith("NOPADDING")) {
2884            Cipher cNoPad = Cipher.getInstance(
2885                    getCipherTransformationWithNoPadding(p.transformation), provider);
2886            cNoPad.init(Cipher.DECRYPT_MODE, key, spec);
2887
2888            if (p.aad != null) {
2889                c.updateAAD(p.aad);
2890            }
2891            final byte[] actualPlaintextPadded = cNoPad.doFinal(p.ciphertext);
2892            assertEquals(provider + ":" + cNoPad.getAlgorithm(),
2893                    Arrays.toString(p.plaintextPadded), Arrays.toString(actualPlaintextPadded));
2894        }
2895
2896        // Test wrapping a key. Every cipher should be able to wrap.
2897        {
2898            // Generate a small SecretKey for AES.
2899            KeyGenerator kg = KeyGenerator.getInstance("AES");
2900            kg.init(128);
2901            SecretKey sk = kg.generateKey();
2902
2903            // Wrap it
2904            c = Cipher.getInstance(p.transformation, provider);
2905            c.init(Cipher.WRAP_MODE, key, spec);
2906            byte[] cipherText = c.wrap(sk);
2907
2908            // Unwrap it
2909            c.init(Cipher.UNWRAP_MODE, key, spec);
2910            Key decryptedKey = c.unwrap(cipherText, sk.getAlgorithm(), Cipher.SECRET_KEY);
2911
2912            assertEquals(
2913                    "sk.getAlgorithm()=" + sk.getAlgorithm() + " decryptedKey.getAlgorithm()="
2914                            + decryptedKey.getAlgorithm() + " encryptKey.getEncoded()="
2915                            + Arrays.toString(sk.getEncoded()) + " decryptedKey.getEncoded()="
2916                            + Arrays.toString(decryptedKey.getEncoded()), sk, decryptedKey);
2917        }
2918    }
2919
2920    /**
2921     * Gets the Cipher transformation with the same algorithm and mode as the provided one but
2922     * which uses no padding.
2923     */
2924    private static String getCipherTransformationWithNoPadding(String transformation) {
2925        // The transformation is assumed to be in the Algorithm/Mode/Padding format.
2926        int paddingModeDelimiterIndex = transformation.lastIndexOf('/');
2927        if (paddingModeDelimiterIndex == -1) {
2928            fail("No padding mode delimiter: " + transformation);
2929        }
2930        String paddingMode = transformation.substring(paddingModeDelimiterIndex + 1);
2931        if (!paddingMode.toLowerCase().endsWith("padding")) {
2932            fail("No padding mode specified:" + transformation);
2933        }
2934        return transformation.substring(0, paddingModeDelimiterIndex) + "/NoPadding";
2935    }
2936
2937    public void testCipher_updateAAD_BeforeInit_Failure() throws Exception {
2938        Cipher c = Cipher.getInstance("AES/ECB/NoPadding");
2939
2940        try {
2941            c.updateAAD((byte[]) null);
2942            fail("should not be able to call updateAAD before Cipher is initialized");
2943        } catch (IllegalArgumentException expected) {
2944        }
2945
2946        try {
2947            c.updateAAD((ByteBuffer) null);
2948            fail("should not be able to call updateAAD before Cipher is initialized");
2949        } catch (IllegalStateException expected) {
2950        }
2951
2952        try {
2953            c.updateAAD(new byte[8]);
2954            fail("should not be able to call updateAAD before Cipher is initialized");
2955        } catch (IllegalStateException expected) {
2956        }
2957
2958        try {
2959            c.updateAAD(null, 0, 8);
2960            fail("should not be able to call updateAAD before Cipher is initialized");
2961        } catch (IllegalStateException expected) {
2962        }
2963
2964        ByteBuffer bb = ByteBuffer.allocate(8);
2965        try {
2966            c.updateAAD(bb);
2967            fail("should not be able to call updateAAD before Cipher is initialized");
2968        } catch (IllegalStateException expected) {
2969        }
2970    }
2971
2972    public void testCipher_updateAAD_AfterInit_Failure() throws Exception {
2973        Cipher c = Cipher.getInstance("AES/ECB/NoPadding");
2974        c.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(new byte[128 / 8], "AES"));
2975
2976        try {
2977            c.updateAAD((byte[]) null);
2978            fail("should not be able to call updateAAD with null input");
2979        } catch (IllegalArgumentException expected) {
2980        }
2981
2982        try {
2983            c.updateAAD((ByteBuffer) null);
2984            fail("should not be able to call updateAAD with null input");
2985        } catch (IllegalArgumentException expected) {
2986        }
2987
2988        try {
2989            c.updateAAD(null, 0, 8);
2990            fail("should not be able to call updateAAD with null input");
2991        } catch (IllegalArgumentException expected) {
2992        }
2993
2994        try {
2995            c.updateAAD(new byte[8], -1, 7);
2996            fail("should not be able to call updateAAD with invalid offset");
2997        } catch (IllegalArgumentException expected) {
2998        }
2999
3000        try {
3001            c.updateAAD(new byte[8], 0, -1);
3002            fail("should not be able to call updateAAD with negative length");
3003        } catch (IllegalArgumentException expected) {
3004        }
3005
3006        try {
3007            c.updateAAD(new byte[8], 0, 8 + 1);
3008            fail("should not be able to call updateAAD with too large length");
3009        } catch (IllegalArgumentException expected) {
3010        }
3011
3012        try {
3013            c.updateAAD(new byte[8]);
3014            fail("should not be able to call updateAAD on non-AEAD cipher");
3015        } catch (UnsupportedOperationException | IllegalStateException expected) {
3016        }
3017    }
3018
3019    public void testCipher_updateAAD_AfterInit_WithGcm_Success() throws Exception {
3020        Cipher c = Cipher.getInstance("AES/GCM/NoPadding");
3021        c.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(new byte[128 / 8], "AES"));
3022        c.updateAAD(new byte[8]);
3023        c.updateAAD(new byte[8]);
3024    }
3025
3026    public void testCipher_updateAAD_AfterUpdate_WithGcm_Sucess() throws Exception {
3027        Cipher c = Cipher.getInstance("AES/GCM/NoPadding");
3028        c.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(new byte[128 / 8], "AES"));
3029        c.updateAAD(new byte[8]);
3030        c.update(new byte[8]);
3031        c.updateAAD(new byte[8]);
3032    }
3033
3034    public void testCipher_ShortBlock_Failure() throws Exception {
3035        for (String provider : AES_PROVIDERS) {
3036            testCipher_ShortBlock_Failure(provider);
3037        }
3038    }
3039
3040    private void testCipher_ShortBlock_Failure(String provider) throws Exception {
3041        final ByteArrayOutputStream errBuffer = new ByteArrayOutputStream();
3042        PrintStream out = new PrintStream(errBuffer);
3043        for (CipherTestParam p : CIPHER_TEST_PARAMS) {
3044            try {
3045                checkCipher_ShortBlock_Failure(p, provider);
3046            } catch (Exception e) {
3047                out.append("Error encountered checking " + p.transformation + ", keySize="
3048                        + (p.key.length * 8)
3049                        + " with provider " + provider + "\n");
3050                e.printStackTrace(out);
3051            }
3052        }
3053        out.flush();
3054        if (errBuffer.size() > 0) {
3055            throw new Exception("Errors encountered:\n\n" + errBuffer.toString() + "\n\n");
3056        }
3057    }
3058
3059    public void testCipher_Update_WithZeroLengthInput_ReturnsNull() throws Exception {
3060        SecretKey key = new SecretKeySpec(AES_128_KEY, "AES");
3061        Cipher c = Cipher.getInstance("AES/ECB/NoPadding");
3062        c.init(Cipher.ENCRYPT_MODE, key);
3063        assertNull(c.update(new byte[0]));
3064        assertNull(c.update(new byte[c.getBlockSize() * 2], 0, 0));
3065
3066        // Try with non-zero offset just in case the implementation mixes up offset and inputLen
3067        assertNull(c.update(new byte[c.getBlockSize() * 2], 16, 0));
3068    }
3069
3070    private void checkCipher_ShortBlock_Failure(CipherTestParam p, String provider) throws Exception {
3071        // Do not try to test ciphers with no padding already.
3072        String noPaddingTransform = getCipherTransformationWithNoPadding(p.transformation);
3073        if (p.transformation.equals(noPaddingTransform)) {
3074            return;
3075        }
3076
3077        SecretKey key = new SecretKeySpec(p.key, "AES");
3078        Cipher c = Cipher.getInstance(
3079                getCipherTransformationWithNoPadding(p.transformation), provider);
3080        if (c.getBlockSize() == 0) {
3081            return;
3082        }
3083
3084        if (!p.transformation.endsWith("NOPADDING")) {
3085            c.init(Cipher.ENCRYPT_MODE, key);
3086            try {
3087                c.doFinal(new byte[] { 0x01, 0x02, 0x03 });
3088                fail("Should throw IllegalBlockSizeException on wrong-sized block; transform="
3089                        + p.transformation + " provider=" + provider);
3090            } catch (IllegalBlockSizeException expected) {
3091            }
3092        }
3093    }
3094
3095    public void testAES_ECB_PKCS5Padding_ShortBuffer_Failure() throws Exception {
3096        for (String provider : AES_PROVIDERS) {
3097            testAES_ECB_PKCS5Padding_ShortBuffer_Failure(provider);
3098        }
3099    }
3100
3101    private void testAES_ECB_PKCS5Padding_ShortBuffer_Failure(String provider) throws Exception {
3102        SecretKey key = new SecretKeySpec(AES_128_KEY, "AES");
3103        Cipher c = Cipher.getInstance("AES/ECB/PKCS5Padding", provider);
3104        c.init(Cipher.ENCRYPT_MODE, key);
3105
3106        final byte[] fragmentOutput = c.update(AES_128_ECB_PKCS5Padding_TestVector_1_Plaintext);
3107        if (fragmentOutput != null) {
3108            assertEquals(0, fragmentOutput.length);
3109        }
3110
3111        // Provide null buffer.
3112        {
3113            try {
3114                c.doFinal(null, 0);
3115                fail("Should throw NullPointerException on null output buffer");
3116            } catch (NullPointerException expected) {
3117            } catch (IllegalArgumentException expected) {
3118            }
3119        }
3120
3121        // Provide short buffer.
3122        {
3123            final byte[] output = new byte[c.getBlockSize() - 1];
3124            try {
3125                c.doFinal(output, 0);
3126                fail("Should throw ShortBufferException on short output buffer");
3127            } catch (ShortBufferException expected) {
3128            }
3129        }
3130
3131        // Start 1 byte into output buffer.
3132        {
3133            final byte[] output = new byte[c.getBlockSize()];
3134            try {
3135                c.doFinal(output, 1);
3136                fail("Should throw ShortBufferException on short output buffer");
3137            } catch (ShortBufferException expected) {
3138            }
3139        }
3140
3141        // Should keep data for real output buffer
3142        {
3143            final byte[] output = new byte[c.getBlockSize()];
3144            assertEquals(AES_128_ECB_PKCS5Padding_TestVector_1_Encrypted.length, c.doFinal(output, 0));
3145            assertTrue(Arrays.equals(AES_128_ECB_PKCS5Padding_TestVector_1_Encrypted, output));
3146        }
3147    }
3148
3149    public void testAES_ECB_NoPadding_IncrementalUpdate_Success() throws Exception {
3150        for (String provider : AES_PROVIDERS) {
3151            testAES_ECB_NoPadding_IncrementalUpdate_Success(provider);
3152        }
3153    }
3154
3155    private void testAES_ECB_NoPadding_IncrementalUpdate_Success(String provider) throws Exception {
3156        SecretKey key = new SecretKeySpec(AES_128_KEY, "AES");
3157        Cipher c = Cipher.getInstance("AES/ECB/NoPadding", provider);
3158        assertEquals(provider, c.getProvider().getName());
3159        c.init(Cipher.ENCRYPT_MODE, key);
3160
3161        for (int i = 0; i < AES_128_ECB_PKCS5Padding_TestVector_1_Plaintext_Padded.length - 1; i++) {
3162            final byte[] outputFragment = c.update(AES_128_ECB_PKCS5Padding_TestVector_1_Plaintext_Padded, i, 1);
3163            if (outputFragment != null) {
3164                assertEquals(0, outputFragment.length);
3165            }
3166        }
3167
3168        final byte[] output = c.doFinal(AES_128_ECB_PKCS5Padding_TestVector_1_Plaintext_Padded,
3169                AES_128_ECB_PKCS5Padding_TestVector_1_Plaintext_Padded.length - 1, 1);
3170        assertNotNull(provider, output);
3171        assertEquals(provider, AES_128_ECB_PKCS5Padding_TestVector_1_Plaintext_Padded.length,
3172                output.length);
3173
3174        assertTrue(provider, Arrays.equals(AES_128_ECB_PKCS5Padding_TestVector_1_Encrypted, output));
3175    }
3176
3177    private static final byte[] AES_IV_ZEROES = new byte[] {
3178            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
3179            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
3180            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
3181    };
3182
3183    public void testAES_ECB_NoPadding_IvParameters_Failure() throws Exception {
3184        for (String provider : AES_PROVIDERS) {
3185            testAES_ECB_NoPadding_IvParameters_Failure(provider);
3186        }
3187    }
3188
3189    private void testAES_ECB_NoPadding_IvParameters_Failure(String provider) throws Exception {
3190        SecretKey key = new SecretKeySpec(AES_128_KEY, "AES");
3191        Cipher c = Cipher.getInstance("AES/ECB/NoPadding", provider);
3192
3193        AlgorithmParameterSpec spec = new IvParameterSpec(AES_IV_ZEROES);
3194        try {
3195            c.init(Cipher.ENCRYPT_MODE, key, spec);
3196            fail("Should not accept an IV in ECB mode; provider=" + provider);
3197        } catch (InvalidAlgorithmParameterException expected) {
3198        }
3199    }
3200
3201    public void testRC4_MultipleKeySizes() throws Exception {
3202        final int SMALLEST_KEY_SIZE = 40;
3203        final int LARGEST_KEY_SIZE = 1024;
3204
3205        /* Make an array of keys for our tests */
3206        SecretKey[] keys = new SecretKey[LARGEST_KEY_SIZE - SMALLEST_KEY_SIZE];
3207        {
3208            KeyGenerator kg = KeyGenerator.getInstance("ARC4");
3209            for (int keysize = SMALLEST_KEY_SIZE; keysize < LARGEST_KEY_SIZE; keysize++) {
3210                final int index = keysize - SMALLEST_KEY_SIZE;
3211                kg.init(keysize);
3212                keys[index] = kg.generateKey();
3213            }
3214        }
3215
3216        /*
3217         * Use this to compare the output of the first provider against
3218         * subsequent providers.
3219         */
3220        String[] expected = new String[LARGEST_KEY_SIZE - SMALLEST_KEY_SIZE];
3221
3222        /* Find all providers that provide ARC4. We must have at least one! */
3223        Map<String, String> filter = new HashMap<String, String>();
3224        filter.put("Cipher.ARC4", "");
3225        Provider[] providers = Security.getProviders(filter);
3226        assertTrue("There must be security providers of Cipher.ARC4", providers.length > 0);
3227
3228        /* Keep track of this for later error messages */
3229        String firstProvider = providers[0].getName();
3230
3231        for (Provider p : providers) {
3232            Cipher c = Cipher.getInstance("ARC4", p);
3233
3234            for (int keysize = SMALLEST_KEY_SIZE; keysize < LARGEST_KEY_SIZE; keysize++) {
3235                final int index = keysize - SMALLEST_KEY_SIZE;
3236                final SecretKey sk = keys[index];
3237
3238                /*
3239                 * Test that encryption works. Donig this in a loop also has the
3240                 * benefit of testing that re-initialization works for this
3241                 * cipher.
3242                 */
3243                c.init(Cipher.ENCRYPT_MODE, sk);
3244                byte[] cipherText = c.doFinal(ORIGINAL_PLAIN_TEXT);
3245                assertNotNull(cipherText);
3246
3247                /*
3248                 * Compare providers against eachother to make sure they're all
3249                 * in agreement. This helps when you add a brand new provider.
3250                 */
3251                if (expected[index] == null) {
3252                    expected[index] = Arrays.toString(cipherText);
3253                } else {
3254                    assertEquals(firstProvider + " should output the same as " + p.getName()
3255                            + " for key size " + keysize, expected[index],
3256                            Arrays.toString(cipherText));
3257                }
3258
3259                c.init(Cipher.DECRYPT_MODE, sk);
3260                byte[] actualPlaintext = c.doFinal(cipherText);
3261                assertEquals("Key size: " + keysize, Arrays.toString(ORIGINAL_PLAIN_TEXT),
3262                        Arrays.toString(actualPlaintext));
3263            }
3264        }
3265    }
3266
3267    /**
3268     * Several exceptions can be thrown by init. Check that in this case we throw the right one,
3269     * as the error could fall under the umbrella of other exceptions.
3270     * http://b/18987633
3271     */
3272    public void testCipher_init_DoesNotSupportKeyClass_throwsInvalidKeyException()
3273            throws Exception {
3274        Provider mockProvider = new MockProvider("MockProvider") {
3275            public void setup() {
3276                put("Cipher.FOO", MockCipherSpi.AllKeyTypes.class.getName());
3277                put("Cipher.FOO SupportedKeyClasses", "none");
3278            }
3279        };
3280
3281        Security.addProvider(mockProvider);
3282        try {
3283            Cipher c = Cipher.getInstance("FOO");
3284            c.init(Cipher.DECRYPT_MODE, new MockKey());
3285            fail("Expected InvalidKeyException");
3286        } catch (InvalidKeyException expected) {
3287        } finally {
3288            Security.removeProvider(mockProvider.getName());
3289        }
3290    }
3291}
3292