1 /*
   2  * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.security;
  27 
  28 import java.util.Locale;
  29 import java.util.Objects;
  30 
  31 /**
  32  * This class specifies the parameters used by a DRBG.
  33  * <p>
  34  * According to
  35  * <a href="http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf">
  36  * NIST Special Publication 800-90A Revision 1, Recommendation for Random Number
  37  * Generation Using Deterministic Random Bit Generators</a>,
  38  * <blockquote>
  39  * A DRBG is based on a DRBG mechanism as specified in this Recommendation
  40  * and includes a source of randomness. A DRBG mechanism uses an algorithm
  41  * (i.e., a DRBG algorithm) that produces a sequence of bits from an initial
  42  * value that is determined by a seed that is determined from the output of
  43  * the randomness source."
  44  * </blockquote>
  45  * <p>
  46  * A DRBG implementation has a configuration, including but not limited to,
  47  * <ul>
  48  * <li> an entropy source,
  49  * <li> a DRBG mechanism (for example, Hash_DRBG),
  50  * <li> a DRBG algorithm (for example, SHA-256 for Hash_DRBG and AES-256
  51  *      for CTR_DRBG. Please note that it is not the algorithm used in
  52  *      {@link SecureRandom#getInstance}, which we will call
  53  *      a <em>SecureRandom algorithm</em> below),
  54  * <li> optionally supported features, including prediction resistance and reseed,
  55  * <li> highest security strength
  56  * </ul>
  57  * <p>
  58  * The configuration is defined by the implementation and not managed
  59  * by the {@code SecureRandom} API.
  60  * <p>
  61  * A DRBG instance is instantiated with parameters from an {@code Instantiate}
  62  * object and other information (for example, the nonce, which is not managed
  63  * by this API). This maps to the {@code Instantiate_function} defined in
  64  * NIST SP 800-90A.
  65  * <p>
  66  * Calling {@link SecureRandom#nextBytes(byte[], SecureRandomNextBytesParameters)}
  67  * and {@link SecureRandom#reseed(SecureRandomReseedParameters)} map to the
  68  * {@code Reseed_function} and {@code Generate_function} defined in
  69  * NIST SP 800-90A, separately. Calling {@link SecureRandom#nextBytes(byte[])}
  70  * is equivalent to calling
  71  * {@link SecureRandom#nextBytes(byte[], SecureRandomNextBytesParameters)}
  72  * with the instantiated strength and prediction resistance flag (as returned
  73  * in {@link SecureRandom#getParameters()}) with no additional input.
  74  * Calling {@link SecureRandom#reseed()} is equivalent to calling
  75  * {@link SecureRandom#reseed(SecureRandomReseedParameters)} with the
  76  * instantiated prediction resistance flag (as returned in
  77  * {@link SecureRandom#getParameters()}) with no additional input.
  78  * <p>
  79  * A DRBG should be implemented as a subclass of {@link SecureRandomSpi}.
  80  * It is recommended that the implementation contain
  81  * {@linkplain SecureRandomSpi#SecureRandomSpi(SecureRandomInstantiateParameters) a constructor}
  82  * that has a {@link DrbgParameters.Instantiate} argument. If implemented this way,
  83  * this implementation can be chosen by any {@code SecureRandom.getInstance()}
  84  * method. If it is chosen by a {@code SecureRandom.getInstance()} with a
  85  * {@link SecureRandomInstantiateParameters} parameter, the parameter is passed
  86  * into this constructor. If it is chosen by a {@code SecureRandom.getInstance()}
  87  * without a {@link SecureRandomInstantiateParameters} parameter, the constructor
  88  * is called with a {@code null} argument and the implementation should choose
  89  * its own parameters. Its {@link SecureRandom#getParameters()} must always
  90  * return a non-null effective {@link Instantiate} object that reflects how the DRBG
  91  * is actually instantiated. A caller can use this information to determine
  92  * whether a {@code SecureRandom} object is a DRBG and what features it supports.
  93  * Please note that the returned value does not necessarily equal to the
  94  * {@code Instantiate} object passed into the {@code SecureRandom.getInstance()}
  95  * call. For example, the requested capability can be {@link Capability#NONE}
  96  * but the returned capability can be {@link Capability#RESEED_ONLY} if the
  97  * implementation supports reseeding. The implementation must implement the
  98  * {@link SecureRandomSpi#engineNextBytes(byte[], SecureRandomNextBytesParameters)}
  99  * method which takes a {@link NextBytes} parameter. Unless the result of
 100  * {@link SecureRandom#getParameters()} has its
 101  * {@linkplain Instantiate#getCapability() capability} being
 102  * {@link Capability#NONE NONE}, it must implement
 103  * {@link SecureRandomSpi#engineReseed(SecureRandomReseedParameters)}
 104  * which takes a {@link Reseed} parameter.
 105  * <p>
 106  * On the other hand, if a DRBG implementation does not contain a
 107  * constructor that has an {@link Instantiate} argument (not recommended),
 108  * it can only be chosen by a {@code SecureRandom.getInstance()}
 109  * without a {@link SecureRandomInstantiateParameters} parameter, but will not be chosen if a {@code getInstance} method with a
 110  * {@link SecureRandomInstantiateParameters} parameter is called. If
 111  * implemented this way, its {@link SecureRandom#getParameters()} must return
 112  * {@code null}, and it does not need to implement either
 113  * {@link SecureRandomSpi#engineNextBytes(byte[], SecureRandomNextBytesParameters)}
 114  * or {@link SecureRandomSpi#engineReseed(SecureRandomReseedParameters)}.
 115  * <p>
 116  * A DRBG might reseed itself automatically if the seed period is bigger
 117  * than the maximum seed life defined by the DRBG mechanism.
 118  * <p>
 119  * Examples:
 120  * <blockquote><pre>
 121  * SecureRandom drbg;
 122  * byte[] buffer = new byte[32];
 123  *
 124  * // Any DRBG is OK
 125  * drbg = SecureRandom.getInstance("DRBG");
 126  * drbg.nextBytes(buffer);
 127  *
 128  * SecureRandomInstantiateParameters params = drbg.getParameters();
 129  * if (params instanceof DrbgParameters.Instantiate) {
 130  *     DrbgParameters.Instantiate ins = (DrbgParameters.Instantiate) params;
 131  *     if (ins.getCapability() != NONE) {
 132  *         drbg.reseed();
 133  *     }
 134  * }
 135  *
 136  * // This might return a weak DRBG instance. It is only guaranteed to support
 137  * // 112 bits of security strength.
 138  * drbg = SecureRandom.getInstance("DRBG",
 139  *         DrbgParameters.instantiate(112, NONE, null);
 140  *
 141  * // Both the next two calls will likely fail, because drbg could be
 142  * // instantiated with a smaller strength with no prediction resistance
 143  * // support.
 144  * drbg.nextBytes(buffer,
 145  *         DrbgParameters.nextBytes(256, false, "more".getBytes()));
 146  * drbg.nextBytes(buffer,
 147  *         DrbgParameters.nextBytes(112, true, "more".getBytes()));
 148  *
 149  * // This returns a strong DRBG instance, with a personalization string.
 150  * // It is guaranteed to support 256 bits of security strength with
 151  * // prediction resistance turned on.
 152  * drbg = SecureRandom.getInstance("DRBG",
 153  *         DrbgParameters.instantiate(256, PR_AND_RESEED, "hello".getBytes()));
 154  *
 155  * // Prediction resistance is not requested in this single call,
 156  * // but an additional input is used.
 157  * drbg.nextBytes(buffer,
 158  *         DrbgParameters.nextBytes(-1, false, "more".getBytes()));
 159  *
 160  * // Same for this call.
 161  * drbg.reseed(DrbgParameters.reseed(false, "extra".getBytes()));
 162  * </pre></blockquote>
 163  *
 164  * @implSpec
 165  * By convention, a provider should name its primary DRBG implementation
 166  * with the <a href=
 167  * "{@docRoot}/../technotes/guides/security/StandardNames.html#SecureRandom">
 168  * standard {@code SecureRandom} algorithm name</a> "DRBG". How this implementation
 169  * is configured is provider-specific. A provider is free to add other DRBG
 170  * implementations with specific configurations using different {@code SecureRandom}
 171  * algorithm names (for example, "Hash_DRBG/SHA-512").
 172  *
 173  * @implNote
 174  * The following notes apply to the "DRBG" implementation in the SUN provider
 175  * of the JDK reference implementation.
 176  * <p>
 177  * This implementation supports the Hash_DRBG and HMAC_DRBG mechanisms with
 178  * DRBG algorithm names SHA-1, SHA-224, SHA-512/224, SHA-256, SHA-512/256,
 179  * SHA-384 and SHA-512, and CTR_DRBG (both using derivation function and
 180  * not using derivation function) with DRBG algorithm names DESede
 181  * (aka 3 Key TDEA), AES-128, AES-192 and AES-256.
 182  * <p>
 183  * The mechanism name and DRBG algorithm name can be configured with the
 184  * {@linkplain Security#getProperty(String) security property} {@code drbg}.
 185  * The default configuration is Hash_DRBG with SHA-256.
 186  * <p>
 187  * For each combination, the security strength can be requested from 112
 188  * up to the highest strength it supports. Reseeding is supported, and
 189  * prediction resistance can be turned on or off.
 190  * <p>
 191  * Personalization string is supported through the
 192  * {@link DrbgParameters.Instantiate} class and additional input is supported
 193  * through the {@link DrbgParameters.NextBytes}
 194  * and {@link DrbgParameters.Reseed} classes.
 195  * <p>
 196  * If a DRBG is not instantiated with a {@link DrbgParameters.Instantiate}
 197  * object explicitly, this implementation instantiates it with a default
 198  * requested strength of 128 bits, no prediction resistance request, and
 199  * no personalization string. These default instantiation parameters can also
 200  * be customized with the {@code drbg} security property.
 201  * <p>
 202  * This implementation reads fresh entropy from the system default entropy
 203  * source determined by the security property {@code securerandom.source}.
 204  * <p>
 205  * This implementation has passed all tests included in the 20151104 version of
 206  * <a href="http://csrc.nist.gov/groups/STM/cavp/documents/drbg/drbgtestvectors.zip">
 207  * The DRBG Test Vectors</a>.
 208  * <p>
 209  * Calling {@link SecureRandom#generateSeed(int)} will directly read
 210  * from a DRBG's entropy source.
 211  *
 212  * @since 9
 213  */
 214 public class DrbgParameters {
 215 
 216     private DrbgParameters() {
 217         // This class should not be instantiated
 218     }
 219 
 220     /**
 221      * The reseedable and prediction resistance capabilities of a DRBG.
 222      * <p>
 223      * When this object is used in a {@code SecureRandom.getInstance()} call,
 224      * it means the required minimum capability. When used in
 225      * {@code SecureRandom.getParameters()}, it means the effective capability.
 226      * <p>
 227      * A DRBG implementation supporting prediction resistance must also
 228      * support reseeding.
 229      *
 230      * @see Instantiate#getCapability()
 231      * @since 9
 232      */
 233     public enum Capability {
 234         /** Both prediction resistance and reseed. */
 235         PR_AND_RESEED,
 236         /** Reseed but no prediction resistance. */
 237         RESEED_ONLY,
 238         /** Neither prediction resistance nor reseed. */
 239         NONE;
 240 
 241         @Override
 242         public String toString() {
 243             return name().toLowerCase(Locale.ROOT);
 244         }
 245     }
 246 
 247     /**
 248      * DRBG parameters for instantiation.
 249      * <p>
 250      * When used in
 251      * {@link SecureRandom#getInstance(String, SecureRandomInstantiateParameters)}
 252      * or one of the other similar {@code getInstance} calls that take a
 253      * {@code SecureRandomInstantiateParameters} parameter, it means the
 254      * requested instantiate parameters the newly created {@code SecureRandom} object
 255      * must support. When used as the return value of the
 256      * {@link SecureRandom#getParameters()} method, it means the effective
 257      * instantiate parameters of the {@code SecureRandom} object.
 258      *
 259      * @since 9
 260      */
 261     public static final class Instantiate
 262             implements SecureRandomInstantiateParameters {
 263 
 264         private final int strength;
 265         private final Capability capability;
 266         private final byte[] personalizationString;
 267 
 268         /**
 269          * Returns the strength.
 270          *
 271          * @return if used in {@code getInstance}, returns the minimum strength
 272          * requested, or -1 if there is no specific request on the strength.
 273          * If used in {@code getParameters}, returns the actual initiated strength.
 274          * The actual strength must be greater than or equal to the minimum
 275          * strength requested.
 276          */
 277         public int getStrength() {
 278             return strength;
 279         }
 280 
 281         /**
 282          * Returns the capability.
 283          * <p>
 284          * Please note that while the {@code Instantiate_function} defined in
 285          * NIST SP 800-90A only includes a {@code prediction_resistance_flag}
 286          * parameter, the {@code Capability} type includes extra values
 287          * for reseeding. If {@code NONE} or {@code RESEED_ONLY} is used in
 288          * an {@code Instantiate} object in calling the
 289          * {@code SecureRandom.getInstance} method, the returned DRBG instance
 290          * is not guaranteed to support reseed. If {@code RESEED_ONLY} or
 291          * {@code PR_AND_RESEED} is used, the instance must support reseed.
 292          * <p>
 293          * The table below lists possible effective values if a certain
 294          * capability is requested, i.e.
 295          * <blockquote><pre>
 296          * Capability req = ...;
 297          * SecureRandom s = SecureRandom.getInstance("DRBG",
 298          *         DrbgParameters(-1, req, null));
 299          * Capability eff = ((DrbgParametes.Initiate) s.getParameters())
 300          *         .getCapability();
 301          * </pre></blockquote>
 302          * <table border=1 summary="requested and effective capabilities">
 303          * <tr>
 304          * <th>Requested Value ({@code req})</th>
 305          * <th>Possible Effective Values ({@code eff})</th>
 306          * </tr>
 307          * <tr><td>NONE</td><td>NONE, RESEED_ONLY, PR_AND_RESEED</td></tr>
 308          * <tr><td>RESEED_ONLY</td><td>RESEED_ONLY, PR_AND_RESEED</td></tr>
 309          * <tr><td>PR_AND_RESEED</td><td>PR_AND_RESEED</td></tr>
 310          * </table>
 311          *
 312          * @return If used in {@code getInstance}, returns the minimum capability
 313          * requested. If used in {@code getParameters}, returns how the DRBG
 314          * is actually instantiated and whether it supports reseeding.
 315          */
 316         public Capability getCapability() {
 317             return capability;
 318         }
 319 
 320         /**
 321          * Returns the personalization string as a byte array.
 322          *
 323          * @return If used in {@code getInstance}, returns the requested
 324          * personalization string as a newly allocated array, or {@code null}
 325          * if no personalization string is requested. The same string
 326          * should be returned in {@code getParameters}
 327          * as a new copy, or {@code null} if no personalization string
 328          * is requested in {@code getInstance}.
 329          */
 330         public byte[] getPersonalizationString() {
 331             return personalizationString == null?
 332                     null: personalizationString.clone();
 333         }
 334 
 335         private Instantiate(int strength, Capability capability,
 336                             byte[] personalizationString) {
 337             this.strength = strength;
 338             this.capability = capability;
 339             this.personalizationString = personalizationString == null
 340                     ? null: personalizationString.clone();
 341         }
 342 
 343         @Override
 344         public String toString() {
 345             // I don't care what personalizationString looks like
 346             return strength + "," + capability + "," + personalizationString;
 347         }
 348     }
 349 
 350     /**
 351      * DRBG parameters for random bits generation. It is used in
 352      * {@link SecureRandom#nextBytes(byte[], SecureRandomNextBytesParameters)}.
 353      *
 354      * @since 9
 355      */
 356     public static final class NextBytes
 357             implements SecureRandomNextBytesParameters {
 358         private final int strength;
 359         private final boolean predictionResistance;
 360         private final byte[] additionalInput;
 361 
 362         /**
 363          * Returns the strength requested.
 364          *
 365          * @return the strength requested, or -1 if the instantiated strength
 366          *      should be used.
 367          */
 368         public int getStrength() {
 369             return strength;
 370         }
 371 
 372         /**
 373          * Returns whether prediction resistance is requested.
 374          *
 375          * @return whether prediction resistance is requested
 376          */
 377         public boolean getPredictionResistance() {
 378             return predictionResistance;
 379         }
 380 
 381         /**
 382          * Returns the requested additional input.
 383          *
 384          * @return the requested additional input, {@code null} if
 385          * not requested. A new byte array is returned each time this method
 386          * is called.
 387          */
 388         public byte[] getAdditionalInput() {
 389             return additionalInput == null? null: additionalInput.clone();
 390         }
 391 
 392         private NextBytes(int strength, boolean predictionResistance,
 393                           byte[] additionalInput) {
 394             this.strength = strength;
 395             this.predictionResistance = predictionResistance;
 396             this.additionalInput = additionalInput == null?
 397                     null: additionalInput.clone();
 398         }
 399     }
 400 
 401     /**
 402      * DRBG parameters for reseed. It is used in
 403      * {@link SecureRandom#reseed(SecureRandomReseedParameters)}.
 404      *
 405      * @since 9
 406      */
 407     public static final class Reseed implements SecureRandomReseedParameters {
 408 
 409         private final byte[] additionalInput;
 410         private final boolean predictionResistance;
 411 
 412         /**
 413          * Returns whether prediction resistance is requested.
 414          *
 415          * @return whether prediction resistance is requested
 416          */
 417         public boolean getPredictionResistance() {
 418             return predictionResistance;
 419         }
 420 
 421         /**
 422          * Returns the requested additional input.
 423          *
 424          * @return the requested additional input, {@code null} if
 425          * not requested. A new byte array is returned each time this method
 426          * is called.
 427          */
 428         public byte[] getAdditionalInput() {
 429             return additionalInput == null? null: additionalInput.clone();
 430         }
 431 
 432         private Reseed(boolean predictionResistance, byte[] additionalInput) {
 433             this.predictionResistance = predictionResistance;
 434             this.additionalInput = additionalInput == null?
 435                     null: additionalInput.clone();
 436         }
 437     }
 438 
 439     /**
 440      * Generates a {@link DrbgParameters.Instantiate} object.
 441      *
 442      * @param strength security strength, -1 for a default strength if used
 443      *                 in {@code getInstance}.
 444      * @param capability capability
 445      * @param personalizationString personalization string as a byte array,
 446      *                              can be {@code null}. The content of this
 447      *                              byte array will be copied.
 448      * @return a new {@code Instantiate} object
 449      * @throws NullPointerException if {@code capacity} is {@code null}.
 450      */
 451     public static Instantiate instantiate(int strength,
 452                                           Capability capability,
 453                                           byte[] personalizationString) {
 454         return new Instantiate(strength, Objects.requireNonNull(capability),
 455                 personalizationString);
 456     }
 457 
 458     /**
 459      * Generates a {@link NextBytes} object.
 460      *
 461      * @param strength requested strength, -1 means the effective instantiated
 462      *                 strength should be used.
 463      * @param predictionResistance prediction resistance requested
 464      * @param additionalInput additional input, can be {@code null}.
 465      *                        The content of this byte array will be copied.
 466      * @return a new {@code NextBytes} object
 467      */
 468     public static NextBytes nextBytes(int strength,
 469                                       boolean predictionResistance,
 470                                       byte[] additionalInput) {
 471         return new NextBytes(strength, predictionResistance, additionalInput);
 472     }
 473 
 474     /**
 475      * Generates a {@link Reseed} object.
 476      *
 477      * @param predictionResistance prediction resistance requested
 478      * @param additionalInput additional input, can be {@code null}.
 479      *                        The content of this byte array will be copied.
 480      * @return a new {@code Reseed} object
 481      */
 482     public static Reseed reseed(
 483             boolean predictionResistance, byte[] additionalInput) {
 484         return new Reseed(predictionResistance, additionalInput);
 485     }
 486 }