Bug 1305970 - land NSS 0x0c845c900217, r=me
authorFranziskus Kiefer <franziskuskiefer@gmail.com>
Sat, 15 Oct 2016 08:45:05 +0200
changeset 348195 a7037a607016fb1727b3fd7194910a7ec5197715
parent 348194 c8183800343eb8363702ff76e2e7df9bf41b2be5
child 348196 fea2dc883057d88fc6ae52b7fadcc07e6ab0e5bd
push id6795
push userjlund@mozilla.com
push dateMon, 23 Jan 2017 14:19:46 +0000
treeherdermozilla-esr52@76101b503191 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersme
bugs1305970
milestone52.0a1
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'
+  }
+}
new file mode 100644
--- /dev/null
+++ b/security/nss/lib/libpkix/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_libpkix_include_exports',
+      'type': 'none',
+      'copies': [
+        {
+          'files': [
+            'pkix.h',
+            'pkix_certsel.h',
+            'pkix_certstore.h',
+