Backed out 1 changesets (bug 1414735)
authorCsoregi Natalia <ncsoregi@mozilla.com>
Mon, 06 Nov 2017 12:27:00 +0200
changeset 390374 bdf69fd8e8715fae20a988a50c2aa3d1dfe59046
parent 390373 b6eccc50ace73fe96fb3d4f3964cb8962c5fa999
child 390375 8f41147476b0a8df54dbad48df60e0576b383a53
push id32828
push userccoroiu@mozilla.com
push dateMon, 06 Nov 2017 23:06:05 +0000
treeherdermozilla-central@c2fe4b3b1b93 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1414735
milestone58.0a1
backs outf019d4ffff53e1931355ec6bf7afa77016222ff8
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out 1 changesets (bug 1414735) Backed out changeset f019d4ffff53 (bug 1414735)for failing Gtest TransportTest.TestCipherMismatch and Xpcshell dom/presentation/tests/xpcshell/test_tcp_control_channel.js tests on a CLOSED TREE r=backout UPGRADE_NSS_RELEASE
old-configure.in
security/manager/ssl/nsNSSIOLayer.cpp
security/nss/TAG-INFO
security/nss/automation/abi-check/expected-report-libnss3.so.txt
security/nss/automation/abi-check/expected-report-libssl3.so.txt
security/nss/automation/abi-check/previous-nss-release
security/nss/cmd/tstclnt/tstclnt.c
security/nss/coreconf/coreconf.dep
security/nss/gtests/common/util.h
security/nss/gtests/pk11_gtest/manifest.mn
security/nss/gtests/pk11_gtest/pk11_encrypt_derive_unittest.cc
security/nss/gtests/pk11_gtest/pk11_gtest.gyp
security/nss/gtests/ssl_gtest/libssl_internals.c
security/nss/gtests/ssl_gtest/manifest.mn
security/nss/gtests/ssl_gtest/ssl_alths_unittest.cc
security/nss/gtests/ssl_gtest/ssl_extension_unittest.cc
security/nss/gtests/ssl_gtest/ssl_gtest.gyp
security/nss/gtests/ssl_gtest/ssl_loopback_unittest.cc
security/nss/gtests/ssl_gtest/ssl_record_unittest.cc
security/nss/gtests/ssl_gtest/tls_agent.cc
security/nss/gtests/ssl_gtest/tls_filter.cc
security/nss/gtests/ssl_gtest/tls_filter.h
security/nss/lib/freebl/poly1305.h
security/nss/lib/nss/nss.h
security/nss/lib/softoken/pkcs11.c
security/nss/lib/softoken/pkcs11c.c
security/nss/lib/softoken/softkver.h
security/nss/lib/softoken/softoknt.h
security/nss/lib/ssl/ssl3con.c
security/nss/lib/ssl/ssl3ecc.c
security/nss/lib/ssl/ssl3exthandle.c
security/nss/lib/ssl/ssl3gthr.c
security/nss/lib/ssl/ssl3prot.h
security/nss/lib/ssl/sslexp.h
security/nss/lib/ssl/sslimpl.h
security/nss/lib/ssl/sslinfo.c
security/nss/lib/ssl/sslsock.c
security/nss/lib/ssl/tls13con.c
security/nss/lib/ssl/tls13con.h
security/nss/lib/ssl/tls13exthandle.c
security/nss/lib/ssl/tls13exthandle.h
security/nss/lib/util/nssutil.h
--- a/old-configure.in
+++ b/old-configure.in
@@ -1910,17 +1910,17 @@ dnl = If NSS was not detected in the sys
 dnl = use the one in the source tree (mozilla/security/nss)
 dnl ========================================================
 
 MOZ_ARG_WITH_BOOL(system-nss,
 [  --with-system-nss       Use system installed NSS],
     _USE_SYSTEM_NSS=1 )
 
 if test -n "$_USE_SYSTEM_NSS"; then
