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

Wang Weijun weijun.wang at oracle.com
Wed Jan 6 08:34:25 UTC 2016


> On Jan 6, 2016, at 3:31 PM, ecki at zusammenkunft.net wrote:
> 
> 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)?

Only shorten. Should check.

> 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.

Discard extra bytes? At least the current code is an approved conditioning function.

> 
> 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".

So if partial is true, the method may return a value smaller than len? Is this really useful? Should the caller call it again and again until enough bytes are available?

> 
> 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 however.

These methods will prevent unnecessary System.arraycopy(). Will consider.

Thanks
Max

> 
> 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