1/*
2 * Copyright (c) 2016, 2017, 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
26package java.security;
27
28import java.util.Locale;
29import 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}/../specs/security/standard-names.html#securerandom-number-generation-algorithms">
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 */
235public 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}
557