Bug 1305970 - land NSS 0x0c845c900217, r=me
authorFranziskus Kiefer <franziskuskiefer@gmail.com>
Sat, 15 Oct 2016 08:45:05 +0200
changeset 318155 a7037a607016fb1727b3fd7194910a7ec5197715
parent 318154 c8183800343eb8363702ff76e2e7df9bf41b2be5
child 318156 fea2dc883057d88fc6ae52b7fadcc07e6ab0e5bd
push id33211
push usercbook@mozilla.com
push dateMon, 17 Oct 2016 09:38:38 +0000
treeherderautoland@e4ef6fa03aa8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersme
bugs1305970
milestone52.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1305970 - land NSS 0x0c845c900217, r=me
security/nss/.gitignore
security/nss/Makefile
security/nss/TAG-INFO
security/nss/automation/taskcluster/docker-arm/setup.sh
security/nss/automation/taskcluster/docker/setup.sh
security/nss/automation/taskcluster/graph/src/extend.js
security/nss/automation/taskcluster/graph/src/try_syntax.js
security/nss/automation/taskcluster/scripts/build.sh
security/nss/automation/taskcluster/scripts/build_gyp.sh
security/nss/automation/taskcluster/scripts/gen_certs.sh
security/nss/automation/taskcluster/scripts/run_scan_build.sh
security/nss/automation/taskcluster/scripts/run_tests.sh
security/nss/automation/taskcluster/scripts/tools.sh
security/nss/build.sh
security/nss/cmd/Makefile
security/nss/cmd/addbuiltin/addbuiltin.gyp
security/nss/cmd/atob/atob.gyp
security/nss/cmd/bltest/bltest.gyp
security/nss/cmd/btoa/btoa.gyp
security/nss/cmd/certcgi/certcgi.gyp
security/nss/cmd/certutil/certext.c
security/nss/cmd/certutil/certutil.gyp
security/nss/cmd/chktest/chktest.gyp
security/nss/cmd/crlutil/crlutil.gyp
security/nss/cmd/crmftest/crmftest.gyp
security/nss/cmd/dbtest/dbtest.gyp
security/nss/cmd/derdump/derdump.gyp
security/nss/cmd/digest/digest.gyp
security/nss/cmd/ecperf/ecperf.c
security/nss/cmd/ecperf/ecperf.gyp
security/nss/cmd/ectest/Makefile
security/nss/cmd/ectest/ectest.c
security/nss/cmd/ectest/manifest.mn
security/nss/cmd/ectest/testvecs.h
security/nss/cmd/fbectest/Makefile
security/nss/cmd/fbectest/fbectest.c
security/nss/cmd/fbectest/fbectest.gyp
security/nss/cmd/fbectest/manifest.mn
security/nss/cmd/fbectest/testvecs.h
security/nss/cmd/fipstest/fipstest.gyp
security/nss/cmd/httpserv/httpserv.gyp
security/nss/cmd/lib/exports.gyp
security/nss/cmd/lib/lib.gyp
security/nss/cmd/listsuites/listsuites.gyp
security/nss/cmd/lowhashtest/lowhashtest.gyp
security/nss/cmd/makepqg/makepqg.gyp
security/nss/cmd/manifest.mn
security/nss/cmd/modutil/modutil.gyp
security/nss/cmd/multinit/multinit.gyp
security/nss/cmd/ocspclnt/ocspclnt.gyp
security/nss/cmd/ocspresp/ocspresp.gyp
security/nss/cmd/oidcalc/oidcalc.gyp
security/nss/cmd/p7content/p7content.gyp
security/nss/cmd/p7env/p7env.gyp
security/nss/cmd/p7sign/p7sign.gyp
security/nss/cmd/p7verify/p7verify.gyp
security/nss/cmd/pk11ectest/Makefile
security/nss/cmd/pk11ectest/manifest.mn
security/nss/cmd/pk11ectest/pk11ectest.c
security/nss/cmd/pk11ectest/pk11ectest.gyp
security/nss/cmd/pk11ectest/testvecs.h
security/nss/cmd/pk11gcmtest/pk11gcmtest.gyp
security/nss/cmd/pk11mode/pk11mode.gyp
security/nss/cmd/pk12util/pk12util.gyp
security/nss/cmd/pk1sign/pk1sign.gyp
security/nss/cmd/pkix-errcodes/pkix-errcodes.gyp
security/nss/cmd/platlibs.gypi
security/nss/cmd/pp/pp.gyp
security/nss/cmd/pwdecrypt/pwdecrypt.gyp
security/nss/cmd/rsaperf/rsaperf.gyp
security/nss/cmd/sdrtest/sdrtest.gyp
security/nss/cmd/selfserv/selfserv.gyp
security/nss/cmd/shlibsign/mangle/mangle.gyp
security/nss/cmd/shlibsign/shlibsign.gyp
security/nss/cmd/signtool/signtool.gyp
security/nss/cmd/signver/signver.gyp
security/nss/cmd/smimetools/smimetools.gyp
security/nss/cmd/ssltap/ssltap.gyp
security/nss/cmd/strsclnt/strsclnt.gyp
security/nss/cmd/symkeyutil/symkeyutil.gyp
security/nss/cmd/tests/tests.gyp
security/nss/cmd/tstclnt/tstclnt.gyp
security/nss/cmd/vfychain/vfychain.gyp
security/nss/cmd/vfyserv/vfyserv.gyp
security/nss/coreconf/Darwin.mk
security/nss/coreconf/Linux.mk
security/nss/coreconf/check_cc_clang.py
security/nss/coreconf/config.gypi
security/nss/coreconf/coreconf.dep
security/nss/coreconf/detect_host_arch.py
security/nss/coreconf/empty.c
security/nss/coreconf/nsinstall/nsinstall.gyp
security/nss/coreconf/nspr_include_dir.py
security/nss/coreconf/nspr_lib_dir.py
security/nss/coreconf/pkg_config.py
security/nss/coreconf/sanitizers.mk
security/nss/exports.gyp
security/nss/external_tests/common/common.gyp
security/nss/external_tests/common/gtest.gypi
security/nss/external_tests/der_gtest/der_gtest.gyp
security/nss/external_tests/google_test/google_test.gyp
security/nss/external_tests/nss_bogo_shim/nss_bogo_shim.gyp
security/nss/external_tests/pk11_gtest/pk11_gtest.gyp
security/nss/external_tests/ssl_gtest/libssl_internals.c
security/nss/external_tests/ssl_gtest/libssl_internals.h
security/nss/external_tests/ssl_gtest/ssl_0rtt_unittest.cc
security/nss/external_tests/ssl_gtest/ssl_auth_unittest.cc
security/nss/external_tests/ssl_gtest/ssl_ciphersuite_unittest.cc
security/nss/external_tests/ssl_gtest/ssl_dhe_unittest.cc
security/nss/external_tests/ssl_gtest/ssl_ecdh_unittest.cc
security/nss/external_tests/ssl_gtest/ssl_gtest.gyp
security/nss/external_tests/ssl_gtest/ssl_hrr_unittest.cc
security/nss/external_tests/ssl_gtest/ssl_loopback_unittest.cc
security/nss/external_tests/ssl_gtest/ssl_resumption_unittest.cc
security/nss/external_tests/ssl_gtest/ssl_staticrsa_unittest.cc
security/nss/external_tests/ssl_gtest/tls_agent.cc
security/nss/external_tests/ssl_gtest/tls_agent.h
security/nss/external_tests/ssl_gtest/tls_connect.cc
security/nss/external_tests/ssl_gtest/tls_connect.h
security/nss/external_tests/util_gtest/util_gtest.gyp
security/nss/fuzz/.clang-format
security/nss/fuzz/Makefile
security/nss/fuzz/clone_corpus.sh
security/nss/fuzz/clone_libfuzzer.sh
security/nss/fuzz/common.mk
security/nss/fuzz/libFuzzer/Makefile
security/nss/fuzz/libFuzzer/config.mk
security/nss/fuzz/libFuzzer/manifest.mn
security/nss/fuzz/manifest.mn
security/nss/fuzz/nssfuzz/Makefile
security/nss/fuzz/nssfuzz/cert_target.cc
security/nss/fuzz/nssfuzz/manifest.mn
security/nss/fuzz/nssfuzz/nssfuzz.cc
security/nss/fuzz/nssfuzz/pkcs8_target.cc
security/nss/fuzz/nssfuzz/registry.h
security/nss/fuzz/nssfuzz/shared.h
security/nss/fuzz/nssfuzz/spki_target.cc
security/nss/lib/base/base.gyp
security/nss/lib/base/exports.gyp
security/nss/lib/certdb/certdb.gyp
security/nss/lib/certdb/crl.c
security/nss/lib/certdb/exports.gyp
security/nss/lib/certhigh/certhigh.gyp
security/nss/lib/certhigh/exports.gyp
security/nss/lib/ckfw/builtins/Makefile
security/nss/lib/ckfw/builtins/builtins.gyp
security/nss/lib/ckfw/builtins/certdata.perl
security/nss/lib/ckfw/builtins/exports.gyp
security/nss/lib/ckfw/ckfw.gyp
security/nss/lib/ckfw/exports.gyp
security/nss/lib/crmf/crmf.gyp
security/nss/lib/crmf/exports.gyp
security/nss/lib/cryptohi/cryptohi.gyp
security/nss/lib/cryptohi/exports.gyp
security/nss/lib/dbm/include/exports.gyp
security/nss/lib/dbm/include/include.gyp
security/nss/lib/dbm/src/src.gyp
security/nss/lib/dev/dev.gyp
security/nss/lib/dev/exports.gyp
security/nss/lib/freebl/alg2268.c
security/nss/lib/freebl/ecl/ecl-curve.h
security/nss/lib/freebl/exports.gyp
security/nss/lib/freebl/freebl.gyp
security/nss/lib/freebl/rijndael.c
security/nss/lib/jar/exports.gyp
security/nss/lib/jar/jar.gyp
security/nss/lib/libpkix/include/exports.gyp
security/nss/lib/libpkix/include/include.gyp
security/nss/lib/libpkix/pkix/certsel/certsel.gyp
security/nss/lib/libpkix/pkix/certsel/exports.gyp
security/nss/lib/libpkix/pkix/checker/checker.gyp
security/nss/lib/libpkix/pkix/checker/exports.gyp
security/nss/lib/libpkix/pkix/crlsel/crlsel.gyp
security/nss/lib/libpkix/pkix/crlsel/exports.gyp
security/nss/lib/libpkix/pkix/params/exports.gyp
security/nss/lib/libpkix/pkix/params/params.gyp
security/nss/lib/libpkix/pkix/results/exports.gyp
security/nss/lib/libpkix/pkix/results/results.gyp
security/nss/lib/libpkix/pkix/store/exports.gyp
security/nss/lib/libpkix/pkix/store/store.gyp
security/nss/lib/libpkix/pkix/top/exports.gyp
security/nss/lib/libpkix/pkix/top/top.gyp
security/nss/lib/libpkix/pkix/util/exports.gyp
security/nss/lib/libpkix/pkix/util/util.gyp
security/nss/lib/libpkix/pkix_pl_nss/module/exports.gyp
security/nss/lib/libpkix/pkix_pl_nss/module/module.gyp
security/nss/lib/libpkix/pkix_pl_nss/pki/exports.gyp
security/nss/lib/libpkix/pkix_pl_nss/pki/pki.gyp
security/nss/lib/libpkix/pkix_pl_nss/system/exports.gyp
security/nss/lib/libpkix/pkix_pl_nss/system/system.gyp
security/nss/lib/nss/exports.gyp
security/nss/lib/nss/nss.gyp
security/nss/lib/pk11wrap/exports.gyp
security/nss/lib/pk11wrap/pk11wrap.gyp
security/nss/lib/pkcs12/exports.gyp
security/nss/lib/pkcs12/pkcs12.gyp
security/nss/lib/pkcs7/exports.gyp
security/nss/lib/pkcs7/pkcs7.gyp
security/nss/lib/pki/exports.gyp
security/nss/lib/pki/pki.gyp
security/nss/lib/smime/exports.gyp
security/nss/lib/smime/smime.gyp
security/nss/lib/softoken/exports.gyp
security/nss/lib/softoken/legacydb/legacydb.gyp
security/nss/lib/softoken/legacydb/lgattr.c
security/nss/lib/softoken/legacydb/pcertdb.c
security/nss/lib/softoken/softoken.gyp
security/nss/lib/sqlite/exports.gyp
security/nss/lib/sqlite/sqlite.gyp
security/nss/lib/ssl/exports.gyp
security/nss/lib/ssl/ssl.gyp
security/nss/lib/ssl/ssl3con.c
security/nss/lib/ssl/ssl3ecc.c
security/nss/lib/ssl/ssl3prot.h
security/nss/lib/ssl/sslimpl.h
security/nss/lib/ssl/sslinfo.c
security/nss/lib/ssl/sslsock.c
security/nss/lib/ssl/sslt.h
security/nss/lib/ssl/tls13con.c
security/nss/lib/sysinit/sysinit.gyp
security/nss/lib/util/exports.gyp
security/nss/lib/util/util.gyp
security/nss/lib/zlib/exports.gyp
security/nss/lib/zlib/zlib.gyp
security/nss/manifest.mn
security/nss/nss.gyp
security/nss/tests/all.sh
security/nss/tests/ec/ectest.sh
--- a/security/nss/.gitignore
+++ b/security/nss/.gitignore
@@ -1,15 +1,19 @@
 *~
 *.swp
 *OPT.OBJ/
 *DBG.OBJ/
 *DBG.OBJD/
+out/*
+*.pyc
 *.bak
 *.out
 *.rej
 *.patch
 GPATH
 GRTAGS
 GTAGS
 #*
 .#*
 .ycm_extra_conf.py*
+fuzz/libFuzzer/*
+fuzz/corpus
--- a/security/nss/Makefile
+++ b/security/nss/Makefile
@@ -80,16 +80,26 @@ ifdef USE_DEBUG_RTL
 NSPR_CONFIGURE_OPTS += --enable-debug-rtl
 endif
 ifdef USE_STATIC_RTL
 NSPR_CONFIGURE_OPTS += --enable-static-rtl
 endif
 ifdef NS_USE_GCC
 NSPR_CONFIGURE_ENV = CC=gcc CXX=g++
 endif
+ifdef CC
+NSPR_CONFIGURE_ENV = CC=$(CC)
+endif
+ifdef CCC
+NSPR_CONFIGURE_ENV += CXX=$(CCC)
+endif
+# Remove -arch definitions. NSPR can't handle that.
+NSPR_CONFIGURE_ENV := $(filter-out -arch x86_64,$(NSPR_CONFIGURE_ENV))
+NSPR_CONFIGURE_ENV := $(filter-out -arch i386,$(NSPR_CONFIGURE_ENV))
+NSPR_CONFIGURE_ENV := $(filter-out -arch ppc,$(NSPR_CONFIGURE_ENV))
 
 ifdef SANITIZER_CFLAGS
 ifdef BUILD_OPT
 NSPR_CONFIGURE_OPTS += --enable-debug-symbols
 endif
 NSPR_CONFIGURE_ENV += CFLAGS='$(SANITIZER_CFLAGS)' \
                       CXXFLAGS='$(SANITIZER_CFLAGS)' \
                       LDFLAGS='$(SANITIZER_LDFLAGS)'
@@ -111,27 +121,39 @@ USEABSPATH="NO"
 endif
 endif
 ifeq ($(USEABSPATH),"YES")
 NSPR_PREFIX = $(shell pwd)/../dist/$(OBJDIR_NAME)
 else
 NSPR_PREFIX = $$(topsrcdir)/../dist/$(OBJDIR_NAME)
 endif
 
+ifndef NSS_GYP
 $(NSPR_CONFIG_STATUS): $(NSPR_CONFIGURE)
 	mkdir -p $(CORE_DEPTH)/../nspr/$(OBJDIR_NAME)
 	cd $(CORE_DEPTH)/../nspr/$(OBJDIR_NAME) ; \
 	$(NSPR_CONFIGURE_ENV) sh ../configure \
 	$(NSPR_CONFIGURE_OPTS) \
 	--with-dist-prefix='$(NSPR_PREFIX)' \
 	--with-dist-includedir='$(NSPR_PREFIX)/include'
+else
+$(NSPR_CONFIG_STATUS): $(NSPR_CONFIGURE)
+	mkdir -p $(CORE_DEPTH)/../nspr/$(OBJDIR_NAME)
+	cd $(CORE_DEPTH)/../nspr/$(OBJDIR_NAME) ; \
+	$(NSPR_CONFIGURE_ENV) sh ../configure \
+	$(NSPR_CONFIGURE_OPTS) \
+	--prefix='$(NSPR_PREFIX)'
+endif
 
 build_nspr: $(NSPR_CONFIG_STATUS)
 	$(MAKE) -C $(CORE_DEPTH)/../nspr/$(OBJDIR_NAME)
 
+install_nspr: build_nspr
+	$(MAKE) -C $(CORE_DEPTH)/../nspr/$(OBJDIR_NAME) install
+
 clobber_nspr: $(NSPR_CONFIG_STATUS)
 	$(MAKE) -C $(CORE_DEPTH)/../nspr/$(OBJDIR_NAME) clobber
 
 build_docs:
 	$(MAKE) -C $(CORE_DEPTH)/doc
 
 clean_docs:
 	$(MAKE) -C $(CORE_DEPTH)/doc clean
--- a/security/nss/TAG-INFO
+++ b/security/nss/TAG-INFO
@@ -1,1 +1,1 @@
-295feaebef58
+0c845c900217
--- a/security/nss/automation/taskcluster/docker-arm/setup.sh
+++ b/security/nss/automation/taskcluster/docker-arm/setup.sh
@@ -19,20 +19,16 @@ apt_packages+=('zlib1g-dev')
 
 # Install packages.
 apt-get install -y --no-install-recommends ${apt_packages[@]}
 
 # Latest Mercurial.
 pip install --upgrade pip
 pip install Mercurial
 
-# Compiler options.
-update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-5 30
-update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-5 30
-
 locale-gen en_US.UTF-8
 dpkg-reconfigure locales
 
 # Cleanup.
 rm -rf ~/.ccache ~/.cache
 apt-get autoremove -y
 apt-get clean
 apt-get autoclean
--- a/security/nss/automation/taskcluster/docker/setup.sh
+++ b/security/nss/automation/taskcluster/docker/setup.sh
@@ -43,26 +43,16 @@ apt-get -y update
 apt-get install -y --no-install-recommends ${apt_packages[@]}
 
 # 32-bit builds
 ln -s /usr/include/x86_64-linux-gnu/zconf.h /usr/include
 
 # Install clang-3.9 into /usr/local/.
 curl http://llvm.org/releases/3.9.0/clang+llvm-3.9.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz | tar xJv -C /usr/local --strip-components=1
 
-# Compiler options.
-update-alternatives --install /usr/bin/gcc gcc /usr/local/bin/clang 5
-update-alternatives --install /usr/bin/g++ g++ /usr/local/bin/clang++ 5
-update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 10
-update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.8 10
-update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-6 20
-update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-6 20
-update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-5 30
-update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-5 30
-
 locale-gen en_US.UTF-8
 dpkg-reconfigure locales
 
 # Cleanup.
 rm -rf ~/.ccache ~/.cache
 apt-get autoremove -y
 apt-get clean
 apt-get autoclean
--- a/security/nss/automation/taskcluster/graph/src/extend.js
+++ b/security/nss/automation/taskcluster/graph/src/extend.js
@@ -9,47 +9,70 @@ const LINUX_IMAGE = {name: "linux", path
 
 const WINDOWS_CHECKOUT_CMD =
   "bash -c \"hg clone -r $NSS_HEAD_REVISION $NSS_HEAD_REPOSITORY nss || " +
     "(sleep 2; hg clone -r $NSS_HEAD_REVISION $NSS_HEAD_REPOSITORY nss) || " +
     "(sleep 5; hg clone -r $NSS_HEAD_REVISION $NSS_HEAD_REPOSITORY nss)\"";
 
 /*****************************************************************************/
 
