1package org.bouncycastle.jcajce.provider.symmetric;
2
3// BEGIN android-removed
4// import java.security.AlgorithmParameters;
5// import java.security.InvalidAlgorithmParameterException;
6// END android-removed
7import java.security.SecureRandom;
8// BEGIN android-removed
9// import java.security.spec.AlgorithmParameterSpec;
10// END android-removed
11import java.security.spec.InvalidKeySpecException;
12import java.security.spec.KeySpec;
13
14import javax.crypto.SecretKey;
15import javax.crypto.spec.DESedeKeySpec;
16// BEGIN android-removed
17// import javax.crypto.spec.IvParameterSpec;
18// END android-removed
19import javax.crypto.spec.SecretKeySpec;
20
21import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
22import org.bouncycastle.crypto.KeyGenerationParameters;
23import org.bouncycastle.crypto.engines.DESedeEngine;
24import org.bouncycastle.crypto.engines.DESedeWrapEngine;
25// BEGIN android-removed
26// import org.bouncycastle.crypto.engines.RFC3211WrapEngine;
27// END android-removed
28import org.bouncycastle.crypto.generators.DESedeKeyGenerator;
29import org.bouncycastle.crypto.macs.CBCBlockCipherMac;
30// BEGIN android-removed
31// import org.bouncycastle.crypto.macs.CFBBlockCipherMac;
32// import org.bouncycastle.crypto.macs.CMac;
33// END android-removed
34import org.bouncycastle.crypto.modes.CBCBlockCipher;
35import org.bouncycastle.crypto.paddings.ISO7816d4Padding;
36import org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
37// BEGIN android-removed
38// import org.bouncycastle.jcajce.provider.symmetric.util.BaseAlgorithmParameterGenerator;
39// END android-removed
40import org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher;
41import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator;
42import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac;
43import org.bouncycastle.jcajce.provider.symmetric.util.BaseSecretKeyFactory;
44import org.bouncycastle.jcajce.provider.symmetric.util.BaseWrapCipher;
45import org.bouncycastle.jcajce.provider.util.AlgorithmProvider;
46import org.bouncycastle.jce.provider.BouncyCastleProvider;
47
48public final class DESede
49{
50    private DESede()
51    {
52    }
53
54    static public class ECB
55        extends BaseBlockCipher
56    {
57        public ECB()
58        {
59            super(new DESedeEngine());
60        }
61    }
62
63    static public class CBC
64        extends BaseBlockCipher
65    {
66        public CBC()
67        {
68            super(new CBCBlockCipher(new DESedeEngine()), 64);
69        }
70    }
71
72    // BEGIN android-removed
73    // /**
74    //  * DESede   CFB8
75    //  */
76    // public static class DESedeCFB8
77    //     extends BaseMac
78    // {
79    //     public DESedeCFB8()
80    //     {
81    //         super(new CFBBlockCipherMac(new DESedeEngine()));
82    //     }
83    // }
84    // END android-removed
85
86    /**
87     * DESede64
88     */
89    public static class DESede64
90        extends BaseMac
91    {
92        public DESede64()
93        {
94            super(new CBCBlockCipherMac(new DESedeEngine(), 64));
95        }
96    }
97
98    /**
99     * DESede64with7816-4Padding
100     */
101    public static class DESede64with7816d4
102        extends BaseMac
103    {
104        public DESede64with7816d4()
105        {
106            super(new CBCBlockCipherMac(new DESedeEngine(), 64, new ISO7816d4Padding()));
107        }
108    }
109
110    public static class CBCMAC
111        extends BaseMac
112    {
113        public CBCMAC()
114        {
115            super(new CBCBlockCipherMac(new DESedeEngine()));
116        }
117    }
118
119    // BEGIN android-removed
120    // static public class CMAC
121    //     extends BaseMac
122    // {
123    //     public CMAC()
124    //     {
125    //         super(new CMac(new DESedeEngine()));
126    //     }
127    // }
128    // END android-removed
129
130    public static class Wrap
131        extends BaseWrapCipher
132    {
133        public Wrap()
134        {
135            super(new DESedeWrapEngine());
136        }
137    }
138
139    // BEGIN android-removed
140    // public static class RFC3211
141    //     extends BaseWrapCipher
142    // {
143    //     public RFC3211()
144    //     {
145    //         super(new RFC3211WrapEngine(new DESedeEngine()), 8);
146    //     }
147    // }
148    // END android-removed
149
150  /**
151     * DESede - the default for this is to generate a key in
152     * a-b-a format that's 24 bytes long but has 16 bytes of
153     * key material (the first 8 bytes is repeated as the last
154     * 8 bytes). If you give it a size, you'll get just what you
155     * asked for.
156     */
157    public static class KeyGenerator
158        extends BaseKeyGenerator
159    {
160        private boolean     keySizeSet = false;
161
162        public KeyGenerator()
163        {
164            super("DESede", 192, new DESedeKeyGenerator());
165        }
166
167        protected void engineInit(
168            int             keySize,
169            SecureRandom random)
170        {
171            super.engineInit(keySize, random);
172            keySizeSet = true;
173        }
174
175        protected SecretKey engineGenerateKey()
176        {
177            if (uninitialised)
178            {
179                engine.init(new KeyGenerationParameters(new SecureRandom(), defaultKeySize));
180                uninitialised = false;
181            }
182
183            //
184            // if no key size has been defined generate a 24 byte key in
185            // the a-b-a format
186            //
187            if (!keySizeSet)
188            {
189                byte[]     k = engine.generateKey();
190
191                System.arraycopy(k, 0, k, 16, 8);
192
193                return new SecretKeySpec(k, algName);
194            }
195            else
196            {
197                return new SecretKeySpec(engine.generateKey(), algName);
198            }
199        }
200    }
201
202    /**
203     * generate a desEDE key in the a-b-c format.
204     */
205    public static class KeyGenerator3
206        extends BaseKeyGenerator
207    {
208        public KeyGenerator3()
209        {
210            super("DESede3", 192, new DESedeKeyGenerator());
211        }
212    }
213
214    /**
215     * PBEWithSHAAnd3-KeyTripleDES-CBC
216     */
217    static public class PBEWithSHAAndDES3Key
218        extends BaseBlockCipher
219    {
220        public PBEWithSHAAndDES3Key()
221        {
222            super(new CBCBlockCipher(new DESedeEngine()));
223        }
224    }
225
226    /**
227     * PBEWithSHAAnd2-KeyTripleDES-CBC
228     */
229    static public class PBEWithSHAAndDES2Key
230        extends BaseBlockCipher
231    {
232        public PBEWithSHAAndDES2Key()
233        {
234            super(new CBCBlockCipher(new DESedeEngine()));
235        }
236    }
237
238    // BEGIN android-removed
239    // public static class AlgParamGen
240    //     extends BaseAlgorithmParameterGenerator
241    // {
242    //     protected void engineInit(
243    //         AlgorithmParameterSpec genParamSpec,
244    //         SecureRandom            random)
245    //         throws InvalidAlgorithmParameterException
246    //     {
247    //         throw new InvalidAlgorithmParameterException("No supported AlgorithmParameterSpec for DES parameter generation.");
248    //     }
249    //
250    //     protected AlgorithmParameters engineGenerateParameters()
251    //     {
252    //         byte[]  iv = new byte[8];
253    //
254    //         if (random == null)
255    //         {
256    //             random = new SecureRandom();
257    //         }
258    //
259    //         random.nextBytes(iv);
260    //
261    //         AlgorithmParameters params;
262    //
263    //         try
264    //         {
265    //             params = AlgorithmParameters.getInstance("DES", BouncyCastleProvider.PROVIDER_NAME);
266    //             params.init(new IvParameterSpec(iv));
267    //         }
268    //         catch (Exception e)
269    //         {
270    //             throw new RuntimeException(e.getMessage());
271    //         }
272    //
273    //         return params;
274    //     }
275    // }
276    // END android-removed
277
278    static public class KeyFactory
279        extends BaseSecretKeyFactory
280    {
281        public KeyFactory()
282        {
283            super("DESede", null);
284        }
285
286        protected KeySpec engineGetKeySpec(
287            SecretKey key,
288            Class keySpec)
289        throws InvalidKeySpecException
290        {
291            if (keySpec == null)
292            {
293                throw new InvalidKeySpecException("keySpec parameter is null");
294            }
295            if (key == null)
296            {
297                throw new InvalidKeySpecException("key parameter is null");
298            }
299
300            if (SecretKeySpec.class.isAssignableFrom(keySpec))
301            {
302                return new SecretKeySpec(key.getEncoded(), algName);
303            }
304            else if (DESedeKeySpec.class.isAssignableFrom(keySpec))
305            {
306                byte[]  bytes = key.getEncoded();
307
308                try
309                {
310                    if (bytes.length == 16)
311                    {
312                        byte[]  longKey = new byte[24];
313
314                        System.arraycopy(bytes, 0, longKey, 0, 16);
315                        System.arraycopy(bytes, 0, longKey, 16, 8);
316
317                        return new DESedeKeySpec(longKey);
318                    }
319                    else
320                    {
321                        return new DESedeKeySpec(bytes);
322                    }
323                }
324                catch (Exception e)
325                {
326                    throw new InvalidKeySpecException(e.toString());
327                }
328            }
329
330            throw new InvalidKeySpecException("Invalid KeySpec");
331        }
332
333        protected SecretKey engineGenerateSecret(
334            KeySpec keySpec)
335        throws InvalidKeySpecException
336        {
337            if (keySpec instanceof DESedeKeySpec)
338            {
339                DESedeKeySpec desKeySpec = (DESedeKeySpec)keySpec;
340                return new SecretKeySpec(desKeySpec.getKey(), "DESede");
341            }
342
343            return super.engineGenerateSecret(keySpec);
344        }
345    }
346
347    public static class Mappings
348        extends AlgorithmProvider
349    {
350        private static final String PREFIX = DESede.class.getName();
351        private static final String PACKAGE = "org.bouncycastle.jcajce.provider.symmetric"; // JDK 1.2
352
353        public Mappings()
354        {
355        }
356
357        public void configure(ConfigurableProvider provider)
358        {
359            provider.addAlgorithm("Cipher.DESEDE", PREFIX + "$ECB");
360            // BEGIN android-removed
361            // provider.addAlgorithm("Cipher." + PKCSObjectIdentifiers.des_EDE3_CBC, PREFIX + "$CBC");
362            // END android-removed
363            provider.addAlgorithm("Cipher.DESEDEWRAP", PREFIX + "$Wrap");
364            // BEGIN android-changed
365            provider.addAlgorithm("Alg.Alias.Cipher." + PKCSObjectIdentifiers.id_alg_CMS3DESwrap, "DESEDEWRAP");
366            // END android-changed
367            // BEGIN android-removed
368            // provider.addAlgorithm("Cipher.DESEDERFC3211WRAP", PREFIX + "$RFC3211");
369            // END android-removed
370
371            if (provider.hasAlgorithm("MessageDigest", "SHA-1"))
372            {
373                provider.addAlgorithm("Cipher.PBEWITHSHAAND3-KEYTRIPLEDES-CBC", PREFIX + "$PBEWithSHAAndDES3Key");
374                // BEGIN android-removed
375                // provider.addAlgorithm("Cipher.BROKENPBEWITHSHAAND3-KEYTRIPLEDES-CBC", PREFIX + "$BrokePBEWithSHAAndDES3Key");
376                // provider.addAlgorithm("Cipher.OLDPBEWITHSHAAND3-KEYTRIPLEDES-CBC", PREFIX + "$OldPBEWithSHAAndDES3Key");
377                // END android-removed
378                provider.addAlgorithm("Cipher.PBEWITHSHAAND2-KEYTRIPLEDES-CBC", PREFIX + "$PBEWithSHAAndDES2Key");
379                // BEGIN android-removed
380                // provider.addAlgorithm("Cipher.BROKENPBEWITHSHAAND2-KEYTRIPLEDES-CBC", PREFIX + "$BrokePBEWithSHAAndDES2Key");
381                // END android-removed
382                provider.addAlgorithm("Alg.Alias.Cipher." + PKCSObjectIdentifiers.pbeWithSHAAnd3_KeyTripleDES_CBC, "PBEWITHSHAAND3-KEYTRIPLEDES-CBC");
383                provider.addAlgorithm("Alg.Alias.Cipher." + PKCSObjectIdentifiers.pbeWithSHAAnd2_KeyTripleDES_CBC, "PBEWITHSHAAND2-KEYTRIPLEDES-CBC");
384                provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1ANDDESEDE", "PBEWITHSHAAND3-KEYTRIPLEDES-CBC");
385                provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND3-KEYTRIPLEDES-CBC", "PBEWITHSHAAND3-KEYTRIPLEDES-CBC");
386                provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND2-KEYTRIPLEDES-CBC", "PBEWITHSHAAND2-KEYTRIPLEDES-CBC");
387            }
388
389            provider.addAlgorithm("KeyGenerator.DESEDE", PREFIX + "$KeyGenerator");
390            // BEGIN android-removed
391            // provider.addAlgorithm("KeyGenerator." + PKCSObjectIdentifiers.des_EDE3_CBC, PREFIX + "$KeyGenerator3");
392            // provider.addAlgorithm("KeyGenerator.DESEDEWRAP", PREFIX + "$KeyGenerator");
393            // END android-removed
394
395            provider.addAlgorithm("SecretKeyFactory.DESEDE", PREFIX + "$KeyFactory");
396
397            // BEGIN android-removed
398            // provider.addAlgorithm("Mac.DESEDECMAC", PREFIX + "$CMAC");
399            // provider.addAlgorithm("Mac.DESEDEMAC", PREFIX + "$CBCMAC");
400            // provider.addAlgorithm("Alg.Alias.Mac.DESEDE", "DESEDEMAC");
401            //
402            // provider.addAlgorithm("Mac.DESEDEMAC/CFB8", PREFIX + "$DESedeCFB8");
403            // provider.addAlgorithm("Alg.Alias.Mac.DESEDE/CFB8", "DESEDEMAC/CFB8");
404            //
405            // provider.addAlgorithm("Mac.DESEDEMAC64", PREFIX + "$DESede64");
406            // provider.addAlgorithm("Alg.Alias.Mac.DESEDE64", "DESEDEMAC64");
407            //
408            // provider.addAlgorithm("Mac.DESEDEMAC64WITHISO7816-4PADDING", PREFIX + "$DESede64with7816d4");
409            // provider.addAlgorithm("Alg.Alias.Mac.DESEDE64WITHISO7816-4PADDING", "DESEDEMAC64WITHISO7816-4PADDING");
410            // provider.addAlgorithm("Alg.Alias.Mac.DESEDEISO9797ALG1MACWITHISO7816-4PADDING", "DESEDEMAC64WITHISO7816-4PADDING");
411            // provider.addAlgorithm("Alg.Alias.Mac.DESEDEISO9797ALG1WITHISO7816-4PADDING", "DESEDEMAC64WITHISO7816-4PADDING");
412            // END android-removed
413
414            provider.addAlgorithm("AlgorithmParameters.DESEDE", PACKAGE + ".util.IvAlgorithmParameters");
415            provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + PKCSObjectIdentifiers.des_EDE3_CBC, "DESEDE");
416
417            // BEGIN android-removed
418            // provider.addAlgorithm("AlgorithmParameterGenerator.DESEDE",  PREFIX + "$AlgParamGen");
419            // provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator." + PKCSObjectIdentifiers.des_EDE3_CBC, "DESEDE");
420            // END android-removed
421        }
422    }
423}
424