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