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