jdk/src/java.base/share/classes/com/sun/crypto/provider/TlsPrfGenerator.java
author martin
Tue, 15 Sep 2015 21:56:04 -0700
changeset 32649 2ee9017c7597
parent 27804 4659e70271c4
permissions -rw-r--r--
8136583: Core libraries should use blessed modifier order Summary: Run blessed-modifier-order script (see bug) Reviewed-by: psandoz, chegar, alanb, plevart
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
17160
2dfc3fe28a65 8006935: Need to take care of long secret keys in HMAC/PRF compuation
xuelei
parents: 7043
diff changeset
     2
 * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3353
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3353
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3353
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3353
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3353
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package com.sun.crypto.provider;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import java.util.Arrays;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.security.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
import java.security.spec.AlgorithmParameterSpec;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
import javax.crypto.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
import javax.crypto.spec.SecretKeySpec;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
import sun.security.internal.spec.TlsPrfParameterSpec;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
 * KeyGenerator implementation for the TLS PRF function.
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
    40
 * <p>
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
    41
 * This class duplicates the HMAC functionality (RFC 2104) with
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
    42
 * performance optimizations (e.g. XOR'ing keys with padding doesn't
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
    43
 * need to be redone for each HMAC operation).
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
 * @author  Andreas Sterbenz
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
 * @since   1.6
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
 */
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
    48
