First commit, supports multiple devices via cryptdevice=, cryptdevice1= etc

This commit is contained in:
Travis Burtrum 2016-09-26 01:03:42 -04:00
parent 4a9b980eb5
commit fbab5a5348

View File

@ -4,136 +4,157 @@ run_hook() {
modprobe -a -q dm-crypt >/dev/null 2>&1 modprobe -a -q dm-crypt >/dev/null 2>&1
[ "${quiet}" = "y" ] && CSQUIET=">/dev/null" [ "${quiet}" = "y" ] && CSQUIET=">/dev/null"
# Get keyfile if specified count=0
ckeyfile="/crypto_keyfile.bin" while true
if [ -n "$cryptkey" ]; then do
IFS=: read ckdev ckarg1 ckarg2 <<EOF num=$count
[ $count -eq 0 ] && num=""
cryptdevice_name="cryptdevice$num"
#cryptdevice=${!cryptdevice_name} # this would work with bash
cryptdevice="$(eval echo "$""$cryptdevice_name")"
cryptkey_name="cryptkey$num"
cryptkey="$(eval echo "$""$cryptkey_name")"
crypto_name="crypto$num"
crypto="$(eval echo "$""$crypto_name")"
if [ -n "${cryptdevice}" ]; then
DEPRECATED_CRYPT=0
IFS=: read cryptdev cryptname cryptoptions <<EOF
$cryptdevice
EOF
else
if [ $count -ne 0 ]; then
break;
fi
DEPRECATED_CRYPT=1
cryptdev="${root}"
cryptname="root"
fi
# Get keyfile if specified
ckeyfile="/crypto_keyfile.bin"
if [ -n "$cryptkey" ]; then
IFS=: read ckdev ckarg1 ckarg2 <<EOF
$cryptkey $cryptkey
EOF EOF
if [ "$ckdev" = "rootfs" ]; then if [ "$ckdev" = "rootfs" ]; then
ckeyfile=$ckarg1 ckeyfile=$ckarg1
elif resolved=$(resolve_device "${ckdev}" ${rootdelay}); then elif resolved=$(resolve_device "${ckdev}" ${rootdelay}); then
case ${ckarg1} in case ${ckarg1} in
*[!0-9]*) *[!0-9]*)
# Use a file on the device # Use a file on the device
# ckarg1 is not numeric: ckarg1=filesystem, ckarg2=path # ckarg1 is not numeric: ckarg1=filesystem, ckarg2=path
mkdir /ckey mkdir /ckey
mount -r -t "$ckarg1" "$resolved" /ckey mount -r -t "$ckarg1" "$resolved" /ckey
dd if="/ckey/$ckarg2" of="$ckeyfile" >/dev/null 2>&1 dd if="/ckey/$ckarg2" of="$ckeyfile" >/dev/null 2>&1
umount /ckey umount /ckey
;;
*)
# Read raw data from the block device
# ckarg1 is numeric: ckarg1=offset, ckarg2=length
dd if="$resolved" 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
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."
}
for cryptopt in ${cryptoptions//,/ }; do
case ${cryptopt} in
allow-discards)
cryptargs="${cryptargs} --allow-discards"
;; ;;
*) *)
# Read raw data from the block device echo "Encryption option '${cryptopt}' not known, ignoring." >&2
# ckarg1 is numeric: ckarg1=offset, ckarg2=length
dd if="$resolved" of="$ckeyfile" bs=1 skip="$ckarg1" count="$ckarg2" >/dev/null 2>&1
;; ;;
esac esac
fi done
[ ! -f ${ckeyfile} ] && echo "Keyfile could not be opened. Reverting to passphrase."
fi
if [ -n "${cryptdevice}" ]; then if resolved=$(resolve_device "${cryptdev}" ${rootdelay}); then
DEPRECATED_CRYPT=0 if cryptsetup isLuks ${resolved} >/dev/null 2>&1; then
IFS=: read cryptdev cryptname cryptoptions <<EOF [ ${DEPRECATED_CRYPT} -eq 1 ] && warn_deprecated
$cryptdevice dopassphrase=1
EOF # If keyfile exists, try to use that
else if [ -f ${ckeyfile} ]; then
DEPRECATED_CRYPT=1 if eval cryptsetup --key-file ${ckeyfile} open --type luks ${resolved} ${cryptname} ${cryptargs} ${CSQUIET}; then
cryptdev="${root}" dopassphrase=0
cryptname="root" else
fi 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:"
warn_deprecated() { #loop until we get a real password
echo "The syntax 'root=${root}' where '${root}' is an encrypted volume is deprecated" while ! eval cryptsetup open --type luks ${resolved} ${cryptname} ${cryptargs} ${CSQUIET}; do
echo "Use 'cryptdevice=${root}:root root=/dev/mapper/root' instead." sleep 2;
} done
fi
for cryptopt in ${cryptoptions//,/ }; do if [ -e "/dev/mapper/${cryptname}" ]; then
case ${cryptopt} in if [ ${DEPRECATED_CRYPT} -eq 1 ]; then
allow-discards) export root="/dev/mapper/root"
cryptargs="${cryptargs} --allow-discards" fi
;;
*)
echo "Encryption option '${cryptopt}' not known, ignoring." >&2
;;
esac
done
if resolved=$(resolve_device "${cryptdev}" ${rootdelay}); then
if cryptsetup isLuks ${resolved} >/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 cryptsetup --key-file ${ckeyfile} open --type luks ${resolved} ${cryptname} ${cryptargs} ${CSQUIET}; then
dopassphrase=0
else else
echo "Invalid keyfile. Reverting to passphrase." err "Password succeeded, but ${cryptname} creation failed, aborting..."
exit 1
fi fi
fi elif [ -n "${crypto}" ]; then
# Ask for a passphrase [ ${DEPRECATED_CRYPT} -eq 1 ] && warn_deprecated
if [ ${dopassphrase} -gt 0 ]; then msg "Non-LUKS encrypted device found..."
echo "" if echo "$crypto" | awk -F: '{ exit(NF == 5) }'; then
echo "A password is required to access the ${cryptname} volume:" err "Verify parameter format: crypto=hash:cipher:keysize:offset:skip"
err "Non-LUKS decryption not attempted..."
#loop until we get a real password return 1
while ! eval cryptsetup open --type luks ${resolved} ${cryptname} ${cryptargs} ${CSQUIET}; do
sleep 2;
done
fi
if [ -e "/dev/mapper/${cryptname}" ]; then
if [ ${DEPRECATED_CRYPT} -eq 1 ]; then
export root="/dev/mapper/root"
fi fi
else exe="cryptsetup open --type plain $resolved $cryptname $cryptargs"
err "Password succeeded, but ${cryptname} creation failed, aborting..." IFS=: read c_hash c_cipher c_keysize c_offset c_skip <<EOF
exit 1
fi
elif [ -n "${crypto}" ]; then
[ ${DEPRECATED_CRYPT} -eq 1 ] && warn_deprecated
msg "Non-LUKS encrypted device found..."
if echo "$crypto" | awk -F: '{ exit(NF == 5) }'; then
err "Verify parameter format: crypto=hash:cipher:keysize:offset:skip"
err "Non-LUKS decryption not attempted..."
return 1
fi
exe="cryptsetup open --type plain $resolved $cryptname $cryptargs"
IFS=: read c_hash c_cipher c_keysize c_offset c_skip <<EOF
$crypto $crypto
EOF EOF
[ -n "$c_hash" ] && exe="$exe --hash '$c_hash'" [ -n "$c_hash" ] && exe="$exe --hash '$c_hash'"
[ -n "$c_cipher" ] && exe="$exe --cipher '$c_cipher'" [ -n "$c_cipher" ] && exe="$exe --cipher '$c_cipher'"
[ -n "$c_keysize" ] && exe="$exe --key-size '$c_keysize'" [ -n "$c_keysize" ] && exe="$exe --key-size '$c_keysize'"
[ -n "$c_offset" ] && exe="$exe --offset '$c_offset'" [ -n "$c_offset" ] && exe="$exe --offset '$c_offset'"
[ -n "$c_skip" ] && exe="$exe --skip '$c_skip'" [ -n "$c_skip" ] && exe="$exe --skip '$c_skip'"
if [ -f "$ckeyfile" ]; then if [ -f "$ckeyfile" ]; then
exe="$exe --key-file $ckeyfile" exe="$exe --key-file $ckeyfile"
else else
exe="$exe --verify-passphrase" exe="$exe --verify-passphrase"
echo "" echo ""
echo "A password is required to access the ${cryptname} volume:" echo "A password is required to access the ${cryptname} volume:"
fi fi
eval "$exe $CSQUIET" eval "$exe $CSQUIET"
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
err "Non-LUKS device decryption failed. verify format: " err "Non-LUKS device decryption failed. verify format: "
err " crypto=hash:cipher:keysize:offset:skip" err " crypto=hash:cipher:keysize:offset:skip"
exit 1 exit 1
fi fi
if [ -e "/dev/mapper/${cryptname}" ]; then if [ -e "/dev/mapper/${cryptname}" ]; then
if [ ${DEPRECATED_CRYPT} -eq 1 ]; then if [ ${DEPRECATED_CRYPT} -eq 1 ]; then
export root="/dev/mapper/root" export root="/dev/mapper/root"
fi
else
err "Password succeeded, but ${cryptname} creation failed, aborting..."
exit 1
fi fi
else else
err "Password succeeded, but ${cryptname} creation failed, aborting..." err "Failed to open encryption mapping: The device ${cryptdev} is not a LUKS volume and the crypto= paramater was not specified."
exit 1
fi 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
fi rm -f ${ckeyfile}
rm -f ${ckeyfile} count=$((count + 1))
done
} }
# vim: set ft=sh ts=4 sw=4 et: # vim: set ft=sh ts=4 sw=4 et: