]>
Commit | Line | Data |
---|---|---|
8d07ddab | 1 | #!/bin/sh |
8d07ddab | 2 | # geninitrd mod: cryptsetup luks |
6e49b0b1 | 3 | USE_LUKS=${USE_LUKS:-yes} |
8d07ddab ER |
4 | |
5 | # true if root device is crypted with cryptsetup luks | |
6 | # and we should init cryptsetup luks at boot | |
7 | have_luks=no | |
8 | ||
8d07ddab | 9 | # device to use for name for cryptsetup luks |
704c497d | 10 | LUKSNAME="" |
8d07ddab | 11 | |
c124d0cf ER |
12 | # setup geninitrd module |
13 | # @access public | |
14 | setup_mod_luks() { | |
15 | cryptsetup=$(find_tool $initrd_dir/cryptsetup /sbin/cryptsetup-initrd) | |
6e49b0b1 ER |
16 | |
17 | if [ ! -x /sbin/cryptsetup ] || [ ! -x "$cryptsetup" ]; then | |
c124d0cf ER |
18 | USE_LUKS=no |
19 | fi | |
20 | } | |
21 | ||
8d07ddab ER |
22 | # return true if node is cryptsetup luks encrypted |
23 | # @param string $node device node to be examined | |
24 | # @access public | |
25 | is_luks() { | |
26 | local node="$1" | |
f7385874 ER |
27 | |
28 | # luks not wanted | |
29 | if is_no "$USE_LUKS"; then | |
30 | return 1 | |
31 | fi | |
32 | ||
a5b35f50 | 33 | local dev dm_name=${node#/dev/mapper/} |
8d07ddab | 34 | if [ "$node" = "$dm_name" ]; then |
02ba8ab7 | 35 | verbose "is_luks: $node is not device mapper name" |
8d07ddab ER |
36 | return 1 |
37 | fi | |
b892656c ER |
38 | |
39 | dev=$(awk -vdm_name="$dm_name" '$1 == dm_name { print $2 }' /etc/crypttab) | |
1d96f045 | 40 | if [ "$dev" ]; then |
52c1e558 | 41 | dev=$(find_devname "$dev") |
1d96f045 ER |
42 | /sbin/cryptsetup isLuks $dev |
43 | rc=$? | |
44 | else | |
a5b35f50 | 45 | rc=1 |
1d96f045 | 46 | fi |
8d07ddab ER |
47 | |
48 | if [ $rc = 0 ]; then | |
02ba8ab7 | 49 | verbose "is_luks: $node is cryptsetup luks" |
8d07ddab | 50 | else |
02ba8ab7 | 51 | verbose "is_luks: $node is not cryptsetup luks" |
8d07ddab ER |
52 | fi |
53 | return $rc | |
54 | } | |
55 | ||
56 | # find modules for $devpath | |
57 | # @param $devpath device to be examined | |
58 | # @access public | |
59 | find_modules_luks() { | |
60 | local devpath="$1" | |
704c497d | 61 | local dev="" |
f4dd815d | 62 | |
704c497d | 63 | LUKSNAME=${devpath#/dev/mapper/} |
8d07ddab | 64 | |
b02a6b13 | 65 | find_module "dm-crypt" |
8d07ddab ER |
66 | |
67 | # TODO: autodetect | |
640d6c7b AM |
68 | find_module "-aes" |
69 | find_module "-cbc" | |
21323b94 JP |
70 | find_module "-cbc(aes)" |
71 | find_module "-xts(aes)" | |
32b9509d AM |
72 | find_module "-af-alg" |
73 | find_module "-algif_hash" | |
74 | find_module "-algif_skcipher" | |
75 | find_module "-loop" | |
8d07ddab | 76 | |
8d07ddab | 77 | # recurse |
b892656c ER |
78 | dev=$(awk -vLUKSNAME="$LUKSNAME" '$1 == LUKSNAME { print $2 }' /etc/crypttab) |
79 | if [ -n "$dev" ]; then | |
52c1e558 | 80 | dev=$(find_devname "$dev") |
704c497d JK |
81 | find_modules_for_devpath $dev |
82 | have_luks=yes | |
83 | else | |
84 | die "Cannot find '$LUKSNAME' in /etc/crypttab" | |
85 | fi | |
8d07ddab ER |
86 | } |
87 | ||
88 | ||
89 | # generate initrd fragment for cryptsetup luks init | |
90 | # @access public | |
91 | initrd_gen_luks() { | |
1b481849 ER |
92 | if ! is_yes "$have_luks"; then |
93 | return | |
94 | fi | |
95 | ||
8d07ddab | 96 | inst_d /bin |
684d5d2a | 97 | inst_exec $cryptsetup /bin/cryptsetup |
99634b92 | 98 | inst_d /var/run/cryptsetup |
8d07ddab ER |
99 | |
100 | mount_dev | |
101 | mount_sys | |
102 | initrd_gen_devices | |
103 | # TODO: 'udevadm settle' is called by lukssetup, is udev optional? | |
104 | ||
02ba8ab7 | 105 | verbose "luks: process /etc/crypttab $LUKSNAME" |
704c497d | 106 | luks_crypttab $LUKSNAME |
8d07ddab ER |
107 | } |
108 | ||
109 | ||
110 | # PRIVATE METHODS | |
111 | key_is_random() { | |
112 | [ "$1" = "/dev/urandom" -o "$1" = "/dev/hw_random" -o "$1" = "/dev/random" ] | |
113 | } | |
114 | ||
115 | # produce cryptsetup from $name from /etc/crypttab | |
116 | luks_crypttab() { | |
704c497d | 117 | local LUKSNAME="$1" |
8d07ddab ER |
118 | |
119 | # copy from /etc/rc.d/init.d/cryptsetup | |
ddf87c79 | 120 | local dst src key opt mode owner failsafe token libdir cryptdir |
8d07ddab ER |
121 | |
122 | while read dst src key opt; do | |
704c497d | 123 | [ "$dst" != "$LUKSNAME" ] && continue |
8d07ddab | 124 | |
a043f983 JP |
125 | failsafe="" |
126 | ||
127 | if [ -z "$key" ] || [ "x$key" = "xnone" ] || [ "x$key" = "x-" ]; then | |
128 | failsafe=1 | |
129 | key="/etc/cryptsetup-keys.d/$LUKSNAME.key" | |
130 | fi | |
131 | ||
132 | if test -e "$key" ; then | |
133 | mode=$(LC_ALL=C ls -l "$key" | cut -c 5-10) | |
134 | owner=$(LC_ALL=C ls -l $key | awk '{ print $3 }') | |
135 | if [ "$mode" != "------" ] && ! key_is_random "$key"; then | |
136 | die "INSECURE MODE FOR $key" | |
8d07ddab | 137 | fi |
a043f983 JP |
138 | if [ "$owner" != root ]; then |
139 | die "INSECURE OWNER FOR $key" | |
140 | fi | |
141 | elif [ -n "$failsafe" ]; then | |
8d07ddab | 142 | key="" |
a043f983 JP |
143 | else |
144 | die "Key file for $dst not found" | |
8d07ddab ER |
145 | fi |
146 | ||
52c1e558 | 147 | src=$(find_devname "$src") |
8d07ddab ER |
148 | if /sbin/cryptsetup isLuks "$src" 2>/dev/null; then |
149 | if key_is_random "$key"; then | |
150 | die "$dst: LUKS requires non-random key, skipping" | |
151 | fi | |
8d07ddab ER |
152 | if [ "$key" ]; then |
153 | keyfile=/etc/.$dst.key | |
154 | inst $key $keyfile | |
155 | fi | |
ddf87c79 JP |
156 | for libdir in $(get_libdir /usr/LIBDIR); do |
157 | if [ -d $libdir/cryptsetup ]; then | |
158 | cryptdir=$libdir/cryptsetup | |
159 | break | |
160 | fi | |
161 | done | |
162 | if ! is_no "$USE_LUKS_TOKEN" && [ -n "$cryptdir" ]; then | |
163 | for token in $(/sbin/cryptsetup luksDump $src | sed -n -e '/^Tokens:/,/^[^[:space:]]/ { /^[[:space:]]*[[:digit:]]*:/ { s/^[[:space:]]*[[:digit:]]*:[[:space:]]*// p } }'); do | |
164 | verbose "Found cryptsetup token: $token" | |
165 | case "$token" in | |
166 | systemd-fido2) | |
167 | inst_d $cryptdir | |
168 | inst_exec $cryptdir/libcryptsetup-token-$token.so $cryptdir | |
169 | inst_exec $libdir/libfido2.so.1 $libdir | |
170 | ;; | |
171 | systemd-tpm2) | |
172 | inst_d $cryptdir | |
173 | inst_exec $cryptdir/libcryptsetup-token-$token.so $cryptdir | |
174 | inst_exec $libdir/libtss2-esys.so.0 $libdir/libtss2-rc.so.0 $libdir/libtss2-mu.so.0 $libdir | |
175 | ;; | |
176 | *) | |
177 | inst_d $cryptdir | |
178 | inst_exec $cryptdir/libcryptsetup-token-$token.so $cryptdir | |
179 | ;; | |
180 | esac | |
181 | done | |
182 | fi | |
8d07ddab | 183 | |
7fcd846e AM |
184 | crypttab_opt="" |
185 | old_IFS="$IFS" | |
186 | IFS="," | |
187 | for option in $opt; do | |
188 | case "$option" in | |
189 | discard|allow-discards) | |
190 | crypttab_opt="$crypttab_opt --allow-discards" | |
191 | ;; | |
192 | *) | |
3b3df72d | 193 | warn "$dst: option \'$option\' is unsupported for LUKS partitions, ignored" |
7fcd846e AM |
194 | ;; |
195 | esac | |
196 | done | |
197 | IFS="$old_IFS" | |
198 | ||
ad5033d7 | 199 | verbose "+ cryptsetup ${keyfile:+-d $keyfile} open $crypttab_opt '$src' '$dst'" |
8d07ddab | 200 | add_linuxrc <<-EOF |
932f5d44 AM |
201 | debugshell |
202 | ||
203 | cryptsetup_opt="" | |
204 | if [ "\$DEBUGINITRD" ]; then | |
205 | cryptsetup_opt="--debug" | |
206 | fi | |
2fcb6fc5 AM |
207 | # cryptsetup can be called twice and in case on crypt on lvm only second |
208 | # will succeed because there will be no src device in first cryptsetup call | |
209 | # this can be called multiple times, before lvm and after lvm. | |
cb006694 AF |
210 | luksdev='$src' |
211 | if [ \${luksdev##/dev/disk/by-uuid/} != \${luksdev} ]; then | |
212 | src_uuid=\${luksdev##/dev/disk/by-uuid/} | |
213 | while read x y z name; do | |
932f5d44 | 214 | found_uuid=\$(cryptsetup \$cryptsetup_opt luksUUID /dev/\${name} 2>/dev/null) |
cb006694 AF |
215 | if [ "\$found_uuid" = "\$src_uuid" ]; then |
216 | luksdev=/dev/\$name | |
217 | break | |
218 | fi | |
219 | done < /proc/partitions | |
220 | fi | |
221 | ||
222 | if [ -e "\$luksdev" ]; then | |
932f5d44 | 223 | crypt_status=\$(cryptsetup \$cryptsetup_opt status '$dst') |
4fa03792 | 224 | if [ "\${crypt_status%%is inactive*}" != "\$crypt_status" ]; then |
2fcb6fc5 | 225 | # is inactive |
ad5033d7 | 226 | cryptsetup \$cryptsetup_opt ${keyfile:+-d $keyfile} open $crypttab_opt "\$luksdev" '$dst' <&1 |
2fcb6fc5 | 227 | fi |
abce1a7f | 228 | fi |
8d07ddab ER |
229 | |
230 | debugshell | |
231 | EOF | |
232 | else | |
233 | die "$dst: only LUKS encryption supported" | |
234 | fi | |
235 | done < /etc/crypttab | |
236 | } |