You are not logged in.

#1 2012-12-30 00:05:21

hunterthomson
Member
Registered: 2008-06-22
Posts: 794
Website

OpenSSL bf-cbc encrypted Keyfile HOOK for LUKS

I modified the this HOOK that maxim_ posted here. That dose not work.
https://bbs.archlinux.org/viewtopic.php … 05#p947805

This one uses Blowfish in CBC mode instead of AES-256.
The password is hashed 1000 times with Whirlpool.
gen-cryptkey adds a a Salt to the encrypted keyfile

https://github.com/tdwyer/bfkeyfile

/lib/initcpio/hooks

#!/usr/bin/ash

run_hook ()
{
    local encfile decfile iteration attempts prompt badpassword dev arg1 arg2 retcode password passwordHash

    if [ "x${bfkf}" != "x" ]; then
        encfile="/enc_keyfile.bin"
        decfile="/crypto_keyfile.bin"

        iteration=1000
        attempts=5

        prompt="Enter password: "
        badpassword="Password incorrect"

        dev="$(echo "${bfkf}" | cut -d: -f1)"
        arg1="$(echo "${bfkf}" | cut -d: -f2)"
        arg2="$(echo "${bfkf}" | cut -d: -f3)"

        if poll_device "${dev}" "${rootdelay}"; then
            case "${arg1}" in
                *[!0-9]*)
                    mkdir /mntkey
                    mount -r -t "${arg1}" "${dev}" /mntkey
                    dd if="/mntkey/${arg2}" of="${encfile}" >/dev/null 2>&1
                    umount /mntkey
                    rm -rf /mntkey
                    ;;
                *)
                    dd if="${dev}" of="${encfile}" bs=1 skip="${arg1}" count="${arg2}" >/dev/null 2>&1
                    ;;
            esac
        fi

        if [ -f "${encfile}" ]; then
            while true; do
                read -rsp "${prompt}" password
                i=0
                while [ ${i} -lt ${iteration} ]; do
                    password=`echo -n "${password}" | openssl dgst -whirlpool -hex 2> /dev/null | cut -d ' ' -f 2`
                    i=$(( ${i} + 1 ))
                done
                openssl bf-cbc -pass pass:"${password}" -d -in "${encfile}" -out "${decfile}" >/dev/null 2>&1
                retcode="$?"
                if [ "${retcode}" != "0" ]; then
                    echo -e "\n${badpassword}\n"
                    attempts=$(( ${attempts} - 1 ))
                    [ "${attempts}" == "0" ] && echo "Keyfile could not be decrypted" && break
                else
                    break
                fi
            done

            rm -f "${encfile}"
        else
            echo "Encrypted keyfile could not be opened. Reverting to 'encrypt' hook."
        fi
    fi
}

/lib/initcpio/install

#!/bin/bash

build() {
    add_binary /usr/bin/openssl
    add_runscript
}

help ()
{
cat<<HELPEOF
  This hook allows for an openssl (bf-cbc) encrypted keyfile for LUKS.
  It relies on standard 'encrypt' hook providing decrypted '/crypto_keyfile.bin' for it.

  You must use gen-cryptkey create the encrypted enc_keyfile.bin
  The password is hashed with Whirlpool 1000 times
  Then your password Hash is used to encrypt the keyfile

  mkinitcpio.conf:
  MODULES: add ext4 vfat or whatever the type of filesystem the keyfile is on
  HOOKS=" ... bfkf encrypt ... filesystems ..."

  Kernel Parameters:
  There is no need for cryptkey=

  Two options are supported:
  1) Using a file on the device:
     bfkf=<device>:<fs-type>:<path>
  2) Reading raw data from the block device:
     bfkf=<device>:<offset>:<size>

  Example: /etc/default/grub
  GRUB_CMDLINE_LINUX="bfkf=/dev/sdb1:ext4:/keyfile.bin cryptdevice=/dev/sda2:root"
HELPEOF
}

# vim: set ft=sh ts=4 sw=4 et:

/usr/bin/gen-cryptkey

#!/bin/bash
#
# GPLv3
# Thomas Dwyer
# tomd.tel
#

iteration=1000

create_msg='Create: gen-cryptkey create'
decrypt_msg='Decrypt: gen-cryptkey decrypt PATH_TO_KEYFILE'

main () {
	action=$1
	if [ -z $action ]; then
		echo -e "Usage:\n$create_msg\n$decrypt_msg"

	elif [ $action == "create" ]; then
		crypt

	elif [ $action == "decrypt" ]; then
		if [ -z $2 ]; then
			echo -e "Usage:\n$create_msg\n$decrypt_msg"
		else
			decrypt $2
		fi
	else
		echo -e "Usage:\n$create_msg\n$decrypt_msg"
	fi
	exit 0
}

crypt () {
	encfile="enc_keyfile.bin"

	echo "$encfile encrypted keyfile will be created"
	echo ''
	read -rsp "Enter password: " password
	password1=`echo -n "$password" | openssl dgst -whirlpool -hex | cut -d ' ' -f 2`
	echo ''
	read -rsp "Enter password Again: " verify
	password2=`echo -n "$verify" | openssl dgst -whirlpool -hex | cut -d ' ' -f 2`
	if [[ "$password1" == "$password2" ]]; then

		for (( i=1; i<=$iteration; i++ )); do
			password=`echo -n "$password" | openssl dgst -whirlpool -hex | cut -d ' ' -f 2`
		done

		dd if=/dev/urandom bs=1k count=256 | openssl bf-cbc -pass pass:"${password}" -salt -out "${encfile}"
	else
		echo "Passwords did not match"
	fi
}

decrypt () {
	encfile=$1
	decfile="crypto_keyfile.bin"

	echo "$encfile Will be decrypted to crypto_keyfile.bin"
	echo ''
	read -rsp "Enter password: " password

	for (( i=1; i<=$iteration; i++ )); do
		password=`echo -n "$password" | openssl dgst -whirlpool -hex | cut -d ' ' -f 2`
	done

	openssl bf-cbc -pass pass:"${password}" -d -in "${encfile}" -out "${decfile}"
}

main $@

Last edited by hunterthomson (2013-01-01 00:01:20)


OpenBSD-current Thinkpad X230, i7-3520M, 16GB CL9 Kingston, Samsung 830 256GB
Contributor: linux-grsec

Offline

#2 2012-12-31 23:56:14

hunterthomson
Member
Registered: 2008-06-22
Posts: 794
Website

Re: OpenSSL bf-cbc encrypted Keyfile HOOK for LUKS

Well, it is working now, so feel free to use it.

If you do use it, make darn sure to keep "at least" 3 backups of the keyfile on 3 different devices.
You will also want to leave your passphrase enabled until you are sure the keyfile is working as it should.

However, I am not going to use this anymore and will no longer be working on it. I will subscribe to this thread and answer any questions. I don't really see a whole lot of added security in this, and it would be kind of a pain to use a keyfile in a Live CD/USB. I think it is good enough to make use of the --iter-time flag when using luksFormat or luksAddKey.  It was a fun ride learning how to write this hook for initcpio

Note: Anyone who wants to write a hook should install busybox and symlink /usr/local/bin/ash to it for testing the HOOK script. The HOOKS use busybox ash not 'sh' nor 'bash', and ash is strange. If your HOOK script has an error you will get a kernel panic.

Last edited by hunterthomson (2012-12-31 23:57:24)


OpenBSD-current Thinkpad X230, i7-3520M, 16GB CL9 Kingston, Samsung 830 256GB
Contributor: linux-grsec

Offline

Board footer

Powered by FluxBB