Small update to random number generator
This commit is contained in:
parent
488b2afc12
commit
f8c380c195
@ -27,7 +27,7 @@
|
|||||||
#include "random.h"
|
#include "random.h"
|
||||||
|
|
||||||
#define NR_DEVS 7 /* number of minor devices */
|
#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 struct device m_geom[NR_DEVS]; /* base and size of each device */
|
||||||
PRIVATE int m_seg[NR_DEVS]; /* segment index 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. */
|
/* Random number generator. Character instead of block device. */
|
||||||
case RANDOM_DEV:
|
case RANDOM_DEV:
|
||||||
if (opcode == DEV_GATHER)
|
if (opcode == DEV_GATHER && !random_isseeded())
|
||||||
{
|
|
||||||
s= random_reseed();
|
|
||||||
if (s < 0)
|
|
||||||
return(EAGAIN);
|
return(EAGAIN);
|
||||||
}
|
|
||||||
left = count;
|
left = count;
|
||||||
while (left > 0) {
|
while (left > 0) {
|
||||||
chunk = (left > RANDOM_BUF_SIZE) ? RANDOM_BUF_SIZE : left;
|
chunk = (left > RANDOM_BUF_SIZE) ? RANDOM_BUF_SIZE : left;
|
||||||
|
@ -33,6 +33,7 @@ PRIVATE u32_t reseed_count;
|
|||||||
FORWARD _PROTOTYPE( void add_sample, (int source, unsigned long sample) );
|
FORWARD _PROTOTYPE( void add_sample, (int source, unsigned long sample) );
|
||||||
FORWARD _PROTOTYPE( void data_block, (rd_keyinstance *keyp,
|
FORWARD _PROTOTYPE( void data_block, (rd_keyinstance *keyp,
|
||||||
void *data) );
|
void *data) );
|
||||||
|
FORWARD _PROTOTYPE( void reseed, (void) );
|
||||||
|
|
||||||
PUBLIC void random_init()
|
PUBLIC void random_init()
|
||||||
{
|
{
|
||||||
@ -54,42 +55,11 @@ PUBLIC void random_init()
|
|||||||
reseed_count= 0;
|
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)
|
if (got_seeded)
|
||||||
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PUBLIC void random_update(source, buf, count)
|
PUBLIC void random_update(source, buf, count)
|
||||||
@ -106,6 +76,7 @@ int count;
|
|||||||
panic("memory", "random_update: bad source", source);
|
panic("memory", "random_update: bad source", source);
|
||||||
for (i= 0; i<count; i++)
|
for (i= 0; i<count; i++)
|
||||||
add_sample(source, buf[i]);
|
add_sample(source, buf[i]);
|
||||||
|
reseed();
|
||||||
}
|
}
|
||||||
|
|
||||||
PUBLIC void random_getbytes(buf, size)
|
PUBLIC void random_getbytes(buf, size)
|
||||||
@ -153,6 +124,8 @@ size_t size;
|
|||||||
* with the number of bits.
|
* with the number of bits.
|
||||||
*/
|
*/
|
||||||
samples += size*8;
|
samples += size*8;
|
||||||
|
|
||||||
|
reseed();
|
||||||
}
|
}
|
||||||
|
|
||||||
PRIVATE void add_sample(source, sample)
|
PRIVATE void add_sample(source, sample)
|
||||||
@ -230,3 +203,38 @@ void *data;
|
|||||||
if (count_lo == 0)
|
if (count_lo == 0)
|
||||||
count_hi++;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ Public interface to the random number generator
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
_PROTOTYPE( void random_init, (void) );
|
_PROTOTYPE( void random_init, (void) );
|
||||||
_PROTOTYPE( int random_reseed, (void) );
|
_PROTOTYPE( int random_isseeded, (void) );
|
||||||
_PROTOTYPE( void random_update, (int source, unsigned long *buf,
|
_PROTOTYPE( void random_update, (int source, unsigned long *buf,
|
||||||
int count) );
|
int count) );
|
||||||
_PROTOTYPE( void random_getbytes, (void *buf, size_t size) );
|
_PROTOTYPE( void random_getbytes, (void *buf, size_t size) );
|
||||||
|
20
etc/usr/rc
20
etc/usr/rc
@ -26,6 +26,8 @@ daemonize()
|
|||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RANDOM_FILE=/usr/adm/random.dat
|
||||||
|
|
||||||
case $action in
|
case $action in
|
||||||
start)
|
start)
|
||||||
# Select console font.
|
# Select console font.
|
||||||
@ -34,6 +36,14 @@ start)
|
|||||||
# Cleanup.
|
# Cleanup.
|
||||||
rm -rf /tmp/. /usr/run/. /usr/spool/lpd/. /usr/spool/locks/.
|
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.
|
# Start servers.
|
||||||
ifs="$IFS"; IFS=,
|
ifs="$IFS"; IFS=,
|
||||||
for server in `sysenv servers`; do daemonize $server; done
|
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.
|
# Run the daily cleanup on systems that are not on at night.
|
||||||
test -f /usr/etc/daily && sh /usr/etc/daily boot &
|
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
|
esac
|
||||||
|
Loading…
x
Reference in New Issue
Block a user