/*
 * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package java.security;

import java.util.Arrays;
import java.util.Locale;
import java.util.Objects;

/**
 * This class specifies the parameters used by a DRBG (Deterministic
 * Random Bit Generator).
 * <p>
 * According to
 * <a href="https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf">
 * NIST Special Publication 800-90A Revision 1, Recommendation for Random
 * Number Generation Using Deterministic Random Bit Generators</a> (800-90Ar1),
 * <blockquote>
 * A DRBG is based on a DRBG mechanism as specified in this Recommendation
 * and includes a source of randomness. A DRBG mechanism uses an algorithm
 * (i.e., a DRBG algorithm) that produces a sequence of bits from an initial
 * value that is determined by a seed that is determined from the output of
 * the randomness source."
 * </blockquote>
 * <p>
 * The 800-90Ar1 specification allows for a variety of DRBG implementation
 * choices, such as:
 * <ul>
 * <li> an entropy source,
 * <li> a DRBG mechanism (for example, Hash_DRBG),
 * <li> a DRBG algorithm (for example, SHA-256 for Hash_DRBG and AES-256
 * for CTR_DRBG. Please note that it is not the algorithm used in
 * {@link SecureRandom#getInstance}, which we will call a
 * <em>SecureRandom algorithm</em> below),
 * <li> optional features, including prediction resistance
 * and reseeding supports,
 * <li> highest security strength.
 * </ul>
 * <p>
 * These choices are set in each implementation and are not directly
 * managed by the {@code SecureRandom} API.  Check your DRBG provider's
 * documentation to find an appropriate implementation for the situation.
 * <p>
 * On the other hand, the 800-90Ar1 specification does have some configurable
 * options, such as:
 * <ul>
 * <li> required security strength,
 * <li> if prediction resistance is required,
 * <li> personalization string and additional input.
 * </ul>
 * <p>
 * A DRBG instance can be instantiated with parameters from an
 * {@link DrbgParameters.Instantiation} object and other information
 * (for example, the nonce, which is not managed by this API). This maps
 * to the {@code Instantiate_function} defined in NIST SP 800-90Ar1.
 * <p>
 * A DRBG instance can be reseeded with parameters from a
 * {@link DrbgParameters.Reseed} object. This maps to the
 * {@code Reseed_function} defined in NIST SP 800-90Ar1. Calling
 * {@link SecureRandom#reseed()} is equivalent to calling
 * {@link SecureRandom#reseed(SecureRandomParameters)} with the effective
 * instantiated prediction resistance flag (as returned by
 * {@link SecureRandom#getParameters()}) with no additional input.
 * <p>
 * A DRBG instance generates data with additional parameters from a
 * {@link DrbgParameters.NextBytes} object. This maps to the
 * {@code Generate_function} defined in NIST SP 800-90Ar1. Calling
 * {@link SecureRandom#nextBytes(byte[])} is equivalent to calling
 * {@link SecureRandom#nextBytes(byte[], SecureRandomParameters)}
 * with the effective instantiated strength and prediction resistance flag
 * (as returned by {@link SecureRandom#getParameters()}) with no
 * additional input.
 * <p>
 * A DRBG should be implemented as a subclass of {@link SecureRandomSpi}.
 * It is recommended that the implementation contain the 1-arg
 * {@linkplain SecureRandomSpi#SecureRandomSpi(SecureRandomParameters) constructor}
 * that takes a {@code DrbgParameters.Instantiation} argument. If implemented
 * this way, this implementation can be chosen by any
 * {@code SecureRandom.getInstance()} method. If it is chosen by a
 * {@code SecureRandom.getInstance()} with a {@link SecureRandomParameters}
 * parameter, the parameter is passed into this constructor. If it is chosen
 * by a {@code SecureRandom.getInstance()} without a
 * {@code SecureRandomParameters} parameter, the constructor is called with
 * a {@code null} argument and the implementation should choose its own
 * parameters. Its {@link SecureRandom#getParameters()} must always return a
 * non-null effective {@code DrbgParameters.Instantiation} object that reflects
 * how the DRBG is actually instantiated. A caller can use this information
 * to determine whether a {@code SecureRandom} object is a DRBG and what
 * features it supports. Please note that the returned value does not
 * necessarily equal to the {@code DrbgParameters.Instantiation} object passed
 * into the {@code SecureRandom.getInstance()} call. For example,
 * the requested capability can be {@link DrbgParameters.Capability#NONE}
 * but the effective value can be {@link DrbgParameters.Capability#RESEED_ONLY}
 * if the implementation supports reseeding. The implementation must implement
 * the {@link SecureRandomSpi#engineNextBytes(byte[], SecureRandomParameters)}
 * method which takes a {@code DrbgParameters.NextBytes} parameter. Unless
 * the result of {@link SecureRandom#getParameters()} has its
 * {@linkplain DrbgParameters.Instantiation#getCapability() capability} being
 * {@link Capability#NONE NONE}, it must implement
 * {@link SecureRandomSpi#engineReseed(SecureRandomParameters)} which takes
 * a {@code DrbgParameters.Reseed} parameter.
 * <p>
 * On the other hand, if a DRBG implementation does not contain a constructor
 * that has an {@code DrbgParameters.Instantiation} argument (not recommended),
 * it can only be chosen by a {@code SecureRandom.getInstance()} without
 * a {@code SecureRandomParameters} parameter, but will not be chosen if
 * a {@code getInstance} method with a {@code SecureRandomParameters} parameter
 * is called. If implemented this way, its {@link SecureRandom#getParameters()}
 * must return {@code null}, and it does not need to implement either
 * {@link SecureRandomSpi#engineNextBytes(byte[], SecureRandomParameters)}
 * or {@link SecureRandomSpi#engineReseed(SecureRandomParameters)}.
 * <p>
 * A DRBG might reseed itself automatically if the seed period is bigger
 * than the maximum seed life defined by the DRBG mechanism.
 * <p>
 * A DRBG implementation should support serialization and deserialization
 * by retaining the configuration and effective parameters, but the internal
 * state must not be serialized and the deserialized object must be
 * reinstantiated.
 * <p>
 * Examples:
 * <blockquote><pre>
 * SecureRandom drbg;
 * byte[] buffer = new byte[32];
 *
 * // Any DRBG is OK
 * drbg = SecureRandom.getInstance("DRBG");
 * drbg.nextBytes(buffer);
 *
 * SecureRandomParameters params = drbg.getParameters();
 * if (params instanceof DrbgParameters.Instantiation) {
 *     DrbgParameters.Instantiation ins = (DrbgParameters.Instantiation) params;
 *     if (ins.getCapability().supportsReseeding()) {
 *         drbg.reseed();
 *     }
 * }
 *
 * // The following call requests a weak DRBG instance. It is only
 * // guaranteed to support 112 bits of security strength.
 * drbg = SecureRandom.getInstance("DRBG",
 *         DrbgParameters.instantiation(112, NONE, null));
 *
 * // Both the next two calls will likely fail, because drbg could be
 * // instantiated with a smaller strength with no prediction resistance
 * // support.
 * drbg.nextBytes(buffer,
 *         DrbgParameters.nextBytes(256, false, "more".getBytes()));
 * drbg.nextBytes(buffer,
 *         DrbgParameters.nextBytes(112, true, "more".getBytes()));
 *
 * // The following call requests a strong DRBG instance, with a
 * // personalization string. If it successfully returns an instance,
 * // that instance is guaranteed to support 256 bits of security strength
 * // with prediction resistance available.
 * drbg = SecureRandom.getInstance("DRBG", DrbgParameters.instantiation(
 *         256, PR_AND_RESEED, "hello".getBytes()));
 *
 * // Prediction resistance is not requested in this single call,
 * // but an additional input is used.
 * drbg.nextBytes(buffer,
 *         DrbgParameters.nextBytes(-1, false, "more".getBytes()));
 *
 * // Same for this call.
 * drbg.reseed(DrbgParameters.reseed(false, "extra".getBytes()));</pre>
 * </blockquote>
 *
 * @implSpec
 * By convention, a provider should name its primary DRBG implementation
 * with the <a href=
 * "{@docRoot}/../specs/security/standard-names.html#securerandom-number-generation-algorithms">
 * standard {@code SecureRandom} algorithm name</a> "DRBG".
 *
 * @implNote
 * The following notes apply to the "DRBG" implementation in the SUN provider
 * of the JDK reference implementation.
 * <p>
 * This implementation supports the Hash_DRBG and HMAC_DRBG mechanisms with
 * DRBG algorithm SHA-224, SHA-512/224, SHA-256, SHA-512/256, SHA-384 and
 * SHA-512, and CTR_DRBG (both using derivation function and not using
 * derivation function) with DRBG algorithm AES-128, AES-192 and AES-256.
 * <p>
 * The mechanism name and DRBG algorithm name are determined by the
 * {@linkplain Security#getProperty(String) security property}
 * {@code securerandom.drbg.config}. The default choice is Hash_DRBG
 * with SHA-256.
 * <p>
 * For each combination, the security strength can be requested from 112
 * up to the highest strength it supports. Both reseeding and prediction
 * resistance are supported.
 * <p>
 * Personalization string is supported through the
 * {@link DrbgParameters.Instantiation} class and additional input is supported
 * through the {@link DrbgParameters.NextBytes} and
 * {@link DrbgParameters.Reseed} classes.
 * <p>
 * If a DRBG is not instantiated with a {@link DrbgParameters.Instantiation}
 * object explicitly, this implementation instantiates it with a default
 * requested strength of 128 bits, no prediction resistance request, and
 * no personalization string. These default instantiation parameters can also
 * be customized with the {@code securerandom.drbg.config} security property.
 * <p>
 * This implementation reads fresh entropy from the system default entropy
 * source determined by the security property {@code securerandom.source}.
 * <p>
 * Calling {@link SecureRandom#generateSeed(int)} will directly read
 * from this system default entropy source.
 *
 * @spec https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf
 *      Recommendation for Random Number Generation Using Deterministic Random Bit Generators
 * @spec security/standard-names.html Java Security Standard Algorithm Names
 *
 * @since 9
 */
