1 /*
   2  * Copyright (c) 1998, 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 /**
  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  *
  62  * @since 1.2
  63  */
  64 
  65 public abstract class SecureRandomSpi implements java.io.Serializable {
  66 
  67     private static final long serialVersionUID = -2991854161009191830L;
  68 
  69     /**
  70      * Constructor without a parameter.
  71      */
  72     public SecureRandomSpi() {
  73         // ignored
  74     }
  75 
  76     /**
  77      * Constructor with a parameter.
  78      *
  79      * @param params the {@link SecureRandomParameters} object.
  80      *               This argument can be {@code null}.
  81      * @throws IllegalArgumentException if {@code params} is
  82      *         unrecognizable or unsupported by this {@code SecureRandom}
  83      *
  84      * @since 9
  85      */
  86     protected SecureRandomSpi(SecureRandomParameters params) {
  87         // ignored
  88     }
  89 
  90     /**
  91      * Reseeds this random object with the given seed. The seed supplements,
  92      * rather than replaces, the existing seed. Thus, repeated calls
  93      * are guaranteed never to reduce randomness.
  94      *
  95      * @param seed the seed.
  96      */
  97     protected abstract void engineSetSeed(byte[] seed);
  98 
  99     /**
 100      * Generates a user-specified number of random bytes.
 101      *
 102      * @param bytes the array to be filled in with random bytes.
 103      */
 104     protected abstract void engineNextBytes(byte[] bytes);
 105 
 106     /**
 107      * Generates a user-specified number of random bytes with
 108      * additional parameters.
 109      *
 110      * @implSpec The default implementation throws
 111      * an {@link UnsupportedOperationException}.
 112      *
 113      * @param bytes the array to be filled in with random bytes
 114      * @param params additional parameters
 115      * @throws UnsupportedOperationException if the implementation
 116      *         has not overridden this method
 117      * @throws IllegalArgumentException if {@code params} is {@code null},
 118      *         unrecognizable or unsupported by this {@code SecureRandom}
 119      *
 120      * @since 9
 121      */
 122     protected void engineNextBytes(
 123             byte[] bytes, SecureRandomParameters params) {
 124         throw new UnsupportedOperationException("not supported");
 125     }
 126 
 127     /**
 128      * Returns the given number of seed bytes.  This call may be used to
 129      * seed other random number generators.
 130      *
 131      * @param numBytes the number of seed bytes to generate.
 132      *
 133      * @return the seed bytes.
 134      */
 135     protected abstract byte[] engineGenerateSeed(int numBytes);
 136 
 137     /**
 138      * Reseeds this random object with entropy input read from its
 139      * entropy source with additional parameters.
 140      * <p>
 141      * If this method is called by {@link SecureRandom#reseed()},
 142      * {@code params} will be {@code null}.
 143      *
 144      * @implSpec The default implementation throws
 145      *           an {@link UnsupportedOperationException}.
 146      *
 147      * @param params extra parameters, can be {@code null}.
 148      * @throws UnsupportedOperationException if the implementation
 149      *         has not overridden this method
 150      * @throws IllegalArgumentException if {@code params} is
 151      *         unrecognizable or unsupported by this {@code SecureRandom}
 152      *
 153      * @since 9
 154      */
 155     protected void engineReseed(SecureRandomParameters params) {
 156         throw new UnsupportedOperationException("not supported");
 157     }
 158 
 159     /**
 160      * Returns the effective {@link SecureRandomParameters}
 161      * that is actually used to instantiate this {@code SecureRandom}.
 162      *
 163      * @implSpec The default implementation returns {@code null}.
 164      *
 165      * @return the parameters used in instantiation, or {@code null} if no
 166      * parameters were used.
 167      *
 168      * @since 9
 169      */
 170     protected SecureRandomParameters engineGetParameters() {
 171         return null;
 172     }
 173 
 174     @Override
 175     public String toString() {
 176         return getClass().getSimpleName();
 177     }
 178 }