Blob Blame History Raw
diff -up ./nss/cmd/fipstest/aesgcm.sh.fipstest ./nss/cmd/fipstest/aesgcm.sh
--- ./nss/cmd/fipstest/aesgcm.sh.fipstest	2014-09-22 11:47:43.486241359 -0700
+++ ./nss/cmd/fipstest/aesgcm.sh	2014-09-22 11:47:43.485241342 -0700
@@ -0,0 +1,63 @@
+#!/bin/sh
+#
+# A Bourne shell script for running the NIST AES Algorithm Validation Suite
+#
+# Before you run the script, set your PATH, LD_LIBRARY_PATH, ... environment
+# variables appropriately so that the fipstest command and the NSPR and NSS
+# shared libraries/DLLs are on the search path.  Then run this script in the
+# directory where the REQUEST (.req) files reside.  The script generates the
+# RESPONSE (.rsp) files in the same directory.
+
+BASEDIR=${1-.}
+TESTDIR=${BASEDIR}/AES_GCM
+COMMAND=${2-run}
+REQDIR=${TESTDIR}/req
+RSPDIR=${TESTDIR}/resp
+
+gcm_decrypt_requests="
+gcmDecrypt128.req
+gcmDecrypt192.req
+gcmDecrypt256.req
+"
+
+gcm_encrypt_extiv_requests="
+gcmEncryptExtIV128.req
+gcmEncryptExtIV192.req
+gcmEncryptExtIV256.req
+"
+gcm_encrypt_intiv_requests="
+"
+
+#gcm_encrypt_intiv_requests="
+#gcmEncryptIntIV128.req
+#gcmEncryptIntIV192.req
+#gcmEncryptIntIV256.req
+#"
+
+if [ ${COMMAND} = "verify" ]; then
+    for request in $gcm_decrypt_requests $gcm_encrypt_extiv_requests; do
+	sh ./validate1.sh ${TESTDIR} $request ' ' '-e /Reason:/d'
+    done
+    for request in $gcm_encrypt_intiv_requests; do
+	name=`basename $request .req`
+    	echo ">>>>>  $name"
+        fipstest aes gcm decrypt ${RSPDIR}/$name.rsp | grep FAIL
+    done
+    exit 0
+fi
+
+for request in $gcm_decrypt_requests; do
+    response=`echo $request | sed -e "s/req/rsp/"`
+    echo $request $response
+    fipstest aes gcm decrypt ${REQDIR}/$request > ${RSPDIR}/$response
+done
+for request in $gcm_encrypt_intiv_requests; do
+    response=`echo $request | sed -e "s/req/rsp/"`
+    echo $request $response
+    fipstest aes gcm encrypt_intiv ${REQDIR}/$request > ${RSPDIR}/$response
+done
+for request in $gcm_encrypt_extiv_requests; do
+    response=`echo $request | sed -e "s/req/rsp/"`
+    echo $request $response
+    fipstest aes gcm encrypt_extiv ${REQDIR}/$request > ${RSPDIR}/$response
+done
diff -up ./nss/cmd/fipstest/aes.sh.fipstest ./nss/cmd/fipstest/aes.sh
--- ./nss/cmd/fipstest/aes.sh.fipstest	2014-06-24 13:45:27.000000000 -0700
+++ ./nss/cmd/fipstest/aes.sh	2014-09-22 11:47:43.486241359 -0700
@@ -1,8 +1,4 @@
 #!/bin/sh
-# 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/.
-
 #
 # A Bourne shell script for running the NIST AES Algorithm Validation Suite
 #
@@ -12,6 +8,12 @@
 # directory where the REQUEST (.req) files reside.  The script generates the
 # RESPONSE (.rsp) files in the same directory.
 
+BASEDIR=${1-.}
+TESTDIR=${BASEDIR}/AES
+COMMAND=${2-run}
+REQDIR=${TESTDIR}/req
+RSPDIR=${TESTDIR}/resp
+
 cbc_kat_requests="
 CBCGFSbox128.req
 CBCGFSbox192.req
@@ -66,33 +68,40 @@ ECBMMT192.req
 ECBMMT256.req
 "
 
-for request in $ecb_kat_requests; do
+if [ ${COMMAND} = "verify" ]; then
+    for request in $cbc_kat_requests $cbc_mct_requests $cbc_mmt_requests $ecb_kat_requests $ecb_mct_requests $ecb_mmt_requests; do
+	sh ./validate1.sh ${TESTDIR} $request
+    done
+    exit 0
+fi
+
+for request in $cbc_kat_requests; do
     response=`echo $request | sed -e "s/req/rsp/"`
     echo $request $response
-    fipstest aes kat ecb $request > $response
+    fipstest aes kat cbc ${REQDIR}/$request > ${RSPDIR}/$response
 done
-for request in $ecb_mmt_requests; do
+for request in $cbc_mct_requests; do
     response=`echo $request | sed -e "s/req/rsp/"`
     echo $request $response
-    fipstest aes mmt ecb $request > $response
+    fipstest aes mct cbc ${REQDIR}/$request > ${RSPDIR}/$response
 done
-for request in $ecb_mct_requests; do
+for request in $cbc_mmt_requests; do
     response=`echo $request | sed -e "s/req/rsp/"`
     echo $request $response
-    fipstest aes mct ecb $request > $response
+    fipstest aes mmt cbc ${REQDIR}/$request > ${RSPDIR}/$response
 done
-for request in $cbc_kat_requests; do
+for request in $ecb_kat_requests; do
     response=`echo $request | sed -e "s/req/rsp/"`
     echo $request $response
-    fipstest aes kat cbc $request > $response
+    fipstest aes kat ecb ${REQDIR}/$request > ${RSPDIR}/$response
 done
-for request in $cbc_mmt_requests; do
+for request in $ecb_mct_requests; do
     response=`echo $request | sed -e "s/req/rsp/"`
     echo $request $response
-    fipstest aes mmt cbc $request > $response
+    fipstest aes mct ecb ${REQDIR}/$request > ${RSPDIR}/$response
 done
-for request in $cbc_mct_requests; do
+for request in $ecb_mmt_requests; do
     response=`echo $request | sed -e "s/req/rsp/"`
     echo $request $response
-    fipstest aes mct cbc $request > $response
+    fipstest aes mmt ecb ${REQDIR}/$request > ${RSPDIR}/$response
 done
diff -up ./nss/cmd/fipstest/dsa.sh.fipstest ./nss/cmd/fipstest/dsa.sh
--- ./nss/cmd/fipstest/dsa.sh.fipstest	2014-06-24 13:45:27.000000000 -0700
+++ ./nss/cmd/fipstest/dsa.sh	2014-09-22 11:47:43.486241359 -0700
@@ -1,8 +1,4 @@
 #!/bin/sh
-# 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/.
-
 #
 # A Bourne shell script for running the NIST DSA Validation System
 #
@@ -11,28 +7,61 @@
 # shared libraries/DLLs are on the search path.  Then run this script in the
 # directory where the REQUEST (.req) files reside.  The script generates the
 # RESPONSE (.rsp) files in the same directory.
+BASEDIR=${1-.}
+TESTDIR=${BASEDIR}/DSA2
+COMMAND=${2-run}
+REQDIR=${TESTDIR}/req
+RSPDIR=${TESTDIR}/resp
+
+
+#
+# several of the DSA tests do use known answer tests to verify the result.
+# in those cases, feed generated tests back into the fipstest tool and
+# see if we can verify those value. NOTE: th PQGVer and SigVer tests verify
+# the dsa pqgver and dsa sigver functions, so we know they can detect errors
+# in those PQGGen and SigGen. Only the KeyPair verify is potentially circular.
+#
+if [ ${COMMAND} = "verify" ]; then
+# verify generated keys
+    name=KeyPair
+    echo ">>>>>  $name"
+    fipstest dsa keyver ${RSPDIR}/$name.rsp | grep ^Result.=.F
+# verify generated pqg values
+    name=PQGGen
+    echo ">>>>>  $name"
+    fipstest dsa pqgver ${RSPDIR}/$name.rsp | grep ^Result.=.F
+# verify PQGVer with known answer
+#    sh ./validate1.sh ${TESTDIR} PQGVer.req ' ' '-e /^Result.=.F/s;.(.*);; -e /^Result.=.P/s;.(.*);;'
+# verify signatures
+    name=SigGen
+    echo ">>>>>  $name"
+    fipstest dsa sigver ${RSPDIR}/$name.rsp | grep ^Result.=.F
+# verify SigVer with known answer
+    sh ./validate1.sh ${TESTDIR} SigVer.req ' ' '-e /^X.=/d -e /^Result.=.F/s;.(.*);;'
+    exit 0
+fi
 
 request=KeyPair.req
 response=`echo $request | sed -e "s/req/rsp/"`
 echo $request $response
-fipstest dsa keypair $request > $response
+fipstest dsa keypair ${REQDIR}/$request > ${RSPDIR}/$response
 
 request=PQGGen.req
 response=`echo $request | sed -e "s/req/rsp/"`
 echo $request $response
-fipstest dsa pqggen $request > $response
+fipstest dsa pqggen ${REQDIR}/$request > ${RSPDIR}/$response
 
-request=PQGVer.req
+request=PQGVer1863.req
 response=`echo $request | sed -e "s/req/rsp/"`
 echo $request $response
-fipstest dsa pqgver $request > $response
+fipstest dsa pqgver ${REQDIR}/$request > ${RSPDIR}/$response
 
 request=SigGen.req
 response=`echo $request | sed -e "s/req/rsp/"`
 echo $request $response
-fipstest dsa siggen $request > $response
+fipstest dsa siggen ${REQDIR}/$request > ${RSPDIR}/$response
 
 request=SigVer.req
 response=`echo $request | sed -e "s/req/rsp/"`
 echo $request $response
-fipstest dsa sigver $request > $response
+fipstest dsa sigver ${REQDIR}/$request > ${RSPDIR}/$response
diff -up ./nss/cmd/fipstest/ecdsa.sh.fipstest ./nss/cmd/fipstest/ecdsa.sh
--- ./nss/cmd/fipstest/ecdsa.sh.fipstest	2014-06-24 13:45:27.000000000 -0700
+++ ./nss/cmd/fipstest/ecdsa.sh	2014-09-22 11:47:43.487241376 -0700
@@ -1,8 +1,4 @@
 #!/bin/sh
-# 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/.
-
 #
 # A Bourne shell script for running the NIST ECDSA Validation System
 #
@@ -11,23 +7,50 @@
 # shared libraries/DLLs are on the search path.  Then run this script in the
 # directory where the REQUEST (.req) files reside.  The script generates the
 # RESPONSE (.rsp) files in the same directory.
+BASEDIR=${1-.}
+TESTDIR=${BASEDIR}/ECDSA2
+COMMAND=${2-run}
+REQDIR=${TESTDIR}/req
+RSPDIR=${TESTDIR}/resp
+
+#
+# several of the ECDSA tests do not use known answer tests to verify the result.
+# In those cases, feed generated tests back into the fipstest tool and
+# see if we can verify those value. NOTE:  PQGVer and SigVer tests verify
+# the dsa pqgver and dsa sigver functions, so we know they can detect errors
+# in those PQGGen and SigGen. Only the KeyPair verify is potentially circular.
+#
+if [ ${COMMAND} = "verify" ]; then
+# verify generated keys
+    name=KeyPair
+    echo ">>>>>  $name"
+    fipstest ecdsa keyver ${RSPDIR}/$name.rsp | grep ^Result.=.F
+    sh ./validate1.sh ${TESTDIR} PKV.req ' ' '-e /^X.=/d -e /^Result.=.F/s;.(.*);; -e /^Result.=.P/s;.(.*);;'
+# verify signatures
+    name=SigGen
+    echo ">>>>>  $name"
+    fipstest ecdsa sigver ${RSPDIR}/$name.rsp | grep ^Result.=.F
+# verify SigVer with known answer
+    sh ./validate1.sh ${TESTDIR} SigVer.req ' ' '-e /^X.=/d -e /^Result.=.F/s;.(.*);; -e /^Result.=.P/s;.(.*);;'
+    exit 0
+fi
 
 request=KeyPair.req
 response=`echo $request | sed -e "s/req/rsp/"`
 echo $request $response
-fipstest ecdsa keypair $request > $response
+fipstest ecdsa keypair ${REQDIR}/$request > ${RSPDIR}/$response
 
 request=PKV.req
 response=`echo $request | sed -e "s/req/rsp/"`
 echo $request $response
-fipstest ecdsa pkv $request > $response
+fipstest ecdsa pkv ${REQDIR}/$request > ${RSPDIR}/$response
 
 request=SigGen.req
 response=`echo $request | sed -e "s/req/rsp/"`
 echo $request $response
-fipstest ecdsa siggen $request > $response
+fipstest ecdsa siggen ${REQDIR}/$request > ${RSPDIR}/$response
 
 request=SigVer.req
 response=`echo $request | sed -e "s/req/rsp/"`
 echo $request $response
-fipstest ecdsa sigver $request > $response
+fipstest ecdsa sigver ${REQDIR}/$request > ${RSPDIR}/$response
diff -up ./nss/cmd/fipstest/fipstest.c.fipstest ./nss/cmd/fipstest/fipstest.c
--- ./nss/cmd/fipstest/fipstest.c.fipstest	2014-06-24 13:45:27.000000000 -0700
+++ ./nss/cmd/fipstest/fipstest.c	2014-09-22 11:49:03.518587576 -0700
@@ -17,6 +17,21 @@
 #include "hasht.h"
 #include "lowkeyi.h"
 #include "softoken.h"
+#include "pkcs11t.h"
+#define __PASTE(x,y) x##y
+#undef CK_PKCS11_FUNCTION_INFO
+#undef CK_NEED_ARG_LIST
+#define CK_EXTERN extern
+#define CK_PKCS11_FUNCTION_INFO(func) \
+                CK_RV __PASTE(NS,func)
+#define CK_NEED_ARG_LIST        1
+#include "pkcs11f.h"
+#undef CK_PKCS11_FUNCTION_INFO
+#undef CK_NEED_ARG_LIST
+#undef __PASTE
+#define SSL3_RANDOM_LENGTH              32
+
+
 
 #if 0
 #include "../../lib/freebl/mpi/mpi.h"
@@ -46,18 +61,18 @@ hex_to_byteval(const char *c2, unsigned
     unsigned char offset;
     *byteval = 0;
     for (i=0; i<2; i++) {
-	if (c2[i] >= '0' && c2[i] <= '9') {
-	    offset = c2[i] - '0';
-	    *byteval |= offset << 4*(1-i);
-	} else if (c2[i] >= 'a' && c2[i] <= 'f') {
-	    offset = c2[i] - 'a';
-	    *byteval |= (offset + 10) << 4*(1-i);
-	} else if (c2[i] >= 'A' && c2[i] <= 'F') {
-	    offset = c2[i] - 'A';
-	    *byteval |= (offset + 10) << 4*(1-i);
-	} else {
-	    return SECFailure;
-	}
+        if (c2[i] >= '0' && c2[i] <= '9') {
+            offset = c2[i] - '0';
+            *byteval |= offset << 4*(1-i);
+        } else if (c2[i] >= 'a' && c2[i] <= 'f') {
+            offset = c2[i] - 'a';
+            *byteval |= (offset + 10) << 4*(1-i);
+        } else if (c2[i] >= 'A' && c2[i] <= 'F') {
+            offset = c2[i] - 'A';
+            *byteval |= (offset + 10) << 4*(1-i);
+        } else {
+            return SECFailure;
+        }
     }
     return SECSuccess;
 }
@@ -68,12 +83,12 @@ byteval_to_hex(unsigned char byteval, ch
     int i;
     unsigned char offset;
     for (i=0; i<2; i++) {
-	offset = (byteval >> 4*(1-i)) & 0x0f;
-	if (offset < 10) {
-	    c2[i] = '0' + offset;
-	} else {
-	    c2[i] = a + offset - 10;
-	}
+        offset = (byteval >> 4*(1-i)) & 0x0f;
+        if (offset < 10) {
+            c2[i] = '0' + offset;
+        } else {
+            c2[i] = a + offset - 10;
+        }
     }
     return SECSuccess;
 }
