Bug 1345368 - land NSS 236a06d9c3c4, r=me

--HG--
extra : rebase_source : b097dd39571750acd76656e275e6899c95d52269
This commit is contained in:
Franziskus Kiefer 2017-05-05 16:07:08 +02:00
parent dddf3fc25d
commit 66955a7251
39 changed files with 1035 additions and 439 deletions

View File

@ -1 +1 @@
fa15eb3ce158
236a06d9c3c4

View File

@ -26,6 +26,7 @@ apt_packages+=('zlib1g-dev')
apt_packages+=('ninja-build')
apt_packages+=('gyp')
apt_packages+=('mercurial')
apt_packages+=('locales')
# Install packages.
apt-get install -y --no-install-recommends ${apt_packages[@]}

View File

@ -12,6 +12,7 @@ apt_packages=()
apt_packages+=('build-essential')
apt_packages+=('ca-certificates')
apt_packages+=('curl')
apt_packages+=('locales')
apt_packages+=('python-dev')
apt_packages+=('python-pip')
apt_packages+=('python-setuptools')

View File

@ -12,6 +12,7 @@ apt-get install -y --no-install-recommends apt-utils
apt_packages=()
apt_packages+=('ca-certificates')
apt_packages+=('curl')
apt_packages+=('locales')
apt_packages+=('xz-utils')
# Latest Mercurial.

View File

@ -7,7 +7,7 @@ export DEBIAN_FRONTEND=noninteractive
apt-get -y update && apt-get -y upgrade
# Need those to install newer packages below.
apt-get install -y --no-install-recommends apt-utils curl ca-certificates
apt-get install -y --no-install-recommends apt-utils curl ca-certificates locales
# Latest Mercurial.
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 41BD8711B1F0EC2B0D85B91CF59CE3A8323293EE

View File

@ -17,6 +17,7 @@ apt_packages+=('git')
apt_packages+=('gyp')
apt_packages+=('libssl-dev')
apt_packages+=('libxml2-utils')
apt_packages+=('locales')
apt_packages+=('ninja-build')
apt_packages+=('pkg-config')
apt_packages+=('zlib1g-dev')
@ -37,7 +38,6 @@ git -C clang-tmp/clang checkout HEAD scripts/update.py
clang-tmp/clang/scripts/update.py
rm -fr clang-tmp
# Generate locales.
locale-gen en_US.UTF-8
dpkg-reconfigure locales

View File

@ -17,6 +17,7 @@ apt_packages+=('npm')
apt_packages+=('git')
apt_packages+=('golang-1.6')
apt_packages+=('libxml2-utils')
apt_packages+=('locales')
apt_packages+=('ninja-build')
apt_packages+=('pkg-config')
apt_packages+=('zlib1g-dev')

View File

