jdk/src/share/classes/sun/security/ssl/CipherBox.java
author xuelei
Fri, 01 Mar 2013 02:34:34 -0800
changeset 16045 9d08c3b9a6a0
parent 14664 e71aa0962e70
child 16067 36055e4b5305
permissions -rw-r--r--
7030966: Support AEAD CipherSuites Reviewed-by: weijun, wetmore, valeriep
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
16045
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
     2
 * Copyright (c) 1996, 2012, 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: 1763
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: 1763
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: 1763
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 1763
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 1763
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
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
package sun.security.ssl;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import java.io.ByteArrayInputStream;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.io.IOException;
7039
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
    31
import java.util.Hashtable;
16045
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
    32
import java.util.Arrays;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
import java.security.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
import javax.crypto.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
import javax.crypto.spec.IvParameterSpec;
16045
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
    37
import javax.crypto.spec.GCMParameterSpec;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
import java.nio.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
import sun.security.ssl.CipherSuite.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
import static sun.security.ssl.CipherSuite.*;
16045
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
    43
import static sun.security.ssl.CipherSuite.CipherType.*;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
import sun.misc.HexDumpEncoder;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
 * This class handles bulk data enciphering/deciphering for each SSLv3
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
 * message.  This provides data confidentiality.  Stream ciphers (such
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
 * as RC4) don't need to do padding; block ciphers (e.g. DES) need it.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
 * Individual instances are obtained by calling the static method
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
 * newCipherBox(), which should only be invoked by BulkCipher.newCipher().
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
 *
