Design and impl review: JEP 273: DRBG-Based SecureRandom Implementations

ecki at zusammenkunft.net ecki at zusammenkunft.net
Wed Jan 6 07:31:37 UTC 2016


Hello,

is the Intention of the default implementation of getFullEntropy to expand a too short array with the DF as well (which is a dangerous thing to do IMHO) or is the conditional conditioning only to condense (aka shorten)? In that case you should maybe add an assert and make the if compare against bigger length only? (On the other hand I wonder why not simly discarding the bytes would be fine, too. I dont see an implementation providing excessive bytes anyway.

Why not have a int fillEntropy (byte [] out, boolean partial (, int pos, int len)) methods instead? (This also avoids the need to exlain "full" as well as "get".

When partial is false the method is guranteed to throw if not enough entropy is available and by not creating arrays it cannot create exceeding bytes.

The default impl for the pos/len is to call  fillEntropy(out, partial, 0, out.length). It might not be needed hoewever.

Bernd
-- 
http://bernd.eckenfels.net

-----Original Message-----
From: Wang Weijun <weijun.wang at oracle.com>
To: Sean Mullan <sean.mullan at oracle.com>
Cc: OpenJDK Dev list <security-dev at openjdk.java.net>
Sent: Mi., 06 Jan. 2016 6:19
Subject: Re: Design and impl review: JEP 273: DRBG-Based SecureRandom Implementations


> On Jan 6, 2016, at 12:01 AM, Sean Mullan <sean.mullan at oracle.com> wrote:
> 
> If you think getFullEntropy is sufficient, then let's just keep the one method.

I thought about this more and we can actually do

/**
 * An interface of a source of entropy input.
 * <p>
 * This interface has 2 methods returning byte arrays containing entropy.
 * The result of {@link #getFullEntropy} contains full entropy and that of
 * {@link #getEntropy} contains the request amount of entropy but might not
 * be full. The default implementation of the methods inside this interface
 * are dependent on each other. An implementation must implement at least
 * one of them to be useful.
 *
 * @since 1.9
 */
public interface EntropyInput {
    /**
     * Fills a byte array with full entropy.
     * <p>
     * This method might block and/or fail.
     *
     * @implSpec The default implementation calls {@link #getEntropy}
     * to return a byte array which might not have full entropy, and then
     * calls the hashdf conditioning function defined in NIST SP 800-90Ar1
     * 10.3.1 to condense it into an array with full entropy.
     *
     * @param entropy the byte array with filled entropy.
     * @throws EntropyNotAvailableException if not enough entropy is available.
     */
    default void getFullEntropy(byte[] entropy) {
        byte[] raw = getEntropy(entropy.length);
        if (raw.length != entropy.length) {
            try {
                MessageDigest md = MessageDigest.getInstance("SHA-256", "SUN");
                raw = HashDrbg.hashDf(md, md.getDigestLength(),
                        entropy.length, raw);
            } catch (Exception e) {
                throw new InternalError(e);
            }
        }
        System.arraycopy(raw, 0, entropy, 0, raw.length);
    }

    /**
     * Returns a byte array with at least length*8 bits of entropy.
     * <p>
     * This method might block and/or fail.
     *
     * @implSpec The default implementation calls {@link #getFullEntropy}
     * to return a byte array which has full entropy.
     *
     * @param length the minimum size of entropy requested in bytes
     * @return a byte array containing entropy
     * @throws EntropyNotAvailableException if not enough entropy is available.
     */
    default byte[] getEntropy(int length) {
        byte[] result = new byte[length];
        getFullEntropy(result);
        return result;
    }
}


More information about the security-dev mailing list