Bug 340724, Upgrade NSS on Mozilla 1.8 branch for 1.8.1 final MOZILLA_1_8_BRANCH FIREFOX_2_0b2_RC1 FIREFOX_2_0b2_RELEASE SEAMONKEY_1_1a_RELEASE
authorkaie%kuix.de
Fri, 04 Aug 2006 19:10:54 +0000
branchMOZILLA_1_8_BRANCH
changeset 7283 6920f22c975c6d67be5e7e0a888a645f8aa5ea50
parent 7184 5981593d299cb1787742f4f5987e3b0fe33e859b
child 7284 341ce7eb1f43c854bcecbddb53f53bf9f76d46d5
child 7347 2f9107038df91a8f38914e1d7bf52a5fbaea08c2
push idunknown
push userunknown
push dateunknown
bugs340724
Bug 340724, Upgrade NSS on Mozilla 1.8 branch for 1.8.1 final r=wtchang, a=mtschrep
security/nss/lib/base/arena.c
security/nss/lib/certhigh/ocsp.c
security/nss/lib/ckfw/builtins/binst.c
security/nss/lib/ckfw/wrap.c
security/nss/lib/crmf/challcli.c
security/nss/lib/crmf/crmfpop.c
security/nss/lib/freebl/Makefile
security/nss/lib/nss/nss.h
security/nss/lib/pk11wrap/pk11cert.c
security/nss/lib/pk11wrap/pk11mech.c
security/nss/lib/pk11wrap/pk11pbe.c
security/nss/lib/pki/pki3hack.c
security/nss/lib/pki/trustdomain.c
security/nss/lib/smime/cmscipher.c
security/nss/lib/smime/cmsrecinfo.c
security/nss/lib/smime/cmsreclist.c
security/nss/lib/softoken/fipstest.c
security/nss/lib/softoken/fipstokn.c
security/nss/lib/softoken/keydb.c
security/nss/lib/softoken/pkcs11.c
security/nss/lib/softoken/pkcs11c.c
security/nss/lib/softoken/pkcs11i.h
security/nss/lib/softoken/rsawrapr.c
security/nss/lib/softoken/softoken.h
security/nss/lib/ssl/ssl3con.c
security/nss/lib/ssl/ssl3ecc.c
security/nss/lib/ssl/sslcon.c
security/nss/lib/ssl/sslimpl.h
security/nss/lib/ssl/sslsnce.c
--- a/security/nss/lib/base/arena.c
+++ b/security/nss/lib/base/arena.c
@@ -515,22 +515,22 @@ nssArena_Destroy
   PRLock *lock;
 
 #ifdef NSSDEBUG
   if( PR_SUCCESS != nssArena_verifyPointer(arena) ) {
     return PR_FAILURE;
   }
 #endif /* NSSDEBUG */
 
-  PR_Lock(arena->lock);
   if( (PRLock *)NULL == arena->lock ) {
     /* Just got destroyed */
     nss_SetError(NSS_ERROR_INVALID_ARENA);
     return PR_FAILURE;
   }
+  PR_Lock(arena->lock);
   
 #ifdef DEBUG
   if( PR_SUCCESS != arena_remove_pointer(arena) ) {
     return PR_FAILURE;
   }
 #endif /* DEBUG */
 
 #ifdef ARENA_DESTRUCTOR_LIST
@@ -580,22 +580,22 @@ nssArena_Mark
   void *p;
 
 #ifdef NSSDEBUG
   if( PR_SUCCESS != nssArena_verifyPointer(arena) ) {
     return (nssArenaMark *)NULL;
   }
 #endif /* NSSDEBUG */
 
-  PR_Lock(arena->lock);
   if( (PRLock *)NULL == arena->lock ) {
     /* Just got destroyed */
     nss_SetError(NSS_ERROR_INVALID_ARENA);
     return (nssArenaMark *)NULL;
   }
+  PR_Lock(arena->lock);
 
 #ifdef ARENA_THREADMARK
   if( (PRThread *)NULL == arena->marking_thread ) {
     /* Unmarked.  Store our thread ID */
     arena->marking_thread = PR_GetCurrentThread();
     /* This call never fails. */
   } else {
     /* Marked.  Verify it's the current thread */
@@ -663,22 +663,22 @@ nss_arena_unmark_release
   }
 #endif /* NSSDEBUG */
 
   if( MARK_MAGIC != arenaMark->magic ) {
     nss_SetError(NSS_ERROR_INVALID_ARENA_MARK);
     return PR_FAILURE;
   }
 
-  PR_Lock(arena->lock);
   if( (PRLock *)NULL == arena->lock ) {
     /* Just got destroyed */
     nss_SetError(NSS_ERROR_INVALID_ARENA);
     return PR_FAILURE;
   }
