|
|
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
|