7093c5
diff --git a/cmd/bltest/blapitest.c b/cmd/bltest/blapitest.c
7093c5
--- a/cmd/bltest/blapitest.c
7093c5
+++ b/cmd/bltest/blapitest.c
7093c5
@@ -3870,17 +3870,17 @@ main(int argc, char **argv)
7093c5
         rv = blapi_selftest(modesToTest, numModesToTest, inoff, outoff,
7093c5
                             encrypt, decrypt);
7093c5
         PORT_Free(cipherInfo);
7093c5
         return rv == SECSuccess ? 0 : 1;
7093c5
     }
7093c5
 
7093c5
     /* Do FIPS self-test */
7093c5
     if (bltest.commands[cmd_FIPS].activated) {
7093c5
-        CK_RV ckrv = sftk_FIPSEntryOK();
7093c5
+        CK_RV ckrv = sftk_FIPSEntryOK(PR_FALSE);
7093c5
         fprintf(stdout, "CK_RV: %ld.\n", ckrv);
7093c5
         PORT_Free(cipherInfo);
7093c5
         if (ckrv == CKR_OK)
7093c5
             return SECSuccess;
7093c5
         return SECFailure;
7093c5
     }
7093c5
 
7093c5
     /*
7093c5
diff --git a/cmd/pk11mode/pk11mode.c b/cmd/pk11mode/pk11mode.c
7093c5
--- a/cmd/pk11mode/pk11mode.c
7093c5
+++ b/cmd/pk11mode/pk11mode.c
7093c5
@@ -318,23 +318,25 @@ static PRBool verbose = PR_FALSE;
7093c5
 
7093c5
 int
7093c5
 main(int argc, char **argv)
7093c5
 {
7093c5
     CK_C_GetFunctionList pC_GetFunctionList;
7093c5
     CK_FUNCTION_LIST_PTR pFunctionList;
7093c5
     CK_RV crv = CKR_OK;
7093c5
     CK_C_INITIALIZE_ARGS_NSS initArgs;
7093c5
+    CK_C_INITIALIZE_ARGS_NSS initArgsRerun; /* rerun selftests */
7093c5
     CK_SLOT_ID *pSlotList = NULL;
7093c5
     CK_TOKEN_INFO tokenInfo;
7093c5
     CK_ULONG slotID = 0; /* slotID == 0 for FIPSMODE */
7093c5
 
7093c5
     CK_UTF8CHAR *pwd = NULL;
7093c5
     CK_ULONG pwdLen = 0;
7093c5
     char *moduleSpec = NULL;
7093c5
+    char *moduleSpecRerun = NULL;
7093c5
     char *configDir = NULL;
7093c5
     char *dbPrefix = NULL;
7093c5
     char *disableUnload = NULL;
7093c5
     PRBool doForkTests = PR_TRUE;
7093c5
 
7093c5
     PLOptStatus os;
7093c5
     PLOptState *opt = PL_CreateOptState(argc, argv, "nvhf:Fd:p:");
7093c5
     while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) {
7093c5
@@ -458,18 +460,23 @@ main(int argc, char **argv)
7093c5
     initArgs.CreateMutex = NULL;
7093c5
     initArgs.DestroyMutex = NULL;
7093c5
     initArgs.LockMutex = NULL;
7093c5
     initArgs.UnlockMutex = NULL;
7093c5
     initArgs.flags = CKF_OS_LOCKING_OK;
7093c5
     moduleSpec = PR_smprintf("configdir='%s' certPrefix='%s' "
7093c5
                              "keyPrefix='%s' secmod='secmod.db' flags= ",
7093c5
                              configDir, dbPrefix, dbPrefix);
7093c5
+    moduleSpecRerun = PR_smprintf("configdir='%s' certPrefix='%s' "
7093c5
+                             "keyPrefix='%s' secmod='secmod.db' flags=forcePOST ",
7093c5
+                             configDir, dbPrefix, dbPrefix);
7093c5
     initArgs.LibraryParameters = (CK_CHAR_PTR *)moduleSpec;
7093c5
     initArgs.pReserved = NULL;
7093c5
+    initArgsRerun = initArgs;
7093c5
+    initArgsRerun.LibraryParameters = (CK_CHAR_PTR *)moduleSpecRerun;
7093c5
 
7093c5
     /*DebugBreak();*/
7093c5
     /* FIPSMODE invokes FC_Initialize as pFunctionList->C_Initialize */
7093c5
     /* NSS cryptographic module library initialization for the FIPS  */
7093c5
     /* Approved mode when FC_Initialize is envoked will perfom       */
7093c5
     /* software integrity test, and power-up self-tests before       */
7093c5
     /* FC_Initialize returns                                         */
7093c5
     crv = pFunctionList->C_Initialize(&initArgs);
7093c5
@@ -705,17 +712,17 @@ main(int argc, char **argv)
7093c5
         PKM_Error("PKM_HybridMode failed with 0x%08X, %-26s\n", crv,
7093c5
                   PKM_CK_RVtoStr(crv));
7093c5
         goto cleanup;
7093c5
     }
