tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 90469d9da14828335fdf050657b5ab0742a220cf
parent 45119548c9489da1bffbcfff635a849d079b699f
Author: John M. Schanck <jschanck@mozilla.com>
Date:   Wed,  3 Dec 2025 23:31:09 +0000

Bug 2000871 - upgrade NSS to NSS_3_119_BETA1. r=nss-reviewers,keeler UPGRADE_NSS_RELEASE

Differential Revision: https://phabricator.services.mozilla.com/D275007

Diffstat:
Msecurity/nss/TAG-INFO | 4++--
Msecurity/nss/automation/ossfuzz/build.sh | 16++++++++--------
Msecurity/nss/automation/taskcluster/scripts/build_cryptofuzz.sh | 8++++++--
Msecurity/nss/cmd/rsaperf/rsaperf.c | 5+----
Msecurity/nss/coreconf/Darwin.mk | 19++++++++++---------
Msecurity/nss/coreconf/config.mk | 1-
Msecurity/nss/coreconf/sanitizers.sh | 5++++-
Asecurity/nss/fuzz/options/pkcs12-no_fuzzer_mode.options | 4++++
Msecurity/nss/gtests/ssl_gtest/tls_ech_unittest.cc | 42++++++++++++++++++++++++++++++++++++++----
Msecurity/nss/lib/pk11wrap/pk11mech.c | 10++++++++++
Msecurity/nss/lib/pk11wrap/pk11pbe.c | 13+++++++++++++
Msecurity/nss/lib/pk11wrap/pk11wrap.gyp | 7+++++++
Msecurity/nss/lib/pkcs12/p12d.c | 40+++++++++++++++++++++++++++++++++++++++-
Msecurity/nss/lib/pkcs12/pkcs12.gyp | 12+++++++++---
Msecurity/nss/lib/sqlite/sqlite.gyp | 2+-
Msecurity/nss/lib/ssl/ssl3exthandle.c | 3+--
Msecurity/nss/lib/ssl/tls13ech.c | 12+++++++-----
Msecurity/nss/moz.yaml | 4++--
18 files changed, 162 insertions(+), 45 deletions(-)

