Bug 1564499 - land NSS bbfc55939d75 UPGRADE_NSS_RELEASE, r=kjacobs
authorJ.C. Jones <jc@mozilla.com>
Thu, 15 Aug 2019 16:06:15 +0000
changeset 488260 d3b872e9aca1f511c540704d6354149b737e3d72
parent 488259 b1133e4b7e953cbb539e27ac7034b357a4e7b326
child 488261 067d47e20a9439ad81d0b119b1b660c9638ff08e
push id36440
push userncsoregi@mozilla.com
push dateFri, 16 Aug 2019 03:57:48 +0000
treeherdermozilla-central@a58b7dc85887 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskjacobs
bugs1564499, 1572593, 1573945, 1415118, 1539788, 1542077, 1572791, 1560593
milestone70.0a1
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
Bug 1564499 - land NSS bbfc55939d75 UPGRADE_NSS_RELEASE, r=kjacobs Revset: reverse(89aa19677e37~-1::bbfc55939d75) 2019-08-14 Kevin Jacobs <kjacobs@mozilla.com> * gtests/ssl_gtest/tls_agent.cc: Bug 1572593 - Re-revert call to CheckCertReqAgainstDefaultCAs to avoid memory leak (filed as bug 1573945). r=jcj Revert back to the changes Franziskus had made. Updated the in- source bug number to point to the new memleak bug. Differential Revision: https://phabricator.services.mozilla.com/D42020 [bbfc55939d75] [tip] 2019-08-12 Kevin Jacobs <kjacobs@mozilla.com> * gtests/freebl_gtest/freebl_gtest.gyp, gtests/mozpkix_gtest/mozpkix_gtest.gyp: Bug 1415118 - Fix --enable-libpkix builds from build.sh r=mt,jcj Differential Revision: https://phabricator.services.mozilla.com/D41617 [f8926908be71] 2019-08-14 J.C. Jones <jjones@mozilla.com> * gtests/ssl_gtest/tls_agent.cc, lib/ssl/ssl3ext.c: Bug 1572593 - Reset advertised extensions in ssl_ConstructExtensions r=mt,kjacobs Reset the list of advertised extensions before sending a new set. This reverts the changes of https://hg.mozilla.org/projects/nss/rev/ 1ca362213631d6edc885b6b965b52ecffcf29afd Differential Revision: https://phabricator.services.mozilla.com/D41302 [b03ff661491e] 2019-08-14 Kevin Jacobs <kjacobs@mozilla.com> * lib/freebl/ctr.c: Bug 1539788 - UBSAN fixup for 128b counter. r=mt,jcj Differential Revision: https://phabricator.services.mozilla.com/D41884 [9d1f5e71773d] 2019-08-13 Kevin Jacobs <kjacobs@mozilla.com> * lib/freebl/chacha20poly1305.c, lib/freebl/ctr.c, lib/freebl/gcm.c, lib/freebl/intel-gcm-wrap.c, lib/freebl/rsapkcs.c: Bug 1539788 - Add length checks for cryptographic primitives r=mt,jcj This patch adds additional length checks around cryptographic primitives. Differential Revision: https://phabricator.services.mozilla.com/D36079 [dfd6996fe742] 2019-08-13 Marcus Burghardt <mburghardt@mozilla.com> * gtests/freebl_gtest/mpi_unittest.cc, lib/freebl/mpi/README, lib/freebl/mpi/mpi.c, lib/freebl/mpi/mpi.h: Bug 1542077 - Added extra controls and tests to mp_set_int and mp_set_ulong. r=jcj,kjacobs Differential Revision: https://phabricator.services.mozilla.com/D40649 [9bc47e69613e] 2019-08-13 J.C. Jones <jjones@mozilla.com> * gtests/ssl_gtest/ssl_resumption_unittest.cc, gtests/ssl_gtest/tls_agent.cc: Bug 1572791 - Fixup clang-format r=bustage [ec113de50cdd] * gtests/ssl_gtest/tls_agent.cc, gtests/ssl_gtest/tls_subcerts_unittest.cc, lib/ssl/tls13subcerts.c: Bug 1572791 - Check for nulls in SSLExp_DelegateCredential and its tests r=kjacobs This particularly catches test errors in tls_subcerts_unittest when the profile is stale. Differential Revision: https://phabricator.services.mozilla.com/D41429 [ed5067857563] 2019-08-13 Kevin Jacobs <kjacobs@mozilla.com> * gtests/ssl_gtest/ssl_auth_unittest.cc, gtests/ssl_gtest/ssl_cert_ext_unittest.cc, gtests/ssl_gtest/ssl_resumption_unittest.cc, gtests/ssl_gtest/tls_agent.cc: Bug 1572791 - Fix ASAN cert errors when SSL gtests run on empty profile r=jcj Differential Revision: https://phabricator.services.mozilla.com/D41787 [cef2aa7f3b8c] 2019-08-09 Kevin Jacobs <kjacobs@mozilla.com> * tests/common/cleanup.sh: Bug 1560593 - Cleanup.sh to treat core dumps as test failures on optimized builds. r=jcj Differential Revision: https://phabricator.services.mozilla.com/D41392 [360010725fdb] Differential Revision: https://phabricator.services.mozilla.com/D42139
security/nss/TAG-INFO
security/nss/coreconf/coreconf.dep
security/nss/gtests/freebl_gtest/freebl_gtest.gyp
security/nss/gtests/freebl_gtest/mpi_unittest.cc
security/nss/gtests/mozpkix_gtest/mozpkix_gtest.gyp
security/nss/gtests/ssl_gtest/ssl_auth_unittest.cc
security/nss/gtests/ssl_gtest/ssl_cert_ext_unittest.cc
security/nss/gtests/ssl_gtest/ssl_resumption_unittest.cc
security/nss/gtests/ssl_gtest/tls_agent.cc
security/nss/gtests/ssl_gtest/tls_subcerts_unittest.cc
security/nss/lib/freebl/chacha20poly1305.c
security/nss/lib/freebl/ctr.c
security/nss/lib/freebl/gcm.c
security/nss/lib/freebl/intel-gcm-wrap.c
security/nss/lib/freebl/mpi/README
security/nss/lib/freebl/mpi/mpi.c
security/nss/lib/freebl/mpi/mpi.h
security/nss/lib/freebl/rsapkcs.c
security/nss/lib/ssl/ssl3ext.c
security/nss/lib/ssl/tls13subcerts.c
security/nss/tests/common/cleanup.sh
--- a/security/nss/TAG-INFO
+++ b/security/nss/TAG-INFO
@@ -1,1 +1,1 @@
-89aa19677e37
+bbfc55939d75
--- a/security/nss/coreconf/coreconf.dep
+++ b/security/nss/coreconf/coreconf.dep
@@ -5,9 +5,8 @@
 
 /*
  * 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/freebl_gtest/freebl_gtest.gyp
+++ b/security/nss/gtests/freebl_gtest/freebl_gtest.gyp
@@ -18,16 +18,17 @@
         '<(DEPTH)/lib/pk11wrap/pk11wrap.gyp:pk11wrap_static',
         '<(DEPTH)/lib/cryptohi/cryptohi.gyp:cryptohi',
         '<(DEPTH)/lib/certhigh/certhigh.gyp:certhi',
         '<(DEPTH)/lib/certdb/certdb.gyp:certdb',
         '<(DEPTH)/lib/base/base.gyp:nssb',
         '<(DEPTH)/lib/dev/dev.gyp:nssdev',
         '<(DEPTH)/lib/pki/pki.gyp:nsspki',
         '<(DEPTH)/lib/ssl/ssl.gyp:ssl',
+        '<(DEPTH)/lib/libpkix/libpkix.gyp:libpkix',
       ],
     },
     {
       'target_name': 'freebl_gtest',
       'type': 'executable',
       'sources': [
         'mpi_unittest.cc',
         'dh_unittest.cc',
--- a/security/nss/gtests/freebl_gtest/mpi_unittest.cc
+++ b/security/nss/gtests/freebl_gtest/mpi_unittest.cc
@@ -285,9 +285,9 @@ TEST_F(DISABLED_MPITest, MpiCmpConstTest
   }
   printf("time c: %u\n", time_c / runs);
 
   mp_clear(&a);
   mp_clear(&b);
   mp_clear(&c);
 }
 
-}  // nss_test
+}  // namespace nss_test
--- a/security/nss/gtests/mozpkix_gtest/mozpkix_gtest.gyp
+++ b/security/nss/gtests/mozpkix_gtest/mozpkix_gtest.gyp
@@ -38,16 +38,17 @@
         '<(DEPTH)/lib/nss/nss.gyp:nss_static',
         '<(DEPTH)/lib/pk11wrap/pk11wrap.gyp:pk11wrap_static',
         '<(DEPTH)/lib/cryptohi/cryptohi.gyp:cryptohi',
         '<(DEPTH)/lib/certhigh/certhigh.gyp:certhi',
         '<(DEPTH)/lib/certdb/certdb.gyp:certdb',
         '<(DEPTH)/lib/base/base.gyp:nssb',
         '<(DEPTH)/lib/dev/dev.gyp:nssdev',
         '<(DEPTH)/lib/pki/pki.gyp:nsspki',
+        '<(DEPTH)/lib/libpkix/libpkix.gyp:libpkix',
         '<(DEPTH)/lib/mozpkix/mozpkix.gyp:mozpkix',
         '<(DEPTH)/lib/mozpkix/mozpkix.gyp:mozpkix-testlib',
       ],
       'include_dirs': [
         '<(DEPTH)/lib/mozpkix/',
         '<(DEPTH)/lib/mozpkix/lib',
         '<(DEPTH)/lib/mozpkix/include/',
         '<(DEPTH)/lib/mozpkix/include/pkix-test/',
--- a/security/nss/gtests/ssl_gtest/ssl_auth_unittest.cc
+++ b/security/nss/gtests/ssl_gtest/ssl_auth_unittest.cc
@@ -242,17 +242,19 @@ TEST_F(TlsConnectStreamTls13, PostHandsh
   // properly sent back.
   EXPECT_LT(0U, capture_cert_req->buffer().len());
   EXPECT_EQ(capture_cert_req->buffer().len(),
             capture_certificate->buffer().len());
   EXPECT_EQ(0, memcmp(capture_cert_req->buffer().data(),
                       capture_certificate->buffer().data(),
                       capture_cert_req->buffer().len()));
   ScopedCERTCertificate cert1(SSL_PeerCertificate(server_->ssl_fd()));
+  ASSERT_NE(nullptr, cert1.get());
   ScopedCERTCertificate cert2(SSL_LocalCertificate(client_->ssl_fd()));
+  ASSERT_NE(nullptr, cert2.get());
   EXPECT_TRUE(SECITEM_ItemsAreEqual(&cert1->derCert, &cert2->derCert));
 }
 
 static SECStatus GetClientAuthDataHook(void* self, PRFileDesc* fd,
                                        CERTDistNames* caNames,
                                        CERTCertificate** clientCert,
                                        SECKEYPrivateKey** clientKey) {
   ScopedCERTCertificate cert;
@@ -284,30 +286,34 @@ TEST_F(TlsConnectStreamTls13, PostHandsh
   EXPECT_EQ(SECSuccess, SSL_SendCertificateRequest(server_->ssl_fd()))
       << "Unexpected error: " << PORT_ErrorToName(PORT_GetError());
   server_->SendData(50);
   client_->ReadBytes(50);
   client_->SendData(50);
   server_->ReadBytes(50);
   EXPECT_EQ(1U, called);
   ScopedCERTCertificate cert1(SSL_PeerCertificate(server_->ssl_fd()));
+  ASSERT_NE(nullptr, cert1.get());
   ScopedCERTCertificate cert2(SSL_LocalCertificate(client_->ssl_fd()));
+  ASSERT_NE(nullptr, cert2.get());
   EXPECT_TRUE(SECITEM_ItemsAreEqual(&cert1->derCert, &cert2->derCert));
   // Send 2nd CertificateRequest.
   EXPECT_EQ(SECSuccess, SSL_GetClientAuthDataHook(
                             client_->ssl_fd(), GetClientAuthDataHook, nullptr));
   EXPECT_EQ(SECSuccess, SSL_SendCertificateRequest(server_->ssl_fd()))
       << "Unexpected error: " << PORT_ErrorToName(PORT_GetError());
   server_->SendData(50);
   client_->ReadBytes(50);
   client_->SendData(50);
   server_->ReadBytes(50);
   EXPECT_EQ(2U, called);
   ScopedCERTCertificate cert3(SSL_PeerCertificate(server_->ssl_fd()));
+  ASSERT_NE(nullptr, cert3.get());
   ScopedCERTCertificate cert4(SSL_LocalCertificate(client_->ssl_fd()));
+  ASSERT_NE(nullptr, cert4.get());
   EXPECT_TRUE(SECITEM_ItemsAreEqual(&cert3->derCert, &cert4->derCert));
   EXPECT_FALSE(SECITEM_ItemsAreEqual(&cert3->derCert, &cert1->derCert));
 }
 
 TEST_F(TlsConnectStreamTls13, PostHandshakeAuthConcurrent) {
   client_->SetupClientAuth();
   EXPECT_EQ(SECSuccess, SSL_OptionSet(client_->ssl_fd(),
                                       SSL_ENABLE_POST_HANDSHAKE_AUTH, PR_TRUE));
@@ -378,30 +384,34 @@ TEST_F(TlsConnectStreamTls13, PostHandsh
   server_->SetAuthCertificateCallback(
       [&called](TlsAgent*, PRBool, PRBool) -> SECStatus {
         called++;
         return SECSuccess;
       });
   Connect();
   EXPECT_EQ(1U, called);
   ScopedCERTCertificate cert1(SSL_PeerCertificate(server_->ssl_fd()));
+  ASSERT_NE(nullptr, cert1.get());
   ScopedCERTCertificate cert2(SSL_LocalCertificate(client_->ssl_fd()));
+  ASSERT_NE(nullptr, cert2.get());
   EXPECT_TRUE(SECITEM_ItemsAreEqual(&cert1->derCert, &cert2->derCert));
   // Send CertificateRequest.
   EXPECT_EQ(SECSuccess, SSL_GetClientAuthDataHook(
                             client_->ssl_fd(), GetClientAuthDataHook, nullptr));
   EXPECT_EQ(SECSuccess, SSL_SendCertificateRequest(server_->ssl_fd()))
       << "Unexpected error: " << PORT_ErrorToName(PORT_GetError());
   server_->SendData(50);
   client_->ReadBytes(50);
   client_->SendData(50);
   server_->ReadBytes(50);
   EXPECT_EQ(2U, called);
   ScopedCERTCertificate cert3(SSL_PeerCertificate(server_->ssl_fd()));
+  ASSERT_NE(nullptr, cert3.get());
   ScopedCERTCertificate cert4(SSL_LocalCertificate(client_->ssl_fd()));
+  ASSERT_NE(nullptr, cert4.get());
   EXPECT_TRUE(SECITEM_ItemsAreEqual(&cert3->derCert, &cert4->derCert));
   EXPECT_FALSE(SECITEM_ItemsAreEqual(&cert3->derCert, &cert1->derCert));
 }
 
 // Damages the request context in a CertificateRequest message.
 // We don't modify a Certificate message instead, so that the client
 // can compute CertificateVerify correctly.
 class TlsDamageCertificateRequestContextFilter : public TlsHandshakeFilter {
@@ -562,17 +572,19 @@ TEST_F(TlsConnectStreamTls13, PostHandsh
   EXPECT_EQ(SECSuccess, SSL_SendCertificateRequest(server_->ssl_fd()))
       << "Unexpected error: " << PORT_ErrorToName(PORT_GetError());
   server_->SendData(50);
   client_->ReadBytes(50);
   client_->SendData(50);
   server_->ReadBytes(50);
   EXPECT_EQ(1U, called);
   ScopedCERTCertificate cert1(SSL_PeerCertificate(server_->ssl_fd()));
+  ASSERT_NE(nullptr, cert1.get());
   ScopedCERTCertificate cert2(SSL_LocalCertificate(client_->ssl_fd()));
+  ASSERT_NE(nullptr, cert2.get());
   EXPECT_TRUE(SECITEM_ItemsAreEqual(&cert1->derCert, &cert2->derCert));
 }
 
 // In TLS 1.3, the client sends its cert rejection on the
 // second flight, and since it has already received the
 // server's Finished, it transitions to complete and
 // then gets an alert from the server. The test harness
 // doesn't handle this right yet.
@@ -609,17 +621,19 @@ static void CheckSigScheme(std::shared_p
                            uint16_t expected_scheme, size_t expected_size) {
   EXPECT_LT(offset + 2U, capture->buffer().len());
 
   uint32_t scheme = 0;
   capture->buffer().Read(offset, 2, &scheme);
   EXPECT_EQ(expected_scheme, static_cast<uint16_t>(scheme));
 
   ScopedCERTCertificate remote_cert(SSL_PeerCertificate(peer->ssl_fd()));
+  ASSERT_NE(nullptr, remote_cert.get());
   ScopedSECKEYPublicKey remote_key(CERT_ExtractPublicKey(remote_cert.get()));
+  ASSERT_NE(nullptr, remote_key.get());
   EXPECT_EQ(expected_size, SECKEY_PublicKeyStrengthInBits(remote_key.get()));
 }
 
 // The server should prefer SHA-256 by default, even for the small key size used
 // in the default certificate.
 TEST_P(TlsConnectTls12, ServerAuthCheckSigAlg) {
   EnsureTlsSetup();
   auto capture_ske = MakeTlsFilter<TlsHandshakeRecorder>(
--- a/security/nss/gtests/ssl_gtest/ssl_cert_ext_unittest.cc
+++ b/security/nss/gtests/ssl_gtest/ssl_cert_ext_unittest.cc
@@ -38,20 +38,20 @@ class SignedCertificateTimestampsExtract
     client->SetHandshakeCallback([this](TlsAgent* agent) {
       const SECItem* scts = SSL_PeerSignedCertTimestamps(agent->ssl_fd());
       ASSERT_TRUE(scts);
       handshake_timestamps_.reset(new DataBuffer(scts->data, scts->len));
     });
   }
 
   void assertTimestamps(const DataBuffer& timestamps) {
-    EXPECT_TRUE(auth_timestamps_);
+    ASSERT_NE(nullptr, auth_timestamps_);
     EXPECT_EQ(timestamps, *auth_timestamps_);
 
-    EXPECT_TRUE(handshake_timestamps_);
+    ASSERT_NE(nullptr, handshake_timestamps_);
     EXPECT_EQ(timestamps, *handshake_timestamps_);
 
     const SECItem* current =
         SSL_PeerSignedCertTimestamps(client_.lock()->ssl_fd());
     EXPECT_EQ(timestamps, DataBuffer(current->data, current->len));
   }
 
  private:
--- a/security/nss/gtests/ssl_gtest/ssl_resumption_unittest.cc
+++ b/security/nss/gtests/ssl_gtest/ssl_resumption_unittest.cc
@@ -418,42 +418,46 @@ static int32_t SwitchCertificates(TlsAge
   if (!ok) return SSL_SNI_SEND_ALERT;
 
   return 0;  // first config
 };
 
 TEST_P(TlsConnectGeneric, ServerSNICertSwitch) {
   Connect();
   ScopedCERTCertificate cert1(SSL_PeerCertificate(client_->ssl_fd()));
+  ASSERT_NE(nullptr, cert1.get());
 
   Reset();
   ConfigureSessionCache(RESUME_NONE, RESUME_NONE);
 
   server_->SetSniCallback(SwitchCertificates);
 
   Connect();
   ScopedCERTCertificate cert2(SSL_PeerCertificate(client_->ssl_fd()));
+  ASSERT_NE(nullptr, cert2.get());
   CheckKeys();
   EXPECT_FALSE(SECITEM_ItemsAreEqual(&cert1->derCert, &cert2->derCert));
 }
 
 TEST_P(TlsConnectGeneric, ServerSNICertTypeSwitch) {
   Reset(TlsAgent::kServerEcdsa256);
   Connect();
   ScopedCERTCertificate cert1(SSL_PeerCertificate(client_->ssl_fd()));
+  ASSERT_NE(nullptr, cert1.get());
 
   Reset();
   ConfigureSessionCache(RESUME_NONE, RESUME_NONE);
 
   // Because we configure an RSA certificate here, it only adds a second, unused
   // certificate, which has no effect on what the server uses.
   server_->SetSniCallback(SwitchCertificates);
 
   Connect();
   ScopedCERTCertificate cert2(SSL_PeerCertificate(client_->ssl_fd()));
+  ASSERT_NE(nullptr, cert2.get());
   CheckKeys(ssl_kea_ecdh, ssl_auth_ecdsa);
   EXPECT_TRUE(SECITEM_ItemsAreEqual(&cert1->derCert, &cert2->derCert));
 }
 
 // Prior to TLS 1.3, we were not fully ephemeral; though 1.3 fixes that
 TEST_P(TlsConnectGenericPre13, ConnectEcdheTwiceReuseKey) {
   auto filter = MakeTlsFilter<TlsHandshakeRecorder>(
       server_, kTlsHandshakeServerKeyExchange);
@@ -528,62 +532,66 @@ TEST_P(TlsConnectTls13, TestTls13ResumeD
 // handshake, after resumption.
 TEST_P(TlsConnectTls13, TestTls13ResumeNoCertificateRequest) {
   ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
   client_->SetupClientAuth();
   server_->RequestClientAuth(true);
   Connect();
   SendReceive();  // Need to read so that we absorb the session ticket.
   ScopedCERTCertificate cert1(SSL_LocalCertificate(client_->ssl_fd()));
+  ASSERT_NE(nullptr, cert1.get());
 
   Reset();
   ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
   ExpectResumption(RESUME_TICKET);
   server_->RequestClientAuth(false);
   auto cr_capture =
       MakeTlsFilter<TlsHandshakeRecorder>(server_, ssl_hs_certificate_request);
   cr_capture->EnableDecryption();
   Connect();
   SendReceive();
   EXPECT_EQ(0U, cr_capture->buffer().len()) << "expect nothing captured yet";
 
   // Sanity check whether the client certificate matches the one
   // decrypted from ticket.
   ScopedCERTCertificate cert2(SSL_PeerCertificate(server_->ssl_fd()));
+  ASSERT_NE(nullptr, cert2.get());
   EXPECT_TRUE(SECITEM_ItemsAreEqual(&cert1->derCert, &cert2->derCert));
 }
 
 // Here we test that 0.5 RTT is available at the server when resuming, even if
 // configured to request a client certificate.  The resumed handshake relies on
 // the authentication from the original handshake, so no certificate is
 // requested this time around.  The server can write before the handshake
 // completes because the PSK binder is sufficient authentication for the client.
 TEST_P(TlsConnectTls13, WriteBeforeHandshakeCompleteOnResumption) {
   ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
   client_->SetupClientAuth();
   server_->RequestClientAuth(true);
   Connect();
   SendReceive();  // Absorb the session ticket.
   ScopedCERTCertificate cert1(SSL_LocalCertificate(client_->ssl_fd()));
+  ASSERT_NE(nullptr, cert1.get());
 
   Reset();
   ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
   ExpectResumption(RESUME_TICKET);
   server_->RequestClientAuth(false);
   StartConnect();
   client_->Handshake();  // ClientHello
   server_->Handshake();  // ServerHello
 
   server_->SendData(10);
   client_->ReadBytes(10);  // Client should emit the Finished as a side-effect.
   server_->Handshake();    // Server consumes the Finished.
   CheckConnected();
 
   // Check whether the client certificate matches the one from the ticket.
   ScopedCERTCertificate cert2(SSL_PeerCertificate(server_->ssl_fd()));
+  ASSERT_NE(nullptr, cert2.get());
   EXPECT_TRUE(SECITEM_ItemsAreEqual(&cert1->derCert, &cert2->derCert));
 }
 
 // We need to enable different cipher suites at different times in the following
 // tests.  Those cipher suites need to be suited to the version.
 static uint16_t ChooseOneCipher(uint16_t version) {
   if (version >= SSL_LIBRARY_VERSION_TLS_1_3) {
     return TLS_AES_128_GCM_SHA256;
@@ -754,33 +762,33 @@ TEST_F(TlsConnectTest, TestTls13Resumpti
   SendReceive();
   CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_rsa_sign,
             ssl_sig_rsa_pss_rsae_sha256);
   // The filter will go away when we reset, so save the captured extension.
   DataBuffer initialTicket(c1->extension());
   ASSERT_LT(0U, initialTicket.len());
 
   ScopedCERTCertificate cert1(SSL_PeerCertificate(client_->ssl_fd()));
-  ASSERT_TRUE(!!cert1.get());
+  ASSERT_NE(nullptr, cert1.get());
 
   Reset();
   ClearStats();
   ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
   ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
   auto c2 =
       MakeTlsFilter<TlsExtensionCapture>(client_, ssl_tls13_pre_shared_key_xtn);
   ExpectResumption(RESUME_TICKET);
   Connect();
   SendReceive();
   CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_rsa_sign,
             ssl_sig_rsa_pss_rsae_sha256);
   ASSERT_LT(0U, c2->extension().len());
 
   ScopedCERTCertificate cert2(SSL_PeerCertificate(client_->ssl_fd()));
-  ASSERT_TRUE(!!cert2.get());
+  ASSERT_NE(nullptr, cert2.get());
 
   // Check that the cipher suite is reported the same on both sides, though in
   // TLS 1.3 resumption actually negotiates a different cipher suite.
   uint16_t resumed_suite;
   EXPECT_TRUE(server_->cipher_suite(&resumed_suite));
   EXPECT_EQ(original_suite, resumed_suite);
   EXPECT_TRUE(client_->cipher_suite(&resumed_suite));
   EXPECT_EQ(original_suite, resumed_suite);
@@ -1171,16 +1179,17 @@ TEST_P(TlsConnectGenericResumptionToken,
   ASSERT_TRUE(client_->MaybeSetResumptionToken());
 
   // Get resumption token infos
   SSLResumptionTokenInfo tokenInfo = {0};
   ScopedSSLResumptionTokenInfo token(&tokenInfo);
   client_->GetTokenInfo(token);
   ScopedCERTCertificate cert(
       PK11_FindCertFromNickname(server_->name().c_str(), nullptr));
+  ASSERT_NE(nullptr, cert.get());
 
   CheckGetInfoResult(now(), 0, 0, cert, token);
 
   Handshake();
   CheckConnected();
 
   SendReceive();
 }
@@ -1251,16 +1260,17 @@ TEST_P(TlsConnectGenericResumptionToken,
   ASSERT_TRUE(client_->MaybeSetResumptionToken());
 
   // Get resumption token infos
   SSLResumptionTokenInfo tokenInfo = {0};
   ScopedSSLResumptionTokenInfo token(&tokenInfo);
   client_->GetTokenInfo(token);
   ScopedCERTCertificate cert(
       PK11_FindCertFromNickname(server_->name().c_str(), nullptr));
+  ASSERT_NE(nullptr, cert.get());
 
   CheckGetInfoResult(now(), 1, 0, cert, token);
 
   Handshake();
   CheckConnected();
   CheckAlpn("a");
 
   SendReceive();
@@ -1286,17 +1296,17 @@ TEST_P(TlsConnectTls13ResumptionToken, C
   ASSERT_TRUE(client_->MaybeSetResumptionToken());
 
   // Get resumption token infos
   SSLResumptionTokenInfo tokenInfo = {0};
   ScopedSSLResumptionTokenInfo token(&tokenInfo);
   client_->GetTokenInfo(token);
   ScopedCERTCertificate cert(
       PK11_FindCertFromNickname(server_->name().c_str(), nullptr));
-
+  ASSERT_NE(nullptr, cert.get());
   CheckGetInfoResult(now(), 1, 1024, cert, token);
 
   ZeroRttSendReceive(true, true);
   Handshake();
   ExpectEarlyDataAccepted(true);
   CheckConnected();
   CheckAlpn("a");
 
--- a/security/nss/gtests/ssl_gtest/tls_agent.cc
+++ b/security/nss/gtests/ssl_gtest/tls_agent.cc
@@ -123,20 +123,24 @@ void TlsAgent::SetState(State s) {
   LOG("Changing state from " << state_ << " to " << s);
   state_ = s;
 }
 
 /*static*/ bool TlsAgent::LoadCertificate(const std::string& name,
                                           ScopedCERTCertificate* cert,
                                           ScopedSECKEYPrivateKey* priv) {
   cert->reset(PK11_FindCertFromNickname(name.c_str(), nullptr));
+  EXPECT_NE(nullptr, cert);
+  if (!cert) return false;
   EXPECT_NE(nullptr, cert->get());
   if (!cert->get()) return false;
 
   priv->reset(PK11_FindKeyByAnyCert(cert->get(), nullptr));
+  EXPECT_NE(nullptr, priv);
+  if (!priv) return false;
   EXPECT_NE(nullptr, priv->get());
   if (!priv->get()) return false;
 
   return true;
 }
 
 // Loads a key pair from the certificate identified by |id|.
 /*static*/ bool TlsAgent::LoadKeyPairFromCert(const std::string& name,
@@ -157,17 +161,20 @@ void TlsAgent::SetState(State s) {
 
 void TlsAgent::DelegateCredential(const std::string& name,
                                   const ScopedSECKEYPublicKey& dc_pub,
                                   SSLSignatureScheme dc_cert_verify_alg,
                                   PRUint32 dc_valid_for, PRTime now,
                                   SECItem* dc) {
   ScopedCERTCertificate cert;
   ScopedSECKEYPrivateKey cert_priv;
-  EXPECT_TRUE(TlsAgent::LoadCertificate(name, &cert, &cert_priv));
+  EXPECT_TRUE(TlsAgent::LoadCertificate(name, &cert, &cert_priv))
+      << "Could not load delegate certificate: " << name
+      << "; test db corrupt?";
+
   EXPECT_EQ(SECSuccess,
             SSL_DelegateCredential(cert.get(), cert_priv.get(), dc_pub.get(),
                                    dc_cert_verify_alg, dc_valid_for, now, dc));
 }
 
 void TlsAgent::EnableDelegatedCredentials() {
   ASSERT_TRUE(EnsureTlsSetup());
   SetOption(SSL_ENABLE_DELEGATED_CREDENTIALS, PR_TRUE);
@@ -332,17 +339,17 @@ void CheckCertReqAgainstDefaultCAs(const
 SECStatus TlsAgent::GetClientAuthDataHook(void* self, PRFileDesc* fd,
                                           CERTDistNames* caNames,
                                           CERTCertificate** clientCert,
                                           SECKEYPrivateKey** clientKey) {
   TlsAgent* agent = reinterpret_cast<TlsAgent*>(self);
   ScopedCERTCertificate peerCert(SSL_PeerCertificate(agent->ssl_fd()));
   EXPECT_TRUE(peerCert) << "Client should be able to see the server cert";
 
-  // See bug 1457716
+  // See bug 1573945
   // CheckCertReqAgainstDefaultCAs(caNames);
 
   ScopedCERTCertificate cert;
   ScopedSECKEYPrivateKey priv;
   if (!TlsAgent::LoadCertificate(agent->name(), &cert, &priv)) {
     return SECFailure;
   }
 
--- a/security/nss/gtests/ssl_gtest/tls_subcerts_unittest.cc
+++ b/security/nss/gtests/ssl_gtest/tls_subcerts_unittest.cc
@@ -235,16 +235,17 @@ TEST_P(TlsConnectTls13, DCAbortBadSignat
 
   ScopedSECKEYPublicKey pub;
   ScopedSECKEYPrivateKey priv;
   EXPECT_TRUE(TlsAgent::LoadKeyPairFromCert(kDCId, &pub, &priv));
 
   StackSECItem dc;
   TlsAgent::DelegateCredential(kDelegatorId, pub, kDCScheme, kDCValidFor, now(),
                                &dc);
+  ASSERT_TRUE(dc.data != nullptr);
 
   // Flip the first bit of the DC so that the signature is invalid.
   dc.data[0] ^= 0x01;
 
   SSLExtraServerCertData extra_data = {ssl_auth_null, nullptr, nullptr,
                                        nullptr,       &dc,     priv.get()};
   EXPECT_TRUE(server_->ConfigServerCert(kDelegatorId, true, &extra_data));
 
--- a/security/nss/lib/freebl/chacha20poly1305.c
+++ b/security/nss/lib/freebl/chacha20poly1305.c
@@ -253,16 +253,21 @@ ChaCha20Poly1305_Open(const ChaCha20Poly
         PORT_SetError(SEC_ERROR_INPUT_LEN);
         return SECFailure;
     }
     ciphertextLen = inputLen - ctx->tagLen;
     if (maxOutputLen < ciphertextLen) {
         PORT_SetError(SEC_ERROR_OUTPUT_LEN);
         return SECFailure;
     }
+    // ChaCha has a 64 octet block, with a 32-bit block counter.
+    if (inputLen >= (1ULL << (6 + 32)) + ctx->tagLen) {
+        PORT_SetError(SEC_ERROR_INPUT_LEN);
+        return SECFailure;
+    }
 
     PORT_Memset(block, 0, sizeof(block));
     // Generate a block of keystream. The first 32 bytes will be the poly1305
     // key. The remainder of the block is discarded.
     ChaCha20Xor(block, (uint8_t *)block, sizeof(block), (uint8_t *)ctx->key,
                 (uint8_t *)nonce, 0);
     Poly1305Do(tag, ad, adLen, input, ciphertextLen, block);
     if (NSS_SecureMemcmp(tag, &input[ciphertextLen], ctx->tagLen) != 0) {
--- a/security/nss/lib/freebl/ctr.c
+++ b/security/nss/lib/freebl/ctr.c
@@ -123,16 +123,22 @@ SECStatus
 CTR_Update(CTRContext *ctr, unsigned char *outbuf,
            unsigned int *outlen, unsigned int maxout,
            const unsigned char *inbuf, unsigned int inlen,
            unsigned int blocksize)
 {
     unsigned int tmp;
     SECStatus rv;
 
+    // Limit block count to 2^counterBits - 2
+    if (ctr->counterBits < (sizeof(unsigned int) * 8) &&
+        inlen > ((1 << ctr->counterBits) - 2) * AES_BLOCK_SIZE) {
+        PORT_SetError(SEC_ERROR_INPUT_LEN);
+        return SECFailure;
+    }
     if (maxout < inlen) {
         *outlen = inlen;
         PORT_SetError(SEC_ERROR_OUTPUT_LEN);
         return SECFailure;
     }
     *outlen = 0;
     if (ctr->bufPtr != blocksize) {
         unsigned int needed = PR_MIN(blocksize - ctr->bufPtr, inlen);
@@ -194,16 +200,22 @@ CTR_Update_HW_AES(CTRContext *ctr, unsig
                   unsigned int *outlen, unsigned int maxout,
                   const unsigned char *inbuf, unsigned int inlen,
                   unsigned int blocksize)
 {
     unsigned int fullblocks;
     unsigned int tmp;
     SECStatus rv;
 
+    // Limit block count to 2^counterBits - 2
+    if (ctr->counterBits < (sizeof(unsigned int) * 8) &&
+        inlen > ((1 << ctr->counterBits) - 2) * AES_BLOCK_SIZE) {
+        PORT_SetError(SEC_ERROR_INPUT_LEN);
+        return SECFailure;
+    }
     if (maxout < inlen) {
         *outlen = inlen;
         PORT_SetError(SEC_ERROR_OUTPUT_LEN);
         return SECFailure;
     }
     *outlen = 0;
     if (ctr->bufPtr != blocksize) {
         unsigned int needed = PR_MIN(blocksize - ctr->bufPtr, inlen);
--- a/security/nss/lib/freebl/gcm.c
+++ b/security/nss/lib/freebl/gcm.c
@@ -474,16 +474,22 @@ cleanup:
 }
 
 SECStatus
 gcmHash_Reset(gcmHashContext *ghash, const unsigned char *AAD,
               unsigned int AADLen)
 {
     SECStatus rv;
 
+    // Limit AADLen in accordance with SP800-38D
+    if (sizeof(AADLen) >= 8 && AADLen > (1ULL << 61) - 1) {
+        PORT_SetError(SEC_ERROR_INPUT_LEN);
+        return SECFailure;
+    }
+
     ghash->cLen = 0;
     PORT_Memset(ghash->counterBuf, 0, GCM_HASH_LEN_LEN * 2);
     ghash->bufLen = 0;
     rv = gcm_zeroX(ghash);
     if (rv != SECSuccess) {
         return rv;
     }
 
--- a/security/nss/lib/freebl/intel-gcm-wrap.c
+++ b/security/nss/lib/freebl/intel-gcm-wrap.c
@@ -57,16 +57,22 @@ intel_AES_GCM_CreateContext(void *contex
     __m128i ONE = _mm_set_epi32(0, 0, 0, 1);
     unsigned int j;
     SECStatus rv;
 
     if (gcmParams->ulIvLen == 0) {
         PORT_SetError(SEC_ERROR_INVALID_ARGS);
         return NULL;
     }
+    // Limit AADLen in accordance with SP800-38D
+    if (sizeof(AAD_whole_len) >= 8 && AAD_whole_len > (1ULL << 61) - 1) {
+        PORT_SetError(SEC_ERROR_INPUT_LEN);
+        return NULL;
+    }
+
     gcm = PORT_ZNew(intel_AES_GCMContext);
     if (gcm == NULL) {
         return NULL;
     }
 
     /* initialize context fields */
     gcm->aes_context = aes;
     gcm->tagBits = gcmParams->ulTagBits;
@@ -155,16 +161,24 @@ intel_AES_GCM_EncryptUpdate(intel_AES_GC
                             unsigned int *outlen, unsigned int maxout,
                             const unsigned char *inbuf, unsigned int inlen,
                             unsigned int blocksize)
 {
     unsigned int tagBytes;
     unsigned char T[AES_BLOCK_SIZE];
     unsigned int j;
 
+    // GCM has a 16 octet block, with a 32-bit block counter
+    // Limit in accordance with SP800-38D
+    if (sizeof(inlen) > 4 &&
+        inlen >= ((1ULL << 32) - 2) * AES_BLOCK_SIZE) {
+        PORT_SetError(SEC_ERROR_INPUT_LEN);
+        return SECFailure;
+    }
+
     tagBytes = (gcm->tagBits + (PR_BITS_PER_BYTE - 1)) / PR_BITS_PER_BYTE;
     if (UINT_MAX - inlen < tagBytes) {
         PORT_SetError(SEC_ERROR_INPUT_LEN);
         return SECFailure;
     }
     if (maxout < inlen + tagBytes) {
         *outlen = inlen + tagBytes;
         PORT_SetError(SEC_ERROR_OUTPUT_LEN);
@@ -212,16 +226,24 @@ intel_AES_GCM_DecryptUpdate(intel_AES_GC
     if (inlen < tagBytes) {
         PORT_SetError(SEC_ERROR_INPUT_LEN);
         return SECFailure;
     }
 
     inlen -= tagBytes;
     intag = inbuf + inlen;
 
+    // GCM has a 16 octet block, with a 32-bit block counter
+    // Limit in accordance with SP800-38D
+    if (sizeof(inlen) > 4 &&
+        inlen >= ((1ULL << 32) - 2) * AES_BLOCK_SIZE) {
+        PORT_SetError(SEC_ERROR_INPUT_LEN);
+        return SECFailure;
+    }
+
     if (maxout < inlen) {
         *outlen = inlen;
         PORT_SetError(SEC_ERROR_OUTPUT_LEN);
         return SECFailure;
     }
 
     intel_aes_gcmDEC(
         inbuf,
--- a/security/nss/lib/freebl/mpi/README
+++ b/security/nss/lib/freebl/mpi/README
@@ -162,16 +162,17 @@ using the mp_clear() function.  Remember
 create as a local variable in a function must be mp_clear()'d before
 that function exits, or else the memory allocated to that mp_int will
 be orphaned and unrecoverable.
 
 To set an mp_int to a given value, the following functions are given:
 
         mp_set(mp_int *mp, mp_digit d);
         mp_set_int(mp_int *mp, long z);
+        mp_set_ulong(mp_int *mp, unsigned long z);
 
 The mp_set() function sets the mp_int to a single digit value, while
 mp_set_int() sets the mp_int to a signed long integer value.
 
 To set an mp_int to zero, use:
 
         mp_zero(mp_int *mp);
 
--- a/security/nss/lib/freebl/mpi/mpi.c
+++ b/security/nss/lib/freebl/mpi/mpi.c
@@ -339,16 +339,18 @@ mp_set(mp_int *mp, mp_digit d)
 /* {{{ mp_set_int(mp, z) */
 
 mp_err
 mp_set_int(mp_int *mp, long z)
 {
     unsigned long v = labs(z);
     mp_err res;
 
+    ARGCHK(mp != NULL, MP_BADARG);
+
     /* https://bugzilla.mozilla.org/show_bug.cgi?id=1509432 */
     if ((res = mp_set_ulong(mp, v)) != MP_OKAY) { /* avoids duplicated code */
         return res;
     }
 
     if (z < 0) {
         SIGN(mp) = NEG;
     }
@@ -1422,17 +1424,17 @@ mp_sqrmod(const mp_int *a, const mp_int 
 mp_err
 s_mp_exptmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c)
 {
     mp_int s, x, mu;
     mp_err res;
     mp_digit d;
     unsigned int dig, bit;
 
-    ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
+    ARGCHK(a != NULL && b != NULL && c != NULL && m != NULL, MP_BADARG);
 
     if (mp_cmp_z(b) < 0 || mp_cmp_z(m) <= 0)
         return MP_RANGE;
 
     if ((res = mp_init(&s)) != MP_OKAY)
         return res;
     if ((res = mp_init_copy(&x, a)) != MP_OKAY ||
         (res = mp_mod(&x, m, &x)) != MP_OKAY)
@@ -1509,17 +1511,17 @@ X:
 /* {{{ mp_exptmod_d(a, d, m, c) */
 
 mp_err
 mp_exptmod_d(const mp_int *a, mp_digit d, const mp_int *m, mp_int *c)
 {
     mp_int s, x;
     mp_err res;
 
-    ARGCHK(a != NULL && c != NULL, MP_BADARG);
+    ARGCHK(a != NULL && c != NULL && m != NULL, MP_BADARG);
 
     if ((res = mp_init(&s)) != MP_OKAY)
         return res;
     if ((res = mp_init_copy(&x, a)) != MP_OKAY)
         goto X;
 
     mp_set(&s, 1);
 
@@ -1562,16 +1564,18 @@ X:
   mp_cmp_z(a)
 
   Compare a <=> 0.  Returns <0 if a<0, 0 if a=0, >0 if a>0.
  */
 
 int
 mp_cmp_z(const mp_int *a)
 {
+    ARGMPCHK(a != NULL);
+
     if (SIGN(a) == NEG)
         return MP_LT;
     else if (USED(a) == 1 && DIGIT(a, 0) == 0)
         return MP_EQ;
     else
         return MP_GT;
 
 } /* end mp_cmp_z() */
@@ -1652,17 +1656,17 @@ mp_cmp_mag(const mp_int *a, const mp_int
 /*
   mp_isodd(a)
 
   Returns a true (non-zero) value if a is odd, false (zero) otherwise.
  */
 int
 mp_isodd(const mp_int *a)
 {
-    ARGCHK(a != NULL, 0);
+    ARGMPCHK(a != NULL);
 
     return (int)(DIGIT(a, 0) & 1);
 
 } /* end mp_isodd() */
 
 /* }}} */
 
 /* {{{ mp_iseven(a) */
@@ -1996,17 +2000,17 @@ mp_trailing_zeros(const mp_int *mp)
 */
 mp_err
 s_mp_almost_inverse(const mp_int *a, const mp_int *p, mp_int *c)
 {
     mp_err res;
     mp_err k = 0;
     mp_int d, f, g;
 
-    ARGCHK(a && p && c, MP_BADARG);
+    ARGCHK(a != NULL && p != NULL && c != NULL, MP_BADARG);
 
     MP_DIGITS(&d) = 0;
     MP_DIGITS(&f) = 0;
     MP_DIGITS(&g) = 0;
     MP_CHECKOK(mp_init(&d));
     MP_CHECKOK(mp_init_copy(&f, a)); /* f = a */
     MP_CHECKOK(mp_init_copy(&g, p)); /* g = p */
 
@@ -2130,17 +2134,17 @@ CLEANUP:
 /* compute mod inverse using Schroeppel's method, only if m is odd */
 mp_err
 s_mp_invmod_odd_m(const mp_int *a, const mp_int *m, mp_int *c)
 {
     int k;
     mp_err res;
     mp_int x;
 
-    ARGCHK(a && m && c, MP_BADARG);
+    ARGCHK(a != NULL && m != NULL && c != NULL, MP_BADARG);
 
     if (mp_cmp_z(a) == 0 || mp_cmp_z(m) == 0)
         return MP_RANGE;
     if (mp_iseven(m))
         return MP_UNDEF;
 
     MP_DIGITS(&x) = 0;
 
@@ -2168,17 +2172,17 @@ CLEANUP:
 
 /* Known good algorithm for computing modular inverse.  But slow. */
 mp_err
 mp_invmod_xgcd(const mp_int *a, const mp_int *m, mp_int *c)
 {
     mp_int g, x;
     mp_err res;
 
-    ARGCHK(a && m && c, MP_BADARG);
+    ARGCHK(a != NULL && m != NULL && c != NULL, MP_BADARG);
 
     if (mp_cmp_z(a) == 0 || mp_cmp_z(m) == 0)
         return MP_RANGE;
 
     MP_DIGITS(&g) = 0;
     MP_DIGITS(&x) = 0;
     MP_CHECKOK(mp_init(&x));
     MP_CHECKOK(mp_init(&g));
@@ -2264,16 +2268,18 @@ mp_err
 s_mp_invmod_even_m(const mp_int *a, const mp_int *m, mp_int *c)
 {
     mp_err res;
     mp_size k;
     mp_int oddFactor, evenFactor; /* factors of the modulus */
     mp_int oddPart, evenPart;     /* parts to combine via CRT. */
     mp_int C2, tmp1, tmp2;
 
+    ARGCHK(a != NULL && m != NULL && c != NULL, MP_BADARG);
+
     /*static const mp_digit d1 = 1; */
     /*static const mp_int one = { MP_ZPOS, 1, 1, (mp_digit *)&d1 }; */
 
     if ((res = s_mp_ispow2(m)) >= 0) {
         k = res;
         return s_mp_invmod_2d(a, k, c);
     }
     MP_DIGITS(&oddFactor) = 0;
@@ -2342,18 +2348,17 @@ CLEANUP:
   Compute c = a^-1 (mod m), if there is an inverse for a (mod m).
   This is equivalent to the question of whether (a, m) = 1.  If not,
   MP_UNDEF is returned, and there is no inverse.
  */
 
 mp_err
 mp_invmod(const mp_int *a, const mp_int *m, mp_int *c)
 {
-
-    ARGCHK(a && m && c, MP_BADARG);
+    ARGCHK(a != NULL && m != NULL && c != NULL, MP_BADARG);
 
     if (mp_cmp_z(a) == 0 || mp_cmp_z(m) == 0)
         return MP_RANGE;
 
     if (mp_isodd(m)) {
         return s_mp_invmod_odd_m(a, m, c);
     }
     if (mp_iseven(a))
@@ -2710,16 +2715,18 @@ mp_strerror(mp_err ec)
 /* {{{ Memory management */
 
 /* {{{ s_mp_grow(mp, min) */
 
 /* Make sure there are at least 'min' digits allocated to mp              */
 mp_err
 s_mp_grow(mp_int *mp, mp_size min)
 {
+    ARGCHK(mp != NULL, MP_BADARG);
+
     if (min > ALLOC(mp)) {
         mp_digit *tmp;
 
         /* Set min to next nearest default precision block size */
         min = MP_ROUNDUP(min, s_mp_defprec);
 
         if ((tmp = s_mp_alloc(min, sizeof(mp_digit))) == NULL)
             return MP_MEM;
@@ -2739,16 +2746,18 @@ s_mp_grow(mp_int *mp, mp_size min)
 /* }}} */
 
 /* {{{ s_mp_pad(mp, min) */
 
 /* Make sure the used size of mp is at least 'min', growing if needed     */
 mp_err
 s_mp_pad(mp_int *mp, mp_size min)
 {
+    ARGCHK(mp != NULL, MP_BADARG);
+
     if (min > USED(mp)) {
         mp_err res;
 
         /* Make sure there is room to increase precision  */
         if (min > ALLOC(mp)) {
             if ((res = s_mp_grow(mp, min)) != MP_OKAY)
                 return res;
         } else {
@@ -2858,16 +2867,18 @@ s_mp_exch(mp_int *a, mp_int *b)
  */
 
 mp_err
 s_mp_lshd(mp_int *mp, mp_size p)
 {
     mp_err res;
     unsigned int ix;
 
+    ARGCHK(mp != NULL, MP_BADARG);
+
     if (p == 0)
         return MP_OKAY;
 
     if (MP_USED(mp) == 1 && MP_DIGIT(mp, 0) == 0)
         return MP_OKAY;
 
     if ((res = s_mp_pad(mp, USED(mp) + p)) != MP_OKAY)
         return res;
@@ -2990,16 +3001,18 @@ s_mp_div_2(mp_int *mp)
 
 mp_err
 s_mp_mul_2(mp_int *mp)
 {
     mp_digit *pd;
     unsigned int ix, used;
     mp_digit kin = 0;
 
+    ARGCHK(mp != NULL, MP_BADARG);
+
     /* Shift digits leftward by 1 bit */
     used = MP_USED(mp);
     pd = MP_DIGITS(mp);
     for (ix = 0; ix < used; ix++) {
         mp_digit d = *pd;
         *pd++ = (d << 1) | kin;
         kin = (d >> (DIGIT_BIT - 1));
     }
@@ -3099,16 +3112,18 @@ s_mp_div_2d(mp_int *mp, mp_digit d)
 mp_err
 s_mp_norm(mp_int *a, mp_int *b, mp_digit *pd)
 {
     mp_digit d;
     mp_digit mask;
     mp_digit b_msd;
     mp_err res = MP_OKAY;
 
+    ARGCHK(a != NULL && b != NULL && pd != NULL, MP_BADARG);
+
     d = 0;
     mask = DIGIT_MAX & ~(DIGIT_MAX >> 1); /* mask is msb of digit */
     b_msd = DIGIT(b, USED(b) - 1);
     while (!(b_msd & mask)) {
         b_msd <<= 1;
         ++d;
     }
 
@@ -4363,16 +4378,18 @@ CLEANUP:
 /* {{{ Primitive comparisons */
 
 /* {{{ s_mp_cmp(a, b) */
 
 /* Compare |a| <=> |b|, return 0 if equal, <0 if a<b, >0 if a>b           */
 int
 s_mp_cmp(const mp_int *a, const mp_int *b)
 {
+    ARGMPCHK(a != NULL && b != NULL);
+
     mp_size used_a = MP_USED(a);
     {
         mp_size used_b = MP_USED(b);
 
         if (used_a > used_b)
             goto IS_GT;
         if (used_a < used_b)
             goto IS_LT;
@@ -4414,16 +4431,18 @@ IS_GT:
 /* }}} */
 
 /* {{{ s_mp_cmp_d(a, d) */
 
 /* Compare |a| <=> d, return 0 if equal, <0 if a<d, >0 if a>d             */
 int
 s_mp_cmp_d(const mp_int *a, mp_digit d)
 {
+    ARGMPCHK(a != NULL);
+
     if (USED(a) > 1)
         return MP_GT;
 
     if (DIGIT(a, 0) < d)
         return MP_LT;
     else if (DIGIT(a, 0) > d)
         return MP_GT;
     else
@@ -4440,16 +4459,18 @@ s_mp_cmp_d(const mp_int *a, mp_digit d)
   k such that v = 2^k, i.e. lg(v).
  */
 int
 s_mp_ispow2(const mp_int *v)
 {
     mp_digit d;
     int extra = 0, ix;
 
+    ARGMPCHK(v != NULL);
+
     ix = MP_USED(v) - 1;
     d = MP_DIGIT(v, ix); /* most significant digit of v */
 
     extra = s_mp_ispow2d(d);
     if (extra < 0 || ix == 0)
         return extra;
 
     while (--ix >= 0) {
@@ -4767,20 +4788,17 @@ mp_to_signed_octets(const mp_int *mp, un
 /* output a buffer of big endian octets exactly as long as requested.
    constant time on the value of mp. */
 mp_err
 mp_to_fixlen_octets(const mp_int *mp, unsigned char *str, mp_size length)
 {
     int ix, jx;
     unsigned int bytes;
 
-    ARGCHK(mp != NULL, MP_BADARG);
-    ARGCHK(str != NULL, MP_BADARG);
-    ARGCHK(!SIGN(mp), MP_BADARG);
-    ARGCHK(length > 0, MP_BADARG);
+    ARGCHK(mp != NULL && str != NULL && !SIGN(mp) && length > 0, MP_BADARG);
 
     /* Constant time on the value of mp.  Don't use mp_unsigned_octet_size. */
     bytes = USED(mp) * MP_DIGIT_SIZE;
 
     /* If the output is shorter than the native size of mp, then check that any
      * bytes not written have zero values.  This check isn't constant time on
      * the assumption that timing-sensitive callers can guarantee that mp fits
      * in the allocated space. */
--- a/security/nss/lib/freebl/mpi/mpi.h
+++ b/security/nss/lib/freebl/mpi/mpi.h
@@ -283,28 +283,37 @@ void freebl_cpuid(unsigned long op, unsi
 #define RADIX MP_RADIX
 #define MAX_RADIX MP_MAX_RADIX
 #define SIGN(MP) MP_SIGN(MP)
 #define USED(MP) MP_USED(MP)
 #define ALLOC(MP) MP_ALLOC(MP)
 #define DIGITS(MP) MP_DIGITS(MP)
 #define DIGIT(MP, N) MP_DIGIT(MP, N)
 
+/* Functions which return an mp_err value will NULL-check their arguments via
+ * ARGCHK(condition, return), where the caller is responsible for checking the
+ * mp_err return code. For functions that return an integer type, the caller 
+ * has no way to tell if the value is an error code or a legitimate value. 
+ * Therefore, ARGMPCHK(condition) will trigger an assertion failure on debug
+ * builds, but no-op in optimized builds. */
 #if MP_ARGCHK == 1
+#define ARGMPCHK(X) /* */
 #define ARGCHK(X, Y)    \
     {                   \
         if (!(X)) {     \
             return (Y); \
         }               \
     }
 #elif MP_ARGCHK == 2
 #include <assert.h>
+#define ARGMPCHK(X) assert(X)
 #define ARGCHK(X, Y) assert(X)
 #else
-#define ARGCHK(X, Y) /*  */
+#define ARGMPCHK(X)  /* */
+#define ARGCHK(X, Y) /* */
 #endif
 
 #ifdef CT_VERIF
 void mp_taint(mp_int *mp);
 void mp_untaint(mp_int *mp);
 #endif
 
 SEC_END_PROTOS
--- a/security/nss/lib/freebl/rsapkcs.c
+++ b/security/nss/lib/freebl/rsapkcs.c
@@ -110,17 +110,17 @@ rsa_modulusBits(SECItem *modulus)
  */
 static unsigned char *
 rsa_FormatOneBlock(unsigned modulusLen,
                    RSA_BlockType blockType,
                    SECItem *data)
 {
     unsigned char *block;
     unsigned char *bp;
-    int padLen;
+    unsigned int padLen;
     int i, j;
     SECStatus rv;
 
     block = (unsigned char *)PORT_Alloc(modulusLen);
     if (block == NULL)
         return NULL;
 
     bp = block;
@@ -130,24 +130,25 @@ rsa_FormatOneBlock(unsigned modulusLen,
      *  0x00 || BlockType
      */
     *bp++ = RSA_BLOCK_FIRST_OCTET;
     *bp++ = (unsigned char)blockType;
 
     switch (blockType) {
 
         /*
-       * Blocks intended for private-key operation.
-       */
+         * Blocks intended for private-key operation.
+         */
         case RSA_BlockPrivate: /* preferred method */
             /*
-         * 0x00 || BT || Pad || 0x00 || ActualData
-         *   1      1   padLen    1      data->len
-         * Pad is either all 0x00 or all 0xff bytes, depending on blockType.
-         */
+             * 0x00 || BT || Pad || 0x00 || ActualData
+             *   1      1   padLen    1      data->len
+             * padLen must be at least RSA_BLOCK_MIN_PAD_LEN (8) bytes.
+             * Pad is either all 0x00 or all 0xff bytes, depending on blockType.
+             */
             padLen = modulusLen - data->len - 3;
             PORT_Assert(padLen >= RSA_BLOCK_MIN_PAD_LEN);
             if (padLen < RSA_BLOCK_MIN_PAD_LEN) {
                 PORT_Free(block);
                 return NULL;
             }
             PORT_Memset(bp, RSA_BLOCK_PRIVATE_PAD_OCTET, padLen);
             bp += padLen;
@@ -157,25 +158,26 @@ rsa_FormatOneBlock(unsigned modulusLen,
 
         /*
          * Blocks intended for public-key operation.
          */
         case RSA_BlockPublic:
             /*
              * 0x00 || BT || Pad || 0x00 || ActualData
              *   1      1   padLen    1      data->len
-             * Pad is all non-zero random bytes.
+             * Pad is 8 or more non-zero random bytes.
              *
              * Build the block left to right.
              * Fill the entire block from Pad to the end with random bytes.
              * Use the bytes after Pad as a supply of extra random bytes from
              * which to find replacements for the zero bytes in Pad.
              * If we need more than that, refill the bytes after Pad with
              * new random bytes as necessary.
              */
+
             padLen = modulusLen - (data->len + 3);
             PORT_Assert(padLen >= RSA_BLOCK_MIN_PAD_LEN);
             if (padLen < RSA_BLOCK_MIN_PAD_LEN) {
                 PORT_Free(block);
                 return NULL;
             }
             j = modulusLen - 2;
             rv = RNG_GenerateGlobalRandomBytes(bp, j);
@@ -231,18 +233,19 @@ rsa_FormatBlock(SECItem *result,
         case RSA_BlockPrivate:
         case RSA_BlockPublic:
             /*
              * 0x00 || BT || Pad || 0x00 || ActualData
              *
              * The "3" below is the first octet + the second octet + the 0x00
              * octet that always comes just before the ActualData.
              */
-            PORT_Assert(data->len <= (modulusLen - (3 + RSA_BLOCK_MIN_PAD_LEN)));
-
+            if (data->len > (modulusLen - (3 + RSA_BLOCK_MIN_PAD_LEN))) {
+                return SECFailure;
+            }
             result->data = rsa_FormatOneBlock(modulusLen, blockType, data);
             if (result->data == NULL) {
                 result->len = 0;
                 return SECFailure;
             }
             result->len = modulusLen;
 
             break;
--- a/security/nss/lib/ssl/ssl3ext.c
+++ b/security/nss/lib/ssl/ssl3ext.c
@@ -709,16 +709,19 @@ loser:
 SECStatus
 ssl_ConstructExtensions(sslSocket *ss, sslBuffer *buf, SSLHandshakeType message)
 {
     const sslExtensionBuilder *sender;
     SECStatus rv;
 
     PORT_Assert(buf->len == 0);
 
+    /* Clear out any extensions previously advertised */
+    ss->xtnData.numAdvertised = 0;
+
     switch (message) {
         case ssl_hs_client_hello:
             if (ss->vrange.max > SSL_LIBRARY_VERSION_3_0) {
                 sender = clientHelloSendersTLS;
             } else {
                 sender = clientHelloSendersSSL3;
             }
             break;
--- a/security/nss/lib/ssl/tls13subcerts.c
+++ b/security/nss/lib/ssl/tls13subcerts.c
@@ -660,16 +660,21 @@ SSLExp_DelegateCredential(const CERTCert
 {
     SECStatus rv;
     SSL3Hashes hash;
     CERTSubjectPublicKeyInfo *spki = NULL;
     SECKEYPrivateKey *tmpPriv = NULL;
     sslDelegatedCredential *dc = NULL;
     sslBuffer dcBuf = SSL_BUFFER_EMPTY;
 
+    if (!cert || !certPriv || !dcPub || !out) {
+        PORT_SetError(SEC_ERROR_INVALID_ARGS);
+        return SECFailure;
+    }
+
     dc = PORT_ZNew(sslDelegatedCredential);
     if (!dc) {
         PORT_SetError(SEC_ERROR_NO_MEMORY);
         goto loser;
     }
 
     /* Serialize the DC parameters. */
     PRTime start;
--- a/security/nss/tests/common/cleanup.sh
+++ b/security/nss/tests/common/cleanup.sh
@@ -1,16 +1,22 @@
 #!/bin/bash
 #
 # 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/.
 
 
 if [ -z "${CLEANUP}" -o "${CLEANUP}" = "${SCRIPTNAME}" ]; then
+    if [ -z "${BUILD_OPT}" ] && [ "$OBJDIR" == "Debug"  ]; then
+        BUILD_OPT=0;
+    elif [ -z "${BUILD_OPT}" ] && [ "$OBJDIR" == "Release" ]; then
+        BUILD_OPT=1;
+    fi
+
     echo
     echo "SUMMARY:"
     echo "========"
     echo "NSS variables:"
     echo "--------------"
     echo "HOST=${HOST}"
     echo "DOMSUF=${DOMSUF}"
     echo "BUILD_OPT=${BUILD_OPT}"
@@ -46,15 +52,16 @@ if [ -z "${CLEANUP}" -o "${CLEANUP}" = "
     LINES_CNT=$(cat ${RESULTS} | grep ">Unknown<" | wc -l | sed s/\ *//)
     echo "Unknown status:     ${LINES_CNT}"
     if [ ${LINES_CNT} -gt 0 ]; then
         echo "TinderboxPrint:Unknown: ${LINES_CNT}"
     fi
     echo
 
     html "END_OF_TEST<BR>"
-    html "</BODY></HTML>" 
+    html "</BODY></HTML>"
     rm -f ${TEMPFILES} 2>/dev/null
-    if [ ${FAILED_CNT} -gt 0 ] || [ ${ASAN_CNT} -gt 0 ]; then
+    if [ ${FAILED_CNT} -gt 0 ] || [ ${ASAN_CNT} -gt 0 ] ||
+       ([ ${BUILD_OPT} -eq 1 ] && [ ${CORE_CNT} -gt 0 ]); then
         exit 1
     fi
 
 fi