8009925: Back out AEAD CipherSuites temporarily
authorwetmore
Tue, 12 Mar 2013 15:31:49 -0700
changeset 16067 36055e4b5305
parent 16066 b9fb0d9c58ec
child 16068 b2b3f6569eae
child 16473 81d282e3cdaf
8009925: Back out AEAD CipherSuites temporarily Reviewed-by: valeriep
jdk/src/share/classes/com/sun/crypto/provider/TlsKeyMaterialGenerator.java
jdk/src/share/classes/sun/security/internal/spec/TlsKeyMaterialParameterSpec.java
jdk/src/share/classes/sun/security/internal/spec/TlsKeyMaterialSpec.java
jdk/src/share/classes/sun/security/pkcs11/P11TlsKeyMaterialGenerator.java
jdk/src/share/classes/sun/security/ssl/Authenticator.java
jdk/src/share/classes/sun/security/ssl/CipherBox.java
jdk/src/share/classes/sun/security/ssl/CipherSuite.java
jdk/src/share/classes/sun/security/ssl/EngineInputRecord.java
jdk/src/share/classes/sun/security/ssl/EngineOutputRecord.java
jdk/src/share/classes/sun/security/ssl/EngineWriter.java
jdk/src/share/classes/sun/security/ssl/Handshaker.java
jdk/src/share/classes/sun/security/ssl/InputRecord.java
jdk/src/share/classes/sun/security/ssl/JsseJce.java
jdk/src/share/classes/sun/security/ssl/MAC.java
jdk/src/share/classes/sun/security/ssl/OutputRecord.java
jdk/src/share/classes/sun/security/ssl/Record.java
jdk/src/share/classes/sun/security/ssl/SSLEngineImpl.java
jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java
jdk/test/sun/security/ec/TestEC.java
jdk/test/sun/security/pkcs11/fips/CipherTest.java
jdk/test/sun/security/pkcs11/sslecc/CipherTest.java
jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/SSLEngineBadBufferArrayAccess.java
jdk/test/sun/security/ssl/javax/net/ssl/TLSv12/ShortRSAKeyGCM.java
jdk/test/sun/security/ssl/sanity/ciphersuites/CipherSuitesInOrder.java
jdk/test/sun/security/ssl/sanity/interop/CipherTest.java
jdk/test/sun/security/ssl/templates/SSLSocketSSLEngineTemplate.java
--- a/jdk/src/share/classes/com/sun/crypto/provider/TlsKeyMaterialGenerator.java	Tue Mar 12 10:35:44 2013 -0400
+++ b/jdk/src/share/classes/com/sun/crypto/provider/TlsKeyMaterialGenerator.java	Tue Mar 12 15:31:49 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -165,18 +165,16 @@
         // partition keyblock into individual secrets
 
         int ofs = 0;