+function isSanitizer(task) {
+  return task.collection == "asan" || task.collection == "ubsan";
+}
+
 queue.filter(task => {
   if (task.group == "Builds") {
-    // Remove extra builds on ASan and ARM.
-    if (task.collection == "asan" || task.collection == "arm-debug") {
+    // Remove extra builds on UBSan and ARM.
+    if (task.collection == "ubsan" || task.collection == "arm-debug") {
       return false;
     }
 
-    // Remove extra builds w/o libpkix for non-linux64-debug.
-    if (task.symbol == "noLibpkix" &&
-        (task.platform != "linux64" || task.collection != "debug")) {
+    // Remove extra builds w/o libpkix for non-asan.
+    if (task.symbol == "noLibpkix" && task.collection != "asan") {
+      return false;
+    }
+
+    // Remove extra builds w/ clang-3.9 on ASan.
+    if (task.symbol == "clang-3.9" && task.collection == "asan") {
+      return false;
+    }
+
+    // Remove extra builds w/ gcc-5 on non-ASan.
+    if (task.symbol == "gcc-5" && task.collection != "asan") {
+      return false;
+    }
+
+    // Remove extra builds on gyp builds (TODO: add when it supports CC/CCC).
+    if (task.collection == "gyp") {
       return false;
     }
   }
 
   if (task.tests == "bogo") {
     // No BoGo tests on Windows.
     if (task.platform == "windows2012-64") {
       return false;
     }
 
     // No BoGo tests on ARM.
     if (task.collection == "arm-debug") {
       return false;
     }
   }
 
+  // Start with BoGo on UBSan builds.
+  if (task.collection == "ubsan" && task.tests && task.tests != "bogo") {
+    return false;
+  }
+
   return true;
 });
 
 queue.map(task => {
-  if (task.collection == "asan") {
+  if (isSanitizer(task)) {
     // CRMF and FIPS tests still leak, unfortunately.
     if (task.tests == "crmf" || task.tests == "fips") {
       task.env.ASAN_OPTIONS = "detect_leaks=0";
     }
 
     // SSL(standard) runs on ASan take some time.
     if (task.tests == "ssl" && task.cycle == "standard") {
       task.maxRunTime = 7200;
@@ -86,37 +109,58 @@ export default async function main() {
   });
 
   await scheduleLinux("Linux 64 (opt)", {
     env: {USE_64: "1", BUILD_OPT: "1"},
     platform: "linux64",
     image: LINUX_IMAGE
   });
 
-  await scheduleLinux("Linux 64 (debug)", {
+  await scheduleLinux("Linux 64 (debug, gyp)", {
+    command: [
+      "/bin/bash",
+      "-c",
+      "bin/checkout.sh && nss/automation/taskcluster/scripts/build_gyp.sh"
+    ],
     env: {USE_64: "1"},
     platform: "linux64",
-    collection: "debug",
+    collection: "gyp",
     image: LINUX_IMAGE
   });
 
   await scheduleLinux("Linux 64 (ASan, debug)", {
     env: {
       NSS_DISABLE_ARENA_FREE_LIST: "1",
       NSS_DISABLE_UNLOAD: "1",
-      GCC_VERSION: "clang",
-      GXX_VERSION: "clang++",
+      CC: "clang",
+      CCC: "clang++",
       USE_ASAN: "1",
       USE_64: "1"
     },
     platform: "linux64",
     collection: "asan",
     image: LINUX_IMAGE
   });
 
+  await scheduleLinux("Linux 64 (ASan+UBSan, debug)", {
+    env: {
+      UBSAN_OPTIONS: "print_stacktrace=1",
+      NSS_DISABLE_ARENA_FREE_LIST: "1",
+      NSS_DISABLE_UNLOAD: "1",
+      CC: "clang",
+      CCC: "clang++",
+      USE_UBSAN: "1",
+      USE_ASAN: "1",
+      USE_64: "1"
+    },
+    platform: "linux64",
+    collection: "ubsan",
+    image: LINUX_IMAGE
+  });
+
   await scheduleWindows("Windows 2012 64 (opt)", {
     env: {BUILD_OPT: "1"}
   });
 
   await scheduleWindows("Windows 2012 64 (debug)", {
     collection: "debug"
   });
 
@@ -132,32 +176,32 @@ export default async function main() {
     tier: 3
   });
 }
 
 /*****************************************************************************/
 
 async function scheduleLinux(name, base) {
   // Build base definition.
-  let build_base = merge(base, {
+  let build_base = merge({
     command: [
       "/bin/bash",
       "-c",
       "bin/checkout.sh && nss/automation/taskcluster/scripts/build.sh"
     ],
     artifacts: {
       public: {
         expires: 24 * 7,
         type: "directory",
         path: "/home/worker/artifacts"
       }
     },
     kind: "build",
     symbol: "B"
-  });
+  }, base);
 
   // The task that builds NSPR+NSS.
   let task_build = queue.scheduleTask(merge(build_base, {name}));
 
   // The task that generates certificates.
   let task_cert = queue.scheduleTask(merge(build_base, {
     name: "Certificates",
     command: [
@@ -178,36 +222,45 @@ async function scheduleLinux(name, base)
     ]
   }));
 
   // Extra builds.
   let extra_base = merge({group: "Builds"}, build_base);
   queue.scheduleTask(merge(extra_base, {
     name: `${name} w/ clang-3.9`,
     env: {
-      GCC_VERSION: "clang",
-      GXX_VERSION: "clang++"
+      CC: "clang",
+      CCC: "clang++",
     },
     symbol: "clang-3.9"
   }));
 
   queue.scheduleTask(merge(extra_base, {
     name: `${name} w/ gcc-4.8`,
     env: {
-      GCC_VERSION: "gcc-4.8",
-      GXX_VERSION: "g++-4.8"
+      CC: "gcc-4.8",
+      CCC: "g++-4.8"
     },
     symbol: "gcc-4.8"
   }));
 
   queue.scheduleTask(merge(extra_base, {
+    name: `${name} w/ gcc-5`,
+    env: {
+      CC: "gcc-5",
+      CCC: "g++-5"
+    },
+    symbol: "gcc-5"
+  }));
+
+  queue.scheduleTask(merge(extra_base, {
     name: `${name} w/ gcc-6.1`,
     env: {
-      GCC_VERSION: "gcc-6",
-      GXX_VERSION: "g++-6"
+      CC: "gcc-6",
+      CCC: "g++-6"
     },
     symbol: "gcc-6.1"
   }));
 
   queue.scheduleTask(merge(extra_base, {
     name: `${name} w/ NSS_DISABLE_LIBPKIX=1`,
     env: {NSS_DISABLE_LIBPKIX: "1"},
     symbol: "noLibpkix"
@@ -360,18 +413,18 @@ async function scheduleTools() {
     ]
   }));
 
   queue.scheduleTask(merge(base, {
     symbol: "scan-build-3.9",
     name: "scan-build-3.9",
     env: {
       USE_64: "1",
-      GCC_VERSION: "clang",
-      GXX_VERSION: "clang++"
+      CC: "clang",
+      CCC: "clang++",
     },
     artifacts: {
       public: {
         expires: 24 * 7,
         type: "directory",
         path: "/home/worker/artifacts"
       }
     },
--- a/security/nss/automation/taskcluster/graph/src/try_syntax.js
+++ b/security/nss/automation/taskcluster/graph/src/try_syntax.js
@@ -17,17 +17,17 @@ function parseOptions(opts) {
   let builds = intersect(opts.build.split(""), ["d", "o"]);
 
   // If the given value is nonsense default to debug and opt builds.
   if (builds.length == 0) {
     builds = ["d", "o"];
   }
 
   // Parse platforms.
-  let allPlatforms = ["linux", "linux64", "linux64-asan", "win64", "arm"];
+  let allPlatforms = ["linux", "linux64", "win64", "arm", "linux64-gyp"];
   let platforms = intersect(opts.platform.split(/\s*,\s*/), allPlatforms);
 
   // If the given value is nonsense or "none" default to all platforms.
   if (platforms.length == 0 && opts.platform != "none") {
     platforms = allPlatforms;
   }
 
   // Parse unit tests.
@@ -95,42 +95,42 @@ function filter(opts) {
     }
 
     let coll = name => name == (task.collection || "opt");
 
     // Filter by platform.
     let found = opts.platforms.some(platform => {
       let aliases = {
         "linux": "linux32",
-        "linux64-asan": "linux64",
+        "linux64-gyp": "linux64",
         "win64": "windows2012-64",
         "arm": "linux32"
       };
 
       // Check the platform name.
       let keep = (task.platform == (aliases[platform] || platform));
 
       // Additional checks.
-      if (platform == "linux64-asan") {
-        keep &= coll("asan");
-      } else if (platform == "arm") {
+      if (platform == "arm") {
         keep &= coll("arm-opt") || coll("arm-debug");
+      } else if (platform == "linux64-gyp") {
+        keep &= coll("gyp");
       } else {
-        keep &= coll("opt") || coll("debug");
+        keep &= coll("opt") || coll("debug") || coll("asan") || coll("ubsan");
       }
 
       return keep;
     });
 
     if (!found) {
       return false;
     }
 
     // Finally, filter by build type.
-    let isDebug = coll("debug") || coll("asan") || coll("arm-debug");
+    let isDebug = coll("debug") || coll("asan") || coll("ubsan") || coll("arm-debug") || coll("gyp");
     return (isDebug && opts.builds.includes("d")) ||
            (!isDebug && opts.builds.includes("o"));
   }
 }
 
 export function initFilter() {
   let comment = process.env.TC_COMMENT || "";
 
--- a/security/nss/automation/taskcluster/scripts/build.sh
+++ b/security/nss/automation/taskcluster/scripts/build.sh
@@ -1,16 +1,13 @@
 #!/usr/bin/env bash
 
 source $(dirname $0)/tools.sh
 
 if [[ $(id -u) -eq 0 ]]; then
-    # Set compiler.
-    switch_compilers
-
     # Drop privileges by re-running this script.
     exec su worker $0
 fi
 
 # Clone NSPR if needed.
 hg_clone https://hg.mozilla.org/projects/nspr nspr default
 
 # Build.
new file mode 100755
--- /dev/null
+++ b/security/nss/automation/taskcluster/scripts/build_gyp.sh
@@ -0,0 +1,21 @@
+#!/usr/bin/env bash
+
+source $(dirname $0)/tools.sh
+
+if [[ $(id -u) -eq 0 ]]; then
+    # Drop privileges by re-running this script.
+    exec su worker $0
+fi
+
+# Clone NSPR if needed.
+hg_clone https://hg.mozilla.org/projects/nspr nspr default
+
+# Build.
+cd nss && NSS_GYP_GEN=1 ./build.sh
+if [ $? != 0 ]; then
+    exit 1
+fi
+
+# Package.
+cd .. && mkdir artifacts
+tar cvfjh artifacts/dist.tar.bz2 dist
--- a/security/nss/automation/taskcluster/scripts/gen_certs.sh
+++ b/security/nss/automation/taskcluster/scripts/gen_certs.sh
@@ -1,18 +1,15 @@
 #!/usr/bin/env bash
 
 set -v -e -x
 
 source $(dirname $0)/tools.sh
 
 if [ $(id -u) = 0 ]; then
-    # Set compiler.
-    switch_compilers
-
     # Stupid Docker.
     echo "127.0.0.1 localhost.localdomain" >> /etc/hosts
 
     # Drop privileges by re-running this script.
     exec su worker $0
 fi
 
 # Fetch artifact if needed.
--- a/security/nss/automation/taskcluster/scripts/run_scan_build.sh
+++ b/security/nss/automation/taskcluster/scripts/run_scan_build.sh
@@ -1,17 +1,13 @@
 #!/usr/bin/env bash
 
 source $(dirname $0)/tools.sh
 
 if [ $(id -u) = 0 ]; then
-
-    # Set compiler.
-    switch_compilers
-
     # Drop privileges by re-running this script.
     exec su worker $0 $@
 fi
 
 # Clone NSPR if needed.
 if [ ! -d "nspr" ]; then
     hg_clone https://hg.mozilla.org/projects/nspr nspr default
 fi
@@ -30,17 +26,17 @@ declare -A scan=( \
     )
 
 # remove .OBJ directories to force a rebuild of just the select few
 for i in "${!scan[@]}"; do
    find "$i" -name "*.OBJ" -exec rm -rf {} \+
 done
 
 # run scan-build (only building affected directories)
-scan-build -o /home/worker/artifacts make nss_build_all && cd ..
+scan-build -o /home/worker/artifacts --use-cc=$(CC) --use-c++=$(CCC) make nss_build_all && cd ..
 
 # print errors we found
 set +v +x
 STATUS=0
 for i in "${!scan[@]}"; do
    n=$(grep -Rn "$i" /home/worker/artifacts/*/report-*.html | wc -l)
    if [ $n -ne ${scan[$i]} ]; then
      STATUS=1
--- a/security/nss/automation/taskcluster/scripts/run_tests.sh
+++ b/security/nss/automation/taskcluster/scripts/run_tests.sh
@@ -1,16 +1,13 @@
 #!/usr/bin/env bash
 
 source $(dirname $0)/tools.sh
 
 if [ $(id -u) = 0 ]; then
-    # Set compiler.
-    switch_compilers
-
     # Stupid Docker.
     echo "127.0.0.1 localhost.localdomain" >> /etc/hosts
 
     # Drop privileges by re-running this script.
     exec su worker $0
 fi
 
 # Fetch artifact if needed.
--- a/security/nss/automation/taskcluster/scripts/tools.sh
+++ b/security/nss/automation/taskcluster/scripts/tools.sh
@@ -1,25 +1,12 @@
 #!/usr/bin/env bash
 
 set -v -e -x
 
-switch_compilers() {
-    GCC=`which ${GCC_VERSION:-gcc-5}`
-    GXX=`which ${GXX_VERSION:-g++-5}`
-
-    if [ -e "$GCC" ] && [ -e "$GXX" ]; then
-        update-alternatives --set gcc $GCC
-        update-alternatives --set g++ $GXX
-    else
-        echo "Unknown compiler $GCC_VERSION/$GXX_VERSION."
-        exit 1
-    fi
-}
-
 # Usage: hg_clone repo dir [revision=@]
 hg_clone() {
     repo=$1
     dir=$2
     rev=${3:-@}
     for i in 0 2 5; do
         sleep $i
         hg clone -r "$rev" "$repo" "$dir" && return
new file mode 100755
--- /dev/null
+++ b/security/nss/build.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+
+CWD="$PWD/$(dirname $0)"
+OBJ_DIR="$(make platform)"
+DIST_DIR="$CWD/../dist/$OBJ_DIR"
+
+# do NSPR things
+NSS_GYP=1 make install_nspr
+
+if [ -z "${USE_64}" ]; then
+    GYP_PARAMS="-Dtarget_arch=ia32"
+fi
+
+# generate NSS build files only if asked for it
+if [ -n "${NSS_GYP_GEN}" -o ! -d out/Debug ]; then
+    PKG_CONFIG_PATH="$CWD/../nspr/$OBJ_DIR/config" gyp -f ninja $GYP_PARAMS --depth=. nss.gyp
+fi
+# build NSS
+# TODO: only doing this for debug build for now
+ninja -C out/Debug/
+if [ $? != 0 ]; then
+    exit 1
+fi
+
+# sign libs
+# TODO: this is done every time at the moment.
+cd out/Debug/
+LD_LIBRARY_PATH=$DIST_DIR/lib/ ./shlibsign -v -i lib/libfreebl3.so
+LD_LIBRARY_PATH=$DIST_DIR/lib/ ./shlibsign -v -i lib/libfreeblpriv3.so
+LD_LIBRARY_PATH=$DIST_DIR/lib/ ./shlibsign -v -i lib/libnssdbm3.so
+LD_LIBRARY_PATH=$DIST_DIR/lib/ ./shlibsign -v -i lib/libsoftokn3.so
+
+# copy files over to the right directory
+cp * "$DIST_DIR/bin/"
+cp lib/* "$DIST_DIR/lib/"
+find . -name "*.a" | xargs cp -t "$DIST_DIR/lib/"
--- a/security/nss/cmd/Makefile
+++ b/security/nss/cmd/Makefile
@@ -12,23 +12,23 @@ include $(CORE_DEPTH)/coreconf/config.mk
 
 ifdef BUILD_LIBPKIX_TESTS
 DIRS += libpkix
 endif
 
 ifeq ($(NSS_BUILD_WITHOUT_SOFTOKEN),1)
 BLTEST_SRCDIR =
 ECPERF_SRCDIR =
-ECTEST_SRCDIR =
+FREEBL_ECTEST_SRCDIR =
 FIPSTEST_SRCDIR =
 SHLIBSIGN_SRCDIR =
 else
 BLTEST_SRCDIR = bltest
 ECPERF_SRCDIR = ecperf
-ECTEST_SRCDIR = ectest
+FREEBL_ECTEST_SRCDIR = fbectest
 FIPSTEST_SRCDIR = fipstest
 SHLIBSIGN_SRCDIR = shlibsign
 endif
 
 LOWHASHTEST_SRCDIR=
 ifeq ($(FREEBL_LOWHASH),1)
 LOWHASHTEST_SRCDIR = lowhashtest  # Add the lowhashtest directory to DIRS.
 endif
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/addbuiltin/addbuiltin.gyp
@@ -0,0 +1,24 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    '../../cmd/platlibs.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'addbuiltin',
+      'type': 'executable',
+      'sources': [
+        'addbuiltin.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ]
+    }
+  ],
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/atob/atob.gyp
@@ -0,0 +1,30 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    '../../cmd/platlibs.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'atob',
+      'type': 'executable',
+      'sources': [
+        'atob.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:dbm_exports',
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ]
+    }
+  ],
+  'target_defaults': {
+    'defines': [
+      'NSPR20'
+    ]
+  },
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/bltest.gyp
@@ -0,0 +1,35 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    '../../cmd/platlibs.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'bltest',
+      'type': 'executable',
+      'sources': [
+        'blapitest.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:dbm_exports',
+        '<(DEPTH)/exports.gyp:nss_exports',
+        '<(DEPTH)/lib/sqlite/sqlite.gyp:sqlite3'
+      ]
+    }
+  ],
+  'target_defaults': {
+    'include_dirs': [
+      '../../nss/lib/softoken'
+    ],
+    'defines': [
+      'NSS_USE_STATIC_LIBS'
+    ]
+  },
+  'variables': {
+    'module': 'nss',
+    'use_static_libs': 1
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/btoa/btoa.gyp
@@ -0,0 +1,30 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    '../../cmd/platlibs.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'btoa',
+      'type': 'executable',
+      'sources': [
+        'btoa.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:dbm_exports',
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ]
+    }
+  ],
+  'target_defaults': {
+    'defines': [
+      'NSPR20'
+    ]
+  },
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/certcgi/certcgi.gyp
@@ -0,0 +1,33 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    '../../cmd/platlibs.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'certcgi',
+      'type': 'executable',
+      'sources': [
+        'certcgi.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:dbm_exports',
+        '<(DEPTH)/exports.gyp:nss_exports',
+        '<(DEPTH)/lib/sqlite/sqlite.gyp:sqlite3'
+      ]
+    }
+  ],
+  'target_defaults': {
+    'defines': [
+      'NSPR20',
+      'NSS_USE_STATIC_LIBS'
+    ]
+  },
+  'variables': {
+    'module': 'nss',
+    'use_static_libs': 1
+  }
+}
\ No newline at end of file
--- a/security/nss/cmd/certutil/certext.c
+++ b/security/nss/cmd/certutil/certext.c
@@ -1235,20 +1235,25 @@ AddCrlDistPoint(void *extHandle)
 
         if (crlDistPoints == NULL) {
             crlDistPoints = PORT_ArenaZNew(arena, CERTCrlDistributionPoints);
             if (crlDistPoints == NULL) {
                 GEN_BREAK(SECFailure);
             }
         }
 
-        crlDistPoints->distPoints =
-            PORT_ArenaGrow(arena, crlDistPoints->distPoints,
-                           sizeof(*crlDistPoints->distPoints) * count,
-                           sizeof(*crlDistPoints->distPoints) * (count + 1));
+        if (crlDistPoints->distPoints) {
+            crlDistPoints->distPoints =
+                PORT_ArenaGrow(arena, crlDistPoints->distPoints,
+                               sizeof(*crlDistPoints->distPoints) * count,
+                               sizeof(*crlDistPoints->distPoints) * (count + 1));
+        } else {
+            crlDistPoints->distPoints =
+                PORT_ArenaZAlloc(arena, sizeof(*crlDistPoints->distPoints) * (count + 1));
+        }
         if (crlDistPoints->distPoints == NULL) {
             GEN_BREAK(SECFailure);
         }
 
         crlDistPoints->distPoints[count] = current;
         ++count;
         if (GetYesNo("Enter another value for the CRLDistributionPoint "
                      "extension [y/N]?") == 0) {
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/certutil/certutil.gyp
@@ -0,0 +1,32 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    '../../cmd/platlibs.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'certutil',
+      'type': 'executable',
+      'sources': [
+        'certext.c',
+        'certutil.c',
+        'keystuff.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:dbm_exports',
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ]
+    }
+  ],
+  'target_defaults': {
+    'defines': [
+      'NSPR20'
+    ]
+  },
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/chktest/chktest.gyp
@@ -0,0 +1,32 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    '../../cmd/platlibs.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'chktest',
+      'type': 'executable',
+      'sources': [
+        'chktest.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:dbm_exports',
+        '<(DEPTH)/exports.gyp:nss_exports',
+        '<(DEPTH)/lib/sqlite/sqlite.gyp:sqlite3'
+      ]
+    }
+  ],
+  'target_defaults': {
+    'defines': [
+      'NSS_USE_STATIC_LIBS'
+    ]
+  },
+  'variables': {
+    'module': 'nss',
+    'use_static_libs': 1
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/crlutil/crlutil.gyp
@@ -0,0 +1,32 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    '../../cmd/platlibs.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'crlutil',
+      'type': 'executable',
+      'sources': [
+        'crlgen.c',
+        'crlgen_lex.c',
+        'crlutil.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:dbm_exports',
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ]
+    }
+  ],
+  'target_defaults': {
+    'defines': [
+      'NSPR20'
+    ]
+  },
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/crmftest/crmftest.gyp
@@ -0,0 +1,25 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    '../../cmd/platlibs.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'crmftest',
+      'type': 'executable',
+      'sources': [
+        'testcrmf.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:nss_exports',
+        '<(DEPTH)/lib/crmf/crmf.gyp:crmf'
+      ]
+    }
+  ],
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/dbtest/dbtest.gyp
@@ -0,0 +1,25 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    '../../cmd/platlibs.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'dbtest',
+      'type': 'executable',
+      'sources': [
+        'dbtest.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:dbm_exports',
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ]
+    }
+  ],
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/derdump/derdump.gyp
@@ -0,0 +1,30 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    '../../cmd/platlibs.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'derdump',
+      'type': 'executable',
+      'sources': [
+        'derdump.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:dbm_exports',
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ]
+    }
+  ],
+  'target_defaults': {
+    'defines': [
+      'NSPR20'
+    ]
+  },
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/digest/digest.gyp
@@ -0,0 +1,30 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    '../../cmd/platlibs.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'digest',
+      'type': 'executable',
+      'sources': [
+        'digest.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:dbm_exports',
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ]
+    }
+  ],
+  'target_defaults': {
+    'defines': [
+      'NSPR20'
+    ]
+  },
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
--- a/security/nss/cmd/ecperf/ecperf.c
+++ b/security/nss/cmd/ecperf/ecperf.c
@@ -4,17 +4,16 @@
 
 #include "blapi.h"
 #include "ec.h"
 #include "ecl-curve.h"
 #include "prprf.h"
 #include "basicutil.h"
 #include "pkcs11.h"
 #include "nspr.h"
-#include "certt.h" /* TODO: remove when old curves are removed */
 #include <stdio.h>
 
 #define __PASTE(x, y) x##y
 
 /*
  * Get the NSS specific PKCS #11 function names.
  */
 #undef CK_PKCS11_FUNCTION_INFO
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/ecperf/ecperf.gyp
@@ -0,0 +1,35 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    '../../cmd/platlibs.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'ecperf',
+      'type': 'executable',
+      'sources': [
+        'ecperf.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:dbm_exports',
+        '<(DEPTH)/exports.gyp:nss_exports',
+        '<(DEPTH)/lib/sqlite/sqlite.gyp:sqlite3'
+      ]
+    }
+  ],
+  'target_defaults': {
+    'include_dirs': [
+      '../../nss/lib/softoken'
+    ],
+    'defines': [
+      'NSS_USE_STATIC_LIBS'
+    ]
+  },
+  'variables': {
+    'module': 'nss',
+    'use_static_libs': 1
+  }
+}
\ No newline at end of file
deleted file mode 100644
--- a/security/nss/cmd/ectest/ectest.c
+++ /dev/null
@@ -1,434 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "blapi.h"
-#include "ec.h"
-#include "ecl-curve.h"
-#include "nss.h"
-#include "secutil.h"
-#include "secitem.h"
-#include "nspr.h"
-#include "pk11pub.h"
-#include <stdio.h>
-
-typedef struct {
-    ECCurveName curve;
-    int iterations;
-    char *privhex;
-    char *our_pubhex;
-    char *their_pubhex;
-    char *common_key;
-    char *name;
-    ECFieldType fieldType;
-} ECDH_KAT;
-
-typedef struct {
-    ECCurveName curve;
-    char *point;
-    char *name;
-    ECFieldType fieldType;
-} ECDH_BAD;
-
-#include "testvecs.h"
-
-/*
- * Initializes a SECItem from a hexadecimal string
- *
- */
-static SECItem *
-hexString2SECItem(PLArenaPool *arena, SECItem *item, const char *str)
-{
-    int i = 0;
-    int byteval = 0;
-    int tmp = PORT_Strlen(str);
-
-    PORT_Assert(arena);
-    PORT_Assert(item);
-
-    if ((tmp % 2) != 0) {
-        return NULL;
-    }
-
-    item = SECITEM_AllocItem(arena, item, tmp / 2);
-    if (item == NULL) {
-        return NULL;
-    }
-
-    while (str[i]) {
-        if ((str[i] >= '0') && (str[i] <= '9')) {
-            tmp = str[i] - '0';
-        } else if ((str[i] >= 'a') && (str[i] <= 'f')) {
-            tmp = str[i] - 'a' + 10;
-        } else if ((str[i] >= 'A') && (str[i] <= 'F')) {
-            tmp = str[i] - 'A' + 10;
-        } else {
-            /* item is in arena and gets freed by the caller */
-            return NULL;
-        }
-
-        byteval = byteval * 16 + tmp;
-        if ((i % 2) != 0) {
-            item->data[i / 2] = byteval;
-            byteval = 0;
-        }
-        i++;
-    }
-
-    return item;
-}
-
-void
-printBuf(const SECItem *item)
-{
-    int i;
-    if (!item || !item->len) {
-        printf("(null)\n");
-        return;
-    }
-
-    for (i = 0; i < item->len; i++) {
-        printf("%02x", item->data[i]);
-    }
-    printf("\n");
-}
-
-/* Initialise test with basic curve populate with only the necessary things */
-SECStatus
-init_params(ECParams *ecParams, ECCurveName curve, PLArenaPool **arena,
-            ECFieldType type)
-{
-    if ((curve < ECCurve_noName) || (curve > ECCurve_pastLastCurve)) {
-        return SECFailure;
-    }
-    *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
-    if (!*arena) {
-        return SECFailure;
-    }
-    ecParams->name = curve;
-    ecParams->type = ec_params_named;
-    ecParams->curveOID.data = NULL;
-    ecParams->curveOID.len = 0;
-    ecParams->curve.seed.data = NULL;
-    ecParams->curve.seed.len = 0;
-    ecParams->DEREncoding.data = NULL;
-    ecParams->DEREncoding.len = 0;
-    ecParams->arena = *arena;
-    ecParams->fieldID.size = ecCurve_map[curve]->size;
-    ecParams->fieldID.type = type;
-    ecParams->cofactor = ecCurve_map[curve]->cofactor;
-    ecParams->pointSize = ecCurve_map[curve]->pointSize;
-
-    return SECSuccess;
-}
-
-SECStatus
-ectest_ecdh_kat(ECDH_KAT *kat)
-{
-    ECCurveName curve = kat->curve;
-    ECParams ecParams = { 0 };
-    ECPrivateKey *ecPriv = NULL;
-    SECItem theirKey = { siBuffer, NULL, 0 };
-    SECStatus rv = SECFailure;
-    PLArenaPool *arena = NULL;
-    SECItem seed = { siBuffer, NULL, 0 };
-    SECItem answer = { siBuffer, NULL, 0 };
-    SECItem answer2 = { siBuffer, NULL, 0 };
-    SECItem derived = { siBuffer, NULL, 0 };
-    char genenc[3 + 2 * 2 * MAX_ECKEY_LEN];
-    int i;
-
-    rv = init_params(&ecParams, curve, &arena, kat->fieldType);
-    if (rv != SECSuccess) {
-        return rv;
-    }
-
-    hexString2SECItem(arena, &ecParams.fieldID.u.prime, ecCurve_map[curve]->irr);
-    hexString2SECItem(arena, &ecParams.curve.a, ecCurve_map[curve]->curvea);
-    hexString2SECItem(arena, &ecParams.curve.b, ecCurve_map[curve]->curveb);
-    genenc[0] = '0';
-    genenc[1] = '4';
-    genenc[2] = '\0';
-    PORT_Assert(PR_ARRAY_SIZE(genenc) >= PORT_Strlen(ecCurve_map[curve]->genx));
-    PORT_Assert(PR_ARRAY_SIZE(genenc) >= PORT_Strlen(ecCurve_map[curve]->geny));
-    strcat(genenc, ecCurve_map[curve]->genx);
-    strcat(genenc, ecCurve_map[curve]->geny);
-    hexString2SECItem(arena, &ecParams.base, genenc);
-    hexString2SECItem(arena, &ecParams.order, ecCurve_map[curve]->order);
-
-    if (kat->our_pubhex) {
-        hexString2SECItem(arena, &answer, kat->our_pubhex);
-    }
-    hexString2SECItem(arena, &seed, kat->privhex);
-    rv = EC_NewKeyFromSeed(&ecParams, &ecPriv, seed.data, seed.len);
-    if (rv != SECSuccess) {
-        rv = SECFailure;
-        goto cleanup;
-    }
-    if (kat->our_pubhex) {
-        if (SECITEM_CompareItem(&answer, &ecPriv->publicValue) != SECEqual) {
-            rv = SECFailure;
-            goto cleanup;
-        }
-    }
-
-    hexString2SECItem(arena, &theirKey, kat->their_pubhex);
-    hexString2SECItem(arena, &answer2, kat->common_key);
-
-    rv = EC_ValidatePublicKey(&ecParams, &theirKey);
-    if (rv != SECSuccess) {
-        printf("EC_ValidatePublicKey failed\n");
-        goto cleanup;
-    }
-
-    for (i = 0; i < kat->iterations; ++i) {
-        rv = ECDH_Derive(&theirKey, &ecParams, &ecPriv->privateValue, PR_TRUE, &derived);
-        if (rv != SECSuccess) {
-            rv = SECFailure;
-            goto cleanup;
-        }
-        rv = SECITEM_CopyItem(ecParams.arena, &theirKey, &ecPriv->privateValue);
-        if (rv != SECSuccess) {
-            goto cleanup;
-        }
-        rv = SECITEM_CopyItem(ecParams.arena, &ecPriv->privateValue, &derived);
-        if (rv != SECSuccess) {
-            goto cleanup;
-        }
-        SECITEM_FreeItem(&derived, PR_FALSE);
-    }
-
-    if (SECITEM_CompareItem(&answer2, &ecPriv->privateValue) != SECEqual) {
-        printf("expected: ");
-        printBuf(&answer2);
-        printf("derived:  ");
-        printBuf(&ecPriv->privateValue);
-        rv = SECFailure;
-        goto cleanup;
-    }
-
-cleanup:
-    PORT_FreeArena(arena, PR_FALSE);
-    if (ecPriv) {
-        PORT_FreeArena(ecPriv->ecParams.arena, PR_FALSE);
-    }
-    if (derived.data) {
-        SECITEM_FreeItem(&derived, PR_FALSE);
-    }
-    return rv;
-}
-
-void
-PrintKey(PK11SymKey *symKey)
-{
-    char *name = PK11_GetSymKeyNickname(symKey);
-    int len = PK11_GetKeyLength(symKey);
-    int strength = PK11_GetKeyStrength(symKey, NULL);
-    SECItem *value = NULL;
-    CK_KEY_TYPE type = PK11_GetSymKeyType(symKey);
-    (void)PK11_ExtractKeyValue(symKey);
-
-    value = PK11_GetKeyData(symKey);
-    printf("%s %3d   %4d   %s  ", name ? name : "no-name", len, strength,
-           type == CKK_GENERIC_SECRET ? "generic" : "ERROR! UNKNOWN KEY TYPE");
-    printBuf(value);
-
-    PORT_Free(name);
-}
-
-SECStatus
-ectest_curve_pkcs11(SECOidTag oid)
-{
-    SECKEYECParams pk_11_ecParams = { siBuffer, NULL, 0 };
-    SECKEYPublicKey *pubKey = NULL;
-    SECKEYPrivateKey *privKey = NULL;
-    SECOidData *oidData = NULL;
-    CK_MECHANISM_TYPE target = CKM_TLS12_MASTER_KEY_DERIVE_DH;
-    PK11SymKey *symKey = NULL;
-    SECStatus rv = SECFailure;
-
-    oidData = SECOID_FindOIDByTag(oid);
-    if (oidData == NULL) {
-        printf(" >>> SECOID_FindOIDByTag failed.\n");
-        goto cleanup;
-    }
-    PORT_Assert(oidData->oid.len < 256);
-    SECITEM_AllocItem(NULL, &pk_11_ecParams, (2 + oidData->oid.len));
-    pk_11_ecParams.data[0] = SEC_ASN1_OBJECT_ID; /* we have to prepend 0x06 */
-    pk_11_ecParams.data[1] = oidData->oid.len;
-    memcpy(pk_11_ecParams.data + 2, oidData->oid.data, oidData->oid.len);
-
-    privKey = SECKEY_CreateECPrivateKey(&pk_11_ecParams, &pubKey, NULL);
-    if (!privKey || !pubKey) {
-        printf(" >>> SECKEY_CreateECPrivateKey failed.\n");
-        goto cleanup;
-    }
-
-    symKey = PK11_PubDeriveWithKDF(privKey, pubKey, PR_FALSE, NULL, NULL,
-                                   CKM_ECDH1_DERIVE, target, CKA_DERIVE, 0,
-                                   CKD_NULL, NULL, NULL);
-    if (!symKey) {
-        printf(" >>> PK11_PubDeriveWithKDF failed.\n");
-        goto cleanup;
-    }
-    PrintKey(symKey);
-    rv = SECSuccess;
-
-cleanup:
-    if (privKey) {
-        SECKEY_DestroyPrivateKey(privKey);
-    }
-    if (pubKey) {
-        SECKEY_DestroyPublicKey(pubKey);
-    }
-    if (symKey) {
-        PK11_FreeSymKey(symKey);
-    }
-    SECITEM_FreeItem(&pk_11_ecParams, PR_FALSE);
-
-    return rv;
-}
-
-SECStatus
-ectest_validate_point(ECDH_BAD *bad)
-{
-    ECParams ecParams = { 0 };
-    SECItem point = { siBuffer, NULL, 0 };
-    SECStatus rv = SECFailure;
-    PLArenaPool *arena = NULL;
-
-    rv = init_params(&ecParams, bad->curve, &arena, bad->fieldType);
-    if (rv != SECSuccess) {
-        return rv;
-    }
-
-    hexString2SECItem(arena, &point, bad->point);
-    rv = EC_ValidatePublicKey(&ecParams, &point);
-
-    PORT_FreeArena(arena, PR_FALSE);
-    return rv;
-}
-
-void
-printUsage(char *prog)
-{
-    printf("Usage: %s [-fp] [-nd]\n"
-           "\t-f: usefreebl\n"
-           "\t-p: usepkcs11\n"
-           "\t-n: NIST curves\n"
-           "\t-d: non-NIST curves\n"
-           "You have to specify at least f or p and n or d.\n"
-           "By default no tests are executed.\n",
-           prog);
-}
-
-/* Performs tests of elliptic curve cryptography over prime fields If
- * tests fail, then it prints an error message, aborts, and returns an
- * error code. Otherwise, returns 0. */
-int
-main(int argv, char **argc)
-{
-    SECStatus rv = SECSuccess;
-    int numkats = 0;
-    int i = 0;
-    int usepkcs11 = 0;
-    int usefreebl = 0;
-    int nist = 0;
-    int nonnist = 0;
-    SECOidTag nistOids[3] = { SEC_OID_SECG_EC_SECP256R1,
-                              SEC_OID_SECG_EC_SECP384R1,
-                              SEC_OID_SECG_EC_SECP521R1 };
-
-    for (i = 1; i < argv; i++) {
-        if (PL_strcasecmp(argc[i], "-p") == 0) {
-            usepkcs11 = 1;
-        } else if (PL_strcasecmp(argc[i], "-f") == 0) {
-            usefreebl = 1;
-        } else if (PL_strcasecmp(argc[i], "-n") == 0) {
-            nist = 1;
-        } else if (PL_strcasecmp(argc[i], "-d") == 0) {
-            nonnist = 1;
-        } else {
-            printUsage(argc[0]);
-            return 1;
-        }
-    }
-    if (!(usepkcs11 || usefreebl) || !(nist || nonnist)) {
-        printUsage(argc[0]);
-        return 1;
-    }
-
-    rv = NSS_NoDB_Init(NULL);
-    if (rv != SECSuccess) {
-        SECU_PrintError("Error:", "NSS_NoDB_Init");
-        goto cleanup;
-    }
-
-    /* Test P256, P384, P521 */
-    if (usefreebl) {
-        if (nist) {
-            while (ecdh_testvecs[numkats].curve != ECCurve_pastLastCurve) {
-                numkats++;
-            }
-            printf("1..%d\n", numkats);
-            for (i = 0; ecdh_testvecs[i].curve != ECCurve_pastLastCurve; i++) {
-                if (ectest_ecdh_kat(&ecdh_testvecs[i]) != SECSuccess) {
-                    printf("not okay %d - %s\n", i + 1, ecdh_testvecs[i].name);
-                    rv = SECFailure;
-                } else {
-                    printf("okay %d - %s\n", i + 1, ecdh_testvecs[i].name);
-                }
-            }
-        }
-
-        /* Test KAT for non-NIST curves */
-        if (nonnist) {
-            for (i = 0; nonnist_testvecs[i].curve != ECCurve_pastLastCurve; i++) {
-                if (ectest_ecdh_kat(&nonnist_testvecs[i]) != SECSuccess) {
-                    printf("not okay %d - %s\n", i + 1, nonnist_testvecs[i].name);
-                    rv = SECFailure;
-                } else {
-                    printf("okay %d - %s\n", i + 1, nonnist_testvecs[i].name);
-                }
-            }
-            for (i = 0; nonnist_testvecs_bad_values[i].curve != ECCurve_pastLastCurve; i++) {
-                if (ectest_validate_point(&nonnist_testvecs_bad_values[i]) == SECSuccess) {
-                    printf("not okay %d - %s\n", i + 1, nonnist_testvecs_bad_values[i].name);
-                    rv = SECFailure;
-                } else {
-                    printf("okay %d - %s\n", i + 1, nonnist_testvecs_bad_values[i].name);
-                }
-            }
-        }
-    }
-
-    /* Test PK11 for non-NIST curves */
-    if (usepkcs11) {
-        if (nonnist) {
-            if (ectest_curve_pkcs11(SEC_OID_CURVE25519) != SECSuccess) {
-                printf("not okay (OID %d) - PK11 test\n", SEC_OID_CURVE25519);
-                rv = SECFailure;
-            } else {
-                printf("okay (OID %d) - PK11 test\n", SEC_OID_CURVE25519);
-            }
-        }
-        if (nist) {
-            for (i = 0; i < 3; ++i) {
-                if (ectest_curve_pkcs11(nistOids[i]) != SECSuccess) {
-                    printf("not okay (OID %d) - PK11 test\n", nistOids[i]);
-                    rv = SECFailure;
-                } else {
-                    printf("okay (OID %d) - PK11 test\n", nistOids[i]);
-                }
-            }
-        }
-    }
-
-cleanup:
-    rv |= NSS_Shutdown();
-
-    if (rv != SECSuccess) {
-        printf("Error: exiting with error value\n");
-    }
-    return rv;
-}
deleted file mode 100644
--- a/security/nss/cmd/ectest/manifest.mn
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DEPTH = ../..
-CORE_DEPTH = ../..
-
-# MODULE public and private header directories are implicitly REQUIRED.
-MODULE = nss
-
-INCLUDES += -I$(CORE_DEPTH)/nss/lib/softoken
-
-CSRCS = ectest.c
-
-PROGRAM = ectest
-
-USE_STATIC_LIBS = 1
rename from security/nss/cmd/ectest/Makefile
rename to security/nss/cmd/fbectest/Makefile
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/fbectest/fbectest.c
@@ -0,0 +1,328 @@
+/* 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 "blapi.h"
+#include "ec.h"
+#include "ecl-curve.h"
+#include "prprf.h"
+#include "basicutil.h"
+#include "secder.h"
+#include "secitem.h"
+#include "nspr.h"
+#include <stdio.h>
+
+typedef struct {
+    ECCurveName curve;
+    int iterations;
+    char *privhex;
+    char *our_pubhex;
+    char *their_pubhex;
+    char *common_key;
+    char *name;
+    ECFieldType fieldType;
+} ECDH_KAT;
+
+typedef struct {
+    ECCurveName curve;
+    char *point;
+    char *name;
+    ECFieldType fieldType;
+} ECDH_BAD;
+
+#include "testvecs.h"
+
+/*
+ * Initializes a SECItem from a hexadecimal string
+ *
+ */
+static SECItem *
+hexString2SECItem(PLArenaPool *arena, SECItem *item, const char *str)
+{
+    int i = 0;
+    int byteval = 0;
+    int tmp = PORT_Strlen(str);
+
+    PORT_Assert(arena);
+    PORT_Assert(item);
+
+    if ((tmp % 2) != 0) {
+        return NULL;
+    }
+
+    item = SECITEM_AllocItem(arena, item, tmp / 2);
+    if (item == NULL) {
+        return NULL;
+    }
+
+    while (str[i]) {
+        if ((str[i] >= '0') && (str[i] <= '9')) {
+            tmp = str[i] - '0';
+        } else if ((str[i] >= 'a') && (str[i] <= 'f')) {
+            tmp = str[i] - 'a' + 10;
+        } else if ((str[i] >= 'A') && (str[i] <= 'F')) {
+            tmp = str[i] - 'A' + 10;
+        } else {
+            /* item is in arena and gets freed by the caller */
+            return NULL;
+        }
+
+        byteval = byteval * 16 + tmp;
+        if ((i % 2) != 0) {
+            item->data[i / 2] = byteval;
+            byteval = 0;
+        }
+        i++;
+    }
+
+    return item;
+}
+
+void
+printBuf(const SECItem *item)
+{
+    int i;
+    if (!item || !item->len) {
+        printf("(null)\n");
+        return;
+    }
+
+    for (i = 0; i < item->len; i++) {
+        printf("%02x", item->data[i]);
+    }
+    printf("\n");
+}
+
+/* Initialise test with basic curve populate with only the necessary things */
+SECStatus
+init_params(ECParams *ecParams, ECCurveName curve, PLArenaPool **arena,
+            ECFieldType type)
+{
+    if ((curve < ECCurve_noName) || (curve > ECCurve_pastLastCurve)) {
+        return SECFailure;
+    }
+    *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+    if (!*arena) {
+        return SECFailure;
+    }
+    ecParams->name = curve;
+    ecParams->type = ec_params_named;
+    ecParams->curveOID.data = NULL;
+    ecParams->curveOID.len = 0;
+    ecParams->curve.seed.data = NULL;
+    ecParams->curve.seed.len = 0;
+    ecParams->DEREncoding.data = NULL;
+    ecParams->DEREncoding.len = 0;
+    ecParams->arena = *arena;
+    ecParams->fieldID.size = ecCurve_map[curve]->size;
+    ecParams->fieldID.type = type;
+    ecParams->cofactor = ecCurve_map[curve]->cofactor;
+    ecParams->pointSize = ecCurve_map[curve]->pointSize;
+
+    return SECSuccess;
+}
+
+SECStatus
+ectest_ecdh_kat(ECDH_KAT *kat)
+{
+    ECCurveName curve = kat->curve;
+    ECParams ecParams = { 0 };
+    ECPrivateKey *ecPriv = NULL;
+    SECItem theirKey = { siBuffer, NULL, 0 };
+    SECStatus rv = SECFailure;
+    PLArenaPool *arena = NULL;
+    SECItem seed = { siBuffer, NULL, 0 };
+    SECItem answer = { siBuffer, NULL, 0 };
+    SECItem answer2 = { siBuffer, NULL, 0 };
+    SECItem derived = { siBuffer, NULL, 0 };
+    char genenc[3 + 2 * 2 * MAX_ECKEY_LEN];
+    int i;
+
+    rv = init_params(&ecParams, curve, &arena, kat->fieldType);
+    if (rv != SECSuccess) {
+        return rv;
+    }
+
+    hexString2SECItem(arena, &ecParams.fieldID.u.prime, ecCurve_map[curve]->irr);
+    hexString2SECItem(arena, &ecParams.curve.a, ecCurve_map[curve]->curvea);
+    hexString2SECItem(arena, &ecParams.curve.b, ecCurve_map[curve]->curveb);
+    genenc[0] = '0';
+    genenc[1] = '4';
+    genenc[2] = '\0';
+    PORT_Assert(PR_ARRAY_SIZE(genenc) >= PORT_Strlen(ecCurve_map[curve]->genx));
+    PORT_Assert(PR_ARRAY_SIZE(genenc) >= PORT_Strlen(ecCurve_map[curve]->geny));
+    strcat(genenc, ecCurve_map[curve]->genx);
+    strcat(genenc, ecCurve_map[curve]->geny);
+    hexString2SECItem(arena, &ecParams.base, genenc);
+    hexString2SECItem(arena, &ecParams.order, ecCurve_map[curve]->order);
+
+    if (kat->our_pubhex) {
+        hexString2SECItem(arena, &answer, kat->our_pubhex);
+    }
+    hexString2SECItem(arena, &seed, kat->privhex);
+    rv = EC_NewKeyFromSeed(&ecParams, &ecPriv, seed.data, seed.len);
+    if (rv != SECSuccess) {
+        rv = SECFailure;
+        goto cleanup;
+    }
+    if (kat->our_pubhex) {
+        if (SECITEM_CompareItem(&answer, &ecPriv->publicValue) != SECEqual) {
+            rv = SECFailure;
+            goto cleanup;
+        }
+    }
+
+    hexString2SECItem(arena, &theirKey, kat->their_pubhex);
+    hexString2SECItem(arena, &answer2, kat->common_key);
+
+    rv = EC_ValidatePublicKey(&ecParams, &theirKey);
+    if (rv != SECSuccess) {
+        printf("EC_ValidatePublicKey failed\n");
+        goto cleanup;
+    }
+
+    for (i = 0; i < kat->iterations; ++i) {
+        rv = ECDH_Derive(&theirKey, &ecParams, &ecPriv->privateValue, PR_TRUE, &derived);
+        if (rv != SECSuccess) {
+            rv = SECFailure;
+            goto cleanup;
+        }
+        rv = SECITEM_CopyItem(ecParams.arena, &theirKey, &ecPriv->privateValue);
+        if (rv != SECSuccess) {
+            goto cleanup;
+        }
+        rv = SECITEM_CopyItem(ecParams.arena, &ecPriv->privateValue, &derived);
+        if (rv != SECSuccess) {
+            goto cleanup;
+        }
+        SECITEM_FreeItem(&derived, PR_FALSE);
+    }
+
+    if (SECITEM_CompareItem(&answer2, &ecPriv->privateValue) != SECEqual) {
+        printf("expected: ");
+        printBuf(&answer2);
+        printf("derived:  ");
+        printBuf(&ecPriv->privateValue);
+        rv = SECFailure;
+        goto cleanup;
+    }
+
+cleanup:
+    PORT_FreeArena(arena, PR_FALSE);
+    if (ecPriv) {
+        PORT_FreeArena(ecPriv->ecParams.arena, PR_FALSE);
+    }
+    if (derived.data) {
+        SECITEM_FreeItem(&derived, PR_FALSE);
+    }
+    return rv;
+}
+
+SECStatus
+ectest_validate_point(ECDH_BAD *bad)
+{
+    ECParams ecParams = { 0 };
+    SECItem point = { siBuffer, NULL, 0 };
+    SECStatus rv = SECFailure;
+    PLArenaPool *arena = NULL;
+
+    rv = init_params(&ecParams, bad->curve, &arena, bad->fieldType);
+    if (rv != SECSuccess) {
+        return rv;
+    }
+
+    hexString2SECItem(arena, &point, bad->point);
+    rv = EC_ValidatePublicKey(&ecParams, &point);
+
+    PORT_FreeArena(arena, PR_FALSE);
+    return rv;
+}
+
+void
+printUsage(char *prog)
+{
+    printf("Usage: %s [-fp] [-nd]\n"
+           "\t-n: NIST curves\n"
+           "\t-d: non-NIST curves\n"
+           "You have to specify at at least one of n or d.\n"
+           "By default no tests are executed.\n",
+           prog);
+}
+
+/* Performs tests of elliptic curve cryptography over prime fields If
+ * tests fail, then it prints an error message, aborts, and returns an
+ * error code. Otherwise, returns 0. */
+int
+main(int argv, char **argc)
+{
+    SECStatus rv = SECSuccess;
+    int numkats = 0;
+    int i = 0;
+    int nist = 0;
+    int nonnist = 0;
+
+    for (i = 1; i < argv; i++) {
+        if (PL_strcasecmp(argc[i], "-n") == 0) {
+            nist = 1;
+        } else if (PL_strcasecmp(argc[i], "-d") == 0) {
+            nonnist = 1;
+        } else {
+            printUsage(argc[0]);
+            return 1;
+        }
+    }
+    if (!nist && !nonnist) {
+        printUsage(argc[0]);
+        return 1;
+    }
+
+    rv = SECOID_Init();
+    if (rv != SECSuccess) {
+        SECU_PrintError("Error:", "SECOID_Init");
+        goto cleanup;
+    }
+
+    /* Test P256, P384, P521 */
+    if (nist) {
+        while (ecdh_testvecs[numkats].curve != ECCurve_pastLastCurve) {
+            numkats++;
+        }
+        printf("1..%d\n", numkats);
+        for (i = 0; ecdh_testvecs[i].curve != ECCurve_pastLastCurve; i++) {
+            if (ectest_ecdh_kat(&ecdh_testvecs[i]) != SECSuccess) {
+                printf("not okay %d - %s\n", i + 1, ecdh_testvecs[i].name);
+                rv = SECFailure;
+            } else {
+                printf("okay %d - %s\n", i + 1, ecdh_testvecs[i].name);
+            }
+        }
+    }
+
+    /* Test KAT for non-NIST curves */
+    if (nonnist) {
+        for (i = 0; nonnist_testvecs[i].curve != ECCurve_pastLastCurve; i++) {
+            if (ectest_ecdh_kat(&nonnist_testvecs[i]) != SECSuccess) {
+                printf("not okay %d - %s\n", i + 1, nonnist_testvecs[i].name);
+                rv = SECFailure;
+            } else {
+                printf("okay %d - %s\n", i + 1, nonnist_testvecs[i].name);
+            }
+        }
+        for (i = 0; nonnist_testvecs_bad_values[i].curve != ECCurve_pastLastCurve; i++) {
+            if (ectest_validate_point(&nonnist_testvecs_bad_values[i]) == SECSuccess) {
+                printf("not okay %d - %s\n", i + 1, nonnist_testvecs_bad_values[i].name);
+                rv = SECFailure;
+            } else {
+                printf("okay %d - %s\n", i + 1, nonnist_testvecs_bad_values[i].name);
+            }
+        }
+    }
+
+cleanup:
+    rv |= SECOID_Shutdown();
+
+    if (rv != SECSuccess) {
+        printf("Error: exiting with error value\n");
+    }
+    return rv;
+}
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/fbectest/fbectest.gyp
@@ -0,0 +1,34 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    '../../cmd/platlibs.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'fbectest',
+      'type': 'executable',
+      'sources': [
+        'fbectest.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:nss_exports',
+        '<(DEPTH)/lib/sqlite/sqlite.gyp:sqlite3'
+      ]
+    }
+  ],
+  'target_defaults': {
+    'include_dirs': [
+      '../../nss/lib/softoken'
+    ],
+    'defines': [
+      'NSS_USE_STATIC_LIBS'
+    ]
+  },
+  'variables': {
+    'module': 'nss',
+    'use_static_libs': 1
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/fbectest/manifest.mn
@@ -0,0 +1,18 @@
+#
+# 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/.
+
+DEPTH = ../..
+CORE_DEPTH = ../..
+
+# MODULE public and private header directories are implicitly REQUIRED.
+MODULE = nss
+
+INCLUDES += -I$(CORE_DEPTH)/nss/lib/softoken
+
+CSRCS = fbectest.c
+
+PROGRAM = fbectest
+
+USE_STATIC_LIBS = 1
rename from security/nss/cmd/ectest/testvecs.h
rename to security/nss/cmd/fbectest/testvecs.h
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/fipstest/fipstest.gyp
@@ -0,0 +1,31 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    '../../cmd/platlibs.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'fipstest',
+      'type': 'executable',
+      'sources': [
+        'fipstest.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:nss_exports',
+        '<(DEPTH)/lib/sqlite/sqlite.gyp:sqlite3'
+      ]
+    }
+  ],
+  'target_defaults': {
+    'defines': [
+      'NSS_USE_STATIC_LIBS'
+    ]
+  },
+  'variables': {
+    'module': 'nss',
+    'use_static_libs': 1
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/httpserv/httpserv.gyp
@@ -0,0 +1,30 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    '../../cmd/platlibs.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'httpserv',
+      'type': 'executable',
+      'sources': [
+        'httpserv.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:dbm_exports',
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ]
+    }
+  ],
+  'target_defaults': {
+    'defines': [
+      'NSPR20'
+    ]
+  },
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/lib/exports.gyp
@@ -0,0 +1,27 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'cmd_lib_exports',
+      'type': 'none',
+      'copies': [
+        {
+          'files': [
+            'basicutil.h',
+            'pk11table.h',
+            'secutil.h'
+          ],
+          'destination': '<(PRODUCT_DIR)/dist/<(module)/private'
+        }
+      ]
+    }
+  ],
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/lib/lib.gyp
@@ -0,0 +1,35 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'sectool',
+      'type': 'static_library',
+      'sources': [
+        'basicutil.c',
+        'derprint.c',
+        'ffs.c',
+        'moreoids.c',
+        'pk11table.c',
+        'pppolicy.c',
+        'secpwd.c',
+        'secutil.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ]
+    }
+  ],
+  'target_defaults': {
+    'defines': [
+      'NSPR20'
+    ]
+  },
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/listsuites/listsuites.gyp
@@ -0,0 +1,24 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    '../../cmd/platlibs.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'listsuites',
+      'type': 'executable',
+      'sources': [
+        'listsuites.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ]
+    }
+  ],
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/lowhashtest/lowhashtest.gyp
@@ -0,0 +1,32 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    '../../cmd/platlibs.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'lowhashtest',
+      'type': 'executable',
+      'sources': [
+        'lowhashtest.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:dbm_exports',
+        '<(DEPTH)/exports.gyp:nss_exports',
+        '<(DEPTH)/lib/freebl/freebl.gyp:freebl3',
+        '<(DEPTH)/cmd/lib/lib.gyp:sectool'
+      ]
+    }
+  ],
+  'target_defaults': {
+    'include_dirs': [
+      '../../nss/lib/freebl'
+    ]
+  },
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/makepqg/makepqg.gyp
@@ -0,0 +1,25 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    '../../cmd/platlibs.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'makepqg',
+      'type': 'executable',
+      'sources': [
+        'makepqg.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:dbm_exports',
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ]
+    }
+  ],
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
--- a/security/nss/cmd/manifest.mn
+++ b/security/nss/cmd/manifest.mn
@@ -18,17 +18,17 @@ LIB_SRCDIRS = \
  lib \
  $(NULL)
 endif
 
 ifndef NSS_BUILD_UTIL_ONLY
 SOFTOKEN_SRCDIRS = \
  $(BLTEST_SRCDIR) \
  $(ECPERF_SRCDIR) \
