jdk/src/java.base/share/classes/sun/security/provider/CtrDrbg.java
author weijun
Thu, 12 May 2016 13:06:03 +0800
changeset 37896 cd841af7dcd0
parent 37895 f59fdd7fb4fb
child 38462 e3d8ddb3512c
permissions -rw-r--r--
8156213: Remove SHA-1 and 3KeyTDEA algorithms from DRBG Reviewed-by: wetmore, 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 javax.crypto.Cipher;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    29
import javax.crypto.NoSuchPaddingException;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    30
import javax.crypto.spec.SecretKeySpec;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    31
import java.io.IOException;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    32
import java.security.*;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    33
import java.util.Arrays;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    34
import java.util.Locale;
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
public class CtrDrbg extends AbstractDrbg {
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
    private static final long serialVersionUID = 9L;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    39
    private static final int AES_LIMIT;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    40
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    41
    static {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    42
        try {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    43
            AES_LIMIT = Cipher.getMaxAllowedKeyLength("AES");
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    44
        } catch (Exception e) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    45
            // should not happen
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    46
            throw new AssertionError("Cannot detect AES", e);
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
    }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    49
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    50
    private transient Cipher cipher;
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
    private String cipherAlg;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    53
    private String keyAlg;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    54
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    55
    private int ctrLen;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    56
    private int blockLen;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    57
    private int keyLen;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    58
    private int seedLen;
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
    private transient byte[] v;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    61
    private transient byte[] k;
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
    public CtrDrbg(SecureRandomParameters params) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    64
        mechName = "CTR_DRBG";
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    65
        configure(params);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    66
    }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    67
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    68
    private static int alg2strength(String algorithm) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    69
        switch (algorithm.toUpperCase(Locale.ROOT)) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    70
            case "AES-128":
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    71
                return 128;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    72
            case "AES-192":
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    73
                return 192;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    74
            case "AES-256":
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    75
                return 256;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    76
            default:
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    77
                throw new IllegalArgumentException(algorithm +
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    78
                        " not supported in CTR_DBRG");
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
    }
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
    @Override
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    83
    protected void chooseAlgorithmAndStrength() {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    84
        if (requestedAlgorithm != null) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    85
            algorithm = requestedAlgorithm.toUpperCase();
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    86
            int supportedStrength = alg2strength(algorithm);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    87
            if (requestedInstantiationSecurityStrength >= 0) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    88
                int tryStrength = getStandardStrength(
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    89
                        requestedInstantiationSecurityStrength);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    90
                if (tryStrength > supportedStrength) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    91
                    throw new IllegalArgumentException(algorithm +
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    92
                            " does not support strength " +
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    93
                            requestedInstantiationSecurityStrength);
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
                this.securityStrength = tryStrength;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    96
            } else {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    97
                this.securityStrength = (DEFAULT_STRENGTH > supportedStrength) ?
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    98
                        supportedStrength : DEFAULT_STRENGTH;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
    99
            }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   100
        } else {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   101
            int tryStrength = (requestedInstantiationSecurityStrength < 0) ?
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   102
                    DEFAULT_STRENGTH : requestedInstantiationSecurityStrength;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   103
            tryStrength = getStandardStrength(tryStrength);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   104
            // Default algorithm, use AES-128 if AES-256 is not available.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   105
            // Remember to sync with "securerandom.drbg.config" in java.security
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   106
            if (tryStrength <= 128 && AES_LIMIT < 256) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   107
                algorithm = "AES-128";
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   108
            } else if (AES_LIMIT >= 256) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   109
                algorithm = "AES-256";
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   110
            } else {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   111
                throw new IllegalArgumentException("unsupported strength " +
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   112
                        requestedInstantiationSecurityStrength);
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
            this.securityStrength = tryStrength;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   115
        }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   116
        switch (algorithm.toUpperCase(Locale.ROOT)) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   117
            case "AES-128":
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   118
            case "AES-192":
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   119
            case "AES-256":
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   120
                this.keyAlg = "AES";
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   121
                this.cipherAlg = "AES/ECB/NoPadding";
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   122
                switch (algorithm) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   123
                    case "AES-128":
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   124
                        this.keyLen = 128 / 8;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   125
                        break;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   126
                    case "AES-192":
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   127
                        this.keyLen = 192 / 8;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   128
                        if (AES_LIMIT < 192) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   129
                            throw new IllegalArgumentException(algorithm +
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   130
                                " not available (because policy) in CTR_DBRG");
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
                        break;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   133
                    case "AES-256":
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   134
                        this.keyLen = 256 / 8;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   135
                        if (AES_LIMIT < 256) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   136
                            throw new IllegalArgumentException(algorithm +
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   137
                                " not available (because policy) in CTR_DBRG");
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   138
                        }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   139
                        break;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   140
                    default:
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   141
                        throw new IllegalArgumentException(algorithm +
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   142
                            " not supported in CTR_DBRG");
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
                this.blockLen = 128 / 8;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   145
                break;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   146
            default:
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   147
                throw new IllegalArgumentException(algorithm +
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   148
                        " not supported in CTR_DBRG");
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
        this.seedLen = this.blockLen + this.keyLen;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   151
        this.ctrLen = this.blockLen;    // TODO
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   152
        if (usedf) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   153
            this.minLength = this.securityStrength / 8;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   154
        } else {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   155
            this.minLength = this.maxLength =
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   156
                    this.maxPersonalizationStringLength =
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   157
                            this.maxAdditionalInputLength = seedLen;
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
    }
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
     * This call, used by the constructors, instantiates the digest.
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
    @Override
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   165
    protected void initEngine() {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   166
        try {
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
             * Use the local SUN implementation to avoid native
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   169
             * performance overhead.
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
            cipher = Cipher.getInstance(cipherAlg, "SunJCE");
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   172
        } catch (NoSuchProviderException | NoSuchAlgorithmException
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   173
                | NoSuchPaddingException e) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   174
            // Fallback to any available.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   175
            try {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   176
                cipher = Cipher.getInstance(cipherAlg);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   177
            } catch (NoSuchAlgorithmException | NoSuchPaddingException exc) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   178
                throw new InternalError(
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   179
                    "internal error: " + cipherAlg + " not available.", exc);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   180
            }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   181
        }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   182
    }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   183
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   184
    private void status() {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   185
        if (debug != null) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   186
            debug.println(this, "Key = " + hex(k));
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   187
            debug.println(this, "V   = " + hex(v));
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   188
            debug.println(this, "reseed counter = " + reseedCounter);
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
    // 800-90Ar1 10.2.1.2. CTR_DRBG_Update
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   193
    private void update(byte[] input) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   194
        if (input.length != seedLen) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   195
            // Should not happen
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   196
            throw new IllegalArgumentException("input length not seedLen: "
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   197
                    + input.length);
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
        try {
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
            int m = (seedLen + blockLen - 1) / blockLen;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   202
            byte[] temp = new byte[m * blockLen];
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
            // Step 1. temp = Null.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   205
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   206
            // Step 2. Loop
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   207
            for (int i = 0; i < m; i++) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   208
                // Step 2.1. Increment
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   209
                addOne(v, ctrLen);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   210
                // Step 2.2. Block_Encrypt
37896
cd841af7dcd0 8156213: Remove SHA-1 and 3KeyTDEA algorithms from DRBG
weijun
parents: 37895
diff changeset
   211
                cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(k, keyAlg));
37796
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   212
                // Step 2.3. Encrypt into right position, no need to cat
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   213
                cipher.doFinal(v, 0, blockLen, temp, i * blockLen);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   214
            }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   215
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   216
            // Step 3. Truncate
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   217
            temp = Arrays.copyOf(temp, seedLen);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   218
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   219
            // Step 4: Add
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   220
            for (int i = 0; i < seedLen; i++) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   221
                temp[i] ^= input[i];
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
            // Step 5: leftmost
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   225
            k = Arrays.copyOf(temp, keyLen);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   226
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   227
            // Step 6: rightmost
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   228
            v = Arrays.copyOfRange(temp, seedLen - blockLen, seedLen);
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
            // Step 7. Return
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   231
        } catch (GeneralSecurityException e) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   232
            throw new InternalError(e);
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
    }
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
    @Override
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   237
    protected void instantiateAlgorithm(byte[] ei) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   238
        if (debug != null) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   239
            debug.println(this, "instantiate");
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
        byte[] more;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   242
        if (usedf) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   243
            // 800-90Ar1 10.2.1.3.2 Step 1-2. cat bytes
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   244
            if (personalizationString == null) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   245
                more = nonce;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   246
            } else {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   247
                more = Arrays.copyOf(
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   248
                        nonce, nonce.length + personalizationString.length);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   249
                System.arraycopy(personalizationString, 0, more, nonce.length,
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   250
                        personalizationString.length);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   251
            }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   252
        } else {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   253
            // 800-90Ar1 10.2.1.3.1
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   254
            // Step 1-2, no need to expand personalizationString, we only XOR
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   255
            // with shorter length
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   256
            more = personalizationString;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   257
        }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   258
        reseedAlgorithm(ei, more);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   259
    }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   260
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   261
    private byte[] df(byte[] input) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   262
        int l = input.length;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   263
        int n = seedLen;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   264
        int slen = 4 + 4 + l + 1;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   265
        byte[] s = new byte[(slen + blockLen - 1) / blockLen * blockLen];
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   266
        s[0] = (byte)(l >> 24);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   267
        s[1] = (byte)(l >> 16);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   268
        s[2] = (byte)(l >> 8);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   269
        s[3] = (byte)(l);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   270
        s[4] = (byte)(n >> 24);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   271
        s[5] = (byte)(n >> 16);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   272
        s[6] = (byte)(n >> 8);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   273
        s[7] = (byte)(n);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   274
        System.arraycopy(input, 0, s, 8, l);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   275
        s[8+l] = (byte)0x80;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   276
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   277
        byte[] k = new byte[keyLen];
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   278
        for (int i = 0; i < k.length; i++) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   279
            k[i] = (byte)i;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   280
        }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   281
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   282
        byte[] temp = new byte[seedLen];
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
        for (int i = 0; i * blockLen < temp.length; i++) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   285
            byte[] iv = new byte[blockLen + s.length];
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   286
            iv[0] = (byte)(i >> 24);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   287
            iv[1] = (byte)(i >> 16);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   288
            iv[2] = (byte)(i >> 8);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   289
            iv[3] = (byte)(i);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   290
            System.arraycopy(s, 0, iv, blockLen, s.length);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   291
            int tailLen = temp.length - blockLen*i;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   292
            if (tailLen > blockLen) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   293
                tailLen = blockLen;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   294
            }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   295
            System.arraycopy(bcc(k, iv), 0, temp, blockLen*i, tailLen);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   296
        }
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
        k = Arrays.copyOf(temp, keyLen);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   299
        byte[] x = Arrays.copyOfRange(temp, keyLen, temp.length);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   300
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   301
        for (int i = 0; i * blockLen < seedLen; i++) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   302
            try {
37896
cd841af7dcd0 8156213: Remove SHA-1 and 3KeyTDEA algorithms from DRBG
weijun
parents: 37895
diff changeset
   303
                cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(k, keyAlg));