-        if (macLength != 0) {
-            byte[] tmp = new byte[macLength];
+        byte[] tmp = new byte[macLength];
 
-            // mac keys
-            System.arraycopy(keyBlock, ofs, tmp, 0, macLength);
-            ofs += macLength;
-            clientMacKey = new SecretKeySpec(tmp, "Mac");
+        // mac keys
+        System.arraycopy(keyBlock, ofs, tmp, 0, macLength);
+        ofs += macLength;
+        clientMacKey = new SecretKeySpec(tmp, "Mac");
 
-            System.arraycopy(keyBlock, ofs, tmp, 0, macLength);
-            ofs += macLength;
-            serverMacKey = new SecretKeySpec(tmp, "Mac");
-        }
+        System.arraycopy(keyBlock, ofs, tmp, 0, macLength);
+        ofs += macLength;
+        serverMacKey = new SecretKeySpec(tmp, "Mac");
 
         if (keyLength == 0) { // SSL_RSA_WITH_NULL_* ciphersuites
             return new TlsKeyMaterialSpec(clientMacKey, serverMacKey);
@@ -200,7 +198,7 @@
 
             // IV keys if needed.
             if (ivLength != 0) {
-                byte[] tmp = new byte[ivLength];
+                tmp = new byte[ivLength];
 
                 System.arraycopy(keyBlock, ofs, tmp, 0, ivLength);
                 ofs += ivLength;
@@ -222,8 +220,8 @@
                 // TLS 1.0
                 byte[] seed = concat(clientRandom, serverRandom);
 
-                byte[] tmp = doTLS10PRF(clientKeyBytes,
-                    LABEL_CLIENT_WRITE_KEY, seed, expandedKeyLength, md5, sha);
+                tmp = doTLS10PRF(clientKeyBytes, LABEL_CLIENT_WRITE_KEY, seed,
+                            expandedKeyLength, md5, sha);
                 clientCipherKey = new SecretKeySpec(tmp, alg);
 
                 tmp = doTLS10PRF(serverKeyBytes, LABEL_SERVER_WRITE_KEY, seed,
@@ -241,7 +239,7 @@
                 }
             } else {
                 // SSLv3
-                byte[] tmp = new byte[expandedKeyLength];
+                tmp = new byte[expandedKeyLength];
 
                 md5.update(clientKeyBytes);
                 md5.update(clientRandom);
--- a/jdk/src/share/classes/sun/security/internal/spec/TlsKeyMaterialParameterSpec.java	Tue Mar 12 10:35:44 2013 -0400
+++ b/jdk/src/share/classes/sun/security/internal/spec/TlsKeyMaterialParameterSpec.java	Tue Mar 12 15:31:49 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -212,6 +212,12 @@
      *     generated.
      */
     public int getIvLength() {
+        // TLS v1.1 or later uses an explicit IV to protect against
+        // the CBC attacks.
+        if (majorVersion >= 0x03 && minorVersion >= 0x02) {
+            return 0;
+        }
+
         return ivLength;
     }
 
--- a/jdk/src/share/classes/sun/security/internal/spec/TlsKeyMaterialSpec.java	Tue Mar 12 10:35:44 2013 -0400
+++ b/jdk/src/share/classes/sun/security/internal/spec/TlsKeyMaterialSpec.java	Tue Mar 12 15:31:49 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -58,8 +58,9 @@
      * <code>new TlsKeymaterialSpec(clientMacKey, serverMacKey,
      * null, null, null, null)</code>.
      *
-     * @param clientMacKey the client MAC key (or null)
-     * @param serverMacKey the server MAC key (or null)
+     * @param clientMacKey the client MAC key
+     * @param serverMacKey the server MAC key
+     * @throws NullPointerException if clientMacKey or serverMacKey is null
      */
     public TlsKeyMaterialSpec(SecretKey clientMacKey, SecretKey serverMacKey) {
         this(clientMacKey, serverMacKey, null, null, null, null);
@@ -72,10 +73,11 @@
      * <code>new TlsKeymaterialSpec(clientMacKey, serverMacKey,
      * clientCipherKey, serverCipherKey, null, null)</code>.
      *
-     * @param clientMacKey the client MAC key (or null)
-     * @param serverMacKey the server MAC key (or null)
+     * @param clientMacKey the client MAC key
+     * @param serverMacKey the server MAC key
      * @param clientCipherKey the client cipher key (or null)
      * @param serverCipherKey the server cipher key (or null)
+     * @throws NullPointerException if clientMacKey or serverMacKey is null
      */
     public TlsKeyMaterialSpec(SecretKey clientMacKey, SecretKey serverMacKey,
             SecretKey clientCipherKey, SecretKey serverCipherKey) {
@@ -88,17 +90,21 @@
      * keys, client and server cipher keys, and client and server
      * initialization vectors.
      *
-     * @param clientMacKey the client MAC key (or null)
-     * @param serverMacKey the server MAC key (or null)
+     * @param clientMacKey the client MAC key
+     * @param serverMacKey the server MAC key
      * @param clientCipherKey the client cipher key (or null)
      * @param clientIv the client initialization vector (or null)
      * @param serverCipherKey the server cipher key (or null)
      * @param serverIv the server initialization vector (or null)
+     *
+     * @throws NullPointerException if clientMacKey or serverMacKey is null
      */
     public TlsKeyMaterialSpec(SecretKey clientMacKey, SecretKey serverMacKey,
             SecretKey clientCipherKey, IvParameterSpec clientIv,
             SecretKey serverCipherKey, IvParameterSpec serverIv) {
-
+        if ((clientMacKey == null) || (serverMacKey == null)) {
+            throw new NullPointerException("MAC keys must not be null");
+        }
         this.clientMacKey = clientMacKey;
         this.serverMacKey = serverMacKey;
         this.clientCipherKey = clientCipherKey;
@@ -137,7 +143,7 @@
     /**
      * Returns the client MAC key.
      *
-     * @return the client MAC key (or null).
+     * @return the client MAC key.
      */
     public SecretKey getClientMacKey() {
         return clientMacKey;
@@ -146,7 +152,7 @@
     /**
      * Return the server MAC key.
      *
-     * @return the server MAC key (or null).
+     * @return the server MAC key.
      */
     public SecretKey getServerMacKey() {
         return serverMacKey;
--- a/jdk/src/share/classes/sun/security/pkcs11/P11TlsKeyMaterialGenerator.java	Tue Mar 12 10:35:44 2013 -0400
+++ b/jdk/src/share/classes/sun/security/pkcs11/P11TlsKeyMaterialGenerator.java	Tue Mar 12 15:31:49 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2007, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -168,22 +168,10 @@
             // Note that the MAC keys do not inherit all attributes from the
             // template, but they do inherit the sensitive/extractable/token
             // flags, which is all P11Key cares about.
-            SecretKey clientMacKey, serverMacKey;
-
-            // The MAC size may be zero for GCM mode.
-            //
-            // PKCS11 does not support GCM mode as the author made the comment,
-            // so the macBits is unlikely to be zero. It's only a place holder.
-            if (macBits != 0) {
-                clientMacKey = P11Key.secretKey
+            SecretKey clientMacKey = P11Key.secretKey
                     (session, out.hClientMacSecret, "MAC", macBits, attributes);
-                serverMacKey = P11Key.secretKey
+            SecretKey serverMacKey = P11Key.secretKey
                     (session, out.hServerMacSecret, "MAC", macBits, attributes);
-            } else {
-                clientMacKey = null;
-                serverMacKey = null;
-            }
-
             SecretKey clientCipherKey, serverCipherKey;
             if (keyBits != 0) {
                 clientCipherKey = P11Key.secretKey(session, out.hClientKey,
--- a/jdk/src/share/classes/sun/security/ssl/Authenticator.java	Tue Mar 12 10:35:44 2013 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,161 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.ssl;
-
-import java.util.Arrays;
-
-/**
- * This class represents an SSL/TLS message authentication token,
- * which encapsulates a sequence number and ensures that attempts to
- * delete or reorder messages can be detected.
- *
- * Each SSL/TLS connection state contains a sequence number, which
- * is maintained separately for read and write states.  The sequence
- * number MUST be set to zero whenever a connection state is made the
- * active state.  Sequence numbers are of type uint64 and may not
- * exceed 2^64-1.  Sequence numbers do not wrap.  If a SSL/TLS
- * implementation would need to wrap a sequence number, it must
- * renegotiate instead.  A sequence number is incremented after each
- * record: specifically, the first record transmitted under a
- * particular connection state MUST use sequence number 0.
- */
-class Authenticator {
-
-    // byte array containing the additional authentication information for
-    // each record
-    private final byte[] block;
-
-    // the block size of SSL v3.0:
-    // sequence number + record type + + record length
-    private static final int BLOCK_SIZE_SSL = 8 + 1 + 2;
-
-    // the block size of TLS v1.0 and later:
-    // sequence number + record type + protocol version + record length
-    private static final int BLOCK_SIZE_TLS = 8 + 1 + 2 + 2;
-
-    /**
-     * Default construct, no message authentication token is initialized.
-     *
-     * Note that this construct can only be called for null MAC
-     */
-    Authenticator() {
-        block = new byte[0];
-    }
-
-    /**
-     * Constructs the message authentication token for the specified
-     * SSL/TLS protocol.
-     */
-    Authenticator(ProtocolVersion protocolVersion) {
-        if (protocolVersion.v >= ProtocolVersion.TLS10.v) {
-            block = new byte[BLOCK_SIZE_TLS];
-            block[9] = protocolVersion.major;
-            block[10] = protocolVersion.minor;
-        } else {
-            block = new byte[BLOCK_SIZE_SSL];
-        }
-    }
-
-    /**
-     * Checks whether the sequence number is close to wrap.
-     *
-     * Sequence numbers are of type uint64 and may not exceed 2^64-1.
-     * Sequence numbers do not wrap. When the sequence number is near
-     * to wrap, we need to close the connection immediately.
-     *
-     * @return true if the sequence number is close to wrap
-     */
-    final boolean seqNumOverflow() {
-        /*
-         * Conservatively, we don't allow more records to be generated
-         * when there are only 2^8 sequence numbers left.
-         */
-        return (block.length != 0 &&
-                block[0] == (byte)0xFF && block[1] == (byte)0xFF &&
-                block[2] == (byte)0xFF && block[3] == (byte)0xFF &&
-                block[4] == (byte)0xFF && block[5] == (byte)0xFF &&
-                block[6] == (byte)0xFF);
-    }
-
-    /**
-     * Checks whether the sequence number close to renew.
-     *
-     * Sequence numbers are of type uint64 and may not exceed 2^64-1.
-     * Sequence numbers do not wrap.  If a TLS
-     * implementation would need to wrap a sequence number, it must
-     * renegotiate instead.
-     *
-     * @return true if the sequence number is huge enough to renew
-     */
-    final boolean seqNumIsHuge() {
-        /*
-         * Conservatively, we should ask for renegotiation when there are
-         * only 2^48 sequence numbers left.
-         */
-        return (block.length != 0 &&
-                block[0] == (byte)0xFF && block[1] == (byte)0xFF);
-    }
-
-    /**
-     * Gets the current sequence number.
-     *
-     * @return the byte array of the current sequence number
-     */
-    final byte[] sequenceNumber() {
-        return Arrays.copyOf(block, 8);
-    }
-
-    /**
-     * Acquires the current message authentication information with the
-     * specified record type and fragment length, and then increases the
-     * sequence number.
-     *
-     * @param  type the record type
-     * @param  length the fragment of the record
-     * @return the byte array of the current message authentication information
-     */
-    final byte[] acquireAuthenticationBytes(byte type, int length) {
-        byte[] copy = block.clone();
-
-        if (block.length != 0) {
-            copy[8] = type;
-            copy[copy.length - 2] = (byte)(length >> 8);
-            copy[copy.length - 1] = (byte)(length);
-
-            /*
-             * Increase the sequence number in the block array
-             * it is a 64-bit number stored in big-endian format
-             */
-            int k = 7;
-            while ((k >= 0) && (++block[k] == 0)) {
-                k--;
-            }
-        }
-
-        return copy;
-    }
-
-}
--- a/jdk/src/share/classes/sun/security/ssl/CipherBox.java	Tue Mar 12 10:35:44 2013 -0400
+++ b/jdk/src/share/classes/sun/security/ssl/CipherBox.java	Tue Mar 12 15:31:49 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,18 +29,15 @@
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.util.Hashtable;
-import java.util.Arrays;
 
 import java.security.*;
 import javax.crypto.*;
 import javax.crypto.spec.IvParameterSpec;
-import javax.crypto.spec.GCMParameterSpec;
 
 import java.nio.*;
 
 import sun.security.ssl.CipherSuite.*;
 import static sun.security.ssl.CipherSuite.*;
-import static sun.security.ssl.CipherSuite.CipherType.*;
 
 import sun.misc.HexDumpEncoder;
 
@@ -105,40 +102,19 @@
     private final Cipher cipher;
 
     /**
+     * Cipher blocksize, 0 for stream ciphers
+     */
+    private int blockSize;
+
+    /**
      * secure random
      */
     private SecureRandom random;
 
     /**
-     * fixed IV, the implicit nonce of AEAD cipher suite, only apply to
-     * AEAD cipher suites
-     */
-    private final byte[] fixedIv;
-
-    /**
-     * the key, reserved only for AEAD cipher initialization
-     */
-    private final Key key;
-
-    /**
-     * the operation mode, reserved for AEAD cipher initialization
+     * Is the cipher of CBC mode?
      */
-    private final int mode;
-
-    /**
-     * the authentication tag size, only apply to AEAD cipher suites
-     */
-    private final int tagSize;
-
-    /**
-     * the record IV length, only apply to AEAD cipher suites
-     */
-    private final int recordIvSize;
-
-    /**
-     * cipher type
-     */
-    private final CipherType cipherType;
+    private final boolean isCBCMode;
 
     /**
      * Fixed masks of various block size, as the initial decryption IVs
@@ -156,13 +132,7 @@
     private CipherBox() {
         this.protocolVersion = ProtocolVersion.DEFAULT;
         this.cipher = null;
-        this.cipherType = STREAM_CIPHER;
-        this.fixedIv = new byte[0];
-        this.key = null;
-        this.mode = Cipher.ENCRYPT_MODE;    // choose at random
-        this.random = null;
-        this.tagSize = 0;
-        this.recordIvSize = 0;
+        this.isCBCMode = false;
     }
 
     /**
@@ -177,13 +147,13 @@
         try {
             this.protocolVersion = protocolVersion;
             this.cipher = JsseJce.getCipher(bulkCipher.transformation);
-            this.mode = encrypt ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE;
+            int mode = encrypt ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE;
 
             if (random == null) {
                 random = JsseJce.getSecureRandom();
             }
             this.random = random;
-            this.cipherType = bulkCipher.cipherType;
+            this.isCBCMode = bulkCipher.isCBCMode;
 
             /*
              * RFC 4346 recommends two algorithms used to generated the
@@ -201,40 +171,14 @@
                 iv = getFixedMask(bulkCipher.ivSize);
             }
 
-            if (cipherType == AEAD_CIPHER) {
-                // AEAD must completely initialize the cipher for each packet,
-                // and so we save initialization parameters for packet
-                // processing time.
-
-                // Set the tag size for AEAD cipher
-                tagSize = bulkCipher.tagSize;
-
-                // Reserve the key for AEAD cipher initialization
-                this.key = key;
-
-                fixedIv = iv.getIV();
-                if (fixedIv == null ||
-                        fixedIv.length != bulkCipher.fixedIvSize) {
-                    throw new RuntimeException("Improper fixed IV for AEAD");
-                }
+            cipher.init(mode, key, iv, random);
 
-                // Set the record IV length for AEAD cipher
-                recordIvSize = bulkCipher.ivSize - bulkCipher.fixedIvSize;
-
-                // DON'T initialize the cipher for AEAD!
-            } else {
-                // CBC only requires one initialization during its lifetime
-                // (future packets/IVs set the proper CBC state), so we can
-                // initialize now.
-
-                // Zeroize the variables that only apply to AEAD cipher
-                this.tagSize = 0;
-                this.fixedIv = new byte[0];
-                this.recordIvSize = 0;
-                this.key = null;
-
-                // Initialize the cipher
-                cipher.init(mode, key, iv, random);
+            // Do not call getBlockSize until after init()
+            // otherwise we would disrupt JCE delayed provider selection
+            blockSize = cipher.getBlockSize();
+            // some providers implement getBlockSize() incorrectly
+            if (blockSize == 1) {
+                blockSize = 0;
             }
         } catch (NoSuchAlgorithmException e) {
             throw e;
@@ -291,11 +235,26 @@
         }
 
         try {
-            int blockSize = cipher.getBlockSize();
-            if (cipherType == BLOCK_CIPHER) {
+            if (blockSize != 0) {
+                // TLSv1.1 needs a IV block
+                if (protocolVersion.v >= ProtocolVersion.TLS11.v) {
+                    // generate a random number
+                    byte[] prefix = new byte[blockSize];
+                    random.nextBytes(prefix);
+
+                    // move forward the plaintext
+                    System.arraycopy(buf, offset,
+                                     buf, offset + prefix.length, len);
+
+                    // prefix the plaintext
+                    System.arraycopy(prefix, 0,
+                                     buf, offset, prefix.length);
+
+                    len += prefix.length;
+                }
+
                 len = addPadding(buf, offset, len, blockSize);
             }
-
             if (debug != null && Debug.isOn("plaintext")) {
                 try {
                     HexDumpEncoder hd = new HexDumpEncoder();
@@ -308,28 +267,14 @@
                         System.out);
                 } catch (IOException e) { }
             }
-
-
-            if (cipherType == AEAD_CIPHER) {
-                try {
-                    return cipher.doFinal(buf, offset, len, buf, offset);
-                } catch (IllegalBlockSizeException | BadPaddingException ibe) {
-                    // unlikely to happen
-                    throw new RuntimeException(
-                        "Cipher error in AEAD mode in JCE provider " +
-                        cipher.getProvider().getName(), ibe);
-                }
-            } else {
-                int newLen = cipher.update(buf, offset, len, buf, offset);
-                if (newLen != len) {
-                    // catch BouncyCastle buffering error
-                    throw new RuntimeException("Cipher buffering error " +
-                        "in JCE provider " + cipher.getProvider().getName());
-                }
-                return newLen;
+            int newLen = cipher.update(buf, offset, len, buf, offset);
+            if (newLen != len) {
+                // catch BouncyCastle buffering error
+                throw new RuntimeException("Cipher buffering error " +
+                    "in JCE provider " + cipher.getProvider().getName());
             }
+            return newLen;
         } catch (ShortBufferException e) {
-            // unlikely to happen, we should have enough buffer space here
             throw new ArrayIndexOutOfBoundsException(e.toString());
         }
     }
@@ -343,7 +288,7 @@
      * set to last position padded/encrypted.  The limit may have changed
      * because of the added padding bytes.
      */
-    int encrypt(ByteBuffer bb, int outLimit) {
+    int encrypt(ByteBuffer bb) {
 
         int len = bb.remaining();
 
@@ -352,71 +297,66 @@
             return len;
         }
 
-        int pos = bb.position();
+        try {
+            int pos = bb.position();
 
-        int blockSize = cipher.getBlockSize();
-        if (cipherType == BLOCK_CIPHER) {
-            // addPadding adjusts pos/limit
-            len = addPadding(bb, blockSize);
-            bb.position(pos);
-        }
+            if (blockSize != 0) {
+                // TLSv1.1 needs a IV block
+                if (protocolVersion.v >= ProtocolVersion.TLS11.v) {
+                    // generate a random number
+                    byte[] prefix = new byte[blockSize];
+                    random.nextBytes(prefix);
 
-        if (debug != null && Debug.isOn("plaintext")) {
-            try {
-                HexDumpEncoder hd = new HexDumpEncoder();
-
-                System.out.println(
-                    "Padded plaintext before ENCRYPTION:  len = "
-                    + len);
-                hd.encodeBuffer(bb.duplicate(), System.out);
-
-            } catch (IOException e) { }
-        }
+                    // move forward the plaintext
+                    byte[] buf = null;
+                    int limit = bb.limit();
+                    if (bb.hasArray()) {
+                        int arrayOffset = bb.arrayOffset();
+                        buf = bb.array();
+                        System.arraycopy(buf, arrayOffset + pos,
+                            buf, arrayOffset + pos + prefix.length,
+                            limit - pos);
+                        bb.limit(limit + prefix.length);
+                    } else {
+                        buf = new byte[limit - pos];
+                        bb.get(buf, 0, limit - pos);
+                        bb.position(pos + prefix.length);
+                        bb.limit(limit + prefix.length);
+                        bb.put(buf);
+                    }
+                    bb.position(pos);
 
-        /*
-         * Encrypt "in-place".  This does not add its own padding.
-         */
-        ByteBuffer dup = bb.duplicate();
-        if (cipherType == AEAD_CIPHER) {
-            try {
-                int outputSize = cipher.getOutputSize(dup.remaining());
-                if (outputSize > bb.remaining()) {
-                    // need to expand the limit of the output buffer for
-                    // the authentication tag.
-                    //
-                    // DON'T worry about the buffer's capacity, we have
-                    // reserved space for the authentication tag.
-                    if (outLimit < pos + outputSize) {
-                        // unlikely to happen
-                        throw new ShortBufferException(
-                                    "need more space in output buffer");
-                    }
-                    bb.limit(pos + outputSize);
+                    // prefix the plaintext
+                    bb.put(prefix);
+                    bb.position(pos);
                 }
-                int newLen = cipher.doFinal(dup, bb);
-                if (newLen != outputSize) {
-                    throw new RuntimeException(
-                            "Cipher buffering error in JCE provider " +
-                            cipher.getProvider().getName());
-                }
-                return newLen;
-            } catch (IllegalBlockSizeException |
-                           BadPaddingException | ShortBufferException ibse) {
-                // unlikely to happen
-                throw new RuntimeException(
-                        "Cipher error in AEAD mode in JCE provider " +
-                        cipher.getProvider().getName(), ibse);
+
+                // addPadding adjusts pos/limit
+                len = addPadding(bb, blockSize);
+                bb.position(pos);
             }
-        } else {
-            int newLen;
-            try {
-                newLen = cipher.update(dup, bb);
-            } catch (ShortBufferException sbe) {
-                // unlikely to happen
-                throw new RuntimeException("Cipher buffering error " +
-                    "in JCE provider " + cipher.getProvider().getName());
+            if (debug != null && Debug.isOn("plaintext")) {
+                try {
+                    HexDumpEncoder hd = new HexDumpEncoder();
+
+                    System.out.println(
+                        "Padded plaintext before ENCRYPTION:  len = "
+                        + len);
+                    hd.encodeBuffer(bb, System.out);
+
+                } catch (IOException e) { }
+                /*
+                 * reset back to beginning
+                 */
+                bb.position(pos);
             }
 
+            /*
+             * Encrypt "in-place".  This does not add its own padding.
+             */
+            ByteBuffer dup = bb.duplicate();
+            int newLen = cipher.update(dup, bb);
+
             if (bb.position() != dup.position()) {
                 throw new RuntimeException("bytebuffer padding error");
             }
@@ -427,6 +367,10 @@
                     "in JCE provider " + cipher.getProvider().getName());
             }
             return newLen;
+        } catch (ShortBufferException e) {
+            RuntimeException exc = new RuntimeException(e.toString());
+            exc.initCause(e);
+            throw exc;
         }
     }
 
@@ -454,23 +398,11 @@
         }
 
         try {
-            int newLen;
-            if (cipherType == AEAD_CIPHER) {
-                try {
-                    newLen = cipher.doFinal(buf, offset, len, buf, offset);
-                } catch (IllegalBlockSizeException ibse) {
-                    // unlikely to happen
-                    throw new RuntimeException(
-                        "Cipher error in AEAD mode in JCE provider " +
-                        cipher.getProvider().getName(), ibse);
-                }
-            } else {
-                newLen = cipher.update(buf, offset, len, buf, offset);
-                if (newLen != len) {
-                    // catch BouncyCastle buffering error
-                    throw new RuntimeException("Cipher buffering error " +
-                        "in JCE provider " + cipher.getProvider().getName());
-                }
+            int newLen = cipher.update(buf, offset, len, buf, offset);
+            if (newLen != len) {
+                // catch BouncyCastle buffering error
+                throw new RuntimeException("Cipher buffering error " +
+                    "in JCE provider " + cipher.getProvider().getName());
             }
             if (debug != null && Debug.isOn("plaintext")) {
                 try {
@@ -484,9 +416,7 @@
                         System.out);
                 } catch (IOException e) { }
             }
-
-            if (cipherType == BLOCK_CIPHER) {
-                int blockSize = cipher.getBlockSize();
+            if (blockSize != 0) {
                 newLen = removePadding(buf, offset, newLen,
                              blockSize, protocolVersion);
 
@@ -494,11 +424,16 @@
                     if (newLen < blockSize) {
                         throw new BadPaddingException("invalid explicit IV");
                     }
+
+                    // discards the first cipher block, the IV component.
+                    System.arraycopy(buf, offset + blockSize,
+                                     buf, offset, newLen - blockSize);
+
+                    newLen -= blockSize;
                 }
             }
             return newLen;
         } catch (ShortBufferException e) {
-            // unlikely to happen, we should have enough buffer space here
             throw new ArrayIndexOutOfBoundsException(e.toString());
         }
     }
@@ -528,29 +463,15 @@
              */
             int pos = bb.position();
             ByteBuffer dup = bb.duplicate();
-            int newLen;
-            if (cipherType == AEAD_CIPHER) {
-                try {
-                    newLen = cipher.doFinal(dup, bb);
-                } catch (IllegalBlockSizeException ibse) {
-                    // unlikely to happen
-                    throw new RuntimeException(
-                        "Cipher error in AEAD mode \"" + ibse.getMessage() +
-                        " \"in JCE provider " + cipher.getProvider().getName());
-                }
-            } else {
-                newLen = cipher.update(dup, bb);
-                if (newLen != len) {
-                    // catch BouncyCastle buffering error
-                    throw new RuntimeException("Cipher buffering error " +
-                        "in JCE provider " + cipher.getProvider().getName());
-                }
+            int newLen = cipher.update(dup, bb);
+            if (newLen != len) {
+                // catch BouncyCastle buffering error
+                throw new RuntimeException("Cipher buffering error " +
+                    "in JCE provider " + cipher.getProvider().getName());
             }
 
-            // reset the limit to the end of the decryted data
-            bb.limit(pos + newLen);
-
             if (debug != null && Debug.isOn("plaintext")) {
+                bb.position(pos);
                 try {
                     HexDumpEncoder hd = new HexDumpEncoder();
 
@@ -558,33 +479,50 @@
                         "Padded plaintext after DECRYPTION:  len = "
                         + newLen);
 
-                    hd.encodeBuffer(
-                        (ByteBuffer)bb.duplicate().position(pos), System.out);
+                    hd.encodeBuffer(bb, System.out);
                 } catch (IOException e) { }
             }
 
             /*
              * Remove the block padding.
              */
-            if (cipherType == BLOCK_CIPHER) {
-                int blockSize = cipher.getBlockSize();
+            if (blockSize != 0) {
                 bb.position(pos);
                 newLen = removePadding(bb, blockSize, protocolVersion);
 
-                // check the explicit IV of TLS v1.1 or later
                 if (protocolVersion.v >= ProtocolVersion.TLS11.v) {
                     if (newLen < blockSize) {
                         throw new BadPaddingException("invalid explicit IV");
                     }
 
+                    // discards the first cipher block, the IV component.
+                    byte[] buf = null;
+                    int limit = bb.limit();
+                    if (bb.hasArray()) {
+                        int arrayOffset = bb.arrayOffset();
+                        buf = bb.array();
+                        System.arraycopy(buf, arrayOffset + pos + blockSize,
+                            buf, arrayOffset + pos, limit - pos - blockSize);
+                        bb.limit(limit - blockSize);
+                    } else {
+                        buf = new byte[limit - pos - blockSize];
+                        bb.position(pos + blockSize);
+                        bb.get(buf);
+                        bb.position(pos);
+                        bb.put(buf);
+                        bb.limit(limit - blockSize);
+                    }
+
                     // reset the position to the end of the decrypted data
-                    bb.position(bb.limit());
+                    limit = bb.limit();
+                    bb.position(limit);
                 }
             }
             return newLen;
         } catch (ShortBufferException e) {
-            // unlikely to happen, we should have enough buffer space here
-            throw new ArrayIndexOutOfBoundsException(e.toString());
+            RuntimeException exc = new RuntimeException(e.toString());
+            exc.initCause(e);
+            throw exc;
         }
     }
 
@@ -757,8 +695,8 @@
                 // ignore return value.
                 cipher.doFinal();
             }
-        } catch (Exception e) {
-            // swallow all types of exceptions.
+        } catch (GeneralSecurityException e) {
+            // swallow for now.
         }
     }
 
@@ -768,234 +706,6 @@
      * @return true if the cipher use CBC mode, false otherwise.
      */
     boolean isCBCMode() {
-        return cipherType == BLOCK_CIPHER;
-    }
-
-    /*
-     * Does the cipher use AEAD mode?
-     *
-     * @return true if the cipher use AEAD mode, false otherwise.
-     */
-    boolean isAEADMode() {
-        return cipherType == AEAD_CIPHER;
-    }
-
-    /*
-     * Is the cipher null?
-     *
-     * @return true if the cipher is null, false otherwise.
-     */
-    boolean isNullCipher() {
-        return cipher == null;
-    }
-
-    /*
-     * Gets the explicit nonce/IV size of the cipher.
-     *
-     * The returned value is the SecurityParameters.record_iv_length in
-     * RFC 4346/5246.  It is the size of explicit IV for CBC mode, and the
-     * size of explicit nonce for AEAD mode.
-     *
-     * @return the explicit nonce size of the cipher.
-     */
-    int getExplicitNonceSize() {
-        switch (cipherType) {
-            case BLOCK_CIPHER:
-                // For block ciphers, the explicit IV length is of length
-                // SecurityParameters.record_iv_length, which is equal to
-                // the SecurityParameters.block_size.
-                if (protocolVersion.v >= ProtocolVersion.TLS11.v) {
-                    return cipher.getBlockSize();
-                }
-                break;
-            case AEAD_CIPHER:
-                return recordIvSize;
-                        // It is also the length of sequence number, which is
-                        // used as the nonce_explicit for AEAD cipher suites.
-        }
-
-        return 0;
-    }
-
-    /*
-     * Applies the explicit nonce/IV to this cipher. This method is used to
-     * decrypt an SSL/TLS input record.
-     *
-     * The returned value is the SecurityParameters.record_iv_length in
-     * RFC 4346/5246.  It is the size of explicit IV for CBC mode, and the
-     * size of explicit nonce for AEAD mode.
-     *
-     * @param  authenticator the authenticator to get the additional
-     *         authentication data
-     * @param  contentType the content type of the input record
-     * @param  bb the byte buffer to get the explicit nonce from
-     *
-     * @return the explicit nonce size of the cipher.
-     */
-    int applyExplicitNonce(Authenticator authenticator, byte contentType,
-            ByteBuffer bb) throws BadPaddingException {
-        switch (cipherType) {
-            case BLOCK_CIPHER:
-                // For block ciphers, the explicit IV length is of length
-                // SecurityParameters.record_iv_length, which is equal to
-                // the SecurityParameters.block_size.
-                if (protocolVersion.v >= ProtocolVersion.TLS11.v) {
-                    return cipher.getBlockSize();
-                }
-                break;
-            case AEAD_CIPHER:
-                if (bb.remaining() < (recordIvSize + tagSize)) {
-                    throw new BadPaddingException(
-                                        "invalid AEAD cipher fragment");
-                }
-
-                // initialize the AEAD cipher for the unique IV
-                byte[] iv = Arrays.copyOf(fixedIv,
-                                    fixedIv.length + recordIvSize);
-                bb.get(iv, fixedIv.length, recordIvSize);
-                bb.position(bb.position() - recordIvSize);
-                GCMParameterSpec spec = new GCMParameterSpec(tagSize * 8, iv);
-                try {
-                    cipher.init(mode, key, spec, random);
-                } catch (InvalidKeyException |
-                            InvalidAlgorithmParameterException ikae) {
-                    // unlikely to happen
-                    throw new RuntimeException(
-                                "invalid key or spec in GCM mode", ikae);
-                }
-
-                // update the additional authentication data
-                byte[] aad = authenticator.acquireAuthenticationBytes(
-                        contentType, bb.remaining() - recordIvSize - tagSize);
-                cipher.updateAAD(aad);
-
-                return recordIvSize;
-                        // It is also the length of sequence number, which is
-                        // used as the nonce_explicit for AEAD cipher suites.
-        }
-
-       return 0;
-    }
-
-    /*
-     * Applies the explicit nonce/IV to this cipher. This method is used to
-     * decrypt an SSL/TLS input record.
-     *
-     * The returned value is the SecurityParameters.record_iv_length in
-     * RFC 4346/5246.  It is the size of explicit IV for CBC mode, and the
-     * size of explicit nonce for AEAD mode.
-     *
-     * @param  authenticator the authenticator to get the additional
-     *         authentication data
-     * @param  contentType the content type of the input record
-     * @param  buf the byte array to get the explicit nonce from
-     * @param  offset the offset of the byte buffer
-     * @param  cipheredLength the ciphered fragment length of the output
-     *         record, it is the TLSCiphertext.length in RFC 4346/5246.
-     *
-     * @return the explicit nonce size of the cipher.
-     */
-    int applyExplicitNonce(Authenticator authenticator,
-            byte contentType, byte[] buf, int offset,
-            int cipheredLength) throws BadPaddingException {
-
-        ByteBuffer bb = ByteBuffer.wrap(buf, offset, cipheredLength);
-
-        return applyExplicitNonce(authenticator, contentType, bb);
-    }
-
-    /*
-     * Creates the explicit nonce/IV to this cipher. This method is used to
-     * encrypt an SSL/TLS output record.
-     *
-     * The size of the returned array is the SecurityParameters.record_iv_length
-     * in RFC 4346/5246.  It is the size of explicit IV for CBC mode, and the
-     * size of explicit nonce for AEAD mode.
-     *
-     * @param  authenticator the authenticator to get the additional
-     *         authentication data
-     * @param  contentType the content type of the input record
-     * @param  fragmentLength the fragment length of the output record, it is
-     *         the TLSCompressed.length in RFC 4346/5246.
-     *
-     * @return the explicit nonce of the cipher.
-     */
-    byte[] createExplicitNonce(Authenticator authenticator,
-            byte contentType, int fragmentLength) {
-
-        byte[] nonce = new byte[0];
-        switch (cipherType) {
-            case BLOCK_CIPHER:
-                if (protocolVersion.v >= ProtocolVersion.TLS11.v) {
-                    // For block ciphers, the explicit IV length is of length
-                    // SecurityParameters.record_iv_length, which is equal to
-                    // the SecurityParameters.block_size.
-                    //
-                    // Generate a random number as the explicit IV parameter.
-                    nonce = new byte[cipher.getBlockSize()];
-                    random.nextBytes(nonce);
-                }
-                break;
-            case AEAD_CIPHER:
-                // To be unique and aware of overflow-wrap, sequence number
-                // is used as the nonce_explicit of AEAD cipher suites.
-                nonce = authenticator.sequenceNumber();
-
-                // initialize the AEAD cipher for the unique IV
-                byte[] iv = Arrays.copyOf(fixedIv,
-                                            fixedIv.length + nonce.length);
-                System.arraycopy(nonce, 0, iv, fixedIv.length, nonce.length);
-                GCMParameterSpec spec = new GCMParameterSpec(tagSize * 8, iv);
-                try {
-                    cipher.init(mode, key, spec, random);
-                } catch (InvalidKeyException |
-                            InvalidAlgorithmParameterException ikae) {
-                    // unlikely to happen
-                    throw new RuntimeException(
-                                "invalid key or spec in GCM mode", ikae);
-                }
-
-                // update the additional authentication data
-                byte[] aad = authenticator.acquireAuthenticationBytes(
-                                                contentType, fragmentLength);
-                cipher.updateAAD(aad);
-                break;
-        }
-
-        return nonce;
-    }
-
-    /*
-     * Is this cipher available?
-     *
-     * This method can only be called by CipherSuite.BulkCipher.isAvailable()
-     * to test the availability of a cipher suites.  Please DON'T use it in
-     * other places, otherwise, the behavior may be unexpected because we may
-     * initialize AEAD cipher improperly in the method.
-     */
-    Boolean isAvailable() {
-        // We won't know whether a cipher for a particular key size is
-        // available until the cipher is successfully initialized.
-        //
-        // We do not initialize AEAD cipher in the constructor.  Need to
-        // initialize the cipher to ensure that the AEAD mode for a
-        // particular key size is supported.
-        if (cipherType == AEAD_CIPHER) {
-            try {
-                Authenticator authenticator =
-                    new Authenticator(protocolVersion);
-                byte[] nonce = authenticator.sequenceNumber();
-                byte[] iv = Arrays.copyOf(fixedIv,
-                                            fixedIv.length + nonce.length);
-                System.arraycopy(nonce, 0, iv, fixedIv.length, nonce.length);
-                GCMParameterSpec spec = new GCMParameterSpec(tagSize * 8, iv);
-
-                cipher.init(mode, key, spec, random);
-            } catch (Exception e) {
-                return Boolean.FALSE;
-            }
-        }   // Otherwise, we have initialized the cipher in the constructor.
-
-        return Boolean.TRUE;
+        return isCBCMode;
     }
 }
--- a/jdk/src/share/classes/sun/security/ssl/CipherSuite.java	Tue Mar 12 10:35:44 2013 -0400
+++ b/jdk/src/share/classes/sun/security/ssl/CipherSuite.java	Tue Mar 12 15:31:49 2013 -0700
@@ -33,14 +33,12 @@
 import java.security.SecureRandom;
 import java.security.KeyManagementException;
 
-import javax.crypto.Cipher;
 import javax.crypto.SecretKey;
 import javax.crypto.spec.IvParameterSpec;
 import javax.crypto.spec.SecretKeySpec;
 
 import static sun.security.ssl.CipherSuite.KeyExchange.*;
 import static sun.security.ssl.CipherSuite.PRF.*;
-import static sun.security.ssl.CipherSuite.CipherType.*;
 import static sun.security.ssl.JsseJce.*;
 
 /**
@@ -137,9 +135,7 @@
         this.keyExchange = keyExchange;
         this.cipher = cipher;
         this.exportable = cipher.exportable;
-        if (cipher.cipherType == CipherType.AEAD_CIPHER) {
-            macAlg = M_NULL;
-        } else if (name.endsWith("_MD5")) {
+        if (name.endsWith("_MD5")) {
             macAlg = M_MD5;
         } else if (name.endsWith("_SHA")) {
             macAlg = M_SHA;
@@ -389,12 +385,6 @@
         }
     }
 
-    static enum CipherType {
-        STREAM_CIPHER,         // null or stream cipher
-        BLOCK_CIPHER,          // block cipher in CBC mode
-        AEAD_CIPHER            // AEAD cipher
-    }
-
     /**
      * An SSL/TLS bulk cipher algorithm. One instance per combination of
      * cipher and key length.
@@ -427,26 +417,14 @@
         // for non-exportable ciphers, this is the same as keySize
         final int expandedKeySize;
 
-        // size of the IV
+        // size of the IV (also block size)
         final int ivSize;
 
-        // size of fixed IV
-        //
-        // record_iv_length = ivSize - fixedIvSize
-        final int fixedIvSize;
-
         // exportable under 512/40 bit rules
         final boolean exportable;
 
         // Is the cipher algorithm of Cipher Block Chaining (CBC) mode?
-        final CipherType cipherType;
-
-        // size of the authentication tag, only applicable to cipher suites in
-        // Galois Counter Mode (GCM)
-        //
-        // As far as we know, all supported GCM cipher suites use 128-bits
-        // authentication tags.
-        final int tagSize = 16;
+        final boolean isCBCMode;
 
         // The secure random used to detect the cipher availability.
         private final static SecureRandom secureRandom;
@@ -459,34 +437,32 @@
             }
         }
 
-        BulkCipher(String transformation, CipherType cipherType, int keySize,
-                int expandedKeySize, int ivSize,
-                int fixedIvSize, boolean allowed) {
-
+        BulkCipher(String transformation, int keySize,
+                int expandedKeySize, int ivSize, boolean allowed) {
             this.transformation = transformation;
             String[] splits = transformation.split("/");
             this.algorithm = splits[0];
-            this.cipherType = cipherType;
+            this.isCBCMode =
+                splits.length <= 1 ? false : "CBC".equalsIgnoreCase(splits[1]);
             this.description = this.algorithm + "/" + (keySize << 3);
             this.keySize = keySize;
             this.ivSize = ivSize;
-            this.fixedIvSize = fixedIvSize;
             this.allowed = allowed;
 
             this.expandedKeySize = expandedKeySize;
             this.exportable = true;
         }
 
-        BulkCipher(String transformation, CipherType cipherType, int keySize,
-                int ivSize, int fixedIvSize, boolean allowed) {
+        BulkCipher(String transformation, int keySize,
+                int ivSize, boolean allowed) {
             this.transformation = transformation;
             String[] splits = transformation.split("/");
             this.algorithm = splits[0];
-            this.cipherType = cipherType;
+            this.isCBCMode =
+                splits.length <= 1 ? false : "CBC".equalsIgnoreCase(splits[1]);
             this.description = this.algorithm + "/" + (keySize << 3);
             this.keySize = keySize;
             this.ivSize = ivSize;
-            this.fixedIvSize = fixedIvSize;
             this.allowed = allowed;
 
             this.expandedKeySize = keySize;
@@ -510,20 +486,16 @@
          * Test if this bulk cipher is available. For use by CipherSuite.
          *
          * Currently all supported ciphers except AES are always available
-         * via the JSSE internal implementations. We also assume AES/128 of
-         * CBC mode is always available since it is shipped with the SunJCE
-         * provider.  However, AES/256 is unavailable when the default JCE
-         * policy jurisdiction files are installed because of key length
-         * restrictions, and AEAD is unavailable when the underlying providers
-         * do not support AEAD/GCM mode.
+         * via the JSSE internal implementations. We also assume AES/128
+         * is always available since it is shipped with the SunJCE provider.
+         * However, AES/256 is unavailable when the default JCE policy
+         * jurisdiction files are installed because of key length restrictions.
          */
         boolean isAvailable() {
             if (allowed == false) {
                 return false;
             }
-
-            if ((this == B_AES_256) ||
-                    (this.cipherType == CipherType.AEAD_CIPHER)) {
+            if (this == B_AES_256) {
                 return isAvailable(this);
             }
 
@@ -541,50 +513,19 @@
         private static synchronized boolean isAvailable(BulkCipher cipher) {
             Boolean b = availableCache.get(cipher);
             if (b == null) {
-                int keySizeInBits = cipher.keySize * 8;
-                if (keySizeInBits > 128) {    // need the JCE unlimited
-                                               // strength jurisdiction policy
-                    try {
-                        if (Cipher.getMaxAllowedKeyLength(
-                                cipher.transformation) < keySizeInBits) {
-                            b = Boolean.FALSE;
-                        }
-                    } catch (Exception e) {
-                        b = Boolean.FALSE;
-                    }
+                try {
+                    SecretKey key = new SecretKeySpec
+                        (new byte[cipher.expandedKeySize], cipher.algorithm);
+                    IvParameterSpec iv =
+                        new IvParameterSpec(new byte[cipher.ivSize]);
+                    cipher.newCipher(ProtocolVersion.DEFAULT,
+                                            key, iv, secureRandom, true);
+                    b = Boolean.TRUE;
+                } catch (NoSuchAlgorithmException e) {
+                    b = Boolean.FALSE;
                 }
-
-                if (b == null) {
-                    b = Boolean.FALSE;          // may be reset to TRUE if
-                                                // the cipher is available
-                    CipherBox temporary = null;
-                    try {
-                        SecretKey key = new SecretKeySpec(
-                                            new byte[cipher.expandedKeySize],
-                                            cipher.algorithm);
-                        IvParameterSpec iv;
-                        if (cipher.cipherType == CipherType.AEAD_CIPHER) {
-                            iv = new IvParameterSpec(
-                                            new byte[cipher.fixedIvSize]);
-                        } else {
-                            iv = new IvParameterSpec(new byte[cipher.ivSize]);
-                        }
-                        temporary = cipher.newCipher(
-                                            ProtocolVersion.DEFAULT,
-                                            key, iv, secureRandom, true);
-                        b = temporary.isAvailable();
-                    } catch (NoSuchAlgorithmException e) {
-                        // not available
-                    } finally {
-                        if (temporary != null) {
-                            temporary.dispose();
-                        }
-                    }
-                }
-
                 availableCache.put(cipher, b);
             }
-
             return b.booleanValue();
         }
 
@@ -632,31 +573,27 @@
 
     // export strength ciphers
     final static BulkCipher B_NULL    =
-        new BulkCipher("NULL",          STREAM_CIPHER,    0,  0,  0, 0, true);
+                        new BulkCipher("NULL",         0,  0, 0, true);
     final static BulkCipher B_RC4_40  =
-        new BulkCipher(CIPHER_RC4,      STREAM_CIPHER,    5, 16,  0, 0, true);
+                        new BulkCipher(CIPHER_RC4,     5, 16, 0, true);
     final static BulkCipher B_RC2_40  =
-        new BulkCipher("RC2",           BLOCK_CIPHER,     5, 16,  8, 0, false);
+                        new BulkCipher("RC2",          5, 16, 8, false);
     final static BulkCipher B_DES_40  =
-        new BulkCipher(CIPHER_DES,      BLOCK_CIPHER,     5,  8,  8, 0, true);
+                        new BulkCipher(CIPHER_DES,     5,  8, 8, true);
 
     // domestic strength ciphers
     final static BulkCipher B_RC4_128 =
-        new BulkCipher(CIPHER_RC4,      STREAM_CIPHER,   16,  0,  0, true);
+                        new BulkCipher(CIPHER_RC4,     16,  0, true);
     final static BulkCipher B_DES     =
-        new BulkCipher(CIPHER_DES,      BLOCK_CIPHER,     8,  8,  0, true);
+                        new BulkCipher(CIPHER_DES,      8,  8, true);
     final static BulkCipher B_3DES    =
-        new BulkCipher(CIPHER_3DES,     BLOCK_CIPHER,    24,  8,  0, true);
+                        new BulkCipher(CIPHER_3DES,    24,  8, true);
     final static BulkCipher B_IDEA    =
-        new BulkCipher("IDEA",          BLOCK_CIPHER,    16,  8,  0, false);
+                        new BulkCipher("IDEA",         16,  8, false);
     final static BulkCipher B_AES_128 =
-        new BulkCipher(CIPHER_AES,      BLOCK_CIPHER,    16, 16,  0, true);
+                        new BulkCipher(CIPHER_AES,     16, 16, true);
     final static BulkCipher B_AES_256 =
-        new BulkCipher(CIPHER_AES,      BLOCK_CIPHER,    32, 16,  0, true);
-    final static BulkCipher B_AES_128_GCM =
-        new BulkCipher(CIPHER_AES_GCM,  AEAD_CIPHER,     16, 12,  4, true);
-    final static BulkCipher B_AES_256_GCM =
-        new BulkCipher(CIPHER_AES_GCM,  AEAD_CIPHER,     32, 12,  4, true);
+                        new BulkCipher(CIPHER_AES,     32, 16, true);
 
     // MACs
     final static MacAlg M_NULL = new MacAlg("NULL", 0);
@@ -956,12 +893,11 @@
          * Definition of the CipherSuites that are enabled by default.
          * They are listed in preference order, most preferred first, using
          * the following criteria:
-         * 1. Prefer Suite B compliant cipher suites, see RFC6460.
-         * 2. Prefer the stronger bulk cipher, in the order of AES_256(GCM),
-         *    AES_128(GCM), AES_256, AES_128, RC-4, 3DES-EDE.
-         * 3. Prefer the stronger MAC algorithm, in the order of SHA384,
+         * 1. Prefer the stronger buld cipher, in the order of AES_256,
+         *    AES_128, RC-4, 3DES-EDE.
+         * 2. Prefer the stronger MAC algorithm, in the order of SHA384,
          *    SHA256, SHA, MD5.
-         * 4. Prefer the better performance of key exchange and digital
+         * 3. Prefer the better performance of key exchange and digital
          *    signature algorithm, in the order of ECDHE-ECDSA, ECDHE-RSA,
          *    RSA, ECDH-ECDSA, ECDH-RSA, DHE-RSA, DHE-DSS.
          */
@@ -974,16 +910,6 @@
 
         //  ID           Key Exchange   Cipher     A  obs  suprt  PRF
         //  ======       ============   =========  =  ===  =====  ========
-
-
-        // Placeholder for cipher suites in GCM mode.
-        //
-        // For better compatibility and interoperability, we decrease the
-        // priority of cipher suites in GCM mode for a while as GCM
-        // technologies mature in the industry.  Eventually we'll move
-        // the GCM suites here.
-
-        // AES_256(CBC)
         add("TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384",
             0xc024, --p, K_ECDHE_ECDSA, B_AES_256, T, max, tls12, P_SHA384);
         add("TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384",
@@ -1014,7 +940,6 @@
         add("TLS_DHE_DSS_WITH_AES_256_CBC_SHA",
             0x0038, --p, K_DHE_DSS,     B_AES_256, T);
 
-        // AES_128(CBC)
         add("TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
             0xc023, --p, K_ECDHE_ECDSA, B_AES_128, T, max, tls12, P_SHA256);
         add("TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
@@ -1045,7 +970,6 @@
         add("TLS_DHE_DSS_WITH_AES_128_CBC_SHA",
             0x0032, --p, K_DHE_DSS,     B_AES_128, T);
 
-        // RC-4
         add("TLS_ECDHE_ECDSA_WITH_RC4_128_SHA",
             0xC007, --p, K_ECDHE_ECDSA, B_RC4_128, N);
         add("TLS_ECDHE_RSA_WITH_RC4_128_SHA",
@@ -1057,51 +981,6 @@
         add("TLS_ECDH_RSA_WITH_RC4_128_SHA",
             0xC00C, --p, K_ECDH_RSA,    B_RC4_128, N);
 
-        // Cipher suites in GCM mode, see RFC 5288/5289.
-        //
-        // We may increase the priority of cipher suites in GCM mode when
-        // GCM technologies become mature in the industry.
-
-        // Suite B compliant cipher suites, see RFC 6460.
-        //
-        // Note that, at present this provider is not Suite B compliant. The
-        // preference order of the GCM cipher suites does not follow the spec
-        // of RFC 6460.
-        add("TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
-            0xc02c, --p, K_ECDHE_ECDSA, B_AES_256_GCM, T, max, tls12, P_SHA384);
-        add("TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
-            0xc02b, --p, K_ECDHE_ECDSA, B_AES_128_GCM, T, max, tls12, P_SHA256);
-
-        // AES_256(GCM)
-        add("TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
-            0xc030, --p, K_ECDHE_RSA,   B_AES_256_GCM, T, max, tls12, P_SHA384);
-        add("TLS_RSA_WITH_AES_256_GCM_SHA384",
-            0x009d, --p, K_RSA,         B_AES_256_GCM, T, max, tls12, P_SHA384);
-        add("TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384",
-            0xc02e, --p, K_ECDH_ECDSA,  B_AES_256_GCM, T, max, tls12, P_SHA384);
-        add("TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384",
-            0xc032, --p, K_ECDH_RSA,    B_AES_256_GCM, T, max, tls12, P_SHA384);
-        add("TLS_DHE_RSA_WITH_AES_256_GCM_SHA384",
-            0x009f, --p, K_DHE_RSA,     B_AES_256_GCM, T, max, tls12, P_SHA384);
-        add("TLS_DHE_DSS_WITH_AES_256_GCM_SHA384",
-            0x00a3, --p, K_DHE_DSS,     B_AES_256_GCM, T, max, tls12, P_SHA384);
-
-        // AES_128(GCM)
-        add("TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
-            0xc02f, --p, K_ECDHE_RSA,   B_AES_128_GCM, T, max, tls12, P_SHA256);
-        add("TLS_RSA_WITH_AES_128_GCM_SHA256",
-            0x009c, --p, K_RSA,         B_AES_128_GCM, T, max, tls12, P_SHA256);
-        add("TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256",
-            0xc02d, --p, K_ECDH_ECDSA,  B_AES_128_GCM, T, max, tls12, P_SHA256);
-        add("TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256",
-            0xc031, --p, K_ECDH_RSA,    B_AES_128_GCM, T, max, tls12, P_SHA256);
-        add("TLS_DHE_RSA_WITH_AES_128_GCM_SHA256",
-            0x009e, --p, K_DHE_RSA,     B_AES_128_GCM, T, max, tls12, P_SHA256);
-        add("TLS_DHE_DSS_WITH_AES_128_GCM_SHA256",
-            0x00a2, --p, K_DHE_DSS,     B_AES_128_GCM, T, max, tls12, P_SHA256);
-        // End of cipher suites in GCM mode.
-
-        // 3DES_EDE
         add("TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA",
             0xC008, --p, K_ECDHE_ECDSA, B_3DES,    T);
         add("TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA",
@@ -1145,22 +1024,17 @@
          */
         p = DEFAULT_SUITES_PRIORITY;
 
-        add("TLS_DH_anon_WITH_AES_256_GCM_SHA384",
-            0x00a7, --p, K_DH_ANON,     B_AES_256_GCM, N, max, tls12, P_SHA384);
-        add("TLS_DH_anon_WITH_AES_128_GCM_SHA256",
-            0x00a6, --p, K_DH_ANON,     B_AES_128_GCM, N, max, tls12, P_SHA256);
-
         add("TLS_DH_anon_WITH_AES_256_CBC_SHA256",
             0x006d, --p, K_DH_ANON,     B_AES_256, N, max, tls12, P_SHA256);
         add("TLS_ECDH_anon_WITH_AES_256_CBC_SHA",
-            0xC019, --p, K_ECDH_ANON,   B_AES_256, N);
+            0xC019, --p, K_ECDH_ANON,   B_AES_256, T);
         add("TLS_DH_anon_WITH_AES_256_CBC_SHA",
             0x003a, --p, K_DH_ANON,     B_AES_256, N);
 
         add("TLS_DH_anon_WITH_AES_128_CBC_SHA256",
             0x006c, --p, K_DH_ANON,     B_AES_128, N, max, tls12, P_SHA256);
         add("TLS_ECDH_anon_WITH_AES_128_CBC_SHA",
-            0xC018, --p, K_ECDH_ANON,   B_AES_128, N);
+            0xC018, --p, K_ECDH_ANON,   B_AES_128, T);
         add("TLS_DH_anon_WITH_AES_128_CBC_SHA",
             0x0034, --p, K_DH_ANON,     B_AES_128, N);
 
@@ -1170,7 +1044,7 @@
             0x0018, --p, K_DH_ANON,     B_RC4_128, N);
 
         add("TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA",
-            0xC017, --p, K_ECDH_ANON,   B_3DES,    N);
+            0xC017, --p, K_ECDH_ANON,   B_3DES,    T);
         add("SSL_DH_anon_WITH_3DES_EDE_CBC_SHA",
             0x001b, --p, K_DH_ANON,     B_3DES,    N);
 
@@ -1325,10 +1199,18 @@
         add("TLS_DH_RSA_WITH_AES_256_CBC_SHA256",          0x0069);
 
         // Unsupported cipher suites from RFC 5288
+        add("TLS_RSA_WITH_AES_128_GCM_SHA256",             0x009c);
+        add("TLS_RSA_WITH_AES_256_GCM_SHA384",             0x009d);
+        add("TLS_DHE_RSA_WITH_AES_128_GCM_SHA256",         0x009e);
+        add("TLS_DHE_RSA_WITH_AES_256_GCM_SHA384",         0x009f);
         add("TLS_DH_RSA_WITH_AES_128_GCM_SHA256",          0x00a0);
         add("TLS_DH_RSA_WITH_AES_256_GCM_SHA384",          0x00a1);
+        add("TLS_DHE_DSS_WITH_AES_128_GCM_SHA256",         0x00a2);
+        add("TLS_DHE_DSS_WITH_AES_256_GCM_SHA384",         0x00a3);
         add("TLS_DH_DSS_WITH_AES_128_GCM_SHA256",          0x00a4);
         add("TLS_DH_DSS_WITH_AES_256_GCM_SHA384",          0x00a5);
+        add("TLS_DH_anon_WITH_AES_128_GCM_SHA256",         0x00a6);
+        add("TLS_DH_anon_WITH_AES_256_GCM_SHA384",         0x00a7);
 
         // Unsupported cipher suites from RFC 5487
         add("TLS_PSK_WITH_AES_128_GCM_SHA256",             0x00a8);
@@ -1387,6 +1269,16 @@
         add("TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA",        0xc021);
         add("TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA",        0xc022);
 
+        // Unsupported cipher suites from RFC 5289
+        add("TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",     0xc02b);
+        add("TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",     0xc02c);
+        add("TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256",      0xc02d);
+        add("TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384",      0xc02e);
+        add("TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",       0xc02f);
+        add("TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",       0xc030);
+        add("TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256",        0xc031);
+        add("TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384",        0xc032);
+
         // Unsupported cipher suites from RFC 5489
         add("TLS_ECDHE_PSK_WITH_RC4_128_SHA",              0xc033);
         add("TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA",         0xc034);
--- a/jdk/src/share/classes/sun/security/ssl/EngineInputRecord.java	Tue Mar 12 10:35:44 2013 -0400
+++ b/jdk/src/share/classes/sun/security/ssl/EngineInputRecord.java	Tue Mar 12 15:31:49 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -178,6 +178,71 @@
     }
 
     /*
+     * Verifies and removes the MAC value.  Returns true if
+     * the MAC checks out OK.
+     *
+     * On entry:
+     *     position = beginning of app/MAC data
+     *     limit = end of MAC data.
+     *
+     * On return:
+     *     position = beginning of app data
+     *     limit = end of app data
+     */
+    boolean checkMAC(MAC signer, ByteBuffer bb) {
+        if (internalData) {
+            return checkMAC(signer);
+        }
+
+        int len = signer.MAClen();
+        if (len == 0) { // no mac
+            return true;
+        }
+
+        /*
+         * Grab the original limit
+         */
+        int lim = bb.limit();
+
+        /*
+         * Delineate the area to apply a MAC on.
+         */
+        int macData = lim - len;
+        bb.limit(macData);
+
+        byte[] mac = signer.compute(contentType(), bb);
+
+        if (len != mac.length) {
+            throw new RuntimeException("Internal MAC error");
+        }
+
+        /*
+         * Delineate the MAC values, position was already set
+         * by doing the compute above.
+         *
+         * We could zero the MAC area, but not much useful information
+         * there anyway.
+         */
+        bb.position(macData);
+        bb.limit(lim);
+
+        try {
+            for (int i = 0; i < len; i++) {
+                if (bb.get() != mac[i]) {  // No BB.equals(byte []); !
+                    return false;
+                }
+            }
+            return true;
+        } finally {
+            /*
+             * Position to the data.
+             */
+            bb.rewind();
+            bb.limit(macData);
+        }
+    }
+
+    /*
      * Pass the data down if it's internally cached, otherwise
      * do it here.
      *
@@ -186,85 +251,16 @@
      * If external data(app), return a new ByteBuffer with data to
      * process.
      */
-    ByteBuffer decrypt(Authenticator authenticator,
-            CipherBox box, ByteBuffer bb) throws BadPaddingException {
+    ByteBuffer decrypt(CipherBox box, ByteBuffer bb)
+            throws BadPaddingException {
 
         if (internalData) {
-            decrypt(authenticator, box);    // MAC is checked during decryption
+            decrypt(box);
             return tmpBB;
         }
 
-        BadPaddingException bpe = null;
-        if (!box.isNullCipher()) {
-            try {
-                // apply explicit nonce for AEAD/CBC cipher suites if needed
-                int nonceSize =
-                    box.applyExplicitNonce(authenticator, contentType(), bb);
-
-                // decrypt the content
-                if (box.isAEADMode()) {
-                    // DON'T encrypt the nonce_explicit for AEAD mode
-                    bb.position(bb.position() + nonceSize);
-                }   // The explicit IV for CBC mode can be decrypted.
-
-                box.decrypt(bb);
-                bb.position(nonceSize); // We don't actually remove the nonce.
-            } catch (BadPaddingException e) {
-                // RFC 2246 states that decryption_failed should be used
-                // for this purpose. However, that allows certain attacks,
-                // so we just send bad record MAC. We also need to make
-                // sure to always check the MAC to avoid a timing attack
-                // for the same issue. See paper by Vaudenay et al and the
-                // update in RFC 4346/5246.
-                //
-                // Failover to message authentication code checking.
-                bpe = new BadPaddingException("invalid padding");
-            }
-        }
-
-        // Requires message authentication code for null, stream and block
-        // cipher suites.
-        if (authenticator instanceof MAC) {
-            MAC signer = (MAC)authenticator;
-            int macLen = signer.MAClen();
-            if (macLen != 0) {
-                if (bb.remaining() < macLen) {
-                    // negative data length, something is wrong
-                    throw new BadPaddingException("bad record");
-                }
-
-                int position = bb.position();
-                int limit = bb.limit();
-                int macOffset = limit - macLen;
-
-                bb.limit(macOffset);
-                byte[] hash = signer.compute(contentType(), bb);
-                if (hash == null || macLen != hash.length) {
-                    // something is wrong with MAC implementation
-                    throw new RuntimeException("Internal MAC error");
-                }
-
-                bb.position(macOffset);
-                bb.limit(limit);
-
-                try {
-                    for (byte b : hash) {       // No BB.equals(byte []); !
-                        if (bb.get() != b) {
-                            throw new BadPaddingException("bad record MAC");
-                        }
-                    }
-                } finally {
-                    // reset to the data
-                    bb.position(position);
-                    bb.limit(macOffset);
-                }
-            }
-        }
-
-        // Is it a failover?
-        if (bpe != null) {
-            throw bpe;
-        }
+        box.decrypt(bb);
+        bb.rewind();
 
         return bb.slice();
     }
@@ -342,8 +338,8 @@
         if (debug != null && Debug.isOn("packet")) {
             try {
                 HexDumpEncoder hd = new HexDumpEncoder();
+                srcBB.limit(srcPos + len);
                 ByteBuffer bb = srcBB.duplicate();  // Use copy of BB
-                bb.limit(srcPos + len);
 
                 System.out.println("[Raw read (bb)]: length = " + len);
                 hd.encodeBuffer(bb, System.out);
--- a/jdk/src/share/classes/sun/security/ssl/EngineOutputRecord.java	Tue Mar 12 10:35:44 2013 -0400
+++ b/jdk/src/share/classes/sun/security/ssl/EngineOutputRecord.java	Tue Mar 12 15:31:49 2013 -0700
@@ -29,6 +29,7 @@
 import java.io.*;
 import java.nio.*;
 
+
 /**
  * A OutputRecord class extension which uses external ByteBuffers
  * or the internal ByteArrayOutputStream for data manipulations.
@@ -100,6 +101,51 @@
         return finishedMsg;
     }
 
+
+    /**
+     * Calculate the MAC value, storing the result either in
+     * the internal buffer, or at the end of the destination
+     * ByteBuffer.
+     * <P>
+     * We assume that the higher levels have assured us enough
+     * room, otherwise we'll indirectly throw a
+     * BufferOverFlowException runtime exception.
+     *
+     * position should equal limit, and points to the next
+     * free spot.
+     */
+    private void addMAC(MAC signer, ByteBuffer bb)
+            throws IOException {
+
+        if (signer.MAClen() != 0) {
+            byte[] hash = signer.compute(contentType(), bb);
+
+            /*
+             * position was advanced to limit in compute above.
+             *
+             * Mark next area as writable (above layers should have
+             * established that we have plenty of room), then write
+             * out the hash.
+             */
+            bb.limit(bb.limit() + hash.length);
+            bb.put(hash);
+        }
+    }
+
+    /*
+     * Encrypt a ByteBuffer.
+     *
+     * We assume that the higher levels have assured us enough
+     * room for the encryption (plus padding), otherwise we'll
+     * indirectly throw a BufferOverFlowException runtime exception.
+     *
+     * position and limit will be the same, and points to the
+     * next free spot.
+     */
+    void encrypt(CipherBox box, ByteBuffer bb) {
+        box.encrypt(bb);
+    }
+
     /*
      * Override the actual write below.  We do things this way to be
      * consistent with InputRecord.  InputRecord may try to write out
@@ -114,8 +160,7 @@
          * Copy data out of buffer, it's ready to go.
          */
         ByteBuffer netBB = (ByteBuffer)
-            ByteBuffer.allocate(len).put(buf, off, len).flip();
-
+            ByteBuffer.allocate(len).put(buf, 0, len).flip();
         writer.putOutboundData(netBB);
     }
 
@@ -123,19 +168,17 @@
      * Main method for writing non-application data.
      * We MAC/encrypt, then send down for processing.
      */
-    void write(Authenticator authenticator, CipherBox writeCipher)
-            throws IOException {
-
+    void write(MAC writeMAC, CipherBox writeCipher) throws IOException {
         /*
          * Sanity check.
          */
         switch (contentType()) {
-            case ct_change_cipher_spec:
-            case ct_alert:
-            case ct_handshake:
-                break;
-            default:
-                throw new RuntimeException("unexpected byte buffers");
+        case ct_change_cipher_spec:
+        case ct_alert:
+        case ct_handshake:
+            break;
+        default:
+            throw new RuntimeException("unexpected byte buffers");
         }
 
         /*
@@ -150,10 +193,10 @@
          */
         if (!isEmpty()) {
             // compress();              // eventually
-            encrypt(authenticator, writeCipher);
-
-            // send down for processing
-            write((OutputStream)null, false, (ByteArrayOutputStream)null);
+            addMAC(writeMAC);
+            encrypt(writeCipher);
+            write((OutputStream)null, false,  // send down for processing
+                (ByteArrayOutputStream)null);
         }
         return;
     }
@@ -161,8 +204,8 @@
     /**
      * Main wrap/write driver.
      */
-    void write(EngineArgs ea, Authenticator authenticator,
-            CipherBox writeCipher) throws IOException {
+    void write(EngineArgs ea, MAC writeMAC, CipherBox writeCipher)
+            throws IOException {
         /*
          * sanity check to make sure someone didn't inadvertantly
          * send us an impossible combination we don't know how
@@ -174,7 +217,7 @@
          * Have we set the MAC's yet?  If not, we're not ready
          * to process application data yet.
          */
-        if (authenticator == MAC.NULL) {
+        if (writeMAC == MAC.NULL) {
             return;
         }
 
@@ -212,7 +255,7 @@
          */
         int length;
         if (engine.needToSplitPayload(writeCipher, protocolVersion)) {
-            write(ea, authenticator, writeCipher, 0x01);
+            write(ea, writeMAC, writeCipher, 0x01);
             ea.resetLim();      // reset application data buffer limit
             length = Math.min(ea.getAppRemaining(),
                         maxDataSizeMinusOneByteRecord);
@@ -222,14 +265,14 @@
 
         // Don't bother to really write empty records.
         if (length > 0) {
-            write(ea, authenticator, writeCipher, length);
+            write(ea, writeMAC, writeCipher, length);
         }
 
         return;
     }
 
-    void write(EngineArgs ea, Authenticator authenticator,
-            CipherBox writeCipher, int length) throws IOException {
+    void write(EngineArgs ea, MAC writeMAC, CipherBox writeCipher,
+            int length) throws IOException {
         /*
          * Copy out existing buffer values.
          */
@@ -243,76 +286,39 @@
          * Don't need to worry about SSLv2 rewrites, if we're here,
          * that's long since done.
          */
-        int dstData = dstPos + headerSize + writeCipher.getExplicitNonceSize();
+        int dstData = dstPos + headerSize;
         dstBB.position(dstData);
 
-        /*
-         * transfer application data into the network data buffer
-         */
         ea.gather(length);
-        dstBB.limit(dstBB.position());
-        dstBB.position(dstData);
 
         /*
          * "flip" but skip over header again, add MAC & encrypt
+         * addMAC will expand the limit to reflect the new
+         * data.
          */
-        if (authenticator instanceof MAC) {
-            MAC signer = (MAC)authenticator;
-            if (signer.MAClen() != 0) {
-                byte[] hash = signer.compute(contentType(), dstBB);
-
-                /*
-                 * position was advanced to limit in compute above.
-                 *
-                 * Mark next area as writable (above layers should have
-                 * established that we have plenty of room), then write
-                 * out the hash.
-                 */
-                dstBB.limit(dstBB.limit() + hash.length);
-                dstBB.put(hash);
-
-                // reset the position and limit
-                dstBB.limit(dstBB.position());
-                dstBB.position(dstData);
-            }
-        }
+        dstBB.limit(dstBB.position());
+        dstBB.position(dstData);
+        addMAC(writeMAC, dstBB);
 
-        if (!writeCipher.isNullCipher()) {
-            /*
-             * Requires explicit IV/nonce for CBC/AEAD cipher suites for TLS 1.1
-             * or later.
-             */
-            if (protocolVersion.v >= ProtocolVersion.TLS11.v &&
-                    (writeCipher.isCBCMode() || writeCipher.isAEADMode())) {
-                byte[] nonce = writeCipher.createExplicitNonce(
-                        authenticator, contentType(), dstBB.remaining());
-                dstBB.position(dstPos + headerSize);
-                dstBB.put(nonce);
-                if (!writeCipher.isAEADMode()) {
-                    // The explicit IV in TLS 1.1 and later can be encrypted.
-                    dstBB.position(dstPos + headerSize);
-                }   // Otherwise, DON'T encrypt the nonce_explicit for AEAD mode
-            }
+        /*
+         * Encrypt may pad, so again the limit may have changed.
+         */
+        dstBB.limit(dstBB.position());
+        dstBB.position(dstData);
+        encrypt(writeCipher, dstBB);
 
-            /*
-             * Encrypt may pad, so again the limit may have changed.
-             */
-            writeCipher.encrypt(dstBB, dstLim);
-
-            if ((debug != null) && (Debug.isOn("record") ||
-                    (Debug.isOn("handshake") &&
-                        (contentType() == ct_change_cipher_spec)))) {
+        if (debug != null
+                && (Debug.isOn("record") || Debug.isOn("handshake"))) {
+            if ((debug != null && Debug.isOn("record"))
+                    || contentType() == ct_change_cipher_spec)
                 System.out.println(Thread.currentThread().getName()
                     // v3.0/v3.1 ...
                     + ", WRITE: " + protocolVersion
                     + " " + InputRecord.contentName(contentType())
                     + ", length = " + length);
-            }
-        } else {
-            dstBB.position(dstBB.limit());
         }
 
-        int packetLength = dstBB.limit() - dstPos - headerSize;
+        int packetLength = dstBB.limit() - dstData;
 
         /*
          * Finish out the record header.
@@ -327,5 +333,7 @@
          * Position was already set by encrypt() above.
          */
         dstBB.limit(dstLim);
+
+        return;
     }
 }
--- a/jdk/src/share/classes/sun/security/ssl/EngineWriter.java	Tue Mar 12 10:35:44 2013 -0400
+++ b/jdk/src/share/classes/sun/security/ssl/EngineWriter.java	Tue Mar 12 15:31:49 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -99,8 +99,7 @@
      * other writeRecord.
      */
     synchronized void writeRecord(EngineOutputRecord outputRecord,
-            Authenticator authenticator,
-            CipherBox writeCipher) throws IOException {
+            MAC writeMAC, CipherBox writeCipher) throws IOException {
 
         /*
          * Only output if we're still open.
@@ -109,7 +108,7 @@
             throw new IOException("writer side was already closed.");
         }
 
-        outputRecord.write(authenticator, writeCipher);
+        outputRecord.write(writeMAC, writeCipher);
 
         /*
          * Did our handshakers notify that we just sent the
@@ -152,8 +151,7 @@
      * Return any determined status.
      */
     synchronized HandshakeStatus writeRecord(
-            EngineOutputRecord outputRecord, EngineArgs ea,
-            Authenticator authenticator,
+            EngineOutputRecord outputRecord, EngineArgs ea, MAC writeMAC,
             CipherBox writeCipher) throws IOException {
 
         /*
@@ -183,7 +181,7 @@
             throw new IOException("The write side was already closed");
         }
 
-        outputRecord.write(ea, authenticator, writeCipher);
+        outputRecord.write(ea, writeMAC, writeCipher);
 
         if (debug != null && Debug.isOn("packet")) {
             dumpPacket(ea, false);
--- a/jdk/src/share/classes/sun/security/ssl/Handshaker.java	Tue Mar 12 10:35:44 2013 -0400
+++ b/jdk/src/share/classes/sun/security/ssl/Handshaker.java	Tue Mar 12 15:31:49 2013 -0700
@@ -49,7 +49,6 @@
 import sun.security.ssl.CipherSuite.*;
 
 import static sun.security.ssl.CipherSuite.PRF.*;
-import static sun.security.ssl.CipherSuite.CipherType.*;
 
 /**
  * Handshaker ... processes handshake records from an SSL V3.0
@@ -715,47 +714,33 @@
     /**
      * Create a new read MAC and return it to caller.
      */
-    Authenticator newReadAuthenticator()
-            throws NoSuchAlgorithmException, InvalidKeyException {
-
-        Authenticator authenticator = null;
-        if (cipherSuite.cipher.cipherType == AEAD_CIPHER) {
-            authenticator = new Authenticator(protocolVersion);
+    MAC newReadMAC() throws NoSuchAlgorithmException, InvalidKeyException {
+        MacAlg macAlg = cipherSuite.macAlg;
+        MAC mac;
+        if (isClient) {
+            mac = macAlg.newMac(protocolVersion, svrMacSecret);
+            svrMacSecret = null;
         } else {
-            MacAlg macAlg = cipherSuite.macAlg;
-            if (isClient) {
-                authenticator = macAlg.newMac(protocolVersion, svrMacSecret);
-                svrMacSecret = null;
-            } else {
-                authenticator = macAlg.newMac(protocolVersion, clntMacSecret);
-                clntMacSecret = null;
-            }
+            mac = macAlg.newMac(protocolVersion, clntMacSecret);
+            clntMacSecret = null;
         }
-
-        return authenticator;
+        return mac;
     }
 
     /**
      * Create a new write MAC and return it to caller.
      */
-    Authenticator newWriteAuthenticator()
-            throws NoSuchAlgorithmException, InvalidKeyException {
-
-        Authenticator authenticator = null;
-        if (cipherSuite.cipher.cipherType == AEAD_CIPHER) {
-            authenticator = new Authenticator(protocolVersion);
+    MAC newWriteMAC() throws NoSuchAlgorithmException, InvalidKeyException {
+        MacAlg macAlg = cipherSuite.macAlg;
+        MAC mac;
+        if (isClient) {
+            mac = macAlg.newMac(protocolVersion, clntMacSecret);
+            clntMacSecret = null;
         } else {
-            MacAlg macAlg = cipherSuite.macAlg;
-            if (isClient) {
-                authenticator = macAlg.newMac(protocolVersion, clntMacSecret);
-                clntMacSecret = null;
-            } else {
-                authenticator = macAlg.newMac(protocolVersion, svrMacSecret);
-                svrMacSecret = null;
-            }
+            mac = macAlg.newMac(protocolVersion, svrMacSecret);
+            svrMacSecret = null;
         }
-
-        return authenticator;
+        return mac;
     }
 
     /*
@@ -1204,23 +1189,11 @@
         int prfHashLength = prf.getPRFHashLength();
         int prfBlockSize = prf.getPRFBlockSize();
 
-        // TLS v1.1 or later uses an explicit IV in CBC cipher suites to
-        // protect against the CBC attacks.  AEAD/GCM cipher suites in TLS
-        // v1.2 or later use a fixed IV as the implicit part of the partially
-        // implicit nonce technique described in RFC 5116.
-        int ivSize = cipher.ivSize;
-        if (cipher.cipherType == AEAD_CIPHER) {
-            ivSize = cipher.fixedIvSize;
-        } else if (protocolVersion.v >= ProtocolVersion.TLS11.v &&
-                cipher.cipherType == BLOCK_CIPHER) {
-            ivSize = 0;
-        }
-
         TlsKeyMaterialParameterSpec spec = new TlsKeyMaterialParameterSpec(
             masterKey, protocolVersion.major, protocolVersion.minor,
             clnt_random.random_bytes, svr_random.random_bytes,
             cipher.algorithm, cipher.keySize, expandedKeySize,
-            ivSize, hashSize,
+            cipher.ivSize, hashSize,
             prfHashAlg, prfHashLength, prfBlockSize);
 
         try {
@@ -1228,15 +1201,14 @@
             kg.init(spec);
             TlsKeyMaterialSpec keySpec = (TlsKeyMaterialSpec)kg.generateKey();
 
-            // Return null if cipher keys are not supposed to be generated.
             clntWriteKey = keySpec.getClientCipherKey();
             svrWriteKey = keySpec.getServerCipherKey();
 
             // Return null if IVs are not supposed to be generated.
+            // e.g. TLS 1.1+.
             clntWriteIV = keySpec.getClientIv();
             svrWriteIV = keySpec.getServerIv();
 
-            // Return null if MAC keys are not supposed to be generated.
             clntMacSecret = keySpec.getClientMacKey();
             svrMacSecret = keySpec.getServerMacKey();
         } catch (GeneralSecurityException e) {
@@ -1261,14 +1233,10 @@
                 printHex(dump, masterKey.getEncoded());
 
                 // Outputs:
-                if (clntMacSecret != null) {
-                    System.out.println("Client MAC write Secret:");
-                    printHex(dump, clntMacSecret.getEncoded());
-                    System.out.println("Server MAC write Secret:");
-                    printHex(dump, svrMacSecret.getEncoded());
-                } else {
-                    System.out.println("... no MAC keys used for this cipher");
-                }
+                System.out.println("Client MAC write Secret:");
+                printHex(dump, clntMacSecret.getEncoded());
+                System.out.println("Server MAC write Secret:");
+                printHex(dump, svrMacSecret.getEncoded());
 
                 if (clntWriteKey != null) {
                     System.out.println("Client write key:");
--- a/jdk/src/share/classes/sun/security/ssl/InputRecord.java	Tue Mar 12 10:35:44 2013 -0400
+++ b/jdk/src/share/classes/sun/security/ssl/InputRecord.java	Tue Mar 12 15:31:49 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -77,17 +77,6 @@
     /*
      * Construct the record to hold the maximum sized input record.
      * Data will be filled in separately.
-     *
-     * The structure of the byte buffer looks like:
-     *
-     *     |--------+---------+---------------------------------|
-     *     | header |   IV    | content, MAC/TAG, padding, etc. |
-     *     | headerPlusIVSize |
-     *
-     * header: the header of an SSL records
-     * IV:     the optional IV/nonce field, it is only required for block
-     *         (TLS 1.1 or later) and AEAD cipher suites.
-     *
      */
     InputRecord() {
         super(new byte[maxRecordSize]);
@@ -144,83 +133,44 @@
         return handshakeHash;
     }
 
-    void decrypt(Authenticator authenticator,
-            CipherBox box) throws BadPaddingException {
-
-        BadPaddingException bpe = null;
-        if (!box.isNullCipher()) {
-            try {
-                int cipheredLength = count - headerSize;
-
-                // apply explicit nonce for AEAD/CBC cipher suites if needed
-                int nonceSize = box.applyExplicitNonce(authenticator,
-                            contentType(), buf, headerSize, cipheredLength);
-                pos = headerSize + nonceSize;
-                lastHashed = pos;   // don't digest the explicit nonce
+    /*
+     * Verify and remove the MAC ... used for all records.
+     */
+    boolean checkMAC(MAC signer) {
+        int len = signer.MAClen();
+        if (len == 0) { // no mac
+            return true;
+        }
 
-                // decrypt the content
-                int offset = headerSize;
-                if (box.isAEADMode()) {
-                    // DON'T encrypt the nonce_explicit for AEAD mode
-                    offset += nonceSize;
-                }   // The explicit IV for CBC mode can be decrypted.
-
-                count = offset + box.decrypt(buf, offset, count - offset);
+        int offset = count - len;
 
-                // Note that we don't remove the nonce from the buffer.
-            } catch (BadPaddingException e) {
-                // RFC 2246 states that decryption_failed should be used
-                // for this purpose. However, that allows certain attacks,
-                // so we just send bad record MAC. We also need to make
-                // sure to always check the MAC to avoid a timing attack
-                // for the same issue. See paper by Vaudenay et al and the
-                // update in RFC 4346/5246.
-                //
-                // Failover to message authenticatoin code checking.
-                bpe = new BadPaddingException("invalid padding");
-            }
+        if (offset < headerSize) {
+            // data length would be negative, something is wrong
+            return false;
         }
 
-        // Requires message authentication code for null, stream and block
-        // cipher suites.
-        if (authenticator instanceof MAC) {
-            MAC signer = (MAC)authenticator;
-            int macLen = signer.MAClen();
-            if (macLen != 0) {
-                int macOffset = count - macLen;
-                int contentLen = macOffset - pos;
-                if (contentLen < 0) {
-                    // negative data length, something is wrong
-                    throw new BadPaddingException("bad record");
-                }
+        byte[] mac = signer.compute(contentType(), buf,
+            headerSize, offset - headerSize);
 
-                count -= macLen;  // Set the count before any MAC checking
-                                  // exception occurs, so that the following
-                                  // process can read the actual decrypted
-                                  // content (minus the MAC) in the fragment
-                                  // if necessary.
-                byte[] hash = signer.compute(contentType(),
-                                            buf, pos, contentLen);
-                if (hash == null || macLen != hash.length) {
-                    // something is wrong with MAC implementation
-                    throw new RuntimeException("Internal MAC error");
-                }
+        if (len != mac.length) {
+            throw new RuntimeException("Internal MAC error");
+        }
 
-                int offset = macOffset;
-                for (byte b : hash) {
-                    if (buf[offset++] != b) {
-                        throw new BadPaddingException("bad record MAC");
-                    }
-                }
+        for (int i = 0; i < len; i++) {
+            if (buf[offset + i] != mac[i]) {
+                return false;
             }
         }
+        count -= len;
+        return true;
+    }
 
-        // Is it a failover?
-        if (bpe != null) {
-            throw bpe;
-        }
+    void decrypt(CipherBox box) throws BadPaddingException {
+        int len = count - headerSize;
+        count = headerSize + box.decrypt(buf, headerSize, len);
     }
 
+
     /*
      * Well ... hello_request messages are _never_ hashed since we can't
      * know when they'd appear in the sequence.
--- a/jdk/src/share/classes/sun/security/ssl/JsseJce.java	Tue Mar 12 10:35:44 2013 -0400
+++ b/jdk/src/share/classes/sun/security/ssl/JsseJce.java	Tue Mar 12 15:31:49 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -155,11 +155,6 @@
      */
     final static String CIPHER_AES = "AES/CBC/NoPadding";
     /**
-     * JCE transformation string for AES in GCM mode
-     * without padding.
-     */
-    final static String CIPHER_AES_GCM = "AES/GCM/NoPadding";
-    /**
      * JCA identifier string for DSA, i.e. a DSA with SHA-1.
      */
     final static String SIGNATURE_DSA = "DSA";
--- a/jdk/src/share/classes/sun/security/ssl/MAC.java	Tue Mar 12 10:35:44 2013 -0400
+++ b/jdk/src/share/classes/sun/security/ssl/MAC.java	Tue Mar 12 15:31:49 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -39,15 +39,19 @@
 
 /**
  * This class computes the "Message Authentication Code" (MAC) for each
- * SSL stream and block cipher message.  This is essentially a shared-secret
- * signature, used to provide integrity protection for SSL messages.  The
- * MAC is actually one of several keyed hashes, as associated with the cipher
- * suite and protocol version. (SSL v3.0 uses one construct, TLS uses another.)
+ * SSL message.  This is essentially a shared-secret signature, used to
+ * provide integrity protection for SSL messages.  The MAC is actually
+ * one of several keyed hashes, as associated with the cipher suite and
+ * protocol version.  (SSL v3.0 uses one construct, TLS uses another.)
+ *
+ * <P>NOTE: MAC computation is the only place in the SSL protocol that the
+ * sequence number is used.  It's also reset to zero with each change of
+ * a cipher spec, so this is the only place this state is needed.
  *
  * @author David Brownell
  * @author Andreas Sterbenz
  */
-final class MAC extends Authenticator {
+final class MAC {
 
     final static MAC NULL = new MAC();
 
@@ -60,9 +64,26 @@
     // JCE Mac object
     private final Mac mac;
 
+    // byte array containing the additional information we MAC in each record
+    // (see below)
+    private final byte[] block;
+
+    // sequence number + record type + + record length
+    private static final int BLOCK_SIZE_SSL = 8 + 1 + 2;
+
+    // sequence number + record type + protocol version + record length
+    private static final int BLOCK_SIZE_TLS = 8 + 1 + 2 + 2;
+
+    // offset of record type in block
+    private static final int BLOCK_OFFSET_TYPE    = 8;
+
+    // offset of protocol version number in block (TLS only)
+    private static final int BLOCK_OFFSET_VERSION = 8 + 1;
+
     private MAC() {
         macSize = 0;
         mac = null;
+        block = null;
     }
 
     /**
@@ -70,8 +91,6 @@
      */
     MAC(MacAlg macAlg, ProtocolVersion protocolVersion, SecretKey key)
             throws NoSuchAlgorithmException, InvalidKeyException {
-        super(protocolVersion);
-
         this.macSize = macAlg.size;
 
         String algorithm;
@@ -91,6 +110,14 @@
 
         mac = JsseJce.getMac(algorithm);
         mac.init(key);
+
+        if (tls) {
+            block = new byte[BLOCK_SIZE_TLS];
+            block[BLOCK_OFFSET_VERSION]   = protocolVersion.major;
+            block[BLOCK_OFFSET_VERSION+1] = protocolVersion.minor;
+        } else {
+            block = new byte[BLOCK_SIZE_SSL];
+        }
     }
 
     /**
@@ -109,15 +136,7 @@
      * @param len the size of the compressed record
      */
     final byte[] compute(byte type, byte buf[], int offset, int len) {
-        if (macSize == 0) {
-            return nullMAC;
-        }
-
-        byte[] additional = acquireAuthenticationBytes(type, len);
-        mac.update(additional);
-        mac.update(buf, offset, len);
-
-        return mac.doFinal();
+        return compute(type, null, buf, offset, len);
     }
 
     /**
@@ -132,13 +151,78 @@
      *          demarcate the data to be MAC'd.
      */
     final byte[] compute(byte type, ByteBuffer bb) {
+        return compute(type, bb, null, 0, bb.remaining());
+    }
+
+    /**
+     * Check whether the sequence number is close to wrap
+     *
+     * Sequence numbers are of type uint64 and may not exceed 2^64-1.
+     * Sequence numbers do not wrap. When the sequence number is near
+     * to wrap, we need to close the connection immediately.
+     */
+    final boolean seqNumOverflow() {
+        /*
+         * Conservatively, we don't allow more records to be generated
+         * when there are only 2^8 sequence numbers left.
+         */
+        return (block != null && mac != null &&
+                block[0] == (byte)0xFF && block[1] == (byte)0xFF &&
+                block[2] == (byte)0xFF && block[3] == (byte)0xFF &&
+                block[4] == (byte)0xFF && block[5] == (byte)0xFF &&
+                block[6] == (byte)0xFF);
+    }
+
+    /*
+     * Check whether to renew the sequence number
+     *
+     * Sequence numbers are of type uint64 and may not exceed 2^64-1.
+     * Sequence numbers do not wrap.  If a TLS
+     * implementation would need to wrap a sequence number, it must
+     * renegotiate instead.
+     */
+    final boolean seqNumIsHuge() {
+        /*
+         * Conservatively, we should ask for renegotiation when there are
+         * only 2^48 sequence numbers left.
+         */
+        return (block != null && mac != null &&
+                block[0] == (byte)0xFF && block[1] == (byte)0xFF);
+    }
+
+    // increment the sequence number in the block array
+    // it is a 64-bit number stored in big-endian format
+    private void incrementSequenceNumber() {
+        int k = 7;
+        while ((k >= 0) && (++block[k] == 0)) {
+            k--;
+        }
+    }
+
+    /*
+     * Compute based on either buffer type, either bb.position/limit
+     * or buf/offset/len.
+     */
+    private byte[] compute(byte type, ByteBuffer bb, byte[] buf,
+            int offset, int len) {
+
         if (macSize == 0) {
             return nullMAC;
         }
 
-        byte[] additional = acquireAuthenticationBytes(type, bb.remaining());
-        mac.update(additional);
-        mac.update(bb);
+        block[BLOCK_OFFSET_TYPE] = type;
+        block[block.length - 2]  = (byte)(len >> 8);
+        block[block.length - 1]  = (byte)(len     );
+
+        mac.update(block);
+        incrementSequenceNumber();
+
+        // content
+        if (bb != null) {
+            mac.update(bb);
+        } else {
+            mac.update(buf, offset, len);
+        }
 
         return mac.doFinal();
     }
--- a/jdk/src/share/classes/sun/security/ssl/OutputRecord.java	Tue Mar 12 10:35:44 2013 -0400
+++ b/jdk/src/share/classes/sun/security/ssl/OutputRecord.java	Tue Mar 12 15:31:49 2013 -0700
@@ -54,7 +54,6 @@
     private int                 lastHashed;
     private boolean             firstMessage;
     final private byte          contentType;
-    private int                 headerOffset;
 
     // current protocol version, sent as record version
     ProtocolVersion     protocolVersion;
@@ -71,23 +70,6 @@
      * Default constructor makes a record supporting the maximum
      * SSL record size.  It allocates the header bytes directly.
      *
-     * The structure of the byte buffer looks like:
-     *
-     *     |---------+--------+-------+---------------------------------|
-     *     | unused  | header |  IV   | content, MAC/TAG, padding, etc. |
-     *     |    headerPlusMaxIVSize   |
-     *
-     * unused: unused part of the buffer of size
-     *
-     *             headerPlusMaxIVSize - header size - IV size
-     *
-     *         When this object is created, we don't know the protocol
-     *         version number, IV length, etc., so reserve space in front
-     *         to avoid extra data movement (copies).
-     * header: the header of an SSL record
-     * IV:     the optional IV/nonce field, it is only required for block
-     *         (TLS 1.1 or later) and AEAD cipher suites.
-     *
      * @param type the content type for the record
      */
     OutputRecord(byte type, int size) {
@@ -95,10 +77,9 @@
         this.protocolVersion = ProtocolVersion.DEFAULT;
         this.helloVersion = ProtocolVersion.DEFAULT_HELLO;
         firstMessage = true;
-        count = headerPlusMaxIVSize;
+        count = headerSize;
         contentType = type;
         lastHashed = count;
-        headerOffset = headerPlusMaxIVSize - headerSize;
     }
 
     OutputRecord(byte type) {
@@ -138,9 +119,8 @@
     @Override
     public synchronized void reset() {
         super.reset();
-        count = headerPlusMaxIVSize;
+        count = headerSize;
         lastHashed = count;
-        headerOffset = headerPlusMaxIVSize - headerSize;
     }
 
     /*
@@ -193,84 +173,58 @@
      * of sending empty records over the network.
      */
     boolean isEmpty() {
-        return count == headerPlusMaxIVSize;
+        return count == headerSize;
     }
 
     /*
-     * Return true if the record is of an alert of the given description.
-     *
-     * Per SSL/TLS specifications, alert messages convey the severity of the
-     * message (warning or fatal) and a description of the alert. An alert
-     * is defined with a two bytes struct, {byte level, byte description},
-     * following after the header bytes.
+     * Return true if the record is of a given alert.
      */
     boolean isAlert(byte description) {
-        if ((count > (headerPlusMaxIVSize + 1)) && (contentType == ct_alert)) {
-            return buf[headerPlusMaxIVSize + 1] == description;
+        // An alert is defined with a two bytes struct,
+        // {byte level, byte description}, following after the header bytes.
+        if (count > (headerSize + 1) && contentType == ct_alert) {
+            return buf[headerSize + 1] == description;
         }
 
         return false;
     }
 
     /*
-     * Encrypt ... length may grow due to block cipher padding, or
-     * message authentication code or tag.
+     * Compute the MAC and append it to this record.  In case we
+     * are automatically flushing a handshake stream, make sure we
+     * have hashed the message first.
      */
-    void encrypt(Authenticator authenticator, CipherBox box)
-            throws IOException {
-
-        // In case we are automatically flushing a handshake stream, make
-        // sure we have hashed the message first.
+    void addMAC(MAC signer) throws IOException {
         //
         // when we support compression, hashing can't go here
         // since it'll need to be done on the uncompressed data,
         // and the MAC applies to the compressed data.
+        //
         if (contentType == ct_handshake) {
             doHashes();
         }
-
-        // Requires message authentication code for stream and block
-        // cipher suites.
-        if (authenticator instanceof MAC) {
-            MAC signer = (MAC)authenticator;
-            if (signer.MAClen() != 0) {
-                byte[] hash = signer.compute(contentType, buf,
-                    headerPlusMaxIVSize, count - headerPlusMaxIVSize);
-                write(hash);
-            }
-        }
-
-        if (!box.isNullCipher()) {
-            // Requires explicit IV/nonce for CBC/AEAD cipher suites for
-            // TLS 1.1 or later.
-            if ((protocolVersion.v >= ProtocolVersion.TLS11.v) &&
-                                    (box.isCBCMode() || box.isAEADMode())) {
-                byte[] nonce = box.createExplicitNonce(authenticator,
-                                    contentType, count - headerPlusMaxIVSize);
-                int offset = headerPlusMaxIVSize - nonce.length;
-                System.arraycopy(nonce, 0, buf, offset, nonce.length);
-                headerOffset = offset - headerSize;
-            } else {
-                headerOffset = headerPlusMaxIVSize - headerSize;
-            }
-
-            // encrypt the content
-            int offset = headerPlusMaxIVSize;
-            if (!box.isAEADMode()) {
-                // The explicit IV can be encrypted.
-                offset = headerOffset + headerSize;
-            }   // Otherwise, DON'T encrypt the nonce_explicit for AEAD mode
-
-            count = offset + box.encrypt(buf, offset, count - offset);
+        if (signer.MAClen() != 0) {
+            byte[] hash = signer.compute(contentType, buf,
+                    headerSize, count - headerSize);
+            write(hash);
         }
     }
 
     /*
+     * Encrypt ... length may grow due to block cipher padding
+     */
+    void encrypt(CipherBox box) {
+        int len = count - headerSize;
+        count = headerSize + box.encrypt(buf, headerSize, len);
+    }
+
+
+    /*
      * Tell how full the buffer is ... for filling it with application or
      * handshake data.
      */
     final int availableDataBytes() {
-        int dataSize = count - headerPlusMaxIVSize;
+        int dataSize = count - headerSize;
         return maxDataSize - dataSize;
     }
 
@@ -316,11 +270,11 @@
          * Don't emit content-free records.  (Even change cipher spec
          * messages have a byte of data!)
          */
-        if (count == headerPlusMaxIVSize) {
+        if (count == headerSize) {
             return;
         }
 
-        int length = count - headerOffset - headerSize;
+        int length = count - headerSize;
         // "should" really never write more than about 14 Kb...
         if (length < 0) {
             throw new SSLException("output record size too small: "
@@ -345,9 +299,7 @@
          */
          if (firstMessage && useV2Hello()) {
             byte[] v3Msg = new byte[length - 4];
-            System.arraycopy(buf, headerPlusMaxIVSize + 4,
-                                        v3Msg, 0, v3Msg.length);
-            headerOffset = 0;   // reset the header offset
+            System.arraycopy(buf, headerSize + 4, v3Msg, 0, v3Msg.length);
             V3toV2ClientHello(v3Msg);
             handshakeHash.reset();
             lastHashed = 2;
@@ -362,11 +314,11 @@
             /*
              * Fill out the header, write it and the message.
              */
-            buf[headerOffset + 0] = contentType;
-            buf[headerOffset + 1] = protocolVersion.major;
-            buf[headerOffset + 2] = protocolVersion.minor;
-            buf[headerOffset + 3] = (byte)(length >> 8);
-            buf[headerOffset + 4] = (byte)(length);
+            buf[0] = contentType;
+            buf[1] = protocolVersion.major;
+            buf[2] = protocolVersion.minor;
+            buf[3] = (byte)(length >> 8);
+            buf[4] = (byte)(length);
         }
         firstMessage = false;
 
@@ -386,8 +338,7 @@
              * when holdRecord is true, the implementation in this class
              * will be used.
              */
-            writeBuffer(heldRecordBuffer,
-                        buf, headerOffset, count - headerOffset, debugOffset);
+            writeBuffer(heldRecordBuffer, buf, 0, count, debugOffset);
         } else {
             // It's time to send, do we have buffered data?
             // May or may not have a heldRecordBuffer.
@@ -395,18 +346,15 @@
                 int heldLen = heldRecordBuffer.size();
 
                 // Ensure the capacity of this buffer.
-                int newCount = count + heldLen - headerOffset;
-                ensureCapacity(newCount);
+                ensureCapacity(count + heldLen);
 
                 // Slide everything in the buffer to the right.
-                System.arraycopy(buf, headerOffset,
-                                    buf, heldLen, count - headerOffset);
+                System.arraycopy(buf, 0, buf, heldLen, count);
 
                 // Prepend the held record to the buffer.
                 System.arraycopy(
                     heldRecordBuffer.toByteArray(), 0, buf, 0, heldLen);
-                count = newCount;
-                headerOffset = 0;
+                count += heldLen;
 
                 // Clear the held buffer.
                 heldRecordBuffer.reset();
@@ -414,8 +362,7 @@
                 // The held buffer has been dumped, set the debug dump offset.
                 debugOffset = heldLen;
             }
-            writeBuffer(s, buf, headerOffset,
-                        count - headerOffset, debugOffset);
+            writeBuffer(s, buf, 0, count, debugOffset);
         }
 
         reset();
@@ -435,11 +382,12 @@
         if (debug != null && Debug.isOn("packet")) {
             try {
                 HexDumpEncoder hd = new HexDumpEncoder();
+                ByteBuffer bb = ByteBuffer.wrap(
+                        buf, off + debugOffset, len - debugOffset);
 
                 System.out.println("[Raw write]: length = " +
-                                                    (len - debugOffset));
-                hd.encodeBuffer(new ByteArrayInputStream(buf,
-                    off + debugOffset, len - debugOffset), System.out);
+                    bb.remaining());
+                hd.encodeBuffer(bb, System.out);
             } catch (IOException e) { }
         }
     }
@@ -452,13 +400,8 @@
         return firstMessage
             && (helloVersion == ProtocolVersion.SSL20Hello)
             && (contentType == ct_handshake)
-            && (buf[headerOffset + 5] == HandshakeMessage.ht_client_hello)
-                                            //  5: recode header size
-            && (buf[headerPlusMaxIVSize + 4 + 2 + 32] == 0);
-                                            // V3 session ID is empty
-                                            //  4: handshake header size
-                                            //  2: client_version in ClientHello
-                                            // 32: random in ClientHello
+            && (buf[5] == HandshakeMessage.ht_client_hello)
+            && (buf[headerSize + 4+2+32] == 0); // V3 session ID is empty
     }
 
     /*
--- a/jdk/src/share/classes/sun/security/ssl/Record.java	Tue Mar 12 10:35:44 2013 -0400
+++ b/jdk/src/share/classes/sun/security/ssl/Record.java	Tue Mar 12 15:31:49 2013 -0700
@@ -52,29 +52,20 @@
     static final int    trailerSize = 20;       // SHA1 hash size
     static final int    maxDataSize = 16384;    // 2^14 bytes of data
     static final int    maxPadding = 256;       // block cipher padding
-    static final int    maxIVLength = 256;      // IV length
-
-    /*
-     * The size of the header plus the max IV length
-     */
-    static final int    headerPlusMaxIVSize =
-                                      headerSize        // header
-                                    + maxIVLength;      // iv
+    static final int    maxIVLength = 256;      // block length
 
     /*
      * SSL has a maximum record size.  It's header, (compressed) data,
-     * padding, and a trailer for the message authentication information (MAC
-     * for block and stream ciphers, and message authentication tag for AEAD
-     * ciphers).
-     *
+     * padding, and a trailer for the MAC.
      * Some compression algorithms have rare cases where they expand the data.
      * As we don't support compression at this time, leave that out.
      */
     static final int    maxRecordSize =
-                                      headerPlusMaxIVSize   // header + iv
-                                    + maxDataSize           // data
-                                    + maxPadding            // padding
-                                    + trailerSize;          // MAC or AEAD tag
+                                      headerSize        // header
+                                    + maxIVLength       // iv
+                                    + maxDataSize       // data
+                                    + maxPadding        // padding
+                                    + trailerSize;      // MAC
 
     static final boolean enableCBCProtection =
             Debug.getBooleanProperty("jsse.enableCBCProtection", true);
@@ -86,7 +77,8 @@
     static final int    maxDataSizeMinusOneByteRecord =
                                   maxDataSize       // max data size
                                 - (                 // max one byte record size
-                                      headerPlusMaxIVSize   // header + iv
+                                      headerSize    // header
+                                    + maxIVLength   // iv
                                     + 1             // one byte data
                                     + maxPadding    // padding
                                     + trailerSize   // MAC
@@ -112,10 +104,11 @@
      * Allocate a smaller array.
      */
     static final int    maxAlertRecordSize =
-                                      headerPlusMaxIVSize   // header + iv
-                                    + 2                     // alert
-                                    + maxPadding            // padding
-                                    + trailerSize;          // MAC
+                                      headerSize        // header
+                                    + maxIVLength       // iv
+                                    + 2                 // alert
+                                    + maxPadding        // padding
+                                    + trailerSize;      // MAC
 
     /*
      * The overflow values of integers of 8, 16 and 24 bits.
--- a/jdk/src/share/classes/sun/security/ssl/SSLEngineImpl.java	Tue Mar 12 10:35:44 2013 -0400
+++ b/jdk/src/share/classes/sun/security/ssl/SSLEngineImpl.java	Tue Mar 12 15:31:49 2013 -0700
@@ -280,7 +280,7 @@
     /*
      * Crypto state that's reinitialized when the session changes.
      */
-    private Authenticator       readAuthenticator, writeAuthenticator;
+    private MAC                 readMAC, writeMAC;
     private CipherBox           readCipher, writeCipher;
     // NOTE: compression state would be saved here
 
@@ -377,9 +377,9 @@
          * Note:  compression support would go here too
          */
         readCipher = CipherBox.NULL;
-        readAuthenticator = MAC.NULL;
+        readMAC = MAC.NULL;
         writeCipher = CipherBox.NULL;
-        writeAuthenticator = MAC.NULL;
+        writeMAC = MAC.NULL;
 
         // default security parameters for secure renegotiation
         secureRenegotiation = false;
@@ -586,7 +586,7 @@
 
         try {
             readCipher = handshaker.newReadCipher();
-            readAuthenticator = handshaker.newReadAuthenticator();
+            readMAC = handshaker.newReadMAC();
         } catch (GeneralSecurityException e) {
             // "can't happen"
             throw new SSLException("Algorithm missing:  ", e);
@@ -622,7 +622,7 @@
 
         try {
             writeCipher = handshaker.newWriteCipher();
-            writeAuthenticator = handshaker.newWriteAuthenticator();
+            writeMAC = handshaker.newWriteMAC();
         } catch (GeneralSecurityException e) {
             // "can't happen"
             throw new SSLException("Algorithm missing:  ", e);
@@ -958,15 +958,34 @@
              * throw a fatal alert if the integrity check fails.
              */
             try {
-                decryptedBB = inputRecord.decrypt(
-                                    readAuthenticator, readCipher, readBB);
+                decryptedBB = inputRecord.decrypt(readCipher, readBB);
             } catch (BadPaddingException e) {
+                // RFC 2246 states that decryption_failed should be used
+                // for this purpose. However, that allows certain attacks,
+                // so we just send bad record MAC. We also need to make
+                // sure to always check the MAC to avoid a timing attack
+                // for the same issue. See paper by Vaudenay et al.
+                //
+                // rewind the BB if necessary.
+                readBB.rewind();
+
+                inputRecord.checkMAC(readMAC, readBB);
+
                 // use the same alert types as for MAC failure below
                 byte alertType = (inputRecord.contentType() ==
                     Record.ct_handshake) ?
                         Alerts.alert_handshake_failure :
                         Alerts.alert_bad_record_mac;
-                fatal(alertType, e.getMessage(), e);
+                fatal(alertType, "Invalid padding", e);
+            }
+
+            if (!inputRecord.checkMAC(readMAC, decryptedBB)) {
+                if (inputRecord.contentType() == Record.ct_handshake) {
+                    fatal(Alerts.alert_handshake_failure,
+                        "bad handshake record MAC");
+                } else {
+                    fatal(Alerts.alert_bad_record_mac, "bad record MAC");
+                }
             }
 
             // if (!inputRecord.decompress(c))
@@ -1118,7 +1137,7 @@
                 hsStatus = getHSStatus(hsStatus);
                 if (connectionState < cs_ERROR && !isInboundDone() &&
                         (hsStatus == HandshakeStatus.NOT_HANDSHAKING)) {
-                    if (checkSequenceNumber(readAuthenticator,
+                    if (checkSequenceNumber(readMAC,
                             inputRecord.contentType())) {
                         hsStatus = getHSStatus(null);
                     }
@@ -1271,7 +1290,7 @@
 
         // eventually compress as well.
         HandshakeStatus hsStatus =
-                writer.writeRecord(eor, ea, writeAuthenticator, writeCipher);
+                writer.writeRecord(eor, ea, writeMAC, writeCipher);
 
         /*
          * We only need to check the sequence number state for
@@ -1288,7 +1307,7 @@
         hsStatus = getHSStatus(hsStatus);
         if (connectionState < cs_ERROR && !isOutboundDone() &&
                 (hsStatus == HandshakeStatus.NOT_HANDSHAKING)) {
-            if (checkSequenceNumber(writeAuthenticator, eor.contentType())) {
+            if (checkSequenceNumber(writeMAC, eor.contentType())) {
                 hsStatus = getHSStatus(null);
             }
         }
@@ -1327,7 +1346,7 @@
      */
     void writeRecord(EngineOutputRecord eor) throws IOException {
         // eventually compress as well.
-        writer.writeRecord(eor, writeAuthenticator, writeCipher);
+        writer.writeRecord(eor, writeMAC, writeCipher);
 
         /*
          * Check the sequence number state
@@ -1341,7 +1360,7 @@
          * of the last record cannot be wrapped.
          */
         if ((connectionState < cs_ERROR) && !isOutboundDone()) {
-            checkSequenceNumber(writeAuthenticator, eor.contentType());
+            checkSequenceNumber(writeMAC, eor.contentType());
         }
     }
 
@@ -1359,14 +1378,14 @@
      *
      * Return true if the handshake status may be changed.
      */
-    private boolean checkSequenceNumber(Authenticator authenticator, byte type)
+    private boolean checkSequenceNumber(MAC mac, byte type)
             throws IOException {
 
         /*
          * Don't bother to check the sequence number for error or
          * closed connections, or NULL MAC
          */
-        if (connectionState >= cs_ERROR || authenticator == MAC.NULL) {
+        if (connectionState >= cs_ERROR || mac == MAC.NULL) {
             return false;
         }
 
@@ -1374,7 +1393,7 @@
          * Conservatively, close the connection immediately when the
          * sequence number is close to overflow
          */
-        if (authenticator.seqNumOverflow()) {
+        if (mac.seqNumOverflow()) {
             /*
              * TLS protocols do not define a error alert for sequence
              * number overflow. We use handshake_failure error alert
@@ -1397,7 +1416,7 @@
          * Don't bother to kickstart the renegotiation when the local is
          * asking for it.
          */
-        if ((type != Record.ct_handshake) && authenticator.seqNumIsHuge()) {
+        if ((type != Record.ct_handshake) && mac.seqNumIsHuge()) {
             if (debug != null && Debug.isOn("ssl")) {
                 System.out.println(Thread.currentThread().getName() +
                         ", request renegotiation " +
--- a/jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java	Tue Mar 12 10:35:44 2013 -0400
+++ b/jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java	Tue Mar 12 15:31:49 2013 -0700
@@ -292,7 +292,7 @@
     /*
      * Crypto state that's reinitialized when the session changes.
      */
-    private Authenticator       readAuthenticator, writeAuthenticator;
+    private MAC                 readMAC, writeMAC;
     private CipherBox           readCipher, writeCipher;
     // NOTE: compression state would be saved here
 
@@ -586,9 +586,9 @@
          * Note:  compression support would go here too
          */
         readCipher = CipherBox.NULL;
-        readAuthenticator = MAC.NULL;
+        readMAC = MAC.NULL;
         writeCipher = CipherBox.NULL;
-        writeAuthenticator = MAC.NULL;
+        writeMAC = MAC.NULL;
 
         // initial security parameters for secure renegotiation
         secureRenegotiation = false;
@@ -829,7 +829,8 @@
             boolean holdRecord) throws IOException {
 
         // r.compress(c);
-        r.encrypt(writeAuthenticator, writeCipher);
+        r.addMAC(writeMAC);
+        r.encrypt(writeCipher);
 
         if (holdRecord) {
             // If we were requested to delay the record due to possibility
@@ -860,7 +861,7 @@
          * of the last record cannot be wrapped.
          */
         if (connectionState < cs_ERROR) {
-            checkSequenceNumber(writeAuthenticator, r.contentType());
+            checkSequenceNumber(writeMAC, r.contentType());
         }
 
         // turn off the flag of the first application record
@@ -985,14 +986,29 @@
              * throw a fatal alert if the integrity check fails.
              */
             try {
-                r.decrypt(readAuthenticator, readCipher);
+                r.decrypt(readCipher);
             } catch (BadPaddingException e) {
+                // RFC 2246 states that decryption_failed should be used
+                // for this purpose. However, that allows certain attacks,
+                // so we just send bad record MAC. We also need to make
+                // sure to always check the MAC to avoid a timing attack
+                // for the same issue. See paper by Vaudenay et al.
+                r.checkMAC(readMAC);
                 // use the same alert types as for MAC failure below
                 byte alertType = (r.contentType() == Record.ct_handshake)
                                         ? Alerts.alert_handshake_failure
                                         : Alerts.alert_bad_record_mac;
-                fatal(alertType, e.getMessage(), e);
+                fatal(alertType, "Invalid padding", e);
             }
+            if (!r.checkMAC(readMAC)) {
+                if (r.contentType() == Record.ct_handshake) {
+                    fatal(Alerts.alert_handshake_failure,
+                        "bad handshake record MAC");
+                } else {
+                    fatal(Alerts.alert_bad_record_mac, "bad record MAC");
+                }
+            }
+
 
             // if (!r.decompress(c))
             //     fatal(Alerts.alert_decompression_failure,
@@ -1143,7 +1159,7 @@
                * of the last record cannot be wrapped.
                */
               if (connectionState < cs_ERROR) {
-                  checkSequenceNumber(readAuthenticator, r.contentType());
+                  checkSequenceNumber(readMAC, r.contentType());
               }
 
               return;
@@ -1166,14 +1182,14 @@
      * implementation would need to wrap a sequence number, it must
      * renegotiate instead."
      */
-    private void checkSequenceNumber(Authenticator authenticator, byte type)
+    private void checkSequenceNumber(MAC mac, byte type)
             throws IOException {
 
         /*
          * Don't bother to check the sequence number for error or
          * closed connections, or NULL MAC.
          */
-        if (connectionState >= cs_ERROR || authenticator == MAC.NULL) {
+        if (connectionState >= cs_ERROR || mac == MAC.NULL) {
             return;
         }
 
@@ -1181,7 +1197,7 @@
          * Conservatively, close the connection immediately when the
          * sequence number is close to overflow
          */
-        if (authenticator.seqNumOverflow()) {
+        if (mac.seqNumOverflow()) {
             /*
              * TLS protocols do not define a error alert for sequence
              * number overflow. We use handshake_failure error alert
@@ -1203,7 +1219,7 @@
          * Don't bother to kickstart the renegotiation when the local is
          * asking for it.
          */
-        if ((type != Record.ct_handshake) && authenticator.seqNumIsHuge()) {
+        if ((type != Record.ct_handshake) && mac.seqNumIsHuge()) {
             if (debug != null && Debug.isOn("ssl")) {
                 System.out.println(Thread.currentThread().getName() +
                         ", request renegotiation " +
@@ -2065,7 +2081,7 @@
 
         try {
             readCipher = handshaker.newReadCipher();
-            readAuthenticator = handshaker.newReadAuthenticator();
+            readMAC = handshaker.newReadMAC();
         } catch (GeneralSecurityException e) {
             // "can't happen"
             throw new SSLException("Algorithm missing:  ", e);
@@ -2096,7 +2112,7 @@
 
         try {
             writeCipher = handshaker.newWriteCipher();
-            writeAuthenticator = handshaker.newWriteAuthenticator();
+            writeMAC = handshaker.newWriteMAC();
         } catch (GeneralSecurityException e) {
             // "can't happen"
             throw new SSLException("Algorithm missing:  ", e);
--- a/jdk/test/sun/security/ec/TestEC.java	Tue Mar 12 10:35:44 2013 -0400
+++ b/jdk/test/sun/security/ec/TestEC.java	Tue Mar 12 15:31:49 2013 -0700
@@ -21,11 +21,6 @@
  * questions.
  */
 
-//
-// SunJSSE does not support dynamic system properties, no way to re-use
-// system properties in samevm/agentvm mode.
-//
-
 /**
  * @test
  * @bug 6840752
@@ -35,7 +30,7 @@
  * @library ../pkcs11/sslecc
  * @library ../../../java/security/testlibrary
  * @compile -XDignore.symbol.file TestEC.java
- * @run main/othervm TestEC
+ * @run main TestEC
  */
 
 import java.security.NoSuchProviderException;
--- a/jdk/test/sun/security/pkcs11/fips/CipherTest.java	Tue Mar 12 10:35:44 2013 -0400
+++ b/jdk/test/sun/security/pkcs11/fips/CipherTest.java	Tue Mar 12 15:31:49 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -147,25 +147,6 @@
             CS_16("TLS_DH_anon_WITH_AES_128_CBC_SHA256",     0x0303, 0xFFFF),
             CS_17("TLS_RSA_WITH_NULL_SHA256",                0x0303, 0xFFFF),
 
-            CS_20("TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", 0x0303, 0xFFFF),
-            CS_21("TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", 0x0303, 0xFFFF),
-            CS_22("TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",   0x0303, 0xFFFF),
-            CS_23("TLS_RSA_WITH_AES_256_GCM_SHA384",         0x0303, 0xFFFF),
-            CS_24("TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384",  0x0303, 0xFFFF),
-            CS_25("TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384",    0x0303, 0xFFFF),
-            CS_26("TLS_DHE_RSA_WITH_AES_256_GCM_SHA384",     0x0303, 0xFFFF),
-            CS_27("TLS_DHE_DSS_WITH_AES_256_GCM_SHA384",     0x0303, 0xFFFF),
-
-            CS_28("TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",   0x0303, 0xFFFF),
-            CS_29("TLS_RSA_WITH_AES_128_GCM_SHA256",         0x0303, 0xFFFF),
-            CS_30("TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256",  0x0303, 0xFFFF),
-            CS_31("TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256",    0x0303, 0xFFFF),
-            CS_32("TLS_DHE_RSA_WITH_AES_128_GCM_SHA256",     0x0303, 0xFFFF),
-            CS_33("TLS_DHE_DSS_WITH_AES_128_GCM_SHA256",     0x0303, 0xFFFF),
-
-            CS_34("TLS_DH_anon_WITH_AES_256_GCM_SHA384",     0x0303, 0xFFFF),
-            CS_35("TLS_DH_anon_WITH_AES_128_GCM_SHA256",     0x0303, 0xFFFF),
-
             // cipher suites obsoleted since TLS 1.2
             CS_50("SSL_RSA_WITH_DES_CBC_SHA",                0x0000, 0x0303),
             CS_51("SSL_DHE_RSA_WITH_DES_CBC_SHA",            0x0000, 0x0303),
--- a/jdk/test/sun/security/pkcs11/sslecc/CipherTest.java	Tue Mar 12 10:35:44 2013 -0400
+++ b/jdk/test/sun/security/pkcs11/sslecc/CipherTest.java	Tue Mar 12 15:31:49 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -147,25 +147,6 @@
             CS_16("TLS_DH_anon_WITH_AES_128_CBC_SHA256",     0x0303, 0xFFFF),
             CS_17("TLS_RSA_WITH_NULL_SHA256",                0x0303, 0xFFFF),
 
-            CS_20("TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", 0x0303, 0xFFFF),
-            CS_21("TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", 0x0303, 0xFFFF),
-            CS_22("TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",   0x0303, 0xFFFF),
-            CS_23("TLS_RSA_WITH_AES_256_GCM_SHA384",         0x0303, 0xFFFF),
-            CS_24("TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384",  0x0303, 0xFFFF),
-            CS_25("TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384",    0x0303, 0xFFFF),
-            CS_26("TLS_DHE_RSA_WITH_AES_256_GCM_SHA384",     0x0303, 0xFFFF),
-            CS_27("TLS_DHE_DSS_WITH_AES_256_GCM_SHA384",     0x0303, 0xFFFF),
-
-            CS_28("TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",   0x0303, 0xFFFF),
-            CS_29("TLS_RSA_WITH_AES_128_GCM_SHA256",         0x0303, 0xFFFF),
-            CS_30("TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256",  0x0303, 0xFFFF),
-            CS_31("TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256",    0x0303, 0xFFFF),
-            CS_32("TLS_DHE_RSA_WITH_AES_128_GCM_SHA256",     0x0303, 0xFFFF),
-            CS_33("TLS_DHE_DSS_WITH_AES_128_GCM_SHA256",     0x0303, 0xFFFF),
-
-            CS_34("TLS_DH_anon_WITH_AES_256_GCM_SHA384",     0x0303, 0xFFFF),
-            CS_35("TLS_DH_anon_WITH_AES_128_GCM_SHA256",     0x0303, 0xFFFF),
-
             // cipher suites obsoleted since TLS 1.2
             CS_50("SSL_RSA_WITH_DES_CBC_SHA",                0x0000, 0x0303),
             CS_51("SSL_DHE_RSA_WITH_DES_CBC_SHA",            0x0000, 0x0303),
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/SSLEngineBadBufferArrayAccess.java	Tue Mar 12 10:35:44 2013 -0400
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/SSLEngineBadBufferArrayAccess.java	Tue Mar 12 15:31:49 2013 -0700
@@ -21,16 +21,14 @@
  * questions.
  */
 
-//
-// SunJSSE does not support dynamic system properties, no way to re-use
-// system properties in samevm/agentvm mode.
-//
-
 /*
  * @test
  * @bug 7031830
  * @summary bad_record_mac failure on TLSv1.2 enabled connection with SSLEngine
  * @run main/othervm SSLEngineBadBufferArrayAccess
+ *
+ *     SunJSSE does not support dynamic system properties, no way to re-use
+ *     system properties in samevm/agentvm mode.
  */
 
 /**
--- a/jdk/test/sun/security/ssl/javax/net/ssl/TLSv12/ShortRSAKeyGCM.java	Tue Mar 12 10:35:44 2013 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,445 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-//
-// SunJSSE does not support dynamic system properties, no way to re-use
-// system properties in samevm/agentvm mode.
-//
-
-/*
- * @test
- * @bug 7030966
- * @summary Support AEAD CipherSuites
- * @run main/othervm ShortRSAKeyGCM PKIX TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
- * @run main/othervm ShortRSAKeyGCM PKIX TLS_RSA_WITH_AES_128_GCM_SHA256
- * @run main/othervm ShortRSAKeyGCM PKIX TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
- * @run main/othervm ShortRSAKeyGCM PKIX TLS_DH_anon_WITH_AES_128_GCM_SHA256
- */
-
-/*
- * Need additional key materials to run the following cases.
- *
- * @run main/othervm ShortRSAKeyGCM PKIX TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
- * @run main/othervm ShortRSAKeyGCM PKIX TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
- * @run main/othervm ShortRSAKeyGCM PKIX TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
- *
- * Need unlimited JCE Unlimited Strength Jurisdiction Policy to run the
- * following cases.
- *
- * @run main/othervm ShortRSAKeyGCM PKIX TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
- * @run main/othervm ShortRSAKeyGCM PKIX TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
- * @run main/othervm ShortRSAKeyGCM PKIX TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
- * @run main/othervm ShortRSAKeyGCM PKIX TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
- * @run main/othervm ShortRSAKeyGCM PKIX TLS_RSA_WITH_AES_256_GCM_SHA384
- * @run main/othervm ShortRSAKeyGCM PKIX TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
- * @run main/othervm ShortRSAKeyGCM PKIX TLS_DH_anon_WITH_AES_256_GCM_SHA384
- */
-
-import java.net.*;
-import java.util.*;
-import java.io.*;
-import javax.net.ssl.*;
-import java.security.Security;
-import java.security.KeyStore;
-import java.security.KeyFactory;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateFactory;
-import java.security.spec.*;
-import java.security.interfaces.*;
-import sun.misc.BASE64Decoder;
-
-
-public class ShortRSAKeyGCM {
-
-    /*
-     * =============================================================
-     * Set the various variables needed for the tests, then
-     * specify what tests to run on each side.
-     */
-
-    /*
-     * Should we run the client or server in a separate thread?
-     * Both sides can throw exceptions, but do you have a preference
-     * as to which side should be the main thread.
-     */
-    static boolean separateServerThread = true;
-
-    /*
-     * Where do we find the keystores?
-     */
-    // Certificates and key used in the test.
-    static String trustedCertStr =
-        "-----BEGIN CERTIFICATE-----\n" +
-        "MIICkjCCAfugAwIBAgIBADANBgkqhkiG9w0BAQQFADA7MQswCQYDVQQGEwJVUzEN\n" +
-        "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwHhcN\n" +
-        "MTEwODE5MDE1MjE5WhcNMzIwNzI5MDE1MjE5WjA7MQswCQYDVQQGEwJVUzENMAsG\n" +
-        "A1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwgZ8wDQYJ\n" +
-        "KoZIhvcNAQEBBQADgY0AMIGJAoGBAM8orG08DtF98TMSscjGsidd1ZoN4jiDpi8U\n" +
-        "ICz+9dMm1qM1d7O2T+KH3/mxyox7Rc2ZVSCaUD0a3CkhPMnlAx8V4u0H+E9sqso6\n" +
-        "iDW3JpOyzMExvZiRgRG/3nvp55RMIUV4vEHOZ1QbhuqG4ebN0Vz2DkRft7+flthf\n" +
-        "vDld6f5JAgMBAAGjgaUwgaIwHQYDVR0OBBYEFLl81dnfp0wDrv0OJ1sxlWzH83Xh\n" +
-        "MGMGA1UdIwRcMFqAFLl81dnfp0wDrv0OJ1sxlWzH83XhoT+kPTA7MQswCQYDVQQG\n" +
-        "EwJVUzENMAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2\n" +
-        "Y2WCAQAwDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQEE\n" +
-        "BQADgYEALlgaH1gWtoBZ84EW8Hu6YtGLQ/L9zIFmHonUPZwn3Pr//icR9Sqhc3/l\n" +
-        "pVTxOINuFHLRz4BBtEylzRIOPzK3tg8XwuLb1zd0db90x3KBCiAL6E6cklGEPwLe\n" +
-        "XYMHDn9eDsaq861Tzn6ZwzMgw04zotPMoZN0mVd/3Qca8UJFucE=\n" +
-        "-----END CERTIFICATE-----";
-
-    static String targetCertStr =
-        "-----BEGIN CERTIFICATE-----\n" +
-        "MIICNDCCAZ2gAwIBAgIBDDANBgkqhkiG9w0BAQQFADA7MQswCQYDVQQGEwJVUzEN\n" +
-        "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwHhcN\n" +
-        "MTExMTA3MTM1NTUyWhcNMzEwNzI1MTM1NTUyWjBPMQswCQYDVQQGEwJVUzENMAsG\n" +
-        "A1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UxEjAQBgNV\n" +
-        "BAMTCWxvY2FsaG9zdDBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQC3Pb49OSPfOD2G\n" +
-        "HSXFCFx1GJEZfqG9ZUf7xuIi/ra5dLjPGAaoY5QF2QOa8VnOriQCXDfyXHxsuRnE\n" +
-        "OomxL7EVAgMBAAGjeDB2MAsGA1UdDwQEAwID6DAdBgNVHQ4EFgQUXNCJK3/dtCIc\n" +
-        "xb+zlA/JINlvs/MwHwYDVR0jBBgwFoAUuXzV2d+nTAOu/Q4nWzGVbMfzdeEwJwYD\n" +
-        "VR0lBCAwHgYIKwYBBQUHAwEGCCsGAQUFBwMCBggrBgEFBQcDAzANBgkqhkiG9w0B\n" +
-        "AQQFAAOBgQB2qIDUxA2caMPpGtUACZAPRUtrGssCINIfItETXJZCx/cRuZ5sP4D9\n" +
-        "N1acoNDn0hCULe3lhXAeTC9NZ97680yJzregQMV5wATjo1FGsKY30Ma+sc/nfzQW\n" +
-        "+h/7RhYtoG0OTsiaDCvyhI6swkNJzSzrAccPY4+ZgU8HiDLzZTmM3Q==\n" +
-        "-----END CERTIFICATE-----";
-
-    // Private key in the format of PKCS#8, key size is 512 bits.
-    static String targetPrivateKey =
-        "MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAtz2+PTkj3zg9hh0l\n" +
-        "xQhcdRiRGX6hvWVH+8biIv62uXS4zxgGqGOUBdkDmvFZzq4kAlw38lx8bLkZxDqJ\n" +
-        "sS+xFQIDAQABAkByx/5Oo2hQ/w2q4L8z+NTRlJ3vdl8iIDtC/4XPnfYfnGptnpG6\n" +
-        "ZThQRvbMZiai0xHQPQMszvAHjZVme1eDl3EBAiEA3aKJHynPVCEJhpfCLWuMwX5J\n" +
-        "1LntwJO7NTOyU5m8rPECIQDTpzn5X44r2rzWBDna/Sx7HW9IWCxNgUD2Eyi2nA7W\n" +
-        "ZQIgJerEorw4aCAuzQPxiGu57PB6GRamAihEAtoRTBQlH0ECIQDN08FgTtnesgCU\n" +
-        "DFYLLcw1CiHvc7fZw4neBDHCrC8NtQIgA8TOUkGnpCZlQ0KaI8KfKWI+vxFcgFnH\n" +
-        "3fnqsTgaUs4=";
-
-    static char passphrase[] = "passphrase".toCharArray();
-
-    /*
-     * Is the server ready to serve?
-     */
-    volatile static boolean serverReady = false;
-
-    /*
-     * Turn on SSL debugging?
-     */
-    static boolean debug = false;
-
-    /*
-     * Define the server side of the test.
-     *
-     * If the server prematurely exits, serverReady will be set to true
-     * to avoid infinite hangs.
-     */
-    void doServerSide() throws Exception {
-        SSLContext context = generateSSLContext(null, targetCertStr,
-                                            targetPrivateKey);
-        SSLServerSocketFactory sslssf = context.getServerSocketFactory();
-        SSLServerSocket sslServerSocket =
-            (SSLServerSocket)sslssf.createServerSocket(serverPort);
-        serverPort = sslServerSocket.getLocalPort();
-
-        /*
-         * Signal Client, we're ready for his connect.
-         */
-        serverReady = true;
-
-        SSLSocket sslSocket = (SSLSocket)sslServerSocket.accept();
-        sslSocket.setEnabledCipherSuites(sslSocket.getSupportedCipherSuites());
-        InputStream sslIS = sslSocket.getInputStream();
-        OutputStream sslOS = sslSocket.getOutputStream();
-
-        sslIS.read();
-        sslOS.write('A');
-        sslOS.flush();
-
-        sslSocket.close();
-    }
-
-    /*
-     * Define the client side of the test.
-     *
-     * If the server prematurely exits, serverReady will be set to true
-     * to avoid infinite hangs.
-     */
-    void doClientSide() throws Exception {
-
-        /*
-         * Wait for server to get started.
-         */
-        while (!serverReady) {
-            Thread.sleep(50);
-        }
-
-        SSLContext context = generateSSLContext(trustedCertStr, null, null);
-        SSLSocketFactory sslsf = context.getSocketFactory();
-
-        SSLSocket sslSocket =
-            (SSLSocket)sslsf.createSocket("localhost", serverPort);
-
-        // enable TLSv1.2 only
-        sslSocket.setEnabledProtocols(new String[] {"TLSv1.2"});
-
-        // enable a block cipher
-        sslSocket.setEnabledCipherSuites(new String[] {cipherSuite});
-
-        InputStream sslIS = sslSocket.getInputStream();
-        OutputStream sslOS = sslSocket.getOutputStream();
-
-        sslOS.write('B');
-        sslOS.flush();
-        sslIS.read();
-
-        sslSocket.close();
-    }
-
-    /*
-     * =============================================================
-     * The remainder is just support stuff
-     */
-    private static String tmAlgorithm;        // trust manager
-    private static String cipherSuite;        // cipher suite
-
-    private static void parseArguments(String[] args) {
-        tmAlgorithm = args[0];
-        cipherSuite = args[1];
-    }
-
-    private static SSLContext generateSSLContext(String trustedCertStr,
-            String keyCertStr, String keySpecStr) throws Exception {
-
-        // generate certificate from cert string
-        CertificateFactory cf = CertificateFactory.getInstance("X.509");
-
-        // create a key store
-        KeyStore ks = KeyStore.getInstance("JKS");
-        ks.load(null, null);
-
-        // import the trused cert
-        Certificate trusedCert = null;
-        ByteArrayInputStream is = null;
-        if (trustedCertStr != null) {
-            is = new ByteArrayInputStream(trustedCertStr.getBytes());
-            trusedCert = cf.generateCertificate(is);
-            is.close();
-
-            ks.setCertificateEntry("RSA Export Signer", trusedCert);
-        }
-
-        if (keyCertStr != null) {
-            // generate the private key.
-            PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec(
-                                new BASE64Decoder().decodeBuffer(keySpecStr));
-            KeyFactory kf = KeyFactory.getInstance("RSA");
-            RSAPrivateKey priKey =
-                    (RSAPrivateKey)kf.generatePrivate(priKeySpec);
-
-            // generate certificate chain
-            is = new ByteArrayInputStream(keyCertStr.getBytes());
-            Certificate keyCert = cf.generateCertificate(is);
-            is.close();
-
-            Certificate[] chain = null;
-            if (trusedCert != null) {
-                chain = new Certificate[2];
-                chain[0] = keyCert;
-                chain[1] = trusedCert;
-            } else {
-                chain = new Certificate[1];
-                chain[0] = keyCert;
-            }
-
-            // import the key entry.
-            ks.setKeyEntry("Whatever", priKey, passphrase, chain);
-        }
-
-        // create SSL context
-        TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmAlgorithm);
-        tmf.init(ks);
-
-        SSLContext ctx = SSLContext.getInstance("TLS");
-        if (keyCertStr != null && !keyCertStr.isEmpty()) {
-            KeyManagerFactory kmf = KeyManagerFactory.getInstance("NewSunX509");
-            kmf.init(ks, passphrase);
-
-            ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
-            ks = null;
-        } else {
-            ctx.init(null, tmf.getTrustManagers(), null);
-        }
-
-        return ctx;
-    }
-
-
-    // use any free port by default
-    volatile int serverPort = 0;
-
-    volatile Exception serverException = null;
-    volatile Exception clientException = null;
-
-    public static void main(String[] args) throws Exception {
-        // reset the security property to make sure that the algorithms
-        // and keys used in this test are not disabled.
-        Security.setProperty("jdk.certpath.disabledAlgorithms", "MD2");
-
-        if (debug) {
-            System.setProperty("javax.net.debug", "all");
-        }
-
-        /*
-         * Get the customized arguments.
-         */
-        parseArguments(args);
-
-        /*
-         * Start the tests.
-         */
-        new ShortRSAKeyGCM();
-    }
-
-    Thread clientThread = null;
-    Thread serverThread = null;
-
-    /*
-     * Primary constructor, used to drive remainder of the test.
-     *
-     * Fork off the other side, then do your work.
-     */
-    ShortRSAKeyGCM() throws Exception {
-        try {
-            if (separateServerThread) {
-                startServer(true);
-                startClient(false);
-            } else {
-                startClient(true);
-                startServer(false);
-            }
-        } catch (Exception e) {
-            // swallow for now.  Show later
-        }
-
-        /*
-         * Wait for other side to close down.
-         */
-        if (separateServerThread) {
-            serverThread.join();
-        } else {
-            clientThread.join();
-        }
-
-        /*
-         * When we get here, the test is pretty much over.
-         * Which side threw the error?
-         */
-        Exception local;
-        Exception remote;
-        String whichRemote;
-
-        if (separateServerThread) {
-            remote = serverException;
-            local = clientException;
-            whichRemote = "server";
-        } else {
-            remote = clientException;
-            local = serverException;
-            whichRemote = "client";
-        }
-
-        /*
-         * If both failed, return the curthread's exception, but also
-         * print the remote side Exception
-         */
-        if ((local != null) && (remote != null)) {
-            System.out.println(whichRemote + " also threw:");
-            remote.printStackTrace();
-            System.out.println();
-            throw local;
-        }
-
-        if (remote != null) {
-            throw remote;
-        }
-
-        if (local != null) {
-            throw local;
-        }
-    }
-
-    void startServer(boolean newThread) throws Exception {
-        if (newThread) {
-            serverThread = new Thread() {
-                public void run() {
-                    try {
-                        doServerSide();
-                    } catch (Exception e) {
-                        /*
-                         * Our server thread just died.
-                         *
-                         * Release the client, if not active already...
-                         */
-                        System.err.println("Server died..." + e);
-                        serverReady = true;
-                        serverException = e;
-                    }
-                }
-            };
-            serverThread.start();
-        } else {
-            try {
-                doServerSide();
-            } catch (Exception e) {
-                serverException = e;
-            } finally {
-                serverReady = true;
-            }
-        }
-    }
-
-    void startClient(boolean newThread) throws Exception {
-        if (newThread) {
-            clientThread = new Thread() {
-                public void run() {
-                    try {
-                        doClientSide();
-                    } catch (Exception e) {
-                        /*
-                         * Our client thread just died.
-                         */
-                        System.err.println("Client died..." + e);
-                        clientException = e;
-                    }
-                }
-            };
-            clientThread.start();
-        } else {
-            try {
-                doClientSide();
-            } catch (Exception e) {
-                clientException = e;
-            }
-        }
-    }
-}
--- a/jdk/test/sun/security/ssl/sanity/ciphersuites/CipherSuitesInOrder.java	Tue Mar 12 10:35:44 2013 -0400
+++ b/jdk/test/sun/security/ssl/sanity/ciphersuites/CipherSuitesInOrder.java	Tue Mar 12 15:31:49 2013 -0700
@@ -21,15 +21,13 @@
  * questions.
  */
 
-//
-// SunJSSE does not support dynamic system properties, no way to re-use
-// system properties in samevm/agentvm mode.
-//
-
 /*
  * @test
  * @bug 7174244
  * @summary NPE in Krb5ProxyImpl.getServerKeys()
+ *
+ *     SunJSSE does not support dynamic system properties, no way to re-use
+ *     system properties in samevm/agentvm mode.
  * @run main/othervm CipherSuitesInOrder
  */
 
@@ -74,22 +72,6 @@
         "SSL_RSA_WITH_RC4_128_SHA",
         "TLS_ECDH_ECDSA_WITH_RC4_128_SHA",
         "TLS_ECDH_RSA_WITH_RC4_128_SHA",
-
-        "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
-        "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
-        "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
-        "TLS_RSA_WITH_AES_256_GCM_SHA384",
-        "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384",
-        "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384",
-        "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384",
-        "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384",
-        "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
-        "TLS_RSA_WITH_AES_128_GCM_SHA256",
-        "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256",
-        "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256",
-        "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256",
-        "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256",
-
         "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA",
         "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA",
         "SSL_RSA_WITH_3DES_EDE_CBC_SHA",
@@ -101,9 +83,6 @@
 
         "TLS_EMPTY_RENEGOTIATION_INFO_SCSV",
 
-        "TLS_DH_anon_WITH_AES_256_GCM_SHA384",
-        "TLS_DH_anon_WITH_AES_128_GCM_SHA256",
-
         "TLS_DH_anon_WITH_AES_256_CBC_SHA256",
         "TLS_ECDH_anon_WITH_AES_256_CBC_SHA",
         "TLS_DH_anon_WITH_AES_256_CBC_SHA",
--- a/jdk/test/sun/security/ssl/sanity/interop/CipherTest.java	Tue Mar 12 10:35:44 2013 -0400
+++ b/jdk/test/sun/security/ssl/sanity/interop/CipherTest.java	Tue Mar 12 15:31:49 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -148,25 +148,6 @@
             CS_16("TLS_DH_anon_WITH_AES_128_CBC_SHA256",     0x0303, 0xFFFF),
             CS_17("TLS_RSA_WITH_NULL_SHA256",                0x0303, 0xFFFF),
 
-            CS_20("TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", 0x0303, 0xFFFF),
-            CS_21("TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", 0x0303, 0xFFFF),
-            CS_22("TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",   0x0303, 0xFFFF),
-            CS_23("TLS_RSA_WITH_AES_256_GCM_SHA384",         0x0303, 0xFFFF),
-            CS_24("TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384",  0x0303, 0xFFFF),
-            CS_25("TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384",    0x0303, 0xFFFF),
-            CS_26("TLS_DHE_RSA_WITH_AES_256_GCM_SHA384",     0x0303, 0xFFFF),
-            CS_27("TLS_DHE_DSS_WITH_AES_256_GCM_SHA384",     0x0303, 0xFFFF),
-
-            CS_28("TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",   0x0303, 0xFFFF),
-            CS_29("TLS_RSA_WITH_AES_128_GCM_SHA256",         0x0303, 0xFFFF),
-            CS_30("TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256",  0x0303, 0xFFFF),
-            CS_31("TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256",    0x0303, 0xFFFF),
-            CS_32("TLS_DHE_RSA_WITH_AES_128_GCM_SHA256",     0x0303, 0xFFFF),
-            CS_33("TLS_DHE_DSS_WITH_AES_128_GCM_SHA256",     0x0303, 0xFFFF),
-
-            CS_34("TLS_DH_anon_WITH_AES_256_GCM_SHA384",     0x0303, 0xFFFF),
-            CS_35("TLS_DH_anon_WITH_AES_128_GCM_SHA256",     0x0303, 0xFFFF),
-
             // cipher suites obsoleted since TLS 1.2
             CS_50("SSL_RSA_WITH_DES_CBC_SHA",                0x0000, 0x0303),
             CS_51("SSL_DHE_RSA_WITH_DES_CBC_SHA",            0x0000, 0x0303),
--- a/jdk/test/sun/security/ssl/templates/SSLSocketSSLEngineTemplate.java	Tue Mar 12 10:35:44 2013 -0400
+++ b/jdk/test/sun/security/ssl/templates/SSLSocketSSLEngineTemplate.java	Tue Mar 12 15:31:49 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -21,15 +21,14 @@
  * questions.
  */
 
-//
-// SunJSSE does not support dynamic system properties, no way to re-use
-// system properties in samevm/agentvm mode.
-//
-
 /*
  * @test
  * @bug 7105780
  * @summary Add SSLSocket client/SSLEngine server to templates directory.
+ *
+ *     SunJSSE does not support dynamic system properties, no way to re-use
+ *     system properties in samevm/agentvm mode.
+ *
  * @run main/othervm SSLSocketSSLEngineTemplate
  */