- $(ECTEST_SRCDIR) \
+ $(FREEBL_ECTEST_SRCDIR) \
  $(FIPSTEST_SRCDIR)  \
  $(LOWHASHTEST_SRCDIR)  \
  $(SHLIBSIGN_SRCDIR) \
  $(NULL)
 endif
 
 ifndef NSS_BUILD_SOFTOKEN_ONLY
 ifndef NSS_BUILD_UTIL_ONLY
@@ -51,16 +51,17 @@ NSS_SRCDIRS = \
  ocspclnt  \
  ocspresp \
  oidcalc  \
  p7content  \
  p7env  \
  p7sign  \
  p7verify  \
  pk12util \
+ pk11ectest \
  pk11gcmtest \
  pk11mode \
  pk1sign  \
  pp  \
  pwdecrypt \
  rsaperf \
  sdrtest \
  selfserv  \
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/modutil/modutil.gyp
@@ -0,0 +1,44 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    '../../cmd/platlibs.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'modutil',
+      'type': 'executable',
+      'sources': [
+        'install-ds.c',
+        'install.c',
+        'installparse.c',
+        'instsec.c',
+        'lex.Pk11Install_yy.c',
+        'modutil.c',
+        'pk11.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:nss_exports',
+        '<(DEPTH)/exports.gyp:dbm_exports',
+        '<(DEPTH)/lib/jar/jar.gyp:jar',
+        '<(DEPTH)/lib/zlib/zlib.gyp:nss_zlib'
+      ]
+    }
+  ],
+  'target_defaults': {
+    'include_dirs': [
+      '<(PRODUCT_DIR)/dist/nss/private',
+      '<(PRODUCT_DIR)/dist/dbm/private'
+    ],
+    'defines': [
+      'NSPR20',
+      'YY_NO_UNPUT',
+      'YY_NO_INPUT'
+    ]
+  },
+  'variables': {
+    'module': 'sectools'
+  }
+}
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/multinit/multinit.gyp
@@ -0,0 +1,24 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    '../../cmd/platlibs.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'multinit',
+      'type': 'executable',
+      'sources': [
+        'multinit.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ]
+    }
+  ],
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/ocspclnt/ocspclnt.gyp
@@ -0,0 +1,25 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    '../../cmd/platlibs.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'ocspclnt',
+      'type': 'executable',
+      'sources': [
+        'ocspclnt.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:dbm_exports',
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ]
+    }
+  ],
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/ocspresp/ocspresp.gyp
@@ -0,0 +1,24 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    '../../cmd/platlibs.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'ocspresp',
+      'type': 'executable',
+      'sources': [
+        'ocspresp.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ]
+    }
+  ],
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/oidcalc/oidcalc.gyp
@@ -0,0 +1,30 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    '../../cmd/platlibs.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'oidcalc',
+      'type': 'executable',
+      'sources': [
+        'oidcalc.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:dbm_exports',
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ]
+    }
+  ],
+  'target_defaults': {
+    'defines': [
+      'NSPR20'
+    ]
+  },
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/p7content/p7content.gyp
@@ -0,0 +1,24 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    '../../cmd/platlibs.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'p7content',
+      'type': 'executable',
+      'sources': [
+        'p7content.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ]
+    }
+  ],
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/p7env/p7env.gyp
@@ -0,0 +1,24 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    '../../cmd/platlibs.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'p7env',
+      'type': 'executable',
+      'sources': [
+        'p7env.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ]
+    }
+  ],
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/p7sign/p7sign.gyp
@@ -0,0 +1,24 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    '../../cmd/platlibs.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'p7sign',
+      'type': 'executable',
+      'sources': [
+        'p7sign.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ]
+    }
+  ],
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/p7verify/p7verify.gyp
@@ -0,0 +1,24 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    '../../cmd/platlibs.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'p7verify',
+      'type': 'executable',
+      'sources': [
+        'p7verify.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ]
+    }
+  ],
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
copy from security/nss/cmd/ectest/Makefile
copy to security/nss/cmd/pk11ectest/Makefile
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/pk11ectest/manifest.mn
@@ -0,0 +1,16 @@
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+DEPTH = ../..
+CORE_DEPTH = ../..
+
+# MODULE public and private header directories are implicitly REQUIRED.
+MODULE = nss
+
+CSRCS = pk11ectest.c
+
+PROGRAM = pk11ectest
+
+USE_STATIC_LIBS = 1
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/pk11ectest/pk11ectest.c
@@ -0,0 +1,171 @@
+/* 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 "blapi.h"
+#include "nss.h"
+#include "secutil.h"
+#include "secitem.h"
+#include "nspr.h"
+#include "pk11pub.h"
+#include <stdio.h>
+
+void
+printBuf(const SECItem *item)
+{
+    int i;
+    if (!item || !item->len) {
+        printf("(null)\n");
+        return;
+    }
+
+    for (i = 0; i < item->len; i++) {
+        printf("%02x", item->data[i]);
+    }
+    printf("\n");
+}
+
+void
+PrintKey(PK11SymKey *symKey)
+{
+    char *name = PK11_GetSymKeyNickname(symKey);
+    int len = PK11_GetKeyLength(symKey);
+    int strength = PK11_GetKeyStrength(symKey, NULL);
+    SECItem *value = NULL;
+    CK_KEY_TYPE type = PK11_GetSymKeyType(symKey);
+    (void)PK11_ExtractKeyValue(symKey);
+
+    value = PK11_GetKeyData(symKey);
+    printf("%s %3d   %4d   %s  ", name ? name : "no-name", len, strength,
+           type == CKK_GENERIC_SECRET ? "generic" : "ERROR! UNKNOWN KEY TYPE");
+    printBuf(value);
+
+    PORT_Free(name);
+}
+
+SECStatus
+ectest_curve_pkcs11(SECOidTag oid)
+{
+    SECKEYECParams pk_11_ecParams = { siBuffer, NULL, 0 };
+    SECKEYPublicKey *pubKey = NULL;
+    SECKEYPrivateKey *privKey = NULL;
+    SECOidData *oidData = NULL;
+    CK_MECHANISM_TYPE target = CKM_TLS12_MASTER_KEY_DERIVE_DH;
+    PK11SymKey *symKey = NULL;
+    SECStatus rv = SECFailure;
+
+    oidData = SECOID_FindOIDByTag(oid);
+    if (oidData == NULL) {
+        printf(" >>> SECOID_FindOIDByTag failed.\n");
+        goto cleanup;
+    }
+    PORT_Assert(oidData->oid.len < 256);
+    SECITEM_AllocItem(NULL, &pk_11_ecParams, (2 + oidData->oid.len));
+    pk_11_ecParams.data[0] = SEC_ASN1_OBJECT_ID; /* we have to prepend 0x06 */
+    pk_11_ecParams.data[1] = oidData->oid.len;
+    memcpy(pk_11_ecParams.data + 2, oidData->oid.data, oidData->oid.len);
+
+    privKey = SECKEY_CreateECPrivateKey(&pk_11_ecParams, &pubKey, NULL);
+    if (!privKey || !pubKey) {
+        printf(" >>> SECKEY_CreateECPrivateKey failed.\n");
+        goto cleanup;
+    }
+
+    symKey = PK11_PubDeriveWithKDF(privKey, pubKey, PR_FALSE, NULL, NULL,
+                                   CKM_ECDH1_DERIVE, target, CKA_DERIVE, 0,
+                                   CKD_NULL, NULL, NULL);
+    if (!symKey) {
+        printf(" >>> PK11_PubDeriveWithKDF failed.\n");
+        goto cleanup;
+    }
+    PrintKey(symKey);
+    rv = SECSuccess;
+
+cleanup:
+    if (privKey) {
+        SECKEY_DestroyPrivateKey(privKey);
+    }
+    if (pubKey) {
+        SECKEY_DestroyPublicKey(pubKey);
+    }
+    if (symKey) {
+        PK11_FreeSymKey(symKey);
+    }
+    SECITEM_FreeItem(&pk_11_ecParams, PR_FALSE);
+
+    return rv;
+}
+
+void
+printUsage(char *prog)
+{
+    printf("Usage: %s [-fp] [-nd]\n"
+           "\t-n: NIST curves\n"
+           "\t-d: non-NIST curves\n"
+           "You have to specify at at least one of n or d.\n"
+           "By default no tests are executed.\n",
+           prog);
+}
+
+/* Performs tests of elliptic curve cryptography over prime fields If
+ * tests fail, then it prints an error message, aborts, and returns an
+ * error code. Otherwise, returns 0. */
+int
+main(int argv, char **argc)
+{
+    SECStatus rv = SECSuccess;
+    int i = 0;
+    int nist = 0;
+    int nonnist = 0;
+    SECOidTag nistOids[3] = { SEC_OID_SECG_EC_SECP256R1,
+                              SEC_OID_SECG_EC_SECP384R1,
+                              SEC_OID_SECG_EC_SECP521R1 };
+
+    for (i = 1; i < argv; i++) {
+        if (PL_strcasecmp(argc[i], "-n") == 0) {
+            nist = 1;
+        } else if (PL_strcasecmp(argc[i], "-d") == 0) {
+            nonnist = 1;
+        } else {
+            printUsage(argc[0]);
+            return 1;
+        }
+    }
+    if (!nist && !nonnist) {
+        printUsage(argc[0]);
+        return 1;
+    }
+
+    rv = NSS_NoDB_Init(NULL);
+    if (rv != SECSuccess) {
+        SECU_PrintError("Error:", "NSS_NoDB_Init");
+        goto cleanup;
+    }
+
+    if (nonnist) {
+        if (ectest_curve_pkcs11(SEC_OID_CURVE25519) != SECSuccess) {
+            printf("not okay (OID %d) - PK11 test\n", SEC_OID_CURVE25519);
+            rv = SECFailure;
+        } else {
+            printf("okay (OID %d) - PK11 test\n", SEC_OID_CURVE25519);
+        }
+    }
+    if (nist) {
+        for (i = 0; i < 3; ++i) {
+            if (ectest_curve_pkcs11(nistOids[i]) != SECSuccess) {
+                printf("not okay (OID %d) - PK11 test\n", nistOids[i]);
+                rv = SECFailure;
+            } else {
+                printf("okay (OID %d) - PK11 test\n", nistOids[i]);
+            }
+        }
+    }
+
+cleanup:
+    rv |= NSS_Shutdown();
+
+    if (rv != SECSuccess) {
+        printf("Error: exiting with error value\n");
+    }
+    return rv;
+}
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/pk11ectest/pk11ectest.gyp
@@ -0,0 +1,31 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    '../../cmd/platlibs.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'pk11ectest',
+      'type': 'executable',
+      'sources': [
+        'pk11ectest.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:nss_exports',
+        '<(DEPTH)/lib/sqlite/sqlite.gyp:sqlite3'
+      ]
+    }
+  ],
+  'target_defaults': {
+    'defines': [
+      'NSS_USE_STATIC_LIBS'
+    ]
+  },
+  'variables': {
+    'module': 'nss',
+    'use_static_libs': 1
+  }
+}
\ No newline at end of file
copy from security/nss/cmd/ectest/testvecs.h
copy to security/nss/cmd/pk11ectest/testvecs.h
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/pk11gcmtest/pk11gcmtest.gyp
@@ -0,0 +1,24 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    '../../cmd/platlibs.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'pk11gcmtest',
+      'type': 'executable',
+      'sources': [
+        'pk11gcmtest.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ]
+    }
+  ],
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/pk11mode/pk11mode.gyp
@@ -0,0 +1,24 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    '../../cmd/platlibs.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'pk11mode',
+      'type': 'executable',
+      'sources': [
+        'pk11mode.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ]
+    }
+  ],
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/pk12util/pk12util.gyp
@@ -0,0 +1,30 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    '../../cmd/platlibs.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'pk12util',
+      'type': 'executable',
+      'sources': [
+        'pk12util.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:dbm_exports',
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ]
+    }
+  ],
+  'target_defaults': {
+    'defines': [
+      'NSPR20'
+    ]
+  },
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/pk1sign/pk1sign.gyp
@@ -0,0 +1,24 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    '../../cmd/platlibs.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'pk1sign',
+      'type': 'executable',
+      'sources': [
+        'pk1sign.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ]
+    }
+  ],
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/pkix-errcodes/pkix-errcodes.gyp
@@ -0,0 +1,24 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    '../../cmd/platlibs.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'pkix-errcodes',
+      'type': 'executable',
+      'sources': [
+        'pkix-errcodes.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ]
+    }
+  ],
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/platlibs.gypi
@@ -0,0 +1,78 @@
+# 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/.
+{
+  'variables': {
+    'use_static_libs%': 0,
+  },
+  'target_defaults': {
+    'dependencies': [
+      '<(DEPTH)/cmd/lib/lib.gyp:sectool',
+    ],
+    'conditions': [
+      ['moz_fold_libs==0', {
+        'dependencies': [
+          '<(DEPTH)/lib/util/util.gyp:nssutil3',
+        ],
+      }],
+      ['<(use_static_libs)==1', {
+        'defines': ['NSS_USE_STATIC_LIBS'],
+        'dependencies': [
+          '<(DEPTH)/lib/smime/smime.gyp:smime',
+          '<(DEPTH)/lib/ssl/ssl.gyp:ssl',
+          '<(DEPTH)/lib/nss/nss.gyp:nss_static',
+          '<(DEPTH)/lib/pkcs12/pkcs12.gyp:pkcs12',
+          '<(DEPTH)/lib/pkcs7/pkcs7.gyp:pkcs7',
+          '<(DEPTH)/lib/certhigh/certhigh.gyp:certhi',
+          '<(DEPTH)/lib/cryptohi/cryptohi.gyp:cryptohi',
+          '<(DEPTH)/lib/pk11wrap/pk11wrap.gyp:pk11wrap',
+          '<(DEPTH)/lib/softoken/softoken.gyp:softokn',
+          '<(DEPTH)/lib/certdb/certdb.gyp:certdb',
+          '<(DEPTH)/lib/pki/pki.gyp:nsspki',
+          '<(DEPTH)/lib/dev/dev.gyp:nssdev',
+          '<(DEPTH)/lib/base/base.gyp:nssb',
+          '<(DEPTH)/lib/freebl/freebl.gyp:freebl',
+          '<(DEPTH)/lib/pk11wrap/pk11wrap.gyp:pk11wrap',
+          '<(DEPTH)/lib/certhigh/certhigh.gyp:certhi',
+          '<(DEPTH)/lib/sqlite/sqlite.gyp:sqlite3',
+        ],
+        'conditions': [
+          [ 'disable_dbm==0', {
+            'dependencies': [
+              '<(DEPTH)/lib/dbm/src/src.gyp:dbm',
+              '<(DEPTH)/lib/softoken/legacydb/legacydb.gyp:nssdbm',
+            ],
+          }],
+          [ 'disable_libpkix==0', {
+            'dependencies': [
+              '<(DEPTH)/lib/libpkix/pkix/certsel/certsel.gyp:pkixcertsel',
+              '<(DEPTH)/lib/libpkix/pkix/checker/checker.gyp:pkixchecker',
+              '<(DEPTH)/lib/libpkix/pkix/params/params.gyp:pkixparams',
+              '<(DEPTH)/lib/libpkix/pkix/results/results.gyp:pkixresults',
+              '<(DEPTH)/lib/libpkix/pkix/top/top.gyp:pkixtop',
+              '<(DEPTH)/lib/libpkix/pkix/util/util.gyp:pkixutil',
+              '<(DEPTH)/lib/libpkix/pkix/crlsel/crlsel.gyp:pkixcrlsel',
+              '<(DEPTH)/lib/libpkix/pkix/store/store.gyp:pkixstore',
+              '<(DEPTH)/lib/libpkix/pkix_pl_nss/pki/pki.gyp:pkixpki',
+              '<(DEPTH)/lib/libpkix/pkix_pl_nss/system/system.gyp:pkixsystem',
+              '<(DEPTH)/lib/libpkix/pkix_pl_nss/module/module.gyp:pkixmodule'
+            ],
+          }],
+        ]},{ # !use_static_libs
+          'conditions': [
+            ['moz_fold_libs==0', {
+              'dependencies': [
+                '<(DEPTH)/lib/ssl/ssl.gyp:ssl3',
+                '<(DEPTH)/lib/smime/smime.gyp:smime3',
+                '<(DEPTH)/lib/nss/nss.gyp:nss3',
+              ],
+            }, {
+              'libraries': [
+                '<(moz_folded_library_name)',
+              ],
+            }]
+          ],
+        }],
+    ],
+  }
+}
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/pp/pp.gyp
@@ -0,0 +1,30 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    '../../cmd/platlibs.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'pp',
+      'type': 'executable',
+      'sources': [
+        'pp.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:dbm_exports',
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ]
+    }
+  ],
+  'target_defaults': {
+    'defines': [
+      'NSPR20'
+    ]
+  },
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/pwdecrypt/pwdecrypt.gyp
@@ -0,0 +1,25 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    '../../cmd/platlibs.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'pwdecrypt',
+      'type': 'executable',
+      'sources': [
+        'pwdecrypt.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:dbm_exports',
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ]
+    }
+  ],
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/rsaperf/rsaperf.gyp
@@ -0,0 +1,36 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    '../../cmd/platlibs.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'rsaperf',
+      'type': 'executable',
+      'sources': [
+        'defkey.c',
+        'rsaperf.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:dbm_exports',
+        '<(DEPTH)/exports.gyp:nss_exports',
+        '<(DEPTH)/lib/sqlite/sqlite.gyp:sqlite3'
+      ]
+    }
+  ],
+  'target_defaults': {
+    'include_dirs': [
+      '../../nss/lib/softoken'
+    ],
+    'defines': [
+      'NSS_USE_STATIC_LIBS'
+    ]
+  },
+  'variables': {
+    'module': 'nss',
+    'use_static_libs': 1
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/sdrtest/sdrtest.gyp
@@ -0,0 +1,25 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    '../../cmd/platlibs.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'sdrtest',
+      'type': 'executable',
+      'sources': [
+        'sdrtest.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:dbm_exports',
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ]
+    }
+  ],
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/selfserv/selfserv.gyp
@@ -0,0 +1,30 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    '../../cmd/platlibs.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'selfserv',
+      'type': 'executable',
+      'sources': [
+        'selfserv.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:dbm_exports',
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ]
+    }
+  ],
+  'target_defaults': {
+    'defines': [
+      'NSPR20'
+    ]
+  },
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/shlibsign/mangle/mangle.gyp
@@ -0,0 +1,31 @@
+# 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/.
+{
+  'includes': [
+    '../../../coreconf/config.gypi',
+    '../../../cmd/platlibs.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'mangle',
+      'type': 'executable',
+      'sources': [
+        'mangle.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ]
+    }
+  ],
+  'target_defaults': {
+    'defines': [
+      'SHLIB_SUFFIX=\"<(dll_suffix)\"',
+      'SHLIB_PREFIX=\"<(dll_prefix)\"'
+    ]
+  },
+  'variables': {
+    'module': 'nss',
+    'use_static_libs': 1
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/shlibsign/shlibsign.gyp
@@ -0,0 +1,30 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    '../../cmd/platlibs.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'shlibsign',
+      'type': 'executable',
+      'sources': [
+        'shlibsign.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ]
+    }
+  ],
+  'target_defaults': {
+    'defines': [
+      'SHLIB_SUFFIX=\"<(dll_suffix)\"',
+      'SHLIB_PREFIX=\"<(dll_prefix)\"'
+    ]
+  },
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/signtool/signtool.gyp
@@ -0,0 +1,33 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    '../../cmd/platlibs.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'signtool',
+      'type': 'executable',
+      'sources': [
+        'certgen.c',
+        'javascript.c',
+        'list.c',
+        'sign.c',
+        'signtool.c',
+        'util.c',
+        'verify.c',
+        'zip.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:nss_exports',
+        '<(DEPTH)/lib/jar/jar.gyp:jar',
+        '<(DEPTH)/lib/zlib/zlib.gyp:nss_zlib'
+      ]
+    }
+  ],
+  'variables': {
+    'module': 'nss'
+  }
+}
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/signver/signver.gyp
@@ -0,0 +1,26 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    '../../cmd/platlibs.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'signver',
+      'type': 'executable',
+      'sources': [
+        'pk7print.c',
+        'signver.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:dbm_exports',
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ]
+    }
+  ],
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/smimetools/smimetools.gyp
@@ -0,0 +1,25 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    '../../cmd/platlibs.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'cmsutil',
+      'type': 'executable',
+      'sources': [
+        'cmsutil.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:dbm_exports',
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ]
+    }
+  ],
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/ssltap/ssltap.gyp
@@ -0,0 +1,25 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    '../../cmd/platlibs.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'ssltap',
+      'type': 'executable',
+      'sources': [
+        'ssltap.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:dbm_exports',
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ]
+    }
+  ],
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/strsclnt/strsclnt.gyp
@@ -0,0 +1,30 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    '../../cmd/platlibs.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'strsclnt',
+      'type': 'executable',
+      'sources': [
+        'strsclnt.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:dbm_exports',
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ]
+    }
+  ],
+  'target_defaults': {
+    'defines': [
+      'NSPR20'
+    ]
+  },
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/symkeyutil/symkeyutil.gyp
@@ -0,0 +1,30 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    '../../cmd/platlibs.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'symkeyutil',
+      'type': 'executable',
+      'sources': [
+        'symkeyutil.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:dbm_exports',
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ]
+    }
+  ],
+  'target_defaults': {
+    'defines': [
+      'NSPR20'
+    ]
+  },
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/tests/tests.gyp
@@ -0,0 +1,91 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    '../../cmd/platlibs.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'baddbdir',
+      'type': 'executable',
+      'sources': [
+        'baddbdir.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:dbm_exports',
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ]
+    },
+    {
+      'target_name': 'conflict',
+      'type': 'executable',
+      'sources': [
+        'conflict.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:dbm_exports',
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ]
+    },
+    {
+      'target_name': 'dertimetest',
+      'type': 'executable',
+      'sources': [
+        'dertimetest.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:dbm_exports',
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ]
+    },
+    {
+      'target_name': 'encodeinttest',
+      'type': 'executable',
+      'sources': [
+        'encodeinttest.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:dbm_exports',
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ]
+    },
+    {
+      'target_name': 'nonspr10',
+      'type': 'executable',
+      'sources': [
+        'nonspr10.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:dbm_exports',
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ]
+    },
+    {
+      'target_name': 'remtest',
+      'type': 'executable',
+      'sources': [
+        'remtest.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:dbm_exports',
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ]
+    },
+    {
+      'target_name': 'secmodtest',
+      'type': 'executable',
+      'sources': [
+        'secmodtest.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:dbm_exports',
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ]
+    }
+  ],
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/tstclnt/tstclnt.gyp
@@ -0,0 +1,31 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    '../../cmd/platlibs.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'tstclnt',
+      'type': 'executable',
+      'sources': [
+        'tstclnt.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:dbm_exports',
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ]
+    }
+  ],
+  'target_defaults': {
+    'defines': [
+      'DLL_PREFIX=\"<(dll_prefix)\"',
+      'DLL_SUFFIX=\"<(dll_suffix)\"'
+    ]
+  },
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/vfychain/vfychain.gyp
@@ -0,0 +1,30 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    '../../cmd/platlibs.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'vfychain',
+      'type': 'executable',
+      'sources': [
+        'vfychain.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ]
+    }
+  ],
+  'target_defaults': {
+    'defines': [
+      'DLL_PREFIX=\"<(dll_prefix)\"',
+      'DLL_SUFFIX=\"<(dll_suffix)\"'
+    ]
+  },
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/vfyserv/vfyserv.gyp
@@ -0,0 +1,32 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    '../../cmd/platlibs.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'vfyserv',
+      'type': 'executable',
+      'sources': [
+        'vfyserv.c',
+        'vfyutil.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:dbm_exports',
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ]
+    }
+  ],
+  'target_defaults': {
+    'defines': [
+      'DLL_PREFIX=\"<(dll_prefix)\"',
+      'DLL_SUFFIX=\"<(dll_suffix)\"'
+    ]
+  },
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
--- a/security/nss/coreconf/Darwin.mk
+++ b/security/nss/coreconf/Darwin.mk
@@ -1,22 +1,22 @@
 #
 # 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/.
 
