org.cryptacular.generator.sp80038d.RBGNonce Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of com.liferay.saml.opensaml.integration Show documentation
Show all versions of com.liferay.saml.opensaml.integration Show documentation
Liferay SAML OpenSAML Integration
/* See LICENSE for licensing and NOTICE for copyright. */
package org.cryptacular.generator.sp80038d;
import org.bouncycastle.crypto.digests.SHA256Digest;
import org.bouncycastle.crypto.prng.drbg.HashSP800DRBG;
import org.bouncycastle.crypto.prng.drbg.SP80090DRBG;
import org.cryptacular.generator.LimitException;
import org.cryptacular.generator.Nonce;
import org.cryptacular.util.ByteUtil;
import org.cryptacular.util.NonceUtil;
/**
* RBG-based nonce generation strategy that uses a RBG component to produce values for the invocation field as described
* in NIST SP-800-38D, section 8.2.2.
*
* NOTE: users of this class are responsible for counting number of invocations and enforcing the
* constraints described in section 8.3; namely the following:
*
* The total number of invocations of the authenticated encryption function shall not exceed 232,
* including all IV lengths and all instances of the authenticated encryption function with the given key.
*
* Instances of this class are thread safe.
*
* @author Middleware Services
*/
public class RBGNonce implements Nonce
{
/** Fixed field value. */
private final byte[] fixed;
/** Number of bytes of random data in invocation field. */
private final int randomLength;
/** Random bit generator. */
private final SP80090DRBG rbg;
/**
* Creates a new instance that produces 12-bytes (96-bits) of random data; that is, the fixed field of the nonce is
* null.
*/
public RBGNonce()
{
this(12);
}
/**
* Creates a new instance that produces length bytes of random data; that is, the fixed field of the nonce is null.
*
* @param randomLength Number of bytes in the random part of the nonce. MUST be at least 12.
*/
public RBGNonce(final int randomLength)
{
this(null, randomLength);
}
/**
* Creates a new instance using the given fixed field value.
*
* @param fixed User-defined fixed field value.
* @param randomLength Number of bytes in the random part of the nonce. MUST be at least 12.
*/
public RBGNonce(final String fixed, final int randomLength)
{
if (randomLength < 12) {
throw new IllegalArgumentException("Must specify at least 12 bytes (96 bits) for random part.");
}
this.randomLength = randomLength;
if (fixed != null) {
this.fixed = ByteUtil.toBytes(fixed);
} else {
this.fixed = new byte[0];
}
this.rbg = newRBG(this.randomLength, this.fixed);
}
@Override
public byte[] generate()
throws LimitException
{
final byte[] random = new byte[randomLength];
synchronized (rbg) {
rbg.generate(random, null, false);
}
final byte[] value = new byte[getLength()];
System.arraycopy(fixed, 0, value, 0, fixed.length);
System.arraycopy(random, 0, value, fixed.length, random.length);
return value;
}
@Override
public int getLength()
{
return fixed.length + randomLength;
}
/**
* Creates a new DRBG instance.
*
* @param length Length in bits of values produced by DRBG.
* @param domain Domain qualifier.
*
* @return New DRBG instance.
*/
private static SP80090DRBG newRBG(final int length, final byte[] domain)
{
return new HashSP800DRBG(
new SHA256Digest(), length, NonceUtil.randomEntropySource(length), domain, NonceUtil.timestampNonce(8));
}
}