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.c31
1 files changed, 24 insertions, 7 deletions
diff --git a/security/nss/lib/freebl/det_rng.c b/security/nss/lib/freebl/det_rng.c
index 04fce30e8..56be2d356 100644
--- a/security/nss/lib/freebl/det_rng.c
+++ b/security/nss/lib/freebl/det_rng.c
@@ -4,23 +4,26 @@
#include "blapi.h"
#include "blapit.h"
-#include "chacha20.h"
+#include "Hacl_Chacha20.h"
#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;
}
@@ -85,7 +99,7 @@ RNG_GenerateGlobalRandomBytes(void *dest, size_t len)
memset(dest, 0, len);
memcpy(dest, globalBytes, PR_MIN(len, GLOBAL_BYTES_SIZE));
- ChaCha20XOR(dest, dest, len, key, nonce, 0);
+ Hacl_Chacha20_chacha20(dest, (uint8_t *)dest, len, (uint8_t *)key, nonce, 0);
ChaCha20Poly1305_DestroyContext(cx, PR_TRUE);
PZ_Unlock(rng_lock);
@@ -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! */