#! /bin/sh
#
# Preserve the random seed between reboots. See urandom(4).
#

# Quietly do nothing if /dev/urandom does not exist
[ -c /dev/urandom ] || exit 0

URANDOM_SEED="/var/lib/random-seed"

# shellcheck source=/dev/null
[ -r "/etc/default/urandom" ] && . "/etc/default/urandom"

if pool_bits=$(cat /proc/sys/kernel/random/poolsize 2> /dev/null); then
	pool_size=$((pool_bits/8))
else
	pool_size=512
fi

init_rng() {
	[ -f "$URANDOM_SEED" ] || return 0
	printf 'Initializing random number generator: '
	dd if="$URANDOM_SEED" bs="$pool_size" of=/dev/urandom count=1 2> /dev/null
	status=$?
	if [ "$status" -eq 0 ]; then
		echo "OK"
	else
		echo "FAIL"
	fi
	return "$status"
}

save_random_seed() {
	printf 'Saving random seed: '
	status=1
	if touch "$URANDOM_SEED.new" 2> /dev/null; then
		old_umask=$(umask)
		umask 077
		dd if=/dev/urandom of="$URANDOM_SEED.tmp" bs="$pool_size" count=1 2> /dev/null
		cat "$URANDOM_SEED" "$URANDOM_SEED.tmp" 2>/dev/null \
			| sha256sum \
			| cut -d ' ' -f 1 > "$URANDOM_SEED.new" && \
		mv "$URANDOM_SEED.new" "$URANDOM_SEED" && status=0
		rm -f "$URANDOM_SEED.tmp"
		umask "$old_umask"
		if [ "$status" -eq 0 ]; then
			echo "OK"
		else
			echo "FAIL"
		fi

	else
		echo "SKIP (read-only file system detected)"
	fi
	return "$status"
}

case "$1" in
	start|restart|reload)
		# Carry a random seed from start-up to start-up
		# Load and then save the whole entropy pool
		init_rng && save_random_seed;;
	stop)
		# Carry a random seed from shut-down to start-up
		# Save the whole entropy pool
		save_random_seed;;
	*)
		echo "Usage: $0 {start|stop|restart|reload}"
		exit 1
esac
