DESede.java revision a198e1ecc615e26a167d0f2dca9fa7e5fc62de10
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    /**
239     * PBEWithSHAAnd3-KeyTripleDES-CBC
240     */
241    static public class PBEWithSHAAndDES3KeyFactory
242        extends DES.DESPBEKeyFactory
243    {
244        public PBEWithSHAAndDES3KeyFactory()
245        {
246            super("PBEwithSHAandDES3Key-CBC", PKCSObjectIdentifiers.pbeWithSHAAnd3_KeyTripleDES_CBC, true, PKCS12, SHA1, 192, 64);
247        }
248    }
249
250    /**
251     * PBEWithSHAAnd2-KeyTripleDES-CBC
252     */
253    static public class PBEWithSHAAndDES2KeyFactory
254        extends DES.DESPBEKeyFactory
255    {
256        public PBEWithSHAAndDES2KeyFactory()
257        {
258            super("PBEwithSHAandDES2Key-CBC", PKCSObjectIdentifiers.pbeWithSHAAnd2_KeyTripleDES_CBC, true, PKCS12, SHA1, 128, 64);
259        }
260    }
261
262    // BEGIN android-removed
263    // public static class AlgParamGen
264    //     extends BaseAlgorithmParameterGenerator
265    // {
266    //     protected void engineInit(
267    //         AlgorithmParameterSpec genParamSpec,
268    //         SecureRandom            random)
269    //         throws InvalidAlgorithmParameterException
270    //     {
271    //         throw new InvalidAlgorithmParameterException("No supported AlgorithmParameterSpec for DES parameter generation.");
272    //     }
273    //
274    //     protected AlgorithmParameters engineGenerateParameters()
275    //     {
276    //         byte[]  iv = new byte[8];
277    //
278    //         if (random == null)
279    //         {
280    //             random = new SecureRandom();
281    //         }
282    //
283    //         random.nextBytes(iv);
284    //
285    //         AlgorithmParameters params;
286    //
287    //         try
288    //         {
289    //             params = AlgorithmParameters.getInstance("DES", BouncyCastleProvider.PROVIDER_NAME);
290    //             params.init(new IvParameterSpec(iv));
291    //         }
292    //         catch (Exception e)
293    //         {
294    //             throw new RuntimeException(e.getMessage());
295    //         }
296    //
297    //         return params;
298    //     }
299    // }
300    // END android-removed
301
302    static public class KeyFactory
303        extends BaseSecretKeyFactory
304    {
305        public KeyFactory()
306        {
307            super("DESede", null);
308        }
309
310        protected KeySpec engineGetKeySpec(
311            SecretKey key,
312            Class keySpec)
313        throws InvalidKeySpecException
314        {
315            if (keySpec == null)
316            {
317                throw new InvalidKeySpecException("keySpec parameter is null");
318            }
319            if (key == null)
320            {
321                throw new InvalidKeySpecException("key parameter is null");
322            }
323
324            if (SecretKeySpec.class.isAssignableFrom(keySpec))
325            {
326                return new SecretKeySpec(key.getEncoded(), algName);
327            }
328            else if (DESedeKeySpec.class.isAssignableFrom(keySpec))
329            {
330                byte[]  bytes = key.getEncoded();
331
332                try
333                {
334                    if (bytes.length == 16)
335                    {
336                        byte[]  longKey = new byte[24];
337
338                        System.arraycopy(bytes, 0, longKey, 0, 16);
339                        System.arraycopy(bytes, 0, longKey, 16, 8);
340
341                        return new DESedeKeySpec(longKey);
342                    }
343                    else
344                    {
345                        return new DESedeKeySpec(bytes);
346                    }
347                }
348                catch (Exception e)
349                {
350                    throw new InvalidKeySpecException(e.toString());
351                }
352            }
353
354            throw new InvalidKeySpecException("Invalid KeySpec");
355        }
356
357        protected SecretKey engineGenerateSecret(
358            KeySpec keySpec)
359        throws InvalidKeySpecException
360        {
361            if (keySpec instanceof DESedeKeySpec)
362            {
363                DESedeKeySpec desKeySpec = (DESedeKeySpec)keySpec;
364                return new SecretKeySpec(desKeySpec.getKey(), "DESede");
365            }
366
367            return super.engineGenerateSecret(keySpec);
368        }
369    }
370
371    public static class Mappings
372        extends AlgorithmProvider
373    {
374        private static final String PREFIX = DESede.class.getName();
375        private static final String PACKAGE = "org.bouncycastle.jcajce.provider.symmetric"; // JDK 1.2
376
377        public Mappings()
378        {
379        }
380
381        public void configure(ConfigurableProvider provider)
382        {
383            provider.addAlgorithm("Cipher.DESEDE", PREFIX + "$ECB");
384            // BEGIN android-removed
385            // provider.addAlgorithm("Cipher." + PKCSObjectIdentifiers.des_EDE3_CBC, PREFIX + "$CBC");
386            // END android-removed
387            provider.addAlgorithm("Cipher.DESEDEWRAP", PREFIX + "$Wrap");
388            // BEGIN android-changed
389            provider.addAlgorithm("Alg.Alias.Cipher." + PKCSObjectIdentifiers.id_alg_CMS3DESwrap, "DESEDEWRAP");
390            // END android-changed
391            // BEGIN android-removed
392            // provider.addAlgorithm("Cipher.DESEDERFC3211WRAP", PREFIX + "$RFC3211");
393            // END android-removed
394
395            provider.addAlgorithm("Alg.Alias.Cipher.TDEA", "DESEDE");
396            provider.addAlgorithm("Alg.Alias.Cipher.TDEAWRAP", "DESEDEWRAP");
397            provider.addAlgorithm("Alg.Alias.KeyGenerator.TDEA", "DESEDE");
398            provider.addAlgorithm("Alg.Alias.AlgorithmParameters.TDEA", "DESEDE");
399            // BEGIN android-removed
400            // provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator.TDEA", "DESEDE");
401            // END android-removed
402            provider.addAlgorithm("Alg.Alias.SecretKeyFactory.TDEA", "DESEDE");
403
404            if (provider.hasAlgorithm("MessageDigest", "SHA-1"))
405            {
406                provider.addAlgorithm("Cipher.PBEWITHSHAAND3-KEYTRIPLEDES-CBC", PREFIX + "$PBEWithSHAAndDES3Key");
407                // BEGIN android-removed
408                // provider.addAlgorithm("Cipher.BROKENPBEWITHSHAAND3-KEYTRIPLEDES-CBC", PREFIX + "$BrokePBEWithSHAAndDES3Key");
409                // provider.addAlgorithm("Cipher.OLDPBEWITHSHAAND3-KEYTRIPLEDES-CBC", PREFIX + "$OldPBEWithSHAAndDES3Key");
410                // END android-removed
411                provider.addAlgorithm("Cipher.PBEWITHSHAAND2-KEYTRIPLEDES-CBC", PREFIX + "$PBEWithSHAAndDES2Key");
412                // BEGIN android-removed
413                // provider.addAlgorithm("Cipher.BROKENPBEWITHSHAAND2-KEYTRIPLEDES-CBC", PREFIX + "$BrokePBEWithSHAAndDES2Key");
414                // END android-removed
415                provider.addAlgorithm("Alg.Alias.Cipher." + PKCSObjectIdentifiers.pbeWithSHAAnd3_KeyTripleDES_CBC, "PBEWITHSHAAND3-KEYTRIPLEDES-CBC");
416                provider.addAlgorithm("Alg.Alias.Cipher." + PKCSObjectIdentifiers.pbeWithSHAAnd2_KeyTripleDES_CBC, "PBEWITHSHAAND2-KEYTRIPLEDES-CBC");
417                provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1ANDDESEDE", "PBEWITHSHAAND3-KEYTRIPLEDES-CBC");
418                provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND3-KEYTRIPLEDES-CBC", "PBEWITHSHAAND3-KEYTRIPLEDES-CBC");
419                provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND2-KEYTRIPLEDES-CBC", "PBEWITHSHAAND2-KEYTRIPLEDES-CBC");
420            }
421
422            provider.addAlgorithm("KeyGenerator.DESEDE", PREFIX + "$KeyGenerator");
423            // BEGIN android-removed
424            // provider.addAlgorithm("KeyGenerator." + PKCSObjectIdentifiers.des_EDE3_CBC, PREFIX + "$KeyGenerator3");
425            // provider.addAlgorithm("KeyGenerator.DESEDEWRAP", PREFIX + "$KeyGenerator");
426            // END android-removed
427
428            provider.addAlgorithm("SecretKeyFactory.DESEDE", PREFIX + "$KeyFactory");
429
430            // BEGIN android-removed
431            // provider.addAlgorithm("Mac.DESEDECMAC", PREFIX + "$CMAC");
432            // provider.addAlgorithm("Mac.DESEDEMAC", PREFIX + "$CBCMAC");
433            // provider.addAlgorithm("Alg.Alias.Mac.DESEDE", "DESEDEMAC");
434            //
435            // provider.addAlgorithm("Mac.DESEDEMAC/CFB8", PREFIX + "$DESedeCFB8");
436            // provider.addAlgorithm("Alg.Alias.Mac.DESEDE/CFB8", "DESEDEMAC/CFB8");
437            //
438            // provider.addAlgorithm("Mac.DESEDEMAC64", PREFIX + "$DESede64");
439            // provider.addAlgorithm("Alg.Alias.Mac.DESEDE64", "DESEDEMAC64");
440            //
441            // provider.addAlgorithm("Mac.DESEDEMAC64WITHISO7816-4PADDING", PREFIX + "$DESede64with7816d4");
442            // provider.addAlgorithm("Alg.Alias.Mac.DESEDE64WITHISO7816-4PADDING", "DESEDEMAC64WITHISO7816-4PADDING");
443            // provider.addAlgorithm("Alg.Alias.Mac.DESEDEISO9797ALG1MACWITHISO7816-4PADDING", "DESEDEMAC64WITHISO7816-4PADDING");
444            // provider.addAlgorithm("Alg.Alias.Mac.DESEDEISO9797ALG1WITHISO7816-4PADDING", "DESEDEMAC64WITHISO7816-4PADDING");
445            // END android-removed
446
447            provider.addAlgorithm("AlgorithmParameters.DESEDE", PACKAGE + ".util.IvAlgorithmParameters");
448            provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + PKCSObjectIdentifiers.des_EDE3_CBC, "DESEDE");
449
450            // BEGIN android-removed
451            // provider.addAlgorithm("AlgorithmParameterGenerator.DESEDE",  PREFIX + "$AlgParamGen");
452            // provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator." + PKCSObjectIdentifiers.des_EDE3_CBC, "DESEDE");
453            // END android-removed
454
455            provider.addAlgorithm("SecretKeyFactory.PBEWITHSHAAND3-KEYTRIPLEDES-CBC", PREFIX + "$PBEWithSHAAndDES3KeyFactory");
456            provider.addAlgorithm("SecretKeyFactory.PBEWITHSHAAND2-KEYTRIPLEDES-CBC", PREFIX + "$PBEWithSHAAndDES2KeyFactory");
457
458            provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAAND3-KEYTRIPLEDES", "PKCS12PBE");
459            provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAAND2-KEYTRIPLEDES", "PKCS12PBE");
460            provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAAND3-KEYTRIPLEDES-CBC", "PKCS12PBE");
461            provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAAND2-KEYTRIPLEDES-CBC", "PKCS12PBE");
462            provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAANDDES3KEY-CBC", "PKCS12PBE");
463            provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAANDDES2KEY-CBC", "PKCS12PBE");
464
465            provider.addAlgorithm("Alg.Alias.SecretKeyFactory.1.2.840.113549.1.12.1.3", "PBEWITHSHAAND3-KEYTRIPLEDES-CBC");
466            provider.addAlgorithm("Alg.Alias.SecretKeyFactory.1.2.840.113549.1.12.1.4", "PBEWITHSHAAND2-KEYTRIPLEDES-CBC");
467            provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWithSHAAnd3KeyTripleDES", "PBEWITHSHAAND3-KEYTRIPLEDES-CBC");
468            provider.addAlgorithm("Alg.Alias.AlgorithmParameters.1.2.840.113549.1.12.1.3", "PKCS12PBE");
469            provider.addAlgorithm("Alg.Alias.AlgorithmParameters.1.2.840.113549.1.12.1.4", "PKCS12PBE");
470            provider.addAlgorithm("Alg.Alias.Cipher.PBEWithSHAAnd3KeyTripleDES",  "PBEWITHSHAAND3-KEYTRIPLEDES-CBC");
471        }
472    }
473}
474