encrypt_hook 5.7 KB
Newer Older
Jan Mette's avatar
Jan Mette committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
# vim: set ft=sh:
# TODO this one needs some work to work with lots of different
#       encryption schemes
run_hook ()
{
    /sbin/modprobe -a -q dm-crypt >/dev/null 2>&1
    if [ -e "/sys/class/misc/device-mapper" ]; then
        if [ ! -e "/dev/mapper/control" ]; then
            /bin/mknod "/dev/mapper/control" c $(cat /sys/class/misc/device-mapper/dev | sed 's|:| |')
        fi
        [ "${quiet}" = "y" ] && CSQUIET=">/dev/null"

        # Get keyfile if specified
        ckeyfile="/crypto_keyfile.bin"
        if [ "x${cryptkey}" != "x" ]; then
            ckdev="$(echo "${cryptkey}" | cut -d: -f1)"
            ckarg1="$(echo "${cryptkey}" | cut -d: -f2)"
            ckarg2="$(echo "${cryptkey}" | cut -d: -f3)"
            if poll_device "${ckdev}" ${rootdelay}; then
                case ${ckarg1} in
                    *[!0-9]*)
                        # Use a file on the device
                        # ckarg1 is not numeric: ckarg1=filesystem, ckarg2=path
                        mkdir /ckey
                        mount -r -t ${ckarg1} ${ckdev} /ckey
                        dd if=/ckey/${ckarg2} of=${ckeyfile} >/dev/null 2>&1
                        umount /ckey
                        ;;
                    *)
                        # Read raw data from the block device
                        # ckarg1 is numeric: ckarg1=offset, ckarg2=length
                        dd if=${ckdev} of=${ckeyfile} bs=1 skip=${ckarg1} count=${ckarg2} >/dev/null 2>&1
                        ;;
                esac
            fi
            [ ! -f ${ckeyfile} ] && echo "Keyfile could not be opened. Reverting to passphrase."
        fi

        if [ -n "${cryptdevice}" ]; then
            DEPRECATED_CRYPT=0
            cryptdev="$(echo "${cryptdevice}" | cut -d: -f1)"
            cryptname="$(echo "${cryptdevice}" | cut -d: -f2)"
        else
            DEPRECATED_CRYPT=1
            cryptdev="${root}"
            cryptname="root"
        fi

        warn_deprecated() {
            echo "The syntax 'root=${root}' where '${root}' is an encrypted volume is deprecated"
            echo "Use 'cryptdevice=${root}:root root=/dev/mapper/root' instead."
        }

        if  poll_device "${cryptdev}" ${rootdelay}; then
            if /sbin/cryptsetup isLuks ${cryptdev} >/dev/null 2>&1; then
                [ ${DEPRECATED_CRYPT} -eq 1 ] && warn_deprecated
                dopassphrase=1
                # If keyfile exists, try to use that
                if [ -f ${ckeyfile} ]; then
                    if eval /sbin/cryptsetup --key-file ${ckeyfile} luksOpen ${cryptdev} ${cryptname} ${CSQUIET}; then
                        dopassphrase=0
                    else
                        echo "Invalid keyfile. Reverting to passphrase."
                    fi
                fi
                # Ask for a passphrase
                if [ ${dopassphrase} -gt 0 ]; then
                    echo ""
                    echo "A password is required to access the ${cryptname} volume:"

                    #loop until we get a real password
                    while ! eval /sbin/cryptsetup luksOpen ${cryptdev} ${cryptname} ${CSQUIET}; do
                        sleep 2;
                    done
                fi
                if [ -e "/dev/mapper/${cryptname}" ]; then
                    if [ ${DEPRECATED_CRYPT} -eq 1 ]; then
                        export root="/dev/mapper/root"
                    fi
                else
                    err "Password succeeded, but ${cryptname} creation failed, aborting..."
                    exit 1
                fi
            elif [ -n "${crypto}" ]; then
                [ ${DEPRECATED_CRYPT} -eq 1 ] && warn_deprecated
                msg "Non-LUKS encrypted device found..."
                if [ $# -ne 5 ]; then
                    err "Verify parameter format: crypto=hash:cipher:keysize:offset:skip"
                    err "Non-LUKS decryption not attempted..."
                    return 1
                fi
                exe="/sbin/cryptsetup create ${cryptname} ${cryptdev}"
                tmp=$(echo "${crypto}" | cut -d: -f1)
                [ -n "${tmp}" ] && exe="${exe} --hash \"${tmp}\""
                tmp=$(echo "${crypto}" | cut -d: -f2)
                [ -n "${tmp}" ] && exe="${exe} --cipher \"${tmp}\""
                tmp=$(echo "${crypto}" | cut -d: -f3)
                [ -n "${tmp}" ] && exe="${exe} --key-size \"${tmp}\""
                tmp=$(echo "${crypto}" | cut -d: -f4)
                [ -n "${tmp}" ] && exe="${exe} --offset \"${tmp}\""
                tmp=$(echo "${crypto}" | cut -d: -f5)
                [ -n "${tmp}" ] && exe="${exe} --skip \"${tmp}\""
                if [ -f ${ckeyfile} ]; then
                    exe="${exe} --key-file ${ckeyfile}"
                else
                    exe="${exe} --verify-passphrase"
                    echo ""
                    echo "A password is required to access the ${cryptname} volume:"
                fi
                eval "${exe} ${CSQUIET}"

                if [ $? -ne 0 ]; then
                    err "Non-LUKS device decryption failed. verify format: "
                    err "      crypto=hash:cipher:keysize:offset:skip"
                    exit 1
                fi
                if [ -e "/dev/mapper/${cryptname}" ]; then
                    if [ ${DEPRECATED_CRYPT} -eq 1 ]; then
                        export root="/dev/mapper/root"
                    fi
                else
                    err "Password succeeded, but ${cryptname} creation failed, aborting..."
                    exit 1
                fi
            else
                err "Failed to open encryption mapping: The device ${cryptdev} is not a LUKS volume and the crypto= paramater was not specified."
            fi
        fi
        rm -f ${ckeyfile}
    fi
}