PKCS5S2ParametersGenerator.java revision a198e1ecc615e26a167d0f2dca9fa7e5fc62de10
1ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwinpackage org.bouncycastle.crypto.generators; 2ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwin 3ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwinimport org.bouncycastle.crypto.CipherParameters; 4ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwinimport org.bouncycastle.crypto.Digest; 5ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwinimport org.bouncycastle.crypto.Mac; 6ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwinimport org.bouncycastle.crypto.PBEParametersGenerator; 7ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwin// BEGIN android-changed 8ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwinimport org.bouncycastle.crypto.digests.AndroidDigestFactory; 9ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwin// END android-changed 10ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwinimport org.bouncycastle.crypto.macs.HMac; 11528700863adefca8de461ce28a7d903729fb96b4Chris Lattnerimport org.bouncycastle.crypto.params.KeyParameter; 125a88dda4be791426ab4d20a6a6c9c65d66614a27Chandler Carruthimport org.bouncycastle.crypto.params.ParametersWithIV; 13ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwin 14ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwin/** 15ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwin * Generator for PBE derived keys and ivs as defined by PKCS 5 V2.0 Scheme 2. 16ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwin * This generator uses a SHA-1 HMac as the calculation function. 17ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwin * <p> 18ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwin * The document this implementation is based on can be found at 19ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwin * <a href=http://www.rsasecurity.com/rsalabs/pkcs/pkcs-5/index.html> 20ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwin * RSA's PKCS5 Page</a> 21ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwin */ 22ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwinpublic class PKCS5S2ParametersGenerator 23ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwin extends PBEParametersGenerator 24ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwin{ 25ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwin private Mac hMac; 26ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwin private byte[] state; 27ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwin 2881f46d9ce1888308b33336f9bea72147430da36bChris Lattner /** 29ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwin * construct a PKCS5 Scheme 2 Parameters generator. 30ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwin */ 31ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwin public PKCS5S2ParametersGenerator() 32ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwin { 3381f46d9ce1888308b33336f9bea72147430da36bChris Lattner // BEGIN android-changed 34ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwin this(AndroidDigestFactory.getSHA1()); 35ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwin // END android-changed 36ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwin } 37ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwin 38ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwin public PKCS5S2ParametersGenerator(Digest digest) 39ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwin { 40ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwin hMac = new HMac(digest); 41ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwin state = new byte[hMac.getMacSize()]; 42ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwin } 43ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwin 44ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwin private void F( 45ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwin byte[] S, 4681f46d9ce1888308b33336f9bea72147430da36bChris Lattner int c, 47ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwin byte[] iBuf, 48ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwin byte[] out, 49ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwin int outOff) 50ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwin { 51ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwin if (c == 0) 52ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwin { 53ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwin throw new IllegalArgumentException("iteration count must be at least 1."); 54ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwin } 55ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwin 56ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwin if (S != null) 5781f46d9ce1888308b33336f9bea72147430da36bChris Lattner { 58ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwin hMac.update(S, 0, S.length); 59ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwin } 60ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwin 61ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwin hMac.update(iBuf, 0, iBuf.length); 62ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwin hMac.doFinal(state, 0); 63ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwin 646b731486d4460e5f1088a6066c0081af048c1e45Eli Bendersky System.arraycopy(state, 0, out, outOff, state.length); 656b731486d4460e5f1088a6066c0081af048c1e45Eli Bendersky 666b731486d4460e5f1088a6066c0081af048c1e45Eli Bendersky for (int count = 1; count < c; count++) 676b731486d4460e5f1088a6066c0081af048c1e45Eli Bendersky { 686b731486d4460e5f1088a6066c0081af048c1e45Eli Bendersky hMac.update(state, 0, state.length); 696b731486d4460e5f1088a6066c0081af048c1e45Eli Bendersky hMac.doFinal(state, 0); 706b731486d4460e5f1088a6066c0081af048c1e45Eli Bendersky 716b731486d4460e5f1088a6066c0081af048c1e45Eli Bendersky for (int j = 0; j != state.length; j++) 726b731486d4460e5f1088a6066c0081af048c1e45Eli Bendersky { 736b731486d4460e5f1088a6066c0081af048c1e45Eli Bendersky out[outOff + j] ^= state[j]; 746b731486d4460e5f1088a6066c0081af048c1e45Eli Bendersky } 756b731486d4460e5f1088a6066c0081af048c1e45Eli Bendersky } 766b731486d4460e5f1088a6066c0081af048c1e45Eli Bendersky } 776b731486d4460e5f1088a6066c0081af048c1e45Eli Bendersky 786b731486d4460e5f1088a6066c0081af048c1e45Eli Bendersky private byte[] generateDerivedKey( 796b731486d4460e5f1088a6066c0081af048c1e45Eli Bendersky int dkLen) 806b731486d4460e5f1088a6066c0081af048c1e45Eli Bendersky { 816b731486d4460e5f1088a6066c0081af048c1e45Eli Bendersky int hLen = hMac.getMacSize(); 826b731486d4460e5f1088a6066c0081af048c1e45Eli Bendersky int l = (dkLen + hLen - 1) / hLen; 836b731486d4460e5f1088a6066c0081af048c1e45Eli Bendersky byte[] iBuf = new byte[4]; 846b731486d4460e5f1088a6066c0081af048c1e45Eli Bendersky byte[] outBytes = new byte[l * hLen]; 856b731486d4460e5f1088a6066c0081af048c1e45Eli Bendersky int outPos = 0; 86d2a5c0d8562407f9acab97451a785b513edd4c9bDaniel Dunbar 87d2a5c0d8562407f9acab97451a785b513edd4c9bDaniel Dunbar CipherParameters param = new KeyParameter(password); 88d2a5c0d8562407f9acab97451a785b513edd4c9bDaniel Dunbar 89d2a5c0d8562407f9acab97451a785b513edd4c9bDaniel Dunbar hMac.init(param); 90d2a5c0d8562407f9acab97451a785b513edd4c9bDaniel Dunbar 91d2a5c0d8562407f9acab97451a785b513edd4c9bDaniel Dunbar for (int i = 1; i <= l; i++) 92d2a5c0d8562407f9acab97451a785b513edd4c9bDaniel Dunbar { 9336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Increment the value in 'iBuf' 94d2a5c0d8562407f9acab97451a785b513edd4c9bDaniel Dunbar int pos = 3; 9536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines while (++iBuf[pos] == 0) 96d2a5c0d8562407f9acab97451a785b513edd4c9bDaniel Dunbar { 9736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines --pos; 98d2a5c0d8562407f9acab97451a785b513edd4c9bDaniel Dunbar } 9936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 100d2a5c0d8562407f9acab97451a785b513edd4c9bDaniel Dunbar F(salt, iterationCount, iBuf, outBytes, outPos); 101d2a5c0d8562407f9acab97451a785b513edd4c9bDaniel Dunbar outPos += hLen; 102d2a5c0d8562407f9acab97451a785b513edd4c9bDaniel Dunbar } 103d2a5c0d8562407f9acab97451a785b513edd4c9bDaniel Dunbar 104d2a5c0d8562407f9acab97451a785b513edd4c9bDaniel Dunbar return outBytes; 105d2a5c0d8562407f9acab97451a785b513edd4c9bDaniel Dunbar } 10636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 107d2a5c0d8562407f9acab97451a785b513edd4c9bDaniel Dunbar /** 108d2a5c0d8562407f9acab97451a785b513edd4c9bDaniel Dunbar * Generate a key parameter derived from the password, salt, and iteration 10936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * count we are currently initialised with. 110d2a5c0d8562407f9acab97451a785b513edd4c9bDaniel Dunbar * 111d2a5c0d8562407f9acab97451a785b513edd4c9bDaniel Dunbar * @param keySize the size of the key we want (in bits) 112d2a5c0d8562407f9acab97451a785b513edd4c9bDaniel Dunbar * @return a KeyParameter object. 113d2a5c0d8562407f9acab97451a785b513edd4c9bDaniel Dunbar */ 114d2a5c0d8562407f9acab97451a785b513edd4c9bDaniel Dunbar public CipherParameters generateDerivedParameters( 115aa80e61b0d79ddf9593f6217063574d0c66c3099Peter Collingbourne int keySize) 116aa80e61b0d79ddf9593f6217063574d0c66c3099Peter Collingbourne { 117aa80e61b0d79ddf9593f6217063574d0c66c3099Peter Collingbourne keySize = keySize / 8; 118aa80e61b0d79ddf9593f6217063574d0c66c3099Peter Collingbourne 119aa80e61b0d79ddf9593f6217063574d0c66c3099Peter Collingbourne byte[] dKey = generateDerivedKey(keySize); 120aa80e61b0d79ddf9593f6217063574d0c66c3099Peter Collingbourne 121aa80e61b0d79ddf9593f6217063574d0c66c3099Peter Collingbourne return new KeyParameter(dKey, 0, keySize); 122aa80e61b0d79ddf9593f6217063574d0c66c3099Peter Collingbourne } 123aa80e61b0d79ddf9593f6217063574d0c66c3099Peter Collingbourne 124aa80e61b0d79ddf9593f6217063574d0c66c3099Peter Collingbourne /** 125aa80e61b0d79ddf9593f6217063574d0c66c3099Peter Collingbourne * Generate a key with initialisation vector parameter derived from 126aa80e61b0d79ddf9593f6217063574d0c66c3099Peter Collingbourne * the password, salt, and iteration count we are currently initialised 127aa80e61b0d79ddf9593f6217063574d0c66c3099Peter Collingbourne * with. 128aa80e61b0d79ddf9593f6217063574d0c66c3099Peter Collingbourne * 129aa80e61b0d79ddf9593f6217063574d0c66c3099Peter Collingbourne * @param keySize the size of the key we want (in bits) 13036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * @param ivSize the size of the iv we want (in bits) 13136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * @return a ParametersWithIV object. 13236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines */ 13336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines public CipherParameters generateDerivedParameters( 13436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines int keySize, 135783a0387c5eef62ff50950aa3e977b2652a3c3a5Alexey Samsonov int ivSize) 136783a0387c5eef62ff50950aa3e977b2652a3c3a5Alexey Samsonov { 137783a0387c5eef62ff50950aa3e977b2652a3c3a5Alexey Samsonov keySize = keySize / 8; 138783a0387c5eef62ff50950aa3e977b2652a3c3a5Alexey Samsonov ivSize = ivSize / 8; 139783a0387c5eef62ff50950aa3e977b2652a3c3a5Alexey Samsonov 140783a0387c5eef62ff50950aa3e977b2652a3c3a5Alexey Samsonov byte[] dKey = generateDerivedKey(keySize + ivSize); 141783a0387c5eef62ff50950aa3e977b2652a3c3a5Alexey Samsonov 142783a0387c5eef62ff50950aa3e977b2652a3c3a5Alexey Samsonov return new ParametersWithIV(new KeyParameter(dKey, 0, keySize), dKey, keySize, ivSize); 14336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 14436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 14536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /** 14636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * Generate a key parameter for use with a MAC derived from the password, 14736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * salt, and iteration count we are currently initialised with. 14836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * 14936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * @param keySize the size of the key we want (in bits) 15036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * @return a KeyParameter object. 15136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines */ 15236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines public CipherParameters generateDerivedMacParameters( 15336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines int keySize) 15436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines { 15536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return generateDerivedParameters(keySize); 156ce0c81e7dd321e9f94f628daa5528f56cab0ab88Torok Edwin } 157} 158