jdk/src/java.base/share/classes/sun/security/ssl/CipherBox.java
author martin
Tue, 15 Sep 2015 21:56:04 -0700
changeset 32649 2ee9017c7597
parent 30904 ec0224270f90
child 34687 d302ed125dc9
permissions -rw-r--r--
8136583: Core libraries should use blessed modifier order Summary: Run blessed-modifier-order script (see bug) Reviewed-by: psandoz, chegar, alanb, plevart
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
29488
1f25b971e59a 6996366: convert MacAlg to an enum
jnimeh
parents: 27292
diff changeset
     2
 * Copyright (c) 1996, 2015, 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;
16913
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
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;
16913
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
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.*;
16913
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
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
32649
2ee9017c7597 8136583: Core libraries should use blessed modifier order
martin
parents: 30904
diff changeset
    96
    static final CipherBox NULL = new CipherBox();
2
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
    /**
16913
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   113
     * fixed IV, the implicit nonce of AEAD cipher suite, only apply to
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   114
     * AEAD cipher suites
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   115
     */
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   116
    private final byte[] fixedIv;
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   117
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   118
    /**
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   119
     * the key, reserved only for AEAD cipher initialization
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   120
     */
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   121
    private final Key key;
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   122
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   123
    /**
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   124
     * the operation mode, reserved for AEAD cipher initialization
10915
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 7039
diff changeset
   125
     */
