You are not logged in.

#1 2024-03-10 16:51:01

CaeriTech
Member
Registered: 2021-07-12
Posts: 41

[SOLVED] mkinitcpio v38 breaks detached headers/keys

Synopses: In addition to upgrading to mkinitcpio 38.1 I had to add a double quote of a variable to my patch to match those added to the new encrypt hook.

The recent changes to mkinitcpio v38 seems to have broked my use of detached headers and keys even though it is said that they should not break user configs.

dmesg error message:

Unknown kernel command line parameters "cryptdevice=/dev/md128:TESTING:header cryptkey=rootfs:/boot/cLX/TESTING~k", will be passed to user space.

This is the hooks decelaration in mkinitcpio.conf:

HOOKS=(autodetect base block consolefont keymap filesystems keyboard mdadm_udev udev encrypt)

And here is the kernel command line:

initrd=\EFI\TESTING\initramfs-linux.img root=/dev/mapper/TESTING cryptdevice=/dev/md128:TESTING:header cryptkey=rootfs:/boot/cLX/TESTING~k init=/usr/lib/systemd/systemd pcie_aspm=force rootdelay=3 rd.udev.log-priority=3 vt.global_cursor_default=0 quiet loglevel=0 fbcon=nodefer fbcon=font:TER16x32

See below for the modifications to the encrypt hook:

#!/usr/bin/ash

run_hook() {
    modprobe -a -q dm-crypt >/dev/null 2>&1
    # assigned by parse_cmdline
    # shellcheck disable=SC2154
    [ "${quiet}" = "y" ] && CSQUIET=">/dev/null"

    # Get keyfile if specified
    ckeyfile="/crypto_keyfile.bin"
    if [ -n "$cryptkey" ]; then
	IFS=: read -r ckdev ckarg1 ckarg2 <<EOF
$cryptkey
EOF

	# rootdelay is assigned by parse_cmdline
	# shellcheck disable=SC2154
	if [ "$ckdev" = "rootfs" ]; then
	    ckeyfile=$ckarg1
	elif resolved=$(resolve_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" "$resolved" /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="$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

    if [ -n "${cryptdevice}" ]; then
	DEPRECATED_CRYPT=0
	IFS=: read -r cryptdev cryptname cryptoptions <<EOF
$cryptdevice
EOF
    else
	DEPRECATED_CRYPT=1
	cryptdev="${root}"
	cryptname="root"
    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

    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."
    }

    set -f
    OLDIFS="$IFS"; IFS=,
############### mod START
    local headerFlag=false
############### mod END
    for cryptopt in ${cryptoptions}; do
	case ${cryptopt} in
	    allow-discards|discard)
		cryptargs="${cryptargs} --allow-discards"
		;;
############### mod START
	    header)
		cryptargs="${cryptargs} --header=/boot/cLX/TESTING~h"
		headerFlag=true
############### mod END
		;;
	    no-read-workqueue|perf-no_read_workqueue)
		cryptargs="${cryptargs} --perf-no_read_workqueue"
		;;
	    no-write-workqueue|perf-no_write_workqueue)
		cryptargs="${cryptargs} --perf-no_write_workqueue"
		;;
	    sector-size=*)
		cryptargs="${cryptargs} --sector-size ${cryptopt#*=}"
		;;
	    *)
		echo "Encryption option '${cryptopt}' not known, ignoring." >&2
		;;
	esac
    done
    set +f
    IFS="$OLDIFS"
    unset OLDIFS

    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
		    echo "Invalid keyfile. Reverting to passphrase."
		fi
	    fi
	    # Ask for a passphrase
	    if [ "${dopassphrase}" -gt 0 ]; then
		if command -v plymouth >/dev/null 2>&1 && plymouth --ping 2>/dev/null; then
		    plymouth ask-for-password \
			--prompt="A password is required to access the ${cryptname} volume" \
			--command="cryptsetup open --type luks --key-file=- ${resolved} ${cryptname} ${cryptargs} ${CSQUIET}"
		else
		    echo ""
		    echo "A password is required to access the ${cryptname} volume:"

		    #loop until we get a real password
		    while ! eval cryptsetup open --type luks "${resolved}" "${cryptname}" "${cryptargs}" "${CSQUIET}"; do
			sleep 2;
		    done
		fi
	    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 -r c_hash c_cipher c_keysize c_offset c_skip <<EOF
