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