2 # geninitrd mod: cryptsetup luks
3 USE_LUKS=${USE_LUKS:-yes}
5 # true if root device is crypted with cryptsetup luks
6 # and we should init cryptsetup luks at boot
9 # device to use for name for cryptsetup luks
12 # setup geninitrd module
15 cryptsetup=$(find_tool $initrd_dir/cryptsetup /sbin/cryptsetup-initrd)
17 if [ ! -x /sbin/cryptsetup ] || [ ! -x "$cryptsetup" ]; then
22 # return true if node is cryptsetup luks encrypted
23 # @param string $node device node to be examined
29 if is_no "$USE_LUKS"; then
33 local dev dm_name=${node#/dev/mapper/}
34 if [ "$node" = "$dm_name" ]; then
35 verbose "is_luks: $node is not device mapper name"
39 dev=$(awk -vdm_name="$dm_name" '$1 == dm_name { print $2 }' /etc/crypttab)
41 dev=$(find_devname "$dev")
42 /sbin/cryptsetup isLuks $dev
49 verbose "is_luks: $node is cryptsetup luks"
51 verbose "is_luks: $node is not cryptsetup luks"
56 # find modules for $devpath
57 # @param $devpath device to be examined
63 LUKSNAME=${devpath#/dev/mapper/}
65 find_module "dm-crypt"
70 find_module "-cbc(aes)"
71 find_module "-xts(aes)"
73 find_module "-algif_hash"
74 find_module "-algif_skcipher"
78 dev=$(awk -vLUKSNAME="$LUKSNAME" '$1 == LUKSNAME { print $2 }' /etc/crypttab)
79 if [ -n "$dev" ]; then
80 dev=$(find_devname "$dev")
81 find_modules_for_devpath $dev
84 die "Cannot find '$LUKSNAME' in /etc/crypttab"
89 # generate initrd fragment for cryptsetup luks init
92 if ! is_yes "$have_luks"; then
97 inst_exec $cryptsetup /bin/cryptsetup
98 inst_d /var/run/cryptsetup
103 # TODO: 'udevadm settle' is called by lukssetup, is udev optional?
105 verbose "luks: process /etc/crypttab $LUKSNAME"
106 luks_crypttab $LUKSNAME
112 [ "$1" = "/dev/urandom" -o "$1" = "/dev/hw_random" -o "$1" = "/dev/random" ]
115 # produce cryptsetup from $name from /etc/crypttab
119 # copy from /etc/rc.d/init.d/cryptsetup
120 local dst src key opt mode owner failsafe token libdir cryptdir
122 while read dst src key opt; do
123 [ "$dst" != "$LUKSNAME" ] && continue
127 if [ -z "$key" ] || [ "x$key" = "xnone" ] || [ "x$key" = "x-" ]; then
129 key="/etc/cryptsetup-keys.d/$LUKSNAME.key"
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"
138 if [ "$owner" != root ]; then
139 die "INSECURE OWNER FOR $key"
141 elif [ -n "$failsafe" ]; then
144 die "Key file for $dst not found"
147 src=$(find_devname "$src")
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"
153 keyfile=/etc/.$dst.key
156 for libdir in $(get_libdir /usr/LIBDIR); do
157 if [ -d $libdir/cryptsetup ]; then
158 cryptdir=$libdir/cryptsetup
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"
168 inst_exec $cryptdir/libcryptsetup-token-$token.so $cryptdir
169 inst_exec $libdir/libfido2.so.1 $libdir
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
178 inst_exec $cryptdir/libcryptsetup-token-$token.so $cryptdir
187 for option in $opt; do
189 discard|allow-discards)
190 crypttab_opt="$crypttab_opt --allow-discards"
193 warn "$dst: option \'$option\' is unsupported for LUKS partitions, ignored"
199 verbose "+ cryptsetup ${keyfile:+-d $keyfile} open $crypttab_opt '$src' '$dst'"
204 if [ "\$DEBUGINITRD" ]; then
205 cryptsetup_opt="--debug"
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.
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
214 found_uuid=\$(cryptsetup \$cryptsetup_opt luksUUID /dev/\${name} 2>/dev/null)
215 if [ "\$found_uuid" = "\$src_uuid" ]; then
219 done < /proc/partitions
222 if [ -e "\$luksdev" ]; then
223 crypt_status=\$(cryptsetup \$cryptsetup_opt status '$dst')
224 if [ "\${crypt_status%%is inactive*}" != "\$crypt_status" ]; then
226 cryptsetup \$cryptsetup_opt ${keyfile:+-d $keyfile} open $crypttab_opt "\$luksdev" '$dst' <&1
233 die "$dst: only LUKS encryption supported"