Home | History | Annotate | Download | only in generators
      1 package org.bouncycastle.crypto.generators;
      2 
      3 import org.bouncycastle.crypto.CipherParameters;
      4 import org.bouncycastle.crypto.Digest;
      5 import org.bouncycastle.crypto.PBEParametersGenerator;
      6 import org.bouncycastle.crypto.params.KeyParameter;
      7 import org.bouncycastle.crypto.params.ParametersWithIV;
      8 // Android-changed: Use Android digests
      9 // import org.bouncycastle.crypto.util.DigestFactory;
     10 import org.bouncycastle.crypto.digests.AndroidDigestFactory;
     11 
     12 /**
     13  * Generator for PBE derived keys and ivs as usd by OpenSSL.
     14  * <p>
     15  * The scheme is a simple extension of PKCS 5 V2.0 Scheme 1 using MD5 with an
     16  * iteration count of 1.
     17  * <p>
     18  */
     19 public class OpenSSLPBEParametersGenerator
     20     extends PBEParametersGenerator
     21 {
     22     // Android-changed: Use Android digests
     23     // private Digest  digest = DigestFactory.createMD5();
     24     private Digest  digest = AndroidDigestFactory.getMD5();
     25 
     26     /**
     27      * Construct a OpenSSL Parameters generator.
     28      */
     29     public OpenSSLPBEParametersGenerator()
     30     {
     31     }
     32 
     33     /**
     34      * Initialise - note the iteration count for this algorithm is fixed at 1.
     35      *
     36      * @param password password to use.
     37      * @param salt salt to use.
     38      */
     39     public void init(
     40        byte[] password,
     41        byte[] salt)
     42     {
     43         super.init(password, salt, 1);
     44     }
     45 
     46     /**
     47      * the derived key function, the ith hash of the password and the salt.
     48      */
     49     private byte[] generateDerivedKey(
     50         int bytesNeeded)
     51     {
     52         byte[]  buf = new byte[digest.getDigestSize()];
     53         byte[]  key = new byte[bytesNeeded];
     54         int     offset = 0;
     55 
     56         for (;;)
     57         {
     58             digest.update(password, 0, password.length);
     59             digest.update(salt, 0, salt.length);
     60 
     61             digest.doFinal(buf, 0);
     62 
     63             int len = (bytesNeeded > buf.length) ? buf.length : bytesNeeded;
     64             System.arraycopy(buf, 0, key, offset, len);
     65             offset += len;
     66 
     67             // check if we need any more
     68             bytesNeeded -= len;
     69             if (bytesNeeded == 0)
     70             {
     71                 break;
     72             }
     73 
     74             // do another round
     75             digest.reset();
     76             digest.update(buf, 0, buf.length);
     77         }
     78 
     79         return key;
     80     }
     81 
     82     /**
     83      * Generate a key parameter derived from the password, salt, and iteration
     84      * count we are currently initialised with.
     85      *
     86      * @param keySize the size of the key we want (in bits)
     87      * @return a KeyParameter object.
     88      * @exception IllegalArgumentException if the key length larger than the base hash size.
     89      */
     90     public CipherParameters generateDerivedParameters(
     91         int keySize)
     92     {
     93         keySize = keySize / 8;
     94 
     95         byte[]  dKey = generateDerivedKey(keySize);
     96 
     97         return new KeyParameter(dKey, 0, keySize);
     98     }
     99 
    100     /**
    101      * Generate a key with initialisation vector parameter derived from
    102      * the password, salt, and iteration count we are currently initialised
    103      * with.
    104      *
    105      * @param keySize the size of the key we want (in bits)
    106      * @param ivSize the size of the iv we want (in bits)
    107      * @return a ParametersWithIV object.
    108      * @exception IllegalArgumentException if keySize + ivSize is larger than the base hash size.
    109      */
    110     public CipherParameters generateDerivedParameters(
    111         int     keySize,
    112         int     ivSize)
    113     {
    114         keySize = keySize / 8;
    115         ivSize = ivSize / 8;
    116 
    117         byte[]  dKey = generateDerivedKey(keySize + ivSize);
    118 
    119         return new ParametersWithIV(new KeyParameter(dKey, 0, keySize), dKey, keySize, ivSize);
    120     }
    121 
    122     /**
    123      * Generate a key parameter for use with a MAC derived from the password,
    124      * salt, and iteration count we are currently initialised with.
    125      *
    126      * @param keySize the size of the key we want (in bits)
    127      * @return a KeyParameter object.
    128      * @exception IllegalArgumentException if the key length larger than the base hash size.
    129      */
    130     public CipherParameters generateDerivedMacParameters(
    131         int keySize)
    132     {
    133         return generateDerivedParameters(keySize);
    134     }
    135 }
    136