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