xref: /freebsd/libexec/rc/rc.d/random (revision d43fa8ef534ac87a16843d45264f56cf11e0fcbc)
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			( chflags nodump "$f" 2>/dev/null || : ) &&
29			chmod 600 "$f" &&
30			fsync "$f" "$(dirname "$f")"
31	done
32	umask ${oumask}
33}
34
35feed_dev_random()
36{
37	for f ; do
38		if [ -f "$f" -a -r "$f" -a -s "$f" ] ; then
39			if dd if="$f" of=/dev/random bs=4096 2>/dev/null ; then
40				debug "entropy read from $f"
41				rm -f "$f"
42			fi
43		fi
44	done
45}
46
47random_start()
48{
49
50	if [ -n "${harvest_mask}" ]; then
51		echo -n 'Setting up harvesting: '
52		${SYSCTL} kern.random.harvest.mask=${harvest_mask} > /dev/null
53		${SYSCTL_N} kern.random.harvest.mask_symbolic
54	fi
55
56	echo -n 'Feeding entropy: '
57
58	if [ ! -w /dev/random ] ; then
59		warn "/dev/random is not writeable"
60		return 1
61	fi
62
63	# Reseed /dev/random with previously stored entropy.
64	case ${entropy_dir:=/var/db/entropy} in
65	[Nn][Oo])
66		;;
67	*)
68		if [ -d "${entropy_dir}" ] ; then
69			feed_dev_random "${entropy_dir}"/*
70		fi
71		;;
72	esac
73
74	case ${entropy_file:=/entropy} in
75	[Nn][Oo])
76		;;
77	*)
78		feed_dev_random "${entropy_file}" /var/db/entropy-file
79		save_dev_random "${entropy_file}"
80		;;
81	esac
82
83	case ${entropy_boot_file:=/boot/entropy} in
84	[Nn][Oo])
85		;;
86	*)
87		save_dev_random "${entropy_boot_file}"
88		;;
89	esac
90
91	echo '.'
92}
93
94random_stop()
95{
96	# Write some entropy so when the machine reboots /dev/random
97	# can be reseeded
98	#
99	case ${entropy_file:=/entropy} in
100	[Nn][Oo])
101		;;
102	*)
103		echo -n 'Writing entropy file: '
104		rm -f ${entropy_file} 2> /dev/null
105		oumask=`umask`
106		umask 077
107		if touch ${entropy_file} 2> /dev/null; then
108			entropy_file_confirmed="${entropy_file}"
109		else
110			# Try this as a reasonable alternative for read-only
111			# roots, diskless workstations, etc.
112			rm -f /var/db/entropy-file 2> /dev/null
113			if touch /var/db/entropy-file 2> /dev/null; then
114				entropy_file_confirmed=/var/db/entropy-file
115			fi
116		fi
117		case ${entropy_file_confirmed} in
118		'')
119			warn 'write failed (read-only fs?)'
120			;;
121		*)
122			save_dev_random "${entropy_file_confirmed}"
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			save_dev_random "${entropy_boot_file_confirmed}"
146			echo '.'
147			;;
148		esac
149		umask ${oumask}
150		;;
151	esac
152}
153
154load_rc_config $name
155run_rc_command "$1"
156