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 }