@ -34,14 +34,8 @@ queue.filter(task => {
return false;
}
// Remove extra builds w/o libpkix for non-linux64-debug.
if (task.symbol == "noLibpkix" &&
(task.platform != "linux64" || task.collection != "debug")) {
return false;
}
// Make modular builds only on Linux x64.
if (task.symbol == "modular" && task.platform != "linux64") {
// Make modular builds only on Linux make.
if (task.symbol == "modular" && task.collection != "make") {
return false;
}
}
@ -58,9 +52,29 @@ queue.filter(task => {
}
}
// GYP builds with -Ddisable_libpkix=1 by default.
if ((task.collection == "gyp" || task.collection == "asan"
|| task.platform == "aarch64") && task.tests == "chains") {
// Only old make builds have -Ddisable_libpkix=0 and can run chain tests.
if (task.tests == "chains" && task.collection != "make" &&
task.platform != "windows2012-64") {
return false;
}
if (task.group == "Test") {
// Don't run test builds on old make platforms
if (task.collection == "make") {
return false;
}
// Disable mpi tests for now on 32-bit builds (bug 1362392)
if (task.platform == "linux32") {
return false;
}
}
// Don't run additional hardware tests on ARM (we don't have anything there).
if (task.group == "Cipher" && task.platform == "aarch64" && task.env &&
(task.env.NSS_DISABLE_PCLMUL == "1" || task.env.NSS_DISABLE_HW_AES == "1"
|| task.env.NSS_DISABLE_AVX == "1")) {
return false;
}
@ -87,47 +101,51 @@ queue.map(task => {
export default async function main() {
await scheduleLinux("Linux 32 (opt)", {
env: {BUILD_OPT: "1"},
platform: "linux32",
image: LINUX_IMAGE
});
}, "-m32 --opt");
await scheduleLinux("Linux 32 (debug)", {
platform: "linux32",
collection: "debug",
image: LINUX_IMAGE
});
}, "-m32");
await scheduleLinux("Linux 64 (opt)", {
env: {USE_64: "1", BUILD_OPT: "1"},
platform: "linux64",
image: LINUX_IMAGE
});
}, "--opt");
await scheduleLinux("Linux 64 (debug)", {
env: {USE_64: "1"},
platform: "linux64",
collection: "debug",
image: LINUX_IMAGE
});
await scheduleLinux("Linux 64 (debug, gyp)", {
command: [
"/bin/bash",
"-c",
"bin/checkout.sh && nss/automation/taskcluster/scripts/build_gyp.sh"
],
await scheduleLinux("Linux 64 (debug, make)", {
env: {USE_64: "1"},
platform: "linux64",
collection: "gyp",
image: LINUX_IMAGE
image: LINUX_IMAGE,
collection: "make",
command: [
"/bin/bash",
"-c",
"bin/checkout.sh && nss/automation/taskcluster/scripts/build.sh"
],
});
await scheduleLinux("Linux 64 (GYP, ASan, debug)", {
await scheduleLinux("Linux 32 (debug, make)", {
platform: "linux32",
image: LINUX_IMAGE,
collection: "make",
command: [
"/bin/bash",
"-c",
"bin/checkout.sh && nss/automation/taskcluster/scripts/build_gyp.sh -g -v --ubsan --asan"
"/bin/bash",
"-c",
"bin/checkout.sh && nss/automation/taskcluster/scripts/build.sh"
],
});
await scheduleLinux("Linux 64 (ASan, debug)", {
env: {
UBSAN_OPTIONS: "print_stacktrace=1",
NSS_DISABLE_ARENA_FREE_LIST: "1",
@ -139,7 +157,7 @@ export default async function main() {
collection: "asan",
image: LINUX_IMAGE,
features: ["allowPtrace"],
});
}, "--ubsan --asan");
await scheduleWindows("Windows 2012 64 (opt)", {
env: {BUILD_OPT: "1"}
@ -151,8 +169,6 @@ export default async function main() {
await scheduleFuzzing();
await scheduleTestBuilds();
await scheduleTools();
let aarch64_base = {
@ -188,13 +204,13 @@ export default async function main() {
/*****************************************************************************/
async function scheduleLinux(name, base) {
async function scheduleLinux(name, base, args = "") {
// Build base definition.
let build_base = merge({
command: [
"/bin/bash",
"-c",
"bin/checkout.sh && nss/automation/taskcluster/scripts/build.sh"
"bin/checkout.sh && nss/automation/taskcluster/scripts/build_gyp.sh " + args
],
artifacts: {
public: {
@ -260,18 +276,19 @@ async function scheduleLinux(name, base) {
symbol: "gcc-6.1"
}));
queue.scheduleTask(merge(extra_base, {
name: `${name} w/ NSS_DISABLE_LIBPKIX=1`,
env: {NSS_DISABLE_LIBPKIX: "1"},
symbol: "noLibpkix"
}));
queue.scheduleTask(merge(extra_base, {
name: `${name} w/ modular builds`,
env: {NSS_BUILD_MODULAR: "1"},
command: [
"/bin/bash",
"-c",
"bin/checkout.sh && nss/automation/taskcluster/scripts/build.sh",
],
symbol: "modular"
}));
await scheduleTestBuilds(merge(base, {group: "Test"}), args);
return queue.submit();
}
@ -400,21 +417,14 @@ async function scheduleFuzzing() {
/*****************************************************************************/
async function scheduleTestBuilds() {
let base = {
platform: "linux64",
collection: "gyp",
group: "Test",
image: LINUX_IMAGE
};
async function scheduleTestBuilds(base, args = "") {
// Build base definition.
let build = merge({
command: [
"/bin/bash",
"-c",
"bin/checkout.sh && " +
"nss/automation/taskcluster/scripts/build_gyp.sh -g -v --test --ct-verif"
"nss/automation/taskcluster/scripts/build_gyp.sh -g -v --test --ct-verif " + args
],
artifacts: {
public: {
@ -425,7 +435,7 @@ async function scheduleTestBuilds() {
},
kind: "build",
symbol: "B",
name: "Linux 64 (debug, gyp, test)"
name: "Linux 64 (debug, test)"
}, base);
// The task that builds NSPR+NSS.
@ -529,7 +539,19 @@ function scheduleTests(task_build, task_cert, test_base) {
name: "Chains tests", symbol: "Chains", tests: "chains"
}));
queue.scheduleTask(merge(no_cert_base, {
name: "Cipher tests", symbol: "Cipher", tests: "cipher"
name: "Cipher tests", symbol: "Default", tests: "cipher", group: "Cipher"
}));
queue.scheduleTask(merge(no_cert_base, {
name: "Cipher tests", symbol: "NoAESNI", tests: "cipher",
env: {NSS_DISABLE_HW_AES: "1"}, group: "Cipher"
}));
queue.scheduleTask(merge(no_cert_base, {
name: "Cipher tests", symbol: "NoPCLMUL", tests: "cipher",
env: {NSS_DISABLE_PCLMUL: "1"}, group: "Cipher"
}));
queue.scheduleTask(merge(no_cert_base, {
name: "Cipher tests", symbol: "NoAVX", tests: "cipher",
env: {NSS_DISABLE_AVX: "1"}, group: "Cipher"
}));
queue.scheduleTask(merge(no_cert_base, {
name: "EC tests", symbol: "EC", tests: "ec"

View File

@ -23,7 +23,7 @@ function parseOptions(opts) {
// Parse platforms.
let allPlatforms = ["linux", "linux64", "linux64-asan", "win64",
"linux64-gyp", "linux64-fuzz", "aarch64"];
"linux64-make", "linux-make", "linux64-fuzz", "aarch64"];
let platforms = intersect(opts.platform.split(/\s*,\s*/), allPlatforms);
// If the given value is nonsense or "none" default to all platforms.
@ -82,11 +82,10 @@ function filter(opts) {
// Filter unit tests.
if (task.tests) {
let found = opts.unittests.some(test => {
// TODO: think of something more intelligent here.
if (task.symbol.toLowerCase().startsWith("mpi") && test == "mpi") {
if (task.group && task.group.toLowerCase() == "ssl" && test == "ssl") {
return true;
}
return (task.group || task.symbol).toLowerCase().startsWith(test);
return task.symbol.toLowerCase().startsWith(test);
});
if (!found) {
@ -107,7 +106,8 @@ function filter(opts) {
"linux": "linux32",
"linux64-asan": "linux64",
"linux64-fuzz": "linux64",
"linux64-gyp": "linux64",
"linux64-make": "linux64",
"linux-make": "linux32",
"win64": "windows2012-64"
};
@ -117,8 +117,8 @@ function filter(opts) {
// Additional checks.
if (platform == "linux64-asan") {
keep &= coll("asan");
} else if (platform == "linux64-gyp") {
keep &= coll("gyp");
} else if (platform == "linux64-make" || platform == "linux-make") {
keep &= coll("make");
} else if (platform == "linux64-fuzz") {
keep &= coll("fuzz");
} else {
@ -133,7 +133,7 @@ function filter(opts) {
}
// Finally, filter by build type.
let isDebug = coll("debug") || coll("asan") || coll("gyp") ||
let isDebug = coll("debug") || coll("asan") || coll("make") ||
coll("fuzz");
return (isDebug && opts.builds.includes("d")) ||
(!isDebug && opts.builds.includes("o"));

View File

@ -49,6 +49,7 @@ fuzz=0
fuzz_tls=0
fuzz_oss=0
no_local_nspr=0
armhf=0
gyp_params=(--depth="$cwd" --generator-output=".")
nspr_params=()
@ -58,6 +59,8 @@ ninja_params=()
arch=$(python "$cwd"/coreconf/detect_host_arch.py)
if [ "$arch" = "x64" -o "$arch" = "aarch64" ]; then
build_64=1
elif [ "$arch" = "arm" ]; then
armhf=1
fi
# parse command line arguments
@ -101,7 +104,7 @@ else
fi
if [ "$build_64" = 1 ]; then
nspr_params+=(--enable-64bit)
else
elif [ ! "$armhf" = 1 ]; then
gyp_params+=(-Dtarget_arch=ia32)
fi
if [ "$fuzz" = 1 ]; then

View File

@ -148,7 +148,7 @@ DSO_LDOPTS = -shared $(ARCHFLAG) -Wl,--gc-sections
# against the libsanitizer runtime built into the main executable.
ZDEFS_FLAG = -Wl,-z,defs
DSO_LDOPTS += $(if $(findstring 2.11.90.0.8,$(shell ld -v)),,$(ZDEFS_FLAG))
LDFLAGS += $(ARCHFLAG)
LDFLAGS += $(ARCHFLAG) -z noexecstack
# On Maemo, we need to use the -rpath-link flag for even the standard system
# library directories.

View File

@ -141,6 +141,52 @@
'debug_optimization_level%': '1',
},
}],
[ 'target_arch=="ia32" or target_arch=="x64"', {
'defines': [
'NSS_X86_OR_X64',
],
# For Windows.
'msvs_settings': {
'VCCLCompilerTool': {
'PreprocessorDefinitions': [
'NSS_X86_OR_X64',
],
},
},
}],
[ 'target_arch=="ia32"', {
'defines': [
'NSS_X86',
],
# For Windows.
'msvs_settings': {
'VCCLCompilerTool': {
'PreprocessorDefinitions': [
'NSS_X86',
],
},
},
}],
[ 'target_arch=="arm64" or target_arch=="aarch64"', {
'defines': [
'NSS_USE_64',
],
}],
[ 'target_arch=="x64"', {
'defines': [
'NSS_X64',
'NSS_USE_64',
],
# For Windows.
'msvs_settings': {
'VCCLCompilerTool': {
'PreprocessorDefinitions': [
'NSS_X64',
'NSS_USE_64',
],
},
},
}],
],
'target_conditions': [
# If we want to properly export a static library, and copy it to lib,
@ -315,6 +361,9 @@
'cflags_cc': [
'-std=c++0x',
],
'ldflags': [
'-z', 'noexecstack',
],
'conditions': [
[ 'target_arch=="ia32"', {
'cflags': ['-m32'],

View File

@ -10,4 +10,3 @@
*/
#error "Do not include this header file."

View File

@ -46,7 +46,7 @@ class DataBuffer {
len_ = len;
}
void Truncate(size_t len) { len_ = std::min(len_, len); }
void Truncate(size_t len) { len_ = (std::min)(len_, len); }
void Assign(const DataBuffer& other) { Assign(other.data(), other.len()); }
@ -126,14 +126,14 @@ class DataBuffer {
size_t old_len = len_;
// The amount of stuff remaining from the tail of the old.
size_t tail_len = old_len - std::min(old_len, index + remove);
size_t tail_len = old_len - (std::min)(old_len, index + remove);
// The new length: the head of the old, the new, and the tail of the old.
len_ = index + ins_len + tail_len;
data_ = new uint8_t[len_ ? len_ : 1];
// The head of the old.
if (old_value) {
Write(0, old_value, std::min(old_len, index));
Write(0, old_value, (std::min)(old_len, index));
}
// Maybe a gap.
if (old_value && index > old_len) {

View File

@ -17,6 +17,8 @@
#endif
#include "databuffer.h"
#include "sslt.h"
namespace nss_test {
const uint8_t kTlsChangeCipherSpecType = 20;
@ -133,6 +135,10 @@ class TlsParser {
size_t offset_;
};
inline std::ostream& operator<<(std::ostream& os, SSLProtocolVariant v) {
return os << ((v == ssl_variant_stream) ? "TLS" : "DTLS");
}
} // namespace nss_test
#endif

View File

@ -1,46 +1,6 @@
#!/bin/sh
LIBFUZZER_REVISION=8837e6cbbc842ab7524b06a2f7360c36add316b3
d=$(dirname $0)
$d/git-copy.sh https://chromium.googlesource.com/chromium/llvm-project/llvm/lib/Fuzzer b96a41ac6bbc3824fc7c7977662bebacac8f0983 $d/../libFuzzer
# [https://llvm.org/bugs/show_bug.cgi?id=31318]
# This prevents a known buffer overrun that won't be fixed as the affected code
# will go away in the near future. Until that is we have to patch it as we seem
# to constantly run into it.
cat <<EOF | patch -p0 -d $d/..
diff --git libFuzzer/FuzzerLoop.cpp libFuzzer/FuzzerLoop.cpp
--- libFuzzer/FuzzerLoop.cpp
+++ libFuzzer/FuzzerLoop.cpp
@@ -476,6 +476,9 @@
uint8_t dummy;
ExecuteCallback(&dummy, 0);
+ // Number of counters might have changed.
+ PrepareCounters(&MaxCoverage);
+
for (const auto &U : *InitialCorpus) {
if (size_t NumFeatures = RunOne(U)) {
CheckExitOnSrcPosOrItem();
EOF
# Latest Libfuzzer uses __sanitizer_dump_coverage(), a symbol to be introduced
# with LLVM 4.0. To keep our code working with LLVM 3.x to simplify development
# of fuzzers we'll just provide it ourselves.
cat <<EOF | patch -p0 -d $d/..
diff --git libFuzzer/FuzzerTracePC.cpp libFuzzer/FuzzerTracePC.cpp
--- libFuzzer/FuzzerTracePC.cpp
+++ libFuzzer/FuzzerTracePC.cpp
@@ -33,6 +33,12 @@
ATTRIBUTE_INTERFACE
uintptr_t __sancov_trace_pc_pcs[fuzzer::TracePC::kNumPCs];
+#if defined(__clang_major__) && (__clang_major__ == 3)
+void __sanitizer_dump_coverage(const uintptr_t *pcs, uintptr_t len) {
+ // SanCov in LLVM 4.x will provide this symbol. Make 3.x work.
+}
+#endif
+
namespace fuzzer {
TracePC TPC;
EOF
$d/git-copy.sh https://chromium.googlesource.com/chromium/llvm-project/llvm/lib/Fuzzer $LIBFUZZER_REVISION $d/../libFuzzer

View File

@ -265,6 +265,12 @@ class TestAgent {
rv = SSL_VersionRangeSet(ssl_fd_, &vrange);
if (rv != SECSuccess) return false;
SSLVersionRange verify_vrange;
rv = SSL_VersionRangeGet(ssl_fd_, &verify_vrange);
if (rv != SECSuccess) return false;
if (vrange.min != verify_vrange.min || vrange.max != verify_vrange.max)
return false;
rv = SSL_OptionSet(ssl_fd_, SSL_NO_CACHE, false);
if (rv != SECSuccess) return false;

View File

@ -39,6 +39,7 @@ CPPSRCS = \
ssl_staticrsa_unittest.cc \
ssl_v2_client_hello_unittest.cc \
ssl_version_unittest.cc \
ssl_versionpolicy_unittest.cc \
test_io.cc \
tls_agent.cc \
tls_connect.cc \

View File

@ -70,11 +70,7 @@ TEST_P(TlsConnectGenericPre13, DamageServerSignature) {
server_->SetTlsRecordFilter(filter);
ExpectAlert(client_, kTlsAlertDecryptError);
ConnectExpectFail();
// TODO(ttaubert@mozilla.com): This is the wrong error code in
// 1.1 and below. Bug 1354488.
client_->CheckErrorCode(version_ >= SSL_LIBRARY_VERSION_TLS_1_2
? SEC_ERROR_BAD_SIGNATURE
: SEC_ERROR_PKCS11_DEVICE_ERROR);
client_->CheckErrorCode(SEC_ERROR_BAD_SIGNATURE);
server_->CheckErrorCode(SSL_ERROR_DECRYPT_ERROR_ALERT);
}
@ -117,11 +113,7 @@ TEST_P(TlsConnectGeneric, DamageClientSignature) {
? TlsAgent::STATE_CONNECTED
: TlsAgent::STATE_CONNECTING,
client_->state());
// TODO(ttaubert@mozilla.com): This is the wrong error code in
// 1.1 and below. Bug 1354488.
server_->CheckErrorCode(version_ >= SSL_LIBRARY_VERSION_TLS_1_2
? SEC_ERROR_BAD_SIGNATURE
: SEC_ERROR_PKCS11_DEVICE_ERROR);
server_->CheckErrorCode(SEC_ERROR_BAD_SIGNATURE);
}
} // namespace nspr_test

View File

@ -36,6 +36,7 @@
'ssl_staticrsa_unittest.cc',
'ssl_v2_client_hello_unittest.cc',
'ssl_version_unittest.cc',
'ssl_versionpolicy_unittest.cc',
'test_io.cc',
'tls_agent.cc',
'tls_connect.cc',

View File

@ -0,0 +1,404 @@
/* -*- 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 "nss.h"
#include "secerr.h"
#include "ssl.h"
#include "ssl3prot.h"
#include "sslerr.h"
#include "sslproto.h"
#include "gtest_utils.h"
#include "scoped_ptrs.h"
#include "tls_connect.h"
#include "tls_filter.h"
#include "tls_parser.h"
#include <iostream>
namespace nss_test {
std::string GetSSLVersionString(uint16_t v) {
switch (v) {
case SSL_LIBRARY_VERSION_3_0:
return "ssl3";
case SSL_LIBRARY_VERSION_TLS_1_0:
return "tls1.0";
case SSL_LIBRARY_VERSION_TLS_1_1:
return "tls1.1";
case SSL_LIBRARY_VERSION_TLS_1_2:
return "tls1.2";
case SSL_LIBRARY_VERSION_TLS_1_3:
return "tls1.3";
case SSL_LIBRARY_VERSION_NONE:
return "NONE";
}
if (v < SSL_LIBRARY_VERSION_3_0) {
return "undefined-too-low";
}
return "undefined-too-high";
}
inline std::ostream& operator<<(std::ostream& stream,
const SSLVersionRange& vr) {
return stream << GetSSLVersionString(vr.min) << ","
<< GetSSLVersionString(vr.max);
}
class VersionRangeWithLabel {
public:
VersionRangeWithLabel(const std::string& label, const SSLVersionRange& vr)
: label_(label), vr_(vr) {}
VersionRangeWithLabel(const std::string& label, uint16_t min, uint16_t max)
: label_(label) {
vr_.min = min;
vr_.max = max;
}
VersionRangeWithLabel(const std::string& label) : label_(label) {
vr_.min = vr_.max = SSL_LIBRARY_VERSION_NONE;
}
void WriteStream(std::ostream& stream) const {
stream << " " << label_ << ": " << vr_;
}
uint16_t min() const { return vr_.min; }
uint16_t max() const { return vr_.max; }
SSLVersionRange range() const { return vr_; }
private:
std::string label_;
SSLVersionRange vr_;
};
inline std::ostream& operator<<(std::ostream& stream,
const VersionRangeWithLabel& vrwl) {
vrwl.WriteStream(stream);
return stream;
}
typedef std::tuple<SSLProtocolVariant, // variant
uint16_t, // policy min
uint16_t, // policy max
uint16_t, // input min
uint16_t> // input max
PolicyVersionRangeInput;
class TestPolicyVersionRange
: public TlsConnectTestBase,
public ::testing::WithParamInterface<PolicyVersionRangeInput> {
public:
TestPolicyVersionRange()
: TlsConnectTestBase(((static_cast<SSLProtocolVariant>(
std::get<0>(GetParam())) == ssl_variant_stream)
? STREAM
: DGRAM),
0),
variant_(static_cast<SSLProtocolVariant>(std::get<0>(GetParam()))),
policy_("policy", std::get<1>(GetParam()), std::get<2>(GetParam())),
input_("input", std::get<3>(GetParam()), std::get<4>(GetParam())),
library_("supported-by-library",
((variant_ == ssl_variant_stream)
? SSL_LIBRARY_VERSION_MIN_SUPPORTED_STREAM
: SSL_LIBRARY_VERSION_MIN_SUPPORTED_DATAGRAM),
SSL_LIBRARY_VERSION_MAX_SUPPORTED) {
TlsConnectTestBase::SkipVersionChecks();
}
void SetPolicy(const SSLVersionRange& policy) {
NSS_SetAlgorithmPolicy(SEC_OID_APPLY_SSL_POLICY, NSS_USE_POLICY_IN_SSL, 0);
SECStatus rv;
rv = NSS_OptionSet(NSS_TLS_VERSION_MIN_POLICY, policy.min);
ASSERT_EQ(SECSuccess, rv);
rv = NSS_OptionSet(NSS_TLS_VERSION_MAX_POLICY, policy.max);
ASSERT_EQ(SECSuccess, rv);
rv = NSS_OptionSet(NSS_DTLS_VERSION_MIN_POLICY, policy.min);
ASSERT_EQ(SECSuccess, rv);
rv = NSS_OptionSet(NSS_DTLS_VERSION_MAX_POLICY, policy.max);
ASSERT_EQ(SECSuccess, rv);
}
void CreateDummySocket(std::shared_ptr<DummyPrSocket>* dummy_socket,
ScopedPRFileDesc* ssl_fd) {
(*dummy_socket)
.reset(new DummyPrSocket(
"dummy", (variant_ == ssl_variant_stream) ? STREAM : DGRAM));
*ssl_fd = (*dummy_socket)->CreateFD();
if (variant_ == ssl_variant_stream) {
SSL_ImportFD(nullptr, ssl_fd->get());
} else {
DTLS_ImportFD(nullptr, ssl_fd->get());
}
}
bool GetOverlap(const SSLVersionRange& r1, const SSLVersionRange& r2,
SSLVersionRange* overlap) {
if (r1.min == SSL_LIBRARY_VERSION_NONE ||
r1.max == SSL_LIBRARY_VERSION_NONE ||
r2.min == SSL_LIBRARY_VERSION_NONE ||
r2.max == SSL_LIBRARY_VERSION_NONE) {
return false;
}
SSLVersionRange temp;
temp.min = PR_MAX(r1.min, r2.min);
temp.max = PR_MIN(r1.max, r2.max);
if (temp.min > temp.max) {
return false;
}
*overlap = temp;
return true;
}
bool IsValidInputForVersionRangeSet(SSLVersionRange* expectedEffectiveRange) {
if (input_.min() <= SSL_LIBRARY_VERSION_3_0 &&
input_.max() >= SSL_LIBRARY_VERSION_TLS_1_3) {
// This is always invalid input, independent of policy
return false;
}
if (input_.min() < library_.min() || input_.max() > library_.max() ||
input_.min() > input_.max()) {
// Asking for unsupported ranges is invalid input for VersionRangeSet
// APIs, regardless of overlap.
return false;
}
SSLVersionRange overlap_with_library;
if (!GetOverlap(input_.range(), library_.range(), &overlap_with_library)) {
return false;
}
SSLVersionRange overlap_with_library_and_policy;
if (!GetOverlap(overlap_with_library, policy_.range(),
&overlap_with_library_and_policy)) {
return false;
}
RemoveConflictingVersions(variant_, &overlap_with_library_and_policy);
*expectedEffectiveRange = overlap_with_library_and_policy;
return true;
}
void RemoveConflictingVersions(SSLProtocolVariant variant,
SSLVersionRange* r) {
ASSERT_TRUE(r != nullptr);
if (r->max >= SSL_LIBRARY_VERSION_TLS_1_3 &&
r->min < SSL_LIBRARY_VERSION_TLS_1_0) {
r->min = SSL_LIBRARY_VERSION_TLS_1_0;
}
}
void SetUp() {
SetPolicy(policy_.range());
TlsConnectTestBase::SetUp();
}
void TearDown() {
TlsConnectTestBase::TearDown();
saved_version_policy_.RestoreOriginalPolicy();
}
protected:
class VersionPolicy {
public:
VersionPolicy() { SaveOriginalPolicy(); }
void RestoreOriginalPolicy() {
SECStatus rv;
rv = NSS_OptionSet(NSS_TLS_VERSION_MIN_POLICY, saved_min_tls_);
ASSERT_EQ(SECSuccess, rv);
rv = NSS_OptionSet(NSS_TLS_VERSION_MAX_POLICY, saved_max_tls_);
ASSERT_EQ(SECSuccess, rv);
rv = NSS_OptionSet(NSS_DTLS_VERSION_MIN_POLICY, saved_min_dtls_);
ASSERT_EQ(SECSuccess, rv);
rv = NSS_OptionSet(NSS_DTLS_VERSION_MAX_POLICY, saved_max_dtls_);
ASSERT_EQ(SECSuccess, rv);
// If it wasn't set initially, clear the bit that we set.
if (!(saved_algorithm_policy_ & NSS_USE_POLICY_IN_SSL)) {
rv = NSS_SetAlgorithmPolicy(SEC_OID_APPLY_SSL_POLICY, 0,
NSS_USE_POLICY_IN_SSL);
ASSERT_EQ(SECSuccess, rv);
}
}
private:
void SaveOriginalPolicy() {
SECStatus rv;
rv = NSS_OptionGet(NSS_TLS_VERSION_MIN_POLICY, &saved_min_tls_);
ASSERT_EQ(SECSuccess, rv);
rv = NSS_OptionGet(NSS_TLS_VERSION_MAX_POLICY, &saved_max_tls_);
ASSERT_EQ(SECSuccess, rv);
rv = NSS_OptionGet(NSS_DTLS_VERSION_MIN_POLICY, &saved_min_dtls_);
ASSERT_EQ(SECSuccess, rv);
rv = NSS_OptionGet(NSS_DTLS_VERSION_MAX_POLICY, &saved_max_dtls_);
ASSERT_EQ(SECSuccess, rv);
rv = NSS_GetAlgorithmPolicy(SEC_OID_APPLY_SSL_POLICY,
&saved_algorithm_policy_);
ASSERT_EQ(SECSuccess, rv);
}
int32_t saved_min_tls_;
int32_t saved_max_tls_;
int32_t saved_min_dtls_;
int32_t saved_max_dtls_;
uint32_t saved_algorithm_policy_;
};
VersionPolicy saved_version_policy_;
SSLProtocolVariant variant_;
const VersionRangeWithLabel policy_;
const VersionRangeWithLabel input_;
const VersionRangeWithLabel library_;
};
static const uint16_t kExpandedVersionsArr[] = {
/* clang-format off */
SSL_LIBRARY_VERSION_3_0 - 1,
SSL_LIBRARY_VERSION_3_0,
SSL_LIBRARY_VERSION_TLS_1_0,
SSL_LIBRARY_VERSION_TLS_1_1,
SSL_LIBRARY_VERSION_TLS_1_2,
#ifndef NSS_DISABLE_TLS_1_3
SSL_LIBRARY_VERSION_TLS_1_3,
#endif
SSL_LIBRARY_VERSION_MAX_SUPPORTED + 1
/* clang-format on */
};
static ::testing::internal::ParamGenerator<uint16_t> kExpandedVersions =
::testing::ValuesIn(kExpandedVersionsArr);
static const SSLProtocolVariant kVariantsArr[] = {ssl_variant_stream,
ssl_variant_datagram};
static ::testing::internal::ParamGenerator<SSLProtocolVariant> kVariants =
::testing::ValuesIn(kVariantsArr);
TEST_P(TestPolicyVersionRange, TestAllTLSVersionsAndPolicyCombinations) {
ASSERT_TRUE(variant_ == ssl_variant_stream ||
variant_ == ssl_variant_datagram)
<< "testing unsupported ssl variant";
std::cerr << "testing: " << variant_ << policy_ << input_ << library_
<< std::endl;
SSLVersionRange supported_range;
SECStatus rv = SSL_VersionRangeGetSupported(variant_, &supported_range);
VersionRangeWithLabel supported("SSL_VersionRangeGetSupported",
supported_range);
std::cerr << supported << std::endl;
std::shared_ptr<DummyPrSocket> dummy_socket;
ScopedPRFileDesc ssl_fd;
CreateDummySocket(&dummy_socket, &ssl_fd);
SECStatus rv_socket;
SSLVersionRange overlap_policy_and_lib;
if (!GetOverlap(policy_.range(), library_.range(), &overlap_policy_and_lib)) {
EXPECT_EQ(SECFailure, rv)
<< "expected SSL_VersionRangeGetSupported to fail with invalid policy";
SSLVersionRange enabled_range;
rv = SSL_VersionRangeGetDefault(variant_, &enabled_range);
EXPECT_EQ(SECFailure, rv)
<< "expected SSL_VersionRangeGetDefault to fail with invalid policy";
SSLVersionRange enabled_range_on_socket;
rv_socket = SSL_VersionRangeGet(ssl_fd.get(), &enabled_range_on_socket);
EXPECT_EQ(SECFailure, rv_socket)
<< "expected SSL_VersionRangeGet to fail with invalid policy";
ConnectExpectFail();
return;
}
EXPECT_EQ(SECSuccess, rv)
<< "expected SSL_VersionRangeGetSupported to succeed with valid policy";
EXPECT_TRUE(supported_range.min != SSL_LIBRARY_VERSION_NONE &&
supported_range.max != SSL_LIBRARY_VERSION_NONE)
<< "expected SSL_VersionRangeGetSupported to return real values with "
"valid policy";
RemoveConflictingVersions(variant_, &overlap_policy_and_lib);
VersionRangeWithLabel overlap_info("overlap", overlap_policy_and_lib);
EXPECT_TRUE(supported_range == overlap_policy_and_lib)
<< "expected range from GetSupported to be identical with calculated "
"overlap "
<< overlap_info;
// We don't know which versions are "enabled by default" by the library,
// therefore we don't know if there's overlap between the default
// and the policy, and therefore, we don't if TLS connections should
// be successful or fail in this combination.
// Therefore we don't test if we can connect, without having configured a
// version range explicitly.
// Now start testing with supplied input.
SSLVersionRange expected_effective_range;
bool is_valid_input =
IsValidInputForVersionRangeSet(&expected_effective_range);
SSLVersionRange temp_input = input_.range();
rv = SSL_VersionRangeSetDefault(variant_, &temp_input);
rv_socket = SSL_VersionRangeSet(ssl_fd.get(), &temp_input);
if (!is_valid_input) {
EXPECT_EQ(SECFailure, rv)
<< "expected failure return from SSL_VersionRangeSetDefault";
EXPECT_EQ(SECFailure, rv_socket)
<< "expected failure return from SSL_VersionRangeSet";
return;
}
EXPECT_EQ(SECSuccess, rv)
<< "expected successful return from SSL_VersionRangeSetDefault";
EXPECT_EQ(SECSuccess, rv_socket)
<< "expected successful return from SSL_VersionRangeSet";
SSLVersionRange effective;
SSLVersionRange effective_socket;
rv = SSL_VersionRangeGetDefault(variant_, &effective);
EXPECT_EQ(SECSuccess, rv)
<< "expected successful return from SSL_VersionRangeGetDefault";
rv_socket = SSL_VersionRangeGet(ssl_fd.get(), &effective_socket);
EXPECT_EQ(SECSuccess, rv_socket)
<< "expected successful return from SSL_VersionRangeGet";
VersionRangeWithLabel expected_info("expectation", expected_effective_range);
VersionRangeWithLabel effective_info("effectively-enabled", effective);
EXPECT_TRUE(expected_effective_range == effective)
<< "range returned by SSL_VersionRangeGetDefault doesn't match "
"expectation: "
<< expected_info << effective_info;
EXPECT_TRUE(expected_effective_range == effective_socket)
<< "range returned by SSL_VersionRangeGet doesn't match "
"expectation: "
<< expected_info << effective_info;
// Because we found overlap between policy and supported versions,
// and because we have used SetDefault to enable at least one version,
// it should be possible to execute an SSL/TLS connection.
Connect();
}
INSTANTIATE_TEST_CASE_P(TLSVersionRanges, TestPolicyVersionRange,
::testing::Combine(kVariants, kExpandedVersions,
kExpandedVersions, kExpandedVersions,
kExpandedVersions));
} // namespace nss_test

View File

@ -72,7 +72,8 @@ TlsAgent::TlsAgent(const std::string& name, Role role, Mode mode)
handshake_callback_(),
auth_certificate_callback_(),
sni_callback_(),
expect_short_headers_(false) {
expect_short_headers_(false),
skip_version_checks_(false) {
memset(&info_, 0, sizeof(info_));
memset(&csinfo_, 0, sizeof(csinfo_));
SECStatus rv = SSL_VersionRangeGetDefault(
@ -165,9 +166,12 @@ bool TlsAgent::EnsureTlsSetup(PRFileDesc* modelSocket) {
}
dummy_fd.release(); // Now subsumed by ssl_fd_.
SECStatus rv = SSL_VersionRangeSet(ssl_fd(), &vrange_);
EXPECT_EQ(SECSuccess, rv);
if (rv != SECSuccess) return false;
SECStatus rv;
if (!skip_version_checks_) {
rv = SSL_VersionRangeSet(ssl_fd(), &vrange_);
EXPECT_EQ(SECSuccess, rv);
if (rv != SECSuccess) return false;
}
if (role_ == SERVER) {
EXPECT_TRUE(ConfigServerCert(name_, true));
@ -435,6 +439,8 @@ void TlsAgent::ExpectReadWriteError() { expect_readwrite_error_ = true; }
void TlsAgent::ExpectShortHeaders() { expect_short_headers_ = true; }
void TlsAgent::SkipVersionChecks() { skip_version_checks_ = true; }
void TlsAgent::SetSignatureSchemes(const SSLSignatureScheme* schemes,
size_t count) {
EXPECT_TRUE(EnsureTlsSetup());

View File

@ -137,6 +137,7 @@ class TlsAgent : public PollTarget {
void EnableFalseStart();
void ExpectResumption();
void ExpectShortHeaders();
void SkipVersionChecks();
void SetSignatureSchemes(const SSLSignatureScheme* schemes, size_t count);
void EnableAlpn(const uint8_t* val, size_t len);
void CheckAlpn(SSLNextProtoState expected_state,
@ -388,6 +389,7 @@ class TlsAgent : public PollTarget {
AuthCertificateCallbackFunction auth_certificate_callback_;
SniCallbackFunction sni_callback_;
bool expect_short_headers_;
bool skip_version_checks_;
};
inline std::ostream& operator<<(std::ostream& stream,
@ -485,6 +487,10 @@ class TlsAgentDgramTestClient : public TlsAgentTestBase {
TlsAgentDgramTestClient() : TlsAgentTestBase(TlsAgent::CLIENT, DGRAM) {}
};
inline bool operator==(const SSLVersionRange& vr1, const SSLVersionRange& vr2) {
return vr1.min == vr2.min && vr1.max == vr2.max;
}
} // namespace nss_test
#endif

View File

@ -110,7 +110,8 @@ TlsConnectTestBase::TlsConnectTestBase(Mode mode, uint16_t version)
expected_resumption_mode_(RESUME_NONE),
session_ids_(),
expect_extended_master_secret_(false),
expect_early_data_accepted_(false) {
expect_early_data_accepted_(false),
skip_version_checks_(false) {
std::string v;
if (mode_ == DGRAM && version_ == SSL_LIBRARY_VERSION_TLS_1_1) {
v = "1.0";
@ -209,6 +210,10 @@ void TlsConnectTestBase::Reset(const std::string& server_name,
const std::string& client_name) {
client_.reset(new TlsAgent(client_name, TlsAgent::CLIENT, mode_));
server_.reset(new TlsAgent(server_name, TlsAgent::SERVER, mode_));
if (skip_version_checks_) {
client_->SkipVersionChecks();
server_->SkipVersionChecks();
}
Init();
}
@ -268,10 +273,12 @@ void TlsConnectTestBase::ConnectWithCipherSuite(uint16_t cipher_suite) {
}
void TlsConnectTestBase::CheckConnected() {
// Check the version is as expected
EXPECT_EQ(client_->version(), server_->version());
EXPECT_EQ(std::min(client_->max_version(), server_->max_version()),
client_->version());
if (!skip_version_checks_) {
// Check the version is as expected
EXPECT_EQ(std::min(client_->max_version(), server_->max_version()),
client_->version());
}
EXPECT_EQ(TlsAgent::STATE_CONNECTED, client_->state());
EXPECT_EQ(TlsAgent::STATE_CONNECTED, server_->state());
@ -510,6 +517,10 @@ void TlsConnectTestBase::EnsureModelSockets() {
new TlsAgent(TlsAgent::kClient, TlsAgent::CLIENT, mode_));
server_model_.reset(
new TlsAgent(TlsAgent::kServerRsa, TlsAgent::SERVER, mode_));
if (skip_version_checks_) {
client_model_->SkipVersionChecks();
server_model_->SkipVersionChecks();
}
}
}
@ -635,6 +646,12 @@ void TlsConnectTestBase::DisableECDHEServerKeyReuse() {
server_->DisableECDHEServerKeyReuse();
}
void TlsConnectTestBase::SkipVersionChecks() {
skip_version_checks_ = true;
client_->SkipVersionChecks();
server_->SkipVersionChecks();
}
TlsConnectGeneric::TlsConnectGeneric()
: TlsConnectTestBase(std::get<0>(GetParam()), std::get<1>(GetParam())) {}

View File

@ -111,6 +111,7 @@ class TlsConnectTestBase : public ::testing::Test {
void ExpectExtendedMasterSecret(bool expected);
void ExpectEarlyDataAccepted(bool expected);
void DisableECDHEServerKeyReuse();
void SkipVersionChecks();
protected:
Mode mode_;
@ -139,6 +140,7 @@ class TlsConnectTestBase : public ::testing::Test {
bool expect_extended_master_secret_;
bool expect_early_data_accepted_;
bool skip_version_checks_;
// Track groups and make sure that there are no duplicates.
class DuplicateGroupChecker {

View File

@ -68,11 +68,13 @@ TEST_F(B64EncodeDecodeTest, FakeEncDecTest) {
}
// These takes a while ...
TEST_F(B64EncodeDecodeTest, LongFakeDecTest1) {
TEST_F(B64EncodeDecodeTest, DISABLED_LongFakeDecTest1) {
EXPECT_TRUE(TestFakeDecode(0x66666666));
}
TEST_F(B64EncodeDecodeTest, LongFakeEncDecTest1) { TestFakeEncode(0x3fffffff); }
TEST_F(B64EncodeDecodeTest, LongFakeEncDecTest2) {
TEST_F(B64EncodeDecodeTest, DISABLED_LongFakeEncDecTest1) {
TestFakeEncode(0x3fffffff);
}
TEST_F(B64EncodeDecodeTest, DISABLED_LongFakeEncDecTest2) {
EXPECT_FALSE(TestFakeEncode(0x40000000));
}

View File

@ -58,4 +58,11 @@ SEC_END_PROTOS
#undef HAVE_NO_SANITIZE_ATTR
SECStatus RSA_Init();
/* Freebl state. */
PRBool aesni_support();
PRBool clmul_support();
PRBool avx_support();
#endif /* _BLAPII_H_ */

View File

@ -0,0 +1,119 @@
/* 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/. */
#ifdef FREEBL_NO_DEPEND
#include "stubs.h"
#endif
#include "blapii.h"
#include "mpi.h"
#include "secerr.h"
#include "prtypes.h"
#include "prinit.h"
#include "prenv.h"
#if defined(_MSC_VER) && !defined(_M_IX86)
#include <intrin.h> /* for _xgetbv() */
#endif
static PRCallOnceType coFreeblInit;
/* State variables. */
static PRBool aesni_support_ = PR_FALSE;
static PRBool clmul_support_ = PR_FALSE;
static PRBool avx_support_ = PR_FALSE;
#ifdef NSS_X86_OR_X64
/*
* Adapted from the example code in "How to detect New Instruction support in
* the 4th generation Intel Core processor family" by Max Locktyukhin.
*
* XGETBV:
* Reads an extended control register (XCR) specified by ECX into EDX:EAX.
*/
static PRBool
check_xcr0_ymm()
{
PRUint32 xcr0;
#if defined(_MSC_VER)
#if defined(_M_IX86)
__asm {
mov ecx, 0
xgetbv
mov xcr0, eax
}
#else
xcr0 = (PRUint32)_xgetbv(0); /* Requires VS2010 SP1 or later. */
#endif /* _M_IX86 */
#else /* _MSC_VER */
/* Old OSX compilers don't support xgetbv. Use byte form. */
__asm__(".byte 0x0F, 0x01, 0xd0"
: "=a"(xcr0)
: "c"(0)
: "%edx");
#endif /* _MSC_VER */
/* Check if xmm and ymm state are enabled in XCR0. */
return (xcr0 & 6) == 6;
}
#define ECX_AESNI (1 << 25)
#define ECX_CLMUL (1 << 1)
#define ECX_XSAVE (1 << 26)
#define ECX_OSXSAVE (1 << 27)
#define ECX_AVX (1 << 28)
#define AVX_BITS (ECX_XSAVE | ECX_OSXSAVE | ECX_AVX)
void
CheckX86CPUSupport()
{
unsigned long eax, ebx, ecx, edx;
char *disable_hw_aes = PR_GetEnvSecure("NSS_DISABLE_HW_AES");
char *disable_pclmul = PR_GetEnvSecure("NSS_DISABLE_PCLMUL");
char *disable_avx = PR_GetEnvSecure("NSS_DISABLE_AVX");
freebl_cpuid(1, &eax, &ebx, &ecx, &edx);
aesni_support_ = (PRBool)((ecx & ECX_AESNI) != 0 && disable_hw_aes == NULL);
clmul_support_ = (PRBool)((ecx & ECX_CLMUL) != 0 && disable_pclmul == NULL);
/* For AVX we check AVX, OSXSAVE, and XSAVE
* as well as XMM and YMM state. */
avx_support_ = (PRBool)((ecx & AVX_BITS) == AVX_BITS) && check_xcr0_ymm() &&
disable_avx == NULL;
}
#endif /* NSS_X86_OR_X64 */
PRBool
aesni_support()
{
return aesni_support_;
}
PRBool
clmul_support()
{
return clmul_support_;
}
PRBool
avx_support()
{
return avx_support_;
}
static PRStatus
FreeblInit(void)
{
#ifdef NSS_X86_OR_X64
CheckX86CPUSupport();
#endif
return PR_SUCCESS;
}
SECStatus
BL_Init()
{
if (PR_CallOnce(&coFreeblInit, FreeblInit) != PR_SUCCESS) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
RSA_Init();
return SECSuccess;
}

View File

@ -158,8 +158,6 @@
'VCCLCompilerTool': {
#TODO: -Ox optimize flags
'PreprocessorDefinitions': [
'NSS_X86_OR_X64',
'NSS_X86',
'MP_ASSEMBLY_MULTIPLY',
'MP_ASSEMBLY_SQUARE',
'MP_ASSEMBLY_DIV_2DX1D',
@ -176,9 +174,6 @@
'VCCLCompilerTool': {
#TODO: -Ox optimize flags
'PreprocessorDefinitions': [
'NSS_USE_64',
'NSS_X86_OR_X64',
'NSS_X64',
'MP_IS_LITTLE_ENDIAN',
'NSS_BEVAND_ARCFOUR',
'MPI_AMD64',
@ -192,11 +187,8 @@
}],
[ 'OS!="win"', {
'conditions': [
[ 'target_arch=="x64"', {
[ 'target_arch=="x64" or target_arch=="arm64" or target_arch=="aarch64"', {
'defines': [
'NSS_USE_64',
'NSS_X86_OR_X64',
'NSS_X64',
# The Makefile does version-tests on GCC, but we're not doing that here.
'HAVE_INT128_SUPPORT',
],
@ -205,12 +197,6 @@
'ecl/uint128.c',
],
}],
[ 'target_arch=="ia32"', {
'defines': [
'NSS_X86_OR_X64',
'NSS_X86',
],
}],
],
}],
[ 'OS=="linux"', {
@ -251,11 +237,7 @@
'MP_ASSEMBLY_SQUARE',
'MP_USE_UINT_DIGIT',
'SHA_NO_LONG_LONG',
],
}],
[ 'target_arch=="arm64" or target_arch=="aarch64"', {
'defines': [
'NSS_USE_64',
'ARMHF',
],
}],
],

View File

@ -33,6 +33,7 @@
'ecl/ecp_jm.c',
'ecl/ecp_mont.c',
'fipsfreebl.c',
'blinit.c',
'freeblver.c',
'gcm.c',
'hmacct.c',

View File

@ -132,6 +132,7 @@ CSRCS = \
chacha20poly1305.c \
cts.c \
ctr.c \
blinit.c \
fipsfreebl.c \
gcm.c \
hmacct.c \

View File

@ -26,17 +26,11 @@
#include "mpi.h"
#ifdef USE_HW_AES
static int has_intel_aes = 0;
static PRBool use_hw_aes = PR_FALSE;
#ifdef INTEL_GCM
#include "intel-gcm.h"
static int has_intel_avx = 0;
static int has_intel_clmul = 0;
static PRBool use_hw_gcm = PR_FALSE;
#if defined(_MSC_VER) && !defined(_M_IX86)
#include <intrin.h> /* for _xgetbv() */
#endif
#endif
#endif /* USE_HW_AES */
@ -999,39 +993,6 @@ AES_AllocateContext(void)
return PORT_ZNew(AESContext);
}
#ifdef INTEL_GCM
/*
* Adapted from the example code in "How to detect New Instruction support in
* the 4th generation Intel Core processor family" by Max Locktyukhin.
*
* XGETBV:
* Reads an extended control register (XCR) specified by ECX into EDX:EAX.
*/
static PRBool
check_xcr0_ymm()
{
PRUint32 xcr0;
#if defined(_MSC_VER)
#if defined(_M_IX86)
__asm {
mov ecx, 0
xgetbv
mov xcr0, eax
}
#else
xcr0 = (PRUint32)_xgetbv(0); /* Requires VS2010 SP1 or later. */
#endif
#else
__asm__("xgetbv"
: "=a"(xcr0)
: "c"(0)
: "%edx");
#endif
/* Check if xmm and ymm state are enabled in XCR0. */
return (xcr0 & 6) == 6;
}
#endif
/*
** Initialize a new AES context suitable for AES encryption/decryption in
** the ECB or CBC mode.
@ -1070,33 +1031,9 @@ aes_InitContext(AESContext *cx, const unsigned char *key, unsigned int keysize,
return SECFailure;
}
#ifdef USE_HW_AES
if (has_intel_aes == 0) {
unsigned long eax, ebx, ecx, edx;
char *disable_hw_aes = PR_GetEnvSecure("NSS_DISABLE_HW_AES");
if (disable_hw_aes == NULL) {
freebl_cpuid(1, &eax, &ebx, &ecx, &edx);
has_intel_aes = (ecx & (1 << 25)) != 0 ? 1 : -1;
use_hw_aes = aesni_support() && (keysize % 8) == 0 && blocksize == 16;
#ifdef INTEL_GCM
has_intel_clmul = (ecx & (1 << 1)) != 0 ? 1 : -1;
if ((ecx & (1 << 27)) != 0 && (ecx & (1 << 28)) != 0 &&
check_xcr0_ymm()) {
has_intel_avx = 1;
} else {
has_intel_avx = -1;
}
#endif
} else {
has_intel_aes = -1;
#ifdef INTEL_GCM
has_intel_avx = -1;
has_intel_clmul = -1;
#endif
}
}
use_hw_aes = (PRBool)(has_intel_aes > 0 && (keysize % 8) == 0 && blocksize == 16);
#ifdef INTEL_GCM
use_hw_gcm = (PRBool)(use_hw_aes && has_intel_avx > 0 && has_intel_clmul > 0);
use_hw_gcm = use_hw_aes && avx_support() && clmul_support();
#endif
#endif /* USE_HW_AES */
/* Nb = (block size in bits) / 32 */

View File

@ -1551,7 +1551,7 @@ cleanup:
return rv;
}
static SECStatus
SECStatus
RSA_Init(void)
{
if (PR_CallOnce(&coBPInit, init_blinding_params_list) != PR_SUCCESS) {
@ -1561,12 +1561,6 @@ RSA_Init(void)
return SECSuccess;
}
SECStatus
BL_Init(void)
{
return RSA_Init();
}
/* cleanup at shutdown */
void
RSA_Cleanup(void)

View File

@ -1211,6 +1211,7 @@ RSA_SignPSS(RSAPrivateKey *key,
if (rv != SECSuccess)
goto done;
// This sets error codes upon failure.
rv = RSA_PrivateKeyOpDoubleChecked(key, output, pssEncoded);
*outputLen = modulusLen;
@ -1270,7 +1271,6 @@ RSA_CheckSignPSS(RSAPublicKey *key,
return rv;
}
/* XXX Doesn't set error code */
SECStatus
RSA_Sign(RSAPrivateKey *key,
unsigned char *output,
@ -1279,34 +1279,34 @@ RSA_Sign(RSAPrivateKey *key,
const unsigned char *input,
unsigned int inputLen)
{
SECStatus rv = SECSuccess;
SECStatus rv = SECFailure;
unsigned int modulusLen = rsa_modulusLen(&key->modulus);
SECItem formatted;
SECItem unformatted;
SECItem formatted = { siBuffer, NULL, 0 };
SECItem unformatted = { siBuffer, (unsigned char *)input, inputLen };
if (maxOutputLen < modulusLen)
return SECFailure;
if (maxOutputLen < modulusLen) {
PORT_SetError(SEC_ERROR_OUTPUT_LEN);
goto done;
}
unformatted.len = inputLen;
unformatted.data = (unsigned char *)input;
formatted.data = NULL;
rv = rsa_FormatBlock(&formatted, modulusLen, RSA_BlockPrivate,
&unformatted);
if (rv != SECSuccess)
if (rv != SECSuccess) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
goto done;
}
// This sets error codes upon failure.
rv = RSA_PrivateKeyOpDoubleChecked(key, output, formatted.data);
*outputLen = modulusLen;
goto done;
done:
if (formatted.data != NULL)
if (formatted.data != NULL) {
PORT_ZFree(formatted.data, modulusLen);
}
return rv;
}
/* XXX Doesn't set error code */
SECStatus
RSA_CheckSign(RSAPublicKey *key,
const unsigned char *sig,
@ -1314,60 +1314,71 @@ RSA_CheckSign(RSAPublicKey *key,
const unsigned char *data,
unsigned int dataLen)
{
SECStatus rv;
SECStatus rv = SECFailure;
unsigned int modulusLen = rsa_modulusLen(&key->modulus);
unsigned int i;
unsigned char *buffer;
unsigned char *buffer = NULL;
if (sigLen != modulusLen) {
PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
goto done;
}
if (sigLen != modulusLen)
goto failure;
/*
* 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.
*/
if (dataLen > modulusLen - (3 + RSA_BLOCK_MIN_PAD_LEN))
goto failure;
if (dataLen > modulusLen - (3 + RSA_BLOCK_MIN_PAD_LEN)) {
PORT_SetError(SEC_ERROR_BAD_DATA);
goto done;
}
buffer = (unsigned char *)PORT_Alloc(modulusLen + 1);
if (!buffer)
goto failure;
if (!buffer) {
PORT_SetError(SEC_ERROR_NO_MEMORY);
goto done;
}
rv = RSA_PublicKeyOp(key, buffer, sig);
if (rv != SECSuccess)
goto loser;
if (RSA_PublicKeyOp(key, buffer, sig) != SECSuccess) {
PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
goto done;
}
/*
* check the padding that was used
*/
if (buffer[0] != RSA_BLOCK_FIRST_OCTET ||
buffer[1] != (unsigned char)RSA_BlockPrivate) {
goto loser;
PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
goto done;
}
for (i = 2; i < modulusLen - dataLen - 1; i++) {
if (buffer[i] != RSA_BLOCK_PRIVATE_PAD_OCTET)
goto loser;
if (buffer[i] != RSA_BLOCK_PRIVATE_PAD_OCTET) {
PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
goto done;
}
}
if (buffer[i] != RSA_BLOCK_AFTER_PAD_OCTET) {
PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
goto done;
}
if (buffer[i] != RSA_BLOCK_AFTER_PAD_OCTET)
goto loser;
/*
* make sure we get the same results
*/
if (PORT_Memcmp(buffer + modulusLen - dataLen, data, dataLen) != 0)
goto loser;
if (PORT_Memcmp(buffer + modulusLen - dataLen, data, dataLen) == 0) {
rv = SECSuccess;
}
PORT_Free(buffer);
return SECSuccess;
loser:
PORT_Free(buffer);
failure:
return SECFailure;
done:
if (buffer) {
PORT_Free(buffer);
}
return rv;
}
/* XXX Doesn't set error code */
SECStatus
RSA_CheckSignRecover(RSAPublicKey *key,
unsigned char *output,
@ -1376,21 +1387,27 @@ RSA_CheckSignRecover(RSAPublicKey *key,
const unsigned char *sig,
unsigned int sigLen)
{
SECStatus rv;
SECStatus rv = SECFailure;
unsigned int modulusLen = rsa_modulusLen(&key->modulus);
unsigned int i;
unsigned char *buffer;
unsigned char *buffer = NULL;
if (sigLen != modulusLen)
goto failure;
if (sigLen != modulusLen) {
PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
goto done;
}
buffer = (unsigned char *)PORT_Alloc(modulusLen + 1);
if (!buffer)
goto failure;
if (!buffer) {
PORT_SetError(SEC_ERROR_NO_MEMORY);
goto done;
}
if (RSA_PublicKeyOp(key, buffer, sig) != SECSuccess) {
PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
goto done;
}
rv = RSA_PublicKeyOp(key, buffer, sig);
if (rv != SECSuccess)
goto loser;
*outputLen = 0;
/*
@ -1398,28 +1415,34 @@ RSA_CheckSignRecover(RSAPublicKey *key,
*/
if (buffer[0] != RSA_BLOCK_FIRST_OCTET ||
buffer[1] != (unsigned char)RSA_BlockPrivate) {
goto loser;
PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
goto done;
}
for (i = 2; i < modulusLen; i++) {
if (buffer[i] == RSA_BLOCK_AFTER_PAD_OCTET) {
*outputLen = modulusLen - i - 1;
break;
}
if (buffer[i] != RSA_BLOCK_PRIVATE_PAD_OCTET)
goto loser;
if (buffer[i] != RSA_BLOCK_PRIVATE_PAD_OCTET) {
PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
goto done;
}
}
if (*outputLen == 0) {
PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
goto done;
}
if (*outputLen > maxOutputLen) {
PORT_SetError(SEC_ERROR_OUTPUT_LEN);
goto done;
}
if (*outputLen == 0)
goto loser;
if (*outputLen > maxOutputLen)
goto loser;
PORT_Memcpy(output, buffer + modulusLen - *outputLen, *outputLen);
rv = SECSuccess;
PORT_Free(buffer);
return SECSuccess;
loser:
PORT_Free(buffer);
failure:
return SECFailure;
done:
if (buffer) {
PORT_Free(buffer);
}
return rv;
}

View File

@ -26,49 +26,6 @@
'defines': [
'MOZILLA_CLIENT=1',
],
'conditions': [
[ 'OS=="win"', {
'configurations': {
'x86_Base': {
'msvs_settings': {
'VCCLCompilerTool': {
'PreprocessorDefinitions': [
'NSS_X86_OR_X64',
'NSS_X86',
],
},
},
},
'x64_Base': {
'msvs_settings': {
'VCCLCompilerTool': {
'PreprocessorDefinitions': [
'NSS_USE_64',
'NSS_X86_OR_X64',
'NSS_X64',
],
},
},
},
},
}, {
'conditions': [
[ 'target_arch=="x64"', {
'defines': [
'NSS_USE_64',
'NSS_X86_OR_X64',
'NSS_X64',
],
}],
[ 'target_arch=="ia32"', {
'defines': [
'NSS_X86_OR_X64',
'NSS_X86',
],
}],
],
}],
],
},
'variables': {
'module': 'nss'

View File

@ -1496,6 +1496,14 @@ extern PRInt32 ssl3_SendRecord(sslSocket *ss, ssl3CipherSpec *cwSpec,
*/
#define SSL_LIBRARY_VERSION_NONE 0
/* SSL_LIBRARY_VERSION_MIN_SUPPORTED is the minimum version that this version
* of libssl supports. Applications should use SSL_VersionRangeGetSupported at
* runtime to determine which versions are supported by the version of libssl
* in use.
*/
#define SSL_LIBRARY_VERSION_MIN_SUPPORTED_DATAGRAM SSL_LIBRARY_VERSION_TLS_1_1
#define SSL_LIBRARY_VERSION_MIN_SUPPORTED_STREAM SSL_LIBRARY_VERSION_3_0
/* SSL_LIBRARY_VERSION_MAX_SUPPORTED is the maximum version that this version
* of libssl supports. Applications should use SSL_VersionRangeGetSupported at
* runtime to determine which versions are supported by the version of libssl

View File

@ -2152,11 +2152,11 @@ SSL_ReconfigFD(PRFileDesc *model, PRFileDesc *fd)
ss->sniSocketConfig = sm->sniSocketConfig;
if (sm->sniSocketConfigArg)
ss->sniSocketConfigArg = sm->sniSocketConfigArg;
if (ss->alertReceivedCallback) {
if (sm->alertReceivedCallback) {
ss->alertReceivedCallback = sm->alertReceivedCallback;
ss->alertReceivedCallbackArg = sm->alertReceivedCallbackArg;
}
if (ss->alertSentCallback) {
if (sm->alertSentCallback) {
ss->alertSentCallback = sm->alertSentCallback;
ss->alertSentCallbackArg = sm->alertSentCallbackArg;
}
@ -2173,61 +2173,82 @@ SSL_ReconfigFD(PRFileDesc *model, PRFileDesc *fd)
return fd;
}
/*
* Get the user supplied range
*/
static SECStatus
ssl3_GetRangePolicy(SSLProtocolVariant protocolVariant, SSLVersionRange *prange)
SECStatus
ssl3_GetEffectiveVersionPolicy(SSLProtocolVariant variant,
SSLVersionRange *effectivePolicy)
{
SECStatus rv;
PRUint32 policy;
PRInt32 option;
PRUint32 policyFlag;
PRInt32 minPolicy, maxPolicy;
/* only use policy constraints if we've set the apply ssl policy bit */
rv = NSS_GetAlgorithmPolicy(SEC_OID_APPLY_SSL_POLICY, &policy);
if ((rv != SECSuccess) || !(policy & NSS_USE_POLICY_IN_SSL)) {
if (variant == ssl_variant_stream) {
effectivePolicy->min = SSL_LIBRARY_VERSION_MIN_SUPPORTED_STREAM;
effectivePolicy->max = SSL_LIBRARY_VERSION_MAX_SUPPORTED;
} else {
effectivePolicy->min = SSL_LIBRARY_VERSION_MIN_SUPPORTED_DATAGRAM;
effectivePolicy->max = SSL_LIBRARY_VERSION_MAX_SUPPORTED;
}
rv = NSS_GetAlgorithmPolicy(SEC_OID_APPLY_SSL_POLICY, &policyFlag);
if ((rv != SECSuccess) || !(policyFlag & NSS_USE_POLICY_IN_SSL)) {
/* Policy is not active, report library extents. */
return SECSuccess;
}
rv = NSS_OptionGet(VERSIONS_POLICY_MIN(variant), &minPolicy);
if (rv != SECSuccess) {
return SECFailure;
}
rv = NSS_OptionGet(VERSIONS_POLICY_MIN(protocolVariant), &option);
rv = NSS_OptionGet(VERSIONS_POLICY_MAX(variant), &maxPolicy);
if (rv != SECSuccess) {
return rv;
return SECFailure;
}
prange->min = (PRUint16)option;
rv = NSS_OptionGet(VERSIONS_POLICY_MAX(protocolVariant), &option);
if (rv != SECSuccess) {
return rv;
}
prange->max = (PRUint16)option;
if (prange->max < prange->min) {
return SECFailure; /* don't accept an invalid policy */
if (minPolicy > effectivePolicy->max ||
maxPolicy < effectivePolicy->min ||
minPolicy > maxPolicy) {
return SECFailure;
}
effectivePolicy->min = PR_MAX(effectivePolicy->min, minPolicy);
effectivePolicy->max = PR_MIN(effectivePolicy->max, maxPolicy);
return SECSuccess;
}
/*
* Constrain a single protocol variant's range based on the user policy
/*
* Assumes that rangeParam values are within the supported boundaries,
* but should contain all potentially allowed versions, even if they contain
* conflicting versions.
* Will return the overlap, or a NONE range if system policy is invalid.
*/
static SECStatus
ssl3_ConstrainVariantRangeByPolicy(SSLProtocolVariant protocolVariant)
ssl3_CreateOverlapWithPolicy(SSLProtocolVariant protocolVariant,
SSLVersionRange *input,
SSLVersionRange *overlap)
{
SSLVersionRange vrange;
SSLVersionRange pvrange;
SECStatus rv;
SSLVersionRange effectivePolicyBoundary;
SSLVersionRange vrange;
vrange = *VERSIONS_DEFAULTS(protocolVariant);
rv = ssl3_GetRangePolicy(protocolVariant, &pvrange);
if (rv != SECSuccess) {
return SECSuccess; /* we don't have any policy */
PORT_Assert(input != NULL);
rv = ssl3_GetEffectiveVersionPolicy(protocolVariant,
&effectivePolicyBoundary);
if (rv == SECFailure) {
/* SECFailure means internal failure or invalid configuration. */
overlap->min = overlap->max = SSL_LIBRARY_VERSION_NONE;
return SECFailure;
}
vrange.min = PR_MAX(vrange.min, pvrange.min);
vrange.max = PR_MIN(vrange.max, pvrange.max);
if (vrange.max >= vrange.min) {
*VERSIONS_DEFAULTS(protocolVariant) = vrange;
} else {
vrange.min = PR_MAX(input->min, effectivePolicyBoundary.min);
vrange.max = PR_MIN(input->max, effectivePolicyBoundary.max);
if (vrange.max < vrange.min) {
/* there was no overlap, turn off range altogether */
pvrange.min = pvrange.max = SSL_LIBRARY_VERSION_NONE;
*VERSIONS_DEFAULTS(protocolVariant) = pvrange;
overlap->min = overlap->max = SSL_LIBRARY_VERSION_NONE;
return SECFailure;
}
*overlap = vrange;
return SECSuccess;
}
@ -2235,16 +2256,17 @@ static PRBool
ssl_VersionIsSupportedByPolicy(SSLProtocolVariant protocolVariant,
SSL3ProtocolVersion version)
{
SSLVersionRange pvrange;
SECStatus rv;
SSLVersionRange effectivePolicyBoundary;
rv = ssl3_GetRangePolicy(protocolVariant, &pvrange);
if (rv == SECSuccess) {
if ((version > pvrange.max) || (version < pvrange.min)) {
return PR_FALSE; /* disallowed by policy */
}
rv = ssl3_GetEffectiveVersionPolicy(protocolVariant,
&effectivePolicyBoundary);
if (rv == SECFailure) {
/* SECFailure means internal failure or invalid configuration. */
return PR_FALSE;
}
return PR_TRUE;
return version >= effectivePolicyBoundary.min &&
version <= effectivePolicyBoundary.max;
}
/*
@ -2254,18 +2276,36 @@ ssl_VersionIsSupportedByPolicy(SSLProtocolVariant protocolVariant,
SECStatus
ssl3_ConstrainRangeByPolicy(void)
{
SECStatus rv;
rv = ssl3_ConstrainVariantRangeByPolicy(ssl_variant_stream);
if (rv != SECSuccess) {
return rv;
}
rv = ssl3_ConstrainVariantRangeByPolicy(ssl_variant_datagram);
if (rv != SECSuccess) {
return rv;
}
/* We ignore failures in ssl3_CreateOverlapWithPolicy. Although an empty
* overlap disables all connectivity, it's an allowed state.
*/
ssl3_CreateOverlapWithPolicy(ssl_variant_stream,
VERSIONS_DEFAULTS(ssl_variant_stream),
VERSIONS_DEFAULTS(ssl_variant_stream));
ssl3_CreateOverlapWithPolicy(ssl_variant_datagram,
VERSIONS_DEFAULTS(ssl_variant_datagram),
VERSIONS_DEFAULTS(ssl_variant_datagram));
return SECSuccess;
}
PRBool
ssl3_VersionIsSupportedByCode(SSLProtocolVariant protocolVariant,
SSL3ProtocolVersion version)
{
switch (protocolVariant) {
case ssl_variant_stream:
return (version >= SSL_LIBRARY_VERSION_MIN_SUPPORTED_STREAM &&
version <= SSL_LIBRARY_VERSION_MAX_SUPPORTED);
case ssl_variant_datagram:
return (version >= SSL_LIBRARY_VERSION_MIN_SUPPORTED_DATAGRAM &&
version <= SSL_LIBRARY_VERSION_MAX_SUPPORTED);
}
/* Can't get here */
PORT_Assert(PR_FALSE);
return PR_FALSE;
}
PRBool
ssl3_VersionIsSupported(SSLProtocolVariant protocolVariant,
SSL3ProtocolVersion version)
@ -2273,33 +2313,7 @@ ssl3_VersionIsSupported(SSLProtocolVariant protocolVariant,
if (!ssl_VersionIsSupportedByPolicy(protocolVariant, version)) {
return PR_FALSE;
}
switch (protocolVariant) {
case ssl_variant_stream:
return (version >= SSL_LIBRARY_VERSION_3_0 &&
version <= SSL_LIBRARY_VERSION_MAX_SUPPORTED);
case ssl_variant_datagram:
return (version >= SSL_LIBRARY_VERSION_TLS_1_1 &&
version <= SSL_LIBRARY_VERSION_MAX_SUPPORTED);
default:
/* Can't get here */
PORT_Assert(PR_FALSE);
return PR_FALSE;
}
}
/* Returns PR_TRUE if the given version range is valid and
** fully supported; otherwise, returns PR_FALSE.
*/
static PRBool
ssl3_VersionRangeIsValid(SSLProtocolVariant protocolVariant,
const SSLVersionRange *vrange)
{
return vrange &&
vrange->min <= vrange->max &&
ssl3_VersionIsSupported(protocolVariant, vrange->min) &&
ssl3_VersionIsSupported(protocolVariant, vrange->max) &&
(vrange->min > SSL_LIBRARY_VERSION_3_0 ||
vrange->max < SSL_LIBRARY_VERSION_TLS_1_3);
return ssl3_VersionIsSupportedByCode(protocolVariant, version);
}
const SECItem *
@ -2325,6 +2339,8 @@ SECStatus
SSL_VersionRangeGetSupported(SSLProtocolVariant protocolVariant,
SSLVersionRange *vrange)
{
SECStatus rv;
if (!vrange) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
@ -2332,15 +2348,15 @@ SSL_VersionRangeGetSupported(SSLProtocolVariant protocolVariant,
switch (protocolVariant) {
case ssl_variant_stream:
vrange->min = SSL_LIBRARY_VERSION_3_0;
vrange->min = SSL_LIBRARY_VERSION_MIN_SUPPORTED_STREAM;
vrange->max = SSL_LIBRARY_VERSION_MAX_SUPPORTED;
// We don't allow SSLv3 and TLSv1.3 together.
if (vrange->max == SSL_LIBRARY_VERSION_TLS_1_3) {
vrange->min = SSL_LIBRARY_VERSION_TLS_1_0;
}
/* We don't allow SSLv3 and TLSv1.3 together.
* However, don't check yet, apply the policy first.
* Because if the effective supported range doesn't use TLS 1.3,
* then we don't need to increase the minimum. */
break;
case ssl_variant_datagram:
vrange->min = SSL_LIBRARY_VERSION_TLS_1_1;
vrange->min = SSL_LIBRARY_VERSION_MIN_SUPPORTED_DATAGRAM;
vrange->max = SSL_LIBRARY_VERSION_MAX_SUPPORTED;
break;
default:
@ -2348,6 +2364,17 @@ SSL_VersionRangeGetSupported(SSLProtocolVariant protocolVariant,
return SECFailure;
}
rv = ssl3_CreateOverlapWithPolicy(protocolVariant, vrange, vrange);
if (rv != SECSuccess) {
/* Library default and policy don't overlap. */
return rv;
}
/* We don't allow SSLv3 and TLSv1.3 together */
if (vrange->max >= SSL_LIBRARY_VERSION_TLS_1_3) {
vrange->min = PR_MAX(vrange->min, SSL_LIBRARY_VERSION_TLS_1_0);
}
return SECSuccess;
}
@ -2363,6 +2390,43 @@ SSL_VersionRangeGetDefault(SSLProtocolVariant protocolVariant,
}
*vrange = *VERSIONS_DEFAULTS(protocolVariant);
return ssl3_CreateOverlapWithPolicy(protocolVariant, vrange, vrange);
}
static PRBool
ssl3_HasConflictingSSLVersions(const SSLVersionRange *vrange)
{
return (vrange->min <= SSL_LIBRARY_VERSION_3_0 &&
vrange->max >= SSL_LIBRARY_VERSION_TLS_1_3);
}
static SECStatus
ssl3_CheckRangeValidAndConstrainByPolicy(SSLProtocolVariant protocolVariant,
SSLVersionRange *vrange)
{
SECStatus rv;
if (vrange->min > vrange->max ||
!ssl3_VersionIsSupportedByCode(protocolVariant, vrange->min) ||
!ssl3_VersionIsSupportedByCode(protocolVariant, vrange->max) ||
ssl3_HasConflictingSSLVersions(vrange)) {
PORT_SetError(SSL_ERROR_INVALID_VERSION_RANGE);
return SECFailure;
}
/* Try to adjust the received range using our policy.
* If there's overlap, we'll use the (possibly reduced) range.
* If there isn't overlap, it's failure. */
rv = ssl3_CreateOverlapWithPolicy(protocolVariant, vrange, vrange);
if (rv != SECSuccess) {
return rv;
}
/* We don't allow SSLv3 and TLSv1.3 together */
if (vrange->max >= SSL_LIBRARY_VERSION_TLS_1_3) {
vrange->min = PR_MAX(vrange->min, SSL_LIBRARY_VERSION_TLS_1_0);
}
return SECSuccess;
}
@ -2371,13 +2435,21 @@ SECStatus
SSL_VersionRangeSetDefault(SSLProtocolVariant protocolVariant,
const SSLVersionRange *vrange)
{
if (!ssl3_VersionRangeIsValid(protocolVariant, vrange)) {
PORT_SetError(SSL_ERROR_INVALID_VERSION_RANGE);
SSLVersionRange constrainedRange;
SECStatus rv;
if (!vrange) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
*VERSIONS_DEFAULTS(protocolVariant) = *vrange;
constrainedRange = *vrange;
rv = ssl3_CheckRangeValidAndConstrainByPolicy(protocolVariant,
&constrainedRange);
if (rv != SECSuccess)
return rv;
*VERSIONS_DEFAULTS(protocolVariant) = constrainedRange;
return SECSuccess;
}
@ -2405,24 +2477,33 @@ SSL_VersionRangeGet(PRFileDesc *fd, SSLVersionRange *vrange)
ssl_ReleaseSSL3HandshakeLock(ss);
ssl_Release1stHandshakeLock(ss);
return SECSuccess;
return ssl3_CreateOverlapWithPolicy(ss->protocolVariant, vrange, vrange);
}
SECStatus
SSL_VersionRangeSet(PRFileDesc *fd, const SSLVersionRange *vrange)
{
sslSocket *ss = ssl_FindSocket(fd);
SSLVersionRange constrainedRange;
sslSocket *ss;
SECStatus rv;
if (!vrange) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
ss = ssl_FindSocket(fd);
if (!ss) {
SSL_DBG(("%d: SSL[%d]: bad socket in SSL_VersionRangeSet",
SSL_GETPID(), fd));
return SECFailure;
}
if (!ssl3_VersionRangeIsValid(ss->protocolVariant, vrange)) {
PORT_SetError(SSL_ERROR_INVALID_VERSION_RANGE);
return SECFailure;
}
constrainedRange = *vrange;
rv = ssl3_CheckRangeValidAndConstrainByPolicy(ss->protocolVariant,
&constrainedRange);
if (rv != SECSuccess)
return rv;
ssl_Get1stHandshakeLock(ss);
ssl_GetSSL3HandshakeLock(ss);
@ -2435,7 +2516,7 @@ SSL_VersionRangeSet(PRFileDesc *fd, const SSLVersionRange *vrange)
return SECFailure;
}
ss->vrange = *vrange;
ss->vrange = constrainedRange;
ssl_ReleaseSSL3HandshakeLock(ss);
ssl_Release1stHandshakeLock(ss);
@ -3684,7 +3765,10 @@ ssl_NewSocket(PRBool makeLocks, SSLProtocolVariant protocolVariant)
ss->opt.noLocks = !makeLocks;
ss->vrange = *VERSIONS_DEFAULTS(protocolVariant);
ss->protocolVariant = protocolVariant;
/* Ignore overlap failures, because returning NULL would trigger assertion
* failures elsewhere. We don't want this scenario to be fatal, it's just
* a state where no SSL connectivity is possible. */
ssl3_CreateOverlapWithPolicy(ss->protocolVariant, &ss->vrange, &ss->vrange);
ss->peerID = NULL;
ss->rTimeout = PR_INTERVAL_NO_TIMEOUT;
ss->wTimeout = PR_INTERVAL_NO_TIMEOUT;

View File

@ -231,20 +231,20 @@ bool EncTool::DoCipher(std::string file_name, std::string out_file,
bool encrypt, key_func_t get_params) {
SECStatus rv;
unsigned int outLen = 0, chunkSize = 1024;
char buffer[chunkSize + 16];
char buffer[1040];
const unsigned char* bufferStart =
reinterpret_cast<const unsigned char*>(buffer);
ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
if (!slot) {
PrintError("Unable to find security device", PR_GetError(), __LINE__);
return SECFailure;
return false;
}
ScopedSECItem key, params;
if (!(this->*get_params)(std::vector<uint8_t>(), key, params)) {
PrintError("Geting keys and params failed.", __LINE__);
return SECFailure;
return false;
}
ScopedPK11SymKey symKey(
@ -252,7 +252,7 @@ bool EncTool::DoCipher(std::string file_name, std::string out_file,
CKA_DECRYPT | CKA_ENCRYPT, key.get(), nullptr));
if (!symKey) {
PrintError("Failure to import key into NSS", PR_GetError(), __LINE__);
return SECFailure;
return false;
}
std::streambuf* buf;
@ -270,21 +270,21 @@ bool EncTool::DoCipher(std::string file_name, std::string out_file,
// Read from stdin.
if (file_name.empty()) {
std::vector<uint8_t> data = ReadInputData("");
uint8_t out[data.size() + 16];
std::vector<uint8_t> out(data.size() + 16);
SECStatus rv;
if (encrypt) {
rv = PK11_Encrypt(symKey.get(), cipher_mech_, params.get(), out, &outLen,
data.size() + 16, data.data(), data.size());
rv = PK11_Encrypt(symKey.get(), cipher_mech_, params.get(), out.data(),
&outLen, data.size() + 16, data.data(), data.size());
} else {
rv = PK11_Decrypt(symKey.get(), cipher_mech_, params.get(), out, &outLen,
data.size() + 16, data.data(), data.size());
rv = PK11_Decrypt(symKey.get(), cipher_mech_, params.get(), out.data(),
&outLen, data.size() + 16, data.data(), data.size());
}
if (rv != SECSuccess) {
PrintError(encrypt ? "Error encrypting" : "Error decrypting",
PR_GetError(), __LINE__);
return false;
};
output.write(reinterpret_cast<char*>(out), outLen);
output.write(reinterpret_cast<char*>(out.data()), outLen);
output.flush();
if (output_file.good()) {
output_file.close();
@ -302,7 +302,7 @@ bool EncTool::DoCipher(std::string file_name, std::string out_file,
if (!input.good()) {
return false;
}
uint8_t out[chunkSize + 16];
uint8_t out[1040];
while (input) {
if (encrypt) {
input.read(buffer, chunkSize);

View File

@ -27,6 +27,9 @@ if [ -z "${CLEANUP}" -o "${CLEANUP}" = "${SCRIPTNAME}" ]; then
echo "NSS_AIA_OCSP=${NSS_AIA_OCSP}"
echo "IOPR_HOSTADDR_LIST=${IOPR_HOSTADDR_LIST}"
echo "PKITS_DATA=${PKITS_DATA}"
echo "NSS_DISABLE_HW_AES=${NSS_DISABLE_HW_AES}"
echo "NSS_DISABLE_PCLMUL=${NSS_DISABLE_PCLMUL}"
echo "NSS_DISABLE_AVX=${NSS_DISABLE_AVX}"
echo
echo "Tests summary:"
echo "--------------"