+CC     ?= gcc
+CCC    ?= g++
+RANLIB ?= ranlib
+
 include $(CORE_DEPTH)/coreconf/UNIX.mk
 include $(CORE_DEPTH)/coreconf/Werror.mk
 
 DEFAULT_COMPILER = gcc
 
-CC		= gcc
-CCC		= g++
-RANLIB		= ranlib
-
 ifndef CPU_ARCH
 # When cross-compiling, CPU_ARCH should already be defined as the target
 # architecture, set to powerpc or i386.
 CPU_ARCH	:= $(shell uname -p)
 endif
 
 ifeq (,$(filter-out i%86,$(CPU_ARCH)))
 ifdef USE_64
--- a/security/nss/coreconf/Linux.mk
+++ b/security/nss/coreconf/Linux.mk
@@ -1,30 +1,30 @@
 #
 # 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/.
 
+CC     ?= gcc
+CCC    ?= g++
+RANLIB ?= ranlib
+
 include $(CORE_DEPTH)/coreconf/UNIX.mk
 
 #
 # The default implementation strategy for Linux is now pthreads
 #
 ifneq ($(OS_TARGET),Android)
 	USE_PTHREADS = 1
 endif
 
 ifeq ($(USE_PTHREADS),1)
 	IMPL_STRATEGY = _PTH
 endif
 
-CC			= gcc
-CCC			= g++
-RANLIB			= ranlib
-
 DEFAULT_COMPILER = gcc
 
 ifeq ($(OS_TARGET),Android)
 ifndef ANDROID_NDK
 	$(error Must set ANDROID_NDK to the path to the android NDK first)
 endif
 ifndef ANDROID_TOOLCHAIN_VERSION
 	$(error Must set ANDROID_TOOLCHAIN_VERSION to the requested version number)
new file mode 100644
--- /dev/null
+++ b/security/nss/coreconf/check_cc_clang.py
@@ -0,0 +1,12 @@
+#!/usr/bin/env python
+
+import os
+import subprocess
+
+def main():
+    cc = os.environ.get('CC', 'cc')
+    cc_is_clang = 'clang' in subprocess.check_output([cc, '--version'])
+    print int(cc_is_clang)
+
+if __name__ == '__main__':
+    main()
new file mode 100644
--- /dev/null
+++ b/security/nss/coreconf/config.gypi
@@ -0,0 +1,409 @@
+# 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/.
+{
+  'variables': {
+    'module%': '',
+    'variables': {
+      'variables': {
+        'variables': {
+          'python%': 'python',
+        },
+        # chromium uses pymod_do_main, but gyp doesn't set a sensible
+        # Python sys.path (gyp_chromium does).
+        'python%': '<(python)',
+        'host_arch%': '<!(<(python) <(DEPTH)/coreconf/detect_host_arch.py)',
+      },
+      'python%': '<(python)',
+      'host_arch%': '<(host_arch)',
+      'conditions': [
+        ['OS=="android"', {
+          'target_arch%': 'arm',
+        }, {
+          # Default architecture we're building for is the architecture we're
+          # building on.
+          'target_arch%': '<(host_arch)',
+        }],
+        ['OS=="win"', {
+          'use_system_zlib%': 0,
+          'nspr_libs%': ['nspr4.lib', 'plc4.lib', 'plds4.lib'],
+          #XXX: gyp breaks if these are empty!
+          'nspr_lib_dir%': ' ',
+          'nspr_include_dir%': ' ',
+          'zlib_libs%': [],
+          #TODO
+          'moz_debug_flags%': '',
+          'dll_prefix': '',
+          'dll_suffix': 'dll',
+        }, {
+          # On non-windows, default to a system NSPR.
+          'nspr_libs%': ['-lplds4', '-lplc4', '-lnspr4'],
+          'nspr_lib_dir%': '<!(<(python) <(DEPTH)/coreconf/nspr_lib_dir.py)',
+          'nspr_include_dir%': '<!(<(python) <(DEPTH)/coreconf/nspr_include_dir.py)',
+          'use_system_zlib%': 1,
+        }],
+        ['OS=="linux" or OS=="android"', {
+          'zlib_libs%': ['<!@(<(python) <(DEPTH)/coreconf/pkg_config.py --libs zlib)'],
+          'moz_debug_flags%': '-gdwarf-2',
+          'optimize_flags%': '-O2',
+          'dll_prefix': 'lib',
+          'dll_suffix': 'so',
+        }],
+        ['OS=="mac"', {
+          'zlib_libs%': ['-lz'],
+          'use_system_sqlite%': 1,
+          'moz_debug_flags%': '-gdwarf-2 -gfull',
+          'optimize_flags%': '-O2',
+          'dll_prefix': 'lib',
+          'dll_suffix': 'dylib',
+        }, {
+          'use_system_sqlite%': 0,
+        }],
+        ['"<(GENERATOR)"=="ninja"', {
+          'cc_is_clang%': '<!(<(python) <(DEPTH)/coreconf/check_cc_clang.py)',
+        }, {
+          'cc_is_clang%': '0',
+        }],
+      ],
+    },
+    # Copy conditionally-set variables out one scope.
+    'python%': '<(python)',
+    'host_arch%': '<(host_arch)',
+    'target_arch%': '<(target_arch)',
+    'use_system_zlib%': '<(use_system_zlib)',
+    'zlib_libs%': ['<@(zlib_libs)'],
+    'moz_debug_flags%': '<(moz_debug_flags)',
+    'nspr_libs%': ['<@(nspr_libs)'],
+    'nspr_lib_dir%': '<(nspr_lib_dir)',
+    'nspr_include_dir%': '<(nspr_include_dir)',
+    'use_system_sqlite%': '<(use_system_sqlite)',
+    'sqlite_libs%': ['-lsqlite3'],
+    'dll_prefix': '<(dll_prefix)',
+    'dll_suffix': '<(dll_suffix)',
+    'cc_is_clang%': '<(cc_is_clang)',
+    'disable_tests%': 0,
+    'disable_chachapoly%': 0,
+    'disable_dbm%': 0,
+    'disable_libpkix%': 0,
+    'ssl_enable_zlib%': 1,
+    'use_asan%': 0,
+    'mozilla_client%': 0,
+    'moz_fold_libs%': 0,
+    'moz_folded_library_name%': '',
+  },
+  'target_defaults': {
+    # Settings specific to targets should go here.
+    # This is mostly for linking to libraries.
+    'variables': {
+      'mapfile%': '',
+    },
+    'include_dirs': [
+      '<(nspr_include_dir)',
+      '<(PRODUCT_DIR)/dist/<(module)/private',
+    ],
+    'conditions': [
+      [ 'OS=="linux"', {
+        'libraries': [
+          '-lpthread',
+          '-ldl',
+          '-lc',
+        ],
+      }],
+    ],
+    'target_conditions': [
+      # mapfile handling
+      [ 'mapfile!=""', {
+        # Work around a gyp bug. Fixed upstream but not in Ubuntu packages:
+        # https://chromium.googlesource.com/external/gyp/+/b85ad3e578da830377dbc1843aa4fbc5af17a192%5E%21/
+        'sources': [
+          '<(DEPTH)/coreconf/empty.c',
+        ],
+        'xcode_settings': {
+          'OTHER_LDFLAGS': [
+            '-exported_symbols_list',
+            '<(INTERMEDIATE_DIR)/out.>(mapfile)',
+          ],
+        },
+        'conditions': [
+          [ 'OS=="linux" or OS=="android"', {
+            'ldflags': [
+              '-Wl,--version-script,<(INTERMEDIATE_DIR)/out.>(mapfile)',
+            ],
+          }],
+          [ 'OS=="win"', {
+            # On Windows, .def files are used directly as sources.
+            'sources': [
+              '>(mapfile)',
+            ],
+          }, {
+            # On other platforms, .def files need processing.
+            'sources': [
+              '<(INTERMEDIATE_DIR)/out.>(mapfile)',
+            ],
+            'actions': [{
+              'action_name': 'generate_mapfile',
+              'inputs': [
+                '>(mapfile)',
+              ],
+              'outputs': [
+                '<(INTERMEDIATE_DIR)/out.>(mapfile)',
+              ],
+              'action': ['<@(process_map_file)'],
+            }],
+          }]
+        ],
+      }],
+      [ '_type=="shared_library" or _type=="executable"', {
+        'libraries': [
+          '<@(nspr_libs)',
+        ],
+        'library_dirs': [
+          '<(nspr_lib_dir)',
+        ],
+      }],
+      # Shared library specific settings.
+      [ '_type=="shared_library"', {
+        'conditions': [
+          [ 'OS=="linux" or OS=="android"', {
+            'ldflags': [
+              '-Wl,--gc-sections',
+              '-Wl,-z,defs',
+            ],
+          }],
+        ],
+        'xcode_settings': {
+          'DYLIB_INSTALL_NAME_BASE': '@executable_path',
+          'DYLIB_COMPATIBILITY_VERSION': '1',
+          'DYLIB_CURRENT_VERSION': '1',
+          'OTHER_LDFLAGS': [
+            '-headerpad_max_install_names',
+          ],
+        },
+        'msvs_settings': {
+          'VCLinkerTool': {
+            'SubSystem': '2',
+          },
+        },
+      }],
+    ],
+    'default_configuration': 'Debug',
+    'configurations': {
+      # Common settings for Debug+Release should go here.
+      'Common_Base': {
+        'abstract': 1,
+        'defines': [
+          'NSS_NO_INIT_SUPPORT',
+          'USE_UTIL_DIRECTLY',
+          'NO_NSPR_10_SUPPORT',
+          'SSL_DISABLE_DEPRECATED_CIPHER_SUITE_NAMES',
+        ],
+        'msvs_configuration_attributes': {
+          'OutputDirectory': '$(SolutionDir)$(ConfigurationName)',
+          'IntermediateDirectory': '$(OutDir)\\obj\\$(ProjectName)',
+        },
+        'msvs_settings': {
+          'VCCLCompilerTool': {
+            'AdditionalIncludeDirectories': ['<(nspr_include_dir)'],
+          },
+        },
+        'xcode_settings': {
+          'CLANG_CXX_LANGUAGE_STANDARD': 'c++0x',
+          'OTHER_CFLAGS': [
+            '-fPIC',
+            '-fno-common',
+            '-pipe',
+          ],
+          # TODO:
+          # 'GCC_TREAT_WARNINGS_AS_ERRORS'
+          # 'WARNING_CFLAGS'
+        },
+        'conditions': [
+          ['OS=="linux" or OS=="android"', {
+            'defines': [
+              'LINUX2_1',
+              'LINUX',
+              'linux',
+              'HAVE_STRERROR',
+              'XP_UNIX',
+              '_REENTRANT',
+            ],
+            'cflags': [
+              '-fPIC',
+              '-pipe',
+              '-ffunction-sections',
+              '-fdata-sections',
+              '<(moz_debug_flags)',
+            ],
+            'cflags_cc': [
+              '-std=c++0x',
+            ],
+            'conditions': [
+
+              [ 'target_arch=="ia32"', {
+                'cflags': ['-m32'],
+                'ldflags': ['-m32'],
+              }],
+              [ 'target_arch=="x64"', {
+                'cflags': ['-m64'],
+                'ldflags': ['-m64'],
+              }],
+            ],
+          }],
+          [ 'OS=="android" and mozilla_client==0', {
+            'defines': [
+              'NO_SYSINFO',
+              'NO_FORK_CHECK',
+              'ANDROID',
+            ],
+          }],
+          [ 'OS=="mac"', {
+            'defines': [
+              'DARWIN',
+              'HAVE_STRERROR',
+              'HAVE_BSD_FLOCK',
+              'XP_UNIX',
+            ],
+            'conditions': [
+              [ 'target_arch=="ia32"', {
+                'xcode_settings': {
+                  'ARCHS': ['i386'],
+                },
+              }],
+              [ 'target_arch=="x64"', {
+                'xcode_settings': {
+                  'ARCHS': ['x86_64'],
+                },
+              }],
+            ],
+          }],
+          [ 'OS=="win"', {
+            'defines': [
+              '_WINDOWS',
+              'WIN95',
+              '_CRT_SECURE_NO_WARNINGS',
+              '_CRT_NONSTDC_NO_WARNINGS',
+            ],
+            'cflags': [
+              '-W3',
+            ],
+          }],
+          [ 'disable_dbm==1', {
+            'defines': [
+              'NSS_DISABLE_DBM',
+            ],
+          }],
+          [ 'disable_libpkix==1', {
+            'defines': [
+              'NSS_DISABLE_LIBPKIX',
+            ],
+          }],
+        ],
+      },
+      # Common settings for x86 should go here.
+      'x86_Base': {
+        'abstract': 1,
+        'msvs_settings': {
+          'VCLinkerTool': {
+            'MinimumRequiredVersion': '5.01',  # XP.
+            'TargetMachine': '1',
+          },
+          'VCCLCompilerTool': {
+            'PreprocessorDefinitions': [
+              'WIN32',
+            ],
+          },
+        },
+        'msvs_configuration_platform': 'Win32',
+      },
+      # Common settings for x86-64 should go here.
+      'x64_Base': {
+        'abstract': 1,
+        'msvs_configuration_platform': 'x64',
+        'msvs_settings': {
+          'VCLinkerTool': {
+            'TargetMachine': '17', # x86-64
+          },
+          'VCCLCompilerTool': {
+            'PreprocessorDefinitions': [
+              'WIN64',
+              '_AMD64_',
+            ],
+          },
+        },
+      },
+      # Common settings for debug should go here.
+      'Debug_Base': {
+        'abstract': 1,
+        #TODO: DEBUG_$USER
+        'defines': ['DEBUG'],
+        'xcode_settings': {
+          'COPY_PHASE_STRIP': 'NO',
+          'GCC_OPTIMIZATION_LEVEL': '0',
+        },
+        'msvs_settings': {
+          'VCCLCompilerTool': {
+            'Optimization': '0',
+            'BasicRuntimeChecks': '3',
+            'RuntimeLibrary': '2', # /MD
+          },
+          'VCLinkerTool': {
+            'LinkIncremental': '1',
+          },
+          'VCResourceCompilerTool': {
+            'PreprocessorDefinitions': ['DEBUG'],
+          },
+        },
+      },
+      # Common settings for release should go here.n
+      'Release_Base': {
+        'abstract': 1,
+        'defines': [
+          'NDEBUG',
+        ],
+        'xcode_settings': {
+          'DEAD_CODE_STRIPPING': 'YES',  # -Wl,-dead_strip
+          'GCC_OPTIMIZATION_LEVEL': '2', # -O2
+        },
+        'msvs_settings': {
+          'VCCLCompilerTool': {
+            'Optimization': '2', # /Os
+            'RuntimeLibrary': '2', # /MD
+          },
+          'VCLinkerTool': {
+            'LinkIncremental': '1',
+          },
+        },
+      },
+      #
+      # Concrete configurations
+      #
+      # These configurations shouldn't have anything in them, it should
+      # all be derived from the _Base configurations above.
+      'Debug': {
+        'inherit_from': ['Common_Base', 'x86_Base', 'Debug_Base'],
+      },
+      'Release': {
+        'inherit_from': ['Common_Base', 'x86_Base', 'Release_Base'],
+      },
+      # The gyp ninja backend requires these.
+      'Debug_x64': {
+        'inherit_from': ['Common_Base', 'x64_Base', 'Debug_Base'],
+      },
+      'Release_x64': {
+        'inherit_from': ['Common_Base', 'x64_Base', 'Release_Base'],
+      },
+    },
+  },
+  'conditions': [
+    [ 'OS=="linux" or OS=="android"', {
+      'variables': {
+        'process_map_file': ['/bin/sh', '-c', '/bin/grep -v ";-" >(mapfile) | sed -e "s,;+,," -e "s; DATA ;;" -e "s,;;,," -e "s,;.*,;," > >@(_outputs)'],
+      },
+    }],
+    [ 'OS=="mac"', {
+      'variables': {
+        'process_map_file': ['/bin/sh', '-c', '/usr/bin/grep -v ";+" >(mapfile) | grep -v ";-" | sed -e "s; DATA ;;" -e "s,;;,," -e "s,;.*,," -e "s,^,_," > >@(_outputs)'],
+      },
+    }],
+  ],
+}
--- a/security/nss/coreconf/coreconf.dep
+++ b/security/nss/coreconf/coreconf.dep
@@ -5,8 +5,9 @@
 
 /*
  * A dummy header file that is a dependency for all the object files.
  * Used to force a full recompilation of NSS in Mozilla's Tinderbox
  * depend builds.  See comments in rules.mk.
  */
 
 #error "Do not include this header file."
+
new file mode 100644
--- /dev/null
+++ b/security/nss/coreconf/detect_host_arch.py
@@ -0,0 +1,33 @@
+#!/usr/bin/env python
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+"""Outputs host CPU architecture in format recognized by gyp."""
+import platform
+import re
+
+def HostArch():
+  """Returns the host architecture with a predictable string."""
+  host_arch = platform.machine().lower()
+  # Convert machine type to format recognized by gyp.
+  if re.match(r'i.86', host_arch) or host_arch == 'i86pc':
+    host_arch = 'ia32'
+  elif host_arch in ['x86_64', 'amd64']:
+    host_arch = 'x64'
+  elif host_arch.startswith('arm'):
+    host_arch = 'arm'
+  elif host_arch.startswith('mips'):
+    host_arch = 'mips'
+  # platform.machine is based on running kernel. It's possible to use 64-bit
+  # kernel with 32-bit userland, e.g. to give linker slightly more memory.
+  # Distinguish between different userland bitness by querying
+  # the python binary.
+  if host_arch == 'x64' and platform.architecture()[0] == '32bit':
+    host_arch = 'ia32'
+  return host_arch
+def DoMain(_):
+  """Hook to be called from gyp without starting a separate python
+  interpreter."""
+  return HostArch()
+if __name__ == '__main__':
+  print DoMain([])
new file mode 100644
--- /dev/null
+++ b/security/nss/coreconf/empty.c
@@ -0,0 +1,1 @@
+/* This file is intentionally empty */
new file mode 100644
--- /dev/null
+++ b/security/nss/coreconf/nsinstall/nsinstall.gyp
@@ -0,0 +1,21 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'nsinstall',
+      'type': 'executable',
+      'sources': [
+        'nsinstall.c',
+        'pathsub.c'
+      ]
+    }
+  ],
+  'variables': {
+    'module': 'coreconf'
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/coreconf/nspr_include_dir.py
@@ -0,0 +1,17 @@
+#!/usr/bin/env python
+
+import os
+import subprocess
+
+def main():
+    try:
+        for part in subprocess.Popen(['pkg-config', '--cflags', 'nspr'], stdout=subprocess.PIPE, stderr=open(os.devnull, 'wb')).communicate()[0].strip().split():
+            if part.startswith('-I'):
+                print part[2:]
+                return
+    except OSError:
+        # pkg-config is probably not installed
+        pass
+
+if __name__ == '__main__':
+    main()
new file mode 100644
--- /dev/null
+++ b/security/nss/coreconf/nspr_lib_dir.py
@@ -0,0 +1,17 @@
+#!/usr/bin/env python
+
+import os
+import subprocess
+
+def main():
+    try:
+        for part in subprocess.Popen(['pkg-config', '--libs', 'nspr'], stdout=subprocess.PIPE, stderr=open(os.devnull, 'wb')).communicate()[0].strip().split():
+            if part.startswith('-L'):
+                print part[2:]
+                return
+    except OSError:
+        # pkg-config is probably not installed
+        pass
+
+if __name__ == '__main__':
+    main()
new file mode 100644
--- /dev/null
+++ b/security/nss/coreconf/pkg_config.py
@@ -0,0 +1,15 @@
+#!/usr/bin/env python
+
+import os
+import subprocess
+import sys
+
+def main():
+    try:
+        subprocess.Popen(['pkg-config'] + sys.argv[1:], stderr=open(os.devnull, 'wb')).wait()
+    except OSError:
+        # pkg-config is probably not installed
+        pass
+
+if __name__ == '__main__':
+    main()
--- a/security/nss/coreconf/sanitizers.mk
+++ b/security/nss/coreconf/sanitizers.mk
@@ -3,16 +3,20 @@
 
 ifeq ($(USE_ASAN), 1)
 SANITIZER_FLAGS_COMMON = -fsanitize=address
 
 ifeq ($(USE_UBSAN), 1)
 SANITIZER_FLAGS_COMMON += -fsanitize=undefined -fno-sanitize-recover=undefined
 endif
 
+ifeq ($(FUZZ), 1)
+SANITIZER_FLAGS_COMMON += -fsanitize-coverage=edge
+endif
+
 SANITIZER_FLAGS_COMMON += $(EXTRA_SANITIZER_FLAGS)
 SANITIZER_CFLAGS = $(SANITIZER_FLAGS_COMMON)
 SANITIZER_LDFLAGS = $(SANITIZER_FLAGS_COMMON)
 OS_CFLAGS += $(SANITIZER_CFLAGS)
 LDFLAGS += $(SANITIZER_LDFLAGS)
 
 # ASan needs frame pointers to save stack traces for allocation/free sites.
 # (Warning: some platforms, like ARM Linux in Thumb mode, don't have useful
new file mode 100644
--- /dev/null
+++ b/security/nss/exports.gyp
@@ -0,0 +1,77 @@
+# 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/.
+{
+  'includes': [
+    'coreconf/config.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'nss_exports',
+      'type': 'none',
+      'direct_dependent_settings': {
+        'include_dirs': [
+          '<(PRODUCT_DIR)/dist/nss/public'
+        ]
+      },
+      'dependencies': [
+        'cmd/lib/exports.gyp:cmd_lib_exports',
+        'lib/base/exports.gyp:lib_base_exports',
+        'lib/certdb/exports.gyp:lib_certdb_exports',
+        'lib/certhigh/exports.gyp:lib_certhigh_exports',
+        'lib/ckfw/builtins/exports.gyp:lib_ckfw_builtins_exports',
+        'lib/ckfw/exports.gyp:lib_ckfw_exports',
+        'lib/crmf/exports.gyp:lib_crmf_exports',
+        'lib/cryptohi/exports.gyp:lib_cryptohi_exports',
+        'lib/dev/exports.gyp:lib_dev_exports',
+        'lib/freebl/exports.gyp:lib_freebl_exports',
+        'lib/jar/exports.gyp:lib_jar_exports',
+        'lib/nss/exports.gyp:lib_nss_exports',
+        'lib/pk11wrap/exports.gyp:lib_pk11wrap_exports',
+        'lib/pkcs12/exports.gyp:lib_pkcs12_exports',
+        'lib/pkcs7/exports.gyp:lib_pkcs7_exports',
+        'lib/pki/exports.gyp:lib_pki_exports',
+        'lib/smime/exports.gyp:lib_smime_exports',
+        'lib/softoken/exports.gyp:lib_softoken_exports',
+        'lib/sqlite/exports.gyp:lib_sqlite_exports',
+        'lib/ssl/exports.gyp:lib_ssl_exports',
+        'lib/util/exports.gyp:lib_util_exports',
+        'lib/zlib/exports.gyp:lib_zlib_exports'
+      ],
+      'conditions': [
+        [ 'disable_libpkix==0', {
+          'dependencies': [
+            'lib/libpkix/include/exports.gyp:lib_libpkix_include_exports',
+            'lib/libpkix/pkix/certsel/exports.gyp:lib_libpkix_pkix_certsel_exports',
+            'lib/libpkix/pkix/checker/exports.gyp:lib_libpkix_pkix_checker_exports',
+            'lib/libpkix/pkix/crlsel/exports.gyp:lib_libpkix_pkix_crlsel_exports',
+            'lib/libpkix/pkix/params/exports.gyp:lib_libpkix_pkix_params_exports',
+            'lib/libpkix/pkix/results/exports.gyp:lib_libpkix_pkix_results_exports',
+            'lib/libpkix/pkix/store/exports.gyp:lib_libpkix_pkix_store_exports',
+            'lib/libpkix/pkix/top/exports.gyp:lib_libpkix_pkix_top_exports',
+            'lib/libpkix/pkix/util/exports.gyp:lib_libpkix_pkix_util_exports',
+            'lib/libpkix/pkix_pl_nss/module/exports.gyp:lib_libpkix_pkix_pl_nss_module_exports',
+            'lib/libpkix/pkix_pl_nss/pki/exports.gyp:lib_libpkix_pkix_pl_nss_pki_exports',
+            'lib/libpkix/pkix_pl_nss/system/exports.gyp:lib_libpkix_pkix_pl_nss_system_exports',
+          ],
+        }],
+      ],
+    },
+    {
+      'target_name': 'dbm_exports',
+      'type': 'none',
+      'conditions': [
+        ['disable_dbm==0', {
+          'direct_dependent_settings': {
+            'include_dirs': [
+              '<(PRODUCT_DIR)/dist/dbm/public'
+            ]
+          },
+          'dependencies': [
+            'lib/dbm/include/exports.gyp:lib_dbm_include_exports'
+          ],
+        }],
+      ],
+    }
+  ]
+}
new file mode 100644
--- /dev/null
+++ b/security/nss/external_tests/common/common.gyp
@@ -0,0 +1,36 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    'gtest.gypi',
+  ],
+  'targets': [
+    {
+      'target_name': 'gtests',
+      'type': 'executable',
+      'sources': [
+        'gtests.cc'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:nss_exports',
+        '<(DEPTH)/lib/nss/nss.gyp:nss3',
+        '<(DEPTH)/lib/util/util.gyp:nssutil3',
+        '<(DEPTH)/lib/smime/smime.gyp:smime3',
+        '<(DEPTH)/lib/ssl/ssl.gyp:ssl3',
+        '<(DEPTH)/external_tests/google_test/google_test.gyp:gtest',
+        '<(DEPTH)/cmd/lib/lib.gyp:sectool'
+      ]
+    }
+  ],
+  'target_defaults': {
+    'include_dirs': [
+      '../../external_tests/google_test/gtest/include',
+      '../../external_tests/common'
+    ],
+  },
+  'variables': {
+    'module': 'nss'
+  }
+}
new file mode 100644
--- /dev/null
+++ b/security/nss/external_tests/common/gtest.gypi
@@ -0,0 +1,30 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi'
+  ],
+  'target_defaults': {
+    'conditions': [
+      ['OS=="win"', {
+        'libraries': [
+          '-lws2_32',
+        ],
+      }],
+      ['OS=="android"', {
+        'libraries': [
+          '-lstdc++',
+        ],
+      }],
+    ],
+    'msvs_settings': {
+      'VCCLCompilerTool': {
+        'ExceptionHandling': 1,
+        'PreprocessorDefinitions': [
+          'NOMINMAX',
+        ],
+      },
+    },
+  },
+}
new file mode 100644
--- /dev/null
+++ b/security/nss/external_tests/der_gtest/der_gtest.gyp
@@ -0,0 +1,37 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    '../common/gtest.gypi',
+  ],
+  'targets': [
+    {
+      'target_name': 'der_gtest',
+      'type': 'executable',
+      'sources': [
+        'der_getint_unittest.cc',
+        '<(DEPTH)/external_tests/common/gtests.cc'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:nss_exports',
+        '<(DEPTH)/lib/nss/nss.gyp:nss3',
+        '<(DEPTH)/lib/util/util.gyp:nssutil3',
+        '<(DEPTH)/lib/smime/smime.gyp:smime3',
+        '<(DEPTH)/lib/ssl/ssl.gyp:ssl3',
+        '<(DEPTH)/external_tests/google_test/google_test.gyp:gtest',
+        '<(DEPTH)/cmd/lib/lib.gyp:sectool'
+      ]
+    }
+  ],
+  'target_defaults': {
+    'include_dirs': [
+      '../../external_tests/google_test/gtest/include',
+      '../../external_tests/common'
+    ]
+  },
+  'variables': {
+    'module': 'nss'
+  }
+}
new file mode 100644
--- /dev/null
+++ b/security/nss/external_tests/google_test/google_test.gyp
@@ -0,0 +1,59 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    '../common/gtest.gypi',
+  ],
+  'targets': [
+    {
+      'target_name': 'gtest',
+      'type': 'static_library',
+      'sources': [
+        'gtest/src/gtest-all.cc'
+      ],
+      'dependencies': [
+        '<(DEPTH)/lib/nss/nss.gyp:nss3',
+        '<(DEPTH)/lib/util/util.gyp:nssutil3',
+        '<(DEPTH)/lib/smime/smime.gyp:smime3',
+        '<(DEPTH)/lib/ssl/ssl.gyp:ssl3',
+        '<(DEPTH)/cmd/lib/lib.gyp:sectool'
+      ]
+    },
+    {
+      'target_name': 'gtest1',
+      'type': 'shared_library',
+      'dependencies': [
+        'gtest'
+      ],
+      # Work around a gyp bug. Fixed upstream in gyp:
+      # https://chromium.googlesource.com/external/gyp/+/93cc6e2c23e4d5ebd179f388e67aa907d0dfd43d
+      'conditions': [
+        ['OS!="win"', {
+          'libraries': [
+            '-lstdc++',
+          ],
+        }],
+      ],
+      # For some reason when just linking static libraries into
+      # a DLL the link fails without this.
+      'msvs_settings': {
+        'VCLinkerTool': {
+          'AdditionalDependencies': [
+            '/DEFAULTLIB:MSVCRT',
+          ],
+        },
+      },
+    }
+  ],
+  'target_defaults': {
+    'include_dirs': [
+      'gtest/include/',
+      'gtest'
+    ],
+  },
+  'variables': {
+    'module': 'gtest'
+  }
+}
new file mode 100644
--- /dev/null
+++ b/security/nss/external_tests/nss_bogo_shim/nss_bogo_shim.gyp
@@ -0,0 +1,79 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'nss_bogo_shim',
+      'type': 'executable',
+      'sources': [
+        'config.cc',
+        'nss_bogo_shim.cc',
+        'nsskeys.cc'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:nss_exports',
+        '<(DEPTH)/lib/util/util.gyp:nssutil3',
+        '<(DEPTH)/lib/sqlite/sqlite.gyp:sqlite3',
+        '<(DEPTH)/external_tests/google_test/google_test.gyp:gtest',
+        '<(DEPTH)/lib/softoken/softoken.gyp:softokn',
+        '<(DEPTH)/lib/smime/smime.gyp:smime',
+        '<(DEPTH)/lib/ssl/ssl.gyp:ssl',
+        '<(DEPTH)/lib/nss/nss.gyp:nss_static',
+        '<(DEPTH)/cmd/lib/lib.gyp:sectool',
+        '<(DEPTH)/lib/pkcs12/pkcs12.gyp:pkcs12',
+        '<(DEPTH)/lib/pkcs7/pkcs7.gyp:pkcs7',
+        '<(DEPTH)/lib/certhigh/certhigh.gyp:certhi',
+        '<(DEPTH)/lib/cryptohi/cryptohi.gyp:cryptohi',
+        '<(DEPTH)/lib/pk11wrap/pk11wrap.gyp:pk11wrap',
+        '<(DEPTH)/lib/softoken/softoken.gyp:softokn',
+        '<(DEPTH)/lib/certdb/certdb.gyp:certdb',
+        '<(DEPTH)/lib/pki/pki.gyp:nsspki',
+        '<(DEPTH)/lib/dev/dev.gyp:nssdev',
+        '<(DEPTH)/lib/base/base.gyp:nssb',
+        '<(DEPTH)/lib/freebl/freebl.gyp:freebl',
+        '<(DEPTH)/lib/nss/nss.gyp:nss_static',
+        '<(DEPTH)/lib/pk11wrap/pk11wrap.gyp:pk11wrap',
+        '<(DEPTH)/lib/certhigh/certhigh.gyp:certhi',
+        '<(DEPTH)/lib/zlib/zlib.gyp:nss_zlib'
+      ],
+      'conditions': [
+        [ 'disable_dbm==0', {
+          'dependencies': [
+            '<(DEPTH)/lib/dbm/src/src.gyp:dbm',
+          ],
+        }],
+        [ 'disable_libpkix==0', {
+          'dependencies': [
+            '<(DEPTH)/lib/libpkix/pkix/certsel/certsel.gyp:pkixcertsel',
+            '<(DEPTH)/lib/libpkix/pkix/checker/checker.gyp:pkixchecker',
+            '<(DEPTH)/lib/libpkix/pkix/crlsel/crlsel.gyp:pkixcrlsel',
+            '<(DEPTH)/lib/libpkix/pkix/params/params.gyp:pkixparams',
+            '<(DEPTH)/lib/libpkix/pkix/results/results.gyp:pkixresults',
+            '<(DEPTH)/lib/libpkix/pkix/store/store.gyp:pkixstore',
+            '<(DEPTH)/lib/libpkix/pkix/top/top.gyp:pkixtop',
+            '<(DEPTH)/lib/libpkix/pkix/util/util.gyp:pkixutil',
+            '<(DEPTH)/lib/libpkix/pkix_pl_nss/system/system.gyp:pkixsystem',
+            '<(DEPTH)/lib/libpkix/pkix_pl_nss/module/module.gyp:pkixmodule',
+            '<(DEPTH)/lib/libpkix/pkix_pl_nss/pki/pki.gyp:pkixpki',
+          ],
+        }],
+      ],
+    }
+  ],
+  'target_defaults': {
+    'defines': [
+      'NSS_USE_STATIC_LIBS'
+    ],
+    'include_dirs': [
+      '../../lib/ssl'
+    ],
+  },
+  'variables': {
+    'module': 'nss',
+    'use_static_libs': 1
+  }
+}
new file mode 100644
--- /dev/null
+++ b/security/nss/external_tests/pk11_gtest/pk11_gtest.gyp
@@ -0,0 +1,41 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    '../common/gtest.gypi',
+  ],
+  'targets': [
+    {
+      'target_name': 'pk11_gtest',
+      'type': 'executable',
+      'sources': [
+        'pk11_aeskeywrap_unittest.cc',
+        'pk11_chacha20poly1305_unittest.cc',
+        'pk11_pbkdf2_unittest.cc',
+        'pk11_prf_unittest.cc',
+        'pk11_rsapss_unittest.cc',
+        '<(DEPTH)/external_tests/common/gtests.cc'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:nss_exports',
+        '<(DEPTH)/lib/nss/nss.gyp:nss3',
+        '<(DEPTH)/lib/util/util.gyp:nssutil3',
+        '<(DEPTH)/lib/smime/smime.gyp:smime3',
+        '<(DEPTH)/lib/ssl/ssl.gyp:ssl3',
+        '<(DEPTH)/external_tests/google_test/google_test.gyp:gtest',
+        '<(DEPTH)/cmd/lib/lib.gyp:sectool'
+      ]
+    }
+  ],
+  'target_defaults': {
+    'include_dirs': [
+      '../../external_tests/google_test/gtest/include',
+      '../../external_tests/common'
+    ]
+  },
+  'variables': {
+    'module': 'nss'
+  }
+}
--- a/security/nss/external_tests/ssl_gtest/libssl_internals.c
+++ b/security/nss/external_tests/ssl_gtest/libssl_internals.c
@@ -19,39 +19,16 @@ SECStatus SSLInt_IncrementClientHandshak
     return SECFailure;
   }
 
   ++ss->clientHelloVersion;
 
   return SECSuccess;
 }
 
