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