jdk/src/java.base/share/classes/sun/security/provider/AbstractDrbg.java
author weijun
Fri, 06 May 2016 11:38:44 +0800
changeset 37796 256c45c4af5d
child 37895 f59fdd7fb4fb
permissions -rw-r--r--
8051408: NIST SP 800-90A SecureRandom implementations Reviewed-by: wetmore, xuelei, coffeys
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
37796
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
     1
/*
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
     2
 * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
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
/**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    36
 * The abstract base class for all DRBGs.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    37
 * <p>
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    38
 * This class creates 5 new abstract methods. 3 are defined by the SP800-90A:
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[])}
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    41
 *  <li>{@link #reseedAlgorithm(byte[], byte[])} (might not be supported)
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    42
 *  <li>{@link #instantiateAlgorithm(byte[])}
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    43
 * </ol>
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    44
 * and 2 for implementation purpose:
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    45
 * <ol>
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    46
 *  <li>{@link #initEngine()}
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    47
 *  <li>{@link #chooseAlgorithmAndStrength}
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    48
 * </ol>
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    49
 * All existing {@link SecureRandomSpi} methods are implemented based on the
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    50
 * methods above as final. The initialization process is divided into 2 phases:
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    51
 * configuration is eagerly called to set up parameters, and instantiation
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    52
 * is lazily called only when nextBytes or reseed is called.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    53
 * <p>
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    54
 * Synchronized keyword should be added to all externally callable engine
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    55
 * methods including {@link #engineReseed}, {@link #engineSetSeed}, and
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    56
 * {@link #engineNextBytes} (but not {@link #engineGenerateSeed}).
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    57
 * Internal methods like {@link #configure} and {@link #instantiateAlgorithm}
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    58
 * are not synchronized. They will either be called in a constructor or
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    59
 * in another synchronized method.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    60
 */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    61
