]> git.pld-linux.org Git - packages/cryptsetup-luks.git/commitdiff
- support for initramfs-tools
authorJan Rękorajski <baggins@pld-linux.org>
Thu, 26 Feb 2009 14:29:05 +0000 (14:29 +0000)
committercvs2git <feedback@pld-linux.org>
Sun, 24 Jun 2012 12:13:13 +0000 (12:13 +0000)
Changed files:
    cryptsetup-luks-initramfs-README -> 1.1
    cryptsetup-luks-initramfs-passdev-hook -> 1.1
    cryptsetup-luks-initramfs-root-conf -> 1.1
    cryptsetup-luks-initramfs-root-hook -> 1.1
    cryptsetup-luks-initramfs-root-local-top -> 1.1

cryptsetup-luks-initramfs-README [new file with mode: 0644]
cryptsetup-luks-initramfs-passdev-hook [new file with mode: 0644]
cryptsetup-luks-initramfs-root-conf [new file with mode: 0644]
cryptsetup-luks-initramfs-root-hook [new file with mode: 0644]
cryptsetup-luks-initramfs-root-local-top [new file with mode: 0644]

diff --git a/cryptsetup-luks-initramfs-README b/cryptsetup-luks-initramfs-README
new file mode 100644 (file)
index 0000000..245fe36
--- /dev/null
@@ -0,0 +1,194 @@
+1. Introduction
+---------------
+Kernels more recent than 2.6.12 have dropped support for devfs, which
+means that initrd-tools can no longer be used to boot into an encrypted
+root partition. Instead, a similar functionality has been developed for 
+use with an initramfs-image.
+
+
+2. A fresh installation
+-----------------------
+If you plan to perform a completely new installation of Debian onto a 
+machine and to do so using an encrypted root partition, you might want 
+to consider using a version of Debian Installer with partman-crypto
+(see http://wiki.debian.org/DebianInstaller/PartmanCrypto).
+
+The installation will then take care of all the details and perform the
+necessary configuration for you, meaning that you should not have to 
+read the rest of this document to get a machine with an encrypted
+root fs up and running.
+
+However, if you are not planning to perform a new installation from scratch,
+the following information might be useful to you.
+
+
+3. Requirements
+---------------
+In order to boot from an encrypted root fs, you need an initramfs-image
+which includes the necessary kernel modules and scripts to setup
+the root device after the kernel has been initialized, but before the rest 
+of the operating system is booted.
+
+To do so, you need two partitions:
+- an unencrypted /boot partition
+- an encrypted / partition
+
+In addition, you need to have initramfs-tools installed.
+
+NOTE: You should make sure that your swap partition is either encrypted, or
+that you are using a swap file on an encrypted partition, as crypto keys and
+other sensitive information might otherwise be written out to the swap
+partition in unencrypted form.
+
+
+4. Setup (regular dm-crypt)
+---------------------------
+First of all, you must edit /etc/crypttab and add a line describing your
+root device, for example:
+
+  cryptroot /dev/hda2 none cipher=aes-cbc-essiv:sha256,size=256,hash=sha256
+
+This will allow cryptsetup to create /dev/mapper/cryptroot from the 
+encrypted partition /dev/hda2 during boot.
+
+In addition, you must also make sure that the root device is listed in 
+/etc/fstab, for example:
+
+  /dev/mapper/cryptroot / ext3 defaults 0 1
+
+This will allow the initramfs support scripts to know which of the devices
+in the crypttab that is the root device.
+
+After doing these changes, you should regenerate the initramfs by running
+"initramfs-update -u", then make sure that your boot loader is configured
+to feed the initramfs to the kernel when booting. The kernel root argument
+should also be changed to /dev/mapper/cryptroot.
+
+Now, reboot the machine, and if everything is correctly configured, you
+should be given a prompt to type in the passphrase for the encrypted
+root partition before the boot can continue.
+
+NOTE: the initramfs scripts default to using the sha256 hash function while
+the plain cryptsetup binary defaults to using the ripemd160 hash function.
+In order to ensure that the crypto setup works in a consistant manner, you
+should make sure that the hash function is specified in the /etc/crypttab file
+if you are using regular dm-crypt (with LUKS the hash function to use is stored
+in the LUKS header).
+
+
+5. Setup (using LUKS)
+---------------------
+If you are using the LUKS feature of cryptsetup, the above setup recipe should
+still apply, but since most options can be derived from the information stored
+in the LUKS header on-disk, the line to add to /etc/crypttab should look
+something like this:
+
+  cryptroot /dev/sda2 none luks
+
+
+6. Exotic key types
+-------------------
+The above examples assume that you use a regular passphrase as the key to the
+encrypted filesystem. However, if you wish to make use of more complex setups
+(such as root-key-on-usb-memory), you can create a script which does all the
+steps necessary to retrieve the key and then prints it to stdout.
+
+Then add a keyscript=/path/to/your/script.sh to the options (fourth column) in
+the above mentioned /etc/crypttab line, so that it looks something like this:
+
+  cryptroot /dev/sda2 none luks,keyscript=/usr/local/sbin/cryptkey
+
+Next, regenerate your initramfs image. This will copy the script into the
+initramfs image under the /keyscripts/ directory.
+
+NOTE: there is a limited set of tools available when the script is executing
+as part of the initramfs bootup, you have to make sure that you do not use
+any tools which are not available or your script, and therefore boot, will
+fail.
+
+
+7. "cryptopts" boot argument
+----------------------------
+In general, you should use the above approach with a line describing your
+root partition in /etc/crypttab and /etc/fstab. However, if for some reason
+you wish to override the settings that are derived from these files and
+stored in the initramfs image, you can use the "cryptopts" boot argument
+(this *only* works for the root partition).
+
+The format of cryptopts is:
+cryptopts=<opt1>=<value1>,<opt2>=<value2>...
+
+Beside the "hash", "size", "cipher" and "lvm" options that correspond to the
+same options in the fourth field of /etc/crypttab, the options "target", 
+"source" and "key" are also supported. They correspond to the first, second 
+and third field of /etc/crypttab, respectively. See the crypttab man page
+for further details.
+
+Several "cryptopts" boot arguments can also be specified in case more than
+one mapping needs to be setup in the initramfs stage of the boot.
+
+Example boot arguments:
+root=/dev/mapper/crypt0 cryptopts=target=crypt0,source=/dev/hda1,cipher=twofish
+
+8. Resume device support
+------------------------
+The initramfs scripts will also try to automatically determine the devices,
+if any, that are used for software suspend (swsusp, suspend2 or uswsusp) and
+to set them up during the initramfs stage in order to allow suspend and resume
+in combination with encryption to keep the resume image safe from potential
+attackers.
+
+If your resume device and your root partition use two different cryptsetup
+mappings, you might want to use the "decrypt_derived" keyscript as described
+below.
+
+9. The "decrypt_derived" keyscript
+----------------------------------
+Assume that you have two entries in /etc/crypttab:
+
+cryptroot /dev/hda1 none luks
+cryptswap /dev/hda2 none luks
+
+If cryptswap is used as your suspend/resume device, you'd normally need to
+enter two different passphrases during the boot, but the "decrypt_derived" 
+script can generate the key for the second mapping using a hash of the key 
+for the first mapping.
+
+In short, you'll need to do something like the following to take advantage
+of the decrypt_derived script:
+
+1) swapoff -a
+2) cryptsetup luksClose cryptswap
+3) edit /etc/crypttab and change the cryptswap line to e.g.:
+cryptswap /dev/hda2 cryptroot cipher=aes-cbc-essiv:sha256,size=256,hash=sha256,keyscript=/lib/cryptsetup/scripts/decrypt_derived,swap
+4) /etc/init.d/cryptdisks start
+5) Make sure that /dev/mapper/cryptswap has been created
+6) swapon -a
+7) (optional) update-initramfs -u
+
+After you've followed the above steps, your swap device should be setup
+automatically after the root device has been setup during the boot stage.
+
+Note: If you don't use suspend device support, it's better to use completely
+random keys for your encrypted swap device. See the section '2. Encrypted
+swap partition(s)' in /usr/share/doc/cryptsetup/README.Debian for information
+on how to setup this.
+
+10. The "passdev" keyscript
+----------------------------
+If you have a keyfile on a removable device (e.g. a USB-key), you can use the
+passdev keyscript. It will wait for the device to appear, mount it read-only,
+read the key and then unmount the device.
+
+The "key" part of /etc/crypttab will be interpreted as <device>:<path>, it is
+strongly recommended that you use one of the persistent device names from
+/dev/disk/*, e.g. /dev/disk/by-label/myusbkey.
+
+This is an example of a suitable line in cryptsetup:
+cryptroot /dev/hda2 /dev/disk/by-label/myusbkey:/keys/root.key cipher=aes-cbc-essiv:sha256,size=256,hash=plain,keyscript=/lib/cryptsetup/scripts/passdev
+
+The above line would cause the boot to pause until /dev/disk/by-label/myusbkey
+appears in the fs, then mount that device and use the file /keys/root.key
+on the device as the key (without any hashing) as the key for the fs.
+
+-- David Härdeman <david@hardeman.nu>
diff --git a/cryptsetup-luks-initramfs-passdev-hook b/cryptsetup-luks-initramfs-passdev-hook
new file mode 100644 (file)
index 0000000..ad6c484
--- /dev/null
@@ -0,0 +1,40 @@
+#!/bin/sh
+
+set -e
+
+PREREQ="cryptroot"
+
+prereqs()
+{
+       echo "$PREREQ"
+}
+
+case $1 in
+prereqs)
+       prereqs
+       exit 0
+       ;;
+esac
+
+. /usr/share/initramfs-tools/hook-functions
+
+# Hooks for adding filesystem modules to the initramfs when the passdev
+# keyscript is used
+
+# Check whether the passdev script has been included
+if [ ! -x "${DESTDIR}/keyscripts/passdev" ]; then
+       exit 0
+fi
+
+# The filesystem type of the removable device is probed at boot-time, so
+# we add a generous list of filesystems to include. This also helps with
+# recovery situation as including e.g. the vfat module might help a user
+# who needs to create a new cryptkey (using a backup of a keyfile) on
+# a windows-machine for example.
+
+# This list needs to be kept in sync with the one defined in passdev.c
+for fs in ext3 ext2 vfat reiserfs xfs isofs udf; do
+       manual_add_modules "$fs" > /dev/null 2>&1 || true
+done
+exit 0
+
diff --git a/cryptsetup-luks-initramfs-root-conf b/cryptsetup-luks-initramfs-root-conf
new file mode 100644 (file)
index 0000000..0e5e64f
--- /dev/null
@@ -0,0 +1,6 @@
+# This will setup non-us keyboards in early userspace,
+# necessary for punching in passphrases.
+KEYMAP=y
+
+# force busybox on initramfs
+BUSYBOX=y
diff --git a/cryptsetup-luks-initramfs-root-hook b/cryptsetup-luks-initramfs-root-hook
new file mode 100644 (file)
index 0000000..f237727
--- /dev/null
@@ -0,0 +1,487 @@
+#!/bin/sh
+
+PREREQ=""
+
+prereqs()
+{
+       echo "$PREREQ"
+}
+
+case $1 in
+prereqs)
+       prereqs
+       exit 0
+       ;;
+esac
+
+. /usr/share/initramfs-tools/hook-functions
+
+get_root_device() {
+       local device mount type options dump pass
+
+       if [ ! -r /etc/fstab ]; then
+               return 1
+       fi
+
+       grep '^[^#]' /etc/fstab | \
+       while read device mount type options dump pass; do
+               if [ "$mount" = "/" ]; then
+                       echo "$device"
+                       return
+               fi
+       done
+}
+
+get_resume_devices() {
+       local device opt count dupe candidates devices
+       candidates=""
+
+       # First, get a list of potential resume devices
+
+       # uswsusp
+       if [ -e /etc/uswsusp.conf ]; then
+               device=$(sed -rn 's/^resume device[[:space:]]*[:=][[:space:]]*// p' /etc/uswsusp.conf)
+               if [ -n "$device" ]; then
+                       candidates="$candidates $device"
+               fi
+       fi
+
+       # uswsusp - again...
+       if [ -e /etc/suspend.conf ]; then
+               device=$(sed -rn 's/^resume device[[:space:]]*[:=][[:space:]]*// p' /etc/suspend.conf)
+               if [ -n "$device" ]; then
+                       candidates="$candidates $device"
+               fi
+       fi
+
+       # regular swsusp
+       for opt in $(cat /proc/cmdline); do
+               case $opt in
+               resume=*)
+                       device="${opt#resume=}"
+                       candidates="$candidates $device"
+                       ;;
+               esac
+       done
+
+       # initramfs-tools
+       if [ -e /etc/initramfs-tools/conf.d/resume ]; then
+               device=$(sed -rn 's/^RESUME[[:space:]]*=[[:space:]]*// p' /etc/initramfs-tools/conf.d/resume)
+               if [ -n "$device" ]; then
+                       candidates="$candidates $device"
+               fi
+       fi
+
+       # Now check the sanity of all candidates
+       devices=""
+       count=0
+       for device in $candidates; do
+               # Weed out clever defaults
+               if [ "$device" = "<path_to_resume_device_file>" ]; then
+                       continue
+               fi
+
+               # Weed out duplicates
+               dupe=0
+               for opt in $devices; do
+                       if [ "$device" = "$opt" ]; then
+                               dupe=1
+                       fi
+               done
+               if [ $dupe -eq 1 ]; then
+                       continue
+               fi
+
+               # This device seems ok
+               devices="$devices $device"
+               count=$(( $count + 1 ))
+       done
+
+       if [ $count -gt 1 ]; then
+               echo "cryptsetup: WARNING: found more than one resume device candidate:" >&2
+               for device in $devices; do
+                       echo "                     $device" >&2
+               done
+       fi
+
+       if [ $count -gt 0 ]; then
+               echo $devices
+       fi
+
+       return 0
+}
+
+node_is_in_crypttab() {
+       local node
+       node="$1"
+
+       grep -q ^$node /etc/crypttab
+       return $?
+}
+
+get_lvm_deps() {
+       local node deps maj min depnode
+       node="$1"
+
+       if [ -z $node ]; then
+               echo "cryptsetup: WARNING: get_lvm_deps - invalid arguments" >&2
+               return 1
+       fi
+
+       if ! deps=$(dmsetup deps "$node" 2> /dev/null | sed 's/[^:]*: *//;s/[ (]//g;s/)/ /g'); then
+               echo "cryptsetup: WARNING: failed to find deps for $node" >&2
+               return 1
+       fi
+
+       # We should now have a list of major,minor pairs, e.g. "3,2 3,3"
+       for dep in $deps; do
+               maj=${dep%,*}
+               min=${dep#*,}
+               depnode=$(dmsetup ls | sed -n "s/\\([^ ]*\\) *($maj, $min)/\\1/p" | sed -e "s/[ \t]*$//")
+               if [ -z "$depnode" ]; then
+                       continue
+               fi
+               if [ "$(dmsetup table "$depnode" 2> /dev/null | cut -d' ' -f3)" != "crypt" ]; then
+                       get_lvm_deps "$depnode"
+                       continue
+               fi
+               echo "$depnode"
+       done
+
+       return 0
+}
+
+get_device_opts() {
+       local target source link extraopts rootopts opt
+       target="$1"
+       extraopts="$2"
+       KEYSCRIPT=""
+       OPTIONS=""
+
+       if [ -z "$target" ]; then
+               echo "cryptsetup: WARNING: get_device_opts - invalid arguments" >&2
+               return 1
+       fi
+
+       opt=$( grep ^$target /etc/crypttab | head -1 | sed 's/[[:space:]]\+/ /g' )
+       source=$( echo $opt | cut -d " " -f2 )
+       key=$( echo $opt | cut -d " " -f3 )
+       rootopts=$( echo $opt | cut -d " " -f4- )
+
+       if [ -z "$opt" ] || [ -z "$source" ] || [ -z "$key" ] || [ -z "$rootopts" ]; then
+               echo "cryptsetup: WARNING: invalid line in /etc/crypttab - $opt" >&2
+               return 1
+       fi
+
+       # Sanity checks for $source
+       if [ -h "$source" ]; then
+               link=$(readlink -nqe "$source")
+               if [ -z "$link" ]; then
+                       echo "cryptsetup: WARNING: $source is a dangling symlink" >&2
+                       return 1
+               fi
+
+               if [ "$link" != "${link#/dev/mapper/}" ]; then
+                       echo "cryptsetup: NOTE: using $link instead of $source for $target" >&2
+                       source="$link"
+               fi
+       fi
+
+       # Sanity checks for $key
+       if [ "$key" = "/dev/random" ] || [ "$key" = "/dev/urandom" ]; then
+               echo "cryptsetup: WARNING: target $target has a random key, skipped" >&2
+               return 1
+       fi
+
+       if [ -n "$extraopts" ]; then
+               rootopts="$extraopts,$rootopts"
+       fi
+
+       # We have all the basic options, let's go trough them
+       OPTIONS="target=$target,source=$source,key=$key"
+       local IFS=", "
+       unset HASH_FOUND
+       unset LUKS_FOUND
+       for opt in $rootopts; do
+               case $opt in
+                       cipher=*)
+                               OPTIONS="$OPTIONS,$opt"
+                               ;;
+                       hash=*)
+                               OPTIONS="$OPTIONS,$opt"
+                               HASH_FOUND=1
+                               ;;
+                       size=*)
+                               OPTIONS="$OPTIONS,$opt"
+                               ;;
+                       lvm=*)
+                               OPTIONS="$OPTIONS,$opt"
+                               ;;
+                       keyscript=*)
+                               opt=${opt#keyscript=}
+                               if [ ! -x "/lib/cryptsetup/scripts/$opt" ] && [ ! -x "$opt" ]; then
+                                       echo "cryptsetup: WARNING: target $target has an invalid keyscript, skipped" >&2
+                                       return 1
+                               fi
+                               KEYSCRIPT="$opt"
+                               OPTIONS="$OPTIONS,keyscript=/keyscripts/$(basename "$opt")"
+                               ;;
+                       tries=*)
+                               OPTIONS="$OPTIONS,$opt"
+                               ;;
+                       luks)
+                               LUKS_FOUND=1
+                               ;;
+                       *)
+                               # Presumably a non-supported option
+                               ;;
+               esac
+       done
+
+       # Warn for missing hash option, unless we have a LUKS partition
+       if [ -z "$HASH_FOUND" ] && [ -z "$LUKS_FOUND" ]; then
+               echo "WARNING: Option hash missing in crypttab for target $target, assuming ripemd160." >&2
+               echo "         If this is wrong, this initramfs image will not boot." >&2
+               echo "         Please read /usr/share/doc/cryptsetup/README.initramfs.gz and add" >&2
+               echo "         the correct hash option to your /etc/crypttab."  >&2
+       fi
+
+       # If keyscript is set, the "key" is just an argument to the script
+       if [ "$key" != "none" ] && [ -z "$KEYSCRIPT" ]; then
+               echo "cryptsetup: WARNING: target $target uses a key file, skipped" >&2
+               return 1
+       fi
+}
+
+get_device_modules() {
+       local node value cipher blockcipher ivhash
+       node="$1"
+
+       # Check the ciphers used by the active root mapping
+       value=$(dmsetup table "$node" | cut -d " " -f4)
+       cipher=$(echo "$value" | cut -d ":" -f1 | cut -d "-" -f1)
+       blockcipher=$(echo "$value" | cut -d ":" -f1 | cut -d "-" -f2)
+       ivhash=$(echo "$value" | cut -d ":" -s -f2)
+
+       if [ -n "$cipher" ]; then
+               echo "$cipher"
+       else
+               return 1
+       fi
+
+       if [ -n "$blockcipher" ] && [ "$blockcipher" != "plain" ]; then
+               echo "$blockcipher"
+       fi
+
+       if [ -n "$ivhash" ] && [ "$ivhash" != "plain" ]; then
+               echo "$ivhash"
+       fi
+       return 0
+}
+
+canonical_device() {
+       local dev altdev
+       dev="$1"
+
+       altdev="${dev#LABEL=}"
+       if [ "$altdev" != "$dev" ]; then
+               dev="/dev/disk/by-label/$altdev"
+       fi
+
+       altdev="${dev#UUID=}"
+       if [ "$altdev" != "$dev" ]; then
+               dev="/dev/disk/by-uuid/$altdev"
+       fi
+
+       if [ -h "$dev" ]; then
+               dev=$(readlink -e "$dev")
+       fi
+
+       altdev="${dev#/dev/mapper/}"
+       if [ "$altdev" != "$dev" ]; then
+               echo "$altdev"
+               return 0
+       fi
+
+       return 1
+}
+
+add_device() {
+       local node nodes opts lastopts i count
+       nodes="$1"
+       opts=""     # Applied to all nodes
+       lastopts="" # Applied to last node
+
+       if [ -z "$nodes" ]; then
+               return 0
+       fi
+
+       # Check that it is a node under /dev/mapper/
+       nodes=$(canonical_device "$nodes") || return 0
+
+       # Can we find this node in crypttab
+       if ! node_is_in_crypttab "$nodes"; then
+               # dm node but not in crypttab, is it a lvm device backed by dm-crypt nodes?
+               lvmnodes=$(get_lvm_deps "$nodes") || return 1
+
+               # not backed by any dm-crypt nodes; stop here
+               if [ -z "$lvmnodes" ]; then
+                   return 0
+               fi
+
+               # It is a lvm device!
+               lastopts="lvm=$nodes"
+               nodes="$lvmnodes"
+       fi
+
+       # Prepare to setup each node
+       count=$(echo "$nodes" | wc -w)
+       i=1
+       for node in $nodes; do
+               # Prepare the additional options
+               if [ $i -eq $count ]; then
+                       if [ -z "$opts" ]; then
+                               opts="$lastopts"
+                       else
+                               opts="$opts,$lastopts"
+                       fi
+               fi
+
+               # Get crypttab root options
+               if ! get_device_opts "$node" "$opts"; then
+                       continue
+               fi
+               echo "$OPTIONS" >> "$DESTDIR/conf/conf.d/cryptroot"
+
+               # If we have a keyscript, make sure it is included
+               if [ -n "$KEYSCRIPT" ]; then
+                       if [ ! -d "$DESTDIR/keyscripts" ]; then
+                               mkdir "$DESTDIR/keyscripts"
+                       fi
+
+                       if [ -e "/lib/cryptsetup/scripts/$KEYSCRIPT" ]; then
+                               copy_exec "/lib/cryptsetup/scripts/$KEYSCRIPT" /keyscripts
+                       elif [ -e "$KEYSCRIPT" ]; then
+                               copy_exec "$KEYSCRIPT" /keyscripts
+                       else
+                               echo "cryptsetup: WARNING: failed to find keyscript $KEYSCRIPT" >&2
+                               continue
+                       fi
+               fi
+
+               # Calculate needed modules
+               modules=$(get_device_modules $node | sort | uniq)
+               if [ -z "$modules" ]; then
+                       echo "cryptsetup: WARNING: failed to determine cipher modules to load for $node" >&2
+                       continue
+               fi
+               echo dm_mod
+               echo dm_crypt
+               echo "$modules"
+
+               i=$(( $i + 1 ))
+       done
+
+       return 0
+}
+
+add_crypto_modules() {
+       local mod file altmod found genericfound
+       mod="$1"
+       found=""
+       genericfound=""
+
+       if [ -z "$mod" ]; then
+               return 1
+       fi
+
+       # We have several potential sources of modules (in order of preference):
+       #
+       #   a) /lib/modules/$VERSION/kernel/arch/$ARCH/crypto/$mod-$specific.ko
+       #   b) /lib/modules/$VERSION/kernel/crypto/$mod_generic.ko
+       #   c) /lib/modules/$VERSION/kernel/crypto/$mod.ko
+       #
+       # and (currently ignored):
+       #
+       #   d) /lib/modules/$VERSION/kernel/drivers/crypto/$specific-$mod.ko
+
+       for file in $(find "$MODULESDIR/kernel/arch/" -name "$mod-*.ko"); do
+               altmod="${file##*/}"
+               altmod="${altmod%.ko}"
+               manual_add_modules "$altmod"
+               found="yes"
+       done
+
+       for file in $(find "$MODULESDIR/kernel/crypto/" -name "${mod}_generic.ko"); do
+               altmod="${file##*/}"
+               altmod="${altmod%.ko}"
+               manual_add_modules "$altmod"
+               found="yes"
+               genericfound="yes"
+       done
+
+       if [ -z "$genericfound" ]; then
+               for file in $(find "$MODULESDIR/kernel/crypto/" -name "${mod}.ko"); do
+                       altmod="${file##*/}"
+                       altmod="${altmod%.ko}"
+                       manual_add_modules "$altmod"
+                       found="yes"
+               done
+       fi
+
+       if [ -z "$found" ]; then
+               return 1
+       fi
+
+       return 0
+}
+
+#
+# Begin real processing
+#
+
+setup="no"
+rootdev=""
+resumedevs=""
+
+# Find the root and resume device(s)
+if [ -r /etc/crypttab ]; then
+       rootdev=$(get_root_device)
+       if [ -z "$rootdev" ]; then
+               echo "cryptsetup: WARNING: could not determine root device from /etc/fstab" >&2
+       fi
+       resumedevs=$(get_resume_devices)
+fi
+
+# Load the config opts and modules for each device
+for dev in $rootdev $resumedevs; do
+       if ! modules=$(add_device "$dev"); then
+               echo "cryptsetup: FAILURE: could not determine configuration for $dev" >&2
+               continue
+       fi
+
+       setup="yes"
+       for mod in $modules; do
+               add_crypto_modules $mod
+       done
+done
+
+# With large initramfs, we always add a basic subset of modules
+if [ "$MODULES" != "dep" ]; then
+       for mod in aes sha256 cbc; do
+               add_crypto_modules $mod
+       done
+fi
+
+# See if we need to add the basic components
+if [ "$MODULES" != "dep" ] || [ "$setup" = "yes" ]; then
+       for mod in dm_mod dm_crypt; do
+               manual_add_modules $mod
+       done
+
+       copy_exec /sbin/cryptsetup
+       copy_exec /sbin/dmsetup
+#      copy_exec /lib/cryptsetup/askpass
+fi
+
+exit 0
diff --git a/cryptsetup-luks-initramfs-root-local-top b/cryptsetup-luks-initramfs-root-local-top
new file mode 100644 (file)
index 0000000..e89e607
--- /dev/null
@@ -0,0 +1,289 @@
+#!/bin/sh
+
+#
+# Standard initramfs preamble
+#
+prereqs()
+{
+       # Make sure that cryptroot is run last in local-top
+       for req in /scripts/local-top/*; do
+               script=${req##*/}
+               if [ $script != cryptroot ]; then
+                       echo $script
+               fi
+       done
+}
+
+case $1 in
+prereqs)
+       prereqs
+       exit 0
+       ;;
+esac
+
+
+#
+# Helper functions
+#
+message()
+{
+       if [ -p /dev/.initramfs/usplash_outfifo ] && [ -x /sbin/usplash_write ]; then
+               usplash_write "TEXT-URGENT $@"
+       else
+               echo "$@" >&2
+       fi
+       return 0
+}
+
+parse_options()
+{
+       local cryptopts
+       cryptopts="$1"
+
+       if [ -z "$cryptopts" ]; then
+               return 1
+       fi
+
+       # Defaults
+       cryptcipher=aes-cbc-essiv:sha256
+       cryptsize=256
+       crypthash=ripemd160
+       crypttarget=cryptroot
+       cryptsource=""
+       cryptlvm=""
+       cryptkeyscript=""
+       cryptkey="" # This is only used as an argument to an eventual keyscript
+       crypttries=3
+
+       local IFS=" ,"
+       for x in $cryptopts; do
+               case $x in
+               hash=*)
+                       crypthash=${x#hash=}
+                       ;;
+               size=*)
+                       cryptsize=${x#size=}
+                       ;;
+               cipher=*)
+                       cryptcipher=${x#cipher=}
+                       ;;
+               target=*)
+                       crypttarget=${x#target=}
+                       ;;
+               source=*)
+                       cryptsource=${x#source=}
+                       if [ ${cryptsource#UUID=} != $cryptsource ]; then
+                               cryptsource="/dev/disk/by-uuid/${cryptsource#UUID=}"
+                       elif [ ${cryptsource#LABEL=} != $cryptsource ]; then
+                               cryptsource="/dev/disk/by-label/${cryptsource#LABEL=}"
+                       fi
+                       ;;
+               lvm=*)
+                       cryptlvm=${x#lvm=}
+                       ;;
+               keyscript=*)
+                       cryptkeyscript=${x#keyscript=}
+                       ;;
+               key=*)
+                       if [ "${x#key=}" != "none" ]; then
+                               cryptkey=${x#key=}
+                       fi
+                       ;;
+               tries=*)
+                       crypttries="${x#tries=}"
+                       case "$crypttries" in
+                         *[![:digit:].]*)
+                               crypttries=3
+                               ;;
+                       esac
+                       ;;
+               esac
+       done
+
+       if [ -z "$cryptsource" ]; then
+               message "cryptsetup: source parameter missing"
+               return 1
+       fi
+       return 0
+}
+
+activate_vg()
+{
+       local vg
+       vg="${1#/dev/mapper/}"
+
+       # Sanity checks
+       if [ ! -x /sbin/lvm ] || [ "$vg" = "$1" ]; then
+               return 1
+       fi
+
+       # Make sure that the device contains at least one dash
+       if [ "${vg%%-*}" = "$vg" ]; then
+               return 1
+       fi
+
+       # Split volume group from logical volume.
+       vg=$(echo ${vg} | sed -e 's#\(.*\)\([^-]\)-[^-].*#\1\2#')
+
+       # Reduce padded --'s to -'s
+       vg=$(echo ${vg} | sed -e 's#--#-#g')
+
+       lvm vgchange -ay ${vg}
+       return $?
+}
+
+activate_evms()
+{
+       local dev module
+       dev="${1#/dev/evms/}"
+
+       # Sanity checks
+       if [ ! -x /sbin/evms_activate ] || [ "$dev" = "$1" ]; then
+               return 1
+       fi
+
+       # Load modules used by evms
+       for module in dm-mod linear raid0 raid1 raid10 raid5 raid6; do
+               /sbin/modprobe -q $module
+       done
+
+       # Activate it
+       /sbin/evms_activate
+       return $?
+}
+
+setup_mapping()
+{
+       local opts count cryptcreate cryptremove NEWROOT
+       opts="$1"
+
+       if [ -z "$opts" ]; then
+               return 0
+       fi
+
+       parse_options "$opts" || return 1
+
+       if [ -n "$cryptkeyscript" ] && [ ! -x "$cryptkeyscript" ]; then
+               message "cryptsetup: error - script \"$cryptkeyscript\" missing"
+               return 1
+       fi
+
+       # The same target can be specified multiple times
+       # e.g. root and resume lvs-on-lvm-on-crypto
+       if [ -e "/dev/mapper/$crypttarget" ]; then
+               return 0
+       fi
+
+       /sbin/modprobe -q dm_crypt
+
+       # Make sure the cryptsource device is available
+       if [ ! -e $cryptsource ]; then
+               activate_vg $cryptsource
+               activate_evms $cryptsource
+       fi
+
+       /sbin/udevadm settle --timeout=30
+
+       if [ ! -e $cryptsource ]; then
+               message "cryptsetup: source device $cryptsource not found"
+               return 1
+       fi
+
+       # Prepare commands
+       if /sbin/cryptsetup isLuks $cryptsource > /dev/null 2>&1; then
+               cryptcreate="/sbin/cryptsetup -T 1 luksOpen $cryptsource $crypttarget"
+       else
+               cryptcreate="/sbin/cryptsetup -T 1 -c $cryptcipher -s $cryptsize -h $crypthash create $crypttarget $cryptsource"
+       fi
+       cryptremove="/sbin/cryptsetup remove $crypttarget"
+       NEWROOT="/dev/mapper/$crypttarget"
+
+       # Try to get a satisfactory password $crypttries times
+       count=0
+       while [ $crypttries -le 0 ] || [ $count -lt $crypttries ]; do
+               count=$(( $count + 1 ))
+
+               if [ $count -gt 1 ]; then
+                       sleep 3
+               fi
+
+               if [ $crypttries -gt 0 ] && [ $count -gt $crypttries ]; then
+                       message "cryptsetup: maximum number of tries exceeded for $crypttarget"
+                       return 1
+               fi
+
+               if [ -z "$cryptkeyscript" ]; then
+                       cryptkeyscript="/lib/cryptsetup/askpass"
+                       cryptkey="Enter passphrase to unlock the disk $cryptsource ($crypttarget): "
+               fi
+
+
+               if ! crypttarget="$crypttarget" cryptsource="$cryptsource" \
+                    $cryptkeyscript "$cryptkey" | $cryptcreate --key-file=- ; then
+                       message "cryptsetup: cryptsetup failed, bad password or options?"
+                       continue
+               fi
+
+               if [ ! -e "$NEWROOT" ]; then
+                       message "cryptsetup: unknown error setting up device mapping"
+                       return 1
+               fi
+
+               FSTYPE=''
+               eval $(fstype < "$NEWROOT")
+
+               # See if we need to setup lvm on the crypto device
+               if [ "$FSTYPE" = "lvm" ] || [ "$FSTYPE" = "lvm2" ]; then
+                       if [ -z "$cryptlvm" ]; then
+                               message "cryptsetup: lvm fs found but no lvm configured"
+                               return 1
+                       elif ! activate_vg "/dev/mapper/$cryptlvm"; then
+                               message "cryptsetup: failed to setup lvm device"
+                               return 1
+                       fi
+
+                       NEWROOT="/dev/mapper/$cryptlvm"
+                       eval $(fstype < "$NEWROOT")
+               fi
+
+               if [ -z "$FSTYPE" ] || [ "$FSTYPE" = "unknown" ]; then
+                       message "cryptsetup: unknown fstype, bad password or options?"
+                       $cryptremove
+                       continue
+               fi
+
+               message "cryptsetup: $crypttarget setup successfully"
+               break
+       done
+
+       /sbin/udevadm settle --timeout=30
+       return 0
+}
+
+#
+# Begin real processing
+#
+
+# Do we have any kernel boot arguments?
+found=''
+for opt in $(cat /proc/cmdline); do
+       case $opt in
+       cryptopts=*)
+               found=yes
+               setup_mapping "${opt#cryptopts=}"
+               ;;
+       esac
+done
+
+if [ -n "$found" ]; then
+       exit 0
+fi
+
+# Do we have any settings from the /conf/conf.d/cryptroot file?
+if [ -r /conf/conf.d/cryptroot ]; then
+       while read mapping <&3; do
+               setup_mapping "$mapping"
+       done 3< /conf/conf.d/cryptroot
+fi
+
+exit 0
This page took 0.139427 seconds and 4 git commands to generate.