package org.bouncycastle.crypto.generators;

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

Basic KDF generator for derived keys and ivs as defined by IEEE P1363a/ISO 18033
This implementation is based on ISO 18033/P1363a.
/** * Basic KDF generator for derived keys and ivs as defined by IEEE P1363a/ISO 18033 * <br> * This implementation is based on ISO 18033/P1363a. */
public class BaseKDFBytesGenerator implements DerivationFunction { private int counterStart; private Digest digest; private byte[] shared; private byte[] iv;
Construct a KDF Parameters generator.

Params:
  • counterStart – value of counter.
  • digest – the digest to be used as the source of derived keys.
/** * Construct a KDF Parameters generator. * <p> * @param counterStart value of counter. * @param digest the digest to be used as the source of derived keys. */
protected BaseKDFBytesGenerator( int counterStart, Digest digest) { this.counterStart = counterStart; this.digest = digest; } public void init( DerivationParameters param) { if (param instanceof KDFParameters) { KDFParameters p = (KDFParameters)param; shared = p.getSharedSecret(); iv = p.getIV(); } else if (param instanceof ISO18033KDFParameters) { ISO18033KDFParameters p = (ISO18033KDFParameters)param; shared = p.getSeed(); iv = null; } else { throw new IllegalArgumentException("KDF parameters required for KDF2Generator"); } }
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 DataLengthException("output buffer too small"); } long oBytes = len; int outLen = digest.getDigestSize(); // // 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 (oBytes > ((2L << 32) - 1)) { throw new IllegalArgumentException("Output length too large"); } int cThreshold = (int)((oBytes + outLen - 1) / outLen); byte[] dig = null; dig = new byte[digest.getDigestSize()]; int counter = counterStart; for (int i = 0; i < cThreshold; i++) { digest.update(shared, 0, shared.length); digest.update((byte)(counter >> 24)); digest.update((byte)(counter >> 16)); digest.update((byte)(counter >> 8)); digest.update((byte)counter); if (iv != null) { digest.update(iv, 0, iv.length); } digest.doFinal(dig, 0); if (len > outLen) { System.arraycopy(dig, 0, out, outOff, outLen); outOff += outLen; len -= outLen; } else { System.arraycopy(dig, 0, out, outOff, len); } counter++; } digest.reset(); return len; } }