@@ -83,7 +98,7 @@ to_hex_str(char *str, const unsigned cha
 {
     unsigned int i;
     for (i=0; i<len; i++) {
-	byteval_to_hex(buf[i], &str[2*i], 'a');
+        byteval_to_hex(buf[i], &str[2*i], 'a');
     }
     str[2*len] = '\0';
 }
@@ -93,7 +108,7 @@ to_hex_str_cap(char *str, const unsigned
 {
     unsigned int i;
     for (i=0; i<len; i++) {
-	byteval_to_hex(buf[i], &str[2*i], 'A');
+        byteval_to_hex(buf[i], &str[2*i], 'A');
     }
     str[2*len] = '\0';
 }
@@ -113,41 +128,41 @@ from_hex_str(unsigned char *buf, unsigne
     /* count the hex digits */
     nxdigit = 0;
     for (nxdigit = 0; isxdigit(str[nxdigit]); nxdigit++) {
-	/* empty body */
+        /* empty body */
     }
     if (nxdigit == 0) {
-	return PR_FALSE;
+        return PR_FALSE;
     }
     if (nxdigit > 2*len) {
-	/*
-	 * The input hex string is too long, but we allow it if the
-	 * extra digits are leading 0's.
-	 */
-	for (j = 0; j < nxdigit-2*len; j++) {
-	    if (str[j] != '0') {
-		return PR_FALSE;
-	    }
-	}
-	/* skip leading 0's */
-	str += nxdigit-2*len;
-	nxdigit = 2*len;
+        /*
+         * The input hex string is too long, but we allow it if the
+         * extra digits are leading 0's.
+         */
+        for (j = 0; j < nxdigit-2*len; j++) {
+            if (str[j] != '0') {
+                return PR_FALSE;
+            }
+        }
+        /* skip leading 0's */
+        str += nxdigit-2*len;
+        nxdigit = 2*len;
     }
     for (i=0, j=0; i< len; i++) {
-	if (2*i < 2*len-nxdigit) {
-	    /* Handle a short input as if we padded it with leading 0's. */
-	    if (2*i+1 < 2*len-nxdigit) {
-		buf[i] = 0;
-	    } else {
-		char tmp[2];
-		tmp[0] = '0';
-		tmp[1] = str[j];
-		hex_to_byteval(tmp, &buf[i]);
-		j++;
-	    }
-	} else {
-	    hex_to_byteval(&str[j], &buf[i]);
-	    j += 2;
-	}
+        if (2*i < 2*len-nxdigit) {
+            /* Handle a short input as if we padded it with leading 0's. */
+            if (2*i+1 < 2*len-nxdigit) {
+                buf[i] = 0;
+            } else {
+                char tmp[2];
+                tmp[0] = '0';
+                tmp[1] = str[j];
+                hex_to_byteval(tmp, &buf[i]);
+                j++;
+            }
+        } else {
+            hex_to_byteval(&str[j], &buf[i]);
+            j += 2;
+        }
     }
     return PR_TRUE;
 }
@@ -292,7 +307,7 @@ tdea_kat_mmt(char *reqfn)
     int crypt = DECRYPT;    /* 1 means encrypt, 0 means decrypt */
     unsigned char key[24];              /* TDEA 3 key bundle */
     unsigned int numKeys = 0;
-    unsigned char iv[8];		/* for all modes except ECB */
+    unsigned char iv[8];                /* for all modes except ECB */
     unsigned char plaintext[8*20];     /* 1 to 20 blocks */
     unsigned int plaintextlen;
     unsigned char ciphertext[8*20];   /* 1 to 20 blocks */  
@@ -876,14 +891,14 @@ aes_encrypt_buf(
 
     cx = AES_CreateContext(key, iv, mode, PR_TRUE, keysize, 16);
     if (cx == NULL) {
-	goto loser;
+        goto loser;
     }
     rv = AES_Encrypt(cx, output, outputlen, maxoutputlen, input, inputlen);
     if (rv != SECSuccess) {
-	goto loser;
+        goto loser;
     }
     if (*outputlen != inputlen) {
-	goto loser;
+        goto loser;
     }
     AES_DestroyContext(cx, PR_TRUE);
     cx = NULL;
@@ -894,26 +909,26 @@ aes_encrypt_buf(
      */
     cx = AES_CreateContext(key, iv, mode, PR_FALSE, keysize, 16);
     if (cx == NULL) {
-	goto loser;
+        goto loser;
     }
     rv = AES_Decrypt(cx, doublecheck, &doublechecklen, sizeof doublecheck,
-	output, *outputlen);
+        output, *outputlen);
     if (rv != SECSuccess) {
-	goto loser;
+        goto loser;
     }
     if (doublechecklen != *outputlen) {
-	goto loser;
+        goto loser;
     }
     AES_DestroyContext(cx, PR_TRUE);
     cx = NULL;
     if (memcmp(doublecheck, input, inputlen) != 0) {
-	goto loser;
+        goto loser;
     }
     rv = SECSuccess;
 
 loser:
     if (cx != NULL) {
-	AES_DestroyContext(cx, PR_TRUE);
+        AES_DestroyContext(cx, PR_TRUE);
     }
     return rv;
 }
@@ -933,15 +948,15 @@ aes_decrypt_buf(
 
     cx = AES_CreateContext(key, iv, mode, PR_FALSE, keysize, 16);
     if (cx == NULL) {
-	goto loser;
+        goto loser;
     }
     rv = AES_Decrypt(cx, output, outputlen, maxoutputlen,
-	input, inputlen);
+        input, inputlen);
     if (rv != SECSuccess) {
-	goto loser;
+        goto loser;
     }
     if (*outputlen != inputlen) {
-	goto loser;
+        goto loser;
     }
     AES_DestroyContext(cx, PR_TRUE);
     cx = NULL;
@@ -952,43 +967,38 @@ aes_decrypt_buf(
      */
     cx = AES_CreateContext(key, iv, mode, PR_TRUE, keysize, 16);
     if (cx == NULL) {
-	goto loser;
+        goto loser;
     }
     rv = AES_Encrypt(cx, doublecheck, &doublechecklen, sizeof doublecheck,
-	output, *outputlen);
+        output, *outputlen);
     if (rv != SECSuccess) {
-	goto loser;
+        goto loser;
     }
     if (doublechecklen != *outputlen) {
-	goto loser;
+        goto loser;
     }
     AES_DestroyContext(cx, PR_TRUE);
     cx = NULL;
     if (memcmp(doublecheck, input, inputlen) != 0) {
-	goto loser;
+        goto loser;
     }
     rv = SECSuccess;
 
 loser:
     if (cx != NULL) {
-	AES_DestroyContext(cx, PR_TRUE);
+        AES_DestroyContext(cx, PR_TRUE);
     }
     return rv;
 }
-
 /*
- * Perform the AES Known Answer Test (KAT) or Multi-block Message
- * Test (MMT) in ECB or CBC mode.  The KAT (there are four types)
- * and MMT have the same structure: given the key and IV (CBC mode
- * only), encrypt the given plaintext or decrypt the given ciphertext.
- * So we can handle them the same way.
+ * Perform the AES GCM tests.
  *
  * reqfn is the pathname of the REQUEST file.
  *
  * The output RESPONSE file is written to stdout.
  */
 void
-aes_kat_mmt(char *reqfn)
+aes_gcm(char *reqfn, int encrypt)
 {
     char buf[512];      /* holds one line from the input REQUEST file.
                          * needs to be large enough to hold the longest
@@ -997,214 +1007,435 @@ aes_kat_mmt(char *reqfn)
     FILE *aesreq;       /* input stream from the REQUEST file */
     FILE *aesresp;      /* output stream to the RESPONSE file */
     int i, j;
-    int mode;           /* NSS_AES (ECB) or NSS_AES_CBC */
-    int encrypt = 0;    /* 1 means encrypt, 0 means decrypt */
     unsigned char key[32];              /* 128, 192, or 256 bits */
     unsigned int keysize;
-    unsigned char iv[16];		/* for all modes except ECB */
+    unsigned char iv[128];                /* handle large gcm IV's */
     unsigned char plaintext[10*16];     /* 1 to 10 blocks */
     unsigned int plaintextlen;
-    unsigned char ciphertext[10*16];    /* 1 to 10 blocks */
+    unsigned char ciphertext[11*16];    /* 1 to 10 blocks + tag */
     unsigned int ciphertextlen;
+    unsigned char aad[10*16];            /* 1 to 10 blocks + tag */
+    unsigned int aadlen;
+    unsigned int tagbits;
+    unsigned int taglen;
+    unsigned int ivlen;
+    CK_GCM_PARAMS params;
     SECStatus rv;
 
     aesreq = fopen(reqfn, "r");
     aesresp = stdout;
     while (fgets(buf, sizeof buf, aesreq) != NULL) {
-	/* a comment or blank line */
-	if (buf[0] == '#' || buf[0] == '\n') {
-	    fputs(buf, aesresp);
-	    continue;
-	}
-	/* [ENCRYPT] or [DECRYPT] */
-	if (buf[0] == '[') {
-	    if (strncmp(&buf[1], "ENCRYPT", 7) == 0) {
-		encrypt = 1;
-	    } else {
-		encrypt = 0;
-	    }
-	    fputs(buf, aesresp);
-	    continue;
-	}
-	/* "COUNT = x" begins a new data set */
-	if (strncmp(buf, "COUNT", 5) == 0) {
-	    mode = NSS_AES;
-	    /* zeroize the variables for the test with this data set */
-	    memset(key, 0, sizeof key);
-	    keysize = 0;
-	    memset(iv, 0, sizeof iv);
-	    memset(plaintext, 0, sizeof plaintext);
-	    plaintextlen = 0;
-	    memset(ciphertext, 0, sizeof ciphertext);
-	    ciphertextlen = 0;
-	    fputs(buf, aesresp);
-	    continue;
-	}
-	/* KEY = ... */
-	if (strncmp(buf, "KEY", 3) == 0) {
-	    i = 3;
-	    while (isspace(buf[i]) || buf[i] == '=') {
-		i++;
-	    }
-	    for (j=0; isxdigit(buf[i]); i+=2,j++) {
-		hex_to_byteval(&buf[i], &key[j]);
-	    }
-	    keysize = j;
-	    fputs(buf, aesresp);
-	    continue;
-	}
-	/* IV = ... */
-	if (strncmp(buf, "IV", 2) == 0) {
-	    mode = NSS_AES_CBC;
-	    i = 2;
-	    while (isspace(buf[i]) || buf[i] == '=') {
-		i++;
-	    }
-	    for (j=0; j<sizeof iv; i+=2,j++) {
-		hex_to_byteval(&buf[i], &iv[j]);
-	    }
-	    fputs(buf, aesresp);
-	    continue;
-	}
-	/* PLAINTEXT = ... */
-	if (strncmp(buf, "PLAINTEXT", 9) == 0) {
-	    /* sanity check */
-	    if (!encrypt) {
-		goto loser;
-	    }
-
-	    i = 9;
-	    while (isspace(buf[i]) || buf[i] == '=') {
-		i++;
-	    }
-	    for (j=0; isxdigit(buf[i]); i+=2,j++) {
-		hex_to_byteval(&buf[i], &plaintext[j]);
-	    }
-	    plaintextlen = j;
-
-	    rv = aes_encrypt_buf(mode, key, keysize,
-		(mode == NSS_AES) ? NULL : iv,
-		ciphertext, &ciphertextlen, sizeof ciphertext,
-		plaintext, plaintextlen);
-	    if (rv != SECSuccess) {
-		goto loser;
-	    }
+        /* a comment or blank line */
+        if (buf[0] == '#' || buf[0] == '\n') {
+            fputs(buf, aesresp);
+            continue;
+        }
+        /* [ENCRYPT] or [DECRYPT] */
+        if (buf[0] == '[') {
+            if (strncmp(buf, "[Taglen", 7)  == 0) {
+                if (sscanf(buf, "[Taglen = %d]", &tagbits) != 1) {
+                    goto loser;
+                }
+                taglen = tagbits/8;
+            } 
+            if (strncmp(buf, "[IVlen", 6)  == 0) {
+                if (sscanf(buf, "[IVlen = %d]", &ivlen) != 1) {
+                    goto loser;
+                }
+                ivlen=ivlen/8;
+            } 
+            fputs(buf, aesresp);
+            continue;
+        }
+        /* "COUNT = x" begins a new data set */
+        if (strncmp(buf, "Count", 5) == 0) {
+            /* zeroize the variables for the test with this data set */
+            memset(key, 0, sizeof key);
+            keysize = 0;
+            memset(iv, 0, sizeof iv);
+            memset(plaintext, 0, sizeof plaintext);
+            plaintextlen = 0;
+            memset(ciphertext, 0, sizeof ciphertext);
+            ciphertextlen = 0;
+            fputs(buf, aesresp);
+            continue;
+        }
+        /* KEY = ... */
+        if (strncmp(buf, "Key", 3) == 0) {
+            i = 3;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            for (j=0; isxdigit(buf[i]); i+=2,j++) {
+                hex_to_byteval(&buf[i], &key[j]);
+            }
+            keysize = j;
+            fputs(buf, aesresp);
+            continue;
+        }
+        /* IV = ... */
+        if (strncmp(buf, "IV", 2) == 0) {
+            i = 2;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            for (j=0; j<sizeof iv; i+=2,j++) {
+                hex_to_byteval(&buf[i], &iv[j]);
+            }
+            fputs(buf, aesresp);
+            continue;
+        }
+        /* PLAINTEXT = ... */
+        if (strncmp(buf, "PT", 2) == 0) {
+            /* sanity check */
+            if (!encrypt) {
+                goto loser;
+            }
 
-	    fputs(buf, aesresp);
-	    fputs("CIPHERTEXT = ", aesresp);
-	    to_hex_str(buf, ciphertext, ciphertextlen);
-	    fputs(buf, aesresp);
-	    fputc('\n', aesresp);
-	    continue;
-	}
-	/* CIPHERTEXT = ... */
-	if (strncmp(buf, "CIPHERTEXT", 10) == 0) {
-	    /* sanity check */
-	    if (encrypt) {
-		goto loser;
-	    }
+            i = 2;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            for (j=0; isxdigit(buf[i]); i+=2,j++) {
+                hex_to_byteval(&buf[i], &plaintext[j]);
+            }
+            plaintextlen = j;
+            fputs(buf, aesresp);
+            continue;
+        }
+        /* CIPHERTEXT = ... */
+        if (strncmp(buf, "CT", 2) == 0) {
+            /* sanity check */
+            if (encrypt) {
+                goto loser;
+            }
 
-	    i = 10;
-	    while (isspace(buf[i]) || buf[i] == '=') {
-		i++;
-	    }
-	    for (j=0; isxdigit(buf[i]); i+=2,j++) {
-		hex_to_byteval(&buf[i], &ciphertext[j]);
-	    }
-	    ciphertextlen = j;
+            i = 2;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            for (j=0; isxdigit(buf[i]); i+=2,j++) {
+                hex_to_byteval(&buf[i], &ciphertext[j]);
+            }
+            ciphertextlen = j;
+            fputs(buf, aesresp);
+            continue;
+        }
+        if (strncmp(buf, "AAD", 3) == 0) {
+            i = 3;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            for (j=0; isxdigit(buf[i]); i+=2,j++) {
+                hex_to_byteval(&buf[i], &aad[j]);
+            }
+            aadlen = j;
+            fputs(buf, aesresp);
+            if (encrypt) {
+                if (encrypt == 2) {
+                    rv = RNG_GenerateGlobalRandomBytes(iv, ivlen);
+                    if (rv != SECSuccess) {
+                        goto loser;
+                    }
+                }
+                params.pIv = iv;
+                params.ulIvLen = ivlen;
+                params.pAAD = aad;
+                params.ulAADLen = aadlen;
+                params.ulTagBits = tagbits;
+                rv = aes_encrypt_buf(NSS_AES_GCM, key, keysize,
+                (unsigned char *)&params,
+                ciphertext, &ciphertextlen, sizeof ciphertext,
+                plaintext, plaintextlen);
+                if (rv != SECSuccess) {
+                    goto loser;
+                }
 
-	    rv = aes_decrypt_buf(mode, key, keysize,
-		(mode == NSS_AES) ? NULL : iv,
-		plaintext, &plaintextlen, sizeof plaintext,
-		ciphertext, ciphertextlen);
-	    if (rv != SECSuccess) {
-		goto loser;
-	    }
+		if (encrypt == 2) {
+                    fputs("IV = ", aesresp);
+                    to_hex_str(buf, iv, ivlen);
+                    fputs(buf, aesresp);
+                    fputc('\n', aesresp);
+		}
+                fputs("CT = ", aesresp);
+                j = ciphertextlen-taglen;
+                to_hex_str(buf, ciphertext, j);
+                fputs(buf, aesresp);
+                fputs("\nTag = ", aesresp);
+                to_hex_str(buf, ciphertext+j, taglen);
+                fputs(buf, aesresp);
+                fputc('\n', aesresp);
+            }
+            continue;
+        }
+        if (strncmp(buf, "Tag", 3) == 0) {
+            /* sanity check */
+            if (encrypt) {
+                goto loser;
+            }
 
-	    fputs(buf, aesresp);
-	    fputs("PLAINTEXT = ", aesresp);
-	    to_hex_str(buf, plaintext, plaintextlen);
-	    fputs(buf, aesresp);
-	    fputc('\n', aesresp);
-	    continue;
-	}
+            i = 3;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            for (j=0; isxdigit(buf[i]); i+=2,j++) {
+                hex_to_byteval(&buf[i], &ciphertext[j+ciphertextlen]);
+            }
+            ciphertextlen += j;
+            params.pIv = iv;
+            params.ulIvLen = ivlen;
+            params.pAAD = aad;
+            params.ulAADLen = aadlen;
+            params.ulTagBits = tagbits;
+            rv = aes_decrypt_buf(NSS_AES_GCM, key, keysize,
+                (unsigned char *)&params,
+                plaintext, &plaintextlen, sizeof plaintext,
+                ciphertext, ciphertextlen);
+            fputs(buf, aesresp);
+            if (rv != SECSuccess) {
+                fprintf(aesresp,"FAIL\n");
+            } else {
+                fputs("PT = ", aesresp);
+                to_hex_str(buf, plaintext, plaintextlen);
+                fputs(buf, aesresp);
+                fputc('\n', aesresp);
+            }
+            continue;
+        }
     }
 loser:
     fclose(aesreq);
 }
 
 /*
- * Generate Key[i+1] from Key[i], CT[j-1], and CT[j] for AES Monte Carlo
- * Test (MCT) in ECB and CBC modes.
- */
-void
-aes_mct_next_key(unsigned char *key, unsigned int keysize,
-    const unsigned char *ciphertext_1, const unsigned char *ciphertext)
-{
-    int k;
-
-    switch (keysize) {
-    case 16:  /* 128-bit key */
-	/* Key[i+1] = Key[i] xor CT[j] */
-	for (k=0; k<16; k++) {
-	    key[k] ^= ciphertext[k];
-	}
-	break;
-    case 24:  /* 192-bit key */
-	/*
-	 * Key[i+1] = Key[i] xor (last 64-bits of
-	 *            CT[j-1] || CT[j])
-	 */
-	for (k=0; k<8; k++) {
-	    key[k] ^= ciphertext_1[k+8];
-	}
-	for (k=8; k<24; k++) {
-	    key[k] ^= ciphertext[k-8];
-	}
-	break;
-    case 32:  /* 256-bit key */
-	/* Key[i+1] = Key[i] xor (CT[j-1] || CT[j]) */
-	for (k=0; k<16; k++) {
-	    key[k] ^= ciphertext_1[k];
-	}
-	for (k=16; k<32; k++) {
-	    key[k] ^= ciphertext[k-16];
-	}
-	break;
-    }
-}
-
-/*
- * Perform the AES Monte Carlo Test (MCT) in ECB mode.  MCT exercises
- * our AES code in streaming mode because the plaintext or ciphertext
- * is generated block by block as we go, so we can't collect all the
- * plaintext or ciphertext in one buffer and encrypt or decrypt it in
- * one shot.
+ * Perform the AES Known Answer Test (KAT) or Multi-block Message
+ * Test (MMT) in ECB or CBC mode.  The KAT (there are four types)
+ * and MMT have the same structure: given the key and IV (CBC mode
+ * only), encrypt the given plaintext or decrypt the given ciphertext.
+ * So we can handle them the same way.
  *
- * reqfn is the pathname of the input REQUEST file.
+ * reqfn is the pathname of the REQUEST file.
  *
  * The output RESPONSE file is written to stdout.
  */
 void
-aes_ecb_mct(char *reqfn)
+aes_kat_mmt(char *reqfn)
 {
-    char buf[80];       /* holds one line from the input REQUEST file.
+    char buf[512];      /* holds one line from the input REQUEST file.
                          * needs to be large enough to hold the longest
-                         * line "KEY = <64 hex digits>\n".
+                         * line "CIPHERTEXT = <320 hex digits>\n".
                          */
     FILE *aesreq;       /* input stream from the REQUEST file */
     FILE *aesresp;      /* output stream to the RESPONSE file */
     int i, j;
+    int mode;           /* NSS_AES (ECB) or NSS_AES_CBC */
     int encrypt = 0;    /* 1 means encrypt, 0 means decrypt */
     unsigned char key[32];              /* 128, 192, or 256 bits */
     unsigned int keysize;
-    unsigned char plaintext[16];        /* PT[j] */
-    unsigned char plaintext_1[16];      /* PT[j-1] */
-    unsigned char ciphertext[16];       /* CT[j] */
+    unsigned char iv[16];                /* for all modes except ECB */
+    unsigned char plaintext[10*16];     /* 1 to 10 blocks */
+    unsigned int plaintextlen;
+    unsigned char ciphertext[10*16];    /* 1 to 10 blocks */
+    unsigned int ciphertextlen;
+    SECStatus rv;
+
+    aesreq = fopen(reqfn, "r");
+    aesresp = stdout;
+    while (fgets(buf, sizeof buf, aesreq) != NULL) {
+        /* a comment or blank line */
+        if (buf[0] == '#' || buf[0] == '\n') {
+            fputs(buf, aesresp);
+            continue;
+        }
+        /* [ENCRYPT] or [DECRYPT] */
+        if (buf[0] == '[') {
+            if (strncmp(&buf[1], "ENCRYPT", 7) == 0) {
+                encrypt = 1;
+            } else {
+                encrypt = 0;
+            }
+            fputs(buf, aesresp);
+            continue;
+        }
+        /* "COUNT = x" begins a new data set */
+        if (strncmp(buf, "COUNT", 5) == 0) {
+            mode = NSS_AES;
+            /* zeroize the variables for the test with this data set */
+            memset(key, 0, sizeof key);
+            keysize = 0;
+            memset(iv, 0, sizeof iv);
+            memset(plaintext, 0, sizeof plaintext);
+            plaintextlen = 0;
+            memset(ciphertext, 0, sizeof ciphertext);
+            ciphertextlen = 0;
+            fputs(buf, aesresp);
+            continue;
+        }
+        /* KEY = ... */
+        if (strncmp(buf, "KEY", 3) == 0) {
+            i = 3;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            for (j=0; isxdigit(buf[i]); i+=2,j++) {
+                hex_to_byteval(&buf[i], &key[j]);
+            }
+            keysize = j;
+            fputs(buf, aesresp);
+            continue;
+        }
+        /* IV = ... */
+        if (strncmp(buf, "IV", 2) == 0) {
+            mode = NSS_AES_CBC;
+            i = 2;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            for (j=0; j<sizeof iv; i+=2,j++) {
+                hex_to_byteval(&buf[i], &iv[j]);
+            }
+            fputs(buf, aesresp);
+            continue;
+        }
+        /* PLAINTEXT = ... */
+        if (strncmp(buf, "PLAINTEXT", 9) == 0) {
+            /* sanity check */
+            if (!encrypt) {
+                goto loser;
+            }
+
+            i = 9;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            for (j=0; isxdigit(buf[i]); i+=2,j++) {
+                hex_to_byteval(&buf[i], &plaintext[j]);
+            }
+            plaintextlen = j;
+
+            rv = aes_encrypt_buf(mode, key, keysize,
+                (mode == NSS_AES) ? NULL : iv,
+                ciphertext, &ciphertextlen, sizeof ciphertext,
+                plaintext, plaintextlen);
+            if (rv != SECSuccess) {
+                goto loser;
+            }
+
+            fputs(buf, aesresp);
+            fputs("CIPHERTEXT = ", aesresp);
+            to_hex_str(buf, ciphertext, ciphertextlen);
+            fputs(buf, aesresp);
+            fputc('\n', aesresp);
+            continue;
+        }
+        /* CIPHERTEXT = ... */
+        if (strncmp(buf, "CIPHERTEXT", 10) == 0) {
+            /* sanity check */
+            if (encrypt) {
+                goto loser;
+            }
+
+            i = 10;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            for (j=0; isxdigit(buf[i]); i+=2,j++) {
+                hex_to_byteval(&buf[i], &ciphertext[j]);
+            }
+            ciphertextlen = j;
+
+            rv = aes_decrypt_buf(mode, key, keysize,
+                (mode == NSS_AES) ? NULL : iv,
+                plaintext, &plaintextlen, sizeof plaintext,
+                ciphertext, ciphertextlen);
+            if (rv != SECSuccess) {
+                goto loser;
+            }
+
+            fputs(buf, aesresp);
+            fputs("PLAINTEXT = ", aesresp);
+            to_hex_str(buf, plaintext, plaintextlen);
+            fputs(buf, aesresp);
+            fputc('\n', aesresp);
+            continue;
+        }
+    }
+loser:
+    fclose(aesreq);
+}
+
+/*
+ * Generate Key[i+1] from Key[i], CT[j-1], and CT[j] for AES Monte Carlo
+ * Test (MCT) in ECB and CBC modes.
+ */
+void
+aes_mct_next_key(unsigned char *key, unsigned int keysize,
+    const unsigned char *ciphertext_1, const unsigned char *ciphertext)
+{
+    int k;
+
+    switch (keysize) {
+    case 16:  /* 128-bit key */
+        /* Key[i+1] = Key[i] xor CT[j] */
+        for (k=0; k<16; k++) {
+            key[k] ^= ciphertext[k];
+        }
+        break;
+    case 24:  /* 192-bit key */
+        /*
+         * Key[i+1] = Key[i] xor (last 64-bits of
+         *            CT[j-1] || CT[j])
+         */
+        for (k=0; k<8; k++) {
+            key[k] ^= ciphertext_1[k+8];
+        }
+        for (k=8; k<24; k++) {
+            key[k] ^= ciphertext[k-8];
+        }
+        break;
+    case 32:  /* 256-bit key */
+        /* Key[i+1] = Key[i] xor (CT[j-1] || CT[j]) */
+        for (k=0; k<16; k++) {
+            key[k] ^= ciphertext_1[k];
+        }
+        for (k=16; k<32; k++) {
+            key[k] ^= ciphertext[k-16];
+        }
+        break;
+    }
+}
+
+/*
+ * Perform the AES Monte Carlo Test (MCT) in ECB mode.  MCT exercises
+ * our AES code in streaming mode because the plaintext or ciphertext
+ * is generated block by block as we go, so we can't collect all the
+ * plaintext or ciphertext in one buffer and encrypt or decrypt it in
+ * one shot.
+ *
+ * reqfn is the pathname of the input REQUEST file.
+ *
+ * The output RESPONSE file is written to stdout.
+ */
+void
+aes_ecb_mct(char *reqfn)
+{
+    char buf[80];       /* holds one line from the input REQUEST file.
+                         * needs to be large enough to hold the longest
+                         * line "KEY = <64 hex digits>\n".
+                         */
+    FILE *aesreq;       /* input stream from the REQUEST file */
+    FILE *aesresp;      /* output stream to the RESPONSE file */
+    int i, j;
+    int encrypt = 0;    /* 1 means encrypt, 0 means decrypt */
+    unsigned char key[32];              /* 128, 192, or 256 bits */
+    unsigned int keysize;
+    unsigned char plaintext[16];        /* PT[j] */
+    unsigned char plaintext_1[16];      /* PT[j-1] */
+    unsigned char ciphertext[16];       /* CT[j] */
     unsigned char ciphertext_1[16];     /* CT[j-1] */
     unsigned char doublecheck[16];
     unsigned int outputlen;
-    AESContext *cx = NULL;	/* the operation being tested */
+    AESContext *cx = NULL;        /* the operation being tested */
     AESContext *cx2 = NULL;     /* the inverse operation done in parallel
                                  * to doublecheck our result.
                                  */
@@ -1213,246 +1444,246 @@ aes_ecb_mct(char *reqfn)
     aesreq = fopen(reqfn, "r");
     aesresp = stdout;
     while (fgets(buf, sizeof buf, aesreq) != NULL) {
-	/* a comment or blank line */
-	if (buf[0] == '#' || buf[0] == '\n') {
-	    fputs(buf, aesresp);
-	    continue;
-	}
-	/* [ENCRYPT] or [DECRYPT] */
-	if (buf[0] == '[') {
-	    if (strncmp(&buf[1], "ENCRYPT", 7) == 0) {
-		encrypt = 1;
-	    } else {
-		encrypt = 0;
-	    }
-	    fputs(buf, aesresp);
-	    continue;
-	}
-	/* "COUNT = x" begins a new data set */
-	if (strncmp(buf, "COUNT", 5) == 0) {
-	    /* zeroize the variables for the test with this data set */
-	    memset(key, 0, sizeof key);
-	    keysize = 0;
-	    memset(plaintext, 0, sizeof plaintext);
-	    memset(ciphertext, 0, sizeof ciphertext);
-	    continue;
-	}
-	/* KEY = ... */
-	if (strncmp(buf, "KEY", 3) == 0) {
-	    /* Key[0] = Key */
-	    i = 3;
-	    while (isspace(buf[i]) || buf[i] == '=') {
-		i++;
-	    }
-	    for (j=0; isxdigit(buf[i]); i+=2,j++) {
-		hex_to_byteval(&buf[i], &key[j]);
-	    }
-	    keysize = j;
-	    continue;
-	}
-	/* PLAINTEXT = ... */
-	if (strncmp(buf, "PLAINTEXT", 9) == 0) {
-	    /* sanity check */
-	    if (!encrypt) {
-		goto loser;
-	    }
-	    /* PT[0] = PT */
-	    i = 9;
-	    while (isspace(buf[i]) || buf[i] == '=') {
-		i++;
-	    }
-	    for (j=0; j<sizeof plaintext; i+=2,j++) {
-		hex_to_byteval(&buf[i], &plaintext[j]);
-	    }
+        /* a comment or blank line */
+        if (buf[0] == '#' || buf[0] == '\n') {
+            fputs(buf, aesresp);
+            continue;
+        }
+        /* [ENCRYPT] or [DECRYPT] */
+        if (buf[0] == '[') {
+            if (strncmp(&buf[1], "ENCRYPT", 7) == 0) {
+                encrypt = 1;
+            } else {
+                encrypt = 0;
+            }
+            fputs(buf, aesresp);
+            continue;
+        }
+        /* "COUNT = x" begins a new data set */
+        if (strncmp(buf, "COUNT", 5) == 0) {
+            /* zeroize the variables for the test with this data set */
+            memset(key, 0, sizeof key);
+            keysize = 0;
+            memset(plaintext, 0, sizeof plaintext);
+            memset(ciphertext, 0, sizeof ciphertext);
+            continue;
+        }
+        /* KEY = ... */
+        if (strncmp(buf, "KEY", 3) == 0) {
+            /* Key[0] = Key */
+            i = 3;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            for (j=0; isxdigit(buf[i]); i+=2,j++) {
+                hex_to_byteval(&buf[i], &key[j]);
+            }
+            keysize = j;
+            continue;
+        }
+        /* PLAINTEXT = ... */
+        if (strncmp(buf, "PLAINTEXT", 9) == 0) {
+            /* sanity check */
+            if (!encrypt) {
+                goto loser;
+            }
+            /* PT[0] = PT */
+            i = 9;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            for (j=0; j<sizeof plaintext; i+=2,j++) {
+                hex_to_byteval(&buf[i], &plaintext[j]);
+            }
 
-	    for (i=0; i<100; i++) {
-		sprintf(buf, "COUNT = %d\n", i);
-	        fputs(buf, aesresp);
-		/* Output Key[i] */
-		fputs("KEY = ", aesresp);
-		to_hex_str(buf, key, keysize);
-		fputs(buf, aesresp);
-		fputc('\n', aesresp);
-		/* Output PT[0] */
-		fputs("PLAINTEXT = ", aesresp);
-		to_hex_str(buf, plaintext, sizeof plaintext);
-		fputs(buf, aesresp);
-		fputc('\n', aesresp);
-
-		cx = AES_CreateContext(key, NULL, NSS_AES,
-		    PR_TRUE, keysize, 16);
-		if (cx == NULL) {
-		    goto loser;
-		}
-		/*
-		 * doublecheck our result by decrypting the result
-		 * and comparing the output with the plaintext.
-		 */
-		cx2 = AES_CreateContext(key, NULL, NSS_AES,
-		    PR_FALSE, keysize, 16);
-		if (cx2 == NULL) {
-		    goto loser;
-		}
-		for (j=0; j<1000; j++) {
-		    /* Save CT[j-1] */
-		    memcpy(ciphertext_1, ciphertext, sizeof ciphertext);
-
-		    /* CT[j] = AES(Key[i], PT[j]) */
-		    outputlen = 0;
-		    rv = AES_Encrypt(cx,
-			ciphertext, &outputlen, sizeof ciphertext,
-			plaintext, sizeof plaintext);
-		    if (rv != SECSuccess) {
-			goto loser;
-		    }
-		    if (outputlen != sizeof plaintext) {
-			goto loser;
-		    }
+            for (i=0; i<100; i++) {
+                sprintf(buf, "COUNT = %d\n", i);
+                fputs(buf, aesresp);
+                /* Output Key[i] */
+                fputs("KEY = ", aesresp);
+                to_hex_str(buf, key, keysize);
+                fputs(buf, aesresp);
+                fputc('\n', aesresp);
+                /* Output PT[0] */
+                fputs("PLAINTEXT = ", aesresp);
+                to_hex_str(buf, plaintext, sizeof plaintext);
+                fputs(buf, aesresp);
+                fputc('\n', aesresp);
+
+                cx = AES_CreateContext(key, NULL, NSS_AES,
+                    PR_TRUE, keysize, 16);
+                if (cx == NULL) {
+                    goto loser;
+                }
+                /*
+                 * doublecheck our result by decrypting the result
+                 * and comparing the output with the plaintext.
+                 */
+                cx2 = AES_CreateContext(key, NULL, NSS_AES,
+                    PR_FALSE, keysize, 16);
+                if (cx2 == NULL) {
+                    goto loser;
+                }
+                for (j=0; j<1000; j++) {
+                    /* Save CT[j-1] */
+                    memcpy(ciphertext_1, ciphertext, sizeof ciphertext);
+
+                    /* CT[j] = AES(Key[i], PT[j]) */
+                    outputlen = 0;
+                    rv = AES_Encrypt(cx,
+                        ciphertext, &outputlen, sizeof ciphertext,
+                        plaintext, sizeof plaintext);
+                    if (rv != SECSuccess) {
+                        goto loser;
+                    }
+                    if (outputlen != sizeof plaintext) {
+                        goto loser;
+                    }
 
-		    /* doublecheck our result */
-		    outputlen = 0;
-		    rv = AES_Decrypt(cx2,
-			doublecheck, &outputlen, sizeof doublecheck,
-			ciphertext, sizeof ciphertext);
-		    if (rv != SECSuccess) {
-			goto loser;
-		    }
-		    if (outputlen != sizeof ciphertext) {
-			goto loser;
-		    }
-		    if (memcmp(doublecheck, plaintext, sizeof plaintext)) {
-			goto loser;
-		    }
+                    /* doublecheck our result */
+                    outputlen = 0;
+                    rv = AES_Decrypt(cx2,
+                        doublecheck, &outputlen, sizeof doublecheck,
+                        ciphertext, sizeof ciphertext);
+                    if (rv != SECSuccess) {
+                        goto loser;
+                    }
+                    if (outputlen != sizeof ciphertext) {
+                        goto loser;
+                    }
+                    if (memcmp(doublecheck, plaintext, sizeof plaintext)) {
+                        goto loser;
+                    }
 
-		    /* PT[j+1] = CT[j] */
-		    memcpy(plaintext, ciphertext, sizeof plaintext);
-		}
-		AES_DestroyContext(cx, PR_TRUE);
-		cx = NULL;
-		AES_DestroyContext(cx2, PR_TRUE);
-		cx2 = NULL;
-
-		/* Output CT[j] */
-		fputs("CIPHERTEXT = ", aesresp);
-		to_hex_str(buf, ciphertext, sizeof ciphertext);
-		fputs(buf, aesresp);
-		fputc('\n', aesresp);
-
-		/* Key[i+1] = Key[i] xor ... */
-		aes_mct_next_key(key, keysize, ciphertext_1, ciphertext);
-		/* PT[0] = CT[j] */
-		/* done at the end of the for(j) loop */
+                    /* PT[j+1] = CT[j] */
+                    memcpy(plaintext, ciphertext, sizeof plaintext);
+                }
+                AES_DestroyContext(cx, PR_TRUE);
+                cx = NULL;
+                AES_DestroyContext(cx2, PR_TRUE);
+                cx2 = NULL;
+
+                /* Output CT[j] */
+                fputs("CIPHERTEXT = ", aesresp);
+                to_hex_str(buf, ciphertext, sizeof ciphertext);
+                fputs(buf, aesresp);
+                fputc('\n', aesresp);
+
+                /* Key[i+1] = Key[i] xor ... */
+                aes_mct_next_key(key, keysize, ciphertext_1, ciphertext);
+                /* PT[0] = CT[j] */
+                /* done at the end of the for(j) loop */
 
-		fputc('\n', aesresp);
-	    }
+                fputc('\n', aesresp);
+            }
 
-	    continue;
-	}
-	/* CIPHERTEXT = ... */
-	if (strncmp(buf, "CIPHERTEXT", 10) == 0) {
-	    /* sanity check */
-	    if (encrypt) {
-		goto loser;
-	    }
-	    /* CT[0] = CT */
-	    i = 10;
-	    while (isspace(buf[i]) || buf[i] == '=') {
-		i++;
-	    }
-	    for (j=0; isxdigit(buf[i]); i+=2,j++) {
-		hex_to_byteval(&buf[i], &ciphertext[j]);
-	    }
+            continue;
+        }
+        /* CIPHERTEXT = ... */
+        if (strncmp(buf, "CIPHERTEXT", 10) == 0) {
+            /* sanity check */
+            if (encrypt) {
+                goto loser;
+            }
+            /* CT[0] = CT */
+            i = 10;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            for (j=0; isxdigit(buf[i]); i+=2,j++) {
+                hex_to_byteval(&buf[i], &ciphertext[j]);
+            }
 
-	    for (i=0; i<100; i++) {
-		sprintf(buf, "COUNT = %d\n", i);
-	        fputs(buf, aesresp);
-		/* Output Key[i] */
-		fputs("KEY = ", aesresp);
-		to_hex_str(buf, key, keysize);
-		fputs(buf, aesresp);
-		fputc('\n', aesresp);
-		/* Output CT[0] */
-		fputs("CIPHERTEXT = ", aesresp);
-		to_hex_str(buf, ciphertext, sizeof ciphertext);
-		fputs(buf, aesresp);
-		fputc('\n', aesresp);
-
-		cx = AES_CreateContext(key, NULL, NSS_AES,
-		    PR_FALSE, keysize, 16);
-		if (cx == NULL) {
-		    goto loser;
-		}
-		/*
-		 * doublecheck our result by encrypting the result
-		 * and comparing the output with the ciphertext.
-		 */
-		cx2 = AES_CreateContext(key, NULL, NSS_AES,
-		    PR_TRUE, keysize, 16);
-		if (cx2 == NULL) {
-		    goto loser;
-		}
-		for (j=0; j<1000; j++) {
-		    /* Save PT[j-1] */
-		    memcpy(plaintext_1, plaintext, sizeof plaintext);
-
-		    /* PT[j] = AES(Key[i], CT[j]) */
-		    outputlen = 0;
-		    rv = AES_Decrypt(cx,
-			plaintext, &outputlen, sizeof plaintext,
-			ciphertext, sizeof ciphertext);
-		    if (rv != SECSuccess) {
-			goto loser;
-		    }
-		    if (outputlen != sizeof ciphertext) {
-			goto loser;
-		    }
+            for (i=0; i<100; i++) {
+                sprintf(buf, "COUNT = %d\n", i);
+                fputs(buf, aesresp);
+                /* Output Key[i] */
+                fputs("KEY = ", aesresp);
+                to_hex_str(buf, key, keysize);
+                fputs(buf, aesresp);
+                fputc('\n', aesresp);
+                /* Output CT[0] */
+                fputs("CIPHERTEXT = ", aesresp);
+                to_hex_str(buf, ciphertext, sizeof ciphertext);
+                fputs(buf, aesresp);
+                fputc('\n', aesresp);
+
+                cx = AES_CreateContext(key, NULL, NSS_AES,
+                    PR_FALSE, keysize, 16);
+                if (cx == NULL) {
+                    goto loser;
+                }
+                /*
+                 * doublecheck our result by encrypting the result
+                 * and comparing the output with the ciphertext.
+                 */
+                cx2 = AES_CreateContext(key, NULL, NSS_AES,
+                    PR_TRUE, keysize, 16);
+                if (cx2 == NULL) {
+                    goto loser;
+                }
+                for (j=0; j<1000; j++) {
+                    /* Save PT[j-1] */
+                    memcpy(plaintext_1, plaintext, sizeof plaintext);
+
+                    /* PT[j] = AES(Key[i], CT[j]) */
+                    outputlen = 0;
+                    rv = AES_Decrypt(cx,
+                        plaintext, &outputlen, sizeof plaintext,
+                        ciphertext, sizeof ciphertext);
+                    if (rv != SECSuccess) {
+                        goto loser;
+                    }
+                    if (outputlen != sizeof ciphertext) {
+                        goto loser;
+                    }
 
-		    /* doublecheck our result */
-		    outputlen = 0;
-		    rv = AES_Encrypt(cx2,
-			doublecheck, &outputlen, sizeof doublecheck,
-			plaintext, sizeof plaintext);
-		    if (rv != SECSuccess) {
-			goto loser;
-		    }
-		    if (outputlen != sizeof plaintext) {
-			goto loser;
-		    }
-		    if (memcmp(doublecheck, ciphertext, sizeof ciphertext)) {
-			goto loser;
-		    }
+                    /* doublecheck our result */
+                    outputlen = 0;
+                    rv = AES_Encrypt(cx2,
+                        doublecheck, &outputlen, sizeof doublecheck,
+                        plaintext, sizeof plaintext);
+                    if (rv != SECSuccess) {
+                        goto loser;
+                    }
+                    if (outputlen != sizeof plaintext) {
+                        goto loser;
+                    }
+                    if (memcmp(doublecheck, ciphertext, sizeof ciphertext)) {
+                        goto loser;
+                    }
 
-		    /* CT[j+1] = PT[j] */
-		    memcpy(ciphertext, plaintext, sizeof ciphertext);
-		}
-		AES_DestroyContext(cx, PR_TRUE);
-		cx = NULL;
-		AES_DestroyContext(cx2, PR_TRUE);
-		cx2 = NULL;
-
-		/* Output PT[j] */
-		fputs("PLAINTEXT = ", aesresp);
-		to_hex_str(buf, plaintext, sizeof plaintext);
-		fputs(buf, aesresp);
-		fputc('\n', aesresp);
-
-		/* Key[i+1] = Key[i] xor ... */
-		aes_mct_next_key(key, keysize, plaintext_1, plaintext);
-		/* CT[0] = PT[j] */
-		/* done at the end of the for(j) loop */
+                    /* CT[j+1] = PT[j] */
+                    memcpy(ciphertext, plaintext, sizeof ciphertext);
+                }
+                AES_DestroyContext(cx, PR_TRUE);
+                cx = NULL;
+                AES_DestroyContext(cx2, PR_TRUE);
+                cx2 = NULL;
+
+                /* Output PT[j] */
+                fputs("PLAINTEXT = ", aesresp);
+                to_hex_str(buf, plaintext, sizeof plaintext);
+                fputs(buf, aesresp);
+                fputc('\n', aesresp);
+
+                /* Key[i+1] = Key[i] xor ... */
+                aes_mct_next_key(key, keysize, plaintext_1, plaintext);
+                /* CT[0] = PT[j] */
+                /* done at the end of the for(j) loop */
 
-		fputc('\n', aesresp);
-	    }
+                fputc('\n', aesresp);
+            }
 
-	    continue;
-	}
+            continue;
+        }
     }
 loser:
     if (cx != NULL) {
-	AES_DestroyContext(cx, PR_TRUE);
+        AES_DestroyContext(cx, PR_TRUE);
     }
     if (cx2 != NULL) {
-	AES_DestroyContext(cx2, PR_TRUE);
+        AES_DestroyContext(cx2, PR_TRUE);
     }
     fclose(aesreq);
 }
@@ -1488,7 +1719,7 @@ aes_cbc_mct(char *reqfn)
     unsigned char ciphertext_1[16];     /* CT[j-1] */
     unsigned char doublecheck[16];
     unsigned int outputlen;
-    AESContext *cx = NULL;	/* the operation being tested */
+    AESContext *cx = NULL;        /* the operation being tested */
     AESContext *cx2 = NULL;     /* the inverse operation done in parallel
                                  * to doublecheck our result.
                                  */
@@ -1497,287 +1728,287 @@ aes_cbc_mct(char *reqfn)
     aesreq = fopen(reqfn, "r");
     aesresp = stdout;
     while (fgets(buf, sizeof buf, aesreq) != NULL) {
-	/* a comment or blank line */
-	if (buf[0] == '#' || buf[0] == '\n') {
-	    fputs(buf, aesresp);
-	    continue;
-	}
-	/* [ENCRYPT] or [DECRYPT] */
-	if (buf[0] == '[') {
-	    if (strncmp(&buf[1], "ENCRYPT", 7) == 0) {
-		encrypt = 1;
-	    } else {
-		encrypt = 0;
-	    }
-	    fputs(buf, aesresp);
-	    continue;
-	}
-	/* "COUNT = x" begins a new data set */
-	if (strncmp(buf, "COUNT", 5) == 0) {
-	    /* zeroize the variables for the test with this data set */
-	    memset(key, 0, sizeof key);
-	    keysize = 0;
-	    memset(iv, 0, sizeof iv);
-	    memset(plaintext, 0, sizeof plaintext);
-	    memset(ciphertext, 0, sizeof ciphertext);
-	    continue;
-	}
-	/* KEY = ... */
-	if (strncmp(buf, "KEY", 3) == 0) {
-	    /* Key[0] = Key */
-	    i = 3;
-	    while (isspace(buf[i]) || buf[i] == '=') {
-		i++;
-	    }
-	    for (j=0; isxdigit(buf[i]); i+=2,j++) {
-		hex_to_byteval(&buf[i], &key[j]);
-	    }
-	    keysize = j;
-	    continue;
-	}
-	/* IV = ... */
-	if (strncmp(buf, "IV", 2) == 0) {
-	    /* IV[0] = IV */
-	    i = 2;
-	    while (isspace(buf[i]) || buf[i] == '=') {
-		i++;
-	    }
-	    for (j=0; j<sizeof iv; i+=2,j++) {
-		hex_to_byteval(&buf[i], &iv[j]);
-	    }
-	    continue;
-	}
-	/* PLAINTEXT = ... */
-	if (strncmp(buf, "PLAINTEXT", 9) == 0) {
-	    /* sanity check */
-	    if (!encrypt) {
-		goto loser;
-	    }
-	    /* PT[0] = PT */
-	    i = 9;
-	    while (isspace(buf[i]) || buf[i] == '=') {
-		i++;
-	    }
-	    for (j=0; j<sizeof plaintext; i+=2,j++) {
-		hex_to_byteval(&buf[i], &plaintext[j]);
-	    }
+        /* a comment or blank line */
+        if (buf[0] == '#' || buf[0] == '\n') {
+            fputs(buf, aesresp);
+            continue;
+        }
+        /* [ENCRYPT] or [DECRYPT] */
+        if (buf[0] == '[') {
+            if (strncmp(&buf[1], "ENCRYPT", 7) == 0) {
+                encrypt = 1;
+            } else {
+                encrypt = 0;
+            }
+            fputs(buf, aesresp);
+            continue;
+        }
+        /* "COUNT = x" begins a new data set */
+        if (strncmp(buf, "COUNT", 5) == 0) {
+            /* zeroize the variables for the test with this data set */
+            memset(key, 0, sizeof key);
+            keysize = 0;
+            memset(iv, 0, sizeof iv);
+            memset(plaintext, 0, sizeof plaintext);
+            memset(ciphertext, 0, sizeof ciphertext);
+            continue;
+        }
+        /* KEY = ... */
+        if (strncmp(buf, "KEY", 3) == 0) {
+            /* Key[0] = Key */
+            i = 3;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            for (j=0; isxdigit(buf[i]); i+=2,j++) {
+                hex_to_byteval(&buf[i], &key[j]);
+            }
+            keysize = j;
+            continue;
+        }
+        /* IV = ... */
+        if (strncmp(buf, "IV", 2) == 0) {
+            /* IV[0] = IV */
+            i = 2;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            for (j=0; j<sizeof iv; i+=2,j++) {
+                hex_to_byteval(&buf[i], &iv[j]);
+            }
+            continue;
+        }
+        /* PLAINTEXT = ... */
+        if (strncmp(buf, "PLAINTEXT", 9) == 0) {
+            /* sanity check */
+            if (!encrypt) {
+                goto loser;
+            }
+            /* PT[0] = PT */
+            i = 9;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            for (j=0; j<sizeof plaintext; i+=2,j++) {
+                hex_to_byteval(&buf[i], &plaintext[j]);
+            }
 
-	    for (i=0; i<100; i++) {
-		sprintf(buf, "COUNT = %d\n", i);
-	        fputs(buf, aesresp);
-		/* Output Key[i] */
-		fputs("KEY = ", aesresp);
-		to_hex_str(buf, key, keysize);
-		fputs(buf, aesresp);
-		fputc('\n', aesresp);
-		/* Output IV[i] */
-		fputs("IV = ", aesresp);
-		to_hex_str(buf, iv, sizeof iv);
-		fputs(buf, aesresp);
-		fputc('\n', aesresp);
-		/* Output PT[0] */
-		fputs("PLAINTEXT = ", aesresp);
-		to_hex_str(buf, plaintext, sizeof plaintext);
-		fputs(buf, aesresp);
-		fputc('\n', aesresp);
-
-		cx = AES_CreateContext(key, iv, NSS_AES_CBC,
-		    PR_TRUE, keysize, 16);
-		if (cx == NULL) {
-		    goto loser;
-		}
-		/*
-		 * doublecheck our result by decrypting the result
-		 * and comparing the output with the plaintext.
-		 */
-		cx2 = AES_CreateContext(key, iv, NSS_AES_CBC,
-		    PR_FALSE, keysize, 16);
-		if (cx2 == NULL) {
-		    goto loser;
-		}
-		/* CT[-1] = IV[i] */
-		memcpy(ciphertext, iv, sizeof ciphertext);
-		for (j=0; j<1000; j++) {
-		    /* Save CT[j-1] */
-		    memcpy(ciphertext_1, ciphertext, sizeof ciphertext);
-		    /*
-		     * If ( j=0 )
-		     *      CT[j] = AES(Key[i], IV[i], PT[j])
-		     *      PT[j+1] = IV[i] (= CT[j-1])
-		     * Else
-		     *      CT[j] = AES(Key[i], PT[j])
-		     *      PT[j+1] = CT[j-1]
-		     */
-		    outputlen = 0;
-		    rv = AES_Encrypt(cx,
-			ciphertext, &outputlen, sizeof ciphertext,
-			plaintext, sizeof plaintext);
-		    if (rv != SECSuccess) {
-			goto loser;
-		    }
-		    if (outputlen != sizeof plaintext) {
-			goto loser;
-		    }
+            for (i=0; i<100; i++) {
+                sprintf(buf, "COUNT = %d\n", i);
+                fputs(buf, aesresp);
+                /* Output Key[i] */
+                fputs("KEY = ", aesresp);
+                to_hex_str(buf, key, keysize);
+                fputs(buf, aesresp);
+                fputc('\n', aesresp);
+                /* Output IV[i] */
+                fputs("IV = ", aesresp);
+                to_hex_str(buf, iv, sizeof iv);
+                fputs(buf, aesresp);
+                fputc('\n', aesresp);
+                /* Output PT[0] */
+                fputs("PLAINTEXT = ", aesresp);
+                to_hex_str(buf, plaintext, sizeof plaintext);
+                fputs(buf, aesresp);
+                fputc('\n', aesresp);
+
+                cx = AES_CreateContext(key, iv, NSS_AES_CBC,
+                    PR_TRUE, keysize, 16);
+                if (cx == NULL) {
+                    goto loser;
+                }
+                /*
+                 * doublecheck our result by decrypting the result
+                 * and comparing the output with the plaintext.
+                 */
+                cx2 = AES_CreateContext(key, iv, NSS_AES_CBC,
+                    PR_FALSE, keysize, 16);
+                if (cx2 == NULL) {
+                    goto loser;
+                }
+                /* CT[-1] = IV[i] */
+                memcpy(ciphertext, iv, sizeof ciphertext);
+                for (j=0; j<1000; j++) {
+                    /* Save CT[j-1] */
+                    memcpy(ciphertext_1, ciphertext, sizeof ciphertext);
+                    /*
+                     * If ( j=0 )
+                     *      CT[j] = AES(Key[i], IV[i], PT[j])
+                     *      PT[j+1] = IV[i] (= CT[j-1])
+                     * Else
+                     *      CT[j] = AES(Key[i], PT[j])
+                     *      PT[j+1] = CT[j-1]
+                     */
+                    outputlen = 0;
+                    rv = AES_Encrypt(cx,
+                        ciphertext, &outputlen, sizeof ciphertext,
+                        plaintext, sizeof plaintext);
+                    if (rv != SECSuccess) {
+                        goto loser;
+                    }
+                    if (outputlen != sizeof plaintext) {
+                        goto loser;
+                    }
 
-		    /* doublecheck our result */
-		    outputlen = 0;
-		    rv = AES_Decrypt(cx2,
-			doublecheck, &outputlen, sizeof doublecheck,
-			ciphertext, sizeof ciphertext);
-		    if (rv != SECSuccess) {
-			goto loser;
-		    }
-		    if (outputlen != sizeof ciphertext) {
-			goto loser;
-		    }
-		    if (memcmp(doublecheck, plaintext, sizeof plaintext)) {
-			goto loser;
-		    }
+                    /* doublecheck our result */
+                    outputlen = 0;
+                    rv = AES_Decrypt(cx2,
+                        doublecheck, &outputlen, sizeof doublecheck,
+                        ciphertext, sizeof ciphertext);
+                    if (rv != SECSuccess) {
+                        goto loser;
+                    }
+                    if (outputlen != sizeof ciphertext) {
+                        goto loser;
+                    }
+                    if (memcmp(doublecheck, plaintext, sizeof plaintext)) {
+                        goto loser;
+                    }
 
-		    memcpy(plaintext, ciphertext_1, sizeof plaintext);
-		}
-		AES_DestroyContext(cx, PR_TRUE);
-		cx = NULL;
-		AES_DestroyContext(cx2, PR_TRUE);
-		cx2 = NULL;
-
-		/* Output CT[j] */
-		fputs("CIPHERTEXT = ", aesresp);
-		to_hex_str(buf, ciphertext, sizeof ciphertext);
-		fputs(buf, aesresp);
-		fputc('\n', aesresp);
-
-		/* Key[i+1] = Key[i] xor ... */
-		aes_mct_next_key(key, keysize, ciphertext_1, ciphertext);
-		/* IV[i+1] = CT[j] */
-		memcpy(iv, ciphertext, sizeof iv);
-		/* PT[0] = CT[j-1] */
-		/* done at the end of the for(j) loop */
+                    memcpy(plaintext, ciphertext_1, sizeof plaintext);
+                }
+                AES_DestroyContext(cx, PR_TRUE);
+                cx = NULL;
+                AES_DestroyContext(cx2, PR_TRUE);
+                cx2 = NULL;
+
+                /* Output CT[j] */
+                fputs("CIPHERTEXT = ", aesresp);
+                to_hex_str(buf, ciphertext, sizeof ciphertext);
+                fputs(buf, aesresp);
+                fputc('\n', aesresp);
+
+                /* Key[i+1] = Key[i] xor ... */
+                aes_mct_next_key(key, keysize, ciphertext_1, ciphertext);
+                /* IV[i+1] = CT[j] */
+                memcpy(iv, ciphertext, sizeof iv);
+                /* PT[0] = CT[j-1] */
+                /* done at the end of the for(j) loop */
 
-		fputc('\n', aesresp);
-	    }
+                fputc('\n', aesresp);
+            }
 
-	    continue;
-	}
-	/* CIPHERTEXT = ... */
-	if (strncmp(buf, "CIPHERTEXT", 10) == 0) {
-	    /* sanity check */
-	    if (encrypt) {
-		goto loser;
-	    }
-	    /* CT[0] = CT */
-	    i = 10;
-	    while (isspace(buf[i]) || buf[i] == '=') {
-		i++;
-	    }
-	    for (j=0; isxdigit(buf[i]); i+=2,j++) {
-		hex_to_byteval(&buf[i], &ciphertext[j]);
-	    }
+            continue;
+        }
+        /* CIPHERTEXT = ... */
+        if (strncmp(buf, "CIPHERTEXT", 10) == 0) {
+            /* sanity check */
+            if (encrypt) {
+                goto loser;
+            }
+            /* CT[0] = CT */
+            i = 10;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            for (j=0; isxdigit(buf[i]); i+=2,j++) {
+                hex_to_byteval(&buf[i], &ciphertext[j]);
+            }
 
-	    for (i=0; i<100; i++) {
-		sprintf(buf, "COUNT = %d\n", i);
-	        fputs(buf, aesresp);
-		/* Output Key[i] */
-		fputs("KEY = ", aesresp);
-		to_hex_str(buf, key, keysize);
-		fputs(buf, aesresp);
-		fputc('\n', aesresp);
-		/* Output IV[i] */
-		fputs("IV = ", aesresp);
-		to_hex_str(buf, iv, sizeof iv);
-		fputs(buf, aesresp);
-		fputc('\n', aesresp);
-		/* Output CT[0] */
-		fputs("CIPHERTEXT = ", aesresp);
-		to_hex_str(buf, ciphertext, sizeof ciphertext);
-		fputs(buf, aesresp);
-		fputc('\n', aesresp);
-
-		cx = AES_CreateContext(key, iv, NSS_AES_CBC,
-		    PR_FALSE, keysize, 16);
-		if (cx == NULL) {
-		    goto loser;
-		}
-		/*
-		 * doublecheck our result by encrypting the result
-		 * and comparing the output with the ciphertext.
-		 */
-		cx2 = AES_CreateContext(key, iv, NSS_AES_CBC,
-		    PR_TRUE, keysize, 16);
-		if (cx2 == NULL) {
-		    goto loser;
-		}
-		/* PT[-1] = IV[i] */
-		memcpy(plaintext, iv, sizeof plaintext);
-		for (j=0; j<1000; j++) {
-		    /* Save PT[j-1] */
-		    memcpy(plaintext_1, plaintext, sizeof plaintext);
-		    /*
-		     * If ( j=0 )
-		     *      PT[j] = AES(Key[i], IV[i], CT[j])
-		     *      CT[j+1] = IV[i] (= PT[j-1])
-		     * Else
-		     *      PT[j] = AES(Key[i], CT[j])
-		     *      CT[j+1] = PT[j-1]
-		     */
-		    outputlen = 0;
-		    rv = AES_Decrypt(cx,
-			plaintext, &outputlen, sizeof plaintext,
-			ciphertext, sizeof ciphertext);
-		    if (rv != SECSuccess) {
-			goto loser;
-		    }
-		    if (outputlen != sizeof ciphertext) {
-			goto loser;
-		    }
+            for (i=0; i<100; i++) {
+                sprintf(buf, "COUNT = %d\n", i);
+                fputs(buf, aesresp);
+                /* Output Key[i] */
+                fputs("KEY = ", aesresp);
+                to_hex_str(buf, key, keysize);
+                fputs(buf, aesresp);
+                fputc('\n', aesresp);
+                /* Output IV[i] */
+                fputs("IV = ", aesresp);
+                to_hex_str(buf, iv, sizeof iv);
+                fputs(buf, aesresp);
+                fputc('\n', aesresp);
+                /* Output CT[0] */
+                fputs("CIPHERTEXT = ", aesresp);
+                to_hex_str(buf, ciphertext, sizeof ciphertext);
+                fputs(buf, aesresp);
+                fputc('\n', aesresp);
+
+                cx = AES_CreateContext(key, iv, NSS_AES_CBC,
+                    PR_FALSE, keysize, 16);
+                if (cx == NULL) {
+                    goto loser;
+                }
+                /*
+                 * doublecheck our result by encrypting the result
+                 * and comparing the output with the ciphertext.
+                 */
+                cx2 = AES_CreateContext(key, iv, NSS_AES_CBC,
+                    PR_TRUE, keysize, 16);
+                if (cx2 == NULL) {
+                    goto loser;
+                }
+                /* PT[-1] = IV[i] */
+                memcpy(plaintext, iv, sizeof plaintext);
+                for (j=0; j<1000; j++) {
+                    /* Save PT[j-1] */
+                    memcpy(plaintext_1, plaintext, sizeof plaintext);
+                    /*
+                     * If ( j=0 )
+                     *      PT[j] = AES(Key[i], IV[i], CT[j])
+                     *      CT[j+1] = IV[i] (= PT[j-1])
+                     * Else
+                     *      PT[j] = AES(Key[i], CT[j])
+                     *      CT[j+1] = PT[j-1]
+                     */
+                    outputlen = 0;
+                    rv = AES_Decrypt(cx,
+                        plaintext, &outputlen, sizeof plaintext,
+                        ciphertext, sizeof ciphertext);
+                    if (rv != SECSuccess) {
+                        goto loser;
+                    }
+                    if (outputlen != sizeof ciphertext) {
+                        goto loser;
+                    }
 
-		    /* doublecheck our result */
-		    outputlen = 0;
-		    rv = AES_Encrypt(cx2,
-			doublecheck, &outputlen, sizeof doublecheck,
-			plaintext, sizeof plaintext);
-		    if (rv != SECSuccess) {
-			goto loser;
-		    }
-		    if (outputlen != sizeof plaintext) {
-			goto loser;
-		    }
-		    if (memcmp(doublecheck, ciphertext, sizeof ciphertext)) {
-			goto loser;
-		    }
+                    /* doublecheck our result */
+                    outputlen = 0;
+                    rv = AES_Encrypt(cx2,
+                        doublecheck, &outputlen, sizeof doublecheck,
+                        plaintext, sizeof plaintext);
+                    if (rv != SECSuccess) {
+                        goto loser;
+                    }
+                    if (outputlen != sizeof plaintext) {
+                        goto loser;
+                    }
+                    if (memcmp(doublecheck, ciphertext, sizeof ciphertext)) {
+                        goto loser;
+                    }
 
-		    memcpy(ciphertext, plaintext_1, sizeof ciphertext);
-		}
-		AES_DestroyContext(cx, PR_TRUE);
-		cx = NULL;
-		AES_DestroyContext(cx2, PR_TRUE);
-		cx2 = NULL;
-
-		/* Output PT[j] */
-		fputs("PLAINTEXT = ", aesresp);
-		to_hex_str(buf, plaintext, sizeof plaintext);
-		fputs(buf, aesresp);
-		fputc('\n', aesresp);
-
-		/* Key[i+1] = Key[i] xor ... */
-		aes_mct_next_key(key, keysize, plaintext_1, plaintext);
-		/* IV[i+1] = PT[j] */
-		memcpy(iv, plaintext, sizeof iv);
-		/* CT[0] = PT[j-1] */
-		/* done at the end of the for(j) loop */
+                    memcpy(ciphertext, plaintext_1, sizeof ciphertext);
+                }
+                AES_DestroyContext(cx, PR_TRUE);
+                cx = NULL;
+                AES_DestroyContext(cx2, PR_TRUE);
+                cx2 = NULL;
+
+                /* Output PT[j] */
+                fputs("PLAINTEXT = ", aesresp);
+                to_hex_str(buf, plaintext, sizeof plaintext);
+                fputs(buf, aesresp);
+                fputc('\n', aesresp);
+
+                /* Key[i+1] = Key[i] xor ... */
+                aes_mct_next_key(key, keysize, plaintext_1, plaintext);
+                /* IV[i+1] = PT[j] */
+                memcpy(iv, plaintext, sizeof iv);
+                /* CT[0] = PT[j-1] */
+                /* done at the end of the for(j) loop */
 
-		fputc('\n', aesresp);
-	    }
+                fputc('\n', aesresp);
+            }
 
-	    continue;
-	}
+            continue;
+        }
     }
 loser:
     if (cx != NULL) {
-	AES_DestroyContext(cx, PR_TRUE);
+        AES_DestroyContext(cx, PR_TRUE);
     }
     if (cx2 != NULL) {
-	AES_DestroyContext(cx2, PR_TRUE);
+        AES_DestroyContext(cx2, PR_TRUE);
     }
     fclose(aesreq);
 }
