#!/usr/bin/ash # shellcheck shell=dash _get_key() { msg ":: getting key for encrypted device..." IFS=: read ckdev ckarg1 ckarg2 </dev/null 2>&1; then msg ":: device ${key} is a LUKS volume..." plymouth ask-for-password --prompt="Password for ckey volume" --dont-pause-progress --number-of-tries=15 --command="/sbin/cryptsetup luksOpen --key-file=- ${ckey} ckey" ckey="/dev/mapper/ckey" fi mount --mkdir -r -t "$ckfs2" "${ckey}" /ckey2 ckey="/ckey2/${ckpath2}" fi dd if="${ckey}" of="${ckeyfile}" >/dev/null 2>&1 if mountpoint -q /ckey2; then umount /ckey2 cryptsetup close --type luks ckey; fi 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." } _get_sig() { msg ":: getting signature for airootfs encrypted container..." DEPRECATED_CRYPT=0 IFS=: read sigdev sigarg1 sigarg2 </dev/null 2>&1; then plymouth ask-for-password --prompt="Password for ckey volume" --dont-pause-progress --number-of-tries=15 --command="/sbin/cryptsetup luksOpen --key-file=- ${sigpath} sigdev" sigpath="/dev/mapper/sigdev" fi msg ":: mount ${sigpath} (${sigfs2}) over /sigdev2" mount --mkdir -r -t "$sigfs2" "${sigpath}" /sigdev2 sigpath="/sigdev2/${sigpath2}" fi dd if="${sigpath}" of="${sigfile}" >/dev/null 2>&1 if mountpoint -q /sigdev2; then umount /sigdev2 cryptsetup close --type luks sigdev; fi umount /sigdev ;; *) # Read raw data from the block device # sigarg1 is numeric: sigarg1=offset, sigarg2=length dd if="${resolved}" of="${sigfile}" bs=1 skip="${sigarg1}" count="${sigarg2}" >/dev/null 2>&1 ;; esac else err "Can't mount device ${sigdev} over /sigdev" launch_interactive_shell fi if [ ! -f "${sigfile}" ]; then err "Signature file could not be opened. " launch_interactive_shell fi } _verify_signature() { local _status local _file="${1}" local _sigfile="${2}" local _dir _filename _dir="$(dirname "${_file}")" _filename="$(basename "${_file}")" cd "${_dir}" || exit 1 gpg --homedir /gpg --status-fd 1 --verify "${_sigfile}" "${_filename}" 2>/dev/null | grep -E '^\[GNUPG:\] GOODSIG' _status=$? cd -- "${OLDPWD}" || exit 1 return ${_status} } _cryptdev() { if [ -n "${cryptdevice}" ]; then DEPRECATED_CRYPT=0 IFS=: read cryptdev cryptname cryptoptions <&2 ;; esac done set +f IFS="$OLDIFS" unset OLDIFS } warn_deprecated() { msg "The syntax 'root=${root}' where '${root}' is an encrypted volume is deprecated" msg "Use 'cryptdevice=${root}:root root=/dev/mapper/root' instead." } _open_root() { resolved=$(cryptsetup isLuks "${cryptdev}" >/dev/null 2>&1 && echo "${cryptdev}") [ "${resolved}" = "" ] && resolved=$(resolve_device "${cryptdev}" ${rootdelay}) if [ "${resolved}" != "" ]; 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 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:" plymouth ask-for-password --prompt="Password for ${cryptname} volume" --dont-pause-progress --number-of-tries=15 --command="/sbin/cryptsetup luksOpen --key-file=- ${resolved} ${cryptname} ${cryptargs} ${CSQUIET}" 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..." return 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 </dev/null 2>&1 # shellcheck disable=SC2154 [ "${quiet}" = "y" ] && CSQUIET=">/dev/null" _cryptdev # Get signature file if specified sigfile="/crypto_sigfile.bin" if [ -n "$sigdevice" ]; then _get_sig fi # shellcheck disable=SC2154 [ "${verify}" = "y" ] && _verify # Get key file if specified ckeyfile="/crypto_keyfile.bin" if [ -n "$cryptkey" ]; then _get_key fi # This may happen if third party hooks do the crypt setup if [ -b "/dev/mapper/${cryptname}" ]; then echo "Device ${cryptname} already exists, not doing any crypt setup." return 0 fi _set_cryptargs _open_root rm -f ${ckeyfile} rm -f "${sigfile}" } # vim: set ft=sh ts=4 sw=4 et: