FileDocCategorySizeDatePackage
BaseKDFBytesGenerator.javaAPI DocAndroid 1.5 API3883Wed May 06 22:41:06 BST 2009org.bouncycastle.crypto.generators

BaseKDFBytesGenerator

public class BaseKDFBytesGenerator extends Object implements org.bouncycastle.crypto.DerivationFunction
Basic KDF generator for derived keys and ivs as defined by IEEE P1363a/ISO 18033
This implementation is based on ISO 18033/P1363a.

Fields Summary
private int
counterStart
private org.bouncycastle.crypto.Digest
digest
private byte[]
shared
private byte[]
iv
Constructors Summary
protected BaseKDFBytesGenerator(int counterStart, org.bouncycastle.crypto.Digest digest)
Construct a KDF Parameters generator.

param
counterStart value of counter.
param
digest the digest to be used as the source of derived keys.

        this.counterStart = counterStart;
        this.digest = digest;
    
Methods Summary
public intgenerateBytes(byte[] out, int outOff, int len)
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.

        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;
    
public org.bouncycastle.crypto.DigestgetDigest()
return the underlying digest.

        return digest;
    
public voidinit(org.bouncycastle.crypto.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");
        }