@@ -1788,31 +2019,31 @@ void write_compact_string(FILE *out, uns
     int j, count = 0, last = -1, z = 0;
     long start = ftell(out);
     for (i=0; i<len; i++) {
-	for (j=7; j>=0; j--) {
-	    if (last < 0) {
-		last = (hash[i] & (1 << j)) ? 1 : 0;
-		fprintf(out, "%d ", last);
-		count = 1;
-	    } else if (hash[i] & (1 << j)) {
-		if (last) {
-		    count++; 
-		} else { 
-		    last = 0;
-		    fprintf(out, "%d ", count);
-		    count = 1;
-		    z++;
-		}
-	    } else {
-		if (!last) {
-		    count++; 
-		} else { 
-		    last = 1;
-		    fprintf(out, "%d ", count);
-		    count = 1;
-		    z++;
-		}
-	    }
-	}
+        for (j=7; j>=0; j--) {
+            if (last < 0) {
+                last = (hash[i] & (1 << j)) ? 1 : 0;
+                fprintf(out, "%d ", last);
+                count = 1;
+            } else if (hash[i] & (1 << j)) {
+                if (last) {
+                    count++; 
+                } else { 
+                    last = 0;
+                    fprintf(out, "%d ", count);
+                    count = 1;
+                    z++;
+                }
+            } else {
+                if (!last) {
+                    count++; 
+                } else { 
+                    last = 1;
+                    fprintf(out, "%d ", count);
+                    count = 1;
+                    z++;
+                }
+            }
+        }
     }
     fprintf(out, "^\n");
     fseek(out, start, SEEK_SET);
@@ -1827,23 +2058,23 @@ int get_next_line(FILE *req, char *key,
     int w = 0;
     int c;
     while ((c = fgetc(req)) != EOF) {
-	if (ignore) {
-	    fprintf(rsp, "%c", c);
-	    if (c == '\n') return ignore;
-	} else if (c == '\n') {
-	    break;
-	} else if (c == '#') {
-	    ignore = 1;
-	    fprintf(rsp, "%c", c);
-	} else if (c == '=') {
-	    writeto[w] = '\0';
-	    w = 0;
-	    writeto = val;
-	} else if (c == ' ' || c == '[' || c == ']') {
-	    continue;
-	} else {
-	    writeto[w++] = c;
-	}
+        if (ignore) {
+            fprintf(rsp, "%c", c);
+            if (c == '\n') return ignore;
+        } else if (c == '\n') {
+            break;
+        } else if (c == '#') {
+            ignore = 1;
+            fprintf(rsp, "%c", c);
+        } else if (c == '=') {
+            writeto[w] = '\0';
+            w = 0;
+            writeto = val;
+        } else if (c == ' ' || c == '[' || c == ']') {
+            continue;
+        } else {
+            writeto[w++] = c;
+        }
     }
     writeto[w] = '\0';
     return (c == EOF) ? -1 : ignore;
@@ -1948,34 +2179,149 @@ getECParams(const char *curve)
     SECOidTag curveOidTag = SEC_OID_UNKNOWN; /* default */
     int i, numCurves;
 
-    if (curve != NULL) {
-        numCurves = sizeof(nameTagPair)/sizeof(CurveNameTagPair);
-	for (i = 0; ((i < numCurves) && (curveOidTag == SEC_OID_UNKNOWN)); 
-	     i++) {
-	    if (PL_strcmp(curve, nameTagPair[i].curveName) == 0)
-	        curveOidTag = nameTagPair[i].curveOidTag;
-	}
+    if (curve != NULL) {
+        numCurves = sizeof(nameTagPair)/sizeof(CurveNameTagPair);
+        for (i = 0; ((i < numCurves) && (curveOidTag == SEC_OID_UNKNOWN)); 
+             i++) {
+            if (PL_strcmp(curve, nameTagPair[i].curveName) == 0)
+                curveOidTag = nameTagPair[i].curveOidTag;
+        }
+    }
+
+    /* Return NULL if curve name is not recognized */
+    if ((curveOidTag == SEC_OID_UNKNOWN) || 
+        (oidData = SECOID_FindOIDByTag(curveOidTag)) == NULL) {
+        fprintf(stderr, "Unrecognized elliptic curve %s\n", curve);
+        return NULL;
+    }
+
+    ecparams = SECITEM_AllocItem(NULL, NULL, (2 + oidData->oid.len));
+
+    /* 
+     * ecparams->data needs to contain the ASN encoding of an object ID (OID)
+     * representing the named curve. The actual OID is in 
+     * oidData->oid.data so we simply prepend 0x06 and OID length
+     */
+    ecparams->data[0] = SEC_ASN1_OBJECT_ID;
+    ecparams->data[1] = oidData->oid.len;
+    memcpy(ecparams->data + 2, oidData->oid.data, oidData->oid.len);
+
+    return ecparams;
+}
+
+/*
+ * HASH_ functions are available to full NSS apps and internally inside
+ * freebl, but not exported to users of freebl. Create short stubs to
+ * replace the functionality for fipstest.
+ */
+SECStatus
+fips_hashBuf(HASH_HashType type, unsigned char *hashBuf, 
+                                        unsigned char *msg, int len)
+{
+    SECStatus rv = SECFailure;
+
+    switch (type) {
+    case HASH_AlgSHA1:
+        rv = SHA1_HashBuf(hashBuf, msg, len);
+        break;
+    case HASH_AlgSHA224:
+        rv = SHA224_HashBuf(hashBuf, msg, len);
+        break;
+    case HASH_AlgSHA256:
+        rv = SHA256_HashBuf(hashBuf, msg, len);
+        break;
+    case HASH_AlgSHA384:
+        rv = SHA384_HashBuf(hashBuf, msg, len);
+        break;
+    case HASH_AlgSHA512:
+        rv = SHA512_HashBuf(hashBuf, msg, len);
+        break;
+    default:
+        break;
+    }
+    return rv;
+}
+
+int
+fips_hashLen(HASH_HashType type)
+{
+    int len = 0;
+
+    switch (type) {
+    case HASH_AlgSHA1:
+        len = SHA1_LENGTH;
+        break;
+    case HASH_AlgSHA224:
+        len = SHA224_LENGTH;
+        break;
+    case HASH_AlgSHA256:
+        len = SHA256_LENGTH;
+        break;
+    case HASH_AlgSHA384:
+        len = SHA384_LENGTH;
+        break;
+    case HASH_AlgSHA512:
+        len = SHA512_LENGTH;
+        break;
+    default:
+        break;
     }
+    return len;
+}
 
-    /* Return NULL if curve name is not recognized */
-    if ((curveOidTag == SEC_OID_UNKNOWN) || 
-	(oidData = SECOID_FindOIDByTag(curveOidTag)) == NULL) {
-        fprintf(stderr, "Unrecognized elliptic curve %s\n", curve);
-	return NULL;
-    }
+SECOidTag
+fips_hashOid(HASH_HashType type)
+{
+    SECOidTag oid = SEC_OID_UNKNOWN;
 
-    ecparams = SECITEM_AllocItem(NULL, NULL, (2 + oidData->oid.len));
+    switch (type) {
+    case HASH_AlgSHA1:
+        oid = SEC_OID_SHA1;
+        break;
+    case HASH_AlgSHA224:
+        oid = SEC_OID_SHA224;
+        break;
+    case HASH_AlgSHA256:
+        oid = SEC_OID_SHA256;
+        break;
+    case HASH_AlgSHA384:
+        oid = SEC_OID_SHA384;
+        break;
+    case HASH_AlgSHA512:
+        oid = SEC_OID_SHA512;
+        break;
+    default:
+        break;
+    }
+    return oid;
+}
 
-    /* 
-     * ecparams->data needs to contain the ASN encoding of an object ID (OID)
-     * representing the named curve. The actual OID is in 
-     * oidData->oid.data so we simply prepend 0x06 and OID length
-     */
-    ecparams->data[0] = SEC_ASN1_OBJECT_ID;
-    ecparams->data[1] = oidData->oid.len;
-    memcpy(ecparams->data + 2, oidData->oid.data, oidData->oid.len);
+HASH_HashType
+sha_get_hashType(int hashbits)
+{
+    HASH_HashType hashType = HASH_AlgNULL;
 
-    return ecparams;
+    switch (hashbits) {
+    case 1:
+    case (SHA1_LENGTH*PR_BITS_PER_BYTE): 
+        hashType = HASH_AlgSHA1;
+        break;
+    case (SHA224_LENGTH*PR_BITS_PER_BYTE): 
+        hashType = HASH_AlgSHA224;
+        break;
+    case (SHA256_LENGTH*PR_BITS_PER_BYTE): 
+        hashType = HASH_AlgSHA256;
+        break;
+    case (SHA384_LENGTH*PR_BITS_PER_BYTE): 
+        hashType = HASH_AlgSHA384;
+        break;
+    case (SHA512_LENGTH*PR_BITS_PER_BYTE): 
+        hashType = HASH_AlgSHA512;
+        break;
+    default:
+        break;
+    }
+    return hashType;
 }
 
 /*
@@ -1996,7 +2342,7 @@ ecdsa_keypair_test(char *reqfn)
     FILE *ecdsareq;     /* input stream from the REQUEST file */
     FILE *ecdsaresp;    /* output stream to the RESPONSE file */
     char curve[16];     /* "nistxddd" */
-    ECParams *ecparams;
+    ECParams *ecparams = NULL;
     int N;
     int i;
     unsigned int len;
@@ -2005,81 +2351,95 @@ ecdsa_keypair_test(char *reqfn)
     ecdsaresp = stdout;
     strcpy(curve, "nist");
     while (fgets(buf, sizeof buf, ecdsareq) != NULL) {
-	/* a comment or blank line */
-	if (buf[0] == '#' || buf[0] == '\n') {
-	    fputs(buf, ecdsaresp);
-	    continue;
-	}
-	/* [X-ddd] */
-	if (buf[0] == '[') {
-	    const char *src;
-	    char *dst;
-	    SECItem *encodedparams;
-
-	    src = &buf[1];
-	    dst = &curve[4];
-	    *dst++ = tolower(*src);
-	    src += 2;  /* skip the hyphen */
-	    *dst++ = *src++;
-	    *dst++ = *src++;
-	    *dst++ = *src++;
-	    *dst = '\0';
-	    encodedparams = getECParams(curve);
-	    if (encodedparams == NULL) {
-		goto loser;
-	    }
-	    if (EC_DecodeParams(encodedparams, &ecparams) != SECSuccess) {
-		goto loser;
-	    }
-	    SECITEM_FreeItem(encodedparams, PR_TRUE);
-	    fputs(buf, ecdsaresp);
-	    continue;
-	}
-	/* N = x */
-	if (buf[0] == 'N') {
-	    if (sscanf(buf, "N = %d", &N) != 1) {
-		goto loser;
-	    }
-	    for (i = 0; i < N; i++) {
-		ECPrivateKey *ecpriv;
+        /* a comment or blank line */
+        if (buf[0] == '#' || buf[0] == '\n') {
+            fputs(buf, ecdsaresp);
+            continue;
+        }
+        /* [X-ddd] */
+        if (buf[0] == '[') {
+            const char *src;
+            char *dst;
+            SECItem *encodedparams;
 
-		if (EC_NewKey(ecparams, &ecpriv) != SECSuccess) {
-		    goto loser;
-		}
-		fputs("d = ", ecdsaresp);
-		to_hex_str(buf, ecpriv->privateValue.data,
-			   ecpriv->privateValue.len);
-		fputs(buf, ecdsaresp);
-		fputc('\n', ecdsaresp);
-		if (EC_ValidatePublicKey(ecparams, &ecpriv->publicValue)
-		    != SECSuccess) {
-		    goto loser;
-		}
-		len = ecpriv->publicValue.len;
-		if (len%2 == 0) {
-		    goto loser;
-		}
-		len = (len-1)/2;
-		if (ecpriv->publicValue.data[0]
-		    != EC_POINT_FORM_UNCOMPRESSED) {
-		    goto loser;
-		}
-		fputs("Qx = ", ecdsaresp);
-		to_hex_str(buf, &ecpriv->publicValue.data[1], len);
-		fputs(buf, ecdsaresp);
-		fputc('\n', ecdsaresp);
-		fputs("Qy = ", ecdsaresp);
-		to_hex_str(buf, &ecpriv->publicValue.data[1+len], len);
-		fputs(buf, ecdsaresp);
-		fputc('\n', ecdsaresp);
-		fputc('\n', ecdsaresp);
-		PORT_FreeArena(ecpriv->ecParams.arena, PR_TRUE);
-	    }
-	    PORT_FreeArena(ecparams->arena, PR_FALSE);
-	    continue;
-	}
+            if (buf[1] == 'B') {
+                fputs(buf, ecdsaresp);
+                continue;
+            }
+            if (ecparams) {
+                PORT_FreeArena(ecparams->arena, PR_FALSE);
+                ecparams = NULL;
+            }
+
+            src = &buf[1];
+            dst = &curve[4];
+            *dst++ = tolower(*src);
+            src += 2;  /* skip the hyphen */
+            *dst++ = *src++;
+            *dst++ = *src++;
+            *dst++ = *src++;
+            *dst = '\0';
+            encodedparams = getECParams(curve);
+            if (encodedparams == NULL) {
+                fprintf(stderr, "Unknown curve %s.", curve);
+                goto loser;
+            }
+            if (EC_DecodeParams(encodedparams, &ecparams) != SECSuccess) {
+                fprintf(stderr, "Curve %s not supported.\n", curve);
+                goto loser;
+            }
+            SECITEM_FreeItem(encodedparams, PR_TRUE);
+            fputs(buf, ecdsaresp);
+            continue;
+        }
+        /* N = x */
+        if (buf[0] == 'N') {
+            if (sscanf(buf, "N = %d", &N) != 1) {
+                goto loser;
+            }
+            for (i = 0; i < N; i++) {
+                ECPrivateKey *ecpriv;
+
+                if (EC_NewKey(ecparams, &ecpriv) != SECSuccess) {
+                    goto loser;
+                }
+                fputs("d = ", ecdsaresp);
+                to_hex_str(buf, ecpriv->privateValue.data,
+                           ecpriv->privateValue.len);
+                fputs(buf, ecdsaresp);
+                fputc('\n', ecdsaresp);
+                if (EC_ValidatePublicKey(ecparams, &ecpriv->publicValue)
+                    != SECSuccess) {
+                    goto loser;
+                }
+                len = ecpriv->publicValue.len;
+                if (len%2 == 0) {
+                    goto loser;
+                }
+                len = (len-1)/2;
+                if (ecpriv->publicValue.data[0]
+                    != EC_POINT_FORM_UNCOMPRESSED) {
+                    goto loser;
+                }
+                fputs("Qx = ", ecdsaresp);
+                to_hex_str(buf, &ecpriv->publicValue.data[1], len);
+                fputs(buf, ecdsaresp);
+                fputc('\n', ecdsaresp);
+                fputs("Qy = ", ecdsaresp);
+                to_hex_str(buf, &ecpriv->publicValue.data[1+len], len);
+                fputs(buf, ecdsaresp);
+                fputc('\n', ecdsaresp);
+                fputc('\n', ecdsaresp);
+                PORT_FreeArena(ecpriv->ecParams.arena, PR_TRUE);
+            }
+            continue;
+        }
     }
 loser:
+    if (ecparams) {
+        PORT_FreeArena(ecparams->arena, PR_FALSE);
+        ecparams = NULL;
+    }
     fclose(ecdsareq);
 }
 
@@ -2111,92 +2471,94 @@ ecdsa_pkv_test(char *reqfn)
     strcpy(curve, "nist");
     pubkey.data = NULL;
     while (fgets(buf, sizeof buf, ecdsareq) != NULL) {
-	/* a comment or blank line */
-	if (buf[0] == '#' || buf[0] == '\n') {
-	    fputs(buf, ecdsaresp);
-	    continue;
-	}
-	/* [X-ddd] */
-	if (buf[0] == '[') {
-	    const char *src;
-	    char *dst;
-	    SECItem *encodedparams;
-
-	    src = &buf[1];
-	    dst = &curve[4];
-	    *dst++ = tolower(*src);
-	    src += 2;  /* skip the hyphen */
-	    *dst++ = *src++;
-	    *dst++ = *src++;
-	    *dst++ = *src++;
-	    *dst = '\0';
-	    if (ecparams != NULL) {
-		PORT_FreeArena(ecparams->arena, PR_FALSE);
-		ecparams = NULL;
-	    }
-	    encodedparams = getECParams(curve);
-	    if (encodedparams == NULL) {
-		goto loser;
-	    }
-	    if (EC_DecodeParams(encodedparams, &ecparams) != SECSuccess) {
-		goto loser;
-	    }
-	    SECITEM_FreeItem(encodedparams, PR_TRUE);
-	    len = (ecparams->fieldID.size + 7) >> 3;
-	    if (pubkey.data != NULL) {
-		PORT_Free(pubkey.data);
-		pubkey.data = NULL;
-	    }
-	    SECITEM_AllocItem(NULL, &pubkey, 2*len+1);
-	    if (pubkey.data == NULL) {
-		goto loser;
-	    }
-	    pubkey.data[0] = EC_POINT_FORM_UNCOMPRESSED;
-	    fputs(buf, ecdsaresp);
-	    continue;
-	}
-	/* Qx = ... */
-	if (strncmp(buf, "Qx", 2) == 0) {
-	    fputs(buf, ecdsaresp);
-	    i = 2;
-	    while (isspace(buf[i]) || buf[i] == '=') {
-		i++;
-	    }
-	    keyvalid = from_hex_str(&pubkey.data[1], len, &buf[i]);
-	    continue;
-	}
-	/* Qy = ... */
-	if (strncmp(buf, "Qy", 2) == 0) {
-	    fputs(buf, ecdsaresp);
-	    if (!keyvalid) {
-		fputs("Result = F\n", ecdsaresp);
-		continue;
-	    }
-	    i = 2;
-	    while (isspace(buf[i]) || buf[i] == '=') {
-		i++;
-	    }
-	    keyvalid = from_hex_str(&pubkey.data[1+len], len, &buf[i]);
-	    if (!keyvalid) {
-		fputs("Result = F\n", ecdsaresp);
-		continue;
-	    }
-	    if (EC_ValidatePublicKey(ecparams, &pubkey) == SECSuccess) {
-		fputs("Result = P\n", ecdsaresp);
-	    } else if (PORT_GetError() == SEC_ERROR_BAD_KEY) {
-		fputs("Result = F\n", ecdsaresp);
-	    } else {
-		goto loser;
-	    }
-	    continue;
-	}
+        /* a comment or blank line */
+        if (buf[0] == '#' || buf[0] == '\n') {
+            fputs(buf, ecdsaresp);
+            continue;
+        }
+        /* [X-ddd] */
+        if (buf[0] == '[') {
+            const char *src;
+            char *dst;
+            SECItem *encodedparams;
+
+            src = &buf[1];
+            dst = &curve[4];
+            *dst++ = tolower(*src);
+            src += 2;  /* skip the hyphen */
+            *dst++ = *src++;
+            *dst++ = *src++;
+            *dst++ = *src++;
+            *dst = '\0';
+            if (ecparams != NULL) {
+                PORT_FreeArena(ecparams->arena, PR_FALSE);
+                ecparams = NULL;
+            }
+            encodedparams = getECParams(curve);
+            if (encodedparams == NULL) {
+                fprintf(stderr, "Unknown curve %s.", curve);
+                goto loser;
+            }
+            if (EC_DecodeParams(encodedparams, &ecparams) != SECSuccess) {
+                fprintf(stderr, "Curve %s not supported.\n", curve);
+                goto loser;
+            }
+            SECITEM_FreeItem(encodedparams, PR_TRUE);
+            len = (ecparams->fieldID.size + 7) >> 3;
+            if (pubkey.data != NULL) {
+                PORT_Free(pubkey.data);
+                pubkey.data = NULL;
+            }
+            SECITEM_AllocItem(NULL, &pubkey, 2*len+1);
+            if (pubkey.data == NULL) {
+                goto loser;
+            }
+            pubkey.data[0] = EC_POINT_FORM_UNCOMPRESSED;
+            fputs(buf, ecdsaresp);
+            continue;
+        }
+        /* Qx = ... */
+        if (strncmp(buf, "Qx", 2) == 0) {
+            fputs(buf, ecdsaresp);
+            i = 2;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            keyvalid = from_hex_str(&pubkey.data[1], len, &buf[i]);
+            continue;
+        }
+        /* Qy = ... */
+        if (strncmp(buf, "Qy", 2) == 0) {
+            fputs(buf, ecdsaresp);
+            if (!keyvalid) {
+                fputs("Result = F\n", ecdsaresp);
+                continue;
+            }
+            i = 2;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            keyvalid = from_hex_str(&pubkey.data[1+len], len, &buf[i]);
+            if (!keyvalid) {
+                fputs("Result = F\n", ecdsaresp);
+                continue;
+            }
+            if (EC_ValidatePublicKey(ecparams, &pubkey) == SECSuccess) {
+                fputs("Result = P\n", ecdsaresp);
+            } else if (PORT_GetError() == SEC_ERROR_BAD_KEY) {
+                fputs("Result = F\n", ecdsaresp);
+            } else {
+                goto loser;
+            }
+            continue;
+        }
     }
 loser:
     if (ecparams != NULL) {
-	PORT_FreeArena(ecparams->arena, PR_FALSE);
+        PORT_FreeArena(ecparams->arena, PR_FALSE);
     }
     if (pubkey.data != NULL) {
-	PORT_Free(pubkey.data);
+        PORT_Free(pubkey.data);
     }
     fclose(ecdsareq);
 }
