1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage org.bouncycastle.jce.provider; 2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.bouncycastle.crypto.DataLengthException; 4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.bouncycastle.crypto.DerivationFunction; 5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.bouncycastle.crypto.DerivationParameters; 6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.bouncycastle.crypto.Digest; 7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.bouncycastle.crypto.params.KDFParameters; 8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/** 10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Generator for PBE derived keys and ivs as defined by IEEE P1363a 11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <br> 12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This implementation is based on draft 9 of IEEE P1363a. <b>Note:</b> 13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * as this is still a draft the output of this generator may change, don't 14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * use it for anything that might be subject to long term storage. 15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic class BrokenKDF2BytesGenerator 17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project implements DerivationFunction 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private Digest digest; 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private byte[] shared; 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private byte[] iv; 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Construct a KDF2 Parameters generator. Generates key material 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * according to IEEE P1363a - if you want orthodox results you should 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * use a digest specified in the standard. 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <p> 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <b>Note:</b> IEEE P1363a standard is still a draft standard, if the standard 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * changes this function, the output of this function will change as well. 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Don't use this routine for anything subject to long term storage. 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param digest the digest to be used as the source of derived keys. 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public BrokenKDF2BytesGenerator( 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Digest digest) 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.digest = digest; 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void init( 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DerivationParameters param) 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!(param instanceof KDFParameters)) 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalArgumentException("KDF parameters required for KDF2Generator"); 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project KDFParameters p = (KDFParameters)param; 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project shared = p.getSharedSecret(); 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project iv = p.getIV(); 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * return the underlying digest. 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public Digest getDigest() 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return digest; 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * fill len bytes of the output buffer with bytes generated from 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the derivation function. 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws IllegalArgumentException if the size of the request will cause an overflow. 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws DataLengthException if the out buffer is too small. 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int generateBytes( 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project byte[] out, 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int outOff, 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int len) 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throws DataLengthException, IllegalArgumentException 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((out.length - len) < outOff) 76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new DataLengthException("output buffer too small"); 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long oBits = len * 8; 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // this is at odds with the standard implementation, the 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // maximum value should be hBits * (2^23 - 1) where hBits 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // is the digest output size in bits. We can't have an 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // array with a long index at the moment... 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (oBits > (digest.getDigestSize() * 8 * (2L^32 - 1))) 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project new IllegalArgumentException("Output length to large"); 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int cThreshold = (int)(oBits / digest.getDigestSize()); 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project byte[] dig = null; 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dig = new byte[digest.getDigestSize()]; 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int counter = 1; counter <= cThreshold; counter++) 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project digest.update(shared, 0, shared.length); 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project digest.update((byte)(counter & 0xff)); 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project digest.update((byte)((counter >> 8) & 0xff)); 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project digest.update((byte)((counter >> 16) & 0xff)); 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project digest.update((byte)((counter >> 24) & 0xff)); 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project digest.update(iv, 0, iv.length); 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project digest.doFinal(dig, 0); 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((len - outOff) > dig.length) 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project System.arraycopy(dig, 0, out, outOff, dig.length); 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project outOff += dig.length; 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project System.arraycopy(dig, 0, out, outOff, len - outOff); 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project digest.reset(); 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return len; 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 128