116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giropackage org.bouncycastle.crypto.generators; 216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.crypto.CipherParameters; 416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.crypto.Digest; 516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.crypto.PBEParametersGenerator; 6c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro// BEGIN android-changed 7c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giroimport org.bouncycastle.crypto.digests.AndroidDigestFactory; 816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.crypto.params.KeyParameter; 916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.crypto.params.ParametersWithIV; 107dad97b63c47edea4e3afb374dcd00c7b7a1bdd4Sergio Giro// BEGIN android-removed 117dad97b63c47edea4e3afb374dcd00c7b7a1bdd4Sergio Giro// import org.bouncycastle.crypto.util.DigestFactory; 127dad97b63c47edea4e3afb374dcd00c7b7a1bdd4Sergio Giro// END android-removed 1316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 1416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro/** 1516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro * Generator for PBE derived keys and ivs as usd by OpenSSL. 1616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro * <p> 1716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro * The scheme is a simple extension of PKCS 5 V2.0 Scheme 1 using MD5 with an 1816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro * iteration count of 1. 1916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro * <p> 2016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro */ 2116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giropublic class OpenSSLPBEParametersGenerator 2216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro extends PBEParametersGenerator 2316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro{ 24c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // BEGIN android-changed 25c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro private Digest digest = AndroidDigestFactory.getMD5(); 26c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // END android-changed 2716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 2816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro /** 2916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro * Construct a OpenSSL Parameters generator. 3016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro */ 3116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro public OpenSSLPBEParametersGenerator() 3216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 3316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 3416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 3516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro /** 3616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro * Initialise - note the iteration count for this algorithm is fixed at 1. 3716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro * 3816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro * @param password password to use. 3916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro * @param salt salt to use. 4016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro */ 4116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro public void init( 4216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro byte[] password, 4316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro byte[] salt) 4416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 4516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro super.init(password, salt, 1); 4616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 4716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 4816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro /** 4916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro * the derived key function, the ith hash of the password and the salt. 5016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro */ 5116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro private byte[] generateDerivedKey( 5216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro int bytesNeeded) 5316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 5416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro byte[] buf = new byte[digest.getDigestSize()]; 5516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro byte[] key = new byte[bytesNeeded]; 5616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro int offset = 0; 5716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 5816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro for (;;) 5916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 6016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro digest.update(password, 0, password.length); 6116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro digest.update(salt, 0, salt.length); 6216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 6316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro digest.doFinal(buf, 0); 6416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 6516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro int len = (bytesNeeded > buf.length) ? buf.length : bytesNeeded; 6616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro System.arraycopy(buf, 0, key, offset, len); 6716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro offset += len; 6816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 6916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro // check if we need any more 7016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro bytesNeeded -= len; 7116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro if (bytesNeeded == 0) 7216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 7316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro break; 7416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 7516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 7616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro // do another round 7716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro digest.reset(); 7816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro digest.update(buf, 0, buf.length); 7916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 8016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 8116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return key; 8216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 8316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 8416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro /** 8516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro * Generate a key parameter derived from the password, salt, and iteration 8616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro * count we are currently initialised with. 8716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro * 8816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro * @param keySize the size of the key we want (in bits) 8916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro * @return a KeyParameter object. 9016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro * @exception IllegalArgumentException if the key length larger than the base hash size. 9116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro */ 9216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro public CipherParameters generateDerivedParameters( 9316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro int keySize) 9416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 9516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro keySize = keySize / 8; 9616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 9716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro byte[] dKey = generateDerivedKey(keySize); 9816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 9916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return new KeyParameter(dKey, 0, keySize); 10016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 10116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 10216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro /** 10316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro * Generate a key with initialisation vector parameter derived from 10416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro * the password, salt, and iteration count we are currently initialised 10516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro * with. 10616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro * 10716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro * @param keySize the size of the key we want (in bits) 10816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro * @param ivSize the size of the iv we want (in bits) 10916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro * @return a ParametersWithIV object. 11016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro * @exception IllegalArgumentException if keySize + ivSize is larger than the base hash size. 11116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro */ 11216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro public CipherParameters generateDerivedParameters( 11316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro int keySize, 11416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro int ivSize) 11516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 11616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro keySize = keySize / 8; 11716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro ivSize = ivSize / 8; 11816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 11916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro byte[] dKey = generateDerivedKey(keySize + ivSize); 12016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 12116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return new ParametersWithIV(new KeyParameter(dKey, 0, keySize), dKey, keySize, ivSize); 12216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 12316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 12416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro /** 12516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro * Generate a key parameter for use with a MAC derived from the password, 12616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro * salt, and iteration count we are currently initialised with. 12716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro * 12816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro * @param keySize the size of the key we want (in bits) 12916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro * @return a KeyParameter object. 13016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro * @exception IllegalArgumentException if the key length larger than the base hash size. 13116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro */ 13216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro public CipherParameters generateDerivedMacParameters( 13316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro int keySize) 13416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 13516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return generateDerivedParameters(keySize); 13616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 13716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro} 138