$crypto
EOF
	    [ -n "$c_hash" ]	&& exe="$exe --hash '$c_hash'"
	    [ -n "$c_cipher" ]	&& exe="$exe --cipher '$c_cipher'"
	    [ -n "$c_keysize" ] && exe="$exe --key-size '$c_keysize'"
	    [ -n "$c_offset" ]	&& exe="$exe --offset '$c_offset'"
	    [ -n "$c_skip" ]	&& exe="$exe --skip '$c_skip'"
	    if [ -f "$ckeyfile" ]; then
		exe="$exe --key-file $ckeyfile"
	    else
		echo ""
		echo "A password is required to access the ${cryptname} volume:"
	    fi
	    if ! eval "$exe $CSQUIET"; then
		err "Non-LUKS device decryption failed. verify format: "
		err "	   crypto=hash:cipher:keysize:offset:skip"
		return 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..."
		return 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}"
}

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

So my question is how do I need to change my mkinitcpio.conf and/or the encrypt hook to have this work as it did prior to mkinitcpio v38?

Last edited by CaeriTech (2024-03-14 19:18:09)


-=[ LIVE enabled UEFI with redundant syslinux pure systemd detached LUKS header partitionless encrypted GPT SSDx3 RAID0 wayland only because I can.  ]=-
    Backward compatibility is for the masses. There's no dual-boot here.

    [CaeriTech remains only artificially intelligent.  Turing would be aghast at just how artificial.]

Offline

#2 2024-03-10 18:06:26

frostschutz
Member
Registered: 2013-11-15
Posts: 1,622

Re: [SOLVED] mkinitcpio v38 breaks detached headers/keys

I don't use detached header so I can't comment on that (without reading deeper into the hook code).

However about this, this might not work anymore:

cryptdevice=/dev/md128

mdadm v4.3 unfortunately rejects anything >md127 now.

example:

# mdadm --create /dev/md128 --level=raid1 ...
mdadm: Value "/dev/md128" cannot be set as devname. Reason: Not POSIX compatible.
# mdadm --assemble /dev/md128 /dev/loop0
mdadm: Value "/dev/md128" cannot be set as devname. Reason: Not POSIX compatible.

You have to use /dev/md0 - 127 or /dev/md/name.

mdadm 4.3 rejects /dev/md128 and larger numbers @ lore.kernel.org/linux-raid

The unknown kernel command message should be normal, the kernel can't know what userspace (initcpio) will do with these.

Last edited by frostschutz (2024-03-10 18:12:27)

Offline

#3 2024-03-10 19:26:15

CaeriTech
Member
Registered: 2021-07-12
Posts: 41

Re: [SOLVED] mkinitcpio v38 breaks detached headers/keys

Thanks frostsuchutz.  I tried using a lower enumeration than 128 for the array but the failure to boot and the error message in dmesg remain.


-=[ LIVE enabled UEFI with redundant syslinux pure systemd detached LUKS header partitionless encrypted GPT SSDx3 RAID0 wayland only because I can.  ]=-
    Backward compatibility is for the masses. There's no dual-boot here.

    [CaeriTech remains only artificially intelligent.  Turing would be aghast at just how artificial.]

Offline

#4 2024-03-10 20:40:18

seth
Member
From: Don't DM me only for attention
Registered: 2012-09-03
Posts: 73,789

Re: [SOLVED] mkinitcpio v38 breaks detached headers/keys

Unknown kernel command line parameters "…", will be passed to user space.

Is normal and not indicative of an error.

So let's talk about

the failure to boot

How *exactly* does that manifest, what are the symptoms and error messages?
Can you still boot the multi-user.target or rescue.target (2nd link below)?

"quiet loglevel=0" - remove that.
"pcie_aspm=force" - errr… why? Tested w/o?
"rootdelay=3" tried "rootwait" instead?

Offline

#5 2024-03-11 14:48:58

CaeriTech
Member
Registered: 2021-07-12
Posts: 41

Re: [SOLVED] mkinitcpio v38 breaks detached headers/keys

Seth I removed/changes the command line parameters you suggested above but the errors remain the same:

mount: /new_root: special device /dev/mapper/TESTING does not exist.
.
.
.
ERROR: Failed to mount '/dev/mapper/TESTING' on real root

I confirmed that the header and key were set up correctly by manually opening /dev/mapper/TESTING from another distribution and it was fully accessible.


-=[ LIVE enabled UEFI with redundant syslinux pure systemd detached LUKS header partitionless encrypted GPT SSDx3 RAID0 wayland only because I can.  ]=-
    Backward compatibility is for the masses. There's no dual-boot here.

    [CaeriTech remains only artificially intelligent.  Turing would be aghast at just how artificial.]

Offline

#6 2024-03-11 15:11:19

seth
Member
From: Don't DM me only for attention
Registered: 2012-09-03
Posts: 73,789

Re: [SOLVED] mkinitcpio v38 breaks detached headers/keys

Ok, but that's at least an actual error message, or part thereof.

Have you confirmed that downgrading to the previous hook fixes this?
https://gitlab.archlinux.org/archlinux/ … 88cf3a1df3

Offline

#7 2024-03-11 15:32:00

CaeriTech
Member
Registered: 2021-07-12
Posts: 41

Re: [SOLVED] mkinitcpio v38 breaks detached headers/keys

That was my first thought but I can't quite figure out how to do that during the installation before I rebuild the initramfs.


-=[ LIVE enabled UEFI with redundant syslinux pure systemd detached LUKS header partitionless encrypted GPT SSDx3 RAID0 wayland only because I can.  ]=-
    Backward compatibility is for the masses. There's no dual-boot here.

    [CaeriTech remains only artificially intelligent.  Turing would be aghast at just how artificial.]

Offline

#8 2024-03-11 15:51:06

seth
Member
From: Don't DM me only for attention
Registered: 2012-09-03
Posts: 73,789

Re: [SOLVED] mkinitcpio v38 breaks detached headers/keys

You can either replace the file and then explicitly regenerate the initramfs or replace the file and "sudo chattr +i" it (make it immutable, it cannot be changed unless "chattr -i")

Offline

#9 2024-03-11 17:49:44

CaeriTech
Member
Registered: 2021-07-12
Posts: 41

Re: [SOLVED] mkinitcpio v38 breaks detached headers/keys

I can confirm that downgrading the encrypt hook results in a successful boot.


-=[ LIVE enabled UEFI with redundant syslinux pure systemd detached LUKS header partitionless encrypted GPT SSDx3 RAID0 wayland only because I can.  ]=-
    Backward compatibility is for the masses. There's no dual-boot here.

    [CaeriTech remains only artificially intelligent.  Turing would be aghast at just how artificial.]

Offline

#10 2024-03-11 18:14:53

seth
Member
From: Don't DM me only for attention
Registered: 2012-09-03
Posts: 73,789

Re: [SOLVED] mkinitcpio v38 breaks detached headers/keys

The almost only difference between the old and new encrypt hooks is that the new one quotes a lot of variables, including your manipulated ${cryptargs}
Make sure that
1. the  problem w/ the repo hook actually remains (and you didn't just have to rebuild the initramfs
2. your codepath gets triggered ("echo foo" behind the "header)" or so)
Then try to unquote the ${cryptargs} vars

Offline

#11 2024-03-12 20:40:09

seth
Member
From: Don't DM me only for attention
Registered: 2012-09-03
Posts: 73,789

Offline

#12 2024-03-14 13:03:35

CaeriTech
Member
Registered: 2021-07-12
Posts: 41

Re: [SOLVED] mkinitcpio v38 breaks detached headers/keys

No luck with the update I'm afraid.  I'm having the same issue with the updated 38.1 version of mkinitcpio.


-=[ LIVE enabled UEFI with redundant syslinux pure systemd detached LUKS header partitionless encrypted GPT SSDx3 RAID0 wayland only because I can.  ]=-
    Backward compatibility is for the masses. There's no dual-boot here.

    [CaeriTech remains only artificially intelligent.  Turing would be aghast at just how artificial.]

Offline

#13 2024-03-14 16:04:09

seth
Member
From: Don't DM me only for attention
Registered: 2012-09-03
Posts: 73,789

Re: [SOLVED] mkinitcpio v38 breaks detached headers/keys

What does your edited hook look like now?

Offline

#14 2024-03-14 17:19:05

CaeriTech
Member
Registered: 2021-07-12
Posts: 41

Re: [SOLVED] mkinitcpio v38 breaks detached headers/keys

[EDIT] Sorry.  if [ $? -ne 0 ] ; then was replaced by if ! eval "$exe $CSQUIET"; then in the new hook and that was my attempt to see if that was the cause since it was one of the more major changes. if ! eval "$exe $CSQUIET"; then is back in the hook again as edited below:
           

#!/usr/bin/ash

run_hook() {
    modprobe -a -q dm-crypt >/dev/null 2>&1
    # assigned by parse_cmdline
    # shellcheck disable=SC2154
    [ "${quiet}" = "y" ] && CSQUIET=">/dev/null"

    # Get keyfile if specified
    ckeyfile="/crypto_keyfile.bin"
    if [ -n "$cryptkey" ]; then
        # cryptkey can contain : which needs to be escaped.
        # shellcheck disable=SC2162
        IFS=: read ckdev ckarg1 ckarg2 <<EOF
$cryptkey
EOF

        # rootdelay is assigned by parse_cmdline
        # shellcheck disable=SC2154
        if [ "$ckdev" = "rootfs" ]; then
            ckeyfile=$ckarg1
        elif resolved=$(resolve_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" "$resolved" /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="$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

    if [ -n "${cryptdevice}" ]; then
        DEPRECATED_CRYPT=0
        # cryptdevice can contain : which needs to be escaped.
        # shellcheck disable=SC2162
        IFS=: read cryptdev cryptname cryptoptions <<EOF
$cryptdevice
EOF
    else
        DEPRECATED_CRYPT=1
        cryptdev="${root}"
        cryptname="root"
    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

    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."
    }

    set -f
    OLDIFS="$IFS"; IFS=,
########## mod START
    local headerFlag=false
########## mod END
    for cryptopt in ${cryptoptions}; do
        case ${cryptopt} in
            allow-discards|discard)
                cryptargs="${cryptargs} --allow-discards"
                ;;
########## mod START
            header)
                cryptargs="${cryptargs} --header=/boot/cLX/TESTING~h"
                headerFlag=true
########## mod END
                ;;
            no-read-workqueue|perf-no_read_workqueue)
                cryptargs="${cryptargs} --perf-no_read_workqueue"
                ;;
            no-write-workqueue|perf-no_write_workqueue)
                cryptargs="${cryptargs} --perf-no_write_workqueue"
                ;;
            sector-size=*)
                cryptargs="${cryptargs} --sector-size ${cryptopt#*=}"
                ;;
            *)
                echo "Encryption option '${cryptopt}' not known, ignoring." >&2
                ;;
        esac
    done
    set +f
    IFS="$OLDIFS"
    unset OLDIFS

    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
                    echo "Invalid keyfile. Reverting to passphrase."
                fi
            fi
            # Ask for a passphrase
            if [ "${dopassphrase}" -gt 0 ]; then
                if command -v plymouth >/dev/null 2>&1 && plymouth --ping 2>/dev/null; then
                    plymouth ask-for-password \
                        --prompt="A password is required to access the ${cryptname} volume" \
                        --command="cryptsetup open --type luks --key-file=- ${resolved} ${cryptname} ${cryptargs} ${CSQUIET}"
                else
                    echo ""
                    echo "A password is required to access the ${cryptname} volume:"

                    #loop until we get a real password
                    while ! eval cryptsetup open --type luks "${resolved}" "${cryptname}" "${cryptargs}" "${CSQUIET}"; do
                        sleep 2;
                    done
                fi
            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"
            # c_cipher can contain : which needs to be escaped.
            # shellcheck disable=SC2162
            IFS=: read c_hash c_cipher c_keysize c_offset c_skip <<EOF
$crypto
EOF
            [ -n "$c_hash" ]    && exe="$exe --hash '$c_hash'"
            [ -n "$c_cipher" ]  && exe="$exe --cipher '$c_cipher'"
            [ -n "$c_keysize" ] && exe="$exe --key-size '$c_keysize'"
            [ -n "$c_offset" ]  && exe="$exe --offset '$c_offset'"
            [ -n "$c_skip" ]    && exe="$exe --skip '$c_skip'"
            if [ -f "$ckeyfile" ]; then
                exe="$exe --key-file $ckeyfile"
            else
                echo ""
                echo "A password is required to access the ${cryptname} volume:"
            fi
            if ! eval "$exe $CSQUIET"; then
                err "Non-LUKS device decryption failed. verify format: "
                err "      crypto=hash:cipher:keysize:offset:skip"
                return 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..."
                return 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}"
}

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

Last edited by CaeriTech (2024-03-14 17:44:44)


-=[ LIVE enabled UEFI with redundant syslinux pure systemd detached LUKS header partitionless encrypted GPT SSDx3 RAID0 wayland only because I can.  ]=-
    Backward compatibility is for the masses. There's no dual-boot here.

    [CaeriTech remains only artificially intelligent.  Turing would be aghast at just how artificial.]

Offline

#15 2024-03-14 17:23:44

