1*4882a593Smuzhiyun#! /bin/sh 2*4882a593Smuzhiyun# 3*4882a593Smuzhiyun# Preserve the random seed between reboots. See urandom(4). 4*4882a593Smuzhiyun# 5*4882a593Smuzhiyun 6*4882a593Smuzhiyun# Quietly do nothing if /dev/urandom does not exist 7*4882a593Smuzhiyun[ -c /dev/urandom ] || exit 0 8*4882a593Smuzhiyun 9*4882a593SmuzhiyunURANDOM_SEED="/var/lib/random-seed" 10*4882a593Smuzhiyun 11*4882a593Smuzhiyun# shellcheck source=/dev/null 12*4882a593Smuzhiyun[ -r "/etc/default/urandom" ] && . "/etc/default/urandom" 13*4882a593Smuzhiyun 14*4882a593Smuzhiyunif pool_bits=$(cat /proc/sys/kernel/random/poolsize 2> /dev/null); then 15*4882a593Smuzhiyun pool_size=$((pool_bits/8)) 16*4882a593Smuzhiyunelse 17*4882a593Smuzhiyun pool_size=512 18*4882a593Smuzhiyunfi 19*4882a593Smuzhiyun 20*4882a593Smuzhiyuncheck_file_size() { 21*4882a593Smuzhiyun [ -f "$URANDOM_SEED" ] || return 1 22*4882a593Smuzhiyun # Try to read two blocks but exactly one will be read if the file has 23*4882a593Smuzhiyun # the correct size. 24*4882a593Smuzhiyun size=$(dd if="$URANDOM_SEED" bs="$pool_size" count=2 2> /dev/null | wc -c) 25*4882a593Smuzhiyun test "$size" -eq "$pool_size" 26*4882a593Smuzhiyun} 27*4882a593Smuzhiyun 28*4882a593Smuzhiyuninit_rng() { 29*4882a593Smuzhiyun if check_file_size; then 30*4882a593Smuzhiyun printf 'Initializing random number generator: ' 31*4882a593Smuzhiyun dd if="$URANDOM_SEED" bs="$pool_size" of=/dev/urandom count=1 2> /dev/null 32*4882a593Smuzhiyun status=$? 33*4882a593Smuzhiyun if [ "$status" -eq 0 ]; then 34*4882a593Smuzhiyun echo "OK" 35*4882a593Smuzhiyun else 36*4882a593Smuzhiyun echo "FAIL" 37*4882a593Smuzhiyun fi 38*4882a593Smuzhiyun return "$status" 39*4882a593Smuzhiyun fi 40*4882a593Smuzhiyun} 41*4882a593Smuzhiyun 42*4882a593Smuzhiyunsave_random_seed() { 43*4882a593Smuzhiyun printf 'Saving random seed: ' 44*4882a593Smuzhiyun if touch "$URANDOM_SEED" 2> /dev/null; then 45*4882a593Smuzhiyun old_umask=$(umask) 46*4882a593Smuzhiyun umask 077 47*4882a593Smuzhiyun dd if=/dev/urandom of="$URANDOM_SEED" bs="$pool_size" count=1 2> /dev/null 48*4882a593Smuzhiyun status=$? 49*4882a593Smuzhiyun umask "$old_umask" 50*4882a593Smuzhiyun if [ "$status" -eq 0 ]; then 51*4882a593Smuzhiyun echo "OK" 52*4882a593Smuzhiyun else 53*4882a593Smuzhiyun echo "FAIL" 54*4882a593Smuzhiyun fi 55*4882a593Smuzhiyun else 56*4882a593Smuzhiyun status=$? 57*4882a593Smuzhiyun echo "SKIP (read-only file system detected)" 58*4882a593Smuzhiyun fi 59*4882a593Smuzhiyun return "$status" 60*4882a593Smuzhiyun} 61*4882a593Smuzhiyun 62*4882a593Smuzhiyuncase "$1" in 63*4882a593Smuzhiyun start|restart|reload) 64*4882a593Smuzhiyun # Carry a random seed from start-up to start-up 65*4882a593Smuzhiyun # Load and then save the whole entropy pool 66*4882a593Smuzhiyun init_rng && save_random_seed;; 67*4882a593Smuzhiyun stop) 68*4882a593Smuzhiyun # Carry a random seed from shut-down to start-up 69*4882a593Smuzhiyun # Save the whole entropy pool 70*4882a593Smuzhiyun save_random_seed;; 71*4882a593Smuzhiyun *) 72*4882a593Smuzhiyun echo "Usage: $0 {start|stop|restart|reload}" 73*4882a593Smuzhiyun exit 1 74*4882a593Smuzhiyunesac 75