@@ -2224,7 +2586,9 @@ ecdsa_siggen_test(char *reqfn)
     unsigned int len;
     unsigned char msg[512];  /* message to be signed (<= 128 bytes) */
     unsigned int msglen;
-    unsigned char sha1[20];  /* SHA-1 hash (160 bits) */
+    unsigned char  sha[HASH_LENGTH_MAX];    /* SHA digest */
+    unsigned int   shaLength = 0;           /* length of SHA */
+    HASH_HashType  shaAlg = HASH_AlgNULL;   /* type of SHA Alg */
     unsigned char sig[2*MAX_ECKEY_LEN];
     SECItem signature, digest;
 
@@ -2232,111 +2596,135 @@ ecdsa_siggen_test(char *reqfn)
     ecdsaresp = stdout;
     strcpy(curve, "nist");
     while (fgets(buf, sizeof buf, ecdsareq) != NULL) {
-	/* a comment or blank line */
-	if (buf[0] == '#' || buf[0] == '\n') {
-	    fputs(buf, ecdsaresp);
-	    continue;
-	}
-	/* [X-ddd] */
-	if (buf[0] == '[') {
-	    const char *src;
-	    char *dst;
-	    SECItem *encodedparams;
-
-	    src = &buf[1];
-	    dst = &curve[4];
-	    *dst++ = tolower(*src);
-	    src += 2;  /* skip the hyphen */
-	    *dst++ = *src++;
-	    *dst++ = *src++;
-	    *dst++ = *src++;
-	    *dst = '\0';
-	    if (ecparams != NULL) {
-		PORT_FreeArena(ecparams->arena, PR_FALSE);
-		ecparams = NULL;
-	    }
-	    encodedparams = getECParams(curve);
-	    if (encodedparams == NULL) {
-		goto loser;
-	    }
-	    if (EC_DecodeParams(encodedparams, &ecparams) != SECSuccess) {
-		goto loser;
-	    }
-	    SECITEM_FreeItem(encodedparams, PR_TRUE);
-	    fputs(buf, ecdsaresp);
-	    continue;
-	}
-	/* Msg = ... */
-	if (strncmp(buf, "Msg", 3) == 0) {
-	    ECPrivateKey *ecpriv;
+        /* a comment or blank line */
+        if (buf[0] == '#' || buf[0] == '\n') {
+            fputs(buf, ecdsaresp);
+            continue;
+        }
+        /* [X-ddd] */
+        if (buf[0] == '[') {
+            const char *src;
+            char *dst;
+            SECItem *encodedparams;
+
+            src = &buf[1];
+            dst = &curve[4];
+            *dst++ = tolower(*src);
+            src += 2;  /* skip the hyphen */
+            *dst++ = *src++;
+            *dst++ = *src++;
+            *dst++ = *src++;
+            *dst = '\0';
+            src++; /* skip the comma */
+            /* set the SHA Algorithm */
+            if (strncmp(src, "SHA-1", 5) == 0) {
+                shaAlg = HASH_AlgSHA1;
+            } else if (strncmp(src, "SHA-224", 7) == 0) {
+                shaAlg = HASH_AlgSHA224;
+            } else if (strncmp(src, "SHA-256", 7) == 0) {
+                shaAlg = HASH_AlgSHA256;
+            } else if (strncmp(src, "SHA-384", 7)== 0) {
+               shaAlg = HASH_AlgSHA384;
+            } else if (strncmp(src, "SHA-512", 7) == 0) {
+               shaAlg = HASH_AlgSHA512;
+            } else {
+               fprintf(ecdsaresp, "ERROR: Unable to find SHAAlg type");
+               goto loser;
+            }
+            if (ecparams != NULL) {
+                PORT_FreeArena(ecparams->arena, PR_FALSE);
+                ecparams = NULL;
+            }
+            encodedparams = getECParams(curve);
+            if (encodedparams == NULL) {
+                fprintf(stderr, "Unknown curve %s.", curve);
+                goto loser;
+            }
+            if (EC_DecodeParams(encodedparams, &ecparams) != SECSuccess) {
+                fprintf(stderr, "Curve %s not supported.\n", curve);
+                goto loser;
+            }
+            SECITEM_FreeItem(encodedparams, PR_TRUE);
+            fputs(buf, ecdsaresp);
+            continue;
+        }
+        /* Msg = ... */
+        if (strncmp(buf, "Msg", 3) == 0) {
+            ECPrivateKey *ecpriv;
 
-	    i = 3;
-	    while (isspace(buf[i]) || buf[i] == '=') {
-		i++;
-	    }
-	    for (j=0; isxdigit(buf[i]); i+=2,j++) {
-		hex_to_byteval(&buf[i], &msg[j]);
-	    }
-	    msglen = j;
-	    if (SHA1_HashBuf(sha1, msg, msglen) != SECSuccess) {
-		goto loser;
-	    }
-	    fputs(buf, ecdsaresp);
+            i = 3;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            for (j=0; isxdigit(buf[i]); i+=2,j++) {
+                hex_to_byteval(&buf[i], &msg[j]);
+            }
+            msglen = j;
+            shaLength = fips_hashLen(shaAlg);
+            if (fips_hashBuf(shaAlg,sha,msg,msglen) != SECSuccess) {
+                if (shaLength == 0) {
+                        fprintf(ecdsaresp, "ERROR: SHAAlg not defined.");
+                }
+                fprintf(ecdsaresp, "ERROR: Unable to generate SHA%x",
+                        shaLength == 160 ? 1 : shaLength);
+                goto loser;
+            }
+            fputs(buf, ecdsaresp);
 
-	    if (EC_NewKey(ecparams, &ecpriv) != SECSuccess) {
-		goto loser;
-	    }
-	    if (EC_ValidatePublicKey(ecparams, &ecpriv->publicValue)
-		!= SECSuccess) {
-		goto loser;
-	    }
-	    len = ecpriv->publicValue.len;
-	    if (len%2 == 0) {
-		goto loser;
-	    }
-	    len = (len-1)/2;
-	    if (ecpriv->publicValue.data[0] != EC_POINT_FORM_UNCOMPRESSED) {
-		goto loser;
-	    }
-	    fputs("Qx = ", ecdsaresp);
-	    to_hex_str(buf, &ecpriv->publicValue.data[1], len);
-	    fputs(buf, ecdsaresp);
-	    fputc('\n', ecdsaresp);
-	    fputs("Qy = ", ecdsaresp);
-	    to_hex_str(buf, &ecpriv->publicValue.data[1+len], len);
-	    fputs(buf, ecdsaresp);
-	    fputc('\n', ecdsaresp);
-
-	    digest.type = siBuffer;
-	    digest.data = sha1;
-	    digest.len = sizeof sha1;
-	    signature.type = siBuffer;
-	    signature.data = sig;
-	    signature.len = sizeof sig;
-	    if (ECDSA_SignDigest(ecpriv, &signature, &digest) != SECSuccess) {
-		goto loser;
-	    }
-	    len = signature.len;
-	    if (len%2 != 0) {
-		goto loser;
-	    }
-	    len = len/2;
-	    fputs("R = ", ecdsaresp);
-	    to_hex_str(buf, &signature.data[0], len);
-	    fputs(buf, ecdsaresp);
-	    fputc('\n', ecdsaresp);
-	    fputs("S = ", ecdsaresp);
-	    to_hex_str(buf, &signature.data[len], len);
-	    fputs(buf, ecdsaresp);
-	    fputc('\n', ecdsaresp);
+            if (EC_NewKey(ecparams, &ecpriv) != SECSuccess) {
+                goto loser;
+            }
+            if (EC_ValidatePublicKey(ecparams, &ecpriv->publicValue)
+                != SECSuccess) {
+                goto loser;
+            }
+            len = ecpriv->publicValue.len;
+            if (len%2 == 0) {
+                goto loser;
+            }
+            len = (len-1)/2;
+            if (ecpriv->publicValue.data[0] != EC_POINT_FORM_UNCOMPRESSED) {
+                goto loser;
+            }
+            fputs("Qx = ", ecdsaresp);
+            to_hex_str(buf, &ecpriv->publicValue.data[1], len);
+            fputs(buf, ecdsaresp);
+            fputc('\n', ecdsaresp);
+            fputs("Qy = ", ecdsaresp);
+            to_hex_str(buf, &ecpriv->publicValue.data[1+len], len);
+            fputs(buf, ecdsaresp);
+            fputc('\n', ecdsaresp);
 
-	    PORT_FreeArena(ecpriv->ecParams.arena, PR_TRUE);
-	    continue;
-	}
+            digest.type = siBuffer;
+            digest.data = sha;
+            digest.len = shaLength;
+            signature.type = siBuffer;
+            signature.data = sig;
+            signature.len = sizeof sig;
+            if (ECDSA_SignDigest(ecpriv, &signature, &digest) != SECSuccess) {
+                goto loser;
+            }
+            len = signature.len;
+            if (len%2 != 0) {
+                goto loser;
+            }
+            len = len/2;
+            fputs("R = ", ecdsaresp);
+            to_hex_str(buf, &signature.data[0], len);
+            fputs(buf, ecdsaresp);
+            fputc('\n', ecdsaresp);
+            fputs("S = ", ecdsaresp);
+            to_hex_str(buf, &signature.data[len], len);
+            fputs(buf, ecdsaresp);
+            fputc('\n', ecdsaresp);
+
+            PORT_FreeArena(ecpriv->ecParams.arena, PR_TRUE);
+            continue;
+        }
     }
 loser:
     if (ecparams != NULL) {
-	PORT_FreeArena(ecparams->arena, PR_FALSE);
+        PORT_FreeArena(ecparams->arena, PR_FALSE);
     }
     fclose(ecdsareq);
 }
