src/java.base/share/classes/sun/security/provider/AbstractDrbg.java
author weijun
Wed, 01 Aug 2018 13:35:08 +0800
changeset 51272 9d92ff04a29c
parent 50777 11e7eb8cb583
permissions -rw-r--r--
8208602: Cannot read PEM X.509 cert if there is whitespace after the header or footer Reviewed-by: xuelei
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
37796
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
     1
/*
50777
11e7eb8cb583 8202608: CommonSeeder test needs a white-box testing mechanism to replace the default entropy source
weijun
parents: 47216
diff changeset
     2
 * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
37796
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
     4
 *
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    10
 *
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    15
 * accompanied this code).
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    16
 *
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    20
 *
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    23
 * questions.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    24
 */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    25
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    26
package sun.security.provider;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    27
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    28
import sun.security.util.Debug;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    29
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    30
import java.security.*;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    31
import java.util.Arrays;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    32
import java.util.Objects;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    33
import static java.security.DrbgParameters.Capability.*;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    34
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    35
/**
38853
971a7101da5b 8157308: Make AbstractDrbg non-Serializable
weijun
parents: 37896
diff changeset
    36
 * The abstract base class for all DRBGs. It is used as {@link DRBG#impl}.
37796
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    37
 * <p>
38853
971a7101da5b 8157308: Make AbstractDrbg non-Serializable
weijun
parents: 37896
diff changeset
    38
 * This class has 5 abstract methods. 3 are defined by SP800-90A:
37796
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    39
 * <ol>
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    40
 *  <li>{@link #generateAlgorithm(byte[], byte[])}
38853
971a7101da5b 8157308: Make AbstractDrbg non-Serializable
weijun
parents: 37896
diff changeset
    41
 *  <li>{@link #reseedAlgorithm(byte[], byte[])} (In fact this is not an
971a7101da5b 8157308: Make AbstractDrbg non-Serializable
weijun
parents: 37896
diff changeset
    42
 *      abstract method, but any DRBG supporting reseeding must override it.)
37796
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    43
 *  <li>{@link #instantiateAlgorithm(byte[])}
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    44
 * </ol>
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    45
 * and 2 for implementation purpose:
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    46
 * <ol>
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    47
 *  <li>{@link #initEngine()}
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    48
 *  <li>{@link #chooseAlgorithmAndStrength}
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    49
 * </ol>
38853
971a7101da5b 8157308: Make AbstractDrbg non-Serializable
weijun
parents: 37896
diff changeset
    50
 * Although this class is not a child class of {@link SecureRandomSpi}, it
971a7101da5b 8157308: Make AbstractDrbg non-Serializable
weijun
parents: 37896
diff changeset
    51
 * implements all abstract methods there as final.
971a7101da5b 8157308: Make AbstractDrbg non-Serializable
weijun
parents: 37896
diff changeset
    52
 * <p>
971a7101da5b 8157308: Make AbstractDrbg non-Serializable
weijun
parents: 37896
diff changeset
    53
 * The initialization process of a DRBG is divided into 2 phases:
971a7101da5b 8157308: Make AbstractDrbg non-Serializable
weijun
parents: 37896
diff changeset
    54
 * {@link #configure configuration} is eagerly called to set up parameters,
971a7101da5b 8157308: Make AbstractDrbg non-Serializable
weijun
parents: 37896
diff changeset
    55
 * and {@link #instantiateIfNecessary instantiation} is lazily called only
971a7101da5b 8157308: Make AbstractDrbg non-Serializable
weijun
parents: 37896
diff changeset
    56
 * when nextBytes or reseed is called.
37796
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    57
 * <p>
37895
f59fdd7fb4fb 8156501: DRBG not synchronized at reseeding
weijun
parents: 37796
diff changeset
    58
 * SecureRandom methods like reseed and nextBytes are not thread-safe.
f59fdd7fb4fb 8156501: DRBG not synchronized at reseeding
weijun
parents: 37796
diff changeset
    59
 * An implementation is required to protect shared access to instantiate states
38853
971a7101da5b 8157308: Make AbstractDrbg non-Serializable
weijun
parents: 37896
diff changeset
    60
 * (instantiated, nonce) and DRBG states (v, c, key, reseedCounter, etc).
37796
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    61
 */
38853
971a7101da5b 8157308: Make AbstractDrbg non-Serializable
weijun
parents: 37896
diff changeset
    62
