From 0738b607f49f97836a632c246fa6e14edd525704 Mon Sep 17 00:00:00 2001 From: Franziskus Kiefer Date: Tue, 5 Sep 2017 12:52:00 +0200 Subject: [PATCH] Bug 1386955 - land NSS 4bf658832d89 UPGRADE_NSS_RELEASE, r=me MozReview-Commit-ID: 7V3T5SpKqi7 --HG-- extra : rebase_source : 165b8ba5806ed4423f5c6048b9776f9f2ffb10cc --- security/nss.symbols | 3 + security/nss/TAG-INFO | 2 +- .../taskcluster/docker-gcc-4.4/Dockerfile | 30 +++++++ .../docker-gcc-4.4/bin/checkout.sh | 20 +++++ .../taskcluster/docker-gcc-4.4/setup.sh | 30 +++++++ .../taskcluster/graph/src/extend.js | 25 ++++++ security/nss/coreconf/coreconf.dep | 1 - .../gtests/ssl_gtest/ssl_loopback_unittest.cc | 8 +- security/nss/gtests/util_gtest/manifest.mn | 2 + .../util_aligned_malloc_unittest.cc | 82 +++++++++++++++++++ security/nss/gtests/util_gtest/util_gtest.gyp | 2 + .../util_gtest/util_memcmpzero_unittest.cc | 45 ++++++++++ security/nss/lib/freebl/ecl/ecp_25519.c | 6 +- security/nss/lib/freebl/gcm.c | 11 +-- security/nss/lib/freebl/rijndael.c | 11 +-- security/nss/lib/freebl/stubs.c | 62 ++++++++++++++ security/nss/lib/freebl/stubs.h | 3 + security/nss/lib/nss/utilwrap.c | 14 ++++ security/nss/lib/ssl/ssl3con.c | 10 ++- security/nss/lib/util/nssutil.def | 8 ++ security/nss/lib/util/secport.c | 62 ++++++++++++++ security/nss/lib/util/secport.h | 7 ++ security/nss/lib/util/utilrename.h | 2 + 23 files changed, 418 insertions(+), 28 deletions(-) create mode 100644 security/nss/automation/taskcluster/docker-gcc-4.4/Dockerfile create mode 100644 security/nss/automation/taskcluster/docker-gcc-4.4/bin/checkout.sh create mode 100644 security/nss/automation/taskcluster/docker-gcc-4.4/setup.sh create mode 100644 security/nss/gtests/util_gtest/util_aligned_malloc_unittest.cc create mode 100644 security/nss/gtests/util_gtest/util_memcmpzero_unittest.cc diff --git a/security/nss.symbols b/security/nss.symbols index da11803787cf..a2fb8ba4644c 100644 --- a/security/nss.symbols +++ b/security/nss.symbols @@ -714,6 +714,9 @@ VFY_VerifyDataWithAlgorithmID VFY_VerifyDigestDirect _SGN_VerifyPKCS1DigestInfo __PK11_SetCertificateNickname +# These symbols are not used by Firefox but are used across NSS library boundaries. +NSS_SecureMemcmpZero +PORT_ZAllocAlignedOffset_Util # These symbols are not used by Firefox itself, but are used by Java's security # libraries, which in turn are used by Java applets/plugins/etc. Provide them # to make Java code happy. diff --git a/security/nss/TAG-INFO b/security/nss/TAG-INFO index c7855368e14b..6052fb1cf3f2 100644 --- a/security/nss/TAG-INFO +++ b/security/nss/TAG-INFO @@ -1 +1 @@ -7fcf7848095c +4bf658832d89 diff --git a/security/nss/automation/taskcluster/docker-gcc-4.4/Dockerfile b/security/nss/automation/taskcluster/docker-gcc-4.4/Dockerfile new file mode 100644 index 000000000000..3330c007fe88 --- /dev/null +++ b/security/nss/automation/taskcluster/docker-gcc-4.4/Dockerfile @@ -0,0 +1,30 @@ +FROM ubuntu:14.04 +MAINTAINER Tim Taubert + +RUN useradd -d /home/worker -s /bin/bash -m worker +WORKDIR /home/worker + +# Add build and test scripts. +ADD bin /home/worker/bin +RUN chmod +x /home/worker/bin/* + +# Install dependencies. +ADD setup.sh /tmp/setup.sh +RUN bash /tmp/setup.sh + +# Change user. +USER worker + +# Env variables. +ENV HOME /home/worker +ENV SHELL /bin/bash +ENV USER worker +ENV LOGNAME worker +ENV HOSTNAME taskcluster-worker +ENV LANG en_US.UTF-8 +ENV LC_ALL en_US.UTF-8 +ENV HOST localhost +ENV DOMSUF localdomain + +# Set a default command for debugging. +CMD ["/bin/bash", "--login"] diff --git a/security/nss/automation/taskcluster/docker-gcc-4.4/bin/checkout.sh b/security/nss/automation/taskcluster/docker-gcc-4.4/bin/checkout.sh new file mode 100644 index 000000000000..9167f6bda6b3 --- /dev/null +++ b/security/nss/automation/taskcluster/docker-gcc-4.4/bin/checkout.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +set -v -e -x + +if [ $(id -u) = 0 ]; then + # Drop privileges by re-running this script. + exec su worker $0 +fi + +# Default values for testing. +REVISION=${NSS_HEAD_REVISION:-default} +REPOSITORY=${NSS_HEAD_REPOSITORY:-https://hg.mozilla.org/projects/nss} + +# Clone NSS. +for i in 0 2 5; do + sleep $i + hg clone -r $REVISION $REPOSITORY nss && exit 0 + rm -rf nss +done +exit 1 diff --git a/security/nss/automation/taskcluster/docker-gcc-4.4/setup.sh b/security/nss/automation/taskcluster/docker-gcc-4.4/setup.sh new file mode 100644 index 000000000000..f6325d966c12 --- /dev/null +++ b/security/nss/automation/taskcluster/docker-gcc-4.4/setup.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash + +set -v -e -x + +# Update packages. +export DEBIAN_FRONTEND=noninteractive +apt-get -y update && apt-get -y upgrade + +apt_packages=() +apt_packages+=('ca-certificates') +apt_packages+=('g++-4.4') +apt_packages+=('gcc-4.4') +apt_packages+=('locales') +apt_packages+=('make') +apt_packages+=('mercurial') +apt_packages+=('zlib1g-dev') + +# Install packages. +apt-get -y update +apt-get install -y --no-install-recommends ${apt_packages[@]} + +locale-gen en_US.UTF-8 +dpkg-reconfigure locales + +# Cleanup. +rm -rf ~/.ccache ~/.cache +apt-get autoremove -y +apt-get clean +apt-get autoclean +rm $0 diff --git a/security/nss/automation/taskcluster/graph/src/extend.js b/security/nss/automation/taskcluster/graph/src/extend.js index 75b7cf5a063d..97cff5680892 100644 --- a/security/nss/automation/taskcluster/graph/src/extend.js +++ b/security/nss/automation/taskcluster/graph/src/extend.js @@ -15,6 +15,11 @@ const LINUX_CLANG39_IMAGE = { path: "automation/taskcluster/docker-clang-3.9" }; +const LINUX_GCC44_IMAGE = { + name: "linux-gcc-4.4", + path: "automation/taskcluster/docker-gcc-4.4" +}; + const FUZZ_IMAGE = { name: "fuzz", path: "automation/taskcluster/docker-fuzz" @@ -405,6 +410,26 @@ async function scheduleLinux(name, base, args = "") { symbol: "clang-4.0" })); + queue.scheduleTask(merge(extra_base, { + name: `${name} w/ gcc-4.4`, + image: LINUX_GCC44_IMAGE, + env: { + USE_64: "1", + CC: "gcc-4.4", + CCC: "g++-4.4", + // gcc-4.6 introduced nullptr. + NSS_DISABLE_GTESTS: "1", + }, + // Use the old Makefile-based build system, GYP doesn't have a proper GCC + // version check for __int128 support. It's mainly meant to cover RHEL6. + command: [ + "/bin/bash", + "-c", + "bin/checkout.sh && nss/automation/taskcluster/scripts/build.sh", + ], + symbol: "gcc-4.4" + })); + queue.scheduleTask(merge(extra_base, { name: `${name} w/ gcc-4.8`, env: { diff --git a/security/nss/coreconf/coreconf.dep b/security/nss/coreconf/coreconf.dep index 590d1bfaeee3..5182f75552c8 100644 --- a/security/nss/coreconf/coreconf.dep +++ b/security/nss/coreconf/coreconf.dep @@ -10,4 +10,3 @@ */ #error "Do not include this header file." - diff --git a/security/nss/gtests/ssl_gtest/ssl_loopback_unittest.cc b/security/nss/gtests/ssl_gtest/ssl_loopback_unittest.cc index d7a21f99db7a..be97291efb14 100644 --- a/security/nss/gtests/ssl_gtest/ssl_loopback_unittest.cc +++ b/security/nss/gtests/ssl_gtest/ssl_loopback_unittest.cc @@ -226,14 +226,14 @@ TEST_P(TlsConnectStream, ShortRead) { ASSERT_EQ(50U, client_->received_bytes()); } -TEST_P(TlsConnectGeneric, ConnectWithCompressionMaybe) { +// We enable compression via the API but it's disabled internally, +// so we should never get it. +TEST_P(TlsConnectGeneric, ConnectWithCompressionEnabled) { EnsureTlsSetup(); client_->EnableCompression(); server_->EnableCompression(); Connect(); - EXPECT_EQ(client_->version() < SSL_LIBRARY_VERSION_TLS_1_3 && - variant_ != ssl_variant_datagram, - client_->is_compressed()); + EXPECT_FALSE(client_->is_compressed()); SendReceive(); } diff --git a/security/nss/gtests/util_gtest/manifest.mn b/security/nss/gtests/util_gtest/manifest.mn index edede657f838..a90e8431ef47 100644 --- a/security/nss/gtests/util_gtest/manifest.mn +++ b/security/nss/gtests/util_gtest/manifest.mn @@ -10,6 +10,8 @@ CPPSRCS = \ util_utf8_unittest.cc \ util_b64_unittest.cc \ util_pkcs11uri_unittest.cc \ + util_aligned_malloc_unittest.cc \ + util_memcmpzero_unittest.cc \ $(NULL) INCLUDES += \ diff --git a/security/nss/gtests/util_gtest/util_aligned_malloc_unittest.cc b/security/nss/gtests/util_gtest/util_aligned_malloc_unittest.cc new file mode 100644 index 000000000000..9745ca7d3eaa --- /dev/null +++ b/security/nss/gtests/util_gtest/util_aligned_malloc_unittest.cc @@ -0,0 +1,82 @@ +/* -*- 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 "gtest/gtest.h" +#include "scoped_ptrs_util.h" + +namespace nss_test { + +struct SomeContext { + uint8_t some_buf[13]; + void *mem; +}; + +template +struct ScopedDelete { + void operator()(T *ptr) { + if (ptr) { + PORT_Free(ptr->mem); + } + } +}; +typedef std::unique_ptr > + ScopedSomeContext; + +class AlignedMallocTest : public ::testing::Test, + public ::testing::WithParamInterface { + protected: + ScopedSomeContext test_align_new(size_t alignment) { + ScopedSomeContext ctx(PORT_ZNewAligned(SomeContext, alignment, mem)); + return ctx; + }; + ScopedSomeContext test_align_alloc(size_t alignment) { + void *mem = nullptr; + ScopedSomeContext ctx((SomeContext *)PORT_ZAllocAligned(sizeof(SomeContext), + alignment, &mem)); + if (ctx) { + ctx->mem = mem; + } + return ctx; + } +}; + +TEST_P(AlignedMallocTest, TestNew) { + size_t alignment = GetParam(); + ScopedSomeContext ctx = test_align_new(alignment); + EXPECT_TRUE(ctx.get()); + EXPECT_EQ(0U, (uintptr_t)ctx.get() % alignment); +} + +TEST_P(AlignedMallocTest, TestAlloc) { + size_t alignment = GetParam(); + ScopedSomeContext ctx = test_align_alloc(alignment); + EXPECT_TRUE(ctx.get()); + EXPECT_EQ(0U, (uintptr_t)ctx.get() % alignment); +} + +class AlignedMallocTestBadSize : public AlignedMallocTest {}; + +TEST_P(AlignedMallocTestBadSize, TestNew) { + size_t alignment = GetParam(); + ScopedSomeContext ctx = test_align_new(alignment); + EXPECT_FALSE(ctx.get()); +} + +TEST_P(AlignedMallocTestBadSize, TestAlloc) { + size_t alignment = GetParam(); + ScopedSomeContext ctx = test_align_alloc(alignment); + EXPECT_FALSE(ctx.get()); +} + +static const size_t kSizes[] = {1, 2, 4, 8, 16, 32, 64}; +static const size_t kBadSizes[] = {0, 7, 17, 24, 56}; + +INSTANTIATE_TEST_CASE_P(AllAligned, AlignedMallocTest, + ::testing::ValuesIn(kSizes)); +INSTANTIATE_TEST_CASE_P(AllAlignedBadSize, AlignedMallocTestBadSize, + ::testing::ValuesIn(kBadSizes)); + +} // namespace nss_test diff --git a/security/nss/gtests/util_gtest/util_gtest.gyp b/security/nss/gtests/util_gtest/util_gtest.gyp index 7abd71b2f648..1c54329b2dbd 100644 --- a/security/nss/gtests/util_gtest/util_gtest.gyp +++ b/security/nss/gtests/util_gtest/util_gtest.gyp @@ -14,6 +14,8 @@ 'util_utf8_unittest.cc', 'util_b64_unittest.cc', 'util_pkcs11uri_unittest.cc', + 'util_aligned_malloc_unittest.cc', + 'util_memcmpzero_unittest.cc', '<(DEPTH)/gtests/common/gtests.cc', ], 'dependencies': [ diff --git a/security/nss/gtests/util_gtest/util_memcmpzero_unittest.cc b/security/nss/gtests/util_gtest/util_memcmpzero_unittest.cc new file mode 100644 index 000000000000..29cac3f67b05 --- /dev/null +++ b/security/nss/gtests/util_gtest/util_memcmpzero_unittest.cc @@ -0,0 +1,45 @@ +/* -*- 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 "gtest/gtest.h" +#include "scoped_ptrs_util.h" + +namespace nss_test { + +class MemcmpZeroTest : public ::testing::Test { + protected: + unsigned int test_memcmp_zero(const std::vector &mem) { + return NSS_SecureMemcmpZero(mem.data(), mem.size()); + }; +}; + +TEST_F(MemcmpZeroTest, TestMemcmpZeroTrue) { + unsigned int rv = test_memcmp_zero(std::vector(37, 0)); + EXPECT_EQ(0U, rv); +} + +TEST_F(MemcmpZeroTest, TestMemcmpZeroFalse5) { + std::vector vec(37, 0); + vec[5] = 1; + unsigned int rv = test_memcmp_zero(vec); + EXPECT_NE(0U, rv); +} + +TEST_F(MemcmpZeroTest, TestMemcmpZeroFalse37) { + std::vector vec(37, 0); + vec[vec.size() - 1] = 0xFF; + unsigned int rv = test_memcmp_zero(vec); + EXPECT_NE(0U, rv); +} + +TEST_F(MemcmpZeroTest, TestMemcmpZeroFalse0) { + std::vector vec(37, 0); + vec[0] = 1; + unsigned int rv = test_memcmp_zero(vec); + EXPECT_NE(0U, rv); +} + +} // namespace nss_test diff --git a/security/nss/lib/freebl/ecl/ecp_25519.c b/security/nss/lib/freebl/ecl/ecp_25519.c index 1e7875fff2c9..38bd34c5016f 100644 --- a/security/nss/lib/freebl/ecl/ecp_25519.c +++ b/security/nss/lib/freebl/ecl/ecp_25519.c @@ -115,5 +115,9 @@ ec_Curve25519_pt_mul(SECItem *X, SECItem *k, SECItem *P) px = P->data; } - return ec_Curve25519_mul(X->data, k->data, px); + SECStatus rv = ec_Curve25519_mul(X->data, k->data, px); + if (NSS_SecureMemcmpZero(X->data, X->len) == 0) { + return SECFailure; + } + return rv; } diff --git a/security/nss/lib/freebl/gcm.c b/security/nss/lib/freebl/gcm.c index 34e034e2432b..780b7a632200 100644 --- a/security/nss/lib/freebl/gcm.c +++ b/security/nss/lib/freebl/gcm.c @@ -574,7 +574,7 @@ GCM_CreateContext(void *context, freeblCipherFunc cipher, const unsigned char *params) { GCMContext *gcm = NULL; - gcmHashContext *ghash = NULL, *ghashmem = NULL; + gcmHashContext *ghash = NULL; unsigned char H[MAX_BLOCK_SIZE]; unsigned int tmp; PRBool freeCtr = PR_FALSE; @@ -595,14 +595,7 @@ GCM_CreateContext(void *context, freeblCipherFunc cipher, if (gcm == NULL) { return NULL; } - /* aligned_alloc is C11 so we have to do it the old way. */ - ghashmem = PORT_ZAlloc(sizeof(gcmHashContext) + 15); - if (ghashmem == NULL) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - ghash = (gcmHashContext *)(((uintptr_t)ghashmem + 15) & ~(uintptr_t)0x0F); - ghash->mem = ghashmem; + ghash = PORT_ZNewAligned(gcmHashContext, 16, mem); /* first plug in the ghash context */ gcm->ghash_context = ghash; diff --git a/security/nss/lib/freebl/rijndael.c b/security/nss/lib/freebl/rijndael.c index 7381ea20111c..79240e937b81 100644 --- a/security/nss/lib/freebl/rijndael.c +++ b/security/nss/lib/freebl/rijndael.c @@ -1017,16 +1017,7 @@ rijndael_decryptCBC(AESContext *cx, unsigned char *output, AESContext * AES_AllocateContext(void) { - /* aligned_alloc is C11 so we have to do it the old way. */ - AESContext *ctx, *ctxmem; - ctxmem = PORT_ZAlloc(sizeof(AESContext) + 15); - if (ctxmem == NULL) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - return NULL; - } - ctx = (AESContext *)(((uintptr_t)ctxmem + 15) & ~(uintptr_t)0x0F); - ctx->mem = ctxmem; - return ctx; + return PORT_ZNewAligned(AESContext, 16, mem); } /* diff --git a/security/nss/lib/freebl/stubs.c b/security/nss/lib/freebl/stubs.c index 8e07849355c8..7c2ecf88d341 100644 --- a/security/nss/lib/freebl/stubs.c +++ b/security/nss/lib/freebl/stubs.c @@ -136,6 +136,11 @@ STUB_DECLARE(int, PORT_GetError_Util, (void)); STUB_DECLARE(PLArenaPool *, PORT_NewArena_Util, (unsigned long chunksize)); STUB_DECLARE(void, PORT_SetError_Util, (int value)); STUB_DECLARE(void *, PORT_ZAlloc_Util, (size_t len)); +STUB_DECLARE(void *, PORT_ZAllocAligned_Util, (size_t bytes, size_t alignment, + void **mem)); +STUB_DECLARE(void *, PORT_ZAllocAlignedOffset_Util, (size_t bytes, + size_t alignment, + size_t offset)); STUB_DECLARE(void, PORT_ZFree_Util, (void *ptr, size_t len)); STUB_DECLARE(void, PR_Assert, (const char *s, const char *file, PRIntn ln)); @@ -174,11 +179,14 @@ STUB_DECLARE(void, SECITEM_FreeItem_Util, (SECItem * zap, PRBool freeit)); STUB_DECLARE(void, SECITEM_ZfreeItem_Util, (SECItem * zap, PRBool freeit)); STUB_DECLARE(SECOidTag, SECOID_FindOIDTag_Util, (const SECItem *oid)); STUB_DECLARE(int, NSS_SecureMemcmp, (const void *a, const void *b, size_t n)); +STUB_DECLARE(unsigned int, NSS_SecureMemcmpZero, (const void *mem, size_t n)); #define PORT_ZNew_stub(type) (type *)PORT_ZAlloc_stub(sizeof(type)) #define PORT_New_stub(type) (type *)PORT_Alloc_stub(sizeof(type)) #define PORT_ZNewArray_stub(type, num) \ (type *)PORT_ZAlloc_stub(sizeof(type) * (num)) +#define PORT_ZNewAligned_stub(type, alignment, mem) \ + (type *)PORT_ZAllocAlignedOffset_stub(sizeof(type), alignment, offsetof(type, mem)) /* * NOTE: in order to support hashing only the memory allocation stubs, @@ -214,6 +222,52 @@ PORT_ZAlloc_stub(size_t len) return ptr; } +/* aligned_alloc is C11. This is an alternative to get aligned memory. */ +extern void * +PORT_ZAllocAligned_stub(size_t bytes, size_t alignment, void **mem) +{ + STUB_SAFE_CALL3(PORT_ZAllocAligned_Util, bytes, alignment, mem); + + /* This only works if alignement is a power of 2. */ + if ((alignment == 0) || (alignment & (alignment - 1))) { + return NULL; + } + + size_t x = alignment - 1; + size_t len = (bytes ? bytes : 1) + x; + + if (!mem) { + return NULL; + } + + /* Always allocate a non-zero amount of bytes */ + *mem = malloc(len); + if (!*mem) { + return NULL; + } + + memset(*mem, 0, len); + return (void *)(((uintptr_t)*mem + x) & ~(uintptr_t)x); +} + +extern void * +PORT_ZAllocAlignedOffset_stub(size_t size, size_t alignment, size_t offset) +{ + STUB_SAFE_CALL3(PORT_ZAllocAlignedOffset_Util, size, alignment, offset); + if (offset > size) { + return NULL; + } + + void *mem = NULL; + void *v = PORT_ZAllocAligned_stub(size, alignment, &mem); + if (!v) { + return NULL; + } + + *((void **)((uintptr_t)v + offset)) = mem; + return v; +} + extern void PORT_ZFree_stub(void *ptr, size_t len) { @@ -590,6 +644,13 @@ NSS_SecureMemcmp_stub(const void *a, const void *b, size_t n) abort(); } +extern unsigned int +NSS_SecureMemcmpZero_stub(const void *mem, size_t n) +{ + STUB_SAFE_CALL2(NSS_SecureMemcmpZero, mem, n); + abort(); +} + #ifdef FREEBL_NO_WEAK static const char *nsprLibName = SHLIB_PREFIX "nspr4." SHLIB_SUFFIX; @@ -642,6 +703,7 @@ freebl_InitNSSUtil(void *lib) STUB_FETCH_FUNCTION(SECITEM_ZfreeItem_Util); STUB_FETCH_FUNCTION(SECOID_FindOIDTag_Util); STUB_FETCH_FUNCTION(NSS_SecureMemcmp); + STUB_FETCH_FUNCTION(NSS_SecureMemcmpZero); return SECSuccess; } diff --git a/security/nss/lib/freebl/stubs.h b/security/nss/lib/freebl/stubs.h index 25ec394ecd74..e63cf7a5de81 100644 --- a/security/nss/lib/freebl/stubs.h +++ b/security/nss/lib/freebl/stubs.h @@ -30,6 +30,8 @@ #define PORT_SetError PORT_SetError_stub #define PORT_ZAlloc PORT_ZAlloc_stub #define PORT_ZFree PORT_ZFree_stub +#define PORT_ZAllocAligned PORT_ZAllocAligned_stub +#define PORT_ZAllocAlignedOffset PORT_ZAllocAlignedOffset_stub #define SECITEM_AllocItem SECITEM_AllocItem_stub #define SECITEM_CompareItem SECITEM_CompareItem_stub @@ -38,6 +40,7 @@ #define SECITEM_ZfreeItem SECITEM_ZfreeItem_stub #define SECOID_FindOIDTag SECOID_FindOIDTag_stub #define NSS_SecureMemcmp NSS_SecureMemcmp_stub +#define NSS_SecureMemcmpZero NSS_SecureMemcmpZero_stub #define PR_Assert PR_Assert_stub #define PR_Access PR_Access_stub diff --git a/security/nss/lib/nss/utilwrap.c b/security/nss/lib/nss/utilwrap.c index 938d95c0f1aa..48e147d885c1 100644 --- a/security/nss/lib/nss/utilwrap.c +++ b/security/nss/lib/nss/utilwrap.c @@ -75,6 +75,8 @@ #undef PORT_UCS2_ASCIIConversion #undef PORT_UCS2_UTF8Conversion #undef PORT_ZAlloc +#undef PORT_ZAllocAligned +#undef PORT_ZAllocAlignedOffset #undef PORT_ZFree #undef SEC_ASN1Decode #undef SEC_ASN1DecodeInteger @@ -144,6 +146,18 @@ PORT_ZAlloc(size_t bytes) return PORT_ZAlloc_Util(bytes); } +void * +PORT_ZAllocAligned(size_t bytes, size_t alignment, void **mem) +{ + return PORT_ZAllocAligned_Util(bytes, alignment, mem); +} + +void * +PORT_ZAllocAlignedOffset(size_t bytes, size_t alignment, size_t offset) +{ + return PORT_ZAllocAlignedOffset_Util(bytes, alignment, offset); +} + void PORT_Free(void *ptr) { diff --git a/security/nss/lib/ssl/ssl3con.c b/security/nss/lib/ssl/ssl3con.c index c616e2a961bf..8daad7c5062f 100644 --- a/security/nss/lib/ssl/ssl3con.c +++ b/security/nss/lib/ssl/ssl3con.c @@ -1,3 +1,4 @@ + /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * SSL3 Protocol @@ -233,11 +234,15 @@ static const unsigned int ssl_compression_method_count = static PRBool ssl_CompressionEnabled(sslSocket *ss, SSLCompressionMethod compression) { - SSL3ProtocolVersion version; - if (compression == ssl_compression_null) { return PR_TRUE; /* Always enabled */ } +/* Compression was disabled in NSS 3.33. It is temporarily possible + * to re-enable it by unifdefing the following block. We will remove + * compression entirely in future versions of NSS. */ +#if 0 + SSL3ProtocolVersion version; + if (ss->sec.isServer) { /* We can't easily check that the client didn't attempt TLS 1.3, * so this will have to do. */ @@ -256,6 +261,7 @@ ssl_CompressionEnabled(sslSocket *ss, SSLCompressionMethod compression) } return ss->opt.enableDeflate; } +#endif #endif return PR_FALSE; } diff --git a/security/nss/lib/util/nssutil.def b/security/nss/lib/util/nssutil.def index f4b9ef7ba321..4159b786fab1 100644 --- a/security/nss/lib/util/nssutil.def +++ b/security/nss/lib/util/nssutil.def @@ -307,3 +307,11 @@ PK11URI_GetQueryAttribute; ;+ local: ;+ *; ;+}; +;+NSSUTIL_3.33 { # NSS Utilities 3.33 release +;+ global: +PORT_ZAllocAligned_Util; +PORT_ZAllocAlignedOffset_Util; +NSS_SecureMemcmpZero; +;+ local: +;+ *; +;+}; diff --git a/security/nss/lib/util/secport.c b/security/nss/lib/util/secport.c index 01a7d0834e26..4eeddec4070a 100644 --- a/security/nss/lib/util/secport.c +++ b/security/nss/lib/util/secport.c @@ -21,6 +21,8 @@ #include "prenv.h" #include "prinit.h" +#include + #ifdef DEBUG #define THREADMARK #endif /* DEBUG */ @@ -119,6 +121,51 @@ PORT_ZAlloc(size_t bytes) return rv; } +/* aligned_alloc is C11. This is an alternative to get aligned memory. */ +void * +PORT_ZAllocAligned(size_t bytes, size_t alignment, void **mem) +{ + size_t x = alignment - 1; + + /* This only works if alignment is a power of 2. */ + if ((alignment == 0) || (alignment & (alignment - 1))) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return NULL; + } + + if (!mem) { + return NULL; + } + + /* Always allocate a non-zero amount of bytes */ + *mem = PORT_ZAlloc((bytes ? bytes : 1) + x); + if (!*mem) { + PORT_SetError(SEC_ERROR_NO_MEMORY); + return NULL; + } + + return (void *)(((uintptr_t)*mem + x) & ~(uintptr_t)x); +} + +void * +PORT_ZAllocAlignedOffset(size_t size, size_t alignment, size_t offset) +{ + PORT_Assert(offset < size); + if (offset > size) { + return NULL; + } + + void *mem = NULL; + void *v = PORT_ZAllocAligned(size, alignment, &mem); + if (!v) { + return NULL; + } + + PORT_Assert(mem); + *((void **)((uintptr_t)v + offset)) = mem; + return v; +} + void PORT_Free(void *ptr) { @@ -733,3 +780,18 @@ NSS_SecureMemcmp(const void *ia, const void *ib, size_t n) return r; } + +/* + * Perform a constant-time check if a memory region is all 0. The return value + * is 0 if the memory region is all zero. + */ +unsigned int +NSS_SecureMemcmpZero(const void *mem, size_t n) +{ + PRUint8 zero = 0; + int i; + for (i = 0; i < n; ++i) { + zero |= *(PRUint8 *)((uintptr_t)mem + i); + } + return zero; +} diff --git a/security/nss/lib/util/secport.h b/security/nss/lib/util/secport.h index fb9ff4ebb569..f1665a2f5ebb 100644 --- a/security/nss/lib/util/secport.h +++ b/security/nss/lib/util/secport.h @@ -45,6 +45,7 @@ #include #include #include +#include #include "prtypes.h" #include "prlog.h" /* for PR_ASSERT */ #include "plarena.h" @@ -88,6 +89,9 @@ SEC_BEGIN_PROTOS extern void *PORT_Alloc(size_t len); extern void *PORT_Realloc(void *old, size_t len); extern void *PORT_ZAlloc(size_t len); +extern void *PORT_ZAllocAligned(size_t bytes, size_t alignment, void **mem); +extern void *PORT_ZAllocAlignedOffset(size_t bytes, size_t alignment, + size_t offset); extern void PORT_Free(void *ptr); extern void PORT_ZFree(void *ptr, size_t len); extern char *PORT_Strdup(const char *s); @@ -131,6 +135,8 @@ SEC_END_PROTOS #define PORT_CheckSuccess(f) (f) #endif #define PORT_ZNew(type) (type *)PORT_ZAlloc(sizeof(type)) +#define PORT_ZNewAligned(type, alignment, mem) \ + (type *)PORT_ZAllocAlignedOffset(sizeof(type), alignment, offsetof(type, mem)) #define PORT_New(type) (type *)PORT_Alloc(sizeof(type)) #define PORT_ArenaNew(poolp, type) \ (type *)PORT_ArenaAlloc(poolp, sizeof(type)) @@ -246,6 +252,7 @@ sec_port_iso88591_utf8_conversion_function( extern int NSS_PutEnv(const char *envVarName, const char *envValue); extern int NSS_SecureMemcmp(const void *a, const void *b, size_t n); +extern unsigned int NSS_SecureMemcmpZero(const void *mem, size_t n); /* * Load a shared library called "newShLibName" in the same directory as diff --git a/security/nss/lib/util/utilrename.h b/security/nss/lib/util/utilrename.h index 1aea3d284e83..19ddba666eaa 100644 --- a/security/nss/lib/util/utilrename.h +++ b/security/nss/lib/util/utilrename.h @@ -70,6 +70,8 @@ #define PORT_UCS2_ASCIIConversion PORT_UCS2_ASCIIConversion_Util #define PORT_UCS2_UTF8Conversion PORT_UCS2_UTF8Conversion_Util #define PORT_ZAlloc PORT_ZAlloc_Util +#define PORT_ZAllocAligned PORT_ZAllocAligned_Util +#define PORT_ZAllocAlignedOffset PORT_ZAllocAlignedOffset_Util #define PORT_ZFree PORT_ZFree_Util #define SEC_ASN1Decode SEC_ASN1Decode_Util #define SEC_ASN1DecodeInteger SEC_ASN1DecodeInteger_Util