diff --git a/lib/pk11wrap/pk11pars.c b/lib/pk11wrap/pk11pars.c --- a/lib/pk11wrap/pk11pars.c +++ b/lib/pk11wrap/pk11pars.c @@ -159,16 +159,20 @@ SECMOD_CreateModuleEx(const char *librar if (parameters) { mod->libraryParams = PORT_ArenaStrdup(mod->arena,parameters); } if (config) { /* XXX: Apply configuration */ } mod->internal = NSSUTIL_ArgHasFlag("flags","internal",nssc); mod->isFIPS = NSSUTIL_ArgHasFlag("flags","FIPS",nssc); + /* if the system FIPS mode is enabled, force FIPS to be on */ + if (SECMOD_GetSystemFIPSEnabled()) { + mod->isFIPS = PR_TRUE; + } mod->isCritical = NSSUTIL_ArgHasFlag("flags","critical",nssc); slotParams = NSSUTIL_ArgGetParamValue("slotParams",nssc); mod->slotInfo = NSSUTIL_ArgParseSlotInfo(mod->arena,slotParams, &mod->slotInfoCount); if (slotParams) PORT_Free(slotParams); /* new field */ mod->trustOrder = NSSUTIL_ArgReadLong("trustOrder",nssc, NSSUTIL_DEFAULT_TRUST_ORDER,NULL); diff --git a/lib/pk11wrap/pk11util.c b/lib/pk11wrap/pk11util.c --- a/lib/pk11wrap/pk11util.c +++ b/lib/pk11wrap/pk11util.c @@ -90,16 +90,35 @@ SECMOD_Shutdown() #endif if (secmod_PrivateModuleCount) { PORT_SetError(SEC_ERROR_BUSY); return SECFailure; } return SECSuccess; } +int SECMOD_GetSystemFIPSEnabled(void) { +#ifdef LINUX + FILE *f; + char d; + size_t size; + + f = fopen("/proc/sys/crypto/fips_enabled", "r"); + if (!f) + return 0; + + size = fread(&d, 1, 1, f); + fclose(f); + if (size != 1) + return 0; + if (d == '1') + return 1; +#endif + return 0; +} /* * retrieve the internal module */ SECMODModule * SECMOD_GetInternalModule(void) { return internalModule; @@ -412,17 +431,17 @@ SECMOD_DeleteModule(const char *name, in */ SECStatus SECMOD_DeleteInternalModule(const char *name) { SECMODModuleList *mlp; SECMODModuleList **mlpp; SECStatus rv = SECFailure; - if (pendingModule) { + if (SECMOD_GetSystemFIPSEnabled() || pendingModule) { PORT_SetError(SEC_ERROR_MODULE_STUCK); return rv; } if (!moduleLock) { PORT_SetError(SEC_ERROR_NOT_INITIALIZED); return rv; } @@ -883,17 +902,17 @@ SECMOD_DestroyModuleList(SECMODModuleLis SECMODModuleList *lp; for ( lp = list; lp != NULL; lp = SECMOD_DestroyModuleListElement(lp)) ; } PRBool SECMOD_CanDeleteInternalModule(void) { - return (PRBool) (pendingModule == NULL); + return (PRBool) ((pendingModule == NULL) && !SECMOD_GetSystemFIPSEnabled()); } /* * check to see if the module has added new slots. PKCS 11 v2.20 allows for * modules to add new slots, but never remove them. Slots cannot be added * between a call to C_GetSlotLlist(Flag, NULL, &count) and the subsequent * C_GetSlotList(flag, &data, &count) so that the array doesn't accidently * grow on the caller. It is permissible for the slots to increase between diff --git a/lib/pk11wrap/secmodi.h b/lib/pk11wrap/secmodi.h --- a/lib/pk11wrap/secmodi.h +++ b/lib/pk11wrap/secmodi.h @@ -108,17 +108,22 @@ SECStatus PBE_PK11ParamToAlgid(SECOidTag PK11SymKey *pk11_TokenKeyGenWithFlagsAndKeyType(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *param, CK_KEY_TYPE keyType, int keySize, SECItem *keyId, CK_FLAGS opFlags, PK11AttrFlags attrFlags, void *wincx); CK_MECHANISM_TYPE pk11_GetPBECryptoMechanism(SECAlgorithmID *algid, SECItem **param, SECItem *pwd, PRBool faulty3DES); - +/* Get the state of the system FIPS mode */ +/* NSS uses this to force FIPS mode if the system bit is on. Applications which + * use the SECMOD_CanDeleteInteral() to check to see if they can switch to or + * from FIPS mode will automatically be told that they can't swith out of FIPS + * mode */ +int SECMOD_GetSystemFIPSEnabled(); extern void pk11sdr_Init(void); extern void pk11sdr_Shutdown(void); /* * Private to pk11wrap. */