public abstract class AbstractDrbg {
37796
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    63
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    64
    /**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    65
     * This field is not null if {@code -Djava.security.debug=securerandom} is
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    66
     * specified on the command line. An implementation can print useful
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    67
     * debug info.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    68
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    69
    protected static final Debug debug = Debug.getInstance(
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    70
            "securerandom", "drbg");
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    71
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    72
    // Common working status
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    73
38853
971a7101da5b 8157308: Make AbstractDrbg non-Serializable
weijun
parents: 37896
diff changeset
    74
    private boolean instantiated = false;
37796
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    75
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    76
    /**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    77
     * Reseed counter of a DRBG instance. A mechanism should increment it
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    78
     * after each random bits generation and reset it in reseed. A mechanism
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    79
     * does <em>not</em> need to compare it to {@link #reseedInterval}.
37895
f59fdd7fb4fb 8156501: DRBG not synchronized at reseeding
weijun
parents: 37796
diff changeset
    80
     *
f59fdd7fb4fb 8156501: DRBG not synchronized at reseeding
weijun
parents: 37796
diff changeset
    81
     * Volatile, will be used in a double checked locking.
37796
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    82
     */
38853
971a7101da5b 8157308: Make AbstractDrbg non-Serializable
weijun
parents: 37896
diff changeset
    83
    protected volatile int reseedCounter = 0;
37796
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    84
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    85
    // Mech features. If not same as below, must be redefined in constructor.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    86
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    87
    /**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    88
     * Default strength of a DRBG instance if it is not configured.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    89
     * 128 is considered secure enough now. A mechanism
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    90
     * can change it in a constructor.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    91
     *
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    92
     * Remember to sync with "securerandom.drbg.config" in java.security.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    93
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    94
    protected static final int DEFAULT_STRENGTH = 128;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    95
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    96
    /**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    97
     * Mechanism name, say, {@code HashDRBG}. Must be set in constructor.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    98
     * This value will be used in {@code toString}.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    99
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   100
    protected String mechName = "DRBG";
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   101
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   102
    /**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   103
     * highest_supported_security_strength of this mechanism for all algorithms
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   104
     * it supports. A mechanism should update the value in its constructor
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   105
     * if the value is not 256.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   106
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   107
    protected int highestSupportedSecurityStrength = 256;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   108
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   109
    /**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   110
     * Whether prediction resistance is supported. A mechanism should update
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   111
     * the value in its constructor if it is <em>not</em> supported.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   112
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   113
    protected boolean supportPredictionResistance = true;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   114
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   115
    /**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   116
     * Whether reseed is supported. A mechanism should update
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   117
     * the value in its constructor if it is <em>not</em> supported.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   118
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   119
    protected boolean supportReseeding = true;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   120
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   121
    // Strength features. If not same as below, must be redefined in
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   122
    // chooseAlgorithmAndStrength. Among these, minLength and seedLen have no
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   123
    // default value and must be redefined. If personalization string or
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   124
    // additional input is not supported, set maxPersonalizationStringLength
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   125
    // or maxAdditionalInputLength to -1.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   126
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   127
    /**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   128
     * Minimum entropy input length in bytes for this DRBG instance.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   129
     * Must be assigned in {@link #chooseAlgorithmAndStrength}.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   130
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   131
    protected int minLength;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   132
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   133
    /**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   134
     * Maximum entropy input length in bytes for this DRBG instance.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   135
     * Should be assigned in {@link #chooseAlgorithmAndStrength} if it is not
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   136
     * {@link Integer#MAX_VALUE}.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   137
     * <p>
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   138
     * In theory this value (and the values below) can be bigger than
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   139
     * {@code Integer.MAX_VALUE} but a Java array can only have an int32 index.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   140
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   141
    protected int maxLength = Integer.MAX_VALUE;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   142
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   143
    /**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   144
     * Maximum personalization string length in bytes for this DRBG instance.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   145
     * Should be assigned in {@link #chooseAlgorithmAndStrength} if it is not
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   146
     * {@link Integer#MAX_VALUE}.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   147
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   148
    protected int maxPersonalizationStringLength = Integer.MAX_VALUE;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   149
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   150
    /**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   151
     * Maximum additional input length in bytes for this DRBG instance.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   152
     * Should be assigned in {@link #chooseAlgorithmAndStrength} if it is not
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   153
     * {@link Integer#MAX_VALUE}.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   154
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   155
    protected int maxAdditionalInputLength = Integer.MAX_VALUE;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   156
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   157
    /**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   158
     * max_number_of_bits_per_request in bytes for this DRBG instance.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   159
     * Should be assigned in {@link #chooseAlgorithmAndStrength} if it is not
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   160
     * {@link Integer#MAX_VALUE}.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   161
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   162
    protected int maxNumberOfBytesPerRequest = Integer.MAX_VALUE;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   163
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   164
    /**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   165
     * Maximum number of requests between reseeds for this DRBG instance.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   166
     * Should be assigned in {@link #chooseAlgorithmAndStrength} if it is not
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   167
     * {@link Integer#MAX_VALUE}.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   168
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   169
    protected int reseedInterval = Integer.MAX_VALUE;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   170
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   171
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   172
    /**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   173
     * Algorithm used by this instance (SHA-512 or AES-256). Must be assigned
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   174
     * in {@link #chooseAlgorithmAndStrength}. This field is used in
38853
971a7101da5b 8157308: Make AbstractDrbg non-Serializable
weijun
parents: 37896
diff changeset
   175
     * {@link #toString()}.
37796
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   176
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   177
    protected String algorithm;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   178
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   179
    // Configurable parameters
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   180
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   181
    /**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   182
     * Security strength for this instance. Must be assigned in
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   183
     * {@link #chooseAlgorithmAndStrength}. Should be at least the requested
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   184
     * strength. Might be smaller than the highest strength
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   185
     * {@link #algorithm} supports. Must not be -1.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   186
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   187
    protected int securityStrength;     // in bits
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   188
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   189
    /**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   190
     * Strength requested in {@link DrbgParameters.Instantiation}.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   191
     * The real strength is based on it. Do not modify it in a mechanism.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   192
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   193
    protected int requestedInstantiationSecurityStrength = -1;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   194
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   195
    /**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   196
     * The personalization string used by this instance. Set inside
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   197
     * {@link #configure(SecureRandomParameters)} and
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   198
     * can be used in a mechanism. Do not modify it in a mechanism.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   199
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   200
    protected byte[] personalizationString;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   201
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   202
    /**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   203
     * The prediction resistance flag used by this instance. Set inside
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   204
     * {@link #configure(SecureRandomParameters)}.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   205
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   206
    private boolean predictionResistanceFlag;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   207
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   208
    // Non-standard configurable parameters
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   209
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   210
    /**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   211
     * Whether a derivation function is used. Requested in
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   212
     * {@link MoreDrbgParameters}. Only CtrDRBG uses it.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   213
     * Do not modify it in a mechanism.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   214
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   215
    protected boolean usedf;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   216
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   217
    /**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   218
     * The nonce for this instance. Set in {@link #instantiateIfNecessary}.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   219
     * After instantiation, this field is not null. Do not modify it
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   220
     * in a mechanism.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   221
     */
38853
971a7101da5b 8157308: Make AbstractDrbg non-Serializable
weijun
parents: 37896
diff changeset
   222
    protected byte[] nonce;
37796
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   223
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   224
    /**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   225
     * Requested nonce in {@link MoreDrbgParameters}. If set to null,
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   226
     * nonce will be chosen by system, and a reinstantiated DRBG will get a
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   227
     * new system-provided nonce.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   228
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   229
    private byte[] requestedNonce;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   230
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   231
    /**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   232
     * Requested algorithm in {@link MoreDrbgParameters}.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   233
     * Do not modify it in a mechanism.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   234
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   235
    protected String requestedAlgorithm;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   236
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   237
    /**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   238
     * The entropy source used by this instance. Set inside
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   239
     * {@link #configure(SecureRandomParameters)}. This field
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   240
     * can be null. {@link #getEntropyInput} will take care of null check.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   241
     */
38853
971a7101da5b 8157308: Make AbstractDrbg non-Serializable
weijun
parents: 37896
diff changeset
   242
    private EntropySource es;
37796
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   243
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   244
    // Five abstract methods for SP 800-90A DRBG
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   245
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   246
    /**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   247
     * Decides what algorithm and strength to use (SHA-256 or AES-256,
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   248
     * 128 or 256). Strength related fields must also be defined or redefined
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   249
     * here. Called in {@link #configure}. A mechanism uses
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   250
     * {@link #requestedAlgorithm},
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   251
     * {@link #requestedInstantiationSecurityStrength}, and
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   252
     * {@link #DEFAULT_STRENGTH} to decide which algorithm and strength to use.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   253
     * <p>
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   254
     * If {@code requestedAlgorithm} is provided, it will always be used.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   255
     * If {@code requestedInstantiationSecurityStrength} is also provided,
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   256
     * the algorithm will use the strength (an exception will be thrown if
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   257
     * the strength is not supported), otherwise, the smaller one of
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   258
     * the highest supported strength of the algorithm and the default strength
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   259
     * will be used.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   260
     * <p>
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   261
     * If {@code requestedAlgorithm} is not provided, an algorithm will be
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   262
     * chosen that supports {@code requestedInstantiationSecurityStrength}
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   263
     * (or {@code DEFAULT_STRENGTH} if there is no request).
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   264
     * <p>
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   265
     * Since every call to {@link #configure} will call this method,
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   266
     * make sure to the calls do not contradict with each other.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   267
     * <p>
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   268
     * Here are some examples of the algorithm and strength chosen (suppose
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   269
     * {@code DEFAULT_STRENGTH} is 128) for HashDRBG:
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   270
     * <pre>
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   271
     * requested             effective
37896
cd841af7dcd0 8156213: Remove SHA-1 and 3KeyTDEA algorithms from DRBG
weijun
parents: 37895
diff changeset
   272
     * (SHA-224, 256)        IAE
37796
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   273
     * (SHA-256, -1)         (SHA-256,128)
37896
cd841af7dcd0 8156213: Remove SHA-1 and 3KeyTDEA algorithms from DRBG
weijun
parents: 37895
diff changeset
   274
     * (SHA-256, 112)        (SHA-256,112)
37796
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   275
     * (SHA-256, 128)        (SHA-256,128)
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   276
     * (SHA-3, -1)           IAE
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   277
     * (null, -1)            (SHA-256,128)
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   278
     * (null, 112)           (SHA-256,112)
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   279
     * (null, 192)           (SHA-256,192)
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   280
     * (null, 256)           (SHA-256,256)
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   281
     * (null, 384)           IAE
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   282
     * </pre>
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   283
     *
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   284
     * @throws IllegalArgumentException if the requested parameters
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   285
     *      can not be supported or contradict with each other.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   286
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   287
    protected abstract void chooseAlgorithmAndStrength();
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   288
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   289
    /**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   290
     * Initiates security engines ({@code MessageDigest}, {@code Mac},
38853
971a7101da5b 8157308: Make AbstractDrbg non-Serializable
weijun
parents: 37896
diff changeset
   291
     * or {@code Cipher}). This method is called during instantiation.
37796
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   292
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   293
    protected abstract void initEngine();
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   294
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   295
    /**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   296
     * Instantiates a DRBG. Called automatically before the first
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   297
     * {@code nextBytes} call.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   298
     * <p>
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   299
     * Note that the other parameters (nonce, strength, ps) are already
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   300
     * stored inside at configuration.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   301
     *
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   302
     * @param ei the entropy input, its length is already conditioned to be
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   303
     *           between {@link #minLength} and {@link #maxLength}.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   304
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   305
    protected abstract void instantiateAlgorithm(byte[] ei);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   306
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   307
    /**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   308
     * The generate function.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   309
     *
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   310
     * @param result fill result here, not null
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   311
     * @param additionalInput additional input, can be null. If not null,
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   312
     *          its length is smaller than {@link #maxAdditionalInputLength}
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   313
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   314
    protected abstract void generateAlgorithm(
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   315
            byte[] result, byte[] additionalInput);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   316
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   317
    /**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   318
     * The reseed function.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   319
     *
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   320
     * @param ei the entropy input, its length is already conditioned to be
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   321
     *           between {@link #minLength} and {@link #maxLength}.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   322
     * @param additionalInput additional input, can be null. If not null,
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   323
     *          its length is smaller than {@link #maxAdditionalInputLength}
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   324
     * @throws UnsupportedOperationException if reseed is not supported
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   325
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   326
    protected void reseedAlgorithm(
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   327
            byte[] ei, byte[] additionalInput) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   328
        throw new UnsupportedOperationException("No reseed function");
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   329
    }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   330
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   331
    // SecureRandomSpi methods taken care of here. All final.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   332
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   333
    protected final void engineNextBytes(byte[] result) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   334
        engineNextBytes(result, DrbgParameters.nextBytes(
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   335
                -1, predictionResistanceFlag, null));
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   336
    }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   337
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   338
    protected final void engineNextBytes(
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   339
            byte[] result, SecureRandomParameters params) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   340
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   341
        Objects.requireNonNull(result);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   342
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   343
        if (debug != null) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   344
            debug.println(this, "nextBytes");
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   345
        }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   346
        if (params instanceof DrbgParameters.NextBytes) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   347
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   348
            // 800-90Ar1 9.3: Generate Process.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   349
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   350
            DrbgParameters.NextBytes dp = (DrbgParameters.NextBytes) params;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   351
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   352
            // Step 2: max_number_of_bits_per_request
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   353
            if (result.length > maxNumberOfBytesPerRequest) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   354
                // generateAlgorithm should be called multiple times to fill
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   355
                // up result. Unimplemented since maxNumberOfBytesPerRequest
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   356
                // is now Integer.MAX_VALUE.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   357
            }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   358
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   359
            // Step 3: check requested_security_strength
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   360
            if (dp.getStrength() > securityStrength) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   361
                throw new IllegalArgumentException("strength too high: "
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   362
                        + dp.getStrength());
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   363
            }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   364
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   365
            // Step 4: check max_additional_input_length
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   366
            byte[] ai = dp.getAdditionalInput();
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   367
            if (ai != null && ai.length > maxAdditionalInputLength) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   368
                throw new IllegalArgumentException("ai too long: "
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   369
                        + ai.length);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   370
            }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   371
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   372
            // Step 5: check prediction_resistance_flag
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   373
            boolean pr = dp.getPredictionResistance();
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   374
            if (!predictionResistanceFlag && pr) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   375
                throw new IllegalArgumentException("pr not available");
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   376
            }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   377
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   378
            instantiateIfNecessary(null);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   379
39481
63ceb7ef04d4 8158589: Possible integer overflow issues for DRBG
weijun
parents: 38853
diff changeset
   380
            // Step 7: Auto reseed (reseedCounter might overflow)
37895
f59fdd7fb4fb 8156501: DRBG not synchronized at reseeding
weijun
parents: 37796
diff changeset
   381
            // Double checked locking, safe because reseedCounter is volatile
39481
63ceb7ef04d4 8158589: Possible integer overflow issues for DRBG
weijun
parents: 38853
diff changeset
   382
            if (reseedCounter < 0 || reseedCounter > reseedInterval || pr) {
37895
f59fdd7fb4fb 8156501: DRBG not synchronized at reseeding
weijun
parents: 37796
diff changeset
   383
                synchronized (this) {
39481
63ceb7ef04d4 8158589: Possible integer overflow issues for DRBG
weijun
parents: 38853
diff changeset
   384
                    if (reseedCounter < 0 || reseedCounter > reseedInterval
63ceb7ef04d4 8158589: Possible integer overflow issues for DRBG
weijun
parents: 38853
diff changeset
   385
                            || pr) {
37895
f59fdd7fb4fb 8156501: DRBG not synchronized at reseeding
weijun
parents: 37796
diff changeset
   386
                        reseedAlgorithm(getEntropyInput(pr), ai);
f59fdd7fb4fb 8156501: DRBG not synchronized at reseeding
weijun
parents: 37796
diff changeset
   387
                        ai = null;
f59fdd7fb4fb 8156501: DRBG not synchronized at reseeding
weijun
parents: 37796
diff changeset
   388
                    }
f59fdd7fb4fb 8156501: DRBG not synchronized at reseeding
weijun
parents: 37796
diff changeset
   389
                }
37796
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   390
            }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   391
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   392
            // Step 8, 10: Generate_algorithm
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   393
            // Step 9: Unnecessary. reseedCounter only updated after generation
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   394
            generateAlgorithm(result, ai);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   395
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   396
            // Step 11: Return
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   397
        } else {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   398
            throw new IllegalArgumentException("unknown params type:"
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   399
                    + params.getClass());
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   400
        }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   401
    }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   402
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   403
    public final void engineReseed(SecureRandomParameters params) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   404
        if (debug != null) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   405
            debug.println(this, "reseed with params");
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   406
        }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   407
        if (!supportReseeding) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   408
            throw new UnsupportedOperationException("Reseed not supported");
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   409
        }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   410
        if (params == null) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   411
            params = DrbgParameters.reseed(predictionResistanceFlag, null);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   412
        }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   413
        if (params instanceof DrbgParameters.Reseed) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   414
            DrbgParameters.Reseed dp = (DrbgParameters.Reseed) params;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   415
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   416
            // 800-90Ar1 9.2: Reseed Process.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   417
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   418
            // Step 2: Check prediction_resistance_request
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   419
            boolean pr = dp.getPredictionResistance();
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   420
            if (!predictionResistanceFlag && pr) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   421
                throw new IllegalArgumentException("pr not available");
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   422
            }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   423
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   424
            // Step 3: Check additional_input length
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   425
            byte[] ai = dp.getAdditionalInput();
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   426
            if (ai != null && ai.length > maxAdditionalInputLength) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   427
                throw new IllegalArgumentException("ai too long: "
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   428
                        + ai.length);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   429
            }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   430
            instantiateIfNecessary(null);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   431
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   432
            // Step 4: Get_entropy_input
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   433
            // Step 5: Check step 4
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   434
            // Step 6-7: Reseed_algorithm
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   435
            reseedAlgorithm(getEntropyInput(pr), ai);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   436
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   437
            // Step 8: Return
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   438
        } else {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   439
            throw new IllegalArgumentException("unknown params type: "
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   440
                    + params.getClass());
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   441
        }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   442
    }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   443
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   444
    /**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   445
     * Returns the given number of seed bytes. A DRBG always uses
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   446
     * {@link SeedGenerator} to get an array with full-entropy.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   447
     * <p>
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   448
     * The implementation is identical to SHA1PRNG's
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   449
     * {@link SecureRandom#engineGenerateSeed}.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   450
     *
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   451
     * @param numBytes the number of seed bytes to generate.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   452
     * @return the seed bytes.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   453
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   454
    public final byte[] engineGenerateSeed(int numBytes) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   455
        byte[] b = new byte[numBytes];
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   456
        SeedGenerator.generateSeed(b);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   457
        return b;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   458
    }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   459
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   460
    /**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   461
     * Reseeds this random object with the given seed. A DRBG always expands
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   462
     * or truncates the input to be between {@link #minLength} and
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   463
     * {@link #maxLength} and uses it to instantiate or reseed itself
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   464
     * (depending on whether the DRBG is instantiated).
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   465
     *
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   466
     * @param input the seed
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   467
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   468
    public final synchronized void engineSetSeed(byte[] input) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   469
        if (debug != null) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   470
            debug.println(this, "setSeed");
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   471
        }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   472
        if (input.length < minLength) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   473
            input = Arrays.copyOf(input, minLength);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   474
        } else if (input.length > maxLength) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   475
            input = Arrays.copyOf(input, maxLength);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   476
        }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   477
        if (!instantiated) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   478
            instantiateIfNecessary(input);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   479
        } else {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   480
            reseedAlgorithm(input, null);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   481
        }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   482
    }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   483
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   484
    // get_entropy_input
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   485
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   486
    private byte[] getEntropyInput(boolean isPr) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   487
        // Should the 1st arg be minEntropy or minLength?
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   488
        //
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   489
        // Technically it should be minEntropy, but CtrDRBG
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   490
        // (not using derivation function) is so confusing
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   491
        // (does it need only strength or seedlen of entropy?)
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   492
        // that it's safer to assume minLength. In all other
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   493
        // cases minLength equals to minEntropy.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   494
        return getEntropyInput(minLength, minLength, maxLength, isPr);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   495
    }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   496
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   497
    private byte[] getEntropyInput(int minEntropy, int minLength,
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   498
                                   int maxLength, boolean pr) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   499
        if (debug != null) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   500
            debug.println(this, "getEntropy(" + minEntropy + "," + minLength +
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   501
                    "," + maxLength + "," + pr + ")");
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   502
        }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   503
        EntropySource esNow = es;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   504
        if (esNow == null) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   505
            esNow = pr ? SeederHolder.prseeder : SeederHolder.seeder;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   506
        }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   507
        return esNow.getEntropy(minEntropy, minLength, maxLength, pr);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   508
    }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   509
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   510
    // Defaults
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   511
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   512
    /**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   513
     * The default {@code EntropySource} determined by system property
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   514
     * "java.security.egd" or security property "securerandom.source".
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   515
     * <p>
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   516
     * This object uses {@link SeedGenerator#generateSeed(byte[])} to
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   517
     * return a byte array containing {@code minLength} bytes. It is
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   518
     * assumed to support prediction resistance and always contains
50777
11e7eb8cb583 8202608: CommonSeeder test needs a white-box testing mechanism to replace the default entropy source
weijun
parents: 47216
diff changeset
   519
     * full-entropy.
37796
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   520
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   521
    private final static EntropySource defaultES =
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   522
            (minE, minLen, maxLen, pr) -> {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   523
        byte[] result = new byte[minLen];
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   524
        SeedGenerator.generateSeed(result);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   525
        return result;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   526
    };
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   527
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   528
    private static class SeederHolder {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   529
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   530
        /**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   531
         * Default EntropySource for SecureRandom with prediction resistance,
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   532
         */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   533
        static final EntropySource prseeder;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   534
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   535
        /**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   536
         * Default EntropySource for SecureRandom without prediction resistance,
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   537
         * which is backed by a DRBG whose EntropySource is {@link #prseeder}.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   538
         */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   539
        static final EntropySource seeder;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   540
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   541
        static {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   542
            prseeder = defaultES;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   543
            // According to SP800-90C section 7, a DRBG without live
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   544
            // entropy (drbg here, with pr being false) can instantiate
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   545
            // another DRBG with weaker strength. So we choose highest
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   546
            // strength we support.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   547
            HashDrbg first = new HashDrbg(new MoreDrbgParameters(
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   548
                    prseeder, null, "SHA-256", null, false,
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   549
                    DrbgParameters.instantiation(
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   550
                            256, NONE,
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   551
                            SeedGenerator.getSystemEntropy())));
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   552
            seeder = (entropy, minLen, maxLen, pr) -> {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   553
                if (pr) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   554
                    // This SEI does not support pr
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   555
                    throw new IllegalArgumentException("pr not supported");
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   556
                }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   557
                byte[] result = new byte[minLen];
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   558
                first.engineNextBytes(result);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   559
                return result;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   560
            };
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   561
        }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   562
    }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   563
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   564
    // Constructor called by overridden methods, initializer...
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   565
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   566
    /**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   567
     * A constructor without argument so that an implementation does not
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   568
     * need to always write {@code super(params)}.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   569
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   570
    protected AbstractDrbg() {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   571
        // Nothing
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   572
    }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   573
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   574
    /**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   575
     * A mechanism shall override this constructor to setup {@link #mechName},
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   576
     * {@link #highestSupportedSecurityStrength},
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   577
     * {@link #supportPredictionResistance}, {@link #supportReseeding}
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   578
     * or other features like {@link #DEFAULT_STRENGTH}. Finally it shall
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   579
     * call {@link #configure} on {@code params}.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   580
     *
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   581
     * @param params the {@link SecureRandomParameters} object.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   582
     *               This argument can be {@code null}.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   583
     * @throws IllegalArgumentException if {@code params} is
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   584
     *         inappropriate for this SecureRandom.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   585
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   586
    protected AbstractDrbg(SecureRandomParameters params) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   587
        // Nothing
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   588
    }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   589
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   590
    /**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   591
     * Returns the current configuration as a {@link DrbgParameters.Instantiation}
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   592
     * object.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   593
     *
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   594
     * @return the curent configuration
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   595
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   596
    protected SecureRandomParameters engineGetParameters() {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   597
        // Or read from variable.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   598
        return DrbgParameters.instantiation(
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   599
                securityStrength,
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   600
                predictionResistanceFlag ? PR_AND_RESEED :
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   601
                        (supportReseeding ? RESEED_ONLY : NONE),
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   602
                personalizationString);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   603
    }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   604
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   605
    /**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   606
     * Configure this DRBG. This method calls
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   607
     * {@link #chooseAlgorithmAndStrength()} and {@link #initEngine()}
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   608
     * but does not do the actual instantiation.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   609
     *
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   610
     * @param params configuration, if null, default configuration (default
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   611
     *               strength, pr_false, no personalization string) is used.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   612
     * @throws IllegalArgumentException if {@code params} is
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   613
     *         inappropriate for this SecureRandom.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   614
     */
