Bug#348147: Add support for cryptoroot
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 to: