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 border=1 summary="requested and effective capabilities">
 267      * <tr>
 268      * <th>Requested Value</th>
 269      * <th>Possible Effective Values</th>
 270      * </tr>
 271      * <tr><td>NONE</td><td>NONE, RESEED_ONLY, PR_AND_RESEED</td></tr>
 272      * <tr><td>RESEED_ONLY</td><td>RESEED_ONLY, PR_AND_RESEED</td></tr>
 273      * <tr><td>PR_AND_RESEED</td><td>PR_AND_RESEED</td></tr>
 274      * </table>
 275      * <p>
 276      * A DRBG implementation supporting prediction resistance must also
 277      * support reseeding.
 278      *
 279      * @since 9
 280      */
 281     public enum Capability {
 282 
 283         /**
 284          * Both prediction resistance and reseed.
 285          */
 286         PR_AND_RESEED,
 287 
 288         /**
 289          * Reseed but no prediction resistance.
 290          */
 291         RESEED_ONLY,
 292 
 293         /**
 294          * Neither prediction resistance nor reseed.
 295          */
 296         NONE;
 297 
 298         @Override
 299         public String toString() {
 300             return name().toLowerCase(Locale.ROOT);
 301         }
 302 
 303         /**
 304          * Returns whether this capability supports reseeding.
 305          *
 306          * @return {@code true} for {@link #PR_AND_RESEED} and
 307          *      {@link #RESEED_ONLY}, and {@code false} for {@link #NONE}
 308          */
 309         public boolean supportsReseeding() {
 310             return this != NONE;
 311         }
 312 
 313         /**
 314          * Returns whether this capability supports prediction resistance.
 315          *
 316          * @return {@code true} for {@link #PR_AND_RESEED}, and {@code false}
 317          *      for {@link #RESEED_ONLY} and {@link #NONE}
 318          */
 319         public boolean supportsPredictionResistance() {
 320             return this == PR_AND_RESEED;
 321         }
 322     }
 323 
 324     /**
 325      * DRBG parameters for instantiation.
 326      * <p>
 327      * When used in
 328      * {@link SecureRandom#getInstance(String, SecureRandomParameters)}
 329      * or one of the other similar {@code getInstance} calls that take a
 330      * {@code SecureRandomParameters} parameter, it means the
 331      * requested instantiate parameters the newly created {@code SecureRandom}
 332      * object must minimally support. When used as the return value of the
 333      * {@link SecureRandom#getParameters()} method, it means the effective
 334      * instantiate parameters of the {@code SecureRandom} object.
 335      *
 336      * @since 9
 337      */
 338     public static final class Instantiation
 339             implements SecureRandomParameters {
 340 
 341         private final int strength;
 342         private final Capability capability;
 343         private final byte[] personalizationString;
 344 
 345         /**
 346          * Returns the security strength in bits.
 347          *
 348          * @return If used in {@code getInstance}, returns the minimum strength
 349          * requested, or -1 if there is no specific request on the strength.
 350          * If used in {@code getParameters}, returns the effective strength.
 351          * The effective strength must be greater than or equal to the minimum
 352          * strength requested.
 353          */
 354         public int getStrength() {
 355             return strength;
 356         }
 357 
 358         /**
 359          * Returns the capability.
 360          *
 361          * @return If used in {@code getInstance}, returns the minimum
 362          * capability requested. If used in {@code getParameters}, returns
 363          * information on the effective prediction resistance flag and
 364          * whether it supports reseeding.
 365          */
 366         public Capability getCapability() {
 367             return capability;
 368         }
 369 
 370         /**
 371          * Returns the personalization string as a byte array.
 372          *
 373          * @return If used in {@code getInstance}, returns the requested
 374          * personalization string as a newly allocated array, or {@code null}
 375          * if no personalization string is requested. The same string should
 376          * be returned in {@code getParameters} as a new copy, or {@code null}
 377          * if no personalization string is requested in {@code getInstance}.
 378          */
 379         public byte[] getPersonalizationString() {
 380             return (personalizationString == null) ?
 381                     null : personalizationString.clone();
 382         }
 383 
 384         private Instantiation(int strength, Capability capability,
 385                               byte[] personalizationString) {
 386             if (strength < -1) {
 387                 throw new IllegalArgumentException(
 388                         "Illegal security strength: " + strength);
 389             }
 390             this.strength = strength;
 391             this.capability = capability;
 392             this.personalizationString = (personalizationString == null) ?
 393                     null : personalizationString.clone();
 394         }
 395 
 396         /**
 397          * Returns a Human-readable string representation of this
 398          * {@code Instantiation}.
 399          *
 400          * @return the string representation
 401          */
 402         @Override
 403         public String toString() {
 404             // I don't care what personalizationString looks like
 405             return strength + "," + capability + "," + personalizationString;
 406         }
 407     }
 408 
 409     /**
 410      * DRBG parameters for random bits generation. It is used in
 411      * {@link SecureRandom#nextBytes(byte[], SecureRandomParameters)}.
 412      *
 413      * @since 9
 414      */
 415     public static final class NextBytes
 416             implements SecureRandomParameters {
 417         private final int strength;
 418         private final boolean predictionResistance;
 419         private final byte[] additionalInput;
 420 
 421         /**
 422          * Returns the security strength requested in bits.
 423          *
 424          * @return the strength requested, or -1 if the effective strength
 425          *      should be used.
 426          */
 427         public int getStrength() {
 428             return strength;
 429         }
 430 
 431         /**
 432          * Returns whether prediction resistance is requested.
 433          *
 434          * @return whether prediction resistance is requested
 435          */
 436         public boolean getPredictionResistance() {
 437             return predictionResistance;
 438         }
 439 
 440         /**
 441          * Returns the requested additional input.
 442          *
 443          * @return the requested additional input, {@code null} if not
 444          * requested. A new byte array is returned each time this method
 445          * is called.
 446          */
 447         public byte[] getAdditionalInput() {
 448             return additionalInput == null? null: additionalInput.clone();
 449         }
 450 
 451         private NextBytes(int strength, boolean predictionResistance,
 452                           byte[] additionalInput) {
 453             if (strength < -1) {
 454                 throw new IllegalArgumentException(
 455                         "Illegal security strength: " + strength);
 456             }
 457             this.strength = strength;
 458             this.predictionResistance = predictionResistance;
 459             this.additionalInput = (additionalInput == null) ?
 460                     null : additionalInput.clone();
 461         }
 462     }
 463 
 464     /**
 465      * DRBG parameters for reseed. It is used in
 466      * {@link SecureRandom#reseed(SecureRandomParameters)}.
 467      *
 468      * @since 9
 469      */
 470     public static final class Reseed implements SecureRandomParameters {
 471 
 472         private final byte[] additionalInput;
 473         private final boolean predictionResistance;
 474 
 475         /**
 476          * Returns whether prediction resistance is requested.
 477          *
 478          * @return whether prediction resistance is requested
 479          */
 480         public boolean getPredictionResistance() {
 481             return predictionResistance;
 482         }
 483 
 484         /**
 485          * Returns the requested additional input.
 486          *
 487          * @return the requested additional input, or {@code null} if
 488          * not requested. A new byte array is returned each time this method
 489          * is called.
 490          */
 491         public byte[] getAdditionalInput() {
 492             return additionalInput == null ? null : additionalInput.clone();
 493         }
 494 
 495         private Reseed(boolean predictionResistance, byte[] additionalInput) {
 496             this.predictionResistance = predictionResistance;
 497             this.additionalInput = (additionalInput == null) ?
 498                     null : additionalInput.clone();
 499         }
 500     }
 501 
 502     /**
 503      * Generates a {@link DrbgParameters.Instantiation} object.
 504      *
 505      * @param strength security strength in bits, -1 for default strength
 506      *                 if used in {@code getInstance}.
 507      * @param capability capability
 508      * @param personalizationString personalization string as a byte array,
 509      *                              can be {@code null}. The content of this
 510      *                              byte array will be copied.
 511      * @return a new {@code Instantiation} object
 512      * @throws NullPointerException if {@code capability} is {@code null}
 513      * @throws IllegalArgumentException if {@code strength} is less than -1
 514      */
 515     public static Instantiation instantiation(int strength,
 516                                               Capability capability,
 517                                               byte[] personalizationString) {
 518         return new Instantiation(strength, Objects.requireNonNull(capability),
 519                 personalizationString);
 520     }
 521 
 522     /**
 523      * Generates a {@link NextBytes} object.
 524      *
 525      * @param strength requested security strength in bits. If set to -1, the
 526      *                 effective strength will be used.
 527      * @param predictionResistance prediction resistance requested
 528      * @param additionalInput additional input, can be {@code null}.
 529      *                        The content of this byte array will be copied.
 530      * @throws IllegalArgumentException if {@code strength} is less than -1
 531      * @return a new {@code NextBytes} object
 532      */
 533     public static NextBytes nextBytes(int strength,
 534                                       boolean predictionResistance,
 535                                       byte[] additionalInput) {
 536         return new NextBytes(strength, predictionResistance, additionalInput);
 537     }
 538 
 539     /**
 540      * Generates a {@link Reseed} object.
 541      *
 542      * @param predictionResistance prediction resistance requested
 543      * @param additionalInput additional input, can be {@code null}.
 544      *                        The content of this byte array will be copied.
 545      * @return a new {@code Reseed} object
 546      */
 547     public static Reseed reseed(
 548             boolean predictionResistance, byte[] additionalInput) {
 549         return new Reseed(predictionResistance, additionalInput);
 550     }
 551 }