package org.bouncycastle.crypto.agreement.kdf;

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 Concatenation Key Derivation Function defined in NIST SP 800-56A, Sect 5.8.1
/** * Generator for Concatenation Key Derivation Function defined in NIST SP 800-56A, Sect 5.8.1 */
public class ConcatenationKDFGenerator implements DerivationFunction { private Digest digest; private byte[] shared; private byte[] otherInfo; private int hLen;
Params:
  • digest – the digest to be used as the source of generated bytes
/** * @param digest the digest to be used as the source of generated bytes */
public ConcatenationKDFGenerator( Digest digest) { this.digest = digest; this.hLen = digest.getDigestSize(); } public void init( DerivationParameters param) { if (param instanceof KDFParameters) { KDFParameters p = (KDFParameters)param; shared = p.getSharedSecret(); otherInfo = p.getIV(); } else { throw new IllegalArgumentException("KDF parameters required for generator"); } }
return the underlying digest.
/** * return the underlying digest. */
public Digest getDigest() { return digest; }
int to octet string.
/** * int to octet string. */
private void ItoOSP( int i, byte[] sp) { sp[0] = (byte)(i >>> 24); sp[1] = (byte)(i >>> 16); sp[2] = (byte)(i >>> 8); sp[3] = (byte)(i >>> 0); }
fill len bytes of the output buffer with bytes generated from the derivation function.
Throws:
  • DataLengthException – if the out buffer is too small.
/** * fill len bytes of the output buffer with bytes generated from * the derivation function. * * @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"); } byte[] hashBuf = new byte[hLen]; byte[] C = new byte[4]; int counter = 1; int outputLen = 0; digest.reset(); if (len > hLen) { do { ItoOSP(counter, C); digest.update(C, 0, C.length); digest.update(shared, 0, shared.length); digest.update(otherInfo, 0, otherInfo.length); digest.doFinal(hashBuf, 0); System.arraycopy(hashBuf, 0, out, outOff + outputLen, hLen); outputLen += hLen; } while ((counter++) < (len / hLen)); } if (outputLen < len) { ItoOSP(counter, C); digest.update(C, 0, C.length); digest.update(shared, 0, shared.length); digest.update(otherInfo, 0, otherInfo.length); digest.doFinal(hashBuf, 0); System.arraycopy(hashBuf, 0, out, outOff + outputLen, len - outputLen); } return len; } }