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