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 (Deterministic
  33  * Random Bit Generator).
  34  * <p>
  35  * According to
  36  * <a href="http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf">
  37  * NIST Special Publication 800-90A Revision 1, Recommendation for Random
  38  * Number Generation Using Deterministic Random Bit Generators</a> (800-90Ar1),
  39  * <blockquote>
  40  * A DRBG is based on a DRBG mechanism as specified in this Recommendation
  41  * and includes a source of randomness. A DRBG mechanism uses an algorithm
  42  * (i.e., a DRBG algorithm) that produces a sequence of bits from an initial
  43  * value that is determined by a seed that is determined from the output of
  44  * the randomness source."
  45  * </blockquote>
  46  * <p>
  47  * The 800-90Ar1 specification allows for a variety of DRBG implementation
  48  * choices, such as:
  49  * <ul>
  50  * <li> an entropy source,
  51  * <li> a DRBG mechanism (for example, Hash_DRBG),
  52  * <li> a DRBG algorithm (for example, SHA-256 for Hash_DRBG and AES-256
  53  * for CTR_DRBG. Please note that it is not the algorithm used in
  54  * {@link SecureRandom#getInstance}, which we will call a
  55  * <em>SecureRandom algorithm</em> below),
  56  * <li> optional features, including prediction resistance
  57  * and reseeding supports,
  58  * <li> highest security strength.
  59  * </ul>
  60  * <p>
  61  * These choices are set in each implementation and are not directly
  62  * managed by the {@code SecureRandom} API.  Check your DRBG provider's
  63  * documentation to find an appropriate implementation for the situation.
  64  * <p>
  65  * On the other hand, the 800-90Ar1 specification does have some configurable
  66  * options, such as:
  67  * <ul>
  68  * <li> required security strength,
  69  * <li> if prediction resistance is required,
  70  * <li> personalization string and additional input.
  71  * </ul>
  72  * <p>
  73  * A DRBG instance can be instantiated with parameters from an
  74  * {@link DrbgParameters.Instantiation} object and other information
  75  * (for example, the nonce, which is not managed by this API). This maps
  76  * to the {@code Instantiate_function} defined in NIST SP 800-90Ar1.
  77  * <p>
  78  * A DRBG instance can be reseeded with parameters from a
  79  * {@link DrbgParameters.Reseed} object. This maps to the
  80  * {@code Reseed_function} defined in NIST SP 800-90Ar1. Calling
  81  * {@link SecureRandom#reseed()} is equivalent to calling
  82  * {@link SecureRandom#reseed(SecureRandomParameters)} with the effective
  83  * instantiated prediction resistance flag (as returned by
  84  * {@link SecureRandom#getParameters()}) with no additional input.
  85  * <p>
  86  * A DRBG instance generates data with additional parameters from a
  87  * {@link DrbgParameters.NextBytes} object. This maps to the
  88  * {@code Generate_function} defined in NIST SP 800-90Ar1. Calling
  89  * {@link SecureRandom#nextBytes(byte[])} is equivalent to calling
  90  * {@link SecureRandom#nextBytes(byte[], SecureRandomParameters)}
  91  * with the effective instantiated strength and prediction resistance flag
  92  * (as returned by {@link SecureRandom#getParameters()}) with no
  93  * additional input.
  94  * <p>
  95  * A DRBG should be implemented as a subclass of {@link SecureRandomSpi}.
  96  * It is recommended that the implementation contain the 1-arg
  97  * {@linkplain SecureRandomSpi#SecureRandomSpi(SecureRandomParameters) constructor}
  98  * that takes a {@code DrbgParameters.Instantiation} argument. If implemented
  99  * this way, this implementation can be chosen by any
 100  * {@code SecureRandom.getInstance()} method. If it is chosen by a
 101  * {@code SecureRandom.getInstance()} with a {@link SecureRandomParameters}
 102  * parameter, the parameter is passed into this constructor. If it is chosen
 103  * by a {@code SecureRandom.getInstance()} without a
 104  * {@code SecureRandomParameters} parameter, the constructor is called with
 105  * a {@code null} argument and the implementation should choose its own
 106  * parameters. Its {@link SecureRandom#getParameters()} must always return a
 107  * non-null effective {@code DrbgParameters.Instantiation} object that reflects
 108  * how the DRBG is actually instantiated. A caller can use this information
 109  * to determine whether a {@code SecureRandom} object is a DRBG and what
 110  * features it supports. Please note that the returned value does not
 111  * necessarily equal to the {@code DrbgParameters.Instantiation} object passed
 112  * into the {@code SecureRandom.getInstance()} call. For example,
 113  * the requested capability can be {@link DrbgParameters.Capability#NONE}
 114  * but the effective value can be {@link DrbgParameters.Capability#RESEED_ONLY}
 115  * if the implementation supports reseeding. The implementation must implement
 116  * the {@link SecureRandomSpi#engineNextBytes(byte[], SecureRandomParameters)}
 117  * method which takes a {@code DrbgParameters.NextBytes} parameter. Unless
 118  * the result of {@link SecureRandom#getParameters()} has its
 119  * {@linkplain DrbgParameters.Instantiation#getCapability() capability} being
 120  * {@link Capability#NONE NONE}, it must implement
 121  * {@link SecureRandomSpi#engineReseed(SecureRandomParameters)} which takes
 122  * a {@code DrbgParameters.Reseed} parameter.
 123  * <p>
 124  * On the other hand, if a DRBG implementation does not contain a constructor
 125  * that has an {@code DrbgParameters.Instantiation} argument (not recommended),
 126  * it can only be chosen by a {@code SecureRandom.getInstance()} without
 127  * a {@code SecureRandomParameters} parameter, but will not be chosen if
 128  * a {@code getInstance} method with a {@code SecureRandomParameters} parameter
 129  * is called. If implemented this way, its {@link SecureRandom#getParameters()}
 130  * must return {@code null}, and it does not need to implement either
 131  * {@link SecureRandomSpi#engineNextBytes(byte[], SecureRandomParameters)}
 132  * or {@link SecureRandomSpi#engineReseed(SecureRandomParameters)}.
 133  * <p>
 134  * A DRBG might reseed itself automatically if the seed period is bigger
 135  * than the maximum seed life defined by the DRBG mechanism.
 136  * <p>
 137  * A DRBG implementation should support serialization and deserialization
 138  * by retaining the configuration and effective parameters, but the internal
 139  * state must not be serialized and the deserialized object must be
 140  * reinstantiated.
 141  * <p>
 142  * Examples:
 143  * <blockquote><pre>
 144  * SecureRandom drbg;
 145  * byte[] buffer = new byte[32];
 146  *
 147  * // Any DRBG is OK
 148  * drbg = SecureRandom.getInstance("DRBG");
 149  * drbg.nextBytes(buffer);
 150  *
 151  * SecureRandomParameters params = drbg.getParameters();
 152  * if (params instanceof DrbgParameters.Instantiation) {
 153  *     DrbgParameters.Instantiation ins = (DrbgParameters.Instantiation) params;
 154  *     if (ins.getCapability().supportsReseeding()) {
 155  *         drbg.reseed();
 156  *     }
 157  * }
 158  *
 159  * // The following call requests a weak DRBG instance. It is only
 160  * // guaranteed to support 112 bits of security strength.
 161  * drbg = SecureRandom.getInstance("DRBG",
 162  *         DrbgParameters.instantiation(112, NONE, null));
 163  *
 164  * // Both the next two calls will likely fail, because drbg could be
 165  * // instantiated with a smaller strength with no prediction resistance
 166  * // support.
 167  * drbg.nextBytes(buffer,
 168  *         DrbgParameters.nextBytes(256, false, "more".getBytes()));
 169  * drbg.nextBytes(buffer,
 170  *         DrbgParameters.nextBytes(112, true, "more".getBytes()));
 171  *
 172  * // The following call requests a strong DRBG instance, with a
 173  * // personalization string. If it successfully returns an instance,
 174  * // that instance is guaranteed to support 256 bits of security strength
 175  * // with prediction resistance available.
 176  * drbg = SecureRandom.getInstance("DRBG", DrbgParameters.instantiation(
 177  *         256, PR_AND_RESEED, "hello".getBytes()));
 178  *
 179  * // Prediction resistance is not requested in this single call,
 180  * // but an additional input is used.
 181  * drbg.nextBytes(buffer,
 182  *         DrbgParameters.nextBytes(-1, false, "more".getBytes()));
 183  *
 184  * // Same for this call.
 185  * drbg.reseed(DrbgParameters.reseed(false, "extra".getBytes()));</pre>
 186  * </blockquote>
 187  *
 188  * @implSpec
 189  * By convention, a provider should name its primary DRBG implementation
 190  * with the <a href=
 191  * "{@docRoot}/../technotes/guides/security/StandardNames.html#SecureRandom">
 192  * standard {@code SecureRandom} algorithm name</a> "DRBG".
 193  *
 194  * @implNote
 195  * The following notes apply to the "DRBG" implementation in the SUN provider
 196  * of the JDK reference implementation.
 197  * <p>
 198  * This implementation supports the Hash_DRBG and HMAC_DRBG mechanisms with
 199  * DRBG algorithm SHA-224, SHA-512/224, SHA-256, SHA-512/256, SHA-384 and
 200  * SHA-512, and CTR_DRBG (both using derivation function and not using
 201  * derivation function) with DRBG algorithm AES-128, AES-192 and AES-256.
 202  * <p>
 203  * The mechanism name and DRBG algorithm name are determined by the
 204  * {@linkplain Security#getProperty(String) security property}
 205  * {@code securerandom.drbg.config}. The default choice is Hash_DRBG
 206  * with SHA-256.
 207  * <p>
 208  * For each combination, the security strength can be requested from 112
 209  * up to the highest strength it supports. Both reseeding and prediction
 210  * resistance are supported.
 211  * <p>
 212  * Personalization string is supported through the
 213  * {@link DrbgParameters.Instantiation} class and additional input is supported
 214  * through the {@link DrbgParameters.NextBytes} and
 215  * {@link DrbgParameters.Reseed} classes.
 216  * <p>
 217  * If a DRBG is not instantiated with a {@link DrbgParameters.Instantiation}
 218  * object explicitly, this implementation instantiates it with a default
 219  * requested strength of 128 bits, no prediction resistance request, and
 220  * no personalization string. These default instantiation parameters can also
 221  * be customized with the {@code securerandom.drbg.config} security property.
 222  * <p>
 223  * This implementation reads fresh entropy from the system default entropy
 224  * source determined by the security property {@code securerandom.source}.
 225  * <p>
 226  * Calling {@link SecureRandom#generateSeed(int)} will directly read
 227  * from this system default entropy source.
 228  * <p>
 229  * This implementation has passed all tests included in the 20151104 version of
 230  * <a href="http://csrc.nist.gov/groups/STM/cavp/documents/drbg/drbgtestvectors.zip">
 231  * The DRBG Test Vectors</a>.
 232  *
 233  * @since 9
 234  */
 235 public class DrbgParameters {
 236 
 237     private DrbgParameters() {
 238         // This class should not be instantiated
 239     }
 240 
 241     /**
 242      * The reseedable and prediction resistance capabilities of a DRBG.
 243      * <p>
 244      * When this object is passed to a {@code SecureRandom.getInstance()} call,
 245      * it is the requested minimum capability. When it's returned from
 246      * {@code SecureRandom.getParameters()}, it is the effective capability.
 247      * <p>
 248      * Please note that while the {@code Instantiate_function} defined in
 249      * NIST SP 800-90Ar1 only includes a {@code prediction_resistance_flag}
 250      * parameter, the {@code Capability} type includes an extra value
 251      * {@link #RESEED_ONLY} because reseeding is an optional function.
 252      * If {@code NONE} is used in an {@code Instantiation} object in calling the
 253      * {@code SecureRandom.getInstance} method, the returned DRBG instance
 254      * is not guaranteed to support reseeding. If {@code RESEED_ONLY} or
 255      * {@code PR_AND_RESEED} is used, the instance must support reseeding.
 256      * <p>
 257      * The table below lists possible effective values if a certain
 258      * capability is requested, i.e.
 259      * <blockquote><pre>
 260      * Capability requested = ...;
 261      * SecureRandom s = SecureRandom.getInstance("DRBG",
 262      *         DrbgParameters(-1, requested, null));
 263      * Capability effective = ((DrbgParametes.Initiate) s.getParameters())
 264      *         .getCapability();</pre>
 265      * </blockquote>
 266      * <table class="plain">
 267      * <caption style="display:none">requested and effective capabilities</caption>
 268      * <thead>
 269      * <tr>
 270      * <th>Requested Value</th>
 271      * <th>Possible Effective Values</th>
 272      * </tr>
 273      * </thead>
 274      * <tbody>
 275      * <tr><td>NONE</td><td>NONE, RESEED_ONLY, PR_AND_RESEED</td></tr>
 276      * <tr><td>RESEED_ONLY</td><td>RESEED_ONLY, PR_AND_RESEED</td></tr>
 277      * <tr><td>PR_AND_RESEED</td><td>PR_AND_RESEED</td></tr>
 278      * </tbody>
 279      * </table>
 280      * <p>
 281      * A DRBG implementation supporting prediction resistance must also
 282      * support reseeding.
 283      *
 284      * @since 9
 285      */
 286     public enum Capability {
 287 
 288         /**
 289          * Both prediction resistance and reseed.
 290          */
 291         PR_AND_RESEED,
 292 
 293         /**
 294          * Reseed but no prediction resistance.
 295          */
 296         RESEED_ONLY,
 297 
 298         /**
 299          * Neither prediction resistance nor reseed.
 300          */
 301         NONE;
 302 
 303         @Override
 304         public String toString() {
 305             return name().toLowerCase(Locale.ROOT);
 306         }
 307 
 308         /**
 309          * Returns whether this capability supports reseeding.
 310          *
 311          * @return {@code true} for {@link #PR_AND_RESEED} and
 312          *      {@link #RESEED_ONLY}, and {@code false} for {@link #NONE}
 313          */
 314         public boolean supportsReseeding() {
 315             return this != NONE;
 316         }
 317 
 318         /**
 319          * Returns whether this capability supports prediction resistance.
 320          *
 321          * @return {@code true} for {@link #PR_AND_RESEED}, and {@code false}
 322          *      for {@link #RESEED_ONLY} and {@link #NONE}
 323          */
 324         public boolean supportsPredictionResistance() {
 325             return this == PR_AND_RESEED;
 326         }
 327     }
 328 
 329     /**
 330      * DRBG parameters for instantiation.
 331      * <p>
 332      * When used in
 333      * {@link SecureRandom#getInstance(String, SecureRandomParameters)}
 334      * or one of the other similar {@code getInstance} calls that take a
 335      * {@code SecureRandomParameters} parameter, it means the
 336      * requested instantiate parameters the newly created {@code SecureRandom}
 337      * object must minimally support. When used as the return value of the
 338      * {@link SecureRandom#getParameters()} method, it means the effective
 339      * instantiate parameters of the {@code SecureRandom} object.
 340      *
 341      * @since 9
 342      */
 343     public static final class Instantiation
 344             implements SecureRandomParameters {
 345 
 346         private final int strength;
 347         private final Capability capability;
 348         private final byte[] personalizationString;
 349 
 350         /**
 351          * Returns the security strength in bits.
 352          *
 353          * @return If used in {@code getInstance}, returns the minimum strength
 354          * requested, or -1 if there is no specific request on the strength.
 355          * If used in {@code getParameters}, returns the effective strength.
 356          * The effective strength must be greater than or equal to the minimum
 357          * strength requested.
 358          */
 359         public int getStrength() {
 360             return strength;
 361         }
 362 
 363         /**
 364          * Returns the capability.
 365          *
 366          * @return If used in {@code getInstance}, returns the minimum
 367          * capability requested. If used in {@code getParameters}, returns
 368          * information on the effective prediction resistance flag and
 369          * whether it supports reseeding.
 370          */
 371         public Capability getCapability() {
 372             return capability;
 373         }
 374 
 375         /**
 376          * Returns the personalization string as a byte array.
 377          *
 378          * @return If used in {@code getInstance}, returns the requested
 379          * personalization string as a newly allocated array, or {@code null}
 380          * if no personalization string is requested. The same string should
 381          * be returned in {@code getParameters} as a new copy, or {@code null}
 382          * if no personalization string is requested in {@code getInstance}.
 383          */
 384         public byte[] getPersonalizationString() {
 385             return (personalizationString == null) ?
 386                     null : personalizationString.clone();
 387         }
 388 
 389         private Instantiation(int strength, Capability capability,
 390                               byte[] personalizationString) {
 391             if (strength < -1) {
 392                 throw new IllegalArgumentException(
 393                         "Illegal security strength: " + strength);
 394             }
 395             this.strength = strength;
 396             this.capability = capability;
 397             this.personalizationString = (personalizationString == null) ?
 398                     null : personalizationString.clone();
 399         }
 400 
 401         /**
 402          * Returns a Human-readable string representation of this
 403          * {@code Instantiation}.
 404          *
 405          * @return the string representation
 406          */
 407         @Override
 408         public String toString() {
 409             // I don't care what personalizationString looks like
 410             return strength + "," + capability + "," + personalizationString;
 411         }
 412     }
 413 
 414     /**
 415      * DRBG parameters for random bits generation. It is used in
 416      * {@link SecureRandom#nextBytes(byte[], SecureRandomParameters)}.
 417      *
 418      * @since 9
 419      */
 420     public static final class NextBytes
 421             implements SecureRandomParameters {
 422         private final int strength;
 423         private final boolean predictionResistance;
 424         private final byte[] additionalInput;
 425 
 426         /**
 427          * Returns the security strength requested in bits.
 428          *
 429          * @return the strength requested, or -1 if the effective strength
 430          *      should be used.
 431          */
 432         public int getStrength() {
 433             return strength;
 434         }
 435 
 436         /**
 437          * Returns whether prediction resistance is requested.
 438          *
 439          * @return whether prediction resistance is requested
 440          */
 441         public boolean getPredictionResistance() {
 442             return predictionResistance;
 443         }
 444 
 445         /**
 446          * Returns the requested additional input.
 447          *
 448          * @return the requested additional input, {@code null} if not
 449          * requested. A new byte array is returned each time this method
 450          * is called.
 451          */
 452         public byte[] getAdditionalInput() {
 453             return additionalInput == null? null: additionalInput.clone();
 454         }
 455 
 456         private NextBytes(int strength, boolean predictionResistance,
 457                           byte[] additionalInput) {
 458             if (strength < -1) {
 459                 throw new IllegalArgumentException(
 460                         "Illegal security strength: " + strength);
 461             }
 462             this.strength = strength;
 463             this.predictionResistance = predictionResistance;
 464             this.additionalInput = (additionalInput == null) ?
 465                     null : additionalInput.clone();
 466         }
 467     }
 468 
 469     /**
 470      * DRBG parameters for reseed. It is used in
 471      * {@link SecureRandom#reseed(SecureRandomParameters)}.
 472      *
 473      * @since 9
 474      */
 475     public static final class Reseed implements SecureRandomParameters {
 476 
 477         private final byte[] additionalInput;
 478         private final boolean predictionResistance;
 479 
 480         /**
 481          * Returns whether prediction resistance is requested.
 482          *
 483          * @return whether prediction resistance is requested
 484          */
 485         public boolean getPredictionResistance() {
 486             return predictionResistance;
 487         }
 488 
 489         /**
 490          * Returns the requested additional input.
 491          *
 492          * @return the requested additional input, or {@code null} if
 493          * not requested. A new byte array is returned each time this method
 494          * is called.
 495          */
 496         public byte[] getAdditionalInput() {
 497             return additionalInput == null ? null : additionalInput.clone();
 498         }
 499 
 500         private Reseed(boolean predictionResistance, byte[] additionalInput) {
 501             this.predictionResistance = predictionResistance;
 502             this.additionalInput = (additionalInput == null) ?
 503                     null : additionalInput.clone();
 504         }
 505     }
 506 
 507     /**
 508      * Generates a {@link DrbgParameters.Instantiation} object.
 509      *
 510      * @param strength security strength in bits, -1 for default strength
 511      *                 if used in {@code getInstance}.
 512      * @param capability capability
 513      * @param personalizationString personalization string as a byte array,
 514      *                              can be {@code null}. The content of this
 515      *                              byte array will be copied.
 516      * @return a new {@code Instantiation} object
 517      * @throws NullPointerException if {@code capability} is {@code null}
 518      * @throws IllegalArgumentException if {@code strength} is less than -1
 519      */
 520     public static Instantiation instantiation(int strength,
 521                                               Capability capability,
 522                                               byte[] personalizationString) {
 523         return new Instantiation(strength, Objects.requireNonNull(capability),
 524                 personalizationString);
 525     }
 526 
 527     /**
 528      * Generates a {@link NextBytes} object.
 529      *
 530      * @param strength requested security strength in bits. If set to -1, the
 531      *                 effective strength will be used.
 532      * @param predictionResistance prediction resistance requested
 533      * @param additionalInput additional input, can be {@code null}.
 534      *                        The content of this byte array will be copied.
 535      * @throws IllegalArgumentException if {@code strength} is less than -1
 536      * @return a new {@code NextBytes} object
 537      */
 538     public static NextBytes nextBytes(int strength,
 539                                       boolean predictionResistance,
 540                                       byte[] additionalInput) {
 541         return new NextBytes(strength, predictionResistance, additionalInput);
 542     }
 543 
 544     /**
 545      * Generates a {@link Reseed} object.
 546      *
 547      * @param predictionResistance prediction resistance requested
 548      * @param additionalInput additional input, can be {@code null}.
 549      *                        The content of this byte array will be copied.
 550      * @return a new {@code Reseed} object
 551      */
 552     public static Reseed reseed(
 553             boolean predictionResistance, byte[] additionalInput) {
 554         return new Reseed(predictionResistance, additionalInput);
 555     }
 556 }