7039
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
    56
 * In RFC 2246, with bock ciphers in CBC mode, the Initialization
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
    57
 * Vector (IV) for the first record is generated with the other keys
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
    58
 * and secrets when the security parameters are set.  The IV for
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
    59
 * subsequent records is the last ciphertext block from the previous
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
    60
 * record.
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
    61
 *
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
    62
 * In RFC 4346, the implicit Initialization Vector (IV) is replaced
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
    63
 * with an explicit IV to protect against CBC attacks.  RFC 4346
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
    64
 * recommends two algorithms used to generated the per-record IV.
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
    65
 * The implementation uses the algorithm (2)(b), as described at
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
    66
 * section 6.2.3.2 of RFC 4346.
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
    67
 *
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
    68
 * The usage of IV in CBC block cipher can be illustrated in
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
    69
 * the following diagrams.
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
    70
 *
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
    71
 *   (random)
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
    72
 *        R         P1                    IV        C1
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
    73
 *        |          |                     |         |
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
    74
 *  SIV---+    |-----+    |-...            |-----    |------
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
    75
 *        |    |     |    |                |    |    |     |
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
    76
 *     +----+  |  +----+  |             +----+  |  +----+  |
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
    77
 *     | Ek |  |  + Ek +  |             | Dk |  |  | Dk |  |
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
    78
 *     +----+  |  +----+  |             +----+  |  +----+  |
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
    79
 *        |    |     |    |                |    |    |     |
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
    80
 *        |----|     |----|           SIV--+    |----|     |-...
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
    81
 *        |          |                     |       |
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
    82
 *       IV         C1                     R      P1
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
    83
 *                                     (discard)
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
    84
 *
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
    85
 *       CBC Encryption                    CBC Decryption
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
    86
 *
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
 * NOTE that any ciphering involved in key exchange (e.g. with RSA) is
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
 * handled separately.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
 * @author David Brownell
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
 * @author Andreas Sterbenz
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
final class CipherBox {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
    // A CipherBox that implements the identity operation
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
    final static CipherBox NULL = new CipherBox();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
    /* Class and subclass dynamic debugging support */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
    private static final Debug debug = Debug.getInstance("ssl");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
    // the protocol version this cipher conforms to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
    private final ProtocolVersion protocolVersion;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
    // cipher object
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
    private final Cipher cipher;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
    /**
7039
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   108
     * secure random
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   109
     */
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   110
    private SecureRandom random;
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   111
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   112
    /**
16045
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   113
     * fixed IV, the implicit nonce of AEAD cipher suite, only apply to
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   114
     * AEAD cipher suites
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   115
     */
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   116
    private final byte[] fixedIv;
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   117
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   118
    /**
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   119
     * the key, reserved only for AEAD cipher initialization
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   120
     */
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   121
    private final Key key;
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   122
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   123
    /**
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   124
     * the operation mode, reserved for AEAD cipher initialization
10915
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 7039
diff changeset
   125
     */
16045
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   126
    private final int mode;
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   127
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   128
    /**
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   129
     * the authentication tag size, only apply to AEAD cipher suites
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   130
     */
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   131
    private final int tagSize;
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   132
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   133
    /**
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   134
     * the record IV length, only apply to AEAD cipher suites
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   135
     */
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   136
    private final int recordIvSize;
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   137
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   138
    /**
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   139
     * cipher type
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   140
     */
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   141
    private final CipherType cipherType;
10915
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 7039
diff changeset
   142
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 7039
diff changeset
   143
    /**
7039
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   144
     * Fixed masks of various block size, as the initial decryption IVs
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   145
     * for TLS 1.1 or later.
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   146
     *
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   147
     * For performance, we do not use random IVs. As the initial decryption
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   148
     * IVs will be discarded by TLS decryption processes, so the fixed masks
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   149
     * do not hurt cryptographic strength.
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   150
     */
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   151
    private static Hashtable<Integer, IvParameterSpec> masks;
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   152
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   153
    /**
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
     * NULL cipherbox. Identity operation, no encryption.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
    private CipherBox() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
        this.protocolVersion = ProtocolVersion.DEFAULT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
        this.cipher = null;
16045
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   159
        this.cipherType = STREAM_CIPHER;
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   160
        this.fixedIv = new byte[0];
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   161
        this.key = null;
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   162
        this.mode = Cipher.ENCRYPT_MODE;    // choose at random
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   163
        this.random = null;
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   164
        this.tagSize = 0;
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   165
        this.recordIvSize = 0;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
     * Construct a new CipherBox using the cipher transformation.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
     * @exception NoSuchAlgorithmException if no appropriate JCE Cipher
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
     * implementation could be found.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
    private CipherBox(ProtocolVersion protocolVersion, BulkCipher bulkCipher,
7039
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   175
            SecretKey key, IvParameterSpec iv, SecureRandom random,
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   176
            boolean encrypt) throws NoSuchAlgorithmException {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
            this.protocolVersion = protocolVersion;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
            this.cipher = JsseJce.getCipher(bulkCipher.transformation);
16045
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   180
            this.mode = encrypt ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE;
7039
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   181
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   182
            if (random == null) {
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   183
                random = JsseJce.getSecureRandom();
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   184
            }
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   185
            this.random = random;
16045
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   186
            this.cipherType = bulkCipher.cipherType;
7039
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   187
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   188
            /*
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   189
             * RFC 4346 recommends two algorithms used to generated the
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   190
             * per-record IV. The implementation uses the algorithm (2)(b),
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   191
             * as described at section 6.2.3.2 of RFC 4346.
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   192
             *
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   193
             * As we don't care about the initial IV value for TLS 1.1 or
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   194
             * later, so if the "iv" parameter is null, we use the default
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   195
             * value generated by Cipher.init() for encryption, and a fixed
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   196
             * mask for decryption.
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   197
             */
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   198
            if (iv == null && bulkCipher.ivSize != 0 &&
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   199
                    mode == Cipher.DECRYPT_MODE &&
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   200
                    protocolVersion.v >= ProtocolVersion.TLS11.v) {
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   201
                iv = getFixedMask(bulkCipher.ivSize);
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   202
            }
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   203
16045
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   204
            if (cipherType == AEAD_CIPHER) {
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   205
                // AEAD must completely initialize the cipher for each packet,
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   206
                // and so we save initialization parameters for packet
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   207
                // processing time.
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   208
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   209
                // Set the tag size for AEAD cipher
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   210
                tagSize = bulkCipher.tagSize;
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   211
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   212
                // Reserve the key for AEAD cipher initialization
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   213
                this.key = key;
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   214
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   215
                fixedIv = iv.getIV();
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   216
                if (fixedIv == null ||
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   217
                        fixedIv.length != bulkCipher.fixedIvSize) {
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   218
                    throw new RuntimeException("Improper fixed IV for AEAD");
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   219
                }
7039
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   220
16045
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   221
                // Set the record IV length for AEAD cipher
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   222
                recordIvSize = bulkCipher.ivSize - bulkCipher.fixedIvSize;
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   223
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   224
                // DON'T initialize the cipher for AEAD!
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   225
            } else {
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   226
                // CBC only requires one initialization during its lifetime
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   227
                // (future packets/IVs set the proper CBC state), so we can
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   228
                // initialize now.
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   229
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   230
                // Zeroize the variables that only apply to AEAD cipher
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   231
                this.tagSize = 0;
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   232
                this.fixedIv = new byte[0];
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   233
                this.recordIvSize = 0;
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   234
                this.key = null;
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   235
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   236
                // Initialize the cipher
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   237
                cipher.init(mode, key, iv, random);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
        } catch (NoSuchAlgorithmException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
            throw e;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
        } catch (Exception e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
            throw new NoSuchAlgorithmException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
                    ("Could not create cipher " + bulkCipher, e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
        } catch (ExceptionInInitializerError e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
            throw new NoSuchAlgorithmException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
                    ("Could not create cipher " + bulkCipher, e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
     * Factory method to obtain a new CipherBox object.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
    static CipherBox newCipherBox(ProtocolVersion version, BulkCipher cipher,
7039
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   254
            SecretKey key, IvParameterSpec iv, SecureRandom random,
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   255
            boolean encrypt) throws NoSuchAlgorithmException {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
        if (cipher.allowed == false) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
            throw new NoSuchAlgorithmException("Unsupported cipher " + cipher);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
        }
7039
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   259
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
        if (cipher == B_NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
            return NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
        } else {
7039
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   263
            return new CipherBox(version, cipher, key, iv, random, encrypt);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
    /*
7039
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   268
     * Get a fixed mask, as the initial decryption IVs for TLS 1.1 or later.
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   269
     */
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   270
    private static IvParameterSpec getFixedMask(int ivSize) {
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   271
        if (masks == null) {
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   272
            masks = new Hashtable<Integer, IvParameterSpec>(5);
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   273
        }
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   274
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   275
        IvParameterSpec iv = masks.get(ivSize);
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   276
        if (iv == null) {
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   277
            iv = new IvParameterSpec(new byte[ivSize]);
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   278
            masks.put(ivSize, iv);
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   279
        }
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   280
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   281
        return iv;
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   282
    }
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   283
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   284
    /*
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
     * Encrypts a block of data, returning the size of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
     * resulting block.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
    int encrypt(byte[] buf, int offset, int len) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
        if (cipher == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
            return len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
        }
7039
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   292
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
        try {
16045
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   294
            int blockSize = cipher.getBlockSize();
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   295
            if (cipherType == BLOCK_CIPHER) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
                len = addPadding(buf, offset, len, blockSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
            }
16045
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   298
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
            if (debug != null && Debug.isOn("plaintext")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
                try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
                    HexDumpEncoder hd = new HexDumpEncoder();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
                    System.out.println(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
                        "Padded plaintext before ENCRYPTION:  len = "
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
                        + len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
                    hd.encodeBuffer(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
                        new ByteArrayInputStream(buf, offset, len),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
                        System.out);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
                } catch (IOException e) { }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
            }
16045
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   311
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   312
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   313
            if (cipherType == AEAD_CIPHER) {
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   314
                try {
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   315
                    return cipher.doFinal(buf, offset, len, buf, offset);
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   316
                } catch (IllegalBlockSizeException | BadPaddingException ibe) {
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   317
                    // unlikely to happen
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   318
                    throw new RuntimeException(
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   319
                        "Cipher error in AEAD mode in JCE provider " +
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   320
                        cipher.getProvider().getName(), ibe);
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   321
                }
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   322
            } else {
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   323
                int newLen = cipher.update(buf, offset, len, buf, offset);
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   324
                if (newLen != len) {
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   325
                    // catch BouncyCastle buffering error
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   326
                    throw new RuntimeException("Cipher buffering error " +
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   327
                        "in JCE provider " + cipher.getProvider().getName());
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   328
                }
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   329
                return newLen;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
        } catch (ShortBufferException e) {
16045
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   332
            // unlikely to happen, we should have enough buffer space here
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
            throw new ArrayIndexOutOfBoundsException(e.toString());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
     * Encrypts a ByteBuffer block of data, returning the size of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
     * resulting block.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
     * The byte buffers position and limit initially define the amount
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
     * to encrypt.  On return, the position and limit are
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
     * set to last position padded/encrypted.  The limit may have changed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
     * because of the added padding bytes.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
     */
16045
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   346
    int encrypt(ByteBuffer bb, int outLimit) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
        int len = bb.remaining();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
        if (cipher == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
            bb.position(bb.limit());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
            return len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
16045
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   355
        int pos = bb.position();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
16045
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   357
        int blockSize = cipher.getBlockSize();
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   358
        if (cipherType == BLOCK_CIPHER) {
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   359
            // addPadding adjusts pos/limit
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   360
            len = addPadding(bb, blockSize);
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   361
            bb.position(pos);
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   362
        }
7039
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   363
16045
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   364
        if (debug != null && Debug.isOn("plaintext")) {
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   365
            try {
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   366
                HexDumpEncoder hd = new HexDumpEncoder();
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   367
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   368
                System.out.println(
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   369
                    "Padded plaintext before ENCRYPTION:  len = "
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   370
                    + len);
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   371
                hd.encodeBuffer(bb.duplicate(), System.out);
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   372
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   373
            } catch (IOException e) { }
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   374
        }
7039
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   375
16045
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   376
        /*
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   377
         * Encrypt "in-place".  This does not add its own padding.
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   378
         */
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   379
        ByteBuffer dup = bb.duplicate();
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   380
        if (cipherType == AEAD_CIPHER) {
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   381
            try {
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   382
                int outputSize = cipher.getOutputSize(dup.remaining());
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   383
                if (outputSize > bb.remaining()) {
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   384
                    // need to expand the limit of the output buffer for
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   385
                    // the authentication tag.
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   386
                    //
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   387
                    // DON'T worry about the buffer's capacity, we have
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   388
                    // reserved space for the authentication tag.
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   389
                    if (outLimit < pos + outputSize) {
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   390
                        // unlikely to happen
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   391
                        throw new ShortBufferException(
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   392
                                    "need more space in output buffer");
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   393
                    }
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   394
                    bb.limit(pos + outputSize);
7039
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   395
                }
16045
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   396
                int newLen = cipher.doFinal(dup, bb);
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   397
                if (newLen != outputSize) {
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   398
                    throw new RuntimeException(
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   399
                            "Cipher buffering error in JCE provider " +
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   400
                            cipher.getProvider().getName());
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   401
                }
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   402
                return newLen;
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   403
            } catch (IllegalBlockSizeException |
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   404
                           BadPaddingException | ShortBufferException ibse) {
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   405
                // unlikely to happen
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   406
                throw new RuntimeException(
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   407
                        "Cipher error in AEAD mode in JCE provider " +
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   408
                        cipher.getProvider().getName(), ibse);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
            }
16045
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   410
        } else {
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   411
            int newLen;
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   412
            try {
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   413
                newLen = cipher.update(dup, bb);
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   414
            } catch (ShortBufferException sbe) {
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   415
                // unlikely to happen
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   416
                throw new RuntimeException("Cipher buffering error " +
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   417
                    "in JCE provider " + cipher.getProvider().getName());
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
            if (bb.position() != dup.position()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
                throw new RuntimeException("bytebuffer padding error");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
            if (newLen != len) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
                // catch BouncyCastle buffering error
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
                throw new RuntimeException("Cipher buffering error " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
                    "in JCE provider " + cipher.getProvider().getName());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
            return newLen;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
     * Decrypts a block of data, returning the size of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
     * resulting block if padding was required.
7039
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   437
     *
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   438
     * For SSLv3 and TLSv1.0, with block ciphers in CBC mode the
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   439
     * Initialization Vector (IV) for the first record is generated by
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   440
     * the handshake protocol, the IV for subsequent records is the
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   441
     * last ciphertext block from the previous record.
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   442
     *
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   443
     * From TLSv1.1, the implicit IV is replaced with an explicit IV to
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   444
     * protect against CBC attacks.
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   445
     *
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   446
     * Differentiating between bad_record_mac and decryption_failed alerts
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   447
     * may permit certain attacks against CBC mode. It is preferable to
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   448
     * uniformly use the bad_record_mac alert to hide the specific type of
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   449
     * the error.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
    int decrypt(byte[] buf, int offset, int len) throws BadPaddingException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
        if (cipher == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
            return len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
        }
7039
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   455
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
        try {
16045
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   457
            int newLen;
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   458
            if (cipherType == AEAD_CIPHER) {
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   459
                try {
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   460
                    newLen = cipher.doFinal(buf, offset, len, buf, offset);
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   461
                } catch (IllegalBlockSizeException ibse) {
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   462
                    // unlikely to happen
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   463
                    throw new RuntimeException(
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   464
                        "Cipher error in AEAD mode in JCE provider " +
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   465
                        cipher.getProvider().getName(), ibse);
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   466
                }
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   467
            } else {
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   468
                newLen = cipher.update(buf, offset, len, buf, offset);
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   469
                if (newLen != len) {
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   470
                    // catch BouncyCastle buffering error
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   471
                    throw new RuntimeException("Cipher buffering error " +
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   472
                        "in JCE provider " + cipher.getProvider().getName());
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   473
                }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
            if (debug != null && Debug.isOn("plaintext")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
                try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
                    HexDumpEncoder hd = new HexDumpEncoder();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
                    System.out.println(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
                        "Padded plaintext after DECRYPTION:  len = "
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
                        + newLen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
                    hd.encodeBuffer(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
                        new ByteArrayInputStream(buf, offset, newLen),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
                        System.out);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
                } catch (IOException e) { }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
            }
16045
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   487
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   488
            if (cipherType == BLOCK_CIPHER) {
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   489
                int blockSize = cipher.getBlockSize();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
                newLen = removePadding(buf, offset, newLen,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
                             blockSize, protocolVersion);
7039
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   492
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   493
                if (protocolVersion.v >= ProtocolVersion.TLS11.v) {
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   494
                    if (newLen < blockSize) {
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   495
                        throw new BadPaddingException("invalid explicit IV");
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   496
                    }
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   497
                }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
            return newLen;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
        } catch (ShortBufferException e) {
16045
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   501
            // unlikely to happen, we should have enough buffer space here
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
            throw new ArrayIndexOutOfBoundsException(e.toString());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
     * Decrypts a block of data, returning the size of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
     * resulting block if padding was required.  position and limit
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
     * point to the end of the decrypted/depadded data.  The initial
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
     * limit and new limit may be different, given we may
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
     * have stripped off some padding bytes.
7039
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   513
     *
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   514
     *  @see decrypt(byte[], int, int)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
    int decrypt(ByteBuffer bb) throws BadPaddingException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
        int len = bb.remaining();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
        if (cipher == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
            bb.position(bb.limit());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
            return len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
            /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
             * Decrypt "in-place".
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
            int pos = bb.position();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
            ByteBuffer dup = bb.duplicate();
16045
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   531
            int newLen;
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   532
            if (cipherType == AEAD_CIPHER) {
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   533
                try {
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   534
                    newLen = cipher.doFinal(dup, bb);
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   535
                } catch (IllegalBlockSizeException ibse) {
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   536
                    // unlikely to happen
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   537
                    throw new RuntimeException(
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   538
                        "Cipher error in AEAD mode \"" + ibse.getMessage() +
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   539
                        " \"in JCE provider " + cipher.getProvider().getName());
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   540
                }
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   541
            } else {
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   542
                newLen = cipher.update(dup, bb);
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   543
                if (newLen != len) {
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   544
                    // catch BouncyCastle buffering error
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   545
                    throw new RuntimeException("Cipher buffering error " +
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   546
                        "in JCE provider " + cipher.getProvider().getName());
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   547
                }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
16045
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   550
            // reset the limit to the end of the decryted data
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   551
            bb.limit(pos + newLen);
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   552
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
            if (debug != null && Debug.isOn("plaintext")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
                try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
                    HexDumpEncoder hd = new HexDumpEncoder();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
                    System.out.println(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
                        "Padded plaintext after DECRYPTION:  len = "
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
                        + newLen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
16045
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   561
                    hd.encodeBuffer(
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   562
                        (ByteBuffer)bb.duplicate().position(pos), System.out);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
                } catch (IOException e) { }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
            /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
             * Remove the block padding.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
             */
16045
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   569
            if (cipherType == BLOCK_CIPHER) {
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   570
                int blockSize = cipher.getBlockSize();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
                bb.position(pos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
                newLen = removePadding(bb, blockSize, protocolVersion);
7039
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   573
16045
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   574
                // check the explicit IV of TLS v1.1 or later
7039
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   575
                if (protocolVersion.v >= ProtocolVersion.TLS11.v) {
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   576
                    if (newLen < blockSize) {
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   577
                        throw new BadPaddingException("invalid explicit IV");
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   578
                    }
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   579
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   580
                    // reset the position to the end of the decrypted data
16045
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   581
                    bb.position(bb.limit());
7039
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   582
                }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
            return newLen;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
        } catch (ShortBufferException e) {
16045
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   586
            // unlikely to happen, we should have enough buffer space here
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   587
            throw new ArrayIndexOutOfBoundsException(e.toString());
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
    private static int addPadding(byte[] buf, int offset, int len,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
            int blockSize) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
        int     newlen = len + 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
        byte    pad;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
        int     i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
        if ((newlen % blockSize) != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
            newlen += blockSize - 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
            newlen -= newlen % blockSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
        pad = (byte) (newlen - len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
        if (buf.length < (newlen + offset)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
            throw new IllegalArgumentException("no space to pad buffer");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
         * TLS version of the padding works for both SSLv3 and TLSv1
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
        for (i = 0, offset += len; i < pad; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
            buf [offset++] = (byte) (pad - 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
        return newlen;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
     * Apply the padding to the buffer.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
     * Limit is advanced to the new buffer length.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
     * Position is equal to limit.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
    private static int addPadding(ByteBuffer bb, int blockSize) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
        int     len = bb.remaining();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
        int     offset = bb.position();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
        int     newlen = len + 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
        byte    pad;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
        int     i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
        if ((newlen % blockSize) != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
            newlen += blockSize - 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
            newlen -= newlen % blockSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
        pad = (byte) (newlen - len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
         * Update the limit to what will be padded.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
        bb.limit(newlen + offset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
         * TLS version of the padding works for both SSLv3 and TLSv1
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
        for (i = 0, offset += len; i < pad; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
            bb.put(offset++, (byte) (pad - 1));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
        bb.position(offset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
        bb.limit(offset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
        return newlen;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
     * Typical TLS padding format for a 64 bit block cipher is as follows:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
     *   xx xx xx xx xx xx xx 00
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
     *   xx xx xx xx xx xx 01 01
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
     *   ...
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
     *   xx 06 06 06 06 06 06 06
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
     *   07 07 07 07 07 07 07 07
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
     * TLS also allows any amount of padding from 1 and 256 bytes as long
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
     * as it makes the data a multiple of the block size
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
    private static int removePadding(byte[] buf, int offset, int len,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
            int blockSize, ProtocolVersion protocolVersion)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
            throws BadPaddingException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
        // last byte is length byte (i.e. actual padding length - 1)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
        int padOffset = offset + len - 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
        int pad = buf[padOffset] & 0x0ff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
        int newlen = len - (pad + 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
        if (newlen < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
            throw new BadPaddingException("Padding length invalid: " + pad);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
        if (protocolVersion.v >= ProtocolVersion.TLS10.v) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
            for (int i = 1; i <= pad; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
                int val = buf[padOffset - i] & 0xff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
                if (val != pad) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
                    throw new BadPaddingException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
                                        ("Invalid TLS padding: " + val);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
        } else { // SSLv3
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
            // SSLv3 requires 0 <= length byte < block size
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
            // some implementations do 1 <= length byte <= block size,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
            // so accept that as well
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
            // v3 does not require any particular value for the other bytes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
            if (pad > blockSize) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
                throw new BadPaddingException("Invalid SSLv3 padding: " + pad);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
        return newlen;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
     * Position/limit is equal the removed padding.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
    private static int removePadding(ByteBuffer bb,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
            int blockSize, ProtocolVersion protocolVersion)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
            throws BadPaddingException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
        int len = bb.remaining();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
        int offset = bb.position();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
        // last byte is length byte (i.e. actual padding length - 1)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
        int padOffset = offset + len - 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
        int pad = bb.get(padOffset) & 0x0ff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
        int newlen = len - (pad + 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
        if (newlen < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
            throw new BadPaddingException("Padding length invalid: " + pad);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
         * We could zero the padding area, but not much useful
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
         * information there.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
        if (protocolVersion.v >= ProtocolVersion.TLS10.v) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
            bb.put(padOffset, (byte)0);         // zero the padding.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
            for (int i = 1; i <= pad; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
                int val = bb.get(padOffset - i) & 0xff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
                if (val != pad) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
                    throw new BadPaddingException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
                                        ("Invalid TLS padding: " + val);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
        } else { // SSLv3
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
            // SSLv3 requires 0 <= length byte < block size
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
            // some implementations do 1 <= length byte <= block size,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
            // so accept that as well
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
            // v3 does not require any particular value for the other bytes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
            if (pad > blockSize) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
                throw new BadPaddingException("Invalid SSLv3 padding: " + pad);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
         * Reset buffer limit to remove padding.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
        bb.position(offset + newlen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
        bb.limit(offset + newlen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
        return newlen;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
    }
1763
0a6b65d56746 6750401: SSL stress test with GF leads to 32 bit max process size in less than 5 minutes,with PCKS11 provider
wetmore
parents: 2
diff changeset
   748
0a6b65d56746 6750401: SSL stress test with GF leads to 32 bit max process size in less than 5 minutes,with PCKS11 provider
wetmore
parents: 2
diff changeset
   749
    /*
0a6b65d56746 6750401: SSL stress test with GF leads to 32 bit max process size in less than 5 minutes,with PCKS11 provider
wetmore
parents: 2
diff changeset
   750
     * Dispose of any intermediate state in the underlying cipher.
0a6b65d56746 6750401: SSL stress test with GF leads to 32 bit max process size in less than 5 minutes,with PCKS11 provider
wetmore
parents: 2
diff changeset
   751
     * For PKCS11 ciphers, this will release any attached sessions, and
0a6b65d56746 6750401: SSL stress test with GF leads to 32 bit max process size in less than 5 minutes,with PCKS11 provider
wetmore
parents: 2
diff changeset
   752
     * thus make finalization faster.
0a6b65d56746 6750401: SSL stress test with GF leads to 32 bit max process size in less than 5 minutes,with PCKS11 provider
wetmore
parents: 2
diff changeset
   753
     */
0a6b65d56746 6750401: SSL stress test with GF leads to 32 bit max process size in less than 5 minutes,with PCKS11 provider
wetmore
parents: 2
diff changeset
   754
    void dispose() {
0a6b65d56746 6750401: SSL stress test with GF leads to 32 bit max process size in less than 5 minutes,with PCKS11 provider
wetmore
parents: 2
diff changeset
   755
        try {
0a6b65d56746 6750401: SSL stress test with GF leads to 32 bit max process size in less than 5 minutes,with PCKS11 provider
wetmore
parents: 2
diff changeset
   756
            if (cipher != null) {
0a6b65d56746 6750401: SSL stress test with GF leads to 32 bit max process size in less than 5 minutes,with PCKS11 provider
wetmore
parents: 2
diff changeset
   757
                // ignore return value.
0a6b65d56746 6750401: SSL stress test with GF leads to 32 bit max process size in less than 5 minutes,with PCKS11 provider
wetmore
parents: 2
diff changeset
   758
                cipher.doFinal();
0a6b65d56746 6750401: SSL stress test with GF leads to 32 bit max process size in less than 5 minutes,with PCKS11 provider
wetmore
parents: 2
diff changeset
   759
            }
16045
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   760
        } catch (Exception e) {
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   761
            // swallow all types of exceptions.
1763
0a6b65d56746 6750401: SSL stress test with GF leads to 32 bit max process size in less than 5 minutes,with PCKS11 provider
wetmore
parents: 2
diff changeset
   762
        }
0a6b65d56746 6750401: SSL stress test with GF leads to 32 bit max process size in less than 5 minutes,with PCKS11 provider
wetmore
parents: 2
diff changeset
   763
    }
0a6b65d56746 6750401: SSL stress test with GF leads to 32 bit max process size in less than 5 minutes,with PCKS11 provider
wetmore
parents: 2
diff changeset
   764
10915
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 7039
diff changeset
   765
    /*
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 7039
diff changeset
   766
     * Does the cipher use CBC mode?
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 7039
diff changeset
   767
     *
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 7039
diff changeset
   768
     * @return true if the cipher use CBC mode, false otherwise.
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 7039
diff changeset
   769
     */
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 7039
diff changeset
   770
    boolean isCBCMode() {
16045
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   771
        return cipherType == BLOCK_CIPHER;
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   772
    }
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   773
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   774
    /*
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   775
     * Does the cipher use AEAD mode?
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   776
     *
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   777
     * @return true if the cipher use AEAD mode, false otherwise.
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   778
     */
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   779
    boolean isAEADMode() {
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   780
        return cipherType == AEAD_CIPHER;
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   781
    }
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   782
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   783
    /*
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   784
     * Is the cipher null?
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   785
     *
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   786
     * @return true if the cipher is null, false otherwise.
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   787
     */
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   788
    boolean isNullCipher() {
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   789
        return cipher == null;
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   790
    }
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   791
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   792
    /*
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   793
     * Gets the explicit nonce/IV size of the cipher.
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   794
     *
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   795
     * The returned value is the SecurityParameters.record_iv_length in
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   796
     * RFC 4346/5246.  It is the size of explicit IV for CBC mode, and the
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   797
     * size of explicit nonce for AEAD mode.
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   798
     *
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   799
     * @return the explicit nonce size of the cipher.
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   800
     */
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   801
    int getExplicitNonceSize() {
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   802
        switch (cipherType) {
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   803
            case BLOCK_CIPHER:
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   804
                // For block ciphers, the explicit IV length is of length
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   805
                // SecurityParameters.record_iv_length, which is equal to
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   806
                // the SecurityParameters.block_size.
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   807
                if (protocolVersion.v >= ProtocolVersion.TLS11.v) {
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   808
                    return cipher.getBlockSize();
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   809
                }
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   810
                break;
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   811
            case AEAD_CIPHER:
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   812
                return recordIvSize;
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   813
                        // It is also the length of sequence number, which is
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   814
                        // used as the nonce_explicit for AEAD cipher suites.
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   815
        }
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   816
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   817
        return 0;
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   818
    }
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   819
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   820
    /*
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   821
     * Applies the explicit nonce/IV to this cipher. This method is used to
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   822
     * decrypt an SSL/TLS input record.
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   823
     *
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   824
     * The returned value is the SecurityParameters.record_iv_length in
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   825
     * RFC 4346/5246.  It is the size of explicit IV for CBC mode, and the
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   826
     * size of explicit nonce for AEAD mode.
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   827
     *
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   828
     * @param  authenticator the authenticator to get the additional
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   829
     *         authentication data
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   830
     * @param  contentType the content type of the input record
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   831
     * @param  bb the byte buffer to get the explicit nonce from
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   832
     *
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   833
     * @return the explicit nonce size of the cipher.
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   834
     */
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   835
    int applyExplicitNonce(Authenticator authenticator, byte contentType,
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   836
            ByteBuffer bb) throws BadPaddingException {
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   837
        switch (cipherType) {
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   838
            case BLOCK_CIPHER:
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   839
                // For block ciphers, the explicit IV length is of length
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   840
                // SecurityParameters.record_iv_length, which is equal to
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   841
                // the SecurityParameters.block_size.
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   842
                if (protocolVersion.v >= ProtocolVersion.TLS11.v) {
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   843
                    return cipher.getBlockSize();
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   844
                }
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   845
                break;
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   846
            case AEAD_CIPHER:
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   847
                if (bb.remaining() < (recordIvSize + tagSize)) {
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   848
                    throw new BadPaddingException(
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   849
                                        "invalid AEAD cipher fragment");
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   850
                }
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   851
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   852
                // initialize the AEAD cipher for the unique IV
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   853
                byte[] iv = Arrays.copyOf(fixedIv,
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   854
                                    fixedIv.length + recordIvSize);
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   855
                bb.get(iv, fixedIv.length, recordIvSize);
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   856
                bb.position(bb.position() - recordIvSize);
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   857
                GCMParameterSpec spec = new GCMParameterSpec(tagSize * 8, iv);
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   858
                try {
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   859
                    cipher.init(mode, key, spec, random);
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   860
                } catch (InvalidKeyException |
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   861
                            InvalidAlgorithmParameterException ikae) {
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   862
                    // unlikely to happen
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   863
                    throw new RuntimeException(
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   864
                                "invalid key or spec in GCM mode", ikae);
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   865
                }
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   866
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   867
                // update the additional authentication data
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   868
                byte[] aad = authenticator.acquireAuthenticationBytes(
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   869
                        contentType, bb.remaining() - recordIvSize - tagSize);
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   870
                cipher.updateAAD(aad);
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   871
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   872
                return recordIvSize;
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   873
                        // It is also the length of sequence number, which is
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   874
                        // used as the nonce_explicit for AEAD cipher suites.
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   875
        }
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   876
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   877
       return 0;
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   878
    }
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   879
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   880
    /*
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   881
     * Applies the explicit nonce/IV to this cipher. This method is used to
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   882
     * decrypt an SSL/TLS input record.
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   883
     *
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   884
     * The returned value is the SecurityParameters.record_iv_length in
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   885
     * RFC 4346/5246.  It is the size of explicit IV for CBC mode, and the
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   886
     * size of explicit nonce for AEAD mode.
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   887
     *
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   888
     * @param  authenticator the authenticator to get the additional
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   889
     *         authentication data
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   890
     * @param  contentType the content type of the input record
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   891
     * @param  buf the byte array to get the explicit nonce from
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   892
     * @param  offset the offset of the byte buffer
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   893
     * @param  cipheredLength the ciphered fragment length of the output
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   894
     *         record, it is the TLSCiphertext.length in RFC 4346/5246.
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   895
     *
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   896
     * @return the explicit nonce size of the cipher.
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   897
     */
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   898
    int applyExplicitNonce(Authenticator authenticator,
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   899
            byte contentType, byte[] buf, int offset,
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   900
            int cipheredLength) throws BadPaddingException {
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   901
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   902
        ByteBuffer bb = ByteBuffer.wrap(buf, offset, cipheredLength);
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   903
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   904
        return applyExplicitNonce(authenticator, contentType, bb);
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   905
    }
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   906
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   907
    /*
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   908
     * Creates the explicit nonce/IV to this cipher. This method is used to
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   909
     * encrypt an SSL/TLS output record.
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   910
     *
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   911
     * The size of the returned array is the SecurityParameters.record_iv_length
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   912
     * in RFC 4346/5246.  It is the size of explicit IV for CBC mode, and the
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   913
     * size of explicit nonce for AEAD mode.
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   914
     *
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   915
     * @param  authenticator the authenticator to get the additional
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   916
     *         authentication data
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   917
     * @param  contentType the content type of the input record
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   918
     * @param  fragmentLength the fragment length of the output record, it is
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   919
     *         the TLSCompressed.length in RFC 4346/5246.
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   920
     *
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   921
     * @return the explicit nonce of the cipher.
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   922
     */
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   923
    byte[] createExplicitNonce(Authenticator authenticator,
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   924
            byte contentType, int fragmentLength) {
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   925
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   926
        byte[] nonce = new byte[0];
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   927
        switch (cipherType) {
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   928
            case BLOCK_CIPHER:
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   929
                if (protocolVersion.v >= ProtocolVersion.TLS11.v) {
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   930
                    // For block ciphers, the explicit IV length is of length
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   931
                    // SecurityParameters.record_iv_length, which is equal to
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   932
                    // the SecurityParameters.block_size.
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   933
                    //
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   934
                    // Generate a random number as the explicit IV parameter.
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   935
                    nonce = new byte[cipher.getBlockSize()];
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   936
                    random.nextBytes(nonce);
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   937
                }
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   938
                break;
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   939
            case AEAD_CIPHER:
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   940
                // To be unique and aware of overflow-wrap, sequence number
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   941
                // is used as the nonce_explicit of AEAD cipher suites.
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   942
                nonce = authenticator.sequenceNumber();
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   943
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   944
                // initialize the AEAD cipher for the unique IV
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   945
                byte[] iv = Arrays.copyOf(fixedIv,
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   946
                                            fixedIv.length + nonce.length);
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   947
                System.arraycopy(nonce, 0, iv, fixedIv.length, nonce.length);
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   948
                GCMParameterSpec spec = new GCMParameterSpec(tagSize * 8, iv);
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   949
                try {
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   950
                    cipher.init(mode, key, spec, random);
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   951
                } catch (InvalidKeyException |
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   952
                            InvalidAlgorithmParameterException ikae) {
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   953
                    // unlikely to happen
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   954
                    throw new RuntimeException(
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   955
                                "invalid key or spec in GCM mode", ikae);
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   956
                }
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   957
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   958
                // update the additional authentication data
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   959
                byte[] aad = authenticator.acquireAuthenticationBytes(
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   960
                                                contentType, fragmentLength);
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   961
                cipher.updateAAD(aad);
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   962
                break;
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   963
        }
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   964
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   965
        return nonce;
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   966
    }
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   967
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   968
    /*
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   969
     * Is this cipher available?
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   970
     *
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   971
     * This method can only be called by CipherSuite.BulkCipher.isAvailable()
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   972
     * to test the availability of a cipher suites.  Please DON'T use it in
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   973
     * other places, otherwise, the behavior may be unexpected because we may
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   974
     * initialize AEAD cipher improperly in the method.
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   975
     */
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   976
    Boolean isAvailable() {
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   977
        // We won't know whether a cipher for a particular key size is
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   978
        // available until the cipher is successfully initialized.
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   979
        //
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   980
        // We do not initialize AEAD cipher in the constructor.  Need to
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   981
        // initialize the cipher to ensure that the AEAD mode for a
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   982
        // particular key size is supported.
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   983
        if (cipherType == AEAD_CIPHER) {
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   984
            try {
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   985
                Authenticator authenticator =
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   986
                    new Authenticator(protocolVersion);
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   987
                byte[] nonce = authenticator.sequenceNumber();
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   988
                byte[] iv = Arrays.copyOf(fixedIv,
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   989
                                            fixedIv.length + nonce.length);
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   990
                System.arraycopy(nonce, 0, iv, fixedIv.length, nonce.length);
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   991
                GCMParameterSpec spec = new GCMParameterSpec(tagSize * 8, iv);
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   992
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   993
                cipher.init(mode, key, spec, random);
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   994
            } catch (Exception e) {
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   995
                return Boolean.FALSE;
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   996
            }
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   997
        }   // Otherwise, we have initialized the cipher in the constructor.
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   998
9d08c3b9a6a0 7030966: Support AEAD CipherSuites
xuelei
parents: 14664
diff changeset
   999
        return Boolean.TRUE;
10915
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 7039
diff changeset
  1000
    }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1001
}