-// This function guesses what key exchange strength libssl will choose.
-PRUint32 SSLInt_DetermineKEABits(PRUint16 serverKeyBits,
-                                 SSLAuthType authAlgorithm,
-                                 PRUint32 symKeyBits) {
-  PRUint32 authBits;
-
-  if (authAlgorithm == ssl_auth_ecdsa || authAlgorithm == ssl_auth_ecdh_rsa ||
-      authAlgorithm == ssl_auth_ecdh_ecdsa) {
-    authBits = serverKeyBits;
-  } else {
-    PORT_Assert(authAlgorithm == ssl_auth_rsa_decrypt ||
-                authAlgorithm == ssl_auth_rsa_sign);
-    authBits = SSL_RSASTRENGTH_TO_ECSTRENGTH(serverKeyBits);
-  }
-
-  // We expect a curve for key exchange to be selected based on the symmetric
-  // key strength (times 2) or the server key size, whichever is smaller.
-  PRUint32 targetKeaBits = PR_MIN(symKeyBits * 2, authBits);
-
-  // P-256 is the preferred curve of minimum size.
-  return PR_MAX(256U, targetKeaBits);
-}
-
 /* Use this function to update the ClientRandom of a client's handshake state
  * after replacing its ClientHello message. We for example need to do this
  * when replacing an SSLv3 ClientHello with its SSLv2 equivalent. */
 SECStatus SSLInt_UpdateSSLv2ClientRandom(PRFileDesc *fd, uint8_t *rnd,
                                          size_t rnd_len, uint8_t *msg,
                                          size_t msg_len) {
   sslSocket *ss = ssl_FindSocket(fd);
   if (!ss) {
--- a/security/nss/external_tests/ssl_gtest/libssl_internals.h
+++ b/security/nss/external_tests/ssl_gtest/libssl_internals.h
@@ -10,19 +10,16 @@
 #include <stdint.h>
 
 #include "prio.h"
 #include "seccomon.h"
 #include "sslt.h"
 
 SECStatus SSLInt_IncrementClientHandshakeVersion(PRFileDesc *fd);
 
-PRUint32 SSLInt_DetermineKEABits(PRUint16 serverKeyBits,
-                                 SSLAuthType authAlgorithm,
-                                 PRUint32 symKeyBits);
 SECStatus SSLInt_UpdateSSLv2ClientRandom(PRFileDesc *fd, uint8_t *rnd,
                                          size_t rnd_len, uint8_t *msg,
                                          size_t msg_len);
 
 PRBool SSLInt_ExtensionNegotiated(PRFileDesc *fd, PRUint16 ext);
 void SSLInt_ClearSessionTicketKey();
 PRInt32 SSLInt_CountTls13CipherSpecs(PRFileDesc *fd);
 void SSLInt_ForceTimerExpiry(PRFileDesc *fd);
--- a/security/nss/external_tests/ssl_gtest/ssl_0rtt_unittest.cc
+++ b/security/nss/external_tests/ssl_gtest/ssl_0rtt_unittest.cc
@@ -91,17 +91,17 @@ TEST_P(TlsConnectTls13, ZeroRttServerOnl
   PRInt32 rv = PR_Read(server_->ssl_fd(), buf, sizeof(buf));
   EXPECT_EQ(SECFailure, rv);
   EXPECT_EQ(PR_WOULD_BLOCK_ERROR, PORT_GetError());
 
   // Now make sure that things complete.
   Handshake();
   CheckConnected();
   SendReceive();
-  CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign);
+  CheckKeys();
 }
 
 TEST_P(TlsConnectTls13, TestTls13ZeroRttAlpn) {
   EnableAlpn();
   SetupForZeroRtt();
   EnableAlpn();
   client_->Set0RttEnabled(true);
   server_->Set0RttEnabled(true);
--- a/security/nss/external_tests/ssl_gtest/ssl_auth_unittest.cc
+++ b/security/nss/external_tests/ssl_gtest/ssl_auth_unittest.cc
@@ -20,56 +20,56 @@ extern "C" {
 #include "tls_filter.h"
 #include "tls_parser.h"
 
 namespace nss_test {
 
 TEST_P(TlsConnectGeneric, ServerAuthBigRsa) {
   Reset(TlsAgent::kRsa2048);
   Connect();
-  CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign);
+  CheckKeys();
 }
 
 TEST_P(TlsConnectGeneric, ClientAuth) {
   client_->SetupClientAuth();
   server_->RequestClientAuth(true);
   Connect();
-  CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign);
+  CheckKeys();
 }
 
 // In TLS 1.3, the client sends its cert rejection on the
 // second flight, and since it has already received the
 // server's Finished, it transitions to complete and
 // then gets an alert from the server. The test harness
 // doesn't handle this right yet.
 TEST_P(TlsConnectStream, DISABLED_ClientAuthRequiredRejected) {
   server_->RequestClientAuth(true);
   ConnectExpectFail();
 }
 
 TEST_P(TlsConnectGeneric, ClientAuthRequestedRejected) {
   server_->RequestClientAuth(false);
   Connect();
-  CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign);
+  CheckKeys();
 }
 
 TEST_P(TlsConnectGeneric, ClientAuthEcdsa) {
   Reset(TlsAgent::kServerEcdsa256);
   client_->SetupClientAuth();
   server_->RequestClientAuth(true);
   Connect();
   CheckKeys(ssl_kea_ecdh, ssl_auth_ecdsa);
 }
 
 TEST_P(TlsConnectGeneric, ClientAuthBigRsa) {
   Reset(TlsAgent::kServerRsa, TlsAgent::kRsa2048);
   client_->SetupClientAuth();
   server_->RequestClientAuth(true);
   Connect();
-  CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign);
+  CheckKeys();
 }
 
 // Offset is the position in the captured buffer where the signature sits.
 static void CheckSigScheme(TlsInspectorRecordHandshakeMessage* capture,
                            size_t offset, TlsAgent* peer,
                            uint16_t expected_scheme, size_t expected_size) {
   EXPECT_LT(offset + 2U, capture->buffer().len());
 
@@ -85,112 +85,128 @@ static void CheckSigScheme(TlsInspectorR
 // The server should prefer SHA-256 by default, even for the small key size used
 // in the default certificate.
 TEST_P(TlsConnectTls12, ServerAuthCheckSigAlg) {
   EnsureTlsSetup();
   auto capture_ske =
       new TlsInspectorRecordHandshakeMessage(kTlsHandshakeServerKeyExchange);
   server_->SetPacketFilter(capture_ske);
   Connect();
-  CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign);
+  CheckKeys();
 
   const DataBuffer& buffer = capture_ske->buffer();
   EXPECT_LT(3U, buffer.len());
   EXPECT_EQ(3U, buffer.data()[0]) << "curve_type == named_curve";
   uint32_t tmp;
   EXPECT_TRUE(buffer.Read(1, 2, &tmp)) << "read NamedCurve";
-  EXPECT_EQ(ssl_grp_ec_secp256r1, tmp);
+  EXPECT_EQ(ssl_grp_ec_curve25519, tmp);
   EXPECT_TRUE(buffer.Read(3, 1, &tmp)) << " read ECPoint";
   CheckSigScheme(capture_ske, 4 + tmp, client_, kTlsSigSchemeRsaPssSha256,
                  1024);
 }
 
 TEST_P(TlsConnectTls12, ClientAuthCheckSigAlg) {
   EnsureTlsSetup();
   auto capture_cert_verify =
       new TlsInspectorRecordHandshakeMessage(kTlsHandshakeCertificateVerify);
   client_->SetPacketFilter(capture_cert_verify);
   client_->SetupClientAuth();
   server_->RequestClientAuth(true);
   Connect();
-  CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign);
+  CheckKeys();
 
   CheckSigScheme(capture_cert_verify, 0, server_, kTlsSigSchemeRsaPkcs1Sha1,
                  1024);
 }
 
 TEST_P(TlsConnectTls12, ClientAuthBigRsaCheckSigAlg) {
   Reset(TlsAgent::kServerRsa, TlsAgent::kRsa2048);
   auto capture_cert_verify =
       new TlsInspectorRecordHandshakeMessage(kTlsHandshakeCertificateVerify);
   client_->SetPacketFilter(capture_cert_verify);
   client_->SetupClientAuth();
   server_->RequestClientAuth(true);
   Connect();
-  CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign);
+  CheckKeys();
   CheckSigScheme(capture_cert_verify, 0, server_, kTlsSigSchemeRsaPssSha256,
                  2048);
 }
 
 static const SSLSignatureAndHashAlg SignatureEcdsaSha384[] = {
     {ssl_hash_sha384, ssl_sign_ecdsa}};
 static const SSLSignatureAndHashAlg SignatureEcdsaSha256[] = {
     {ssl_hash_sha256, ssl_sign_ecdsa}};
 static const SSLSignatureAndHashAlg SignatureRsaSha384[] = {
     {ssl_hash_sha384, ssl_sign_rsa}};
 static const SSLSignatureAndHashAlg SignatureRsaSha256[] = {
     {ssl_hash_sha256, ssl_sign_rsa}};
 
+static SSLNamedGroup NamedGroupForEcdsa384(uint16_t version) {
+  // NSS tries to match the group size to the symmetric cipher. In TLS 1.1 and
+  // 1.0, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA is the highest priority suite, so
+  // we use P-384. With TLS 1.2 on we pick AES-128 GCM so use x25519.
+  if (version <= SSL_LIBRARY_VERSION_TLS_1_1) {
+    return ssl_grp_ec_secp384r1;
+  }
+  return ssl_grp_ec_curve25519;
+}
+
 // When signature algorithms match up, this should connect successfully; even
 // for TLS 1.1 and 1.0, where they should be ignored.
 TEST_P(TlsConnectGeneric, SignatureAlgorithmServerAuth) {
   Reset(TlsAgent::kServerEcdsa384);
   client_->SetSignatureAlgorithms(SignatureEcdsaSha384,
                                   PR_ARRAY_SIZE(SignatureEcdsaSha384));
   server_->SetSignatureAlgorithms(SignatureEcdsaSha384,
                                   PR_ARRAY_SIZE(SignatureEcdsaSha384));
   Connect();
-  CheckKeys(ssl_kea_ecdh, ssl_auth_ecdsa);
+  CheckKeys(ssl_kea_ecdh, NamedGroupForEcdsa384(version_), ssl_auth_ecdsa,
+            ssl_sig_ecdsa_secp384r1_sha384);
 }
 
 // Here the client picks a single option, which should work in all versions.
 // Defaults on the server include the first option.
 TEST_P(TlsConnectGeneric, SignatureAlgorithmClientOnly) {
   const SSLSignatureAndHashAlg clientAlgorithms[] = {
       {ssl_hash_sha384, ssl_sign_ecdsa},
       {ssl_hash_sha384, ssl_sign_rsa},  // supported but unusable
       {ssl_hash_md5, ssl_sign_ecdsa}    // unsupported and ignored
   };
   Reset(TlsAgent::kServerEcdsa384);
   client_->SetSignatureAlgorithms(clientAlgorithms,
                                   PR_ARRAY_SIZE(clientAlgorithms));
   Connect();
-  CheckKeys(ssl_kea_ecdh, ssl_auth_ecdsa);
+  CheckKeys(ssl_kea_ecdh, NamedGroupForEcdsa384(version_), ssl_auth_ecdsa,
+            ssl_sig_ecdsa_secp384r1_sha384);
 }
 
 // Here the server picks a single option, which should work in all versions.
 // Defaults on the client include the provided option.
 TEST_P(TlsConnectGeneric, SignatureAlgorithmServerOnly) {
   Reset(TlsAgent::kServerEcdsa384);
   server_->SetSignatureAlgorithms(SignatureEcdsaSha384,
                                   PR_ARRAY_SIZE(SignatureEcdsaSha384));
   Connect();
-  CheckKeys(ssl_kea_ecdh, ssl_auth_ecdsa);
+  CheckKeys(ssl_kea_ecdh, NamedGroupForEcdsa384(version_), ssl_auth_ecdsa,
+            ssl_sig_ecdsa_secp384r1_sha384);
 }
 
 // In TlS 1.2, a P-256 cert can be used with SHA-384.
 TEST_P(TlsConnectTls12, SignatureSchemeCurveMismatch12) {
   Reset(TlsAgent::kServerEcdsa256);
   client_->SetSignatureAlgorithms(SignatureEcdsaSha384,
                                   PR_ARRAY_SIZE(SignatureEcdsaSha384));
   Connect();
-  CheckKeys(ssl_kea_ecdh, ssl_auth_ecdsa);
+  // The scheme is reported as using secp384r1, but this is just the generic
+  // ECDSA + SHA-384 codepoint as defined in TLS 1.2.
+  CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_ecdsa,
+            ssl_sig_ecdsa_secp384r1_sha384);
 }
 
-#ifdef NSS_ENABLE_TLS_1_3
+#ifndef NSS_DISABLE_TLS_1_3
 TEST_P(TlsConnectTls13, SignatureAlgorithmServerUnsupported) {
   Reset(TlsAgent::kServerEcdsa256);  // P-256 cert
   server_->SetSignatureAlgorithms(SignatureEcdsaSha384,
                                   PR_ARRAY_SIZE(SignatureEcdsaSha384));
   ConnectExpectFail();
   server_->CheckErrorCode(SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM);
   client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
 }
--- a/security/nss/external_tests/ssl_gtest/ssl_ciphersuite_unittest.cc
+++ b/security/nss/external_tests/ssl_gtest/ssl_ciphersuite_unittest.cc
@@ -289,18 +289,17 @@ TEST_P(TlsCipherSuiteTest, WriteLimit) {
   static const ::testing::internal::ParamGenerator<uint16_t>                   \
       k##name##Ciphers = ::testing::ValuesIn(k##name##CiphersArr);             \
   INSTANTIATE_TEST_CASE_P(                                                     \
       CipherSuite##name, TlsCipherSuiteTest,                                   \
       ::testing::Combine(TlsConnectTestBase::kTlsModes##modes,                 \
                          TlsConnectTestBase::kTls##versions, k##name##Ciphers, \
                          groups, sigalgs));
 
-static const SSLNamedGroup kDummyNamedGroupParamsArr[] = {
-    static_cast<SSLNamedGroup>(0)};
+static const SSLNamedGroup kDummyNamedGroupParamsArr[] = {ssl_grp_none};
 static const auto kDummyNamedGroupParams =
     ::testing::ValuesIn(kDummyNamedGroupParamsArr);
 static const TlsSignatureScheme kDummySignatureSchemesParamsArr[] = {
     kTlsSignatureNone};
 static const auto kDummySignatureSchemesParams =
     ::testing::ValuesIn(kDummySignatureSchemesParamsArr);
 
 #ifndef NSS_DISABLE_TLS_1_3
@@ -399,19 +398,19 @@ inline std::ostream &operator<<(std::ost
                 << "\", key size = " << vals.keySize;
 }
 
 class SecurityStatusTest
     : public TlsCipherSuiteTestBase,
       public ::testing::WithParamInterface<SecStatusParams> {
  public:
   SecurityStatusTest()
-      : TlsCipherSuiteTestBase(
-            "TLS", GetParam().version, GetParam().cipher_suite,
-            static_cast<SSLNamedGroup>(0), kTlsSignatureNone) {}
+      : TlsCipherSuiteTestBase("TLS", GetParam().version,
+                               GetParam().cipher_suite, ssl_grp_none,
+                               kTlsSignatureNone) {}
 };
 
 // SSL_SecurityStatus produces fairly useless output when compared to
 // SSL_GetCipherSuiteInfo and SSL_GetChannelInfo, but we can't break it, so we
 // need to check it.
 TEST_P(SecurityStatusTest, CheckSecurityStatus) {
   SetupCertificate();
   EnableSingleCipher();
--- a/security/nss/external_tests/ssl_gtest/ssl_dhe_unittest.cc
+++ b/security/nss/external_tests/ssl_gtest/ssl_dhe_unittest.cc
@@ -18,33 +18,34 @@
 #include "tls_filter.h"
 #include "tls_parser.h"
 
 namespace nss_test {
 
 TEST_P(TlsConnectGeneric, ConnectDhe) {
   EnableOnlyDheCiphers();
   Connect();
-  CheckKeys(ssl_kea_dh, ssl_auth_rsa_sign);
+  CheckKeys(ssl_kea_dh, ssl_grp_ffdhe_2048, ssl_auth_rsa_sign,
+            ssl_sig_rsa_pss_sha256);
 }
 
 TEST_P(TlsConnectTls13, SharesForBothEcdheAndDhe) {
   EnsureTlsSetup();
   client_->ConfigNamedGroups(kAllDHEGroups);
 
   auto groups_capture = new TlsExtensionCapture(ssl_supported_groups_xtn);
   auto shares_capture = new TlsExtensionCapture(ssl_tls13_key_share_xtn);
   std::vector<PacketFilter*> captures;
   captures.push_back(groups_capture);
   captures.push_back(shares_capture);
   client_->SetPacketFilter(new ChainedPacketFilter(captures));
 
   Connect();
 
-  CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign);
+  CheckKeys();
 
   bool ec, dh;
   auto track_group_type = [&ec, &dh](SSLNamedGroup group) {
     if ((group & 0xff00U) == 0x100U) {
       dh = true;
     } else {
       ec = true;
     }
@@ -448,17 +449,20 @@ TEST_P(TlsConnectGeneric, Ffdhe3072) {
 TEST_P(TlsConnectGenericPre13, PreferredFfdhe) {
   EnableOnlyDheCiphers();
   static const SSLDHEGroupType groups[] = {ssl_ff_dhe_3072_group,
                                            ssl_ff_dhe_2048_group};
   EXPECT_EQ(SECSuccess, SSL_DHEGroupPrefSet(server_->ssl_fd(), groups,
                                             PR_ARRAY_SIZE(groups)));
 
   Connect();
-  CheckKeys(ssl_kea_dh, ssl_auth_rsa_sign, 3072);
+  client_->CheckKEA(ssl_kea_dh, ssl_grp_ffdhe_3072, 3072);
+  server_->CheckKEA(ssl_kea_dh, ssl_grp_ffdhe_3072, 3072);
+  client_->CheckAuthType(ssl_auth_rsa_sign, ssl_sig_rsa_pss_sha256);
+  server_->CheckAuthType(ssl_auth_rsa_sign, ssl_sig_rsa_pss_sha256);
 }
 
 TEST_P(TlsConnectGenericPre13, MismatchDHE) {
   EnableOnlyDheCiphers();
   EXPECT_EQ(SECSuccess, SSL_OptionSet(client_->ssl_fd(),
                                       SSL_REQUIRE_DH_NAMED_GROUPS, PR_TRUE));
   static const SSLDHEGroupType serverGroups[] = {ssl_ff_dhe_3072_group};
   EXPECT_EQ(SECSuccess, SSL_DHEGroupPrefSet(server_->ssl_fd(), serverGroups,
@@ -485,14 +489,14 @@ TEST_P(TlsConnectTls13, ResumeFfdhe) {
   TlsExtensionCapture* clientCapture =
       new TlsExtensionCapture(ssl_tls13_pre_shared_key_xtn);
   client_->SetPacketFilter(clientCapture);
   TlsExtensionCapture* serverCapture =
       new TlsExtensionCapture(ssl_tls13_pre_shared_key_xtn);
   server_->SetPacketFilter(serverCapture);
   ExpectResumption(RESUME_TICKET);
   Connect();
-  CheckKeys(ssl_kea_dh, ssl_auth_rsa_sign);
+  CheckKeys(ssl_kea_dh, ssl_grp_ffdhe_2048, ssl_auth_rsa_sign, ssl_sig_none);
   ASSERT_LT(0UL, clientCapture->extension().len());
   ASSERT_LT(0UL, serverCapture->extension().len());
 }
 
 }  // namespace nss_test
--- a/security/nss/external_tests/ssl_gtest/ssl_ecdh_unittest.cc
+++ b/security/nss/external_tests/ssl_gtest/ssl_ecdh_unittest.cc
@@ -26,125 +26,135 @@ namespace nss_test {
 
 TEST_P(TlsConnectGenericPre13, ConnectEcdh) {
   SetExpectedVersion(std::get<1>(GetParam()));
   Reset(TlsAgent::kServerEcdhEcdsa);
   DisableAllCiphers();
   EnableSomeEcdhCiphers();
 
   Connect();
-  CheckKeys(ssl_kea_ecdh, ssl_auth_ecdh_ecdsa);
+  CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp256r1, ssl_auth_ecdh_ecdsa,
+            ssl_sig_none);
 }
 
 TEST_P(TlsConnectGenericPre13, ConnectEcdhWithoutDisablingSuites) {
   SetExpectedVersion(std::get<1>(GetParam()));
   Reset(TlsAgent::kServerEcdhEcdsa);
   EnableSomeEcdhCiphers();
 
   Connect();
-  CheckKeys(ssl_kea_ecdh, ssl_auth_ecdh_ecdsa);
+  CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp256r1, ssl_auth_ecdh_ecdsa,
+            ssl_sig_none);
 }
 
 TEST_P(TlsConnectGeneric, ConnectEcdhe) {
   Connect();
-  CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign);
+  CheckKeys();
 }
 
 // If we pick a 256-bit cipher suite and use a P-384 certificate, the server
 // should choose P-384 for key exchange too.  Only valid for TLS == 1.2 because
 // we don't have 256-bit ciphers before then and 1.3 doesn't try to couple
 // DHE size to symmetric size.
 TEST_P(TlsConnectTls12, ConnectEcdheP384) {
   Reset(TlsAgent::kServerEcdsa384);
   ConnectWithCipherSuite(TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256);
-  CheckKeys(ssl_kea_ecdh, ssl_auth_ecdsa, 384);
+  // This uses SHA-256 because TLS 1.2 doesn't care for the
+  // pairing of curve and hash function like in TLS 1.3.
+  CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp384r1, ssl_auth_ecdsa,
+            ssl_sig_ecdsa_secp256r1_sha256);
 }
 
 TEST_P(TlsConnectGeneric, ConnectEcdheP384Client) {
   EnsureTlsSetup();
   const std::vector<SSLNamedGroup> groups = {ssl_grp_ec_secp384r1,
                                              ssl_grp_ffdhe_2048};
   client_->ConfigNamedGroups(groups);
   server_->ConfigNamedGroups(groups);
   Connect();
-  CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign, 384);
+  CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp384r1, ssl_auth_rsa_sign,
+            ssl_sig_rsa_pss_sha256);
 }
 
 // This causes a HelloRetryRequest in TLS 1.3.  Earlier versions don't care.
 TEST_P(TlsConnectGeneric, ConnectEcdheP384Server) {
   EnsureTlsSetup();
   auto hrr_capture =
       new TlsInspectorRecordHandshakeMessage(kTlsHandshakeHelloRetryRequest);
   server_->SetPacketFilter(hrr_capture);
   const std::vector<SSLNamedGroup> groups = {ssl_grp_ec_secp384r1};
   server_->ConfigNamedGroups(groups);
   Connect();
-  CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign, 384);
+  CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp384r1, ssl_auth_rsa_sign,
+            ssl_sig_rsa_pss_sha256);
   EXPECT_EQ(version_ == SSL_LIBRARY_VERSION_TLS_1_3,
             hrr_capture->buffer().len() != 0);
 }
 
 // This enables only P-256 on the client and disables it on the server.
 // This test will fail when we add other groups that identify as ECDHE.
 TEST_P(TlsConnectGeneric, ConnectEcdheGroupMismatch) {
   EnsureTlsSetup();
-  const std::vector<SSLNamedGroup> clientGroups = {ssl_grp_ec_secp256r1,
-                                                   ssl_grp_ffdhe_2048};
-  const std::vector<SSLNamedGroup> serverGroups = {ssl_grp_ffdhe_2048};
-  client_->ConfigNamedGroups(clientGroups);
-  server_->ConfigNamedGroups(serverGroups);
+  const std::vector<SSLNamedGroup> client_groups = {ssl_grp_ec_secp256r1,
+                                                    ssl_grp_ffdhe_2048};
+  const std::vector<SSLNamedGroup> server_groups = {ssl_grp_ffdhe_2048};
+  client_->ConfigNamedGroups(client_groups);
+  server_->ConfigNamedGroups(server_groups);
 
   Connect();
   CheckKeys(ssl_kea_dh, ssl_auth_rsa_sign);
 }
 
 TEST_P(TlsKeyExchangeTest, P384Priority) {
   // P256, P384 and P521 are enabled. Both prefer P384.
   const std::vector<SSLNamedGroup> groups = {
       ssl_grp_ec_secp384r1, ssl_grp_ec_secp256r1, ssl_grp_ec_secp521r1};
   EnsureKeyShareSetup();
   ConfigNamedGroups(groups);
   client_->DisableAllCiphers();
   client_->EnableCiphersByKeyExchange(ssl_kea_ecdh);
   Connect();
 
-  CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign, 384);
+  CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp384r1, ssl_auth_rsa_sign,
+            ssl_sig_rsa_pss_sha256);
 
   std::vector<SSLNamedGroup> shares = {ssl_grp_ec_secp384r1};
   CheckKEXDetails(groups, shares);
 }
 
 TEST_P(TlsKeyExchangeTest, DuplicateGroupConfig) {
   const std::vector<SSLNamedGroup> groups = {
       ssl_grp_ec_secp384r1, ssl_grp_ec_secp384r1, ssl_grp_ec_secp384r1,
       ssl_grp_ec_secp256r1, ssl_grp_ec_secp256r1};
   EnsureKeyShareSetup();
   ConfigNamedGroups(groups);
   client_->DisableAllCiphers();
   client_->EnableCiphersByKeyExchange(ssl_kea_ecdh);
   Connect();
 
-  CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign, 384);
+  CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp384r1, ssl_auth_rsa_sign,
+            ssl_sig_rsa_pss_sha256);
 
   std::vector<SSLNamedGroup> shares = {ssl_grp_ec_secp384r1};
   std::vector<SSLNamedGroup> expectedGroups = {ssl_grp_ec_secp384r1,
                                                ssl_grp_ec_secp256r1};
   CheckKEXDetails(expectedGroups, shares);
 }
 
 TEST_P(TlsKeyExchangeTest, P384PriorityDHEnabled) {
   // P256, P384,  P521, and FFDHE2048 are enabled. Both prefer P384.
   const std::vector<SSLNamedGroup> groups = {
       ssl_grp_ec_secp384r1, ssl_grp_ffdhe_2048, ssl_grp_ec_secp256r1,
       ssl_grp_ec_secp521r1};
   EnsureKeyShareSetup();
   ConfigNamedGroups(groups);
   Connect();
 
-  CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign, 384);
+  CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp384r1, ssl_auth_rsa_sign,
+            ssl_sig_rsa_pss_sha256);
 
   if (version_ >= SSL_LIBRARY_VERSION_TLS_1_3) {
     std::vector<SSLNamedGroup> shares = {ssl_grp_ec_secp384r1};
     CheckKEXDetails(groups, shares);
   } else {
     std::vector<SSLNamedGroup> oldtlsgroups = {
         ssl_grp_ec_secp384r1, ssl_grp_ec_secp256r1, ssl_grp_ec_secp521r1};
     CheckKEXDetails(oldtlsgroups, std::vector<SSLNamedGroup>());
@@ -152,23 +162,24 @@ TEST_P(TlsKeyExchangeTest, P384PriorityD
 }
 
 TEST_P(TlsConnectGenericPre13, P384PriorityOnServer) {
   EnsureTlsSetup();
   client_->DisableAllCiphers();
   client_->EnableCiphersByKeyExchange(ssl_kea_ecdh);
 
   // The server prefers P384. It has to win.
-  const std::vector<SSLNamedGroup> serverGroups = {
+  const std::vector<SSLNamedGroup> server_groups = {
       ssl_grp_ec_secp384r1, ssl_grp_ec_secp256r1, ssl_grp_ec_secp521r1};
-  server_->ConfigNamedGroups(serverGroups);
+  server_->ConfigNamedGroups(server_groups);
 
   Connect();
 
-  CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign, 384);
+  CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp384r1, ssl_auth_rsa_sign,
+            ssl_sig_rsa_pss_sha256);
 }
 
 TEST_P(TlsConnectGenericPre13, P384PriorityFromModelSocket) {
 #ifdef NSS_ECC_MORE_THAN_SUITE_B
   // We can't run this test with a model socket and more than suite B.
   return;
 #endif
   EnsureModelSockets();
@@ -177,26 +188,27 @@ TEST_P(TlsConnectGenericPre13, P384Prior
   const std::vector<SSLNamedGroup> groups = {
       ssl_grp_ec_secp384r1, ssl_grp_ec_secp256r1, ssl_grp_ec_secp521r1,
       ssl_grp_ffdhe_2048};
   client_model_->ConfigNamedGroups(groups);
   server_model_->ConfigNamedGroups(groups);
 
   Connect();
 
-  CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign, 384);
+  CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp384r1, ssl_auth_rsa_sign,
+            ssl_sig_rsa_pss_sha256);
 }
 
 // If we only have a lame group, we fall back to static RSA.
 TEST_P(TlsConnectGenericPre13, UseLameGroup) {
   const std::vector<SSLNamedGroup> groups = {ssl_grp_ec_secp192r1};
   client_->ConfigNamedGroups(groups);
   server_->ConfigNamedGroups(groups);
   Connect();
-  CheckKeys(ssl_kea_rsa, ssl_auth_rsa_decrypt);
+  CheckKeys(ssl_kea_rsa, ssl_grp_none, ssl_auth_rsa_decrypt, ssl_sig_none);
 }
 
 // In TLS 1.3, we can't generate the ClientHello.
 TEST_P(TlsConnectTls13, UseLameGroup) {
   const std::vector<SSLNamedGroup> groups = {ssl_grp_ec_sect283k1};
   client_->ConfigNamedGroups(groups);
   server_->ConfigNamedGroups(groups);
   client_->StartConnect();
@@ -206,82 +218,240 @@ TEST_P(TlsConnectTls13, UseLameGroup) {
 #endif
 }
 
 TEST_P(TlsConnectStreamPre13, ConfiguredGroupsRenegotiate) {
   EnsureTlsSetup();
   client_->DisableAllCiphers();
   client_->EnableCiphersByKeyExchange(ssl_kea_ecdh);
 
-  const std::vector<SSLNamedGroup> serverGroups = {ssl_grp_ec_secp256r1,
-                                                   ssl_grp_ec_secp384r1};
-  const std::vector<SSLNamedGroup> clientGroups = {ssl_grp_ec_secp384r1};
-  server_->ConfigNamedGroups(clientGroups);
-  client_->ConfigNamedGroups(serverGroups);
+  const std::vector<SSLNamedGroup> client_groups = {ssl_grp_ec_secp256r1};
+  const std::vector<SSLNamedGroup> server_groups = {ssl_grp_ec_secp256r1,
+                                                    ssl_grp_ec_secp256r1};
+  client_->ConfigNamedGroups(client_groups);
+  server_->ConfigNamedGroups(server_groups);
 
   Connect();
 
-  CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign, 384);
+  CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp256r1, ssl_auth_rsa_sign,
+            ssl_sig_rsa_pss_sha256);
   CheckConnected();
 
   // The renegotiation has to use the same preferences as the original session.
   server_->PrepareForRenegotiate();
   client_->StartRenegotiate();
   Handshake();