@@ -2364,7 +2752,9 @@ ecdsa_sigver_test(char *reqfn)
     unsigned int olen;  /* length in bytes of the base point order */
     unsigned char msg[512];  /* message that was signed (<= 128 bytes) */
     unsigned int msglen;
-    unsigned char sha1[20];  /* SHA-1 hash (160 bits) */
+    unsigned char  sha[HASH_LENGTH_MAX];    /* SHA digest */
+    unsigned int   shaLength = 0;           /* length of SHA */
+    HASH_HashType  shaAlg = HASH_AlgNULL;   /* type of SHA Alg */
     unsigned char sig[2*MAX_ECKEY_LEN];
     SECItem signature, digest;
     PRBool keyvalid = PR_TRUE;
@@ -2375,158 +2765,182 @@ ecdsa_sigver_test(char *reqfn)
     ecpub.ecParams.arena = NULL;
     strcpy(curve, "nist");
     while (fgets(buf, sizeof buf, ecdsareq) != NULL) {
-	/* a comment or blank line */
-	if (buf[0] == '#' || buf[0] == '\n') {
-	    fputs(buf, ecdsaresp);
-	    continue;
-	}
-	/* [X-ddd] */
-	if (buf[0] == '[') {
-	    const char *src;
-	    char *dst;
-	    SECItem *encodedparams;
-	    ECParams *ecparams;
-
-	    src = &buf[1];
-	    dst = &curve[4];
-	    *dst++ = tolower(*src);
-	    src += 2;  /* skip the hyphen */
-	    *dst++ = *src++;
-	    *dst++ = *src++;
-	    *dst++ = *src++;
-	    *dst = '\0';
-	    encodedparams = getECParams(curve);
-	    if (encodedparams == NULL) {
-		goto loser;
-	    }
-	    if (EC_DecodeParams(encodedparams, &ecparams) != SECSuccess) {
-		goto loser;
-	    }
-	    SECITEM_FreeItem(encodedparams, PR_TRUE);
-	    if (ecpub.ecParams.arena != NULL) {
-		PORT_FreeArena(ecpub.ecParams.arena, PR_FALSE);
-	    }
-	    ecpub.ecParams.arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
-	    if (ecpub.ecParams.arena == NULL) {
-		goto loser;
-	    }
-	    if (EC_CopyParams(ecpub.ecParams.arena, &ecpub.ecParams, ecparams)
-		!= SECSuccess) {
-		goto loser;
-	    }
-	    PORT_FreeArena(ecparams->arena, PR_FALSE);
-	    flen = (ecpub.ecParams.fieldID.size + 7) >> 3;
-	    olen = ecpub.ecParams.order.len;
-	    if (2*olen > sizeof sig) {
-		goto loser;
-	    }
-	    ecpub.publicValue.type = siBuffer;
-	    ecpub.publicValue.data = NULL;
-	    ecpub.publicValue.len = 0;
-	    SECITEM_AllocItem(ecpub.ecParams.arena,
-			      &ecpub.publicValue, 2*flen+1);
-	    if (ecpub.publicValue.data == NULL) {
-		goto loser;
-	    }
-	    ecpub.publicValue.data[0] = EC_POINT_FORM_UNCOMPRESSED;
-	    fputs(buf, ecdsaresp);
-	    continue;
-	}
-	/* Msg = ... */
-	if (strncmp(buf, "Msg", 3) == 0) {
-	    i = 3;
-	    while (isspace(buf[i]) || buf[i] == '=') {
-		i++;
-	    }
-	    for (j=0; isxdigit(buf[i]); i+=2,j++) {
-		hex_to_byteval(&buf[i], &msg[j]);
-	    }
-	    msglen = j;
-	    if (SHA1_HashBuf(sha1, msg, msglen) != SECSuccess) {
-		goto loser;
-	    }
-	    fputs(buf, ecdsaresp);
+        /* a comment or blank line */
+        if (buf[0] == '#' || buf[0] == '\n') {
+            fputs(buf, ecdsaresp);
+            continue;
+        }
+        /* [X-ddd] */
+        if (buf[0] == '[') {
+            const char *src;
+            char *dst;
+            SECItem *encodedparams;
+            ECParams *ecparams;
+
+            src = &buf[1];
+            dst = &curve[4];
+            *dst++ = tolower(*src);
+            src += 2;  /* skip the hyphen */
+            *dst++ = *src++;
+            *dst++ = *src++;
+            *dst++ = *src++;
+            *dst = '\0';
+            src++; /* skip the comma */
+            /* set the SHA Algorithm */
+            if (strncmp(src, "SHA-1", 5) == 0) {
+                shaAlg = HASH_AlgSHA1;
+            } else if (strncmp(src, "SHA-224", 7) == 0) {
+                shaAlg = HASH_AlgSHA224;
+            } else if (strncmp(src, "SHA-256", 7) == 0) {
+                shaAlg = HASH_AlgSHA256;
+            } else if (strncmp(src, "SHA-384", 7)== 0) {
+               shaAlg = HASH_AlgSHA384;
+            } else if (strncmp(src, "SHA-512", 7) == 0) {
+               shaAlg = HASH_AlgSHA512;
+            } else {
+               fprintf(ecdsaresp, "ERROR: Unable to find SHAAlg type");
+               goto loser;
+            }
+            encodedparams = getECParams(curve);
+            if (encodedparams == NULL) {
+                fprintf(stderr, "Unknown curve %s.", curve);
+                goto loser;
+            }
+            if (EC_DecodeParams(encodedparams, &ecparams) != SECSuccess) {
+                fprintf(stderr, "Curve %s not supported.\n", curve);
+                goto loser;
+            }
+            SECITEM_FreeItem(encodedparams, PR_TRUE);
+            if (ecpub.ecParams.arena != NULL) {
+                PORT_FreeArena(ecpub.ecParams.arena, PR_FALSE);
+            }
+            ecpub.ecParams.arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+            if (ecpub.ecParams.arena == NULL) {
+                goto loser;
+            }
+            if (EC_CopyParams(ecpub.ecParams.arena, &ecpub.ecParams, ecparams)
+                != SECSuccess) {
+                goto loser;
+            }
+            PORT_FreeArena(ecparams->arena, PR_FALSE);
+            flen = (ecpub.ecParams.fieldID.size + 7) >> 3;
+            olen = ecpub.ecParams.order.len;
+            if (2*olen > sizeof sig) {
+                goto loser;
+            }
+            ecpub.publicValue.type = siBuffer;
+            ecpub.publicValue.data = NULL;
+            ecpub.publicValue.len = 0;
+            SECITEM_AllocItem(ecpub.ecParams.arena,
+                              &ecpub.publicValue, 2*flen+1);
+            if (ecpub.publicValue.data == NULL) {
+                goto loser;
+            }
+            ecpub.publicValue.data[0] = EC_POINT_FORM_UNCOMPRESSED;
+            fputs(buf, ecdsaresp);
+            continue;
+        }
+        /* Msg = ... */
+        if (strncmp(buf, "Msg", 3) == 0) {
+            i = 3;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            for (j=0; isxdigit(buf[i]); i+=2,j++) {
+                hex_to_byteval(&buf[i], &msg[j]);
+            }
+            msglen = j;
+            shaLength = fips_hashLen(shaAlg);
+            if (fips_hashBuf(shaAlg,sha,msg,msglen) != SECSuccess) {
+                if (shaLength == 0) {
+                        fprintf(ecdsaresp, "ERROR: SHAAlg not defined.");
+                }
+                fprintf(ecdsaresp, "ERROR: Unable to generate SHA%x",
+                        shaLength == 160 ? 1 : shaLength);
+                goto loser;
+            }
+            fputs(buf, ecdsaresp);
 
-	    digest.type = siBuffer;
-	    digest.data = sha1;
-	    digest.len = sizeof sha1;
+            digest.type = siBuffer;
+            digest.data = sha;
+            digest.len = shaLength;
 
-	    continue;
-	}
-	/* Qx = ... */
-	if (strncmp(buf, "Qx", 2) == 0) {
-	    fputs(buf, ecdsaresp);
-	    i = 2;
-	    while (isspace(buf[i]) || buf[i] == '=') {
-		i++;
-	    }
-	    keyvalid = from_hex_str(&ecpub.publicValue.data[1], flen,
-				    &buf[i]);
-	    continue;
-	}
-	/* Qy = ... */
-	if (strncmp(buf, "Qy", 2) == 0) {
-	    fputs(buf, ecdsaresp);
-	    if (!keyvalid) {
-		continue;
-	    }
-	    i = 2;
-	    while (isspace(buf[i]) || buf[i] == '=') {
-		i++;
-	    }
-	    keyvalid = from_hex_str(&ecpub.publicValue.data[1+flen], flen,
-				    &buf[i]);
-	    if (!keyvalid) {
-		continue;
-	    }
-	    if (EC_ValidatePublicKey(&ecpub.ecParams, &ecpub.publicValue)
-		!= SECSuccess) {
-		if (PORT_GetError() == SEC_ERROR_BAD_KEY) {
-		    keyvalid = PR_FALSE;
-		} else {
-		    goto loser;
-		}
-	    }
-	    continue;
-	}
-	/* R = ... */
-	if (buf[0] == 'R') {
-	    fputs(buf, ecdsaresp);
-	    i = 1;
-	    while (isspace(buf[i]) || buf[i] == '=') {
-		i++;
-	    }
-	    sigvalid = from_hex_str(sig, olen, &buf[i]);
-	    continue;
-	}
-	/* S = ... */
-	if (buf[0] == 'S') {
-	    fputs(buf, ecdsaresp);
-	    i = 1;
-	    while (isspace(buf[i]) || buf[i] == '=') {
-		i++;
-	    }
-	    if (sigvalid) {
-		sigvalid = from_hex_str(&sig[olen], olen, &buf[i]);
-	    }
-	    signature.type = siBuffer;
-	    signature.data = sig;
-	    signature.len = 2*olen;
-
-	    if (!keyvalid || !sigvalid) {
-		fputs("Result = F\n", ecdsaresp);
-	    } else if (ECDSA_VerifyDigest(&ecpub, &signature, &digest)
-		== SECSuccess) {
-		fputs("Result = P\n", ecdsaresp);
-	    } else {
-		fputs("Result = F\n", ecdsaresp);
-	    }
-	    continue;
-	}
+            continue;
+        }
+        /* Qx = ... */
+        if (strncmp(buf, "Qx", 2) == 0) {
+            fputs(buf, ecdsaresp);
+            i = 2;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            keyvalid = from_hex_str(&ecpub.publicValue.data[1], flen,
+                                    &buf[i]);
+            continue;
+        }
+        /* Qy = ... */
+        if (strncmp(buf, "Qy", 2) == 0) {
+            fputs(buf, ecdsaresp);
+            if (!keyvalid) {
+                continue;
+            }
+            i = 2;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            keyvalid = from_hex_str(&ecpub.publicValue.data[1+flen], flen,
+                                    &buf[i]);
+            if (!keyvalid) {
+                continue;
+            }
+            if (EC_ValidatePublicKey(&ecpub.ecParams, &ecpub.publicValue)
+                != SECSuccess) {
+                if (PORT_GetError() == SEC_ERROR_BAD_KEY) {
+                    keyvalid = PR_FALSE;
+                } else {
+                    goto loser;
+                }
+            }
+            continue;
+        }
+        /* R = ... */
+        if (buf[0] == 'R') {
+            fputs(buf, ecdsaresp);
+            i = 1;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            sigvalid = from_hex_str(sig, olen, &buf[i]);
+            continue;
+        }
+        /* S = ... */
+        if (buf[0] == 'S') {
+            fputs(buf, ecdsaresp);
+            i = 1;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            if (sigvalid) {
+                sigvalid = from_hex_str(&sig[olen], olen, &buf[i]);
+            }
+            signature.type = siBuffer;
+            signature.data = sig;
+            signature.len = 2*olen;
+
+            if (!keyvalid || !sigvalid) {
+                fputs("Result = F\n", ecdsaresp);
+            } else if (ECDSA_VerifyDigest(&ecpub, &signature, &digest)
+                == SECSuccess) {
+                fputs("Result = P\n", ecdsaresp);
+            } else {
+                fputs("Result = F\n", ecdsaresp);
+            }
+            continue;
+        }
     }
 loser:
     if (ecpub.ecParams.arena != NULL) {
-	PORT_FreeArena(ecpub.ecParams.arena, PR_FALSE);
+        PORT_FreeArena(ecpub.ecParams.arena, PR_FALSE);
     }
     fclose(ecdsareq);
 }
@@ -2543,8 +2957,8 @@ alloc_value(char *buf, int *len)
     int i, count;
 
     if (strncmp(buf, "<None>", 6) == 0) {
-	*len = 0;
-	return NULL;
+        *len = 0;
+        return NULL;
     }
 
     /* find the length of the number */
@@ -2552,17 +2966,17 @@ alloc_value(char *buf, int *len)
     *len = count/2;
 
     if (*len == 0) {
-	return NULL;
+        return NULL;
     }
 
     value = PORT_Alloc(*len);
     if (!value) {
-	*len = 0;
-	return NULL;
+        *len = 0;
+        return NULL;
     }
-	
+        
     for (i=0; i<*len; buf+=2 , i++) {
-	hex_to_byteval(buf, &value[i]);
+        hex_to_byteval(buf, &value[i]);
     }
     
 
@@ -2574,7 +2988,7 @@ isblankline(char *b)
 {
    while (isspace(*b)) b++;
    if ((*b == '\n') || (*b == 0)) {
-	return PR_TRUE;
+        return PR_TRUE;
    }
    return PR_FALSE;
 }
@@ -2608,9 +3022,9 @@ drbg(char *reqfn)
     int additionalInputLen = 0;
     unsigned char *entropyInput = NULL;
     int entropyInputLen = 0;
-    unsigned char predictedreturn_bytes[SHA256_LENGTH];
-    unsigned char return_bytes[SHA256_LENGTH];
-    int return_bytes_len = SHA256_LENGTH;
+    unsigned char *predictedreturn_bytes = NULL;
+    unsigned char *return_bytes = NULL;
+    int return_bytes_len = 0;
     enum { NONE, INSTANTIATE, GENERATE, RESEED, RESULT } command =
     NONE;
     PRBool genResult = PR_FALSE;
@@ -2621,23 +3035,23 @@ drbg(char *reqfn)
     while (fgets(buf, sizeof buf, rngreq) != NULL) {
        switch (command) {
             case INSTANTIATE:
-		if (debug) {
-		    fputs("# PRNGTEST_Instantiate(",rngresp);
-		    to_hex_str(buf2,entropyInput, entropyInputLen);
-		    fputs(buf2,rngresp);
-		    fprintf(rngresp,",%d,",entropyInputLen);
-		    to_hex_str(buf2,nonce, nonceLen);
-		    fputs(buf2,rngresp);
-		    fprintf(rngresp,",%d,",nonceLen);
-		    to_hex_str(buf2,personalizationString, 
-					personalizationStringLen);
-		    fputs(buf2,rngresp);
-		    fprintf(rngresp,",%d)\n", personalizationStringLen);
-		}
+                if (debug) {
+                    fputs("# PRNGTEST_Instantiate(",rngresp);
+                    to_hex_str(buf2,entropyInput, entropyInputLen);
+                    fputs(buf2,rngresp);
+                    fprintf(rngresp,",%d,",entropyInputLen);
+                    to_hex_str(buf2,nonce, nonceLen);
+                    fputs(buf2,rngresp);
+                    fprintf(rngresp,",%d,",nonceLen);
+                    to_hex_str(buf2,personalizationString, 
+                                        personalizationStringLen);
+                    fputs(buf2,rngresp);
+                    fprintf(rngresp,",%d)\n", personalizationStringLen);
+                }
                 rv = PRNGTEST_Instantiate(entropyInput, entropyInputLen,
                                           nonce, nonceLen,
                                           personalizationString, 
-				          personalizationStringLen);
+                                          personalizationStringLen);
                 if (rv != SECSuccess) {
                     goto loser;
                 }
@@ -2646,17 +3060,17 @@ drbg(char *reqfn)
             case GENERATE:
             case RESULT:
                 memset(return_bytes, 0, return_bytes_len);
-		if (debug) {
-		    fputs("# PRNGTEST_Generate(returnbytes",rngresp);
-		    fprintf(rngresp,",%d,", return_bytes_len);
-		    to_hex_str(buf2,additionalInput, additionalInputLen);
-		    fputs(buf2,rngresp);
-		    fprintf(rngresp,",%d)\n",additionalInputLen);
-		}
+                if (debug) {
+                    fputs("# PRNGTEST_Generate(returnbytes",rngresp);
+                    fprintf(rngresp,",%d,", return_bytes_len);
+                    to_hex_str(buf2,additionalInput, additionalInputLen);
+                    fputs(buf2,rngresp);
+                    fprintf(rngresp,",%d)\n",additionalInputLen);
+                }
                 rv = PRNGTEST_Generate((PRUint8 *) return_bytes, 
-					return_bytes_len,
+                                        return_bytes_len,
                                        (PRUint8 *) additionalInput, 
-					additionalInputLen);
+                                        additionalInputLen);
                 if (rv != SECSuccess) {
                     goto loser;
                 }
@@ -2666,9 +3080,9 @@ drbg(char *reqfn)
                     to_hex_str(buf2, return_bytes, return_bytes_len);
                     fputs(buf2, rngresp);
                     fputc('\n', rngresp);