7093c5
 
7093c5
     if (doForkTests) {
7093c5
         /* testing one more C_Initialize / C_Finalize to exercise getpid()
7093c5
          * fork check code */
7093c5
-        crv = pFunctionList->C_Initialize(&initArgs);
7093c5
+        crv = pFunctionList->C_Initialize(&initArgsRerun);
7093c5
         if (crv == CKR_OK) {
7093c5
             PKM_LogIt("C_Initialize succeeded\n");
7093c5
         } else {
7093c5
             PKM_Error("C_Initialize failed with 0x%08X, %-26s\n", crv,
7093c5
                       PKM_CK_RVtoStr(crv));
7093c5
             goto cleanup;
7093c5
         }
7093c5
         crv = pFunctionList->C_Finalize(NULL);
7093c5
@@ -741,16 +748,19 @@ cleanup:
7093c5
         free(configDir);
7093c5
     }
7093c5
     if (dbPrefix) {
7093c5
         free(dbPrefix);
7093c5
     }
7093c5
     if (moduleSpec) {
7093c5
         PR_smprintf_free(moduleSpec);
7093c5
     }
7093c5
+    if (moduleSpecRerun) {
7093c5
+        PR_smprintf_free(moduleSpecRerun);
7093c5
+    }
7093c5
 
7093c5
 #ifdef _WIN32
7093c5
     FreeLibrary(hModule);
7093c5
 #else
7093c5
     disableUnload = PR_GetEnvSecure("NSS_DISABLE_UNLOAD");
7093c5
     if (!disableUnload) {
7093c5
         PR_UnloadLibrary(lib);
7093c5
     }
7093c5
diff --git a/lib/freebl/blapii.h b/lib/freebl/blapii.h
7093c5
--- a/lib/freebl/blapii.h
7093c5
+++ b/lib/freebl/blapii.h
7093c5
@@ -24,17 +24,17 @@ typedef SECStatus (*freeblAeadFunc)(void
7093c5
                                     void *params, unsigned int paramsLen,
7093c5
                                     const unsigned char *aad, unsigned int aadLen,
7093c5
                                     unsigned int blocksize);
7093c5
 typedef void (*freeblDestroyFunc)(void *cx, PRBool freeit);
7093c5
 
7093c5
 SEC_BEGIN_PROTOS
7093c5
 
7093c5
 #ifndef NSS_FIPS_DISABLED
7093c5
-SECStatus BL_FIPSEntryOK(PRBool freeblOnly);
7093c5
+SECStatus BL_FIPSEntryOK(PRBool freeblOnly, PRBool rerun);
7093c5
 PRBool BL_POSTRan(PRBool freeblOnly);
7093c5
 #endif
7093c5
 
7093c5
 #if defined(XP_UNIX) && !defined(NO_FORK_CHECK)
7093c5
 
7093c5
 extern PRBool bl_parentForkedAfterC_Initialize;
7093c5
 
7093c5
 #define SKIP_AFTER_FORK(x)                 \
