src/java.base/share/classes/sun/security/provider/HashDrbg.java
author weijun
Wed, 01 Aug 2018 13:35:08 +0800
changeset 51272 9d92ff04a29c
parent 47216 71c04702a3d5
permissions -rw-r--r--
8208602: Cannot read PEM X.509 cert if there is whitespace after the header or footer Reviewed-by: xuelei
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
37796
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
     1
/*
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 java.math.BigInteger;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    29
import java.security.DigestException;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    30
import java.security.MessageDigest;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    31
import java.security.NoSuchAlgorithmException;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    32
import java.security.NoSuchProviderException;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    33
import java.security.SecureRandomParameters;
39481
63ceb7ef04d4 8158589: Possible integer overflow issues for DRBG
weijun
parents: 38853
diff changeset
    34
import java.util.ArrayList;
37796
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    35
import java.util.Arrays;
39481
63ceb7ef04d4 8158589: Possible integer overflow issues for DRBG
weijun
parents: 38853
diff changeset
    36
import java.util.List;
37796
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    37
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    38
public class HashDrbg extends AbstractHashDrbg {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    39
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    40
    private static final byte[] ZERO = new byte[1];
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    41
    private static final byte[] ONE = new byte[]{1};
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    42
38853
971a7101da5b 8157308: Make AbstractDrbg non-Serializable
weijun
parents: 37895
diff changeset
    43
    private MessageDigest digest;
37796
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    44
38853
971a7101da5b 8157308: Make AbstractDrbg non-Serializable
weijun
parents: 37895
diff changeset
    45
    private byte[] v;
971a7101da5b 8157308: Make AbstractDrbg non-Serializable
weijun
parents: 37895
diff changeset
    46
    private byte[] c;
37796
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    47
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    48
    public HashDrbg(SecureRandomParameters params) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    49
        mechName = "Hash_DRBG";
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    50
        configure(params);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    51
    }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    52
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    53
    /**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    54
     * This call, used by the constructors, instantiates the digest.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    55
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    56
    @Override
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    57
    protected void initEngine() {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    58
        try {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    59
            /*
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    60
             * Use the local SUN implementation to avoid native
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    61
             * performance overhead.
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
            digest = MessageDigest.getInstance(algorithm, "SUN");
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    64
        } catch (NoSuchProviderException | NoSuchAlgorithmException e) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    65
            // Fallback to any available.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    66
            try {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    67
                digest = MessageDigest.getInstance(algorithm);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    68
            } catch (NoSuchAlgorithmException exc) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    69
                throw new InternalError(
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    70
                    "internal error: " + algorithm + " not available.", exc);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    71
            }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    72
        }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    73
    }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    74
39481
63ceb7ef04d4 8158589: Possible integer overflow issues for DRBG
weijun
parents: 38853
diff changeset
    75
    private byte[] hashDf(int requested, List<byte[]> inputs) {
37796
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    76
        return hashDf(digest, outLen, requested, inputs);
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
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    79
    /**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    80
     * A hash-based derivation function defined in NIST SP 800-90Ar1 10.3.1.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    81
     * The function is used inside Hash_DRBG, and can also be used as an
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    82
     * approved conditioning function as described in 800-90B 6.4.2.2.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    83
     *
39481
63ceb7ef04d4 8158589: Possible integer overflow issues for DRBG
weijun
parents: 38853
diff changeset
    84
     * Note: In each current call, requested is seedLen, therefore small,
63ceb7ef04d4 8158589: Possible integer overflow issues for DRBG
weijun
parents: 38853
diff changeset
    85
     * no need to worry about overflow.
63ceb7ef04d4 8158589: Possible integer overflow issues for DRBG
weijun
parents: 38853
diff changeset
    86
     *
37796
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    87
     * @param digest a {@code MessageDigest} object in reset state
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    88
     * @param outLen {@link MessageDigest#getDigestLength} of {@code digest}
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    89
     * @param requested requested output length, in bytes
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    90
     * @param inputs input data
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    91
     * @return the condensed/expanded output
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
    public static byte[] hashDf(MessageDigest digest, int outLen,
39481
63ceb7ef04d4 8158589: Possible integer overflow issues for DRBG
weijun
parents: 38853
diff changeset
    94
                                int requested, List<byte[]> inputs) {
63ceb7ef04d4 8158589: Possible integer overflow issues for DRBG
weijun
parents: 38853
diff changeset
    95
        // 1. temp = the Null string.
63ceb7ef04d4 8158589: Possible integer overflow issues for DRBG
weijun
parents: 38853
diff changeset
    96
        // 2. len = upper_int(no_of_bits_to_return / outLen)
37796
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    97
        int len = (requested + outLen - 1) / outLen;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    98
        byte[] temp = new byte[len * outLen];
39481
63ceb7ef04d4 8158589: Possible integer overflow issues for DRBG
weijun
parents: 38853
diff changeset
    99
        // 3. counter = 0x01
37796
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   100
        int counter = 1;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   101
39481
63ceb7ef04d4 8158589: Possible integer overflow issues for DRBG
weijun
parents: 38853
diff changeset
   102
        // 4. For i = 1 to len do
37796
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   103
        for (int i=0; i<len; i++) {
39481
63ceb7ef04d4 8158589: Possible integer overflow issues for DRBG
weijun
parents: 38853
diff changeset
   104
            // 4.1 temp = temp
63ceb7ef04d4 8158589: Possible integer overflow issues for DRBG
weijun
parents: 38853
diff changeset
   105
            //      || Hash (counter || no_of_bits_to_return || input_string).
37796
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   106
            digest.update((byte) counter);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   107
            digest.update((byte)(requested >> 21)); // requested*8 as int32
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   108
            digest.update((byte)(requested >> 13));
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   109
            digest.update((byte)(requested >> 5));
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   110
            digest.update((byte)(requested << 3));
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   111
            for (byte[] input : inputs) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   112
                digest.update(input);
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
            try {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   115
                digest.digest(temp, i * outLen, outLen);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   116
            } catch (DigestException e) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   117
                throw new AssertionError("will not happen", e);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   118
            }
39481
63ceb7ef04d4 8158589: Possible integer overflow issues for DRBG
weijun
parents: 38853
diff changeset
   119
            // 4.2 counter = counter + 1
37796
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   120
            counter++;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   121
        }
39481
63ceb7ef04d4 8158589: Possible integer overflow issues for DRBG
weijun
parents: 38853
diff changeset
   122
        // 5. requested_bits = leftmost (temp, no_of_bits_to_return).
37796
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   123
        return temp.length == requested? temp: Arrays.copyOf(temp, requested);
39481
63ceb7ef04d4 8158589: Possible integer overflow issues for DRBG
weijun
parents: 38853
diff changeset
   124
        // 6. Return
37796
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
    // This method is used by both instantiation and reseeding.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   128
    @Override
39481
63ceb7ef04d4 8158589: Possible integer overflow issues for DRBG
weijun
parents: 38853
diff changeset
   129
    protected final synchronized void hashReseedInternal(List<byte[]> inputs) {
37796
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   130
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   131
        // 800-90Ar1 10.1.1.2: Instantiate Process.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   132
        // 800-90Ar1 10.1.1.3: Reseed Process.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   133
        byte[] seed;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   134
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   135
        // Step 2: seed = Hash_df (seed_material, seedlen).
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   136
        if (v != null) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   137
            // Step 1 of 10.1.1.3: Prepend 0x01 || V
39481
63ceb7ef04d4 8158589: Possible integer overflow issues for DRBG
weijun
parents: 38853
diff changeset
   138
            inputs.add(0, ONE);
63ceb7ef04d4 8158589: Possible integer overflow issues for DRBG
weijun
parents: 38853
diff changeset
   139
            inputs.add(1, v);
63ceb7ef04d4 8158589: Possible integer overflow issues for DRBG
weijun
parents: 38853
diff changeset
   140
            seed = hashDf(seedLen, inputs);
37796
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   141
        } else {
39481
63ceb7ef04d4 8158589: Possible integer overflow issues for DRBG
weijun
parents: 38853
diff changeset
   142
            seed = hashDf(seedLen, inputs);
37796
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   143
        }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   144
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   145
        // Step 3. V = seed.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   146
        v = seed;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   147
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   148
        // Step 4. C = Hash_df ((0x00 || V), seedlen).
39481
63ceb7ef04d4 8158589: Possible integer overflow issues for DRBG
weijun
parents: 38853
diff changeset
   149
        inputs = new ArrayList<>(2);
63ceb7ef04d4 8158589: Possible integer overflow issues for DRBG
weijun
parents: 38853
diff changeset
   150
        inputs.add(ZERO);
63ceb7ef04d4 8158589: Possible integer overflow issues for DRBG
weijun
parents: 38853
diff changeset
   151
        inputs.add(v);
63ceb7ef04d4 8158589: Possible integer overflow issues for DRBG
weijun
parents: 38853
diff changeset
   152
        c = hashDf(seedLen, inputs);
37796
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
        // Step 5. reseed_counter = 1.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   155
        reseedCounter = 1;
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
        //status();
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   158
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   159
        // Step 6: Return
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
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   162
    private void status() {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   163
        if (debug != null) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   164
            debug.println(this, "V = " + hex(v));
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   165
            debug.println(this, "C = " + hex(c));
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   166
            debug.println(this, "reseed counter = " + reseedCounter);
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
    }
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
     * Adds byte arrays into an existing one.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   172
     *
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   173
     * @param out existing array
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   174
     * @param data more arrays, can be of different length
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
    private static void addBytes(byte[] out, int len, byte[]... data) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   177
        for (byte[] d: data) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   178
            int dlen = d.length;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   179
            int carry = 0;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   180
            for (int i = 0; i < len; i++) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   181
                int sum = (out[len - i - 1] & 0xff) + carry;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   182
                if (i < dlen) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   183
                    sum += (d[dlen - i - 1] & 0xff);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   184
                }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   185
                out[len - i - 1] = (byte) sum;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   186
                carry = sum >> 8;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   187
                if (i >= dlen - 1 && carry == 0) break;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   188
            }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   189
        }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   190
    }
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
    /**
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   193
     * Generates a user-specified number of random bytes.
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
     * @param result the array to be filled in with random bytes.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   196
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   197
    @Override
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   198
    public final synchronized void generateAlgorithm(
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   199
            byte[] result, byte[] additionalInput) {
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
        if (debug != null) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   202
            debug.println(this, "generateAlgorithm");
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   203
        }
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
        // 800-90Ar1 10.1.1.4: Hash_DRBG_Generate Process
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
        // Step 1: Check reseed_counter. Will not fail. Already checked in
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   208
        // AbstractDrbg#engineNextBytes.
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
        // Step 2: additional_input
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   211
        if (additionalInput != null) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   212
            digest.update((byte)2);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   213
            digest.update(v);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   214
            digest.update(additionalInput);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   215
            addBytes(v, seedLen, digest.digest());
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   216
        }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   217
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   218
        // Step 3. Hashgen (requested_number_of_bits, V).
39481
63ceb7ef04d4 8158589: Possible integer overflow issues for DRBG
weijun
parents: 38853
diff changeset
   219
        hashGen(result, v);
37796
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
        // Step 4. H = Hash (0x03 || V).
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   222
        digest.update((byte)3);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   223
        digest.update(v);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   224
        byte[] h = digest.digest();
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   225
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   226
        // Step 5. V = (V + H + C + reseed_counter) mod 2seedlen.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   227
        byte[] rcBytes;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   228
        if (reseedCounter < 256) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   229
            rcBytes = new byte[]{(byte)reseedCounter};
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   230
        } else {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   231
            rcBytes = BigInteger.valueOf(reseedCounter).toByteArray();
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   232
        }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   233
        addBytes(v, seedLen, h, c, rcBytes);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   234
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   235
        // Step 6. reseed_counter = reseed_counter + 1.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   236
        reseedCounter++;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   237
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   238
        //status();
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   239
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   240
        // Step 7: Return.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   241
    }
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
    // 800-90Ar1 10.1.1.4: Hashgen
39481
63ceb7ef04d4 8158589: Possible integer overflow issues for DRBG
weijun
parents: 38853
diff changeset
   244
    private void hashGen(byte[] output, byte[] v) {
37796
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
        // Step 2. data = V
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   247
        byte[] data = v;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   248
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   249
        // Step 3: W is output not filled
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   250
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   251
        // Step 4: For i = 1 to m
39481
63ceb7ef04d4 8158589: Possible integer overflow issues for DRBG
weijun
parents: 38853
diff changeset
   252
        int pos = 0;
63ceb7ef04d4 8158589: Possible integer overflow issues for DRBG
weijun
parents: 38853
diff changeset
   253
        int len = output.length;
63ceb7ef04d4 8158589: Possible integer overflow issues for DRBG
weijun
parents: 38853
diff changeset
   254
63ceb7ef04d4 8158589: Possible integer overflow issues for DRBG
weijun
parents: 38853
diff changeset
   255
        while (len > 0) {
63ceb7ef04d4 8158589: Possible integer overflow issues for DRBG
weijun
parents: 38853
diff changeset
   256
            if (len < outLen) {
37796
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   257
                // Step 4.1 w = Hash (data).
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   258
                // Step 4.2 W = W || w.
39481
63ceb7ef04d4 8158589: Possible integer overflow issues for DRBG
weijun
parents: 38853
diff changeset
   259
                System.arraycopy(digest.digest(data), 0, output, pos,
63ceb7ef04d4 8158589: Possible integer overflow issues for DRBG
weijun
parents: 38853
diff changeset
   260
                        len);
37796
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   261
            } else {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   262
                try {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   263
                    // Step 4.1 w = Hash (data).
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   264
                    digest.update(data);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   265
                    // Step 4.2 digest into right position, no need to cat
39481
63ceb7ef04d4 8158589: Possible integer overflow issues for DRBG
weijun
parents: 38853
diff changeset
   266
                    digest.digest(output, pos, outLen);
37796
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   267
                } catch (DigestException e) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   268
                    throw new AssertionError("will not happen", e);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   269
                }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   270
            }
39481
63ceb7ef04d4 8158589: Possible integer overflow issues for DRBG
weijun
parents: 38853
diff changeset
   271
            len -= outLen;
63ceb7ef04d4 8158589: Possible integer overflow issues for DRBG
weijun
parents: 38853
diff changeset
   272
            if (len <= 0) {
63ceb7ef04d4 8158589: Possible integer overflow issues for DRBG
weijun
parents: 38853
diff changeset
   273
                // shortcut, so that data and pos needn't be updated
63ceb7ef04d4 8158589: Possible integer overflow issues for DRBG
weijun
parents: 38853
diff changeset
   274
                break;
37796
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   275
            }
39481
63ceb7ef04d4 8158589: Possible integer overflow issues for DRBG
weijun
parents: 38853
diff changeset
   276
            // Step 4.3 data = (data + 1) mod 2^seedlen.
63ceb7ef04d4 8158589: Possible integer overflow issues for DRBG
weijun
parents: 38853
diff changeset
   277
            if (data == v) {
63ceb7ef04d4 8158589: Possible integer overflow issues for DRBG
weijun
parents: 38853
diff changeset
   278
                data = Arrays.copyOf(v, v.length);
63ceb7ef04d4 8158589: Possible integer overflow issues for DRBG
weijun
parents: 38853
diff changeset
   279
            }
63ceb7ef04d4 8158589: Possible integer overflow issues for DRBG
weijun
parents: 38853
diff changeset
   280
            addBytes(data, seedLen, ONE);
63ceb7ef04d4 8158589: Possible integer overflow issues for DRBG
weijun
parents: 38853
diff changeset
   281
            pos += outLen;
37796
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   282
        }
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
        // Step 5: No need to truncate
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   285
        // Step 6: Return
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
}