All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.bouncycastle.crypto.params.KDFCounterParameters Maven / Gradle / Ivy

Go to download

The Bouncy Castle Crypto package is a Java implementation of cryptographic algorithms. This jar contains JCE provider and lightweight API for the Bouncy Castle Cryptography APIs for JDK 1.4.

There is a newer version: 1.78.1
Show newest version
package org.bouncycastle.crypto.params;

import org.bouncycastle.crypto.DerivationParameters;
import org.bouncycastle.util.Arrays;

/**
 * This KDF has been defined by the publicly available NIST SP 800-108 specification.
 * NIST SP800-108 allows for alternative orderings of the input fields, meaning that the input can be formated in multiple ways.
 * There are 3 supported formats:  - Below [i]_2 is a counter of r-bits length concatenated to the fixedInputData.
 *  
 *  1: K(i) := PRF( KI, [i]_2 || Label || 0x00 || Context || [L]_2 ) with the counter at the very beginning of the fixedInputData (The default implementation has this format)
 *  2: K(i) := PRF( KI, Label || 0x00 || Context || [L]_2 || [i]_2 ) with the counter at the very end of the fixedInputData
 *  3a: K(i) := PRF( KI, Label || 0x00 || [i]_2 || Context || [L]_2 ) OR:
 *  3b: K(i) := PRF( KI, Label || 0x00 || [i]_2 || [L]_2 || Context ) OR:
 *  3c: K(i) := PRF( KI, Label || [i]_2 || 0x00 || Context || [L]_2 ) etc... with the counter somewhere in the 'middle' of the fixedInputData.
 * 
 * This function must be called with the following KDFCounterParameters():
 *  
 *   KI
 *   The part of the fixedInputData that comes BEFORE the counter OR null
 *   the part of the fixedInputData that comes AFTER the counter OR null
 *   the length of the counter in bits (not bytes)
 *  
 * Resulting function calls assuming an 8 bit counter.
 *  
 *  1.  KDFCounterParameters(ki, 	null, 									"Label || 0x00 || Context || [L]_2]",	8); 
 *  2.  KDFCounterParameters(ki, 	"Label || 0x00 || Context || [L]_2]", 	null,									8); 
 *  3a. KDFCounterParameters(ki, 	"Label || 0x00",						"Context || [L]_2]",					8);  
 *  3b. KDFCounterParameters(ki, 	"Label || 0x00",						"[L]_2] || Context",					8);
 *  3c. KDFCounterParameters(ki, 	"Label", 								"0x00 || Context || [L]_2]",			8); 
 * 
 */
public final class KDFCounterParameters
    implements DerivationParameters
{

    private byte[] ki;
    private byte[] fixedInputDataCounterPrefix;
    private byte[] fixedInputDataCounterSuffix;
    private int r;

    /**
     * Base constructor - suffix fixed input data only.
     *
     * @param ki the KDF seed
     * @param fixedInputDataCounterSuffix  fixed input data to follow counter.
     * @param r length of the counter in bits.
     */
    public KDFCounterParameters(byte[] ki, byte[] fixedInputDataCounterSuffix, int r)
    {
    	this(ki, null, fixedInputDataCounterSuffix, r);
    }

    /**
     * Base constructor - prefix and suffix fixed input data.
     *
     * @param ki the KDF seed
     * @param fixedInputDataCounterPrefix fixed input data to precede counter
     * @param fixedInputDataCounterSuffix fixed input data to follow counter.
     * @param r length of the counter in bits.
     */
    public KDFCounterParameters(byte[] ki, byte[] fixedInputDataCounterPrefix, byte[] fixedInputDataCounterSuffix, int r)
    {
        if (ki == null)
        {
            throw new IllegalArgumentException("A KDF requires Ki (a seed) as input");
        }
        this.ki = Arrays.clone(ki);

        if (fixedInputDataCounterPrefix == null)
        {
            this.fixedInputDataCounterPrefix = new byte[0];
        }
        else
        {
            this.fixedInputDataCounterPrefix = Arrays.clone(fixedInputDataCounterPrefix);
        }
        
        if (fixedInputDataCounterSuffix == null)
        {
            this.fixedInputDataCounterSuffix = new byte[0];
        }
        else
        {
            this.fixedInputDataCounterSuffix = Arrays.clone(fixedInputDataCounterSuffix);
        }

        if (r != 8 && r != 16 && r != 24 && r != 32)
        {
            throw new IllegalArgumentException("Length of counter should be 8, 16, 24 or 32");
        }
        this.r = r;
    }
    
    public byte[] getKI()
    {
        return ki;
    }

    public byte[] getFixedInputData()
    {
    	//Retained for backwards compatibility
        return Arrays.clone(fixedInputDataCounterSuffix);
    }

    public byte[] getFixedInputDataCounterPrefix()
    {
        return Arrays.clone(fixedInputDataCounterPrefix);
    }
    
    public byte[] getFixedInputDataCounterSuffix()
    {
        return Arrays.clone(fixedInputDataCounterSuffix);
    }

    public int getR()
    {
        return r;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy