xref: /freebsd/libexec/rc/rc.d/random (revision 0957b409)
1#!/bin/sh
2#
3# $FreeBSD$
4#
5
6# PROVIDE: random
7# REQUIRE: FILESYSTEMS
8# BEFORE: netif
9# KEYWORD: nojail shutdown
10
11. /etc/rc.subr
12
13name="random"
14desc="Harvest and save entropy for random device"
15start_cmd="random_start"
16stop_cmd="random_stop"
17
18extra_commands="saveseed"
19saveseed_cmd="${name}_stop"
20
21save_dev_random()
22{
23	oumask=`umask`
24	umask 077
25	for f ; do
26		debug "saving entropy to $f"
27		dd if=/dev/random of="$f" bs=4096 count=1 status=none &&
28			chmod 600 "$f"
29	done
30	umask ${oumask}
31}
32
33feed_dev_random()
34{
35	for f ; do
36		if [ -f "$f" -a -r "$f" -a -s "$f" ] ; then
37			if dd if="$f" of=/dev/random bs=4096 2>/dev/null ; then
38				debug "entropy read from $f"
39				rm -f "$f"
40			fi
41		fi
42	done
43}
44
45random_start()
46{
47
48	if [ ${harvest_mask} -gt 0 ]; then
49		echo -n 'Setting up harvesting: '
50		${SYSCTL} kern.random.harvest.mask=${harvest_mask} > /dev/null
51		${SYSCTL_N} kern.random.harvest.mask_symbolic
52	fi
53
54	echo -n 'Feeding entropy: '
55
56	if [ ! -w /dev/random ] ; then
57		warn "/dev/random is not writeable"
58		return 1
59	fi
60
61	# Reseed /dev/random with previously stored entropy.
62	case ${entropy_dir:=/var/db/entropy} in
63	[Nn][Oo])
64		;;
65	*)
66		if [ -d "${entropy_dir}" ] ; then
67			feed_dev_random "${entropy_dir}"/*
68		fi
69		;;
70	esac
71
72	case ${entropy_file:=/entropy} in
73	[Nn][Oo])
74		;;
75	*)
76		feed_dev_random "${entropy_file}" /var/db/entropy-file
77		save_dev_random "${entropy_file}"
78		;;
79	esac
80
81	case ${entropy_boot_file:=/boot/entropy} in
82	[Nn][Oo])
83		;;
84	*)
85		save_dev_random "${entropy_boot_file}"
86		;;
87	esac
88
89	echo '.'
90}
91
92random_stop()
93{
94	# Write some entropy so when the machine reboots /dev/random
95	# can be reseeded
96	#
97	case ${entropy_file:=/entropy} in
98	[Nn][Oo])
99		;;
100	*)
101		echo -n 'Writing entropy file:'
102		rm -f ${entropy_file} 2> /dev/null
103		oumask=`umask`
104		umask 077
105		if touch ${entropy_file} 2> /dev/null; then
106			entropy_file_confirmed="${entropy_file}"
107		else
108			# Try this as a reasonable alternative for read-only
109			# roots, diskless workstations, etc.
110			rm -f /var/db/entropy-file 2> /dev/null
111			if touch /var/db/entropy-file 2> /dev/null; then
112				entropy_file_confirmed=/var/db/entropy-file
113			fi
114		fi
115		case ${entropy_file_confirmed} in
116		'')
117			warn 'write failed (read-only fs?)'
118			;;
119		*)
120			dd if=/dev/random of=${entropy_file_confirmed} \
121			    bs=4096 count=1 2> /dev/null ||
122			    warn 'write failed (unwriteable file or full fs?)'
123			echo '.'
124			;;
125		esac
126		umask ${oumask}
127		;;
128	esac
129	case ${entropy_boot_file:=/boot/entropy} in
130	[Nn][Oo])
131		;;
132	*)
133		echo -n 'Writing early boot entropy file:'
134		rm -f ${entropy_boot_file} 2> /dev/null
135		oumask=`umask`
136		umask 077
137		if touch ${entropy_boot_file} 2> /dev/null; then
138			entropy_boot_file_confirmed="${entropy_boot_file}"
139		fi
140		case ${entropy_boot_file_confirmed} in
141		'')
142			warn 'write failed (read-only fs?)'
143			;;
144		*)
145			dd if=/dev/random of=${entropy_boot_file_confirmed} \
146			    bs=4096 count=1 2> /dev/null ||
147			    warn 'write failed (unwriteable file or full fs?)'
148			echo '.'
149			;;
150		esac
151		umask ${oumask}
152		;;
153	esac
154}
155
156load_rc_config $name
157run_rc_command "$1"
158