frostschutz
Member
Registered: 2013-11-15
Posts: 1,622

Re: [SOLVED] mkinitcpio v38 breaks detached headers/keys

the headerFlag isn't used anywhere?

why is this disabled? ######## if ! eval "$exe $CSQUIET";

Offline

#16 2024-03-14 17:35:43

seth
Member
From: Don't DM me only for attention
Registered: 2012-09-03
Posts: 73,789

Re: [SOLVED] mkinitcpio v38 breaks detached headers/keys

The latter is for sure a problem because the next line queries the result of the previous call and looks like a remnant from the old version?

Offline

#17 2024-03-14 17:45:29

CaeriTech
Member
Registered: 2021-07-12
Posts: 41

Re: [SOLVED] mkinitcpio v38 breaks detached headers/keys

See my [EDIT] above...


-=[ LIVE enabled UEFI with redundant syslinux pure systemd detached LUKS header partitionless encrypted GPT SSDx3 RAID0 wayland only because I can.  ]=-
    Backward compatibility is for the masses. There's no dual-boot here.

    [CaeriTech remains only artificially intelligent.  Turing would be aghast at just how artificial.]

Offline

#18 2024-03-14 18:02:30

seth
Member
From: Don't DM me only for attention
Registered: 2012-09-03
Posts: 73,789

Re: [SOLVED] mkinitcpio v38 breaks detached headers/keys

Offline

#19 2024-03-14 19:15:20

CaeriTech
Member
Registered: 2021-07-12
Posts: 41

Re: [SOLVED] mkinitcpio v38 breaks detached headers/keys

You got it!  I did not add those double quotes you mentioned from the outset being in the new hook to my patch and it completely missed the if $headerFlag || cryptsetup isLuks "${resolved}" >/dev/null 2>&1; then modification.

Thanks seth for taking the time to look into this.  It's not the first time I've had an obvious error staring me in the face that took another pair of eyes to bring to my attention.  I can boot perfectly now. Thanks again.

This is what the correctly modified encrypt hook looks like now:

#!/usr/bin/ash

run_hook() {
    modprobe -a -q dm-crypt >/dev/null 2>&1
    # assigned by parse_cmdline
    # shellcheck disable=SC2154
    [ "${quiet}" = "y" ] && CSQUIET=">/dev/null"

    # Get keyfile if specified
    ckeyfile="/crypto_keyfile.bin"
    if [ -n "$cryptkey" ]; then
        # cryptkey can contain : which needs to be escaped.
        # shellcheck disable=SC2162
        IFS=: read ckdev ckarg1 ckarg2 <<EOF
$cryptkey
EOF

        # rootdelay is assigned by parse_cmdline
        # shellcheck disable=SC2154
        if [ "$ckdev" = "rootfs" ]; then
            ckeyfile=$ckarg1
        elif resolved=$(resolve_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" "$resolved" /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="$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

    if [ -n "${cryptdevice}" ]; then
        DEPRECATED_CRYPT=0
        # cryptdevice can contain : which needs to be escaped.
        # shellcheck disable=SC2162
        IFS=: read cryptdev cryptname cryptoptions <<EOF
$cryptdevice
EOF
    else
        DEPRECATED_CRYPT=1
        cryptdev="${root}"
        cryptname="root"
    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

    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."
    }

    set -f
    OLDIFS="$IFS"; IFS=,
########### mod START
    local headerFlag=false
########### mod END
    for cryptopt in ${cryptoptions}; do
        case ${cryptopt} in
            allow-discards|discard)
                cryptargs="${cryptargs} --allow-discards"
                ;;
########### mod START
            header)
                cryptargs="${cryptargs} --header=/boot/cLX/TESTING~h"
                headerFlag=true
########### mod END
                ;;
            no-read-workqueue|perf-no_read_workqueue)
                cryptargs="${cryptargs} --perf-no_read_workqueue"
                ;;
            no-write-workqueue|perf-no_write_workqueue)
                cryptargs="${cryptargs} --perf-no_write_workqueue"
                ;;
            sector-size=*)
                cryptargs="${cryptargs} --sector-size ${cryptopt#*=}"
                ;;
            *)
                echo "Encryption option '${cryptopt}' not known, ignoring." >&2
                ;;
        esac
    done
    set +f
    IFS="$OLDIFS"
    unset OLDIFS

    if resolved=$(resolve_device "${cryptdev}" "${rootdelay}"); then
########### mod START
      if $headerFlag || cryptsetup isLuks "${resolved}" >/dev/null 2>&1; then