public final class DrbgParameters {

    private DrbgParameters() {
        // This class should not be instantiated
    }

    /**
     * The reseedable and prediction resistance capabilities of a DRBG.
     * <p>
     * When this object is passed to a {@code SecureRandom.getInstance()} call,
     * it is the requested minimum capability. When it's returned from
     * {@code SecureRandom.getParameters()}, it is the effective capability.
     * <p>
     * Please note that while the {@code Instantiate_function} defined in
     * NIST SP 800-90Ar1 only includes a {@code prediction_resistance_flag}
     * parameter, the {@code Capability} type includes an extra value
     * {@link #RESEED_ONLY} because reseeding is an optional function.
     * If {@code NONE} is used in an {@code Instantiation} object in calling the
     * {@code SecureRandom.getInstance} method, the returned DRBG instance
     * is not guaranteed to support reseeding. If {@code RESEED_ONLY} or
     * {@code PR_AND_RESEED} is used, the instance must support reseeding.
     * <p>
     * The table below lists possible effective values if a certain
     * capability is requested, i.e.
     * <blockquote><pre>
     * Capability requested = ...;
     * SecureRandom s = SecureRandom.getInstance("DRBG",
     *         DrbgParameters(-1, requested, null));
     * Capability effective = ((DrbgParametes.Initiate) s.getParameters())
     *         .getCapability();</pre>
     * </blockquote>
     * <table class="striped">
     * <caption style="display:none">requested and effective capabilities</caption>
     * <thead>
     * <tr>
     * <th scope="col">Requested Value</th>
     * <th scope="col">Possible Effective Values</th>
     * </tr>
     * </thead>
     * <tbody style="text-align:left">
     * <tr><th scope="row">NONE</th><td>NONE, RESEED_ONLY, PR_AND_RESEED</td></tr>
     * <tr><th scope="row">RESEED_ONLY</th><td>RESEED_ONLY, PR_AND_RESEED</td></tr>
     * <tr><th scope="row">PR_AND_RESEED</th><td>PR_AND_RESEED</td></tr>
     * </tbody>
     * </table>
     * <p>
     * A DRBG implementation supporting prediction resistance must also
     * support reseeding.
     *
     * @since 9
     */
    public enum Capability {

