1 |
commit: 73a05632d61171685ac4960c6b684cefa6d82afd |
2 |
Author: Dmitry Baranov <reagentoo <AT> gmail <DOT> com> |
3 |
AuthorDate: Wed Oct 14 19:03:01 2020 +0000 |
4 |
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org> |
5 |
CommitDate: Sat Aug 7 17:20:10 2021 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/genkernel.git/commit/?id=73a05632 |
7 |
|
8 |
Add support for LUKS detached header |
9 |
|
10 |
Signed-off-by: Dmitry Baranov <reagentoo <AT> gmail.com> |
11 |
|
12 |
defaults/initrd.scripts | 162 +++++++++++++++++++++++++++++++++++++++++++----- |
13 |
defaults/linuxrc | 18 ++++++ |
14 |
doc/genkernel.8.txt | 22 +++++++ |
15 |
3 files changed, 186 insertions(+), 16 deletions(-) |
16 |
|
17 |
diff --git a/defaults/initrd.scripts b/defaults/initrd.scripts |
18 |
index 33a48b3..5a83d93 100644 |
19 |
--- a/defaults/initrd.scripts |
20 |
+++ b/defaults/initrd.scripts |
21 |
@@ -306,7 +306,7 @@ bootstrapFS() { |
22 |
fi |
23 |
|
24 |
# Setup the filesystem nodes and directories |
25 |
- for i in ${CDROOT_PATH} /mnt/livecd /mnt/key /mnt/gentoo /tmp /tmp/.initrd /dev /proc /run /sys; do |
26 |
+ for i in ${CDROOT_PATH} /mnt/header /mnt/livecd /mnt/key /mnt/gentoo /tmp /tmp/.initrd /dev /proc /run /sys; do |
27 |
run mkdir -p "${NEW_ROOT}${i}" |
28 |
run chmod 755 "${NEW_ROOT}${i}" |
29 |
done |
30 |
@@ -391,6 +391,14 @@ bootstrapCD() { |
31 |
fi |
32 |
} |
33 |
|
34 |
+bootstrapHeader() { |
35 |
+ # $1 = ROOT/SWAP |
36 |
+ local HEADERDEVS=$(devicelist) |
37 |
+ eval local headerloc='"${CRYPT_'${1}'_HEADER}"' |
38 |
+ |
39 |
+ findmediamount "header" "${headerloc}" "CRYPT_${1}_HEADERDEV" "/mnt/header" ${HEADERDEVS} |
40 |
+} |
41 |
+ |
42 |
bootstrapKey() { |
43 |
# $1 = ROOT/SWAP |
44 |
local KEYDEVS=$(devicelist) |
45 |
@@ -1828,12 +1836,17 @@ openLUKS() { |
46 |
|
47 |
local LUKS_NAME="${1}" |
48 |
eval local LUKS_DEVICE='"${CRYPT_'${TYPE}'}"' |
49 |
+ eval local LUKS_HEADER='"${CRYPT_'${TYPE}'_HEADER}"' |
50 |
+ eval local LUKS_HEADERDEV='"${CRYPT_'${TYPE}'_HEADERDEV}"' |
51 |
+ eval local LUKS_HEADERDEV_FSTYPE='"${CRYPT_'${TYPE}'_HEADERDEV_FSTYPE}"' |
52 |
eval local LUKS_KEY='"${CRYPT_'${TYPE}'_KEY}"' |
53 |
eval local LUKS_KEYDEV='"${CRYPT_'${TYPE}'_KEYDEV}"' |
54 |
eval local LUKS_KEYDEV_FSTYPE='"${CRYPT_'${TYPE}'_KEYDEV_FSTYPE}"' |
55 |
eval local OPENED_LOCKFILE='"${CRYPT_'${TYPE}'_OPENED_LOCKFILE}"' |
56 |
- local DEV_ERROR=0 KEY_ERROR=0 KEYDEV_ERROR=0 |
57 |
- local mntkey="/mnt/key/" crypt_filter_ret= |
58 |
+ local DEV_ERROR=0 |
59 |
+ local HEADER_ERROR=0 HEADERDEV_ERROR=0 |
60 |
+ local KEY_ERROR=0 KEYDEV_ERROR=0 |
61 |
+ local mntheader="/mnt/header/" mntkey="/mnt/key/" crypt_filter_ret= |
62 |
|
63 |
if [ -z "${LUKS_DEVICE}" ] |
64 |
then |
65 |
@@ -1853,13 +1866,27 @@ openLUKS() { |
66 |
good_msg "The LUKS device ${LUKS_DEVICE} meanwhile was opened by someone else." |
67 |
break |
68 |
# if crypt_silent=1 and some error occurs, enter shell quietly |
69 |
- elif [ \( ${CRYPT_SILENT} -eq 1 \) -a \( \( \( ${DEV_ERROR} -eq 1 \) -o \( ${KEY_ERROR} -eq 1 \) \) -o \( ${KEYDEV_ERROR} -eq 1 \) \) ] |
70 |
+ elif [ \( ${CRYPT_SILENT} -eq 1 \) -a \( \( \( ${DEV_ERROR} -eq 1 \) \) ] |
71 |
+ then |
72 |
+ run_emergency_shell |
73 |
+ elif [ \( ${CRYPT_SILENT} -eq 1 \) -a \( \( \( ${HEADER_ERROR} -eq 1 \) \) -o \( ${HEADERDEV_ERROR} -eq 1 \) \) ] |
74 |
+ then |
75 |
+ run_emergency_shell |
76 |
+ elif [ \( ${CRYPT_SILENT} -eq 1 \) -a \( \( \( ${KEY_ERROR} -eq 1 \) \) -o \( ${KEYDEV_ERROR} -eq 1 \) \) ] |
77 |
then |
78 |
run_emergency_shell |
79 |
elif [ ${DEV_ERROR} -eq 1 ] |
80 |
then |
81 |
prompt_user "LUKS_DEVICE" "${LUKS_NAME}" |
82 |
DEV_ERROR=0 |
83 |
+ elif [ ${HEADER_ERROR} -eq 1 ] |
84 |
+ then |
85 |
+ prompt_user "LUKS_HEADER" "${LUKS_NAME} header" |
86 |
+ HEADER_ERROR=0 |
87 |
+ elif [ ${HEADERDEV_ERROR} -eq 1 ] |
88 |
+ then |
89 |
+ prompt_user "LUKS_HEADERDEV" "${LUKS_NAME} header device" |
90 |
+ HEADERDEV_ERROR=0 |
91 |
elif [ ${KEY_ERROR} -eq 1 ] |
92 |
then |
93 |
prompt_user "LUKS_KEY" "${LUKS_NAME} key" |
94 |
@@ -1877,18 +1904,93 @@ openLUKS() { |
95 |
continue |
96 |
fi |
97 |
|
98 |
- if ! run cryptsetup isLuks ${LUKS_DEVICE} |
99 |
+ # Handle headers |
100 |
+ if [ -n "${LUKS_HEADER}" ] |
101 |
+ then |
102 |
+ local REAL_LUKS_HEADERDEV="${LUKS_HEADERDEV}" |
103 |
+ if [ ! -e "${mntheader}${LUKS_HEADER}" ] |
104 |
+ then |
105 |
+ REAL_LUKS_HEADERDEV=$(find_real_device "${LUKS_HEADERDEV}") |
106 |
+ if [ -b "${REAL_LUKS_HEADERDEV}" ] |
107 |
+ then |
108 |
+ good_msg "Using header device ${REAL_LUKS_HEADERDEV}." ${CRYPT_SILENT} |
109 |
+ else |
110 |
+ good_msg "Please insert removable device ${LUKS_HEADERDEV} for ${LUKS_NAME}" ${CRYPT_SILENT} |
111 |
+ # abort after 10 secs |
112 |
+ local count=10 |
113 |
+ while [ ${count} -gt 0 ] |
114 |
+ do |
115 |
+ count=$((count-1)) |
116 |
+ sleep 1 |
117 |
+ REAL_LUKS_HEADERDEV=$(find_real_device "${LUKS_HEADERDEV}") |
118 |
+ if [ -b "${REAL_LUKS_HEADERDEV}" ] |
119 |
+ then |
120 |
+ good_msg "Removable device ${REAL_LUKS_HEADERDEV} detected." ${CRYPT_SILENT} |
121 |
+ break |
122 |
+ fi |
123 |
+ done |
124 |
+ if [ ! -b "${REAL_LUKS_HEADERDEV}" ] |
125 |
+ then |
126 |
+ eval CRYPT_${TYPE}_HEADER=${LUKS_HEADER} |
127 |
+ bootstrapHeader ${TYPE} |
128 |
+ eval LUKS_HEADERDEV='"${CRYPT_'${TYPE}'_HEADERDEV}"' |
129 |
+ REAL_LUKS_HEADERDEV=$(find_real_device "${LUKS_HEADERDEV}") |
130 |
+ if [ ! -b "${REAL_LUKS_HEADERDEV}" ] |
131 |
+ then |
132 |
+ HEADERDEV_ERROR=1 |
133 |
+ bad_msg "Removable device ${LUKS_HEADERDEV} not found." ${CRYPT_SILENT} |
134 |
+ continue |
135 |
+ fi |
136 |
+ # continue otherwise will mount headerdev which is mounted by bootstrap |
137 |
+ continue |
138 |
+ fi |
139 |
+ fi |
140 |
+ |
141 |
+ # At this point a device was recognized, now let's see if the header is there |
142 |
+ [ ! -d "${mntheader}" ] && mkdir -p "${mntheader}" >/dev/null 2>&1 |
143 |
+ |
144 |
+ # determine fs -- 'auto' will not trigger module loading! |
145 |
+ LUKS_HEADERDEV_FSTYPE=$(determine_fs "${REAL_LUKS_HEADERDEV}" "${LUKS_HEADERDEV_FSTYPE}") |
146 |
+ |
147 |
+ if ! run mount -n -t ${LUKS_HEADERDEV_FSTYPE} -o ro ${REAL_LUKS_HEADERDEV} ${mntheader} >/dev/null 2>&1 |
148 |
+ then |
149 |
+ HEADERDEV_ERROR=1 |
150 |
+ bad_msg "Mounting of device ${REAL_LUKS_HEADERDEV} failed." ${CRYPT_SILENT} |
151 |
+ continue |
152 |
+ fi |
153 |
+ |
154 |
+ good_msg "Removable device ${REAL_LUKS_HEADERDEV} mounted." ${CRYPT_SILENT} |
155 |
+ sleep 2 |
156 |
+ |
157 |
+ # headerfile exists? |
158 |
+ if [ ! -e "${mntheader}${LUKS_HEADER}" ] |
159 |
+ then |
160 |
+ run umount -n "${mntheader}" >/dev/null 2>&1 |
161 |
+ HEADER_ERROR=1 |
162 |
+ HEADERDEV_ERROR=1 |
163 |
+ bad_msg "Header {LUKS_HEADER} on device ${REAL_LUKS_HEADERDEV} not found." ${CRYPT_SILENT} |
164 |
+ continue |
165 |
+ fi |
166 |
+ fi |
167 |
+ |
168 |
+ if ! run cryptsetup isLuks ${LUKS_DEVICE} --header ${mntheader}${LUKS_HEADER} |
169 |
+ then |
170 |
+ bad_msg "The LUKS device ${LUKS_DEVICE} does not contain a LUKS header" ${CRYPT_SILENT} |
171 |
+ DEV_ERROR=1 |
172 |
+ continue |
173 |
+ fi |
174 |
+ |
175 |
+ # At this point a candidate header exists (either mounted before or not) |
176 |
+ good_msg "${LUKS_HEADER} on device ${REAL_LUKS_HEADERDEV} found" ${CRYPT_SILENT} |
177 |
+ |
178 |
+ cryptsetup_options="${cryptsetup_options} --header ${mntheader}${LUKS_HEADER}" |
179 |
+ elif ! run cryptsetup isLuks ${LUKS_DEVICE} |
180 |
then |
181 |
bad_msg "The LUKS device ${LUKS_DEVICE} does not contain a LUKS header" ${CRYPT_SILENT} |
182 |
DEV_ERROR=1 |
183 |
continue |
184 |
fi |
185 |
|
186 |
- if [ -n "${cryptsetup_options}" ] |
187 |
- then |
188 |
- good_msg "Using the following cryptsetup options for ${LUKS_NAME}: ${cryptsetup_options}" ${CRYPT_SILENT} |
189 |
- fi |
190 |
- |
191 |
# Handle keys |
192 |
if [ -n "${LUKS_KEY}" ] |
193 |
then |
194 |
@@ -1946,6 +2048,7 @@ openLUKS() { |
195 |
|
196 |
good_msg "Removable device ${REAL_LUKS_KEYDEV} mounted." ${CRYPT_SILENT} |
197 |
sleep 2 |
198 |
+ |
199 |
# keyfile exists? |
200 |
if [ ! -e "${mntkey}${LUKS_KEY}" ] |
201 |
then |
202 |
@@ -1956,6 +2059,7 @@ openLUKS() { |
203 |
continue |
204 |
fi |
205 |
fi |
206 |
+ |
207 |
# At this point a candidate key exists (either mounted before or not) |
208 |
good_msg "${LUKS_KEY} on device ${REAL_LUKS_KEYDEV} found" ${CRYPT_SILENT} |
209 |
|
210 |
@@ -1975,7 +2079,13 @@ openLUKS() { |
211 |
cryptsetup_options="${cryptsetup_options} -d ${mntkey}${LUKS_KEY}" |
212 |
fi |
213 |
fi |
214 |
- # At this point, keyfile or not, we're ready! |
215 |
+ |
216 |
+ if [ -n "${cryptsetup_options}" ] |
217 |
+ then |
218 |
+ good_msg "Using the following cryptsetup options for ${LUKS_NAME}: ${cryptsetup_options}" ${CRYPT_SILENT} |
219 |
+ fi |
220 |
+ |
221 |
+ # At this point, {header,key}file or not, we're ready! |
222 |
crypt_filter "${gpg_cmd}cryptsetup ${cryptsetup_options} luksOpen ${LUKS_DEVICE} ${LUKS_NAME}" |
223 |
crypt_filter_ret=$? |
224 |
|
225 |
@@ -1992,6 +2102,8 @@ openLUKS() { |
226 |
then |
227 |
bad_msg "Failed to open LUKS device ${LUKS_DEVICE}" ${CRYPT_SILENT} |
228 |
DEV_ERROR=1 |
229 |
+ HEADER_ERROR=1 |
230 |
+ HEADERDEV_ERROR=1 |
231 |
KEY_ERROR=1 |
232 |
KEYDEV_ERROR=1 |
233 |
fi |
234 |
@@ -2000,11 +2112,17 @@ openLUKS() { |
235 |
|
236 |
udevsettle |
237 |
|
238 |
+ if run mountpoint "${mntheader}" >/dev/null 2>&1 |
239 |
+ then |
240 |
+ run umount "${mntheader}" >/dev/null 2>&1 |
241 |
+ fi |
242 |
+ |
243 |
if run mountpoint "${mntkey}" >/dev/null 2>&1 |
244 |
then |
245 |
run umount "${mntkey}" >/dev/null 2>&1 |
246 |
fi |
247 |
|
248 |
+ [ -d "${mntheader}" ] && run rmdir -p "${mntheader}" >/dev/null 2>&1 |
249 |
[ -d "${mntkey}" ] && run rmdir -p "${mntkey}" >/dev/null 2>&1 |
250 |
} |
251 |
|
252 |
@@ -2341,8 +2459,14 @@ start_LUKS() { |
253 |
# if key is set but neither ssh enabled or key device is given, find |
254 |
# the key device |
255 |
|
256 |
- [ -n "${CRYPT_ROOT_KEY}" ] && [ -z "${CRYPT_ROOT_KEYDEV}" ] \ |
257 |
- && sleep 6 && bootstrapKey "ROOT" |
258 |
+ if [ -n "${CRYPT_ROOT_KEY}" ] |
259 |
+ then |
260 |
+ ( [ -z "${CRYPT_ROOT_KEYDEV}" ] || [ -z "${CRYPT_ROOT_HEADERDEV}" ] ) \ |
261 |
+ && sleep 6 |
262 |
+ |
263 |
+ [ -z "${CRYPT_ROOT_KEYDEV}" ] && bootstrapKey "ROOT" |
264 |
+ [ -z "${CRYPT_ROOT_HEADERDEV}" ] && bootstrapHeader "ROOT" |
265 |
+ fi |
266 |
|
267 |
if [ -n "${CRYPT_ROOT}" ] |
268 |
then |
269 |
@@ -2356,9 +2480,15 @@ start_LUKS() { |
270 |
fi |
271 |
fi |
272 |
|
273 |
- # same for swap, but no need to sleep if root was unencrypted |
274 |
- [ -n "${CRYPT_SWAP_KEY}" ] && [ -z "${CRYPT_SWAP_KEYDEV}" ] \ |
275 |
- && { [ -z "${CRYPT_ROOT}" ] && sleep 6; bootstrapKey "SWAP"; } |
276 |
+ if [ -n "${CRYPT_SWAP_KEY}" ] |
277 |
+ then |
278 |
+ # same for swap, but no need to sleep if root was unencrypted |
279 |
+ ( [ -z "${CRYPT_ROOT_KEYDEV}" ] || [ -z "${CRYPT_ROOT_HEADERDEV}" ] ) \ |
280 |
+ && [ -z "${CRYPT_ROOT}" ] && sleep 6 |
281 |
+ |
282 |
+ [ -z "${CRYPT_SWAP_KEYDEV}" ] && bootstrapKey "SWAP" |
283 |
+ [ -z "${CRYPT_SWAP_HEADERDEV}" ] && bootstrapHeader "SWAP" |
284 |
+ fi |
285 |
|
286 |
if [ -n "${CRYPT_SWAP}" ] |
287 |
then |
288 |
|
289 |
diff --git a/defaults/linuxrc b/defaults/linuxrc |
290 |
index 6ede740..ff08ba2 100644 |
291 |
--- a/defaults/linuxrc |
292 |
+++ b/defaults/linuxrc |
293 |
@@ -228,6 +228,15 @@ do |
294 |
crypt_swap_options=*) |
295 |
CRYPT_SWAP_OPTIONS=$(echo ${CRYPT_SWAP_OPTIONS} ${x#*=} | sed -e 's/,/ /g') |
296 |
;; |
297 |
+ root_header=*) |
298 |
+ CRYPT_ROOT_HEADER=${x#*=} |
299 |
+ ;; |
300 |
+ root_headerdev=*) |
301 |
+ CRYPT_ROOT_HEADERDEV=${x#*=} |
302 |
+ ;; |
303 |
+ root_headerdev_fstype=*) |
304 |
+ CRYPT_ROOT_HEADERDEV_FSTYPE=${x#*=} |
305 |
+ ;; |
306 |
root_key=*) |
307 |
CRYPT_ROOT_KEY=${x#*=} |
308 |
;; |
309 |
@@ -245,6 +254,15 @@ do |
310 |
fi |
311 |
unset tmp_enabled |
312 |
;; |
313 |
+ swap_header=*) |
314 |
+ CRYPT_SWAP_HEADER=${x#*=} |
315 |
+ ;; |
316 |
+ swap_headerdev=*) |
317 |
+ CRYPT_SWAP_HEADERDEV=${x#*=} |
318 |
+ ;; |
319 |
+ swap_headerdev_fstype=*) |
320 |
+ CRYPT_SWAP_HEADERDEV_FSTYPE=${x#*=} |
321 |
+ ;; |
322 |
swap_key=*) |
323 |
CRYPT_SWAP_KEY=${x#*=} |
324 |
;; |
325 |
|
326 |
diff --git a/doc/genkernel.8.txt b/doc/genkernel.8.txt |
327 |
index 262027b..33f7733 100644 |
328 |
--- a/doc/genkernel.8.txt |
329 |
+++ b/doc/genkernel.8.txt |
330 |
@@ -688,6 +688,19 @@ recognized by the kernel itself. |
331 |
cryptsetup when opening swap volume. Can be specified multiple |
332 |
times or separate multiple options with a comma. |
333 |
|
334 |
+*root_header*=<...>:: |
335 |
+ In case your encrypted root uses a LUKS detached header, you can |
336 |
+ use a device like a usb pen to store the header file. This value |
337 |
+ should be the key path relative to the mount point. |
338 |
+ |
339 |
+*root_headerdev*=<...>:: |
340 |
+ If necessary provide the name of the device that carries the |
341 |
+ root_header. If unset while using root_header, it will automatically |
342 |
+ look for the device in every boot. |
343 |
+ |
344 |
+*root_headerdev_fstype*=<...>:: |
345 |
+ Used filesystem for *root_headerdev*. See *rootfstype* for more details. |
346 |
+ |
347 |
*root_key*=<...>:: |
348 |
In case your root is encrypted with a key, you can use a device |
349 |
like a usb pen to store the key. This value should be the key |
350 |
@@ -706,6 +719,15 @@ recognized by the kernel itself. |
351 |
with SSD setups. Have a look at 'https://en.wikipedia.org/wiki/TRIM' |
352 |
for more information. |
353 |
|
354 |
+*swap_header*=<...>:: |
355 |
+ Same as root_header for swap. |
356 |
+ |
357 |
+*swap_headerdev*=<...>:: |
358 |
+ Same as root_headerdev for swap. |
359 |
+ |
360 |
+*swap_headerdev_fstype*=<...>:: |
361 |
+ Used filesystem for *swap_headerdev*. See *rootfstype* for more details. |
362 |
+ |
363 |
*swap_key*=<...>:: |
364 |
Same as root_key for swap. |