abstract class TlsPrfGenerator extends KeyGeneratorSpi {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
    // magic constants and utility functions, also used by other files
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
    // in this package
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
32649
2ee9017c7597 8136583: Core libraries should use blessed modifier order
martin
parents: 27804
diff changeset
    53
    private static final byte[] B0 = new byte[0];
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
32649
2ee9017c7597 8136583: Core libraries should use blessed modifier order
martin
parents: 27804
diff changeset
    55
    static final byte[] LABEL_MASTER_SECRET = // "master secret"
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
        { 109, 97, 115, 116, 101, 114, 32, 115, 101, 99, 114, 101, 116 };
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
32649
2ee9017c7597 8136583: Core libraries should use blessed modifier order
martin
parents: 27804
diff changeset
    58
    static final byte[] LABEL_KEY_EXPANSION = // "key expansion"
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
        { 107, 101, 121, 32, 101, 120, 112, 97, 110, 115, 105, 111, 110 };
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
32649
2ee9017c7597 8136583: Core libraries should use blessed modifier order
martin
parents: 27804
diff changeset
    61
    static final byte[] LABEL_CLIENT_WRITE_KEY = // "client write key"
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
        { 99, 108, 105, 101, 110, 116, 32, 119, 114, 105, 116, 101, 32,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
          107, 101, 121 };
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
32649
2ee9017c7597 8136583: Core libraries should use blessed modifier order
martin
parents: 27804
diff changeset
    65
    static final byte[] LABEL_SERVER_WRITE_KEY = // "server write key"
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
        { 115, 101, 114, 118, 101, 114, 32, 119, 114, 105, 116, 101, 32,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
          107, 101, 121 };
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
32649
2ee9017c7597 8136583: Core libraries should use blessed modifier order
martin
parents: 27804
diff changeset
    69
    static final byte[] LABEL_IV_BLOCK = // "IV block"
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
        { 73, 86, 32, 98, 108, 111, 99, 107 };
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
     * TLS HMAC "inner" and "outer" padding.  This isn't a function
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
     * of the digest algorithm.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
     */
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
    76
    private static final byte[] HMAC_ipad64  = genPad((byte)0x36, 64);
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
    77
    private static final byte[] HMAC_ipad128 = genPad((byte)0x36, 128);
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
    78
    private static final byte[] HMAC_opad64  = genPad((byte)0x5c, 64);
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
    79
    private static final byte[] HMAC_opad128 = genPad((byte)0x5c, 128);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
    // SSL3 magic mix constants ("A", "BB", "CCC", ...)
32649
2ee9017c7597 8136583: Core libraries should use blessed modifier order
martin
parents: 27804
diff changeset
    82
    static final byte[][] SSL3_CONST = genConst();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
    static byte[] genPad(byte b, int count) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
        byte[] padding = new byte[count];
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
        Arrays.fill(padding, b);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
        return padding;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
    static byte[] concat(byte[] b1, byte[] b2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
        int n1 = b1.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
        int n2 = b2.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
        byte[] b = new byte[n1 + n2];
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
        System.arraycopy(b1, 0, b, 0, n1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
        System.arraycopy(b2, 0, b, n1, n2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
        return b;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
    private static byte[][] genConst() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
        int n = 10;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
        byte[][] arr = new byte[n][];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
        for (int i = 0; i < n; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
            byte[] b = new byte[i + 1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
            Arrays.fill(b, (byte)('A' + i));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
            arr[i] = b;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
        return arr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
    // PRF implementation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
32649
2ee9017c7597 8136583: Core libraries should use blessed modifier order
martin
parents: 27804
diff changeset
   112
    private static final String MSG = "TlsPrfGenerator must be "
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
        + "initialized using a TlsPrfParameterSpec";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
27804
4659e70271c4 8066617: Suppress deprecation warnings in java.base module
darcy
parents: 25859
diff changeset
   115
    @SuppressWarnings("deprecation")
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
    private TlsPrfParameterSpec spec;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
    public TlsPrfGenerator() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
    protected void engineInit(SecureRandom random) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
        throw new InvalidParameterException(MSG);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
27804
4659e70271c4 8066617: Suppress deprecation warnings in java.base module
darcy
parents: 25859
diff changeset
   125
    @SuppressWarnings("deprecation")
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
    protected void engineInit(AlgorithmParameterSpec params,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
            SecureRandom random) throws InvalidAlgorithmParameterException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
        if (params instanceof TlsPrfParameterSpec == false) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
            throw new InvalidAlgorithmParameterException(MSG);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
        this.spec = (TlsPrfParameterSpec)params;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
        SecretKey key = spec.getSecret();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
        if ((key != null) && ("RAW".equals(key.getFormat()) == false)) {
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   134
            throw new InvalidAlgorithmParameterException(
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   135
                "Key encoding format must be RAW");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
    protected void engineInit(int keysize, SecureRandom random) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
        throw new InvalidParameterException(MSG);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   143
    SecretKey engineGenerateKey0(boolean tls12) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
        if (spec == null) {
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   145
            throw new IllegalStateException(
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   146
                "TlsPrfGenerator must be initialized");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
        SecretKey key = spec.getSecret();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
        byte[] secret = (key == null) ? null : key.getEncoded();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
            byte[] labelBytes = spec.getLabel().getBytes("UTF8");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
            int n = spec.getOutputLength();
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   153
            byte[] prfBytes = (tls12 ?
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   154
                doTLS12PRF(secret, labelBytes, spec.getSeed(), n,
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   155
                    spec.getPRFHashAlg(), spec.getPRFHashLength(),
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   156
                    spec.getPRFBlockSize()) :
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   157
                doTLS10PRF(secret, labelBytes, spec.getSeed(), n));
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
            return new SecretKeySpec(prfBytes, "TlsPrf");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
        } catch (GeneralSecurityException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
            throw new ProviderException("Could not generate PRF", e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
        } catch (java.io.UnsupportedEncodingException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
            throw new ProviderException("Could not generate PRF", e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   166
    static byte[] doTLS12PRF(byte[] secret, byte[] labelBytes,
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   167
            byte[] seed, int outputLength,
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   168
            String prfHash, int prfHashLength, int prfBlockSize)
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   169
            throws NoSuchAlgorithmException, DigestException {
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   170
        if (prfHash == null) {
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   171
            throw new NoSuchAlgorithmException("Unspecified PRF algorithm");
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   172
        }
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   173
        MessageDigest prfMD = MessageDigest.getInstance(prfHash);
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   174
        return doTLS12PRF(secret, labelBytes, seed, outputLength,
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   175
            prfMD, prfHashLength, prfBlockSize);
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   176
    }
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   177
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   178
    static byte[] doTLS12PRF(byte[] secret, byte[] labelBytes,
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   179
            byte[] seed, int outputLength,
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   180
            MessageDigest mdPRF, int mdPRFLen, int mdPRFBlockSize)
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   181
            throws DigestException {
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   182
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   183
        if (secret == null) {
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   184
            secret = B0;
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   185
        }
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   186
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   187
        // If we have a long secret, digest it first.
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   188
        if (secret.length > mdPRFBlockSize) {
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   189
            secret = mdPRF.digest(secret);
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   190
        }
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   191
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   192
        byte[] output = new byte[outputLength];
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   193
        byte [] ipad;
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   194
        byte [] opad;
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   195
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   196
        switch (mdPRFBlockSize) {
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   197
        case 64:
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   198
            ipad = HMAC_ipad64.clone();
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   199
            opad = HMAC_opad64.clone();
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   200
            break;
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   201
        case 128:
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   202
            ipad = HMAC_ipad128.clone();
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   203
            opad = HMAC_opad128.clone();
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   204
            break;
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   205
        default:
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   206
            throw new DigestException("Unexpected block size.");
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   207
        }
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   208
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   209
        // P_HASH(Secret, label + seed)
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   210
        expand(mdPRF, mdPRFLen, secret, 0, secret.length, labelBytes,
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   211
            seed, output, ipad, opad);
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   212
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   213
        return output;
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   214
    }
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   215
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   216
    static byte[] doTLS10PRF(byte[] secret, byte[] labelBytes,
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   217
            byte[] seed, int outputLength) throws NoSuchAlgorithmException,
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   218
            DigestException {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
        MessageDigest md5 = MessageDigest.getInstance("MD5");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
        MessageDigest sha = MessageDigest.getInstance("SHA1");
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   221
        return doTLS10PRF(secret, labelBytes, seed, outputLength, md5, sha);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   224
    static byte[] doTLS10PRF(byte[] secret, byte[] labelBytes,
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   225
            byte[] seed, int outputLength, MessageDigest md5,
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   226
            MessageDigest sha) throws DigestException {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
         * Split the secret into two halves S1 and S2 of same length.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
         * S1 is taken from the first half of the secret, S2 from the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
         * second half.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
         * Their length is created by rounding up the length of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
         * overall secret divided by two; thus, if the original secret
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
         * is an odd number of bytes long, the last byte of S1 will be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
         * the same as the first byte of S2.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
         * Note: Instead of creating S1 and S2, we determine the offset into
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
         * the overall secret where S2 starts.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
        if (secret == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
            secret = B0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
        int off = secret.length >> 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
        int seclen = off + (secret.length & 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
17160
2dfc3fe28a65 8006935: Need to take care of long secret keys in HMAC/PRF compuation
xuelei
parents: 7043
diff changeset
   246
        byte[] secKey = secret;
2dfc3fe28a65 8006935: Need to take care of long secret keys in HMAC/PRF compuation
xuelei
parents: 7043
diff changeset
   247
        int keyLen = seclen;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
        byte[] output = new byte[outputLength];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
        // P_MD5(S1, label + seed)
17160
2dfc3fe28a65 8006935: Need to take care of long secret keys in HMAC/PRF compuation
xuelei
parents: 7043
diff changeset
   251
        // If we have a long secret, digest it first.
2dfc3fe28a65 8006935: Need to take care of long secret keys in HMAC/PRF compuation
xuelei
parents: 7043
diff changeset
   252
        if (seclen > 64) {              // 64: block size of HMAC-MD5
2dfc3fe28a65 8006935: Need to take care of long secret keys in HMAC/PRF compuation
xuelei
parents: 7043
diff changeset
   253
            md5.update(secret, 0, seclen);
2dfc3fe28a65 8006935: Need to take care of long secret keys in HMAC/PRF compuation
xuelei
parents: 7043
diff changeset
   254
            secKey = md5.digest();
2dfc3fe28a65 8006935: Need to take care of long secret keys in HMAC/PRF compuation
xuelei
parents: 7043
diff changeset
   255
            keyLen = secKey.length;
2dfc3fe28a65 8006935: Need to take care of long secret keys in HMAC/PRF compuation
xuelei
parents: 7043
diff changeset
   256
        }
2dfc3fe28a65 8006935: Need to take care of long secret keys in HMAC/PRF compuation
xuelei
parents: 7043
diff changeset
   257
        expand(md5, 16, secKey, 0, keyLen, labelBytes, seed, output,
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   258
            HMAC_ipad64.clone(), HMAC_opad64.clone());
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
        // P_SHA-1(S2, label + seed)
17160
2dfc3fe28a65 8006935: Need to take care of long secret keys in HMAC/PRF compuation
xuelei
parents: 7043
diff changeset
   261
        // If we have a long secret, digest it first.
2dfc3fe28a65 8006935: Need to take care of long secret keys in HMAC/PRF compuation
xuelei
parents: 7043
diff changeset
   262
        if (seclen > 64) {              // 64: block size of HMAC-SHA1
2dfc3fe28a65 8006935: Need to take care of long secret keys in HMAC/PRF compuation
xuelei
parents: 7043
diff changeset
   263
            sha.update(secret, off, seclen);
2dfc3fe28a65 8006935: Need to take care of long secret keys in HMAC/PRF compuation
xuelei
parents: 7043
diff changeset
   264
            secKey = sha.digest();
2dfc3fe28a65 8006935: Need to take care of long secret keys in HMAC/PRF compuation
xuelei
parents: 7043
diff changeset
   265
            keyLen = secKey.length;
2dfc3fe28a65 8006935: Need to take care of long secret keys in HMAC/PRF compuation
xuelei
parents: 7043
diff changeset
   266
            off = 0;
2dfc3fe28a65 8006935: Need to take care of long secret keys in HMAC/PRF compuation
xuelei
parents: 7043
diff changeset
   267
        }
2dfc3fe28a65 8006935: Need to take care of long secret keys in HMAC/PRF compuation
xuelei
parents: 7043
diff changeset
   268
        expand(sha, 20, secKey, off, keyLen, labelBytes, seed, output,
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   269
            HMAC_ipad64.clone(), HMAC_opad64.clone());
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
        return output;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
     * @param digest the MessageDigest to produce the HMAC
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
     * @param hmacSize the HMAC size
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
     * @param secret the secret
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
     * @param secOff the offset into the secret
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
     * @param secLen the secret length
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
     * @param label the label
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
     * @param seed the seed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
     * @param output the output array
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
     */
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   284
    private static void expand(MessageDigest digest, int hmacSize,
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
            byte[] secret, int secOff, int secLen, byte[] label, byte[] seed,
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   286
            byte[] output, byte[] pad1, byte[] pad2) throws DigestException {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
         * modify the padding used, by XORing the key into our copy of that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
         * padding.  That's to avoid doing that for each HMAC computation.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
        for (int i = 0; i < secLen; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
            pad1[i] ^= secret[i + secOff];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
            pad2[i] ^= secret[i + secOff];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
        byte[] tmp = new byte[hmacSize];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
        byte[] aBytes = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
         * compute:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
         *     P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
         *                            HMAC_hash(secret, A(2) + seed) +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
         *                            HMAC_hash(secret, A(3) + seed) + ...
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
         * A() is defined as:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
         *     A(0) = seed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
         *     A(i) = HMAC_hash(secret, A(i-1))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
        int remaining = output.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
        int ofs = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
        while (remaining > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
            /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
             * compute A() ...
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
            // inner digest
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
            digest.update(pad1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
            if (aBytes == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
                digest.update(label);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
                digest.update(seed);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
                digest.update(aBytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
            digest.digest(tmp, 0, hmacSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
            // outer digest
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
            digest.update(pad2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
            digest.update(tmp);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
            if (aBytes == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
                aBytes = new byte[hmacSize];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
            digest.digest(aBytes, 0, hmacSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
            /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
             * compute HMAC_hash() ...
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
            // inner digest
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
            digest.update(pad1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
            digest.update(aBytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
            digest.update(label);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
            digest.update(seed);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
            digest.digest(tmp, 0, hmacSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
            // outer digest
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
            digest.update(pad2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
            digest.update(tmp);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
            digest.digest(tmp, 0, hmacSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
            int k = Math.min(hmacSize, remaining);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
            for (int i = 0; i < k; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
                output[ofs++] ^= tmp[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
            remaining -= k;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   357
    /**
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   358
     * A KeyGenerator implementation that supports TLS 1.2.
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   359
     * <p>
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   360
     * TLS 1.2 uses a different hash algorithm than 1.0/1.1 for the PRF
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   361
     * calculations.  As of 2010, there is no PKCS11-level support for TLS
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   362
     * 1.2 PRF calculations, and no known OS's have an internal variant
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   363
     * we could use.  Therefore for TLS 1.2, we are updating JSSE to request
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   364
     * a different provider algorithm:  "SunTls12Prf".  If we reused the
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   365
     * name "SunTlsPrf", the PKCS11 provider would need be updated to
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   366
     * fail correctly when presented with the wrong version number
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   367
     * (via Provider.Service.supportsParameters()), and add the
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   368
     * appropriate supportsParamters() checks into KeyGenerators (not
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   369
     * currently there).
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   370
     */
32649
2ee9017c7597 8136583: Core libraries should use blessed modifier order
martin
parents: 27804
diff changeset
   371
    public static class V12 extends TlsPrfGenerator {
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   372
        protected SecretKey engineGenerateKey() {
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   373
            return engineGenerateKey0(true);
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   374
        }
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   375
    }
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   376
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   377
    /**
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   378
     * A KeyGenerator implementation that supports TLS 1.0/1.1.
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   379
     */
32649
2ee9017c7597 8136583: Core libraries should use blessed modifier order
martin
parents: 27804
diff changeset
   380
    public static class V10 extends TlsPrfGenerator {
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   381
        protected SecretKey engineGenerateKey() {
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   382
            return engineGenerateKey0(false);
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   383
        }
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 5506
diff changeset
   384
    }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
}