        /**
         * Both prediction resistance and reseed.
         */
        PR_AND_RESEED,

        /**
         * Reseed but no prediction resistance.
         */
        RESEED_ONLY,

        /**
         * Neither prediction resistance nor reseed.
         */
        NONE;

        @Override
        public String toString() {
            return name().toLowerCase(Locale.ROOT);
        }

        /**
         * Returns whether this capability supports reseeding.
         *
         * @return {@code true} for {@link #PR_AND_RESEED} and
         *      {@link #RESEED_ONLY}, and {@code false} for {@link #NONE}
         */
        public boolean supportsReseeding() {
            return this != NONE;
        }

        /**
         * Returns whether this capability supports prediction resistance.
         *
         * @return {@code true} for {@link #PR_AND_RESEED}, and {@code false}
         *      for {@link #RESEED_ONLY} and {@link #NONE}
         */
        public boolean supportsPredictionResistance() {
            return this == PR_AND_RESEED;
        }
    }

    /**
     * DRBG parameters for instantiation.
     * <p>
     * When used in
     * {@link SecureRandom#getInstance(String, SecureRandomParameters)}
     * or one of the other similar {@code getInstance} calls that take a
     * {@code SecureRandomParameters} parameter, it means the
     * requested instantiate parameters the newly created {@code SecureRandom}
     * object must minimally support. When used as the return value of the
     * {@link SecureRandom#getParameters()} method, it means the effective
     * instantiate parameters of the {@code SecureRandom} object.
     *
     * @since 9
     */
    public static final class Instantiation
            implements SecureRandomParameters {

        private final int strength;
        private final Capability capability;
        private final byte[] personalizationString;

        /**
         * Returns the security strength in bits.
         *
         * @return If used in {@code getInstance}, returns the minimum strength
         * requested, or -1 if there is no specific request on the strength.
         * If used in {@code getParameters}, returns the effective strength.
         * The effective strength must be greater than or equal to the minimum
         * strength requested.
         */
        public int getStrength() {
            return strength;
        }

        /**
         * Returns the capability.
         *
         * @return If used in {@code getInstance}, returns the minimum
         * capability requested. If used in {@code getParameters}, returns
         * information on the effective prediction resistance flag and
         * whether it supports reseeding.
         */
        public Capability getCapability() {
            return capability;
        }

        /**
         * Returns the personalization string as a byte array.
         *
         * @return If used in {@code getInstance}, returns the requested
         * personalization string as a newly allocated array, or {@code null}
         * if no personalization string is requested. The same string should
         * be returned in {@code getParameters} as a new copy, or {@code null}
         * if no personalization string is requested in {@code getInstance}.
         */
        public byte[] getPersonalizationString() {
            return (personalizationString == null) ?
                    null : personalizationString.clone();
        }

        private Instantiation(int strength, Capability capability,
                              byte[] personalizationString) {
            if (strength < -1) {
                throw new IllegalArgumentException(
                        "Illegal security strength: " + strength);
            }
            this.strength = strength;
            this.capability = capability;
            this.personalizationString = (personalizationString == null) ?
                    null : personalizationString.clone();
        }

        /**
         * Returns a Human-readable string representation of this
         * {@code Instantiation}.
         *
         * @return the string representation
         */
        @Override
        public String toString() {
            // I don't care what personalizationString looks like
            return strength + "," + capability + "," + Arrays.toString(personalizationString);
        }
    }