16913
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   126
    private final int mode;
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   127
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   128
    /**
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   129
     * the authentication tag size, only apply to AEAD cipher suites
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   130
     */
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   131
    private final int tagSize;
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   132
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   133
    /**
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   134
     * the record IV length, only apply to AEAD cipher suites
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   135
     */
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   136
    private final int recordIvSize;
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   137
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   138
    /**
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   139
     * cipher type
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   140
     */
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
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() {
30904
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
   157
        this.protocolVersion = ProtocolVersion.DEFAULT_TLS;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
        this.cipher = null;
30904
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
   159
        this.cipherType = NULL_CIPHER;
16913
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   160
        this.fixedIv = new byte[0];
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   161
        this.key = null;
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   162
        this.mode = Cipher.ENCRYPT_MODE;    // choose at random
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   163
        this.random = null;
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   164
        this.tagSize = 0;
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
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);
16913
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
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;
16913
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
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 &&
30904
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
   200
                    protocolVersion.useTLS11PlusSpec()) {
7039
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
16913
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   204
            if (cipherType == AEAD_CIPHER) {
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   205
                // AEAD must completely initialize the cipher for each packet,
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   206
                // and so we save initialization parameters for packet
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   207
                // processing time.
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   208
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   209
                // Set the tag size for AEAD cipher
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   210
                tagSize = bulkCipher.tagSize;
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   211
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   212
                // Reserve the key for AEAD cipher initialization
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   213
                this.key = key;
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   214
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   215
                fixedIv = iv.getIV();
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   216
                if (fixedIv == null ||
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   217
                        fixedIv.length != bulkCipher.fixedIvSize) {
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   218
                    throw new RuntimeException("Improper fixed IV for AEAD");
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   219
                }
7039
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   220
16913
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   221
                // Set the record IV length for AEAD cipher
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   222
                recordIvSize = bulkCipher.ivSize - bulkCipher.fixedIvSize;
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   223
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   224
                // DON'T initialize the cipher for AEAD!
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   225
            } else {
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   226
                // CBC only requires one initialization during its lifetime
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   227
                // (future packets/IVs set the proper CBC state), so we can
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   228
                // initialize now.
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   229
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   230
                // Zeroize the variables that only apply to AEAD cipher
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   231
                this.tagSize = 0;
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   232
                this.fixedIv = new byte[0];
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   233
                this.recordIvSize = 0;
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   234
                this.key = null;
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   235
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   236
                // Initialize the cipher
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
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
29488
1f25b971e59a 6996366: convert MacAlg to an enum
jnimeh
parents: 27292
diff changeset
   260
        if (cipher == BulkCipher.B_NULL) {
2
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 {
16913
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   294
            int blockSize = cipher.getBlockSize();
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
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
            }
16913
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
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
            }
16913
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   311
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   312
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   313
            if (cipherType == AEAD_CIPHER) {
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   314
                try {
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   315
                    return cipher.doFinal(buf, offset, len, buf, offset);
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   316
                } catch (IllegalBlockSizeException | BadPaddingException ibe) {
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   317
                    // unlikely to happen
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   318
                    throw new RuntimeException(
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   319
                        "Cipher error in AEAD mode in JCE provider " +
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   320
                        cipher.getProvider().getName(), ibe);
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   321
                }
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   322
            } else {
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   323
                int newLen = cipher.update(buf, offset, len, buf, offset);
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   324
                if (newLen != len) {
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   325
                    // catch BouncyCastle buffering error
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   326
                    throw new RuntimeException("Cipher buffering error " +
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   327
                        "in JCE provider " + cipher.getProvider().getName());
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   328
                }
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
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) {
16913
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
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
     */
16913
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
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
16913
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   355
        int pos = bb.position();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
16913
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   357
        int blockSize = cipher.getBlockSize();
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   358
        if (cipherType == BLOCK_CIPHER) {
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   359
            // addPadding adjusts pos/limit
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   360
            len = addPadding(bb, blockSize);
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   361
            bb.position(pos);
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   362
        }
7039
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   363
16913
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   364
        if (debug != null && Debug.isOn("plaintext")) {
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   365
            try {
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   366
                HexDumpEncoder hd = new HexDumpEncoder();
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   367
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   368
                System.out.println(
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   369
                    "Padded plaintext before ENCRYPTION:  len = "
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   370
                    + len);
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   371
                hd.encodeBuffer(bb.duplicate(), System.out);
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   372
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   373
            } catch (IOException e) { }
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   374
        }
7039
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   375
16913
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   376
        /*
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   377
         * Encrypt "in-place".  This does not add its own padding.
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   378
         */
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   379
        ByteBuffer dup = bb.duplicate();
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   380
        if (cipherType == AEAD_CIPHER) {
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   381
            try {
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   382
                int outputSize = cipher.getOutputSize(dup.remaining());
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   383
                if (outputSize > bb.remaining()) {
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   384
                    // need to expand the limit of the output buffer for
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   385
                    // the authentication tag.
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   386
                    //
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   387
                    // DON'T worry about the buffer's capacity, we have
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   388
                    // reserved space for the authentication tag.
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   389
                    if (outLimit < pos + outputSize) {
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   390
                        // unlikely to happen
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   391
                        throw new ShortBufferException(
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   392
                                    "need more space in output buffer");
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   393
                    }
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   394
                    bb.limit(pos + outputSize);
7039
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   395
                }
16913
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   396
                int newLen = cipher.doFinal(dup, bb);
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   397
                if (newLen != outputSize) {
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   398
                    throw new RuntimeException(
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   399
                            "Cipher buffering error in JCE provider " +
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   400
                            cipher.getProvider().getName());
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   401
                }
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   402
                return newLen;
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   403
            } catch (IllegalBlockSizeException |
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   404
                           BadPaddingException | ShortBufferException ibse) {
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   405
                // unlikely to happen
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   406
                throw new RuntimeException(
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   407
                        "Cipher error in AEAD mode in JCE provider " +
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   408
                        cipher.getProvider().getName(), ibse);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
            }
16913
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   410
        } else {
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   411
            int newLen;
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   412
            try {
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   413
                newLen = cipher.update(dup, bb);
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   414
            } catch (ShortBufferException sbe) {
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   415
                // unlikely to happen
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   416
                throw new RuntimeException("Cipher buffering error " +
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
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
     */
16113
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   451
    int decrypt(byte[] buf, int offset, int len,
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   452
            int tagLen) throws BadPaddingException {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
        if (cipher == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
            return len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
        }
7039
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   456
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
        try {
16913
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   458
            int newLen;
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   459
            if (cipherType == AEAD_CIPHER) {
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   460
                try {
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   461
                    newLen = cipher.doFinal(buf, offset, len, buf, offset);
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   462
                } catch (IllegalBlockSizeException ibse) {
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   463
                    // unlikely to happen
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   464
                    throw new RuntimeException(
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   465
                        "Cipher error in AEAD mode in JCE provider " +
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   466
                        cipher.getProvider().getName(), ibse);
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   467
                }
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   468
            } else {
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   469
                newLen = cipher.update(buf, offset, len, buf, offset);
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   470
                if (newLen != len) {
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   471
                    // catch BouncyCastle buffering error
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   472
                    throw new RuntimeException("Cipher buffering error " +
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   473
                        "in JCE provider " + cipher.getProvider().getName());
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   474
                }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
            if (debug != null && Debug.isOn("plaintext")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
                try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
                    HexDumpEncoder hd = new HexDumpEncoder();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
                    System.out.println(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
                        "Padded plaintext after DECRYPTION:  len = "
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
                        + newLen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
                    hd.encodeBuffer(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
                        new ByteArrayInputStream(buf, offset, newLen),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
                        System.out);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
                } catch (IOException e) { }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
            }
16113
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   488
16913
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   489
            if (cipherType == BLOCK_CIPHER) {
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   490
                int blockSize = cipher.getBlockSize();
16113
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   491
                newLen = removePadding(
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   492
                    buf, offset, newLen, tagLen, blockSize, protocolVersion);
7039
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   493
30904
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
   494
                if (protocolVersion.useTLS11PlusSpec()) {
7039
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   495
                    if (newLen < blockSize) {
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   496
                        throw new BadPaddingException("invalid explicit IV");
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   497
                    }
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   498
                }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
            return newLen;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
        } catch (ShortBufferException e) {
16913
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   502
            // unlikely to happen, we should have enough buffer space here
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
            throw new ArrayIndexOutOfBoundsException(e.toString());
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
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
     * Decrypts a block of data, returning the size of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
     * resulting block if padding was required.  position and limit
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
     * point to the end of the decrypted/depadded data.  The initial
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
     * limit and new limit may be different, given we may
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
     * have stripped off some padding bytes.
7039
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   514
     *
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   515
     *  @see decrypt(byte[], int, int)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
     */
16113
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   517
    int decrypt(ByteBuffer bb, int tagLen) throws BadPaddingException {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
        int len = bb.remaining();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
        if (cipher == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
            bb.position(bb.limit());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
            return len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
            /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
             * Decrypt "in-place".
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
            int pos = bb.position();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
            ByteBuffer dup = bb.duplicate();
16913
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   532
            int newLen;
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   533
            if (cipherType == AEAD_CIPHER) {
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   534
                try {
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   535
                    newLen = cipher.doFinal(dup, bb);
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   536
                } catch (IllegalBlockSizeException ibse) {
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   537
                    // unlikely to happen
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   538
                    throw new RuntimeException(
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   539
                        "Cipher error in AEAD mode \"" + ibse.getMessage() +
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   540
                        " \"in JCE provider " + cipher.getProvider().getName());
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   541
                }
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   542
            } else {
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   543
                newLen = cipher.update(dup, bb);
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   544
                if (newLen != len) {
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   545
                    // catch BouncyCastle buffering error
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   546
                    throw new RuntimeException("Cipher buffering error " +
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   547
                        "in JCE provider " + cipher.getProvider().getName());
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   548
                }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
16913
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   551
            // reset the limit to the end of the decryted data
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   552
            bb.limit(pos + newLen);
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   553
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
            if (debug != null && Debug.isOn("plaintext")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
                try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
                    HexDumpEncoder hd = new HexDumpEncoder();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
                    System.out.println(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
                        "Padded plaintext after DECRYPTION:  len = "
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
                        + newLen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
16113
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   562
                    hd.encodeBuffer(
27292
7ff4b24b33ce 4774077: Use covariant return types in the NIO buffer hierarchy
rwarburton
parents: 25859
diff changeset
   563
                        bb.duplicate().position(pos), System.out);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
                } catch (IOException e) { }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
            /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
             * Remove the block padding.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
             */
16913
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   570
            if (cipherType == BLOCK_CIPHER) {
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   571
                int blockSize = cipher.getBlockSize();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
                bb.position(pos);
16913
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   573
                newLen = removePadding(bb, tagLen, blockSize, protocolVersion);
7039
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   574
16913
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   575
                // check the explicit IV of TLS v1.1 or later
30904
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
   576
                if (protocolVersion.useTLS11PlusSpec()) {
7039
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   577
                    if (newLen < blockSize) {
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   578
                        throw new BadPaddingException("invalid explicit IV");
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   579
                    }
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   580
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   581
                    // reset the position to the end of the decrypted data
16913
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   582
                    bb.position(bb.limit());
7039
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 5506
diff changeset
   583
                }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
            return newLen;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
        } catch (ShortBufferException e) {
16913
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   587
            // unlikely to happen, we should have enough buffer space here
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   588
            throw new ArrayIndexOutOfBoundsException(e.toString());
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
    private static int addPadding(byte[] buf, int offset, int len,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
            int blockSize) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
        int     newlen = len + 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
        byte    pad;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
        int     i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
        if ((newlen % blockSize) != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
            newlen += blockSize - 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
            newlen -= newlen % blockSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
        pad = (byte) (newlen - len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
        if (buf.length < (newlen + offset)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
            throw new IllegalArgumentException("no space to pad buffer");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
         * TLS version of the padding works for both SSLv3 and TLSv1
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
        for (i = 0, offset += len; i < pad; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
            buf [offset++] = (byte) (pad - 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
        return newlen;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
     * Apply the padding to the buffer.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
     * Limit is advanced to the new buffer length.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
     * Position is equal to limit.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
    private static int addPadding(ByteBuffer bb, int blockSize) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
        int     len = bb.remaining();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
        int     offset = bb.position();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
        int     newlen = len + 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
        byte    pad;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
        int     i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
        if ((newlen % blockSize) != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
            newlen += blockSize - 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
            newlen -= newlen % blockSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
        pad = (byte) (newlen - len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
         * Update the limit to what will be padded.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
        bb.limit(newlen + offset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
         * TLS version of the padding works for both SSLv3 and TLSv1
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
        for (i = 0, offset += len; i < pad; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
            bb.put(offset++, (byte) (pad - 1));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
        bb.position(offset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
        bb.limit(offset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
        return newlen;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
16113
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   656
    /*
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   657
     * A constant-time check of the padding.
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   658
     *
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   659
     * NOTE that we are checking both the padding and the padLen bytes here.
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   660
     *
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   661
     * The caller MUST ensure that the len parameter is a positive number.
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   662
     */
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   663
    private static int[] checkPadding(
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   664
            byte[] buf, int offset, int len, byte pad) {
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   665
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   666
        if (len <= 0) {
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   667
            throw new RuntimeException("padding len must be positive");
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   668
        }
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   669
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   670
        // An array of hits is used to prevent Hotspot optimization for
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   671
        // the purpose of a constant-time check.
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   672
        int[] results = {0, 0};    // {missed #, matched #}
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   673
        for (int i = 0; i <= 256;) {
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   674
            for (int j = 0; j < len && i <= 256; j++, i++) {     // j <= i
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   675
                if (buf[offset + j] != pad) {
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   676
                    results[0]++;       // mismatched padding data
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   677
                } else {
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   678
                    results[1]++;       // matched padding data
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   679
                }
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   680
            }
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   681
        }
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   682
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   683
        return results;
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   684
    }
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   685
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   686
    /*
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   687
     * A constant-time check of the padding.
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   688
     *
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   689
     * NOTE that we are checking both the padding and the padLen bytes here.
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   690
     *
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   691
     * The caller MUST ensure that the bb parameter has remaining.
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   692
     */
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   693
    private static int[] checkPadding(ByteBuffer bb, byte pad) {
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   694
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   695
        if (!bb.hasRemaining()) {
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   696
            throw new RuntimeException("hasRemaining() must be positive");
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   697
        }
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   698
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   699
        // An array of hits is used to prevent Hotspot optimization for
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   700
        // the purpose of a constant-time check.
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   701
        int[] results = {0, 0};    // {missed #, matched #}
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   702
        bb.mark();
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   703
        for (int i = 0; i <= 256; bb.reset()) {
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   704
            for (; bb.hasRemaining() && i <= 256; i++) {
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   705
                if (bb.get() != pad) {
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   706
                    results[0]++;       // mismatched padding data
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   707
                } else {
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   708
                    results[1]++;       // matched padding data
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   709
                }
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   710
            }
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   711
        }
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   712
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   713
        return results;
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   714
    }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
     * Typical TLS padding format for a 64 bit block cipher is as follows:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
     *   xx xx xx xx xx xx xx 00
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
     *   xx xx xx xx xx xx 01 01
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
     *   ...
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
     *   xx 06 06 06 06 06 06 06
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
     *   07 07 07 07 07 07 07 07
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
     * TLS also allows any amount of padding from 1 and 256 bytes as long
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
     * as it makes the data a multiple of the block size
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
    private static int removePadding(byte[] buf, int offset, int len,
16113
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   727
            int tagLen, int blockSize,
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   728
            ProtocolVersion protocolVersion) throws BadPaddingException {
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   729
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
        // last byte is length byte (i.e. actual padding length - 1)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
        int padOffset = offset + len - 1;
16113
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   732
        int padLen = buf[padOffset] & 0xFF;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
16113
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   734
        int newLen = len - (padLen + 1);
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   735
        if ((newLen - tagLen) < 0) {
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   736
            // If the buffer is not long enough to contain the padding plus
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   737
            // a MAC tag, do a dummy constant-time padding check.
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   738
            //
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   739
            // Note that it is a dummy check, so we won't care about what is
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   740
            // the actual padding data.
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   741
            checkPadding(buf, offset, len, (byte)(padLen & 0xFF));
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   742
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   743
            throw new BadPaddingException("Invalid Padding length: " + padLen);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
16113
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   746
        // The padding data should be filled with the padding length value.
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   747
        int[] results = checkPadding(buf, offset + newLen,
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   748
                        padLen + 1, (byte)(padLen & 0xFF));
30904
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
   749
        if (protocolVersion.useTLS10PlusSpec()) {
16113
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   750
            if (results[0] != 0) {          // padding data has invalid bytes
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   751
                throw new BadPaddingException("Invalid TLS padding data");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
        } else { // SSLv3
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
            // SSLv3 requires 0 <= length byte < block size
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
            // some implementations do 1 <= length byte <= block size,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
            // so accept that as well
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
            // v3 does not require any particular value for the other bytes
16113
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   758
            if (padLen > blockSize) {
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   759
                throw new BadPaddingException("Invalid SSLv3 padding");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
        }
16113
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   762
        return newLen;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
     * Position/limit is equal the removed padding.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
    private static int removePadding(ByteBuffer bb,
16113
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   769
            int tagLen, int blockSize,
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   770
            ProtocolVersion protocolVersion) throws BadPaddingException {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
        int len = bb.remaining();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
        int offset = bb.position();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
        // last byte is length byte (i.e. actual padding length - 1)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
        int padOffset = offset + len - 1;
16113
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   777
        int padLen = bb.get(padOffset) & 0xFF;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
16113
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   779
        int newLen = len - (padLen + 1);
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   780
        if ((newLen - tagLen) < 0) {
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   781
            // If the buffer is not long enough to contain the padding plus
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   782
            // a MAC tag, do a dummy constant-time padding check.
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   783
            //
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   784
            // Note that it is a dummy check, so we won't care about what is
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   785
            // the actual padding data.
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   786
            checkPadding(bb.duplicate(), (byte)(padLen & 0xFF));
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   787
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   788
            throw new BadPaddingException("Invalid Padding length: " + padLen);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   789
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   790
16113
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   791
        // The padding data should be filled with the padding length value.
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   792
        int[] results = checkPadding(
27292
7ff4b24b33ce 4774077: Use covariant return types in the NIO buffer hierarchy
rwarburton
parents: 25859
diff changeset
   793
                bb.duplicate().position(offset + newLen),
16113
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   794
                (byte)(padLen & 0xFF));
30904
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
   795
        if (protocolVersion.useTLS10PlusSpec()) {
16113
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   796
            if (results[0] != 0) {          // padding data has invalid bytes
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   797
                throw new BadPaddingException("Invalid TLS padding data");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   798
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   799
        } else { // SSLv3
90ce3da70b43 Initial load
duke
parents:
diff changeset
   800
            // SSLv3 requires 0 <= length byte < block size
90ce3da70b43 Initial load
duke
parents:
diff changeset
   801
            // some implementations do 1 <= length byte <= block size,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   802
            // so accept that as well
90ce3da70b43 Initial load
duke
parents:
diff changeset
   803
            // v3 does not require any particular value for the other bytes
16113
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   804
            if (padLen > blockSize) {
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   805
                throw new BadPaddingException("Invalid SSLv3 padding");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   807
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   808
90ce3da70b43 Initial load
duke
parents:
diff changeset
   809
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   810
         * Reset buffer limit to remove padding.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   811
         */
16113
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   812
        bb.position(offset + newLen);
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   813
        bb.limit(offset + newLen);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   814
16113
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   815
        return newLen;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   816
    }
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
   817
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
   818
    /*
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
   819
     * 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
   820
     * 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
   821
     * 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
   822
     */
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
   823
    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
   824
        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
   825
            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
   826
                // 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
   827
                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
   828
            }
16913
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   829
        } catch (Exception e) {
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   830
            // 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
   831
        }
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
   832
    }
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
   833
10915
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 7039
diff changeset
   834
    /*
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 7039
diff changeset
   835
     * Does the cipher use CBC mode?
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 7039
diff changeset
   836
     *
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 7039
diff changeset
   837
     * @return true if the cipher use CBC mode, false otherwise.
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 7039
diff changeset
   838
     */
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 7039
diff changeset
   839
    boolean isCBCMode() {
16913
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   840
        return cipherType == BLOCK_CIPHER;
10915
1e20964cebf3 7064341: jsse/runtime security problem
xuelei
parents: 7039
diff changeset
   841
    }
16113
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   842
16913
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   843
    /*
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   844
     * Does the cipher use AEAD mode?
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   845
     *
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   846
     * @return true if the cipher use AEAD mode, false otherwise.
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   847
     */
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   848
    boolean isAEADMode() {
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   849
        return cipherType == AEAD_CIPHER;
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   850
    }
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   851
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   852
    /*
16113
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   853
     * Is the cipher null?
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   854
     *
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   855
     * @return true if the cipher is null, false otherwise.
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   856
     */
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   857
    boolean isNullCipher() {
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   858
        return cipher == null;
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   859
    }
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
   860
16913
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   861
    /*
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   862
     * Gets the explicit nonce/IV size of the cipher.
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   863
     *
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   864
     * The returned value is the SecurityParameters.record_iv_length in
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   865
     * RFC 4346/5246.  It is the size of explicit IV for CBC mode, and the
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   866
     * size of explicit nonce for AEAD mode.
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   867
     *
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   868
     * @return the explicit nonce size of the cipher.
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   869
     */
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   870
    int getExplicitNonceSize() {
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   871
        switch (cipherType) {
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   872
            case BLOCK_CIPHER:
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   873
                // For block ciphers, the explicit IV length is of length
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   874
                // SecurityParameters.record_iv_length, which is equal to
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   875
                // the SecurityParameters.block_size.
30904
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
   876
                if (protocolVersion.useTLS11PlusSpec()) {
16913
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   877
                    return cipher.getBlockSize();
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   878
                }
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   879
                break;
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   880
            case AEAD_CIPHER:
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   881
                return recordIvSize;
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   882
                        // It is also the length of sequence number, which is
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   883
                        // used as the nonce_explicit for AEAD cipher suites.
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   884
        }
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   885
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   886
        return 0;
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   887
    }
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   888
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   889
    /*
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   890
     * Applies the explicit nonce/IV to this cipher. This method is used to
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   891
     * decrypt an SSL/TLS input record.
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   892
     *
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   893
     * The returned value is the SecurityParameters.record_iv_length in
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   894
     * RFC 4346/5246.  It is the size of explicit IV for CBC mode, and the
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   895
     * size of explicit nonce for AEAD mode.
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   896
     *
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   897
     * @param  authenticator the authenticator to get the additional
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   898
     *         authentication data
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   899
     * @param  contentType the content type of the input record
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   900
     * @param  bb the byte buffer to get the explicit nonce from
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   901
     *
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   902
     * @return the explicit nonce size of the cipher.
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   903
     */
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   904
    int applyExplicitNonce(Authenticator authenticator, byte contentType,
30904
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
   905
            ByteBuffer bb, byte[] sequence) throws BadPaddingException {
16913
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   906
        switch (cipherType) {
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   907
            case BLOCK_CIPHER:
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   908
                // sanity check length of the ciphertext
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   909
                int tagLen = (authenticator instanceof MAC) ?
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   910
                                    ((MAC)authenticator).MAClen() : 0;
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   911
                if (tagLen != 0) {
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   912
                    if (!sanityCheck(tagLen, bb.remaining())) {
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   913
                        throw new BadPaddingException(
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   914
                                "ciphertext sanity check failed");
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   915
                    }
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   916
                }
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   917
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   918
                // For block ciphers, the explicit IV length is of length
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   919
                // SecurityParameters.record_iv_length, which is equal to
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   920
                // the SecurityParameters.block_size.
30904
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
   921
                if (protocolVersion.useTLS11PlusSpec()) {
16913
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   922
                    return cipher.getBlockSize();
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   923
                }
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   924
                break;
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   925
            case AEAD_CIPHER:
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   926
                if (bb.remaining() < (recordIvSize + tagSize)) {
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   927
                    throw new BadPaddingException(
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   928
                                        "invalid AEAD cipher fragment");
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   929
                }
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   930
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   931
                // initialize the AEAD cipher for the unique IV
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   932
                byte[] iv = Arrays.copyOf(fixedIv,
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   933
                                    fixedIv.length + recordIvSize);
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   934
                bb.get(iv, fixedIv.length, recordIvSize);
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   935
                bb.position(bb.position() - recordIvSize);
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   936
                GCMParameterSpec spec = new GCMParameterSpec(tagSize * 8, iv);
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   937
                try {
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   938
                    cipher.init(mode, key, spec, random);
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   939
                } catch (InvalidKeyException |
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   940
                            InvalidAlgorithmParameterException ikae) {
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   941
                    // unlikely to happen
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   942
                    throw new RuntimeException(
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   943
                                "invalid key or spec in GCM mode", ikae);
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   944
                }
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   945
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   946
                // update the additional authentication data
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   947
                byte[] aad = authenticator.acquireAuthenticationBytes(
30904
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
   948
                        contentType, bb.remaining() - recordIvSize - tagSize,
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
   949
                        sequence);
16913
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   950
                cipher.updateAAD(aad);
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   951
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   952
                return recordIvSize;
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   953
                        // It is also the length of sequence number, which is
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   954
                        // used as the nonce_explicit for AEAD cipher suites.
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   955
        }
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   956
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   957
       return 0;
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   958
    }
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   959
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   960
    /*
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   961
     * Creates the explicit nonce/IV to this cipher. This method is used to
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   962
     * encrypt an SSL/TLS output record.
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   963
     *
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   964
     * The size of the returned array is the SecurityParameters.record_iv_length
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   965
     * in RFC 4346/5246.  It is the size of explicit IV for CBC mode, and the
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   966
     * size of explicit nonce for AEAD mode.
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   967
     *
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   968
     * @param  authenticator the authenticator to get the additional
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   969
     *         authentication data
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   970
     * @param  contentType the content type of the input record
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   971
     * @param  fragmentLength the fragment length of the output record, it is
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   972
     *         the TLSCompressed.length in RFC 4346/5246.
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   973
     *
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   974
     * @return the explicit nonce of the cipher.
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   975
     */
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   976
    byte[] createExplicitNonce(Authenticator authenticator,
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   977
            byte contentType, int fragmentLength) {
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   978
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   979
        byte[] nonce = new byte[0];
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   980
        switch (cipherType) {
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   981
            case BLOCK_CIPHER:
30904
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
   982
                if (protocolVersion.useTLS11PlusSpec()) {
16913
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   983
                    // For block ciphers, the explicit IV length is of length
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   984
                    // SecurityParameters.record_iv_length, which is equal to
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   985
                    // the SecurityParameters.block_size.
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   986
                    //
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   987
                    // Generate a random number as the explicit IV parameter.
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   988
                    nonce = new byte[cipher.getBlockSize()];
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   989
                    random.nextBytes(nonce);
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   990
                }
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   991
                break;
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   992
            case AEAD_CIPHER:
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   993
                // To be unique and aware of overflow-wrap, sequence number
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   994
                // is used as the nonce_explicit of AEAD cipher suites.
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   995
                nonce = authenticator.sequenceNumber();
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   996
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   997
                // initialize the AEAD cipher for the unique IV
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   998
                byte[] iv = Arrays.copyOf(fixedIv,
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
   999
                                            fixedIv.length + nonce.length);
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1000
                System.arraycopy(nonce, 0, iv, fixedIv.length, nonce.length);
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1001
                GCMParameterSpec spec = new GCMParameterSpec(tagSize * 8, iv);
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1002
                try {
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1003
                    cipher.init(mode, key, spec, random);
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1004
                } catch (InvalidKeyException |
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1005
                            InvalidAlgorithmParameterException ikae) {
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1006
                    // unlikely to happen
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1007
                    throw new RuntimeException(
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1008
                                "invalid key or spec in GCM mode", ikae);
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1009
                }
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1010
30904
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1011
                // Update the additional authentication data, using the
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1012
                // implicit sequence number of the authenticator.
16913
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1013
                byte[] aad = authenticator.acquireAuthenticationBytes(
30904
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1014
                                        contentType, fragmentLength, null);
16913
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1015
                cipher.updateAAD(aad);
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1016
                break;
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1017
        }
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1018
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1019
        return nonce;
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1020
    }
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1021
30904
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1022
    // See also CipherSuite.calculatePacketSize().
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1023
    int calculatePacketSize(int fragmentSize, int macLen, int headerSize) {
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1024
        int packetSize = fragmentSize;
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1025
        if (cipher != null) {
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1026
            int blockSize = cipher.getBlockSize();
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1027
            switch (cipherType) {
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1028
                case BLOCK_CIPHER:
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1029
                    packetSize += macLen;
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1030
                    packetSize += 1;        // 1 byte padding length field
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1031
                    packetSize +=           // use the minimal padding
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1032
                            (blockSize - (packetSize % blockSize)) % blockSize;
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1033
                    if (protocolVersion.useTLS11PlusSpec()) {
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1034
                        packetSize += blockSize;        // explicit IV
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1035
                    }
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1036
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1037
                    break;
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1038
                case AEAD_CIPHER:
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1039
                    packetSize += recordIvSize;
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1040
                    packetSize += tagSize;
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1041
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1042
                    break;
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1043
                default:    // NULL_CIPHER or STREAM_CIPHER
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1044
                    packetSize += macLen;
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1045
            }
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1046
        }
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1047
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1048
        return packetSize + headerSize;
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1049
    }
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1050
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1051
    // See also CipherSuite.calculateFragSize().
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1052
    int calculateFragmentSize(int packetLimit, int macLen, int headerSize) {
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1053
        int fragLen = packetLimit - headerSize;
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1054
        if (cipher != null) {
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1055
            int blockSize = cipher.getBlockSize();
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1056
            switch (cipherType) {
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1057
                case BLOCK_CIPHER:
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1058
                    if (protocolVersion.useTLS11PlusSpec()) {
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1059
                        fragLen -= blockSize;           // explicit IV
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1060
                    }
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1061
                    fragLen -= (fragLen % blockSize);   // cannot hold a block
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1062
                    // No padding for a maximum fragment.
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1063
                    fragLen -= 1;       // 1 byte padding length field: 0x00
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1064
                    fragLen -= macLen;
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1065
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1066
                    break;
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1067
                case AEAD_CIPHER:
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1068
                    fragLen -= recordIvSize;
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1069
                    fragLen -= tagSize;
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1070
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1071
                    break;
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1072
                default:    // NULL_CIPHER or STREAM_CIPHER
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1073
                    fragLen -= macLen;
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1074
            }
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1075
        }
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1076
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1077
        return fragLen;
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1078
    }
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1079
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1080
    // Estimate the maximum fragment size of a received packet.
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1081
    int estimateFragmentSize(int packetSize, int macLen, int headerSize) {
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1082
        int fragLen = packetSize - headerSize;
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1083
        if (cipher != null) {
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1084
            int blockSize = cipher.getBlockSize();
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1085
            switch (cipherType) {
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1086
                case BLOCK_CIPHER:
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1087
                    if (protocolVersion.useTLS11PlusSpec()) {
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1088
                        fragLen -= blockSize;       // explicit IV
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1089
                    }
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1090
                    // No padding for a maximum fragment.
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1091
                    fragLen -= 1;       // 1 byte padding length field: 0x00
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1092
                    fragLen -= macLen;
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1093
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1094
                    break;
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1095
                case AEAD_CIPHER:
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1096
                    fragLen -= recordIvSize;
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1097
                    fragLen -= tagSize;
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1098
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1099
                    break;
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1100
                default:    // NULL_CIPHER or STREAM_CIPHER
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1101
                    fragLen -= macLen;
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1102
            }
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1103
        }
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1104
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1105
        return fragLen;
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1106
    }
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1107
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1108
16913
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1109
    /*
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1110
     * Is this cipher available?
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1111
     *
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1112
     * This method can only be called by CipherSuite.BulkCipher.isAvailable()
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1113
     * to test the availability of a cipher suites.  Please DON'T use it in
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1114
     * other places, otherwise, the behavior may be unexpected because we may
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1115
     * initialize AEAD cipher improperly in the method.
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1116
     */
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1117
    Boolean isAvailable() {
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1118
        // We won't know whether a cipher for a particular key size is
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1119
        // available until the cipher is successfully initialized.
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1120
        //
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1121
        // We do not initialize AEAD cipher in the constructor.  Need to
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1122
        // initialize the cipher to ensure that the AEAD mode for a
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1123
        // particular key size is supported.
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1124
        if (cipherType == AEAD_CIPHER) {
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1125
            try {
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1126
                Authenticator authenticator =
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1127
                    new Authenticator(protocolVersion);
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1128
                byte[] nonce = authenticator.sequenceNumber();
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1129
                byte[] iv = Arrays.copyOf(fixedIv,
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1130
                                            fixedIv.length + nonce.length);
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1131
                System.arraycopy(nonce, 0, iv, fixedIv.length, nonce.length);
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1132
                GCMParameterSpec spec = new GCMParameterSpec(tagSize * 8, iv);
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1133
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1134
                cipher.init(mode, key, spec, random);
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1135
            } catch (Exception e) {
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1136
                return Boolean.FALSE;
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1137
            }
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1138
        }   // Otherwise, we have initialized the cipher in the constructor.
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1139
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1140
        return Boolean.TRUE;
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1141
    }
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1142
16113
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
  1143
    /**
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
  1144
     * Sanity check the length of a fragment before decryption.
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
  1145
     *
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
  1146
     * In CBC mode, check that the fragment length is one or multiple times
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
  1147
     * of the block size of the cipher suite, and is at least one (one is the
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
  1148
     * smallest size of padding in CBC mode) bigger than the tag size of the
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
  1149
     * MAC algorithm except the explicit IV size for TLS 1.1 or later.
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
  1150
     *
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
  1151
     * In non-CBC mode, check that the fragment length is not less than the
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
  1152
     * tag size of the MAC algorithm.
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
  1153
     *
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
  1154
     * @return true if the length of a fragment matches above requirements
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
  1155
     */
16913
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1156
    private boolean sanityCheck(int tagLen, int fragmentLen) {
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1157
        if (!isCBCMode()) {
16113
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
  1158
            return fragmentLen >= tagLen;
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
  1159
        }
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
  1160
16913
a6f4d1626ad9 8011680: Re-integrate AEAD implementation of JSSE
xuelei
parents: 16126
diff changeset
  1161
        int blockSize = cipher.getBlockSize();
16113
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
  1162
        if ((fragmentLen % blockSize) == 0) {
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
  1163
            int minimal = tagLen + 1;
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
  1164
            minimal = (minimal >= blockSize) ? minimal : blockSize;
30904
ec0224270f90 8043758: Datagram Transport Layer Security (DTLS)
xuelei
parents: 29488
diff changeset
  1165
            if (protocolVersion.useTLS11PlusSpec()) {
16113
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
  1166
                minimal += blockSize;   // plus the size of the explicit IV
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
  1167
            }
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
  1168
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
  1169
            return (fragmentLen >= minimal);
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
  1170
        }
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
  1171
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
  1172
        return false;
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
  1173
    }
946ec9b22004 8006777: Improve TLS handling of invalid messages
xuelei
parents: 14664
diff changeset
  1174
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1175
}