Small update to random number generator

This commit is contained in:
Philip Homburg 2005-07-19 12:16:55 +00:00
parent 488b2afc12
commit f8c380c195
4 changed files with 65 additions and 41 deletions

View file

@ -27,7 +27,7 @@
#include "random.h"
#define NR_DEVS 7 /* number of minor devices */
#define KRANDOM_PERIOD 10 /* ticks between krandom calls */
#define KRANDOM_PERIOD 1 /* ticks between krandom calls */
PRIVATE struct device m_geom[NR_DEVS]; /* base and size of each device */
PRIVATE int m_seg[NR_DEVS]; /* segment index of each device */
@ -183,12 +183,8 @@ unsigned nr_req; /* length of request vector */
/* Random number generator. Character instead of block device. */
case RANDOM_DEV:
if (opcode == DEV_GATHER)
{
s= random_reseed();
if (s < 0)
if (opcode == DEV_GATHER && !random_isseeded())
return(EAGAIN);
}
left = count;
while (left > 0) {
chunk = (left > RANDOM_BUF_SIZE) ? RANDOM_BUF_SIZE : left;

View file

@ -33,6 +33,7 @@ PRIVATE u32_t reseed_count;
FORWARD _PROTOTYPE( void add_sample, (int source, unsigned long sample) );
FORWARD _PROTOTYPE( void data_block, (rd_keyinstance *keyp,
void *data) );
FORWARD _PROTOTYPE( void reseed, (void) );
PUBLIC void random_init()
{
@ -54,42 +55,11 @@ PUBLIC void random_init()
reseed_count= 0;
}
PUBLIC int random_reseed()
PUBLIC int random_isseeded()
{
int i;
SHA256_CTX ctx;
u8_t digest[SHA256_DIGEST_LENGTH];
if (samples >= MIN_SAMPLES)
{
reseed_count++;
printf("random_reseed: round %d, samples = %d\n",
reseed_count, samples);
SHA256_Init(&ctx);
if (got_seeded)
SHA256_Update(&ctx, random_key, sizeof(random_key));
SHA256_Final(digest, &pool_ctx[0]);
SHA256_Update(&ctx, digest, sizeof(digest));
SHA256_Init(&pool_ctx[0]);
for (i= 1; i<NR_POOLS; i++)
{
if ((reseed_count & (1UL << (i-1))) != 0)
break;
printf("random_reseed: adding pool %d\n", i);
SHA256_Final(digest, &pool_ctx[i]);
SHA256_Update(&ctx, digest, sizeof(digest));
SHA256_Init(&pool_ctx[i]);
}
SHA256_Final(digest, &ctx);
assert(sizeof(random_key) == sizeof(digest));
memcpy(random_key, &digest, sizeof(random_key));
samples= 0;
got_seeded= 1;
}
if (got_seeded)
return 0;
return -1;
return 1;
return 0;
}
PUBLIC void random_update(source, buf, count)
@ -106,6 +76,7 @@ int count;
panic("memory", "random_update: bad source", source);
for (i= 0; i<count; i++)
add_sample(source, buf[i]);
reseed();
}
PUBLIC void random_getbytes(buf, size)
@ -153,6 +124,8 @@ size_t size;
* with the number of bits.
*/
samples += size*8;
reseed();
}
PRIVATE void add_sample(source, sample)
@ -230,3 +203,38 @@ void *data;
if (count_lo == 0)
count_hi++;
}
PRIVATE void reseed()
{
int i;
SHA256_CTX ctx;
u8_t digest[SHA256_DIGEST_LENGTH];
if (samples < MIN_SAMPLES)
return;
reseed_count++;
printf("reseed: round %d, samples = %d\n", reseed_count, samples);
SHA256_Init(&ctx);
if (got_seeded)
SHA256_Update(&ctx, random_key, sizeof(random_key));
SHA256_Final(digest, &pool_ctx[0]);
SHA256_Update(&ctx, digest, sizeof(digest));
SHA256_Init(&pool_ctx[0]);
for (i= 1; i<NR_POOLS; i++)
{
if ((reseed_count & (1UL << (i-1))) != 0)
break;
printf("random_reseed: adding pool %d\n", i);
SHA256_Final(digest, &pool_ctx[i]);
SHA256_Update(&ctx, digest, sizeof(digest));
SHA256_Init(&pool_ctx[i]);
}
SHA256_Final(digest, &ctx);
assert(sizeof(random_key) == sizeof(digest));
memcpy(random_key, &digest, sizeof(random_key));
samples= 0;
got_seeded= 1;
}

View file

@ -5,7 +5,7 @@ Public interface to the random number generator
*/
_PROTOTYPE( void random_init, (void) );
_PROTOTYPE( int random_reseed, (void) );
_PROTOTYPE( int random_isseeded, (void) );
_PROTOTYPE( void random_update, (int source, unsigned long *buf,
int count) );
_PROTOTYPE( void random_getbytes, (void *buf, size_t size) );

View file

@ -26,6 +26,8 @@ daemonize()
done
}
RANDOM_FILE=/usr/adm/random.dat
case $action in
start)
# Select console font.
@ -34,6 +36,14 @@ start)
# Cleanup.
rm -rf /tmp/. /usr/run/. /usr/spool/lpd/. /usr/spool/locks/.
# load random number generator
if [ -f $RANDOM_FILE ]
then
cat < $RANDOM_FILE >/dev/random
# overwrite $RANDOM_FILE. We don't want to use this data again
dd if=/dev/random of=$RANDOM_FILE bs=1024 count=1
fi
# Start servers.
ifs="$IFS"; IFS=,
for server in `sysenv servers`; do daemonize $server; done
@ -106,4 +116,14 @@ prompt to investigate, otherwise just wait until an address is received..."
# Run the daily cleanup on systems that are not on at night.
test -f /usr/etc/daily && sh /usr/etc/daily boot &
;;
stop|down)
# Save random data.
if dd if=/dev/random of=$RANDOM_FILE.new bs=1024 count=1 2>/dev/null
then
mv $RANDOM_FILE.new $RANDOM_FILE
else
echo 'Failed to save random data.'
fi
esac