37796
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   304
                int tailLen = temp.length - blockLen*i;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   305
                if (tailLen > blockLen) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   306
                    tailLen = blockLen;
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
                x = cipher.doFinal(x);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   309
                System.arraycopy(x, 0, temp, blockLen * i, tailLen);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   310
            } catch (GeneralSecurityException e) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   311
                throw new InternalError(e);
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
        }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   314
        return temp;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   315
    }
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
    private byte[] bcc(byte[] k, byte[] data) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   318
        byte[] chain = new byte[blockLen];
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   319
        int n = data.length / blockLen;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   320
        for (int i = 0; i < n; i++) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   321
            byte[] inputBlock = Arrays.copyOfRange(
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   322
                    data, i * blockLen, i * blockLen + blockLen);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   323
            for (int j = 0; j < blockLen; j++) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   324
                inputBlock[j] ^= chain[j];
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   325
            }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   326
            try {
37896
cd841af7dcd0 8156213: Remove SHA-1 and 3KeyTDEA algorithms from DRBG
weijun
parents: 37895
diff changeset
   327
                cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(k, keyAlg));
37796
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   328
                chain = cipher.doFinal(inputBlock);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   329
            } catch (GeneralSecurityException e) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   330
                throw new InternalError(e);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   331
            }
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
        return chain;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   334
    }
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
37895
f59fdd7fb4fb 8156501: DRBG not synchronized at reseeding
weijun
parents: 37796
diff changeset
   337
    protected synchronized void reseedAlgorithm(
37796
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   338
            byte[] ei,
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   339
            byte[] additionalInput) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   340
        if (usedf) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   341
            // 800-90Ar1 10.2.1.3.2 Instantiate.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   342
            // 800-90Ar1 10.2.1.4.2 Reseed.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   343
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   344
            // Step 1: cat bytes
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   345
            if (additionalInput != null) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   346
                byte[] temp = Arrays.copyOf(
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   347
                        ei, ei.length + additionalInput.length);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   348
                System.arraycopy(additionalInput, 0, temp, ei.length,
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   349
                        additionalInput.length);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   350
                ei = temp;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   351
            }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   352
            // Step 2. df (seed_material, seedlen).
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   353
            ei = df(ei);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   354
        } else {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   355
            // 800-90Ar1 10.2.1.3.1 Instantiate
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   356
            // 800-90Ar1 10.2.1.4.1 Reseed
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   357
            // Step 1-2. Needless
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   358
            // Step 3. seed_material = entropy_input XOR more
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   359
            if (additionalInput != null) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   360
                // additionalInput.length <= seedLen
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   361
                for (int i = 0; i < additionalInput.length; i++) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   362
                    ei[i] ^= additionalInput[i];
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   363
                }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   364
            }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   365
        }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   366
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   367
        if (v == null) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   368
            // 800-90Ar1 10.2.1.3.2 Instantiate. Step 3-4
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   369
            // 800-90Ar1 10.2.1.3.1 Instantiate. Step 4-5
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   370
            k = new byte[keyLen];
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   371
            v = new byte[blockLen];
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   372
        }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   373
        //status();
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   374
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   375
        // 800-90Ar1 10.2.1.3.1 Instantiate. Step 6
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   376
        // 800-90Ar1 10.2.1.3.2 Instantiate. Step 5
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   377
        // 800-90Ar1 10.2.1.4.1 Reseed. Step 4
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   378
        // 800-90Ar1 10.2.1.4.2 Reseed. Step 3
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   379
        update(ei);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   380
        // 800-90Ar1 10.2.1.3.1 Instantiate. Step 7
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   381
        // 800-90Ar1 10.2.1.3.2 Instantiate. Step 6
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   382
        // 800-90Ar1 10.2.1.4.1 Reseed. Step 5
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   383
        // 800-90Ar1 10.2.1.4.2 Reseed. Step 4
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   384
        reseedCounter = 1;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   385
        //status();
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   386
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   387
        // Whatever step. Return
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   388
    }
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
     * Add one to data, only touch the last len bytes.
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   392
     */
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   393
    private static void addOne(byte[] data, int len) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   394
        for (int i = 0; i < len; i++) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   395
            data[data.length - 1 - i]++;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   396
            if (data[data.length - 1 - i] != 0) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   397
                break;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   398
            }
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 synchronized void generateAlgorithm(
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   404
            byte[] result, byte[] additionalInput) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   405
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   406
        if (debug != null) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   407
            debug.println(this, "generateAlgorithm");
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   408
        }
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
        // 800-90Ar1 10.2.1.5.1 Generate
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   411
        // 800-90Ar1 10.2.1.5.2 Generate
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
        // Step 1: Check reseed_counter. Will not fail. Already checked in
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   414
        // AbstractDrbg#engineNextBytes.
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
        if (additionalInput != null) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   417
            if (usedf) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   418
                // 10.2.1.5.2 Step 2.1
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   419
                additionalInput = df(additionalInput);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   420
            } else {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   421
                // 10.2.1.5.1 Step 2.1-2.2
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   422
                additionalInput = Arrays.copyOf(additionalInput, seedLen);
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
            // 10.2.1.5.1 Step 2.3
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   425
            // 10.2.1.5.2 Step 2.2
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   426
            update(additionalInput);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   427
        } else {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   428
            // 10.2.1.5.1 Step 2 Else
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   429
            // 10.2.1.5.2 Step 2 Else
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   430
            additionalInput = new byte[seedLen];
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
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   433
        // Step 3. temp = Null
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   434
        int pos = 0;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   435
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   436
        // Step 4. Loop
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   437
        while (pos < result.length) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   438
            int tailLen = result.length - pos;
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   439
            // Step 4.1. Increment
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   440
            addOne(v, ctrLen);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   441
            try {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   442
                // Step 4.2. Encrypt
37896
cd841af7dcd0 8156213: Remove SHA-1 and 3KeyTDEA algorithms from DRBG
weijun
parents: 37895
diff changeset
   443
                cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(k, keyAlg));
37796
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   444
                byte[] out = cipher.doFinal(v);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   445
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   446
                // Step 4.3 and 5. Cat bytes and leftmost
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   447
                System.arraycopy(out, 0, result, pos,
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   448
                        (tailLen > blockLen) ? blockLen : tailLen);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   449
            } catch (GeneralSecurityException e) {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   450
                throw new InternalError(e);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   451
            }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   452
            pos += blockLen;
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
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   455
        // Step 6. Update
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   456
        update(additionalInput);
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   457
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   458
        // Step 7. reseed_counter++
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   459
        reseedCounter++;
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
        //status();
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   462
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   463
        // Step 8. Return
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   464
    }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   465
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   466
    private void readObject(java.io.ObjectInputStream s)
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   467
            throws IOException, ClassNotFoundException {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   468
        s.defaultReadObject ();
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   469
        initEngine();
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   470
    }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   471
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   472
    @Override
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   473
    public String toString() {
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   474
        return super.toString() + "/"
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   475
                + (usedf ? "use_df" : "no_df");
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   476
    }
256c45c4af5d 8051408: NIST SP 800-90A SecureRandom implementations
weijun
parents:
diff changeset
   477
}