    /**
     * DRBG parameters for random bits generation. It is used in
     * {@link SecureRandom#nextBytes(byte[], SecureRandomParameters)}.
     *
     * @since 9
     */
    public static final class NextBytes
            implements SecureRandomParameters {
        private final int strength;
        private final boolean predictionResistance;
        private final byte[] additionalInput;

        /**
         * Returns the security strength requested in bits.
         *
         * @return the strength requested, or -1 if the effective strength
         *      should be used.
         */
        public int getStrength() {
            return strength;
        }

        /**
         * Returns whether prediction resistance is requested.
         *
         * @return whether prediction resistance is requested
         */
        public boolean getPredictionResistance() {
            return predictionResistance;
        }

        /**
         * Returns the requested additional input.
         *
         * @return the requested additional input, {@code null} if not
         * requested. A new byte array is returned each time this method
         * is called.
         */
        public byte[] getAdditionalInput() {
            return additionalInput == null? null: additionalInput.clone();
        }

        private NextBytes(int strength, boolean predictionResistance,
                          byte[] additionalInput) {
            if (strength < -1) {
                throw new IllegalArgumentException(
                        "Illegal security strength: " + strength);
            }
            this.strength = strength;
            this.predictionResistance = predictionResistance;
            this.additionalInput = (additionalInput == null) ?
                    null : additionalInput.clone();
        }
    }

