1 /*
2  * Copyright (c) 1998, 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 
26 package java.security;
27 
28 /**
29  * This class defines the <i>Service Provider Interface</i> (<b>SPI</b>)
30  * for the {@link SecureRandom} class.
31  * <p>
32  * All the abstract methods in this class must be implemented by each
33  * service provider who wishes to supply the implementation
34  * of a cryptographically strong pseudo-random number generator.
35  *
36  * @implSpec
37  * If the {@link #SecureRandomSpi(SecureRandomParameters)}
38  * constructor is overridden in an implementation, it will always be called
39  * whenever a {@code SecureRandom} is instantiated. Precisely, if an object is
40  * instantiated with one of {@code SecureRandom}'s {@code getInstance} methods
41  * <em>without</em> a {@link SecureRandomParameters} parameter,
42  * the constructor will be called with a {@code null} argument and the
43  * implementation is responsible for creating its own
44  * {@code SecureRandomParameters} parameter for use when
45  * {@link #engineGetParameters()} is called. If an object
46  * is instantiated with one of {@code SecureRandom}'s {@code getInstance}
47  * methods <em>with</em> a {@code SecureRandomParameters} argument,
48  * the constructor will be called with that argument. The
49  * {@link #engineGetParameters()} method must not return {@code null}.
50  * <p>
51  * Otherwise, if the {@code SecureRandomSpi(SecureRandomParameters)}
52  * constructor is not overridden in an implementation, the
53  * {@link #SecureRandomSpi()} constructor must be overridden and it will be
54  * called if an object is instantiated with one of {@code SecureRandom}'s
55  * {@code getInstance} methods <em>without</em> a
56  * {@code SecureRandomParameters} argument. Calling one of
57  * {@code SecureRandom}'s {@code getInstance} methods <em>with</em>
58  * a {@code SecureRandomParameters} argument will never
59  * return an instance of this implementation. The
60  * {@link #engineGetParameters()} method must return {@code null}.
61  * <p>
62  * See {@link SecureRandom} for additional details on thread safety. By
63  * default, a {@code SecureRandomSpi} implementation is considered to be
64  * not safe for use by multiple concurrent threads and {@code SecureRandom}
65  * will synchronize access to each of the applicable engine methods
66  * (see {@link SecureRandom} for the list of methods). However, if a
67  * {@code SecureRandomSpi} implementation is thread-safe, the <a href=
68  * "{@docRoot}/../specs/security/standard-names.html#service-attributes">
69  * service provider attribute</a> "ThreadSafe" should be set to "true" during
70  * its registration, as follows:
71  * <blockquote><pre>
72  * put("SecureRandom.AlgName ThreadSafe", "true");</pre>
73  * </blockquote>
74  * or
75  * <blockquote><pre>
76  * putService(new Service(this, "SecureRandom", "AlgName", className,
77  *          null, Map.of("ThreadSafe", "true")));</pre>
78  * </blockquote>
79  * {@code SecureRandom} will call the applicable engine methods
80  * without any synchronization.
81  *
82  * @since 1.2
83  */
84 
85 public abstract class SecureRandomSpi implements java.io.Serializable {
86 
87     private static final long serialVersionUID = -2991854161009191830L;
88 
89     /**
90      * Constructor without a parameter.
91      */
SecureRandomSpi()92     public SecureRandomSpi() {
93         // ignored
94     }
95 
96     /**
97      * Constructor with a parameter.
98      *
99      * @param params the {@link SecureRandomParameters} object.
100      *               This argument can be {@code null}.
101      * @throws IllegalArgumentException if {@code params} is
102      *         unrecognizable or unsupported by this {@code SecureRandom}
103      *
104      * @since 9
105      */
SecureRandomSpi(SecureRandomParameters params)106     protected SecureRandomSpi(SecureRandomParameters params) {
107         // ignored
108     }
109 
110     /**
111      * Reseeds this random object with the given seed. The seed supplements,
112      * rather than replaces, the existing seed. Thus, repeated calls
113      * are guaranteed never to reduce randomness.
114      *
115      * @param seed the seed.
116      */
engineSetSeed(byte[] seed)117     protected abstract void engineSetSeed(byte[] seed);
118 
119     /**
120      * Generates a user-specified number of random bytes.
121      * <p>
122      * Some random number generators can only generate a limited amount
123      * of random bytes per invocation. If the size of {@code bytes}
124      * is greater than this limit, the implementation should invoke
125      * its generation process multiple times to completely fill the
126      * buffer before returning from this method.
127      *
128      * @param bytes the array to be filled in with random bytes.
129      */
engineNextBytes(byte[] bytes)130     protected abstract void engineNextBytes(byte[] bytes);
131 
132     /**
133      * Generates a user-specified number of random bytes with
134      * additional parameters.
135      * <p>
136      * Some random number generators can only generate a limited amount
137      * of random bytes per invocation. If the size of {@code bytes}
138      * is greater than this limit, the implementation should invoke
139      * its generation process multiple times to completely fill the
140      * buffer before returning from this method.
141      *
142      * @implSpec The default implementation throws
143      * an {@link UnsupportedOperationException}.
144      *
145      * @param bytes the array to be filled in with random bytes
146      * @param params additional parameters
147      * @throws UnsupportedOperationException if the implementation
148      *         has not overridden this method
149      * @throws IllegalArgumentException if {@code params} is {@code null},
150      *         illegal or unsupported by this {@code SecureRandom}
151      *
152      * @since 9
153      */
engineNextBytes( byte[] bytes, SecureRandomParameters params)154     protected void engineNextBytes(
155             byte[] bytes, SecureRandomParameters params) {
156         throw new UnsupportedOperationException();
157     }
158 
159     /**
160      * Returns the given number of seed bytes.  This call may be used to
161      * seed other random number generators.
162      *
163      * @param numBytes the number of seed bytes to generate.
164      *
165      * @return the seed bytes.
166      */
engineGenerateSeed(int numBytes)167     protected abstract byte[] engineGenerateSeed(int numBytes);
168 
169     /**
170      * Reseeds this random object with entropy input read from its
171      * entropy source with additional parameters.
172      * <p>
173      * If this method is called by {@link SecureRandom#reseed()},
174      * {@code params} will be {@code null}.
175      * <p>
176      * Do not override this method if the implementation does not
177      * support reseeding.
178      *
179      * @implSpec The default implementation throws
180      *           an {@link UnsupportedOperationException}.
181      *
182      * @param params extra parameters, can be {@code null}.
183      * @throws UnsupportedOperationException if the implementation
184      *         has not overridden this method
185      * @throws IllegalArgumentException if {@code params} is
186      *         illegal or unsupported by this {@code SecureRandom}
187      *
188      * @since 9
189      */
engineReseed(SecureRandomParameters params)190     protected void engineReseed(SecureRandomParameters params) {
191         throw new UnsupportedOperationException();
192     }
193 
194     /**
195      * Returns the effective {@link SecureRandomParameters} for this
196      * {@code SecureRandom} instance.
197      *
198      * @implSpec The default implementation returns {@code null}.
199      *
200      * @return the effective {@link SecureRandomParameters} parameters,
201      * or {@code null} if no parameters were used.
202      *
203      * @since 9
204      */
engineGetParameters()205     protected SecureRandomParameters engineGetParameters() {
206         return null;
207     }
208 
209     /**
210      * Returns a Human-readable string representation of this
211      * {@code SecureRandom}.
212      *
213      * @return the string representation
214      */
215     @Override
toString()216     public String toString() {
217         return getClass().getSimpleName();
218     }
219 }
220