diff --git a/security/nss/TAG-INFO b/security/nss/TAG-INFO @@ -1 +1 @@ -NSS_3_117_RTM -\ No newline at end of file +NSS_3_119_BETA1 +\ No newline at end of file diff --git a/security/nss/automation/ossfuzz/build.sh b/security/nss/automation/ossfuzz/build.sh @@ -9,9 +9,6 @@ # List of targets disabled for oss-fuzz. declare -A disabled=() -# List of targets we want to fuzz in TLS and non-TLS mode. -declare -A tls_targets=([tls-client]=1 [tls-server]=1 [dtls-client]=1 [dtls-server]=1) - # Helper function that copies a fuzzer binary and its seed corpus. copy_fuzzer() { @@ -38,7 +35,7 @@ CXX="$CXX -stdlib=libc++" LDFLAGS="$CFLAGS" \ for fuzzer in $(find ../dist/Debug/bin -name "nssfuzz-*" -printf "%f\n"); do name=${fuzzer:8} if [ -z "${disabled[$name]:-}" ]; then - [ -n "${tls_targets[$name]:-}" ] && name="${name}-no_fuzzer_mode" + [ -f "fuzz/options/${name}-no_fuzzer_mode.options" ] && name="${name}-no_fuzzer_mode" copy_fuzzer $fuzzer $name fi done @@ -56,13 +53,16 @@ if [ -d "$SRC/nss-corpus/cryptofuzz" ]; then zip $OUT/cryptofuzz_seed_corpus.zip $SRC/nss-corpus/cryptofuzz/* fi +# TLS Fuzzing mode: Totally Lacking Security +# This mode disables a lot of cryptography to help the fuzzer. +# It was originally used for the TLS-specific fuzzers but has been generalized. # Build the library again (TLS fuzzing mode). CXX="$CXX -stdlib=libc++" LDFLAGS="$CFLAGS" \ ./build.sh -c -v --fuzz=oss --fuzz=tls --disable-tests -# Copy dual mode targets in TLS mode. -for name in "${!tls_targets[@]}"; do - if [ -z "${disabled[$name]:-}" ]; then - copy_fuzzer nssfuzz-$name $name +for fuzzer in $(find ../dist/Debug/bin -name "nssfuzz-*" -printf "%f\n"); do + name=${fuzzer:8} + if [ -z "${disabled[$name]:-}" ] && [ -f "fuzz/options/${name}-no_fuzzer_mode.options" ]; then + copy_fuzzer "$fuzzer" "$name" fi done diff --git a/security/nss/automation/taskcluster/scripts/build_cryptofuzz.sh b/security/nss/automation/taskcluster/scripts/build_cryptofuzz.sh @@ -3,11 +3,15 @@ # NOTE: This file is used to build Cryptofuzz both on CI and OSS-Fuzz. # +set -e +set -x +set -o pipefail + # Do differential fuzzing with Botan (and not OpenSSL) since NSS has # symbol collisions with OpenSSL and therefore they can't be used together # in Cryptofuzz. -export CRYPTOFUZZ_VERSION="687d3064c5cef2b0fe1f30824065a2f2c9c0bbd8" -export BOTAN_VERSION="3.6.1" +export CRYPTOFUZZ_VERSION="3d2377257129fc5da6effb92b0736e31db147dee" +export BOTAN_VERSION="3.10.0" git clone -q https://github.com/MozillaSecurity/cryptofuzz.git git -C cryptofuzz checkout "$CRYPTOFUZZ_VERSION" diff --git a/security/nss/cmd/rsaperf/rsaperf.c b/security/nss/cmd/rsaperf/rsaperf.c @@ -343,7 +343,6 @@ main(int argc, char **argv) int threadNum = DEFAULT_THREADS; ThreadRunData **runDataArr = NULL; PRThread **threadsArr = NULL; - int calcThreads = 0; progName = strrchr(argv[0], '/'); if (!progName) @@ -651,14 +650,12 @@ main(int argc, char **argv) 0); } iters = 0; - calcThreads = 0; - for (i = 0; i < threadNum; i++, calcThreads++) { + for (i = 0; i < threadNum; i++) { PR_JoinThread(threadsArr[i]); if (runDataArr[i]->status != SECSuccess) { const char *errStr = SECU_Strerror(runDataArr[i]->errNum); fprintf(stderr, "Thread %d: Error in RSA operation: %d : %s\n", i, runDataArr[i]->errNum, errStr); - calcThreads -= 1; } else { iters += runDataArr[i]->iterRes; } diff --git a/security/nss/coreconf/Darwin.mk b/security/nss/coreconf/Darwin.mk @@ -18,25 +18,26 @@ ifndef CPU_ARCH CPU_ARCH := $(shell uname -p) endif -ifeq (,$(filter-out i%86,$(CPU_ARCH))) -ifdef USE_64 +ifeq (x86_64,$(CPU_ARCH)) CC += -arch x86_64 CCC += -arch x86_64 override CPU_ARCH = x86_64 -else +else ifeq (i386,$(CPU_ARCH)) OS_REL_CFLAGS = -Di386 CC += -arch i386 CCC += -arch i386 override CPU_ARCH = x86 -endif -else -ifeq (arm,$(CPU_ARCH)) -# Nothing set for arm currently. -else +else ifeq (,$(filter-out aarch64 arm,$(CPU_ARCH))) +CC += -arch arm64 +CCC += -arch arm64 +override CPU_ARCH = aarch64 +else ifeq (powerpc,$(CPU_ARCH)) OS_REL_CFLAGS = -Dppc CC += -arch ppc CCC += -arch ppc -endif +override CPU_ARCH = ppc +else + $(error Unknown CPU architecture) endif ifneq (,$(MACOS_SDK_DIR)) diff --git a/security/nss/coreconf/config.mk b/security/nss/coreconf/config.mk @@ -148,7 +148,6 @@ ifndef NSS_DISABLE_AVX2 ifneq ($(CPU_ARCH),x86_64) # Disable AVX2 entirely on non-Intel platforms NSS_DISABLE_AVX2 = 1 - $(warning CPU_ARCH is not x86_64, disabling -mavx2) else # Clang reports its version as an older gcc, but it's OK ifndef CC_IS_CLANG diff --git a/security/nss/coreconf/sanitizers.sh b/security/nss/coreconf/sanitizers.sh @@ -20,7 +20,10 @@ enable_sanitizer() fi local cflags - cflags=$(${python:-python} $cwd/coreconf/sanitizers.py "$@") + cflags=$(${python:-python3} "${cwd}/coreconf/sanitizers.py" "$@") + if [ $? -ne 0 ]; then + exit 1 + fi sanitizer_flags="$sanitizer_flags $cflags" } diff --git a/security/nss/fuzz/options/pkcs12-no_fuzzer_mode.options b/security/nss/fuzz/options/pkcs12-no_fuzzer_mode.options @@ -0,0 +1,4 @@ +[libfuzzer] +len_control = 100 +max_len = 16777215 +rss_limit_mb = 4096 diff --git a/security/nss/gtests/ssl_gtest/tls_ech_unittest.cc b/security/nss/gtests/ssl_gtest/tls_ech_unittest.cc @@ -111,10 +111,9 @@ class TlsConnectStreamTls13Ech : public TlsConnectTestBase { DataBuffer name; ASSERT_TRUE(parser.ReadVariable(&name, 2)); ASSERT_EQ(0U, parser.remaining()); - // Manual comparison to silence coverity false-positives. - ASSERT_EQ(name.len(), kPublicName.length()); - ASSERT_EQ(0, - memcmp(kPublicName.c_str(), name.data(), kPublicName.length())); + std::string captured_name(reinterpret_cast<const char*>(name.data()), + name.len()); + EXPECT_EQ(expected_name, captured_name); } void DoEchRetry(const ScopedSECKEYPublicKey& server_pub, @@ -2392,6 +2391,41 @@ TEST_F(TlsConnectStreamTls13, NoEchFromTls12Client) { ASSERT_FALSE(filter->captured()); } +TEST_F(TlsConnectStreamTls13Ech, CorrectPreLimInfoFromTls12ClientWithEch) { + EnsureTlsSetup(); + SetupEch(client_, server_); + client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2, + SSL_LIBRARY_VERSION_TLS_1_2); + server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2, + SSL_LIBRARY_VERSION_TLS_1_3); + client_->ExpectEch(false); + server_->ExpectEch(false); + SetExpectedVersion(SSL_LIBRARY_VERSION_TLS_1_2); + Connect(); + SSLPreliminaryChannelInfo channelPreInfo; + SSL_GetPreliminaryChannelInfo(server_->ssl_fd(), &channelPreInfo, + sizeof(channelPreInfo)); + EXPECT_EQ(PR_FALSE, channelPreInfo.echAccepted); + EXPECT_EQ(NULL, channelPreInfo.echPublicName); +} + +TEST_F(TlsConnectStreamTls13Ech, CorrectSNIFromTls12ClientWithEch) { + EnsureTlsSetup(); + SetupEch(client_, server_); + client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2, + SSL_LIBRARY_VERSION_TLS_1_2); + server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2, + SSL_LIBRARY_VERSION_TLS_1_3); + client_->ExpectEch(false); + server_->ExpectEch(false); + SetExpectedVersion(SSL_LIBRARY_VERSION_TLS_1_2); + auto filter = + MakeTlsFilter<TlsExtensionCapture>(client_, ssl_server_name_xtn); + Connect(); + ASSERT_TRUE(filter->captured()); + CheckSniExtension(filter->extension(), "server"); +} + TEST_F(TlsConnectStreamTls13, EchOuterWith12Max) { EnsureTlsSetup(); SetupEch(client_, server_); diff --git a/security/nss/lib/pk11wrap/pk11mech.c b/security/nss/lib/pk11wrap/pk11mech.c @@ -802,6 +802,11 @@ PK11_GetIVLength(CK_MECHANISM_TYPE type) case CKM_CAST_ECB: case CKM_CAST3_ECB: case CKM_CAST5_ECB: + case CKM_AES_KEY_WRAP: + case CKM_AES_KEY_WRAP_PAD: + case CKM_AES_KEY_WRAP_KWP: + case CKM_NSS_AES_KEY_WRAP: + case CKM_NSS_AES_KEY_WRAP_PAD: return 0; case CKM_RC2_CBC: case CKM_DES_CBC: @@ -909,6 +914,11 @@ pk11_ParamFromIVWithLen(CK_MECHANISM_TYPE type, SECItem *iv, int keyLen) case CKM_CAST3_ECB: case CKM_CAST5_ECB: case CKM_RC4: + case CKM_AES_KEY_WRAP: + case CKM_AES_KEY_WRAP_PAD: + case CKM_AES_KEY_WRAP_KWP: + case CKM_NSS_AES_KEY_WRAP: + case CKM_NSS_AES_KEY_WRAP_PAD: break; case CKM_RC2_ECB: rc2_ecb_params = (CK_RC2_PARAMS *)PORT_Alloc(sizeof(CK_RC2_PARAMS)); diff --git a/security/nss/lib/pk11wrap/pk11pbe.c b/security/nss/lib/pk11wrap/pk11pbe.c @@ -1425,6 +1425,18 @@ pk11_RawPBEKeyGenWithKeyType(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, CK_PKCS5_PBKD2_PARAMS pbev2_1_params; CK_ULONG pwLen; #endif +#ifdef UNSAFE_FUZZER_MODE + PK11SymKey *zeroKey = NULL; + unsigned char zeroBuff[32] = { 0 }; + SECItem zeroItem = { siBuffer, zeroBuff, sizeof zeroBuff }; + + zeroKey = PK11_ImportSymKeyWithFlags(slot, type, PK11_OriginUnwrap, + CKA_FLAGS_ONLY, &zeroItem, + CKF_SIGN | CKF_ENCRYPT | CKF_DECRYPT | + CKF_UNWRAP | CKF_WRAP, + PR_FALSE, wincx); + return zeroKey; +#else /* UNSAFE_FUZZER_MODE */ /* do some sanity checks */ if ((params == NULL) || (params->data == NULL)) { @@ -1481,6 +1493,7 @@ pk11_RawPBEKeyGenWithKeyType(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, return pk11_TokenKeyGenWithFlagsAndKeyType(slot, type, params, keyType, keyLen, NULL, CKF_SIGN | CKF_ENCRYPT | CKF_DECRYPT | CKF_UNWRAP | CKF_WRAP, 0, wincx); +#endif /* UNSAFE_FUZZER_MODE */ } /* diff --git a/security/nss/lib/pk11wrap/pk11wrap.gyp b/security/nss/lib/pk11wrap/pk11wrap.gyp @@ -64,6 +64,13 @@ 'NSS_SHLIB_VERSION=\"3\"', 'SOFTOKEN_SHLIB_VERSION=\"3\"' ], + 'conditions': [ + [ 'fuzz_tls==1', { + 'defines': [ + 'UNSAFE_FUZZER_MODE', + ], + }], + ], }, 'variables': { 'module': 'nss' diff --git a/security/nss/lib/pkcs12/p12d.c b/security/nss/lib/pkcs12/p12d.c @@ -1318,6 +1318,38 @@ static const char bufferEnd[] = { "BufferEnd" }; #endif #define FUDGE 128 /* must be as large as bufferEnd or more. */ +#ifdef UNSAFE_FUZZER_MODE +static PRBool +fuzzer_parity_check(const unsigned char *buf, size_t len) +{ + unsigned char p = 0; + for (size_t i = 0; i < len; i++) + p ^= buf[i]; + return (p & 1) != 0; +} + +static SECStatus +sec_pkcs12_decoder_unsafe_parity_outcome(SEC_PKCS12DecoderContext *p12dcx) +{ + PRBool allow = PR_TRUE; + if (p12dcx->pfx.encodedMacData.data && p12dcx->pfx.encodedMacData.len) { + allow = fuzzer_parity_check(p12dcx->pfx.encodedMacData.data, p12dcx->pfx.encodedMacData.len); + } + + if (p12dcx->dClose) { + (*p12dcx->dClose)(p12dcx->dArg, PR_TRUE); + p12dcx->dIsOpen = PR_FALSE; + } + + if (!allow) { + PORT_SetError(SEC_ERROR_PKCS12_INVALID_MAC); + return SECFailure; + } + + return SECSuccess; +} +#endif /* UNSAFE_FUZZER_MODE */ + /* verify the hmac by reading the data from the temporary file * using the routines specified when the decodingContext was * created and return SECSuccess if the hmac matches. @@ -1340,6 +1372,9 @@ sec_pkcs12_decoder_verify_mac(SEC_PKCS12DecoderContext *p12dcx) PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } +#ifdef UNSAFE_FUZZER_MODE + return sec_pkcs12_decoder_unsafe_parity_outcome(p12dcx); +#endif /* UNSAFE_FUZZER_MODE */ buf = (unsigned char *)PORT_Alloc(IN_BUF_LEN + FUDGE); if (!buf) return SECFailure; /* error code has been set. */ @@ -1461,7 +1496,9 @@ SEC_PKCS12DecoderVerify(SEC_PKCS12DecoderContext *p12dcx) if (rv != SECSuccess) { return rv; } - +#ifdef UNSAFE_FUZZER_MODE + return sec_pkcs12_decoder_unsafe_parity_outcome(p12dcx); +#else /* UNSAFE_FUZZER_MODE */ /* check the signature or the mac depending on the type of * integrity used. */ @@ -1480,6 +1517,7 @@ SEC_PKCS12DecoderVerify(SEC_PKCS12DecoderContext *p12dcx) } PORT_SetError(SEC_ERROR_PKCS12_INVALID_MAC); return SECFailure; +#endif /* UNSAFE_FUZZER_MODE */ } /* SEC_PKCS12DecoderFinish diff --git a/security/nss/lib/pkcs12/pkcs12.gyp b/security/nss/lib/pkcs12/pkcs12.gyp @@ -20,10 +20,17 @@ ], 'dependencies': [ '<(DEPTH)/exports.gyp:nss_exports' - ] + ], + 'conditions': [ + [ 'fuzz_tls==1', { + 'defines': [ + 'UNSAFE_FUZZER_MODE', + ], + }], + ], } ], 'variables': { 'module': 'nss' } -} -\ No newline at end of file +} diff --git a/security/nss/lib/sqlite/sqlite.gyp b/security/nss/lib/sqlite/sqlite.gyp @@ -11,7 +11,7 @@ 'target_name': 'sqlite3', 'type': 'none', 'link_settings': { - 'libraries': ['<(sqlite_libs)'], + 'libraries': ['<@(sqlite_libs)'], }, }], }, { diff --git a/security/nss/lib/ssl/ssl3exthandle.c b/security/nss/lib/ssl/ssl3exthandle.c @@ -80,8 +80,7 @@ ssl3_ClientSendServerNameXtn(const sslSocket *ss, TLSExtensionData *xtnData, /* If ECH, write the public name. The real server name * is emplaced while constructing CHInner extensions. */ - sslEchConfig *cfg = (sslEchConfig *)PR_LIST_HEAD(&ss->echConfigs); - const char *sniContents = PR_CLIST_IS_EMPTY(&ss->echConfigs) ? url : cfg->contents.publicName; + const char *sniContents = ss->ssl3.hs.echHpkeCtx ? ss->ssl3.hs.echPublicName : url; rv = ssl3_ClientFormatServerNameXtn(ss, sniContents, strlen(sniContents), xtnData, buf); if (rv != SECSuccess) { return SECFailure; diff --git a/security/nss/lib/ssl/tls13ech.c b/security/nss/lib/ssl/tls13ech.c @@ -1090,7 +1090,7 @@ tls13_OpenClientHelloInner(sslSocket *ss, const SECItem *outer, const SECItem *o } #else rv = SECITEM_CopyItem(NULL, decryptedChInner, &ss->xtnData.ech->innerCh); - if (rv != SECSuccess) { + if (rv != SECSuccess || decryptedChInner->len <= TLS13_ECH_AEAD_TAG_LEN) { goto loser; } decryptedChInner->len -= TLS13_ECH_AEAD_TAG_LEN; /* Fake tag */ @@ -2697,6 +2697,8 @@ tls13_MaybeAcceptEch(sslSocket *ss, const SECItem *sidBytes, const PRUint8 *chOu TLSExtension *hrrXtn; PRBool previouslyOfferedEch; + PORT_Assert(!ss->ssl3.hs.echAccepted); + if (!ss->xtnData.ech || ss->xtnData.ech->receivedInnerXtn || IS_DTLS(ss)) { ss->ssl3.hs.echDecided = PR_TRUE; return SECSuccess; @@ -2707,14 +2709,13 @@ tls13_MaybeAcceptEch(sslSocket *ss, const SECItem *sidBytes, const PRUint8 *chOu if (ss->ssl3.hs.helloRetry) { ss->ssl3.hs.echDecided = PR_TRUE; PORT_Assert(!ss->ssl3.hs.echHpkeCtx); + hrrXtn = ssl3_FindExtension(ss, ssl_tls13_cookie_xtn); if (!hrrXtn) { /* If the client doesn't echo cookie, we can't decrypt. */ return SECSuccess; } - PORT_Assert(!ss->ssl3.hs.echHpkeCtx); - PRUint8 *tmp = hrrXtn->data.data; PRUint32 len = hrrXtn->data.len; rv = ssl3_ExtConsumeHandshakeVariable(ss, &cookieData, 2, @@ -2735,8 +2736,8 @@ tls13_MaybeAcceptEch(sslSocket *ss, const SECItem *sidBytes, const PRUint8 *chOu ss->ssl3.hs.echHpkeCtx = echData.hpkeCtx; const PRUint8 greaseConstant[TLS13_ECH_SIGNAL_LEN] = { 0 }; - ss->ssl3.hs.echAccepted = previouslyOfferedEch && - !NSS_SecureMemcmp(greaseConstant, echData.signal, TLS13_ECH_SIGNAL_LEN); + PRBool signal = previouslyOfferedEch && + !NSS_SecureMemcmp(greaseConstant, echData.signal, TLS13_ECH_SIGNAL_LEN); if (echData.configId != ss->xtnData.ech->configId || echData.kdfId != ss->xtnData.ech->kdfId || @@ -2749,6 +2750,7 @@ tls13_MaybeAcceptEch(sslSocket *ss, const SECItem *sidBytes, const PRUint8 *chOu if (!ss->ssl3.hs.echHpkeCtx) { return SECSuccess; } + ss->ssl3.hs.echAccepted = signal; } if (ss->ssl3.hs.echDecided && !ss->ssl3.hs.echAccepted) { diff --git a/security/nss/moz.yaml b/security/nss/moz.yaml @@ -9,8 +9,8 @@ origin: description: nss url: https://hg-edge.mozilla.org/projects/nss - release: 28cc2eb89479695ce2b2cb0933dccaae85887697 (2025-11-24T20:15:29Z). - revision: 28cc2eb89479695ce2b2cb0933dccaae85887697 + release: 8c7bdebef8325c782fc5e1cce9a1940d326f1fb0 (2025-12-03T17:41:07Z). + revision: 8c7bdebef8325c782fc5e1cce9a1940d326f1fb0 license: MPL-2.0 license-file: COPYING