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