-  CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign, 384);
+  CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp256r1, ssl_auth_rsa_sign,
+            ssl_sig_rsa_pss_sha256);
 }
 
 TEST_P(TlsKeyExchangeTest, Curve25519) {
   Reset(TlsAgent::kServerEcdsa256);
   const std::vector<SSLNamedGroup> groups = {
       ssl_grp_ec_curve25519, ssl_grp_ec_secp256r1, ssl_grp_ec_secp521r1};
   EnsureKeyShareSetup();
   ConfigNamedGroups(groups);
   Connect();
 
-  CheckKeys(ssl_kea_ecdh, ssl_auth_ecdsa, 255);
+  CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_ecdsa,
+            ssl_sig_ecdsa_secp256r1_sha256);
   const std::vector<SSLNamedGroup> shares = {ssl_grp_ec_curve25519};
   CheckKEXDetails(groups, shares);
 }
 
-TEST_P(TlsConnectGeneric, P256andCurve25519OnlyServer) {
+TEST_P(TlsConnectGenericPre13, GroupPreferenceServerPriority) {
   EnsureTlsSetup();
   client_->DisableAllCiphers();
   client_->EnableCiphersByKeyExchange(ssl_kea_ecdh);
 
-  // the client sends a P256 key share while the server prefers 25519
+  // The client prefers P256 while the server prefers 25519.
+  // The server's preference has to win.
+  const std::vector<SSLNamedGroup> client_groups = {ssl_grp_ec_secp256r1,
+                                                    ssl_grp_ec_curve25519};
   const std::vector<SSLNamedGroup> server_groups = {ssl_grp_ec_curve25519,
                                                     ssl_grp_ec_secp256r1};
+  client_->ConfigNamedGroups(client_groups);
+  server_->ConfigNamedGroups(server_groups);
+
+  Connect();
+
+  CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_rsa_sign,
+            ssl_sig_rsa_pss_sha256);
+}
+
+#ifndef NSS_DISABLE_TLS_1_3
+TEST_P(TlsKeyExchangeTest13, Curve25519P256EqualPriorityClient13) {
+  EnsureKeyShareSetup();
+
+  // The client sends a P256 key share while the server prefers 25519.
+  // We have to accept P256 without retry.
   const std::vector<SSLNamedGroup> client_groups = {ssl_grp_ec_secp256r1,
                                                     ssl_grp_ec_curve25519};
+  const std::vector<SSLNamedGroup> server_groups = {ssl_grp_ec_curve25519,
+                                                    ssl_grp_ec_secp256r1};
+  client_->ConfigNamedGroups(client_groups);
+  server_->ConfigNamedGroups(server_groups);
+
+  Connect();
+
+  CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp256r1, ssl_auth_rsa_sign,
+            ssl_sig_rsa_pss_sha256);
+  const std::vector<SSLNamedGroup> shares = {ssl_grp_ec_secp256r1};
+  CheckKEXDetails(client_groups, shares, false);
+}
+
+TEST_P(TlsKeyExchangeTest13, Curve25519P256EqualPriorityServer13) {
+  EnsureKeyShareSetup();
+
+  // The client sends a 25519 key share while the server prefers P256.
+  // We have to accept 25519 without retry.
+  const std::vector<SSLNamedGroup> client_groups = {ssl_grp_ec_curve25519,
+                                                    ssl_grp_ec_secp256r1};
+  const std::vector<SSLNamedGroup> server_groups = {ssl_grp_ec_secp256r1,
+                                                    ssl_grp_ec_curve25519};
   client_->ConfigNamedGroups(client_groups);
   server_->ConfigNamedGroups(server_groups);
 
   Connect();
 
-  CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign, 255);
+  CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_rsa_sign,
+            ssl_sig_rsa_pss_sha256);
+  const std::vector<SSLNamedGroup> shares = {ssl_grp_ec_curve25519};
+  CheckKEXDetails(client_groups, shares, false);
+}
+
+TEST_P(TlsKeyExchangeTest13, EqualPriorityTestRetryECServer13) {
+  EnsureKeyShareSetup();
+
+  // The client sends a 25519 key share while the server prefers P256.
+  // The server prefers P-384 over x25519, so it must not consider P-256 and
+  // x25519 to be equivalent. It will therefore request a P-256 share
+  // with a HelloRetryRequest.
+  const std::vector<SSLNamedGroup> client_groups = {
+      ssl_grp_ec_curve25519, ssl_grp_ec_secp256r1, ssl_grp_ec_secp384r1};
+  const std::vector<SSLNamedGroup> server_groups = {
+      ssl_grp_ec_secp256r1, ssl_grp_ec_secp384r1, ssl_grp_ec_curve25519};
+  client_->ConfigNamedGroups(client_groups);
+  server_->ConfigNamedGroups(server_groups);
+
+  Connect();
+
+  CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp256r1, ssl_auth_rsa_sign,
+            ssl_sig_rsa_pss_sha256);
+  const std::vector<SSLNamedGroup> shares = {ssl_grp_ec_curve25519};
+  CheckKEXDetails(client_groups, shares, true);
 }
 
+TEST_P(TlsKeyExchangeTest13, NotEqualPriorityWithIntermediateGroup13) {
+  EnsureKeyShareSetup();
+
+  // The client sends a 25519 key share while the server prefers P256.
+  // The server prefers ffdhe_2048 over x25519, so it must not consider the
+  // P-256 and x25519 to be equivalent. It will therefore request a P-256 share
+  // with a HelloRetryRequest.
+  const std::vector<SSLNamedGroup> client_groups = {
+      ssl_grp_ec_curve25519, ssl_grp_ec_secp256r1, ssl_grp_ffdhe_2048};
+  const std::vector<SSLNamedGroup> server_groups = {
+      ssl_grp_ec_secp256r1, ssl_grp_ffdhe_2048, ssl_grp_ec_curve25519};
+  client_->ConfigNamedGroups(client_groups);
+  server_->ConfigNamedGroups(server_groups);
+
+  Connect();
+
+  CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp256r1, ssl_auth_rsa_sign,
+            ssl_sig_rsa_pss_sha256);
+  const std::vector<SSLNamedGroup> shares = {ssl_grp_ec_curve25519};
+  CheckKEXDetails(client_groups, shares, true);
+}
+
+TEST_P(TlsKeyExchangeTest13,
+       NotEqualPriorityWithUnsupportedIntermediateGroup13) {
+  EnsureKeyShareSetup();
+
+  // As in the previous test, the server prefers ffdhe_2048. Thus, even though
+  // the client doesn't support this group, the server must not regard x25519 as
+  // equivalent to P-256.
+  const std::vector<SSLNamedGroup> client_groups = {ssl_grp_ec_curve25519,
+                                                    ssl_grp_ec_secp256r1};
+  const std::vector<SSLNamedGroup> server_groups = {
+      ssl_grp_ec_secp256r1, ssl_grp_ffdhe_2048, ssl_grp_ec_curve25519};
+  client_->ConfigNamedGroups(client_groups);
+  server_->ConfigNamedGroups(server_groups);
+
+  Connect();
+
+  CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp256r1, ssl_auth_rsa_sign,
+            ssl_sig_rsa_pss_sha256);
+  const std::vector<SSLNamedGroup> shares = {ssl_grp_ec_curve25519};
+  CheckKEXDetails(client_groups, shares, true);
+}
+
+TEST_P(TlsKeyExchangeTest13, EqualPriority13) {
+  EnsureKeyShareSetup();
+
+  // The client sends a 25519 key share while the server prefers P256.
+  // We have to accept 25519 without retry because it's considered equivalent to
+  // P256 by the server.
+  const std::vector<SSLNamedGroup> client_groups = {
+      ssl_grp_ec_curve25519, ssl_grp_ffdhe_2048, ssl_grp_ec_secp256r1};
+  const std::vector<SSLNamedGroup> server_groups = {ssl_grp_ec_secp256r1,
+                                                    ssl_grp_ec_curve25519};
+  client_->ConfigNamedGroups(client_groups);
+  server_->ConfigNamedGroups(server_groups);
+
+  Connect();
+
+  CheckKeys();
+  const std::vector<SSLNamedGroup> shares = {ssl_grp_ec_curve25519};
+  CheckKEXDetails(client_groups, shares, false);
+}
+#endif
+
 TEST_P(TlsConnectGeneric, P256ClientAndCurve25519Server) {
   EnsureTlsSetup();
   client_->DisableAllCiphers();
   client_->EnableCiphersByKeyExchange(ssl_kea_ecdh);
 
-  // the client sends a P256 key share while the server prefers 25519.
+  // The client sends a P256 key share while the server prefers 25519.
+  const std::vector<SSLNamedGroup> client_groups = {ssl_grp_ec_secp256r1};
   const std::vector<SSLNamedGroup> server_groups = {ssl_grp_ec_curve25519};
-  const std::vector<SSLNamedGroup> client_groups = {ssl_grp_ec_secp256r1};
 
   client_->ConfigNamedGroups(client_groups);
   server_->ConfigNamedGroups(server_groups);
 
   ConnectExpectFail();
   client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
   server_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
 }
 
+TEST_P(TlsKeyExchangeTest13, MultipleClientShares) {
+  EnsureKeyShareSetup();
+
+  // The client sends 25519 and P256 key shares. The server prefers P256,
+  // which must be chosen here.
+  const std::vector<SSLNamedGroup> client_groups = {ssl_grp_ec_curve25519,
+                                                    ssl_grp_ec_secp256r1};
+  const std::vector<SSLNamedGroup> server_groups = {ssl_grp_ec_secp256r1,
+                                                    ssl_grp_ec_curve25519};
+  client_->ConfigNamedGroups(client_groups);
+  server_->ConfigNamedGroups(server_groups);
+
+  // Generate a key share on the client for both curves.
+  EXPECT_EQ(SECSuccess, SSL_SendAdditionalKeyShares(client_->ssl_fd(), 1));
+
+  Connect();
+
+  // The server would accept 25519 but its preferred group (P256) has to win.
+  CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp256r1, ssl_auth_rsa_sign,
+            ssl_sig_rsa_pss_sha256);
+  const std::vector<SSLNamedGroup> shares = {ssl_grp_ec_curve25519,
+                                             ssl_grp_ec_secp256r1};
+  CheckKEXDetails(client_groups, shares, false);
+}
+
 // Replace the point in the client key exchange message with an empty one
 class ECCClientKEXFilter : public TlsHandshakeFilter {
  public:
   ECCClientKEXFilter() {}
 
  protected:
   virtual PacketFilter::Action FilterHandshake(const HandshakeHeader &header,
                                                const DataBuffer &input,
@@ -334,9 +504,15 @@ TEST_P(TlsConnectGenericPre13, ConnectEC
   ConnectExpectFail();
   server_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_CLIENT_KEY_EXCH);
 }
 
 INSTANTIATE_TEST_CASE_P(KeyExchangeTest, TlsKeyExchangeTest,
                         ::testing::Combine(TlsConnectTestBase::kTlsModesAll,
                                            TlsConnectTestBase::kTlsV11Plus));
 
+#ifndef NSS_DISABLE_TLS_1_3
+INSTANTIATE_TEST_CASE_P(KeyExchangeTest, TlsKeyExchangeTest13,
+                        ::testing::Combine(TlsConnectTestBase::kTlsModesAll,
+                                           TlsConnectTestBase::kTlsV13));
+#endif
+
 }  // namespace nss_test
new file mode 100644
--- /dev/null
+++ b/security/nss/external_tests/ssl_gtest/ssl_gtest.gyp
@@ -0,0 +1,100 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    '../common/gtest.gypi',
+  ],
+  'targets': [
+    {
+      'target_name': 'ssl_gtest',
+      'type': 'executable',
+      'sources': [
+        'libssl_internals.c',
+        'ssl_agent_unittest.cc',
+        'ssl_auth_unittest.cc',
+        'ssl_ciphersuite_unittest.cc',
+        'ssl_dhe_unittest.cc',
+        'ssl_drop_unittest.cc',
+        'ssl_ems_unittest.cc',
+        'ssl_extension_unittest.cc',
+        'ssl_gtest.cc',
+        'ssl_loopback_unittest.cc',
+        'ssl_resumption_unittest.cc',
+        'ssl_skip_unittest.cc',
+        'ssl_staticrsa_unittest.cc',
+        'ssl_v2_client_hello_unittest.cc',
+        'ssl_version_unittest.cc',
+        'test_io.cc',
+        'tls_agent.cc',
+        'tls_connect.cc',
+        'tls_filter.cc',
+        'tls_hkdf_unittest.cc',
+        'tls_parser.cc'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:nss_exports',
+        '<(DEPTH)/lib/util/util.gyp:nssutil3',
+        '<(DEPTH)/lib/sqlite/sqlite.gyp:sqlite3',
+        '<(DEPTH)/external_tests/google_test/google_test.gyp:gtest',
+        '<(DEPTH)/lib/softoken/softoken.gyp:softokn',
+        '<(DEPTH)/lib/smime/smime.gyp:smime',
+        '<(DEPTH)/lib/ssl/ssl.gyp:ssl',
+        '<(DEPTH)/lib/nss/nss.gyp:nss_static',
+        '<(DEPTH)/cmd/lib/lib.gyp:sectool',
+        '<(DEPTH)/lib/pkcs12/pkcs12.gyp:pkcs12',
+        '<(DEPTH)/lib/pkcs7/pkcs7.gyp:pkcs7',
+        '<(DEPTH)/lib/certhigh/certhigh.gyp:certhi',
+        '<(DEPTH)/lib/cryptohi/cryptohi.gyp:cryptohi',
+        '<(DEPTH)/lib/pk11wrap/pk11wrap.gyp:pk11wrap',
+        '<(DEPTH)/lib/softoken/softoken.gyp:softokn',
+        '<(DEPTH)/lib/certdb/certdb.gyp:certdb',
+        '<(DEPTH)/lib/pki/pki.gyp:nsspki',
+        '<(DEPTH)/lib/dev/dev.gyp:nssdev',
+        '<(DEPTH)/lib/base/base.gyp:nssb',
+        '<(DEPTH)/lib/freebl/freebl.gyp:freebl',
+        '<(DEPTH)/lib/nss/nss.gyp:nss_static',
+        '<(DEPTH)/lib/pk11wrap/pk11wrap.gyp:pk11wrap',
+        '<(DEPTH)/lib/certhigh/certhigh.gyp:certhi',
+        '<(DEPTH)/lib/zlib/zlib.gyp:nss_zlib'
+      ],
+      'conditions': [
+        [ 'disable_dbm==0', {
+          'dependencies': [
+            '<(DEPTH)/lib/dbm/src/src.gyp:dbm',
+          ],
+        }],
+        [ 'disable_libpkix==0', {
+          'dependencies': [
+            '<(DEPTH)/lib/libpkix/pkix/certsel/certsel.gyp:pkixcertsel',
+            '<(DEPTH)/lib/libpkix/pkix/checker/checker.gyp:pkixchecker',
+            '<(DEPTH)/lib/libpkix/pkix/crlsel/crlsel.gyp:pkixcrlsel',
+            '<(DEPTH)/lib/libpkix/pkix/params/params.gyp:pkixparams',
+            '<(DEPTH)/lib/libpkix/pkix/results/results.gyp:pkixresults',
+            '<(DEPTH)/lib/libpkix/pkix/store/store.gyp:pkixstore',
+            '<(DEPTH)/lib/libpkix/pkix/top/top.gyp:pkixtop',
+            '<(DEPTH)/lib/libpkix/pkix/util/util.gyp:pkixutil',
+            '<(DEPTH)/lib/libpkix/pkix_pl_nss/system/system.gyp:pkixsystem',
+            '<(DEPTH)/lib/libpkix/pkix_pl_nss/module/module.gyp:pkixmodule',
+            '<(DEPTH)/lib/libpkix/pkix_pl_nss/pki/pki.gyp:pkixpki',
+          ],
+        }],
+      ],
+    }
+  ],
+  'target_defaults': {
+    'include_dirs': [
+      '../../external_tests/google_test/gtest/include',
+      '../../external_tests/common',
+      '../../lib/ssl'
+    ],
+    'defines': [
+      'NSS_USE_STATIC_LIBS'
+    ]
+  },
+  'variables': {
+    'module': 'nss',
+    'use_static_libs': 1
+  }
+}
--- a/security/nss/external_tests/ssl_gtest/ssl_hrr_unittest.cc
+++ b/security/nss/external_tests/ssl_gtest/ssl_hrr_unittest.cc
@@ -110,47 +110,47 @@ TEST_F(TlsConnectDatagram13, DropClientS
                                                     ssl_grp_ec_secp521r1};
   server_->ConfigNamedGroups(groups);
   server_->SetPacketFilter(new SelectiveDropFilter(0x2));
   Connect();
 }
 
 class TlsKeyExchange13 : public TlsKeyExchangeTest {};
 
-// This should work, with an HRR, because the server prefers P-256 and the
+// This should work, with an HRR, because the server prefers x25519 and the
 // client generates a share for P-384 on the initial ClientHello.
 TEST_P(TlsKeyExchange13, ConnectEcdhePreferenceMismatchHrr) {
   EnsureKeyShareSetup();
   static const std::vector<SSLNamedGroup> client_groups = {
-      ssl_grp_ec_secp384r1, ssl_grp_ec_secp256r1};
+      ssl_grp_ec_secp384r1, ssl_grp_ec_curve25519};
   static const std::vector<SSLNamedGroup> server_groups = {
-      ssl_grp_ec_secp256r1, ssl_grp_ec_secp384r1};
+      ssl_grp_ec_curve25519, ssl_grp_ec_secp384r1};
   client_->ConfigNamedGroups(client_groups);
   server_->ConfigNamedGroups(server_groups);
   Connect();
-  CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign);
+  CheckKeys();
   static const std::vector<SSLNamedGroup> expectedShares = {
       ssl_grp_ec_secp384r1};
   CheckKEXDetails(client_groups, expectedShares, true /* expect_hrr */);
 }
 
-// This should work, but not use HRR because the key share for P-256 was
+// This should work, but not use HRR because the key share for x25519 was
 // pre-generated by the client.
 TEST_P(TlsKeyExchange13, ConnectEcdhePreferenceMismatchHrrExtraShares) {
   EnsureKeyShareSetup();
   static const std::vector<SSLNamedGroup> client_groups = {
-      ssl_grp_ec_secp384r1, ssl_grp_ec_secp256r1};
+      ssl_grp_ec_secp384r1, ssl_grp_ec_curve25519};
   static const std::vector<SSLNamedGroup> server_groups = {
-      ssl_grp_ec_secp256r1, ssl_grp_ec_secp384r1};
+      ssl_grp_ec_curve25519, ssl_grp_ec_secp384r1};
   client_->ConfigNamedGroups(client_groups);
   server_->ConfigNamedGroups(server_groups);
   EXPECT_EQ(SECSuccess, SSL_SendAdditionalKeyShares(client_->ssl_fd(), 1));
 
   Connect();
-  CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign);
+  CheckKeys();
   CheckKEXDetails(client_groups, client_groups, false /* expect_hrr */);
 }
 
 TEST_F(TlsConnectTest, Select12AfterHelloRetryRequest) {
   EnsureTlsSetup();
   client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
                            SSL_LIBRARY_VERSION_TLS_1_3);
   server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
--- a/security/nss/external_tests/ssl_gtest/ssl_loopback_unittest.cc
+++ b/security/nss/external_tests/ssl_gtest/ssl_loopback_unittest.cc
@@ -24,17 +24,17 @@ extern "C" {
 
 namespace nss_test {
 
 TEST_P(TlsConnectGeneric, SetupOnly) {}
 
 TEST_P(TlsConnectGeneric, Connect) {
   SetExpectedVersion(std::get<1>(GetParam()));
   Connect();
-  CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign);
+  CheckKeys();
 }
 
 TEST_P(TlsConnectGeneric, ConnectEcdsa) {
   SetExpectedVersion(std::get<1>(GetParam()));
   Reset(TlsAgent::kServerEcdsa256);
   Connect();
   CheckKeys(ssl_kea_ecdh, ssl_auth_ecdsa);
 }
--- a/security/nss/external_tests/ssl_gtest/ssl_resumption_unittest.cc
+++ b/security/nss/external_tests/ssl_gtest/ssl_resumption_unittest.cc
@@ -221,17 +221,17 @@ TEST_P(TlsConnectGeneric, ServerSNICertS
   Reset();
   EnsureTlsSetup();
   ConfigureSessionCache(RESUME_NONE, RESUME_NONE);
 
   server_->SetSniCallback(SwitchCertificates);
 
   Connect();
   ScopedCERTCertificate cert2(SSL_PeerCertificate(client_->ssl_fd()));
-  CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign);
+  CheckKeys();
   EXPECT_FALSE(SECITEM_ItemsAreEqual(&cert1->derCert, &cert2->derCert));
 }
 
 TEST_P(TlsConnectGeneric, ServerSNICertTypeSwitch) {
   Reset(TlsAgent::kServerEcdsa256);
   Connect();
   ScopedCERTCertificate cert1(SSL_PeerCertificate(client_->ssl_fd()));
 
@@ -250,28 +250,28 @@ TEST_P(TlsConnectGeneric, ServerSNICertT
 }
 
 // Prior to TLS 1.3, we were not fully ephemeral; though 1.3 fixes that
 TEST_P(TlsConnectGenericPre13, ConnectEcdheTwiceReuseKey) {
   TlsInspectorRecordHandshakeMessage* i1 =
       new TlsInspectorRecordHandshakeMessage(kTlsHandshakeServerKeyExchange);
   server_->SetPacketFilter(i1);
   Connect();
-  CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign);
+  CheckKeys();
   TlsServerKeyExchangeEcdhe dhe1;
   EXPECT_TRUE(dhe1.Parse(i1->buffer()));
 
   // Restart
   Reset();
   TlsInspectorRecordHandshakeMessage* i2 =
       new TlsInspectorRecordHandshakeMessage(kTlsHandshakeServerKeyExchange);
   server_->SetPacketFilter(i2);
   ConfigureSessionCache(RESUME_NONE, RESUME_NONE);
   Connect();
-  CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign);
+  CheckKeys();
 
   TlsServerKeyExchangeEcdhe dhe2;
   EXPECT_TRUE(dhe2.Parse(i2->buffer()));
 
   // Make sure they are the same.
   EXPECT_EQ(dhe1.public_key_.len(), dhe2.public_key_.len());
   EXPECT_TRUE(!memcmp(dhe1.public_key_.data(), dhe2.public_key_.data(),
                       dhe1.public_key_.len()));
@@ -282,116 +282,117 @@ TEST_P(TlsConnectGenericPre13, ConnectEc
   server_->EnsureTlsSetup();
   SECStatus rv =
       SSL_OptionSet(server_->ssl_fd(), SSL_REUSE_SERVER_ECDHE_KEY, PR_FALSE);
   EXPECT_EQ(SECSuccess, rv);
   TlsInspectorRecordHandshakeMessage* i1 =
       new TlsInspectorRecordHandshakeMessage(kTlsHandshakeServerKeyExchange);
   server_->SetPacketFilter(i1);
   Connect();
-  CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign);
+  CheckKeys();
   TlsServerKeyExchangeEcdhe dhe1;
   EXPECT_TRUE(dhe1.Parse(i1->buffer()));
 
   // Restart
   Reset();
   server_->EnsureTlsSetup();
   rv = SSL_OptionSet(server_->ssl_fd(), SSL_REUSE_SERVER_ECDHE_KEY, PR_FALSE);
   EXPECT_EQ(SECSuccess, rv);
   TlsInspectorRecordHandshakeMessage* i2 =
       new TlsInspectorRecordHandshakeMessage(kTlsHandshakeServerKeyExchange);
   server_->SetPacketFilter(i2);
   ConfigureSessionCache(RESUME_NONE, RESUME_NONE);
   Connect();
-  CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign);
+  CheckKeys();
 
   TlsServerKeyExchangeEcdhe dhe2;
   EXPECT_TRUE(dhe2.Parse(i2->buffer()));
 
   // Make sure they are different.
   EXPECT_FALSE((dhe1.public_key_.len() == dhe2.public_key_.len()) &&
                (!memcmp(dhe1.public_key_.data(), dhe2.public_key_.data(),
                         dhe1.public_key_.len())));
 }
 
 // Verify that TLS 1.3 reports an accurate group on resumption.
 TEST_P(TlsConnectTls13, TestTls13ResumeDifferentGroup) {
   ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
   Connect();
   SendReceive();  // Need to read so that we absorb the session ticket.
-  CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign);
+  CheckKeys();
 
   Reset();
   ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
   ExpectResumption(RESUME_TICKET);
   client_->ConfigNamedGroups(kFFDHEGroups);
   server_->ConfigNamedGroups(kFFDHEGroups);
   Connect();
-  CheckKeys(ssl_kea_dh, ssl_auth_rsa_sign);
+  CheckKeys(ssl_kea_dh, ssl_grp_ffdhe_2048, ssl_auth_rsa_sign, ssl_sig_none);
 }
 
 // Test that we don't resume when we can't negotiate the same cipher.
 TEST_P(TlsConnectTls13, TestTls13ResumeClientDifferentCipher) {
   ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
   client_->EnableSingleCipher(TLS_AES_128_GCM_SHA256);
   Connect();
   SendReceive();  // Need to read so that we absorb the session ticket.
-  CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign);
+  CheckKeys();
 
   Reset();
   ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
   ExpectResumption(RESUME_NONE);
   client_->EnableSingleCipher(TLS_AES_256_GCM_SHA384);
   Connect();
-  CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign);
+  CheckKeys();
 }
 
 // Test that we don't resume when we can't negotiate the same cipher.
 TEST_P(TlsConnectTls13, TestTls13ResumeServerDifferentCipher) {
   ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
   server_->EnableSingleCipher(TLS_AES_128_GCM_SHA256);
   Connect();
   SendReceive();  // Need to read so that we absorb the session ticket.
-  CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign);
+  CheckKeys();
 
   Reset();
   ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
   ExpectResumption(RESUME_NONE);
   server_->EnableSingleCipher(TLS_AES_256_GCM_SHA384);
   Connect();
-  CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign);
+  CheckKeys();
 }
 
 // Test that two TLS resumptions work and produce the same ticket.
 // This will change after bug 1257047 is fixed.
 TEST_F(TlsConnectTest, TestTls13ResumptionTwice) {
   ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
   client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1,
                            SSL_LIBRARY_VERSION_TLS_1_3);
   server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1,
                            SSL_LIBRARY_VERSION_TLS_1_3);
   Connect();
   SendReceive();  // Need to read so that we absorb the session ticket.
-  CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign);
+  CheckKeys();
   uint16_t original_suite;
   EXPECT_TRUE(client_->cipher_suite(&original_suite));
 
   Reset();
   ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
   TlsExtensionCapture* c1 =
       new TlsExtensionCapture(ssl_tls13_pre_shared_key_xtn);
   client_->SetPacketFilter(c1);
   client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1,
                            SSL_LIBRARY_VERSION_TLS_1_3);
   server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1,
                            SSL_LIBRARY_VERSION_TLS_1_3);
   ExpectResumption(RESUME_TICKET);
   Connect();
   SendReceive();
-  CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign);
+  CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_rsa_sign,
+            ssl_sig_none);
   // The filter will go away when we reset, so save the captured extension.
   DataBuffer initialTicket(c1->extension());
   ASSERT_LT(0U, initialTicket.len());
 
   ScopedCERTCertificate cert1(SSL_PeerCertificate(client_->ssl_fd()));
   ASSERT_TRUE(!!cert1.get());
 
   Reset();
@@ -402,17 +403,18 @@ TEST_F(TlsConnectTest, TestTls13Resumpti
   client_->SetPacketFilter(c2);
   client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1,
                            SSL_LIBRARY_VERSION_TLS_1_3);
   server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1,
                            SSL_LIBRARY_VERSION_TLS_1_3);
   ExpectResumption(RESUME_TICKET);
   Connect();
   SendReceive();
-  CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign);
+  CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_rsa_sign,
+            ssl_sig_none);
   ASSERT_LT(0U, c2->extension().len());
 
   ScopedCERTCertificate cert2(SSL_PeerCertificate(client_->ssl_fd()));
   ASSERT_TRUE(!!cert2.get());
 
   // Check that the cipher suite is reported the same on both sides, though in
   // TLS 1.3 resumption actually negotiates a different cipher suite.
   uint16_t resumed_suite;
--- a/security/nss/external_tests/ssl_gtest/ssl_staticrsa_unittest.cc
+++ b/security/nss/external_tests/ssl_gtest/ssl_staticrsa_unittest.cc
@@ -36,17 +36,17 @@ const uint8_t kBogusClientKeyExchange[] 
     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
 };
 
 TEST_P(TlsConnectGenericPre13, ConnectStaticRSA) {
   EnableOnlyStaticRsaCiphers();
   Connect();
-  CheckKeys(ssl_kea_rsa, ssl_auth_rsa_decrypt);
+  CheckKeys(ssl_kea_rsa, ssl_grp_none, ssl_auth_rsa_decrypt, ssl_sig_none);
 }
 
 // Test that a totally bogus EPMS is handled correctly.
 // This test is stream so we can catch the bad_record_mac alert.
 TEST_P(TlsConnectStreamPre13, ConnectStaticRSABogusCKE) {
   EnableOnlyStaticRsaCiphers();
   TlsInspectorReplaceHandshakeMessage* i1 =
       new TlsInspectorReplaceHandshakeMessage(
--- a/security/nss/external_tests/ssl_gtest/tls_agent.cc
+++ b/security/nss/external_tests/ssl_gtest/tls_agent.cc
@@ -229,30 +229,31 @@ void TlsAgent::DisableAllCiphers() {
         SSL_CipherPrefSet(ssl_fd_, SSL_ImplementedCiphers[i], PR_FALSE);
     EXPECT_EQ(SECSuccess, rv);
   }
 }
 
 // Not actually all groups, just the onece that we are actually willing
 // to use.
 const std::vector<SSLNamedGroup> kAllDHEGroups = {
-    ssl_grp_ec_secp256r1, ssl_grp_ec_secp384r1, ssl_grp_ec_secp521r1,
-    ssl_grp_ffdhe_2048,   ssl_grp_ffdhe_3072,   ssl_grp_ffdhe_4096,
-    ssl_grp_ffdhe_6144,   ssl_grp_ffdhe_8192};
+    ssl_grp_ec_curve25519, ssl_grp_ec_secp256r1, ssl_grp_ec_secp384r1,
+    ssl_grp_ec_secp521r1,  ssl_grp_ffdhe_2048,   ssl_grp_ffdhe_3072,
+    ssl_grp_ffdhe_4096,    ssl_grp_ffdhe_6144,   ssl_grp_ffdhe_8192};
 
 const std::vector<SSLNamedGroup> kECDHEGroups = {
-    ssl_grp_ec_secp256r1, ssl_grp_ec_secp384r1, ssl_grp_ec_secp521r1};
+    ssl_grp_ec_curve25519, ssl_grp_ec_secp256r1, ssl_grp_ec_secp384r1,
+    ssl_grp_ec_secp521r1};
 
 const std::vector<SSLNamedGroup> kFFDHEGroups = {
     ssl_grp_ffdhe_2048, ssl_grp_ffdhe_3072, ssl_grp_ffdhe_4096,
     ssl_grp_ffdhe_6144, ssl_grp_ffdhe_8192};
 
 // Defined because the big DHE groups are ridiculously slow.
 const std::vector<SSLNamedGroup> kFasterDHEGroups = {
-    ssl_grp_ec_secp256r1, ssl_grp_ec_secp384r1, ssl_grp_ec_secp521r1,
+    ssl_grp_ec_curve25519, ssl_grp_ec_secp256r1, ssl_grp_ec_secp384r1,
     ssl_grp_ffdhe_2048, ssl_grp_ffdhe_3072};
 
 void TlsAgent::EnableCiphersByKeyExchange(SSLKEAType kea) {
   EXPECT_TRUE(EnsureTlsSetup());
 
   for (size_t i = 0; i < SSL_NumImplementedCiphers; ++i) {
     SSLCipherSuiteInfo csinfo;
 
@@ -398,68 +399,87 @@ void TlsAgent::SetSignatureAlgorithms(co
         algorithms[j].hashAlg == configuredAlgorithms[i].hashAlg &&
         algorithms[j].sigAlg == configuredAlgorithms[i].sigAlg) {
       ++i;
     }
   }
   EXPECT_EQ(i, configuredCount) << "algorithms in use were all set";
 }
 
