Package: initramfs-tools
Version: 0.49
Severity: wishlist
Tags: patch

I've attached a first attempt at adding cryptroot support.

It adds two new boot options:

cryptroot: the device which the encrypted filesystem resides on
          example: cryptroot=/dev/hda1

cryptopts: a comma-separated list of arguments to cryptsetup, currently supported options are hash, size and cipher. If none are specified, defaults (the example below) will be used. example: cryptopts=hash=sha256,size=256,cipher=aes-cbc-essiv:sha256

if cryptroot is present, the root argument is expected to be the node where cryptsetup should setup the unencrypted fs, so it should be under the /dev/mapper hierarchy. An example of a complete set of arguments for cryptroot is:
root=/dev/mapper/cryptroot cryptroot=/dev/hda1 
cryptopts=hash=sha256,size=256,cipher=aes-cbc-essiv:sha256

Admittedly, having both a root and a cryptroot command line option is somewhat ugly, but avoiding it would require the init script to source the files under scripts instead of executing them. The ROOT variable could then be set to the encrypted node (/dev/hda1 in the example above) until the cryptroot script is run which could setup the /dev/mapper/cryptroot node and change the ROOT variable accordingly. This would for instance have the advantage of making any changes to the lvm script unnecessary. Alas, this is not possible without major changes...

The cryptroot hook copies cryptsetup to the initramfs (if present) and if /etc/mkinitramfs/cryptgetpw is present on the system it is also included.

If no cryptgetpw script is present, the cryptroot script will ask the user to input the password via keyboard. If the script is present, it is executed and its output piped to cryptsetup. This allows users to create more complex password schemes (for example, I currently use a cryptgetpw which loads the password from a USB key) by creating an appropriate script.

Comments/suggestions are very welcome (especially a clean way of altering the ROOT variable from the scripts/local-top/cryptroot would be nice)...

Re,
David Härdeman
diff -Nur -x udev initramfs-tools-bak/hooks/cryptroot 
initramfs-tools/hooks/cryptroot
--- initramfs-tools-bak/hooks/cryptroot 1970-01-01 01:00:00.000000000 +0100
+++ initramfs-tools/hooks/cryptroot     2006-01-14 20:50:37.000000000 +0100
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+PREREQ=""
+
+prereqs()
+{
+       echo "$PREREQ"
+}
+
+case $1 in
+prereqs)
+       prereqs
+       exit 0
+       ;;
+esac
+
+. /usr/share/initramfs-tools/hook-functions
+
+if [ -x "/sbin/cryptsetup" ]; then
+       copy_exec /sbin/cryptsetup /sbin
+       if [ -x "/etc/mkinitramfs/cryptgetpw" ]; then
+               copy_exec /etc/mkinitramfs/cryptgetpw /sbin
+       fi
+fi
+
+exit 0
diff -Nur -x udev initramfs-tools-bak/init initramfs-tools/init
--- initramfs-tools-bak/init    2005-12-28 01:27:43.000000000 +0100
+++ initramfs-tools/init        2006-01-12 22:06:29.000000000 +0100
@@ -28,6 +28,9 @@
 export resume=${RESUME}
 export rootmnt=/root
 export debug=
+export cryptroot=
+export cryptopts=
+
 for x in $(cat /proc/cmdline); do
        case $x in
        init=*)
@@ -59,6 +62,12 @@
                exec >/tmp/initramfs.debug 2>&1
                set -x
                ;;
+       cryptroot=*)
+               cryptroot=${x#cryptroot=}
+               ;;
+       cryptopts=*)
+               cryptopts=${x#cryptopts=}
+               ;;
        break=*)
                break=${x#break=}
                ;;
diff -Nur -x udev initramfs-tools-bak/scripts/local-top/cryptroot 
initramfs-tools/scripts/local-top/cryptroot
--- initramfs-tools-bak/scripts/local-top/cryptroot     1970-01-01 
01:00:00.000000000 +0100
+++ initramfs-tools/scripts/local-top/cryptroot 2006-01-15 09:27:03.000000000 
+0100
@@ -0,0 +1,75 @@
+#!/bin/sh
+
+PREREQ="md lvm evms"
+
+prereqs()
+{
+       echo "$PREREQ"
+}
+
+case $1 in
+# get pre-requisites
+prereqs)
+       prereqs
+       exit 0
+       ;;
+esac
+
+if [ ! -x "/sbin/cryptsetup" ]; then
+       echo "$0: no cryptsetup present"
+       exit 0
+fi
+
+# If we have a cryptroot, root must be a device-mapper partition
+if [ -n "$cryptroot" ]; then
+       cryptnode=${ROOT#/dev/mapper/}
+       if [ "$cryptnode" = "$ROOT" ]; then
+               panic "$0: root must be a device-mapper partition"
+       fi
+else
+       exit 0
+fi
+
+cryptciper=aes-cbc-essiv:sha256
+cryptsize=256
+crypthash=sha256
+
+if [ -n "$cryptopts" ]; then
+       argc=0
+       while [ 1 ]; do
+               arg=$( echo "$cryptopts" | cut -d "," -f $argc )
+               [ -n "$arg" ] || break
+               argc=$(( argc + 1 ))
+
+               case "$arg" in
+               hash=*)
+                       crypthash=${arg#hash=}
+                       ;;
+               size=*)
+                       cryptsize=${arg#size=}
+                       ;;
+               cipher=*)
+                       cryptcipher=${arg#cipher=}
+                       ;;
+               esac
+       done
+fi
+
+while [ 1 ]; do
+       if [ -x "/sbin/cryptgetpw" ]; then
+               /sbin/cryptgetpw | /sbin/cryptsetup -c $cryptcipher -s 
$cryptsize -h $crypthash create $cryptnode $cryptroot
+       else
+               /sbin/cryptsetup -c $cryptcipher -s $cryptsize -h $crypthash 
create $cryptnode $cryptroot
+       fi
+
+       eval $( fstype < "$ROOT" )
+       if [ "$FSTYPE" = "unknown" ]; then
+               echo "$0: fstype not recognized, bad password?"
+               /sbin/cryptsetup remove $cryptnode
+               sleep 3
+               continue
+       fi
+       break
+done
+
+exit 0
diff -Nur -x udev initramfs-tools-bak/scripts/local-top/lvm 
initramfs-tools/scripts/local-top/lvm
--- initramfs-tools-bak/scripts/local-top/lvm   2006-01-14 21:21:51.000000000 
+0100
+++ initramfs-tools/scripts/local-top/lvm       2006-01-14 21:21:36.000000000 
+0100
@@ -15,7 +15,11 @@
        ;;
 esac
 
-vg=${ROOT#/dev/mapper/}
+if [ -n "$cryptroot" ]; then
+       vg=${cryptroot#/dev/mapper/}
+else
+       vg=${ROOT#/dev/mapper/}
+fi
 
 case ${vg} in
        /dev/root)

Reply via email to