0701 nwnss: make rand helpers seed deterministic
This commit is contained in:
@@ -106,7 +106,7 @@ still stay original and remain listed, because later imports may rely on them.
|
||||
| PARTIAL | `src/nwnss/comn/common/ndp_messagehandler.c` | ORIG wrapper | link smoke | Novell wrapper name/pattern; full audit open. |
|
||||
| TEMP | `src/nwnss/comn/comnModule.c` | TEMP | link smoke | Transition module identity bridge; should disappear later. |
|
||||
| AUDITED | `src/nwnss/library/bit.c` | PORT | nwnss.bit, nwnss.bitmap | No original provider found beyond bit.h/libNSS.imp; native-NINT semantics fixed/tested in 0698. |
|
||||
| AUDITED | `src/nwnss/library/misc/rand.c` | PORT | nwnss.rand, nwnss.namespace | No original provider found beyond rand.h/libNSS.imp/callers; libsodium entropy port checked in 0700. |
|
||||
| AUDITED | `src/nwnss/library/misc/rand.c` | PORT | nwnss.rand, nwnss.namespace | No original provider found beyond rand.h/libNSS.imp/callers; seed-deterministic PRNG port checked in 0700/0701; libsodium only initializes default state before explicit seeding. |
|
||||
| TODO | `src/nwnss/library/misc/rbpTree.c` | PORT | nwnss.rbpTree | Algorithmic port; has tests, but original-provider search/checklist still open. |
|
||||
| TODO | `src/nwnss/library/os/currentTime.c` | PORT | nwnss.utc | Userspace time port; full audit open. |
|
||||
| AUDITED | `src/nwnss/library/os/delay.c` | ORIG+FIX/PORT | nwnss.schedule, nwnss.snooze | Scheduler functions kept as functions, not macros; checked in 0688-0690. |
|
||||
@@ -606,7 +606,7 @@ even if it already compiles or has indirect test coverage.
|
||||
| TODO | ORIG+FIX? | not yet classified | `src/nwnss/library/misc/histogram.c` | Must be compared against original source and classified. |
|
||||
| TODO | ORIG+FIX? | not yet classified | `src/nwnss/library/misc/lbVolume.c` | Must be compared against original source and classified. |
|
||||
| TODO | ORIG+FIX? | not yet classified | `src/nwnss/library/misc/nssErrorTable.c` | Must be compared against original source and classified. |
|
||||
| AUDITED | PORT | nwnss.rand, nwnss.namespace | `src/nwnss/library/misc/rand.c` | No original provider found beyond rand.h/libNSS.imp/callers; libsodium entropy port checked in 0700. |
|
||||
| AUDITED | PORT | nwnss.rand, nwnss.namespace | `src/nwnss/library/misc/rand.c` | No original provider found beyond rand.h/libNSS.imp/callers; seed-deterministic PRNG port checked in 0700/0701; libsodium only initializes default state before explicit seeding. |
|
||||
| TODO | PORT | nwnss.rbpTree | `src/nwnss/library/misc/rbpTree.c` | Algorithmic port; has tests, but original-provider search/checklist still open. |
|
||||
| TODO | ORIG+FIX? | not yet classified | `src/nwnss/library/misc/register.c` | Must be compared against original source and classified. |
|
||||
| TODO | ORIG+FIX? | not yet classified | `src/nwnss/library/misc/sysimp.c` | Must be compared against original source and classified. |
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -17,27 +17,80 @@ static QUAD deterministic_rand(void)
|
||||
return deterministic_next++;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
static int check_repeatable_quad_seed(void)
|
||||
{
|
||||
unsigned freq[4];
|
||||
SQUAD first;
|
||||
SQUAD second;
|
||||
QUAD long_value;
|
||||
double chi;
|
||||
SQUAD first_a;
|
||||
SQUAD second_a;
|
||||
SQUAD first_b;
|
||||
SQUAD second_b;
|
||||
SQUAD first_other;
|
||||
|
||||
srandQuad(0x123456789abcdef0ULL);
|
||||
first = randQuad();
|
||||
second = randQuad();
|
||||
CHECK(first != second);
|
||||
first_a = randQuad();
|
||||
second_a = randQuad();
|
||||
CHECK(first_a != second_a);
|
||||
|
||||
srandQuad(0x123456789abcdef0ULL);
|
||||
first_b = randQuad();
|
||||
second_b = randQuad();
|
||||
CHECK(first_b == first_a);
|
||||
CHECK(second_b == second_a);
|
||||
|
||||
srandQuad(0x123456789abcdef1ULL);
|
||||
first_other = randQuad();
|
||||
CHECK(first_other != first_a);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int check_repeatable_rnd_quad_seed(void)
|
||||
{
|
||||
SQUAD seq_a[3];
|
||||
SQUAD seq_b[3];
|
||||
int i;
|
||||
|
||||
srndQuad(0x55aaULL);
|
||||
first = rndQuad();
|
||||
second = rndQuad();
|
||||
CHECK(first != second);
|
||||
for (i = 0; i < 3; ++i)
|
||||
seq_a[i] = rndQuad();
|
||||
|
||||
srndQuad(0x55aaULL);
|
||||
for (i = 0; i < 3; ++i)
|
||||
seq_b[i] = rndQuad();
|
||||
|
||||
for (i = 0; i < 3; ++i)
|
||||
CHECK(seq_a[i] == seq_b[i]);
|
||||
|
||||
CHECK(seq_a[0] != seq_a[1]);
|
||||
CHECK(seq_a[1] != seq_a[2]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int check_repeatable_long_seed(void)
|
||||
{
|
||||
QUAD first_a;
|
||||
QUAD second_a;
|
||||
QUAD first_b;
|
||||
QUAD second_b;
|
||||
|
||||
srndLong(0x77bbULL);
|
||||
long_value = rndLong();
|
||||
CHECK((SQUAD)long_value == (SQUAD)long_value);
|
||||
first_a = rndLong();
|
||||
second_a = rndLong();
|
||||
CHECK(first_a != second_a);
|
||||
|
||||
srndLong(0x77bbULL);
|
||||
first_b = rndLong();
|
||||
second_b = rndLong();
|
||||
CHECK(first_b == first_a);
|
||||
CHECK(second_b == second_a);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int check_chi_square(void)
|
||||
{
|
||||
unsigned freq[4];
|
||||
double chi;
|
||||
|
||||
deterministic_next = 0;
|
||||
chi = chiSquareQuad(8, 4, freq, deterministic_rand);
|
||||
@@ -62,3 +115,13 @@ int main(void)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CHECK(check_repeatable_quad_seed() == 0);
|
||||
CHECK(check_repeatable_rnd_quad_seed() == 0);
|
||||
CHECK(check_repeatable_long_seed() == 0);
|
||||
CHECK(check_chi_square() == 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user