37895
f59fdd7fb4fb 8156501: DRBG not synchronized at reseeding
weijun
parents: 37796
diff changeset
   615
    protected final void configure(SecureRandomParameters params) {
37796
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   616
        if (debug != null) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   617
            debug.println(this, "configure " + this + " with " + params);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   618
        }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   619
        if (params == null) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   620
            params = DrbgParameters.instantiation(-1, RESEED_ONLY, null);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   621
        }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   622
        if (params instanceof MoreDrbgParameters) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   623
            MoreDrbgParameters m = (MoreDrbgParameters)params;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   624
            this.requestedNonce = m.nonce;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   625
            this.es = m.es;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   626
            this.requestedAlgorithm = m.algorithm;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   627
            this.usedf = m.usedf;
38853
971a7101da5b 8157308: Make AbstractDrbg non-Serializable
weijun
parents: 37896
diff changeset
   628
            params = DrbgParameters.instantiation(m.strength,
971a7101da5b 8157308: Make AbstractDrbg non-Serializable
weijun
parents: 37896
diff changeset
   629
                    m.capability, m.personalizationString);
37796
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   630
        }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   631
        if (params != null) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   632
            if (params instanceof DrbgParameters.Instantiation) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   633
                DrbgParameters.Instantiation inst =
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   634
                        (DrbgParameters.Instantiation) params;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   635
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   636
                // 800-90Ar1 9.1: Instantiate Process. Steps 1-5.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   637
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   638
                // Step 1: Check requested_instantiation_security_strength
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   639
                if (inst.getStrength() > highestSupportedSecurityStrength) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   640
                    throw new IllegalArgumentException("strength too big: "
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   641
                            + inst.getStrength());
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   642
                }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   643
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   644
                // Step 2: Check prediction_resistance_flag
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   645
                if (inst.getCapability().supportsPredictionResistance()
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   646
                        && !supportPredictionResistance) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   647
                    throw new IllegalArgumentException("pr not supported");
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   648
                }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   649
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   650
                // Step 3: Check personalization_string
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   651
                byte[] ps = inst.getPersonalizationString();
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   652
                if (ps != null && ps.length > maxPersonalizationStringLength) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   653
                    throw new IllegalArgumentException("ps too long: "
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   654
                            + ps.length);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   655
                }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   656
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   657
                if (inst.getCapability().supportsReseeding()
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   658
                        && !supportReseeding) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   659
                    throw new IllegalArgumentException("reseed not supported");
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   660
                }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   661
                this.personalizationString = ps;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   662
                this.predictionResistanceFlag =
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   663
                        inst.getCapability().supportsPredictionResistance();
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   664
                this.requestedInstantiationSecurityStrength = inst.getStrength();
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   665
            } else {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   666
                throw new IllegalArgumentException("unknown params: "
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   667
                        + params.getClass());
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   668
            }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   669
        }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   670
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   671
        // Step 4: Set security_strength
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   672
        chooseAlgorithmAndStrength();
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   673
        instantiated = false;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   674
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   675
        // Step 5: no-op.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   676
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   677
        if (debug != null) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   678
            debug.println(this, "configured " + this);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   679
        }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   680
    }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   681
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   682
    /**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   683
     * Instantiate if necessary,
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   684
     *
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   685
     * @param entropy a user-provided entropy, the length is already good.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   686
     *                If null, will fetch entropy input automatically.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   687
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   688
    private synchronized void instantiateIfNecessary(byte[] entropy) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   689
        if (!instantiated) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   690
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   691
            // 800-90Ar1 9.1: Instantiate Process. Steps 6-12.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   692
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   693
            // Step 6: Get_entropy_input
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   694
            // Step 7: check error (getEntropyInput throw no exception now)
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   695
            if (entropy == null) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   696
                entropy = getEntropyInput(predictionResistanceFlag);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   697
            }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   698
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   699
            // Step 8. nonce
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   700
            if (requestedNonce != null) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   701
                nonce = requestedNonce;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   702
            } else {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   703
                nonce = NonceProvider.next();
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   704
            }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   705
            initEngine();
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   706
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   707
            // Step 9-11: Instantiate_algorithm
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   708
            instantiateAlgorithm(entropy);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   709
            instantiated = true;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   710
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   711
            // Step 12: Return
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   712
        }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   713
    }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   714
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   715
    // Nonce provider
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   716
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   717
    private static class NonceProvider {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   718
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   719
        // 128 bits of nonce can be used by 256-bit strength DRBG
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   720
        private static final byte[] block = new byte[16];
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   721
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   722
        private static synchronized byte[] next() {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   723
            int k = 15;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   724
            while ((k >= 0) && (++block[k] == 0)) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   725
                k--;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   726
            }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   727
            return block.clone();
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   728
        }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   729
    }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   730
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   731
    // Misc
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   732
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   733
    /** A handy method returning hexdump string with no colon or new line.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   734
     *
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   735
     * @param in input byte array
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   736
     * @return the hexdump string
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   737
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   738
    protected static String hex(byte[] in) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   739
        StringBuilder sb = new StringBuilder();
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   740
        for (byte b : in) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   741
            sb.append(String.format("%02x", b&0xff));
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   742
        }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   743
        return sb.toString();
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   744
    }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   745
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   746
    /**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   747
     * Returns the smallest standard strength (112, 128, 192, 256) that is
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   748
     * greater or equal to the input.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   749
     *
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   750
     * @param input the input strength
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   751
     * @return the standard strength
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   752
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   753
    protected static int getStandardStrength(int input) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   754
        if (input <= 112) return 112;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   755
        if (input <= 128) return 128;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   756
        if (input <= 192) return 192;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   757
        if (input <= 256) return 256;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   758
        throw new IllegalArgumentException("input too big: " + input);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   759
    }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   760
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   761
    @Override
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   762
    public String toString() {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   763
        return mechName + ","  + algorithm
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   764
                + "," + securityStrength + ","
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   765
                + (predictionResistanceFlag ? "pr_and_reseed"
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   766
                        : (supportReseeding ? "reseed_only" : "none"));
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   767
    }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   768
}