Bug 1305970 - land NSS 0x233a44e96b22, r=me
authorFranziskus Kiefer <franziskuskiefer@gmail.com>
Thu, 29 Sep 2016 07:59:34 +0200
changeset 315714 73db35241e5a4c8f4b5783a7874998f21ace0eee
parent 315713 2eeb786c68abc7e8d5fa7a9f071e027ac12d34d7
child 315715 0e716d57f4b2c4dfd99ce779037517a868a9ab07
push id30753
push usercbook@mozilla.com
push dateThu, 29 Sep 2016 09:45:12 +0000
treeherdermozilla-central@f7d5008ee2ab [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersme
bugs1305970
milestone52.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1305970 - land NSS 0x233a44e96b22, r=me
security/nss/TAG-INFO
security/nss/automation/taskcluster/docker-arm/Dockerfile
security/nss/automation/taskcluster/docker-arm/bin/checkout.sh
security/nss/automation/taskcluster/docker-arm/bin/uname.sh
security/nss/automation/taskcluster/graph/src/extend.js
security/nss/cmd/bltest/blapitest.c
security/nss/cmd/bltest/pkcs1_vectors.h
security/nss/cmd/selfserv/selfserv.c
security/nss/coreconf/coreconf.dep
security/nss/lib/freebl/mpi/README
security/nss/lib/freebl/mpi/mpi-test.c
security/nss/lib/freebl/mpi/mpi.c
security/nss/lib/freebl/mpi/mpi.h
security/nss/lib/freebl/mpi/tests/mptest-3.c
security/nss/lib/freebl/rsa.c
security/nss/lib/ssl/sslimpl.h
security/nss/lib/ssl/tls13con.c
security/nss/tests/cipher/cipher.txt
security/nss/tests/ssl/ssl.sh
--- a/security/nss/TAG-INFO
+++ b/security/nss/TAG-INFO
@@ -1,1 +1,1 @@
-206d7e12c036
+233a44e96b22
--- a/security/nss/automation/taskcluster/docker-arm/Dockerfile
+++ b/security/nss/automation/taskcluster/docker-arm/Dockerfile
@@ -1,10 +1,10 @@
 FROM armv7/armhf-ubuntu:16.04
-MAINTAINER Tim Taubert <ttaubert@mozilla.com>
+MAINTAINER Franziskus Kiefer <franziskuskiefer@gmail.com>
 
 RUN useradd -d /home/worker -s /bin/bash -m worker
 WORKDIR /home/worker
 
 # Add build and test scripts.
 ADD bin /home/worker/bin
 RUN chmod +x /home/worker/bin/*
 
--- a/security/nss/automation/taskcluster/docker-arm/bin/checkout.sh
+++ b/security/nss/automation/taskcluster/docker-arm/bin/checkout.sh
@@ -1,13 +1,18 @@
 #!/usr/bin/env bash
 
 set -v -e -x
 
 if [ $(id -u) = 0 ]; then
+    # set up fake uname
+    if [ ! -f /bin/uname-real ]; then
+        mv /bin/uname /bin/uname-real
+        ln -s /home/worker/bin/uname.sh /bin/uname
+    fi
     # Drop privileges by re-running this script.
     exec su worker $0
 fi
 
 # Default values for testing.
 REVISION=${NSS_HEAD_REVISION:-default}
 REPOSITORY=${NSS_HEAD_REPOSITORY:-https://hg.mozilla.org/projects/nss}
 
new file mode 100755
--- /dev/null
+++ b/security/nss/automation/taskcluster/docker-arm/bin/uname.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+args=`getopt rmvs $*`
+set -- $args
+for i
+do
+  if [ "$i" == "-v" ]; then
+    /bin/uname-real -v
+  fi
+  if [ "$i" == "-r" ]; then
+    echo "4.4.16-v7+"
+  fi
+  if [ "$i" == "-m" ]; then
+    echo "armv7l"
+  fi
+  if [ "$i" == "-s" ]; then
+    echo "Linux"
+  fi
+done
\ No newline at end of file
--- a/security/nss/automation/taskcluster/graph/src/extend.js
+++ b/security/nss/automation/taskcluster/graph/src/extend.js
@@ -119,17 +119,17 @@ export default async function main() {
 
   await scheduleWindows("Windows 2012 64 (debug)", {
     collection: "debug"
   });
 
   await scheduleTools();
 
   await scheduleLinux("Linux 32 (ARM, debug)", {
-    image: "ttaubert/nss-rpi-ci:0.0.3",
+    image: "franziskus/nss-arm-ci",
     provisioner: "localprovisioner",
     collection: "arm-debug",
     workerType: "nss-rpi",
     platform: "linux32",
     maxRunTime: 7200,
     tier: 3
   });
 }
--- a/security/nss/cmd/bltest/blapitest.c
+++ b/security/nss/cmd/bltest/blapitest.c
@@ -16,16 +16,18 @@
 #include "basicutil.h"
 #include "plgetopt.h"
 #include "softoken.h"
 #include "nspr.h"
 #include "secport.h"
 #include "secoid.h"
 #include "nssutil.h"
 
+#include "pkcs1_vectors.h"
+
 #ifndef NSS_DISABLE_ECC
 #include "ecl-curve.h"
 SECStatus EC_DecodeParams(const SECItem *encodedParams,
                           ECParams **ecparams);
 SECStatus EC_CopyParams(PLArenaPool *arena, ECParams *dstParams,
                         const ECParams *srcParams);
 #endif
 
@@ -3405,28 +3407,74 @@ rsaPrivKeysAreEqual(RSAPrivateKey *src, 
         fprintf(stderr, "original key:\n");
         dump_rsakey(src);
         fprintf(stderr, "recreated key:\n");
         dump_rsakey(dest);
     }
     return areEqual;
 }
 
+static int
+doRSAPopulateTestKV()
+{
+    RSAPrivateKey tstKey = { 0 };
+    SECStatus rv;
+    int failed = 0;
+    int i;
+
+    tstKey.arena = NULL;
+
+    /* Test public exponent, private exponent, modulus cases from
+     * pkcs1v15sign-vectors.txt. Some are valid PKCS#1 keys but not valid RSA
+     * ones (de = 1 mod lcm(p − 1, q − 1))
+     */
+    for (i = 0; i < PR_ARRAY_SIZE(PKCS1_VECTORS); ++i) {
+        struct pkcs1_test_vector *v = &PKCS1_VECTORS[i];
+
+        rsaPrivKeyReset(&tstKey);
+        tstKey.privateExponent.data = v->d;
+        tstKey.privateExponent.len = v->d_len;
+        tstKey.publicExponent.data = v->e;
+        tstKey.publicExponent.len = v->e_len;
+        tstKey.modulus.data = v->n;
+        tstKey.modulus.len = v->n_len;
+
+        rv = RSA_PopulatePrivateKey(&tstKey);
+        if (rv != SECSuccess) {
+            fprintf(stderr, "RSA Populate failed: pkcs1v15sign-vector %d\n", i);
+            failed = 1;
+        } else if (memcmp(v->q, tstKey.prime1.data, v->q_len) ||
+                   tstKey.prime1.len != v->q_len) {
+            fprintf(stderr, "RSA Populate key mismatch: pkcs1v15sign-vector %d q\n", i);
+            failed = 1;
+        } else if (memcmp(v->p, tstKey.prime2.data, v->p_len) ||
+                   tstKey.prime1.len != v->p_len) {
+            fprintf(stderr, "RSA Populate key mismatch: pkcs1v15sign-vector %d p\n", i);
+            failed = 1;
+        } else {
+            fprintf(stderr, "RSA Populate success: pkcs1v15sign-vector %d p\n", i);
+        }
+    }
+
+    PORT_FreeArena(tstKey.arena, PR_TRUE);
+    return failed;
+}
+
 /*
  * Test the RSA populate command to see that it can really build
- * keys from it's components.
+ * keys from its components.
  */
 static int
 doRSAPopulateTest(unsigned int keySize, unsigned long exponent)
 {
     RSAPrivateKey *srcKey;
     RSAPrivateKey tstKey = { 0 };
     SECItem expitem = { 0, 0, 0 };
     SECStatus rv;
-    unsigned char pubExp[4];
+    unsigned char pubExp[32];
     int expLen = 0;
     int failed = 0;
     int i;
 
     for (i = 0; i < sizeof(unsigned long); i++) {
         int shift = (sizeof(unsigned long) - i - 1) * 8;
         if (expLen || (exponent && ((unsigned long)0xffL << shift))) {
             pubExp[expLen] = (unsigned char)((exponent >> shift) & 0xff);
@@ -3499,18 +3547,18 @@ doRSAPopulateTest(unsigned int keySize, 
     tstKey.publicExponent = srcKey->publicExponent;
     tstKey.prime2 = srcKey->prime2; /* use q in the prime2 position */
 
     rv = RSA_PopulatePrivateKey(&tstKey);
     if (rv != SECSuccess) {
         fprintf(stderr, "RSA Populate failed: pubExp privExp q\n");
         fprintf(stderr, " - not fatal\n");
         /* it's possible that we can't uniquely determine the original key
-     * from just the exponents and prime. Populate returns an error rather
-     * than return the wrong key. */
+         * from just the exponents and prime. Populate returns an error rather
+         * than return the wrong key. */
     } else if (!rsaPrivKeysAreEqual(&tstKey, srcKey)) {
         /* if we returned a key, it *must* be correct */
         fprintf(stderr, "RSA Populate key mismatch: pubExp privExp  q\n");
         rv = RSA_PrivateKeyCheck(&tstKey);
         failed = 1;
     }
 
     /* test the advanced case2, public exponent, private exponent, modulus */
@@ -3524,28 +3572,30 @@ doRSAPopulateTest(unsigned int keySize, 
     if (rv != SECSuccess) {
         fprintf(stderr, "RSA Populate failed: pubExp privExp mod\n");
         failed = 1;
     } else if (!rsaPrivKeysAreEqual(&tstKey, srcKey)) {
         fprintf(stderr, "RSA Populate key mismatch: pubExp privExp  mod\n");
         failed = 1;
     }
 
+    PORT_FreeArena(srcKey->arena, PR_TRUE);
     return failed ? -1 : 0;
 }
 
 /* bltest commands */
 enum {
     cmd_Decrypt = 0,
     cmd_Encrypt,
     cmd_FIPS,
     cmd_Hash,
     cmd_Nonce,
     cmd_Dump,
     cmd_RSAPopulate,
+    cmd_RSAPopulateKV,
     cmd_Sign,
     cmd_SelfTest,
     cmd_Verify
 };
 
 /* bltest options */
 enum {
     opt_B64 = 0,
@@ -3589,16 +3639,17 @@ static secuCommandFlag bltest_commands[]
     {
       { /* cmd_Decrypt */ 'D', PR_FALSE, 0, PR_FALSE },
       { /* cmd_Encrypt */ 'E', PR_FALSE, 0, PR_FALSE },
       { /* cmd_FIPS */ 'F', PR_FALSE, 0, PR_FALSE },
       { /* cmd_Hash */ 'H', PR_FALSE, 0, PR_FALSE },
       { /* cmd_Nonce */ 'N', PR_FALSE, 0, PR_FALSE },
       { /* cmd_Dump */ 'P', PR_FALSE, 0, PR_FALSE },
       { /* cmd_RSAPopulate */ 'R', PR_FALSE, 0, PR_FALSE },
+      { /* cmd_RSAPopulateKV */ 'K', PR_FALSE, 0, PR_FALSE },
       { /* cmd_Sign */ 'S', PR_FALSE, 0, PR_FALSE },
       { /* cmd_SelfTest */ 'T', PR_FALSE, 0, PR_FALSE },
       { /* cmd_Verify */ 'V', PR_FALSE, 0, PR_FALSE }
     };
 
 static secuCommandFlag bltest_options[] =
     {
       { /* opt_B64 */ 'a', PR_FALSE, 0, PR_FALSE },
@@ -3726,16 +3777,22 @@ main(int argc, char **argv)
 
     testdir = (bltest.options[opt_SelfTestDir].activated) ? strdup(bltest.options[opt_SelfTestDir].arg)
                                                           : ".";
 
     /*
      * Handle three simple cases first
      */
 
+    /* test the RSA_PopulatePrivateKey function with known vectors */
+    if (bltest.commands[cmd_RSAPopulateKV].activated) {
+        PORT_Free(cipherInfo);
+        return doRSAPopulateTestKV();
+    }
+
     /* test the RSA_PopulatePrivateKey function */
     if (bltest.commands[cmd_RSAPopulate].activated) {
         unsigned int keySize = 1024;
         unsigned long exponent = 65537;
         int rounds = 1;
         int ret = -1;
 
         if (bltest.options[opt_KeySize].activated) {
@@ -3753,16 +3810,17 @@ main(int argc, char **argv)
             ret = doRSAPopulateTest(keySize, exponent);
             if (ret != 0) {
                 break;
             }
         }
         if (ret != 0) {
             fprintf(stderr, "RSA Populate test round %d: FAILED\n", i);
         }
+        PORT_Free(cipherInfo);
         return ret;
     }
 
     /* Do BLAPI self-test */
     if (bltest.commands[cmd_SelfTest].activated) {
         PRBool encrypt = PR_TRUE, decrypt = PR_TRUE;
         /* user may specified a set of ciphers to test.  parse them. */
         bltestCipherMode modesToTest[NUMMODES];
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/pkcs1_vectors.h
@@ -0,0 +1,789 @@
+/* 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/. */
+
+/* Vectors from pkcs1v15sign-vectors.txt */
+
+struct pkcs1_test_vector {
+    unsigned char *n;
+    unsigned long n_len;
+    unsigned char *e;
+    unsigned long e_len;
+    unsigned char *d;
+    unsigned long d_len;
+    unsigned char *p;
+    unsigned long p_len;
+    unsigned char *q;
+    unsigned long q_len;
+};
+
+struct pkcs1_test_vector PKCS1_VECTORS[15] = {
+    {
+        (unsigned char[]){
+            0xa5, 0x6e, 0x4a, 0x0e, 0x70, 0x10, 0x17, 0x58, 0x9a, 0x51,
+            0x87, 0xdc, 0x7e, 0xa8, 0x41, 0xd1, 0x56, 0xf2, 0xec, 0x0e,
+            0x36, 0xad, 0x52, 0xa4, 0x4d, 0xfe, 0xb1, 0xe6, 0x1f, 0x7a,
+            0xd9, 0x91, 0xd8, 0xc5, 0x10, 0x56, 0xff, 0xed, 0xb1, 0x62,
+            0xb4, 0xc0, 0xf2, 0x83, 0xa1, 0x2a, 0x88, 0xa3, 0x94, 0xdf,
+            0xf5, 0x26, 0xab, 0x72, 0x91, 0xcb, 0xb3, 0x07, 0xce, 0xab,
+            0xfc, 0xe0, 0xb1, 0xdf, 0xd5, 0xcd, 0x95, 0x08, 0x09, 0x6d,
+            0x5b, 0x2b, 0x8b, 0x6d, 0xf5, 0xd6, 0x71, 0xef, 0x63, 0x77,
+            0xc0, 0x92, 0x1c, 0xb2, 0x3c, 0x27, 0x0a, 0x70, 0xe2, 0x59,
+            0x8e, 0x6f, 0xf8, 0x9d, 0x19, 0xf1, 0x05, 0xac, 0xc2, 0xd3,
+            0xf0, 0xcb, 0x35, 0xf2, 0x92, 0x80, 0xe1, 0x38, 0x6b, 0x6f,
+            0x64, 0xc4, 0xef, 0x22, 0xe1, 0xe1, 0xf2, 0x0d, 0x0c, 0xe8,
+            0xcf, 0xfb, 0x22, 0x49, 0xbd, 0x9a, 0x21, 0x37 },
+        128,
+        (unsigned char[]){ 0x01, 0x00, 0x01 }, 3,
+        (unsigned char[]){
+            0x33, 0xa5, 0x04, 0x2a, 0x90, 0xb2, 0x7d, 0x4f, 0x54, 0x51,
+            0xca, 0x9b, 0xbb, 0xd0, 0xb4, 0x47, 0x71, 0xa1, 0x01, 0xaf,
+            0x88, 0x43, 0x40, 0xae, 0xf9, 0x88, 0x5f, 0x2a, 0x4b, 0xbe,
+            0x92, 0xe8, 0x94, 0xa7, 0x24, 0xac, 0x3c, 0x56, 0x8c, 0x8f,
+            0x97, 0x85, 0x3a, 0xd0, 0x7c, 0x02, 0x66, 0xc8, 0xc6, 0xa3,
+            0xca, 0x09, 0x29, 0xf1, 0xe8, 0xf1, 0x12, 0x31, 0x88, 0x44,
+            0x29, 0xfc, 0x4d, 0x9a, 0xe5, 0x5f, 0xee, 0x89, 0x6a, 0x10,
+            0xce, 0x70, 0x7c, 0x3e, 0xd7, 0xe7, 0x34, 0xe4, 0x47, 0x27,
+            0xa3, 0x95, 0x74, 0x50, 0x1a, 0x53, 0x26, 0x83, 0x10, 0x9c,
+            0x2a, 0xba, 0xca, 0xba, 0x28, 0x3c, 0x31, 0xb4, 0xbd, 0x2f,
+            0x53, 0xc3, 0xee, 0x37, 0xe3, 0x52, 0xce, 0xe3, 0x4f, 0x9e,
+            0x50, 0x3b, 0xd8, 0x0c, 0x06, 0x22, 0xad, 0x79, 0xc6, 0xdc,
+            0xee, 0x88, 0x35, 0x47, 0xc6, 0xa3, 0xb3, 0x25 },
+        128,
+        (unsigned char[]){
+            0xb6, 0x9d, 0xca, 0x1c, 0xf7, 0xd4, 0xd7, 0xec, 0x81, 0xe7,
+            0x5b, 0x90, 0xfc, 0xca, 0x87, 0x4a, 0xbc, 0xde, 0x12, 0x3f,
+            0xd2, 0x70, 0x01, 0x80, 0xaa, 0x90, 0x47, 0x9b, 0x6e, 0x48,
+            0xde, 0x8d, 0x67, 0xed, 0x24, 0xf9, 0xf1, 0x9d, 0x85, 0xba,
+            0x27, 0x58, 0x74, 0xf5, 0x42, 0xcd, 0x20, 0xdc, 0x72, 0x3e,
+            0x69, 0x63, 0x36, 0x4a, 0x1f, 0x94, 0x25, 0x45, 0x2b, 0x26,
+            0x9a, 0x67, 0x99, 0xfd },
+        64,
+        (unsigned char[]){
+            0xe7, 0xe8, 0x94, 0x27, 0x20, 0xa8, 0x77, 0x51, 0x72, 0x73,
+            0xa3, 0x56, 0x05, 0x3e, 0xa2, 0xa1, 0xbc, 0x0c, 0x94, 0xaa,
+            0x72, 0xd5, 0x5c, 0x6e, 0x86, 0x29, 0x6b, 0x2d, 0xfc, 0x96,
+            0x79, 0x48, 0xc0, 0xa7, 0x2c, 0xbc, 0xcc, 0xa7, 0xea, 0xcb,
+            0x35, 0x70, 0x6e, 0x09, 0xa1, 0xdf, 0x55, 0xa1, 0x53, 0x5b,
+            0xd9, 0xb3, 0xcc, 0x34, 0x16, 0x0b, 0x3b, 0x6d, 0xcd, 0x3e,
+            0xda, 0x8e, 0x64, 0x43 },
+        64,
+    },
+    {
+        (unsigned char[]){
+            0xa5, 0x6e, 0x4a, 0x0e, 0x70, 0x10, 0x17, 0x58, 0x9a, 0x51,
+            0x87, 0xdc, 0x7e, 0xa8, 0x41, 0xd1, 0x56, 0xf2, 0xec, 0x0e,
+            0x36, 0xad, 0x52, 0xa4, 0x4d, 0xfe, 0xb1, 0xe6, 0x1f, 0x7a,
+            0xd9, 0x91, 0xd8, 0xc5, 0x10, 0x56, 0xff, 0xed, 0xb1, 0x62,
+            0xb4, 0xc0, 0xf2, 0x83, 0xa1, 0x2a, 0x88, 0xa3, 0x94, 0xdf,
+            0xf5, 0x26, 0xab, 0x72, 0x91, 0xcb, 0xb3, 0x07, 0xce, 0xab,
+            0xfc, 0xe0, 0xb1, 0xdf, 0xd5, 0xcd, 0x95, 0x08, 0x09, 0x6d,
+            0x5b, 0x2b, 0x8b, 0x6d, 0xf5, 0xd6, 0x71, 0xef, 0x63, 0x77,
+            0xc0, 0x92, 0x1c, 0xb2, 0x3c, 0x27, 0x0a, 0x70, 0xe2, 0x59,
+            0x8e, 0x6f, 0xf8, 0x9d, 0x19, 0xf1, 0x05, 0xac, 0xc2, 0xd3,
+            0xf0, 0xcb, 0x35, 0xf2, 0x92, 0x80, 0xe1, 0x38, 0x6b, 0x6f,
+            0x64, 0xc4, 0xef, 0x22, 0xe1, 0xe1, 0xf2, 0x0d, 0x0c, 0xe8,
+            0xcf, 0xfb, 0x22, 0x49, 0xbd, 0x9a, 0x21, 0x37 },
+        128,
+        (unsigned char[]){ 0x01, 0x00, 0x01 }, 3,
+        (unsigned char[]){
+            0x33, 0xa5, 0x04, 0x2a, 0x90, 0xb2, 0x7d, 0x4f, 0x54, 0x51,
+            0xca, 0x9b, 0xbb, 0xd0, 0xb4, 0x47, 0x71, 0xa1, 0x01, 0xaf,
+            0x88, 0x43, 0x40, 0xae, 0xf9, 0x88, 0x5f, 0x2a, 0x4b, 0xbe,
+            0x92, 0xe8, 0x94, 0xa7, 0x24, 0xac, 0x3c, 0x56, 0x8c, 0x8f,
+            0x97, 0x85, 0x3a, 0xd0, 0x7c, 0x02, 0x66, 0xc8, 0xc6, 0xa3,
+            0xca, 0x09, 0x29, 0xf1, 0xe8, 0xf1, 0x12, 0x31, 0x88, 0x44,
+            0x29, 0xfc, 0x4d, 0x9a, 0xe5, 0x5f, 0xee, 0x89, 0x6a, 0x10,
+            0xce, 0x70, 0x7c, 0x3e, 0xd7, 0xe7, 0x34, 0xe4, 0x47, 0x27,
+            0xa3, 0x95, 0x74, 0x50, 0x1a, 0x53, 0x26, 0x83, 0x10, 0x9c,
+            0x2a, 0xba, 0xca, 0xba, 0x28, 0x3c, 0x31, 0xb4, 0xbd, 0x2f,
+            0x53, 0xc3, 0xee, 0x37, 0xe3, 0x52, 0xce, 0xe3, 0x4f, 0x9e,
+            0x50, 0x3b, 0xd8, 0x0c, 0x06, 0x22, 0xad, 0x79, 0xc6, 0xdc,
+            0xee, 0x88, 0x35, 0x47, 0xc6, 0xa3, 0xb3, 0x25 },
+        128,
+        (unsigned char[]){
+            0xb6, 0x9d, 0xca, 0x1c, 0xf7, 0xd4, 0xd7, 0xec, 0x81, 0xe7,
+            0x5b, 0x90, 0xfc, 0xca, 0x87, 0x4a, 0xbc, 0xde, 0x12, 0x3f,
+            0xd2, 0x70, 0x01, 0x80, 0xaa, 0x90, 0x47, 0x9b, 0x6e, 0x48,
+            0xde, 0x8d, 0x67, 0xed, 0x24, 0xf9, 0xf1, 0x9d, 0x85, 0xba,
+            0x27, 0x58, 0x74, 0xf5, 0x42, 0xcd, 0x20, 0xdc, 0x72, 0x3e,
+            0x69, 0x63, 0x36, 0x4a, 0x1f, 0x94, 0x25, 0x45, 0x2b, 0x26,
+            0x9a, 0x67, 0x99, 0xfd },
+        64,
+        (unsigned char[]){
+            0xe7, 0xe8, 0x94, 0x27, 0x20, 0xa8, 0x77, 0x51, 0x72, 0x73,
+            0xa3, 0x56, 0x05, 0x3e, 0xa2, 0xa1, 0xbc, 0x0c, 0x94, 0xaa,
+            0x72, 0xd5, 0x5c, 0x6e, 0x86, 0x29, 0x6b, 0x2d, 0xfc, 0x96,
+            0x79, 0x48, 0xc0, 0xa7, 0x2c, 0xbc, 0xcc, 0xa7, 0xea, 0xcb,
+            0x35, 0x70, 0x6e, 0x09, 0xa1, 0xdf, 0x55, 0xa1, 0x53, 0x5b,
+            0xd9, 0xb3, 0xcc, 0x34, 0x16, 0x0b, 0x3b, 0x6d, 0xcd, 0x3e,
+            0xda, 0x8e, 0x64, 0x43 },
+        64,
+    },
+    {
+        (unsigned char[]){
+            0xa5, 0x6e, 0x4a, 0x0e, 0x70, 0x10, 0x17, 0x58, 0x9a, 0x51,
+            0x87, 0xdc, 0x7e, 0xa8, 0x41, 0xd1, 0x56, 0xf2, 0xec, 0x0e,
+            0x36, 0xad, 0x52, 0xa4, 0x4d, 0xfe, 0xb1, 0xe6, 0x1f, 0x7a,
+            0xd9, 0x91, 0xd8, 0xc5, 0x10, 0x56, 0xff, 0xed, 0xb1, 0x62,
+            0xb4, 0xc0, 0xf2, 0x83, 0xa1, 0x2a, 0x88, 0xa3, 0x94, 0xdf,
+            0xf5, 0x26, 0xab, 0x72, 0x91, 0xcb, 0xb3, 0x07, 0xce, 0xab,
+            0xfc, 0xe0, 0xb1, 0xdf, 0xd5, 0xcd, 0x95, 0x08, 0x09, 0x6d,
+            0x5b, 0x2b, 0x8b, 0x6d, 0xf5, 0xd6, 0x71, 0xef, 0x63, 0x77,
+            0xc0, 0x92, 0x1c, 0xb2, 0x3c, 0x27, 0x0a, 0x70, 0xe2, 0x59,
+            0x8e, 0x6f, 0xf8, 0x9d, 0x19, 0xf1, 0x05, 0xac, 0xc2, 0xd3,
+            0xf0, 0xcb, 0x35, 0xf2, 0x92, 0x80, 0xe1, 0x38, 0x6b, 0x6f,
+            0x64, 0xc4, 0xef, 0x22, 0xe1, 0xe1, 0xf2, 0x0d, 0x0c, 0xe8,
+            0xcf, 0xfb, 0x22, 0x49, 0xbd, 0x9a, 0x21, 0x37 },
+        128,
+        (unsigned char[]){ 0x01, 0x00, 0x01 }, 3,
+        (unsigned char[]){
+            0x33, 0xa5, 0x04, 0x2a, 0x90, 0xb2, 0x7d, 0x4f, 0x54, 0x51,
+            0xca, 0x9b, 0xbb, 0xd0, 0xb4, 0x47, 0x71, 0xa1, 0x01, 0xaf,
+            0x88, 0x43, 0x40, 0xae, 0xf9, 0x88, 0x5f, 0x2a, 0x4b, 0xbe,
+            0x92, 0xe8, 0x94, 0xa7, 0x24, 0xac, 0x3c, 0x56, 0x8c, 0x8f,
+            0x97, 0x85, 0x3a, 0xd0, 0x7c, 0x02, 0x66, 0xc8, 0xc6, 0xa3,
+            0xca, 0x09, 0x29, 0xf1, 0xe8, 0xf1, 0x12, 0x31, 0x88, 0x44,
+            0x29, 0xfc, 0x4d, 0x9a, 0xe5, 0x5f, 0xee, 0x89, 0x6a, 0x10,
+            0xce, 0x70, 0x7c, 0x3e, 0xd7, 0xe7, 0x34, 0xe4, 0x47, 0x27,
+            0xa3, 0x95, 0x74, 0x50, 0x1a, 0x53, 0x26, 0x83, 0x10, 0x9c,
+            0x2a, 0xba, 0xca, 0xba, 0x28, 0x3c, 0x31, 0xb4, 0xbd, 0x2f,
+            0x53, 0xc3, 0xee, 0x37, 0xe3, 0x52, 0xce, 0xe3, 0x4f, 0x9e,
+            0x50, 0x3b, 0xd8, 0x0c, 0x06, 0x22, 0xad, 0x79, 0xc6, 0xdc,
+            0xee, 0x88, 0x35, 0x47, 0xc6, 0xa3, 0xb3, 0x25 },
+        128,
+        (unsigned char[]){
+            0xb6, 0x9d, 0xca, 0x1c, 0xf7, 0xd4, 0xd7, 0xec, 0x81, 0xe7,
+            0x5b, 0x90, 0xfc, 0xca, 0x87, 0x4a, 0xbc, 0xde, 0x12, 0x3f,
+            0xd2, 0x70, 0x01, 0x80, 0xaa, 0x90, 0x47, 0x9b, 0x6e, 0x48,
+            0xde, 0x8d, 0x67, 0xed, 0x24, 0xf9, 0xf1, 0x9d, 0x85, 0xba,
+            0x27, 0x58, 0x74, 0xf5, 0x42, 0xcd, 0x20, 0xdc, 0x72, 0x3e,
+            0x69, 0x63, 0x36, 0x4a, 0x1f, 0x94, 0x25, 0x45, 0x2b, 0x26,
+            0x9a, 0x67, 0x99, 0xfd },
+        64,
+        (unsigned char[]){
+            0xe7, 0xe8, 0x94, 0x27, 0x20, 0xa8, 0x77, 0x51, 0x72, 0x73,
+            0xa3, 0x56, 0x05, 0x3e, 0xa2, 0xa1, 0xbc, 0x0c, 0x94, 0xaa,
+            0x72, 0xd5, 0x5c, 0x6e, 0x86, 0x29, 0x6b, 0x2d, 0xfc, 0x96,
+            0x79, 0x48, 0xc0, 0xa7, 0x2c, 0xbc, 0xcc, 0xa7, 0xea, 0xcb,
+            0x35, 0x70, 0x6e, 0x09, 0xa1, 0xdf, 0x55, 0xa1, 0x53, 0x5b,
+            0xd9, 0xb3, 0xcc, 0x34, 0x16, 0x0b, 0x3b, 0x6d, 0xcd, 0x3e,
+            0xda, 0x8e, 0x64, 0x43 },
+        64,
+    },
+    {
+        (unsigned char[]){
+            0xa5, 0x6e, 0x4a, 0x0e, 0x70, 0x10, 0x17, 0x58, 0x9a, 0x51,
+            0x87, 0xdc, 0x7e, 0xa8, 0x41, 0xd1, 0x56, 0xf2, 0xec, 0x0e,
+            0x36, 0xad, 0x52, 0xa4, 0x4d, 0xfe, 0xb1, 0xe6, 0x1f, 0x7a,
+            0xd9, 0x91, 0xd8, 0xc5, 0x10, 0x56, 0xff, 0xed, 0xb1, 0x62,
+            0xb4, 0xc0, 0xf2, 0x83, 0xa1, 0x2a, 0x88, 0xa3, 0x94, 0xdf,
+            0xf5, 0x26, 0xab, 0x72, 0x91, 0xcb, 0xb3, 0x07, 0xce, 0xab,
+            0xfc, 0xe0, 0xb1, 0xdf, 0xd5, 0xcd, 0x95, 0x08, 0x09, 0x6d,
+            0x5b, 0x2b, 0x8b, 0x6d, 0xf5, 0xd6, 0x71, 0xef, 0x63, 0x77,
+            0xc0, 0x92, 0x1c, 0xb2, 0x3c, 0x27, 0x0a, 0x70, 0xe2, 0x59,
+            0x8e, 0x6f, 0xf8, 0x9d, 0x19, 0xf1, 0x05, 0xac, 0xc2, 0xd3,
+            0xf0, 0xcb, 0x35, 0xf2, 0x92, 0x80, 0xe1, 0x38, 0x6b, 0x6f,
+            0x64, 0xc4, 0xef, 0x22, 0xe1, 0xe1, 0xf2, 0x0d, 0x0c, 0xe8,
+            0xcf, 0xfb, 0x22, 0x49, 0xbd, 0x9a, 0x21, 0x37 },
+        128,
+        (unsigned char[]){ 0x01, 0x00, 0x01 }, 3,
+        (unsigned char[]){
+            0x33, 0xa5, 0x04, 0x2a, 0x90, 0xb2, 0x7d, 0x4f, 0x54, 0x51,
+            0xca, 0x9b, 0xbb, 0xd0, 0xb4, 0x47, 0x71, 0xa1, 0x01, 0xaf,
+            0x88, 0x43, 0x40, 0xae, 0xf9, 0x88, 0x5f, 0x2a, 0x4b, 0xbe,
+            0x92, 0xe8, 0x94, 0xa7, 0x24, 0xac, 0x3c, 0x56, 0x8c, 0x8f,
+            0x97, 0x85, 0x3a, 0xd0, 0x7c, 0x02, 0x66, 0xc8, 0xc6, 0xa3,
+            0xca, 0x09, 0x29, 0xf1, 0xe8, 0xf1, 0x12, 0x31, 0x88, 0x44,
+            0x29, 0xfc, 0x4d, 0x9a, 0xe5, 0x5f, 0xee, 0x89, 0x6a, 0x10,
+            0xce, 0x70, 0x7c, 0x3e, 0xd7, 0xe7, 0x34, 0xe4, 0x47, 0x27,
+            0xa3, 0x95, 0x74, 0x50, 0x1a, 0x53, 0x26, 0x83, 0x10, 0x9c,
+            0x2a, 0xba, 0xca, 0xba, 0x28, 0x3c, 0x31, 0xb4, 0xbd, 0x2f,
+            0x53, 0xc3, 0xee, 0x37, 0xe3, 0x52, 0xce, 0xe3, 0x4f, 0x9e,
+            0x50, 0x3b, 0xd8, 0x0c, 0x06, 0x22, 0xad, 0x79, 0xc6, 0xdc,
+            0xee, 0x88, 0x35, 0x47, 0xc6, 0xa3, 0xb3, 0x25 },
+        128,
+        (unsigned char[]){
+            0xb6, 0x9d, 0xca, 0x1c, 0xf7, 0xd4, 0xd7, 0xec, 0x81, 0xe7,
+            0x5b, 0x90, 0xfc, 0xca, 0x87, 0x4a, 0xbc, 0xde, 0x12, 0x3f,
+            0xd2, 0x70, 0x01, 0x80, 0xaa, 0x90, 0x47, 0x9b, 0x6e, 0x48,
+            0xde, 0x8d, 0x67, 0xed, 0x24, 0xf9, 0xf1, 0x9d, 0x85, 0xba,
+            0x27, 0x58, 0x74, 0xf5, 0x42, 0xcd, 0x20, 0xdc, 0x72, 0x3e,
+            0x69, 0x63, 0x36, 0x4a, 0x1f, 0x94, 0x25, 0x45, 0x2b, 0x26,
+            0x9a, 0x67, 0x99, 0xfd },
+        64,
+        (unsigned char[]){
+            0xe7, 0xe8, 0x94, 0x27, 0x20, 0xa8, 0x77, 0x51, 0x72, 0x73,
+            0xa3, 0x56, 0x05, 0x3e, 0xa2, 0xa1, 0xbc, 0x0c, 0x94, 0xaa,
+            0x72, 0xd5, 0x5c, 0x6e, 0x86, 0x29, 0x6b, 0x2d, 0xfc, 0x96,
+            0x79, 0x48, 0xc0, 0xa7, 0x2c, 0xbc, 0xcc, 0xa7, 0xea, 0xcb,
+            0x35, 0x70, 0x6e, 0x09, 0xa1, 0xdf, 0x55, 0xa1, 0x53, 0x5b,
+            0xd9, 0xb3, 0xcc, 0x34, 0x16, 0x0b, 0x3b, 0x6d, 0xcd, 0x3e,
+            0xda, 0x8e, 0x64, 0x43 },
+        64,
+    },
+    {
+        (unsigned char[]){
+            0xa5, 0x6e, 0x4a, 0x0e, 0x70, 0x10, 0x17, 0x58, 0x9a, 0x51,
+            0x87, 0xdc, 0x7e, 0xa8, 0x41, 0xd1, 0x56, 0xf2, 0xec, 0x0e,
+            0x36, 0xad, 0x52, 0xa4, 0x4d, 0xfe, 0xb1, 0xe6, 0x1f, 0x7a,
+            0xd9, 0x91, 0xd8, 0xc5, 0x10, 0x56, 0xff, 0xed, 0xb1, 0x62,
+            0xb4, 0xc0, 0xf2, 0x83, 0xa1, 0x2a, 0x88, 0xa3, 0x94, 0xdf,
+            0xf5, 0x26, 0xab, 0x72, 0x91, 0xcb, 0xb3, 0x07, 0xce, 0xab,
+            0xfc, 0xe0, 0xb1, 0xdf, 0xd5, 0xcd, 0x95, 0x08, 0x09, 0x6d,
+            0x5b, 0x2b, 0x8b, 0x6d, 0xf5, 0xd6, 0x71, 0xef, 0x63, 0x77,
+            0xc0, 0x92, 0x1c, 0xb2, 0x3c, 0x27, 0x0a, 0x70, 0xe2, 0x59,
+            0x8e, 0x6f, 0xf8, 0x9d, 0x19, 0xf1, 0x05, 0xac, 0xc2, 0xd3,
+            0xf0, 0xcb, 0x35, 0xf2, 0x92, 0x80, 0xe1, 0x38, 0x6b, 0x6f,
+            0x64, 0xc4, 0xef, 0x22, 0xe1, 0xe1, 0xf2, 0x0d, 0x0c, 0xe8,
+            0xcf, 0xfb, 0x22, 0x49, 0xbd, 0x9a, 0x21, 0x37 },
+        128,
+        (unsigned char[]){ 0x01, 0x00, 0x01 }, 3,
+        (unsigned char[]){
+            0x33, 0xa5, 0x04, 0x2a, 0x90, 0xb2, 0x7d, 0x4f, 0x54, 0x51,
+            0xca, 0x9b, 0xbb, 0xd0, 0xb4, 0x47, 0x71, 0xa1, 0x01, 0xaf,
+            0x88, 0x43, 0x40, 0xae, 0xf9, 0x88, 0x5f, 0x2a, 0x4b, 0xbe,
+            0x92, 0xe8, 0x94, 0xa7, 0x24, 0xac, 0x3c, 0x56, 0x8c, 0x8f,
+            0x97, 0x85, 0x3a, 0xd0, 0x7c, 0x02, 0x66, 0xc8, 0xc6, 0xa3,
+            0xca, 0x09, 0x29, 0xf1, 0xe8, 0xf1, 0x12, 0x31, 0x88, 0x44,
+            0x29, 0xfc, 0x4d, 0x9a, 0xe5, 0x5f, 0xee, 0x89, 0x6a, 0x10,
+            0xce, 0x70, 0x7c, 0x3e, 0xd7, 0xe7, 0x34, 0xe4, 0x47, 0x27,
+            0xa3, 0x95, 0x74, 0x50, 0x1a, 0x53, 0x26, 0x83, 0x10, 0x9c,
+            0x2a, 0xba, 0xca, 0xba, 0x28, 0x3c, 0x31, 0xb4, 0xbd, 0x2f,
+            0x53, 0xc3, 0xee, 0x37, 0xe3, 0x52, 0xce, 0xe3, 0x4f, 0x9e,
+            0x50, 0x3b, 0xd8, 0x0c, 0x06, 0x22, 0xad, 0x79, 0xc6, 0xdc,
+            0xee, 0x88, 0x35, 0x47, 0xc6, 0xa3, 0xb3, 0x25 },
+        128,
+        (unsigned char[]){
+            0xb6, 0x9d, 0xca, 0x1c, 0xf7, 0xd4, 0xd7, 0xec, 0x81, 0xe7,
+            0x5b, 0x90, 0xfc, 0xca, 0x87, 0x4a, 0xbc, 0xde, 0x12, 0x3f,
+            0xd2, 0x70, 0x01, 0x80, 0xaa, 0x90, 0x47, 0x9b, 0x6e, 0x48,
+            0xde, 0x8d, 0x67, 0xed, 0x24, 0xf9, 0xf1, 0x9d, 0x85, 0xba,
+            0x27, 0x58, 0x74, 0xf5, 0x42, 0xcd, 0x20, 0xdc, 0x72, 0x3e,
+            0x69, 0x63, 0x36, 0x4a, 0x1f, 0x94, 0x25, 0x45, 0x2b, 0x26,
+            0x9a, 0x67, 0x99, 0xfd },
+        64,
+        (unsigned char[]){
+            0xe7, 0xe8, 0x94, 0x27, 0x20, 0xa8, 0x77, 0x51, 0x72, 0x73,
+            0xa3, 0x56, 0x05, 0x3e, 0xa2, 0xa1, 0xbc, 0x0c, 0x94, 0xaa,
+            0x72, 0xd5, 0x5c, 0x6e, 0x86, 0x29, 0x6b, 0x2d, 0xfc, 0x96,
+            0x79, 0x48, 0xc0, 0xa7, 0x2c, 0xbc, 0xcc, 0xa7, 0xea, 0xcb,
+            0x35, 0x70, 0x6e, 0x09, 0xa1, 0xdf, 0x55, 0xa1, 0x53, 0x5b,
+            0xd9, 0xb3, 0xcc, 0x34, 0x16, 0x0b, 0x3b, 0x6d, 0xcd, 0x3e,
+            0xda, 0x8e, 0x64, 0x43 },
+        64,
+    },
+    {
+        (unsigned char[]){
+            0xa5, 0x6e, 0x4a, 0x0e, 0x70, 0x10, 0x17, 0x58, 0x9a, 0x51,
+            0x87, 0xdc, 0x7e, 0xa8, 0x41, 0xd1, 0x56, 0xf2, 0xec, 0x0e,
+            0x36, 0xad, 0x52, 0xa4, 0x4d, 0xfe, 0xb1, 0xe6, 0x1f, 0x7a,
+            0xd9, 0x91, 0xd8, 0xc5, 0x10, 0x56, 0xff, 0xed, 0xb1, 0x62,
+            0xb4, 0xc0, 0xf2, 0x83, 0xa1, 0x2a, 0x88, 0xa3, 0x94, 0xdf,
+            0xf5, 0x26, 0xab, 0x72, 0x91, 0xcb, 0xb3, 0x07, 0xce, 0xab,
+            0xfc, 0xe0, 0xb1, 0xdf, 0xd5, 0xcd, 0x95, 0x08, 0x09, 0x6d,
+            0x5b, 0x2b, 0x8b, 0x6d, 0xf5, 0xd6, 0x71, 0xef, 0x63, 0x77,
+            0xc0, 0x92, 0x1c, 0xb2, 0x3c, 0x27, 0x0a, 0x70, 0xe2, 0x59,
+            0x8e, 0x6f, 0xf8, 0x9d, 0x19, 0xf1, 0x05, 0xac, 0xc2, 0xd3,
+            0xf0, 0xcb, 0x35, 0xf2, 0x92, 0x80, 0xe1, 0x38, 0x6b, 0x6f,
+            0x64, 0xc4, 0xef, 0x22, 0xe1, 0xe1, 0xf2, 0x0d, 0x0c, 0xe8,
+            0xcf, 0xfb, 0x22, 0x49, 0xbd, 0x9a, 0x21, 0x37 },
+        128,
+        (unsigned char[]){ 0x01, 0x00, 0x01 }, 3,
+        (unsigned char[]){
+            0x33, 0xa5, 0x04, 0x2a, 0x90, 0xb2, 0x7d, 0x4f, 0x54, 0x51,
+            0xca, 0x9b, 0xbb, 0xd0, 0xb4, 0x47, 0x71, 0xa1, 0x01, 0xaf,
+            0x88, 0x43, 0x40, 0xae, 0xf9, 0x88, 0x5f, 0x2a, 0x4b, 0xbe,
+            0x92, 0xe8, 0x94, 0xa7, 0x24, 0xac, 0x3c, 0x56, 0x8c, 0x8f,
+            0x97, 0x85, 0x3a, 0xd0, 0x7c, 0x02, 0x66, 0xc8, 0xc6, 0xa3,
+            0xca, 0x09, 0x29, 0xf1, 0xe8, 0xf1, 0x12, 0x31, 0x88, 0x44,
+            0x29, 0xfc, 0x4d, 0x9a, 0xe5, 0x5f, 0xee, 0x89, 0x6a, 0x10,
+            0xce, 0x70, 0x7c, 0x3e, 0xd7, 0xe7, 0x34, 0xe4, 0x47, 0x27,
+            0xa3, 0x95, 0x74, 0x50, 0x1a, 0x53, 0x26, 0x83, 0x10, 0x9c,
+            0x2a, 0xba, 0xca, 0xba, 0x28, 0x3c, 0x31, 0xb4, 0xbd, 0x2f,
+            0x53, 0xc3, 0xee, 0x37, 0xe3, 0x52, 0xce, 0xe3, 0x4f, 0x9e,
+            0x50, 0x3b, 0xd8, 0x0c, 0x06, 0x22, 0xad, 0x79, 0xc6, 0xdc,
+            0xee, 0x88, 0x35, 0x47, 0xc6, 0xa3, 0xb3, 0x25 },
+        128,
+        (unsigned char[]){
+            0xb6, 0x9d, 0xca, 0x1c, 0xf7, 0xd4, 0xd7, 0xec, 0x81, 0xe7,
+            0x5b, 0x90, 0xfc, 0xca, 0x87, 0x4a, 0xbc, 0xde, 0x12, 0x3f,
+            0xd2, 0x70, 0x01, 0x80, 0xaa, 0x90, 0x47, 0x9b, 0x6e, 0x48,
+            0xde, 0x8d, 0x67, 0xed, 0x24, 0xf9, 0xf1, 0x9d, 0x85, 0xba,
+            0x27, 0x58, 0x74, 0xf5, 0x42, 0xcd, 0x20, 0xdc, 0x72, 0x3e,
+            0x69, 0x63, 0x36, 0x4a, 0x1f, 0x94, 0x25, 0x45, 0x2b, 0x26,
+            0x9a, 0x67, 0x99, 0xfd },
+        64,
+        (unsigned char[]){
+            0xe7, 0xe8, 0x94, 0x27, 0x20, 0xa8, 0x77, 0x51, 0x72, 0x73,
+            0xa3, 0x56, 0x05, 0x3e, 0xa2, 0xa1, 0xbc, 0x0c, 0x94, 0xaa,
+            0x72, 0xd5, 0x5c, 0x6e, 0x86, 0x29, 0x6b, 0x2d, 0xfc, 0x96,
+            0x79, 0x48, 0xc0, 0xa7, 0x2c, 0xbc, 0xcc, 0xa7, 0xea, 0xcb,
+            0x35, 0x70, 0x6e, 0x09, 0xa1, 0xdf, 0x55, 0xa1, 0x53, 0x5b,
+            0xd9, 0xb3, 0xcc, 0x34, 0x16, 0x0b, 0x3b, 0x6d, 0xcd, 0x3e,
+            0xda, 0x8e, 0x64, 0x43 },
+        64,
+    },
+    {
+        (unsigned char[]){
+            0xa5, 0x6e, 0x4a, 0x0e, 0x70, 0x10, 0x17, 0x58, 0x9a, 0x51,
+            0x87, 0xdc, 0x7e, 0xa8, 0x41, 0xd1, 0x56, 0xf2, 0xec, 0x0e,
+            0x36, 0xad, 0x52, 0xa4, 0x4d, 0xfe, 0xb1, 0xe6, 0x1f, 0x7a,
+            0xd9, 0x91, 0xd8, 0xc5, 0x10, 0x56, 0xff, 0xed, 0xb1, 0x62,
+            0xb4, 0xc0, 0xf2, 0x83, 0xa1, 0x2a, 0x88, 0xa3, 0x94, 0xdf,
+            0xf5, 0x26, 0xab, 0x72, 0x91, 0xcb, 0xb3, 0x07, 0xce, 0xab,
+            0xfc, 0xe0, 0xb1, 0xdf, 0xd5, 0xcd, 0x95, 0x08, 0x09, 0x6d,
+            0x5b, 0x2b, 0x8b, 0x6d, 0xf5, 0xd6, 0x71, 0xef, 0x63, 0x77,
+            0xc0, 0x92, 0x1c, 0xb2, 0x3c, 0x27, 0x0a, 0x70, 0xe2, 0x59,
+            0x8e, 0x6f, 0xf8, 0x9d, 0x19, 0xf1, 0x05, 0xac, 0xc2, 0xd3,
+            0xf0, 0xcb, 0x35, 0xf2, 0x92, 0x80, 0xe1, 0x38, 0x6b, 0x6f,
+            0x64, 0xc4, 0xef, 0x22, 0xe1, 0xe1, 0xf2, 0x0d, 0x0c, 0xe8,
+            0xcf, 0xfb, 0x22, 0x49, 0xbd, 0x9a, 0x21, 0x37 },
+        128,
+        (unsigned char[]){ 0x01, 0x00, 0x01 }, 3,
+        (unsigned char[]){
+            0x33, 0xa5, 0x04, 0x2a, 0x90, 0xb2, 0x7d, 0x4f, 0x54, 0x51,
+            0xca, 0x9b, 0xbb, 0xd0, 0xb4, 0x47, 0x71, 0xa1, 0x01, 0xaf,
+            0x88, 0x43, 0x40, 0xae, 0xf9, 0x88,
+            0x5f, 0x2a, 0x4b, 0xbe, 0x92, 0xe8, 0x94, 0xa7, 0x24, 0xac,
+
+            0x3c, 0x56, 0x8c, 0x8f, 0x97, 0x85, 0x3a, 0xd0, 0x7c, 0x02,
+
+            0x66, 0xc8, 0xc6, 0xa3, 0xca, 0x09, 0x29, 0xf1, 0xe8, 0xf1,
+            0x12, 0x31, 0x88, 0x44, 0x29, 0xfc, 0x4d, 0x9a, 0xe5, 0x5f,
+            0xee, 0x89, 0x6a, 0x10, 0xce, 0x70, 0x7c, 0x3e, 0xd7, 0xe7,
+            0x34, 0xe4, 0x47, 0x27, 0xa3, 0x95, 0x74, 0x50, 0x1a, 0x53,
+            0x26, 0x83, 0x10, 0x9c, 0x2a, 0xba, 0xca, 0xba, 0x28, 0x3c,
+            0x31, 0xb4, 0xbd, 0x2f, 0x53, 0xc3, 0xee, 0x37, 0xe3, 0x52,
+            0xce, 0xe3, 0x4f, 0x9e, 0x50, 0x3b, 0xd8, 0x0c, 0x06, 0x22,
+            0xad, 0x79, 0xc6, 0xdc, 0xee, 0x88, 0x35, 0x47, 0xc6, 0xa3,
+            0xb3, 0x25 },
+        128,
+        (unsigned char[]){
+            0xb6, 0x9d, 0xca, 0x1c, 0xf7, 0xd4, 0xd7, 0xec, 0x81, 0xe7,
+            0x5b, 0x90, 0xfc, 0xca, 0x87, 0x4a, 0xbc, 0xde, 0x12, 0x3f,
+            0xd2, 0x70, 0x01, 0x80, 0xaa, 0x90, 0x47, 0x9b, 0x6e, 0x48,
+            0xde, 0x8d, 0x67, 0xed, 0x24, 0xf9, 0xf1, 0x9d, 0x85, 0xba,
+            0x27, 0x58, 0x74, 0xf5, 0x42, 0xcd, 0x20, 0xdc, 0x72, 0x3e,
+            0x69, 0x63, 0x36, 0x4a, 0x1f, 0x94, 0x25, 0x45, 0x2b, 0x26,
+            0x9a, 0x67, 0x99, 0xfd },
+        64,
+        (unsigned char[]){
+            0xe7, 0xe8, 0x94, 0x27, 0x20, 0xa8, 0x77, 0x51, 0x72, 0x73,
+            0xa3, 0x56, 0x05, 0x3e, 0xa2, 0xa1, 0xbc, 0x0c, 0x94, 0xaa,
+            0x72, 0xd5, 0x5c, 0x6e, 0x86, 0x29, 0x6b, 0x2d, 0xfc, 0x96,
+            0x79, 0x48, 0xc0, 0xa7, 0x2c, 0xbc, 0xcc, 0xa7, 0xea, 0xcb,
+            0x35, 0x70, 0x6e, 0x09, 0xa1, 0xdf, 0x55, 0xa1, 0x53, 0x5b,
+            0xd9, 0xb3, 0xcc, 0x34, 0x16, 0x0b, 0x3b, 0x6d, 0xcd, 0x3e,
+            0xda, 0x8e, 0x64, 0x43 },
+        64,
+    },
+    {
+        (unsigned char[]){
+            0xa5, 0x6e, 0x4a, 0x0e, 0x70, 0x10, 0x17, 0x58, 0x9a, 0x51,
+            0x87, 0xdc, 0x7e, 0xa8, 0x41, 0xd1, 0x56, 0xf2, 0xec, 0x0e,
+            0x36, 0xad, 0x52, 0xa4, 0x4d, 0xfe, 0xb1, 0xe6, 0x1f, 0x7a,
+            0xd9, 0x91, 0xd8, 0xc5, 0x10, 0x56, 0xff, 0xed, 0xb1, 0x62,
+            0xb4, 0xc0, 0xf2, 0x83, 0xa1, 0x2a, 0x88, 0xa3, 0x94, 0xdf,
+            0xf5, 0x26, 0xab, 0x72, 0x91, 0xcb, 0xb3, 0x07, 0xce, 0xab,
+            0xfc, 0xe0, 0xb1, 0xdf, 0xd5, 0xcd, 0x95, 0x08, 0x09, 0x6d,
+            0x5b, 0x2b, 0x8b, 0x6d, 0xf5, 0xd6, 0x71, 0xef, 0x63, 0x77,
+            0xc0, 0x92, 0x1c, 0xb2, 0x3c, 0x27, 0x0a, 0x70, 0xe2, 0x59,
+            0x8e, 0x6f, 0xf8, 0x9d, 0x19, 0xf1, 0x05, 0xac, 0xc2, 0xd3,
+            0xf0, 0xcb, 0x35, 0xf2, 0x92, 0x80, 0xe1, 0x38, 0x6b, 0x6f,
+            0x64, 0xc4, 0xef, 0x22, 0xe1, 0xe1, 0xf2, 0x0d, 0x0c, 0xe8,
+            0xcf, 0xfb, 0x22, 0x49, 0xbd, 0x9a, 0x21, 0x37 },
+        128,
+        (unsigned char[]){ 0x01, 0x00, 0x01 }, 3,
+        (unsigned char[]){
+            0x33, 0xa5, 0x04, 0x2a, 0x90, 0xb2, 0x7d, 0x4f, 0x54, 0x51,
+            0xca, 0x9b, 0xbb, 0xd0, 0xb4, 0x47, 0x71, 0xa1, 0x01, 0xaf,
+            0x88, 0x43, 0x40, 0xae, 0xf9, 0x88, 0x5f, 0x2a, 0x4b, 0xbe,
+            0x92, 0xe8, 0x94, 0xa7, 0x24, 0xac, 0x3c, 0x56, 0x8c, 0x8f,
+            0x97, 0x85, 0x3a, 0xd0, 0x7c, 0x02, 0x66, 0xc8, 0xc6, 0xa3,
+            0xca, 0x09, 0x29, 0xf1, 0xe8, 0xf1, 0x12, 0x31, 0x88, 0x44,
+            0x29, 0xfc, 0x4d, 0x9a, 0xe5, 0x5f, 0xee, 0x89, 0x6a, 0x10,
+            0xce, 0x70, 0x7c, 0x3e, 0xd7, 0xe7, 0x34, 0xe4, 0x47, 0x27,
+            0xa3, 0x95, 0x74, 0x50, 0x1a, 0x53, 0x26, 0x83, 0x10, 0x9c,
+            0x2a, 0xba, 0xca, 0xba, 0x28, 0x3c, 0x31, 0xb4, 0xbd, 0x2f,
+            0x53, 0xc3, 0xee, 0x37, 0xe3, 0x52, 0xce, 0xe3, 0x4f, 0x9e,
+            0x50, 0x3b, 0xd8, 0x0c, 0x06, 0x22, 0xad, 0x79, 0xc6, 0xdc,
+            0xee, 0x88, 0x35, 0x47, 0xc6, 0xa3, 0xb3, 0x25 },
+        128,
+        (unsigned char[]){
+            0xb6, 0x9d, 0xca, 0x1c, 0xf7, 0xd4, 0xd7, 0xec, 0x81, 0xe7,
+            0x5b, 0x90, 0xfc, 0xca, 0x87, 0x4a, 0xbc, 0xde, 0x12, 0x3f,
+            0xd2, 0x70, 0x01, 0x80, 0xaa, 0x90, 0x47, 0x9b, 0x6e, 0x48,
+            0xde, 0x8d, 0x67, 0xed, 0x24, 0xf9, 0xf1, 0x9d, 0x85, 0xba,
+            0x27, 0x58, 0x74, 0xf5, 0x42, 0xcd, 0x20, 0xdc, 0x72, 0x3e,
+            0x69, 0x63, 0x36, 0x4a, 0x1f, 0x94, 0x25, 0x45, 0x2b, 0x26,
+            0x9a, 0x67, 0x99, 0xfd },
+        64,
+        (unsigned char[]){
+            0xe7, 0xe8, 0x94, 0x27, 0x20, 0xa8, 0x77, 0x51, 0x72, 0x73,
+            0xa3, 0x56, 0x05, 0x3e, 0xa2, 0xa1, 0xbc, 0x0c, 0x94, 0xaa,
+            0x72, 0xd5, 0x5c, 0x6e, 0x86, 0x29, 0x6b, 0x2d, 0xfc, 0x96,
+            0x79, 0x48, 0xc0, 0xa7, 0x2c, 0xbc, 0xcc, 0xa7, 0xea, 0xcb,
+            0x35, 0x70, 0x6e, 0x09, 0xa1, 0xdf, 0x55, 0xa1, 0x53, 0x5b,
+            0xd9, 0xb3, 0xcc, 0x34, 0x16, 0x0b, 0x3b, 0x6d, 0xcd, 0x3e,
+            0xda, 0x8e, 0x64, 0x43 },
+        64,
+    },
+    {
+        (unsigned char[]){
+            0xa5, 0x6e, 0x4a, 0x0e, 0x70, 0x10, 0x17, 0x58, 0x9a, 0x51,
+            0x87, 0xdc, 0x7e, 0xa8, 0x41, 0xd1, 0x56, 0xf2, 0xec, 0x0e,
+            0x36, 0xad, 0x52, 0xa4, 0x4d, 0xfe, 0xb1, 0xe6, 0x1f, 0x7a,
+            0xd9, 0x91, 0xd8, 0xc5, 0x10, 0x56, 0xff, 0xed, 0xb1, 0x62,
+            0xb4, 0xc0, 0xf2, 0x83, 0xa1, 0x2a, 0x88, 0xa3, 0x94, 0xdf,
+            0xf5, 0x26, 0xab, 0x72, 0x91, 0xcb, 0xb3, 0x07, 0xce, 0xab,
+            0xfc, 0xe0, 0xb1, 0xdf, 0xd5, 0xcd, 0x95, 0x08, 0x09, 0x6d,
+            0x5b, 0x2b, 0x8b, 0x6d, 0xf5, 0xd6, 0x71, 0xef, 0x63, 0x77,
+            0xc0, 0x92, 0x1c, 0xb2, 0x3c, 0x27, 0x0a, 0x70, 0xe2, 0x59,
+            0x8e, 0x6f, 0xf8, 0x9d, 0x19, 0xf1, 0x05, 0xac, 0xc2, 0xd3,
+            0xf0, 0xcb, 0x35, 0xf2, 0x92, 0x80, 0xe1, 0x38, 0x6b, 0x6f,
+            0x64, 0xc4, 0xef, 0x22, 0xe1, 0xe1, 0xf2, 0x0d, 0x0c, 0xe8,
+            0xcf, 0xfb, 0x22, 0x49, 0xbd, 0x9a, 0x21, 0x37 },
+        128,
+        (unsigned char[]){ 0x01, 0x00, 0x01 }, 3,
+        (unsigned char[]){
+            0x33, 0xa5, 0x04, 0x2a, 0x90, 0xb2, 0x7d, 0x4f, 0x54, 0x51,
+            0xca, 0x9b, 0xbb, 0xd0, 0xb4, 0x47, 0x71, 0xa1, 0x01, 0xaf,
+            0x88, 0x43, 0x40, 0xae, 0xf9, 0x88, 0x5f, 0x2a, 0x4b, 0xbe,
+            0x92, 0xe8, 0x94, 0xa7, 0x24, 0xac, 0x3c, 0x56, 0x8c, 0x8f,
+            0x97, 0x85, 0x3a, 0xd0, 0x7c, 0x02, 0x66, 0xc8, 0xc6, 0xa3,
+            0xca, 0x09, 0x29, 0xf1, 0xe8, 0xf1, 0x12, 0x31, 0x88, 0x44,
+            0x29, 0xfc, 0x4d, 0x9a, 0xe5, 0x5f, 0xee, 0x89, 0x6a, 0x10,
+            0xce, 0x70, 0x7c, 0x3e, 0xd7, 0xe7, 0x34, 0xe4, 0x47, 0x27,
+            0xa3, 0x95, 0x74, 0x50, 0x1a, 0x53, 0x26, 0x83, 0x10, 0x9c,
+            0x2a, 0xba, 0xca, 0xba, 0x28, 0x3c, 0x31, 0xb4, 0xbd, 0x2f,
+            0x53, 0xc3, 0xee, 0x37, 0xe3, 0x52, 0xce, 0xe3, 0x4f, 0x9e,
+            0x50, 0x3b, 0xd8, 0x0c, 0x06, 0x22, 0xad, 0x79, 0xc6, 0xdc,
+            0xee, 0x88, 0x35, 0x47, 0xc6, 0xa3, 0xb3, 0x25 },
+        128,
+        (unsigned char[]){
+            0xb6, 0x9d, 0xca, 0x1c, 0xf7, 0xd4, 0xd7, 0xec, 0x81, 0xe7,
+            0x5b, 0x90, 0xfc, 0xca, 0x87, 0x4a, 0xbc, 0xde, 0x12, 0x3f,
+            0xd2, 0x70, 0x01, 0x80, 0xaa, 0x90, 0x47, 0x9b, 0x6e, 0x48,
+            0xde, 0x8d, 0x67, 0xed, 0x24, 0xf9, 0xf1, 0x9d, 0x85, 0xba,
+            0x27, 0x58, 0x74, 0xf5, 0x42, 0xcd, 0x20, 0xdc, 0x72, 0x3e,
+            0x69, 0x63, 0x36, 0x4a, 0x1f, 0x94, 0x25, 0x45, 0x2b, 0x26,
+            0x9a, 0x67, 0x99, 0xfd },
+        64,
+        (unsigned char[]){
+            0xe7, 0xe8, 0x94, 0x27, 0x20, 0xa8, 0x77, 0x51, 0x72, 0x73,
+            0xa3, 0x56, 0x05, 0x3e, 0xa2, 0xa1, 0xbc, 0x0c, 0x94, 0xaa,
+            0x72, 0xd5, 0x5c, 0x6e, 0x86, 0x29, 0x6b, 0x2d, 0xfc, 0x96,
+            0x79, 0x48, 0xc0, 0xa7, 0x2c, 0xbc, 0xcc, 0xa7, 0xea, 0xcb,
+            0x35, 0x70, 0x6e, 0x09, 0xa1, 0xdf, 0x55, 0xa1, 0x53, 0x5b,
+            0xd9, 0xb3, 0xcc, 0x34, 0x16, 0x0b, 0x3b, 0x6d, 0xcd, 0x3e,
+            0xda, 0x8e, 0x64, 0x43 },
+        64,
+    },
+    {
+        (unsigned char[]){
+            0xa5, 0x6e, 0x4a, 0x0e, 0x70, 0x10, 0x17, 0x58, 0x9a, 0x51,
+            0x87, 0xdc, 0x7e, 0xa8, 0x41, 0xd1, 0x56, 0xf2, 0xec, 0x0e,
+            0x36, 0xad, 0x52, 0xa4, 0x4d, 0xfe, 0xb1, 0xe6, 0x1f, 0x7a,
+            0xd9, 0x91, 0xd8, 0xc5, 0x10, 0x56, 0xff, 0xed, 0xb1, 0x62,
+            0xb4, 0xc0, 0xf2, 0x83, 0xa1, 0x2a, 0x88, 0xa3, 0x94, 0xdf,
+            0xf5, 0x26, 0xab, 0x72, 0x91, 0xcb, 0xb3, 0x07, 0xce, 0xab,
+            0xfc, 0xe0, 0xb1, 0xdf, 0xd5, 0xcd, 0x95, 0x08, 0x09, 0x6d,
+            0x5b, 0x2b, 0x8b, 0x6d, 0xf5, 0xd6, 0x71, 0xef, 0x63, 0x77,
+            0xc0, 0x92, 0x1c, 0xb2, 0x3c, 0x27, 0x0a, 0x70, 0xe2, 0x59,
+            0x8e, 0x6f, 0xf8, 0x9d, 0x19, 0xf1, 0x05, 0xac, 0xc2, 0xd3,
+            0xf0, 0xcb, 0x35, 0xf2, 0x92, 0x80, 0xe1, 0x38, 0x6b, 0x6f,
+            0x64, 0xc4, 0xef, 0x22, 0xe1, 0xe1, 0xf2, 0x0d, 0x0c, 0xe8,
+            0xcf, 0xfb, 0x22, 0x49, 0xbd, 0x9a, 0x21, 0x37 },
+        128,
+        (unsigned char[]){ 0x01, 0x00, 0x01 }, 3,
+        (unsigned char[]){
+            0x33, 0xa5, 0x04, 0x2a, 0x90, 0xb2, 0x7d, 0x4f, 0x54, 0x51,
+            0xca, 0x9b, 0xbb, 0xd0, 0xb4, 0x47, 0x71, 0xa1, 0x01, 0xaf,
+            0x88, 0x43, 0x40, 0xae, 0xf9, 0x88, 0x5f, 0x2a, 0x4b, 0xbe,
+            0x92, 0xe8, 0x94, 0xa7, 0x24, 0xac, 0x3c, 0x56, 0x8c, 0x8f,
+            0x97, 0x85, 0x3a, 0xd0, 0x7c, 0x02, 0x66, 0xc8, 0xc6, 0xa3,
+            0xca, 0x09, 0x29, 0xf1, 0xe8, 0xf1, 0x12, 0x31, 0x88, 0x44,
+            0x29, 0xfc, 0x4d, 0x9a, 0xe5, 0x5f, 0xee, 0x89, 0x6a, 0x10,
+            0xce, 0x70, 0x7c, 0x3e, 0xd7, 0xe7, 0x34, 0xe4, 0x47, 0x27,
+            0xa3, 0x95, 0x74, 0x50, 0x1a, 0x53, 0x26, 0x83, 0x10, 0x9c,
+            0x2a, 0xba, 0xca, 0xba, 0x28, 0x3c, 0x31, 0xb4, 0xbd, 0x2f,
+            0x53, 0xc3, 0xee, 0x37, 0xe3, 0x52, 0xce, 0xe3, 0x4f, 0x9e,
+            0x50, 0x3b, 0xd8, 0x0c, 0x06, 0x22, 0xad, 0x79, 0xc6, 0xdc,
+            0xee, 0x88, 0x35, 0x47, 0xc6, 0xa3, 0xb3, 0x25 },
+        128,
+        (unsigned char[]){
+            0xb6, 0x9d, 0xca, 0x1c, 0xf7, 0xd4, 0xd7, 0xec, 0x81, 0xe7,
+            0x5b, 0x90, 0xfc, 0xca, 0x87, 0x4a, 0xbc, 0xde, 0x12, 0x3f,
+            0xd2, 0x70, 0x01, 0x80, 0xaa, 0x90, 0x47, 0x9b, 0x6e, 0x48,
+            0xde, 0x8d, 0x67, 0xed, 0x24, 0xf9, 0xf1, 0x9d, 0x85, 0xba,
+            0x27, 0x58, 0x74, 0xf5, 0x42, 0xcd, 0x20, 0xdc, 0x72, 0x3e,
+            0x69, 0x63, 0x36, 0x4a, 0x1f, 0x94, 0x25, 0x45, 0x2b, 0x26,
+            0x9a, 0x67, 0x99, 0xfd },
+        64,
+        (unsigned char[]){
+            0xe7, 0xe8, 0x94, 0x27, 0x20, 0xa8, 0x77, 0x51, 0x72, 0x73,
+            0xa3, 0x56, 0x05, 0x3e, 0xa2, 0xa1, 0xbc, 0x0c, 0x94, 0xaa,
+            0x72, 0xd5, 0x5c, 0x6e, 0x86, 0x29, 0x6b, 0x2d, 0xfc, 0x96,
+            0x79, 0x48, 0xc0, 0xa7, 0x2c, 0xbc, 0xcc, 0xa7, 0xea, 0xcb,
+            0x35, 0x70, 0x6e, 0x09, 0xa1, 0xdf, 0x55, 0xa1, 0x53, 0x5b,
+            0xd9, 0xb3, 0xcc, 0x34, 0x16, 0x0b, 0x3b, 0x6d, 0xcd, 0x3e,
+            0xda, 0x8e, 0x64, 0x43 },
+        64,
+    },
+    {
+        (unsigned char[]){
+            0xa5, 0x6e, 0x4a, 0x0e, 0x70, 0x10, 0x17, 0x58, 0x9a, 0x51,
+            0x87, 0xdc, 0x7e, 0xa8, 0x41, 0xd1, 0x56, 0xf2, 0xec, 0x0e,
+            0x36, 0xad, 0x52, 0xa4, 0x4d, 0xfe, 0xb1, 0xe6, 0x1f, 0x7a,
+            0xd9, 0x91, 0xd8, 0xc5, 0x10, 0x56, 0xff, 0xed, 0xb1, 0x62,
+            0xb4, 0xc0, 0xf2, 0x83, 0xa1, 0x2a, 0x88, 0xa3, 0x94, 0xdf,
+            0xf5, 0x26, 0xab, 0x72, 0x91, 0xcb, 0xb3, 0x07, 0xce, 0xab,
+            0xfc, 0xe0, 0xb1, 0xdf, 0xd5, 0xcd, 0x95, 0x08, 0x09, 0x6d,
+            0x5b, 0x2b, 0x8b, 0x6d, 0xf5, 0xd6, 0x71, 0xef, 0x63, 0x77,
+            0xc0, 0x92, 0x1c, 0xb2, 0x3c, 0x27, 0x0a, 0x70, 0xe2, 0x59,
+            0x8e, 0x6f, 0xf8, 0x9d, 0x19, 0xf1, 0x05, 0xac, 0xc2, 0xd3,
+            0xf0, 0xcb, 0x35, 0xf2, 0x92, 0x80, 0xe1, 0x38, 0x6b, 0x6f,
+            0x64, 0xc4, 0xef, 0x22, 0xe1, 0xe1, 0xf2, 0x0d, 0x0c, 0xe8,
+            0xcf, 0xfb, 0x22, 0x49, 0xbd, 0x9a, 0x21, 0x37 },
+        128,
+        (unsigned char[]){ 0x01, 0x00, 0x01 }, 3,
+        (unsigned char[]){
+            0x33, 0xa5, 0x04, 0x2a, 0x90, 0xb2, 0x7d, 0x4f, 0x54, 0x51,
+            0xca, 0x9b, 0xbb, 0xd0, 0xb4, 0x47, 0x71, 0xa1, 0x01, 0xaf,
+            0x88, 0x43, 0x40, 0xae, 0xf9, 0x88, 0x5f, 0x2a, 0x4b, 0xbe,
+            0x92, 0xe8, 0x94, 0xa7, 0x24, 0xac, 0x3c, 0x56, 0x8c, 0x8f,
+            0x97, 0x85, 0x3a, 0xd0, 0x7c, 0x02, 0x66, 0xc8, 0xc6, 0xa3,
+            0xca, 0x09, 0x29, 0xf1, 0xe8, 0xf1, 0x12, 0x31, 0x88, 0x44,
+            0x29, 0xfc, 0x4d, 0x9a, 0xe5, 0x5f, 0xee, 0x89, 0x6a, 0x10,
+            0xce, 0x70, 0x7c, 0x3e, 0xd7, 0xe7, 0x34, 0xe4, 0x47, 0x27,
+            0xa3, 0x95, 0x74, 0x50, 0x1a, 0x53, 0x26, 0x83, 0x10, 0x9c,
+            0x2a, 0xba, 0xca, 0xba, 0x28, 0x3c, 0x31, 0xb4, 0xbd, 0x2f,
+            0x53, 0xc3, 0xee, 0x37, 0xe3, 0x52, 0xce, 0xe3, 0x4f, 0x9e,
+            0x50, 0x3b, 0xd8, 0x0c, 0x06, 0x22, 0xad, 0x79, 0xc6, 0xdc,
+            0xee, 0x88, 0x35, 0x47, 0xc6, 0xa3, 0xb3, 0x25 },
+        128,
+        (unsigned char[]){
+            0xb6, 0x9d, 0xca, 0x1c, 0xf7, 0xd4, 0xd7, 0xec, 0x81, 0xe7,
+            0x5b, 0x90, 0xfc, 0xca, 0x87, 0x4a, 0xbc, 0xde, 0x12, 0x3f,
+            0xd2, 0x70, 0x01, 0x80, 0xaa, 0x90, 0x47, 0x9b, 0x6e, 0x48,
+            0xde, 0x8d, 0x67, 0xed, 0x24, 0xf9, 0xf1, 0x9d, 0x85, 0xba,
+            0x27, 0x58, 0x74, 0xf5, 0x42, 0xcd, 0x20, 0xdc, 0x72, 0x3e,
+            0x69, 0x63, 0x36, 0x4a, 0x1f, 0x94, 0x25, 0x45, 0x2b, 0x26,
+            0x9a, 0x67, 0x99, 0xfd },
+        64,
+        (unsigned char[]){
+            0xe7, 0xe8, 0x94, 0x27, 0x20, 0xa8, 0x77, 0x51, 0x72, 0x73,
+            0xa3, 0x56, 0x05, 0x3e, 0xa2, 0xa1, 0xbc, 0x0c, 0x94, 0xaa,
+            0x72, 0xd5, 0x5c, 0x6e, 0x86, 0x29, 0x6b, 0x2d, 0xfc, 0x96,
+            0x79, 0x48, 0xc0, 0xa7, 0x2c, 0xbc, 0xcc, 0xa7, 0xea, 0xcb,
+            0x35, 0x70, 0x6e, 0x09, 0xa1, 0xdf, 0x55, 0xa1, 0x53, 0x5b,
+            0xd9, 0xb3, 0xcc, 0x34, 0x16, 0x0b, 0x3b, 0x6d, 0xcd, 0x3e,
+            0xda, 0x8e, 0x64, 0x43 },
+        64,
+    },
+    {
+        (unsigned char[]){
+            0xa5, 0x6e, 0x4a, 0x0e, 0x70, 0x10, 0x17, 0x58, 0x9a, 0x51,
+            0x87, 0xdc, 0x7e, 0xa8, 0x41, 0xd1, 0x56, 0xf2, 0xec, 0x0e,
+            0x36, 0xad, 0x52, 0xa4, 0x4d, 0xfe, 0xb1, 0xe6, 0x1f, 0x7a,
+            0xd9, 0x91, 0xd8, 0xc5, 0x10, 0x56, 0xff, 0xed, 0xb1, 0x62,
+            0xb4, 0xc0, 0xf2, 0x83, 0xa1, 0x2a, 0x88, 0xa3, 0x94, 0xdf,
+            0xf5, 0x26, 0xab, 0x72, 0x91, 0xcb, 0xb3, 0x07, 0xce, 0xab,
+            0xfc, 0xe0, 0xb1, 0xdf, 0xd5, 0xcd, 0x95, 0x08, 0x09, 0x6d,
+            0x5b, 0x2b, 0x8b, 0x6d, 0xf5, 0xd6, 0x71, 0xef, 0x63, 0x77,
+            0xc0, 0x92, 0x1c, 0xb2, 0x3c, 0x27, 0x0a, 0x70, 0xe2, 0x59,
+            0x8e, 0x6f, 0xf8, 0x9d, 0x19, 0xf1, 0x05, 0xac, 0xc2, 0xd3,
+            0xf0, 0xcb, 0x35, 0xf2, 0x92, 0x80, 0xe1, 0x38, 0x6b, 0x6f,
+            0x64, 0xc4, 0xef, 0x22, 0xe1, 0xe1, 0xf2, 0x0d, 0x0c, 0xe8,
+            0xcf, 0xfb, 0x22, 0x49, 0xbd, 0x9a, 0x21, 0x37 },
+        128,
+        (unsigned char[]){ 0x01, 0x00, 0x01 }, 3,
+        (unsigned char[]){
+            0x33, 0xa5, 0x04, 0x2a, 0x90, 0xb2, 0x7d, 0x4f, 0x54, 0x51,
+            0xca, 0x9b, 0xbb, 0xd0, 0xb4, 0x47, 0x71, 0xa1, 0x01, 0xaf,
+            0x88, 0x43, 0x40, 0xae, 0xf9, 0x88, 0x5f, 0x2a, 0x4b, 0xbe,
+            0x92, 0xe8, 0x94, 0xa7, 0x24, 0xac, 0x3c, 0x56, 0x8c, 0x8f,
+            0x97, 0x85, 0x3a, 0xd0, 0x7c, 0x02, 0x66, 0xc8, 0xc6, 0xa3,
+            0xca, 0x09, 0x29, 0xf1, 0xe8, 0xf1, 0x12, 0x31, 0x88, 0x44,
+            0x29, 0xfc, 0x4d, 0x9a, 0xe5, 0x5f, 0xee, 0x89, 0x6a, 0x10,
+            0xce, 0x70, 0x7c, 0x3e, 0xd7, 0xe7, 0x34, 0xe4, 0x47, 0x27,
+            0xa3, 0x95, 0x74, 0x50, 0x1a, 0x53, 0x26, 0x83, 0x10, 0x9c,
+            0x2a, 0xba, 0xca, 0xba, 0x28, 0x3c, 0x31, 0xb4, 0xbd, 0x2f,
+            0x53, 0xc3, 0xee, 0x37, 0xe3, 0x52, 0xce, 0xe3, 0x4f, 0x9e,
+            0x50, 0x3b, 0xd8, 0x0c, 0x06, 0x22, 0xad, 0x79, 0xc6, 0xdc,
+            0xee, 0x88, 0x35, 0x47, 0xc6, 0xa3, 0xb3, 0x25 },
+        128,
+        (unsigned char[]){
+            0xb6, 0x9d, 0xca, 0x1c, 0xf7, 0xd4, 0xd7, 0xec, 0x81, 0xe7,
+            0x5b, 0x90, 0xfc, 0xca, 0x87, 0x4a, 0xbc, 0xde, 0x12, 0x3f,
+            0xd2, 0x70, 0x01, 0x80, 0xaa, 0x90, 0x47, 0x9b, 0x6e, 0x48,
+            0xde, 0x8d, 0x67, 0xed, 0x24, 0xf9, 0xf1, 0x9d, 0x85, 0xba,
+            0x27, 0x58, 0x74, 0xf5, 0x42, 0xcd, 0x20, 0xdc, 0x72, 0x3e,
+            0x69, 0x63, 0x36, 0x4a, 0x1f, 0x94, 0x25, 0x45, 0x2b, 0x26,
+            0x9a, 0x67, 0x99, 0xfd },
+        64,
+        (unsigned char[]){
+            0xe7, 0xe8, 0x94, 0x27, 0x20, 0xa8, 0x77, 0x51, 0x72, 0x73,
+            0xa3, 0x56, 0x05, 0x3e, 0xa2, 0xa1, 0xbc, 0x0c, 0x94, 0xaa,
+            0x72, 0xd5, 0x5c, 0x6e, 0x86, 0x29, 0x6b, 0x2d, 0xfc, 0x96,
+            0x79, 0x48, 0xc0, 0xa7, 0x2c, 0xbc, 0xcc, 0xa7, 0xea, 0xcb,
+            0x35, 0x70, 0x6e, 0x09, 0xa1, 0xdf, 0x55, 0xa1, 0x53, 0x5b,
+            0xd9, 0xb3, 0xcc, 0x34, 0x16, 0x0b, 0x3b, 0x6d, 0xcd, 0x3e,
+            0xda, 0x8e, 0x64, 0x43 },
+        64,
+    },
+    {
+        (unsigned char[]){
+            0xa5, 0x6e, 0x4a, 0x0e, 0x70, 0x10, 0x17, 0x58, 0x9a, 0x51,
+            0x87, 0xdc, 0x7e, 0xa8, 0x41, 0xd1, 0x56, 0xf2, 0xec, 0x0e,
+            0x36, 0xad, 0x52, 0xa4, 0x4d, 0xfe, 0xb1, 0xe6, 0x1f, 0x7a,
+            0xd9, 0x91, 0xd8, 0xc5, 0x10, 0x56, 0xff, 0xed, 0xb1, 0x62,
+            0xb4, 0xc0, 0xf2, 0x83, 0xa1, 0x2a, 0x88, 0xa3, 0x94, 0xdf,
+            0xf5, 0x26, 0xab, 0x72, 0x91, 0xcb, 0xb3, 0x07, 0xce, 0xab,
+            0xfc, 0xe0, 0xb1, 0xdf, 0xd5, 0xcd, 0x95, 0x08, 0x09, 0x6d,
+            0x5b, 0x2b, 0x8b, 0x6d, 0xf5, 0xd6, 0x71, 0xef, 0x63, 0x77,
+            0xc0, 0x92, 0x1c, 0xb2, 0x3c, 0x27, 0x0a, 0x70, 0xe2, 0x59,
+            0x8e, 0x6f, 0xf8, 0x9d, 0x19, 0xf1, 0x05, 0xac, 0xc2, 0xd3,
+            0xf0, 0xcb, 0x35, 0xf2, 0x92, 0x80, 0xe1, 0x38, 0x6b, 0x6f,
+            0x64, 0xc4, 0xef, 0x22, 0xe1, 0xe1, 0xf2, 0x0d, 0x0c, 0xe8,
+            0xcf, 0xfb, 0x22, 0x49, 0xbd, 0x9a, 0x21, 0x37 },
+        128,
+        (unsigned char[]){ 0x01, 0x00, 0x01 }, 3,
+        (unsigned char[]){
+            0x33, 0xa5, 0x04, 0x2a, 0x90, 0xb2, 0x7d, 0x4f, 0x54, 0x51,
+            0xca, 0x9b, 0xbb, 0xd0, 0xb4, 0x47, 0x71, 0xa1, 0x01, 0xaf,
+            0x88, 0x43, 0x40, 0xae, 0xf9, 0x88, 0x5f, 0x2a, 0x4b, 0xbe,
+            0x92, 0xe8, 0x94, 0xa7, 0x24, 0xac, 0x3c, 0x56, 0x8c, 0x8f,
+            0x97, 0x85, 0x3a, 0xd0, 0x7c, 0x02, 0x66, 0xc8, 0xc6, 0xa3,
+            0xca, 0x09, 0x29, 0xf1, 0xe8, 0xf1, 0x12, 0x31, 0x88, 0x44,
+            0x29, 0xfc, 0x4d, 0x9a, 0xe5, 0x5f, 0xee, 0x89, 0x6a, 0x10,
+            0xce, 0x70, 0x7c, 0x3e, 0xd7, 0xe7, 0x34, 0xe4, 0x47, 0x27,
+            0xa3, 0x95, 0x74, 0x50, 0x1a, 0x53, 0x26, 0x83, 0x10, 0x9c,
+            0x2a, 0xba, 0xca, 0xba, 0x28, 0x3c, 0x31, 0xb4, 0xbd, 0x2f,
+            0x53, 0xc3, 0xee, 0x37, 0xe3, 0x52, 0xce, 0xe3, 0x4f, 0x9e,
+            0x50, 0x3b, 0xd8, 0x0c, 0x06, 0x22, 0xad, 0x79, 0xc6, 0xdc,
+            0xee, 0x88, 0x35, 0x47, 0xc6, 0xa3, 0xb3, 0x25 },
+        128,
+        (unsigned char[]){
+            0xb6, 0x9d, 0xca, 0x1c, 0xf7, 0xd4, 0xd7, 0xec, 0x81, 0xe7,
+            0x5b, 0x90, 0xfc, 0xca, 0x87, 0x4a, 0xbc, 0xde, 0x12, 0x3f,
+            0xd2, 0x70, 0x01, 0x80, 0xaa, 0x90, 0x47, 0x9b, 0x6e, 0x48,
+            0xde, 0x8d, 0x67, 0xed, 0x24, 0xf9, 0xf1, 0x9d, 0x85, 0xba,
+            0x27, 0x58, 0x74, 0xf5, 0x42, 0xcd, 0x20, 0xdc, 0x72, 0x3e,
+            0x69, 0x63, 0x36, 0x4a, 0x1f, 0x94, 0x25, 0x45, 0x2b, 0x26,
+            0x9a, 0x67, 0x99, 0xfd },
+        64,
+        (unsigned char[]){
+            0xe7, 0xe8, 0x94, 0x27, 0x20, 0xa8, 0x77, 0x51, 0x72, 0x73,
+            0xa3, 0x56, 0x05, 0x3e, 0xa2, 0xa1, 0xbc, 0x0c, 0x94, 0xaa,
+            0x72, 0xd5, 0x5c, 0x6e, 0x86, 0x29, 0x6b, 0x2d, 0xfc, 0x96,
+            0x79, 0x48, 0xc0, 0xa7, 0x2c, 0xbc, 0xcc, 0xa7, 0xea, 0xcb,
+            0x35, 0x70, 0x6e, 0x09, 0xa1, 0xdf, 0x55, 0xa1, 0x53, 0x5b,
+            0xd9, 0xb3, 0xcc, 0x34, 0x16, 0x0b, 0x3b, 0x6d, 0xcd, 0x3e,
+            0xda, 0x8e, 0x64, 0x43 },
+        64,
+    },
+    {
+        (unsigned char[]){
+            0xa5, 0x6e, 0x4a, 0x0e, 0x70, 0x10, 0x17, 0x58, 0x9a, 0x51,
+            0x87, 0xdc, 0x7e, 0xa8, 0x41, 0xd1, 0x56, 0xf2, 0xec, 0x0e,
+            0x36, 0xad, 0x52, 0xa4, 0x4d, 0xfe, 0xb1, 0xe6, 0x1f, 0x7a,
+            0xd9, 0x91, 0xd8, 0xc5, 0x10, 0x56, 0xff, 0xed, 0xb1, 0x62,
+            0xb4, 0xc0, 0xf2, 0x83, 0xa1, 0x2a, 0x88, 0xa3, 0x94, 0xdf,
+            0xf5, 0x26, 0xab, 0x72, 0x91, 0xcb, 0xb3, 0x07, 0xce, 0xab,
+            0xfc, 0xe0, 0xb1, 0xdf, 0xd5, 0xcd, 0x95, 0x08, 0x09, 0x6d,
+            0x5b, 0x2b, 0x8b, 0x6d, 0xf5, 0xd6, 0x71, 0xef, 0x63, 0x77,
+            0xc0, 0x92, 0x1c, 0xb2, 0x3c, 0x27, 0x0a, 0x70, 0xe2, 0x59,
+            0x8e, 0x6f, 0xf8, 0x9d, 0x19, 0xf1, 0x05, 0xac, 0xc2, 0xd3,
+            0xf0, 0xcb, 0x35, 0xf2, 0x92, 0x80, 0xe1, 0x38, 0x6b, 0x6f,
+            0x64, 0xc4, 0xef, 0x22, 0xe1, 0xe1, 0xf2, 0x0d, 0x0c, 0xe8,
+            0xcf, 0xfb, 0x22, 0x49, 0xbd, 0x9a, 0x21, 0x37 },
+        128,
+        (unsigned char[]){ 0x01, 0x00, 0x01 }, 3,
+        (unsigned char[]){
+            0x33, 0xa5, 0x04, 0x2a, 0x90, 0xb2, 0x7d, 0x4f, 0x54, 0x51,
+            0xca, 0x9b, 0xbb, 0xd0, 0xb4, 0x47, 0x71, 0xa1, 0x01, 0xaf,
+            0x88, 0x43, 0x40, 0xae, 0xf9, 0x88, 0x5f, 0x2a, 0x4b, 0xbe,
+            0x92, 0xe8, 0x94, 0xa7, 0x24, 0xac, 0x3c, 0x56, 0x8c, 0x8f,
+            0x97, 0x85, 0x3a, 0xd0, 0x7c, 0x02, 0x66, 0xc8, 0xc6, 0xa3,
+            0xca, 0x09, 0x29, 0xf1, 0xe8, 0xf1, 0x12, 0x31, 0x88, 0x44,
+            0x29, 0xfc, 0x4d, 0x9a, 0xe5, 0x5f, 0xee, 0x89, 0x6a, 0x10,
+            0xce, 0x70, 0x7c, 0x3e, 0xd7, 0xe7, 0x34, 0xe4, 0x47, 0x27,
+            0xa3, 0x95, 0x74, 0x50, 0x1a, 0x53, 0x26, 0x83, 0x10, 0x9c,
+            0x2a, 0xba, 0xca, 0xba, 0x28, 0x3c, 0x31, 0xb4, 0xbd, 0x2f,
+            0x53, 0xc3, 0xee, 0x37, 0xe3, 0x52, 0xce, 0xe3, 0x4f, 0x9e,
+            0x50, 0x3b, 0xd8, 0x0c, 0x06, 0x22, 0xad, 0x79, 0xc6, 0xdc,
+            0xee, 0x88, 0x35, 0x47, 0xc6, 0xa3, 0xb3, 0x25 },
+        128,
+        (unsigned char[]){
+            0xb6, 0x9d, 0xca, 0x1c, 0xf7, 0xd4, 0xd7, 0xec, 0x81, 0xe7,
+            0x5b, 0x90, 0xfc, 0xca, 0x87, 0x4a, 0xbc, 0xde, 0x12, 0x3f,
+            0xd2, 0x70, 0x01, 0x80, 0xaa, 0x90, 0x47, 0x9b, 0x6e, 0x48,
+            0xde, 0x8d, 0x67, 0xed, 0x24, 0xf9, 0xf1, 0x9d, 0x85, 0xba,
+            0x27, 0x58, 0x74, 0xf5, 0x42, 0xcd, 0x20, 0xdc, 0x72, 0x3e,
+            0x69, 0x63, 0x36, 0x4a, 0x1f, 0x94, 0x25, 0x45, 0x2b, 0x26,
+            0x9a, 0x67, 0x99, 0xfd },
+        64,
+        (unsigned char[]){
+            0xe7, 0xe8, 0x94, 0x27, 0x20, 0xa8, 0x77, 0x51, 0x72, 0x73,
+            0xa3, 0x56, 0x05, 0x3e, 0xa2, 0xa1, 0xbc, 0x0c, 0x94, 0xaa,
+            0x72, 0xd5, 0x5c, 0x6e, 0x86, 0x29, 0x6b, 0x2d, 0xfc, 0x96,
+            0x79, 0x48, 0xc0, 0xa7, 0x2c, 0xbc, 0xcc, 0xa7, 0xea, 0xcb,
+            0x35, 0x70, 0x6e, 0x09, 0xa1, 0xdf, 0x55, 0xa1, 0x53, 0x5b,
+            0xd9, 0xb3, 0xcc, 0x34, 0x16, 0x0b, 0x3b, 0x6d, 0xcd, 0x3e,
+            0xda, 0x8e, 0x64, 0x43 },
+        64,
+    },
+    {
+        (unsigned char[]){
+            0xa5, 0x6e, 0x4a, 0x0e, 0x70, 0x10, 0x17, 0x58, 0x9a, 0x51,
+            0x87, 0xdc, 0x7e, 0xa8, 0x41, 0xd1, 0x56, 0xf2, 0xec, 0x0e,
+            0x36, 0xad, 0x52, 0xa4, 0x4d, 0xfe, 0xb1, 0xe6, 0x1f, 0x7a,
+            0xd9, 0x91, 0xd8, 0xc5, 0x10, 0x56, 0xff, 0xed, 0xb1, 0x62,
+            0xb4, 0xc0, 0xf2, 0x83, 0xa1, 0x2a, 0x88, 0xa3, 0x94, 0xdf,
+            0xf5, 0x26, 0xab, 0x72, 0x91, 0xcb, 0xb3, 0x07, 0xce, 0xab,
+            0xfc, 0xe0, 0xb1, 0xdf, 0xd5, 0xcd, 0x95, 0x08, 0x09, 0x6d,
+            0x5b, 0x2b, 0x8b, 0x6d, 0xf5, 0xd6, 0x71, 0xef, 0x63, 0x77,
+            0xc0, 0x92, 0x1c, 0xb2, 0x3c, 0x27, 0x0a, 0x70, 0xe2, 0x59,
+            0x8e, 0x6f, 0xf8, 0x9d, 0x19, 0xf1, 0x05, 0xac, 0xc2, 0xd3,
+            0xf0, 0xcb, 0x35, 0xf2, 0x92, 0x80, 0xe1, 0x38, 0x6b, 0x6f,
+            0x64, 0xc4, 0xef, 0x22, 0xe1, 0xe1, 0xf2, 0x0d, 0x0c, 0xe8,
+            0xcf, 0xfb, 0x22, 0x49, 0xbd, 0x9a, 0x21, 0x37 },
+        128,
+        (unsigned char[]){ 0x01, 0x00, 0x01 }, 3,
+        (unsigned char[]){
+            0x33, 0xa5, 0x04, 0x2a, 0x90, 0xb2, 0x7d, 0x4f, 0x54, 0x51,
+            0xca, 0x9b, 0xbb, 0xd0, 0xb4, 0x47, 0x71, 0xa1, 0x01, 0xaf,
+            0x88, 0x43, 0x40, 0xae, 0xf9, 0x88, 0x5f, 0x2a, 0x4b, 0xbe,
+            0x92, 0xe8, 0x94, 0xa7, 0x24, 0xac, 0x3c, 0x56, 0x8c, 0x8f,
+            0x97, 0x85, 0x3a, 0xd0, 0x7c, 0x02, 0x66, 0xc8, 0xc6, 0xa3,
+            0xca, 0x09, 0x29, 0xf1, 0xe8, 0xf1, 0x12, 0x31, 0x88, 0x44,
+            0x29, 0xfc, 0x4d, 0x9a, 0xe5, 0x5f, 0xee, 0x89, 0x6a, 0x10,
+            0xce, 0x70, 0x7c, 0x3e, 0xd7, 0xe7, 0x34, 0xe4, 0x47, 0x27,
+            0xa3, 0x95, 0x74, 0x50, 0x1a, 0x53, 0x26, 0x83, 0x10, 0x9c,
+            0x2a, 0xba, 0xca, 0xba, 0x28, 0x3c, 0x31, 0xb4, 0xbd, 0x2f,
+            0x53, 0xc3, 0xee, 0x37, 0xe3, 0x52, 0xce, 0xe3, 0x4f, 0x9e,
+            0x50, 0x3b, 0xd8, 0x0c, 0x06, 0x22, 0xad, 0x79, 0xc6, 0xdc,
+            0xee, 0x88, 0x35, 0x47, 0xc6, 0xa3, 0xb3, 0x25 },
+        128,
+        (unsigned char[]){
+            0xb6, 0x9d, 0xca, 0x1c, 0xf7, 0xd4, 0xd7, 0xec, 0x81, 0xe7,
+            0x5b, 0x90, 0xfc, 0xca, 0x87, 0x4a, 0xbc, 0xde, 0x12, 0x3f,
+            0xd2, 0x70, 0x01, 0x80, 0xaa, 0x90, 0x47, 0x9b, 0x6e, 0x48,
+            0xde, 0x8d, 0x67, 0xed, 0x24, 0xf9, 0xf1, 0x9d, 0x85, 0xba,
+            0x27, 0x58, 0x74, 0xf5, 0x42, 0xcd, 0x20, 0xdc, 0x72, 0x3e,
+            0x69, 0x63, 0x36, 0x4a, 0x1f, 0x94, 0x25, 0x45, 0x2b, 0x26,
+            0x9a, 0x67, 0x99, 0xfd },
+        64,
+        (unsigned char[]){
+            0xe7, 0xe8, 0x94, 0x27, 0x20, 0xa8, 0x77, 0x51, 0x72, 0x73,
+            0xa3, 0x56, 0x05, 0x3e, 0xa2, 0xa1, 0xbc, 0x0c, 0x94, 0xaa,
+            0x72, 0xd5, 0x5c, 0x6e, 0x86, 0x29, 0x6b, 0x2d, 0xfc, 0x96,
+            0x79, 0x48, 0xc0, 0xa7, 0x2c, 0xbc, 0xcc, 0xa7, 0xea, 0xcb,
+            0x35, 0x70, 0x6e, 0x09, 0xa1, 0xdf, 0x55, 0xa1, 0x53, 0x5b,
+            0xd9, 0xb3, 0xcc, 0x34, 0x16, 0x0b, 0x3b, 0x6d, 0xcd, 0x3e,
+            0xda, 0x8e, 0x64, 0x43 },
+        64,
+    }
+};
--- a/security/nss/cmd/selfserv/selfserv.c
+++ b/security/nss/cmd/selfserv/selfserv.c
@@ -56,16 +56,19 @@
 
 int NumSidCacheEntries = 1024;
 
 static int handle_connection(PRFileDesc *, PRFileDesc *, int);
 
 static const char envVarName[] = { SSL_ENV_VAR_NAME };
 static const char inheritableSockName[] = { "SELFSERV_LISTEN_SOCKET" };
 
+#define MAX_VIRT_SERVER_NAME_ARRAY_INDEX 10
+#define MAX_CERT_NICKNAME_ARRAY_INDEX 10
+
 #define DEFAULT_BULK_TEST 16384
 #define MAX_BULK_TEST 1048576 /* 1 MB */
 static PRBool testBulk;
 static PRUint32 testBulkSize = DEFAULT_BULK_TEST;
 static PRInt32 testBulkTotal;
 static char *testBulkBuf;
 static PRDescIdentity log_layer_id = PR_INVALID_IO_LAYER;
 static PRFileDesc *loggingFD;
@@ -87,17 +90,17 @@ static enum ocspStaplingModeEnum {
     osm_badsig,    /* supply a good status response with a bad signature */
     osm_corrupted, /* supply a corrupted data block as the status */
     osm_random,    /* use a random response for each connection */
     osm_ocsp       /* retrieve ocsp status from external ocsp server,
               use empty status if server is unavailable */
 } ocspStaplingMode = osm_disabled;
 typedef enum ocspStaplingModeEnum ocspStaplingModeType;
 static char *ocspStaplingCA = NULL;
-static SECItemArray *certStatus[kt_kea_size] = { NULL };
+static SECItemArray *certStatus[MAX_CERT_NICKNAME_ARRAY_INDEX] = { NULL };
 
 const int ssl3CipherSuites[] = {
     -1,                                /* SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA* a */
     -1,                                /* SSL_FORTEZZA_DMS_WITH_RC4_128_SHA     * b */
     TLS_RSA_WITH_RC4_128_MD5,          /* c */
     TLS_RSA_WITH_3DES_EDE_CBC_SHA,     /* d */
     TLS_RSA_WITH_DES_CBC_SHA,          /* e */
     -1,                                /* TLS_RSA_EXPORT_WITH_RC4_40_MD5        * f */
@@ -423,18 +426,16 @@ myBadCertHandler(void *arg, PRFileDesc *
     int err = PR_GetError();
     if (!MakeCertOK)
         fprintf(stderr,
                 "selfserv: -- SSL: Client Certificate Invalid, err %d.\n%s\n",
                 err, SECU_Strerror(err));
     return (MakeCertOK ? SECSuccess : SECFailure);
 }
 
-#define MAX_VIRT_SERVER_NAME_ARRAY_INDEX 10
-
 /* Simple SNI socket config function that does not use SSL_ReconfigFD.
  * Only uses one server name but verifies that the names match. */
 PRInt32
 mySSLSNISocketConfig(PRFileDesc *fd, const SECItem *sniNameArr,
                      PRUint32 sniNameArrSize, void *arg)
 {
     PRInt32 i = 0;
     const SECItem *current = sniNameArr;
@@ -799,16 +800,19 @@ PRBool enableCompression = PR_FALSE;
 PRBool failedToNegotiateName = PR_FALSE;
 PRBool enableExtendedMasterSecret = PR_FALSE;
 PRBool zeroRTT = PR_FALSE;
 PRBool enableALPN = PR_FALSE;
 
 static char *virtServerNameArray[MAX_VIRT_SERVER_NAME_ARRAY_INDEX];
 static int virtServerNameIndex = 1;
 
+static char *certNicknameArray[MAX_CERT_NICKNAME_ARRAY_INDEX];
+static int certNicknameIndex = 0;
+
 static const char stopCmd[] = { "GET /stop " };
 static const char getCmd[] = { "GET " };
 static const char EOFmsg[] = { "EOF\r\n\r\n\r\n" };
 static const char outHeader[] = {
     "HTTP/1.0 200 OK\r\n"
     "Server: Generic Web Server\r\n"
     "Date: Tue, 26 Aug 1997 22:10:05 GMT\r\n"
     "Content-type: text/plain\r\n"
@@ -1161,17 +1165,17 @@ makeSignedOCSPResponse(PLArenaPool *aren
     CERT_DestroyOCSPCertID(cid);
     cid = NULL;
 
     return result;
 }
 
 void
 setupCertStatus(PLArenaPool *arena, enum ocspStaplingModeEnum ocspStaplingMode,
-                CERTCertificate *cert, SSLKEAType kea, secuPWData *pwdata)
+                CERTCertificate *cert, int index, secuPWData *pwdata)
 {
     if (ocspStaplingMode == osm_random) {
         /* 6 different responses */
         int r = rand() % 6;
         switch (r) {
             case 0:
                 ocspStaplingMode = osm_good;
                 break;
@@ -1215,17 +1219,17 @@ setupCertStatus(PLArenaPool *arena, enum
             case osm_ocsp:
                 errExit("stapling mode \"ocsp\" not implemented");
                 break;
                 break;
             default:
                 break;
         }
         if (multiOcspResponses) {
-            certStatus[kea] = multiOcspResponses;
+            certStatus[index] = multiOcspResponses;
         }
     }
 }
 
 int
 handle_connection(
     PRFileDesc *tcp_sock,
     PRFileDesc *model_sock,
@@ -1246,17 +1250,16 @@ handle_connection(
     int numIOVs;
     PRSocketOptionData opt;
     PRIOVec iovs[16];
     char msgBuf[160];
     char buf[10240];
     char fileName[513];
     char proto[128];
     PRDescIdentity aboveLayer = PR_INVALID_IO_LAYER;
-    SSLKEAType kea;
 
     pBuf = buf;
     bufRem = sizeof buf;
 
     VLOG(("selfserv: handle_connection: starting"));
     opt.option = PR_SockOpt_Nonblocking;
     opt.value.non_blocking = PR_FALSE;
     PR_SetSocketOption(tcp_sock, &opt);
@@ -1273,22 +1276,16 @@ handle_connection(
         if (rv != SECSuccess) {
             errWarn("SSL_ResetHandshake");
             goto cleanup;
         }
     } else {
         ssl_sock = tcp_sock;
     }
 
-    for (kea = kt_rsa; kea < kt_kea_size; kea++) {
-        if (certStatus[kea] != NULL) {
-            SSL_SetStapledOCSPResponses(ssl_sock, certStatus[kea], kea);
-        }
-    }
-
     if (loggingLayer) {
         /* find the layer where our new layer is to be pushed */
         aboveLayer = PR_GetLayersIdentity(ssl_sock->lower);
         if (aboveLayer == PR_INVALID_IO_LAYER) {
             errExit("PRGetUniqueIdentity");
         }
         /* create the new layer - this is a very cheap operation */
         loggingFD = PR_CreateIOLayerStub(log_layer_id, &loggingMethods);
@@ -1815,19 +1812,19 @@ handshakeCallback(PRFileDesc *fd, void *
 void
 server_main(
     PRFileDesc *listen_sock,
     int requestCert,
     SECKEYPrivateKey **privKey,
     CERTCertificate **cert,
     const char *expectedHostNameVal)
 {
+    int i;
     PRFileDesc *model_sock = NULL;
     int rv;
-    SSLKEAType kea;
     SECStatus secStatus;
 
     if (useModelSocket) {
         model_sock = PR_NewTCPSocket();
         if (model_sock == NULL) {
             errExit("PR_NewTCPSocket on model socket");
         }
         model_sock = SSL_ImportFD(NULL, model_sock);
@@ -1914,22 +1911,27 @@ server_main(
         rv = SSL_OptionSet(model_sock, SSL_ENABLE_EXTENDED_MASTER_SECRET, PR_TRUE);
         if (rv != SECSuccess) {
             errExit("error enabling extended master secret ");
         }
     }
 
     /* This uses the legacy certificate API.  See mySSLSNISocketConfig() for the
      * new, prefered API. */
-    for (kea = kt_rsa; kea < kt_kea_size; kea++) {
-        if (cert[kea] != NULL) {
-            secStatus = SSL_ConfigSecureServer(model_sock,
-                                               cert[kea], privKey[kea], kea);
+    for (i = 0; i < certNicknameIndex; i++) {
+        if (cert[i] != NULL) {
+            const SSLExtraServerCertData ocspData = {
+                ssl_auth_null, NULL, certStatus[i], NULL
+            };
+
+            secStatus = SSL_ConfigServerCert(model_sock, cert[i],
+                                             privKey[i], &ocspData,
+                                             sizeof(ocspData));
             if (secStatus != SECSuccess)
-                errExit("SSL_ConfigSecureServer");
+                errExit("SSL_ConfigServerCert");
         }
     }
 
     if (bigBuf.data) { /* doing FDX */
         rv = SSL_OptionSet(model_sock, SSL_ENABLE_FDX, 1);
         if (rv < 0) {
             errExit("SSL_OptionSet SSL_ENABLE_FDX");
         }
@@ -2164,32 +2166,27 @@ enableOCSPStapling(const char *mode)
     }
     return SECFailure;
 }
 
 int
 main(int argc, char **argv)
 {
     char *progName = NULL;
-    char *nickName = NULL;
-#ifndef NSS_DISABLE_ECC
-    char *ecNickName = NULL;
-#endif
-    char *dsaNickName = NULL;
     const char *fileName = NULL;
     char *cipherString = NULL;
     const char *dir = ".";
     char *passwd = NULL;
     char *pwfile = NULL;
     const char *pidFile = NULL;
     char *tmp;
     char *envString;
     PRFileDesc *listen_sock;
-    CERTCertificate *cert[kt_kea_size] = { NULL };
-    SECKEYPrivateKey *privKey[kt_kea_size] = { NULL };
+    CERTCertificate *cert[MAX_CERT_NICKNAME_ARRAY_INDEX] = { NULL };
+    SECKEYPrivateKey *privKey[MAX_CERT_NICKNAME_ARRAY_INDEX] = { NULL };
     int optionsFound = 0;
     int maxProcs = 1;
     unsigned short port = 0;
     SECStatus rv;
     PRStatus prStatus;
     PRBool bindOnly = PR_FALSE;
     PRBool useLocalThreads = PR_FALSE;
     PLOptState *optstate;
@@ -2271,17 +2268,21 @@ main(int argc, char **argv)
                 NoReuse = PR_TRUE;
                 break;
 
             case 'R':
                 disableRollBack = PR_TRUE;
                 break;
 
             case 'S':
-                dsaNickName = PORT_Strdup(optstate->value);
+                if (certNicknameIndex >= MAX_CERT_NICKNAME_ARRAY_INDEX) {
+                    Usage(progName);
+                    break;
+                }
+                certNicknameArray[certNicknameIndex++] = PORT_Strdup(optstate->value);
                 break;
 
             case 'T':
                 if (enableOCSPStapling(optstate->value) != SECSuccess) {
                     fprintf(stderr, "Invalid OCSP stapling mode.\n");
                     fprintf(stderr, "Run '%s -h' for usage information.\n", progName);
                     exit(53);
                 }
@@ -2326,17 +2327,21 @@ main(int argc, char **argv)
                 break;
 
             case 'd':
                 dir = optstate->value;
                 break;
 
 #ifndef NSS_DISABLE_ECC
             case 'e':
-                ecNickName = PORT_Strdup(optstate->value);
+                if (certNicknameIndex >= MAX_CERT_NICKNAME_ARRAY_INDEX) {
+                    Usage(progName);
+                    break;
+                }
+                certNicknameArray[certNicknameIndex++] = PORT_Strdup(optstate->value);
                 break;
 #endif /* NSS_DISABLE_ECC */
 
             case 'f':
                 pwdata.source = PW_FROMFILE;
                 pwdata.data = pwfile = PORT_Strdup(optstate->value);
                 break;
 
@@ -2367,17 +2372,21 @@ main(int argc, char **argv)
                 useLocalThreads = PR_TRUE;
                 break;
 
             case 'm':
                 useModelSocket = PR_TRUE;
                 break;
 
             case 'n':
-                nickName = PORT_Strdup(optstate->value);
+                if (certNicknameIndex >= MAX_CERT_NICKNAME_ARRAY_INDEX) {
+                    Usage(progName);
+                    break;
+                }
+                certNicknameArray[certNicknameIndex++] = PORT_Strdup(optstate->value);
                 virtServerNameArray[0] = PORT_Strdup(optstate->value);
                 break;
 
             case 'P':
                 certPrefix = PORT_Strdup(optstate->value);
                 break;
 
             case 'o':
@@ -2476,24 +2485,18 @@ main(int argc, char **argv)
             exit(1);
         }
         if (listen_sock) {
             PR_Close(listen_sock);
         }
         exit(0);
     }
 
-    if ((nickName == NULL) &&
-        (dsaNickName == NULL)
-#ifndef NSS_DISABLE_ECC
-        && (ecNickName == NULL)
-#endif
-            ) {
-
-        fprintf(stderr, "Required arg '-n' (rsa nickname) not supplied.\n");
+    if (certNicknameIndex == 0) {
+        fprintf(stderr, "Must specify at least one certificate nickname using '-n' (RSA), '-S' (DSA), or 'e' (EC).\n");
         fprintf(stderr, "Run '%s -h' for usage information.\n", progName);
         exit(6);
     }
 
     if (port == 0) {
         fprintf(stderr, "Required argument 'port' must be non-zero value\n");
         exit(7);
     }
@@ -2638,66 +2641,33 @@ main(int argc, char **argv)
         }
         PORT_Free(cstringSaved);
     }
 
     certStatusArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
     if (!certStatusArena)
         errExit("cannot allocate certStatusArena");
 
-    if (nickName) {
-        cert[kt_rsa] = PK11_FindCertFromNickname(nickName, &pwdata);
-        if (cert[kt_rsa] == NULL) {
-            fprintf(stderr, "selfserv: Can't find certificate %s\n", nickName);
+    for (i = 0; i < certNicknameIndex; i++) {
+        cert[i] = PK11_FindCertFromNickname(certNicknameArray[i], &pwdata);
+        if (cert[i] == NULL) {
+            fprintf(stderr, "selfserv: Can't find certificate %s\n", certNicknameArray[i]);
             exit(10);
         }
-        privKey[kt_rsa] = PK11_FindKeyByAnyCert(cert[kt_rsa], &pwdata);
-        if (privKey[kt_rsa] == NULL) {
+        privKey[i] = PK11_FindKeyByAnyCert(cert[i], &pwdata);
+        if (privKey[i] == NULL) {
             fprintf(stderr, "selfserv: Can't find Private Key for cert %s\n",
-                    nickName);
+                    certNicknameArray[i]);
             exit(11);
         }
-        setupCertStatus(certStatusArena, ocspStaplingMode, cert[kt_rsa], kt_rsa,
-                        &pwdata);
+#ifdef NSS_DISABLE_ECC
+        if (privKey[i]->keyType != ecKey)
+#endif
+            setupCertStatus(certStatusArena, ocspStaplingMode, cert[i], i, &pwdata);
     }
-    if (dsaNickName) {
-        /* Investigate if ssl_kea_dh should be changed to ssl_auth_dsa.
-         * See bug 102794.*/
-        cert[ssl_kea_dh] = PK11_FindCertFromNickname(dsaNickName, &pwdata);
-        if (cert[ssl_kea_dh] == NULL) {
-            fprintf(stderr, "selfserv: Can't find certificate %s\n", dsaNickName);
-            exit(12);
-        }
-        privKey[ssl_kea_dh] = PK11_FindKeyByAnyCert(cert[ssl_kea_dh], &pwdata);
-        if (privKey[ssl_kea_dh] == NULL) {
-            fprintf(stderr, "selfserv: Can't find Private Key for cert %s\n",
-                    dsaNickName);
-            exit(11);
-        }
-        setupCertStatus(certStatusArena, ocspStaplingMode, cert[ssl_kea_dh], ssl_kea_dh,
-                        &pwdata);
-    }
-#ifndef NSS_DISABLE_ECC
-    if (ecNickName) {
-        cert[kt_ecdh] = PK11_FindCertFromNickname(ecNickName, &pwdata);
-        if (cert[kt_ecdh] == NULL) {
-            fprintf(stderr, "selfserv: Can't find certificate %s\n",
-                    ecNickName);
-            exit(13);
-        }
-        privKey[kt_ecdh] = PK11_FindKeyByAnyCert(cert[kt_ecdh], &pwdata);
-        if (privKey[kt_ecdh] == NULL) {
-            fprintf(stderr, "selfserv: Can't find Private Key for cert %s\n",
-                    ecNickName);
-            exit(11);
-        }
-        setupCertStatus(certStatusArena, ocspStaplingMode, cert[kt_ecdh], kt_ecdh,
-                        &pwdata);
-    }
-#endif /* NSS_DISABLE_ECC */
 
     if (configureWeakDHE > 0) {
         fprintf(stderr, "selfserv: Creating dynamic weak DH parameters\n");
         rv = SSL_EnableWeakDHEPrimeGroup(NULL, PR_TRUE);
         if (rv != SECSuccess) {
             goto cleanup;
         }
         fprintf(stderr, "selfserv: Done creating dynamic weak DH parameters\n");
@@ -2734,55 +2704,45 @@ cleanup:
     }
     if (failedToNegotiateName) {
         fprintf(stderr, "selfserv: Failed properly negotiate server name\n");
         exit(1);
     }
 
     {
         int i;
-        for (i = 0; i < kt_kea_size; i++) {
+        for (i = 0; i < certNicknameIndex; i++) {
             if (cert[i]) {
                 CERT_DestroyCertificate(cert[i]);
             }
             if (privKey[i]) {
                 SECKEY_DestroyPrivateKey(privKey[i]);
             }
+            PORT_Free(certNicknameArray[i]);
         }
         for (i = 0; virtServerNameArray[i]; i++) {
             PORT_Free(virtServerNameArray[i]);
         }
     }
 
     if (debugCache) {
         nss_DumpCertificateCacheInfo();
     }
-    if (nickName) {
-        PORT_Free(nickName);
-    }
     if (expectedHostNameVal) {
         PORT_Free(expectedHostNameVal);
     }
     if (passwd) {
         PORT_Free(passwd);
     }
     if (pwfile) {
         PORT_Free(pwfile);
     }
     if (certPrefix && certPrefix != emptyString) {
         PORT_Free(certPrefix);
     }
-#ifndef NSS_DISABLE_ECC
-    if (ecNickName) {
-        PORT_Free(ecNickName);
-    }
-#endif
-    if (dsaNickName) {
-        PORT_Free(dsaNickName);
-    }
 
     if (hasSidCache) {
         SSL_ShutdownServerSessionIDCache();
     }
     if (certStatusArena) {
         PORT_FreeArena(certStatusArena, PR_FALSE);
     }
     if (NSS_Shutdown() != SECSuccess) {
--- 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."
+
--- a/security/nss/lib/freebl/mpi/README
+++ b/security/nss/lib/freebl/mpi/README
@@ -229,17 +229,16 @@ basic arithmetic functions on full mp_in
 mp_add(a, b, c)         - computes c = a + b
 mp_sub(a, b, c)         - computes c = a - b
 mp_mul(a, b, c)         - computes c = a * b
 mp_sqr(a, b)            - computes b = a * a
 mp_div(a, b, q, r)      - computes q, r such that a = bq + r
 mp_div_2d(a, d, q, r)   - computes q = a / 2^d, r = a % 2^d
 mp_expt(a, b, c)        - computes c = a ** b
 mp_2expt(a, k)          - computes a = 2^k
-mp_sqrt(a, c)           - computes c = floor(sqrt(a))
 
 The mp_div_2d() function efficiently computes division by powers of
 two.  Either the q or r parameter may be NULL, in which case that
 portion of the computation will be discarded.
 
 The algorithms used for some of the computations here are described in
 the following files which are included with this distribution:
 
--- a/security/nss/lib/freebl/mpi/mpi-test.c
+++ b/security/nss/lib/freebl/mpi/mpi-test.c
@@ -1177,49 +1177,16 @@ test_2expt(void)
     }
 
     return 0;
 }
 
 /*------------------------------------------------------------------------*/
 
 int
-test_sqrt(void)
-{
-    mp_int a;
-    int res = 0;
-
-    mp_init(&a);
-    mp_read_radix(&a, mp9, 16);
-    mp_sqrt(&a, &a);
-    mp_toradix(&a, g_intbuf, 16);
-
-    if (strcmp(g_intbuf, t_mp9) != 0) {
-        reason("error: computed %s, expected %s\n", g_intbuf, t_mp9);
-        res = 1;
-        goto CLEANUP;
-    }
-
-    mp_read_radix(&a, mp15, 16);
-    mp_sqrt(&a, &a);
-    mp_toradix(&a, g_intbuf, 16);
-
-    if (strcmp(g_intbuf, t_mp15) != 0) {
-        reason("error: computed %s, expected %s\n", g_intbuf, t_mp15);
-        res = 1;
-    }
-
-CLEANUP:
-    mp_clear(&a);
-    return res;
-}
-
-/*------------------------------------------------------------------------*/
-
-int
 test_mod_d(void)
 {
     mp_int a;
     mp_digit r;
 
     mp_init(&a);
     mp_read_radix(&a, mp5, 16);
     IFOK(mp_mod_d(&a, md5, &r));
--- a/security/nss/lib/freebl/mpi/mpi.c
+++ b/security/nss/lib/freebl/mpi/mpi.c
@@ -1292,98 +1292,16 @@ mp_mod_d(const mp_int *a, mp_digit d, mp
         *c = rem;
 
     return MP_OKAY;
 
 } /* end mp_mod_d() */
 
 /* }}} */
 
-/* {{{ mp_sqrt(a, b) */
-
-/*
-  mp_sqrt(a, b)
-
-  Compute the integer square root of a, and store the result in b.
-  Uses an integer-arithmetic version of Newton's iterative linear
-  approximation technique to determine this value; the result has the
-  following two properties:
-
-     b^2 <= a
-     (b+1)^2 >= a
-
-  It is a range error to pass a negative value.
- */
-mp_err
-mp_sqrt(const mp_int *a, mp_int *b)
-{
-    mp_int x, t;
-    mp_err res;
-    mp_size used;
-
-    ARGCHK(a != NULL && b != NULL, MP_BADARG);
-
-    /* Cannot take square root of a negative value */
-    if (SIGN(a) == NEG)
-        return MP_RANGE;
-
-    /* Special cases for zero and one, trivial     */
-    if (mp_cmp_d(a, 1) <= 0)
-        return mp_copy(a, b);
-
-    /* Initialize the temporaries we'll use below  */
-    if ((res = mp_init_size(&t, USED(a))) != MP_OKAY)
-        return res;
-
-    /* Compute an initial guess for the iteration as a itself */
-    if ((res = mp_init_copy(&x, a)) != MP_OKAY)
-        goto X;
-
-    used = MP_USED(&x);
-    if (used > 1) {
-        s_mp_rshd(&x, used / 2);
-    }
-
-    for (;;) {
-        /* t = (x * x) - a */
-        if ((res = mp_copy(&x, &t)) != MP_OKAY ||
-            (res = mp_sqr(&t, &t)) != MP_OKAY ||
-            (res = mp_sub(&t, a, &t)) != MP_OKAY)
-            goto CLEANUP;
-
-        /* t = t / 2x       */
-        s_mp_mul_2(&x);
-        if ((res = mp_div(&t, &x, &t, NULL)) != MP_OKAY)
-            goto CLEANUP;
-        s_mp_div_2(&x);
-
-        /* Terminate the loop, if the quotient is zero */
-        if (mp_cmp_z(&t) == MP_EQ)
-            break;
-
-        /* x = x - t       */
-        if ((res = mp_sub(&x, &t, &x)) != MP_OKAY)
-            goto CLEANUP;
-    }
-
-    /* Copy result to output parameter */
-    MP_CHECKOK(mp_sub_d(&x, 1, &x));
-    s_mp_exch(&x, b);
-
-CLEANUP:
-    mp_clear(&x);
-X:
-    mp_clear(&t);
-
-    return res;
-
-} /* end mp_sqrt() */
-
-/* }}} */
-
 /* }}} */
 
 /*------------------------------------------------------------------------*/
 /* {{{ Modular arithmetic */
 
 #if MP_MODARITH
 /* {{{ mp_addmod(a, b, m, c) */
 
--- a/security/nss/lib/freebl/mpi/mpi.h
+++ b/security/nss/lib/freebl/mpi/mpi.h
@@ -191,17 +191,16 @@ mp_err mp_mul(const mp_int *a, const mp_
 mp_err mp_sqr(const mp_int *a, mp_int *b);
 #else
 #define mp_sqr(a, b) mp_mul(a, a, b)
 #endif
 mp_err mp_div(const mp_int *a, const mp_int *b, mp_int *q, mp_int *r);
 mp_err mp_div_2d(const mp_int *a, mp_digit d, mp_int *q, mp_int *r);
 mp_err mp_expt(mp_int *a, mp_int *b, mp_int *c);
 mp_err mp_2expt(mp_int *a, mp_digit k);
-mp_err mp_sqrt(const mp_int *a, mp_int *b);
 
 /* Modular arithmetic      */
 #if MP_MODARITH
 mp_err mp_mod(const mp_int *a, const mp_int *m, mp_int *c);
 mp_err mp_mod_d(const mp_int *a, mp_digit d, mp_digit *c);
 mp_err mp_addmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c);
 mp_err mp_submod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c);
 mp_err mp_mulmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c);
--- a/security/nss/lib/freebl/mpi/tests/mptest-3.c
+++ b/security/nss/lib/freebl/mpi/tests/mptest-3.c
@@ -12,17 +12,16 @@
 #include <string.h>
 #include <ctype.h>
 #include <limits.h>
 
 #include <time.h>
 
 #include "mpi.h"
 
-#define SQRT 1 /* define nonzero to get square-root test  */
 #define EXPT 0 /* define nonzero to get exponentiate test */
 
 int
 main(int argc, char *argv[])
 {
     int ix;
     mp_int a, b, c, d;
     mp_digit r;
@@ -92,30 +91,15 @@ main(int argc, char *argv[])
 
     ix = rand() % 256;
     printf("\nc = 2^%d\n", ix);
     mp_2expt(&c, ix);
     printf("c = ");
     mp_print(&c, stdout);
     fputc('\n', stdout);
 
-#if SQRT
-    printf("\nc = sqrt(a)\n");
-    if ((res = mp_sqrt(&a, &c)) != MP_OKAY) {
-        printf("mp_sqrt: %s\n", mp_strerror(res));
-    } else {
-        printf("c = ");
-        mp_print(&c, stdout);
-        fputc('\n', stdout);
-        mp_sqr(&c, &c);
-        printf("c^2 = ");
-        mp_print(&c, stdout);
-        fputc('\n', stdout);
-    }
-#endif
-
     mp_clear(&d);
     mp_clear(&c);
     mp_clear(&b);
     mp_clear(&a);
 
     return 0;
 }
--- a/security/nss/lib/freebl/rsa.c
+++ b/security/nss/lib/freebl/rsa.c
@@ -378,91 +378,182 @@ rsa_is_prime(mp_int *p)
     }
 
     /* If that passed, run some Miller-Rabin tests */
     res = mpp_pprime(p, 2);
     return res;
 }
 
 /*
- * Try to find the two primes based on 2 exponents plus either a prime
- *   or a modulus.
+ * Factorize a RSA modulus n into p and q by using the exponents e and d.
+ *
+ * In: e, d, n
+ * Out: p, q
+ *
+ * See Handbook of Applied Cryptography, 8.2.2(i).
+ *
+ * The algorithm is probabilistic, it is run 64 times and each run has a 50%
+ * chance of succeeding with a runtime of O(log(e*d)).
  *
- * In: e, d and either p or n (depending on the setting of hasModulus).
+ * The returned p might be smaller than q.
+ */
+static mp_err
+rsa_factorize_n_from_exponents(mp_int *e, mp_int *d, mp_int *p, mp_int *q,
+                               mp_int *n)
+{
+    /* lambda is the private modulus: e*d = 1 mod lambda */
+    /* so: e*d - 1 = k*lambda = t*2^s where t is odd */
+    mp_int klambda;
+    mp_int t, onetwentyeight;
+    unsigned long s = 0;
+    unsigned long i;
+
+    /* cand = a^(t * 2^i) mod n, next_cand = a^(t * 2^(i+1)) mod n */
+    mp_int a;
+    mp_int cand;
+    mp_int next_cand;
+
+    mp_int n_minus_one;
+    mp_err err = MP_OKAY;
+
+    MP_DIGITS(&klambda) = 0;
+    MP_DIGITS(&t) = 0;
+    MP_DIGITS(&a) = 0;
+    MP_DIGITS(&cand) = 0;
+    MP_DIGITS(&n_minus_one) = 0;
+    MP_DIGITS(&next_cand) = 0;
+    MP_DIGITS(&onetwentyeight) = 0;
+    CHECK_MPI_OK(mp_init(&klambda));
+    CHECK_MPI_OK(mp_init(&t));
+    CHECK_MPI_OK(mp_init(&a));
+    CHECK_MPI_OK(mp_init(&cand));
+    CHECK_MPI_OK(mp_init(&n_minus_one));
+    CHECK_MPI_OK(mp_init(&next_cand));
+    CHECK_MPI_OK(mp_init(&onetwentyeight));
+
+    mp_set_int(&onetwentyeight, 128);
+
+    /* calculate k*lambda = e*d - 1 */
+    CHECK_MPI_OK(mp_mul(e, d, &klambda));
+    CHECK_MPI_OK(mp_sub_d(&klambda, 1, &klambda));
+
+    /* factorize klambda into t*2^s */
+    CHECK_MPI_OK(mp_copy(&klambda, &t));
+    while (mpp_divis_d(&t, 2) == MP_YES) {
+        CHECK_MPI_OK(mp_div_2(&t, &t));
+        s += 1;
+    }
+
+    /* precompute n_minus_one = n - 1 */
+    CHECK_MPI_OK(mp_copy(n, &n_minus_one));
+    CHECK_MPI_OK(mp_sub_d(&n_minus_one, 1, &n_minus_one));
+
+    /* pick random bases a, each one has a 50% leading to a factorization */
+    CHECK_MPI_OK(mp_set_int(&a, 2));
+    /* The following is equivalent to for (a=2, a <= 128, a+=2) */
+    while (mp_cmp(&a, &onetwentyeight) <= 0) {
+        /* compute the base cand = a^(t * 2^0) [i = 0] */
+        CHECK_MPI_OK(mp_exptmod(&a, &t, n, &cand));
+
+        for (i = 0; i < s; i++) {
+            /* condition 1: skip the base if we hit a trivial factor of n */
+            if (mp_cmp(&cand, &n_minus_one) == 0 || mp_cmp_d(&cand, 1) == 0) {
+                break;
+            }
+
+            /* increase i in a^(t * 2^i) by squaring the number */
+            CHECK_MPI_OK(mp_exptmod_d(&cand, 2, n, &next_cand));
+
+            /* condition 2: a^(t * 2^(i+1)) = 1 mod n */
+            if (mp_cmp_d(&next_cand, 1) == 0) {
+                /* conditions verified, gcd(a^(t * 2^i) - 1, n) is a factor */
+                CHECK_MPI_OK(mp_sub_d(&cand, 1, &cand));
+                CHECK_MPI_OK(mp_gcd(&cand, n, p));
+                if (mp_cmp_d(p, 1) == 0) {
+                    CHECK_MPI_OK(mp_add_d(&cand, 1, &cand));
+                    break;
+                }
+                CHECK_MPI_OK(mp_div(n, p, q, NULL));
+                goto cleanup;
+            }
+            CHECK_MPI_OK(mp_copy(&next_cand, &cand));
+        }
+
+        CHECK_MPI_OK(mp_add_d(&a, 2, &a));
+    }
+
+    /* if we reach here it's likely (2^64 - 1 / 2^64) that d is wrong */
+    err = MP_RANGE;
+
+cleanup:
+    mp_clear(&klambda);
+    mp_clear(&t);
+    mp_clear(&a);
+    mp_clear(&cand);
+    mp_clear(&n_minus_one);
+    mp_clear(&next_cand);
+    mp_clear(&onetwentyeight);
+    return err;
+}
+
+/*
+ * Try to find the two primes based on 2 exponents plus a prime.
+ *
+ * In: e, d and p.
  * Out: p,q.
  *
  * Step 1, Since d = e**-1 mod phi, we know that d*e == 1 mod phi, or
  *  d*e = 1+k*phi, or d*e-1 = k*phi. since d is less than phi and e is
  *  usually less than d, then k must be an integer between e-1 and 1
  *  (probably on the order of e).
- * Step 1a, If we were passed just a prime, we can divide k*phi by that
- *      prime-1 and get k*(q-1). This will reduce the size of our division
- *      through the rest of the loop.
+ * Step 1a, We can divide k*phi by prime-1 and get k*(q-1). This will reduce
+ *      the size of our division through the rest of the loop.
  * Step 2, Loop through the values k=e-1 to 1 looking for k. k should be on
  *  the order or e, and e is typically small. This may take a while for
  *  a large random e. We are looking for a k that divides kphi
  *  evenly. Once we find a k that divides kphi evenly, we assume it
  *  is the true k. It's possible this k is not the 'true' k but has
  *  swapped factors of p-1 and/or q-1. Because of this, we
  *  tentatively continue Steps 3-6 inside this loop, and may return looking
  *  for another k on failure.
- * Step 3, Calculate are tentative phi=kphi/k. Note: real phi is (p-1)*(q-1).
- * Step 4a, if we have a prime, kphi is already k*(q-1), so phi is or tenative
- *      q-1. q = phi+1. If k is correct, q should be the right length and
- *      prime.
+ * Step 3, Calculate our tentative phi=kphi/k. Note: real phi is (p-1)*(q-1).
+ * Step 4a, kphi is k*(q-1), so phi is our tenative q-1. q = phi+1.
+ *      If k is correct, q should be the right length and prime.
  * Step 4b, It's possible q-1 and k could have swapped factors. We now have a
  *  possible solution that meets our criteria. It may not be the only
  *      solution, however, so we keep looking. If we find more than one,
  *      we will fail since we cannot determine which is the correct
  *      solution, and returning the wrong modulus will compromise both
  *      moduli. If no other solution is found, we return the unique solution.
- * Step 5a, If we have the modulus (n=pq), then use the following formula to
- *  calculate  s=(p+q): , phi = (p-1)(q-1) = pq  -p-q +1 = n-s+1. so
- *  s=n-phi+1.
- * Step 5b, Use n=pq and s=p+q to solve for p and q as follows:
- *  since q=s-p, then n=p*(s-p)= sp - p^2, rearranging p^2-s*p+n = 0.
- *  from the quadratic equation we have p=1/2*(s+sqrt(s*s-4*n)) and
- *  q=1/2*(s-sqrt(s*s-4*n)) if s*s-4*n is a perfect square, we are DONE.
- *  If it is not, continue in our look looking for another k. NOTE: the
- *  code actually distributes the 1/2 and results in the equations:
- *  sqrt = sqrt(s/2*s/2-n), p=s/2+sqrt, q=s/2-sqrt. The algebra saves us
- *  and extra divide by 2 and a multiply by 4.
  *
  * This will return p & q. q may be larger than p in the case that p was given
  * and it was the smaller prime.
  */
 static mp_err
-rsa_get_primes_from_exponents(mp_int *e, mp_int *d, mp_int *p, mp_int *q,
-                              mp_int *n, PRBool hasModulus,
-                              unsigned int keySizeInBits)
+rsa_get_prime_from_exponents(mp_int *e, mp_int *d, mp_int *p, mp_int *q,
+                             mp_int *n, unsigned int keySizeInBits)
 {
     mp_int kphi; /* k*phi */
     mp_int k;    /* current guess at 'k' */
     mp_int phi;  /* (p-1)(q-1) */
-    mp_int s;    /* p+q/2 (s/2 in the algebra) */
     mp_int r;    /* remainder */
-    mp_int tmp;  /* p-1 if p is given, n+1 is modulus is given */
-    mp_int sqrt; /* sqrt(s/2*s/2-n) */
+    mp_int tmp;  /* p-1 if p is given */
     mp_err err = MP_OKAY;
     unsigned int order_k;
 
     MP_DIGITS(&kphi) = 0;
     MP_DIGITS(&phi) = 0;
-    MP_DIGITS(&s) = 0;
     MP_DIGITS(&k) = 0;
     MP_DIGITS(&r) = 0;
     MP_DIGITS(&tmp) = 0;
-    MP_DIGITS(&sqrt) = 0;
     CHECK_MPI_OK(mp_init(&kphi));
     CHECK_MPI_OK(mp_init(&phi));
-    CHECK_MPI_OK(mp_init(&s));
     CHECK_MPI_OK(mp_init(&k));
     CHECK_MPI_OK(mp_init(&r));
     CHECK_MPI_OK(mp_init(&tmp));
-    CHECK_MPI_OK(mp_init(&sqrt));
 
     /* our algorithm looks for a factor k whose maximum size is dependent
      * on the size of our smallest exponent, which had better be the public
      * exponent (if it's the private, the key is vulnerable to a brute force
      * attack).
      *
      * since our factor search is linear, we need to limit the maximum
      * size of the public key. this should not be a problem normally, since
@@ -501,161 +592,103 @@ rsa_get_primes_from_exponents(mp_int *e,
     if (mp_cmp(&k, e) >= 0) {
         /* also can't be bigger then e-1 */
         CHECK_MPI_OK(mp_sub_d(e, 1, &k));
     }
 
     /* calculate our temp value */
     /* This saves recalculating this value when the k guess is wrong, which
      * is reasonably frequent. */
-    /* for the modulus case, tmp = n+1 (used to calculate p+q = tmp - phi) */
-    /* for the prime case, tmp = p-1 (used to calculate q-1= phi/tmp) */
-    if (hasModulus) {
-        CHECK_MPI_OK(mp_add_d(n, 1, &tmp));
-    } else {
-        CHECK_MPI_OK(mp_sub_d(p, 1, &tmp));
-        CHECK_MPI_OK(mp_div(&kphi, &tmp, &kphi, &r));
-        if (mp_cmp_z(&r) != 0) {
-            /* p-1 doesn't divide kphi, some parameter wasn't correct */
-            err = MP_RANGE;
-            goto cleanup;
-        }
-        mp_zero(q);
-        /* kphi is now k*(q-1) */
+    /* tmp = p-1 (used to calculate q-1= phi/tmp) */
+    CHECK_MPI_OK(mp_sub_d(p, 1, &tmp));
+    CHECK_MPI_OK(mp_div(&kphi, &tmp, &kphi, &r));
+    if (mp_cmp_z(&r) != 0) {
+        /* p-1 doesn't divide kphi, some parameter wasn't correct */
+        err = MP_RANGE;
+        goto cleanup;
     }
+    mp_zero(q);
+    /* kphi is now k*(q-1) */
 
     /* rest of the for loop */
     for (; (err == MP_OKAY) && (mpl_significant_bits(&k) >= order_k);
          err = mp_sub_d(&k, 1, &k)) {
+        CHECK_MPI_OK(err);
         /* looking for k as a factor of kphi */
         CHECK_MPI_OK(mp_div(&kphi, &k, &phi, &r));
         if (mp_cmp_z(&r) != 0) {
             /* not a factor, try the next one */
             continue;
         }
         /* we have a possible phi, see if it works */
-        if (!hasModulus) {
-            if ((unsigned)mpl_significant_bits(&phi) != keySizeInBits / 2) {
-                /* phi is not the right size */
-                continue;
-            }
-            /* phi should be divisible by 2, since
-         * q is odd and phi=(q-1). */
-            if (mpp_divis_d(&phi, 2) == MP_NO) {
-                /* phi is not divisible by 4 */
-                continue;
-            }
-            /* we now have a candidate for the second prime */
-            CHECK_MPI_OK(mp_add_d(&phi, 1, &tmp));
-
-            /* check to make sure it is prime */
-            err = rsa_is_prime(&tmp);
-            if (err != MP_OKAY) {
-                if (err == MP_NO) {
-                    /* No, then we still have the wrong phi */
-                    continue;
-                }
-                goto cleanup;
-            }
-            /*
-             * It is possible that we have the wrong phi if
-             * k_guess*(q_guess-1) = k*(q-1) (k and q-1 have swapped factors).
-             * since our q_quess is prime, however. We have found a valid
-             * rsa key because:
-             *   q is the correct order of magnitude.
-             *   phi = (p-1)(q-1) where p and q are both primes.
-             *   e*d mod phi = 1.
-             * There is no way to know from the info given if this is the
-             * original key. We never want to return the wrong key because if
-             * two moduli with the same factor is known, then euclid's gcd
-             * algorithm can be used to find that factor. Even though the
-             * caller didn't pass the original modulus, it doesn't mean the
-             * modulus wasn't known or isn't available somewhere. So to be safe
-             * if we can't be sure we have the right q, we don't return any.
-             *
-             * So to make sure we continue looking for other valid q's. If none
-             * are found, then we can safely return this one, otherwise we just
-             * fail */
-            if (mp_cmp_z(q) != 0) {
-                /* this is the second valid q, don't return either,
-                 * just fail */
-                err = MP_RANGE;
-                break;
-            }
-            /* we only have one q so far, save it and if no others are found,
-             * it's safe to return it */
-            CHECK_MPI_OK(mp_copy(&tmp, q));
-            continue;
-        }
-        /* test our tentative phi */
-        /* phi should be the correct order */
-        if ((unsigned)mpl_significant_bits(&phi) != keySizeInBits) {
+        if ((unsigned)mpl_significant_bits(&phi) != keySizeInBits / 2) {
             /* phi is not the right size */
             continue;
         }
-        /* phi should be divisible by 4, since
-         * p and q are odd and phi=(p-1)(q-1). */
-        if (mpp_divis_d(&phi, 4) == MP_NO) {
+        /* phi should be divisible by 2, since
+         * q is odd and phi=(q-1). */
+        if (mpp_divis_d(&phi, 2) == MP_NO) {
             /* phi is not divisible by 4 */
             continue;
         }
-        /* n was given, calculate s/2=(p+q)/2 */
-        CHECK_MPI_OK(mp_sub(&tmp, &phi, &s));
-        CHECK_MPI_OK(mp_div_2(&s, &s));
+        /* we now have a candidate for the second prime */
+        CHECK_MPI_OK(mp_add_d(&phi, 1, &tmp));
 
-        /* calculate sqrt(s/2*s/2-n) */
-        CHECK_MPI_OK(mp_sqr(&s, &sqrt));
-        CHECK_MPI_OK(mp_sub(&sqrt, n, &r)); /* r as a tmp */
-        CHECK_MPI_OK(mp_sqrt(&r, &sqrt));
-        /* make sure it's a perfect square */
-        /* r is our original value we took the square root of */
-        /* q is the square of our tentative square root. They should be equal*/
-        CHECK_MPI_OK(mp_sqr(&sqrt, q)); /* q as a tmp */
-        if (mp_cmp(&r, q) != 0) {
-            /* sigh according to the doc, mp_sqrt could return sqrt-1 */
-            CHECK_MPI_OK(mp_add_d(&sqrt, 1, &sqrt));
-            CHECK_MPI_OK(mp_sqr(&sqrt, q));
-            if (mp_cmp(&r, q) != 0) {
-                /* s*s-n not a perfect square, this phi isn't valid, find another.*/
+        /* check to make sure it is prime */
+        err = rsa_is_prime(&tmp);
+        if (err != MP_OKAY) {
+            if (err == MP_NO) {
+                /* No, then we still have the wrong phi */
                 continue;
             }
+            goto cleanup;
         }
-
-        /* NOTE: In this case we know we have the one and only answer.
-         * "Why?", you ask. Because:
-         *    1) n is a composite of two large primes (or it wasn't a
-         *       valid RSA modulus).
-         *    2) If we know any number such that x^2-n is a perfect square
-         *       and x is not (n+1)/2, then we can calculate 2 non-trivial
-         *       factors of n.
-         *    3) Since we know that n has only 2 non-trivial prime factors,
-         *       we know the two factors we have are the only possible factors.
-         */
-
-        /* Now we are home free to calculate p and q */
-        /* p = s/2 + sqrt, q= s/2 - sqrt */
-        CHECK_MPI_OK(mp_add(&s, &sqrt, p));
-        CHECK_MPI_OK(mp_sub(&s, &sqrt, q));
-        break;
+        /*
+         * It is possible that we have the wrong phi if
+         * k_guess*(q_guess-1) = k*(q-1) (k and q-1 have swapped factors).
+         * since our q_quess is prime, however. We have found a valid
+         * rsa key because:
+         *   q is the correct order of magnitude.
+         *   phi = (p-1)(q-1) where p and q are both primes.
+         *   e*d mod phi = 1.
+         * There is no way to know from the info given if this is the
+         * original key. We never want to return the wrong key because if
+         * two moduli with the same factor is known, then euclid's gcd
+         * algorithm can be used to find that factor. Even though the
+         * caller didn't pass the original modulus, it doesn't mean the
+         * modulus wasn't known or isn't available somewhere. So to be safe
+         * if we can't be sure we have the right q, we don't return any.
+         *
+         * So to make sure we continue looking for other valid q's. If none
+         * are found, then we can safely return this one, otherwise we just
+         * fail */
+        if (mp_cmp_z(q) != 0) {
+            /* this is the second valid q, don't return either,
+             * just fail */
+            err = MP_RANGE;
+            break;
+        }
+        /* we only have one q so far, save it and if no others are found,
+         * it's safe to return it */
+        CHECK_MPI_OK(mp_copy(&tmp, q));
+        continue;
     }
     if ((unsigned)mpl_significant_bits(&k) < order_k) {
-        if (hasModulus || (mp_cmp_z(q) == 0)) {
+        if (mp_cmp_z(q) == 0) {
             /* If we get here, something was wrong with the parameters we
              * were given */
             err = MP_RANGE;
         }
     }
 cleanup:
     mp_clear(&kphi);
     mp_clear(&phi);
-    mp_clear(&s);
     mp_clear(&k);
     mp_clear(&r);
     mp_clear(&tmp);
-    mp_clear(&sqrt);
     return err;
 }
 
 /*
  * take a private key with only a few elements and fill out the missing pieces.
  *
  * All the entries will be overwritten with data allocated out of the arena
  * If no arena is supplied, one will be created.
@@ -675,37 +708,33 @@ cleanup:
  *
  * All parameters will be replaced in the key structure with new parameters
  * Allocated out of the arena. There is no attempt to free the old structures.
  * Prime1 will always be greater than prime2 (even if the caller supplies the
  * smaller prime as prime1 or the larger prime as prime2). The parameters are
  * not overwritten on failure.
  *
  *  How it works:
- *     We can generate all the parameters from:
- *        one of the exponents, plus the two primes. (rsa_build_key_from_primes) *
+ *     We can generate all the parameters from one of the exponents, plus the
+ *        two primes. (rsa_build_key_from_primes)
  *     If we are given one of the exponents and both primes, we are done.
  *     If we are given one of the exponents, the modulus and one prime, we
  *        caclulate the second prime by dividing the modulus by the given
- *        prime, giving us and exponent and 2 primes.
- *     If we are given 2 exponents and either the modulus or one of the primes
- *        we calculate k*phi = d*e-1, where k is an integer less than d which
+ *        prime, giving us an exponent and 2 primes.
+ *     If we are given 2 exponents and one of the primes we calculate
+ *        k*phi = d*e-1, where k is an integer less than d which
  *        divides d*e-1. We find factor k so we can isolate phi.
  *            phi = (p-1)(q-1)
- *       If one of the primes are given, we can use phi to find the other prime
- *        as follows: q = (phi/(p-1)) + 1. We now have 2 primes and an
- *        exponent. (NOTE: if more then one prime meets this condition, the
- *        operation will fail. See comments elsewhere in this file about this).
- *       If the modulus is given, then we can calculate the sum of the primes
- *        as follows: s := (p+q), phi = (p-1)(q-1) = pq -p - q +1, pq = n ->
- *        phi = n - s + 1, s = n - phi +1.  Now that we have s = p+q and n=pq,
- *    we can solve our 2 equations and 2 unknowns as follows: q=s-p ->
- *        n=p*(s-p)= sp -p^2 -> p^2-sp+n = 0. Using the quadratic to solve for
- *        p, p=1/2*(s+ sqrt(s*s-4*n)) [q=1/2*(s-sqrt(s*s-4*n)]. We again have
- *        2 primes and an exponent.
+ *        We can use phi to find the other prime as follows:
+ *        q = (phi/(p-1)) + 1. We now have 2 primes and an exponent.
+ *        (NOTE: if more then one prime meets this condition, the operation
+ *        will fail. See comments elsewhere in this file about this).
+ *        (rsa_get_prime_from_exponents)
+ *     If we are given 2 exponents and the modulus we factor the modulus to
+ *        get the 2 missing primes (rsa_factorize_n_from_exponents)
  *
  */
 SECStatus
 RSA_PopulatePrivateKey(RSAPrivateKey *key)
 {
     PLArenaPool *arena = NULL;
     PRBool needPublicExponent = PR_TRUE;
     PRBool needPrivateExponent = PR_TRUE;
@@ -797,21 +826,23 @@ RSA_PopulatePrivateKey(RSAPrivateKey *ke
         }
         prime_count++;
     }
 
     /* If we didn't have enough primes try to calculate the primes from
      * the exponents */
     if (prime_count < 2) {
         /* if we don't have at least 2 primes at this point, then we need both
-     * exponents and one prime or a modulus*/
+         * exponents and one prime or a modulus*/
         if (!needPublicExponent && !needPrivateExponent &&
-            ((prime_count > 0) || hasModulus)) {
-            CHECK_MPI_OK(rsa_get_primes_from_exponents(&e, &d, &p, &q,
-                                                       &n, hasModulus, keySizeInBits));
+            (prime_count > 0)) {
+            CHECK_MPI_OK(rsa_get_prime_from_exponents(&e, &d, &p, &q, &n,
+                                                      keySizeInBits));
+        } else if (!needPublicExponent && !needPrivateExponent && hasModulus) {
+            CHECK_MPI_OK(rsa_factorize_n_from_exponents(&e, &d, &p, &q, &n));
         } else {
             /* not enough given parameters to get both primes */
             err = MP_BADARG;
             goto cleanup;
         }
     }
 
     /* Assure p > q */
--- a/security/nss/lib/ssl/sslimpl.h
+++ b/security/nss/lib/ssl/sslimpl.h
@@ -24,16 +24,17 @@
 #include "nssilock.h"
 #include "pkcs11t.h"
 #if defined(XP_UNIX) || defined(XP_BEOS)
 #include "unistd.h"
 #endif
 #include "nssrwlk.h"
 #include "prthread.h"
 #include "prclist.h"
+#include "private/pprthred.h"
 
 #include "sslt.h" /* for some formerly private types, now public */
 
 /* to make some of these old enums public without namespace pollution,
 ** it was necessary to prepend ssl_ to the names.
 ** These #defines preserve compatibility with the old code here in libssl.
 */
 typedef SSLMACAlgorithm SSL3MACAlgorithm;
@@ -93,19 +94,16 @@ extern int Debug;
 #ifdef DEBUG
 #define SSL_DBG(b) \
     if (ssl_debug) \
     ssl_Trace b
 #else
 #define SSL_DBG(b)
 #endif
 
-#include "private/pprthred.h" /* for PR_InMonitor() */
-#define ssl_InMonitor(m) PZ_InMonitor(m)
-
 #define LSB(x) ((unsigned char)((x)&0xff))
 #define MSB(x) ((unsigned char)(((unsigned)(x)) >> 8))
 
 /************************************************************************/
 
 typedef enum { SSLAppOpRead = 0,
                SSLAppOpWrite,
                SSLAppOpRDWR,
@@ -113,27 +111,24 @@ typedef enum { SSLAppOpRead = 0,
                SSLAppOpHeader
 } SSLAppOperation;
 
 #define SSL3_SESSIONID_BYTES 32
 
 #define SSL_MIN_CHALLENGE_BYTES 16
 #define SSL_MAX_CHALLENGE_BYTES 32
 
-#define SSL3_RSA_PMS_LENGTH 48
 #define SSL3_MASTER_SECRET_LENGTH 48
 
 /* number of wrap mechanisms potentially used to wrap master secrets. */
 #define SSL_NUM_WRAP_MECHS 16
 
 /* This makes the cert cache entry exactly 4k. */
 #define SSL_MAX_CACHED_CERT_LEN 4060
 
-#define NUM_MIXERS 9
-
 #ifndef BPB
 #define BPB 8 /* Bits Per Byte */
 #endif
 
 /* The default value from RFC 4347 is 1s, which is too slow. */
 #define DTLS_RETRANSMIT_INITIAL_MS 50
 /* The maximum time to wait between retransmissions. */
 #define DTLS_RETRANSMIT_MAX_MS 10000
@@ -336,17 +331,16 @@ typedef struct sslOptionsStr {
 } sslOptions;
 
 typedef enum { sslHandshakingUndetermined = 0,
                sslHandshakingAsClient,
                sslHandshakingAsServer
 } sslHandshakingType;
 
 #define SSL_LOCK_RANK_SPEC 255
-#define SSL_LOCK_RANK_GLOBAL NSS_RWLOCK_RANK_NONE
 
 /* These are the valid values for shutdownHow.
 ** These values are each 1 greater than the NSPR values, and the code
 ** depends on that relation to efficiently convert PR_SHUTDOWN values
 ** into ssl_SHUTDOWN values.  These values use one bit for read, and
 ** another bit for write, and can be used as bitmasks.
 */
 #define ssl_SHUTDOWN_NONE 0 /* NOT shutdown at all */
@@ -407,19 +401,17 @@ struct sslGatherStr {
 
     /* the start of the buffered DTLS record in dtlsPacket */
     unsigned int dtlsPacketOffset;
 };
 
 /* sslGather.state */
 #define GS_INIT 0
 #define GS_HEADER 1
-#define GS_MAC 2
-#define GS_DATA 3
-#define GS_PAD 4
+#define GS_DATA 2
 
 /*
 ** ssl3State and CipherSpec structs
 */
 
 /* The SSL bulk cipher definition */
 typedef enum {
     cipher_null,
@@ -444,41 +436,32 @@ typedef enum { type_stream,
 
 #define MAX_IV_LENGTH 24
 
 typedef PRUint64 sslSequenceNumber;
 typedef PRUint16 DTLSEpoch;
 
 typedef void (*DTLSTimerCb)(sslSocket *);
 
-/* 400 is large enough for MD5, SHA-1, and SHA-256.
- * For SHA-384 support, increase it to 712. */
-#define MAX_MAC_CONTEXT_BYTES 712
-#define MAX_MAC_CONTEXT_LLONGS (MAX_MAC_CONTEXT_BYTES / 8)
-
-#define MAX_CIPHER_CONTEXT_BYTES 2080
-#define MAX_CIPHER_CONTEXT_LLONGS (MAX_CIPHER_CONTEXT_BYTES / 8)
-
 typedef struct {
     SSL3Opaque wrapped_master_secret[48];
     PRUint16 wrapped_master_secret_len;
     PRUint8 msIsWrapped;
     PRUint8 resumable;
     PRUint8 extendedMasterSecretUsed;
 } ssl3SidKeys; /* 52 bytes */
 
 typedef struct {
     PK11SymKey *write_key;
     PK11SymKey *write_mac_key;
     PK11Context *write_mac_context;
     SECItem write_key_item;
     SECItem write_iv_item;
     SECItem write_mac_key_item;
     SSL3Opaque write_iv[MAX_IV_LENGTH];
-    PRUint64 cipher_context[MAX_CIPHER_CONTEXT_LLONGS];
 } ssl3KeyMaterial;
 
 typedef SECStatus (*SSLCipher)(void *context,
                                unsigned char *out,
                                int *outlen,
                                int maxout,
                                const unsigned char *in,
                                int inlen);
@@ -540,18 +523,16 @@ typedef struct {
     void *decompressContext;
     PK11SymKey *master_secret;
     sslSequenceNumber write_seq_num;
     sslSequenceNumber read_seq_num;
     SSL3ProtocolVersion version;
     ssl3KeyMaterial client;
     ssl3KeyMaterial server;
     SECItem msItem;
-    unsigned char key_block[NUM_MIXERS * HASH_LENGTH_MAX];
-    unsigned char raw_master_secret[56];
     DTLSEpoch epoch;
     DTLSRecvdRecords recvdRecords;
 
     PRUint8 refCt;
     const char *phase;
 } ssl3CipherSpec;
 
 typedef enum { never_cached,
--- a/security/nss/lib/ssl/tls13con.c
+++ b/security/nss/lib/ssl/tls13con.c
@@ -180,17 +180,17 @@ tls13_HandshakeState(SSL3WaitState st)
     return "unknown";
 }
 #endif
 
 #define TLS13_WAIT_STATE_MASK 0x80
 
 #define TLS13_BASE_WAIT_STATE(ws) (ws & ~TLS13_WAIT_STATE_MASK)
 /* We don't mask idle_handshake because other parts of the code use it*/
-#define TLS13_WAIT_STATE(ws) (ws == idle_handshake ? ws : ws | TLS13_WAIT_STATE_MASK)
+#define TLS13_WAIT_STATE(ws) (((ws == idle_handshake) || (ws == wait_server_hello)) ? ws : ws | TLS13_WAIT_STATE_MASK)
 #define TLS13_CHECK_HS_STATE(ss, err, ...)                          \
     tls13_CheckHsState(ss, err, #err, __func__, __FILE__, __LINE__, \
                        __VA_ARGS__,                                 \
                        wait_invalid)
 void
 tls13_SetHsState(sslSocket *ss, SSL3WaitState ws,
                  const char *func, const char *file, int line)
 {
@@ -210,17 +210,17 @@ tls13_SetHsState(sslSocket *ss, SSL3Wait
 }
 
 static PRBool
 tls13_InHsStateV(sslSocket *ss, va_list ap)
 {
     SSL3WaitState ws;
 
     while ((ws = va_arg(ap, SSL3WaitState)) != wait_invalid) {
-        if (ws == TLS13_BASE_WAIT_STATE(ss->ssl3.hs.ws)) {
+        if (TLS13_WAIT_STATE(ws) == ss->ssl3.hs.ws) {
             return PR_TRUE;
         }
     }
     return PR_FALSE;
 }
 
 PRBool
 tls13_InHsState(sslSocket *ss, ...)
--- a/security/nss/tests/cipher/cipher.txt
+++ b/security/nss/tests/cipher/cipher.txt
@@ -40,16 +40,17 @@
 	0	rc4_-E		RC4_Encrypt
 	0	rc4_-D		RC4_Decrypt
 	0	rsa_-E		RSA_Encrypt
 	0	rsa_-D		RSA_Decrypt
 	0	rsa_oaep_-E	RSA_EncryptOAEP
 	0	rsa_oaep_-D	RSA_DecryptOAEP
 	0	rsa_pss_-S	RSA_SignPSS
 	0	rsa_pss_-V	RSA_CheckSignPSS
+	0	rsa_-K		RSA_Populate
 	0	dsa_-S		DSA_Sign
 	0	dsa_-V		DSA_Verify
 	0	md2_-H		MD2_Hash
 	0	md5_-H		MD5_Hash
 	0	sha1_-H		SHA1_Hash
 	0	sha224_-H	SHA224_Hash
 	0	sha256_-H	SHA256_Hash
 	0	sha384_-H	SHA384_Hash
--- a/security/nss/tests/ssl/ssl.sh
+++ b/security/nss/tests/ssl/ssl.sh
@@ -209,23 +209,20 @@ kill_selfserv()
 start_selfserv()
 {
   if [ -n "$testname" ] ; then
       echo "$SCRIPTNAME: $testname ----"
   fi
   sparam=`echo $sparam | sed -e 's;_; ;g'`
   if [ -z "$NSS_DISABLE_ECC" ] && \
      [ -z "$NO_ECC_CERTS" -o "$NO_ECC_CERTS" != "1"  ] ; then
-      ECC_OPTIONS="-e ${HOSTADDR}-ec"
+      ECC_OPTIONS="-e ${HOSTADDR}-ecmixed -e ${HOSTADDR}-ec"
   else
       ECC_OPTIONS=""
   fi
-  if [ "$1" = "mixed" ]; then
-      ECC_OPTIONS="-e ${HOSTADDR}-ecmixed"
-  fi
   echo "selfserv starting at `date`"
   echo "selfserv -D -p ${PORT} -d ${P_R_SERVERDIR} -n ${HOSTADDR} ${SERVER_OPTIONS} \\"
   echo "         ${ECC_OPTIONS} -S ${HOSTADDR}-dsa -w nss ${sparam} -i ${R_SERVERPID}\\"
   echo "         -V ssl3:tls1.2 $verbose -H 1 &"
   if [ ${fileout} -eq 1 ]; then
       ${PROFTOOL} ${BINDIR}/selfserv -D -p ${PORT} -d ${P_R_SERVERDIR} -n ${HOSTADDR} ${SERVER_OPTIONS} \
                ${ECC_OPTIONS} -S ${HOSTADDR}-dsa -w nss ${sparam} -i ${R_SERVERPID} -V ssl3:tls1.2 $verbose -H 1 \
                > ${SERVEROUTFILE} 2>&1 &
@@ -267,17 +264,16 @@ start_selfserv()
 ssl_cov()
 {
   #verbose="-v"
   html_head "SSL Cipher Coverage $NORM_EXT - server $SERVER_MODE/client $CLIENT_MODE $ECC_STRING"
 
   testname=""
   sparam="$CIPHER_SUITES"
 
-  mixed=0
   start_selfserv # Launch the server
 
   VMIN="ssl3"
   VMAX="tls1.1"
 
   exec < ${SSLCOV}
   while read ectype testmax param testname
   do
@@ -294,44 +290,16 @@ ssl_cov()
           fi
           if [ "$testmax" = "TLS11" ]; then
               VMAX="tls1.1"
           fi
           if [ "$testmax" = "TLS12" ]; then
               VMAX="tls1.2"
           fi
 
-# These five tests need an EC cert signed with RSA
-# This requires a different certificate loaded in selfserv
-# due to a (current) NSS limitation of only loaded one cert
-# per type so the default selfserv setup will not work.
-#:C00B TLS ECDH RSA WITH NULL SHA
-#:C00C TLS ECDH RSA WITH RC4 128 SHA
-#:C00D TLS ECDH RSA WITH 3DES EDE CBC SHA
-#:C00E TLS ECDH RSA WITH AES 128 CBC SHA
-#:C00F TLS ECDH RSA WITH AES 256 CBC SHA
-
-          if [ $mixed -eq 0 ]; then
-            if [ "${param}" = ":C00B" -o "${param}" = ":C00C" -o "${param}" = ":C00D" -o "${param}" = ":C00E" -o "${param}" = ":C00F" ]; then
-              kill_selfserv
-              start_selfserv mixed
-              mixed=1
-            else
-              is_selfserv_alive
-            fi
-          else
-            if [ "${param}" = ":C00B" -o "${param}" = ":C00C" -o "${param}" = ":C00D" -o "${param}" = ":C00E" -o "${param}" = ":C00F" ]; then
-              is_selfserv_alive
-            else
-              kill_selfserv
-              start_selfserv
-              mixed=0
-            fi
-          fi
-
           echo "tstclnt -p ${PORT} -h ${HOSTADDR} -c ${param} -V ${VMIN}:${VMAX} ${CLIENT_OPTIONS} \\"
           echo "        -f -d ${P_R_CLIENTDIR} $verbose -w nss < ${REQUEST_FILE}"
 
           rm ${TMP}/$HOST.tmp.$$ 2>/dev/null
           ${PROFTOOL} ${BINDIR}/tstclnt -p ${PORT} -h ${HOSTADDR} -c ${param} -V ${VMIN}:${VMAX} ${CLIENT_OPTIONS} -f \
                   -d ${P_R_CLIENTDIR} $verbose -w nss < ${REQUEST_FILE} \
                   >${TMP}/$HOST.tmp.$$  2>&1
           ret=$?
@@ -589,25 +557,17 @@ ssl_stress()
           echo "$SCRIPTNAME: skipping  $testname (non-FIPS only)"
       elif [ "`echo $ectype | cut -b 1`" != "#" ]; then
           cparam=`echo $cparam | sed -e 's;_; ;g' -e "s/TestUser/$USER_NICKNAME/g" `
           if [ "$ectype" = "SNI" ]; then
               cparam=`echo $cparam | sed -e "s/Host/$HOST/g" -e "s/Dom/$DOMSUF/g" `
               sparam=`echo $sparam | sed -e "s/Host/$HOST/g" -e "s/Dom/$DOMSUF/g" `
           fi
 
-# These tests need the mixed cert
-# Stress TLS ECDH-RSA AES 128 CBC with SHA (no reuse)
-# Stress TLS ECDH-RSA AES 128 CBC with SHA (no reuse, client auth)
-          p=`echo "$sparam" | sed -e "s/\(.*\)\(-c_:C0..\)\(.*\)/\2/"`;
-          if [ "$p" = "-c_:C00E" ]; then
-              start_selfserv mixed
-          else
-              start_selfserv
-          fi
+          start_selfserv
 
           if [ "`uname -n`" = "sjsu" ] ; then
               echo "debugging disapering selfserv... ps -ef | grep selfserv"
               ps -ef | grep selfserv
           fi
 
           echo "strsclnt -q -p ${PORT} -d ${P_R_CLIENTDIR} ${CLIENT_OPTIONS} -w nss $cparam \\"
           echo "         -V ssl3:tls1.2 $verbose ${HOSTADDR}"
@@ -722,17 +682,16 @@ ssl_policy()
 
   if [ ! -f "${P_R_CLIENTDIR}/pkcs11.txt" ] ; then
       return;
   fi
 
   echo "Saving pkcs11.txt"
   cp ${P_R_CLIENTDIR}/pkcs11.txt ${P_R_CLIENTDIR}/pkcs11.txt.sav
 
-  mixed=0
   start_selfserv # Launch the server
 
   VMIN="ssl3"
   VMAX="tls1.2"
 
   exec < ${SSLPOLICY}
   while read value ectype testmax param policy testname
   do
@@ -748,44 +707,16 @@ ssl_policy()
           fi
           if [ "$testmax" = "TLS11" ]; then
               VMAX="tls1.1"
           fi
           if [ "$testmax" = "TLS12" ]; then
               VMAX="tls1.2"
           fi
 
-# These five tests need an EC cert signed with RSA
-# This requires a different certificate loaded in selfserv
-# due to a (current) NSS limitation of only loaded one cert
-# per type so the default selfserv setup will not work.
-#:C00B TLS ECDH RSA WITH NULL SHA
-#:C00C TLS ECDH RSA WITH RC4 128 SHA
-#:C00D TLS ECDH RSA WITH 3DES EDE CBC SHA
-#:C00E TLS ECDH RSA WITH AES 128 CBC SHA
-#:C00F TLS ECDH RSA WITH AES 256 CBC SHA
-
-          if [ $mixed -eq 0 ]; then
-            if [ "${param}" = ":C00B" -o "${param}" = ":C00C" -o "${param}" = ":C00D" -o "${param}" = ":C00E" -o "${param}" = ":C00F" ]; then
-              kill_selfserv
-              start_selfserv mixed
-              mixed=1
-            else
-              is_selfserv_alive
-            fi
-          else
-            if [ "${param}" = ":C00B" -o "${param}" = ":C00C" -o "${param}" = ":C00D" -o "${param}" = ":C00E" -o "${param}" = ":C00F" ]; then
-              is_selfserv_alive
-            else
-              kill_selfserv
-              start_selfserv
-              mixed=0
-            fi
-          fi
-
           # load the policy
           policy=`echo ${policy} | sed -e 's;_; ;g'`
 
           cat  > ${P_R_CLIENTDIR}/pkcs11.txt << ++EOF++
 library=
 name=NSS Internal PKCS #11 Module
 parameters=configdir='./client' certPrefix='' keyPrefix='' secmod='secmod.db' flags= updatedir='' updateCertPrefix='' updateKeyPrefix='' updateid='' updateTokenDescription=''
 NSS=Flags=internal,critical trustOrder=75 cipherOrder=100 slotParams=(1={slotFlags=[RSA,DSA,DH,RC2,RC4,DES,RANDOM,SHA1,MD5,MD2,SSL,TLS,AES,Camellia,SEED,SHA256,SHA512] askpw=any timeout=30})