-/* Used to detect whether we've already been initialized */
-static int gRandomInstalled = 0;
-static PrngRef gPrngRef;
-static int gRandomError = 1;
-static mutex_t *gYarrowMutex = 0;
-
-#define RESEED_TICKS 50 /* how long a reseed operation can take */
-
-
-enum {kBSizeInBits = 160}; // MUST be a multiple of 32!!!
-enum {kBSizeInBytes = kBSizeInBits / 8};
-typedef u_int32_t BlockWord;
-enum {kWordSizeInBits = 32};
-enum {kBSize = 5};
-typedef BlockWord Block[kBSize];
-
-/* define prototypes to keep the compiler happy... */
-
-void add_blocks(Block a, Block b, BlockWord carry);
-void fips_initialize(void);
-void random_block(Block b);
-
-/*
- * Get 120 bits from yarrow
- */
-
-/*
- * add block b to block a
- */
-void
-add_blocks(Block a, Block b, BlockWord carry)
-{
- int i = kBSize;
- while (--i >= 0)
- {
- u_int64_t c = (u_int64_t)carry +
- (u_int64_t)a[i] +
- (u_int64_t)b[i];
- a[i] = c & ((1LL << kWordSizeInBits) - 1);
- carry = c >> kWordSizeInBits;
- }
-}
-
-
-
-struct sha1_ctxt g_sha1_ctx;
-char zeros[(512 - kBSizeInBits) / 8];
-Block g_xkey;
-Block g_random_data;
-int g_bytes_used;
-
-/*
- * Setup for fips compliance
- */
-
-/*
- * get a random block of data per fips 186-2
- */
-void
-random_block(Block b)
-{
- // do one iteration
- Block xSeed;
- prngOutput (gPrngRef, (BYTE*) &xSeed, sizeof (xSeed));
-
- // add the seed to the previous value of g_xkey
- add_blocks (g_xkey, xSeed, 0);
-
- // compute "G"
- SHA1Update (&g_sha1_ctx, (const u_int8_t *) &g_xkey, sizeof (g_xkey));
-
- // add zeros to fill the internal SHA-1 buffer
- SHA1Update (&g_sha1_ctx, (const u_int8_t *)zeros, sizeof (zeros));
-
- // write the resulting block
- memmove(b, g_sha1_ctx.h.b8, sizeof (Block));
-
- // fix up the next value of g_xkey
- add_blocks (g_xkey, b, 1);
-}
-
-/*
- *Initialize ONLY the Yarrow generator.
- */
-void
-PreliminarySetup(void)
-{
- prng_error_status perr;
- struct timeval tt;
- char buffer [16];
-
- /* create a Yarrow object */
- perr = prngInitialize(&gPrngRef);
- if (perr != 0) {
- printf ("Couldn't initialize Yarrow, /dev/random will not work.\n");
- return;
- }
-
- /* clear the error flag, reads and write should then work */
- gRandomError = 0;
-
- /* get a little non-deterministic data as an initial seed. */
- microtime(&tt);
-
- /*
- * So how much of the system clock is entropic?
- * It's hard to say, but assume that at least the
- * least significant byte of a 64 bit structure
- * is entropic. It's probably more, how can you figure
- * the exact time the user turned the computer on, for example.
- */
- perr = prngInput(gPrngRef, (BYTE*) &tt, sizeof (tt), SYSTEM_SOURCE, 8);
- if (perr != 0) {
- /* an error, complain */
- printf ("Couldn't seed Yarrow.\n");
- return;
- }
-
- /* turn the data around */
- perr = prngOutput(gPrngRef, (BYTE*)buffer, sizeof (buffer));
-
- /* and scramble it some more */
- perr = prngForceReseed(gPrngRef, RESEED_TICKS);
-
- /* make a mutex to control access */
- gYarrowMutex = mutex_alloc(0);
-
- fips_initialize ();
-}
-
-void
-fips_initialize(void)
-{
- /* Read the initial value of g_xkey from yarrow */
- prngOutput (gPrngRef, (BYTE*) &g_xkey, sizeof (g_xkey));
-
- /* initialize our SHA1 generator */
- SHA1Init (&g_sha1_ctx);
-
- /* other initializations */
- memset (zeros, 0, sizeof (zeros));
- g_bytes_used = 0;
- random_block(g_random_data);
-}