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