public abstract class AbstractDrbg extends SecureRandomSpi {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    62
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    63
    private static final long serialVersionUID = 9L;
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
    /**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    66
     * This field is not null if {@code -Djava.security.debug=securerandom} is
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    67
     * specified on the command line. An implementation can print useful
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    68
     * debug info.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    69
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    70
    protected static final Debug debug = Debug.getInstance(
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    71
            "securerandom", "drbg");
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    72
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    73
    // Common working status
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    74
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    75
    private transient boolean instantiated = false;
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
    /**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    78
     * Reseed counter of a DRBG instance. A mechanism should increment it
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    79
     * after each random bits generation and reset it in reseed. A mechanism
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    80
     * does <em>not</em> need to compare it to {@link #reseedInterval}.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    81
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    82
    protected transient int reseedCounter = 0;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    83
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    84
    // Mech features. If not same as below, must be redefined in constructor.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    85
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
     * Default strength of a DRBG instance if it is not configured.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    88
     * 128 is considered secure enough now. A mechanism
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    89
     * can change it in a constructor.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    90
     *
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    91
     * Remember to sync with "securerandom.drbg.config" in java.security.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    92
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    93
    protected static final int DEFAULT_STRENGTH = 128;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    94
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
     * Mechanism name, say, {@code HashDRBG}. Must be set in constructor.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    97
     * This value will be used in {@code toString}.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    98
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    99
    protected String mechName = "DRBG";
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   100
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
     * highest_supported_security_strength of this mechanism for all algorithms
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   103
     * it supports. A mechanism should update the value in its constructor
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   104
     * if the value is not 256.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   105
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   106
    protected int highestSupportedSecurityStrength = 256;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   107
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
     * Whether prediction resistance is supported. A mechanism should update
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   110
     * the value in its constructor if it is <em>not</em> supported.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   111
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   112
    protected boolean supportPredictionResistance = true;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   113
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
     * Whether reseed is supported. A mechanism should update
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   116
     * the value in its constructor if it is <em>not</em> supported.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   117
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   118
    protected boolean supportReseeding = true;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   119
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   120
    // Strength features. If not same as below, must be redefined in
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   121
    // chooseAlgorithmAndStrength. Among these, minLength and seedLen have no
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   122
    // default value and must be redefined. If personalization string or
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   123
    // additional input is not supported, set maxPersonalizationStringLength
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   124
    // or maxAdditionalInputLength to -1.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   125
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
     * Minimum entropy input length in bytes for this DRBG instance.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   128
     * Must be assigned in {@link #chooseAlgorithmAndStrength}.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   129
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   130
    protected int minLength;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   131
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
     * Maximum entropy input length in bytes for this DRBG instance.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   134
     * Should be assigned in {@link #chooseAlgorithmAndStrength} if it is not
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   135
     * {@link Integer#MAX_VALUE}.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   136
     * <p>
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   137
     * In theory this value (and the values below) can be bigger than
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   138
     * {@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
   139
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   140
    protected int maxLength = Integer.MAX_VALUE;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   141
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
     * Maximum personalization string length in bytes for this DRBG instance.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   144
     * Should be assigned in {@link #chooseAlgorithmAndStrength} if it is not
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   145
     * {@link Integer#MAX_VALUE}.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   146
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   147
    protected int maxPersonalizationStringLength = Integer.MAX_VALUE;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   148
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
     * Maximum additional input length in bytes for this DRBG instance.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   151
     * Should be assigned in {@link #chooseAlgorithmAndStrength} if it is not
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   152
     * {@link Integer#MAX_VALUE}.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   153
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   154
    protected int maxAdditionalInputLength = Integer.MAX_VALUE;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   155
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
     * max_number_of_bits_per_request in bytes for this DRBG instance.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   158
     * Should be assigned in {@link #chooseAlgorithmAndStrength} if it is not
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   159
     * {@link Integer#MAX_VALUE}.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   160
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   161
    protected int maxNumberOfBytesPerRequest = Integer.MAX_VALUE;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   162
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
     * Maximum number of requests between reseeds for this DRBG instance.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   165
     * Should be assigned in {@link #chooseAlgorithmAndStrength} if it is not
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   166
     * {@link Integer#MAX_VALUE}.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   167
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   168
    protected int reseedInterval = Integer.MAX_VALUE;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   169
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
     * 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
   173
     * in {@link #chooseAlgorithmAndStrength}. This field is used in
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   174
     * {@link #toString()} and {@link DRBG#algorithmName}.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   175
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   176
    protected String algorithm;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   177
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   178
    // Configurable parameters
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   179
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
     * Security strength for this instance. Must be assigned in
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   182
     * {@link #chooseAlgorithmAndStrength}. Should be at least the requested
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   183
     * strength. Might be smaller than the highest strength
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   184
     * {@link #algorithm} supports. Must not be -1.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   185
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   186
    protected int securityStrength;     // in bits
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   187
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
     * Strength requested in {@link DrbgParameters.Instantiation}.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   190
     * 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
   191
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   192
    protected int requestedInstantiationSecurityStrength = -1;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   193
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
     * The personalization string used by this instance. Set inside
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   196
     * {@link #configure(SecureRandomParameters)} and
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   197
     * 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
   198
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   199
    protected byte[] personalizationString;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   200
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
     * The prediction resistance flag used by this instance. Set inside
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   203
     * {@link #configure(SecureRandomParameters)}.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   204
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   205
    private boolean predictionResistanceFlag;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   206
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   207
    // Non-standard configurable parameters
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   208
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
     * Whether a derivation function is used. Requested in
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   211
     * {@link MoreDrbgParameters}. Only CtrDRBG uses it.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   212
     * Do not modify it in a mechanism.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   213
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   214
    protected boolean usedf;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   215
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
     * The nonce for this instance. Set in {@link #instantiateIfNecessary}.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   218
     * After instantiation, this field is not null. Do not modify it
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   219
     * in a mechanism.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   220
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   221
    protected transient byte[] nonce;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   222
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
     * Requested nonce in {@link MoreDrbgParameters}. If set to null,
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   225
     * 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
   226
     * new system-provided nonce.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   227
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   228
    private byte[] requestedNonce;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   229
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
     * Requested algorithm in {@link MoreDrbgParameters}.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   232
     * Do not modify it in a mechanism.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   233
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   234
    protected String requestedAlgorithm;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   235
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
     * The entropy source used by this instance. Set inside
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   238
     * {@link #configure(SecureRandomParameters)}. This field
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   239
     * can be null. {@link #getEntropyInput} will take care of null check.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   240
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   241
    private transient EntropySource es;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   242
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   243
    // Five abstract methods for SP 800-90A DRBG
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   244
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
     * Decides what algorithm and strength to use (SHA-256 or AES-256,
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   247
     * 128 or 256). Strength related fields must also be defined or redefined
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   248
     * here. Called in {@link #configure}. A mechanism uses
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   249
     * {@link #requestedAlgorithm},
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   250
     * {@link #requestedInstantiationSecurityStrength}, and
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   251
     * {@link #DEFAULT_STRENGTH} to decide which algorithm and strength to use.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   252
     * <p>
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   253
     * If {@code requestedAlgorithm} is provided, it will always be used.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   254
     * If {@code requestedInstantiationSecurityStrength} is also provided,
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   255
     * the algorithm will use the strength (an exception will be thrown if
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   256
     * the strength is not supported), otherwise, the smaller one of
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   257
     * the highest supported strength of the algorithm and the default strength
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   258
     * will be used.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   259
     * <p>
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   260
     * If {@code requestedAlgorithm} is not provided, an algorithm will be
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   261
     * chosen that supports {@code requestedInstantiationSecurityStrength}
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   262
     * (or {@code DEFAULT_STRENGTH} if there is no request).
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   263
     * <p>
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   264
     * Since every call to {@link #configure} will call this method,
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   265
     * make sure to the calls do not contradict with each other.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   266
     * <p>
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   267
     * Here are some examples of the algorithm and strength chosen (suppose
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   268
     * {@code DEFAULT_STRENGTH} is 128) for HashDRBG:
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   269
     * <pre>
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   270
     * requested             effective
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   271
     * (SHA-1, -1)           (SHA-1,128)
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   272
     * (SHA-1, 112)          (SHA-1,112)
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   273
     * (SHA-1, 192)          IAE
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   274
     * (SHA-256, -1)         (SHA-256,128)
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},
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   291
     * or {@code Cipher}). Must be called in deserialization. Please note
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   292
     * that before instantiation the algorithm might not be available yet.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   293
     * In this case, just return and this method will be called
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   294
     * automatically at instantiation.
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
    protected abstract void initEngine();
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   297
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   298
    /**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   299
     * Instantiates a DRBG. Called automatically before the first
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   300
     * {@code nextBytes} call.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   301
     * <p>
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   302
     * Note that the other parameters (nonce, strength, ps) are already
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   303
     * stored inside at configuration.
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
     * @param ei the entropy input, its length is already conditioned to be
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   306
     *           between {@link #minLength} and {@link #maxLength}.
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
    protected abstract void instantiateAlgorithm(byte[] ei);
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
    /**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   311
     * The generate function.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   312
     *
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   313
     * @param result fill result here, not null
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   314
     * @param additionalInput additional input, can be null. If not null,
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   315
     *          its length is smaller than {@link #maxAdditionalInputLength}
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
    protected abstract void generateAlgorithm(
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   318
            byte[] result, byte[] additionalInput);
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
    /**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   321
     * The reseed function.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   322
     *
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   323
     * @param ei the entropy input, its length is already conditioned to be
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   324
     *           between {@link #minLength} and {@link #maxLength}.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   325
     * @param additionalInput additional input, can be null. If not null,
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   326
     *          its length is smaller than {@link #maxAdditionalInputLength}
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   327
     * @throws UnsupportedOperationException if reseed is not supported
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   328
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   329
    protected void reseedAlgorithm(
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   330
            byte[] ei, byte[] additionalInput) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   331
        throw new UnsupportedOperationException("No reseed function");
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
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   334
    // SecureRandomSpi methods taken care of here. All final.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   335
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   336
    @Override
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   337
    protected final void engineNextBytes(byte[] result) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   338
        engineNextBytes(result, DrbgParameters.nextBytes(
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   339
                -1, predictionResistanceFlag, null));
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
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   342
    @Override
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   343
    protected final void engineNextBytes(
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   344
            byte[] result, SecureRandomParameters params) {
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
        Objects.requireNonNull(result);
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
        if (debug != null) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   349
            debug.println(this, "nextBytes");
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   350
        }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   351
        if (params instanceof DrbgParameters.NextBytes) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   352
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   353
            // 800-90Ar1 9.3: Generate Process.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   354
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   355
            DrbgParameters.NextBytes dp = (DrbgParameters.NextBytes) params;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   356
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   357
            // Step 2: max_number_of_bits_per_request
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   358
            if (result.length > maxNumberOfBytesPerRequest) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   359
                // generateAlgorithm should be called multiple times to fill
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   360
                // up result. Unimplemented since maxNumberOfBytesPerRequest
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   361
                // is now Integer.MAX_VALUE.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   362
            }
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
            // Step 3: check requested_security_strength
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   365
            if (dp.getStrength() > securityStrength) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   366
                throw new IllegalArgumentException("strength too high: "
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   367
                        + dp.getStrength());
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   368
            }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   369
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   370
            // Step 4: check max_additional_input_length
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   371
            byte[] ai = dp.getAdditionalInput();
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   372
            if (ai != null && ai.length > maxAdditionalInputLength) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   373
                throw new IllegalArgumentException("ai too long: "
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   374
                        + ai.length);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   375
            }
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
            // Step 5: check prediction_resistance_flag
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   378
            boolean pr = dp.getPredictionResistance();
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   379
            if (!predictionResistanceFlag && pr) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   380
                throw new IllegalArgumentException("pr not available");
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   381
            }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   382
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   383
            instantiateIfNecessary(null);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   384
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   385
            // Step 7: Auto reseed
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   386
            if (reseedCounter > reseedInterval || pr) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   387
                reseedAlgorithm(getEntropyInput(pr), ai);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   388
                ai = null;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   389
            }
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
            // Step 8, 10: Generate_algorithm
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   392
            // Step 9: Unnecessary. reseedCounter only updated after generation
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   393
            generateAlgorithm(result, ai);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   394
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   395
            // Step 11: Return
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   396
        } else {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   397
            throw new IllegalArgumentException("unknown params type:"
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   398
                    + params.getClass());
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   399
        }
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
    @Override
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
    @Override
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   455
    public final byte[] engineGenerateSeed(int numBytes) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   456
        byte[] b = new byte[numBytes];
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   457
        SeedGenerator.generateSeed(b);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   458
        return b;
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
    /**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   462
     * Reseeds this random object with the given seed. A DRBG always expands
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   463
     * or truncates the input to be between {@link #minLength} and
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   464
     * {@link #maxLength} and uses it to instantiate or reseed itself
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   465
     * (depending on whether the DRBG is instantiated).
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   466
     *
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   467
     * @param input the seed
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   468
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   469
    @Override
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   470
    public final synchronized void engineSetSeed(byte[] input) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   471
        if (debug != null) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   472
            debug.println(this, "setSeed");
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   473
        }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   474
        if (input.length < minLength) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   475
            input = Arrays.copyOf(input, minLength);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   476
        } else if (input.length > maxLength) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   477
            input = Arrays.copyOf(input, maxLength);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   478
        }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   479
        if (!instantiated) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   480
            instantiateIfNecessary(input);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   481
        } else {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   482
            reseedAlgorithm(input, null);
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
    }
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
    // get_entropy_input
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   487
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   488
    private byte[] getEntropyInput(boolean isPr) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   489
        // Should the 1st arg be minEntropy or minLength?
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   490
        //
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   491
        // Technically it should be minEntropy, but CtrDRBG
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   492
        // (not using derivation function) is so confusing
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   493
        // (does it need only strength or seedlen of entropy?)
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   494
        // that it's safer to assume minLength. In all other
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   495
        // cases minLength equals to minEntropy.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   496
        return getEntropyInput(minLength, minLength, maxLength, isPr);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   497
    }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   498
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   499
    private byte[] getEntropyInput(int minEntropy, int minLength,
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   500
                                   int maxLength, boolean pr) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   501
        if (debug != null) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   502
            debug.println(this, "getEntropy(" + minEntropy + "," + minLength +
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   503
                    "," + maxLength + "," + pr + ")");
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   504
        }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   505
        EntropySource esNow = es;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   506
        if (esNow == null) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   507
            esNow = pr ? SeederHolder.prseeder : SeederHolder.seeder;
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
        return esNow.getEntropy(minEntropy, minLength, maxLength, pr);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   510
    }
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
    // Defaults
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   513
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   514
    /**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   515
     * The default {@code EntropySource} determined by system property
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   516
     * "java.security.egd" or security property "securerandom.source".
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   517
     * <p>
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   518
     * This object uses {@link SeedGenerator#generateSeed(byte[])} to
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   519
     * return a byte array containing {@code minLength} bytes. It is
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   520
     * assumed to support prediction resistance and always contains
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   521
     * full-entropy. A trusted application can update this field.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   522
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   523
    private final static EntropySource defaultES =
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   524
            (minE, minLen, maxLen, pr) -> {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   525
        byte[] result = new byte[minLen];
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   526
        SeedGenerator.generateSeed(result);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   527
        return result;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   528
    };
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
    private static class SeederHolder {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   531
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
         * Default EntropySource for SecureRandom with prediction resistance,
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
        static final EntropySource prseeder;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   536
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   537
        /**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   538
         * Default EntropySource for SecureRandom without prediction resistance,
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   539
         * which is backed by a DRBG whose EntropySource is {@link #prseeder}.
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 final EntropySource seeder;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   542
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   543
        static {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   544
            prseeder = defaultES;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   545
            // According to SP800-90C section 7, a DRBG without live
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   546
            // entropy (drbg here, with pr being false) can instantiate
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   547
            // another DRBG with weaker strength. So we choose highest
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   548
            // strength we support.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   549
            HashDrbg first = new HashDrbg(new MoreDrbgParameters(
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   550
                    prseeder, null, "SHA-256", null, false,
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   551
                    DrbgParameters.instantiation(
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   552
                            256, NONE,
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   553
                            SeedGenerator.getSystemEntropy())));
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   554
            seeder = (entropy, minLen, maxLen, pr) -> {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   555
                if (pr) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   556
                    // This SEI does not support pr
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   557
                    throw new IllegalArgumentException("pr not supported");
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   558
                }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   559
                byte[] result = new byte[minLen];
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   560
                first.engineNextBytes(result);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   561
                return result;
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
    }
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
    // Constructor called by overridden methods, initializer...
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   567
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   568
    /**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   569
     * A constructor without argument so that an implementation does not
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   570
     * need to always write {@code super(params)}.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   571
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   572
    protected AbstractDrbg() {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   573
        // Nothing
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
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   576
    /**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   577
     * A mechanism shall override this constructor to setup {@link #mechName},
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   578
     * {@link #highestSupportedSecurityStrength},
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   579
     * {@link #supportPredictionResistance}, {@link #supportReseeding}
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   580
     * or other features like {@link #DEFAULT_STRENGTH}. Finally it shall
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   581
     * call {@link #configure} on {@code params}.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   582
     *
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   583
     * @param params the {@link SecureRandomParameters} object.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   584
     *               This argument can be {@code null}.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   585
     * @throws IllegalArgumentException if {@code params} is
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   586
     *         inappropriate for this SecureRandom.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   587
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   588
    protected AbstractDrbg(SecureRandomParameters params) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   589
        // Nothing
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
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   592
    /**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   593
     * Returns the current configuration as a {@link DrbgParameters.Instantiation}
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   594
     * object.
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
     * @return the curent configuration
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   597
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   598
    @Override
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   599
    protected SecureRandomParameters engineGetParameters() {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   600
        // Or read from variable.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   601
        return DrbgParameters.instantiation(
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   602
                securityStrength,
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   603
                predictionResistanceFlag ? PR_AND_RESEED :
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   604
                        (supportReseeding ? RESEED_ONLY : NONE),
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   605
                personalizationString);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   606
    }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   607
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   608
    /**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   609
     * Configure this DRBG. This method calls
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   610
     * {@link #chooseAlgorithmAndStrength()} and {@link #initEngine()}
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   611
     * but does not do the actual instantiation.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   612
     *
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   613
     * @param params configuration, if null, default configuration (default
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   614
     *               strength, pr_false, no personalization string) is used.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   615
     * @throws IllegalArgumentException if {@code params} is
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   616
     *         inappropriate for this SecureRandom.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   617
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   618
    protected final synchronized void configure(
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   619
            SecureRandomParameters params) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   620
        if (debug != null) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   621
            debug.println(this, "configure " + this + " with " + params);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   622
        }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   623
        if (params == null) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   624
            params = DrbgParameters.instantiation(-1, RESEED_ONLY, null);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   625
        }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   626
        if (params instanceof MoreDrbgParameters) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   627
            MoreDrbgParameters m = (MoreDrbgParameters)params;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   628
            this.requestedNonce = m.nonce;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   629
            this.es = m.es;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   630
            this.requestedAlgorithm = m.algorithm;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   631
            this.usedf = m.usedf;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   632
            params = m.config;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   633
        }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   634
        if (params != null) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   635
            if (params instanceof DrbgParameters.Instantiation) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   636
                DrbgParameters.Instantiation inst =
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   637
                        (DrbgParameters.Instantiation) params;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   638
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   639
                // 800-90Ar1 9.1: Instantiate Process. Steps 1-5.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   640
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   641
                // Step 1: Check requested_instantiation_security_strength
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   642
                if (inst.getStrength() > highestSupportedSecurityStrength) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   643
                    throw new IllegalArgumentException("strength too big: "
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   644
                            + inst.getStrength());
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   645
                }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   646
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   647
                // Step 2: Check prediction_resistance_flag
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   648
                if (inst.getCapability().supportsPredictionResistance()
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   649
                        && !supportPredictionResistance) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   650
                    throw new IllegalArgumentException("pr not supported");
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   651
                }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   652
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   653
                // Step 3: Check personalization_string
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   654
                byte[] ps = inst.getPersonalizationString();
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   655
                if (ps != null && ps.length > maxPersonalizationStringLength) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   656
                    throw new IllegalArgumentException("ps too long: "
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   657
                            + ps.length);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   658
                }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   659
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   660
                if (inst.getCapability().supportsReseeding()
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   661
                        && !supportReseeding) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   662
                    throw new IllegalArgumentException("reseed not supported");
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   663
                }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   664
                this.personalizationString = ps;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   665
                this.predictionResistanceFlag =
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   666
                        inst.getCapability().supportsPredictionResistance();
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   667
                this.requestedInstantiationSecurityStrength = inst.getStrength();
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   668
            } else {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   669
                throw new IllegalArgumentException("unknown params: "
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   670
                        + params.getClass());
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   671
            }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   672
        }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   673
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   674
        // Step 4: Set security_strength
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   675
        chooseAlgorithmAndStrength();
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   676
        instantiated = false;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   677
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   678
        // Step 5: no-op.
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
        if (debug != null) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   681
            debug.println(this, "configured " + this);
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
    }
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
    /**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   686
     * Instantiate if necessary,
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
     * @param entropy a user-provided entropy, the length is already good.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   689
     *                If null, will fetch entropy input automatically.
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
    private synchronized void instantiateIfNecessary(byte[] entropy) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   692
        if (!instantiated) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   693
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   694
            // 800-90Ar1 9.1: Instantiate Process. Steps 6-12.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   695
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   696
            // Step 6: Get_entropy_input
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   697
            // Step 7: check error (getEntropyInput throw no exception now)
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   698
            if (entropy == null) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   699
                entropy = getEntropyInput(predictionResistanceFlag);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   700
            }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   701
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   702
            // Step 8. nonce
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   703
            if (requestedNonce != null) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   704
                nonce = requestedNonce;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   705
            } else {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   706
                nonce = NonceProvider.next();
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   707
            }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   708
            initEngine();
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   709
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   710
            // Step 9-11: Instantiate_algorithm
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   711
            instantiateAlgorithm(entropy);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   712
            instantiated = true;
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
            // Step 12: Return
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   715
        }
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
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   718
    // Nonce provider
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   719
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   720
    private static class NonceProvider {
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
        // 128 bits of nonce can be used by 256-bit strength DRBG
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   723
        private static final byte[] block = new byte[16];
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   724
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   725
        private static synchronized byte[] next() {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   726
            int k = 15;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   727
            while ((k >= 0) && (++block[k] == 0)) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   728
                k--;
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
            return block.clone();
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   731
        }
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
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   734
    // Misc
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   735
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   736
    /** A handy method returning hexdump string with no colon or new line.
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
     * @param in input byte array
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   739
     * @return the hexdump string
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   740
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   741
    protected static String hex(byte[] in) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   742
        StringBuilder sb = new StringBuilder();
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   743
        for (byte b : in) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   744
            sb.append(String.format("%02x", b&0xff));
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
        return sb.toString();
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   747
    }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   748
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
     * Returns the smallest standard strength (112, 128, 192, 256) that is
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   751
     * greater or equal to the input.
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
     * @param input the input strength
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   754
     * @return the standard strength
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   755
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   756
    protected static int getStandardStrength(int input) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   757
        if (input <= 112) return 112;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   758
        if (input <= 128) return 128;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   759
        if (input <= 192) return 192;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   760
        if (input <= 256) return 256;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   761
        throw new IllegalArgumentException("input too big: " + input);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   762
    }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   763
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   764
    @Override
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   765
    public String toString() {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   766
        return mechName + ","  + algorithm
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   767
                + "," + securityStrength + ","
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   768
                + (predictionResistanceFlag ? "pr_and_reseed"
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   769
                        : (supportReseeding ? "reseed_only" : "none"));
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   770
    }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   771
}