-		    if (debug) {
-			fputs("# PRNGTEST_Uninstantiate()\n",rngresp);
-		    }
+                    if (debug) {
+                        fputs("# PRNGTEST_Uninstantiate()\n",rngresp);
+                    }
                     rv = PRNGTEST_Uninstantiate();
                     if (rv != SECSuccess) {
                         goto loser;
@@ -2678,23 +3092,23 @@ drbg(char *reqfn)
                     to_hex_str(buf2, return_bytes, return_bytes_len);
                     fputs(buf2, rngresp);
                     fputc('\n', rngresp);
-		}
+                }
                     
                 memset(additionalInput, 0, additionalInputLen);
                 break;
                     
             case RESEED:
                 if (entropyInput || additionalInput) {
-		    if (debug) {
-			fputs("# PRNGTEST_Reseed(",rngresp);
-			fprintf(rngresp,",%d,", return_bytes_len);
-			to_hex_str(buf2,entropyInput, entropyInputLen);
-			fputs(buf2,rngresp);
-			fprintf(rngresp,",%d,", entropyInputLen);
-			to_hex_str(buf2,additionalInput, additionalInputLen);
-			fputs(buf2,rngresp);
-			fprintf(rngresp,",%d)\n",additionalInputLen);
-		    }	
+                    if (debug) {
+                        fputs("# PRNGTEST_Reseed(",rngresp);
+                        fprintf(rngresp,",%d,", return_bytes_len);
+                        to_hex_str(buf2,entropyInput, entropyInputLen);
+                        fputs(buf2,rngresp);
+                        fprintf(rngresp,",%d,", entropyInputLen);
+                        to_hex_str(buf2,additionalInput, additionalInputLen);
+                        fputs(buf2,rngresp);
+                        fprintf(rngresp,",%d)\n",additionalInputLen);
+                    }        
                     rv = PRNGTEST_Reseed(entropyInput, entropyInputLen,
                                              additionalInput, additionalInputLen);
                     if (rv != SECSuccess) {
@@ -2736,6 +3150,28 @@ drbg(char *reqfn)
             fputs(buf, rngresp);
             continue;
         }
+
+        if (strncmp(buf, "[ReturnedBitsLen", 16)  == 0) {
+            if (return_bytes) {
+                PORT_ZFree(return_bytes, return_bytes_len);
+                return_bytes = NULL;
+            }
+	    if (predictedreturn_bytes) {
+                PORT_ZFree(predictedreturn_bytes, return_bytes_len);
+                predictedreturn_bytes = NULL;
+            }
+            return_bytes_len = 0;
+            if (sscanf(buf, "[ReturnedBitsLen = %d]", &return_bytes_len) != 1) {
+                goto loser;
+            }
+            return_bytes_len = return_bytes_len/8;
+            if (return_bytes_len > 0) {
+                return_bytes = PORT_Alloc(return_bytes_len);
+                predictedreturn_bytes = PORT_Alloc(return_bytes_len);
+            }
+            fputs(buf, rngresp);
+            continue;
+        }
         
         if (strncmp(buf, "[EntropyInputLen", 16)  == 0) {
             if (entropyInput) {
@@ -2746,7 +3182,7 @@ drbg(char *reqfn)
             if (sscanf(buf, "[EntropyInputLen = %d]", &entropyInputLen) != 1) {
                 goto loser;
             }
-	    entropyInputLen = entropyInputLen/8;
+            entropyInputLen = entropyInputLen/8;
             if (entropyInputLen > 0) {
                 entropyInput = PORT_Alloc(entropyInputLen);
             }
@@ -2764,7 +3200,7 @@ drbg(char *reqfn)
             if (sscanf(buf, "[NonceLen = %d]", &nonceLen) != 1) {
                 goto loser;
             }
-	    nonceLen = nonceLen/8;
+            nonceLen = nonceLen/8;
             if (nonceLen > 0) {
                 nonce = PORT_Alloc(nonceLen);
             }               
@@ -2782,7 +3218,7 @@ drbg(char *reqfn)
             if (sscanf(buf, "[PersonalizationStringLen = %d]", &personalizationStringLen) != 1) {
                 goto loser;
             }
-	    personalizationStringLen = personalizationStringLen / 8;
+            personalizationStringLen = personalizationStringLen / 8;
             if (personalizationStringLen > 0) {
                 personalizationString = PORT_Alloc(personalizationStringLen);
             }
@@ -2801,7 +3237,7 @@ drbg(char *reqfn)
             if (sscanf(buf, "[AdditionalInputLen = %d]", &additionalInputLen) != 1) {
                 goto loser;
             }
-	    additionalInputLen = additionalInputLen/8;
+            additionalInputLen = additionalInputLen/8;
             if (additionalInputLen > 0) {
                 additionalInput = PORT_Alloc(additionalInputLen);
             }
@@ -2938,7 +3374,7 @@ drbg(char *reqfn)
 
             if (memcmp(return_bytes, 
                        predictedreturn_bytes, return_bytes_len) != 0) {
-		if (debug) {
+                if (debug) {
                 fprintf(rngresp, "# Generate failed:\n");
                 fputs(  "#   predicted=", rngresp);
                 to_hex_str(buf, predictedreturn_bytes, 
@@ -2948,7 +3384,7 @@ drbg(char *reqfn)
                 fputs(buf2, rngresp);
                 fputc('\n', rngresp);
 
-		} else {
+                } else {
                 fprintf(stderr, "Generate failed:\n");
                 fputs(  "   predicted=", stderr);
                 to_hex_str(buf, predictedreturn_bytes, 
@@ -2957,10 +3393,133 @@ drbg(char *reqfn)
                 fputs("\n   actual  = ", stderr);
                 fputs(buf2, stderr);
                 fputc('\n', stderr);
-		}
+                }
+            }
+            memset(predictedreturn_bytes, 0 , sizeof predictedreturn_bytes);
+
+            continue;
+        }
+    }
+loser:
+    fclose(rngreq);
+}
+
+/*
+ * Perform the RNG Variable Seed Test (VST) for the RNG algorithm
+ * "DSA - Generation of X", used both as specified and as a generic
+ * purpose RNG.  The presence of "Q = ..." in the REQUEST file
+ * indicates we are using the algorithm as specified.
+ *
+ * reqfn is the pathname of the REQUEST file.
+ *
+ * The output RESPONSE file is written to stdout.
+ */
+void
+rng_vst(char *reqfn)
+{
+    char buf[256];      /* holds one line from the input REQUEST file.
+                         * needs to be large enough to hold the longest
+                         * line "XSeed = <128 hex digits>\n".
+                         */
+    FILE *rngreq;       /* input stream from the REQUEST file */
+    FILE *rngresp;      /* output stream to the RESPONSE file */
+    unsigned int i, j;
+    unsigned char Q[DSA1_SUBPRIME_LEN];
+    PRBool hasQ = PR_FALSE;
+    unsigned int b;  /* 160 <= b <= 512, b is a multiple of 8 */
+    unsigned char XKey[512/8];
+    unsigned char XSeed[512/8];
+    unsigned char GENX[DSA1_SIGNATURE_LEN];
+    unsigned char DSAX[DSA1_SUBPRIME_LEN];
+    SECStatus rv;
+
+    rngreq = fopen(reqfn, "r");
+    rngresp = stdout;
+    while (fgets(buf, sizeof buf, rngreq) != NULL) {
+        /* a comment or blank line */
+        if (buf[0] == '#' || buf[0] == '\n') {
+            fputs(buf, rngresp);
+            continue;
+        }
+        /* [Xchange - SHA1] */
+        if (buf[0] == '[') {
+            fputs(buf, rngresp);
+            continue;
+        }
+        /* Q = ... */
+        if (buf[0] == 'Q') {
+            i = 1;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            for (j=0; j<sizeof Q; i+=2,j++) {
+                hex_to_byteval(&buf[i], &Q[j]);
+            }
+            fputs(buf, rngresp);
+            hasQ = PR_TRUE;
+            continue;
+        }
+        /* "COUNT = x" begins a new data set */
+        if (strncmp(buf, "COUNT", 5) == 0) {
+            /* zeroize the variables for the test with this data set */
+            b = 0;
+            memset(XKey, 0, sizeof XKey);
+            memset(XSeed, 0, sizeof XSeed);
+            fputs(buf, rngresp);
+            continue;
+        }
+        /* b = ... */
+        if (buf[0] == 'b') {
+            i = 1;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            b = atoi(&buf[i]);
+            if (b < 160 || b > 512 || b%8 != 0) {
+                goto loser;
+            }
+            fputs(buf, rngresp);
+            continue;
+        }
+        /* XKey = ... */
+        if (strncmp(buf, "XKey", 4) == 0) {
+            i = 4;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            for (j=0; j<b/8; i+=2,j++) {
+                hex_to_byteval(&buf[i], &XKey[j]);
+            }
+            fputs(buf, rngresp);
+            continue;
+        }
+        /* XSeed = ... */
+        if (strncmp(buf, "XSeed", 5) == 0) {
+            i = 5;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
             }
-            memset(predictedreturn_bytes, 0 , sizeof predictedreturn_bytes);
+            for (j=0; j<b/8; i+=2,j++) {
+                hex_to_byteval(&buf[i], &XSeed[j]);
+            }
+            fputs(buf, rngresp);
 
+            rv = FIPS186Change_GenerateX(XKey, XSeed, GENX);
+            if (rv != SECSuccess) {
+                goto loser;
+            }
+            fputs("X = ", rngresp);
+            if (hasQ) {
+                rv = FIPS186Change_ReduceModQForDSA(GENX, Q, DSAX);
+                if (rv != SECSuccess) {
+                    goto loser;
+                }
+                to_hex_str(buf, DSAX, sizeof DSAX);
+            } else {
+                to_hex_str(buf, GENX, sizeof GENX);
+            }
+            fputs(buf, rngresp);
+            fputc('\n', rngresp);
             continue;
         }
     }
@@ -2969,129 +3528,6 @@ loser:
 }
 
 /*
- * Perform the RNG Variable Seed Test (VST) for the RNG algorithm
- * "DSA - Generation of X", used both as specified and as a generic
- * purpose RNG.  The presence of "Q = ..." in the REQUEST file
- * indicates we are using the algorithm as specified.
- *
- * reqfn is the pathname of the REQUEST file.
- *
- * The output RESPONSE file is written to stdout.
- */
-void
-rng_vst(char *reqfn)
-{
-    char buf[256];      /* holds one line from the input REQUEST file.
-                         * needs to be large enough to hold the longest
-                         * line "XSeed = <128 hex digits>\n".
-                         */
-    FILE *rngreq;       /* input stream from the REQUEST file */
-    FILE *rngresp;      /* output stream to the RESPONSE file */
-    unsigned int i, j;
-    unsigned char Q[DSA1_SUBPRIME_LEN];
-    PRBool hasQ = PR_FALSE;
-    unsigned int b;  /* 160 <= b <= 512, b is a multiple of 8 */
-    unsigned char XKey[512/8];
-    unsigned char XSeed[512/8];
-    unsigned char GENX[DSA1_SIGNATURE_LEN];
-    unsigned char DSAX[DSA1_SUBPRIME_LEN];
-    SECStatus rv;
-
-    rngreq = fopen(reqfn, "r");
-    rngresp = stdout;
-    while (fgets(buf, sizeof buf, rngreq) != NULL) {
-	/* a comment or blank line */
-	if (buf[0] == '#' || buf[0] == '\n') {
-	    fputs(buf, rngresp);
-	    continue;
-	}
-	/* [Xchange - SHA1] */
-	if (buf[0] == '[') {
-	    fputs(buf, rngresp);
-	    continue;
-	}
-	/* Q = ... */
-	if (buf[0] == 'Q') {
-	    i = 1;
-	    while (isspace(buf[i]) || buf[i] == '=') {
-		i++;
-	    }
-	    for (j=0; j<sizeof Q; i+=2,j++) {
-		hex_to_byteval(&buf[i], &Q[j]);
-	    }
-	    fputs(buf, rngresp);
-	    hasQ = PR_TRUE;
-	    continue;
-	}
-	/* "COUNT = x" begins a new data set */
-	if (strncmp(buf, "COUNT", 5) == 0) {
-	    /* zeroize the variables for the test with this data set */
-	    b = 0;
-	    memset(XKey, 0, sizeof XKey);
-	    memset(XSeed, 0, sizeof XSeed);
-	    fputs(buf, rngresp);
-	    continue;
-	}
-	/* b = ... */
-	if (buf[0] == 'b') {
-	    i = 1;
-	    while (isspace(buf[i]) || buf[i] == '=') {
-		i++;
-	    }
-	    b = atoi(&buf[i]);
-	    if (b < 160 || b > 512 || b%8 != 0) {
-		goto loser;
-	    }
-	    fputs(buf, rngresp);
-	    continue;
-	}
-	/* XKey = ... */
-	if (strncmp(buf, "XKey", 4) == 0) {
-	    i = 4;
-	    while (isspace(buf[i]) || buf[i] == '=') {
-		i++;
-	    }
-	    for (j=0; j<b/8; i+=2,j++) {
-		hex_to_byteval(&buf[i], &XKey[j]);
-	    }
-	    fputs(buf, rngresp);
-	    continue;
-	}
-	/* XSeed = ... */
-	if (strncmp(buf, "XSeed", 5) == 0) {
-	    i = 5;
-	    while (isspace(buf[i]) || buf[i] == '=') {
-		i++;
-	    }
-	    for (j=0; j<b/8; i+=2,j++) {
-		hex_to_byteval(&buf[i], &XSeed[j]);
-	    }
-	    fputs(buf, rngresp);
-
-	    rv = FIPS186Change_GenerateX(XKey, XSeed, GENX);
-	    if (rv != SECSuccess) {
-		goto loser;
-	    }
-	    fputs("X = ", rngresp);
-	    if (hasQ) {
-		rv = FIPS186Change_ReduceModQForDSA(GENX, Q, DSAX);
-		if (rv != SECSuccess) {
-		    goto loser;
-		}
-		to_hex_str(buf, DSAX, sizeof DSAX);
-	    } else {
-		to_hex_str(buf, GENX, sizeof GENX);
-	    }
-	    fputs(buf, rngresp);
-	    fputc('\n', rngresp);
-	    continue;
-	}
-    }
-loser:
-    fclose(rngreq);
-}
-
-/*
  * Perform the RNG Monte Carlo Test (MCT) for the RNG algorithm
  * "DSA - Generation of X", used both as specified and as a generic
  * purpose RNG.  The presence of "Q = ..." in the REQUEST file
@@ -3157,179 +3593,64 @@ rng_mct(char *reqfn)
 	}
 	/* b = ... */
 	if (buf[0] == 'b') {
-	    i = 1;
-	    while (isspace(buf[i]) || buf[i] == '=') {
-		i++;
-	    }
-	    b = atoi(&buf[i]);
-	    if (b < 160 || b > 512 || b%8 != 0) {
-		goto loser;
-	    }
-	    fputs(buf, rngresp);
-	    continue;
-	}
-	/* XKey = ... */
-	if (strncmp(buf, "XKey", 4) == 0) {
-	    i = 4;
-	    while (isspace(buf[i]) || buf[i] == '=') {
-		i++;
-	    }
-	    for (j=0; j<b/8; i+=2,j++) {
-		hex_to_byteval(&buf[i], &XKey[j]);
-	    }
-	    fputs(buf, rngresp);
-	    continue;
-	}
-	/* XSeed = ... */
-	if (strncmp(buf, "XSeed", 5) == 0) {
-	    unsigned int k;
-	    i = 5;
-	    while (isspace(buf[i]) || buf[i] == '=') {
-		i++;
-	    }
-	    for (j=0; j<b/8; i+=2,j++) {
-		hex_to_byteval(&buf[i], &XSeed[j]);
-	    }
-	    fputs(buf, rngresp);
-
-	    for (k = 0; k < 10000; k++) {
-		rv = FIPS186Change_GenerateX(XKey, XSeed, GENX);
-		if (rv != SECSuccess) {
-		    goto loser;
-		}
-	    }
-	    fputs("X = ", rngresp);
-	    if (hasQ) {
-		rv = FIPS186Change_ReduceModQForDSA(GENX, Q, DSAX);
-		if (rv != SECSuccess) {
-		    goto loser;
-		}
-		to_hex_str(buf, DSAX, sizeof DSAX);
-	    } else {
-		to_hex_str(buf, GENX, sizeof GENX);
-	    }
-	    fputs(buf, rngresp);
-	    fputc('\n', rngresp);
-	    continue;
-	}
-    }
-loser:
-    fclose(rngreq);
-}
-
-/*
- * HASH_ functions are available to full NSS apps and internally inside
- * freebl, but not exported to users of freebl. Create short stubs to
- * replace the functionality for fipstest.
- */
-SECStatus
-fips_hashBuf(HASH_HashType type, unsigned char *hashBuf, 
-					unsigned char *msg, int len)
-{
-    SECStatus rv = SECFailure;
-
-    switch (type) {
-    case HASH_AlgSHA1:
-	rv = SHA1_HashBuf(hashBuf, msg, len);
-	break;
-    case HASH_AlgSHA224:
-	rv = SHA224_HashBuf(hashBuf, msg, len);
-	break;
-    case HASH_AlgSHA256:
-	rv = SHA256_HashBuf(hashBuf, msg, len);
-	break;
-    case HASH_AlgSHA384:
-	rv = SHA384_HashBuf(hashBuf, msg, len);
-	break;
-    case HASH_AlgSHA512:
-	rv = SHA512_HashBuf(hashBuf, msg, len);
-	break;
-    default:
-	break;
-    }
-    return rv;
-}
-
-int
-fips_hashLen(HASH_HashType type)
-{
-    int len = 0;
-
-    switch (type) {
-    case HASH_AlgSHA1:
-	len = SHA1_LENGTH;
-	break;
-    case HASH_AlgSHA224:
-	len = SHA224_LENGTH;
-	break;
-    case HASH_AlgSHA256:
-	len = SHA256_LENGTH;
-	break;
-    case HASH_AlgSHA384:
-	len = SHA384_LENGTH;
-	break;
-    case HASH_AlgSHA512:
-	len = SHA512_LENGTH;
-	break;
-    default:
-	break;
-    }
-    return len;
-}
-
-SECOidTag
-fips_hashOid(HASH_HashType type)
-{
-    SECOidTag oid = SEC_OID_UNKNOWN;
-
-    switch (type) {
-    case HASH_AlgSHA1:
-	oid = SEC_OID_SHA1;
-	break;
-    case HASH_AlgSHA224:
-	oid = SEC_OID_SHA224;
-	break;
-    case HASH_AlgSHA256:
-	oid = SEC_OID_SHA256;
-	break;
-    case HASH_AlgSHA384:
-	oid = SEC_OID_SHA384;
-	break;
-    case HASH_AlgSHA512:
-	oid = SEC_OID_SHA512;
-	break;
-    default:
-	break;
-    }
-    return oid;
-}
-
-HASH_HashType
-sha_get_hashType(int hashbits)
-{
-    HASH_HashType hashType = HASH_AlgNULL;
+	    i = 1;
+	    while (isspace(buf[i]) || buf[i] == '=') {
+		i++;
+	    }
+	    b = atoi(&buf[i]);
+	    if (b < 160 || b > 512 || b%8 != 0) {
+		goto loser;
+	    }
+	    fputs(buf, rngresp);
+	    continue;
+	}
+	/* XKey = ... */
+	if (strncmp(buf, "XKey", 4) == 0) {
+	    i = 4;
+	    while (isspace(buf[i]) || buf[i] == '=') {
+		i++;
+	    }
+	    for (j=0; j<b/8; i+=2,j++) {
+		hex_to_byteval(&buf[i], &XKey[j]);
+	    }
+	    fputs(buf, rngresp);
+	    continue;
+	}
+	/* XSeed = ... */
+	if (strncmp(buf, "XSeed", 5) == 0) {
+	    unsigned int k;
+	    i = 5;
+	    while (isspace(buf[i]) || buf[i] == '=') {
+		i++;
+	    }
+	    for (j=0; j<b/8; i+=2,j++) {
+		hex_to_byteval(&buf[i], &XSeed[j]);
+	    }
+	    fputs(buf, rngresp);
 
-    switch (hashbits) {
-    case 1:
-    case (SHA1_LENGTH*PR_BITS_PER_BYTE):
-	hashType = HASH_AlgSHA1;
-	break;
-    case (SHA224_LENGTH*PR_BITS_PER_BYTE):
-	hashType = HASH_AlgSHA224;
-	break;
-    case (SHA256_LENGTH*PR_BITS_PER_BYTE):
-	hashType = HASH_AlgSHA256;
-	break;
-    case (SHA384_LENGTH*PR_BITS_PER_BYTE):
-	hashType = HASH_AlgSHA384;
-	break;
-    case (SHA512_LENGTH*PR_BITS_PER_BYTE):
-	hashType = HASH_AlgSHA512;
-	break;
-    default:
-	break;
+	    for (k = 0; k < 10000; k++) {
+		rv = FIPS186Change_GenerateX(XKey, XSeed, GENX);
+		if (rv != SECSuccess) {
+		    goto loser;
+		}
+	    }
+	    fputs("X = ", rngresp);
+	    if (hasQ) {
+		rv = FIPS186Change_ReduceModQForDSA(GENX, Q, DSAX);
+		if (rv != SECSuccess) {
+		    goto loser;
+		}
+		to_hex_str(buf, DSAX, sizeof DSAX);
+	    } else {
+		to_hex_str(buf, GENX, sizeof GENX);
+	    }
+	    fputs(buf, rngresp);
+	    fputc('\n', rngresp);
+	    continue;
+	}
     }
-    return hashType;
+loser:
+    fclose(rngreq);
 }
 
 /*
@@ -3419,7 +3740,7 @@ void sha_test(char *reqfn)
     unsigned int MDlen;   /* the length of the Message Digest in Bytes  */
     unsigned int msgLen;  /* the length of the input Message in Bytes */
     unsigned char *msg = NULL; /* holds the message to digest.*/
-    size_t bufSize = 25608; /*MAX buffer size */
+    size_t bufSize = 256*128; /*MAX buffer size */
     char *buf = NULL;      /* holds one line from the input REQUEST file.*/
     unsigned char seed[HASH_LENGTH_MAX];   /* max size of seed 64 bytes */
     unsigned char MD[HASH_LENGTH_MAX];     /* message digest */
@@ -3726,7 +4047,7 @@ void hmac_test(char *reqfn)
                          msg, msgLen, hash_alg) != SECSuccess) {
                goto loser;
            }
-           fputs("MAC = ", resp);
+           fputs("Mac = ", resp);
            to_hex_str(buf, HMAC, TLen);
            fputs(buf, resp);
            fputc('\n', resp);
@@ -3791,18 +4112,18 @@ dsa_keypair_test(char *reqfn)
             }
 
             if (sscanf(buf, "[mod = L=%d, N=%d]", &L, &N) != 2) {
-		use_dsa1 = PR_TRUE;
+                use_dsa1 = PR_TRUE;
                 if (sscanf(buf, "[mod = %d]", &L) != 1) {
                     goto loser;
-		}
+                }
             }
             fputs(buf, dsaresp);
             fputc('\n', dsaresp);
 
-	    if (use_dsa1) {
+            if (use_dsa1) {
                 /*************************************************************
                  * PQG_ParamGenSeedLen doesn't take a key size, it takes an 
-		 * index that points to a valid key size.
+                 * index that points to a valid key size.
                  */
                 keySizeIndex = PQG_PBITS_TO_INDEX(L);
                 if(keySizeIndex == -1 || L<512 || L>1024) {
@@ -3816,13 +4137,13 @@ dsa_keypair_test(char *reqfn)
                 if (PQG_ParamGenSeedLen(keySizeIndex, PQG_TEST_SEED_BYTES,
                     &pqg, &vfy) != SECSuccess) {
                     fprintf(dsaresp, 
-				"ERROR: Unable to generate PQG parameters");
+                                "ERROR: Unable to generate PQG parameters");
                     goto loser;
                 }
-	    } else {
+            } else {
                 if (PQG_ParamGenV2(L, N, N, &pqg, &vfy) != SECSuccess) {
                     fprintf(dsaresp, 
-				"ERROR: Unable to generate PQG parameters");
+                                "ERROR: Unable to generate PQG parameters");
                     goto loser;
                 }
             }
