]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - libexec/rc/rc.d/geli
cdn-patch: use key from efi if it exists
[FreeBSD/FreeBSD.git] / libexec / rc / rc.d / geli
1 #!/bin/sh
2 #
3 # Copyright (c) 2005 Pawel Jakub Dawidek <pjd@FreeBSD.org>
4 # All rights reserved.
5 #
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions
8 # are met:
9 # 1. Redistributions of source code must retain the above copyright
10 #    notice, this list of conditions and the following disclaimer.
11 # 2. Redistributions in binary form must reproduce the above copyright
12 #    notice, this list of conditions and the following disclaimer in the
13 #    documentation and/or other materials provided with the distribution.
14 #
15 # THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
16 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 # ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
19 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 # SUCH DAMAGE.
26 #
27 #
28
29 # PROVIDE: disks
30 # KEYWORD: nojail
31
32 . /etc/rc.subr
33
34 name="geli"
35 desc="GELI disk encryption"
36 start_precmd='[ -n "$(geli_make_list)" -o -n "${geli_groups}" ]'
37 start_cmd="geli_start"
38 stop_cmd="geli_stop"
39 required_modules="geom_eli:g_eli"
40
41 # Takes provider
42 # Reads key from EFIvar
43 # Returns tempfile pathname containing key
44 geli_efi()
45 {
46         local provider="${1}"
47         local provider_=`ltr ${provider} '/-' '_'`
48         local guid="65537263-7465-654b-4f79-44666f6f216d"
49
50         eval "efi=\${geli_${provider_}_efi}"
51
52         if checkyesno efi
53         then
54                 efivar="$(printf "%s-%s" "${guid}" "$(echo -n "${provider}" | sha256)")"
55                 tmpkey="$(mktemp "/tmp/efikey_${provider_}")"
56                 efivar --binary --no-name "${efivar}" > "${tmpkey}"
57                 if [ -s "${tmpkey}" ]
58                 then
59                         echo "${tmpkey}"
60                 fi
61         fi
62 }
63
64 geli_efi_init()
65 {
66         mount -t tmpfs tmpfs /tmp
67 }
68
69 geli_efi_fini()
70 {
71         umount -t tmpfs /tmp
72 }
73
74 geli_start()
75 {
76         devices=`geli_make_list`
77
78         if [ -z "${geli_tries}" ]; then
79                 if [ -n "${geli_attach_attempts}" ]; then
80                         # Compatibility with rc.d/gbde.
81                         geli_tries=${geli_attach_attempts}
82                 else
83                         geli_tries=`${SYSCTL_N} kern.geom.eli.tries`
84                 fi
85         fi
86
87         geli_efi_init
88
89         for provider in ${devices}; do
90                 provider_=`ltr ${provider} '/-' '_'`
91
92                 eval "flags=\${geli_${provider_}_flags}"
93                 if [ -z "${flags}" ]; then
94                         flags=${geli_default_flags}
95                 fi
96
97                 efikey="$(geli_efi "${provider}")"
98                 if [ -s "${efikey}" ]
99                 then
100                         echo "Acquired key for ${provider} from EFI."
101                         flags="${flags} -p -k ${efikey}"
102                 fi
103
104                 if [ -e "/dev/${provider}" -a ! -e "/dev/${provider}.eli" ]; then
105                         echo "Configuring Disk Encryption for ${provider}."
106                         count=1
107                         while [ ${count} -le ${geli_tries} ]; do
108                                 geli attach ${flags} ${provider}
109                                 if [ -e "/dev/${provider}.eli" ]; then
110                                         break
111                                 fi
112                                 echo "Attach failed; attempt ${count} of ${geli_tries}."
113                                 count=$((count+1))
114                         done
115                 fi
116         done
117
118         for group in ${geli_groups}; do
119                 group_=`ltr ${group} '/-' '_'`
120
121                 eval "flags=\${geli_${group_}_flags}"
122                 if [ -z "${flags}" ]; then
123                         flags=${geli_default_flags}
124                 fi
125
126                 eval "providers=\${geli_${group_}_devices}"
127                 if [ -z "${providers}" ]; then
128                         echo "No devices listed in geli group ${group}."
129                         continue
130                 fi
131
132                 efikey="$(geli_efi "${group}")"
133                 if [ -s "${efikey}" ]
134                 then
135                         echo "Acquired key for ${group} from EFI."
136                         flags="${flags} -p -k ${efikey}"
137                 fi
138
139                 if [ -e "/dev/${providers%% *}" -a ! -e "/dev/${providers%% *}.eli" ]; then
140                         echo "Configuring Disk Encryption for geli group ${group}, containing ${providers}."
141                         count=1
142                         while [ ${count} -le ${geli_tries} ]; do
143                                 geli attach ${flags} ${providers}
144                                 if [ -e "/dev/${providers%% *}.eli" ]; then
145                                         break
146                                 fi
147                                 echo "Attach failed; attempt ${count} of ${geli_tries}."
148                                 count=$((count+1))
149                         done
150                 fi
151         done
152
153         geli_efi_fini
154 }
155
156 geli_stop()
157 {
158         devices=`geli_make_list`
159
160         for group in ${geli_groups}; do
161                 group_=`ltr ${group} '/-' '_'`
162
163                 eval "providers=\${geli_${group_}_devices}"
164
165                 devices="${devices} ${providers}"
166         done
167
168         for provider in ${devices}; do
169                 if [ -e "/dev/${provider}.eli" ]; then
170                         umount "/dev/${provider}.eli" 2>/dev/null
171                         geli detach "${provider}"
172                 fi
173         done
174 }
175
176 load_rc_config $name
177 run_rc_command "$1"