7093c5
diff --git a/lib/freebl/blapit.h b/lib/freebl/blapit.h
7093c5
--- a/lib/freebl/blapit.h
7093c5
+++ b/lib/freebl/blapit.h
7093c5
@@ -223,16 +223,21 @@ typedef int __BLAPI_DEPRECATED __attribu
7093c5
  *
7093c5
  * If we arbitrarily set p = 10^-18 (1 chance in trillion trillion operation)
7093c5
  * we get GCMIV_RANDOM_BIRTHDAY_BITS = -(-18)/.301 -1 = 59 (.301 = log10 2)
7093c5
  * GCMIV_RANDOM_BIRTHDAY_BITS should be at least 59, call it a round 64. NOTE:
7093c5
  * the variable IV size for TLS is 64 bits, which explains why it's not safe
7093c5
  * to use a random value for the nonce in TLS. */
7093c5
 #define GCMIV_RANDOM_BIRTHDAY_BITS 64
7093c5
 
7093c5
+/* flag to tell BLAPI_Verify* to rerun the post and integrity tests */
7093c5
+#define BLAPI_FIPS_RERUN_FLAG '\377'  /* 0xff, 255 invalide code for UFT8/ASCII */
7093c5
+#define BLAPI_FIPS_RERUN_FLAG_STRING "\377"  /* The above as a C string */
7093c5
+
7093c5
+
7093c5
 /***************************************************************************
7093c5
 ** Opaque objects
7093c5
 */
7093c5
 
7093c5
 struct DESContextStr;
7093c5
 struct RC2ContextStr;
7093c5
 struct RC4ContextStr;
7093c5
 struct RC5ContextStr;
7093c5
diff --git a/lib/freebl/fipsfreebl.c b/lib/freebl/fipsfreebl.c
7093c5
--- a/lib/freebl/fipsfreebl.c
7093c5
+++ b/lib/freebl/fipsfreebl.c
7093c5
@@ -2211,29 +2211,37 @@ bl_startup_tests(void)
7093c5
 }
7093c5
 
7093c5
 /*
7093c5
  * this is called from the freebl init entry points that controll access to
7093c5
  * all other freebl functions. This prevents freebl from operating if our
7093c5
  * power on selftest failed.
7093c5
  */
7093c5
 SECStatus
7093c5
-BL_FIPSEntryOK(PRBool freebl_only)
7093c5
+BL_FIPSEntryOK(PRBool freebl_only, PRBool rerun)
7093c5
 {
7093c5
 #ifdef NSS_NO_INIT_SUPPORT
7093c5
     /* this should only be set on platforms that can't handle one of the INIT
7093c5
     * schemes.  This code allows those platforms to continue to function,
7093c5
     * though they don't meet the strict NIST requirements. If NSS_NO_INIT_SUPPORT
7093c5
     * is not set, and init support has not been properly enabled, freebl
7093c5
     * will always fail because of the test below
7093c5
     */
7093c5
     if (!self_tests_freebl_ran) {
7093c5
         bl_startup_tests();
7093c5
     }
7093c5
 #endif
7093c5
+    if (rerun) {
7093c5
+        /* reset the flags */
7093c5
+        self_tests_freebl_ran = PR_FALSE;
7093c5
+        self_tests_success = PR_FALSE;
7093c5
+        self_tests_success = PR_FALSE;
7093c5
+        self_tests_freebl_success = PR_FALSE;
7093c5
+        bl_startup_tests();
7093c5
+    }
7093c5
     /* if the general self tests succeeded, we're done */
7093c5
     if (self_tests_success) {
7093c5
         return SECSuccess;
7093c5
     }
7093c5
     /* standalone freebl can initialize */
7093c5
     if (freebl_only && self_tests_freebl_success) {
7093c5
         return SECSuccess;
7093c5
     }
7093c5
diff --git a/lib/freebl/nsslowhash.c b/lib/freebl/nsslowhash.c
7093c5
--- a/lib/freebl/nsslowhash.c
7093c5
+++ b/lib/freebl/nsslowhash.c
7093c5
@@ -55,17 +55,17 @@ NSSLOW_Init(void)
7093c5
 #ifdef FREEBL_NO_DEPEND
7093c5
     (void)FREEBL_InitStubs();
7093c5
 #endif
7093c5
 
7093c5
 #ifndef NSS_FIPS_DISABLED
7093c5
     /* make sure the FIPS product is installed if we are trying to
7093c5
      * go into FIPS mode */
7093c5
     if (nsslow_GetFIPSEnabled()) {
7093c5
-        if (BL_FIPSEntryOK(PR_TRUE) != SECSuccess) {
7093c5
+        if (BL_FIPSEntryOK(PR_TRUE, PR_FALSE) != SECSuccess) {
7093c5
             PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
7093c5
             post_failed = PR_TRUE;
7093c5
             return NULL;
7093c5
         }
7093c5
     }
7093c5
 #endif
7093c5
     post_failed = PR_FALSE;
7093c5
 
7093c5
diff --git a/lib/freebl/shvfy.c b/lib/freebl/shvfy.c
7093c5
--- a/lib/freebl/shvfy.c
7093c5
+++ b/lib/freebl/shvfy.c
7093c5
@@ -282,52 +282,62 @@ readItem(PRFileDesc *fd, SECItem *item)
7093c5
         PORT_Free(item->data);
7093c5
         item->data = NULL;
7093c5
         item->len = 0;
7093c5
         return SECFailure;
7093c5
     }
7093c5
     return SECSuccess;
7093c5
 }
