0701 nwnss: make rand helpers seed deterministic

This commit is contained in:
Mario Fetka
2026-06-17 10:53:02 +00:00
parent c7f7164931
commit 8cc8b8663d
3 changed files with 110 additions and 39 deletions

View File

@@ -4,12 +4,18 @@
|
| The shipped NSS sources contain shared/sdk/library/rand.h and export
| these symbols from the NSS library import lists, but no corresponding
| C implementation was present in the supplied source archives.
| C implementation was present in the supplied source archives or public
| sources checked during the nwnss import audit.
|
| Keep the NSS symbol surface and back every generated value with the
| bundled libsodium randombytes backend. The seed entry points are kept
| as API-compatible state hooks only; they do not replace OS entropy with
| a private deterministic generator.
| Novell LibC documents rand()/rand_r() as seeded pseudo-random sequence
| APIs. Keep the same seed-driven model for the wider NSS QUAD helpers:
| srandQuad()/srndQuad()/srndLong() set deterministic state and subsequent
| randQuad()/rndQuad()/rndLong() calls advance that state. If callers use
| the generator before explicitly seeding it, initialize the state once
| from libsodium randombytes_buf(), which is the userspace equivalent of a
| kernel random-byte source.
|
| This is a MARS userspace port, not Novell original source.
+-------------------------------------------------------------------------*/
#include <rand.h>
@@ -18,12 +24,11 @@
#include <sodium/core.h>
#include <sodium/randombytes.h>
static QUAD seedSalt;
static QUAD seedCounter;
static int haveSeedSalt;
static QUAD randState;
static int haveRandState;
static int sodiumReady;
static void nwnssRandInit(void)
static void nwnssRandInitSodium(void)
{
if (!sodiumReady) {
int rc = sodium_init();
@@ -32,34 +37,37 @@ static void nwnssRandInit(void)
}
}
static QUAD nwnssSeedMix(void)
static QUAD nwnssRandNextFromState(QUAD *state)
{
QUAD z;
if (!haveSeedSalt)
return 0;
z = seedSalt + (++seedCounter * 0x9e3779b97f4a7c15ULL);
*state += 0x9e3779b97f4a7c15ULL;
z = *state;
z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9ULL;
z = (z ^ (z >> 27)) * 0x94d049bb133111ebULL;
return z ^ (z >> 31);
}
static void nwnssRandEnsureSeeded(void)
{
if (haveRandState)
return;
nwnssRandInitSodium();
randombytes_buf(&randState, sizeof(randState));
haveRandState = 1;
}
void srandQuad(QUAD seed)
{
seedSalt ^= seed + 0x4e53534c49424e57ULL;
seedCounter = 0;
haveSeedSalt = 1;
randState = seed;
haveRandState = 1;
}
SQUAD randQuad(void)
{
QUAD value;
nwnssRandInit();
randombytes_buf(&value, sizeof(value));
value ^= nwnssSeedMix();
return (SQUAD)value;
nwnssRandEnsureSeeded();
return (SQUAD)nwnssRandNextFromState(&randState);
}
void srndQuad(QUAD seed)