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