DES.java revision 53b61f9fe9d58034fcc7021137e92460f91b70ce
1package org.bouncycastle.jcajce.provider.symmetric;
2
3import java.security.AlgorithmParameters;
4import java.security.InvalidAlgorithmParameterException;
5import java.security.SecureRandom;
6import java.security.spec.AlgorithmParameterSpec;
7import java.security.spec.InvalidKeySpecException;
8import java.security.spec.KeySpec;
9
10import javax.crypto.SecretKey;
11import javax.crypto.spec.DESKeySpec;
12import javax.crypto.spec.IvParameterSpec;
13import javax.crypto.spec.PBEKeySpec;
14import javax.crypto.spec.SecretKeySpec;
15
16import org.bouncycastle.asn1.ASN1ObjectIdentifier;
17import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
18import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
19import org.bouncycastle.crypto.CipherParameters;
20import org.bouncycastle.crypto.KeyGenerationParameters;
21import org.bouncycastle.crypto.engines.DESEngine;
22import org.bouncycastle.crypto.engines.RFC3211WrapEngine;
23import org.bouncycastle.crypto.generators.DESKeyGenerator;
24import org.bouncycastle.crypto.macs.CBCBlockCipherMac;
25import org.bouncycastle.crypto.macs.CFBBlockCipherMac;
26import org.bouncycastle.crypto.macs.CMac;
27import org.bouncycastle.crypto.macs.ISO9797Alg3Mac;
28import org.bouncycastle.crypto.modes.CBCBlockCipher;
29import org.bouncycastle.crypto.paddings.ISO7816d4Padding;
30import org.bouncycastle.crypto.params.DESParameters;
31import org.bouncycastle.crypto.params.KeyParameter;
32import org.bouncycastle.crypto.params.ParametersWithIV;
33import org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
34import org.bouncycastle.jcajce.provider.symmetric.util.BCPBEKey;
35import org.bouncycastle.jcajce.provider.symmetric.util.BaseAlgorithmParameterGenerator;
36import org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher;
37import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator;
38import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac;
39import org.bouncycastle.jcajce.provider.symmetric.util.BaseSecretKeyFactory;
40import org.bouncycastle.jcajce.provider.symmetric.util.BaseWrapCipher;
41import org.bouncycastle.jcajce.provider.symmetric.util.PBE;
42import org.bouncycastle.jcajce.provider.util.AlgorithmProvider;
43
44public final class DES
45{
46    private DES()
47    {
48    }
49
50    static public class ECB
51        extends BaseBlockCipher
52    {
53        public ECB()
54        {
55            super(new DESEngine());
56        }
57    }
58
59    static public class CBC
60        extends BaseBlockCipher
61    {
62        public CBC()
63        {
64            super(new CBCBlockCipher(new DESEngine()), 64);
65        }
66    }
67
68    /**
69     * DES   CFB8
70     */
71    public static class DESCFB8
72        extends BaseMac
73    {
74        public DESCFB8()
75        {
76            super(new CFBBlockCipherMac(new DESEngine()));
77        }
78    }
79
80    /**
81     * DES64
82     */
83    public static class DES64
84        extends BaseMac
85    {
86        public DES64()
87        {
88            super(new CBCBlockCipherMac(new DESEngine(), 64));
89        }
90    }
91
92    /**
93     * DES64with7816-4Padding
94     */
95    public static class DES64with7816d4
96        extends BaseMac
97    {
98        public DES64with7816d4()
99        {
100            super(new CBCBlockCipherMac(new DESEngine(), 64, new ISO7816d4Padding()));
101        }
102    }
103
104    public static class CBCMAC
105        extends BaseMac
106    {
107        public CBCMAC()
108        {
109            super(new CBCBlockCipherMac(new DESEngine()));
110        }
111    }
112
113    static public class CMAC
114        extends BaseMac
115    {
116        public CMAC()
117        {
118            super(new CMac(new DESEngine()));
119        }
120    }
121
122    /**
123     * DES9797Alg3with7816-4Padding
124     */
125    public static class DES9797Alg3with7816d4
126        extends BaseMac
127    {
128        public DES9797Alg3with7816d4()
129        {
130            super(new ISO9797Alg3Mac(new DESEngine(), new ISO7816d4Padding()));
131        }
132    }
133
134    /**
135     * DES9797Alg3
136     */
137    public static class DES9797Alg3
138        extends BaseMac
139    {
140        public DES9797Alg3()
141        {
142            super(new ISO9797Alg3Mac(new DESEngine()));
143        }
144    }
145
146    public static class RFC3211
147        extends BaseWrapCipher
148    {
149        public RFC3211()
150        {
151            super(new RFC3211WrapEngine(new DESEngine()), 8);
152        }
153    }
154
155    public static class AlgParamGen
156        extends BaseAlgorithmParameterGenerator
157    {
158        protected void engineInit(
159            AlgorithmParameterSpec genParamSpec,
160            SecureRandom            random)
161            throws InvalidAlgorithmParameterException
162        {
163            throw new InvalidAlgorithmParameterException("No supported AlgorithmParameterSpec for DES parameter generation.");
164        }
165
166        protected AlgorithmParameters engineGenerateParameters()
167        {
168            byte[]  iv = new byte[8];
169
170            if (random == null)
171            {
172                random = new SecureRandom();
173            }
174
175            random.nextBytes(iv);
176
177            AlgorithmParameters params;
178
179            try
180            {
181                params = createParametersInstance("DES");
182                params.init(new IvParameterSpec(iv));
183            }
184            catch (Exception e)
185            {
186                throw new RuntimeException(e.getMessage());
187            }
188
189            return params;
190        }
191    }
192
193  /**
194     * DES - the default for this is to generate a key in
195     * a-b-a format that's 24 bytes long but has 16 bytes of
196     * key material (the first 8 bytes is repeated as the last
197     * 8 bytes). If you give it a size, you'll get just what you
198     * asked for.
199     */
200    public static class KeyGenerator
201        extends BaseKeyGenerator
202    {
203        public KeyGenerator()
204        {
205            super("DES", 64, new DESKeyGenerator());
206        }
207
208        protected void engineInit(
209            int             keySize,
210            SecureRandom random)
211        {
212            super.engineInit(keySize, random);
213        }
214
215        protected SecretKey engineGenerateKey()
216        {
217            if (uninitialised)
218            {
219                engine.init(new KeyGenerationParameters(new SecureRandom(), defaultKeySize));
220                uninitialised = false;
221            }
222
223            return new SecretKeySpec(engine.generateKey(), algName);
224        }
225    }
226
227    static public class KeyFactory
228        extends BaseSecretKeyFactory
229    {
230        public KeyFactory()
231        {
232            super("DES", null);
233        }
234
235        protected KeySpec engineGetKeySpec(
236            SecretKey key,
237            Class keySpec)
238        throws InvalidKeySpecException
239        {
240            if (keySpec == null)
241            {
242                throw new InvalidKeySpecException("keySpec parameter is null");
243            }
244            if (key == null)
245            {
246                throw new InvalidKeySpecException("key parameter is null");
247            }
248
249            if (SecretKeySpec.class.isAssignableFrom(keySpec))
250            {
251                return new SecretKeySpec(key.getEncoded(), algName);
252            }
253            else if (DESKeySpec.class.isAssignableFrom(keySpec))
254            {
255                byte[]  bytes = key.getEncoded();
256
257                try
258                {
259                    return new DESKeySpec(bytes);
260                }
261                catch (Exception e)
262                {
263                    throw new InvalidKeySpecException(e.toString());
264                }
265            }
266
267            throw new InvalidKeySpecException("Invalid KeySpec");
268        }
269
270        protected SecretKey engineGenerateSecret(
271            KeySpec keySpec)
272        throws InvalidKeySpecException
273        {
274            if (keySpec instanceof DESKeySpec)
275            {
276                DESKeySpec desKeySpec = (DESKeySpec)keySpec;
277                return new SecretKeySpec(desKeySpec.getKey(), "DES");
278            }
279
280            return super.engineGenerateSecret(keySpec);
281        }
282    }
283
284    static public class DESPBEKeyFactory
285        extends BaseSecretKeyFactory
286    {
287        private boolean forCipher;
288        private int     scheme;
289        private int     digest;
290        private int     keySize;
291        private int     ivSize;
292
293        public DESPBEKeyFactory(
294            String              algorithm,
295            ASN1ObjectIdentifier oid,
296            boolean             forCipher,
297            int                 scheme,
298            int                 digest,
299            int                 keySize,
300            int                 ivSize)
301        {
302            super(algorithm, oid);
303
304            this.forCipher = forCipher;
305            this.scheme = scheme;
306            this.digest = digest;
307            this.keySize = keySize;
308            this.ivSize = ivSize;
309        }
310
311        protected SecretKey engineGenerateSecret(
312            KeySpec keySpec)
313        throws InvalidKeySpecException
314        {
315            if (keySpec instanceof PBEKeySpec)
316            {
317                PBEKeySpec pbeSpec = (PBEKeySpec)keySpec;
318                CipherParameters param;
319
320                if (pbeSpec.getSalt() == null)
321                {
322                    return new BCPBEKey(this.algName, this.algOid, scheme, digest, keySize, ivSize, pbeSpec, null);
323                }
324
325                if (forCipher)
326                {
327                    param = PBE.Util.makePBEParameters(pbeSpec, scheme, digest, keySize, ivSize);
328                }
329                else
330                {
331                    param = PBE.Util.makePBEMacParameters(pbeSpec, scheme, digest, keySize);
332                }
333
334                KeyParameter kParam;
335                if (param instanceof ParametersWithIV)
336                {
337                    kParam = (KeyParameter)((ParametersWithIV)param).getParameters();
338                }
339                else
340                {
341                    kParam = (KeyParameter)param;
342                }
343
344                DESParameters.setOddParity(kParam.getKey());
345
346                return new BCPBEKey(this.algName, this.algOid, scheme, digest, keySize, ivSize, pbeSpec, param);
347            }
348
349            throw new InvalidKeySpecException("Invalid KeySpec");
350        }
351    }
352
353    /**
354     * PBEWithMD2AndDES
355     */
356    static public class PBEWithMD2KeyFactory
357        extends DESPBEKeyFactory
358    {
359        public PBEWithMD2KeyFactory()
360        {
361            super("PBEwithMD2andDES", PKCSObjectIdentifiers.pbeWithMD2AndDES_CBC, true, PKCS5S1, MD2, 64, 64);
362        }
363    }
364
365    /**
366     * PBEWithMD5AndDES
367     */
368    static public class PBEWithMD5KeyFactory
369        extends DESPBEKeyFactory
370    {
371        public PBEWithMD5KeyFactory()
372        {
373            super("PBEwithMD5andDES", PKCSObjectIdentifiers.pbeWithMD5AndDES_CBC, true, PKCS5S1, MD5, 64, 64);
374        }
375    }
376
377    /**
378     * PBEWithSHA1AndDES
379     */
380    static public class PBEWithSHA1KeyFactory
381        extends DESPBEKeyFactory
382    {
383        public PBEWithSHA1KeyFactory()
384        {
385            super("PBEwithSHA1andDES", PKCSObjectIdentifiers.pbeWithSHA1AndDES_CBC, true, PKCS5S1, SHA1, 64, 64);
386        }
387    }
388
389    /**
390     * PBEWithMD2AndDES
391     */
392    static public class PBEWithMD2
393        extends BaseBlockCipher
394    {
395        public PBEWithMD2()
396        {
397            super(new CBCBlockCipher(new DESEngine()));
398        }
399    }
400
401    /**
402     * PBEWithMD5AndDES
403     */
404    static public class PBEWithMD5
405        extends BaseBlockCipher
406    {
407        public PBEWithMD5()
408        {
409            super(new CBCBlockCipher(new DESEngine()));
410        }
411    }
412
413    /**
414     * PBEWithSHA1AndDES
415     */
416    static public class PBEWithSHA1
417        extends BaseBlockCipher
418    {
419        public PBEWithSHA1()
420        {
421            super(new CBCBlockCipher(new DESEngine()));
422        }
423    }
424
425    public static class Mappings
426        extends AlgorithmProvider
427    {
428        private static final String PREFIX = DES.class.getName();
429        private static final String PACKAGE = "org.bouncycastle.jcajce.provider.symmetric"; // JDK 1.2
430
431        public Mappings()
432        {
433        }
434
435        public void configure(ConfigurableProvider provider)
436        {
437
438            provider.addAlgorithm("Cipher.DES", PREFIX + "$ECB");
439            provider.addAlgorithm("Cipher." + OIWObjectIdentifiers.desCBC, PREFIX + "$CBC");
440
441            addAlias(provider, OIWObjectIdentifiers.desCBC, "DES");
442
443            provider.addAlgorithm("Cipher.DESRFC3211WRAP", PREFIX + "$RFC3211");
444
445            provider.addAlgorithm("KeyGenerator.DES", PREFIX + "$KeyGenerator");
446
447            provider.addAlgorithm("SecretKeyFactory.DES", PREFIX + "$KeyFactory");
448
449            provider.addAlgorithm("Mac.DESCMAC", PREFIX + "$CMAC");
450            provider.addAlgorithm("Mac.DESMAC", PREFIX + "$CBCMAC");
451            provider.addAlgorithm("Alg.Alias.Mac.DES", "DESMAC");
452
453            provider.addAlgorithm("Mac.DESMAC/CFB8", PREFIX + "$DESCFB8");
454            provider.addAlgorithm("Alg.Alias.Mac.DES/CFB8", "DESMAC/CFB8");
455
456            provider.addAlgorithm("Mac.DESMAC64", PREFIX + "$DES64");
457            provider.addAlgorithm("Alg.Alias.Mac.DES64", "DESMAC64");
458
459            provider.addAlgorithm("Mac.DESMAC64WITHISO7816-4PADDING", PREFIX + "$DES64with7816d4");
460            provider.addAlgorithm("Alg.Alias.Mac.DES64WITHISO7816-4PADDING", "DESMAC64WITHISO7816-4PADDING");
461            provider.addAlgorithm("Alg.Alias.Mac.DESISO9797ALG1MACWITHISO7816-4PADDING", "DESMAC64WITHISO7816-4PADDING");
462            provider.addAlgorithm("Alg.Alias.Mac.DESISO9797ALG1WITHISO7816-4PADDING", "DESMAC64WITHISO7816-4PADDING");
463
464            provider.addAlgorithm("Mac.DESWITHISO9797", PREFIX + "$DES9797Alg3");
465            provider.addAlgorithm("Alg.Alias.Mac.DESISO9797MAC", "DESWITHISO9797");
466
467            provider.addAlgorithm("Mac.ISO9797ALG3MAC", PREFIX + "$DES9797Alg3");
468            provider.addAlgorithm("Alg.Alias.Mac.ISO9797ALG3", "ISO9797ALG3MAC");
469            provider.addAlgorithm("Mac.ISO9797ALG3WITHISO7816-4PADDING", PREFIX + "$DES9797Alg3with7816d4");
470            provider.addAlgorithm("Alg.Alias.Mac.ISO9797ALG3MACWITHISO7816-4PADDING", "ISO9797ALG3WITHISO7816-4PADDING");
471
472            provider.addAlgorithm("AlgorithmParameters.DES", PACKAGE + ".util.IvAlgorithmParameters");
473            provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + OIWObjectIdentifiers.desCBC, "DES");
474
475            provider.addAlgorithm("AlgorithmParameterGenerator.DES",  PREFIX + "$AlgParamGen");
476            provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator." + OIWObjectIdentifiers.desCBC, "DES");
477
478            provider.addAlgorithm("Cipher.PBEWITHMD2ANDDES", PREFIX + "$PBEWithMD2");
479            provider.addAlgorithm("Cipher.PBEWITHMD5ANDDES", PREFIX + "$PBEWithMD5");
480            provider.addAlgorithm("Cipher.PBEWITHSHA1ANDDES", PREFIX + "$PBEWithSHA1");
481
482            provider.addAlgorithm("Alg.Alias.Cipher." + PKCSObjectIdentifiers.pbeWithMD2AndDES_CBC, "PBEWITHMD2ANDDES");
483            provider.addAlgorithm("Alg.Alias.Cipher." + PKCSObjectIdentifiers.pbeWithMD5AndDES_CBC, "PBEWITHMD5ANDDES");
484            provider.addAlgorithm("Alg.Alias.Cipher." + PKCSObjectIdentifiers.pbeWithSHA1AndDES_CBC, "PBEWITHSHA1ANDDES");
485
486            provider.addAlgorithm("SecretKeyFactory.PBEWITHMD2ANDDES", PREFIX + "$PBEWithMD2KeyFactory");
487            provider.addAlgorithm("SecretKeyFactory.PBEWITHMD5ANDDES", PREFIX + "$PBEWithMD5KeyFactory");
488            provider.addAlgorithm("SecretKeyFactory.PBEWITHSHA1ANDDES", PREFIX + "$PBEWithSHA1KeyFactory");
489
490            provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHMD2ANDDES-CBC", "PBEWITHMD2ANDDES");
491            provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHMD5ANDDES-CBC", "PBEWITHMD5ANDDES");
492            provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA1ANDDES-CBC", "PBEWITHSHA1ANDDES");
493            provider.addAlgorithm("Alg.Alias.SecretKeyFactory." + PKCSObjectIdentifiers.pbeWithMD2AndDES_CBC, "PBEWITHMD2ANDDES");
494            provider.addAlgorithm("Alg.Alias.SecretKeyFactory." + PKCSObjectIdentifiers.pbeWithMD5AndDES_CBC, "PBEWITHMD5ANDDES");
495            provider.addAlgorithm("Alg.Alias.SecretKeyFactory." + PKCSObjectIdentifiers.pbeWithSHA1AndDES_CBC, "PBEWITHSHA1ANDDES");
496        }
497
498        private void addAlias(ConfigurableProvider provider, ASN1ObjectIdentifier oid, String name)
499        {
500            provider.addAlgorithm("Alg.Alias.KeyGenerator." + oid.getId(), name);
501            provider.addAlgorithm("Alg.Alias.KeyFactory." + oid.getId(), name);
502        }
503    }
504}
505