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