    /**
     * DRBG parameters for reseed. It is used in
     * {@link SecureRandom#reseed(SecureRandomParameters)}.
     *
     * @since 9
     */
    public static final class Reseed implements SecureRandomParameters {

        private final byte[] additionalInput;
        private final boolean predictionResistance;

        /**
         * Returns whether prediction resistance is requested.
         *
         * @return whether prediction resistance is requested
         */
        public boolean getPredictionResistance() {
            return predictionResistance;
        }

        /**
         * Returns the requested additional input.
         *
         * @return the requested additional input, or {@code null} if
         * not requested. A new byte array is returned each time this method
         * is called.
         */
        public byte[] getAdditionalInput() {
            return additionalInput == null ? null : additionalInput.clone();
        }

        private Reseed(boolean predictionResistance, byte[] additionalInput) {
            this.predictionResistance = predictionResistance;
            this.additionalInput = (additionalInput == null) ?
                    null : additionalInput.clone();
        }
    }

    /**
     * Generates a {@link DrbgParameters.Instantiation} object.
     *
     * @param strength security strength in bits, -1 for default strength
     *                 if used in {@code getInstance}.
     * @param capability capability
     * @param personalizationString personalization string as a byte array,
     *                              can be {@code null}. The content of this
     *                              byte array will be copied.
     * @return a new {@code Instantiation} object
     * @throws NullPointerException if {@code capability} is {@code null}
     * @throws IllegalArgumentException if {@code strength} is less than -1
     */
    public static Instantiation instantiation(int strength,
                                              Capability capability,
                                              byte[] personalizationString) {
        return new Instantiation(strength, Objects.requireNonNull(capability),
                personalizationString);
    }

    /**
     * Generates a {@link NextBytes} object.
     *
     * @param strength requested security strength in bits. If set to -1, the
     *                 effective strength will be used.
     * @param predictionResistance prediction resistance requested
     * @param additionalInput additional input, can be {@code null}.
     *                        The content of this byte array will be copied.
     * @throws IllegalArgumentException if {@code strength} is less than -1
     * @return a new {@code NextBytes} object
     */
    public static NextBytes nextBytes(int strength,
                                      boolean predictionResistance,
                                      byte[] additionalInput) {
        return new NextBytes(strength, predictionResistance, additionalInput);
    }

    /**
     * Generates a {@link Reseed} object.
     *
     * @param predictionResistance prediction resistance requested
     * @param additionalInput additional input, can be {@code null}.
     *                        The content of this byte array will be copied.
     * @return a new {@code Reseed} object
     */
    public static Reseed reseed(
            boolean predictionResistance, byte[] additionalInput) {
        return new Reseed(predictionResistance, additionalInput);
    }
}