-void TlsAgent::CheckKEA(SSLKEAType type, size_t kea_size) const {
+void TlsAgent::CheckKEA(SSLKEAType kea_type, SSLNamedGroup kea_group,
+                        size_t kea_size) const {
   EXPECT_EQ(STATE_CONNECTED, state_);
-  EXPECT_EQ(type, info_.keaType);
+  EXPECT_EQ(kea_type, info_.keaType);
+  EXPECT_EQ(kea_group, info_.keaGroup);
+  if (kea_size == 0) {
+    switch (kea_group) {
+      case ssl_grp_ec_curve25519:
+        kea_size = 255;
+        break;
+      case ssl_grp_ec_secp256r1:
+        kea_size = 256;
+        break;
+      case ssl_grp_ec_secp384r1:
+        kea_size = 384;
+        break;
+      case ssl_grp_ffdhe_2048:
+        kea_size = 2048;
+        break;
+      default:
+        if (kea_type == ssl_kea_rsa) {
+          kea_size = server_key_bits_;
+        } else {
+          EXPECT_TRUE(false) << "need to update group sizes";
+        }
+    }
+  }
   EXPECT_EQ(kea_size, info_.keaKeyBits);
 }
 
-void TlsAgent::CheckKEA(SSLKEAType type) const {
-  PRUint32 ecKEAKeyBits = SSLInt_DetermineKEABits(
-      server_key_bits_, info_.authType, csinfo_.symKeyBits);
-  switch (type) {
-    case ssl_kea_ecdh:
-      CheckKEA(type, ecKEAKeyBits);
-      break;
-    case ssl_kea_dh:
-      CheckKEA(type, 2048);
-      break;
-    case ssl_kea_rsa:
-      CheckKEA(type, server_key_bits_);
-      break;
-    default:
-      EXPECT_TRUE(false) << "Unknown KEA type";
-      break;
+void TlsAgent::CheckAuthType(SSLAuthType auth_type,
+                             SSLSignatureScheme sig_scheme) const {
+  EXPECT_EQ(STATE_CONNECTED, state_);
+  EXPECT_EQ(auth_type, info_.authType);
+  EXPECT_EQ(server_key_bits_, info_.authKeyBits);
+  if (expected_version_ < SSL_LIBRARY_VERSION_TLS_1_2) {
+    switch (auth_type) {
+      case ssl_auth_rsa_sign:
+        sig_scheme = ssl_sig_rsa_pkcs1_sha1md5;
+        break;
+      case ssl_auth_ecdsa:
+        sig_scheme = ssl_sig_ecdsa_sha1;
+        break;
+      default:
+        break;
+    }
   }
-}
-
-void TlsAgent::CheckAuthType(SSLAuthType type) const {
-  EXPECT_EQ(STATE_CONNECTED, state_);
-  EXPECT_EQ(type, info_.authType);
-  EXPECT_EQ(server_key_bits_, info_.authKeyBits);
+  EXPECT_EQ(sig_scheme, info_.signatureScheme);
 
   if (info_.protocolVersion >= SSL_LIBRARY_VERSION_TLS_1_3) {
     return;
   }
 
   // Check authAlgorithm, which is the old value for authType.  This is a second
   // switch
   // statement because default label is different.
-  switch (type) {
+  switch (auth_type) {
     case ssl_auth_rsa_sign:
       EXPECT_EQ(ssl_auth_rsa_decrypt, csinfo_.authAlgorithm)
           << "authAlgorithm for RSA is always decrypt";
       break;
     case ssl_auth_ecdh_rsa:
       EXPECT_EQ(ssl_auth_rsa_decrypt, csinfo_.authAlgorithm)
           << "authAlgorithm for ECDH_RSA is RSA decrypt (i.e., wrong)";
       break;
     case ssl_auth_ecdh_ecdsa:
       EXPECT_EQ(ssl_auth_ecdsa, csinfo_.authAlgorithm)
           << "authAlgorithm for ECDH_ECDSA is ECDSA (i.e., wrong)";
       break;
     default:
-      EXPECT_EQ(type, csinfo_.authAlgorithm)
+      EXPECT_EQ(auth_type, csinfo_.authAlgorithm)
           << "authAlgorithm is (usually) the same as authType";
       break;
   }
 }
 
 void TlsAgent::EnableFalseStart() {
   EXPECT_TRUE(EnsureTlsSetup());
 
@@ -819,16 +839,19 @@ void TlsAgentTestBase::Init(const std::s
   agent_->adapter()->SetPeer(DummyPrSocket::GetAdapter(fd_));
   agent_->StartConnect();
 }
 
 void TlsAgentTestBase::EnsureInit() {
   if (!agent_) {
     Init();
   }
+  const std::vector<SSLNamedGroup> groups = {
+      ssl_grp_ec_secp256r1, ssl_grp_ec_secp384r1, ssl_grp_ffdhe_2048};
+  agent_->ConfigNamedGroups(groups);
 }
 
 void TlsAgentTestBase::ProcessMessage(const DataBuffer& buffer,
                                       TlsAgent::State expected_state,
                                       int32_t error_code) {
   std::cerr << "Process message: " << buffer << std::endl;
   EnsureInit();
   agent_->adapter()->PacketReceived(buffer);
--- a/security/nss/external_tests/ssl_gtest/tls_agent.h
+++ b/security/nss/external_tests/ssl_gtest/tls_agent.h
@@ -83,19 +83,20 @@ class TlsAgent : public PollTarget {
 
   void SetPeer(TlsAgent* peer) { adapter_->SetPeer(peer->adapter_); }
 
   void SetPacketFilter(PacketFilter* filter) {
     adapter_->SetPacketFilter(filter);
   }
 
   void StartConnect(PRFileDesc* model = nullptr);
-  void CheckKEA(SSLKEAType type) const;
-  void CheckKEA(SSLKEAType type, size_t kea_size) const;
-  void CheckAuthType(SSLAuthType type) const;
+  void CheckKEA(SSLKEAType kea_type, SSLNamedGroup group,
+                size_t kea_size = 0) const;
+  void CheckAuthType(SSLAuthType auth_type,
+                     SSLSignatureScheme sig_scheme) const;
 
   void DisableAllCiphers();
   void EnableCiphersByAuthType(SSLAuthType authType);
   void EnableCiphersByKeyExchange(SSLKEAType kea);
   void EnableGroupsByKeyExchange(SSLKEAType kea);
   void EnableGroupsByAuthType(SSLAuthType authType);
   void EnableSingleCipher(uint16_t cipher);
 
--- a/security/nss/external_tests/ssl_gtest/tls_connect.cc
+++ b/security/nss/external_tests/ssl_gtest/tls_connect.cc
@@ -303,27 +303,68 @@ void TlsConnectTestBase::CheckConnected(
 
   CheckExtendedMasterSecret();
   CheckEarlyDataAccepted();
   CheckResumption(expected_resumption_mode_);
   client_->CheckSecretsDestroyed();
   server_->CheckSecretsDestroyed();
 }
 
-void TlsConnectTestBase::CheckKeys(SSLKEAType kea_type, SSLAuthType auth_type,
-                                   size_t kea_size) const {
-  if (kea_size) {
-    client_->CheckKEA(kea_type, kea_size);
-    server_->CheckKEA(kea_type, kea_size);
-  } else {
-    client_->CheckKEA(kea_type);
-    server_->CheckKEA(kea_type);
+void TlsConnectTestBase::CheckKeys(SSLKEAType kea_type, SSLNamedGroup kea_group,
+                                   SSLAuthType auth_type,
+                                   SSLSignatureScheme sig_scheme) const {
+  client_->CheckKEA(kea_type, kea_group);
+  server_->CheckKEA(kea_type, kea_group);
+  client_->CheckAuthType(auth_type, sig_scheme);
+  server_->CheckAuthType(auth_type, sig_scheme);
+}
+
+void TlsConnectTestBase::CheckKeys(SSLKEAType kea_type,
+                                   SSLAuthType auth_type) const {
+  SSLNamedGroup group;
+  switch (kea_type) {
+    case ssl_kea_ecdh:
+      group = ssl_grp_ec_curve25519;
+      break;
+    case ssl_kea_dh:
+      group = ssl_grp_ffdhe_2048;
+      break;
+    case ssl_kea_rsa:
+      group = ssl_grp_none;
+      break;
+    default:
+      EXPECT_TRUE(false) << "unexpected KEA";
+      group = ssl_grp_none;
+      break;
   }
-  client_->CheckAuthType(auth_type);
-  server_->CheckAuthType(auth_type);
+
+  SSLSignatureScheme scheme;
+  switch (auth_type) {
+    case ssl_auth_rsa_decrypt:
+      scheme = ssl_sig_none;
+      break;
+    case ssl_auth_rsa_sign:
+      scheme = ssl_sig_rsa_pss_sha256;
+      break;
+    case ssl_auth_ecdsa:
+      scheme = ssl_sig_ecdsa_secp256r1_sha256;
+      break;
+    case ssl_auth_dsa:
+      scheme = ssl_sig_dsa_sha1;
+      break;
+    default:
+      EXPECT_TRUE(false) << "unexpected auth type";
+      scheme = static_cast<SSLSignatureScheme>(0x0100);
+      break;
+  }
+  CheckKeys(kea_type, group, auth_type, scheme);
+}
+
+void TlsConnectTestBase::CheckKeys() const {
+  CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign);
 }
 
 void TlsConnectTestBase::ConnectExpectFail() {
   server_->StartConnect();
   client_->StartConnect();
   Handshake();
   ASSERT_EQ(TlsAgent::STATE_ERROR, client_->state());
   ASSERT_EQ(TlsAgent::STATE_ERROR, server_->state());
@@ -458,34 +499,34 @@ void TlsConnectTestBase::SetupForZeroRtt
   ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
   client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1,
                            SSL_LIBRARY_VERSION_TLS_1_3);
   server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1,
                            SSL_LIBRARY_VERSION_TLS_1_3);
   server_->Set0RttEnabled(true);  // So we signal that we allow 0-RTT.
   Connect();
   SendReceive();  // Need to read so that we absorb the session ticket.
-  CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign);
+  CheckKeys();
 
   Reset();
   client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1,
                            SSL_LIBRARY_VERSION_TLS_1_3);
   server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1,
                            SSL_LIBRARY_VERSION_TLS_1_3);
   server_->StartConnect();
   client_->StartConnect();
 }
 
 // Do a first connection so we can do resumption
 void TlsConnectTestBase::SetupForResume() {
   EnsureTlsSetup();
   ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
   Connect();
   SendReceive();  // Need to read so that we absorb the session ticket.
-  CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign);
+  CheckKeys();
 
   Reset();
 }
 
 void TlsConnectTestBase::ZeroRttSendReceive(
     bool expect_writable, bool expect_readable,
     std::function<bool()> post_clienthello_check) {
   const char* k0RttData = "ABCDEF";
--- a/security/nss/external_tests/ssl_gtest/tls_connect.h
+++ b/security/nss/external_tests/ssl_gtest/tls_connect.h
@@ -67,18 +67,23 @@ class TlsConnectTestBase : public ::test
   void Handshake();
   // Connect and check that it works.
   void Connect();
   // Check that the connection was successfully established.
   void CheckConnected();
   // Connect and expect it to fail.
   void ConnectExpectFail();
   void ConnectWithCipherSuite(uint16_t cipher_suite);
-  void CheckKeys(SSLKEAType kea_type, SSLAuthType auth_type,
-                 size_t kea_size = 0) const;
+  // Check that the keys used in the handshake match expectations.
+  void CheckKeys(SSLKEAType kea_type, SSLNamedGroup kea_group,
+                 SSLAuthType auth_type, SSLSignatureScheme sig_scheme) const;
+  // This version guesses some of the values.
+  void CheckKeys(SSLKEAType kea_type, SSLAuthType auth_type) const;
+  // This version assumes defaults.
+  void CheckKeys() const;
   void CheckGroups(const DataBuffer& groups,
                    std::function<void(SSLNamedGroup)> check_group);
   void CheckShares(const DataBuffer& shares,
                    std::function<void(SSLNamedGroup)> check_group);
 
   void SetExpectedVersion(uint16_t version);
   // Expect resumption of a particular type.
   void ExpectResumption(SessionResumptionMode expected);
@@ -245,11 +250,14 @@ class TlsKeyExchangeTest : public TlsCon
   void ConfigNamedGroups(const std::vector<SSLNamedGroup>& groups);
   std::vector<SSLNamedGroup> GetGroupDetails(const DataBuffer& ext);
   std::vector<SSLNamedGroup> GetShareDetails(const DataBuffer& ext);
   void CheckKEXDetails(const std::vector<SSLNamedGroup>& expectedGroups,
                        const std::vector<SSLNamedGroup>& expectedShares,
                        bool expect_hrr = false);
 };
 
+class TlsKeyExchangeTest13 : public TlsKeyExchangeTest {};
+class TlsKeyExchangeTestPre13 : public TlsKeyExchangeTest {};
+
 }  // namespace nss_test
 
 #endif
new file mode 100644
--- /dev/null
+++ b/security/nss/external_tests/util_gtest/util_gtest.gyp
@@ -0,0 +1,39 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi',
+    '../common/gtest.gypi',
+  ],
+  'targets': [
+    {
+      'target_name': 'util_gtest',
+      'type': 'executable',
+      'sources': [
+        'util_utf8_unittest.cc',
+        '<(DEPTH)/external_tests/common/gtests.cc'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:nss_exports',
+        '<(DEPTH)/lib/nss/nss.gyp:nss3',
+        '<(DEPTH)/lib/util/util.gyp:nssutil3',
+        '<(DEPTH)/lib/smime/smime.gyp:smime3',
+        '<(DEPTH)/lib/ssl/ssl.gyp:ssl3',
+        '<(DEPTH)/external_tests/google_test/google_test.gyp:gtest',
+        '<(DEPTH)/lib/util/util.gyp:nssutil',
+        '<(DEPTH)/cmd/lib/lib.gyp:sectool'
+      ]
+    }
+  ],
+  'target_defaults': {
+    'include_dirs': [
+      '../../external_tests/google_test/gtest/include',
+      '../../external_tests/common',
+      '../../lib/util'
+    ]
+  },
+  'variables': {
+    'module': 'nss'
+  }
+}
new file mode 100644
--- /dev/null
+++ b/security/nss/fuzz/.clang-format
@@ -0,0 +1,4 @@
+---
+Language: Cpp
+BasedOnStyle: Google
+...
new file mode 100644
--- /dev/null
+++ b/security/nss/fuzz/Makefile
@@ -0,0 +1,42 @@
+#! gmake
+#
+# 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/.
+
+#######################################################################
+# (1) Include initial platform-independent assignments (MANDATORY).   #
+#######################################################################
+
+include manifest.mn
+
+#######################################################################
+# (2) Include "global" configuration information. (OPTIONAL)          #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/config.mk
+
+#######################################################################
+# (3) Include "component" configuration information. (OPTIONAL)       #
+#######################################################################
+
+
+#######################################################################
+# (4) Include "local" platform-dependent assignments (OPTIONAL).      #
+#######################################################################
+
+
+#######################################################################
+# (5) Execute "global" rules. (OPTIONAL)                              #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/rules.mk
+
+#######################################################################
+# (6) Execute "component" rules. (OPTIONAL)                           #
+#######################################################################
+
+
+#######################################################################
+# (7) Execute "local" rules. (OPTIONAL).                              #
+#######################################################################
new file mode 100755
--- /dev/null
+++ b/security/nss/fuzz/clone_corpus.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+cd $(dirname $0)
+git clone https://github.com/mozilla/nss-fuzzing-corpus corpus
new file mode 100755
--- /dev/null
+++ b/security/nss/fuzz/clone_libfuzzer.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+cd $(dirname $0)
+mkdir tmp/
+git clone -q https://chromium.googlesource.com/chromium/llvm-project/llvm/lib/Fuzzer tmp/
+mv tmp/.git libFuzzer
+rm -fr tmp
+cd libFuzzer
+git reset --hard 4333f2ca71eb7951fcafcdcb111012fbe25c5e7e
new file mode 100644
--- /dev/null
+++ b/security/nss/fuzz/common.mk
@@ -0,0 +1,10 @@
+#! gmake
+#
+# 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/.
+
+MKPROG = $(CCC)
+MKSHLIB = $(CCC) $(DSO_LDOPTS) $(DARWIN_SDK_SHLIBFLAGS)
+
+CXXFLAGS += -std=c++11
new file mode 100644
--- /dev/null
+++ b/security/nss/fuzz/libFuzzer/Makefile
@@ -0,0 +1,45 @@
+#! gmake
+#
+# 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/.
+
+#######################################################################
+# (1) Include initial platform-independent assignments (MANDATORY).   #
+#######################################################################
+
+include manifest.mn
+
+#######################################################################
+# (2) Include "global" configuration information. (OPTIONAL)          #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/config.mk
+
+#######################################################################
+# (3) Include "component" configuration information. (OPTIONAL)       #
+#######################################################################
+
+include config.mk
+
+include ../common.mk
+
+#######################################################################
+# (4) Include "local" platform-dependent assignments (OPTIONAL).      #
+#######################################################################
+
+
+#######################################################################
+# (5) Execute "global" rules. (OPTIONAL)                              #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/rules.mk
+
+#######################################################################
+# (6) Execute "component" rules. (OPTIONAL)                           #
+#######################################################################
+
+
+#######################################################################
+# (7) Execute "local" rules. (OPTIONAL).                              #
+#######################################################################
new file mode 100644
--- /dev/null
+++ b/security/nss/fuzz/libFuzzer/config.mk
@@ -0,0 +1,14 @@
+#
+# 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/.
+
+# According to the LLVM docs, LibFuzzer isn't supposed to be built with any
+# sanitizer flags and in fact, building it with ASan coverage currently causes
+# Clang 3.9+ to crash, so we filter out all sanitizer-related flags here.
+CXXFLAGS := $(filter-out -fsanitize%,$(CXXFLAGS))
+CFLAGS := $(filter-out -fsanitize%,$(CFLAGS))
+LDFLAGS := $(filter-out -fsanitize%,$(LDFLAGS))
+DARWIN_SDK_SHLIBFLAGS := $(filter-out -fsanitize%,$(DARWIN_SDK_SHLIBFLAGS))
+
+CXXFLAGS += -g -O2
new file mode 100644
--- /dev/null
+++ b/security/nss/fuzz/libFuzzer/manifest.mn
@@ -0,0 +1,26 @@
+#
+# 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/.
+CORE_DEPTH = ../..
+DEPTH      = ../..
+MODULE = nss
+
+CPPSRCS = \
+      FuzzerCrossOver.cpp \
+      FuzzerDriver.cpp \
+      FuzzerExtFunctionsDlsym.cpp \
+      FuzzerExtFunctionsWeak.cpp \
+      FuzzerIO.cpp \
+      FuzzerLoop.cpp \
+      FuzzerMutate.cpp \
+      FuzzerSHA1.cpp \
+      FuzzerTracePC.cpp \
+      FuzzerTraceState.cpp \
+      FuzzerUtil.cpp \
+      FuzzerUtilDarwin.cpp \
+      FuzzerUtilLinux.cpp \
+      $(NULL)
+
+LIBRARY_NAME = Fuzzer
+LIBRARY_VERSION = 1
new file mode 100644
--- /dev/null
+++ b/security/nss/fuzz/manifest.mn
@@ -0,0 +1,8 @@
+# 
+# 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/.
+CORE_DEPTH = ..
+DEPTH      = ..
+
+DIRS = libFuzzer nssfuzz
new file mode 100644
--- /dev/null
+++ b/security/nss/fuzz/nssfuzz/Makefile
@@ -0,0 +1,45 @@
+#! gmake
+#
+# 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/.
+
+#######################################################################
+# (1) Include initial platform-independent assignments (MANDATORY).   #
+#######################################################################
+
+include manifest.mn
+
+#######################################################################
+# (2) Include "global" configuration information. (OPTIONAL)          #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/config.mk
+
+#######################################################################
+# (3) Include "component" configuration information. (OPTIONAL)       #
+#######################################################################
+
+include $(CORE_DEPTH)/cmd/platlibs.mk
+
+include ../common.mk
+
+#######################################################################
+# (4) Include "local" platform-dependent assignments (OPTIONAL).      #
+#######################################################################
+
+
+#######################################################################
+# (5) Execute "global" rules. (OPTIONAL)                              #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/rules.mk
+
+#######################################################################
+# (6) Execute "component" rules. (OPTIONAL)                           #
+#######################################################################
+
+
+#######################################################################
+# (7) Execute "local" rules. (OPTIONAL).                              #
+#######################################################################
new file mode 100644
--- /dev/null
+++ b/security/nss/fuzz/nssfuzz/cert_target.cc
@@ -0,0 +1,35 @@
+/* -*- 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 <assert.h>
+#include <stdint.h>
+#include <memory>
+
+#include "cert.h"
+
+#include "registry.h"
+#include "shared.h"
+
+extern "C" int cert_fuzzing_target(const uint8_t *Data, size_t Size) {
+  SECItem data = {siBuffer, (unsigned char *)Data, (unsigned int)Size};
+
+  static std::unique_ptr<NSSDatabase> db(new NSSDatabase());
+  assert(db != nullptr);
+
+  static CERTCertDBHandle *certDB = CERT_GetDefaultCertDB();
+  assert(certDB != NULL);
+
+  CERTCertificate *cert =
+      CERT_NewTempCertificate(certDB, &data, nullptr, false, true);
+
+  if (cert) {
+    CERT_DestroyCertificate(cert);
+  }
+
+  return 0;
+}
+
+REGISTER_FUZZING_TARGET("cert", cert_fuzzing_target, 3072, "Certificate Import")
new file mode 100644
--- /dev/null
+++ b/security/nss/fuzz/nssfuzz/manifest.mn
@@ -0,0 +1,24 @@
+#
+# 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/.
+CORE_DEPTH = ../..
+DEPTH      = ../..
+MODULE = nss
+
+CPPSRCS = \
+      cert_target.cc \
+      pkcs8_target.cc \
+      spki_target.cc \
+      nssfuzz.cc \
+      $(NULL)
+
+INCLUDES += -I$(CORE_DEPTH)/fuzz/libFuzzer
+
+REQUIRES = nspr nss
+
+PROGRAM = nssfuzz
+
+EXTRA_LIBS = $(DIST)/lib/$(LIB_PREFIX)Fuzzer.$(LIB_SUFFIX)
+
+USE_STATIC_LIBS = 1
new file mode 100644
--- /dev/null
+++ b/security/nss/fuzz/nssfuzz/nssfuzz.cc
@@ -0,0 +1,114 @@
+/* -*- 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 <iomanip>
+#include <iostream>
+#include <memory>
+
+#include "keyhi.h"
+#include "pk11pub.h"
+
+#include "FuzzerInternal.h"
+#include "registry.h"
+#include "shared.h"
+
+using namespace std;
+
+void printUsage(const vector<string> &args) {
+  size_t sep = args.at(0).rfind("/") + 1;
+  string progName = args.at(0).substr(sep);
+
+  cerr << progName << " - Various libFuzzer targets for NSS" << endl << endl;
+  cerr << "Usage: " << progName << " <target> <libFuzzer options>" << endl
+       << endl;
+  cerr << "Valid targets:" << endl;
+
+  vector<string> names = Registry::Names();
+
+  // Find length of the longest name.
+  size_t name_w =
+      max_element(names.begin(), names.end(), [](string &a, string &b) {
+        return a.size() < b.size();
+      })->size();
+
+  // Find length of the longest description.
+  auto max = max_element(names.begin(), names.end(), [](string &a, string &b) {
+    return Registry::Desc(a).size() < Registry::Desc(b).size();
+  });
+  size_t desc_w = Registry::Desc(*max).size();
+
+  // Print list of targets.
+  for (string name : names) {
+    cerr << "  " << left << setw(name_w) << name << " - " << setw(desc_w)
+         << Registry::Desc(name)
+         << " [default max_len=" << Registry::MaxLen(name) << "]" << endl;
+  }
+
+  // Some usage examples.
+  cerr << endl << "Run fuzzer with a given corpus directory:" << endl;
+  cerr << "  " << progName << " <target> /path/to/corpus" << endl;
+
+  cerr << endl << "Run fuzzer with a single test input:" << endl;
+  cerr << "  " << progName
+       << " <target> ./crash-14d4355b971092e39572bc306a135ddf9f923e19" << endl;
+
+  cerr << endl
+       << "Specify the number of cores you wish to dedicate to fuzzing:"
+       << endl;
+  cerr << "  " << progName << " <target> -jobs=8 -workers=8 /path/to/corpus"
+       << endl;
+
+  cerr << endl << "Override the maximum length of a test input:" << endl;
+  cerr << "  " << progName << " <target> -max_len=2048 /path/to/corpus" << endl;
+
+  cerr << endl
+       << "Minimize a given corpus and put the result into 'new_corpus':"
+       << endl;
+  cerr << "  " << progName
+       << " <target> -merge=1 -max_len=50000 ./new_corpus /path/to/corpus"
+       << endl;
+
+  cerr << endl << "Merge new test inputs into a corpus:" << endl;
+  cerr
+      << "  " << progName
+      << " <target> -merge=1 -max_len=50000 /path/to/corpus ./inputs1 ./inputs2"
+      << endl;
+
+  cerr << endl << "Print libFuzzer usage information:" << endl;
+  cerr << "  " << progName << " <target> -help=1" << endl << endl;
+
+  cerr << "Check out the docs at http://llvm.org/docs/LibFuzzer.html" << endl;
+}
+
+int main(int argc, char **argv) {
+  vector<string> args(argv, argv + argc);
+
+  if (args.size() < 2 || !Registry::Has(args[1])) {
+    printUsage(args);
+    return 1;
+  }
+
+  string targetName = args.at(1);
+  uint16_t maxLen = Registry::MaxLen(targetName);
+  string maxLenArg = "-max_len=" + to_string(maxLen);
+
+  auto find = [](string &a) {
+    return a.find("-max_len=") == 0 || a.find("-merge=1") == 0;
+  };
+
+  if (any_of(args.begin(), args.end(), find)) {
+    // Remove the 2nd argument.
+    argv[1] = argv[0];
+    argv++;
+    argc--;
+  } else {
+    // Set default max_len arg, if none given and we're not merging.
+    argv[1] = const_cast<char *>(maxLenArg.c_str());
+  }
+
+  // Hand control to the libFuzzer driver.
+  return fuzzer::FuzzerDriver(&argc, &argv, Registry::Func(targetName));
+}
new file mode 100644
--- /dev/null
+++ b/security/nss/fuzz/nssfuzz/pkcs8_target.cc
@@ -0,0 +1,37 @@
+/* -*- 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 <assert.h>
+#include <stdint.h>
+#include <memory>
+
+#include "keyhi.h"
+#include "pk11pub.h"
+
+#include "registry.h"
+#include "shared.h"
+
+extern "C" int pkcs8_fuzzing_target(const uint8_t *Data, size_t Size) {
+  SECItem data = {siBuffer, (unsigned char *)Data, (unsigned int)Size};
+
+  static std::unique_ptr<NSSDatabase> db(new NSSDatabase());
+  assert(db != nullptr);
+
+  PK11SlotInfo *slot = PK11_GetInternalSlot();
+  assert(slot != nullptr);
+
+  SECKEYPrivateKey *key = nullptr;
+  if (PK11_ImportDERPrivateKeyInfoAndReturnKey(slot, &data, nullptr, nullptr,
+                                               false, false, KU_ALL, &key,
+                                               nullptr) == SECSuccess) {
+    SECKEY_DestroyPrivateKey(key);
+  }
+
+  PK11_FreeSlot(slot);
+  return 0;
+}
+
+REGISTER_FUZZING_TARGET("pkcs8", pkcs8_fuzzing_target, 2048, "PKCS#8 Import")
new file mode 100644
--- /dev/null
+++ b/security/nss/fuzz/nssfuzz/registry.h
@@ -0,0 +1,71 @@
+/* -*- 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/. */
+
+#ifndef registry_h__
+#define registry_h__
+
+#include <map>
+#include "nss.h"
+#include "FuzzerInternal.h"
+
+class Registry {
+ public:
+  static void Add(std::string name, fuzzer::UserCallback func,
+                  uint16_t max_len, std::string desc) {
+    assert(!Has(name));
+    GetInstance().targets_[name] = TargetData(func, max_len, desc);
+  }
+
+  static bool Has(std::string name) {
+    return GetInstance().targets_.count(name) > 0;
+  }
+
+  static fuzzer::UserCallback Func(std::string name) {
+    assert(Has(name));
+    return std::get<0>(Get(name));
+  }
+
+  static uint16_t MaxLen(std::string name) {
+    assert(Has(name));
+    return std::get<1>(Get(name));
+  }
+
+  static std::string& Desc(std::string name) {
+    assert(Has(name));
+    return std::get<2>(Get(name));
+  }
+
+  static std::vector<std::string> Names() {
+    std::vector<std::string> names;
+    for (auto &it : GetInstance().targets_) {
+      names.push_back(it.first);
+    }
+    return names;
+  }
+
+ private:
+  typedef std::tuple<fuzzer::UserCallback, uint16_t, std::string> TargetData;
+
+  static Registry& GetInstance() {
+    static Registry registry;
+    return registry;
+  }
+
+  static TargetData& Get(std::string name) {
+    return GetInstance().targets_[name];
+  }
+
+  Registry() {}
+
+  std::map<std::string, TargetData> targets_;
+};
+
+#define REGISTER_FUZZING_TARGET(name, func, max_len, desc)            \
+  static void __attribute__ ((constructor)) RegisterFuzzingTarget() { \
+    Registry::Add(name, func, max_len, desc);                         \
+  }
+
+#endif // registry_h__
new file mode 100644
--- /dev/null
+++ b/security/nss/fuzz/nssfuzz/shared.h
@@ -0,0 +1,18 @@
+/* -*- 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/. */
+
+#ifndef shared_h__
+#define shared_h__
+
+#include "nss.h"
+
+class NSSDatabase {
+ public:
+  NSSDatabase() { NSS_NoDB_Init(nullptr); }
+  ~NSSDatabase() { NSS_Shutdown(); }
+};
+
+#endif // shared_h__
new file mode 100644
--- /dev/null
+++ b/security/nss/fuzz/nssfuzz/spki_target.cc
@@ -0,0 +1,35 @@
+/* -*- 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 <assert.h>
+#include <stdint.h>
+#include <memory>
+
+#include "keyhi.h"
+#include "pk11pub.h"
+
+#include "registry.h"
+#include "shared.h"
+
+extern "C" int spki_fuzzing_target(const uint8_t *Data, size_t Size) {
+  SECItem data = {siBuffer, (unsigned char *)Data, (unsigned int)Size};
+
+  static std::unique_ptr<NSSDatabase> db(new NSSDatabase());
+  assert(db != nullptr);
+
+  CERTSubjectPublicKeyInfo *spki = SECKEY_DecodeDERSubjectPublicKeyInfo(&data);
+
+  if (spki) {
+    SECKEYPublicKey *key = SECKEY_ExtractPublicKey(spki);
+    SECKEY_DestroyPublicKey(key);
+  }
+
+  SECKEY_DestroySubjectPublicKeyInfo(spki);
+
+  return 0;
+}
+
+REGISTER_FUZZING_TARGET("spki", spki_fuzzing_target, 1024, "SPKI Import")
new file mode 100644
--- /dev/null
+++ b/security/nss/lib/base/base.gyp
@@ -0,0 +1,32 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'nssb',
+      'type': 'static_library',
+      'sources': [
+        'arena.c',
+        'error.c',
+        'errorval.c',
+        'hash.c',
+        'hashops.c',
+        'item.c',
+        'libc.c',
+        'list.c',
+        'tracker.c',
+        'utf8.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ]
+    }
+  ],
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/lib/base/exports.gyp
@@ -0,0 +1,33 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'lib_base_exports',
+      'type': 'none',
+      'copies': [
+        {
+          'files': [
+            'nssbase.h',
+            'nssbaset.h'
+          ],
+          'destination': '<(PRODUCT_DIR)/dist/<(module)/public'
+        },
+        {
+          'files': [
+            'base.h',
+            'baset.h'
+          ],
+          'destination': '<(PRODUCT_DIR)/dist/<(module)/private'
+        }
+      ]
+    }
+  ],
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/lib/certdb/certdb.gyp
@@ -0,0 +1,34 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'certdb',
+      'type': 'static_library',
+      'sources': [
+        'alg1485.c',
+        'certdb.c',
+        'certv3.c',
+        'certxutl.c',
+        'crl.c',
+        'genname.c',
+        'polcyxtn.c',
+        'secname.c',
+        'stanpcertdb.c',
+        'xauthkid.c',
+        'xbsconst.c',
+        'xconst.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ]
+    }
+  ],
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
--- a/security/nss/lib/certdb/crl.c
+++ b/security/nss/lib/certdb/crl.c
@@ -1953,20 +1953,21 @@ DPCache_SelectCRL(CRLDPCache* cache)
         /* cache is in an invalid state, so reset it */
         if (cache->selected) {
             cache->selected = NULL;
         }
         /* also sort the CRLs imperfectly */
         qsort(cache->crls, cache->ncrls, sizeof(CachedCrl*), SortImperfectCRLs);
         return SECSuccess;
     }