7093c5
 
7093c5
-static PRBool blapi_SHVerifyFile(const char *shName, PRBool self);
7093c5
+static PRBool blapi_SHVerifyFile(const char *shName, PRBool self, PRBool rerun);
7093c5
 
7093c5
 static PRBool
7093c5
-blapi_SHVerify(const char *name, PRFuncPtr addr, PRBool self)
7093c5
+blapi_SHVerify(const char *name, PRFuncPtr addr, PRBool self, PRBool rerun)
7093c5
 {
7093c5
     PRBool result = PR_FALSE; /* if anything goes wrong,
7093c5
                    * the signature does not verify */
7093c5
     /* find our shared library name */
7093c5
     char *shName = PR_GetLibraryFilePathname(name, addr);
7093c5
     if (!shName) {
7093c5
         goto loser;
7093c5
     }
7093c5
-    result = blapi_SHVerifyFile(shName, self);
7093c5
+    result = blapi_SHVerifyFile(shName, self, rerun);
7093c5
 
7093c5
 loser:
7093c5
     if (shName != NULL) {
7093c5
         PR_Free(shName);
7093c5
     }
7093c5
 
7093c5
     return result;
7093c5
 }
7093c5
 
7093c5
 PRBool
7093c5
 BLAPI_SHVerify(const char *name, PRFuncPtr addr)
7093c5
 {
7093c5
-    return blapi_SHVerify(name, addr, PR_FALSE);
7093c5
+    PRBool rerun = PR_FALSE;
7093c5
+    if (name && *name == BLAPI_FIPS_RERUN_FLAG) {
7093c5
+        name++;
7093c5
+        rerun = PR_TRUE;
7093c5
+    }
7093c5
+    return blapi_SHVerify(name, addr, PR_FALSE, rerun);
7093c5
 }
7093c5
 
7093c5
 PRBool
7093c5
 BLAPI_SHVerifyFile(const char *shName)
7093c5
 {
7093c5
-    return blapi_SHVerifyFile(shName, PR_FALSE);
7093c5
+    PRBool rerun = PR_FALSE;
7093c5
+    if (shName && *shName == BLAPI_FIPS_RERUN_FLAG) {
7093c5
+        shName++;
7093c5
+        rerun = PR_TRUE;
7093c5
+    }
7093c5
+    return blapi_SHVerifyFile(shName, PR_FALSE, rerun);
7093c5
 }
7093c5
 
7093c5
 static PRBool
