package org.bouncycastle.jce.provider;

import org.bouncycastle.crypto.DataLengthException;
import org.bouncycastle.crypto.DerivationFunction;
import org.bouncycastle.crypto.DerivationParameters;
import org.bouncycastle.crypto.Digest;
import org.bouncycastle.crypto.OutputLengthException;
import org.bouncycastle.crypto.params.KDFParameters;

Generator for PBE derived keys and ivs as defined by IEEE P1363a
This implementation is based on draft 9 of IEEE P1363a. Note: as this is still a draft the output of this generator may change, don't use it for anything that might be subject to long term storage.
/** * Generator for PBE derived keys and ivs as defined by IEEE P1363a * <br> * This implementation is based on draft 9 of IEEE P1363a. <b>Note:</b> * as this is still a draft the output of this generator may change, don't * use it for anything that might be subject to long term storage. */
public class BrokenKDF2BytesGenerator implements DerivationFunction { private Digest digest; private byte[] shared; private byte[] iv;
Construct a KDF2 Parameters generator. Generates key material according to IEEE P1363a - if you want orthodox results you should use a digest specified in the standard.

Note: IEEE P1363a standard is still a draft standard, if the standard changes this function, the output of this function will change as well. Don't use this routine for anything subject to long term storage.

Params:
  • digest – the digest to be used as the source of derived keys.
/** * Construct a KDF2 Parameters generator. Generates key material * according to IEEE P1363a - if you want orthodox results you should * use a digest specified in the standard. * <p> * <b>Note:</b> IEEE P1363a standard is still a draft standard, if the standard * changes this function, the output of this function will change as well. * Don't use this routine for anything subject to long term storage. * * @param digest the digest to be used as the source of derived keys. */
public BrokenKDF2BytesGenerator( Digest digest) { this.digest = digest; } public void init( DerivationParameters param) { if (!(param instanceof KDFParameters)) { throw new IllegalArgumentException("KDF parameters required for generator"); } KDFParameters p = (KDFParameters)param; shared = p.getSharedSecret(); iv = p.getIV(); }
return the underlying digest.
/** * return the underlying digest. */
public Digest getDigest() { return digest; }
fill len bytes of the output buffer with bytes generated from the derivation function.
Throws:
  • IllegalArgumentException – if the size of the request will cause an overflow.
  • DataLengthException – if the out buffer is too small.
/** * fill len bytes of the output buffer with bytes generated from * the derivation function. * * @throws IllegalArgumentException if the size of the request will cause an overflow. * @throws DataLengthException if the out buffer is too small. */
public int generateBytes( byte[] out, int outOff, int len) throws DataLengthException, IllegalArgumentException { if ((out.length - len) < outOff) { throw new OutputLengthException("output buffer too small"); } long oBits = len * 8L; // // this is at odds with the standard implementation, the // maximum value should be hBits * (2^32 - 1) where hBits // is the digest output size in bits. We can't have an // array with a long index at the moment... // if (oBits > (digest.getDigestSize() * 8L * (1L<<32 - 1))) { throw new IllegalArgumentException("Output length too large"); } int cThreshold = (int)(oBits / digest.getDigestSize()); byte[] dig = null; dig = new byte[digest.getDigestSize()]; for (int counter = 1; counter <= cThreshold; counter++) { digest.update(shared, 0, shared.length); digest.update((byte)(counter & 0xff)); digest.update((byte)((counter >> 8) & 0xff)); digest.update((byte)((counter >> 16) & 0xff)); digest.update((byte)((counter >> 24) & 0xff)); digest.update(iv, 0, iv.length); digest.doFinal(dig, 0); if ((len - outOff) > dig.length) { System.arraycopy(dig, 0, out, outOff, dig.length); outOff += dig.length; } else { System.arraycopy(dig, 0, out, outOff, len - outOff); } } digest.reset(); return len; } }