-    /* all CRLs are good, sort them by thisUpdate */
-    qsort(cache->crls, cache->ncrls, sizeof(CachedCrl*), SortCRLsByThisUpdate);
 
     if (cache->ncrls) {
+        /* all CRLs are good, sort them by thisUpdate */
+        qsort(cache->crls, cache->ncrls, sizeof(CachedCrl*), SortCRLsByThisUpdate);
+
         /* pick the newest CRL */
         selected = cache->crls[cache->ncrls - 1];
 
         /* and populate the cache */
         if (SECSuccess != CachedCrl_Populate(selected)) {
             return SECFailure;
         }
     }
new file mode 100644
--- /dev/null
+++ b/security/nss/lib/certdb/exports.gyp
@@ -0,0 +1,36 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'lib_certdb_exports',
+      'type': 'none',
+      'copies': [
+        {
+          'files': [
+            'cert.h',
+            'certdb.h',
+            'certt.h'
+          ],
+          'destination': '<(PRODUCT_DIR)/dist/<(module)/public'
+        },
+        {
+          'files': [
+            'certi.h',
+            'certxutl.h',
+            'genname.h',
+            'xconst.h'
+          ],
+          'destination': '<(PRODUCT_DIR)/dist/<(module)/private'
+        }
+      ]
+    }
+  ],
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/lib/certhigh/certhigh.gyp
@@ -0,0 +1,31 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'certhi',
+      'type': 'static_library',
+      'sources': [
+        'certhigh.c',
+        'certhtml.c',
+        'certreq.c',
+        'certvfy.c',
+        'certvfypkix.c',
+        'crlv2.c',
+        'ocsp.c',
+        'ocspsig.c',
+        'xcrldist.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ]
+    }
+  ],
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/lib/certhigh/exports.gyp
@@ -0,0 +1,33 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'lib_certhigh_exports',
+      'type': 'none',
+      'copies': [
+        {
+          'files': [
+            'ocsp.h',
+            'ocspt.h'
+          ],
+          'destination': '<(PRODUCT_DIR)/dist/<(module)/public'
+        },
+        {
+          'files': [
+            'ocspi.h',
+            'ocspti.h'
+          ],
+          'destination': '<(PRODUCT_DIR)/dist/<(module)/private'
+        }
+      ]
+    }
+  ],
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
--- a/security/nss/lib/ckfw/builtins/Makefile
+++ b/security/nss/lib/ckfw/builtins/Makefile
@@ -46,9 +46,9 @@ include $(CORE_DEPTH)/coreconf/rules.mk
 
 # By default, use the unmodified certdata.txt.
 ifndef NSS_CERTDATA_TXT
 NSS_CERTDATA_TXT = certdata.txt
 endif
 
 $(OBJDIR)/certdata.c: $(NSS_CERTDATA_TXT) certdata.perl
 	@$(MAKE_OBJDIR)
-	$(PERL) certdata.perl < $(NSS_CERTDATA_TXT) > $@
+	$(PERL) certdata.perl $(NSS_CERTDATA_TXT) $@
new file mode 100644
--- /dev/null
+++ b/security/nss/lib/ckfw/builtins/builtins.gyp
@@ -0,0 +1,61 @@
+# 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/.
+{
+  'includes': [
+    '../../../coreconf/config.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'nssckbi',
+      'type': 'shared_library',
+      'sources': [
+        'anchor.c',
+        'bfind.c',
+        'binst.c',
+        'bobject.c',
+        'bsession.c',
+        'bslot.c',
+        'btoken.c',
+        'ckbiver.c',
+        'constants.c',
+        '<(INTERMEDIATE_DIR)/certdata.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:nss_exports',
+        '<(DEPTH)/lib/ckfw/ckfw.gyp:nssckfw',
+        '<(DEPTH)/lib/base/base.gyp:nssb'
+      ],
+      'actions': [
+        {
+          'msvs_cygwin_shell': 0,
+          'action': [
+            'perl',
+            'certdata.perl',
+            'certdata.txt',
+            '<@(_outputs)',
+          ],
+          'inputs': [
+            'certdata.perl',
+            'certdata.txt'
+          ],
+          'outputs': [
+            '<(INTERMEDIATE_DIR)/certdata.c'
+          ],
+          'action_name': 'generate_certdata_c'
+        }
+      ],
+      'variables': {
+        'mapfile': 'nssckbi.def'
+      }
+    }
+  ],
+  'target_defaults': {
+    'include_dirs': [
+      '.'
+    ]
+  },
+  'variables': {
+    'module': 'nss',
+  }
+}
--- a/security/nss/lib/ckfw/builtins/certdata.perl
+++ b/security/nss/lib/ckfw/builtins/certdata.perl
@@ -9,16 +9,28 @@ my %constants;
 my $count = 0;
 my $o;
 my @objects = ();
 my @objsize;
 
 $constants{CK_TRUE} = "static const CK_BBOOL ck_true = CK_TRUE;\n";
 $constants{CK_FALSE} = "static const CK_BBOOL ck_false = CK_FALSE;\n";
 
+if( scalar @ARGV == 0 ) {
+  print STDERR "Usage: $0 <input-file> [output-file]\n";
+  exit 1;
+}
+
+open(STDIN, '<', $ARGV[0])
+  or die "Could not open input file '$ARGV[0]' $!";
+if( scalar @ARGV > 1 ) {
+  open(STDOUT, '>', $ARGV[1])
+    or die "Could not open output file '$ARGV[1]' $!";
+}
+
 while(<>) {
   my @fields = ();
   my $size;
 
   s/^((?:[^"#]+|"[^"]*")*)(\s*#.*$)/$1/;
   next if (/^\s*$/);
 
   # This was taken from the perl faq #4.
new file mode 100644
--- /dev/null
+++ b/security/nss/lib/ckfw/builtins/exports.gyp
@@ -0,0 +1,25 @@
+# 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/.
+{
+  'includes': [
+    '../../../coreconf/config.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'lib_ckfw_builtins_exports',
+      'type': 'none',
+      'copies': [
+        {
+          'files': [
+            'nssckbi.h'
+          ],
+          'destination': '<(PRODUCT_DIR)/dist/<(module)/public'
+        }
+      ]
+    }
+  ],
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/lib/ckfw/ckfw.gyp
@@ -0,0 +1,34 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'nssckfw',
+      'type': 'static_library',
+      'sources': [
+        'crypto.c',
+        'find.c',
+        'hash.c',
+        'instance.c',
+        'mechanism.c',
+        'mutex.c',
+        'object.c',
+        'session.c',
+        'sessobj.c',
+        'slot.c',
+        'token.c',
+        'wrap.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ]
+    }
+  ],
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/lib/ckfw/exports.gyp
@@ -0,0 +1,44 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'lib_ckfw_exports',
+      'type': 'none',
+      'copies': [
+        {
+          'files': [
+            'nssck.api',
+            'nssckepv.h',
+            'nssckft.h',
+            'nssckfw.h',
+            'nssckfwc.h',
+            'nssckfwt.h',
+            'nssckg.h',
+            'nssckmdt.h',
+            'nssckt.h'
+          ],
+          'destination': '<(PRODUCT_DIR)/dist/<(module)/public'
+        },
+        {
+          'files': [
+            'ck.h',
+            'ckfw.h',
+            'ckfwm.h',
+            'ckfwtm.h',
+            'ckmd.h',
+            'ckt.h'
+          ],
+          'destination': '<(PRODUCT_DIR)/dist/<(module)/private'
+        }
+      ]
+    }
+  ],
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/lib/crmf/crmf.gyp
@@ -0,0 +1,39 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'crmf',
+      'type': 'static_library',
+      'sources': [
+        'asn1cmn.c',
+        'challcli.c',
+        'cmmfasn1.c',
+        'cmmfchal.c',
+        'cmmfrec.c',
+        'cmmfresp.c',
+        'crmfcont.c',
+        'crmfdec.c',
+        'crmfenc.c',
+        'crmfget.c',
+        'crmfpop.c',
+        'crmfreq.c',
+        'crmftmpl.c',
+        'encutil.c',
+        'respcli.c',
+        'respcmn.c',
+        'servget.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ]
+    }
+  ],
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/lib/crmf/exports.gyp
@@ -0,0 +1,37 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'lib_crmf_exports',
+      'type': 'none',
+      'copies': [
+        {
+          'files': [
+            'cmmf.h',
+            'cmmft.h',
+            'crmf.h',
+            'crmft.h'
+          ],
+          'destination': '<(PRODUCT_DIR)/dist/<(module)/public'
+        },
+        {
+          'files': [
+            'cmmfi.h',
+            'cmmfit.h',
+            'crmfi.h',
+            'crmfit.h'
+          ],
+          'destination': '<(PRODUCT_DIR)/dist/<(module)/private'
+        }
+      ]
+    }
+  ],
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/lib/cryptohi/cryptohi.gyp
@@ -0,0 +1,27 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'cryptohi',
+      'type': 'static_library',
+      'sources': [
+        'dsautil.c',
+        'sechash.c',
+        'seckey.c',
+        'secsign.c',
+        'secvfy.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ]
+    }
+  ],
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/lib/cryptohi/exports.gyp
@@ -0,0 +1,37 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi'
+  ],
+  'variables': {
+    'module': 'nss'
+  },
+  'targets': [
+    {
+      'target_name': 'lib_cryptohi_exports',
+      'type': 'none',
+      'copies': [
+        {
+          'files': [
+            'cryptohi.h',
+            'cryptoht.h',
+            'key.h',
+            'keyhi.h',
+            'keyt.h',
+            'keythi.h',
+            'sechash.h'
+          ],
+          'destination': '<(PRODUCT_DIR)/dist/<(module)/public'
+        },
+        {
+          'files': [
+            'keyi.h',
+          ],
+          'destination': '<(PRODUCT_DIR)/dist/<(module)/private'
+        }
+      ]
+    }
+  ],
+}
new file mode 100644
--- /dev/null
+++ b/security/nss/lib/dbm/include/exports.gyp
@@ -0,0 +1,38 @@
+# 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/.
+{
+  'includes': [
+    '../../../coreconf/config.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'lib_dbm_include_exports',
+      'type': 'none',
+      'copies': [
+        {
+          'files': [
+            'mcom_db.h',
+            'ncompat.h',
+            'winfile.h'
+          ],
+          'destination': '<(PRODUCT_DIR)/dist/<(module)/public'
+        },
+        {
+          'files': [
+            'extern.h',
+            'hash.h',
+            'hsearch.h',
+            'page.h',
+            'queue.h',
+            'search.h'
+          ],
+          'destination': '<(PRODUCT_DIR)/dist/<(module)/private'
+        }
+      ]
+    }
+  ],
+  'variables': {
+    'module': 'dbm'
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/lib/dbm/include/include.gyp
@@ -0,0 +1,12 @@
+# 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/.
+{
+  'includes': [
+    '../../../coreconf/config.gypi'
+  ],
+  'targets': [],
+  'variables': {
+    'module': 'dbm'
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/lib/dbm/src/src.gyp
@@ -0,0 +1,40 @@
+# 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/.
+{
+  'includes': [
+    '../../../coreconf/config.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'dbm',
+      'type': 'static_library',
+      'sources': [
+        'db.c',
+        'dirent.c',
+        'h_bigkey.c',
+        'h_func.c',
+        'h_log2.c',
+        'h_page.c',
+        'hash.c',
+        'hash_buf.c',
+        'mktemp.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:dbm_exports'
+      ]
+    }
+  ],
+  'target_defaults': {
+    'defines': [
+      'STDC_HEADERS',
+      'HAVE_STRERROR',
+      'HAVE_SNPRINTF',
+      'MEMMOVE',
+      '__DBINTERFACE_PRIVATE'
+    ]
+  },
+  'variables': {
+    'module': 'dbm'
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/lib/dev/dev.gyp
@@ -0,0 +1,26 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'nssdev',
+      'type': 'static_library',
+      'sources': [
+        'ckhelper.c',
+        'devslot.c',
+        'devtoken.c',
+        'devutil.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ]
+    }
+  ],
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/lib/dev/exports.gyp
@@ -0,0 +1,31 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'lib_dev_exports',
+      'type': 'none',
+      'copies': [
+        {
+          'files': [
+            'ckhelper.h',
+            'dev.h',
+            'devm.h',
+            'devt.h',
+            'devtm.h',
+            'nssdev.h',
+            'nssdevt.h'
+          ],
+          'destination': '<(PRODUCT_DIR)/dist/<(module)/private'
+        }
+      ]
+    }
+  ],
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
--- a/security/nss/lib/freebl/alg2268.c
+++ b/security/nss/lib/freebl/alg2268.c
@@ -5,16 +5,17 @@
  * 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 "blapi.h"
+#include "blapii.h"
 #include "secerr.h"
 #ifdef XP_UNIX_XXX
 #include <stddef.h> /* for ptrdiff_t */
 #endif
 
 /*
 ** RC2 symmetric block cypher
 */
@@ -413,17 +414,17 @@ rc2_EncryptCBC(RC2Context *cx, unsigned 
         STORE(iBlock.s)
         output += RC2_BLOCK_SIZE;
         input += RC2_BLOCK_SIZE;
         inputLen -= RC2_BLOCK_SIZE;
     }
     return SECSuccess;
 }
 
-static SECStatus
+static SECStatus NO_SANITIZE_ALIGNMENT
 rc2_DecryptCBC(RC2Context *cx, unsigned char *output,
                const unsigned char *input, unsigned int inputLen)
 {
     RC2Block iBlock;
     RC2Block oBlock;
 
     while (inputLen > 0) {
         LOAD(iBlock.s)
--- a/security/nss/lib/freebl/ecl/ecl-curve.h
+++ b/security/nss/lib/freebl/ecl/ecl-curve.h
@@ -1,23 +1,26 @@
 /* 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 "certt.h"
 #include "ecl-exp.h"
 #include <stdlib.h>
 
 #ifndef __ecl_curve_h_
 #define __ecl_curve_h_
 
 #ifdef NSS_ECC_MORE_THAN_SUITE_B
 #error This source file is for Basic ECC only .
 #endif
 
+/* copied from certt.h */
+#define KU_DIGITAL_SIGNATURE (0x80) /* bit 0 */
+#define KU_KEY_AGREEMENT (0x08)     /* bit 4 */
+
 static const ECCurveParams ecCurve_NIST_P256 = {
     "NIST-P256", ECField_GFp, 256,
     "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF",
     "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC",
     "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B",
     "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296",
     "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5",
     "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551",
new file mode 100644
--- /dev/null
+++ b/security/nss/lib/freebl/exports.gyp
@@ -0,0 +1,48 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'lib_freebl_exports',
+      'type': 'none',
+      'copies': [
+        {
+          'files': [
+            'blapit.h',
+            'ecl/ecl-exp.h',
+            'shsign.h'
+          ],
+          'conditions': [
+            [ 'OS=="linux"', {
+              'files': [
+                'nsslowhash.h',
+              ],
+            }],
+          ],
+          'destination': '<(PRODUCT_DIR)/dist/<(module)/public'
+        },
+        {
+          'files': [
+            'alghmac.h',
+            'blapi.h',
+            'chacha20poly1305.h',
+            'ec.h',
+            'ecl/ecl-curve.h',
+            'ecl/ecl.h',
+            'hmacct.h',
+            'secmpi.h',
+            'secrng.h'
+          ],
+          'destination': '<(PRODUCT_DIR)/dist/<(module)/private'
+        }
+      ]
+    }
+  ],
+  'variables': {
+    'module': 'nss'
+  }
+}
new file mode 100644
--- /dev/null
+++ b/security/nss/lib/freebl/freebl.gyp
@@ -0,0 +1,393 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'intel-gcm-wrap_c_lib',
+      'type': 'static_library',
+      'sources': [
+        'intel-gcm-wrap.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ],
+      'cflags': [
+        '-mssse3'
+      ],
+      'cflags_mozilla': [
+        '-mssse3'
+      ]
+    },
+    {
+      'target_name': 'freebl',
+      'type': 'static_library',
+      'sources': [
+        'loader.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ]
+    },
+    {
+      'target_name': '<(freebl_name)',
+      'type': 'shared_library',
+      'sources': [
+        'aeskeywrap.c',
+        'alg2268.c',
+        'alghmac.c',
+        'arcfive.c',
+        'arcfour.c',
+        'camellia.c',
+        'chacha20poly1305.c',
+        'ctr.c',
+        'cts.c',
+        'des.c',
+        'desblapi.c',
+        'dh.c',
+        'drbg.c',
+        'dsa.c',
+        'ec.c',
+        'ecdecode.c',
+        'ecl/ec_naf.c',
+        'ecl/ecl.c',
+        'ecl/ecl_curve.c',
+        'ecl/ecl_gf.c',
+        'ecl/ecl_mult.c',
+        'ecl/ecp_25519.c',
+        'ecl/ecp_256.c',
+        'ecl/ecp_256_32.c',
+        'ecl/ecp_384.c',
+        'ecl/ecp_521.c',
+        'ecl/ecp_aff.c',
+        'ecl/ecp_jac.c',
+        'ecl/ecp_jm.c',
+        'ecl/ecp_mont.c',
+        'fipsfreebl.c',
+        'freeblver.c',
+        'gcm.c',
+        'hmacct.c',
+        'jpake.c',
+        'ldvector.c',
+        'md2.c',
+        'md5.c',
+        'mpi/mp_gf2m.c',
+        'mpi/mpcpucache.c',
+        'mpi/mpi.c',
+        'mpi/mplogic.c',
+        'mpi/mpmontg.c',
+        'mpi/mpprime.c',
+        'pqg.c',
+        'rawhash.c',
+        'rijndael.c',
+        'rsa.c',
+        'rsapkcs.c',
+        'seed.c',
+        'sha512.c',
+        'sha_fast.c',
+        'shvfy.c',
+        'sysrand.c',
+        'tlsprfalg.c'
+      ],
+      'conditions': [
+        [ 'OS=="linux"', {
+          'sources': [
+            'nsslowhash.c',
+            'stubs.c',
+          ],
+          'conditions': [
+            [ 'target_arch=="x64"', {
+              'sources': [
+                'arcfour-amd64-gas.s',
+                'intel-aes.s',
+                'intel-gcm.s',
+                'mpi/mpi_amd64.c',
+                'mpi/mpi_amd64_gas.s',
+                'mpi/mp_comba.c',
+              ],
+              'dependencies': [
+                'intel-gcm-wrap_c_lib',
+              ],
+              'conditions': [
+                [ 'cc_is_clang==1', {
+                  'cflags': [
+                    '-no-integrated-as',
+                  ],
+                  'cflags_mozilla': [
+                    '-no-integrated-as',
+                  ],
+                  'asflags_mozilla': [
+                    '-no-integrated-as',
+                  ],
+                }],
+              ],
+            }],
+            [ 'target_arch=="ia32"', {
+              'sources': [
+                'mpi/mpi_x86.s',
+              ],
+            }],
+            [ 'target_arch=="arm"', {
+              'sources': [
+                'mpi/mpi_arm.c',
+              ],
+            }],
+          ],
+        }, {
+          # not Linux
+          'conditions': [
+            [ 'moz_fold_libs==0', {
+              'dependencies': [
+                '../util/util.gyp:nssutil3',
+              ],
+            }, {
+              'libraries': [
+                '<(moz_folded_library_name)',
+              ],
+            }],
+          ],
+        }],
+        [ 'OS=="win"', {
+          'sources': [
+            #TODO: building with mingw should not need this.
+            'ecl/uint128.c',
+            #TODO: clang-cl needs -msse3 here
+            'intel-gcm-wrap.c',
+          ],
+          'libraries': [
+            'advapi32.lib',
+          ],
+          'conditions': [
+            [ 'target_arch=="x64"', {
+              'sources': [
+                'arcfour-amd64-masm.asm',
+                'mpi/mpi_amd64.c',
+                'mpi/mpi_amd64_masm.asm',
+                'mpi/mp_comba_amd64_masm.asm',
+                'intel-aes-x64-masm.asm',
+                'intel-gcm-x64-masm.asm',
+              ],
+            }, {
+              # not x64
+              'sources': [
+                'mpi/mpi_x86_asm.c',
+                'intel-aes-x86-masm.asm',
+                'intel-gcm-x86-masm.asm',
+              ],
+            }],
+          ],
+        }],
+        ['target_arch=="ia32" or target_arch=="x64"', {
+          'sources': [
+            # All intel architectures get the 64 bit version
+            'ecl/curve25519_64.c',
+          ],
+        }, {
+          'sources': [
+            # All non intel architectures get the generic 32 bit implementation (slow!)
+            'ecl/curve25519_32.c',
+          ],
+        }],
+        #TODO uint128.c
+        [ 'disable_chachapoly==0', {
+          'conditions': [
+            [ 'OS!="win" and target_arch=="x64"', {
+              'sources': [
+                'chacha20_vec.c',
+                'poly1305-donna-x64-sse2-incremental-source.c',
+              ],
+            }, {
+              # not x64
+              'sources': [
+                'chacha20.c',
+                'poly1305.c',
+              ],
+            }],
+          ],
+        }],
+        [ 'OS=="mac"', {
+          'conditions': [
+            [ 'target_arch=="ia32"', {
+              'sources': [
+                'mpi/mpi_sse2.s',
+              ],
+              'defines': [
+                'MP_USE_UINT_DIGIT',
+                'MP_ASSEMBLY_MULTIPLY',
+                'MP_ASSEMBLY_SQUARE',
+                'MP_ASSEMBLY_DIV_2DX1D',
+              ],
+            }],
+          ],
+        }],
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:nss_exports',
+      ],
+      'variables': {
+       'conditions': [
+         [ 'OS=="linux"', {
+           'mapfile': 'freebl_hash_vector.def',
+         }, {
+           'mapfile': 'freebl.def',
+         }],
+       ]
+      },
+      'ldflags': [
+        '-Wl,-Bsymbolic'
+      ]
+    },
+  ],
+  'conditions': [
+    [ 'OS=="linux"', {
+      # stub build
+      'targets': [
+        {
+          'target_name': 'freebl3',
+          'type': 'shared_library',
+          'sources': [
+            'lowhash_vector.c'
+          ],
+          'dependencies': [
+            '<(DEPTH)/exports.gyp:nss_exports'
+          ],
+          'variables': {
+            'mapfile': 'freebl_hash.def'
+          }
+        },
+      ],
+    }],
+  ],
+  'target_defaults': {
+    'include_dirs': [
+      'mpi',
+      'ecl'
+    ],
+    'defines': [
+      'SHLIB_SUFFIX=\"<(dll_suffix)\"',
+      'SHLIB_PREFIX=\"<(dll_prefix)\"',
+      'SHLIB_VERSION=\"3\"',
+      'SOFTOKEN_SHLIB_VERSION=\"3\"',
+      'RIJNDAEL_INCLUDE_TABLES',
+      'MP_API_COMPATIBLE'
+    ],
+    'conditions': [
+      [ 'OS=="win"', {
+        'configurations': {
+          'x86_Base': {
+            'msvs_settings': {
+              'VCCLCompilerTool': {
+                #TODO: -Ox optimize flags
+                'PreprocessorDefinitions': [
+                  'NSS_X86_OR_X64',
+                  'NSS_X86',
+                  'MP_ASSEMBLY_MULTIPLY',
+                  'MP_ASSEMBLY_SQUARE',
+                  'MP_ASSEMBLY_DIV_2DX1D',
+                  'MP_USE_UINT_DIGIT',
+                  'MP_NO_MP_WORD',
+                  'USE_HW_AES',
+                  'INTEL_GCM',
+                ],
+              },
+            },
+          },
+          'x64_Base': {
+            'msvs_settings': {
+              'VCCLCompilerTool': {
+                #TODO: -Ox optimize flags
+                'PreprocessorDefinitions': [
+                  'NSS_USE_64',
+                  'NSS_X86_OR_X64',
+                  'NSS_X64',
+                  'MP_IS_LITTLE_ENDIAN',
+                  'NSS_BEVAND_ARCFOUR',
+                  'MPI_AMD64',
+                  'MP_ASSEMBLY_MULTIPLY',
+                  'NSS_USE_COMBA',
+                  'USE_HW_AES',
+                  'INTEL_GCM',
+                ],
+              },
+            },
+          },
+        },
+      }, {
+        'conditions': [
+          [ 'target_arch=="x64"', {
+            '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',
+            ],
+          }, {
+            'sources': [
+              'ecl/uint128.c',
+            ],
+          }],
+          [ 'target_arch=="ia32"', {
+            'defines': [
+              'NSS_X86_OR_X64',
+              'NSS_X86',
+            ],
+          }],
+        ],
+      }],
+      [ 'OS=="linux"', {
+        'defines': [
+          'FREEBL_NO_DEPEND',
+          'FREEBL_LOWHASH',
+        ],
+        'conditions': [
+          [ 'target_arch=="x64"', {
+            'defines': [
+              'MP_IS_LITTLE_ENDIAN',
+              'NSS_BEVAND_ARCFOUR',
+              'MPI_AMD64',
+              'MP_ASSEMBLY_MULTIPLY',
+              'NSS_USE_COMBA',
+              'USE_HW_AES',
+              'INTEL_GCM',
+            ],
+          }],
+          [ 'target_arch=="ia32"', {
+            'defines': [
+              'MP_IS_LITTLE_ENDIAN',
+              'MP_ASSEMBLY_MULTIPLY',
+              'MP_ASSEMBLY_SQUARE',
+              'MP_ASSEMBLY_DIV_2DX1D',
+              'MP_USE_UINT_DIGIT',
+            ],
+          }],
+          [ 'target_arch=="arm"', {
+            'defines': [
+              'MP_ASSEMBLY_MULTIPLY',
+              'MP_ASSEMBLY_SQUARE',
+              'MP_USE_UINT_DIGIT',
+              'SHA_NO_LONG_LONG',
+            ],
+          }],
+        ],
+      }],
+      [ 'OS=="mac"', {
+      }],
+      [ 'OS=="win"', {
+      }],
+    ],
+  },
+  'variables': {
+    'module': 'nss',
+    'conditions': [
+      [ 'OS=="linux"', {
+        'freebl_name': 'freeblpriv3',
+      }, {
+        'freebl_name': 'freebl3',
+      }],
+    ],
+  }
+}
--- a/security/nss/lib/freebl/rijndael.c
+++ b/security/nss/lib/freebl/rijndael.c
@@ -91,20 +91,26 @@ static PRBool use_hw_gcm = PR_FALSE;
 #else /* not RIJNDAEL_INCLUDE_TABLES */
 
 /*
  * Code for generating T-table values.
  */
 
 #ifdef IS_LITTLE_ENDIAN
 #define WORD4(b0, b1, b2, b3) \
-    (((b3) << 24) | ((b2) << 16) | ((b1) << 8) | (b0))
+    ((((PRUint32)b3) << 24) | \
+     (((PRUint32)b2) << 16) | \
+     (((PRUint32)b1) << 8) |  \
+     ((PRUint32)b0))
 #else
 #define WORD4(b0, b1, b2, b3) \
-    (((b0) << 24) | ((b1) << 16) | ((b2) << 8) | (b3))
+    ((((PRUint32)b0) << 24) | \
+     (((PRUint32)b1) << 16) | \
+     (((PRUint32)b2) << 8) |  \
+     ((PRUint32)b3))
 #endif
 
 /*
  * Define the S and S**-1 tables (both have been stored)
  */
 #define SBOX(b) (_S[b])
 #define SINV(b) (_SInv[b])
 
@@ -344,21 +350,21 @@ init_rijndael_tables(void)
 #endif /* code to generate tables */
 
 /**************************************************************************
  *
  * Stuff related to the Rijndael key schedule
  *
  *************************************************************************/
 
-#define SUBBYTE(w)                    \
-    ((SBOX((w >> 24) & 0xff) << 24) | \
-     (SBOX((w >> 16) & 0xff) << 16) | \
-     (SBOX((w >> 8) & 0xff) << 8) |   \
-     (SBOX((w)&0xff)))
+#define SUBBYTE(w)                                \
+    ((((PRUint32)SBOX((w >> 24) & 0xff)) << 24) | \
+     (((PRUint32)SBOX((w >> 16) & 0xff)) << 16) | \
+     (((PRUint32)SBOX((w >> 8) & 0xff)) << 8) |   \
+     (((PRUint32)SBOX((w)&0xff))))
 
 #ifdef IS_LITTLE_ENDIAN
 #define ROTBYTE(b) \
     ((b >> 8) | (b << 24))
 #else
 #define ROTBYTE(b) \
     ((b << 8) | (b >> 24))
 #endif
@@ -556,17 +562,17 @@ typedef union {
 
 #define COLUMN_0(state) state.w[0]
 #define COLUMN_1(state) state.w[1]
 #define COLUMN_2(state) state.w[2]
 #define COLUMN_3(state) state.w[3]
 
 #define STATE_BYTE(i) state.b[i]
 
-static SECStatus
+static SECStatus NO_SANITIZE_ALIGNMENT
 rijndael_encryptBlock128(AESContext *cx,
                          unsigned char *output,
                          const unsigned char *input)
 {
     unsigned int r;
     PRUint32 *roundkeyw;
     rijndael_state state;
     PRUint32 C0, C1, C2, C3;
@@ -652,17 +658,17 @@ rijndael_encryptBlock128(AESContext *cx,
 #else
     if ((ptrdiff_t)output & 0x3) {
         memcpy(output, outBuf, sizeof outBuf);
     }
 #endif
     return SECSuccess;
 }
 
-static SECStatus
+static SECStatus NO_SANITIZE_ALIGNMENT
 rijndael_decryptBlock128(AESContext *cx,
                          unsigned char *output,
                          const unsigned char *input)
 {
     int r;
     PRUint32 *roundkeyw;
     rijndael_state state;
     PRUint32 C0, C1, C2, C3;
new file mode 100644
--- /dev/null
+++ b/security/nss/lib/jar/exports.gyp
@@ -0,0 +1,27 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'lib_jar_exports',
+      'type': 'none',
+      'copies': [
+        {
+          'files': [
+            'jar-ds.h',
+            'jar.h',
+            'jarfile.h'
+          ],
+          'destination': '<(PRODUCT_DIR)/dist/<(module)/public'
+        }
+      ]
+    }
+  ],
+  'variables': {
+    'module': 'nss'
+  }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/lib/jar/jar.gyp
@@ -0,0 +1,76 @@
+# 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/.
+{
+  'includes': [
+    '../../coreconf/config.gypi'
+  ],
+  'targets': [
+    {
+      'target_name': 'jar',
+      'type': 'static_library',
+      'sources': [
+        'jar-ds.c',
+        'jar.c',
+        'jarfile.c',
+        'jarint.c',
+        'jarsign.c',
+        'jarver.c'
+      ],
+      'dependencies': [
+        '<(DEPTH)/exports.gyp:nss_exports'
+      ]
+    }
+  ],
+  'target_defaults': {
+    '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'
+  }
+}
<