+  PR_Lock(arena->lock);
 
 #ifdef ARENA_THREADMARK
   if( (PRThread *)NULL != arena->marking_thread ) {
     if( PR_GetCurrentThread() != arena->marking_thread ) {
       PR_Unlock(arena->lock);
       nss_SetError(NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD);
       return PR_FAILURE;
     }
@@ -903,22 +903,22 @@ nss_ZAlloc
     void *rv;
     /* Arena allocation */
 #ifdef NSSDEBUG
     if( PR_SUCCESS != nssArena_verifyPointer(arenaOpt) ) {
       return (void *)NULL;
     }
 #endif /* NSSDEBUG */
 
-    PR_Lock(arenaOpt->lock);
     if( (PRLock *)NULL == arenaOpt->lock ) {
       /* Just got destroyed */
       nss_SetError(NSS_ERROR_INVALID_ARENA);
       return (void *)NULL;
     }
+    PR_Lock(arenaOpt->lock);
 
 #ifdef ARENA_THREADMARK
     if( (PRThread *)NULL != arenaOpt->marking_thread ) {
       if( PR_GetCurrentThread() != arenaOpt->marking_thread ) {
         nss_SetError(NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD);
         PR_Unlock(arenaOpt->lock);
         return (void *)NULL;
       }
--- a/security/nss/lib/certhigh/ocsp.c
+++ b/security/nss/lib/certhigh/ocsp.c
@@ -849,16 +849,17 @@ ocsp_AddServiceLocatorExtension(ocspSing
 				&serviceLocator->locator);
     if (rv != SECSuccess) {
 	if (PORT_GetError() != SEC_ERROR_EXTENSION_NOT_FOUND)
 	    goto loser;
     }
 
     /* prepare for following loser gotos */
     rv = SECFailure;
+    PORT_SetError(0);
 
     extensionHandle = cert_StartExtensions(singleRequest,
                        singleRequest->arena, SetSingleReqExts);
     if (extensionHandle == NULL)
 	goto loser;
 
     rv = CERT_EncodeAndAddExtension(extensionHandle,
 				    SEC_OID_PKIX_OCSP_SERVICE_LOCATOR,
@@ -2437,16 +2438,17 @@ ocsp_CertIsOCSPSigner(CERTCertificate *c
 	    goto success;
 	}
 	
 	oids++;
     }
 
 loser:
     retval = PR_FALSE;
+    PORT_SetError(SEC_ERROR_OCSP_INVALID_SIGNING_CERT);
     goto done;
 success:
     retval = PR_TRUE;
 done:
     if ( extItem.data != NULL ) {
 	PORT_Free(extItem.data);
     }
     if ( oidSeq != NULL ) {
@@ -2622,17 +2624,17 @@ ocsp_CheckSignature(ocspSignature *signa
 	    }
 	}
     }
 
     if (signerCert == NULL) {
 	rv = SECFailure;
 	if (PORT_GetError() == SEC_ERROR_UNKNOWN_CERT) {
 	    /* Make the error a little more specific. */
-	    PORT_SetError(SEC_ERROR_UNKNOWN_SIGNER);
+	    PORT_SetError(SEC_ERROR_OCSP_INVALID_SIGNING_CERT);
 	}
 	goto finish;
     }
 
     /*
      * We could mark this true at the top of this function, or always
      * below at "finish", but if the problem was just that we could not
      * find the signer's cert, leave that as if the signature hasn't
@@ -3194,17 +3196,17 @@ ocsp_VerifySingleResponse(CERTOCSPSingle
  *   in the cert.
  * INPUTS:
  *   CERTCertificate *cert
  *     The certificate being examined.
  * RETURN:
  *   char *
  *     A copy of the URI for the OCSP method, if found.  If either the
  *     extension is not present or it does not contain an entry for OCSP,
- *     SEC_ERROR_EXTENSION_NOT_FOUND will be set and a NULL returned.
+ *     SEC_ERROR_CERT_BAD_ACCESS_LOCATION will be set and a NULL returned.
  *     Any other error will also result in a NULL being returned.
  *     
  *     This result should be freed (via PORT_Free) when no longer in use.
  */
 char *
 CERT_GetOCSPAuthorityInfoAccessLocation(CERTCertificate *cert)
 {
     CERTGeneralName *locname = NULL;
@@ -3222,18 +3224,20 @@ CERT_GetOCSPAuthorityInfoAccessLocation(
      * and we can free the entire thing on our way out.
      */
     encodedAuthInfoAccess = SECITEM_AllocItem(NULL, NULL, 0);
     if (encodedAuthInfoAccess == NULL)
 	goto loser;
 
     rv = CERT_FindCertExtension(cert, SEC_OID_X509_AUTH_INFO_ACCESS,
 				encodedAuthInfoAccess);
-    if (rv == SECFailure)
+    if (rv == SECFailure) {
+	PORT_SetError(SEC_ERROR_CERT_BAD_ACCESS_LOCATION);
 	goto loser;
+    }
 
     /*
      * The rest of the things allocated in the routine will come out of
      * this arena, which is temporary just for us to decode and get at the
      * AIA extension.  The whole thing will be destroyed on our way out,
      * after we have copied the location string (url) itself (if found).
      */
     arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
@@ -3253,34 +3257,34 @@ CERT_GetOCSPAuthorityInfoAccessLocation(
     /*
      * If we found an AIA extension, but it did not include an OCSP method,
      * that should look to our caller as if we did not find the extension
      * at all, because it is only an OCSP method that we care about.
      * So set the same error that would be set if the AIA extension was
      * not there at all.
      */
     if (locname == NULL) {
-	PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND);
+	PORT_SetError(SEC_ERROR_CERT_BAD_ACCESS_LOCATION);
 	goto loser;
     }
 
     /*
      * The following is just a pointer back into locname (i.e. not a copy);
      * thus it should not be freed.
      */
     location = CERT_GetGeneralNameByType(locname, certURI, PR_FALSE);
     if (location == NULL) {
 	/*
 	 * XXX Appears that CERT_GetGeneralNameByType does not set an
 	 * error if there is no name by that type.  For lack of anything
 	 * better, act as if the extension was not found.  In the future
 	 * this should probably be something more like the extension was
 	 * badly formed.
 	 */
-	PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND);
+	PORT_SetError(SEC_ERROR_CERT_BAD_ACCESS_LOCATION);
 	goto loser;
     }
 
     /*
      * That location is really a string, but it has a specified length
      * without a null-terminator.  We need a real string that does have
      * a null-terminator, and we need a copy of it anyway to return to
      * our caller -- so allocate and copy.
@@ -3476,20 +3480,23 @@ CERT_CheckOCSPStatus(CERTCertDBHandle *h
      * be checked -- that is, we consider it a success and just return.
      * The way we tell that is by looking at the error number to see if
      * the problem was no AIA extension was found; any other error was
      * a true failure that we unfortunately have to treat as an overall
      * failure here.
      */
     location = ocsp_GetResponderLocation(handle, cert, &locationIsDefault);
     if (location == NULL) {
-	if (PORT_GetError() == SEC_ERROR_EXTENSION_NOT_FOUND)
+	int err = PORT_GetError();
+	if (err == SEC_ERROR_EXTENSION_NOT_FOUND ||
+	    err == SEC_ERROR_CERT_BAD_ACCESS_LOCATION) {
+	    PORT_SetError(0);
 	    return SECSuccess;
-	else
-	    return SECFailure;
+	}
+	return SECFailure;
     }
 
     /*
      * For now, create a cert-list of one.
      * XXX In the fullness of time, we will want/need to handle a
      * certificate chain.  This will be done either when a new parameter
      * tells us to, or some configuration variable tells us to.  In any
      * case, handling it is complicated because we may need to send as
--- a/security/nss/lib/ckfw/builtins/binst.c
+++ b/security/nss/lib/ckfw/builtins/binst.c
@@ -96,16 +96,21 @@ builtins_mdInstance_GetLibraryDescriptio
 
 static CK_VERSION
 builtins_mdInstance_GetLibraryVersion
 (
   NSSCKMDInstance *mdInstance,
   NSSCKFWInstance *fwInstance
 )
 {
+  extern const char __nss_builtins_rcsid[];
+  extern const char __nss_builtins_sccsid[];
+  volatile char c; /* force a reference that won't get optimized away */
+
+  c = __nss_builtins_rcsid[0] + __nss_builtins_sccsid[0];
   return nss_builtins_LibraryVersion;
 }
 
 static CK_RV
 builtins_mdInstance_GetSlots
 (
   NSSCKMDInstance *mdInstance,
   NSSCKFWInstance *fwInstance,
--- a/security/nss/lib/ckfw/wrap.c
+++ b/security/nss/lib/ckfw/wrap.c
@@ -642,17 +642,18 @@ NSSCKFWC_GetTokenInfo
   }
 
   return CKR_OK;
 
  loser:
   switch( error ) {
   case CKR_DEVICE_REMOVED:
   case CKR_TOKEN_NOT_PRESENT:
-    (void)nssCKFWToken_Destroy(fwToken);
+    if (fwToken)
+      nssCKFWToken_Destroy(fwToken);
     break;
   case CKR_CRYPTOKI_NOT_INITIALIZED:
   case CKR_DEVICE_ERROR:
   case CKR_DEVICE_MEMORY:
   case CKR_FUNCTION_FAILED:
   case CKR_GENERAL_ERROR:
   case CKR_HOST_MEMORY:
   case CKR_SLOT_ID_INVALID:
@@ -836,17 +837,18 @@ NSSCKFWC_GetMechanismList
   if( CKR_OK == error ) {
     return CKR_OK;
   }
 
  loser:
   switch( error ) {
   case CKR_DEVICE_REMOVED:
   case CKR_TOKEN_NOT_PRESENT:
-    (void)nssCKFWToken_Destroy(fwToken);
+    if (fwToken)
+      nssCKFWToken_Destroy(fwToken);
     break;
   case CKR_BUFFER_TOO_SMALL:
   case CKR_CRYPTOKI_NOT_INITIALIZED:
   case CKR_DEVICE_ERROR:
   case CKR_DEVICE_MEMORY:
   case CKR_FUNCTION_FAILED:
   case CKR_GENERAL_ERROR:
   case CKR_HOST_MEMORY:
@@ -939,17 +941,18 @@ NSSCKFWC_GetMechanismInfo
   /* More here... */
 
   return CKR_OK;
 
  loser:
   switch( error ) {
   case CKR_DEVICE_REMOVED:
   case CKR_TOKEN_NOT_PRESENT:
-    (void)nssCKFWToken_Destroy(fwToken);
+    if (fwToken)
+      nssCKFWToken_Destroy(fwToken);
     break;
   case CKR_CRYPTOKI_NOT_INITIALIZED:
   case CKR_DEVICE_ERROR:
   case CKR_DEVICE_MEMORY:
   case CKR_FUNCTION_FAILED:
   case CKR_GENERAL_ERROR:
   case CKR_HOST_MEMORY:
   case CKR_MECHANISM_INVALID:
@@ -1029,17 +1032,18 @@ NSSCKFWC_InitToken
   }
 
   return CKR_OK;
 
  loser:
   switch( error ) {
   case CKR_DEVICE_REMOVED:
   case CKR_TOKEN_NOT_PRESENT:
-    (void)nssCKFWToken_Destroy(fwToken);
+    if (fwToken)
+      nssCKFWToken_Destroy(fwToken);
     break;
   case CKR_CRYPTOKI_NOT_INITIALIZED:
   case CKR_DEVICE_ERROR:
   case CKR_DEVICE_MEMORY:
   case CKR_FUNCTION_FAILED:
   case CKR_GENERAL_ERROR:
   case CKR_HOST_MEMORY:
   case CKR_PIN_INCORRECT:
--- a/security/nss/lib/crmf/challcli.c
+++ b/security/nss/lib/crmf/challcli.c
@@ -117,64 +117,49 @@ cmmf_get_owf(CMMFPOPODecKeyChallContent 
 
 SECStatus 
 CMMF_POPODecKeyChallContDecryptChallenge(CMMFPOPODecKeyChallContent *inChalCont,
 					 int                         inIndex,
 					 SECKEYPrivateKey           *inPrivKey)
 {
     CMMFChallenge  *challenge;
     SECItem        *decryptedRand=NULL;
+    PRArenaPool    *poolp  = NULL;
     SECAlgorithmID *owf;
-    PK11SlotInfo   *slot;
-    PK11SymKey     *symKey = NULL;
     SECStatus       rv     = SECFailure;
+    SECOidTag       tag;
     CMMFRand        randStr;
     SECItem         hashItem;
-    SECOidTag       tag;
     unsigned char   hash[HASH_LENGTH_MAX]; 
-    PRArenaPool    *poolp  = NULL;
 
     PORT_Assert(inChalCont != NULL && inPrivKey != NULL);
     if (inChalCont == NULL || inIndex <0 || inIndex > inChalCont->numChallenges
 	|| inPrivKey == NULL){
         return SECFailure;
     }
-    challenge = inChalCont->challenges[inIndex];
-    decryptedRand = PORT_ZNew(SECItem);
-    if (decryptedRand == NULL) {
-        goto loser;
-    }
-    decryptedRand->data = 
-        PORT_NewArray(unsigned char, challenge->challenge.len);
-    if (decryptedRand->data == NULL) {
-        goto loser;
-    }
-    slot = inPrivKey->pkcs11Slot;
-    symKey = PK11_PubUnwrapSymKey(inPrivKey, &challenge->challenge, 
-				  CKM_RSA_PKCS, CKA_VALUE, 0);
-    if (symKey == NULL) {
-      rv = SECFailure;
-      goto loser;
-    }
-    rv = PK11_ExtractKeyValue(symKey);
-    if (rv != SECSuccess) {
-      goto loser;
-    }
-    decryptedRand = PK11_GetKeyData(symKey);
 
     poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE);
     if (poolp == NULL) {
         goto loser;
     }
+
+    challenge = inChalCont->challenges[inIndex];
+    decryptedRand = SECITEM_AllocItem(poolp, NULL, challenge->challenge.len);
+    if (decryptedRand == NULL) {
+        goto loser;
+    }
+    rv = PK11_PrivDecryptPKCS1(inPrivKey, decryptedRand->data, 
+    			&decryptedRand->len, decryptedRand->len, 
+			challenge->challenge.data, challenge->challenge.len);
+    if (rv != SECSuccess) {
+        goto loser;
+    }
+
     rv = SEC_ASN1DecodeItem(poolp, &randStr, CMMFRandTemplate,
 			    decryptedRand); 
-    /* The decryptedRand returned points to a member within the symKey 
-     * structure, so we don't want to free it. Let the symKey destruction 
-     * function deal with freeing that memory.
-     */
     if (rv != SECSuccess) {
         goto loser;
     }
     rv = SECFailure; /* Just so that when we do go to loser,
 		      * I won't have to set it again.
 		      */
     owf = cmmf_get_owf(inChalCont, inIndex);
     if (owf == NULL) {
@@ -191,38 +176,37 @@ CMMF_POPODecKeyChallContDecryptChallenge
     if (rv != SECSuccess) {
         goto loser;
     }
     hashItem.data = hash;
     if (SECITEM_CompareItem(&hashItem, &challenge->witness) != SECEqual) {
         /* The hash for the data we decrypted doesn't match the hash provided
 	 * in the challenge.  Bail out.
 	 */
+	PORT_SetError(SEC_ERROR_BAD_DATA);
         rv = SECFailure;
 	goto loser;
     }
     rv = PK11_HashBuf(tag, hash, challenge->senderDER.data, 
 		      challenge->senderDER.len);
     if (rv != SECSuccess) {
         goto loser;
     }
     if (SECITEM_CompareItem(&hashItem, &randStr.senderHash) != SECEqual) {
         /* The hash for the data we decrypted doesn't match the hash provided
 	 * in the challenge.  Bail out.
 	 */
+	PORT_SetError(SEC_ERROR_BAD_DATA);
         rv = SECFailure;
 	goto loser;
     }
     /* All of the hashes have verified, so we can now store the integer away.*/
     rv = SECITEM_CopyItem(inChalCont->poolp, &challenge->randomNumber,
 			  &randStr.integer);
  loser:
-    if (symKey != NULL) {
-        PK11_FreeSymKey(symKey);
-    }
     if (poolp) {
     	PORT_FreeArena(poolp, PR_FALSE);
     }
     return rv;
 }
 
 SECStatus
 CMMF_POPODecKeyChallContentGetRandomNumber
@@ -270,17 +254,20 @@ CMMF_EncodePOPODecKeyRespContent(long   
     if (response->responses == NULL) {
         goto loser;
     }
     for (i=0; i<inNumRand; i++) {
         currItem = response->responses[i] = PORT_ArenaZNew(poolp,SECItem);
 	if (currItem == NULL) {
 	    goto loser;
 	}
-	SEC_ASN1EncodeInteger(poolp, currItem,inDecodedRand[i]);
+	currItem = SEC_ASN1EncodeInteger(poolp, currItem, inDecodedRand[i]);
+	if (currItem == NULL) {
+	    goto loser;
+	}
     }
     rv = cmmf_user_encode(response, inCallback, inArg,
 			  CMMFPOPODecKeyRespContentTemplate);
  loser:
     if (poolp != NULL) {
         PORT_FreeArena(poolp, PR_FALSE);
     }
     return rv;
--- a/security/nss/lib/crmf/crmfpop.c
+++ b/security/nss/lib/crmf/crmfpop.c
@@ -180,18 +180,18 @@ crmf_encode_certreq(CRMFCertRequest *inC
 
 static SECStatus
 crmf_sign_certreq(PRArenaPool        *poolp, 
 		  CRMFPOPOSigningKey *crmfSignKey, 
 		  CRMFCertRequest    *certReq,
 		  SECKEYPrivateKey   *inKey,
 		  SECAlgorithmID     *inAlgId)
 {
-    SECItem                      derCertReq;
-    SECItem                      certReqSig;
+    SECItem                      derCertReq = { siBuffer, NULL, 0 };
+    SECItem                      certReqSig = { siBuffer, NULL, 0 };
     SECStatus                    rv = SECSuccess;
 
     rv = crmf_encode_certreq(certReq, &derCertReq);
     if (rv != SECSuccess) {
        goto loser;
     }
     rv = SEC_SignData(&certReqSig, derCertReq.data, derCertReq.len,
 		      inKey,SECOID_GetAlgorithmTag(inAlgId));
--- a/security/nss/lib/freebl/Makefile
+++ b/security/nss/lib/freebl/Makefile
@@ -278,17 +278,17 @@ ifeq ($(CPU_ARCH),sparc)
 	    ARCHFLAG = -xarch=v8plus
 	    SOLARIS_AS_FLAGS = -xarch=v8plus -K PIC
 	endif
 	ifdef USE_ABI32_FPU
 	    # this builds for Sparc v8+a ABI32_FPU architecture, 64-bit registers, 
 	    # 32-bit ABI, it uses FPU code, and 32-bit word size.
 	    # these flags were determined by running cc -### -fast and copying
 	    # the generated flag settings
-	    SOL_CFLAGS += -D__MATHERR_ERRNO_DONTCARE -fns -fsimple=2 -fsingle
+	    SOL_CFLAGS += -D__MATHERR_ERRNO_DONTCARE -fns -fsimple=1 -fsingle
 	    SOL_CFLAGS += -xalias_level=basic -xbuiltin=%all
 	    SOL_CFLAGS += $(FPU_TARGET_OPTIMIZER) -xdepend
 	    SOL_CFLAGS += -xlibmil -xmemalign=8s -xO5
 	    ARCHFLAG = -xarch=v8plusa
 	    SOLARIS_AS_FLAGS = -xarch=v8plusa -K PIC
 	endif
 	ifdef USE_ABI64_INT
 	    # this builds for Sparc v9a pure 64-bit architecture,
@@ -296,17 +296,17 @@ ifeq ($(CPU_ARCH),sparc)
  	    SOL_CFLAGS += -xO4 -xtarget=generic
 	    ARCHFLAG = -xarch=v9
 	    SOLARIS_AS_FLAGS = -xarch=v9 -K PIC
 	endif
 	ifdef USE_ABI64_FPU
 	    # this builds for Sparc v9a pure 64-bit architecture
 	    # It uses floating point, and 32-bit word size.
 	    # See comment for USE_ABI32_FPU.
-	    SOL_CFLAGS += -D__MATHERR_ERRNO_DONTCARE -fns -fsimple=2 -fsingle
+	    SOL_CFLAGS += -D__MATHERR_ERRNO_DONTCARE -fns -fsimple=1 -fsingle
 	    SOL_CFLAGS += -xalias_level=basic -xbuiltin=%all
 	    SOL_CFLAGS += $(FPU_TARGET_OPTIMIZER) -xdepend
 	    SOL_CFLAGS += -xlibmil -xmemalign=8s -xO5
 	    ARCHFLAG = -xarch=v9a
 	    SOLARIS_AS_FLAGS = -xarch=v9a -K PIC
 	endif
     endif # NS_USE_GCC
 
--- a/security/nss/lib/nss/nss.h
+++ b/security/nss/lib/nss/nss.h
@@ -48,23 +48,23 @@ SEC_BEGIN_PROTOS
 /*
  * NSS's major version, minor version, patch level, and whether
  * this is a beta release.
  *
  * The format of the version string should be
  *     "<major version>.<minor version>[.<patch level>] [<Beta>]"
  */
 #ifdef NSS_ENABLE_ECC
-#define NSS_VERSION  "3.11.2 ECC Beta"
+#define NSS_VERSION  "3.11.3 ECC Beta"
 #else
-#define NSS_VERSION  "3.11.2 Beta"
+#define NSS_VERSION  "3.11.3 Beta"
 #endif
 #define NSS_VMAJOR   3
 #define NSS_VMINOR   11
-#define NSS_VPATCH   2
+#define NSS_VPATCH   3
 #define NSS_BETA     PR_TRUE
 
 /*
  * Return a boolean that indicates whether the underlying library
  * will perform as the caller expects.
  *
  * The only argument is a string, which should be the verson
  * identifier of the NSS library. That string will be compared
--- a/security/nss/lib/pk11wrap/pk11cert.c
+++ b/security/nss/lib/pk11wrap/pk11cert.c
@@ -697,17 +697,40 @@ PK11_FindCertsFromNickname(char *nicknam
 	instances = nssToken_FindCertificatesByNickname(token,
 	                                                NULL,
 	                                                nickname,
 	                                                tokenOnly,
 	                                                0,
 	                                                &status);
 	nssPKIObjectCollection_AddInstances(collection, instances, 0);
 	nss_ZFreeIf(instances);
-	nssList_Destroy(nameList);
+
+        /* if it wasn't found, repeat the process for email address */
+        if (nssPKIObjectCollection_Count(collection) == 0 &&
+            PORT_Strchr(nickname, '@') != NULL) 
+        {
+            char* lowercaseName = CERT_FixupEmailAddr(nickname);
+            if (lowercaseName) {
+                (void)nssTrustDomain_GetCertsForEmailAddressFromCache(defaultTD, 
+                                                                      lowercaseName, 
+                                                                      nameList);
+                transfer_token_certs_to_collection(nameList, token, collection);
+                instances = nssToken_FindCertificatesByEmail(token,
+                                                             NULL,
+                                                             lowercaseName,
+                                                             tokenOnly,
+                                                             0,
+                                                             &status);
+                nssPKIObjectCollection_AddInstances(collection, instances, 0);
+                nss_ZFreeIf(instances);
+                PORT_Free(lowercaseName);
+            }
+        }
+
+        nssList_Destroy(nameList);
 	foundCerts = nssPKIObjectCollection_GetCertificates(collection,
 	                                                    NULL, 0, NULL);
 	nssPKIObjectCollection_Destroy(collection);
     }
     if (slot) {
 	PK11_FreeSlot(slot);
     }
     if (nickCopy) PORT_Free(nickCopy);
--- a/security/nss/lib/pk11wrap/pk11mech.c
+++ b/security/nss/lib/pk11wrap/pk11mech.c
@@ -818,26 +818,26 @@ PK11_ParamFromIV(CK_MECHANISM_TYPE type,
 	param->data = (unsigned char *) rc2_params;
 	param->len = sizeof(CK_RC2_CBC_PARAMS);
 	break;
     case CKM_RC5_CBC:
     case CKM_RC5_CBC_PAD:
 	rc5_cbc_params = (CK_RC5_CBC_PARAMS *)
 		PORT_Alloc(sizeof(CK_RC5_CBC_PARAMS) + ((iv) ? iv->len : 0));
 	if (rc5_cbc_params == NULL) break;
-	if (iv && iv->data) {
+	if (iv && iv->data && iv->len) {
 	    rc5_cbc_params->pIv = ((CK_BYTE_PTR) rc5_cbc_params) 
 						+ sizeof(CK_RC5_CBC_PARAMS);
 	    PORT_Memcpy(rc5_cbc_params->pIv,iv->data,iv->len);
 	    rc5_cbc_params->ulIvLen = iv->len;
 	    rc5_cbc_params->ulWordsize = iv->len/2;
 	} else {
 	    rc5_cbc_params->ulWordsize = 4;
 	    rc5_cbc_params->pIv = NULL;
-	    rc5_cbc_params->ulIvLen = iv->len;
+	    rc5_cbc_params->ulIvLen = 0;
 	}
 	rc5_cbc_params->ulRounds = 16;
 	param->data = (unsigned char *) rc5_cbc_params;
 	param->len = sizeof(CK_RC5_CBC_PARAMS);
 	break;
     case CKM_RC5_ECB:
 	rc5_params = (CK_RC5_PARAMS *)PORT_Alloc(sizeof(CK_RC5_PARAMS));
 	if (rc5_params == NULL) break;
--- a/security/nss/lib/pk11wrap/pk11pbe.c
+++ b/security/nss/lib/pk11wrap/pk11pbe.c
@@ -699,52 +699,71 @@ RSA_FormatBlock(SECItem *result, unsigne
  *
  ****************************************************************************/
 
 static void
 pk11_destroy_ck_pbe_params(CK_PBE_PARAMS *pbe_params)
 {
     if (pbe_params) {
 	if (pbe_params->pPassword)
-	    PORT_ZFree(pbe_params->pPassword, PR_FALSE);
+	    PORT_ZFree(pbe_params->pPassword, pbe_params->ulPasswordLen);
 	if (pbe_params->pSalt)
-	    PORT_ZFree(pbe_params->pSalt, PR_FALSE);
-	PORT_ZFree(pbe_params, PR_TRUE);
+	    PORT_ZFree(pbe_params->pSalt, pbe_params->ulSaltLen);
+	PORT_ZFree(pbe_params, sizeof(CK_PBE_PARAMS));
     }
 }
 
 SECItem * 
 PK11_CreatePBEParams(SECItem *salt, SECItem *pwd, unsigned int iterations)
 {
     CK_PBE_PARAMS *pbe_params = NULL;
     SECItem *paramRV = NULL;
-    pbe_params = (CK_PBE_PARAMS *)PORT_ZAlloc(sizeof(CK_PBE_PARAMS));
+
+    paramRV = SECITEM_AllocItem(NULL, NULL, sizeof(CK_PBE_PARAMS));
+    if (!paramRV ) {
+	goto loser;
+    }
+    /* init paramRV->data with zeros. SECITEM_AllocItem does not do it */
+    PORT_Memset(paramRV->data, 0, sizeof(CK_PBE_PARAMS));
+
+    pbe_params = (CK_PBE_PARAMS *)paramRV->data;
     pbe_params->pPassword = (CK_CHAR_PTR)PORT_ZAlloc(pwd->len);
-    if (pbe_params->pPassword != NULL) {
-	PORT_Memcpy(pbe_params->pPassword, pwd->data, pwd->len);
-	pbe_params->ulPasswordLen = pwd->len;
-    } else goto loser;
+    if (!pbe_params->pPassword) {
+        goto loser;
+    }
+    PORT_Memcpy(pbe_params->pPassword, pwd->data, pwd->len);
+    pbe_params->ulPasswordLen = pwd->len;
+
     pbe_params->pSalt = (CK_CHAR_PTR)PORT_ZAlloc(salt->len);
-    if (pbe_params->pSalt != NULL) {
-	PORT_Memcpy(pbe_params->pSalt, salt->data, salt->len);
-	pbe_params->ulSaltLen = salt->len;
-    } else goto loser;
+    if (!pbe_params->pSalt) {
+	goto loser;
+    }
+    PORT_Memcpy(pbe_params->pSalt, salt->data, salt->len);
+    pbe_params->ulSaltLen = salt->len;
+
     pbe_params->ulIteration = (CK_ULONG)iterations;
-    paramRV = SECITEM_AllocItem(NULL, NULL, sizeof(CK_PBE_PARAMS));
-    paramRV->data = (unsigned char *)pbe_params;
     return paramRV;
+
 loser:
-    pk11_destroy_ck_pbe_params(pbe_params);
+    if (pbe_params)
+        pk11_destroy_ck_pbe_params(pbe_params);
+    if (paramRV) 
+    	PORT_ZFree(paramRV, sizeof(SECItem));
     return NULL;
 }
 
 void
-PK11_DestroyPBEParams(SECItem *params)
+PK11_DestroyPBEParams(SECItem *pItem)
 {
-    pk11_destroy_ck_pbe_params((CK_PBE_PARAMS *)params->data);
+    if (pItem) {
+	CK_PBE_PARAMS * params = (CK_PBE_PARAMS *)(pItem->data);
+	if (params)
+	    pk11_destroy_ck_pbe_params(params);
+	PORT_ZFree(pItem, sizeof(SECItem));
+    }
 }
 
 SECAlgorithmID *
 PK11_CreatePBEAlgorithmID(SECOidTag algorithm, int iteration, SECItem *salt)
 {
     SECAlgorithmID *algid = NULL;
     algid = SEC_PKCS5CreateAlgorithmID(algorithm, salt, iteration);
     return algid;
@@ -761,16 +780,19 @@ PK11_RawPBEKeyGen(PK11SlotInfo *slot, CK
     if(faulty3DES && (type == CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC)) {
 	type = CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC;
     }
     if(mech == NULL) {
 	return NULL;
     }
 
     pbe_params = (CK_PBE_PARAMS *)mech->data;
+    if (!pbe_params) {
+	return NULL;
+    }
     pbe_params->pPassword = (CK_CHAR_PTR)PORT_ZAlloc(pwitem->len);
     if(pbe_params->pPassword != NULL) {
 	PORT_Memcpy(pbe_params->pPassword, pwitem->data, pwitem->len);
 	pbe_params->ulPasswordLen = pwitem->len;
     } else {
 	SECITEM_ZfreeItem(mech, PR_TRUE);
 	return NULL;
     }
--- a/security/nss/lib/pki/pki3hack.c
+++ b/security/nss/lib/pki/pki3hack.c
@@ -141,36 +141,43 @@ STAN_LoadDefaultNSS3TrustDomain (
     if (!td) {
 	return PR_FAILURE;
     }
     /*
      * Deadlock warning: we should never acquire the moduleLock while
      * we hold the tokensLock. We can use the NSSRWLock Rank feature to
      * guarrentee this. tokensLock have a higher rank than module lock.
      */
-    SECMOD_GetReadLock(moduleLock);
-    NSSRWLock_LockWrite(td->tokensLock);
     td->tokenList = nssList_Create(td->arena, PR_TRUE);
     if (!td->tokenList) {
-	NSSRWLock_UnlockWrite(td->tokensLock);
-	SECMOD_ReleaseReadLock(moduleLock);
-	NSSTrustDomain_Destroy(td);
-	return PR_FAILURE;
+	goto loser;
     }
+    SECMOD_GetReadLock(moduleLock);
+    NSSRWLock_LockWrite(td->tokensLock);
     for (mlp = SECMOD_GetDefaultModuleList(); mlp != NULL; mlp=mlp->next) {
 	for (i=0; i < mlp->module->slotCount; i++) {
 	    STAN_InitTokenForSlotInfo(td, mlp->module->slots[i]);
 	}
     }
     td->tokens = nssList_CreateIterator(td->tokenList);
     NSSRWLock_UnlockWrite(td->tokensLock);
     SECMOD_ReleaseReadLock(moduleLock);
-    g_default_trust_domain = td;
+    if (!td->tokens) {
+	goto loser;
+    }
     g_default_crypto_context = NSSTrustDomain_CreateCryptoContext(td, NULL);
+    if (!g_default_crypto_context) {
+	goto loser;
+    }
+    g_default_trust_domain = td;
     return PR_SUCCESS;
+
+  loser:
+    NSSTrustDomain_Destroy(td);
+    return PR_FAILURE;
 }
 
 /*
  * must be called holding the ModuleListLock (either read or write).
  */
 NSS_IMPLEMENT SECStatus
 STAN_AddModuleToDefaultTrustDomain (
   SECMODModule *module
--- a/security/nss/lib/pki/trustdomain.c
+++ b/security/nss/lib/pki/trustdomain.c
@@ -129,20 +129,25 @@ NSSTrustDomain_Destroy (
   NSSTrustDomain *td
 )
 {
     PRStatus status = PR_SUCCESS;
     if (--td->refCount == 0) {
 	/* Destroy each token in the list of tokens */
 	if (td->tokens) {
 	    nssListIterator_Destroy(td->tokens);
+	    td->tokens = NULL;
+	}
+	if (td->tokenList) {
 	    nssList_Clear(td->tokenList, token_destructor);
 	    nssList_Destroy(td->tokenList);
+	    td->tokenList = NULL;
 	}
 	NSSRWLock_Destroy(td->tokensLock);
+	td->tokensLock = NULL;
 	status = nssTrustDomain_DestroyCache(td);
 	if (status == PR_FAILURE) {
 	    return status;
 	}
 	/* Destroy the trust domain */
 	nssArena_Destroy(td->arena);
     }
     return status;
--- a/security/nss/lib/smime/cmscipher.c
+++ b/security/nss/lib/smime/cmscipher.c
@@ -219,18 +219,19 @@ NSS_CMSCipherContext_StartEncrypt(PRAren
     } else {
 	mechanism = PK11_AlgtagToMechanism(algtag);
 	if ((param = PK11_GenerateNewParam(mechanism, key)) == NULL)
 	    return NULL;
 	needToEncodeAlgid = PR_TRUE;
     }
 
     cc = (NSSCMSCipherContext *)PORT_ZAlloc(sizeof(NSSCMSCipherContext));
-    if (cc == NULL)
-	return NULL;
+    if (cc == NULL) {
+	goto loser;
+    }
 
     /* now find pad and block sizes for our mechanism */
     cc->pad_size = PK11_GetBlockSize(mechanism,param);
     slot = PK11_GetSlotFromKey(key);
     cc->block_size = PK11_IsHW(slot) ? BLOCK_SIZE : cc->pad_size;
     PK11_FreeSlot(slot);
 
     /* and here we go, creating a PK11 cipher context */
--- a/security/nss/lib/smime/cmsrecinfo.c
+++ b/security/nss/lib/smime/cmsrecinfo.c
@@ -182,34 +182,16 @@ nss_cmsrecipientinfo_create(NSSCMSMessag
 		PORT_SetError(SEC_ERROR_NO_MEMORY);
 		break;
 	    }
 	} else {
 	    PORT_SetError(SEC_ERROR_INVALID_ARGS);
 	    rv = SECFailure;
 	}
 	break;
-    case SEC_OID_MISSI_KEA_DSS_OLD:
-    case SEC_OID_MISSI_KEA_DSS:
-    case SEC_OID_MISSI_KEA:
-	PORT_Assert(type == NSSCMSRecipientID_IssuerSN);
-	if (type != NSSCMSRecipientID_IssuerSN) {
-	    rv = SECFailure;
-	    break;
-	}
-	/* backward compatibility - this is not really a keytrans operation */
-	ri->recipientInfoType = NSSCMSRecipientInfoID_KeyTrans;
-	/* hardcoded issuerSN choice for now */
-	ri->ri.keyTransRecipientInfo.recipientIdentifier.identifierType = NSSCMSRecipientID_IssuerSN;
-	ri->ri.keyTransRecipientInfo.recipientIdentifier.id.issuerAndSN = CERT_GetCertIssuerAndSN(poolp, cert);
-	if (ri->ri.keyTransRecipientInfo.recipientIdentifier.id.issuerAndSN == NULL) {
-	    rv = SECFailure;
-	    break;
-	}
-	break;
     case SEC_OID_X942_DIFFIE_HELMAN_KEY: /* dh-public-number */
 	PORT_Assert(type == NSSCMSRecipientID_IssuerSN);
 	if (type != NSSCMSRecipientID_IssuerSN) {
 	    rv = SECFailure;
 	    break;
 	}
 	/* a key agreement op */
 	ri->recipientInfoType = NSSCMSRecipientInfoID_KeyAgree;
@@ -525,30 +507,16 @@ NSS_CMSRecipientInfo_WrapBulkKey(NSSCMSR
 	    rv = NSS_CMSUtil_EncryptSymKey_RSAPubKey(poolp, extra->pubKey,
 	                         bulkkey, &ri->ri.keyTransRecipientInfo.encKey);
  	    if (rv != SECSuccess)
 		break;
 	}
 
 	rv = SECOID_SetAlgorithmID(poolp, &(ri->ri.keyTransRecipientInfo.keyEncAlg), certalgtag, NULL);
 	break;
-    case SEC_OID_MISSI_KEA_DSS_OLD:
-    case SEC_OID_MISSI_KEA_DSS:
-    case SEC_OID_MISSI_KEA:
-	rv = NSS_CMSUtil_EncryptSymKey_MISSI(poolp, cert, bulkkey,
-					bulkalgtag,
-					&ri->ri.keyTransRecipientInfo.encKey,
-					&params, ri->cmsg->pwfn_arg);
-	if (rv != SECSuccess)
-	    break;
-
-	/* here, we DO need to pass the params to the wrap function because, with
-	 * RSA, there is no funny stuff going on with generation of IV vectors or so */
-	rv = SECOID_SetAlgorithmID(poolp, &(ri->ri.keyTransRecipientInfo.keyEncAlg), certalgtag, params);
-	break;
     case SEC_OID_X942_DIFFIE_HELMAN_KEY: /* dh-public-number */
 	rek = ri->ri.keyAgreeRecipientInfo.recipientEncryptedKeys[0];
 	if (rek == NULL) {
 	    rv = SECFailure;
 	    break;
 	}
 
 	oiok = &(ri->ri.keyAgreeRecipientInfo.originatorIdentifierOrKey);
--- a/security/nss/lib/smime/cmsreclist.c
+++ b/security/nss/lib/smime/cmsreclist.c
@@ -61,50 +61,58 @@ nss_cms_recipients_traverse(NSSCMSRecipi
     NSSCMSRecipientInfo *ri;
     NSSCMSRecipientEncryptedKey *rek;
 
     for (i = 0; recipientinfos[i] != NULL; i++) {
 	ri = recipientinfos[i];
 	switch (ri->recipientInfoType) {
 	case NSSCMSRecipientInfoID_KeyTrans:
 	    if (recipient_list) {
+		NSSCMSRecipientIdentifier *recipId =
+		   &ri->ri.keyTransRecipientInfo.recipientIdentifier;
+
+		if (recipId->identifierType != NSSCMSRecipientID_IssuerSN &&
+                    recipId->identifierType != NSSCMSRecipientID_SubjectKeyID) {
+		    PORT_SetError(SEC_ERROR_INVALID_ARGS);
+		    return -1;
+		}                
 		/* alloc one & fill it out */
 		rle = (NSSCMSRecipient *)PORT_ZAlloc(sizeof(NSSCMSRecipient));
-		if (rle == NULL)
+		if (!rle)
 		    return -1;
 		
 		rle->riIndex = i;
 		rle->subIndex = -1;
-		switch (ri->ri.keyTransRecipientInfo.recipientIdentifier.identifierType) {
+		switch (recipId->identifierType) {
 		case NSSCMSRecipientID_IssuerSN:
 		    rle->kind = RLIssuerSN;
-		    rle->id.issuerAndSN = ri->ri.keyTransRecipientInfo.recipientIdentifier.id.issuerAndSN;
+		    rle->id.issuerAndSN = recipId->id.issuerAndSN;
 		    break;
 		case NSSCMSRecipientID_SubjectKeyID:
 		    rle->kind = RLSubjKeyID;
-		    rle->id.subjectKeyID = ri->ri.keyTransRecipientInfo.recipientIdentifier.id.subjectKeyID;
+		    rle->id.subjectKeyID = recipId->id.subjectKeyID;
 		    break;
-		default:
-		    PORT_SetError(SEC_ERROR_INVALID_ARGS);
-		    return -1;
+		default: /* we never get here because of identifierType check
+                            we done before. Leaving it to kill compiler warning */
+		    break;
 		}
 		recipient_list[rlindex++] = rle;
 	    } else {
 		count++;
 	    }
 	    break;
 	case NSSCMSRecipientInfoID_KeyAgree:
 	    if (ri->ri.keyAgreeRecipientInfo.recipientEncryptedKeys == NULL)
 		break;
 	    for (j=0; ri->ri.keyAgreeRecipientInfo.recipientEncryptedKeys[j] != NULL; j++) {
 		if (recipient_list) {
 		    rek = ri->ri.keyAgreeRecipientInfo.recipientEncryptedKeys[j];
 		    /* alloc one & fill it out */
 		    rle = (NSSCMSRecipient *)PORT_ZAlloc(sizeof(NSSCMSRecipient));
-		    if (rle == NULL)
+		    if (!rle)
 			return -1;
 		    
 		    rle->riIndex = i;
 		    rle->subIndex = j;
 		    switch (rek->recipientIdentifier.identifierType) {
 		    case NSSCMSKeyAgreeRecipientID_IssuerSN:
 			rle->kind = RLIssuerSN;
 			rle->id.issuerAndSN = rek->recipientIdentifier.id.issuerAndSN;
--- a/security/nss/lib/softoken/fipstest.c
+++ b/security/nss/lib/softoken/fipstest.c
@@ -112,16 +112,19 @@ EC_CopyParams(PRArenaPool *arena, ECPara
 /* FIPS preprocessor directives for DSA.                        */
 #define FIPS_DSA_TYPE                           siBuffer
 #define FIPS_DSA_DIGEST_LENGTH                  20  /* 160-bits */
 #define FIPS_DSA_SUBPRIME_LENGTH                20  /* 160-bits */
 #define FIPS_DSA_SIGNATURE_LENGTH               40  /* 320-bits */
 #define FIPS_DSA_PRIME_LENGTH                   64  /* 512-bits */
 #define FIPS_DSA_BASE_LENGTH                    64  /* 512-bits */
 
+/* FIPS preprocessor directives for RNG.                        */
+#define FIPS_RNG_XKEY_LENGTH                    32  /* 512-bits */
+
 static CK_RV
 sftk_fips_RC2_PowerUpSelfTest( void )
 {
     /* RC2 Known Key (40-bits). */
     static const PRUint8 rc2_known_key[] = { "RSARC" };
 
     /* RC2-CBC Known Initialization Vector (64-bits). */
     static const PRUint8 rc2_cbc_known_initialization_vector[] = {"Security"};
@@ -1762,16 +1765,76 @@ sftk_fips_DSA_PowerUpSelfTest( void )
     if( dsa_status != SECSuccess )
         return( CKR_DEVICE_ERROR );
 
     return( CKR_OK );
 
 
 }
 
+static CK_RV
+sftk_fips_RNG_PowerUpSelfTest( void )
+{
+   static const PRUint8 XKeyValue[] = {
+                     0x8d,0xf2,0xa4,0x94,0x49,0x22,0x76,0xaa,
+                     0x3d,0x25,0x75,0x9b,0xb0,0x68,0x69,0xcb,
+                     0xea,0xc0,0xd8,0x3a,0xfb,0x8d,0x0c,0xf7,
+                     0xcb,0xb8,0x32,0x4f,0x0d,0x78,0x82,0xe5};
+   static const PRUint8 XSeed[] = {
+                     0xea,0xc0,0xd8,0x3a,0xfb,0x8d,0x0c,0xf7,
+                     0xcb,0xb8,0x32,0x4f,0x0d,0x78,0x82,0xe5,
+                     0xd0,0x76,0x2f,0xc5,0xb7,0x21,0x0e,0xaf,
+                     0xc2,0xe9,0xad,0xac,0x32,0xab,0x7a,0xac};
+   static const PRUint8 Q[] = {   
+                     0x85,0x89,0x9c,0x77,0xa3,0x79,0xff,0x1a,
+                     0x86,0x6f,0x2f,0x3e,0x2e,0xf9,0x8c,0x9c,
+                     0x9d,0xef,0xeb,0xed};
+   static const PRUint8 rng_known_GENX[] = {
+                     0x65,0x48,0xe3,0xca,0xac,0x64,0x2d,0xf7,
+                     0x7b,0xd3,0x4e,0x79,0xc9,0x7d,0xa6,0xa8,
+                     0xa2,0xc2,0x1f,0x8f,0xe9,0xb9,0xd3,0xa1,
+                     0x3f,0xf7,0x0c,0xcd,0xa6,0xca,0xbf,0xce,
+                     0x84,0x0e,0xb6,0xf1,0x0d,0xbe,0xa9,0xa3};
+   static const PRUint8 rng_known_DSAX[] = {
+                     0x7a,0x86,0xf1,0x7f,0xbd,0x4e,0x6e,0xd9,
+                     0x0a,0x26,0x21,0xd0,0x19,0xcb,0x86,0x73,
+                     0x10,0x1f,0x60,0xd7};
+
+   SECStatus rng_status = SECSuccess;
+   PRUint8 GENX[2*SHA1_LENGTH];
+   PRUint8 DSAX[FIPS_DSA_SUBPRIME_LENGTH];
+   PRUint8 XKey[FIPS_RNG_XKEY_LENGTH];
+  
+   PORT_Memcpy (XKey, XKeyValue, FIPS_RNG_XKEY_LENGTH);
+   
+   /*******************************************/
+   /* Generate X with a known seed.           */
+   /*******************************************/
+   rng_status = FIPS186Change_GenerateX(XKey, XSeed, GENX);
+
+   /* Verify GENX to perform the RNG integrity check */
+   if( ( rng_status != SECSuccess ) ||
+       ( PORT_Memcmp( GENX, rng_known_GENX,
+                      (2*SHA1_LENGTH) ) != 0 ) )
+       return( CKR_DEVICE_ERROR );
+
+   /*******************************************/
+   /* Generate DSAX fow given Q.              */
+   /*******************************************/
+
+   rng_status = FIPS186Change_ReduceModQForDSA(GENX, Q, DSAX);
+
+   /* Verify DSAX to perform the RNG integrity check */
+   if( ( rng_status != SECSuccess ) ||
+       ( PORT_Memcmp( DSAX, rng_known_DSAX,
+                      (FIPS_DSA_SUBPRIME_LENGTH) ) != 0 ) )
+       return( CKR_DEVICE_ERROR );
+       
+   return( CKR_OK ); 
+}
 
 CK_RV
 sftk_fipsPowerUpSelfTest( void )
 {
     CK_RV rv;
 
     /* RC2 Power-Up SelfTest(s). */
     rv = sftk_fips_RC2_PowerUpSelfTest();
@@ -1845,16 +1908,22 @@ sftk_fipsPowerUpSelfTest( void )
     if( rv != CKR_OK )
         return rv;
 
     /* DSA Power-Up SelfTest(s). */
     rv = sftk_fips_DSA_PowerUpSelfTest();
 
     if( rv != CKR_OK )
         return rv;
+
+    /* RNG Power-Up SelfTest(s). */
+    rv = sftk_fips_RNG_PowerUpSelfTest();
+
+    if( rv != CKR_OK )
+        return rv;
     
 #ifdef NSS_ENABLE_ECC
     /* ECDSA Power-Up SelfTest(s). */
     rv = sftk_fips_ECDSA_PowerUpSelfTest();
 
     if( rv != CKR_OK )
         return rv;
 #endif
--- a/security/nss/lib/softoken/fipstokn.c
+++ b/security/nss/lib/softoken/fipstokn.c
@@ -101,17 +101,17 @@ libaudit_init(void)
 }
 #endif /* LINUX */
 
 
 /*
  * ******************** Password Utilities *******************************
  */
 static PRBool isLoggedIn = PR_FALSE;
-static PRBool fatalError = PR_FALSE;
+PRBool sftk_fatalError = PR_FALSE;
 
 /*
  * This function returns
  *   - CKR_PIN_INVALID if the password/PIN is not a legal UTF8 string
  *   - CKR_PIN_LEN_RANGE if the password/PIN is too short or does not
  *     consist of characters from three or more character classes.
  *   - CKR_OK otherwise
  *
@@ -199,30 +199,30 @@ static CK_RV sftk_newPinCheck(CK_CHAR_PT
 	return CKR_PIN_LEN_RANGE;
     }
     return CKR_OK;
 }
 
 
 /* FIPS required checks before any useful cryptographic services */
 static CK_RV sftk_fipsCheck(void) {
-    if (isLoggedIn != PR_TRUE) 
+    if (sftk_fatalError) 
+	return CKR_DEVICE_ERROR;
+    if (!isLoggedIn) 
 	return CKR_USER_NOT_LOGGED_IN;
-    if (fatalError) 
-	return CKR_DEVICE_ERROR;
     return CKR_OK;
 }
 
 
 #define SFTK_FIPSCHECK() \
     CK_RV rv; \
     if ((rv = sftk_fipsCheck()) != CKR_OK) return rv;
 
 #define SFTK_FIPSFATALCHECK() \
-    if (fatalError) return CKR_DEVICE_ERROR;
+    if (sftk_fatalError) return CKR_DEVICE_ERROR;
 
 
 /* grab an attribute out of a raw template */
 void *
 fc_getAttribute(CK_ATTRIBUTE_PTR pTemplate, 
 				CK_ULONG ulCount, CK_ATTRIBUTE_TYPE type)
 {
     int i;
@@ -419,26 +419,26 @@ CK_RV FC_Initialize(CK_VOID_PTR pReserve
     if ((envp = PR_GetEnv("NSS_ENABLE_AUDIT")) != NULL) {
 	sftk_audit_enabled = (atoi(envp) == 1);
     }
 
     crv = nsc_CommonInitialize(pReserved, PR_TRUE);
 
     /* not an 'else' rv can be set by either SFTK_LowInit or SFTK_SlotInit*/
     if (crv != CKR_OK) {
-	fatalError = PR_TRUE;
+	sftk_fatalError = PR_TRUE;
 	return crv;
     }
 
-    fatalError = PR_FALSE; /* any error has been reset */
+    sftk_fatalError = PR_FALSE; /* any error has been reset */
 
     crv = sftk_fipsPowerUpSelfTest();
     if (crv != CKR_OK) {
         nsc_CommonFinalize(NULL, PR_TRUE);
-	fatalError = PR_TRUE;
+	sftk_fatalError = PR_TRUE;
 	if (sftk_audit_enabled) {
 	    char msg[128];
 	    PR_snprintf(msg,sizeof msg,
 			"C_Initialize()=0x%08lX "
 			"self-test: cryptographic algorithm test failed",
 			(PRUint32)crv);
 	    sftk_LogAuditMessage(NSS_AUDIT_ERROR, msg);
 	}
@@ -531,17 +531,17 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, 
     return crv;
 }
 
 
 /* FC_InitPIN initializes the normal user's PIN. */
  CK_RV FC_InitPIN(CK_SESSION_HANDLE hSession,
     					CK_CHAR_PTR pPin, CK_ULONG ulPinLen) {
     CK_RV rv;
-    if (fatalError) return CKR_DEVICE_ERROR;
+    if (sftk_fatalError) return CKR_DEVICE_ERROR;
     if ((rv = sftk_newPinCheck(pPin,ulPinLen)) == CKR_OK) {
 	rv = NSC_InitPIN(hSession,pPin,ulPinLen);
     }
     if (sftk_audit_enabled) {
 	char msg[128];
 	NSSAuditSeverity severity = (rv == CKR_OK) ?
 		NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
 	PR_snprintf(msg,sizeof msg,
@@ -611,35 +611,35 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, 
     }
     return rv;
 }
 
 /* FC_Login logs a user into a token. */
  CK_RV FC_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType,
 				    CK_CHAR_PTR pPin, CK_ULONG usPinLen) {
     CK_RV rv;
-    if (fatalError) return CKR_DEVICE_ERROR;
+    if (sftk_fatalError) return CKR_DEVICE_ERROR;
     rv = NSC_Login(hSession,userType,pPin,usPinLen);
     if (rv == CKR_OK)
 	isLoggedIn = PR_TRUE;
     else if (rv == CKR_USER_ALREADY_LOGGED_IN)
     {
 	isLoggedIn = PR_TRUE;
 
 	/* Provide FIPS PUB 140-2 power-up self-tests on demand. */
 	rv = sftk_fipsPowerUpSelfTest();
 	if (rv == CKR_OK)
 		rv = CKR_USER_ALREADY_LOGGED_IN;
 	else
-		fatalError = PR_TRUE;
+		sftk_fatalError = PR_TRUE;
     }
     if (sftk_audit_enabled) {
 	char msg[128];
 	NSSAuditSeverity severity;
-	if (fatalError) {
+	if (sftk_fatalError) {
 	    severity = NSS_AUDIT_ERROR;
 	    PR_snprintf(msg,sizeof msg,
 			"C_Login(hSession=%lu, userType=%lu)=0x%08lX ",
 			"self-test: cryptographic algorithm test failed",
 			(PRUint32)hSession,(PRUint32)userType,(PRUint32)rv);
 	} else {
 	    severity = (rv == CKR_OK || rv == CKR_USER_ALREADY_LOGGED_IN) ?
 			NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
@@ -1102,17 +1102,17 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, 
 	    return CKR_ATTRIBUTE_VALUE_INVALID;
 	}
     }
     crv = NSC_GenerateKeyPair (hSession,pMechanism,pPublicKeyTemplate,
     		usPublicKeyAttributeCount,pPrivateKeyTemplate,
 		usPrivateKeyAttributeCount,phPublicKey,phPrivateKey);
     if (crv == CKR_GENERAL_ERROR) {
 	/* pairwise consistency check failed. */
-	fatalError = PR_TRUE;
+	sftk_fatalError = PR_TRUE;
     }
     return crv;
 }
 
 
 /* FC_WrapKey wraps (i.e., encrypts) a key. */
  CK_RV FC_WrapKey(CK_SESSION_HANDLE hSession,
     CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hWrappingKey,
@@ -1178,31 +1178,31 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, 
  * generator. */
  CK_RV FC_SeedRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed,
     CK_ULONG usSeedLen) {
     CK_RV crv;
 
     SFTK_FIPSFATALCHECK();
     crv = NSC_SeedRandom(hSession,pSeed,usSeedLen);
     if (crv != CKR_OK) {
-	fatalError = PR_TRUE;
+	sftk_fatalError = PR_TRUE;
     }
     return crv;
 }
 
 
 /* FC_GenerateRandom generates random data. */
  CK_RV FC_GenerateRandom(CK_SESSION_HANDLE hSession,
     CK_BYTE_PTR	pRandomData, CK_ULONG ulRandomLen) {
     CK_RV crv;
 
     SFTK_FIPSFATALCHECK();
     crv = NSC_GenerateRandom(hSession,pRandomData,ulRandomLen);
     if (crv != CKR_OK) {
-	fatalError = PR_TRUE;
+	sftk_fatalError = PR_TRUE;
 	if (sftk_audit_enabled) {
 	    char msg[128];
 	    PR_snprintf(msg,sizeof msg,
 			"C_GenerateRandom(hSession=%lu, pRandomData=%p, "
 			"ulRandomLen=%lu)=0x%08lX "
 			"self-test: continuous RNG test failed",
 			(PRUint32)hSession,pRandomData,
 			(PRUint32)ulRandomLen,(PRUint32)crv);
--- a/security/nss/lib/softoken/keydb.c
+++ b/security/nss/lib/softoken/keydb.c
@@ -575,23 +575,28 @@ makeGlobalVersion(NSSLOWKEYDBHandle *han
 
 static SECStatus
 makeGlobalSalt(NSSLOWKEYDBHandle *handle)
 {
     DBT saltKey;
     DBT saltData;
     unsigned char saltbuf[16];
     int status;
+    SECStatus rv;
     
     saltKey.data = SALT_STRING;
     saltKey.size = sizeof(SALT_STRING) - 1;
 
     saltData.data = (void *)saltbuf;
     saltData.size = sizeof(saltbuf);
-    RNG_GenerateGlobalRandomBytes(saltbuf, sizeof(saltbuf));
+    rv = RNG_GenerateGlobalRandomBytes(saltbuf, sizeof(saltbuf));
+    if ( rv != SECSuccess ) {
+	sftk_fatalError = PR_TRUE;
+	return(rv);
+    }
 
     /* put global salt into the database now */
     status = keydb_Put(handle, &saltKey, &saltData, 0);
     if ( status ) {
 	return(SECFailure);
     }
 
     return(SECSuccess);
@@ -1517,21 +1522,22 @@ seckey_create_rc4_salt(void)
     if(salt == NULL)
 	return NULL;
 
     salt->data = (unsigned char *)PORT_ZAlloc(sizeof(unsigned char) *
 	SALT_LENGTH);
     if(salt->data != NULL)
     {
 	salt->len = SALT_LENGTH;
-	RNG_GenerateGlobalRandomBytes(salt->data, salt->len);
-	rv = SECSuccess;
+	rv = RNG_GenerateGlobalRandomBytes(salt->data, salt->len);
+	if(rv != SECSuccess)
+	    sftk_fatalError = PR_TRUE;
     }
 	
-    if(rv == SECFailure)
+    if(rv != SECSuccess)
     {
 	SECITEM_FreeItem(salt, PR_TRUE);
 	salt = NULL;
     }
 
     return salt;
 }
 
--- a/security/nss/lib/softoken/pkcs11.c
+++ b/security/nss/lib/softoken/pkcs11.c
@@ -1532,16 +1532,19 @@ sftk_GenerateSecretCKA_ID(NSSLOWKEYDBHan
 
     retries = 0;
     do {
 	rv = RNG_GenerateGlobalRandomBytes(id->data,id->len);
     } while (rv == SECSuccess && nsslowkey_KeyForIDExists(handle,id) && 
 				(++retries <= SFTK_KEY_MAX_RETRIES));
 
     if ((rv != SECSuccess) || (retries > SFTK_KEY_MAX_RETRIES)) {
+	if (rv != SECSuccess) {
+	    sftk_fatalError = PR_TRUE;
+	}
 	crv = CKR_DEVICE_ERROR; /* random number generator is bad */
 	PORT_Free(id->data);
 	id->data = NULL;
 	id->len = 0;
     }
     return crv;
 }
 
--- a/security/nss/lib/softoken/pkcs11c.c
+++ b/security/nss/lib/softoken/pkcs11c.c
@@ -1661,16 +1661,19 @@ nsc_DSA_Sign_Stub(void *ctx, void *sigBu
     SECStatus rv;
     NSSLOWKEYPrivateKey *key = (NSSLOWKEYPrivateKey *)ctx;
 
     signature.data = (unsigned char *)sigBuf;
     signature.len = maxSigLen;
     digest.data = (unsigned char *)dataBuf;
     digest.len = dataLen;
     rv = DSA_SignDigest(&(key->u.dsa), &signature, &digest);
+    if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
+	sftk_fatalError = PR_TRUE;
+    }
     *sigLen = signature.len;
     return rv;
 }
 
 #ifdef NSS_ENABLE_ECC
 static SECStatus
 nsc_ECDSAVerifyStub(void *ctx, void *sigBuf, unsigned int sigLen,
                     void *dataBuf, unsigned int dataLen)
@@ -1694,16 +1697,19 @@ nsc_ECDSASignStub(void *ctx, void *sigBu
     SECStatus rv;
     NSSLOWKEYPrivateKey *key = (NSSLOWKEYPrivateKey *)ctx;
 
     signature.data = (unsigned char *)sigBuf;
     signature.len = maxSigLen;
     digest.data = (unsigned char *)dataBuf;
     digest.len = dataLen;
     rv = ECDSA_SignDigest(&(key->u.ec), &signature, &digest);
+    if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
+	sftk_fatalError = PR_TRUE;
+    }
     *sigLen = signature.len;
     return rv;
 }
 #endif /* NSS_ENABLE_ECC */
 
 /* NSC_SignInit setups up the signing operations. There are three basic
  * types of signing:
  *	(1) the tradition single part, where "Raw RSA" or "Raw DSA" is applied
@@ -2599,16 +2605,19 @@ nsc_parameter_gen(CK_KEY_TYPE key_type, 
 
     if (seedBits == 0) {
 	rv = PQG_ParamGen(j, &params, &vfy);
     } else {
 	rv = PQG_ParamGenSeedLen(j,seedBits/8, &params, &vfy);
     }
 
     if (rv != SECSuccess) {
+	if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
+	    sftk_fatalError = PR_TRUE;
+	}
 	return CKR_DEVICE_ERROR;
     }
     crv = sftk_AddAttributeType(key,CKA_PRIME,
 				 params->prime.data, params->prime.len);
     if (crv != CKR_OK) goto loser;
     crv = sftk_AddAttributeType(key,CKA_SUBPRIME,
 				 params->subPrime.data, params->subPrime.len);
     if (crv != CKR_OK) goto loser;
@@ -3427,16 +3436,19 @@ CK_RV NSC_GenerateKeyPair (CK_SESSION_HA
 	if (crv != CKR_OK) {
 	    PORT_Free(pubExp.data);
 	    break;
 	}
 
 	rsaPriv = RSA_NewKey(public_modulus_bits, &pubExp);
 	PORT_Free(pubExp.data);
 	if (rsaPriv == NULL) {
+	    if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
+		sftk_fatalError = PR_TRUE;
+	    }
 	    crv = CKR_DEVICE_ERROR;
 	    break;
 	}
         /* now fill in the RSA dependent paramenters in the public key */
         crv = sftk_AddAttributeType(publicKey,CKA_MODULUS,
 			   sftk_item_expand(&rsaPriv->modulus));
 	if (crv != CKR_OK) goto kpg_done;
         /* now fill in the RSA dependent paramenters in the private key */
@@ -3543,17 +3555,23 @@ kpg_done:
 	    
 	/* Generate the key */
 	rv = DSA_NewKey(&pqgParam, &dsaPriv);
 
 	PORT_Free(pqgParam.prime.data);
 	PORT_Free(pqgParam.subPrime.data);
 	PORT_Free(pqgParam.base.data);
 
-	if (rv != SECSuccess) { crv = CKR_DEVICE_ERROR; break; }
+	if (rv != SECSuccess) {
+	    if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
+		sftk_fatalError = PR_TRUE;
+	    }
+	    crv = CKR_DEVICE_ERROR;
+	    break;
+	}
 
 	/* store the generated key into the attributes */
         crv = sftk_AddAttributeType(publicKey,CKA_VALUE,
 			   sftk_item_expand(&dsaPriv->publicValue));
 	if (crv != CKR_OK) goto dsagn_done;
 
         /* now fill in the RSA dependent paramenters in the private key */
         crv = sftk_AddAttributeType(privateKey,CKA_NETSCAPE_DB,
@@ -3611,16 +3629,19 @@ dsagn_done:
 	    PORT_Free(dhParam.base.data);
 	    break;
 	}
 
 	rv = DH_NewKey(&dhParam, &dhPriv);
 	PORT_Free(dhParam.prime.data);
 	PORT_Free(dhParam.base.data);
 	if (rv != SECSuccess) { 
+	    if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
+		sftk_fatalError = PR_TRUE;
+	    }
 	    crv = CKR_DEVICE_ERROR;
 	    break;
 	}
 
 	crv=sftk_AddAttributeType(publicKey, CKA_VALUE, 
 				sftk_item_expand(&dhPriv->publicValue));
 	if (crv != CKR_OK) goto dhgn_done;
 
@@ -3660,18 +3681,21 @@ dhgn_done:
 	PORT_Free(ecEncodedParams.data);
 	if (rv != SECSuccess) {
 	    crv = CKR_DEVICE_ERROR;
 	    break;
 	}
 	rv = EC_NewKey(ecParams, &ecPriv);
 	PORT_FreeArena(ecParams->arena, PR_TRUE);
 	if (rv != SECSuccess) { 
-	  crv = CKR_DEVICE_ERROR;
-	  break;
+	    if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
+		sftk_fatalError = PR_TRUE;
+	    }
+	    crv = CKR_DEVICE_ERROR;
+	    break;
 	}
 
 	crv = sftk_AddAttributeType(publicKey, CKA_EC_POINT, 
 				sftk_item_expand(&ecPriv->publicValue));
 	if (crv != CKR_OK) goto ecgn_done;
 
 	crv = sftk_AddAttributeType(privateKey, CKA_VALUE, 
 			      sftk_item_expand(&ecPriv->privateValue));
@@ -4785,25 +4809,26 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE h
 	}
 	if (ssl3_master->RandomInfo.ulServerRandomLen != SSL3_RANDOM_LENGTH) {
 	   crv = CKR_MECHANISM_PARAM_INVALID;
 	   break;
 	}
 
         if (isTLS) {
 	    SECStatus status;
- 	    SECItem crsr   = { siBuffer, crsrdata, sizeof crsrdata };
- 	    SECItem master = { siBuffer, key_block, SSL3_MASTER_SECRET_LENGTH};
- 	    SECItem pms    = { siBuffer };
-
-	    /* HPUX won't let a structure member be initialized with the 
-	     * value of a variable, but the address of a local variable. :-/
-	     */
- 	    pms.data = (unsigned char*)att->attrib.pValue;
-	    pms.len  =                 att->attrib.ulValueLen;
+ 	    SECItem crsr   = { siBuffer, NULL, 0 };
+ 	    SECItem master = { siBuffer, NULL, 0 };
+ 	    SECItem pms    = { siBuffer, NULL, 0 };
+
+ 	    crsr.data   = crsrdata;
+	    crsr.len    = sizeof crsrdata;
+ 	    master.data = key_block;
+	    master.len  = SSL3_MASTER_SECRET_LENGTH;
+ 	    pms.data    = (unsigned char*)att->attrib.pValue;
+	    pms.len     =                 att->attrib.ulValueLen;
 
 	    status = TLS_PRF(&pms, "master secret", &crsr, &master, isFIPS);
 	    if (status != SECSuccess) {
 	    	crv = CKR_FUNCTION_FAILED;
 		break;
 	    }
 	} else {
 	    /* now allocate the hash contexts */
@@ -4934,20 +4959,23 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE h
 	    block_needed = sizeof key_block;
 
 	/*
 	 * generate the key material: This looks amazingly similar to the
 	 * PMS code, and is clearly crying out for a function to provide it.
 	 */
 	if (isTLS) {
 	    SECStatus     status;
-	    SECItem       srcr   = { siBuffer, srcrdata, sizeof srcrdata };
-	    SECItem       keyblk = { siBuffer, key_block };
-	    SECItem       master = { siBuffer }; 
-
+	    SECItem       srcr   = { siBuffer, NULL, 0 };
+	    SECItem       keyblk = { siBuffer, NULL, 0 };
+	    SECItem       master = { siBuffer, NULL, 0 }; 
+
+	    srcr.data   = srcrdata;
+	    srcr.len    = sizeof srcrdata;
+	    keyblk.data = key_block;
 	    keyblk.len  = block_needed;
 	    master.data = (unsigned char*)att->attrib.pValue;
 	    master.len  =                 att->attrib.ulValueLen;
 
 	    status = TLS_PRF(&master, "key expansion", &srcr, &keyblk,
 			      isFIPS);
 	    if (status != SECSuccess) {
 		goto key_and_mac_derive_fail;
@@ -5104,28 +5132,30 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE h
 
 	    } else {
 
 		/*
 		** Generate TLS Export write keys and IVs.
 		*/
 		SECStatus     status;
 		SECItem       secret = { siBuffer, NULL, 0 };
-		SECItem       crsr   = { siBuffer, crsrdata, sizeof crsrdata };
+		SECItem       crsr   = { siBuffer, NULL, 0 };
 		SECItem       keyblk = { siBuffer, NULL, 0 };
 
 		/*
 		** client_write_key[CipherSpec.key_material]
 		** final_client_write_key = PRF(client_write_key, 
 		**                              "client write key",
 		**                              client_random + server_random);
 		*/
 		secret.data = &key_block[i];
 		secret.len  = effKeySize;
 		i          += effKeySize;
+		crsr.data   = crsrdata;
+		crsr.len    = sizeof crsrdata;
 		keyblk.data = key_block2;
 		keyblk.len  = sizeof key_block2;
 		status = TLS_PRF(&secret, "client write key", &crsr, &keyblk,
 				  isFIPS);
 		if (status != SECSuccess) {
 		    goto key_and_mac_derive_fail;
 		}
 		crv = sftk_buildSSLKey(hSession, key, PR_FALSE, key_block2, 
--- a/security/nss/lib/softoken/pkcs11i.h
+++ b/security/nss/lib/softoken/pkcs11i.h
@@ -551,17 +551,17 @@ typedef struct sftk_parametersStr {
 #define SECMOD_DB "secmod.db"
 #define CERT_DB_FMT "%scert%s.db"
 #define KEY_DB_FMT "%skey%s.db"
 #endif
 
 SEC_BEGIN_PROTOS
 
 /* shared functions between pkcs11.c and fipstokn.c */
-extern int nsf_init;
+extern PRBool nsf_init;
 extern CK_RV nsc_CommonInitialize(CK_VOID_PTR pReserved, PRBool isFIPS);
 extern CK_RV nsc_CommonFinalize(CK_VOID_PTR pReserved, PRBool isFIPS);
 extern CK_RV nsc_CommonGetSlotList(CK_BBOOL tokPresent, 
 	CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount, int moduleIndex);
 
 /* slot initialization, reinit, shutdown and destruction */
 extern CK_RV SFTK_SlotInit(char *configdir,
 			sftk_token_parameters *params, int moduleIndex);
--- a/security/nss/lib/softoken/rsawrapr.c
+++ b/security/nss/lib/softoken/rsawrapr.c
@@ -188,16 +188,17 @@ oaep_xor_with_h2(unsigned char *salt, un
 static unsigned char *
 rsa_FormatOneBlock(unsigned modulusLen, RSA_BlockType blockType,
 		   SECItem *data)
 {
     unsigned char *block;
     unsigned char *bp;
     int padLen;
     int i;
+    SECStatus rv;
 
     block = (unsigned char *) PORT_Alloc(modulusLen);
     if (block == NULL)
 	return NULL;
 
     bp = block;
 
     /*
@@ -249,18 +250,23 @@ rsa_FormatOneBlock(unsigned modulusLen, 
 	PORT_Assert (padLen >= RSA_BLOCK_MIN_PAD_LEN);
 	if (padLen < RSA_BLOCK_MIN_PAD_LEN) {
 	    PORT_Free (block);
 	    return NULL;
 	}
 	for (i = 0; i < padLen; i++) {
 	    /* Pad with non-zero random data. */
 	    do {
-		RNG_GenerateGlobalRandomBytes(bp + i, 1);
-	    } while (bp[i] == RSA_BLOCK_AFTER_PAD_OCTET);
+		rv = RNG_GenerateGlobalRandomBytes(bp + i, 1);
+	    } while (rv == SECSuccess && bp[i] == RSA_BLOCK_AFTER_PAD_OCTET);
+	    if (rv != SECSuccess) {
+		sftk_fatalError = PR_TRUE;
+		PORT_Free (block);
+		return NULL;
+	    }
 	}
 	bp += padLen;
 	*bp++ = RSA_BLOCK_AFTER_PAD_OCTET;
 	PORT_Memcpy (bp, data->data, data->len);
 
 	break;
 
       /*
@@ -287,17 +293,22 @@ rsa_FormatOneBlock(unsigned modulusLen, 
 	 *
 	 * Whew!
 	 */
 
 
 	/*
 	 * Salt
 	 */
-	RNG_GenerateGlobalRandomBytes(bp, OAEP_SALT_LEN);
+	rv = RNG_GenerateGlobalRandomBytes(bp, OAEP_SALT_LEN);
+	if (rv != SECSuccess) {
+	    sftk_fatalError = PR_TRUE;
+	    PORT_Free (block);
+	    return NULL;
+	}
 	bp += OAEP_SALT_LEN;
 
 	/*
 	 * Pad1
 	 */
 	PORT_Memset (bp, OAEP_PAD_OCTET, OAEP_PAD_LEN);
 	bp += OAEP_PAD_LEN;
 
@@ -305,18 +316,24 @@ rsa_FormatOneBlock(unsigned modulusLen, 
 	 * Data
 	 */
 	PORT_Memcpy (bp, data->data, data->len);
 	bp += data->len;
 
 	/*
 	 * Pad2
 	 */
-	if (bp < (block + modulusLen))
-	    RNG_GenerateGlobalRandomBytes(bp, block - bp + modulusLen);
+	if (bp < (block + modulusLen)) {
+	    rv = RNG_GenerateGlobalRandomBytes(bp, block - bp + modulusLen);
+	    if (rv != SECSuccess) {
+		sftk_fatalError = PR_TRUE;
+		PORT_Free (block);
+		return NULL;
+	    }
+	}
 
 	/*
 	 * Now we have the following:
 	 * 0x00 || BT || Salt || PaddedData
 	 * (From this point on, "Pad1 || Data [|| Pad2]" is treated
 	 * as the one entity PaddedData.)
 	 *
 	 * We need to turn PaddedData into Modified1.
@@ -458,16 +475,19 @@ RSA_Sign(NSSLOWKEYPrivateKey *key,
     unformatted.data = input;
     formatted.data   = NULL;
     rv = rsa_FormatBlock(&formatted, modulus_len, RSA_BlockPrivate,
 			 &unformatted);
     if (rv != SECSuccess) 
     	goto done;
 
     rv = RSA_PrivateKeyOpDoubleChecked(&key->u.rsa, output, formatted.data);
+    if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
+	sftk_fatalError = PR_TRUE;
+    }
     *output_len = modulus_len;
 
     goto done;
 
 done:
     if (formatted.data != NULL) 
     	PORT_ZFree(formatted.data, modulus_len);
     return rv;
@@ -660,18 +680,22 @@ RSA_DecryptBlock(NSSLOWKEYPrivateKey *ke
     if (input_len != modulus_len)
     	goto failure;
 
     buffer = (unsigned char *)PORT_Alloc(modulus_len + 1);
     if (!buffer)
     	goto failure;
 
     rv = RSA_PrivateKeyOp(&key->u.rsa, buffer, input);
-    if (rv != SECSuccess) 
+    if (rv != SECSuccess) {
+	if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
+	    sftk_fatalError = PR_TRUE;
+	}
     	goto loser;
+    }
 
     if (buffer[0] != 0 || buffer[1] != 2) 
     	goto loser;
     *output_len = 0;
     for (i = 2; i < modulus_len; i++) {
 	if (buffer[i] == 0) {
 	    *output_len = modulus_len - i - 1;
 	    break;
@@ -720,16 +744,19 @@ RSA_SignRaw(NSSLOWKEYPrivateKey *key,
     unformatted.len  = input_len;
     unformatted.data = input;
     formatted.data   = NULL;
     rv = rsa_FormatBlock(&formatted, modulus_len, RSA_BlockRaw, &unformatted);
     if (rv != SECSuccess) 
     	goto done;
 
     rv = RSA_PrivateKeyOpDoubleChecked(&key->u.rsa, output, formatted.data);
+    if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
+	sftk_fatalError = PR_TRUE;
+    }
     *output_len = modulus_len;
 
 done:
     if (formatted.data != NULL) 
     	PORT_ZFree(formatted.data, modulus_len);
     return rv;
 }
 
@@ -869,17 +896,21 @@ RSA_DecryptRaw(NSSLOWKEYPrivateKey *key,
     	goto failure;
     PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
     if (key->keyType != NSSLOWKEYRSAKey)
     	goto failure;
     if (input_len != modulus_len) 
     	goto failure;
 
     rv = RSA_PrivateKeyOp(&key->u.rsa, output, input);
-    if (rv != SECSuccess)
+    if (rv != SECSuccess) {
+	if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
+	    sftk_fatalError = PR_TRUE;
+	}
     	goto failure;
+    }
 
     *output_len = modulus_len;
     return SECSuccess;
 
 failure:
     return SECFailure;
 }
--- a/security/nss/lib/softoken/softoken.h
+++ b/security/nss/lib/softoken/softoken.h
@@ -179,11 +179,16 @@ unsigned long sftk_MapKeySize(CK_KEY_TYP
 
 /*
 ** FIPS 140-2 auditing
 */
 extern PRBool sftk_audit_enabled;
 
 extern void sftk_LogAuditMessage(NSSAuditSeverity severity, const char *msg);
 
+/*
+** FIPS 140-2 Error state
+*/
+extern PRBool sftk_fatalError;
+
 SEC_END_PROTOS
 
 #endif /* _SOFTOKEN_H_ */
--- a/security/nss/lib/ssl/ssl3con.c
+++ b/security/nss/lib/ssl/ssl3con.c
@@ -3502,16 +3502,21 @@ ssl3_SendClientHello(sslSocket *ss)
 	    return SECFailure;
 	}
 	maxBytes        -= extLen;
 	total_exten_len += extLen;
 
 	if (total_exten_len > 0)
 	    total_exten_len += 2;
     }
+#if defined(NSS_ENABLE_ECC) && !defined(NSS_ECC_MORE_THAN_SUITE_B)
+    else { /* SSL3 only */
+    	ssl3_DisableECCSuites(ss, NULL); /* disable all ECC suites */
+    }
+#endif
 
     /* how many suites are permitted by policy and user preference? */
     num_suites = count_cipher_suites(ss, ss->ssl3.policy, PR_TRUE);
     if (!num_suites)
     	return SECFailure;	/* count_cipher_suites has set error code. */
 
     length = sizeof(SSL3ProtocolVersion) + SSL3_RANDOM_LENGTH +
 	1 + ((sid == NULL) ? 0 : sid->u.ssl3.sessionIDLength) +
@@ -6776,33 +6781,35 @@ ssl3_SendCertificate(sslSocket *ss)
     rv = ssl3_AppendHandshakeHeader(ss, certificate, len + 3);
     if (rv != SECSuccess) {
 	return rv; 		/* err set by AppendHandshake. */
     }
     rv = ssl3_AppendHandshakeNumber(ss, len, 3);
     if (rv != SECSuccess) {
 	return rv; 		/* err set by AppendHandshake. */
     }
-    for (i = 0; i < certChain->len; i++) {
+    if (certChain) {
+        for (i = 0; i < certChain->len; i++) {
 #ifdef NISCC_TEST
-	if (fakeCert.len > 0 && i == ndex) {
-	    rv = ssl3_AppendHandshakeVariable(ss, fakeCert.data, fakeCert.len, 
-	                                      3);
-	    SECITEM_FreeItem(&fakeCert, PR_FALSE);
-	} else {
-	    rv = ssl3_AppendHandshakeVariable(ss, certChain->certs[i].data,
-					      certChain->certs[i].len, 3);
-	}
+            if (fakeCert.len > 0 && i == ndex) {
+                rv = ssl3_AppendHandshakeVariable(ss, fakeCert.data,
+                                                  fakeCert.len, 3);
+                SECITEM_FreeItem(&fakeCert, PR_FALSE);
+            } else {
+                rv = ssl3_AppendHandshakeVariable(ss, certChain->certs[i].data,
+                                                  certChain->certs[i].len, 3);
+            }
 #else
-	rv = ssl3_AppendHandshakeVariable(ss, certChain->certs[i].data,
-					  certChain->certs[i].len, 3);
+            rv = ssl3_AppendHandshakeVariable(ss, certChain->certs[i].data,
+                                              certChain->certs[i].len, 3);
 #endif
-	if (rv != SECSuccess) {
-	    return rv; 		/* err set by AppendHandshake. */
-	}
+            if (rv != SECSuccess) {
+                return rv; 		/* err set by AppendHandshake. */
+            }
+        }
     }
 
     return SECSuccess;
 }
 
 /* This is used to delete the CA certificates in the peer certificate chain
  * from the cert database after they've been validated.
  */
--- a/security/nss/lib/ssl/ssl3ecc.c
+++ b/security/nss/lib/ssl/ssl3ecc.c
@@ -950,16 +950,18 @@ static const ssl3CipherSuite ecSuites[] 
     TLS_ECDH_RSA_WITH_RC4_128_SHA,
     0 /* end of list marker */
 };
 
 /* On this socket, Disable the ECC cipher suites in the argument's list */
 SECStatus
 ssl3_DisableECCSuites(sslSocket * ss, const ssl3CipherSuite * suite)
 {
+    if (!suite)
+    	suite = ecSuites;
     for (; *suite; ++suite) {
 	SECStatus rv      = ssl3_CipherPrefSet(ss, *suite, PR_FALSE);
 
 	PORT_Assert(rv == SECSuccess); /* else is coding error */
     }
     return SECSuccess;
 }
 
--- a/security/nss/lib/ssl/sslcon.c
+++ b/security/nss/lib/ssl/sslcon.c
@@ -3115,17 +3115,21 @@ ssl2_BeginClientHandshake(sslSocket *ss)
 	ssl_GetXmitBufLock(ss);    /***************************************/
 	ssl_GetSSL3HandshakeLock(ss);
 	rv =  ssl3_SendClientHello(ss);
 	ssl_ReleaseSSL3HandshakeLock(ss);
 	ssl_ReleaseXmitBufLock(ss); /***************************************/
 
 	return rv;
     }
-   
+#if defined(NSS_ENABLE_ECC) && !defined(NSS_ECC_MORE_THAN_SUITE_B)
+    /* ensure we don't neogtiate ECC cipher suites with SSL2 hello */
+    ssl3_DisableECCSuites(ss, NULL); /* disable all ECC suites */
+#endif
+
     if (!ss->cipherSpecs) {
         rv = ssl2_ConstructCipherSpecs(ss);
 	if (rv < 0) {
 	    return rv;
     	}
     }
     localCipherSpecs = ss->cipherSpecs;
     localCipherSize  = ss->sizeCipherSpecs;
--- a/security/nss/lib/ssl/sslimpl.h
+++ b/security/nss/lib/ssl/sslimpl.h
@@ -1269,16 +1269,18 @@ int ssl3_GatherCompleteHandshake(sslSock
  * key, signed by the larger key.  The smaller key is a "step down" key.
  * Generate that key pair and keep it around.
  */
 extern SECStatus ssl3_CreateRSAStepDownKeys(sslSocket *ss);
 
 #ifdef NSS_ENABLE_ECC
 extern void      ssl3_FilterECCipherSuitesByServerCerts(sslSocket *ss);
 extern PRBool    ssl3_IsECCEnabled(sslSocket *ss);
+extern SECStatus ssl3_DisableECCSuites(sslSocket * ss, 
+                                       const ssl3CipherSuite * suite);
 #endif /* NSS_ENABLE_ECC */
 
 extern SECStatus ssl3_CipherPrefSetDefault(ssl3CipherSuite which, PRBool on);
 extern SECStatus ssl3_CipherPrefGetDefault(ssl3CipherSuite which, PRBool *on);
 extern SECStatus ssl2_CipherPrefSetDefault(PRInt32 which, PRBool enabled);
 extern SECStatus ssl2_CipherPrefGetDefault(PRInt32 which, PRBool *enabled);
 
 extern SECStatus ssl3_CipherPrefSet(sslSocket *ss, ssl3CipherSuite which, PRBool on);
--- a/security/nss/lib/ssl/sslsnce.c
+++ b/security/nss/lib/ssl/sslsnce.c
@@ -887,17 +887,18 @@ CloseCache(cacheDesc *cache)
 {
     int locks_initialized = cache->numSIDCacheLocksInitialized;
 
     if (cache->cacheMem) {
 	/* If everInherited is true, this shared cache was (and may still
 	** be) in use by multiple processes.  We do not wish to destroy
 	** the mutexes while they are still in use.  
 	*/
-	if (PR_FALSE == cache->sharedCache->everInherited) {
+	if (cache->sharedCache &&
+            PR_FALSE == cache->sharedCache->everInherited) {
 	    sidCacheLock *pLock = cache->sidCacheLocks;
 	    for (; locks_initialized > 0; --locks_initialized, ++pLock ) {
 		sslMutex_Destroy(&pLock->mutex);
 	    }
 	}
 	if (cache->shared) {
 	    PR_MemUnmap(cache->cacheMem, cache->cacheMemSize);
 	} else {
@@ -936,16 +937,22 @@ InitCache(cacheDesc *cache, int maxCache
     }
 
     /* make sure loser can clean up properly */
     cache->shared = shared;
     cache->cacheMem    = cacheMem    = NULL;
     cache->cacheMemMap = cacheMemMap = NULL;
     cache->sharedCache = (cacheDesc *)0;
 
+    cache->numSIDCacheLocksInitialized = 0;
+    cache->nextCertCacheEntry = 0;
+    cache->stopPolling = PR_FALSE;
+    cache->everInherited = PR_FALSE;
+    cache->poller = NULL;
+
     cache->numSIDCacheEntries = maxCacheEntries ? maxCacheEntries 
                                                 : DEF_SID_CACHE_ENTRIES;
     cache->numSIDCacheSets    = 
     	SID_HOWMANY(cache->numSIDCacheEntries, SID_CACHE_ENTRIES_PER_SET);
 
     cache->numSIDCacheEntries = 
     	cache->numSIDCacheSets * SID_CACHE_ENTRIES_PER_SET;