########### mod END
            [ "${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
                if command -v plymouth >/dev/null 2>&1 && plymouth --ping 2>/dev/null; then
                    plymouth ask-for-password \
                        --prompt="A password is required to access the ${cryptname} volume" \
                        --command="cryptsetup open --type luks --key-file=- ${resolved} ${cryptname} ${cryptargs} ${CSQUIET}"
                else
                    echo ""
                    echo "A password is required to access the ${cryptname} volume:"

                    #loop until we get a real password
                    while ! eval cryptsetup open --type luks "${resolved}" "${cryptname}" "${cryptargs}" "${CSQUIET}"; do
                        sleep 2;
                    done
                fi
            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"
            # c_cipher can contain : which needs to be escaped.
            # shellcheck disable=SC2162
            IFS=: read c_hash c_cipher c_keysize c_offset c_skip <<EOF
$crypto
EOF
            [ -n "$c_hash" ]    && exe="$exe --hash '$c_hash'"
            [ -n "$c_cipher" ]  && exe="$exe --cipher '$c_cipher'"
            [ -n "$c_keysize" ] && exe="$exe --key-size '$c_keysize'"
            [ -n "$c_offset" ]  && exe="$exe --offset '$c_offset'"
            [ -n "$c_skip" ]    && exe="$exe --skip '$c_skip'"
            if [ -f "$ckeyfile" ]; then
                exe="$exe --key-file $ckeyfile"
            else
                echo ""
                echo "A password is required to access the ${cryptname} volume:"
            fi
            if ! eval "$exe $CSQUIET"; then
                err "Non-LUKS device decryption failed. verify format: "
                err "      crypto=hash:cipher:keysize:offset:skip"
                return 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..."
                return 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}"
}

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

-=[ LIVE enabled UEFI with redundant syslinux pure systemd detached LUKS header partitionless encrypted GPT SSDx3 RAID0 wayland only because I can.  ]=-
    Backward compatibility is for the masses. There's no dual-boot here.

    [CaeriTech remains only artificially intelligent.  Turing would be aghast at just how artificial.]

Offline

#20 2024-04-05 03:31:43

The WiFi Nerds
Member
Registered: 2024-03-26
Posts: 3

Re: [SOLVED] mkinitcpio v38 breaks detached headers/keys

I was hoping this would go away. I've had this error since I first installed Arch using Archinstall. Assumed it may be related to this post and just fix itself.

I boot fine and the system works great for the most part. Is there a change that I do need to make, however?

Kernel command line: initrd=\amd-ucode.img initrd=\initramfs-linux.img cryptdevice=PARTUUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx:root root=/dev/mapper/root zswap.enabled=0 rootflags=subvol=@ rw rootfstype=btrfs
Apr 04 16:41:56 archlinux kernel: Unknown kernel command line parameters "cryptdevice=PARTUUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx:root", will be passed to user space.

I've tried reading this discourse and can't quite put my finger on what needs to be done; only that it's related to the xxx:root  I replaced my UUID's with x's for obscurity only.

Last edited by The WiFi Nerds (2024-04-05 03:41:20)

Offline

#21 2024-04-05 06:57:22

seth
Member
From: Don't DM me only for attention
Registered: 2012-09-03
Posts: 73,789

Re: [SOLVED] mkinitcpio v38 breaks detached headers/keys

This thread is about a very specific problem with a botched patch. It's not related to that warning

"cryptdevice" is simply not a https://raw.githubusercontent.com/torva … meters.txt and whatever you add to the kernel commandline that the kernel doesn't understand, it'll pass just through to the userspace so the parameters can be interpreted by any regular process (eg. to control startup behavior, you could have a shell profile that auto-starts X11 unless you add "nofuckinggui" to the kernel parameters (inserting "fuck" helps a lot to not accidentallly collide w/ legit parameters wink)

Since this could also be a typo where you wanted to add an actual kernel parameter but misspelled it, the kernel warns about this.
Do you know the meme where Leslie Nielsen stands in front of a burning building?

Offline

#22 2024-04-05 10:14:27

The WiFi Nerds
Member
Registered: 2024-03-26
Posts: 3

Re: [SOLVED] mkinitcpio v38 breaks detached headers/keys

I do now lol

Sorry about that, I was quite tired and puzzled by that one, I appreciate you taking the time to respond.

Last edited by The WiFi Nerds (2024-04-05 10:14:41)

Offline

Board footer

Powered by FluxBB