summaryrefslogtreecommitdiffstats
path: root/security/nss/lib/freebl/det_rng.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/nss/lib/freebl/det_rng.c')
-rw-r--r--security/nss/lib/freebl/det_rng.c27
1 files changed, 22 insertions, 5 deletions
diff --git a/security/nss/lib/freebl/det_rng.c b/security/nss/lib/freebl/det_rng.c
index 04fce30e8..53d48bc7c 100644
--- a/security/nss/lib/freebl/det_rng.c
+++ b/security/nss/lib/freebl/det_rng.c
@@ -8,19 +8,22 @@
#include "nssilock.h"
#include "seccomon.h"
#include "secerr.h"
+#include "prinit.h"
#define GLOBAL_BYTES_SIZE 100
static PRUint8 globalBytes[GLOBAL_BYTES_SIZE];
static unsigned long globalNumCalls = 0;
static PZLock *rng_lock = NULL;
+static PRCallOnceType coRNGInit;
+static const PRCallOnceType pristineCallOnce;
-SECStatus
-RNG_RNGInit(void)
+static PRStatus
+rng_init(void)
{
rng_lock = PZ_NewLock(nssILockOther);
if (!rng_lock) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
+ return PR_FAILURE;
}
/* --- LOCKED --- */
PZ_Lock(rng_lock);
@@ -28,6 +31,17 @@ RNG_RNGInit(void)
PZ_Unlock(rng_lock);
/* --- UNLOCKED --- */
+ return PR_SUCCESS;
+}
+
+SECStatus
+RNG_RNGInit(void)
+{
+ /* Allow only one call to initialize the context */
+ if (PR_CallOnce(&coRNGInit, rng_init) != PR_SUCCESS) {
+ return SECFailure;
+ }
+
return SECSuccess;
}
@@ -97,8 +111,11 @@ RNG_GenerateGlobalRandomBytes(void *dest, size_t len)
void
RNG_RNGShutdown(void)
{
- PZ_DestroyLock(rng_lock);
- rng_lock = NULL;
+ if (rng_lock) {
+ PZ_DestroyLock(rng_lock);
+ rng_lock = NULL;
+ }
+ coRNGInit = pristineCallOnce;
}
/* Test functions are not implemented! */