7093c5
-blapi_SHVerifyFile(const char *shName, PRBool self)
7093c5
+blapi_SHVerifyFile(const char *shName, PRBool self, PRBool rerun)
7093c5
 {
7093c5
     char *checkName = NULL;
7093c5
     PRFileDesc *checkFD = NULL;
7093c5
     PRFileDesc *shFD = NULL;
7093c5
     void *hashcx = NULL;
7093c5
     const SECHashObject *hashObj = NULL;
7093c5
     SECItem signature = { 0, NULL, 0 };
7093c5
     SECItem hash;
7093c5
@@ -346,17 +356,17 @@ blapi_SHVerifyFile(const char *shName, P
7093c5
     unsigned char hashBuf[HASH_LENGTH_MAX];
7093c5
 
7093c5
     PORT_Memset(&key, 0, sizeof(key));
7093c5
     hash.data = hashBuf;
7093c5
     hash.len = sizeof(hashBuf);
7093c5
 
7093c5
     /* If our integrity check was never ran or failed, fail any other
7093c5
      * integrity checks to prevent any token going into FIPS mode. */
7093c5
-    if (!self && (BL_FIPSEntryOK(PR_FALSE) != SECSuccess)) {
7093c5
+    if (!self && (BL_FIPSEntryOK(PR_FALSE, rerun) != SECSuccess)) {
7093c5
         return PR_FALSE;
7093c5
     }
7093c5
 
7093c5
     if (!shName) {
7093c5
         goto loser;
7093c5
     }
7093c5
 
7093c5
     /* figure out the name of our check file */
7093c5
@@ -536,17 +546,17 @@ BLAPI_VerifySelf(const char *name)
7093c5
 {
7093c5
     if (name == NULL) {
7093c5
         /*
7093c5
          * If name is NULL, freebl is statically linked into softoken.
7093c5
          * softoken will call BLAPI_SHVerify next to verify itself.
7093c5
          */
7093c5
         return PR_TRUE;
7093c5
     }
7093c5
-    return blapi_SHVerify(name, (PRFuncPtr)decodeInt, PR_TRUE);
7093c5
+    return blapi_SHVerify(name, (PRFuncPtr)decodeInt, PR_TRUE, PR_FALSE);
7093c5
 }
7093c5
 
7093c5
 #else /* NSS_FIPS_DISABLED */
7093c5
 
7093c5
 PRBool
7093c5
 BLAPI_SHVerifyFile(const char *shName)
7093c5
 {
7093c5
     return PR_FALSE;
7093c5
diff --git a/lib/softoken/fipstest.c b/lib/softoken/fipstest.c
7093c5
--- a/lib/softoken/fipstest.c
7093c5
+++ b/lib/softoken/fipstest.c
7093c5
@@ -684,22 +684,25 @@ sftk_fips_HKDF_PowerUpSelfTest(void)
7093c5
 
7093c5
 static PRBool sftk_self_tests_ran = PR_FALSE;
7093c5
 static PRBool sftk_self_tests_success = PR_FALSE;
7093c5
 
7093c5
 /*
7093c5
  * This function is called at dll load time, the code tha makes this
7093c5
  * happen is platform specific on defined above.
7093c5
  */
7093c5
-static void
7093c5
-sftk_startup_tests(void)
7093c5
+void sftk_startup_tests_with_rerun(PRBool rerun)
7093c5
 {
7093c5
     SECStatus rv;
7093c5
-    const char *libraryName = SOFTOKEN_LIB_NAME;
7093c5
-
7093c5
+    /*const char *nlibraryName = SOFTOKEN_LIB_NAME;
7093c5
+    const char *rlibraryName = BLAPI_FIPS_RERUN_FLAG_STRING SOFTOKEN_LIB_NAME; */
7093c5
+    const char *libraryName = rerun ?
7093c5
+               BLAPI_FIPS_RERUN_FLAG_STRING SOFTOKEN_LIB_NAME :
7093c5
+               SOFTOKEN_LIB_NAME;
7093c5
+    
7093c5
     PORT_Assert(!sftk_self_tests_ran);
7093c5
     PORT_Assert(!sftk_self_tests_success);
7093c5
     sftk_self_tests_ran = PR_TRUE;
7093c5
     sftk_self_tests_success = PR_FALSE; /* just in case */
7093c5
 
7093c5
     /* need to initiallize the oid library before the RSA tests */
7093c5
     rv = SECOID_Init();
7093c5
     if (rv != SECSuccess) {
7093c5
@@ -746,35 +749,46 @@ sftk_startup_tests(void)
7093c5
     rv = sftk_fips_pbkdf_PowerUpSelfTests();
7093c5
     if (rv != SECSuccess) {
7093c5
         return;
7093c5
     }
7093c5
 
7093c5
     sftk_self_tests_success = PR_TRUE;
7093c5
 }
7093c5
 
7093c5
+static void
7093c5
+sftk_startup_tests(void)
7093c5
+{
7093c5
+    sftk_startup_tests_with_rerun(PR_FALSE);
7093c5
+}
7093c5
+
7093c5
 /*
7093c5
  * this is called from nsc_Common_Initizialize entry points that gates access
7093c5
  * to * all other pkcs11 functions. This prevents softoken operation if our
7093c5
  * power on selftest failed.
7093c5
  */
7093c5
 CK_RV
7093c5
-sftk_FIPSEntryOK()
7093c5
+sftk_FIPSEntryOK(PRBool rerun)
7093c5
 {
7093c5
 #ifdef NSS_NO_INIT_SUPPORT
7093c5
     /* this should only be set on platforms that can't handle one of the INIT
7093c5
      * schemes.  This code allows those platforms to continue to function,
7093c5
      * though they don't meet the strict NIST requirements. If NSS_NO_INIT_SUPPORT
7093c5
      * is not set, and init support has not been properly enabled, softken
7093c5
      * will always fail because of the test below
7093c5
      */
7093c5
     if (!sftk_self_tests_ran) {
7093c5
         sftk_startup_tests();
7093c5
     }
7093c5
 #endif
7093c5
+    if (rerun) {
7093c5
+        sftk_self_tests_ran = PR_FALSE;
7093c5
+        sftk_self_tests_success = PR_FALSE;
7093c5
+        sftk_startup_tests_with_rerun(PR_TRUE);
7093c5
+    }
7093c5
     if (!sftk_self_tests_success) {
7093c5
         return CKR_DEVICE_ERROR;
7093c5
     }
7093c5
     return CKR_OK;
7093c5
 }
7093c5
 #else
7093c5
 #include "pkcs11t.h"
7093c5
 CK_RV
7093c5
diff --git a/lib/softoken/fipstokn.c b/lib/softoken/fipstokn.c
7093c5
--- a/lib/softoken/fipstokn.c
7093c5
+++ b/lib/softoken/fipstokn.c
7093c5
@@ -524,25 +524,32 @@ fc_log_init_error(CK_RV crv)
7093c5
 }
7093c5
 
7093c5
 /* FC_Initialize initializes the PKCS #11 library. */
7093c5
 CK_RV
7093c5
 FC_Initialize(CK_VOID_PTR pReserved)
7093c5
 {
7093c5
     const char *envp;
7093c5
     CK_RV crv;
7093c5
+    PRBool rerun;
7093c5
 
7093c5
     if ((envp = PR_GetEnv("NSS_ENABLE_AUDIT")) != NULL) {
7093c5
         sftk_audit_enabled = (atoi(envp) == 1);
7093c5
     }
7093c5
 
7093c5
+    /* if we have the forcePOST flag on, rerun the integrity checks */
7093c5
+    /* we need to know this before we fully parse the arguments in
7093c5
+     * nsc_CommonInitialize, so read it now */
7093c5
+    rerun = sftk_RawArgHasFlag("flags", "forcePost", pReserved);
7093c5
+
7093c5
     /* At this point we should have already done post and integrity checks.
7093c5
      * if we haven't, it probably means the FIPS product has not been installed
7093c5
-     * or the tests failed. Don't let an application try to enter FIPS mode */
7093c5
-    crv = sftk_FIPSEntryOK();
7093c5
+     * or the tests failed. Don't let an application try to enter FIPS mode. This
7093c5
+     * also forces the tests to be rerun if forcePOST is set. */
7093c5
+    crv = sftk_FIPSEntryOK(rerun);
7093c5
     if (crv != CKR_OK) {
7093c5
         sftk_fatalError = PR_TRUE;
7093c5
         fc_log_init_error(crv);
7093c5
         return crv;
7093c5
     }
7093c5
 
7093c5
     sftk_ForkReset(pReserved, &crv;;
7093c5
 
7093c5
diff --git a/lib/softoken/pkcs11i.h b/lib/softoken/pkcs11i.h
7093c5
--- a/lib/softoken/pkcs11i.h
7093c5
+++ b/lib/softoken/pkcs11i.h
7093c5
@@ -869,16 +869,17 @@ extern CK_RV sftk_MechAllowsOperation(CK
7093c5
  * acquiring a reference to the keydb from the slot */
7093c5
 NSSLOWKEYPrivateKey *sftk_FindKeyByPublicKey(SFTKSlot *slot, SECItem *dbKey);
7093c5
 
7093c5
 /*
7093c5
  * parameter parsing functions
7093c5
  */
7093c5
 CK_RV sftk_parseParameters(char *param, sftk_parameters *parsed, PRBool isFIPS);
7093c5
 void sftk_freeParams(sftk_parameters *params);
7093c5
+PRBool sftk_RawArgHasFlag(const char *entry, const char *flag, const void *pReserved);
7093c5
 
7093c5
 /*
7093c5
  * narrow objects
7093c5
  */
7093c5
 SFTKSessionObject *sftk_narrowToSessionObject(SFTKObject *);
7093c5
 SFTKTokenObject *sftk_narrowToTokenObject(SFTKObject *);
7093c5
 
7093c5
 /*
7093c5
diff --git a/lib/softoken/sftkpars.c b/lib/softoken/sftkpars.c
7093c5
--- a/lib/softoken/sftkpars.c
7093c5
+++ b/lib/softoken/sftkpars.c
7093c5
@@ -244,8 +244,21 @@ sftk_freeParams(sftk_parameters *params)
7093c5
     FREE_CLEAR(params->configdir);
7093c5
     FREE_CLEAR(params->secmodName);
7093c5
     FREE_CLEAR(params->man);
7093c5
     FREE_CLEAR(params->libdes);
7093c5
     FREE_CLEAR(params->tokens);
7093c5
     FREE_CLEAR(params->updatedir);
7093c5
     FREE_CLEAR(params->updateID);
7093c5
 }
7093c5
+
7093c5
+PRBool
7093c5
+sftk_RawArgHasFlag(const char *entry, const char *flag, const void *pReserved)
7093c5
+{
7093c5
+    CK_C_INITIALIZE_ARGS *init_args = (CK_C_INITIALIZE_ARGS *)pReserved;
7093c5
+
7093c5
+    /* if we don't have any params, the flag isn't set */
7093c5
+    if ((!init_args || !init_args->LibraryParameters)) {
7093c5
+        return PR_FALSE;
7093c5
+    }
7093c5
+
7093c5
+    return NSSUTIL_ArgHasFlag(entry, flag, (const char *)init_args->LibraryParameters);
7093c5
+}
7093c5
diff --git a/lib/softoken/softoken.h b/lib/softoken/softoken.h
7093c5
--- a/lib/softoken/softoken.h
7093c5
+++ b/lib/softoken/softoken.h
7093c5
@@ -52,17 +52,17 @@ extern unsigned char *CBC_PadBuffer(PLAr
7093c5
                                     unsigned int inlen, unsigned int *outlen,
7093c5
                                     int blockSize);
7093c5
 
7093c5
 /****************************************/
7093c5
 /*
7093c5
 ** Power-Up selftests are required for FIPS.
7093c5
 */
7093c5
 /* make sure Power-up selftests have been run. */
7093c5
-extern CK_RV sftk_FIPSEntryOK(void);
7093c5
+extern CK_RV sftk_FIPSEntryOK(PRBool rerun);
7093c5
 
7093c5
 /*
7093c5
 ** make known fixed PKCS #11 key types to their sizes in bytes
7093c5
 */
7093c5
 unsigned long sftk_MapKeySize(CK_KEY_TYPE keyType);
7093c5
 
7093c5
 /*
7093c5
 ** FIPS 140-2 auditing