-    AM_PATH_NSS(3.35, [MOZ_SYSTEM_NSS=1], [AC_MSG_ERROR([you don't have NSS installed or your version is too old])])
+    AM_PATH_NSS(3.34, [MOZ_SYSTEM_NSS=1], [AC_MSG_ERROR([you don't have NSS installed or your version is too old])])
 fi
 
 if test -n "$MOZ_SYSTEM_NSS"; then
    NSS_LIBS="$NSS_LIBS -lcrmf"
 else
    NSS_CFLAGS="-I${DIST}/include/nss"
    case "${OS_ARCH}" in
         # Only few platforms have been tested with GYP
--- a/security/manager/ssl/nsNSSIOLayer.cpp
+++ b/security/manager/ssl/nsNSSIOLayer.cpp
@@ -70,17 +70,17 @@ namespace {
 // does not impact other normal sockets not using the flags.)
 //
 // Their current definitions are:
 //
 // bits 0-2 (mask 0x07) specify the max tls version
 //          0 means no override 1->4 are 1.0, 1.1, 1.2, 1.3, 4->7 unused
 // bits 3-5 (mask 0x38) specify the tls fallback limit
 //          0 means no override, values 1->4 match prefs
-// bit    6 (mask 0x40) specifies use of SSL_AltHandshakeType on handshake
+// bit    6 (mask 0x40) specifies use of SSL_AltServerHelloType on handshake
 
 enum {
   kTLSProviderFlagMaxVersion10   = 0x01,
   kTLSProviderFlagMaxVersion11   = 0x02,
   kTLSProviderFlagMaxVersion12   = 0x03,
   kTLSProviderFlagMaxVersion13   = 0x04,
 };
 
@@ -89,17 +89,17 @@ static uint32_t getTLSProviderFlagMaxVer
   return (flags & 0x07);
 }
 
 static uint32_t getTLSProviderFlagFallbackLimit(uint32_t flags)
 {
   return (flags & 0x38) >> 3;
 }
 
-static bool getTLSProviderFlagAltHandshake(uint32_t flags)
+static bool getTLSProviderFlagAltServerHello(uint32_t flags)
 {
   return (flags & 0x40);
 }
 
 #define MAX_ALPN_LENGTH 255
 
 void
 getSiteKey(const nsACString& hostName, uint16_t port,
@@ -2596,23 +2596,23 @@ nsSSLIOLayerSetOptions(PRFileDesc* fd, b
       range.max = SSL_LIBRARY_VERSION_TLS_1_3;
     } else {
       MOZ_LOG(gPIPNSSLog, LogLevel::Error,
               ("[%p] nsSSLIOLayerSetOptions: unknown version flags %d\n",
                fd, versionFlags));
     }
   }
 
-  // enabling alternative handshake
-  if (getTLSProviderFlagAltHandshake(infoObject->GetProviderTlsFlags())) {
+  // enabling alternative server hello
+  if (getTLSProviderFlagAltServerHello(infoObject->GetProviderTlsFlags())) {
     MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
-            ("[%p] nsSSLIOLayerSetOptions: Use AltHandshake\n", fd));
-    if (SECSuccess != SSL_UseAltHandshakeType(fd, PR_TRUE)) {
+            ("[%p] nsSSLIOLayerSetOptions: Use AltServerHello\n", fd));
+    if (SECSuccess != SSL_UseAltServerHelloType(fd, PR_TRUE)) {
           MOZ_LOG(gPIPNSSLog, LogLevel::Error,
-                  ("[%p] nsSSLIOLayerSetOptions: Use AltHandshake failed\n", fd));
+                  ("[%p] nsSSLIOLayerSetOptions: Use AltServerHello failed\n", fd));
           // continue on default path
     }
   }
 
   if ((infoObject->GetProviderFlags() & nsISocketProvider::BE_CONSERVATIVE) &&
       (range.max > SSL_LIBRARY_VERSION_TLS_1_2)) {
     MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
             ("[%p] nsSSLIOLayerSetOptions: range.max limited to 1.2 due to BE_CONSERVATIVE flag\n",
--- a/security/nss/TAG-INFO
+++ b/security/nss/TAG-INFO
@@ -1,1 +1,1 @@
-72ddcd9b1621
+NSS_3_34_BETA1
--- a/security/nss/automation/abi-check/expected-report-libnss3.so.txt
+++ b/security/nss/automation/abi-check/expected-report-libnss3.so.txt
@@ -0,0 +1,11 @@
+Functions changes summary: 0 Removed, 0 Changed, 4 Added functions
+Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
+
+4 Added functions:
+
+  'function SECItem* SEC_CreateSignatureAlgorithmParameters(SECItem*, SECOidTag, SECOidTag, const SECItem*, const SECKEYPrivateKey*)'    {SEC_CreateSignatureAlgorithmParameters@@NSS_3.34}
+  'function SECStatus SEC_DerSignDataWithAlgorithmID(SECItem*, const unsigned char*, int, SECKEYPrivateKey*, SECAlgorithmID*)'    {SEC_DerSignDataWithAlgorithmID@@NSS_3.34}
+  'function SECStatus SEC_SignDataWithAlgorithmID(SECItem*, const unsigned char*, int, SECKEYPrivateKey*, SECAlgorithmID*)'    {SEC_SignDataWithAlgorithmID@@NSS_3.34}
+  'function void SGN_NewContextWithAlgorithmID(SECAlgorithmID*, SECKEYPrivateKey*)'    {SGN_NewContextWithAlgorithmID@@NSS_3.34}
+
+
--- a/security/nss/automation/abi-check/expected-report-libssl3.so.txt
+++ b/security/nss/automation/abi-check/expected-report-libssl3.so.txt
@@ -0,0 +1,15 @@
+Functions changes summary: 0 Removed, 1 Changed, 0 Added function
+Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
+
+1 function with some indirect sub-type change:
+
+  [C]'function SECStatus SSL_GetChannelInfo(SSLChannelInfo*, PRUintn)' at sslinfo.c:26:1 has some indirect sub-type changes:
+    parameter 1 of type 'SSLChannelInfo*' has sub-type changes:
+      in pointed to type 'typedef SSLChannelInfo' at sslt.h:288:1:
+        underlying type 'struct SSLChannelInfoStr' at sslt.h:229:1 changed:
+          type size changed from 896 to 960 bits
+          2 data member insertions:
+            'SSLNamedGroup SSLChannelInfoStr::originalKeaGroup', at offset 864 (in bits) at sslt.h:281:1
+            'PRBool SSLChannelInfoStr::resumed', at offset 896 (in bits) at sslt.h:284:1
+
+
--- a/security/nss/automation/abi-check/previous-nss-release
+++ b/security/nss/automation/abi-check/previous-nss-release
@@ -1,1 +1,1 @@
-NSS_3_34_BRANCH
+NSS_3_33_BRANCH
--- a/security/nss/cmd/tstclnt/tstclnt.c
+++ b/security/nss/cmd/tstclnt/tstclnt.c
@@ -247,17 +247,17 @@ PrintParameterUsage(void)
     fprintf(stderr, "%-20s Require the use of FFDHE supported groups [RFC7919]\n", "-H");
     fprintf(stderr, "%-20s Read from a file instead of stdin\n", "-A");
     fprintf(stderr, "%-20s Allow 0-RTT data (TLS 1.3 only)\n", "-Z");
     fprintf(stderr, "%-20s Disconnect and reconnect up to N times total\n", "-L");
     fprintf(stderr, "%-20s Comma separated list of enabled groups for TLS key exchange.\n"
                     "%-20s The following values are valid:\n"
                     "%-20s P256, P384, P521, x25519, FF2048, FF3072, FF4096, FF6144, FF8192\n",
             "-I", "", "");
-    fprintf(stderr, "%-20s Enable alternative TLS 1.3 handshake\n", "-X alt-server-hello");
+    fprintf(stderr, "%-20s Enable alternate content type for TLS 1.3 ServerHello\n", "-X alt-server-hello");
 }
 
 static void
 Usage(const char *progName)
 {
     PrintUsageHeader(progName);
     PrintParameterUsage();
     exit(1);
@@ -1178,17 +1178,17 @@ run_client(void)
             SECU_PrintError(progName, "error enabling 0-RTT");
             error = 1;
             goto done;
         }
     }
 
     /* Alternate ServerHello content type (TLS 1.3 only) */
     if (enableAltServerHello) {
-        rv = SSL_UseAltHandshakeType(s, PR_TRUE);
+        rv = SSL_UseAltServerHelloType(s, PR_TRUE);
         if (rv != SECSuccess) {
             SECU_PrintError(progName, "error enabling alternate ServerHello type");
             error = 1;
             goto done;
         }
     }
 
     /* require the use of fixed finite-field DH groups */
--- a/security/nss/coreconf/coreconf.dep
+++ b/security/nss/coreconf/coreconf.dep
@@ -5,8 +5,9 @@
 
 /*
  * A dummy header file that is a dependency for all the object files.
  * Used to force a full recompilation of NSS in Mozilla's Tinderbox
  * depend builds.  See comments in rules.mk.
  */
 
 #error "Do not include this header file."
+
--- a/security/nss/gtests/common/util.h
+++ b/security/nss/gtests/common/util.h
@@ -5,17 +5,17 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef util_h__
 #define util_h__
 
 #include <cassert>
 #include <vector>
 
-static inline std::vector<uint8_t> hex_string_to_bytes(std::string s) {
+std::vector<uint8_t> hex_string_to_bytes(std::string s) {
   std::vector<uint8_t> bytes;
   for (size_t i = 0; i < s.length(); i += 2) {
     bytes.push_back(std::stoul(s.substr(i, 2), nullptr, 16));
   }
   return bytes;
 }
 
 #endif  // util_h__
--- a/security/nss/gtests/pk11_gtest/manifest.mn
+++ b/security/nss/gtests/pk11_gtest/manifest.mn
@@ -6,17 +6,16 @@ CORE_DEPTH = ../..
 DEPTH      = ../..
 MODULE = nss
 
 CPPSRCS = \
       pk11_aeskeywrap_unittest.cc \
       pk11_chacha20poly1305_unittest.cc \
       pk11_curve25519_unittest.cc \
       pk11_ecdsa_unittest.cc \
-      pk11_encrypt_derive_unittest.cc \
       pk11_export_unittest.cc \
       pk11_pbkdf2_unittest.cc \
       pk11_prf_unittest.cc \
       pk11_prng_unittest.cc \
       pk11_rsapss_unittest.cc \
       pk11_der_private_key_import_unittest.cc \
       $(NULL)
 
deleted file mode 100644
--- a/security/nss/gtests/pk11_gtest/pk11_encrypt_derive_unittest.cc
+++ /dev/null
@@ -1,210 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "pk11pub.h"
-#include "nssutil.h"
-#include <stdio.h>
-#include "prerror.h"
-#include "nss.h"
-#include "gtest/gtest.h"
-#include "scoped_ptrs.h"
-#include "cpputil.h"
-#include "databuffer.h"
-#include "util.h"
-
-#define MAX_KEY_SIZE 24
-
-namespace nss_test {
-
-static const uint8_t kIv[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
-                              0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
-                              0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
-static const uint8_t kInput[] = {
-    0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00, 0xff, 0xee, 0xdd, 0xcc,
-    0xbb, 0xaa, 0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00};
-
-class EncryptDeriveTest
-    : public ::testing::Test,
-      public ::testing::WithParamInterface<CK_MECHANISM_TYPE> {
- public:
-  void TestEncryptDerive() {
-    ScopedPK11SymKey derived_key(PK11_Derive(key_.get(), derive_mech(),
-                                             derive_param(), encrypt_mech(),
-                                             CKA_DECRYPT, keysize()));
-    ASSERT_TRUE(derived_key);
-
-    uint8_t derived_key_data[MAX_KEY_SIZE];
-    ASSERT_GE(sizeof(derived_key_data), keysize());
-    GetKeyData(derived_key, derived_key_data, keysize());
-    RemoveChecksum(derived_key_data);
-
-    uint8_t reference_key_data[MAX_KEY_SIZE];
-    unsigned int reference_len = 0;
-    SECStatus rv = PK11_Encrypt(key_.get(), encrypt_mech(), encrypt_param(),
-                                reference_key_data, &reference_len, keysize(),
-                                kInput, keysize());
-    ASSERT_EQ(SECSuccess, rv);
-    ASSERT_EQ(keysize(), static_cast<size_t>(reference_len));
-    RemoveChecksum(reference_key_data);
-
-    EXPECT_EQ(DataBuffer(reference_key_data, keysize()),
-              DataBuffer(derived_key_data, keysize()));
-  }
-
- protected:
-  unsigned int keysize() const { return 16; }
-
- private:
-  CK_MECHANISM_TYPE encrypt_mech() const { return GetParam(); }
-
-  CK_MECHANISM_TYPE derive_mech() const {
-    switch (encrypt_mech()) {
-      case CKM_DES3_ECB:
-        return CKM_DES3_ECB_ENCRYPT_DATA;
-      case CKM_DES3_CBC:
-        return CKM_DES3_CBC_ENCRYPT_DATA;
-      case CKM_AES_ECB:
-        return CKM_AES_ECB_ENCRYPT_DATA;
-      case CKM_AES_CBC:
-        return CKM_AES_CBC_ENCRYPT_DATA;
-      case CKM_CAMELLIA_ECB:
-        return CKM_CAMELLIA_ECB_ENCRYPT_DATA;
-      case CKM_CAMELLIA_CBC:
-        return CKM_CAMELLIA_CBC_ENCRYPT_DATA;
-      case CKM_SEED_ECB:
-        return CKM_SEED_ECB_ENCRYPT_DATA;
-      case CKM_SEED_CBC:
-        return CKM_SEED_CBC_ENCRYPT_DATA;
-      default:
-        ADD_FAILURE() << "Unknown mechanism";
-        break;
-    }
-    return CKM_INVALID_MECHANISM;
-  }
-
-  SECItem* derive_param() const {
-    static CK_AES_CBC_ENCRYPT_DATA_PARAMS aes_data;
-    static CK_DES_CBC_ENCRYPT_DATA_PARAMS des_data;
-    static CK_KEY_DERIVATION_STRING_DATA string_data;
-    static SECItem param = {siBuffer, NULL, 0};
-
-    switch (encrypt_mech()) {
-      case CKM_DES3_ECB:
-      case CKM_AES_ECB:
-      case CKM_CAMELLIA_ECB:
-      case CKM_SEED_ECB:
-        string_data.pData = toUcharPtr(kInput);
-        string_data.ulLen = keysize();
-        param.data = reinterpret_cast<uint8_t*>(&string_data);
-        param.len = sizeof(string_data);
-        break;
-
-      case CKM_DES3_CBC:
-        des_data.pData = toUcharPtr(kInput);
-        des_data.length = keysize();
-        PORT_Memcpy(des_data.iv, kIv, 8);
-        param.data = reinterpret_cast<uint8_t*>(&des_data);
-        param.len = sizeof(des_data);
-        break;
-
-      case CKM_AES_CBC:
-      case CKM_CAMELLIA_CBC:
-      case CKM_SEED_CBC:
-        aes_data.pData = toUcharPtr(kInput);
-        aes_data.length = keysize();
-        PORT_Memcpy(aes_data.iv, kIv, keysize());
-        param.data = reinterpret_cast<uint8_t*>(&aes_data);
-        param.len = sizeof(aes_data);
-        break;
-
-      default:
-        ADD_FAILURE() << "Unknown mechanism";
-        break;
-    }
-    return &param;
-  }
-
-  SECItem* encrypt_param() const {
-    static SECItem param = {siBuffer, NULL, 0};
-
-    switch (encrypt_mech()) {
-      case CKM_DES3_ECB:
-      case CKM_AES_ECB:
-      case CKM_CAMELLIA_ECB:
-      case CKM_SEED_ECB:
-        // No parameter needed here.
-        break;
-
-      case CKM_DES3_CBC:
-      case CKM_AES_CBC:
-      case CKM_CAMELLIA_CBC:
-      case CKM_SEED_CBC:
-        param.data = toUcharPtr(kIv);
-        param.len = keysize();
-        break;
-
-      default:
-        ADD_FAILURE() << "Unknown mechanism";
-        break;
-    }
-    return &param;
-  }
-
-  virtual void SetUp() {
-    slot_.reset(PK11_GetBestSlot(derive_mech(), NULL));
-    ASSERT_TRUE(slot_);
-
-    key_.reset(PK11_TokenKeyGenWithFlags(slot_.get(), encrypt_mech(), NULL,
-                                         keysize(), NULL,
-                                         CKF_ENCRYPT | CKF_DERIVE, 0, NULL));
-    ASSERT_TRUE(key_);
-  }
-
-  void GetKeyData(ScopedPK11SymKey& key, uint8_t* buf, size_t max_len) const {
-    ASSERT_EQ(SECSuccess, PK11_ExtractKeyValue(key.get()));
-    SECItem* data = PK11_GetKeyData(key.get());
-    ASSERT_TRUE(data);
-    ASSERT_EQ(max_len, static_cast<size_t>(data->len));
-    PORT_Memcpy(buf, data->data, data->len);
-  }
-
-  // Remove checksum if the key is a 3DES key.
-  void RemoveChecksum(uint8_t* key_data) const {
-    if (encrypt_mech() != CKM_DES3_CBC && encrypt_mech() != CKM_DES3_ECB) {
-      return;
-    }
-    for (size_t i = 0; i < keysize(); ++i) {
-      key_data[i] &= 0xfe;
-    }
-  }
-
-  ScopedPK11SlotInfo slot_;
-  ScopedPK11SymKey key_;
-};
-
-TEST_P(EncryptDeriveTest, Test) { TestEncryptDerive(); }
-
-static const CK_MECHANISM_TYPE kEncryptDeriveMechanisms[] = {
-    CKM_DES3_ECB,     CKM_DES3_CBC,     CKM_AES_ECB,  CKM_AES_ECB, CKM_AES_CBC,
-    CKM_CAMELLIA_ECB, CKM_CAMELLIA_CBC, CKM_SEED_ECB, CKM_SEED_CBC};
-
-INSTANTIATE_TEST_CASE_P(EncryptDeriveTests, EncryptDeriveTest,
-                        ::testing::ValuesIn(kEncryptDeriveMechanisms));
-
-// This class handles the case where 3DES takes a 192-bit key
-// where all 24 octets will be used.
-class EncryptDerive3Test : public EncryptDeriveTest {
- protected:
-  unsigned int keysize() const { return 24; }
-};
-
-TEST_P(EncryptDerive3Test, Test) { TestEncryptDerive(); }
-
-static const CK_MECHANISM_TYPE kDES3EncryptDeriveMechanisms[] = {CKM_DES3_ECB,
-                                                                 CKM_DES3_CBC};
-
-INSTANTIATE_TEST_CASE_P(Encrypt3DeriveTests, EncryptDerive3Test,
-                        ::testing::ValuesIn(kDES3EncryptDeriveMechanisms));
-
-}  // namespace nss_test
--- a/security/nss/gtests/pk11_gtest/pk11_gtest.gyp
+++ b/security/nss/gtests/pk11_gtest/pk11_gtest.gyp
@@ -11,17 +11,16 @@
       'target_name': 'pk11_gtest',
       'type': 'executable',
       'sources': [
         'pk11_aeskeywrap_unittest.cc',
         'pk11_aes_gcm_unittest.cc',
         'pk11_chacha20poly1305_unittest.cc',
         'pk11_curve25519_unittest.cc',
         'pk11_ecdsa_unittest.cc',
-        'pk11_encrypt_derive_unittest.cc',
         'pk11_pbkdf2_unittest.cc',
         'pk11_prf_unittest.cc',
         'pk11_prng_unittest.cc',
         'pk11_rsapss_unittest.cc',
         'pk11_der_private_key_import_unittest.cc',
         '<(DEPTH)/gtests/common/gtests.cc'
       ],
       'dependencies': [
--- a/security/nss/gtests/ssl_gtest/libssl_internals.c
+++ b/security/nss/gtests/ssl_gtest/libssl_internals.c
@@ -35,22 +35,22 @@ SECStatus SSLInt_UpdateSSLv2ClientRandom
   }
 
   ssl3_InitState(ss);
   ssl3_RestartHandshakeHashes(ss);
 
   // Ensure we don't overrun hs.client_random.
   rnd_len = PR_MIN(SSL3_RANDOM_LENGTH, rnd_len);
 
-  // Zero the client_random.
-  PORT_Memset(ss->ssl3.hs.client_random, 0, SSL3_RANDOM_LENGTH);
+  // Zero the client_random struct.
+  PORT_Memset(&ss->ssl3.hs.client_random, 0, SSL3_RANDOM_LENGTH);
 
   // Copy over the challenge bytes.
   size_t offset = SSL3_RANDOM_LENGTH - rnd_len;
-  PORT_Memcpy(ss->ssl3.hs.client_random + offset, rnd, rnd_len);
+  PORT_Memcpy(&ss->ssl3.hs.client_random.rand[offset], rnd, rnd_len);
 
   // Rehash the SSLv2 client hello message.
   return ssl3_UpdateHandshakeHashes(ss, msg, msg_len);
 }
 
 PRBool SSLInt_ExtensionNegotiated(PRFileDesc *fd, PRUint16 ext) {
   sslSocket *ss = ssl_FindSocket(fd);
   return (PRBool)(ss && ssl3_ExtensionNegotiated(ss, ext));
--- a/security/nss/gtests/ssl_gtest/manifest.mn
+++ b/security/nss/gtests/ssl_gtest/manifest.mn
@@ -9,17 +9,16 @@ MODULE = nss
 # These sources have access to libssl internals
 CSRCS = \
       libssl_internals.c \
       $(NULL)
 
 CPPSRCS = \
       ssl_0rtt_unittest.cc \
       ssl_agent_unittest.cc \
-      ssl_alths_unittest.cc \
       ssl_auth_unittest.cc \
       ssl_cert_ext_unittest.cc \
       ssl_ciphersuite_unittest.cc \
       ssl_damage_unittest.cc \
       ssl_dhe_unittest.cc \
       ssl_drop_unittest.cc \
       ssl_ecdh_unittest.cc \
       ssl_ems_unittest.cc \
deleted file mode 100644
--- a/security/nss/gtests/ssl_gtest/ssl_alths_unittest.cc
+++ /dev/null
@@ -1,189 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include <memory>
-#include <vector>
-#include "ssl.h"
-#include "sslerr.h"
-#include "sslproto.h"
-
-#include "gtest_utils.h"
-#include "tls_connect.h"
-#include "tls_filter.h"
-#include "tls_parser.h"
-
-namespace nss_test {
-
-static const uint32_t kServerHelloVersionAlt = SSL_LIBRARY_VERSION_TLS_1_2;
-static const uint16_t kServerHelloVersionRegular =
-    0x7f00 | TLS_1_3_DRAFT_VERSION;
-
-class AltHandshakeTest : public TlsConnectStreamTls13 {
- protected:
-  void SetUp() {
-    TlsConnectStreamTls13::SetUp();
-    client_ccs_recorder_ =
-        std::make_shared<TlsRecordRecorder>(kTlsChangeCipherSpecType);
-    server_handshake_recorder_ =
-        std::make_shared<TlsRecordRecorder>(kTlsHandshakeType);
-    server_ccs_recorder_ =
-        std::make_shared<TlsRecordRecorder>(kTlsChangeCipherSpecType);
-    server_hello_recorder_ =
-        std::make_shared<TlsInspectorRecordHandshakeMessage>(
-            kTlsHandshakeServerHello);
-  }
-
-  void SetAltHandshakeTypeEnabled() {
-    client_->SetAltHandshakeTypeEnabled();
-    server_->SetAltHandshakeTypeEnabled();
-  }
-
-  void InstallFilters() {
-    client_->SetPacketFilter(client_ccs_recorder_);
-    auto chain = std::make_shared<ChainedPacketFilter>(ChainedPacketFilterInit(
-        {server_handshake_recorder_, server_ccs_recorder_,
-         server_hello_recorder_}));
-    server_->SetPacketFilter(chain);
-  }
-
-  void CheckServerHelloRecordVersion(uint16_t record_version) {
-    ASSERT_EQ(record_version,
-              server_handshake_recorder_->record(0).header.version());
-  }
-
-  void CheckServerHelloVersion(uint16_t server_hello_version) {
-    uint32_t ver;
-    ASSERT_TRUE(server_hello_recorder_->buffer().Read(0, 2, &ver));
-    ASSERT_EQ(server_hello_version, ver);
-  }
-
-  void CheckForRegularHandshake() {
-    EXPECT_EQ(0U, client_ccs_recorder_->count());
-    EXPECT_EQ(0U, server_ccs_recorder_->count());
-    CheckServerHelloVersion(kServerHelloVersionRegular);
-    CheckServerHelloRecordVersion(SSL_LIBRARY_VERSION_TLS_1_0);
-  }
-
-  void CheckForAltHandshake() {
-    EXPECT_EQ(1U, client_ccs_recorder_->count());
-    EXPECT_EQ(1U, server_ccs_recorder_->count());
-    CheckServerHelloVersion(kServerHelloVersionAlt);
-    CheckServerHelloRecordVersion(SSL_LIBRARY_VERSION_TLS_1_2);
-  }
-
-  std::shared_ptr<TlsRecordRecorder> client_ccs_recorder_;
-  std::shared_ptr<TlsRecordRecorder> server_handshake_recorder_;
-  std::shared_ptr<TlsRecordRecorder> server_ccs_recorder_;
-  std::shared_ptr<TlsInspectorRecordHandshakeMessage> server_hello_recorder_;
-};
-
-TEST_F(AltHandshakeTest, ClientOnly) {
-  client_->SetAltHandshakeTypeEnabled();
-  InstallFilters();
-  Connect();
-  CheckForRegularHandshake();
-}
-
-TEST_F(AltHandshakeTest, ServerOnly) {
-  server_->SetAltHandshakeTypeEnabled();
-  InstallFilters();
-  Connect();
-  CheckForRegularHandshake();
-}
-
-TEST_F(AltHandshakeTest, Enabled) {
-  SetAltHandshakeTypeEnabled();
-  InstallFilters();
-  Connect();
-  CheckForAltHandshake();
-}
-
-TEST_F(AltHandshakeTest, ZeroRtt) {
-  SetAltHandshakeTypeEnabled();
-  SetupForZeroRtt();
-  SetAltHandshakeTypeEnabled();
-  client_->Set0RttEnabled(true);
-  server_->Set0RttEnabled(true);
-
-  InstallFilters();
-
-  ExpectResumption(RESUME_TICKET);
-  ZeroRttSendReceive(true, true);
-  Handshake();
-  ExpectEarlyDataAccepted(true);
-  CheckConnected();
-
-  CheckForAltHandshake();
-}
-
-// Neither client nor server has the extension prior to resumption, so the
-// client doesn't send a CCS before its 0-RTT data.
-TEST_F(AltHandshakeTest, DisabledBeforeZeroRtt) {
-  SetupForZeroRtt();
-  SetAltHandshakeTypeEnabled();
-  client_->Set0RttEnabled(true);
-  server_->Set0RttEnabled(true);
-
-  InstallFilters();
-
-  ExpectResumption(RESUME_TICKET);
-  ZeroRttSendReceive(true, true);
-  Handshake();
-  ExpectEarlyDataAccepted(true);
-  CheckConnected();
-
-  EXPECT_EQ(0U, client_ccs_recorder_->count());
-  EXPECT_EQ(1U, server_ccs_recorder_->count());
-  CheckServerHelloVersion(kServerHelloVersionAlt);
-}
-
-// Both use the alternative in the initial handshake but only the server enables
-// it on resumption.
-TEST_F(AltHandshakeTest, ClientDisabledAfterZeroRtt) {
-  SetAltHandshakeTypeEnabled();
-  SetupForZeroRtt();
-  server_->SetAltHandshakeTypeEnabled();
-  client_->Set0RttEnabled(true);
-  server_->Set0RttEnabled(true);
-
-  InstallFilters();
-
-  ExpectResumption(RESUME_TICKET);
-  ZeroRttSendReceive(true, true);
-  Handshake();
-  ExpectEarlyDataAccepted(true);
-  CheckConnected();
-
-  CheckForRegularHandshake();
-}
-
-// If the alternative handshake isn't negotiated after 0-RTT, and the client has
-// it enabled, it will send a ChangeCipherSpec.  The server chokes on it if it
-// hasn't negotiated the alternative handshake.
-TEST_F(AltHandshakeTest, ServerDisabledAfterZeroRtt) {
-  SetAltHandshakeTypeEnabled();
-  SetupForZeroRtt();
-  client_->SetAltHandshakeTypeEnabled();
-  client_->Set0RttEnabled(true);
-  server_->Set0RttEnabled(true);
-
-  client_->ExpectSendAlert(kTlsAlertEndOfEarlyData);
-  client_->Handshake();  // Send ClientHello (and CCS)
-
-  server_->Handshake();  // Consume the ClientHello, which is OK.
-  client_->ExpectResumption();
-  client_->Handshake();  // Read the server handshake.
-  EXPECT_EQ(TlsAgent::STATE_CONNECTED, client_->state());
-
-  // Now the server reads the CCS instead of more handshake messages.
-  ExpectAlert(server_, kTlsAlertBadRecordMac);
-  server_->Handshake();
-  EXPECT_EQ(TlsAgent::STATE_ERROR, server_->state());
-  client_->Handshake();  // Consume the alert.
-  EXPECT_EQ(TlsAgent::STATE_ERROR, client_->state());
-}
-
-}  // nss_test
--- a/security/nss/gtests/ssl_gtest/ssl_extension_unittest.cc
+++ b/security/nss/gtests/ssl_gtest/ssl_extension_unittest.cc
@@ -1074,16 +1074,20 @@ TEST_P(TlsBogusExtensionTest13, AddBogus
 
 TEST_P(TlsBogusExtensionTest13, AddBogusExtensionHelloRetryRequest) {
   static const std::vector<SSLNamedGroup> groups = {ssl_grp_ec_secp384r1};
   server_->ConfigNamedGroups(groups);
 
   Run(kTlsHandshakeHelloRetryRequest);
 }
 
+TEST_P(TlsBogusExtensionTest13, AddVersionExtensionServerHello) {
+  Run(kTlsHandshakeServerHello, ssl_tls13_supported_versions_xtn);
+}
+
 TEST_P(TlsBogusExtensionTest13, AddVersionExtensionEncryptedExtensions) {
   Run(kTlsHandshakeEncryptedExtensions, ssl_tls13_supported_versions_xtn);
 }
 
 TEST_P(TlsBogusExtensionTest13, AddVersionExtensionCertificate) {
   Run(kTlsHandshakeCertificate, ssl_tls13_supported_versions_xtn);
 }
 
--- a/security/nss/gtests/ssl_gtest/ssl_gtest.gyp
+++ b/security/nss/gtests/ssl_gtest/ssl_gtest.gyp
@@ -10,17 +10,16 @@
     {
       'target_name': 'ssl_gtest',
       'type': 'executable',
       'sources': [
         'libssl_internals.c',
         'selfencrypt_unittest.cc',
         'ssl_0rtt_unittest.cc',
         'ssl_agent_unittest.cc',
-        'ssl_alths_unittest.cc',
         'ssl_auth_unittest.cc',
         'ssl_cert_ext_unittest.cc',
         'ssl_ciphersuite_unittest.cc',
         'ssl_damage_unittest.cc',
         'ssl_dhe_unittest.cc',
         'ssl_drop_unittest.cc',
         'ssl_ecdh_unittest.cc',
         'ssl_ems_unittest.cc',
--- a/security/nss/gtests/ssl_gtest/ssl_loopback_unittest.cc
+++ b/security/nss/gtests/ssl_gtest/ssl_loopback_unittest.cc
@@ -6,16 +6,17 @@
 
 #include <functional>
 #include <memory>
 #include <vector>
 #include "secerr.h"
 #include "ssl.h"
 #include "sslerr.h"
 #include "sslproto.h"
+#include "ssl3prot.h"
 
 extern "C" {
 // This is not something that should make you happy.
 #include "libssl_internals.h"
 }
 
 #include "gtest_utils.h"
 #include "scoped_ptrs.h"
@@ -98,19 +99,19 @@ class HelloTruncator : public TlsHandsha
 };
 
 // Verify that when NSS reports that an alert is sent, it is actually sent.
 TEST_P(TlsConnectGeneric, CaptureAlertServer) {
   client_->SetPacketFilter(std::make_shared<HelloTruncator>());
   auto alert_recorder = std::make_shared<TlsAlertRecorder>();
   server_->SetPacketFilter(alert_recorder);
 
-  ConnectExpectAlert(server_, kTlsAlertDecodeError);
+  ConnectExpectAlert(server_, kTlsAlertIllegalParameter);
   EXPECT_EQ(kTlsAlertFatal, alert_recorder->level());
-  EXPECT_EQ(kTlsAlertDecodeError, alert_recorder->description());
+  EXPECT_EQ(kTlsAlertIllegalParameter, alert_recorder->description());
 }
 
 TEST_P(TlsConnectGenericPre13, CaptureAlertClient) {
   server_->SetPacketFilter(std::make_shared<HelloTruncator>());
   auto alert_recorder = std::make_shared<TlsAlertRecorder>();
   client_->SetPacketFilter(alert_recorder);
 
   ConnectExpectAlert(client_, kTlsAlertDecodeError);
@@ -301,16 +302,52 @@ TEST_F(TlsConnectStreamTls13, Tls13Faile
 TEST_F(TlsConnectStreamTls13, NegotiateShortHeaders) {
   client_->SetShortHeadersEnabled();
   server_->SetShortHeadersEnabled();
   client_->ExpectShortHeaders();
   server_->ExpectShortHeaders();
   Connect();
 }
 
+TEST_F(TlsConnectStreamTls13, ClientAltHandshakeType) {
+  client_->SetAltHandshakeTypeEnabled();
+  auto filter = std::make_shared<TlsHeaderRecorder>();
+  server_->SetPacketFilter(filter);
+  Connect();
+  ASSERT_EQ(kTlsHandshakeType, filter->header(0)->content_type());
+}
+
+TEST_F(TlsConnectStreamTls13, ServerAltHandshakeType) {
+  server_->SetAltHandshakeTypeEnabled();
+  auto filter = std::make_shared<TlsHeaderRecorder>();
+  server_->SetPacketFilter(filter);
+  Connect();
+  ASSERT_EQ(kTlsHandshakeType, filter->header(0)->content_type());
+}
+
+TEST_F(TlsConnectStreamTls13, BothAltHandshakeType) {
+  client_->SetAltHandshakeTypeEnabled();
+  server_->SetAltHandshakeTypeEnabled();
+  auto header_filter = std::make_shared<TlsHeaderRecorder>();
+  auto sh_filter = std::make_shared<TlsInspectorRecordHandshakeMessage>(
+      kTlsHandshakeServerHello);
+  std::vector<std::shared_ptr<PacketFilter>> filters = {header_filter,
+                                                        sh_filter};
+  auto chained = std::make_shared<ChainedPacketFilter>(filters);
+  server_->SetPacketFilter(chained);
+  header_filter->SetAgent(server_.get());
+  header_filter->EnableDecryption();
+  Connect();
+  ASSERT_EQ(kTlsAltHandshakeType, header_filter->header(0)->content_type());
+  ASSERT_EQ(kTlsHandshakeType, header_filter->header(1)->content_type());
+  uint32_t ver;
+  ASSERT_TRUE(sh_filter->buffer().Read(0, 2, &ver));
+  ASSERT_EQ((uint32_t)(0x7a00 | TLS_1_3_DRAFT_VERSION), ver);
+}
+
 INSTANTIATE_TEST_CASE_P(
     GenericStream, TlsConnectGeneric,
     ::testing::Combine(TlsConnectTestBase::kTlsVariantsStream,
                        TlsConnectTestBase::kTlsVAll));
 INSTANTIATE_TEST_CASE_P(
     GenericDatagram, TlsConnectGeneric,
     ::testing::Combine(TlsConnectTestBase::kTlsVariantsDatagram,
                        TlsConnectTestBase::kTlsV11Plus));
--- a/security/nss/gtests/ssl_gtest/ssl_record_unittest.cc
+++ b/security/nss/gtests/ssl_gtest/ssl_record_unittest.cc
@@ -5,18 +5,16 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nss.h"
 #include "ssl.h"
 #include "sslimpl.h"
 
 #include "databuffer.h"
 #include "gtest_utils.h"
-#include "tls_connect.h"
-#include "tls_filter.h"
 
 namespace nss_test {
 
 const static size_t kMacSize = 20;
 
 class TlsPaddingTest
     : public ::testing::Test,
       public ::testing::WithParamInterface<std::tuple<size_t, bool>> {
@@ -48,18 +46,18 @@ class TlsPaddingTest
   }
 
   void Unpad(bool expect_success) {
     std::cerr << "Content length=" << plaintext_len_
               << " padding length=" << pad_len_
               << " total length=" << plaintext_.len() << std::endl;
     std::cerr << "Plaintext: " << plaintext_ << std::endl;
     sslBuffer s;
-    s.buf = const_cast<unsigned char*>(
-        static_cast<const unsigned char*>(plaintext_.data()));
+    s.buf = const_cast<unsigned char *>(
+        static_cast<const unsigned char *>(plaintext_.data()));
     s.len = plaintext_.len();
     SECStatus rv = ssl_RemoveTLSCBCPadding(&s, kMacSize);
     if (expect_success) {
       EXPECT_EQ(SECSuccess, rv);
       EXPECT_EQ(plaintext_len_, static_cast<size_t>(s.len));
     } else {
       EXPECT_EQ(SECFailure, rv);
     }
@@ -96,85 +94,16 @@ TEST_P(TlsPaddingTest, FirstByteOfPadWro
 TEST_P(TlsPaddingTest, LastByteOfPadWrong) {
   if (pad_len_) {
     plaintext_.Write(plaintext_.len() - 2,
                      plaintext_.data()[plaintext_.len() - 1] + 1, 1);
     Unpad(false);
   }
 }
 
-class RecordReplacer : public TlsRecordFilter {
- public:
-  RecordReplacer(size_t size)
-      : TlsRecordFilter(), enabled_(false), size_(size) {}
-
-  PacketFilter::Action FilterRecord(const TlsRecordHeader& header,
-                                    const DataBuffer& data,
-                                    DataBuffer* changed) override {
-    if (!enabled_) {
-      return KEEP;
-    }
-
-    EXPECT_EQ(kTlsApplicationDataType, header.content_type());
-    changed->Allocate(size_);
-
-    for (size_t i = 0; i < size_; ++i) {
-      changed->data()[i] = i & 0xff;
-    }
-
-    enabled_ = false;
-    return CHANGE;
-  }
-
-  void Enable() { enabled_ = true; }
-
- private:
-  bool enabled_;
-  size_t size_;
-};
-
-TEST_F(TlsConnectStreamTls13, LargeRecord) {
-  EnsureTlsSetup();
-
-  const size_t record_limit = 16384;
-  auto replacer = std::make_shared<RecordReplacer>(record_limit);
-  client_->SetTlsRecordFilter(replacer);
-  replacer->EnableDecryption();
-  Connect();
-
-  replacer->Enable();
-  client_->SendData(10);
-  WAIT_(server_->received_bytes() == record_limit, 2000);
-  ASSERT_EQ(record_limit, server_->received_bytes());
-}
-
-TEST_F(TlsConnectStreamTls13, TooLargeRecord) {
-  EnsureTlsSetup();
-
-  const size_t record_limit = 16384;
-  auto replacer = std::make_shared<RecordReplacer>(record_limit + 1);
-  client_->SetTlsRecordFilter(replacer);
-  replacer->EnableDecryption();
-  Connect();
-
-  replacer->Enable();
-  ExpectAlert(server_, kTlsAlertRecordOverflow);
-  client_->SendData(10);  // This is expanded.
-
-  uint8_t buf[record_limit + 2];
-  PRInt32 rv = PR_Read(server_->ssl_fd(), buf, sizeof(buf));
-  EXPECT_GT(0, rv);
-  EXPECT_EQ(SSL_ERROR_RX_RECORD_TOO_LONG, PORT_GetError());
-
-  // Read the server alert.
-  rv = PR_Read(client_->ssl_fd(), buf, sizeof(buf));
-  EXPECT_GT(0, rv);
-  EXPECT_EQ(SSL_ERROR_RECORD_OVERFLOW_ALERT, PORT_GetError());
-}
-
 const static size_t kContentSizesArr[] = {
     1, kMacSize - 1, kMacSize, 30, 31, 32, 36, 256, 257, 287, 288};
 
 auto kContentSizes = ::testing::ValuesIn(kContentSizesArr);
 const static bool kTrueFalseArr[] = {true, false};
 auto kTrueFalse = ::testing::ValuesIn(kTrueFalseArr);
 
 INSTANTIATE_TEST_CASE_P(TlsPadding, TlsPaddingTest,
--- a/security/nss/gtests/ssl_gtest/tls_agent.cc
+++ b/security/nss/gtests/ssl_gtest/tls_agent.cc
@@ -382,17 +382,17 @@ void TlsAgent::SetShortHeadersEnabled() 
 
   SECStatus rv = SSLInt_EnableShortHeaders(ssl_fd());
   EXPECT_EQ(SECSuccess, rv);
 }
 
 void TlsAgent::SetAltHandshakeTypeEnabled() {
   EXPECT_TRUE(EnsureTlsSetup());
 
-  SECStatus rv = SSL_UseAltHandshakeType(ssl_fd(), PR_TRUE);
+  SECStatus rv = SSL_UseAltServerHelloType(ssl_fd(), true);
   EXPECT_EQ(SECSuccess, rv);
 }
 
 void TlsAgent::SetVersionRange(uint16_t minver, uint16_t maxver) {
   vrange_.min = minver;
   vrange_.max = maxver;
 
   if (ssl_fd()) {
--- a/security/nss/gtests/ssl_gtest/tls_filter.cc
+++ b/security/nss/gtests/ssl_gtest/tls_filter.cc
@@ -358,25 +358,16 @@ PacketFilter::Action TlsInspectorReplace
   if (header.handshake_type() == handshake_type_) {
     *output = buffer_;
     return CHANGE;
   }
 
   return KEEP;
 }
 
-PacketFilter::Action TlsRecordRecorder::FilterRecord(
-    const TlsRecordHeader& header, const DataBuffer& input,
-    DataBuffer* output) {
-  if (!filter_ || (header.content_type() == ct_)) {
-    records_.push_back({header, input});
-  }
-  return KEEP;
-}
-
 PacketFilter::Action TlsConversationRecorder::FilterRecord(
     const TlsRecordHeader& header, const DataBuffer& input,
     DataBuffer* output) {
   buffer_.Append(input);
   return KEEP;
 }
 
 PacketFilter::Action TlsHeaderRecorder::FilterRecord(
--- a/security/nss/gtests/ssl_gtest/tls_filter.h
+++ b/security/nss/gtests/ssl_gtest/tls_filter.h
@@ -58,21 +58,16 @@ class TlsRecordHeader : public TlsVersio
   // Return the offset of the end of the write.
   size_t Write(DataBuffer* buffer, size_t offset, const DataBuffer& body) const;
 
  private:
   uint8_t content_type_;
   uint64_t sequence_number_;
 };
 
-struct TlsRecord {
-  const TlsRecordHeader header;
-  const DataBuffer buffer;
-};
-
 // Abstract filter that operates on entire (D)TLS records.
 class TlsRecordFilter : public PacketFilter {
  public:
   TlsRecordFilter() : agent_(nullptr), count_(0), cipher_spec_() {}
 
   void SetAgent(const TlsAgent* agent) { agent_ = agent; }
   const TlsAgent* agent() const { return agent_; }
 
@@ -221,38 +216,16 @@ class TlsInspectorReplaceHandshakeMessag
                                                const DataBuffer& input,
                                                DataBuffer* output);
 
  private:
   uint8_t handshake_type_;
   DataBuffer buffer_;
 };
 
-class TlsRecordRecorder : public TlsRecordFilter {
- public:
-  TlsRecordRecorder(uint8_t ct) : filter_(true), ct_(ct), records_() {}
-  TlsRecordRecorder()
-      : filter_(false),
-        ct_(content_handshake),  // dummy (<optional> is C++14)
-        records_() {}
-  virtual PacketFilter::Action FilterRecord(const TlsRecordHeader& header,
-                                            const DataBuffer& input,
-                                            DataBuffer* output);
-
-  size_t count() const { return records_.size(); }
-  void Clear() { records_.clear(); }
-
-  const TlsRecord& record(size_t i) const { return records_[i]; }
-
- private:
-  bool filter_;
-  uint8_t ct_;
-  std::vector<TlsRecord> records_;
-};
-
 // Make a copy of the complete conversation.
 class TlsConversationRecorder : public TlsRecordFilter {
  public:
   TlsConversationRecorder(DataBuffer& buffer) : buffer_(buffer) {}
 
   virtual PacketFilter::Action FilterRecord(const TlsRecordHeader& header,
                                             const DataBuffer& input,
                                             DataBuffer* output);
@@ -269,26 +242,21 @@ class TlsHeaderRecorder : public TlsReco
                                             DataBuffer* output);
   const TlsRecordHeader* header(size_t index);
 
  private:
   std::vector<TlsRecordHeader> headers_;
 };
 
 // Runs multiple packet filters in series.
-typedef std::initializer_list<std::shared_ptr<PacketFilter>>
-    ChainedPacketFilterInit;
-
-// Runs multiple packet filters in series.
 class ChainedPacketFilter : public PacketFilter {
  public:
   ChainedPacketFilter() {}
   ChainedPacketFilter(const std::vector<std::shared_ptr<PacketFilter>> filters)
       : filters_(filters.begin(), filters.end()) {}
-  ChainedPacketFilter(ChainedPacketFilterInit il) : filters_(il) {}
   virtual ~ChainedPacketFilter() {}
 
   virtual PacketFilter::Action Filter(const DataBuffer& input,
                                       DataBuffer* output);
 
   // Takes ownership of the filter.
   void Add(std::shared_ptr<PacketFilter> filter) { filters_.push_back(filter); }
 
--- a/security/nss/lib/freebl/poly1305.h
+++ b/security/nss/lib/freebl/poly1305.h
@@ -3,18 +3,16 @@
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef FREEBL_POLY1305_H_
 #define FREEBL_POLY1305_H_
 
-#include "stddef.h"
-
 typedef unsigned char poly1305_state[512];
 
 /* Poly1305Init sets up |state| so that it can be used to calculate an
  * authentication tag with the one-time key |key|. Note that |key| is a
  * one-time key and therefore there is no `reset' method because that would
  * enable several messages to be authenticated with the same key. */
 extern void Poly1305Init(poly1305_state* state, const unsigned char key[32]);
 
--- a/security/nss/lib/nss/nss.h
+++ b/security/nss/lib/nss/nss.h
@@ -17,19 +17,19 @@
 
 /*
  * NSS's major version, minor version, patch level, build number, and whether
  * this is a beta release.
  *
  * The format of the version string should be
  *     "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
  */
-#define NSS_VERSION "3.35" _NSS_CUSTOMIZED " Beta"
+#define NSS_VERSION "3.34" _NSS_CUSTOMIZED " Beta"
 #define NSS_VMAJOR 3
-#define NSS_VMINOR 35
+#define NSS_VMINOR 34
 #define NSS_VPATCH 0
 #define NSS_VBUILD 0
 #define NSS_BETA PR_TRUE
 
 #ifndef RC_INVOKED
 
 #include "seccomon.h"
 
--- a/security/nss/lib/softoken/pkcs11.c
+++ b/security/nss/lib/softoken/pkcs11.c
@@ -416,30 +416,21 @@ static const struct mechanismList mechan
     { CKM_IDEA_ECB, { 16, 16, CKF_EN_DE_WR_UN }, PR_TRUE },
     { CKM_IDEA_CBC, { 16, 16, CKF_EN_DE_WR_UN }, PR_TRUE },
     { CKM_IDEA_MAC, { 16, 16, CKF_SN_VR }, PR_TRUE },
     { CKM_IDEA_MAC_GENERAL, { 16, 16, CKF_SN_VR }, PR_TRUE },
     { CKM_IDEA_CBC_PAD, { 16, 16, CKF_EN_DE_WR_UN }, PR_TRUE },
 #endif
     /* --------------------- Secret Key Operations ------------------------ */
     { CKM_GENERIC_SECRET_KEY_GEN, { 1, 32, CKF_GENERATE }, PR_TRUE },
-    { CKM_CONCATENATE_BASE_AND_KEY, { 1, 32, CKF_DERIVE }, PR_FALSE },
-    { CKM_CONCATENATE_BASE_AND_DATA, { 1, 32, CKF_DERIVE }, PR_FALSE },
-    { CKM_CONCATENATE_DATA_AND_BASE, { 1, 32, CKF_DERIVE }, PR_FALSE },
-    { CKM_XOR_BASE_AND_DATA, { 1, 32, CKF_DERIVE }, PR_FALSE },
+    { CKM_CONCATENATE_BASE_AND_KEY, { 1, 32, CKF_GENERATE }, PR_FALSE },
+    { CKM_CONCATENATE_BASE_AND_DATA, { 1, 32, CKF_GENERATE }, PR_FALSE },
+    { CKM_CONCATENATE_DATA_AND_BASE, { 1, 32, CKF_GENERATE }, PR_FALSE },
+    { CKM_XOR_BASE_AND_DATA, { 1, 32, CKF_GENERATE }, PR_FALSE },
     { CKM_EXTRACT_KEY_FROM_KEY, { 1, 32, CKF_DERIVE }, PR_FALSE },
-    { CKM_DES3_ECB_ENCRYPT_DATA, { 1, 32, CKF_DERIVE }, PR_FALSE },
-    { CKM_DES3_CBC_ENCRYPT_DATA, { 1, 32, CKF_DERIVE }, PR_FALSE },
-    { CKM_AES_ECB_ENCRYPT_DATA, { 1, 32, CKF_DERIVE }, PR_FALSE },
-    { CKM_AES_CBC_ENCRYPT_DATA, { 1, 32, CKF_DERIVE }, PR_FALSE },
-    { CKM_CAMELLIA_ECB_ENCRYPT_DATA, { 1, 32, CKF_DERIVE }, PR_FALSE },
-    { CKM_CAMELLIA_CBC_ENCRYPT_DATA, { 1, 32, CKF_DERIVE }, PR_FALSE },
-    { CKM_SEED_ECB_ENCRYPT_DATA, { 1, 32, CKF_DERIVE }, PR_FALSE },
-    { CKM_SEED_CBC_ENCRYPT_DATA, { 1, 32, CKF_DERIVE }, PR_FALSE },
-
     /* ---------------------- SSL Key Derivations ------------------------- */
     { CKM_SSL3_PRE_MASTER_KEY_GEN, { 48, 48, CKF_GENERATE }, PR_FALSE },
     { CKM_SSL3_MASTER_KEY_DERIVE, { 48, 48, CKF_DERIVE }, PR_FALSE },
     { CKM_SSL3_MASTER_KEY_DERIVE_DH, { 8, 128, CKF_DERIVE }, PR_FALSE },
     { CKM_SSL3_KEY_AND_MAC_DERIVE, { 48, 48, CKF_DERIVE }, PR_FALSE },
     { CKM_SSL3_MD5_MAC, { 0, 16, CKF_DERIVE }, PR_FALSE },
     { CKM_SSL3_SHA1_MAC, { 0, 20, CKF_DERIVE }, PR_FALSE },
     { CKM_MD5_KEY_DERIVATION, { 0, 16, CKF_DERIVE }, PR_FALSE },
--- a/security/nss/lib/softoken/pkcs11c.c
+++ b/security/nss/lib/softoken/pkcs11c.c
@@ -1519,17 +1519,18 @@ NSC_DecryptUpdate(CK_SESSION_HANDLE hSes
             rv = (*context->update)(context->cipherInfo, pPart, &padoutlen,
                                     maxout, context->padBuf, context->blockSize);
             if (rv != SECSuccess)
                 return sftk_MapDecryptError(PORT_GetError());
             pPart += padoutlen;
             maxout -= padoutlen;
         }
         /* now save the final block for the next decrypt or the final */
-        PORT_Memcpy(context->padBuf, &pEncryptedPart[ulEncryptedPartLen - context->blockSize],
+        PORT_Memcpy(context->padBuf, &pEncryptedPart[ulEncryptedPartLen -
+                                                     context->blockSize],
                     context->blockSize);
         context->padDataLength = context->blockSize;
         ulEncryptedPartLen -= context->padDataLength;
     }
 
     /* do it: NOTE: this assumes buf size in is >= buf size out! */
     rv = (*context->update)(context->cipherInfo, pPart, &outlen,
                             maxout, pEncryptedPart, ulEncryptedPartLen);
@@ -6236,53 +6237,16 @@ sftk_ANSI_X9_63_kdf(CK_BYTE **key, CK_UL
     else if (kdf == CKD_SHA512_KDF)
         return sftk_compute_ANSI_X9_63_kdf(key, key_len, SharedSecret, SharedInfo,
                                            SharedInfoLen, SHA512_HashBuf, SHA512_LENGTH);
     else
         return CKR_MECHANISM_INVALID;
 }
 
 /*
- *  Handle the derive from a block encryption cipher
- */
-CK_RV
-sftk_DeriveEncrypt(SFTKCipher encrypt, void *cipherInfo,
-                   int blockSize, SFTKObject *key, CK_ULONG keySize,
-                   unsigned char *data, CK_ULONG len)
-{
-    /* large enough for a 512-bit key */
-    unsigned char tmpdata[SFTK_MAX_DERIVE_KEY_SIZE];
-    SECStatus rv;
-    unsigned int outLen;
-    CK_RV crv;
-
-    if ((len % blockSize) != 0) {
-        return CKR_MECHANISM_PARAM_INVALID;
-    }
-    if (len > SFTK_MAX_DERIVE_KEY_SIZE) {
-        return CKR_MECHANISM_PARAM_INVALID;
-    }
-    if (keySize && (len < keySize)) {
-        return CKR_MECHANISM_PARAM_INVALID;
-    }
-    if (keySize == 0) {
-        keySize = len;
-    }
-
-    rv = (*encrypt)(cipherInfo, &tmpdata, &outLen, len, data, len);
-    if (rv != SECSuccess) {
-        crv = sftk_MapCryptError(PORT_GetError());
-        return crv;
-    }
-
-    crv = sftk_forceAttribute(key, CKA_VALUE, tmpdata, keySize);
-    return crv;
-}
-
-/*
  * SSL Key generation given pre master secret
  */
 #define NUM_MIXERS 9
 static const char *const mixers[NUM_MIXERS] = {
     "A",
     "BB",
     "CCC",
     "DDDD",
@@ -6930,182 +6894,16 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession
             }
             MD5_DestroyContext(md5, PR_TRUE);
             SHA1_DestroyContext(sha, PR_TRUE);
             sftk_FreeObject(key);
             key = NULL;
             break;
         }
 
-        case CKM_DES3_ECB_ENCRYPT_DATA:
-        case CKM_DES3_CBC_ENCRYPT_DATA: {
-            void *cipherInfo;
-            unsigned char des3key[MAX_DES3_KEY_SIZE];
-            CK_DES_CBC_ENCRYPT_DATA_PARAMS *desEncryptPtr;
-            int mode;
-            unsigned char *iv;
-            unsigned char *data;
-            CK_ULONG len;
-
-            if (mechanism == CKM_DES3_ECB_ENCRYPT_DATA) {
-                stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)
-                                pMechanism->pParameter;
-                mode = NSS_DES_EDE3;
-                iv = NULL;
-                data = stringPtr->pData;
-                len = stringPtr->ulLen;
-            } else {
-                mode = NSS_DES_EDE3_CBC;
-                desEncryptPtr =
-                    (CK_DES_CBC_ENCRYPT_DATA_PARAMS *)
-                        pMechanism->pParameter;
-                iv = desEncryptPtr->iv;
-                data = desEncryptPtr->pData;
-                len = desEncryptPtr->length;
-            }
-            if (att->attrib.ulValueLen == 16) {
-                PORT_Memcpy(des3key, att->attrib.pValue, 16);
-                PORT_Memcpy(des3key + 16, des3key, 8);
-            } else if (att->attrib.ulValueLen == 24) {
-                PORT_Memcpy(des3key, att->attrib.pValue, 24);
-            } else {
-                crv = CKR_KEY_SIZE_RANGE;
-                break;
-            }
-            cipherInfo = DES_CreateContext(des3key, iv, mode, PR_TRUE);
-            PORT_Memset(des3key, 0, 24);
-            if (cipherInfo == NULL) {
-                crv = CKR_HOST_MEMORY;
-                break;
-            }
-            crv = sftk_DeriveEncrypt((SFTKCipher)DES_Encrypt,
-                                     cipherInfo, 8, key, keySize,
-                                     data, len);
-            DES_DestroyContext(cipherInfo, PR_TRUE);
-            break;
-        }
-
-        case CKM_AES_ECB_ENCRYPT_DATA:
-        case CKM_AES_CBC_ENCRYPT_DATA: {
-            void *cipherInfo;
-            CK_AES_CBC_ENCRYPT_DATA_PARAMS *aesEncryptPtr;
-            int mode;
-            unsigned char *iv;
-            unsigned char *data;
-            CK_ULONG len;
-
-            if (mechanism == CKM_AES_ECB_ENCRYPT_DATA) {
-                mode = NSS_AES;
-                iv = NULL;
-                stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)pMechanism->pParameter;
-                data = stringPtr->pData;
-                len = stringPtr->ulLen;
-            } else {
-                aesEncryptPtr =
-                    (CK_AES_CBC_ENCRYPT_DATA_PARAMS *)pMechanism->pParameter;
-                mode = NSS_AES_CBC;
-                iv = aesEncryptPtr->iv;
-                data = aesEncryptPtr->pData;
-                len = aesEncryptPtr->length;
-            }
-
-            cipherInfo = AES_CreateContext((unsigned char *)att->attrib.pValue,
-                                           iv, mode, PR_TRUE,
-                                           att->attrib.ulValueLen, 16);
-            if (cipherInfo == NULL) {
-                crv = CKR_HOST_MEMORY;
-                break;
-            }
-            crv = sftk_DeriveEncrypt((SFTKCipher)AES_Encrypt,
-                                     cipherInfo, 16, key, keySize,
-                                     data, len);
-            AES_DestroyContext(cipherInfo, PR_TRUE);
-            break;
-        }
-
-        case CKM_CAMELLIA_ECB_ENCRYPT_DATA:
-        case CKM_CAMELLIA_CBC_ENCRYPT_DATA: {
-            void *cipherInfo;
-            CK_AES_CBC_ENCRYPT_DATA_PARAMS *aesEncryptPtr;
-            int mode;
-            unsigned char *iv;
-            unsigned char *data;
-            CK_ULONG len;
-
-            if (mechanism == CKM_CAMELLIA_ECB_ENCRYPT_DATA) {
-                stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)
-                                pMechanism->pParameter;
-                aesEncryptPtr = NULL;
-                mode = NSS_CAMELLIA;
-                data = stringPtr->pData;
-                len = stringPtr->ulLen;
-                iv = NULL;
-            } else {
-                stringPtr = NULL;
-                aesEncryptPtr = (CK_AES_CBC_ENCRYPT_DATA_PARAMS *)
-                                    pMechanism->pParameter;
-                mode = NSS_CAMELLIA_CBC;
-                iv = aesEncryptPtr->iv;
-                data = aesEncryptPtr->pData;
-                len = aesEncryptPtr->length;
-            }
-
-            cipherInfo = Camellia_CreateContext((unsigned char *)att->attrib.pValue,
-                                                iv, mode, PR_TRUE,
-                                                att->attrib.ulValueLen);
-            if (cipherInfo == NULL) {
-                crv = CKR_HOST_MEMORY;
-                break;
-            }
-            crv = sftk_DeriveEncrypt((SFTKCipher)Camellia_Encrypt,
-                                     cipherInfo, 16, key, keySize,
-                                     data, len);
-            Camellia_DestroyContext(cipherInfo, PR_TRUE);
-            break;
-        }
-
-        case CKM_SEED_ECB_ENCRYPT_DATA:
-        case CKM_SEED_CBC_ENCRYPT_DATA: {
-            void *cipherInfo;
-            CK_AES_CBC_ENCRYPT_DATA_PARAMS *aesEncryptPtr;
-            int mode;
-            unsigned char *iv;
-            unsigned char *data;
-            CK_ULONG len;
-
-            if (mechanism == CKM_SEED_ECB_ENCRYPT_DATA) {
-                mode = NSS_SEED;
-                stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)
-                                pMechanism->pParameter;
-                aesEncryptPtr = NULL;
-                data = stringPtr->pData;
-                len = stringPtr->ulLen;
-                iv = NULL;
-            } else {
-                mode = NSS_SEED_CBC;
-                aesEncryptPtr = (CK_AES_CBC_ENCRYPT_DATA_PARAMS *)
-                                    pMechanism->pParameter;
-                iv = aesEncryptPtr->iv;
-                data = aesEncryptPtr->pData;
-                len = aesEncryptPtr->length;
-            }
-
-            cipherInfo = SEED_CreateContext((unsigned char *)att->attrib.pValue,
-                                            iv, mode, PR_TRUE);
-            if (cipherInfo == NULL) {
-                crv = CKR_HOST_MEMORY;
-                break;
-            }
-            crv = sftk_DeriveEncrypt((SFTKCipher)SEED_Encrypt,
-                                     cipherInfo, 16, key, keySize,
-                                     data, len);
-            SEED_DestroyContext(cipherInfo, PR_TRUE);
-            break;
-        }
-
         case CKM_CONCATENATE_BASE_AND_KEY: {
             SFTKObject *newKey;
 
             crv = sftk_DeriveSensitiveCheck(sourceKey, key);
             if (crv != CKR_OK)
                 break;
 
             session = sftk_SessionFromHandle(hSession);
--- a/security/nss/lib/softoken/softkver.h
+++ b/security/nss/lib/softoken/softkver.h
@@ -12,16 +12,16 @@
 
 /*
  * Softoken's major version, minor version, patch level, build number,
  * and whether this is a beta release.
  *
  * The format of the version string should be
  *     "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
  */
-#define SOFTOKEN_VERSION "3.35" SOFTOKEN_ECC_STRING " Beta"
+#define SOFTOKEN_VERSION "3.34" SOFTOKEN_ECC_STRING " Beta"
 #define SOFTOKEN_VMAJOR 3
-#define SOFTOKEN_VMINOR 35
+#define SOFTOKEN_VMINOR 34
 #define SOFTOKEN_VPATCH 0
 #define SOFTOKEN_VBUILD 0
 #define SOFTOKEN_BETA PR_TRUE
 
 #endif /* _SOFTKVER_H_ */
--- a/security/nss/lib/softoken/softoknt.h
+++ b/security/nss/lib/softoken/softoknt.h
@@ -4,19 +4,16 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef _SOFTOKNT_H_
 #define _SOFTOKNT_H_
 
 #define NSS_SOFTOKEN_DEFAULT_CHUNKSIZE 2048
-#define DES_BLOCK_SIZE 8     /* bytes */
-#define MAX_DES3_KEY_SIZE 24 /* DES_BLOCK_SIZE * 3 */
-#define SFTK_MAX_DERIVE_KEY_SIZE 64
 
 /*
  * FIPS 140-2 auditing
  */
 typedef enum {
     NSS_AUDIT_ERROR = 3,   /* errors */
     NSS_AUDIT_WARNING = 2, /* warning messages */
     NSS_AUDIT_INFO = 1     /* informational messages */
--- a/security/nss/lib/ssl/ssl3con.c
+++ b/security/nss/lib/ssl/ssl3con.c
@@ -1,8 +1,9 @@
+
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /*
  * SSL3 Protocol
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
@@ -1041,29 +1042,16 @@ Null_Cipher(void *ctx, unsigned char *ou
     }
     return SECSuccess;
 }
 
 /*
  * SSL3 Utility functions
  */
 
-static void
-ssl_SetSpecVersions(sslSocket *ss, ssl3CipherSpec *spec)
-{
-    spec->version = ss->version;
-    if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) {
-        tls13_SetSpecRecordVersion(ss, spec);
-    } else if (IS_DTLS(ss)) {
-        spec->recordVersion = dtls_TLSVersionToDTLSVersion(ss->version);
-    } else {
-        spec->recordVersion = ss->version;
-    }
-}
-
 /* allowLargerPeerVersion controls whether the function will select the
  * highest enabled SSL version or fail when peerVersion is greater than the
  * highest enabled version.
  *
  * If allowLargerPeerVersion is true, peerVersion is the peer's highest
  * enabled version rather than the peer's selected version.
  */
 SECStatus
@@ -1103,48 +1091,49 @@ ssl_ClientReadVersion(sslSocket *ss, PRU
     }
 
 #ifdef TLS_1_3_DRAFT_VERSION
     if (temp == SSL_LIBRARY_VERSION_TLS_1_3) {
         (void)SSL3_SendAlert(ss, alert_fatal, protocol_version);
         PORT_SetError(SSL_ERROR_UNSUPPORTED_VERSION);
         return SECFailure;
     }
-    if (temp == tls13_EncodeDraftVersion(SSL_LIBRARY_VERSION_TLS_1_3)) {
-        v = SSL_LIBRARY_VERSION_TLS_1_3;
-    } else if (temp == tls13_EncodeAltDraftVersion(SSL_LIBRARY_VERSION_TLS_1_3)) {
-        if (!ss->opt.enableAltHandshaketype || IS_DTLS(ss)) {
-            (void)SSL3_SendAlert(ss, alert_fatal, protocol_version);
-            PORT_SetError(SSL_ERROR_UNSUPPORTED_VERSION);
-            return SECFailure;
-        }
-        ss->ssl3.hs.altHandshakeType = PR_TRUE;
+    if (temp == tls13_EncodeDraftVersion(SSL_LIBRARY_VERSION_TLS_1_3) || (ss->opt.enableAltHandshaketype &&
+                                                                          (temp == tls13_EncodeAltDraftVersion(SSL_LIBRARY_VERSION_TLS_1_3)))) {
         v = SSL_LIBRARY_VERSION_TLS_1_3;
     } else {
         v = (SSL3ProtocolVersion)temp;
     }
 #else
     v = (SSL3ProtocolVersion)temp;
 #endif
 
     if (IS_DTLS(ss)) {
         /* If this fails, we get 0 back and the next check to fails. */
         v = dtls_DTLSVersionToTLSVersion(v);
     }
 
+    PORT_Assert(!SSL_ALL_VERSIONS_DISABLED(&ss->vrange));
+    if (ss->vrange.min > v || ss->vrange.max < v) {
+        (void)SSL3_SendAlert(ss, alert_fatal,
+                             (v > SSL_LIBRARY_VERSION_3_0) ? protocol_version
+                                                           : handshake_failure);
+        PORT_SetError(SSL_ERROR_UNSUPPORTED_VERSION);
+        return SECFailure;
+    }
     *version = v;
     return SECSuccess;
 }
 
 static SECStatus
-ssl3_GetNewRandom(SSL3Random random)
+ssl3_GetNewRandom(SSL3Random *random)
 {
     SECStatus rv;
 
-    rv = PK11_GenerateRandom(random, SSL3_RANDOM_LENGTH);
+    rv = PK11_GenerateRandom(random->rand, SSL3_RANDOM_LENGTH);
     if (rv != SECSuccess) {
         ssl_MapLowLevelError(SSL_ERROR_GENERATE_RANDOM_FAILURE);
     }
     return rv;
 }
 
 /* Called by ssl3_SendServerKeyExchange and ssl3_SendCertificateVerify */
 SECStatus
@@ -1458,19 +1447,19 @@ ssl3_ComputeDHKeyHash(sslSocket *ss, SSL
         hashBuf = buf;
     } else {
         hashBuf = PORT_Alloc(bufLen);
         if (!hashBuf) {
             return SECFailure;
         }
     }
 
-    memcpy(hashBuf, ss->ssl3.hs.client_random, SSL3_RANDOM_LENGTH);
+    memcpy(hashBuf, &ss->ssl3.hs.client_random, SSL3_RANDOM_LENGTH);
     pBuf = hashBuf + SSL3_RANDOM_LENGTH;
-    memcpy(pBuf, ss->ssl3.hs.server_random, SSL3_RANDOM_LENGTH);
+    memcpy(pBuf, &ss->ssl3.hs.server_random, SSL3_RANDOM_LENGTH);
     pBuf += SSL3_RANDOM_LENGTH;
     pBuf = ssl_EncodeUintX(dh_p.len, 2, pBuf);
     memcpy(pBuf, dh_p.data, dh_p.len);
     pBuf += dh_p.len;
     pBuf = ssl_EncodeUintX(dh_g.len, 2, pBuf);
     memcpy(pBuf, dh_g.data, dh_g.len);
     pBuf += dh_g.len;
     pBuf = ssl_EncodeUintX(yLen, 2, pBuf);
@@ -1586,17 +1575,17 @@ ssl3_SetupPendingCipherSpec(sslSocket *s
 
     /* This hack provides maximal interoperability with SSL 3 servers. */
     cwSpec = ss->ssl3.cwSpec;
     if (cwSpec->mac_def->mac == mac_null) {
         /* SSL records are not being MACed. */
         cwSpec->version = ss->version;
     }
 
-    ssl_SetSpecVersions(ss, ss->ssl3.pwSpec);
+    pwSpec->version = ss->version;
     isTLS = (PRBool)(pwSpec->version > SSL_LIBRARY_VERSION_3_0);
 
     SSL_TRC(3, ("%d: SSL3[%d]: Set XXX Pending Cipher Suite to 0x%04x",
                 SSL_GETPID(), ss->fd, suite));
 
     suite_def = ssl_LookupCipherSuiteDef(suite);
     if (suite_def == NULL) {
         ssl_ReleaseSpecWriteLock(ss);
@@ -1781,58 +1770,61 @@ ssl3_InitCompressionContext(ssl3CipherSp
 }
 
 /* ssl3_BuildRecordPseudoHeader writes the SSL/TLS pseudo-header (the data
  * which is included in the MAC or AEAD additional data) to |out| and returns
  * its length. See https://tools.ietf.org/html/rfc5246#section-6.2.3.3 for the
  * definition of the AEAD additional data.
  *
  * TLS pseudo-header includes the record's version field, SSL's doesn't. Which
- * pseudo-header definition to use should be decided based on the version of
+ * pseudo-header defintiion to use should be decided based on the version of
  * the protocol that was negotiated when the cipher spec became current, NOT
  * based on the version value in the record itself, and the decision is passed
  * to this function as the |includesVersion| argument. But, the |version|
  * argument should be the record's version value.
  */
-static SECStatus
-ssl3_BuildRecordPseudoHeader(PRUint8 *out, DTLSEpoch epoch,
+static unsigned int
+ssl3_BuildRecordPseudoHeader(unsigned char *out,
                              sslSequenceNumber seq_num,
                              SSL3ContentType type,
                              PRBool includesVersion,
                              SSL3ProtocolVersion version,
                              PRBool isDTLS,
                              int length)
 {
-    if (isDTLS) {
-        out[0] = (unsigned char)(epoch >> 8);
-        out[1] = (unsigned char)(epoch >> 0);
-    } else {
-        out[0] = (unsigned char)(seq_num >> 56);
-        out[1] = (unsigned char)(seq_num >> 48);
-    }
+    out[0] = (unsigned char)(seq_num >> 56);
+    out[1] = (unsigned char)(seq_num >> 48);
     out[2] = (unsigned char)(seq_num >> 40);
     out[3] = (unsigned char)(seq_num >> 32);
     out[4] = (unsigned char)(seq_num >> 24);
     out[5] = (unsigned char)(seq_num >> 16);
     out[6] = (unsigned char)(seq_num >> 8);
     out[7] = (unsigned char)(seq_num >> 0);
     out[8] = type;
 
     /* SSL3 MAC doesn't include the record's version field. */
     if (!includesVersion) {
         out[9] = MSB(length);
         out[10] = LSB(length);
         return 11;
     }
+
     /* TLS MAC and AEAD additional data include version. */
-    out[9] = MSB(version);
-    out[10] = LSB(version);
+    if (isDTLS) {
+        SSL3ProtocolVersion dtls_version;
+
+        dtls_version = dtls_TLSVersionToDTLSVersion(version);
+        out[9] = MSB(dtls_version);
+        out[10] = LSB(dtls_version);
+    } else {
+        out[9] = MSB(version);
+        out[10] = LSB(version);
+    }
     out[11] = MSB(length);
     out[12] = LSB(length);
-    PRINT_BUF(50, (NULL, "Pseudoheader", out, 13));
     return 13;
 }
 
 static SECStatus
 ssl3_AESGCM(ssl3KeyMaterial *keys,
             PRBool doDecrypt,
             unsigned char *out,
             int *outlen,
@@ -2376,16 +2368,17 @@ ssl3_ClientAuthTokenPresent(sslSessionID
     return isPresent;
 }
 
 /* Caller must hold the spec read lock. */
 SECStatus
 ssl3_CompressMACEncryptRecord(ssl3CipherSpec *cwSpec,
                               PRBool isServer,
                               PRBool isDTLS,
+                              PRBool capRecordVersion,
                               SSL3ContentType type,
                               const PRUint8 *pIn,
                               PRUint32 contentLen,
                               sslBuffer *wrBuf)
 {
     const ssl3BulkCipherDef *cipher_def;
     SECStatus rv;
     PRUint32 macLen = 0;
@@ -2432,18 +2425,18 @@ ssl3_CompressMACEncryptRecord(ssl3Cipher
                                 &outlen, wrBuf->space - ivLen, pIn, contentLen);
         if (rv != SECSuccess)
             return rv;
         pIn = wrBuf->buf + ivLen;
         contentLen = outlen;
     }
 
     pseudoHeaderLen = ssl3_BuildRecordPseudoHeader(
-        pseudoHeader, cwSpec->epoch, cwSpec->write_seq_num, type,
-        cwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_0, cwSpec->recordVersion,
+        pseudoHeader, cwSpec->write_seq_num, type,
+        cwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_0, cwSpec->version,
         isDTLS, contentLen);
     PORT_Assert(pseudoHeaderLen <= sizeof(pseudoHeader));
     if (cipher_def->type == type_aead) {
         const int nonceLen = cipher_def->explicit_nonce_size;
         const int tagLen = cipher_def->tag_size;
 
         if (nonceLen + contentLen + tagLen > wrBuf->space) {
             PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
@@ -2544,22 +2537,24 @@ ssl3_CompressMACEncryptRecord(ssl3Cipher
             wrBuf->len += cipherBytesPart2;
         }
     }
 
     return SECSuccess;
 }
 
 SECStatus
-ssl_ProtectRecord(sslSocket *ss, ssl3CipherSpec *cwSpec, SSL3ContentType type,
+ssl_ProtectRecord(sslSocket *ss, ssl3CipherSpec *cwSpec,
+                  PRBool capRecordVersion, SSL3ContentType type,
                   const PRUint8 *pIn, PRUint32 contentLen, sslBuffer *wrBuf)
 {
     const ssl3BulkCipherDef *cipher_def = cwSpec->cipher_def;
     PRUint16 headerLen;
     sslBuffer protBuf;
+    SSL3ProtocolVersion version = cwSpec->version;
     PRBool isTLS13;
     PRUint8 *ptr = wrBuf->buf;
     SECStatus rv;
 
     if (ss->ssl3.hs.shortHeaders) {
         PORT_Assert(!IS_DTLS(ss));
         PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3);
         headerLen = TLS13_RECORD_HEADER_LENGTH_SHORT;
@@ -2583,17 +2578,17 @@ ssl_ProtectRecord(sslSocket *ss, ssl3Cip
 #ifdef UNSAFE_FUZZER_MODE
     rv = Null_Cipher(NULL, protBuf.buf, (int *)&protBuf.len, protBuf.space,
                      pIn, contentLen);
 #else
     if (isTLS13) {
         rv = tls13_ProtectRecord(ss, cwSpec, type, pIn, contentLen, &protBuf);
     } else {
         rv = ssl3_CompressMACEncryptRecord(cwSpec, ss->sec.isServer,
-                                           IS_DTLS(ss), type,
+                                           IS_DTLS(ss), capRecordVersion, type,
                                            pIn, contentLen, &protBuf);
     }
 #endif
     if (rv != SECSuccess) {
         return SECFailure; /* error was set */
     }
 
     PORT_Assert(protBuf.len <= MAX_FRAGMENT_LENGTH + (isTLS13 ? 256 : 1024));
@@ -2607,27 +2602,35 @@ ssl_ProtectRecord(sslSocket *ss, ssl3Cip
         if (isTLS13 && cipher_def->calg != ssl_calg_null) {
             *ptr++ = content_application_data;
         } else
 #endif
         {
             *ptr++ = type;
         }
 
-        ptr = ssl_EncodeUintX(cwSpec->recordVersion, 2, ptr);
         if (IS_DTLS(ss)) {
-            ptr = ssl_EncodeUintX(cwSpec->epoch, 2, ptr);
-            ptr = ssl_EncodeUintX(cwSpec->write_seq_num, 6, ptr);
+            version = isTLS13 ? SSL_LIBRARY_VERSION_TLS_1_1 : version;
+            version = dtls_TLSVersionToDTLSVersion(version);
+
+            ptr = ssl_EncodeUintX(version, 2, ptr);
+            ptr = ssl_EncodeUintX(cwSpec->write_seq_num, 8, ptr);
+        } else {
+            if (capRecordVersion || isTLS13) {
+                version = PR_MIN(SSL_LIBRARY_VERSION_TLS_1_0, version);
+            }
+            ptr = ssl_EncodeUintX(version, 2, ptr);
         }
         (void)ssl_EncodeUintX(protBuf.len, 2, ptr);
     }
     ++cwSpec->write_seq_num;
 
     return SECSuccess;
 }
+
 /* Process the plain text before sending it.
  * Returns the number of bytes of plaintext that were successfully sent
  *  plus the number of bytes of plaintext that were copied into the
  *  output (write) buffer.
  * Returns SECFailure on a hard IO error, memory error, or crypto error.
  * Does NOT return SECWouldBlock.
  *
  * Notes on the use of the private ssl flags:
@@ -2638,43 +2641,65 @@ ssl_ProtectRecord(sslSocket *ss, ssl3Cip
  *    then buffer remaining bytes of ciphertext into pending buf,
  *    and continue to do that for all succssive records until all
  *    bytes are used.
  * ssl_SEND_FLAG_FORCE_INTO_BUFFER
  *    As above, except this suppresses all write attempts, and forces
  *    all ciphertext into the pending ciphertext buffer.
  * ssl_SEND_FLAG_USE_EPOCH (for DTLS)
  *    Forces the use of the provided epoch
+ * ssl_SEND_FLAG_CAP_RECORD_VERSION
+ *    Caps the record layer version number of TLS ClientHello to { 3, 1 }
+ *    (TLS 1.0). Some TLS 1.0 servers (which seem to use F5 BIG-IP) ignore
+ *    ClientHello.client_version and use the record layer version number
+ *    (TLSPlaintext.version) instead when negotiating protocol versions. In
+ *    addition, if the record layer version number of ClientHello is { 3, 2 }
+ *    (TLS 1.1) or higher, these servers reset the TCP connections. Lastly,
+ *    some F5 BIG-IP servers hang if a record containing a ClientHello has a
+ *    version greater than { 3, 1 } and a length greater than 255. Set this
+ *    flag to work around such servers.
  */
 PRInt32
 ssl3_SendRecord(sslSocket *ss,
                 ssl3CipherSpec *cwSpec, /* non-NULL for DTLS retransmits */
                 SSL3ContentType type,
                 const PRUint8 *pIn, /* input buffer */
                 PRInt32 nIn,        /* bytes of input */
                 PRInt32 flags)
 {
     sslBuffer *wrBuf = &ss->sec.writeBuf;
     SECStatus rv;
     PRInt32 totalSent = 0;
+    PRBool capRecordVersion;
     ssl3CipherSpec *spec;
 
     SSL_TRC(3, ("%d: SSL3[%d] SendRecord type: %s nIn=%d",
                 SSL_GETPID(), ss->fd, ssl3_DecodeContentType(type),
                 nIn));
     PRINT_BUF(50, (ss, "Send record (plain text)", pIn, nIn));
 
     PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
 
     if (ss->ssl3.fatalAlertSent) {
         SSL_TRC(3, ("%d: SSL3[%d] Suppress write, fatal alert already sent",
                     SSL_GETPID(), ss->fd));
         return SECFailure;
     }
 
+    capRecordVersion = ((flags & ssl_SEND_FLAG_CAP_RECORD_VERSION) != 0);
+
+    if (capRecordVersion) {
+        /* ssl_SEND_FLAG_CAP_RECORD_VERSION can only be used with the
+         * TLS initial ClientHello. */
+        PORT_Assert(!IS_DTLS(ss));
+        PORT_Assert(!ss->firstHsDone);
+        PORT_Assert(type == content_handshake);
+        PORT_Assert(ss->ssl3.hs.ws == wait_server_hello);
+    }
+
     if (ss->ssl3.initialized == PR_FALSE) {
         /* This can happen on a server if the very first incoming record
         ** looks like a defective ssl3 record (e.g. too long), and we're
         ** trying to send an alert.
         */
         PR_ASSERT(type == content_alert);
         ssl3_InitState(ss);
     }
@@ -2715,29 +2740,29 @@ ssl3_SendRecord(sslSocket *ss,
                 SSL_DBG(("%d: SSL3[%d]: SendRecord, tried to get %d bytes",
                          SSL_GETPID(), ss->fd, spaceNeeded));
                 goto spec_locked_loser; /* sslBuffer_Grow set error code. */
             }
         }
 
         if (numRecords == 2) {
             sslBuffer secondRecord;
-            rv = ssl_ProtectRecord(ss, ss->ssl3.cwSpec, type,
+            rv = ssl_ProtectRecord(ss, ss->ssl3.cwSpec, capRecordVersion, type,
                                    pIn, 1, wrBuf);
             if (rv != SECSuccess)
                 goto spec_locked_loser;
 
             PRINT_BUF(50, (ss, "send (encrypted) record data [1/2]:",
                            wrBuf->buf, wrBuf->len));
 
             secondRecord.buf = wrBuf->buf + wrBuf->len;
             secondRecord.len = 0;
             secondRecord.space = wrBuf->space - wrBuf->len;
 
-            rv = ssl_ProtectRecord(ss, ss->ssl3.cwSpec, type,
+            rv = ssl_ProtectRecord(ss, ss->ssl3.cwSpec, capRecordVersion, type,
                                    pIn + 1, contentLen - 1, &secondRecord);
             if (rv == SECSuccess) {
                 PRINT_BUF(50, (ss, "send (encrypted) record data [2/2]:",
                                secondRecord.buf, secondRecord.len));
                 wrBuf->len += secondRecord.len;
             }
         } else {
             if (cwSpec) {
@@ -2746,17 +2771,18 @@ ssl3_SendRecord(sslSocket *ss,
                 PORT_Assert(IS_DTLS(ss) &&
                             (type == content_handshake ||
                              type == content_change_cipher_spec));
                 spec = cwSpec;
             } else {
                 spec = ss->ssl3.cwSpec;
             }
 
-            rv = ssl_ProtectRecord(ss, spec, type, pIn, contentLen, wrBuf);
+            rv = ssl_ProtectRecord(ss, spec, !IS_DTLS(ss) && capRecordVersion,
+                                   type, pIn, contentLen, wrBuf);
             if (rv == SECSuccess) {
                 PRINT_BUF(50, (ss, "send (encrypted) record data:",
                                wrBuf->buf, wrBuf->len));
             }
         }
 
     spec_locked_loser:
         ssl_ReleaseSpecReadLock(ss); /************************************/
@@ -2949,33 +2975,40 @@ ssl3_FlushHandshake(sslSocket *ss, PRInt
  * This function returns SECSuccess or SECFailure, never SECWouldBlock.
  * Always set sendBuf.len to 0, even when returning SECFailure.
  *
  * Called from ssl3_FlushHandshake
  */
 static SECStatus
 ssl3_FlushHandshakeMessages(sslSocket *ss, PRInt32 flags)
 {
-    static const PRInt32 allowedFlags = ssl_SEND_FLAG_FORCE_INTO_BUFFER;
+    static const PRInt32 allowedFlags = ssl_SEND_FLAG_FORCE_INTO_BUFFER |
+                                        ssl_SEND_FLAG_CAP_RECORD_VERSION;
     PRInt32 count = -1;
     SECStatus rv;
+    SSL3ContentType ct = content_handshake;
 
     PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
     PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
 
     if (!ss->sec.ci.sendBuf.buf || !ss->sec.ci.sendBuf.len)
         return SECSuccess;
 
     /* only these flags are allowed */
     PORT_Assert(!(flags & ~allowedFlags));
     if ((flags & ~allowedFlags) != 0) {
         PORT_SetError(SEC_ERROR_INVALID_ARGS);
         return SECFailure;
     }
-    count = ssl3_SendRecord(ss, NULL, content_handshake,
+    /* Maybe send the first message with alt handshake type. */
+    if (ss->ssl3.hs.altHandshakeType) {
+        ct = content_alt_handshake;
+        ss->ssl3.hs.altHandshakeType = PR_FALSE;
+    }
+    count = ssl3_SendRecord(ss, NULL, ct,
                             ss->sec.ci.sendBuf.buf,
                             ss->sec.ci.sendBuf.len, flags);
     if (count < 0) {
         int err = PORT_GetError();
         PORT_Assert(err != PR_WOULD_BLOCK_ERROR);
         if (err == PR_WOULD_BLOCK_ERROR) {
             PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
         }
@@ -3374,59 +3407,45 @@ ssl3_HandleAlert(sslSocket *ss, sslBuffe
  * Called from ssl3_HandleServerHelloDone,
  *             ssl3_HandleClientHello,
  * and         ssl3_HandleFinished
  *
  * Acquires and releases spec write lock, to protect switching the current
  * and pending write spec pointers.
  */
 
-SECStatus
-ssl3_SendChangeCipherSpecsInt(sslSocket *ss)
+static SECStatus
+ssl3_SendChangeCipherSpecs(sslSocket *ss)
 {
     PRUint8 change = change_cipher_spec_choice;
+    ssl3CipherSpec *pwSpec;
     SECStatus rv;
+    PRInt32 sent;
 
     SSL_TRC(3, ("%d: SSL3[%d]: send change_cipher_spec record",
                 SSL_GETPID(), ss->fd));
 
+    PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
+    PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
+
     rv = ssl3_FlushHandshake(ss, ssl_SEND_FLAG_FORCE_INTO_BUFFER);
     if (rv != SECSuccess) {
-        return SECFailure; /* error code set by ssl3_FlushHandshake */
-    }
-
+        return rv; /* error code set by ssl3_FlushHandshake */
+    }
     if (!IS_DTLS(ss)) {
-        PRInt32 sent;
-        sent = ssl3_SendRecord(ss, NULL, content_change_cipher_spec,
-                               &change, 1, ssl_SEND_FLAG_FORCE_INTO_BUFFER);
+        sent = ssl3_SendRecord(ss, NULL, content_change_cipher_spec, &change, 1,
+                               ssl_SEND_FLAG_FORCE_INTO_BUFFER);
         if (sent < 0) {
-            return SECFailure; /* error code set by ssl3_SendRecord */
+            return (SECStatus)sent; /* error code set by ssl3_SendRecord */
         }
     } else {
-        SECStatus rv;
         rv = dtls_QueueMessage(ss, content_change_cipher_spec, &change, 1);
         if (rv != SECSuccess) {
-            return SECFailure;
-        }
-    }
-    return SECSuccess;
-}
-
-static SECStatus
-ssl3_SendChangeCipherSpecs(sslSocket *ss)
-{
-    ssl3CipherSpec *pwSpec;
-    SECStatus rv;
-
-    PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
-    PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
-
-    rv = ssl3_SendChangeCipherSpecsInt(ss);
-    if (rv != SECSuccess) {
-        return rv; /* Error code set. */
+            return rv;
+        }
     }
 
     /* swap the pending and current write specs. */
     ssl_GetSpecWriteLock(ss); /**************************************/
     pwSpec = ss->ssl3.pwSpec;
 
     ss->ssl3.pwSpec = ss->ssl3.cwSpec;
     ss->ssl3.cwSpec = pwSpec;
@@ -3640,16 +3659,18 @@ ssl3_ComputeMasterSecretFinish(sslSocket
  **
  ** Called from: ssl3_ComputeMasterSecret
  */
 static SECStatus
 ssl3_ComputeMasterSecretInt(sslSocket *ss, PK11SymKey *pms,
                             PK11SymKey **msp)
 {
     ssl3CipherSpec *pwSpec = ss->ssl3.pwSpec;
+    unsigned char *cr = (unsigned char *)&ss->ssl3.hs.client_random;
+    unsigned char *sr = (unsigned char *)&ss->ssl3.hs.server_random;
     PRBool isTLS = (PRBool)(pwSpec->version > SSL_LIBRARY_VERSION_3_0);
     PRBool isTLS12 =
         (PRBool)(isTLS && pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);
     /*
      * Whenever isDH is true, we need to use CKM_TLS_MASTER_KEY_DERIVE_DH
      * which, unlike CKM_TLS_MASTER_KEY_DERIVE, converts arbitrary size
      * data into a 48-byte value, and does not expect to return the version.
      */
@@ -3688,19 +3709,19 @@ ssl3_ComputeMasterSecretInt(sslSocket *s
         keyFlags = 0;
     }
 
     if (!isDH) {
         pms_version_ptr = &pms_version;
     }
 
     master_params.pVersion = pms_version_ptr;
-    master_params.RandomInfo.pClientRandom = ss->ssl3.hs.client_random;
+    master_params.RandomInfo.pClientRandom = cr;
     master_params.RandomInfo.ulClientRandomLen = SSL3_RANDOM_LENGTH;
-    master_params.RandomInfo.pServerRandom = ss->ssl3.hs.server_random;
+    master_params.RandomInfo.pServerRandom = sr;
     master_params.RandomInfo.ulServerRandomLen = SSL3_RANDOM_LENGTH;
     if (isTLS12) {
         master_params.prfHashMechanism = ssl3_GetPrfHashMechanism(ss);
         master_params_len = sizeof(CK_TLS12_MASTER_KEY_DERIVE_PARAMS);
     } else {
         /* prfHashMechanism is not relevant with this PRF */
         master_params_len = sizeof(CK_SSL3_MASTER_KEY_DERIVE_PARAMS);
     }
@@ -3840,17 +3861,19 @@ ssl3_DeriveMasterSecret(sslSocket *ss, P
  * Caller MUST hold the specWriteLock, and SSL3HandshakeLock.
  * ssl3_InitPendingCipherSpec does that.
  *
  */
 static SECStatus
 ssl3_DeriveConnectionKeys(sslSocket *ss)
 {
     ssl3CipherSpec *pwSpec = ss->ssl3.pwSpec;
-    PRBool isTLS = (PRBool)(ss->version > SSL_LIBRARY_VERSION_3_0);
+    unsigned char *cr = (unsigned char *)&ss->ssl3.hs.client_random;
+    unsigned char *sr = (unsigned char *)&ss->ssl3.hs.server_random;
+    PRBool isTLS = (PRBool)(pwSpec->version > SSL_LIBRARY_VERSION_3_0);
     PRBool isTLS12 =
         (PRBool)(isTLS && pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);
     const ssl3BulkCipherDef *cipher_def = pwSpec->cipher_def;
     PK11SlotInfo *slot = NULL;
     PK11SymKey *symKey = NULL;
     void *pwArg = ss->pkcs11PinArg;
     int keySize;
     CK_TLS12_KEY_MAT_PARAMS key_material_params; /* may be used as a
@@ -3881,19 +3904,19 @@ ssl3_DeriveConnectionKeys(sslSocket *ss)
         pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_1) {
         /* Block ciphers in >= TLS 1.1 use a per-record, explicit IV. */
         key_material_params.ulIVSizeInBits = 0;
         memset(pwSpec->client.write_iv, 0, cipher_def->iv_size);
         memset(pwSpec->server.write_iv, 0, cipher_def->iv_size);
     }
 
     key_material_params.bIsExport = PR_FALSE;
-    key_material_params.RandomInfo.pClientRandom = ss->ssl3.hs.client_random;
+    key_material_params.RandomInfo.pClientRandom = cr;
     key_material_params.RandomInfo.ulClientRandomLen = SSL3_RANDOM_LENGTH;
-    key_material_params.RandomInfo.pServerRandom = ss->ssl3.hs.server_random;
+    key_material_params.RandomInfo.pServerRandom = sr;
     key_material_params.RandomInfo.ulServerRandomLen = SSL3_RANDOM_LENGTH;
     key_material_params.pReturnedKeyMaterial = &returnedKeys;
 
     returnedKeys.pIVClient = pwSpec->client.write_iv;
     returnedKeys.pIVServer = pwSpec->server.write_iv;
     keySize = cipher_def->key_size;
 
     if (skipKeysAndIVs) {
@@ -4911,28 +4934,16 @@ ssl_ClientHelloTypeName(sslClientHelloTy
         CHTYPE(renegotiation); /* TLS <= 1.2 only */
     }
     PORT_Assert(0);
     return NULL;
 }
 #undef CHTYPE
 #endif
 
-PR_STATIC_ASSERT(SSL3_SESSIONID_BYTES == SSL3_RANDOM_LENGTH);
-static void
-ssl_MakeFakeSid(sslSocket *ss, PRUint8 *buf)
-{
-    PRUint8 x = 0x5a;
-    int i;
-    for (i = 0; i < SSL3_SESSIONID_BYTES; ++i) {
-        x += ss->ssl3.hs.client_random[i];
-        buf[i] = x;
-    }
-}
-
 /* Called from ssl3_HandleHelloRequest(),
  *             ssl3_RedoHandshake()
  *             ssl_BeginClientHandshake (when resuming ssl3 session)
  *             dtls_HandleHelloVerifyRequest(with resending=PR_TRUE)
  *
  * The |type| argument indicates what is going on here:
  * - client_hello_initial is set for the very first ClientHello
  * - client_hello_retry indicates that this is a second attempt after receiving
@@ -5234,24 +5245,21 @@ ssl3_SendClientHello(sslSocket *ss, sslC
     /* count compression methods */
     numCompressionMethods = 0;
     for (i = 0; i < ssl_compression_method_count; i++) {
         if (ssl_CompressionEnabled(ss, ssl_compression_methods[i]))
             numCompressionMethods++;
     }
 
     length = sizeof(SSL3ProtocolVersion) + SSL3_RANDOM_LENGTH +
-             1 + /* session id length */
+             1 + (sid->version >= SSL_LIBRARY_VERSION_TLS_1_3
+                      ? 0
+                      : sid->u.ssl3.sessionIDLength) +
              2 + num_suites * sizeof(ssl3CipherSuite) +
              1 + numCompressionMethods + total_exten_len;
-    if (sid->version < SSL_LIBRARY_VERSION_TLS_1_3) {
-        length += sid->u.ssl3.sessionIDLength;
-    } else if (ss->opt.enableAltHandshaketype && !IS_DTLS(ss)) {
-        length += SSL3_SESSIONID_BYTES;
-    }
     if (IS_DTLS(ss)) {
         length += 1 + ss->ssl3.hs.cookie.len;
     }
 
     if (total_exten_len > 0) {
         ssl3_CalculatePaddingExtLen(ss, length);
         if (ss->xtnData.paddingLen) {
             total_exten_len += 4 + ss->xtnData.paddingLen;
@@ -5285,45 +5293,38 @@ ssl3_SendClientHello(sslSocket *ss, sslC
         if (sid->u.ssl3.lock) {
             PR_RWLock_Unlock(sid->u.ssl3.lock);
         }
         return rv; /* err set by ssl3_AppendHandshake* */
     }
 
     /* Generate a new random if this is the first attempt. */
     if (type == client_hello_initial) {
-        rv = ssl3_GetNewRandom(ss->ssl3.hs.client_random);
+        rv = ssl3_GetNewRandom(&ss->ssl3.hs.client_random);
         if (rv != SECSuccess) {
             if (sid->u.ssl3.lock) {
                 PR_RWLock_Unlock(sid->u.ssl3.lock);
             }
             return rv; /* err set by GetNewRandom. */
         }
     }
-    rv = ssl3_AppendHandshake(ss, ss->ssl3.hs.client_random,
+    rv = ssl3_AppendHandshake(ss, &ss->ssl3.hs.client_random,
                               SSL3_RANDOM_LENGTH);
     if (rv != SECSuccess) {
         if (sid->u.ssl3.lock) {
             PR_RWLock_Unlock(sid->u.ssl3.lock);
         }
         return rv; /* err set by ssl3_AppendHandshake* */
     }
 
-    if (sid->version < SSL_LIBRARY_VERSION_TLS_1_3) {
+    if (sid->version < SSL_LIBRARY_VERSION_TLS_1_3)
         rv = ssl3_AppendHandshakeVariable(
             ss, sid->u.ssl3.sessionID, sid->u.ssl3.sessionIDLength, 1);
-    } else if (ss->opt.enableAltHandshaketype && !IS_DTLS(ss)) {
-        /* We're faking session resumption, so rather than create new
-         * randomness, just mix up the client random a little. */
-        PRUint8 buf[SSL3_SESSIONID_BYTES];
-        ssl_MakeFakeSid(ss, buf);
-        rv = ssl3_AppendHandshakeVariable(ss, buf, SSL3_SESSIONID_BYTES, 1);
-    } else {
+    else
         rv = ssl3_AppendHandshakeNumber(ss, 0, 1);
-    }
     if (rv != SECSuccess) {
         if (sid->u.ssl3.lock) {
             PR_RWLock_Unlock(sid->u.ssl3.lock);
         }
         return rv; /* err set by ssl3_AppendHandshake* */
     }
 
     if (IS_DTLS(ss)) {
@@ -5457,16 +5458,19 @@ ssl3_SendClientHello(sslSocket *ss, sslC
     if (ss->ssl3.hs.sendingSCSV) {
         /* Since we sent the SCSV, pretend we sent empty RI extension. */
         TLSExtensionData *xtnData = &ss->xtnData;
         xtnData->advertised[xtnData->numAdvertised++] =
             ssl_renegotiation_info_xtn;
     }
 
     flags = 0;
+    if (!ss->firstHsDone && !IS_DTLS(ss)) {
+        flags |= ssl_SEND_FLAG_CAP_RECORD_VERSION;
+    }
     rv = ssl3_FlushHandshake(ss, flags);
     if (rv != SECSuccess) {
         return rv; /* error code set by ssl3_FlushHandshake */
     }
 
     if (version >= SSL_LIBRARY_VERSION_TLS_1_3) {
         rv = tls13_MaybeDo0RTTHandshake(ss);
         if (rv != SECSuccess) {
@@ -6547,96 +6551,52 @@ done:
     if (buf.data)
         PORT_Free(buf.data);
     return rv;
 }
 
 /* Once a cipher suite has been selected, make sure that the necessary secondary
  * information is properly set. */
 SECStatus
-ssl3_SetupCipherSuite(sslSocket *ss, PRBool initHashes)
-{
-    ss->ssl3.hs.suite_def = ssl_LookupCipherSuiteDef(ss->ssl3.hs.cipher_suite);
+ssl3_SetCipherSuite(sslSocket *ss, ssl3CipherSuite chosenSuite,
+                    PRBool initHashes)
+{
+    ss->ssl3.hs.cipher_suite = chosenSuite;
+    ss->ssl3.hs.suite_def = ssl_LookupCipherSuiteDef(chosenSuite);
     if (!ss->ssl3.hs.suite_def) {
         PORT_Assert(0);
         PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
         return SECFailure;
     }
 
     ss->ssl3.hs.kea_def = &kea_defs[ss->ssl3.hs.suite_def->key_exchange_alg];
     ss->ssl3.hs.preliminaryInfo |= ssl_preinfo_cipher_suite;
 
     if (!initHashes) {
         return SECSuccess;
     }
-    /* Now we have a cipher suite, initialize the handshake hashes. */
+    /* Now we've have a cipher suite, initialize the handshake hashes. */
     return ssl3_InitHandshakeHashes(ss);
 }
 
-/* Once a cipher suite has been selected, make sure that the necessary secondary
- * information is properly set. */
-SECStatus
-ssl3_SetCipherSuite(sslSocket *ss, ssl3CipherSuite chosenSuite,
-                    PRBool initHashes)
-{
-    ss->ssl3.hs.cipher_suite = chosenSuite;
-    return ssl3_SetupCipherSuite(ss, initHashes);
-}
-
-SECStatus
-ssl_ClientSetCipherSuite(sslSocket *ss, SSL3ProtocolVersion version,
-                         ssl3CipherSuite suite, PRBool initHashes)
-{
-    int i;
-
-    i = ssl3_config_match_init(ss);
-    PORT_Assert(i > 0);
-    if (i <= 0) {
-        return SECFailure;
-    }
-    for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) {
-        ssl3CipherSuiteCfg *suiteCfg = &ss->cipherSuites[i];
-        if (suite == suiteCfg->cipher_suite) {
-            SSLVersionRange vrange = { version, version };
-            if (!config_match(suiteCfg, ss->ssl3.policy, &vrange, ss)) {
-                /* config_match already checks whether the cipher suite is
-                 * acceptable for the version, but the check is repeated here
-                 * in order to give a more precise error code. */
-                if (!ssl3_CipherSuiteAllowedForVersionRange(suite, &vrange)) {
-                    PORT_SetError(SSL_ERROR_CIPHER_DISALLOWED_FOR_VERSION);
-                } else {
-                    PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
-                }
-                return SECFailure;
-            }
-            break;
-        }
-    }
-    if (i >= ssl_V3_SUITES_IMPLEMENTED) {
-        PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
-        return SECFailure;
-    }
-
-    ss->ssl3.hs.cipher_suite = (ssl3CipherSuite)suite;
-    return ssl3_SetupCipherSuite(ss, initHashes);
-}
-
 /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
  * ssl3 ServerHello message.
  * Caller must hold Handshake and RecvBuf locks.
  */
 static SECStatus
 ssl3_HandleServerHello(sslSocket *ss, PRUint8 *b, PRUint32 length)
 {
-    PRUint32 cipher;
+    PRUint32 temp;
+    PRBool suite_found = PR_FALSE;
+    int i;
     int errCode = SSL_ERROR_RX_MALFORMED_SERVER_HELLO;
     SECStatus rv;
     SECItem sidBytes = { siBuffer, NULL, 0 };
+    PRBool isTLS = PR_FALSE;
     SSL3AlertDescription desc = illegal_parameter;
-    TLSExtension *versionExtension;
 #ifndef TLS_1_3_DRAFT_VERSION
     SSL3ProtocolVersion downgradeCheckVersion;
 #endif
 
     SSL_TRC(3, ("%d: SSL3[%d]: handle server_hello handshake",
                 SSL_GETPID(), ss->fd));
     PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
     PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
@@ -6657,101 +6617,21 @@ ssl3_HandleServerHello(sslSocket *ss, PR
         CERT_DestroyCertificate(ss->ssl3.clientCertificate);
         ss->ssl3.clientCertificate = NULL;
     }
     if (ss->ssl3.clientPrivateKey != NULL) {
         SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey);
         ss->ssl3.clientPrivateKey = NULL;
     }
 
-    /* Note that if we are doing the alternative handshake for TLS 1.3, this
-     * will set the version to TLS 1.2.  We will amend that once all other
-     * fields have been read. */
     rv = ssl_ClientReadVersion(ss, &b, &length, &ss->version);
     if (rv != SECSuccess) {
         goto loser; /* alert has been sent */
     }
 
-    rv = ssl3_ConsumeHandshake(
-        ss, ss->ssl3.hs.server_random, SSL3_RANDOM_LENGTH, &b, &length);
-    if (rv != SECSuccess) {
-        goto loser; /* alert has been sent */
-    }
-
-    if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
-        rv = ssl3_ConsumeHandshakeVariable(ss, &sidBytes, 1, &b, &length);
-        if (rv != SECSuccess) {
-            goto loser; /* alert has been sent */
-        }
-        if (sidBytes.len > SSL3_SESSIONID_BYTES) {
-            if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_0)
-                desc = decode_error;
-            goto alert_loser; /* malformed. */
-        }
-    }
-
-    /* Read the cipher suite. */
-    rv = ssl3_ConsumeHandshakeNumber(ss, &cipher, 2, &b, &length);
-    if (rv != SECSuccess) {
-        goto loser; /* alert has been sent */
-    }
-
-    /* Compression method. */
-    if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
-        PRUint32 compression;
-        rv = ssl3_ConsumeHandshakeNumber(ss, &compression, 1, &b, &length);
-        if (rv != SECSuccess) {
-            goto loser; /* alert has been sent */
-        }
-        if (compression != ssl_compression_null) {
-            desc = illegal_parameter;
-            errCode = SSL_ERROR_RX_MALFORMED_SERVER_HELLO;
-            goto alert_loser;
-        }
-    }
-
-    /* Parse extensions. */
-    if (length != 0) {
-        PRUint32 extensionLength;
-        rv = ssl3_ConsumeHandshakeNumber(ss, &extensionLength, 2, &b, &length);
-        if (rv != SECSuccess) {
-            goto loser; /* alert already sent */
-        }
-        if (extensionLength != length) {
-            desc = decode_error;
-            goto alert_loser;
-        }
-        rv = ssl3_ParseExtensions(ss, &b, &length);
-        if (rv != SECSuccess) {
-            goto alert_loser; /* malformed */
-        }
-    }
-
-    /* Update the version based on the extension, as necessary. */
-    versionExtension = ssl3_FindExtension(ss, ssl_tls13_supported_versions_xtn);
-    if (versionExtension) {
-        rv = ssl_ClientReadVersion(ss, &versionExtension->data.data,
-                                   &versionExtension->data.len,
-                                   &ss->version);
-        if (rv != SECSuccess) {
-            errCode = PORT_GetError();
-            goto loser; /* An alert is sent by ssl_ClientReadVersion */
-        }
-    }
-
-    PORT_Assert(!SSL_ALL_VERSIONS_DISABLED(&ss->vrange));
-    /* Check that the version is within the configured range. */
-    if (ss->vrange.min > ss->version || ss->vrange.max < ss->version) {
-        desc = (ss->version > SSL_LIBRARY_VERSION_3_0)
-                   ? protocol_version
-                   : handshake_failure;
-        errCode = SSL_ERROR_UNSUPPORTED_VERSION;
-        goto alert_loser;
-    }
-
     /* The server didn't pick 1.3 although we either received a
      * HelloRetryRequest, or we prepared to send early app data. */
     if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
         if (ss->ssl3.hs.helloRetry) {
             /* SSL3_SendAlert() will uncache the SID. */
             desc = illegal_parameter;
             errCode = SSL_ERROR_RX_MALFORMED_SERVER_HELLO;
             goto alert_loser;
@@ -6768,16 +6648,24 @@ ssl3_HandleServerHello(sslSocket *ss, PR
      * in the first handshake. This isn't really the best place for
      * us to be getting this version number, but it's what we have.
      * (1294697). */
     if (ss->firstHsDone && (ss->version != ss->ssl3.crSpec->version)) {
         desc = illegal_parameter;
         errCode = SSL_ERROR_UNSUPPORTED_VERSION;
         goto alert_loser;
     }
+    ss->ssl3.hs.preliminaryInfo |= ssl_preinfo_version;
+    isTLS = (ss->version > SSL_LIBRARY_VERSION_3_0);
+
+    rv = ssl3_ConsumeHandshake(
+        ss, &ss->ssl3.hs.server_random, SSL3_RANDOM_LENGTH, &b, &length);
+    if (rv != SECSuccess) {
+        goto loser; /* alert has been sent */
+    }
 
 #ifndef TLS_1_3_DRAFT_VERSION
     /* Check the ServerHello.random per
      * [draft-ietf-tls-tls13-11 Section 6.3.1.1].
      *
      * TLS 1.3 clients receiving a TLS 1.2 or below ServerHello MUST check
      * that the top eight octets are not equal to either of these values.
      * TLS 1.2 clients SHOULD also perform this check if the ServerHello
@@ -6787,74 +6675,138 @@ ssl3_HandleServerHello(sslSocket *ss, PR
      * Disable this test during the TLS 1.3 draft version period.
      */
     downgradeCheckVersion = ss->ssl3.downgradeCheckVersion ? ss->ssl3.downgradeCheckVersion
                                                            : ss->vrange.max;
 
     if (downgradeCheckVersion >= SSL_LIBRARY_VERSION_TLS_1_2 &&
         downgradeCheckVersion > ss->version) {
         /* Both sections use the same sentinel region. */
-        PRUint8 *downgrade_sentinel =
-            ss->ssl3.hs.server_random +
+        unsigned char *downgrade_sentinel =
+            ss->ssl3.hs.server_random.rand +
             SSL3_RANDOM_LENGTH - sizeof(tls13_downgrade_random);
         if (!PORT_Memcmp(downgrade_sentinel,
                          tls13_downgrade_random,
                          sizeof(tls13_downgrade_random)) ||
             !PORT_Memcmp(downgrade_sentinel,
                          tls12_downgrade_random,
                          sizeof(tls12_downgrade_random))) {
             desc = illegal_parameter;
             errCode = SSL_ERROR_RX_MALFORMED_SERVER_HELLO;
             goto alert_loser;
         }
     }
 #endif
 
-    /* Finally, now all the version-related checks have passed. */
-    ss->ssl3.hs.preliminaryInfo |= ssl_preinfo_version;
-    /* Update the write cipher spec to match the version. */
-    if (!ss->firstHsDone) {
-        ssl_GetSpecWriteLock(ss);
-        ssl_SetSpecVersions(ss, ss->ssl3.cwSpec);
-        ssl_ReleaseSpecWriteLock(ss);
-    }
-
-    /* Check that the session ID is as expected. */
-    if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) {
-        PRUint8 buf[SSL3_SESSIONID_BYTES];
-        unsigned int expectedSidLen;
-        if (ss->ssl3.hs.altHandshakeType) {
-            expectedSidLen = SSL3_SESSIONID_BYTES;
-            ssl_MakeFakeSid(ss, buf);
-        } else {
-            expectedSidLen = 0;
-        }
-        if (sidBytes.len != expectedSidLen ||
-            PORT_Memcmp(buf, sidBytes.data, expectedSidLen) != 0) {
-            desc = illegal_parameter;
-            errCode = SSL_ERROR_RX_MALFORMED_SERVER_HELLO;
-            goto alert_loser;
-        }
-    }
-
-    /* Set compression (to be removed soon), and cipher suite. */
-    ss->ssl3.hs.compression = ssl_compression_null;
-    rv = ssl_ClientSetCipherSuite(ss, ss->version, cipher,
-                                  PR_TRUE /* init hashes */);
-    if (rv != SECSuccess) {
+    if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
+        rv = ssl3_ConsumeHandshakeVariable(ss, &sidBytes, 1, &b, &length);
+        if (rv != SECSuccess) {
+            goto loser; /* alert has been sent */
+        }
+        if (sidBytes.len > SSL3_SESSIONID_BYTES) {
+            if (isTLS)
+                desc = decode_error;
+            goto alert_loser; /* malformed. */
+        }
+    }
+
+    /* find selected cipher suite in our list. */
+    rv = ssl3_ConsumeHandshakeNumber(ss, &temp, 2, &b, &length);
+    if (rv != SECSuccess) {
+        goto loser; /* alert has been sent */
+    }
+    i = ssl3_config_match_init(ss);
+    PORT_Assert(i > 0);
+    if (i <= 0) {
         errCode = PORT_GetError();
         goto loser;
     }
-
-    rv = ssl3_HandleParsedExtensions(ss, server_hello);
-    ssl3_DestroyRemoteExtensions(&ss->ssl3.hs.remoteExtensions);
-    if (rv != SECSuccess) {
+    for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) {
+        ssl3CipherSuiteCfg *suite = &ss->cipherSuites[i];
+        if (temp == suite->cipher_suite) {
+            SSLVersionRange vrange = { ss->version, ss->version };
+            if (!config_match(suite, ss->ssl3.policy, &vrange, ss)) {
+                /* config_match already checks whether the cipher suite is
+                 * acceptable for the version, but the check is repeated here
+                 * in order to give a more precise error code. */
+                if (!ssl3_CipherSuiteAllowedForVersionRange(temp, &vrange)) {
+                    desc = handshake_failure;
+                    errCode = SSL_ERROR_CIPHER_DISALLOWED_FOR_VERSION;
+                    goto alert_loser;
+                }
+
+                break; /* failure */
+            }
+
+            suite_found = PR_TRUE;
+            break; /* success */
+        }
+    }
+    if (!suite_found) {
+        desc = handshake_failure;
+        errCode = SSL_ERROR_NO_CYPHER_OVERLAP;
+        goto alert_loser;
+    }
+
+    rv = ssl3_SetCipherSuite(ss, (ssl3CipherSuite)temp, PR_TRUE);
+    if (rv != SECSuccess) {
+        desc = internal_error;
+        errCode = PORT_GetError();
         goto alert_loser;
     }
 
+    if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
+        /* find selected compression method in our list. */
+        rv = ssl3_ConsumeHandshakeNumber(ss, &temp, 1, &b, &length);
+        if (rv != SECSuccess) {
+            goto loser; /* alert has been sent */
+        }
+        suite_found = PR_FALSE;
+        for (i = 0; i < ssl_compression_method_count; i++) {
+            if (temp == ssl_compression_methods[i]) {
+                if (!ssl_CompressionEnabled(ss, ssl_compression_methods[i])) {
+                    break; /* failure */
+                }
+                suite_found = PR_TRUE;
+                break; /* success */
+            }
+        }
+        if (!suite_found) {
+            desc = handshake_failure;
+            errCode = SSL_ERROR_NO_COMPRESSION_OVERLAP;
+            goto alert_loser;
+        }
+        ss->ssl3.hs.compression = (SSLCompressionMethod)temp;
+    } else {
+        ss->ssl3.hs.compression = ssl_compression_null;
+    }
+
+    /* Note that if !isTLS and the extra stuff is not extensions, we
+     * do NOT goto alert_loser.
+     * There are some old SSL 3.0 implementations that do send stuff
+     * after the end of the server hello, and we deliberately ignore
+     * such stuff in the interest of maximal interoperability (being
+     * "generous in what you accept").
+     * Update: Starting in NSS 3.12.6, we handle the renegotiation_info
+     * extension in SSL 3.0.
+     */
+    if (length != 0) {
+        SECItem extensions;
+        rv = ssl3_ConsumeHandshakeVariable(ss, &extensions, 2, &b, &length);
+        if (rv != SECSuccess || length != 0) {
+            if (isTLS)
+                goto alert_loser;
+        } else {
+            rv = ssl3_HandleExtensions(ss, &extensions.data,
+                                       &extensions.len, server_hello);
+            if (rv != SECSuccess)
+                goto alert_loser;
+        }
+    }
+
     if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) {
         rv = tls13_HandleServerHelloPart2(ss);
         if (rv != SECSuccess) {
             errCode = PORT_GetError();
             goto loser;
         }
     } else {
         rv = ssl3_HandleServerHelloPart2(ss, &sidBytes, &errCode);
@@ -7971,17 +7923,16 @@ ssl3_NewSessionID(sslSocket *ss, PRBool 
     sid->version = ss->version;
     sid->sigScheme = ssl_sig_none;
 
     sid->u.ssl3.keys.resumable = PR_TRUE;
     sid->u.ssl3.policy = SSL_ALLOWED;
     sid->u.ssl3.clientWriteKey = NULL;
     sid->u.ssl3.serverWriteKey = NULL;
     sid->u.ssl3.keys.extendedMasterSecretUsed = PR_FALSE;
-    sid->u.ssl3.altHandshakeType = ss->ssl3.hs.altHandshakeType;
 
     if (is_server) {
         SECStatus rv;
         int pid = SSL_GETPID();
 
         sid->u.ssl3.sessionIDLength = SSL3_SESSIONID_BYTES;
         sid->u.ssl3.sessionID[0] = (pid >> 8) & 0xff;
         sid->u.ssl3.sessionID[1] = pid & 0xff;
@@ -8388,17 +8339,17 @@ ssl3_HandleClientHello(sslSocket *ss, PR
         ss->clientHelloVersion = version =
             dtls_DTLSVersionToTLSVersion((SSL3ProtocolVersion)tmp);
     } else {
         ss->clientHelloVersion = version = (SSL3ProtocolVersion)tmp;
     }
 
     /* Grab the client random data. */
     rv = ssl3_ConsumeHandshake(
-        ss, ss->ssl3.hs.client_random, SSL3_RANDOM_LENGTH, &b, &length);
+        ss, &ss->ssl3.hs.client_random, SSL3_RANDOM_LENGTH, &b, &length);
     if (rv != SECSuccess) {
         goto loser; /* malformed */
     }
 
     /* Grab the client's SID, if present. */
     rv = ssl3_ConsumeHandshakeVariable(ss, &sidBytes, 1, &b, &length);
     if (rv != SECSuccess) {
         goto loser; /* malformed */
@@ -8428,25 +8379,24 @@ ssl3_HandleClientHello(sslSocket *ss, PR
      * we are restarting a previous session until extensions have been
      * parsed, since we might have received a SessionTicket extension.
      * Note: we allow extensions even when negotiating SSL3 for the sake
      * of interoperability (and backwards compatibility).
      */
 
     if (length) {
         /* Get length of hello extensions */
-        PRUint32 extensionLength;
-        rv = ssl3_ConsumeHandshakeNumber(ss, &extensionLength, 2, &b, &length);
+        PRUint32 extension_length;
+        rv = ssl3_ConsumeHandshakeNumber(ss, &extension_length, 2, &b, &length);
         if (rv != SECSuccess) {
             goto loser; /* alert already sent */
         }
-        if (extensionLength != length) {
-            errCode = SSL_ERROR_RX_MALFORMED_CLIENT_HELLO;
-            desc = decode_error;
-            goto alert_loser;
+        if (extension_length != length) {
+            ssl3_DecodeError(ss); /* send alert */
+            goto loser;
         }
 
         rv = ssl3_ParseExtensions(ss, &b, &length);
         if (rv != SECSuccess) {
             goto loser; /* malformed */
         }
     }
 
@@ -8467,44 +8417,27 @@ ssl3_HandleClientHello(sslSocket *ss, PR
                                    PR_TRUE);
         if (rv != SECSuccess) {
             desc = (version > SSL_LIBRARY_VERSION_3_0) ? protocol_version
                                                        : handshake_failure;
             errCode = SSL_ERROR_UNSUPPORTED_VERSION;
             goto alert_loser;
         }
     }
-
-    if (ss->firstHsDone && ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) {
-        desc = unexpected_message;
-        errCode = SSL_ERROR_RENEGOTIATION_NOT_ALLOWED;
-        goto alert_loser;
-    }
-
     isTLS13 = ss->version >= SSL_LIBRARY_VERSION_TLS_1_3;
     ss->ssl3.hs.preliminaryInfo |= ssl_preinfo_version;
-    /* Update the write spec to match the selected version. */
-    if (!ss->firstHsDone) {
-        ssl_GetSpecWriteLock(ss);
-        ssl_SetSpecVersions(ss, ss->ssl3.cwSpec);
-        ssl_ReleaseSpecWriteLock(ss);
-    }
-
-    if (ss->ssl3.hs.altHandshakeType) {
-        rv = SECITEM_CopyItem(NULL, &ss->ssl3.hs.fakeSid, &sidBytes);
-        if (rv != SECSuccess) {
-            desc = internal_error;
-            errCode = PORT_GetError();
-            goto alert_loser;
-        }
+
+    /* You can't resume TLS 1.3 like this. */
+    if (isTLS13 && sidBytes.len) {
+        goto alert_loser;
     }
 
     /* Generate the Server Random now so it is available
      * when we process the ClientKeyShare in TLS 1.3 */
-    rv = ssl3_GetNewRandom(ss->ssl3.hs.server_random);
+    rv = ssl3_GetNewRandom(&ss->ssl3.hs.server_random);
     if (rv != SECSuccess) {
         errCode = SSL_ERROR_GENERATE_RANDOM_FAILURE;
         goto loser;
     }
 
 #ifndef TLS_1_3_DRAFT_VERSION
     /*
      * [draft-ietf-tls-tls13-11 Section 6.3.1.1].
@@ -8520,18 +8453,18 @@ ssl3_HandleClientHello(sslSocket *ss, PR
      *
      * 44 4F 57 4E 47 52 44 00
      *
      * TODO(ekr@rtfm.com): Note this change was not added in the SSLv2
      * compat processing code since that will most likely be removed before
      * we ship the final version of TLS 1.3. Bug 1306672.
      */
     if (ss->vrange.max > ss->version) {
-        PRUint8 *downgrade_sentinel =
-            ss->ssl3.hs.server_random +
+        unsigned char *downgrade_sentinel =
+            ss->ssl3.hs.server_random.rand +
             SSL3_RANDOM_LENGTH - sizeof(tls13_downgrade_random);
 
         switch (ss->vrange.max) {
             case SSL_LIBRARY_VERSION_TLS_1_3:
                 PORT_Memcpy(downgrade_sentinel,
                             tls13_downgrade_random,
                             sizeof(tls13_downgrade_random));
                 break;
@@ -8544,17 +8477,16 @@ ssl3_HandleClientHello(sslSocket *ss, PR
                 /* Do not change random. */
                 break;
         }
     }
 #endif
 
     /* Now parse the rest of the extensions. */
     rv = ssl3_HandleParsedExtensions(ss, client_hello);
-    ssl3_DestroyRemoteExtensions(&ss->ssl3.hs.remoteExtensions);
     if (rv != SECSuccess) {
         goto loser; /* malformed */
     }
 
     /* If the ClientHello version is less than our maximum version, check for a
      * TLS_FALLBACK_SCSV and reject the connection if found. */
     if (ss->vrange.max > ss->version) {
         for (i = 0; i + 1 < suites.len; i += 2) {
@@ -8585,18 +8517,26 @@ ssl3_HandleClientHello(sslSocket *ss, PR
                 PRUint8 *b2 = (PRUint8 *)emptyRIext;
                 PRUint32 L2 = sizeof emptyRIext;
                 (void)ssl3_HandleExtensions(ss, &b2, &L2, client_hello);
                 break;
             }
         }
     }
 
-    /* The check for renegotiation in TLS 1.3 is earlier. */
-    if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
+    /* This is a second check for TLS 1.3 and re-handshake to stop us
+     * from re-handshake up to TLS 1.3, so it happens after version
+     * negotiation. */
+    if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) {
+        if (ss->firstHsDone) {
+            desc = unexpected_message;
+            errCode = SSL_ERROR_RENEGOTIATION_NOT_ALLOWED;
+            goto alert_loser;
+        }
+    } else {
         if (ss->firstHsDone &&
             (ss->opt.enableRenegotiation == SSL_RENEGOTIATE_REQUIRES_XTN ||
              ss->opt.enableRenegotiation == SSL_RENEGOTIATE_TRANSITIONAL) &&
             !ssl3_ExtensionNegotiated(ss, ssl_renegotiation_info_xtn)) {
             desc = no_renegotiation;
             level = alert_warning;
             errCode = SSL_ERROR_RENEGOTIATION_NOT_ALLOWED;
             goto alert_loser;
@@ -9179,21 +9119,16 @@ ssl3_HandleV2ClientHello(sslSocket *ss, 
     if (rv != SECSuccess) {
         /* send back which ever alert client will understand. */
         desc = (version > SSL_LIBRARY_VERSION_3_0) ? protocol_version
                                                    : handshake_failure;
         errCode = SSL_ERROR_UNSUPPORTED_VERSION;
         goto alert_loser;
     }
     ss->ssl3.hs.preliminaryInfo |= ssl_preinfo_version;
-    if (!ss->firstHsDone) {
-        ssl_GetSpecWriteLock(ss);
-        ssl_SetSpecVersions(ss, ss->ssl3.cwSpec);
-        ssl_ReleaseSpecWriteLock(ss);
-    }
 
     /* if we get a non-zero SID, just ignore it. */
     if (length != total) {
         SSL_DBG(("%d: SSL3[%d]: bad v2 client hello message, len=%d should=%d",
                  SSL_GETPID(), ss->fd, length, total));
         desc = illegal_parameter;
         errCode = SSL_ERROR_RX_MALFORMED_CLIENT_HELLO;
         goto alert_loser;
@@ -9206,21 +9141,22 @@ ssl3_HandleV2ClientHello(sslSocket *ss, 
         rand_length > SSL_MAX_CHALLENGE_BYTES) {
         desc = illegal_parameter;
         errCode = SSL_ERROR_RX_MALFORMED_CLIENT_HELLO;
         goto alert_loser;
     }
 
     PORT_Assert(SSL_MAX_CHALLENGE_BYTES == SSL3_RANDOM_LENGTH);
 
-    PORT_Memset(ss->ssl3.hs.client_random, 0, SSL3_RANDOM_LENGTH);
-    PORT_Memcpy(&ss->ssl3.hs.client_random[SSL3_RANDOM_LENGTH - rand_length],
-                random, rand_length);
-
-    PRINT_BUF(60, (ss, "client random:", ss->ssl3.hs.client_random,
+    PORT_Memset(&ss->ssl3.hs.client_random, 0, SSL3_RANDOM_LENGTH);
+    PORT_Memcpy(
+        &ss->ssl3.hs.client_random.rand[SSL3_RANDOM_LENGTH - rand_length],
+        random, rand_length);
+
+    PRINT_BUF(60, (ss, "client random:", &ss->ssl3.hs.client_random.rand[0],
                    SSL3_RANDOM_LENGTH));
     i = ssl3_config_match_init(ss);
     if (i <= 0) {
         errCode = PORT_GetError(); /* error code is already set. */
         goto alert_loser;
     }
 
     /* Select a cipher suite.
@@ -9362,82 +9298,68 @@ ssl3_SendServerHello(sslSocket *ss)
 
     sid = ss->sec.ci.sid;
 
     extensions_len = ssl3_CallHelloExtensionSenders(
         ss, PR_FALSE, maxBytes, &ss->xtnData.serverHelloSenders[0]);
     if (extensions_len > 0)
         extensions_len += 2; /* Add sizeof total extension length */
 
+    /* TLS 1.3 doesn't use the session_id or compression_method
+     * fields in the ServerHello. */
     length = sizeof(SSL3ProtocolVersion) + SSL3_RANDOM_LENGTH;
-
-    /* Adjust for session ID.  In TLS 1.3 proper it isn't even present.  In the
-     * alternative TLS 1.3 handshake, it is copied from the client. */
     if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
-        length += 1; /* Session ID Length */
-        if (sid) {
-            length += sid->u.ssl3.sessionIDLength;
-        }
-    } else if (ss->ssl3.hs.altHandshakeType) {
-        length += 1 + ss->ssl3.hs.fakeSid.len;
+        length += 1 + ((sid == NULL) ? 0 : sid->u.ssl3.sessionIDLength);
     }
     length += sizeof(ssl3CipherSuite);
-    if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3 ||
-        ss->ssl3.hs.altHandshakeType) {
-        length += 1; /* Compression. */
+    if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
+        length += 1; /* Compression */
     }
     length += extensions_len;
 
     rv = ssl3_AppendHandshakeHeader(ss, server_hello, length);
     if (rv != SECSuccess) {
         return rv; /* err set by AppendHandshake. */
     }
 
     if (IS_DTLS(ss) && ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
         version = dtls_TLSVersionToDTLSVersion(ss->version);
-    } else if (ss->ssl3.hs.altHandshakeType) {
-        version = SSL_LIBRARY_VERSION_TLS_1_2;
     } else {
-        version = tls13_EncodeDraftVersion(ss->version);
+        version = ss->ssl3.hs.altHandshakeType ? tls13_EncodeAltDraftVersion(ss->version) : tls13_EncodeDraftVersion(ss->version);
     }
 
     rv = ssl3_AppendHandshakeNumber(ss, version, 2);
     if (rv != SECSuccess) {
         return rv; /* err set by AppendHandshake. */
     }
     /* Random already generated in ssl3_HandleClientHello */
     rv = ssl3_AppendHandshake(
-        ss, ss->ssl3.hs.server_random, SSL3_RANDOM_LENGTH);
+        ss, &ss->ssl3.hs.server_random, SSL3_RANDOM_LENGTH);
     if (rv != SECSuccess) {
         return rv; /* err set by AppendHandshake. */
     }
 
     if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
         if (sid) {
             rv = ssl3_AppendHandshakeVariable(
                 ss, sid->u.ssl3.sessionID, sid->u.ssl3.sessionIDLength, 1);
         } else {
             rv = ssl3_AppendHandshakeNumber(ss, 0, 1);
         }
-    } else if (ss->ssl3.hs.altHandshakeType) {
-        rv = ssl3_AppendHandshakeVariable(ss, ss->ssl3.hs.fakeSid.data,
-                                          ss->ssl3.hs.fakeSid.len, 1);
-        SECITEM_FreeItem(&ss->ssl3.hs.fakeSid, PR_FALSE);
-    }
-    if (rv != SECSuccess) {
-        return SECFailure; /* err set by AppendHandshake. */
+        if (rv != SECSuccess) {
+            return rv; /* err set by AppendHandshake. */
+        }
     }
 
     rv = ssl3_AppendHandshakeNumber(ss, ss->ssl3.hs.cipher_suite, 2);
     if (rv != SECSuccess) {
         return rv; /* err set by AppendHandshake. */
     }
-    if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3 ||
-        ss->ssl3.hs.altHandshakeType) {
-        rv = ssl3_AppendHandshakeNumber(ss, ssl_compression_null, 1);
+    if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
+        rv = ssl3_AppendHandshakeNumber(ss, ss->ssl3.hs.compression, 1);
         if (rv != SECSuccess) {
             return rv; /* err set by AppendHandshake. */
         }
     }
     if (extensions_len) {
         PRInt32 sent_len;
 
         extensions_len -= 2;
@@ -11266,17 +11188,17 @@ ssl3_RecordKeyLog(sslSocket *ss, const c
 
     /* There could be multiple, concurrent writers to the
      * keylog, so we have to do everything in a single call to
      * fwrite. */
 
     strcpy(buf, label);
     offset = strlen(label);
     buf[offset++] += ' ';
-    hexEncode(buf + offset, ss->ssl3.hs.client_random, SSL3_RANDOM_LENGTH);
+    hexEncode(buf + offset, ss->ssl3.hs.client_random.rand, SSL3_RANDOM_LENGTH);
     offset += SSL3_RANDOM_LENGTH * 2;
     buf[offset++] = ' ';
     hexEncode(buf + offset, keyData->data, keyData->len);
     offset += keyData->len * 2;
     buf[offset++] = '\n';
 
     PORT_Assert(offset == len);
 
@@ -11635,17 +11557,16 @@ ssl3_FillInCachedSID(sslSocket *ss, sslS
 
     if (ss->xtnData.nextProtoState != SSL_NEXT_PROTO_NO_SUPPORT &&
         ss->xtnData.nextProto.data) {
         if (SECITEM_CopyItem(
                 NULL, &sid->u.ssl3.alpnSelection, &ss->xtnData.nextProto) != SECSuccess) {
             return SECFailure; /* error already set. */
         }
     }
-    sid->u.ssl3.altHandshakeType = ss->ssl3.hs.altHandshakeType;
 
     ssl_GetSpecReadLock(ss); /*************************************/
 
     /* Copy the master secret (wrapped or unwrapped) into the sid */
     if (ss->ssl3.crSpec->msItem.len && ss->ssl3.crSpec->msItem.data) {
         sid->u.ssl3.keys.wrapped_master_secret_len =
             ss->ssl3.crSpec->msItem.len;
         memcpy(sid->u.ssl3.keys.wrapped_master_secret,
@@ -12450,17 +12371,17 @@ ssl3_UnprotectRecord(sslSocket *ss, SSL3
         /* XXX For many AEAD ciphers, the plaintext is shorter than the
          * ciphertext by a fixed byte count, but it is not true in general.
          * Each AEAD cipher should provide a function that returns the
          * plaintext length for a given ciphertext. */
         unsigned int decryptedLen =
             cText->buf->len - cipher_def->explicit_nonce_size -
             cipher_def->tag_size;
         headerLen = ssl3_BuildRecordPseudoHeader(
-            header, crSpec->epoch, IS_DTLS(ss) ? cText->seq_num : crSpec->read_seq_num,
+            header, IS_DTLS(ss) ? cText->seq_num : crSpec->read_seq_num,
             rType, isTLS, cText->version, IS_DTLS(ss), decryptedLen);
         PORT_Assert(headerLen <= sizeof(header));
         rv = crSpec->aead(
             ss->sec.isServer ? &crSpec->client : &crSpec->server,
             PR_TRUE,                /* do decrypt */
             plaintext->buf,         /* out */
             (int *)&plaintext->len, /* outlen */
             plaintext->space,       /* maxout */
@@ -12499,18 +12420,17 @@ ssl3_UnprotectRecord(sslSocket *ss, SSL3
             } else {
                 good &= SECStatusToMask(ssl_RemoveTLSCBCPadding(
                     plaintext, macSize));
             }
         }
 
         /* compute the MAC */
         headerLen = ssl3_BuildRecordPseudoHeader(
-            header, crSpec->epoch,
-            IS_DTLS(ss) ? cText->seq_num : crSpec->read_seq_num,
+            header, IS_DTLS(ss) ? cText->seq_num : crSpec->read_seq_num,
             rType, isTLS, cText->version, IS_DTLS(ss),
             plaintext->len - crSpec->mac_size);
         PORT_Assert(headerLen <= sizeof(header));
         if (cipher_def->type == type_block) {
             rv = ssl3_ComputeRecordMACConstantTime(
                 crSpec, (PRBool)(!ss->sec.isServer), header, headerLen,
                 plaintext->buf, plaintext->len, originalLen,
                 hash, &hashBytes);
@@ -12691,36 +12611,21 @@ ssl3_HandleRecord(sslSocket *ss, SSL3Cip
     if (rv != SECSuccess) {
         ssl_ReleaseSpecReadLock(ss); /***************************/
 
         SSL_DBG(("%d: SSL3[%d]: decryption failed", SSL_GETPID(), ss->fd));
 
         /* Clear the temp buffer used for decompression upon failure. */
         sslBuffer_Clear(&temp_buf);
 
-        /* Zero the input so that we don't process it again. */
-        databuf->len = 0;
-
-        /* Ignore a CCS if the alternative handshake is negotiated.  Note that
-         * this will fail if the server fails to negotiate the alternative
-         * handshake type in a 0-RTT session that is resumed from a session that
-         * did negotiate it.  We don't care about that corner case right now. */
-        if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3 &&
-            cText->type == content_change_cipher_spec &&
-            ss->ssl3.hs.ws != idle_handshake &&
-            ss->ssl3.hs.altHandshakeType &&
-            cText->buf->len == 1 &&
-            cText->buf->buf[0] == change_cipher_spec_choice) {
-            /* Ignore the error. */
-            return SECSuccess;
-        }
         if (IS_DTLS(ss) ||
             (ss->sec.isServer &&
              ss->ssl3.hs.zeroRttIgnore == ssl_0rtt_ignore_trial)) {
             /* Silently drop the packet */
+            databuf->len = 0; /* Needed to ensure data not left around */
             return SECSuccess;
         } else {
             int errCode = PORT_GetError();
             SSL3_SendAlert(ss, alert_fatal, alert);
             /* Reset the error code in case SSL3_SendAlert called
              * PORT_SetError(). */
             PORT_SetError(errCode);
             return SECFailure;
@@ -12799,17 +12704,17 @@ ssl3_HandleRecord(sslSocket *ss, SSL3Cip
         }
 
         sslBuffer_Clear(&temp_buf);
     }
 
     /*
     ** Having completed the decompression, check the length again.
     */
-    if (isTLS && databuf->len > MAX_FRAGMENT_LENGTH) {
+    if (isTLS && databuf->len > (MAX_FRAGMENT_LENGTH + 1024)) {
         SSL3_SendAlert(ss, alert_fatal, record_overflow);
         PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG);
         return SECFailure;
     }
 
     /* Application data records are processed by the caller of this
     ** function, not by this function.
     */
@@ -12949,37 +12854,17 @@ ssl3_InitState(sslSocket *ss)
 
     ssl_InitSecState(&ss->sec);
 
     ssl_GetSpecWriteLock(ss);
     ss->ssl3.crSpec = ss->ssl3.cwSpec = &ss->ssl3.specs[0];
     ss->ssl3.prSpec = ss->ssl3.pwSpec = &ss->ssl3.specs[1];
     ssl3_InitCipherSpec(ss->ssl3.crSpec);
     ssl3_InitCipherSpec(ss->ssl3.prSpec);
-    ss->ssl3.crSpec->version = ss->vrange.max;
-    if (IS_DTLS(ss)) {
-        ss->ssl3.crSpec->recordVersion = SSL_LIBRARY_VERSION_DTLS_1_0_WIRE;
-    } else {
-        /* For new connections, cap the record layer version number of TLS
-         * ClientHello to { 3, 1 } (TLS 1.0). Some TLS 1.0 servers (which seem
-         * to use F5 BIG-IP) ignore ClientHello.client_version and use the
-         * record layer version number (TLSPlaintext.version) instead when
-         * negotiating protocol versions. In addition, if the record layer
-         * version number of ClientHello is { 3, 2 } (TLS 1.1) or higher, these
-         * servers reset the TCP connections. Lastly, some F5 BIG-IP servers
-         * hang if a record containing a ClientHello has a version greater than
-         * { 3, 1 } and a length greater than 255. Set this flag to work around
-         * such servers.
-         *
-         * We bump the version up when we settle on a version.  Before producing
-         * an initial ServerHello, or when processing it.
-         */
-        ss->ssl3.crSpec->recordVersion = PR_MIN(SSL_LIBRARY_VERSION_TLS_1_0,
-                                                ss->vrange.max);
-    }
+    ss->ssl3.crSpec->version = ss->ssl3.prSpec->version = ss->vrange.max;
     ssl_ReleaseSpecWriteLock(ss);
 
     ss->ssl3.hs.sendingSCSV = PR_FALSE;
     ss->ssl3.hs.preliminaryInfo = 0;
     ss->ssl3.hs.ws = (ss->sec.isServer) ? wait_client_hello : wait_server_hello;
 
     ssl3_ResetExtensionData(&ss->xtnData);
     PR_INIT_CLIST(&ss->ssl3.hs.remoteExtensions);
@@ -13338,17 +13223,16 @@ ssl3_DestroySSL3Info(sslSocket *ss)
         sslBuffer_Clear(&ss->ssl3.hs.messages);
     }
 
     /* free the SSL3Buffer (msg_body) */
     PORT_Free(ss->ssl3.hs.msg_body.buf);
 
     SECITEM_FreeItem(&ss->ssl3.hs.newSessionTicket.ticket, PR_FALSE);
     SECITEM_FreeItem(&ss->ssl3.hs.srvVirtName, PR_FALSE);
-    SECITEM_FreeItem(&ss->ssl3.hs.fakeSid, PR_FALSE);
 
     if (ss->ssl3.hs.certificateRequest) {
         PORT_FreeArena(ss->ssl3.hs.certificateRequest->arena, PR_FALSE);
         ss->ssl3.hs.certificateRequest = NULL;
     }
 
     /* free up the CipherSpecs */
     ssl3_DestroyCipherSpec(&ss->ssl3.specs[0], PR_TRUE /*freeSrvName*/);
--- a/security/nss/lib/ssl/ssl3ecc.c
+++ b/security/nss/lib/ssl/ssl3ecc.c
@@ -106,17 +106,17 @@ ssl_ECPubKey2NamedGroup(const SECKEYPubl
 
     return NULL;
 }
 
 /* Caller must set hiLevel error code. */
 static SECStatus
 ssl3_ComputeECDHKeyHash(SSLHashType hashAlg,
                         SECItem ec_params, SECItem server_ecpoint,
-                        PRUint8 *client_rand, PRUint8 *server_rand,
+                        SSL3Random *client_rand, SSL3Random *server_rand,
                         SSL3Hashes *hashes)
 {
     PRUint8 *hashBuf;
     PRUint8 *pBuf;
     SECStatus rv = SECSuccess;
     unsigned int bufLen;
     /*
      * We only support named curves (the appropriate checks are made before this
@@ -592,18 +592,18 @@ ssl3_HandleECDHServerKeyExchange(sslSock
     /* failures after this point are not malformed handshakes. */
     /* TLS: send decrypt_error if signature failed. */
     desc = isTLS ? decrypt_error : handshake_failure;
 
     /*
      *  check to make sure the hash is signed by right guy
      */
     rv = ssl3_ComputeECDHKeyHash(hashAlg, ec_params, ec_point,
-                                 ss->ssl3.hs.client_random,
-                                 ss->ssl3.hs.server_random,
+                                 &ss->ssl3.hs.client_random,
+                                 &ss->ssl3.hs.server_random,
                                  &hashes);
 
     if (rv != SECSuccess) {
         errCode =
             ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
         goto alert_loser;
     }
     rv = ssl3_VerifySignedHashes(ss, sigScheme, &hashes, &signature);
@@ -706,18 +706,18 @@ ssl3_SendECDHServerKeyExchange(sslSocket
     if (ss->ssl3.pwSpec->version == SSL_LIBRARY_VERSION_TLS_1_2) {
         hashAlg = ssl_SignatureSchemeToHashType(ss->ssl3.hs.signatureScheme);
     } else {
         /* Use ssl_hash_none to represent the MD5+SHA1 combo. */
         hashAlg = ssl_hash_none;
     }
     rv = ssl3_ComputeECDHKeyHash(hashAlg, ec_params,
                                  pubKey->u.ec.publicValue,
-                                 ss->ssl3.hs.client_random,
-                                 ss->ssl3.hs.server_random,
+                                 &ss->ssl3.hs.client_random,
+                                 &ss->ssl3.hs.server_random,
                                  &hashes);
     if (rv != SECSuccess) {
         ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
         goto loser;
     }
 
     isTLS12 = (PRBool)(ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);
 
--- a/security/nss/lib/ssl/ssl3exthandle.c
+++ b/security/nss/lib/ssl/ssl3exthandle.c
@@ -797,17 +797,17 @@ ssl3_ClientHandleStatusRequestXtn(const 
     }
 
     /* Keep track of negotiated extensions. */
     xtnData->negotiated[xtnData->numNegotiated++] = ex_type;
     return SECSuccess;
 }
 
 PRUint32 ssl_ticket_lifetime = 2 * 24 * 60 * 60; /* 2 days in seconds */
-#define TLS_EX_SESS_TICKET_VERSION (0x0107)
+#define TLS_EX_SESS_TICKET_VERSION (0x0106)
 
 /*
  * Called from ssl3_SendNewSessionTicket, tls13_SendNewSessionTicket
  */
 SECStatus
 ssl3_EncodeSessionTicket(sslSocket *ss,
                          const NewSessionTicket *ticket,
                          SECItem *ticket_data)
@@ -889,17 +889,16 @@ ssl3_EncodeSessionTicket(sslSocket *ss,
         + 2                                    /* master_secret.length */
         + ms_item.len                          /* master_secret */
         + 1                                    /* client_auth_type */
         + cert_length                          /* cert */
         + 2 + srvName->len                     /* name len + length field */
         + 1                                    /* extendedMasterSecretUsed */
         + sizeof(ticket->ticket_lifetime_hint) /* ticket lifetime hint */
         + sizeof(ticket->flags)                /* ticket flags */
-        + 1                                    /* alt handshake type */
         + 1 + alpnSelection->len               /* alpn value + length field */
         + 4;                                   /* maxEarlyData */
 
     if (SECITEM_AllocItem(NULL, &plaintext_item, plaintext_length) == NULL)
         goto loser;
 
     plaintext = plaintext_item;
 
@@ -1036,21 +1035,16 @@ ssl3_EncodeSessionTicket(sslSocket *ss,
     if (rv != SECSuccess)
         goto loser;
     if (alpnSelection->len) {
         rv = ssl3_AppendToItem(&plaintext, alpnSelection->data,
                                alpnSelection->len);
         if (rv != SECSuccess)
             goto loser;
     }
-    /* Alternative handshake type. */
-    rv = ssl3_AppendNumberToItem(
-        &plaintext, ss->sec.ci.sid->u.ssl3.altHandshakeType, 1);
-    if (rv != SECSuccess)
-        goto loser;
 
     rv = ssl3_AppendNumberToItem(&plaintext, ssl_max_early_data_size, 4);
     if (rv != SECSuccess)
         goto loser;
 
     /* Check that we are totally full. */
     PORT_Assert(plaintext.len == 0);
 
@@ -1307,24 +1301,16 @@ ssl_ParseSessionTicket(sslSocket *ss, co
     rv = ssl3_ExtConsumeHandshakeVariable(ss, &parsedTicket->alpnSelection, 1,
                                           &buffer, &len);
     PORT_Assert(parsedTicket->alpnSelection.len < 256);
     if (rv != SECSuccess) {
         PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
         return SECFailure;
     }
 
-    rv = ssl3_ExtConsumeHandshakeNumber(ss, &temp, 1, &buffer, &len);
-    if (rv != SECSuccess) {
-        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
-        return SECFailure;
-    }
-    PORT_Assert(temp == PR_TRUE || temp == PR_FALSE);
-    parsedTicket->altHandshakeType = temp;
-
     rv = ssl3_ExtConsumeHandshakeNumber(ss, &temp, 4, &buffer, &len);
     if (rv != SECSuccess) {
         PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
         return SECFailure;
     }
     parsedTicket->maxEarlyData = temp;
 
 #ifndef UNSAFE_FUZZER_MODE
@@ -1379,17 +1365,16 @@ ssl_CreateSIDFromTicket(sslSocket *ss, c
     PORT_Memcpy(sid->u.ssl3.keys.wrapped_master_secret,
                 parsedTicket->master_secret, parsedTicket->ms_length);
     sid->u.ssl3.keys.wrapped_master_secret_len = parsedTicket->ms_length;
     sid->u.ssl3.masterWrapMech = parsedTicket->msWrapMech;
     sid->u.ssl3.keys.msIsWrapped = parsedTicket->ms_is_wrapped;
     sid->u.ssl3.masterValid = PR_TRUE;
     sid->u.ssl3.keys.resumable = PR_TRUE;
     sid->u.ssl3.keys.extendedMasterSecretUsed = parsedTicket->extendedMasterSecretUsed;
-    sid->u.ssl3.altHandshakeType = parsedTicket->altHandshakeType;
 
     /* Copy over client cert from session ticket if there is one. */
     if (parsedTicket->peer_cert.data != NULL) {
         PORT_Assert(!sid->peerCert);
         sid->peerCert = CERT_NewTempCertificate(ss->dbHandle,
                                                 &parsedTicket->peer_cert,
                                                 NULL, PR_FALSE, PR_TRUE);
         if (!sid->peerCert) {
--- a/security/nss/lib/ssl/ssl3gthr.c
+++ b/security/nss/lib/ssl/ssl3gthr.c
@@ -390,18 +390,17 @@ dtls_GatherData(sslSocket *ss, sslGather
  */
 int
 ssl3_GatherCompleteHandshake(sslSocket *ss, int flags)
 {
     int rv;
     SSL3Ciphertext cText;
     PRBool keepGoing = PR_TRUE;
 
-    SSL_TRC(30, ("%d: SSL3[%d]: ssl3_GatherCompleteHandshake",
-                 SSL_GETPID(), ss->fd));
+    SSL_TRC(30, ("ssl3_GatherCompleteHandshake"));
 
     /* ssl3_HandleRecord may end up eventually calling ssl_FinishHandshake,
      * which requires the 1stHandshakeLock, which must be acquired before the
      * RecvBufLock.
      */
     PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss));
     PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
 
@@ -504,16 +503,17 @@ ssl3_GatherCompleteHandshake(sslSocket *
                 } else {
                     cText.type = (SSL3ContentType)ss->gs.hdr[0];
                     cText.version = (ss->gs.hdr[1] << 8) | ss->gs.hdr[2];
                 }
 
                 if (IS_DTLS(ss)) {
                     sslSequenceNumber seq_num;
 
+                    cText.version = dtls_DTLSVersionToTLSVersion(cText.version);
                     /* DTLS sequence number */
                     PORT_Memcpy(&seq_num, &ss->gs.hdr[3], sizeof(seq_num));
                     cText.seq_num = PR_ntohll(seq_num);
                 }
 
                 cText.buf = &ss->gs.inbuf;
                 rv = ssl3_HandleRecord(ss, &cText, &ss->gs.buf);
             }
--- a/security/nss/lib/ssl/ssl3prot.h
+++ b/security/nss/lib/ssl/ssl3prot.h
@@ -146,17 +146,19 @@ typedef enum {
     certificate_status = 22,
     next_proto = 67
 } SSL3HandshakeType;
 
 typedef struct {
     PRUint8 empty;
 } SSL3HelloRequest;
 
-typedef PRUint8 SSL3Random[SSL3_RANDOM_LENGTH];
+typedef struct {
+    PRUint8 rand[SSL3_RANDOM_LENGTH];
+} SSL3Random;
 
 typedef struct {
     PRUint8 id[32];
     PRUint8 length;
 } SSL3SessionID;
 
 typedef struct {
     SSL3ProtocolVersion client_version;
--- a/security/nss/lib/ssl/sslexp.h
+++ b/security/nss/lib/ssl/sslexp.h
@@ -17,20 +17,21 @@ SEC_BEGIN_PROTOS
  * future NSS versions. Code that uses these functions needs to safeguard
  * against the function not being available. */
 
 #define SSL_EXPERIMENTAL_API(name, arglist, args)                   \
     (SSL_GetExperimentalAPI(name)                                   \
          ? ((SECStatus(*) arglist)SSL_GetExperimentalAPI(name))args \
          : SECFailure)
 
-/* Make the TLS 1.3 handshake mimic TLS 1.2 session resumption.
+/* Allow the ServerHello to be record type 24. Experiment to test:
+ * https://github.com/tlswg/tls13-spec/pull/1051
  * This will either become part of the standard or be disabled
  * after we have tested it.
  */
-#define SSL_UseAltHandshakeType(fd, enable)                  \
-    SSL_EXPERIMENTAL_API("SSL_UseAltHandshakeType",          \
+#define SSL_UseAltServerHelloType(fd, enable)                \
+    SSL_EXPERIMENTAL_API("SSL_UseAltServerHelloType",        \
                          (PRFileDesc * _fd, PRBool _enable), \
                          (fd, enable))
 
 SEC_END_PROTOS
 
 #endif /* __sslexp_h_ */
--- a/security/nss/lib/ssl/sslimpl.h
+++ b/security/nss/lib/ssl/sslimpl.h
@@ -224,16 +224,18 @@ struct sslSocketOpsStr {
     int (*getpeername)(sslSocket *, PRNetAddr *);
     int (*getsockname)(sslSocket *, PRNetAddr *);
 };
 
 /* Flags interpreted by ssl send functions. */
 #define ssl_SEND_FLAG_FORCE_INTO_BUFFER 0x40000000
 #define ssl_SEND_FLAG_NO_BUFFER 0x20000000
 #define ssl_SEND_FLAG_NO_RETRANSMIT 0x08000000 /* DTLS only */
+#define ssl_SEND_FLAG_CAP_RECORD_VERSION \
+    0x04000000 /* TLS only */
 #define ssl_SEND_FLAG_MASK 0x7f000000
 
 /*
 ** A buffer object.
 */
 struct sslBufferStr {
     unsigned char *buf;
     unsigned int len;
@@ -493,17 +495,16 @@ struct ssl3CipherSpecStr {
     SSLDestroy destroyCompressContext;
     void *compressContext;
     SSLDestroy destroyDecompressContext;
     void *decompressContext;
     PK11SymKey *master_secret;
     sslSequenceNumber write_seq_num;
     sslSequenceNumber read_seq_num;
     SSL3ProtocolVersion version;
-    SSL3ProtocolVersion recordVersion;
     ssl3KeyMaterial client;
     ssl3KeyMaterial server;
     SECItem msItem;
     DTLSEpoch epoch;
     DTLSRecvdRecords recvdRecords;
     /* The number of 0-RTT bytes that can be sent or received in TLS 1.3. This
      * will be zero for everything but 0-RTT. */
     PRUint32 earlyDataRemaining;
@@ -603,18 +604,16 @@ struct sslSessionIDStr {
             ** (used only in client).
             */
             SECItem signedCertTimestamps;
 
             /* The NPN/ALPN value negotiated in the original connection.
              * Used for TLS 1.3. */
             SECItem alpnSelection;
 
-            PRBool altHandshakeType;
-
             /* This lock is lazily initialized by CacheSID when a sid is first
              * cached. Before then, there is no need to lock anything because
              * the sid isn't being shared by anything.
              */
             PRRWLock *lock;
 
             /* The lock must be held while reading or writing these members
              * because they change while the sid is cached.
@@ -882,18 +881,17 @@ typedef struct SSL3HandshakeStateStr {
     ssl3CipherSuite zeroRttSuite;   /* The cipher suite we used for 0-RTT. */
     PRCList bufferedEarlyData;      /* Buffered TLS 1.3 early data
                                      * on server.*/
     PRBool helloRetry;              /* True if HelloRetryRequest has been sent
                                      * or received. */
     ssl3KEADef kea_def_mutable;     /* Used to hold the writable kea_def
                                      * we use for TLS 1.3 */
     PRBool shortHeaders;            /* Assigned if we are doing short headers. */
-    PRBool altHandshakeType;        /* Alternative ServerHello content type. */
-    SECItem fakeSid;                /* ... (server) the SID the client used. */
+    PRBool altHandshakeType;        /* Assigned if we are doing the wrapped handshake. */
 } SSL3HandshakeState;
 
 /*
 ** This is the "ssl3" struct, as in "ss->ssl3".
 ** note:
 ** usually,   crSpec == cwSpec and prSpec == pwSpec.
 ** Sometimes, crSpec == pwSpec and prSpec == cwSpec.
 ** But there are never more than 2 actual specs.
@@ -1019,17 +1017,16 @@ typedef struct SessionTicketStr {
     PRUint8 master_secret[48];
     PRBool extendedMasterSecretUsed;
     ClientAuthenticationType client_auth_type;
     SECItem peer_cert;
     PRUint32 timestamp;
     PRUint32 flags;
     SECItem srvName; /* negotiated server name */
     SECItem alpnSelection;
-    PRBool altHandshakeType;
     PRUint32 maxEarlyData;
 } SessionTicket;
 
 /*
  * SSL2 buffers used in SSL3.
  *     writeBuf in the SecurityInfo maintained by sslsecur.c is used
  *              to hold the data just about to be passed to the kernel
  *     sendBuf in the ConnectInfo maintained by sslcon.c is used
@@ -1651,20 +1648,16 @@ extern SECStatus ssl3_HandleHandshakeMes
 extern void ssl3_DestroySSL3Info(sslSocket *ss);
 
 extern SECStatus ssl_ClientReadVersion(sslSocket *ss, PRUint8 **b,
                                        PRUint32 *length,
                                        SSL3ProtocolVersion *version);
 extern SECStatus ssl3_NegotiateVersion(sslSocket *ss,
                                        SSL3ProtocolVersion peerVersion,
                                        PRBool allowLargerPeerVersion);
-extern SECStatus ssl_ClientSetCipherSuite(sslSocket *ss,
-                                          SSL3ProtocolVersion version,
-                                          ssl3CipherSuite suite,
-                                          PRBool initHashes);
 
 extern SECStatus ssl_GetPeerInfo(sslSocket *ss);
 
 /* ECDH functions */
 extern SECStatus ssl3_SendECDHClientKeyExchange(sslSocket *ss,
                                                 SECKEYPublicKey *svrPubKey);
 extern SECStatus ssl3_HandleECDHServerKeyExchange(sslSocket *ss,
                                                   PRUint8 *b, PRUint32 length);
@@ -1828,17 +1821,16 @@ SECStatus ssl_GetCertificateRequestCAs(s
                                        SECItem **namesp, unsigned int *nnamesp);
 SECStatus ssl3_ParseCertificateRequestCAs(sslSocket *ss, PRUint8 **b,
                                           PRUint32 *length, PLArenaPool *arena,
                                           CERTDistNames *ca_list);
 SECStatus ssl3_CompleteHandleCertificateRequest(
     sslSocket *ss, const SSLSignatureScheme *signatureSchemes,
     unsigned int signatureSchemeCount, CERTDistNames *ca_list);
 SECStatus ssl3_SendServerHello(sslSocket *ss);
-SECStatus ssl3_SendChangeCipherSpecsInt(sslSocket *ss);
 SECStatus ssl3_ComputeHandshakeHashes(sslSocket *ss,
                                       ssl3CipherSpec *spec,
                                       SSL3Hashes *hashes,
                                       PRUint32 sender);
 SECStatus ssl_CreateECDHEphemeralKeyPair(const sslSocket *ss,
                                          const sslNamedGroupDef *ecGroup,
                                          sslEphemeralKeyPair **keyPair);
 SECStatus ssl_CreateStaticECDHEKey(sslSocket *ss,
--- a/security/nss/lib/ssl/sslinfo.c
+++ b/security/nss/lib/ssl/sslinfo.c
@@ -463,19 +463,19 @@ SSL_ExportKeyingMaterial(PRFileDesc *fd,
     if (hasContext) {
         valLen += 2 /* PRUint16 length */ + contextLen;
     }
     val = PORT_Alloc(valLen);
     if (!val) {
         return SECFailure;
     }
     i = 0;
-    PORT_Memcpy(val + i, ss->ssl3.hs.client_random, SSL3_RANDOM_LENGTH);
+    PORT_Memcpy(val + i, &ss->ssl3.hs.client_random.rand, SSL3_RANDOM_LENGTH);
     i += SSL3_RANDOM_LENGTH;
-    PORT_Memcpy(val + i, ss->ssl3.hs.server_random, SSL3_RANDOM_LENGTH);
+    PORT_Memcpy(val + i, &ss->ssl3.hs.server_random.rand, SSL3_RANDOM_LENGTH);
     i += SSL3_RANDOM_LENGTH;
     if (hasContext) {
         val[i++] = contextLen >> 8;
         val[i++] = contextLen;
         PORT_Memcpy(val + i, context, contextLen);
         i += contextLen;
     }
     PORT_Assert(i == valLen);
--- a/security/nss/lib/ssl/sslsock.c
+++ b/security/nss/lib/ssl/sslsock.c
@@ -3870,17 +3870,17 @@ SSL_CanBypass(CERTCertificate *cert, SEC
     {                      \
         "SSL_" #n, SSL_##n \
     }
 struct {
     const char *const name;
     void *function;
 } ssl_experimental_functions[] = {
 #ifndef SSL_DISABLE_EXPERIMENTAL_API
-    EXP(UseAltHandshakeType),
+    EXP(UseAltServerHelloType),
 #endif
     { "", NULL }
 };
 #undef EXP
 #undef PUB
 
 void *
 SSL_GetExperimentalAPI(const char *name)
--- a/security/nss/lib/ssl/tls13con.c
+++ b/security/nss/lib/ssl/tls13con.c
@@ -128,16 +128,19 @@ const char keylogLabelClientTrafficSecre
 const char keylogLabelServerTrafficSecret[] = "SERVER_TRAFFIC_SECRET_0";
 const char keylogLabelExporterSecret[] = "EXPORTER_SECRET";
 
 #define TRAFFIC_SECRET(ss, dir, name) ((ss->sec.isServer ^            \
                                         (dir == CipherSpecWrite))     \
                                            ? ss->ssl3.hs.client##name \
                                            : ss->ssl3.hs.server##name)
 
+const SSL3ProtocolVersion kTlsRecordVersion = SSL_LIBRARY_VERSION_TLS_1_0;
+const SSL3ProtocolVersion kDtlsRecordVersion = SSL_LIBRARY_VERSION_TLS_1_1;
+
 /* Belt and suspenders in case we ever add a TLS 1.4. */
 PR_STATIC_ASSERT(SSL_LIBRARY_VERSION_MAX_SUPPORTED <=
                  SSL_LIBRARY_VERSION_TLS_1_3);
 
 /* Use this instead of FATAL_ERROR when no alert shall be sent. */
 #define LOG_ERROR(ss, prError)                                                     \
     do {                                                                           \
         SSL_TRC(3, ("%d: TLS13[%d]: fatal error %d in %s (%s:%d)",                 \
@@ -1720,19 +1723,17 @@ tls13_HandleHelloRetryRequest(sslSocket 
         ssl_ReleaseSpecWriteLock(ss);
     } else {
         PORT_Assert(ss->ssl3.hs.zeroRttState == ssl_0rtt_none);
     }
 
     /* Version. */
     rv = ssl_ClientReadVersion(ss, &b, &length, &version);
     if (rv != SECSuccess) {
-        FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_HELLO_RETRY_REQUEST,
-                    protocol_version);
-        return SECFailure;
+        return SECFailure; /* alert already sent */
     }
     if (version > ss->vrange.max || version < SSL_LIBRARY_VERSION_TLS_1_3) {
         FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_HELLO_RETRY_REQUEST,
                     protocol_version);
         return SECFailure;
     }
 
     /* Extensions. */
@@ -1935,23 +1936,16 @@ tls13_SendServerHelloSequence(sslSocket 
     PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
     PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
 
     rv = ssl3_SendServerHello(ss);
     if (rv != SECSuccess) {
         return rv; /* err code is set. */
     }
 
-    if (ss->ssl3.hs.altHandshakeType) {
-        rv = ssl3_SendChangeCipherSpecsInt(ss);
-        if (rv != SECSuccess) {
-            return rv;
-        }
-    }
-
     rv = tls13_SendEncryptedServerSequence(ss);
     if (rv != SECSuccess) {
         err = PORT_GetError();
     }
     /* Even if we get an error, since the ServerHello was successfully
      * serialized, we should give it a chance to reach the network.  This gives
      * the client a chance to perform the key exchange and decrypt the alert
      * we're about to send. */
@@ -2705,74 +2699,37 @@ tls13_DeriveTrafficKeys(sslSocket *ss, s
         *prkp = NULL;
     }
     return SECSuccess;
 
 loser:
     return SECFailure;
 }
 
-void
-tls13_SetSpecRecordVersion(sslSocket *ss, ssl3CipherSpec *spec)
+static SECStatus
+tls13_SetupPendingCipherSpec(sslSocket *ss)
 {
-    const SSL3ProtocolVersion kTlsRecordVersion = SSL_LIBRARY_VERSION_TLS_1_0;
-    const SSL3ProtocolVersion kTlsAltRecordVersion = SSL_LIBRARY_VERSION_TLS_1_2;
-    const SSL3ProtocolVersion kDtlsRecordVersion = SSL_LIBRARY_VERSION_DTLS_1_0_WIRE;
-
-    /* Set the record version. */
-    if (IS_DTLS(ss)) {
-        spec->recordVersion = kDtlsRecordVersion;
-    } else if (spec->epoch == TrafficKeyEarlyApplicationData) {
-        /* For early data, the previous session determines the record type that
-         * is used (and not what this session might negotiate). */
-        if (ss->sec.ci.sid && ss->sec.ci.sid->u.ssl3.altHandshakeType) {
-            spec->recordVersion = kTlsAltRecordVersion;
-        } else {
-            spec->recordVersion = kTlsRecordVersion;
-        }
-    } else if (ss->ssl3.hs.altHandshakeType) {
-        spec->recordVersion = kTlsAltRecordVersion;
-    } else {
-        spec->recordVersion = kTlsRecordVersion;
-    }
-    SSL_TRC(10, ("%d: TLS13[%d]: Set record version to 0x%04x",
-                 SSL_GETPID(), ss->fd, spec->recordVersion));
-}
-
-static SECStatus
-tls13_SetupPendingCipherSpec(sslSocket *ss, ssl3CipherSpec *spec)
-{
+    ssl3CipherSpec *pSpec;
     ssl3CipherSuite suite = ss->ssl3.hs.cipher_suite;
+    const ssl3BulkCipherDef *bulk = ssl_GetBulkCipherDef(
+        ssl_LookupCipherSuiteDef(suite));
 
     PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
 
     ssl_GetSpecWriteLock(ss); /*******************************/
 
-    spec = ss->ssl3.pwSpec;
+    pSpec = ss->ssl3.pwSpec;
     /* Version isn't set when we send 0-RTT data. */
-    spec->version = PR_MAX(SSL_LIBRARY_VERSION_TLS_1_3, ss->version);
+    pSpec->version = PR_MAX(SSL_LIBRARY_VERSION_TLS_1_3, ss->version);
 
     SSL_TRC(3, ("%d: TLS13[%d]: Set Pending Cipher Suite to 0x%04x",
                 SSL_GETPID(), ss->fd, suite));
-
-    spec->cipher_def = ssl_GetBulkCipherDef(ssl_LookupCipherSuiteDef(suite));
-    switch (spec->cipher_def->calg) {
-        case ssl_calg_aes_gcm:
-            spec->aead = tls13_AESGCM;
-            break;
-        case ssl_calg_chacha20:
-            spec->aead = tls13_ChaCha20Poly1305;
-            break;
-        default:
-            PORT_Assert(0);
-            return SECFailure;
-            break;
-    }
-
-    tls13_SetSpecRecordVersion(ss, spec);
+    pSpec->cipher_def = bulk;
+
+    ssl_ReleaseSpecWriteLock(ss); /*******************************/
     return SECSuccess;
 }
 
 /* Install a new cipher spec for this direction. */
 static SECStatus
 tls13_SetCipherSpec(sslSocket *ss, TrafficKeyType type,
                     CipherSpecDirection direction, PRBool deleteSecret)
 {
@@ -2792,16 +2749,39 @@ tls13_SetCipherSpec(sslSocket *ss, Traff
     if (!spec) {
         PORT_SetError(SEC_ERROR_NO_MEMORY);
         return SECFailure;
     }
     spec->refCt = 1;
     PR_APPEND_LINK(&spec->link, &ss->ssl3.hs.cipherSpecs);
     ss->ssl3.pwSpec = ss->ssl3.prSpec = spec;
 
+    rv = tls13_SetupPendingCipherSpec(ss);
+    if (rv != SECSuccess)
+        return SECFailure;
+
+    switch (spec->cipher_def->calg) {
+        case calg_aes_gcm:
+            spec->aead = tls13_AESGCM;
+            break;
+        case calg_chacha20:
+            spec->aead = tls13_ChaCha20Poly1305;
+            break;
+        default:
+            PORT_Assert(0);
+            return SECFailure;
+            break;
+    }
+
+    rv = tls13_DeriveTrafficKeys(ss, spec, type, direction,
+                                 deleteSecret);
+    if (rv != SECSuccess) {
+        return SECFailure;
+    }
+
     /* We use the epoch for cipher suite identification, so increment
      * it in both TLS and DTLS. */
     if ((*specp)->epoch == PR_UINT16_MAX) {
         return SECFailure;
     }
     spec->epoch = (PRUint16)type;
 
     if (!IS_DTLS(ss)) {
@@ -2809,27 +2789,16 @@ tls13_SetCipherSpec(sslSocket *ss, Traff
     } else {
         /* The sequence number has the high 16 bits as the epoch. */
         spec->read_seq_num = spec->write_seq_num =
             (sslSequenceNumber)spec->epoch << 48;
 
         dtls_InitRecvdRecords(&spec->recvdRecords);
     }
 
-    /* This depends on spec having a valid direction and epoch. */
-    rv = tls13_SetupPendingCipherSpec(ss, spec);
-    if (rv != SECSuccess)
-        return SECFailure;
-
-    rv = tls13_DeriveTrafficKeys(ss, spec, type, direction,
-                                 deleteSecret);
-    if (rv != SECSuccess) {
-        return SECFailure;
-    }
-
     if (type == TrafficKeyEarlyApplicationData) {
         spec->earlyDataRemaining =
             ss->sec.ci.sid->u.ssl3.locked.sessionTicket.max_early_data_size;
     }
 
     /* Now that we've set almost everything up, finally cut over. */
     ssl_GetSpecWriteLock(ss);
     tls13_CipherSpecRelease(*specp); /* May delete old cipher. */
@@ -3771,24 +3740,16 @@ tls13_SendClientSecondRound(sslSocket *s
         return SECWouldBlock;
     }
 
     if (ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted) {
         rv = tls13_SendEndOfEarlyData(ss);
         if (rv != SECSuccess) {
             return SECFailure; /* Error code already set. */
         }
-    } else if (ss->ssl3.hs.zeroRttState == ssl_0rtt_none &&
-               ss->ssl3.hs.altHandshakeType) {
-        ssl_GetXmitBufLock(ss); /*******************************/
-        rv = ssl3_SendChangeCipherSpecsInt(ss);
-        ssl_ReleaseXmitBufLock(ss); /*******************************/
-        if (rv != SECSuccess) {
-            return rv;
-        }
     }
 
     rv = tls13_SetCipherSpec(ss, TrafficKeyHandshake,
                              CipherSpecWrite, PR_FALSE);
     if (rv != SECSuccess) {
         FATAL_ERROR(ss, SSL_ERROR_INIT_CIPHER_SUITE_FAILURE, internal_error);
         return SECFailure;
     }
@@ -4080,18 +4041,17 @@ static const struct {
     { ssl_tls13_pre_shared_key_xtn, ExtensionSendClear },
     { ssl_tls13_early_data_xtn, ExtensionSendEncrypted },
     { ssl_next_proto_nego_xtn, ExtensionNotUsed },
     { ssl_renegotiation_info_xtn, ExtensionNotUsed },
     { ssl_signed_cert_timestamp_xtn, ExtensionSendCertificate },
     { ssl_cert_status_xtn, ExtensionSendCertificate },
     { ssl_tls13_ticket_early_data_info_xtn, ExtensionNewSessionTicket },
     { ssl_tls13_cookie_xtn, ExtensionSendHrr },
-    { ssl_tls13_short_header_xtn, ExtensionSendClear },
-    { ssl_tls13_supported_versions_xtn, ExtensionSendClear }
+    { ssl_tls13_short_header_xtn, ExtensionSendClear }
 };
 
 PRBool
 tls13_ExtensionAllowed(PRUint16 extension, SSL3HandshakeType message)
 {
     unsigned int i;
 
     PORT_Assert((message == client_hello) ||
@@ -4274,18 +4234,19 @@ tls13_UnprotectRecord(sslSocket *ss, SSL
         SSL_TRC(3,
                 ("%d: TLS13[%d]: record has invalid exterior content type=%d",
                  SSL_GETPID(), ss->fd, cText->type));
         /* Do we need a better error here? */
         PORT_SetError(SSL_ERROR_BAD_MAC_READ);
         return SECFailure;
     }
 
-    /* Check the version number in the record. */
-    if (cText->version != crSpec->recordVersion) {
+    /* Check the version number in the record */
+    if ((IS_DTLS(ss) && cText->version != kDtlsRecordVersion) ||
+        (!IS_DTLS(ss) && cText->version != kTlsRecordVersion)) {
         /* Do we need a better error here? */
         SSL_TRC(3,
                 ("%d: TLS13[%d]: record has bogus version",
                  SSL_GETPID(), ss->fd));
         return SECFailure;
     }
 
     /* Decrypt */
@@ -4398,50 +4359,36 @@ tls13_MaybeDo0RTTHandshake(sslSocket *ss
     SSL_TRC(3, ("%d: TLS13[%d]: in 0-RTT mode", SSL_GETPID(), ss->fd));
 
     /* Set the ALPN data as if it was negotiated. We check in the ServerHello
      * handler that the server negotiates the same value. */
     if (ss->sec.ci.sid->u.ssl3.alpnSelection.len) {
         ss->xtnData.nextProtoState = SSL_NEXT_PROTO_EARLY_VALUE;
         rv = SECITEM_CopyItem(NULL, &ss->xtnData.nextProto,
                               &ss->sec.ci.sid->u.ssl3.alpnSelection);
-        if (rv != SECSuccess) {
-            return SECFailure;
-        }
-    }
-
-    /* If the alternative handshake type option is enabled and the last session
-     * had the alternative handshake type, then send CCS. */
-    if (ss->opt.enableAltHandshaketype &&
-        ss->sec.ci.sid->u.ssl3.altHandshakeType) {
-        ssl_GetXmitBufLock(ss);
-        rv = ssl3_SendChangeCipherSpecsInt(ss);
-        ssl_ReleaseXmitBufLock(ss);
-        if (rv != SECSuccess) {
-            return SECFailure;
-        }
+        if (rv != SECSuccess)
+            return rv;
     }
 
     /* Cipher suite already set in tls13_SetupClientHello. */
     ss->ssl3.hs.preliminaryInfo = 0;
 
     rv = tls13_DeriveSecret(ss, ss->ssl3.hs.currentSecret,
                             kHkdfLabelClient,
                             kHkdfLabelEarlyTrafficSecret,
                             keylogLabelClientEarlyTrafficSecret,
                             NULL,
                             &ss->ssl3.hs.clientEarlyTrafficSecret);
-    if (rv != SECSuccess) {
+    if (rv != SECSuccess)
         return SECFailure;
-    }
 
     rv = tls13_SetCipherSpec(ss, TrafficKeyEarlyApplicationData,
                              CipherSpecWrite, PR_TRUE);
     if (rv != SECSuccess) {
-        return SECFailure;
+        return rv;
     }
 
     return SECSuccess;
 }
 
 PRInt32
 tls13_Read0RttData(sslSocket *ss, void *buf, PRInt32 len)
 {
@@ -4552,17 +4499,17 @@ tls13_EncodeDraftVersion(SSL3ProtocolVer
     return (PRUint16)version;
 }
 
 PRUint16
 tls13_EncodeAltDraftVersion(SSL3ProtocolVersion version)
 {
 #ifdef TLS_1_3_DRAFT_VERSION
     if (version == SSL_LIBRARY_VERSION_TLS_1_3) {
-        return 0x7e02;
+        return 0x7a00 | TLS_1_3_DRAFT_VERSION;
     }
 #endif
     return (PRUint16)version;
 }
 
 /* Pick the highest version we support that is also advertised. */
 SECStatus
 tls13_NegotiateVersion(sslSocket *ss, const TLSExtension *supported_versions)
@@ -4589,44 +4536,37 @@ tls13_NegotiateVersion(sslSocket *ss, co
 
         for (offset = 0; offset < versions.len; offset += 2) {
             PRUint16 supported =
                 (versions.data[offset] << 8) | versions.data[offset + 1];
             if (supported == wire) {
                 ss->version = version;
                 return SECSuccess;
             }
-            if (ss->opt.enableAltHandshaketype &&
-                !IS_DTLS(ss) &&
+            if (ss->opt.enableAltHandshaketype && !IS_DTLS(ss) &&
                 supported == alt_wire) {
-                rv = ssl3_RegisterExtensionSender(ss, &ss->xtnData,
-                                                  ssl_tls13_supported_versions_xtn,
-                                                  tls13_ServerSendSupportedVersionsXtn);
-                if (rv != SECSuccess) {
-                    return SECFailure;
-                }
+                ss->version = version;
                 ss->ssl3.hs.altHandshakeType = PR_TRUE;
-                ss->version = version;
                 return SECSuccess;
             }
         }
     }
 
     FATAL_ERROR(ss, SSL_ERROR_UNSUPPORTED_VERSION, protocol_version);
     return SECFailure;
 }
 
 SECStatus
-SSLExp_UseAltHandshakeType(PRFileDesc *fd, PRBool enable)
+SSLExp_UseAltServerHelloType(PRFileDesc *fd, PRBool enable)
 {
     sslSocket *ss;
 
     ss = ssl_FindSocket(fd);
-    if (!ss || IS_DTLS(ss)) {
-        SSL_DBG(("%d: SSL[%d]: bad socket in SSLExp_UseAltHandshakeType",
+    if (!ss) {
+        SSL_DBG(("%d: SSL[%d]: bad socket in SSLExp_UseAltServerHelloType",
                  SSL_GETPID(), fd));
         PORT_SetError(SEC_ERROR_INVALID_ARGS);
         return SECFailure;
     }
 
     ss->opt.enableAltHandshaketype = enable;
 
     return SECSuccess;
--- a/security/nss/lib/ssl/tls13con.h
+++ b/security/nss/lib/ssl/tls13con.h
@@ -80,12 +80,11 @@ PRInt32 tls13_Read0RttData(sslSocket *ss
 SECStatus tls13_HandleEndOfEarlyData(sslSocket *ss);
 SECStatus tls13_HandleEarlyApplicationData(sslSocket *ss, sslBuffer *origBuf);
 PRBool tls13_ClientAllow0Rtt(const sslSocket *ss, const sslSessionID *sid);
 PRUint16 tls13_EncodeDraftVersion(SSL3ProtocolVersion version);
 PRUint16 tls13_EncodeAltDraftVersion(SSL3ProtocolVersion version);
 SECStatus tls13_NegotiateVersion(sslSocket *ss,
                                  const TLSExtension *supported_versions);
 SECStatus tls13_SendNewSessionTicket(sslSocket *ss);
-SECStatus SSLExp_UseAltHandshakeType(PRFileDesc *fd, PRBool enable);
-void tls13_SetSpecRecordVersion(sslSocket *ss, ssl3CipherSpec *spec);
+SECStatus SSLExp_UseAltServerHelloType(PRFileDesc *fd, PRBool enable);
 
 #endif /* __tls13con_h_ */
--- a/security/nss/lib/ssl/tls13exthandle.c
+++ b/security/nss/lib/ssl/tls13exthandle.c
@@ -868,37 +868,32 @@ tls13_ClientHandleTicketEarlyDataInfoXtn
 
     xtnData->max_early_data_size = PR_ntohl(utmp);
 
     return SECSuccess;
 }
 
 /*
  *     struct {
- *       select (Handshake.msg_type) {
- *       case client_hello:
  *          ProtocolVersion versions<2..254>;
- *       case server_hello:
- *          ProtocolVersion version;
- *       };
  *     } SupportedVersions;
  */
 PRInt32
 tls13_ClientSendSupportedVersionsXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append,
                                      PRUint32 maxBytes)
 {
     PRInt32 extensions_len;
     PRUint16 version;
     SECStatus rv;
 
     if (ss->vrange.max < SSL_LIBRARY_VERSION_TLS_1_3) {
         return 0;
     }
 
-    SSL_TRC(3, ("%d: TLS13[%d]: client send supported_versions extension",
+    SSL_TRC(3, ("%d: TLS13[%d]: send supported_versions extension",
                 SSL_GETPID(), ss->fd));
 
     /* Extension type, extension len fiels, vector len field,
      * length of the values. */
     extensions_len = 2 + 2 + 1 +
                      2 * (ss->vrange.max - ss->vrange.min + 1);
 
     if (ss->opt.enableAltHandshaketype && !IS_DTLS(ss)) {
@@ -941,60 +936,16 @@ tls13_ClientSendSupportedVersionsXtn(con
 
         xtnData->advertised[xtnData->numAdvertised++] =
             ssl_tls13_supported_versions_xtn;
     }
 
     return extensions_len;
 }
 
-PRInt32
-tls13_ServerSendSupportedVersionsXtn(const sslSocket *ss,
-                                     TLSExtensionData *xtnData,
-                                     PRBool append, PRUint32 maxBytes)
-{
-    SECStatus rv;
-    PRInt32 extensions_len;
-
-    if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
-        PORT_Assert(0); /* Can't happen. */
-        return SECSuccess;
-    }
-    if (!ss->ssl3.hs.altHandshakeType) {
-        PORT_Assert(0); /* Can't happen. */
-        return SECSuccess;
-    }
-
-    SSL_TRC(3, ("%d: TLS13[%d]: server send supported_versions extension",
-                SSL_GETPID(), ss->fd));
-
-    extensions_len = 2 + 2 + 2; /* type, len, version */
-    if (maxBytes < (PRUint32)extensions_len) {
-        PORT_Assert(0);
-        return 0;
-    }
-
-    if (append) {
-        rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_tls13_supported_versions_xtn, 2);
-        if (rv != SECSuccess)
-            return -1;
-
-        rv = ssl3_ExtAppendHandshakeNumber(ss, 2, 2);
-        if (rv != SECSuccess)
-            return -1;
-
-        rv = ssl3_ExtAppendHandshakeNumber(
-            ss, tls13_EncodeAltDraftVersion(SSL_LIBRARY_VERSION_TLS_1_3), 2);
-        if (rv != SECSuccess) {
-            return -1;
-        }
-    }
-    return extensions_len;
-}
-
 /*
  *    struct {
  *        opaque cookie<1..2^16-1>;
  *    } Cookie;
  */
 SECStatus
 tls13_ClientHandleHrrCookie(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data)
 {
--- a/security/nss/lib/ssl/tls13exthandle.h
+++ b/security/nss/lib/ssl/tls13exthandle.h
@@ -48,20 +48,16 @@ PRInt32 tls13_ServerSendEarlyDataXtn(con
                                      PRBool append,
                                      PRUint32 maxBytes);
 SECStatus tls13_ClientHandleTicketEarlyDataInfoXtn(
     const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type,
     SECItem *data);
 PRInt32 tls13_ClientSendSupportedVersionsXtn(const sslSocket *ss, TLSExtensionData *xtnData,
                                              PRBool append,
                                              PRUint32 maxBytes);
-PRInt32 tls13_ServerSendSupportedVersionsXtn(const sslSocket *ss,
-                                             TLSExtensionData *xtnData,
-                                             PRBool append,
-                                             PRUint32 maxBytes);
 SECStatus tls13_ClientHandleHrrCookie(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type,
                                       SECItem *data);
 PRInt32 tls13_ClientSendHrrCookieXtn(const sslSocket *ss, TLSExtensionData *xtnData,
                                      PRBool append,
                                      PRUint32 maxBytes);
 PRInt32 tls13_ClientSendPskKeyExchangeModesXtn(const sslSocket *ss,
                                                TLSExtensionData *xtnData,
                                                PRBool append, PRUint32 maxBytes);
--- a/security/nss/lib/util/nssutil.h
+++ b/security/nss/lib/util/nssutil.h
@@ -14,19 +14,19 @@
 
 /*
  * NSS utilities's major version, minor version, patch level, build number,
  * and whether this is a beta release.
  *
  * The format of the version string should be
  *     "<major version>.<minor version>[.<patch level>[.<build number>]][ <Beta>]"
  */
-#define NSSUTIL_VERSION "3.35 Beta"
+#define NSSUTIL_VERSION "3.34 Beta"
 #define NSSUTIL_VMAJOR 3
-#define NSSUTIL_VMINOR 35
+#define NSSUTIL_VMINOR 34
 #define NSSUTIL_VPATCH 0
 #define NSSUTIL_VBUILD 0
 #define NSSUTIL_BETA PR_TRUE
 
 SEC_BEGIN_PROTOS
 
 /*
  * Returns a const string of the UTIL library version.