@@ -3871,7 +4192,7 @@ loser:
  */
 typedef enum {
     FIPS186_1,/* Generate/Verify P,Q & G  according to FIPS 186-1 */
-    A_1_1_2, /* Generate Probable P & Q */
+    A_1_2_1, /* Generate Provable P & Q */
     A_1_1_3, /* Verify Probable P & Q */
     A_1_2_2, /* Verify Provable P & Q */
     A_2_1,   /* Generate Unverifiable G */
@@ -3919,37 +4240,37 @@ dsa_pqgver_test(char *reqfn)
         /* [A.xxxxx ] */
         if (buf[0] == '['  && buf[1] == 'A') {
 
-	    if (strncmp(&buf[1],"A.1.1.3",7) == 0) {
-		type = A_1_1_3;
-	    } else if (strncmp(&buf[1],"A.2.2",5) == 0) {
-		type = A_2_2;
-	    } else if (strncmp(&buf[1],"A.2.4",5) == 0) {
-		type = A_2_4;
-	    } else if (strncmp(&buf[1],"A.1.2.2",7) == 0) {
-		type = A_1_2_2;
-	    /* validate our output from PQGGEN */
-	    } else if (strncmp(&buf[1],"A.1.1.2",7) == 0) {
-		type = A_2_4; /* validate PQ and G together */
-	    } else {
-		fprintf(stderr, "Unknown dsa ver test %s\n", &buf[1]);
-		exit(1);
-	    }
-		
+            if (strncmp(&buf[1],"A.1.1.3",7) == 0) {
+                type = A_1_1_3;
+            } else if (strncmp(&buf[1],"A.2.2",5) == 0) {
+                type = A_2_2;
+            } else if (strncmp(&buf[1],"A.2.4",5) == 0) {
+                type = A_2_4;
+            } else if (strncmp(&buf[1],"A.1.2.2",7) == 0) {
+                type = A_1_2_2;
+            /* validate our output from PQGGEN */
+            } else if (strncmp(&buf[1],"A.1.1.2",7) == 0) {
+                type = A_2_4; /* validate PQ and G together */
+            } else {
+                fprintf(stderr, "Unknown dsa ver test %s\n", &buf[1]);
+                exit(1);
+            }
+                
             fputs(buf, dsaresp);
             continue;
         }
-	
+        
 
         /* [Mod = x] */
         if (buf[0] == '[') {
 
-	    if (type == FIPS186_1) {
+            if (type == FIPS186_1) {
                 N=160;
                 if (sscanf(buf, "[mod = %d]", &L) != 1) {
                     goto loser;
-		}
-	    } else if (sscanf(buf, "[mod = L=%d, N=%d", &L, &N) != 2) {
-		goto loser;
+                }
+            } else if (sscanf(buf, "[mod = L=%d, N=%d", &L, &N) != 2) {
+                goto loser;
             }
 
             if (pqg.prime.data) { /* P */
@@ -3973,17 +4294,17 @@ dsa_pqgver_test(char *reqfn)
             /*calculate the size of p, g, and h then allocate items  */
             pghSize = L/8;
 
-	    pqg.base.data = vfy.h.data = NULL;
-	    vfy.seed.len = pqg.base.len = vfy.h.len = 0;
+            pqg.base.data = vfy.h.data = NULL;
+            vfy.seed.len = pqg.base.len = vfy.h.len = 0;
             SECITEM_AllocItem(NULL, &pqg.prime, pghSize);
             SECITEM_AllocItem(NULL, &vfy.seed, pghSize*3);
-	    if (type == A_2_2) {
-		SECITEM_AllocItem(NULL, &vfy.h, pghSize);
-	    	vfy.h.len = pghSize;
-	    } else if (type == A_2_4) {
-		SECITEM_AllocItem(NULL, &vfy.h, 1);
-	    	vfy.h.len = 1;
-	    }
+            if (type == A_2_2) {
+                SECITEM_AllocItem(NULL, &vfy.h, pghSize);
+                    vfy.h.len = pghSize;
+            } else if (type == A_2_4) {
+                SECITEM_AllocItem(NULL, &vfy.h, 1);
+                    vfy.h.len = 1;
+            }
             pqg.prime.len = pghSize;
             /* q is always N bits */
             SECITEM_AllocItem(NULL, &pqg.subPrime, N/8);
@@ -4042,24 +4363,24 @@ dsa_pqgver_test(char *reqfn)
         if (strncmp(buf, "Seed", 4) == 0) {
             i = 4;
         } else if (strncmp(buf, "domain_parameter_seed", 21) == 0) {
-	    i = 21;
-	} else if (strncmp(buf,"firstseed",9) == 0) {
-	    i = 9;
-	} else {
-	    i = 0;
-	}
-	if (i) {
+            i = 21;
+        } else if (strncmp(buf,"firstseed",9) == 0) {
+            i = 9;
+        } else {
+            i = 0;
+        }
+        if (i) {
             while (isspace(buf[i]) || buf[i] == '=') {
                 i++;
             }
             for (j=0; isxdigit(buf[i]); i+=2,j++) {
                 hex_to_byteval(&buf[i], &vfy.seed.data[j]);
             }
-	    vfy.seed.len = j;
+            vfy.seed.len = j;
 
             fputs(buf, dsaresp);
-	    if (type == A_2_4) {
-		SECStatus result;
+            if (type == A_2_4) {
+                SECStatus result;
 
                 /* Verify the Parameters */
                 SECStatus rv = PQG_VerifyParams(&pqg, &vfy, &result);
@@ -4071,49 +4392,49 @@ dsa_pqgver_test(char *reqfn)
                 } else {
                     fprintf(dsaresp, "Result = F\n");
                 }
-	    }
+            }
             continue;
         }
-	if ((strncmp(buf,"pseed",5) == 0) ||
-	    (strncmp(buf,"qseed",5) == 0))
-	{
-	    i = 5;
+        if ((strncmp(buf,"pseed",5) == 0) ||
+            (strncmp(buf,"qseed",5) == 0))
+        {
+            i = 5;
             while (isspace(buf[i]) || buf[i] == '=') {
                 i++;
             }
             for (j=vfy.seed.len; isxdigit(buf[i]); i+=2,j++) {
                 hex_to_byteval(&buf[i], &vfy.seed.data[j]);
             }
-	    vfy.seed.len = j;
+            vfy.seed.len = j;
             fputs(buf, dsaresp);
 
             continue;
-	}
+        }
         if (strncmp(buf, "index", 4) == 0) {
-	    i=5;
+            i=5;
             while (isspace(buf[i]) || buf[i] == '=') {
                 i++;
             }
-	    hex_to_byteval(&buf[i], &vfy.h.data[0]);
-	    vfy.h.len = 1;
+            hex_to_byteval(&buf[i], &vfy.h.data[0]);
+            vfy.h.len = 1;
             fputs(buf, dsaresp);
-	}
+        }
 
         /* c = ...  or counter=*/
         if (buf[0] == 'c')  {
-	    if (strncmp(buf,"counter", 7) == 0) {
+            if (strncmp(buf,"counter", 7) == 0) {
                 if (sscanf(buf, "counter = %u", &vfy.counter) != 1) {
                     goto loser;
-		}
-	    } else {
+                }
+            } else {
                 if (sscanf(buf, "c = %u", &vfy.counter) != 1) {
                     goto loser;
-		}
+                }
             }
 
             fputs(buf, dsaresp);
             if (type == A_1_1_3) {
-		SECStatus result;
+                SECStatus result;
                 /* only verify P and Q, we have everything now. do it */
                 SECStatus rv = PQG_VerifyParams(&pqg, &vfy, &result);
                 if (rv != SECSuccess) {
@@ -4128,17 +4449,17 @@ dsa_pqgver_test(char *reqfn)
             }
             continue;
         }
-	if (strncmp(buf,"pgen_counter", 12) == 0) {
+        if (strncmp(buf,"pgen_counter", 12) == 0) {
             if (sscanf(buf, "pgen_counter = %u", &vfy.counter) != 1) {
                 goto loser;
-            }	
+            }        
             fputs(buf, dsaresp);
-	    continue;
-	}
-	if (strncmp(buf,"qgen_counter", 12) == 0) {
+            continue;
+        }
+        if (strncmp(buf,"qgen_counter", 12) == 0) {
             fputs(buf, dsaresp);
             if (type == A_1_2_2) {
-		SECStatus result;
+                SECStatus result;
                 /* only verify P and Q, we have everything now. do it */
                 SECStatus rv = PQG_VerifyParams(&pqg, &vfy, &result);
                 if (rv != SECSuccess) {
@@ -4151,8 +4472,8 @@ dsa_pqgver_test(char *reqfn)
                 }
                 fprintf(dsaresp, "\n");
             } 
-	    continue;
-	}
+            continue;
+        }
         /* H = ... */
         if (buf[0] == 'H') {
             SECStatus rv, result = SECFailure;
@@ -4164,18 +4485,18 @@ dsa_pqgver_test(char *reqfn)
             for (j=0; isxdigit(buf[i]); i+=2,j++) {
                 hex_to_byteval(&buf[i], &vfy.h.data[j]);
             }
-	    vfy.h.len = j;
+            vfy.h.len = j;
             fputs(buf, dsaresp);
 
-	    /* this should be a byte value. Remove the leading zeros. If
-	     * it doesn't reduce to a byte, PQG_VerifyParams will catch it 
-	    if (type == A_2_2) {
-		data_save = vfy.h.data;
-		while(vfy.h.data[0] && (vfy.h.len > 1)) {
-			vfy.h.data++;
-			vfy.h.len--;
-		}
-	    } */
+            /* this should be a byte value. Remove the leading zeros. If
+             * it doesn't reduce to a byte, PQG_VerifyParams will catch it 
+            if (type == A_2_2) {
+                data_save = vfy.h.data;
+                while(vfy.h.data[0] && (vfy.h.len > 1)) {
+                        vfy.h.data++;
+                        vfy.h.len--;
+                }
+            } */
 
             /* Verify the Parameters */
             rv = PQG_VerifyParams(&pqg, &vfy, &result);
@@ -4232,6 +4553,7 @@ dsa_pqggen_test(char *reqfn)
     int L;
     int i;
     unsigned int j;
+    int output_g = 1;
     PQGParams *pqg = NULL;
     PQGVerify *vfy = NULL;
     unsigned int keySizeIndex;
@@ -4248,21 +4570,23 @@ dsa_pqggen_test(char *reqfn)
 
         /* [A.xxxxx ] */
         if (buf[0] == '['  && buf[1] == 'A') {
-	    if (strncmp(&buf[1],"A.1.1.2",7) == 0) {
-		type = A_1_1_2;
-	    } else if (strncmp(&buf[1],"A.2.1",5) == 0) {
-		fprintf(stderr, "NSS only Generates G with P&Q\n");
-		exit(1);
-	    } else if (strncmp(&buf[1],"A.2.3",5) == 0) {
-		fprintf(stderr, "NSS only Generates G with P&Q\n");
-		exit(1);
-	    } else if (strncmp(&buf[1],"A.1.2.1",7) == 0) {
-		fprintf(stderr, "NSS does not support Shawe-Taylor Primes\n");
+            if (strncmp(&buf[1],"A.1.1.2",7) == 0) {
+                fprintf(stderr, "NSS does Generate Probablistic Primes\n");
 		exit(1);
-	    } else {
-		fprintf(stderr, "Unknown dsa ver test %s\n", &buf[1]);
-		exit(1);
-	    }
+            } else if (strncmp(&buf[1],"A.2.1",5) == 0) {
+                type = A_1_2_1;
+		output_g = 1;
+                exit(1);
+            } else if (strncmp(&buf[1],"A.2.3",5) == 0) {
+                fprintf(stderr, "NSS only Generates G with P&Q\n");
+                exit(1);
+            } else if (strncmp(&buf[1],"A.1.2.1",7) == 0) {
+                type = A_1_2_1;
+		output_g = 0;
+            } else {
+                fprintf(stderr, "Unknown dsa pqggen test %s\n", &buf[1]);
+                exit(1);
+            }
             fputs(buf, dsaresp);
             continue;
         }
@@ -4270,19 +4594,19 @@ dsa_pqggen_test(char *reqfn)
         /* [Mod = ... ] */
         if (buf[0] == '[') {
 
-	    if (type == FIPS186_1) {
+            if (type == FIPS186_1) {
                 N=160;
                 if (sscanf(buf, "[mod = %d]", &L) != 1) {
                     goto loser;
-		}
-	    } else if (sscanf(buf, "[mod = L=%d, N=%d", &L, &N) != 2) {
-		goto loser;
+                }
+            } else if (sscanf(buf, "[mod = L=%d, N=%d", &L, &N) != 2) {
+                goto loser;
             }
 
             fputs(buf, dsaresp);
             fputc('\n', dsaresp);
 
-	    if (type == FIPS186_1) {
+            if (type == FIPS186_1) {
                 /************************************************************
                  * PQG_ParamGenSeedLen doesn't take a key size, it takes an
                  * index that points to a valid key size.
@@ -4299,7 +4623,11 @@ dsa_pqggen_test(char *reqfn)
         }
         /* N = ... */
         if (buf[0] == 'N') {
-            if (sscanf(buf, "N = %d", &count) != 1) {
+	    if (strncmp(buf, "Num", 3) == 0) {
+                if (sscanf(buf, "Num = %d", &count) != 1) {
+                    goto loser;
+                }
+            } else if (sscanf(buf, "N = %d", &count) != 1) {
                 goto loser;
             }
             for (i = 0; i < count; i++) {
@@ -4320,24 +4648,38 @@ dsa_pqggen_test(char *reqfn)
                 fprintf(dsaresp, "P = %s\n", buf);
                 to_hex_str(buf, pqg->subPrime.data, pqg->subPrime.len);
                 fprintf(dsaresp, "Q = %s\n", buf);
-                to_hex_str(buf, pqg->base.data, pqg->base.len);
-                fprintf(dsaresp, "G = %s\n", buf);
-		if (type == FIPS186_1) {
+		if (output_g) {
+                    to_hex_str(buf, pqg->base.data, pqg->base.len);
+                    fprintf(dsaresp, "G = %s\n", buf);
+		}
+                if (type == FIPS186_1) {
                     to_hex_str(buf, vfy->seed.data, vfy->seed.len);
                     fprintf(dsaresp, "Seed = %s\n", buf);
                     fprintf(dsaresp, "c = %d\n", vfy->counter);
                     to_hex_str(buf, vfy->h.data, vfy->h.len);
                     fputs("H = ", dsaresp);
                     for (j=vfy->h.len; j< pqg->prime.len; j++) {
-                	fprintf(dsaresp, "00");
+                        fprintf(dsaresp, "00");
                     }
                     fprintf(dsaresp, "%s\n", buf);
-		} else {
-                    fprintf(dsaresp, "counter = %d\n", vfy->counter);
-		    fprintf(dsaresp, "index = %02x\n", vfy->h.data[0]);
-                    to_hex_str(buf, vfy->seed.data, vfy->seed.len);
-                    fprintf(dsaresp, "domain_parameter_seed = %s\n", buf);
-		}
+                } else {
+                    unsigned int seedlen = vfy->seed.len/2;
+		    unsigned int pgen_counter = vfy->counter >> 16;
+		    unsigned int qgen_counter = vfy->counter & 0xffff;
+                    /*fprintf(dsaresp, "index = %02x\n", vfy->h.data[0]); */
+                    to_hex_str(buf, vfy->seed.data, seedlen);
+                    fprintf(dsaresp, "pseed = %s\n", buf);
+                    to_hex_str(buf, vfy->seed.data+seedlen, seedlen);
+                    fprintf(dsaresp, "qseed = %s\n", buf);
+                    fprintf(dsaresp, "pgen_counter = %d\n", vfy->counter);
+                    fprintf(dsaresp, "qgen_counter = %d\n", vfy->counter);
+		    if (output_g) {
+                        to_hex_str(buf, vfy->seed.data, vfy->seed.len);
+                        fprintf(dsaresp, "domain_parameter_seed = %s\n", buf);
+		        fprintf(dsaresp, "index = %02x\n", vfy->h.data[0]);
+		    }
+		
+                }
                 fputc('\n', dsaresp);
                 if(pqg!=NULL) {
                     PQG_DestroyParams(pqg);
@@ -4423,7 +4765,7 @@ dsa_siggen_test(char *reqfn)
             if (sscanf(buf, "[mod = L=%d,  N=%d, SHA-%d]", &L, & N,
                 &hashNum) != 3) {
                 use_dsa1 = PR_TRUE;
-		hashNum = 1;
+                hashNum = 1;
                 if (sscanf(buf, "[mod = %d]", &modulus) != 1) {
                     goto loser;
                 }
@@ -4470,11 +4812,11 @@ dsa_siggen_test(char *reqfn)
                 goto loser;
             }
  
-	    hashType = sha_get_hashType(hashNum);
-	    if (hashType == HASH_AlgNULL) {
-		fprintf(dsaresp, "ERROR: invalid hash (SHA-%d)",hashNum);
-		goto loser;
-	    }
+            hashType = sha_get_hashType(hashNum);
+            if (hashType == HASH_AlgNULL) {
+                fprintf(dsaresp, "ERROR: invalid hash (SHA-%d)",hashNum);
+                goto loser;
+            }
             continue;
         }
 
@@ -4483,10 +4825,10 @@ dsa_siggen_test(char *reqfn)
             unsigned char msg[128]; /* MAX msg 128 */
             unsigned int len = 0;
 
-	    if (hashType == HASH_AlgNULL) {
-		fprintf(dsaresp, "ERROR: Hash Alg not set");
-		goto loser;
-	    }
+            if (hashType == HASH_AlgNULL) {
+                fprintf(dsaresp, "ERROR: Hash Alg not set");
+                goto loser;
+            }
 
             memset(hashBuf, 0, sizeof hashBuf);
             memset(sig,  0, sizeof sig);
@@ -4500,7 +4842,7 @@ dsa_siggen_test(char *reqfn)
             }
             if (fips_hashBuf(hashType, hashBuf, msg, j) != SECSuccess) {
                  fprintf(dsaresp, "ERROR: Unable to generate SHA% digest", 
-			 hashNum);
+                         hashNum);
                  goto loser;
             }
 
@@ -4595,8 +4937,8 @@ dsa_sigver_test(char *reqfn)
 
             if (sscanf(buf, "[mod = L=%d,  N=%d, SHA-%d]", &L, & N,
                 &hashNum) != 3) {
-		N=160;
-		hashNum = 1;
+                N=160;
+                hashNum = 1;
                 if (sscanf(buf, "[mod = %d]", &L) != 1) {
                     goto loser;
                 }
@@ -4628,11 +4970,11 @@ dsa_sigver_test(char *reqfn)
             SECITEM_AllocItem(NULL, &pubkey.params.subPrime, N/8);
             pubkey.params.subPrime.len = N/8;
 
-	    hashType = sha_get_hashType(hashNum);
-	    if (hashType == HASH_AlgNULL) {
-		fprintf(dsaresp, "ERROR: invalid hash (SHA-%d)",hashNum);
-		goto loser;
-	    }
+            hashType = sha_get_hashType(hashNum);
+            if (hashType == HASH_AlgNULL) {
+                fprintf(dsaresp, "ERROR: invalid hash (SHA-%d)",hashNum);
+                goto loser;
+            }
 
             continue;
         }
@@ -4686,10 +5028,10 @@ dsa_sigver_test(char *reqfn)
             unsigned char msg[128]; /* MAX msg 128 */
             memset(hashBuf, 0, sizeof hashBuf);
 
-	    if (hashType == HASH_AlgNULL) {
-		fprintf(dsaresp, "ERROR: Hash Alg not set");
-		goto loser;
-	    }
+            if (hashType == HASH_AlgNULL) {
+                fprintf(dsaresp, "ERROR: Hash Alg not set");
+                goto loser;
+            }
 
             i = 3;
             while (isspace(buf[i]) || buf[i] == '=') {
@@ -4700,7 +5042,7 @@ dsa_sigver_test(char *reqfn)
             }
             if (fips_hashBuf(hashType, hashBuf, msg, j) != SECSuccess) {
                 fprintf(dsaresp, "ERROR: Unable to generate SHA-%d digest",
-								hashNum);
+                                                                hashNum);
                 goto loser;
             }
 
@@ -4740,17 +5082,17 @@ dsa_sigver_test(char *reqfn)
 
         /* S = ... */
         if (buf[0] == 'S') {
-	    if (hashType == HASH_AlgNULL) {
-		fprintf(dsaresp, "ERROR: Hash Alg not set");
-		goto loser;
-	    }
+            if (hashType == HASH_AlgNULL) {
+                fprintf(dsaresp, "ERROR: Hash Alg not set");
+                goto loser;
+            }
 
             i = 1;
             while (isspace(buf[i]) || buf[i] == '=') {
                 i++;
             }
             for (j=pubkey.params.subPrime.len; 
-				j< pubkey.params.subPrime.len*2; i+=2,j++) {
+                                j< pubkey.params.subPrime.len*2; i+=2,j++) {
                 hex_to_byteval(&buf[i], &sig[j]);
             }
             fputs(buf, dsaresp);
@@ -4767,7 +5109,7 @@ dsa_sigver_test(char *reqfn)
             } else {
                 fprintf(dsaresp, "Result = F\n");
             }
-	    fprintf(dsaresp, "\n");
+            fprintf(dsaresp, "\n");
             continue;
         }
     }
@@ -4945,16 +5287,16 @@ rsa_siggen_test(char *reqfn)
             for (j=0; isxdigit(buf[i]) && j < sizeof(msg); i+=2,j++) {
                 hex_to_byteval(&buf[i], &msg[j]);
             }
-	    shaLength = fips_hashLen(shaAlg);
-	    if (fips_hashBuf(shaAlg,sha,msg,j) != SECSuccess) {
-		if (shaLength == 0) {
-            	    fprintf(rsaresp, "ERROR: SHAAlg not defined.");
-		}
+            shaLength = fips_hashLen(shaAlg);
+            if (fips_hashBuf(shaAlg,sha,msg,j) != SECSuccess) {
+                if (shaLength == 0) {
+                        fprintf(rsaresp, "ERROR: SHAAlg not defined.");
+                }
                 fprintf(rsaresp, "ERROR: Unable to generate SHA%x",
-			shaLength == 160 ? 1 : shaLength);
+                        shaLength == 160 ? 1 : shaLength);
                 goto loser;
             }
-	    shaOid = fips_hashOid(shaAlg);
+            shaOid = fips_hashOid(shaAlg);
 
             /* Perform RSA signature with the RSA private key. */
             rv = RSA_HashSign( shaOid,
@@ -5169,13 +5511,13 @@ rsa_sigver_test(char *reqfn)
                 hex_to_byteval(&buf[i], &msg[j]);
             }
 
-	    shaLength = fips_hashLen(shaAlg);
-	    if (fips_hashBuf(shaAlg,sha,msg,j) != SECSuccess) {
-		if (shaLength == 0) {
-            	    fprintf(rsaresp, "ERROR: SHAAlg not defined.");
-		}
+            shaLength = fips_hashLen(shaAlg);
+            if (fips_hashBuf(shaAlg,sha,msg,j) != SECSuccess) {
+                if (shaLength == 0) {
+                        fprintf(rsaresp, "ERROR: SHAAlg not defined.");
+                }
                 fprintf(rsaresp, "ERROR: Unable to generate SHA%x",
-			shaLength == 160 ? 1 : shaLength);
+                        shaLength == 160 ? 1 : shaLength);
                 goto loser;
             }
 
@@ -5208,6 +5550,8 @@ rsa_sigver_test(char *reqfn)
             signatureLength = j;
             fputs(buf, rsaresp);
 
+            shaOid = fips_hashOid(shaAlg);
+
             /* Perform RSA verification with the RSA public key. */
             rv = RSA_HashCheckSign( shaOid,
                                     rsa_public_key,
@@ -5233,6 +5577,295 @@ loser:
     }
 }
 
+void
+tls(char *reqfn)
+{
+    char buf[256];      /* holds one line from the input REQUEST file.
+                         * needs to be large enough to hold the longest
+                         * line "XSeed = <128 hex digits>\n".
+                         */
+    unsigned char *pms = NULL;
+    int pms_len;
+    unsigned char *master_secret = NULL;
+    unsigned char *key_block = NULL;
+    int key_block_len;
+    unsigned char serverHello_random[SSL3_RANDOM_LENGTH];
+    unsigned char clientHello_random[SSL3_RANDOM_LENGTH];
+    unsigned char server_random[SSL3_RANDOM_LENGTH];
+    unsigned char client_random[SSL3_RANDOM_LENGTH];
+    FILE *tlsreq;       /* input stream from the REQUEST file */
+    FILE *tlsresp;      /* output stream to the RESPONSE file */
+    unsigned int i, j;
+    CK_SLOT_ID slotList[10];
+    CK_SLOT_ID slotID;
+    CK_ULONG slotListCount = sizeof(slotList)/sizeof(slotList[0]);
+    CK_ULONG count;
+    static const CK_C_INITIALIZE_ARGS pk11args= {
+	NULL, NULL, NULL, NULL, CKF_LIBRARY_CANT_CREATE_OS_THREADS , 
+	"flags=readOnly,noCertDB,noModDB", NULL };
+    static const CK_OBJECT_CLASS ck_secret = CKO_SECRET_KEY;
+    static const CK_KEY_TYPE ck_generic = CKK_GENERIC_SECRET;
+    static const CK_BBOOL ck_false = CK_FALSE;
+    static const CK_BBOOL ck_true = CK_TRUE;
+    static const CK_ULONG one = 1;
+    CK_ATTRIBUTE create_template[] = {
+	{ CKA_VALUE,        NULL,        0                  },
+	{ CKA_CLASS,        &ck_secret,  sizeof(ck_secret)  },
+	{ CKA_KEY_TYPE,     &ck_generic, sizeof(ck_generic) },
+	{ CKA_DERIVE,       &ck_true,    sizeof (ck_true)   },
+    };
+    CK_ULONG create_template_count = 
+			sizeof(create_template)/sizeof(create_template[0]);
+    CK_ATTRIBUTE derive_template[] = {
+	{ CKA_CLASS,        &ck_secret,  sizeof(ck_secret)  },
+	{ CKA_KEY_TYPE,     &ck_generic, sizeof(ck_generic) },
+	{ CKA_DERIVE,       &ck_true,    sizeof(ck_true)    },
+	{ CKA_VALUE_LEN,    &one,        sizeof(one)        },
+    };
+    CK_ULONG derive_template_count = 
+			sizeof(derive_template)/sizeof(derive_template[0]);
+    CK_ATTRIBUTE master_template = 
+	{ CKA_VALUE, NULL, 0 };
+    CK_ATTRIBUTE kb1_template = 
+	{ CKA_VALUE, NULL, 0 };
+    CK_ATTRIBUTE kb2_template = 
+	{ CKA_VALUE, NULL, 0 };
+    
+
+    CK_MECHANISM master_mech = { CKM_TLS_MASTER_KEY_DERIVE , NULL, 0 };
+    CK_MECHANISM key_block_mech = { CKM_TLS_KEY_AND_MAC_DERIVE , NULL, 0};
+    CK_SSL3_MASTER_KEY_DERIVE_PARAMS master_params;
+    CK_SSL3_KEY_MAT_PARAMS key_block_params;
+    CK_SSL3_KEY_MAT_OUT key_material;
+    CK_RV crv;
+
+    /* set up PKCS #11 parameters */
+    master_params.pVersion = NULL;
+    master_params.RandomInfo.pClientRandom = clientHello_random;
+    master_params.RandomInfo.ulClientRandomLen = sizeof(clientHello_random);
+    master_params.RandomInfo.pServerRandom = serverHello_random;
+    master_params.RandomInfo.ulServerRandomLen = sizeof(serverHello_random);
+    master_mech.pParameter = (void *) &master_params;
+    master_mech.ulParameterLen = sizeof(master_params);
+    key_block_params.ulMacSizeInBits = 0;
+    key_block_params.ulKeySizeInBits = 0;
+    key_block_params.ulIVSizeInBits = 0;
+    key_block_params.bIsExport = PR_FALSE; /* ignored anyway for TLS mech */
+    key_block_params.RandomInfo.pClientRandom = client_random;
+    key_block_params.RandomInfo.ulClientRandomLen = sizeof(client_random);
+    key_block_params.RandomInfo.pServerRandom = server_random;
+    key_block_params.RandomInfo.ulServerRandomLen = sizeof(server_random);
+    key_block_params.pReturnedKeyMaterial = &key_material;
+    key_block_mech.pParameter = (void *) &key_block_params;
+    key_block_mech.ulParameterLen = sizeof(key_block_params);
+    
+
+    crv = NSC_Initialize((CK_VOID_PTR)&pk11args);
+    if (crv != CKR_OK) {
+	fprintf(stderr,"NSC_Initialize failed crv=0x%x\n",crv);
+	goto loser;
+    }
+    count = slotListCount;
+    crv = NSC_GetSlotList(PR_TRUE,slotList, &count);
+    if (crv != CKR_OK) {
+	fprintf(stderr,"NSC_GetSlotList failed crv=0x%x\n",crv);
+	goto loser;
+    }
+    if ((count > slotListCount) || count < 1) {
+	fprintf(stderr,
+"NSC_GetSlotList returned too many or too few slots: %d slots max=%d min=1\n",
+		count, slotListCount);
+	goto loser;
+    }
+    slotID = slotList[0];
+    tlsreq = fopen(reqfn, "r");
+    tlsresp = stdout;
+    while (fgets(buf, sizeof buf, tlsreq) != NULL) {
+        /* a comment or blank line */
+        if (buf[0] == '#' || buf[0] == '\n') {
+            fputs(buf, tlsresp);
+            continue;
+        }
+        /* [Xchange - SHA1] */
+        if (buf[0] == '[') {
+            if (strncmp(buf, "[TLS", 4)  == 0) {
+		if (buf[7] == '0') {
+    		    master_mech.mechanism = CKM_TLS_MASTER_KEY_DERIVE;
+    		    key_block_mech.mechanism = CKM_TLS_KEY_AND_MAC_DERIVE;
+		} else if (buf[7] == '2') {
+    		    master_mech.mechanism = 
+					CKM_NSS_TLS_MASTER_KEY_DERIVE_SHA256;
+    		    key_block_mech.mechanism = 
+					CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256;
+		} else {
+		    fprintf(stderr, "Unknown TLS type %x\n", buf);
+		    goto loser;
+		} 
+	    }
+            if (strncmp(buf, "[pre-master", 11)  == 0) {
+                if (sscanf(buf, "[pre-master secret length = %d]", 
+				&pms_len) != 1) {
+                    goto loser;
+                }
+                pms_len = pms_len/8;
+		pms = malloc(pms_len);
+	 	master_secret = malloc(pms_len);
+		create_template[0].pValue = pms;
+		create_template[0].ulValueLen = pms_len;
+		master_template.pValue = master_secret;
+		master_template.ulValueLen = pms_len;
+            } 
+            if (strncmp(buf, "[key", 4)  == 0) {
+                if (sscanf(buf, "[key block length = %d]", &key_block_len) != 1) {
+                    goto loser;
+                }
+    		key_block_params.ulKeySizeInBits = 8;
+    		key_block_params.ulIVSizeInBits = key_block_len/2-8;
+                key_block_len=key_block_len/8;
+		key_block = malloc(key_block_len);
+		kb1_template.pValue = &key_block[0];
+		kb1_template.ulValueLen = 1;
+		kb2_template.pValue = &key_block[1];
+		kb2_template.ulValueLen = 1;
+		key_material.pIVClient = &key_block[2];
+		key_material.pIVServer = &key_block[2+key_block_len/2-1];
+            } 
+            fputs(buf, tlsresp);
+            continue;
+        }
+        /* "COUNT = x" begins a new data set */
+        if (strncmp(buf, "COUNT", 5) == 0) {
+            /* zeroize the variables for the test with this data set */
+            memset(pms, 0, pms_len);
+            memset(master_secret, 0, pms_len);
+            memset(key_block, 0, key_block_len);
+            fputs(buf, tlsresp);
+            continue;
+        }
+        /* pre_master_secret = ... */
+        if (strncmp(buf, "pre_master_secret", 17) == 0) {
+            i = 17;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            for (j=0; j<pms_len; i+=2,j++) {
+                hex_to_byteval(&buf[i], &pms[j]);
+            }
+            fputs(buf, tlsresp);
+            continue;
+        }
+        /* serverHello_random = ... */
+        if (strncmp(buf, "serverHello_random", 18) == 0) {
+            i = 18;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            for (j=0; j<SSL3_RANDOM_LENGTH; i+=2,j++) {
+                hex_to_byteval(&buf[i], &serverHello_random[j]);
+            }
+            fputs(buf, tlsresp);
+            continue;
+        }
+        /* clientHello_random = ... */
+        if (strncmp(buf, "clientHello_random", 18) == 0) {
+            i = 18;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            for (j=0; j<SSL3_RANDOM_LENGTH; i+=2,j++) {
+                hex_to_byteval(&buf[i], &clientHello_random[j]);
+            }
+            fputs(buf, tlsresp);
+            continue;
+        }
+        /* server_random = ... */
+        if (strncmp(buf, "server_random", 13) == 0) {
+            i = 13;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            for (j=0; j<SSL3_RANDOM_LENGTH; i+=2,j++) {
+                hex_to_byteval(&buf[i], &server_random[j]);
+            }
+            fputs(buf, tlsresp);
+            continue;
+        }
+        /* client_random = ... */
+        if (strncmp(buf, "client_random", 13) == 0) {
+	    CK_SESSION_HANDLE session;
+ 	    CK_OBJECT_HANDLE pms_handle;
+ 	    CK_OBJECT_HANDLE master_handle;
+ 	    CK_OBJECT_HANDLE fake_handle;
+            i = 13;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            for (j=0; j<SSL3_RANDOM_LENGTH; i+=2,j++) {
+                hex_to_byteval(&buf[i], &client_random[j]);
+            }
+            fputs(buf, tlsresp);
+	    crv = NSC_OpenSession(slotID, 0, NULL, NULL, &session);
+	    if (crv != CKR_OK) {
+		fprintf(stderr,"NSC_OpenSession failed crv=0x%x\n",crv);
+		goto loser;
+	    }
+	    crv = NSC_CreateObject(session, create_template, 
+					create_template_count, &pms_handle);
+	    if (crv != CKR_OK) {
+		fprintf(stderr,"NSC_CreateObject failed crv=0x%x\n",crv);
+		goto loser;
+	    }
+	    crv = NSC_DeriveKey(session, &master_mech, pms_handle, 
+		derive_template, derive_template_count-1, &master_handle);
+	    if (crv != CKR_OK) {
+		fprintf(stderr,"NSC_DeriveKey(master) failed crv=0x%x\n",crv);
+		goto loser;
+	    }
+	    crv = NSC_GetAttributeValue(session, master_handle, 
+							&master_template, 1);
+	    if (crv != CKR_OK) {
+		fprintf(stderr,"NSC_GetAttribute failed crv=0x%x\n",crv);
+		goto loser;
+	    }
+            fputs("master_secret = ", tlsresp);
+            to_hex_str(buf, master_secret, pms_len);
+            fputs(buf, tlsresp);
+            fputc('\n', tlsresp);
+	    crv = NSC_DeriveKey(session, &key_block_mech, master_handle,
+			derive_template, derive_template_count, &fake_handle);
+	    if (crv != CKR_OK) {
+		fprintf(stderr,
+			"NSC_DeriveKey(keyblock) failed crv=0x%x\n",crv);
+		goto loser;
+	    }
+	    crv = NSC_GetAttributeValue(session, key_material.hClientKey, 
+							&kb1_template, 1);
+	    if (crv != CKR_OK) {
+		fprintf(stderr,"NSC_GetAttribute failed crv=0x%x\n",crv);
+		goto loser;
+	    }
+	    crv = NSC_GetAttributeValue(session, key_material.hServerKey, 
+							&kb2_template, 1);
+	    if (crv != CKR_OK) {
+		fprintf(stderr,"NSC_GetAttribute failed crv=0x%x\n",crv);
+		goto loser;
+	    }
+            fputs("key_block = ", tlsresp);
+            to_hex_str(buf, key_block, key_block_len);
+            fputs(buf, tlsresp);
+            fputc('\n', tlsresp);
+	    crv = NSC_CloseSession(session);
+            continue;
+        }
+    }
+loser:
+    NSC_Finalize(NULL);
+    if (pms) free(pms);
+    if (master_secret) free(master_secret);
+    if (key_block) free(key_block);
+    fclose(tlsreq);
+}
+
 int main(int argc, char **argv)
 {
     if (argc < 2) exit (-1);
@@ -5265,23 +5898,31 @@ int main(int argc, char **argv)
     /*   AES     */
     /*************/
     } else if (strcmp(argv[1], "aes") == 0) {
-	/* argv[2]=kat|mmt|mct argv[3]=ecb|cbc argv[4]=<test name>.req */
-	if (       strcmp(argv[2], "kat") == 0) {
-	    /* Known Answer Test (KAT) */
-	    aes_kat_mmt(argv[4]);
-	} else if (strcmp(argv[2], "mmt") == 0) {
-	    /* Multi-block Message Test (MMT) */
-	    aes_kat_mmt(argv[4]);
-	} else if (strcmp(argv[2], "mct") == 0) {
-	    /* Monte Carlo Test (MCT) */
-	    if (       strcmp(argv[3], "ecb") == 0) {
-		/* ECB mode */
-		aes_ecb_mct(argv[4]);
-	    } else if (strcmp(argv[3], "cbc") == 0) {
-		/* CBC mode */
-		aes_cbc_mct(argv[4]);
-	    }
-	}
+        /* argv[2]=kat|mmt|mct argv[3]=ecb|cbc argv[4]=<test name>.req */
+        if (       strcmp(argv[2], "kat") == 0) {
+            /* Known Answer Test (KAT) */
+            aes_kat_mmt(argv[4]);
+        } else if (strcmp(argv[2], "mmt") == 0) {
+            /* Multi-block Message Test (MMT) */
+            aes_kat_mmt(argv[4]);
+        } else if (strcmp(argv[2], "gcm") == 0) {
+            if (       strcmp(argv[3], "decrypt") == 0) {
+                aes_gcm(argv[4],0);
+            } else if (strcmp(argv[3], "encrypt_extiv") == 0) {
+                aes_gcm(argv[4],1);
+            } else if (strcmp(argv[3], "encrypt_intiv") == 0) {
+                aes_gcm(argv[4],2);
+            }
+        } else if (strcmp(argv[2], "mct") == 0) {
+            /* Monte Carlo Test (MCT) */
+            if (       strcmp(argv[3], "ecb") == 0) {
+                /* ECB mode */
+                aes_ecb_mct(argv[4]);
+            } else if (strcmp(argv[3], "cbc") == 0) {
+                /* CBC mode */
+                aes_cbc_mct(argv[4]);
+            }
+        }
     /*************/
     /*   SHA     */
     /*************/
diff -up ./nss/cmd/fipstest/hmac.sh.fipstest ./nss/cmd/fipstest/hmac.sh
--- ./nss/cmd/fipstest/hmac.sh.fipstest	2014-06-24 13:45:27.000000000 -0700
+++ ./nss/cmd/fipstest/hmac.sh	2014-09-22 11:47:43.492241460 -0700
@@ -1,8 +1,4 @@
 #!/bin/sh
-# 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/.
-
 #
 # A Bourne shell script for running the NIST HMAC Algorithm Validation Suite
 #
@@ -11,14 +7,26 @@
 # shared libraries/DLLs are on the search path.  Then run this script in the
 # directory where the REQUEST (.req) files reside.  The script generates the
 # RESPONSE (.rsp) files in the same directory.
+
+BASEDIR=${1-.}
+TESTDIR=${BASEDIR}/HMAC
+COMMAND=${2-run}
+REQDIR=${TESTDIR}/req
+RSPDIR=${TESTDIR}/resp
                                
 hmac_requests="
 HMAC.req
 "
 
+if [ ${COMMAND} = "verify" ]; then
+    for request in $hmac_requests; do
+	sh ./validate1.sh ${TESTDIR} $request
+    done
+    exit 0
+fi
 for request in $hmac_requests; do
     response=`echo $request | sed -e "s/req/rsp/"`
     echo $request $response
-    fipstest hmac $request > $response
+    fipstest hmac ${REQDIR}/$request > ${RSPDIR}/$response
 done
 
diff -up ./nss/cmd/fipstest/rng.sh.fipstest ./nss/cmd/fipstest/rng.sh
--- ./nss/cmd/fipstest/rng.sh.fipstest	2014-06-24 13:45:27.000000000 -0700
+++ ./nss/cmd/fipstest/rng.sh	2014-09-22 11:47:43.493241477 -0700
@@ -1,8 +1,4 @@
 #!/bin/sh
-# 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/.
-
 #
 # A Bourne shell script for running the NIST RNG Validation Suite
 #
@@ -11,13 +7,24 @@
 # shared libraries/DLLs are on the search path.  Then run this script in the
 # directory where the REQUEST (.req) files reside.  The script generates the
 # RESPONSE (.rsp) files in the same directory.
+BASEDIR=${1-.}
+TESTDIR=${BASEDIR}/DRBG800-90A
+COMMAND=${2-run}
+REQDIR=${TESTDIR}/req
+RSPDIR=${TESTDIR}/resp
 
 drbg_requests="
-SHA256_DRBG.req
+Hash_DRBG.req
 "
 
+if [ ${COMMAND} = "verify" ]; then
+    for request in $drbg_requests; do
+	sh ./validate1.sh ${TESTDIR} $request
+    done
+    exit 0
+fi
 for request in $drbg_requests; do
     response=`echo $request | sed -e "s/req/rsp/"`
     echo $request $response
-    fipstest drbg $request > $response
+    fipstest drbg ${REQDIR}/$request > ${RSPDIR}/$response
 done
diff -up ./nss/cmd/fipstest/rsa.sh.fipstest ./nss/cmd/fipstest/rsa.sh
--- ./nss/cmd/fipstest/rsa.sh.fipstest	2014-06-24 13:45:27.000000000 -0700
+++ ./nss/cmd/fipstest/rsa.sh	2014-09-22 11:47:43.493241477 -0700
@@ -1,8 +1,4 @@
 #!/bin/sh
-# 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/.
-
 #
 # A Bourne shell script for running the NIST RSA Validation System
 #
@@ -11,14 +7,31 @@
 # shared libraries/DLLs are on the search path.  Then run this script in the
 # directory where the REQUEST (.req) files reside.  The script generates the
 # RESPONSE (.rsp) files in the same directory.
+BASEDIR=${1-.}
+TESTDIR=${BASEDIR}/RSA2
+COMMAND=${2-run}
+REQDIR=${TESTDIR}/req
+RSPDIR=${TESTDIR}/resp
 
+if [ ${COMMAND} = "verify" ]; then
+#verify the signatures. The fax file does not have any known answers, so
+#use our own verify function.
+    name=SigGen15_186-3
+    echo ">>>>>  $name"
+    fipstest rsa sigver ${RSPDIR}/$name.rsp | grep ^Result.=.F
+#    fipstest rsa sigver ${REQDIR}/SigVer15_186-3.req | grep ^Result.=.F
+#The Fax file has the private exponent and the salt value, remove it
+#also remove the false reason
+    sh ./validate1.sh ${TESTDIR} SigVer15_186-3.req ' ' '-e /^SaltVal/d -e/^d.=/d -e /^p.=/d -e /^q.=/d -e /^EM.with/d -e /^Result.=.F/s;.(.*);;'
+    exit 0
+fi
 
-request=SigGen15.req
+request=SigGen15_186-3.req
 response=`echo $request | sed -e "s/req/rsp/"`
 echo $request $response
-fipstest rsa siggen $request > $response
+fipstest rsa siggen ${REQDIR}/$request > ${RSPDIR}/$response
 
-request=SigVer15.req
+request=SigVer15_186-3.req
 response=`echo $request | sed -e "s/req/rsp/"`
 echo $request $response
-fipstest rsa sigver $request > $response
+fipstest rsa sigver ${REQDIR}/$request > ${RSPDIR}/$response
diff -up ./nss/cmd/fipstest/runtest.sh.fipstest ./nss/cmd/fipstest/runtest.sh
--- ./nss/cmd/fipstest/runtest.sh.fipstest	2014-09-22 11:47:43.493241477 -0700
+++ ./nss/cmd/fipstest/runtest.sh	2014-09-22 11:47:43.493241477 -0700
@@ -0,0 +1,12 @@
+#!/bin/sh
+TESTDIR=${1-.}
+COMMAND=${2-run}
+TESTS="aes aesgcm dsa ecdsa hmac tls rng rsa sha tdea"
+if [ ${NSS_ENABLE_ECC}x = 1x ]; then
+   TESTS=${TESTS} ecdsa
+fi
+for i in $TESTS
+do
+    echo "********************Running $i tests"
+    sh ./${i}.sh ${TESTDIR} ${COMMAND}
+done
diff -up ./nss/cmd/fipstest/sha.sh.fipstest ./nss/cmd/fipstest/sha.sh
--- ./nss/cmd/fipstest/sha.sh.fipstest	2014-06-24 13:45:27.000000000 -0700
+++ ./nss/cmd/fipstest/sha.sh	2014-09-22 11:47:43.494241494 -0700
@@ -1,8 +1,4 @@
 #!/bin/sh
-# 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/.
-
 #
 # A Bourne shell script for running the NIST SHA Algorithm Validation Suite
 #
@@ -11,9 +7,15 @@
 # shared libraries/DLLs are on the search path.  Then run this script in the
 # directory where the REQUEST (.req) files reside.  The script generates the
 # RESPONSE (.rsp) files in the same directory.
+BASEDIR=${1-.}
+TESTDIR=${BASEDIR}/SHA
+COMMAND=${2-run}
+REQDIR=${TESTDIR}/req
+RSPDIR=${TESTDIR}/resp
                                
 sha_ShortMsg_requests="
 SHA1ShortMsg.req
+SHA224ShortMsg.req
 SHA256ShortMsg.req
 SHA384ShortMsg.req
 SHA512ShortMsg.req
@@ -21,6 +23,7 @@ SHA512ShortMsg.req
 
 sha_LongMsg_requests="
 SHA1LongMsg.req
+SHA224LongMsg.req
 SHA256LongMsg.req
 SHA384LongMsg.req
 SHA512LongMsg.req
@@ -28,23 +31,32 @@ SHA512LongMsg.req
 
 sha_Monte_requests="
 SHA1Monte.req
+SHA224Monte.req
 SHA256Monte.req
 SHA384Monte.req
 SHA512Monte.req
 "
+
+if [ ${COMMAND} = "verify" ]; then
+    for request in $sha_ShortMsg_requests $sha_LongMsg_requests $sha_Monte_requests; do
+	sh ./validate1.sh ${TESTDIR} $request
+    done
+    exit 0
+fi
+
 for request in $sha_ShortMsg_requests; do
     response=`echo $request | sed -e "s/req/rsp/"`
     echo $request $response
-    fipstest sha $request > $response
+    fipstest sha ${REQDIR}/$request > ${RSPDIR}/$response
 done
 for request in $sha_LongMsg_requests; do
     response=`echo $request | sed -e "s/req/rsp/"`
     echo $request $response
-    fipstest sha $request > $response
+    fipstest sha ${REQDIR}/$request > ${RSPDIR}/$response
 done
 for request in $sha_Monte_requests; do
     response=`echo $request | sed -e "s/req/rsp/"`
     echo $request $response
-    fipstest sha $request > $response
+    fipstest sha ${REQDIR}/$request > ${RSPDIR}/$response
 done
 
diff -up ./nss/cmd/fipstest/tdea.sh.fipstest ./nss/cmd/fipstest/tdea.sh
--- ./nss/cmd/fipstest/tdea.sh.fipstest	2014-06-24 13:45:27.000000000 -0700
+++ ./nss/cmd/fipstest/tdea.sh	2014-09-22 11:47:43.494241494 -0700
@@ -1,8 +1,4 @@
 #!/bin/sh
-# 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/.
-
 #
 # A Bourne shell script for running the NIST tdea Algorithm Validation Suite
 #
@@ -12,6 +8,12 @@
 # directory where the REQUEST (.req) files reside.  The script generates the
 # RESPONSE (.rsp) files in the same directory.
 
+BASEDIR=${1-.}
+TESTDIR=${BASEDIR}/TDES
+COMMAND=${2-run}
+REQDIR=${TESTDIR}/req
+RSPDIR=${TESTDIR}/resp
+
 #CBC_Known_Answer_tests
 #Initial Permutation KAT  
 #Permutation Operation KAT 
@@ -59,33 +61,42 @@ TECBMMT2.req
 TECBMMT3.req
 "
 
-for request in $ecb_mmt_requests; do
+
+if [ ${COMMAND} = "verify" ]; then
+    for request in $cbc_kat_requests $cbc_monte_requests $cbc_mmt_requests $ecb_kat_requests $ecb_monte_requests $ecb_mmt_requests
+    do
+	sh ./validate1.sh ${TESTDIR} $request "-e /^NumKeys/d"
+    done
+    exit 0
+fi
+
+for request in $cbc_kat_requests; do
     response=`echo $request | sed -e "s/req/rsp/"`
     echo $request $response
-    fipstest tdea mmt ecb $request > $response
+    fipstest tdea kat cbc ${REQDIR}/$request > ${RSPDIR}/$response
 done
-for request in $ecb_kat_requests; do
+for request in $cbc_mmt_requests; do
     response=`echo $request | sed -e "s/req/rsp/"`
     echo $request $response
-    fipstest tdea kat ecb $request > $response
+    fipstest tdea mmt cbc ${REQDIR}/$request > ${RSPDIR}/$response
 done
-for request in $ecb_monte_requests; do
+for request in $cbc_monte_requests; do
     response=`echo $request | sed -e "s/req/rsp/"`
     echo $request $response
-    fipstest tdea mct ecb $request > $response
+    fipstest tdea mct cbc ${REQDIR}/$request > ${RSPDIR}/$response
 done
-for request in $cbc_mmt_requests; do
+for request in $ecb_kat_requests; do
     response=`echo $request | sed -e "s/req/rsp/"`
     echo $request $response
-    fipstest tdea mmt cbc $request > $response
+    fipstest tdea kat ecb ${REQDIR}/$request > ${RSPDIR}/$response
 done
-for request in $cbc_kat_requests; do
+for request in $ecb_mmt_requests; do
     response=`echo $request | sed -e "s/req/rsp/"`
     echo $request $response
-    fipstest tdea kat cbc $request > $response
+    fipstest tdea mmt ecb ${REQDIR}/$request > ${RSPDIR}/$response
 done
-for request in $cbc_monte_requests; do
+for request in $ecb_monte_requests; do
     response=`echo $request | sed -e "s/req/rsp/"`
     echo $request $response
-    fipstest tdea mct cbc $request > $response
+    fipstest tdea mct ecb ${REQDIR}/$request > ${RSPDIR}/$response
 done
diff -up ./nss/cmd/fipstest/tls.sh.fipstest ./nss/cmd/fipstest/tls.sh
--- ./nss/cmd/fipstest/tls.sh.fipstest	2014-09-22 11:47:43.494241494 -0700
+++ ./nss/cmd/fipstest/tls.sh	2014-09-22 11:47:43.494241494 -0700
@@ -0,0 +1,30 @@
+#!/bin/sh
+#
+# A Bourne shell script for running the NIST RNG Validation Suite
+#
+# Before you run the script, set your PATH, LD_LIBRARY_PATH, ... environment
+# variables appropriately so that the fipstest command and the NSPR and NSS
+# shared libraries/DLLs are on the search path.  Then run this script in the
+# directory where the REQUEST (.req) files reside.  The script generates the
+# RESPONSE (.rsp) files in the same directory.
+BASEDIR=${1-.}
+TESTDIR=${BASEDIR}/KDF135
+COMMAND=${2-run}
+REQDIR=${TESTDIR}/req
+RSPDIR=${TESTDIR}/resp
+
+drbg_requests="
+tls.req
+"
+
+if [ ${COMMAND} = "verify" ]; then
+    for request in $drbg_requests; do
+	sh ./validate1.sh ${TESTDIR} $request
+    done
+    exit 0
+fi
+for request in $drbg_requests; do
+    response=`echo $request | sed -e "s/req/rsp/"`
+    echo $request $response
+    fipstest tls ${REQDIR}/$request > ${RSPDIR}/$response
+done
diff -up ./nss/cmd/fipstest/validate1.sh.fipstest ./nss/cmd/fipstest/validate1.sh
--- ./nss/cmd/fipstest/validate1.sh.fipstest	2014-09-22 11:47:43.495241511 -0700
+++ ./nss/cmd/fipstest/validate1.sh	2014-09-22 11:47:43.495241511 -0700
@@ -0,0 +1,15 @@
+#!/bin/sh
+TESTDIR=${1-.}
+request=${2}
+extraneous_response=${3}
+extraneous_fax=${4}
+name=`basename $request .req`
+echo ">>>>>  $name"
+sed -e 's;
;;g' -e 's;	; ;g' -e '/^#/d' $extraneous_response ${TESTDIR}/resp/${name}.rsp > /tmp/y1
+size=`sum /tmp/y1 | awk '{ print $NF }'`
+if [ $size -eq 0 ]; then
+   echo "${TESTDIR}/resp/${name}.rsp: empty"
+   exit 1;
+fi
+sed -e 's;
;;g' -e 's;	; ;g' -e '/^#/d' $extraneous_fax ${TESTDIR}/fax/${name}.fax > /tmp/y2
+diff -i -w -B /tmp/y1 /tmp/y2
diff -up ./nss/cmd/fipstest/validate.sh.fipstest ./nss/cmd/fipstest/validate.sh
--- ./nss/cmd/fipstest/validate.sh.fipstest	2014-09-22 11:47:43.495241511 -0700
+++ ./nss/cmd/fipstest/validate.sh	2014-09-22 11:47:43.495241511 -0700
@@ -0,0 +1,2 @@
+#!/bin/sh
+sh ./runtest.sh ${1-.} verify