PKCS5S2ParametersGenerator.java revision 5db505e1f6a68c8d5dfdb0fed0b8607dea7bed96
14f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.compackage org.bouncycastle.crypto.generators; 292b9cd57673dad9c0ead2956bad0ded4e5ac49f8shannonwoods@chromium.org 34f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.comimport org.bouncycastle.crypto.CipherParameters; 44f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.comimport org.bouncycastle.crypto.Digest; 54f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.comimport org.bouncycastle.crypto.Mac; 64f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.comimport org.bouncycastle.crypto.PBEParametersGenerator; 74f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com// BEGIN android-changed 84f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.comimport org.bouncycastle.crypto.digests.AndroidDigestFactory; 94f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com// END android-changed 104f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.comimport org.bouncycastle.crypto.macs.HMac; 114f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.comimport org.bouncycastle.crypto.params.KeyParameter; 12b35602556fd332fa32620c4ba5e998e781e331a8shannon.woods@transgaming.comimport org.bouncycastle.crypto.params.ParametersWithIV; 1344fa7594bc518b1b004b1deb91d1c2f125df9f68Geoff Lang 14a2ecfcccf1d1a85e6054a7314ce1f9de0648ac7fshannonwoods@chromium.org/** 15b155bbcbacceeee8bed049d26ed0ee62d9bfd208Jamie Madill * Generator for PBE derived keys and ivs as defined by PKCS 5 V2.0 Scheme 2. 16b155bbcbacceeee8bed049d26ed0ee62d9bfd208Jamie Madill * This generator uses a SHA-1 HMac as the calculation function. 174f26786863c81244acdd5b36738ae25e2c56b312Jamie Madill * <p> 18b155bbcbacceeee8bed049d26ed0ee62d9bfd208Jamie Madill * The document this implementation is based on can be found at 194f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com * <a href=http://www.rsasecurity.com/rsalabs/pkcs/pkcs-5/index.html> 204f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com * RSA's PKCS5 Page</a> 2149ec992d80abe48f86034738e8d14c71de3c0b84shannonwoods@chromium.org */ 2249ec992d80abe48f86034738e8d14c71de3c0b84shannonwoods@chromium.orgpublic class PKCS5S2ParametersGenerator 2349ec992d80abe48f86034738e8d14c71de3c0b84shannonwoods@chromium.org extends PBEParametersGenerator 2449ec992d80abe48f86034738e8d14c71de3c0b84shannonwoods@chromium.org{ 2560dafe8f061e921a2b22fde9f2eb0e1264048121apatrick@chromium.org private Mac hMac; 2660dafe8f061e921a2b22fde9f2eb0e1264048121apatrick@chromium.org private byte[] state; 2760dafe8f061e921a2b22fde9f2eb0e1264048121apatrick@chromium.org 2860dafe8f061e921a2b22fde9f2eb0e1264048121apatrick@chromium.org /** 2960dafe8f061e921a2b22fde9f2eb0e1264048121apatrick@chromium.org * construct a PKCS5 Scheme 2 Parameters generator. 3060dafe8f061e921a2b22fde9f2eb0e1264048121apatrick@chromium.org */ 3160dafe8f061e921a2b22fde9f2eb0e1264048121apatrick@chromium.org public PKCS5S2ParametersGenerator() 3260dafe8f061e921a2b22fde9f2eb0e1264048121apatrick@chromium.org { 3360dafe8f061e921a2b22fde9f2eb0e1264048121apatrick@chromium.org // BEGIN android-changed 3460dafe8f061e921a2b22fde9f2eb0e1264048121apatrick@chromium.org this(AndroidDigestFactory.getSHA1()); 3560dafe8f061e921a2b22fde9f2eb0e1264048121apatrick@chromium.org // END android-changed 364f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com } 374f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com 384f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com public PKCS5S2ParametersGenerator(Digest digest) 394f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com { 404f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com hMac = new HMac(digest); 414f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com state = new byte[hMac.getMacSize()]; 424f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com } 434f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com 44e2b2212912010fafc2675485f8ddd67c6b29130ddaniel@transgaming.com private void F( 454f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com byte[] S, 464f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com int c, 474f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com byte[] iBuf, 4881655a720e752e0f0107993b6b575c5411f3a01edaniel@transgaming.com byte[] out, 4981655a720e752e0f0107993b6b575c5411f3a01edaniel@transgaming.com int outOff) 5081655a720e752e0f0107993b6b575c5411f3a01edaniel@transgaming.com { 5181655a720e752e0f0107993b6b575c5411f3a01edaniel@transgaming.com if (c == 0) 5281655a720e752e0f0107993b6b575c5411f3a01edaniel@transgaming.com { 5381655a720e752e0f0107993b6b575c5411f3a01edaniel@transgaming.com throw new IllegalArgumentException("iteration count must be at least 1."); 5481655a720e752e0f0107993b6b575c5411f3a01edaniel@transgaming.com } 5581655a720e752e0f0107993b6b575c5411f3a01edaniel@transgaming.com 5681655a720e752e0f0107993b6b575c5411f3a01edaniel@transgaming.com if (S != null) 5781655a720e752e0f0107993b6b575c5411f3a01edaniel@transgaming.com { 5881655a720e752e0f0107993b6b575c5411f3a01edaniel@transgaming.com hMac.update(S, 0, S.length); 5981655a720e752e0f0107993b6b575c5411f3a01edaniel@transgaming.com } 6081655a720e752e0f0107993b6b575c5411f3a01edaniel@transgaming.com 61b155bbcbacceeee8bed049d26ed0ee62d9bfd208Jamie Madill hMac.update(iBuf, 0, iBuf.length); 62b155bbcbacceeee8bed049d26ed0ee62d9bfd208Jamie Madill hMac.doFinal(state, 0); 63b155bbcbacceeee8bed049d26ed0ee62d9bfd208Jamie Madill 64b155bbcbacceeee8bed049d26ed0ee62d9bfd208Jamie Madill System.arraycopy(state, 0, out, outOff, state.length); 65b155bbcbacceeee8bed049d26ed0ee62d9bfd208Jamie Madill 6670656a64851b8014a325dd711297054032e466c1Jamie Madill for (int count = 1; count < c; count++) 6770656a64851b8014a325dd711297054032e466c1Jamie Madill { 6870656a64851b8014a325dd711297054032e466c1Jamie Madill hMac.update(state, 0, state.length); 6970656a64851b8014a325dd711297054032e466c1Jamie Madill hMac.doFinal(state, 0); 7070656a64851b8014a325dd711297054032e466c1Jamie Madill 7170656a64851b8014a325dd711297054032e466c1Jamie Madill for (int j = 0; j != state.length; j++) 7270656a64851b8014a325dd711297054032e466c1Jamie Madill { 7370656a64851b8014a325dd711297054032e466c1Jamie Madill out[outOff + j] ^= state[j]; 7470656a64851b8014a325dd711297054032e466c1Jamie Madill } 7570656a64851b8014a325dd711297054032e466c1Jamie Madill } 7670656a64851b8014a325dd711297054032e466c1Jamie Madill } 7770656a64851b8014a325dd711297054032e466c1Jamie Madill 7870656a64851b8014a325dd711297054032e466c1Jamie Madill private byte[] generateDerivedKey( 79b31f532d7137039e73d5bbdcc0b54a9883718c58apatrick@chromium.org int dkLen) 80b31f532d7137039e73d5bbdcc0b54a9883718c58apatrick@chromium.org { 81b31f532d7137039e73d5bbdcc0b54a9883718c58apatrick@chromium.org int hLen = hMac.getMacSize(); 8231c4f2354382991a2f199d2584ec17bd3db0ae8dshannon.woods@transgaming.com int l = (dkLen + hLen - 1) / hLen; 8331c4f2354382991a2f199d2584ec17bd3db0ae8dshannon.woods@transgaming.com byte[] iBuf = new byte[4]; 84b31f532d7137039e73d5bbdcc0b54a9883718c58apatrick@chromium.org byte[] outBytes = new byte[l * hLen]; 85b31f532d7137039e73d5bbdcc0b54a9883718c58apatrick@chromium.org int outPos = 0; 864f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com 874f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com CipherParameters param = new KeyParameter(password); 88b31f532d7137039e73d5bbdcc0b54a9883718c58apatrick@chromium.org 894f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com hMac.init(param); 904f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com 914f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com for (int i = 1; i <= l; i++) 924f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com { 934f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com // Increment the value in 'iBuf' 944f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com int pos = 3; 954f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com while (++iBuf[pos] == 0) 96e2b2212912010fafc2675485f8ddd67c6b29130ddaniel@transgaming.com { 974f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com --pos; 984f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com } 994f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com 100e2b2212912010fafc2675485f8ddd67c6b29130ddaniel@transgaming.com F(salt, iterationCount, iBuf, outBytes, outPos); 1014f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com outPos += hLen; 1024f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com } 1034f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com 1044f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com return outBytes; 1054f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com } 1064f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com 1074f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com /** 1084f39fd99568ce175f04b5ed72062bfed0fa41803daniel@transgaming.com * Generate a key parameter derived from the password, salt, and iteration 109b31f532d7137039e73d5bbdcc0b54a9883718c58apatrick@chromium.org * count we are currently initialised with. 110f1f28c80b0486e2b1d7dc7d976efb16a467fc5dajbauman@chromium.org * 111f1f28c80b0486e2b1d7dc7d976efb16a467fc5dajbauman@chromium.org * @param keySize the size of the key we want (in bits) 112fb8394756ea5940cf41e8276a81d54bacdceb5a6Shannon Woods * @return a KeyParameter object. 113f1f28c80b0486e2b1d7dc7d976efb16a467fc5dajbauman@chromium.org */ 114f1f28c80b0486e2b1d7dc7d976efb16a467fc5dajbauman@chromium.org public CipherParameters generateDerivedParameters( 115f1f28c80b0486e2b1d7dc7d976efb16a467fc5dajbauman@chromium.org int keySize) 116f1f28c80b0486e2b1d7dc7d976efb16a467fc5dajbauman@chromium.org { 117f1f28c80b0486e2b1d7dc7d976efb16a467fc5dajbauman@chromium.org keySize = keySize / 8; 118f1f28c80b0486e2b1d7dc7d976efb16a467fc5dajbauman@chromium.org 119f1f28c80b0486e2b1d7dc7d976efb16a467fc5dajbauman@chromium.org byte[] dKey = generateDerivedKey(keySize); 120f1f28c80b0486e2b1d7dc7d976efb16a467fc5dajbauman@chromium.org 121f1f28c80b0486e2b1d7dc7d976efb16a467fc5dajbauman@chromium.org return new KeyParameter(dKey, 0, keySize); 122f1f28c80b0486e2b1d7dc7d976efb16a467fc5dajbauman@chromium.org } 123a2ecfcccf1d1a85e6054a7314ce1f9de0648ac7fshannonwoods@chromium.org 124f1f28c80b0486e2b1d7dc7d976efb16a467fc5dajbauman@chromium.org /** 125f1f28c80b0486e2b1d7dc7d976efb16a467fc5dajbauman@chromium.org * Generate a key with initialisation vector parameter derived from 126f1f28c80b0486e2b1d7dc7d976efb16a467fc5dajbauman@chromium.org * the password, salt, and iteration count we are currently initialised 127f1f28c80b0486e2b1d7dc7d976efb16a467fc5dajbauman@chromium.org * with. 128f1f28c80b0486e2b1d7dc7d976efb16a467fc5dajbauman@chromium.org * 129f1f28c80b0486e2b1d7dc7d976efb16a467fc5dajbauman@chromium.org * @param keySize the size of the key we want (in bits) 130f1f28c80b0486e2b1d7dc7d976efb16a467fc5dajbauman@chromium.org * @param ivSize the size of the iv we want (in bits) 131f1f28c80b0486e2b1d7dc7d976efb16a467fc5dajbauman@chromium.org * @return a ParametersWithIV object. 132f1f28c80b0486e2b1d7dc7d976efb16a467fc5dajbauman@chromium.org */ 133f1f28c80b0486e2b1d7dc7d976efb16a467fc5dajbauman@chromium.org public CipherParameters generateDerivedParameters( 13483217796ed57efe8954fc3b53d743aae1a6cfe6bGeoff Lang int keySize, 13583217796ed57efe8954fc3b53d743aae1a6cfe6bGeoff Lang int ivSize) 13683217796ed57efe8954fc3b53d743aae1a6cfe6bGeoff Lang { 13783217796ed57efe8954fc3b53d743aae1a6cfe6bGeoff Lang keySize = keySize / 8; 138f1f28c80b0486e2b1d7dc7d976efb16a467fc5dajbauman@chromium.org ivSize = ivSize / 8; 139aa48067ac8125da0a96b10be3ea6e9df0fbaab43apatrick@chromium.org 140a43d829fabc8a251d6695922966ad25320e4c99fshannonwoods@chromium.org byte[] dKey = generateDerivedKey(keySize + ivSize); 141a43d829fabc8a251d6695922966ad25320e4c99fshannonwoods@chromium.org 142a43d829fabc8a251d6695922966ad25320e4c99fshannonwoods@chromium.org return new ParametersWithIV(new KeyParameter(dKey, 0, keySize), dKey, keySize, ivSize); 1437ab02fafb5de8cabadaa5eff10e473e79f9b027eJamie Madill } 144a43d829fabc8a251d6695922966ad25320e4c99fshannonwoods@chromium.org 1457ab02fafb5de8cabadaa5eff10e473e79f9b027eJamie Madill /** 146a43d829fabc8a251d6695922966ad25320e4c99fshannonwoods@chromium.org * Generate a key parameter for use with a MAC derived from the password, 147a43d829fabc8a251d6695922966ad25320e4c99fshannonwoods@chromium.org * salt, and iteration count we are currently initialised with. 148a43d829fabc8a251d6695922966ad25320e4c99fshannonwoods@chromium.org * 1492e38b800b3f448dd1a2e96a31db25d3bd5b6a3f4daniel@transgaming.com * @param keySize the size of the key we want (in bits) 1502e38b800b3f448dd1a2e96a31db25d3bd5b6a3f4daniel@transgaming.com * @return a KeyParameter object. 1512e38b800b3f448dd1a2e96a31db25d3bd5b6a3f4daniel@transgaming.com */ 1522e38b800b3f448dd1a2e96a31db25d3bd5b6a3f4daniel@transgaming.com public CipherParameters generateDerivedMacParameters( 1532e38b800b3f448dd1a2e96a31db25d3bd5b6a3f4daniel@transgaming.com int keySize) 1542e38b800b3f448dd1a2e96a31db25d3bd5b6a3f4daniel@transgaming.com { 1552e38b800b3f448dd1a2e96a31db25d3bd5b6a3f4daniel@transgaming.com return generateDerivedParameters(keySize); 1562e38b800b3f448dd1a2e96a31db25d3bd5b6a3f4daniel@transgaming.com } 1572e38b800b3f448dd1a2e96a31db25d3bd5b6a3f4daniel@transgaming.com} 1582e38b800b3f448dd1a2e96a31db25d3bd5b6a3f4daniel@transgaming.com