1package org.bouncycastle.jce.provider;
2
3import java.security.AlgorithmParameters;
4import java.security.InvalidAlgorithmParameterException;
5import java.security.InvalidKeyException;
6import java.security.InvalidParameterException;
7import java.security.Key;
8import java.security.NoSuchAlgorithmException;
9import java.security.SecureRandom;
10import java.security.spec.AlgorithmParameterSpec;
11
12import javax.crypto.BadPaddingException;
13import javax.crypto.Cipher;
14import javax.crypto.IllegalBlockSizeException;
15import javax.crypto.NoSuchPaddingException;
16import javax.crypto.SecretKey;
17import javax.crypto.ShortBufferException;
18import javax.crypto.spec.IvParameterSpec;
19import javax.crypto.spec.PBEParameterSpec;
20import javax.crypto.spec.RC2ParameterSpec;
21import javax.crypto.spec.RC5ParameterSpec;
22
23import org.bouncycastle.crypto.BlockCipher;
24import org.bouncycastle.crypto.BufferedBlockCipher;
25import org.bouncycastle.crypto.CipherParameters;
26import org.bouncycastle.crypto.DataLengthException;
27import org.bouncycastle.crypto.InvalidCipherTextException;
28import org.bouncycastle.crypto.engines.*;
29import org.bouncycastle.crypto.modes.CBCBlockCipher;
30import org.bouncycastle.crypto.modes.CFBBlockCipher;
31import org.bouncycastle.crypto.modes.CTSBlockCipher;
32import org.bouncycastle.crypto.modes.GOFBBlockCipher;
33import org.bouncycastle.crypto.modes.OFBBlockCipher;
34// BEGIN android-removed
35// import org.bouncycastle.crypto.modes.OpenPGPCFBBlockCipher;
36// import org.bouncycastle.crypto.modes.PGPCFBBlockCipher;
37// END android-removed
38import org.bouncycastle.crypto.modes.SICBlockCipher;
39import org.bouncycastle.crypto.paddings.ISO10126d2Padding;
40import org.bouncycastle.crypto.paddings.ISO7816d4Padding;
41import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher;
42import org.bouncycastle.crypto.paddings.TBCPadding;
43import org.bouncycastle.crypto.paddings.X923Padding;
44import org.bouncycastle.crypto.paddings.ZeroBytePadding;
45import org.bouncycastle.crypto.params.KeyParameter;
46import org.bouncycastle.crypto.params.ParametersWithIV;
47import org.bouncycastle.crypto.params.ParametersWithRandom;
48import org.bouncycastle.crypto.params.ParametersWithSBox;
49import org.bouncycastle.crypto.params.RC2Parameters;
50import org.bouncycastle.crypto.params.RC5Parameters;
51// BEGIN android-removed
52// import org.bouncycastle.jce.spec.GOST28147ParameterSpec;
53// END android-removed
54import org.bouncycastle.util.Strings;
55
56public class JCEBlockCipher extends WrapCipherSpi
57    implements PBE
58{
59    //
60    // specs we can handle.
61    //
62    private Class[]                 availableSpecs =
63                                    {
64                                        RC2ParameterSpec.class,
65                                        RC5ParameterSpec.class,
66                                        IvParameterSpec.class,
67                                        PBEParameterSpec.class,
68                                        //GOST28147ParameterSpec.class
69                                    };
70
71    private BlockCipher             baseEngine;
72    private BufferedBlockCipher     cipher;
73    private ParametersWithIV        ivParam;
74
75    private int                     ivLength = 0;
76
77    private boolean                 padded = true;
78
79    private PBEParameterSpec        pbeSpec = null;
80    private String                  pbeAlgorithm = null;
81
82    private String                  modeName = null;
83
84    protected JCEBlockCipher(
85        BlockCipher engine)
86    {
87        baseEngine = engine;
88
89        cipher = new PaddedBufferedBlockCipher(engine);
90    }
91
92    protected JCEBlockCipher(
93        BlockCipher engine,
94        int         ivLength)
95    {
96        baseEngine = engine;
97
98        this.cipher = new PaddedBufferedBlockCipher(engine);
99        this.ivLength = ivLength / 8;
100    }
101
102    protected int engineGetBlockSize()
103    {
104        return baseEngine.getBlockSize();
105    }
106
107    protected byte[] engineGetIV()
108    {
109        return (ivParam != null) ? ivParam.getIV() : null;
110    }
111
112    protected int engineGetKeySize(
113        Key     key)
114    {
115        return key.getEncoded().length * 8;
116    }
117
118    protected int engineGetOutputSize(
119        int     inputLen)
120    {
121        return cipher.getOutputSize(inputLen);
122    }
123
124    protected AlgorithmParameters engineGetParameters()
125    {
126        if (engineParams == null)
127        {
128            if (pbeSpec != null)
129            {
130                try
131                {
132                    engineParams = AlgorithmParameters.getInstance(pbeAlgorithm, "BC");
133                    engineParams.init(pbeSpec);
134                }
135                catch (Exception e)
136                {
137                    return null;
138                }
139            }
140            else if (ivParam != null)
141            {
142                String  name = cipher.getUnderlyingCipher().getAlgorithmName();
143
144                if (name.indexOf('/') >= 0)
145                {
146                    name = name.substring(0, name.indexOf('/'));
147                }
148
149                try
150                {
151                    engineParams = AlgorithmParameters.getInstance(name, "BC");
152                    engineParams.init(ivParam.getIV());
153                }
154                catch (Exception e)
155                {
156                    throw new RuntimeException(e.toString());
157                }
158            }
159        }
160
161        return engineParams;
162    }
163
164    protected void engineSetMode(
165        String  mode)
166        throws NoSuchAlgorithmException
167    {
168        modeName = Strings.toUpperCase(mode);
169
170        if (modeName.equals("ECB"))
171        {
172            ivLength = 0;
173            cipher = new PaddedBufferedBlockCipher(baseEngine);
174        }
175        else if (modeName.equals("CBC"))
176        {
177            ivLength = baseEngine.getBlockSize();
178            cipher = new PaddedBufferedBlockCipher(
179                            new CBCBlockCipher(baseEngine));
180        }
181        else if (modeName.startsWith("OFB"))
182        {
183            ivLength = baseEngine.getBlockSize();
184            if (modeName.length() != 3)
185            {
186                int wordSize = Integer.parseInt(modeName.substring(3));
187
188                cipher = new PaddedBufferedBlockCipher(
189                                new OFBBlockCipher(baseEngine, wordSize));
190            }
191            else
192            {
193                cipher = new PaddedBufferedBlockCipher(
194                        new OFBBlockCipher(baseEngine, 8 * baseEngine.getBlockSize()));
195            }
196        }
197        else if (modeName.startsWith("CFB"))
198        {
199            ivLength = baseEngine.getBlockSize();
200            if (modeName.length() != 3)
201            {
202                int wordSize = Integer.parseInt(modeName.substring(3));
203
204                cipher = new PaddedBufferedBlockCipher(
205                                new CFBBlockCipher(baseEngine, wordSize));
206            }
207            else
208            {
209                cipher = new PaddedBufferedBlockCipher(
210                        new CFBBlockCipher(baseEngine, 8 * baseEngine.getBlockSize()));
211            }
212        }
213        // BEGIN android-removed
214        // else if (modeName.startsWith("PGP"))
215        // {
216        //     if (modeName.equalsIgnoreCase("PGPCFBwithIV"))
217        //     {
218        //         ivLength = baseEngine.getBlockSize();
219        //         cipher = new PaddedBufferedBlockCipher(
220        //             new PGPCFBBlockCipher(baseEngine, true));
221        //     }
222        //     else
223        //     {
224        //         ivLength = baseEngine.getBlockSize();
225        //         cipher = new PaddedBufferedBlockCipher(
226        //             new PGPCFBBlockCipher(baseEngine, false));
227        //     }
228        // }
229        // else if (modeName.equalsIgnoreCase("OpenPGPCFB"))
230        // {
231        //     ivLength = 0;
232        //     cipher = new PaddedBufferedBlockCipher(
233        //         new OpenPGPCFBBlockCipher(baseEngine));
234        // }
235        // END android-removed
236        else if (modeName.startsWith("SIC"))
237        {
238            ivLength = baseEngine.getBlockSize();
239            if (ivLength < 16)
240            {
241                throw new IllegalArgumentException("Warning: SIC-Mode can become a twotime-pad if the blocksize of the cipher is too small. Use a cipher with a block size of at least 128 bits (e.g. AES)");
242            }
243            cipher = new BufferedBlockCipher(
244                        new SICBlockCipher(baseEngine));
245        }
246        else if (modeName.startsWith("CTR"))
247        {
248            ivLength = baseEngine.getBlockSize();
249            cipher = new BufferedBlockCipher(
250                        new SICBlockCipher(baseEngine));
251        }
252        else if (modeName.startsWith("GOFB"))
253        {
254            ivLength = baseEngine.getBlockSize();
255            cipher = new BufferedBlockCipher(
256                        new GOFBBlockCipher(baseEngine));
257        }
258        else if (modeName.startsWith("CTS"))
259        {
260            ivLength = baseEngine.getBlockSize();
261            cipher = new CTSBlockCipher(new CBCBlockCipher(baseEngine));
262        }
263        else
264        {
265            throw new NoSuchAlgorithmException("can't support mode " + mode);
266        }
267    }
268
269    protected void engineSetPadding(
270        String  padding)
271    throws NoSuchPaddingException
272    {
273        String  paddingName = Strings.toUpperCase(padding);
274
275        if (paddingName.equals("NOPADDING"))
276        {
277            padded = false;
278
279            if (!(cipher instanceof CTSBlockCipher))
280            {
281                cipher = new BufferedBlockCipher(cipher.getUnderlyingCipher());
282            }
283        }
284        else if (paddingName.equals("PKCS5PADDING") || paddingName.equals("PKCS7PADDING"))
285        {
286            cipher = new PaddedBufferedBlockCipher(cipher.getUnderlyingCipher());
287        }
288        else if (paddingName.equals("ZEROBYTEPADDING"))
289        {
290            cipher = new PaddedBufferedBlockCipher(cipher.getUnderlyingCipher(), new ZeroBytePadding());
291        }
292        else if (paddingName.equals("ISO10126PADDING") || paddingName.equals("ISO10126-2PADDING"))
293        {
294            cipher = new PaddedBufferedBlockCipher(cipher.getUnderlyingCipher(), new ISO10126d2Padding());
295        }
296        else if (paddingName.equals("X9.23PADDING") || paddingName.equals("X923PADDING"))
297        {
298            cipher = new PaddedBufferedBlockCipher(cipher.getUnderlyingCipher(), new X923Padding());
299        }
300        else if (paddingName.equals("ISO7816-4PADDING") || paddingName.equals("ISO9797-1PADDING"))
301        {
302            cipher = new PaddedBufferedBlockCipher(cipher.getUnderlyingCipher(), new ISO7816d4Padding());
303        }
304        else if (paddingName.equals("TBCPADDING"))
305        {
306            cipher = new PaddedBufferedBlockCipher(cipher.getUnderlyingCipher(), new TBCPadding());
307        }
308        else if (paddingName.equals("WITHCTS"))
309        {
310            padded = false;
311            cipher = new CTSBlockCipher(cipher.getUnderlyingCipher());
312        }
313        else
314        {
315            throw new NoSuchPaddingException("Padding " + padding + " unknown.");
316        }
317    }
318
319    protected void engineInit(
320        int                     opmode,
321        Key                     key,
322        AlgorithmParameterSpec  params,
323        SecureRandom            random)
324        throws InvalidKeyException, InvalidAlgorithmParameterException
325    {
326        CipherParameters        param;
327
328        this.pbeSpec = null;
329        this.pbeAlgorithm = null;
330        this.engineParams = null;
331
332        //
333        // basic key check
334        //
335        if (!(key instanceof SecretKey))
336        {
337            throw new InvalidKeyException("Key for algorithm " + key.getAlgorithm() + " not suitable for symmetric enryption.");
338        }
339
340        //
341        // for RC5-64 we must have some default parameters
342        //
343        if (params == null && baseEngine.getAlgorithmName().startsWith("RC5-64"))
344        {
345            throw new InvalidAlgorithmParameterException("RC5 requires an RC5ParametersSpec to be passed in.");
346        }
347
348        //
349        // a note on iv's - if ivLength is zero the IV gets ignored (we don't use it).
350        //
351        if (key instanceof JCEPBEKey)
352        {
353            JCEPBEKey   k = (JCEPBEKey)key;
354
355            if (k.getOID() != null)
356            {
357                pbeAlgorithm = k.getOID().getId();
358            }
359            else
360            {
361                pbeAlgorithm = k.getAlgorithm();
362            }
363
364            if (k.getParam() != null)
365            {
366                param = k.getParam();
367                pbeSpec = new PBEParameterSpec(k.getSalt(), k.getIterationCount());
368            }
369            else if (params instanceof PBEParameterSpec)
370            {
371                pbeSpec = (PBEParameterSpec)params;
372                param = PBE.Util.makePBEParameters(k, params, cipher.getUnderlyingCipher().getAlgorithmName());
373            }
374            else
375            {
376                throw new InvalidAlgorithmParameterException("PBE requires PBE parameters to be set.");
377            }
378
379            if (param instanceof ParametersWithIV)
380            {
381                ivParam = (ParametersWithIV)param;
382            }
383        }
384        else if (params == null)
385        {
386            param = new KeyParameter(key.getEncoded());
387        }
388        else if (params instanceof IvParameterSpec)
389        {
390            if (ivLength != 0)
391            {
392                IvParameterSpec p = (IvParameterSpec)params;
393
394                if (p.getIV().length != ivLength)
395                {
396                    throw new InvalidAlgorithmParameterException("IV must be " + ivLength + " bytes long.");
397                }
398
399                param = new ParametersWithIV(new KeyParameter(key.getEncoded()), p.getIV());
400                ivParam = (ParametersWithIV)param;
401            }
402            else
403            {
404                if (modeName != null && modeName.equals("ECB"))
405                {
406                    throw new InvalidAlgorithmParameterException("ECB mode does not use an IV");
407                }
408
409                param = new KeyParameter(key.getEncoded());
410            }
411        }
412        // BEGIN android-removed
413        // else if (params instanceof GOST28147ParameterSpec)
414        // {
415        //     GOST28147ParameterSpec    gost28147Param = (GOST28147ParameterSpec)params;
416        //
417        //     param = new ParametersWithSBox(
418        //                new KeyParameter(key.getEncoded()), ((GOST28147ParameterSpec)params).getSbox());
419        //
420        //     if (gost28147Param.getIV() != null && ivLength != 0)
421        //     {
422        //         param = new ParametersWithIV(param, gost28147Param.getIV());
423        //         ivParam = (ParametersWithIV)param;
424        //     }
425        // }
426        // END android-removed
427        else if (params instanceof RC2ParameterSpec)
428        {
429            RC2ParameterSpec    rc2Param = (RC2ParameterSpec)params;
430
431            param = new RC2Parameters(key.getEncoded(), ((RC2ParameterSpec)params).getEffectiveKeyBits());
432
433            if (rc2Param.getIV() != null && ivLength != 0)
434            {
435                param = new ParametersWithIV(param, rc2Param.getIV());
436                ivParam = (ParametersWithIV)param;
437            }
438        }
439        else if (params instanceof RC5ParameterSpec)
440        {
441            RC5ParameterSpec    rc5Param = (RC5ParameterSpec)params;
442
443            param = new RC5Parameters(key.getEncoded(), ((RC5ParameterSpec)params).getRounds());
444            if (baseEngine.getAlgorithmName().startsWith("RC5"))
445            {
446                if (baseEngine.getAlgorithmName().equals("RC5-32"))
447                {
448                    if (rc5Param.getWordSize() != 32)
449                    {
450                        throw new InvalidAlgorithmParameterException("RC5 already set up for a word size of 32 not " + rc5Param.getWordSize() + ".");
451                    }
452                }
453                else if (baseEngine.getAlgorithmName().equals("RC5-64"))
454                {
455                    if (rc5Param.getWordSize() != 64)
456                    {
457                        throw new InvalidAlgorithmParameterException("RC5 already set up for a word size of 64 not " + rc5Param.getWordSize() + ".");
458                    }
459                }
460            }
461            else
462            {
463                throw new InvalidAlgorithmParameterException("RC5 parameters passed to a cipher that is not RC5.");
464            }
465            if ((rc5Param.getIV() != null) && (ivLength != 0))
466            {
467                param = new ParametersWithIV(param, rc5Param.getIV());
468                ivParam = (ParametersWithIV)param;
469            }
470        }
471        else
472        {
473            throw new InvalidAlgorithmParameterException("unknown parameter type.");
474        }
475
476        if ((ivLength != 0) && !(param instanceof ParametersWithIV))
477        {
478            SecureRandom    ivRandom = random;
479
480            if (ivRandom == null)
481            {
482                ivRandom = new SecureRandom();
483            }
484
485            if ((opmode == Cipher.ENCRYPT_MODE) || (opmode == Cipher.WRAP_MODE))
486            {
487                byte[]  iv = new byte[ivLength];
488
489                ivRandom.nextBytes(iv);
490                param = new ParametersWithIV(param, iv);
491                ivParam = (ParametersWithIV)param;
492            }
493            else if (cipher.getUnderlyingCipher().getAlgorithmName().indexOf("PGPCFB") < 0)
494            {
495                throw new InvalidAlgorithmParameterException("no IV set when one expected");
496            }
497        }
498
499        if (random != null && padded)
500        {
501            param = new ParametersWithRandom(param, random);
502        }
503
504        try
505        {
506            switch (opmode)
507            {
508            case Cipher.ENCRYPT_MODE:
509            case Cipher.WRAP_MODE:
510                cipher.init(true, param);
511                break;
512            case Cipher.DECRYPT_MODE:
513            case Cipher.UNWRAP_MODE:
514                cipher.init(false, param);
515                break;
516            default:
517                throw new InvalidParameterException("unknown opmode " + opmode + " passed");
518            }
519        }
520        catch (Exception e)
521        {
522            throw new InvalidKeyException(e.getMessage());
523        }
524    }
525
526    protected void engineInit(
527        int                 opmode,
528        Key                 key,
529        AlgorithmParameters params,
530        SecureRandom        random)
531    throws InvalidKeyException, InvalidAlgorithmParameterException
532    {
533        AlgorithmParameterSpec  paramSpec = null;
534
535        if (params != null)
536        {
537            for (int i = 0; i != availableSpecs.length; i++)
538            {
539                try
540                {
541                    paramSpec = params.getParameterSpec(availableSpecs[i]);
542                    break;
543                }
544                catch (Exception e)
545                {
546                    continue;
547                }
548            }
549
550            if (paramSpec == null)
551            {
552                throw new InvalidAlgorithmParameterException("can't handle parameter " + params.toString());
553            }
554        }
555
556        engineInit(opmode, key, paramSpec, random);
557
558        engineParams = params;
559    }
560
561    protected void engineInit(
562        int                 opmode,
563        Key                 key,
564        SecureRandom        random)
565        throws InvalidKeyException
566    {
567        try
568        {
569            engineInit(opmode, key, (AlgorithmParameterSpec)null, random);
570        }
571        catch (InvalidAlgorithmParameterException e)
572        {
573            throw new InvalidKeyException(e.getMessage());
574        }
575    }
576
577    protected byte[] engineUpdate(
578        byte[]  input,
579        int     inputOffset,
580        int     inputLen)
581    {
582        int     length = cipher.getUpdateOutputSize(inputLen);
583
584        if (length > 0)
585        {
586                byte[]  out = new byte[length];
587
588                int len = cipher.processBytes(input, inputOffset, inputLen, out, 0);
589
590                if (len == 0)
591                {
592                    return null;
593                }
594                else if (len != out.length)
595                {
596                    byte[]  tmp = new byte[len];
597
598                    System.arraycopy(out, 0, tmp, 0, len);
599
600                    return tmp;
601                }
602
603                return out;
604        }
605
606        cipher.processBytes(input, inputOffset, inputLen, null, 0);
607
608        return null;
609    }
610
611    protected int engineUpdate(
612        byte[]  input,
613        int     inputOffset,
614        int     inputLen,
615        byte[]  output,
616        int     outputOffset)
617        throws ShortBufferException
618    {
619        try
620        {
621            return cipher.processBytes(input, inputOffset, inputLen, output, outputOffset);
622        }
623        catch (DataLengthException e)
624        {
625            throw new ShortBufferException(e.getMessage());
626        }
627    }
628
629    protected byte[] engineDoFinal(
630        byte[]  input,
631        int     inputOffset,
632        int     inputLen)
633        throws IllegalBlockSizeException, BadPaddingException
634    {
635        int     len = 0;
636        byte[]  tmp = new byte[engineGetOutputSize(inputLen)];
637
638        if (inputLen != 0)
639        {
640            len = cipher.processBytes(input, inputOffset, inputLen, tmp, 0);
641        }
642
643        try
644        {
645            len += cipher.doFinal(tmp, len);
646        }
647        catch (DataLengthException e)
648        {
649            throw new IllegalBlockSizeException(e.getMessage());
650        }
651        catch (InvalidCipherTextException e)
652        {
653            throw new BadPaddingException(e.getMessage());
654        }
655
656        byte[]  out = new byte[len];
657
658        System.arraycopy(tmp, 0, out, 0, len);
659
660        return out;
661    }
662
663    protected int engineDoFinal(
664        byte[]  input,
665        int     inputOffset,
666        int     inputLen,
667        byte[]  output,
668        int     outputOffset)
669        throws IllegalBlockSizeException, BadPaddingException, ShortBufferException
670    {
671        // BEGIN android-note
672        // added ShortBufferException to the throws statement
673        // END android-note
674        int     len = 0;
675
676        // BEGIN android-added
677        int outputLen = cipher.getOutputSize(inputLen);
678
679        if (outputLen + outputOffset > output.length) {
680            throw new ShortBufferException("need at least " + outputLen + " bytes");
681        }
682        // BEGIN android-added
683
684        if (inputLen != 0)
685        {
686                len = cipher.processBytes(input, inputOffset, inputLen, output, outputOffset);
687        }
688
689        try
690        {
691            return (len + cipher.doFinal(output, outputOffset + len));
692        }
693        catch (DataLengthException e)
694        {
695            throw new IllegalBlockSizeException(e.getMessage());
696        }
697        catch (InvalidCipherTextException e)
698        {
699            throw new BadPaddingException(e.getMessage());
700        }
701    }
702
703    /*
704     * The ciphers that inherit from us.
705     */
706
707    /**
708     * DES
709     */
710    static public class DES
711        extends JCEBlockCipher
712    {
713        public DES()
714        {
715            super(new DESEngine());
716        }
717    }
718
719    /**
720     * DESCBC
721     */
722    static public class DESCBC
723        extends JCEBlockCipher
724    {
725        public DESCBC()
726        {
727            super(new CBCBlockCipher(new DESEngine()), 64);
728        }
729    }
730
731    /**
732     * DESede
733     */
734    static public class DESede
735        extends JCEBlockCipher
736    {
737        public DESede()
738        {
739            super(new DESedeEngine());
740        }
741    }
742
743    /**
744     * DESedeCBC
745     */
746    static public class DESedeCBC
747        extends JCEBlockCipher
748    {
749        public DESedeCBC()
750        {
751            super(new CBCBlockCipher(new DESedeEngine()), 64);
752        }
753    }
754
755    /**
756     *  GOST28147
757     */
758    // BEGIN android-removed
759    // static public class GOST28147
760    //     extends JCEBlockCipher
761    // {
762    //     public GOST28147()
763    //     {
764    //         super(new GOST28147Engine());
765    //     }
766    // }
767    //
768    // static public class GOST28147cbc
769    //     extends JCEBlockCipher
770    // {
771    //     public GOST28147cbc()
772    //     {
773    //         super(new CBCBlockCipher(new GOST28147Engine()), 64);
774    //     }
775    // }
776    // END android-removed
777
778    /**
779     * AES
780     */
781    static public class AES
782        extends JCEBlockCipher
783    {
784        public AES()
785        {
786            super(new AESFastEngine());
787        }
788    }
789
790    /**
791     * AESCBC
792     */
793    static public class AESCBC
794        extends JCEBlockCipher
795    {
796        public AESCBC()
797        {
798            super(new CBCBlockCipher(new AESFastEngine()), 128);
799        }
800    }
801
802    /**
803     * AESCFB
804     */
805    static public class AESCFB
806        extends JCEBlockCipher
807    {
808        public AESCFB()
809        {
810            super(new CFBBlockCipher(new AESFastEngine(), 128), 128);
811        }
812    }
813
814    /**
815     * AESOFB
816     */
817    static public class AESOFB
818        extends JCEBlockCipher
819    {
820        public AESOFB()
821        {
822            super(new OFBBlockCipher(new AESFastEngine(), 128), 128);
823        }
824    }
825
826    /**
827     * Camellia
828     */
829    // BEGIN android-removed
830    // static public class Camellia
831    //     extends JCEBlockCipher
832    // {
833    //     public Camellia()
834    //     {
835    //         super(new CamelliaEngine());
836    //     }
837    // }
838    // END android-removed
839
840    /**
841     * CAST5
842     */
843    // BEGIN android-removed
844    // static public class CAST5
845    //     extends JCEBlockCipher
846    // {
847    //     public CAST5()
848    //     {
849    //         super(new CAST5Engine());
850    //     }
851    // }
852    // END android-removed
853
854    /**
855     * CAST5 CBC
856     */
857    // BEGIN android-removed
858    // static public class CAST5CBC
859    //     extends JCEBlockCipher
860    // {
861    //     public CAST5CBC()
862    //     {
863    //         super(new CBCBlockCipher(new CAST5Engine()), 64);
864    //     }
865    // }
866    // END android-removed
867
868    /**
869     * CAST6
870     */
871    // BEGIN android-removed
872    // static public class CAST6
873    //     extends JCEBlockCipher
874    // {
875    //     public CAST6()
876    //     {
877    //         super(new CAST6Engine());
878    //     }
879    // }
880    // BEGIN android-removed
881
882    /**
883     * PBEWithMD5AndDES
884     */
885    static public class PBEWithMD5AndDES
886        extends JCEBlockCipher
887    {
888        public PBEWithMD5AndDES()
889        {
890            super(new CBCBlockCipher(new DESEngine()));
891        }
892    }
893
894    /**
895     * PBEWithMD5AndRC2
896     */
897    static public class PBEWithMD5AndRC2
898        extends JCEBlockCipher
899    {
900        public PBEWithMD5AndRC2()
901        {
902            super(new CBCBlockCipher(new RC2Engine()));
903        }
904    }
905
906    /**
907     * PBEWithSHA1AndDES
908     */
909    static public class PBEWithSHA1AndDES
910        extends JCEBlockCipher
911    {
912        public PBEWithSHA1AndDES()
913        {
914            super(new CBCBlockCipher(new DESEngine()));
915        }
916    }
917
918    /**
919     * PBEWithSHAAnd3-KeyTripleDES-CBC
920     */
921    static public class PBEWithSHAAndDES3Key
922        extends JCEBlockCipher
923    {
924        public PBEWithSHAAndDES3Key()
925        {
926            super(new CBCBlockCipher(new DESedeEngine()));
927        }
928    }
929
930    /**
931     * PBEWithSHAAnd2-KeyTripleDES-CBC
932     */
933    static public class PBEWithSHAAndDES2Key
934        extends JCEBlockCipher
935    {
936        public PBEWithSHAAndDES2Key()
937        {
938            super(new CBCBlockCipher(new DESedeEngine()));
939        }
940    }
941
942    /**
943     * PBEWithAES-CBC
944     */
945    static public class PBEWithAESCBC
946        extends JCEBlockCipher
947    {
948        public PBEWithAESCBC()
949        {
950            super(new CBCBlockCipher(new AESFastEngine()));
951        }
952    }
953
954    /**
955     * PBEWITHSHAAND40BITRC2-CBC
956     */
957    static public class PBEWithSHAAnd40BitRC2
958        extends JCEBlockCipher
959    {
960        public PBEWithSHAAnd40BitRC2()
961        {
962            super(new CBCBlockCipher(new RC2Engine()));
963        }
964    }
965}
966