agherzan / yubikey-full-disk-encryption

Use YubiKey to unlock a LUKS partition
Apache License 2.0
795 stars 50 forks source link

Grub always asking for password before YKFDE #53

Closed RikuXan closed 4 years ago

RikuXan commented 4 years ago

Whenever I start my computer, Grub prompts me for the LUKS decryption password (and drops me to a rescue shell if I don't comply) before I even have the chance to use YKFDE. After supplying my decryption password to Grub (I have two passwords enrolled, one "simple" password and one 2FA YubiKey password) the boot continues and goes into the YKFDE prompt where I put in my challenge, touch my YubiKey and am then told that the crypt device is already decrypted and mounted.

My boot partition is not encrypted, my /etc/mkinitcpio.conf hooks are HOOKS="base udev autodetect keyboard keymap modconf block ykfde filesystems fsck", my /etc/defaults/grub default command line is GRUB_CMDLINE_LINUX_DEFAULT="quiet cryptdevice=/dev/nvme0n1p2:luks-manjaro:allow-discards root=/dev/mapper/luks-manjaro resume=/dev/mapper/luks-manjaro".

I'm assuming my Grub is somehow misconfigured, but I coulnd't find any resources on how to do so correctly.

judemille commented 4 years ago

That looks to me like GRUB is configured to decrypt your rootfs. Can you post your /etc/default/grub in its entirety?

RikuXan commented 4 years ago

@juliandemille Please excuse the delay, but I wasn't able to access my computer over the weekend. The contents of my /etc/default/grub are

GRUB_DEFAULT=saved
GRUB_TIMEOUT=5
GRUB_TIMEOUT_STYLE=menu
GRUB_DISTRIBUTOR='Manjaro'
GRUB_CMDLINE_LINUX_DEFAULT="quiet cryptdevice=/dev/nvme0n1p2:luks-manjaro:allow-discards root=/dev/mapper/luks-manjaro resume=/dev/mapper/luks-manjaro"
GRUB_CMDLINE_LINUX=""

# If you want to enable the save default function, uncomment the following
# line, and set GRUB_DEFAULT to saved.
GRUB_SAVEDEFAULT=true

# Preload both GPT and MBR modules so that they are not missed
GRUB_PRELOAD_MODULES="part_gpt part_msdos"

# Uncomment to enable booting from LUKS encrypted devices
#GRUB_ENABLE_CRYPTODISK=y

# Uncomment to use basic console
GRUB_TERMINAL_INPUT=console

# Uncomment to disable graphical terminal
#GRUB_TERMINAL_OUTPUT=console

# The resolution used on graphical terminal
# note that you can use only modes which your graphic card supports via VBE
# you can see them in real GRUB with the command 'videoinfo'
GRUB_GFXMODE=auto

# Uncomment to allow the kernel use the same resolution used by grub
GRUB_GFXPAYLOAD_LINUX=keep

# Uncomment if you want GRUB to pass to the Linux kernel the old parameter
# format "root=/dev/xxx" instead of "root=/dev/disk/by-uuid/xxx"
#GRUB_DISABLE_LINUX_UUID=true

# Uncomment to disable generation of recovery mode menu entries
GRUB_DISABLE_RECOVERY=true

# Uncomment and set to the desired menu colors.  Used by normal and wallpaper
# modes only.  Entries specified as foreground/background.
GRUB_COLOR_NORMAL="light-gray/black"
GRUB_COLOR_HIGHLIGHT="green/black"

# Uncomment one of them for the gfx desired, a image background or a gfxtheme
#GRUB_BACKGROUND="/usr/share/grub/background.png"
GRUB_THEME="/usr/share/grub/themes/manjaro/theme.txt"

# Uncomment to get a beep at GRUB start
#GRUB_INIT_TUNE="480 440 1"

I did try booting with GRUB_ENABLE_CRYPTODISK=y commented in and out, with no apparent difference.

judemille commented 4 years ago

Try setting GRUB_ENABLE_CRYPTODISK to n and make sure to re-run grub-mkconfig with wherever your GRUB config is (probably /boot/grub/grub.cfg).

RikuXan commented 4 years ago

I uncommented the line and changed the y to n and then regenerated the config with sudo grub-mkconfig -o /boot/grub/grub.cfg. Nothing changed though, I was still prompted for decryption by grub. Is it possible that there are settings anywhere else, that overwrite my changes to /etc/default/grub? If it helps, my generated grub.cfg is as follows:

#
# DO NOT EDIT THIS FILE
#
# It is automatically generated by grub-mkconfig using templates
# from /etc/grub.d and settings from /etc/default/grub
#

### BEGIN /etc/grub.d/00_header ###
insmod part_gpt
insmod part_msdos
if [ -s $prefix/grubenv ]; then
  load_env
fi
if [ "${next_entry}" ] ; then
   set default="${next_entry}"
   set next_entry=
   save_env next_entry
   set boot_once=true
else
   set default="${saved_entry}"
fi

if [ x"${feature_menuentry_id}" = xy ]; then
  menuentry_id_option="--id"
else
  menuentry_id_option=""
fi

export menuentry_id_option

if [ "${prev_saved_entry}" ]; then
  set saved_entry="${prev_saved_entry}"
  save_env saved_entry
  set prev_saved_entry=
  save_env prev_saved_entry
  set boot_once=true
fi

function savedefault {
  if [ -z "${boot_once}" ]; then
    saved_entry="${chosen}"
    save_env saved_entry
  fi
}

function load_video {
  if [ x$feature_all_video_module = xy ]; then
    insmod all_video
  else
    insmod efi_gop
    insmod efi_uga
    insmod ieee1275_fb
    insmod vbe
    insmod vga
    insmod video_bochs
    insmod video_cirrus
  fi
}

set menu_color_normal=light-gray/black
set menu_color_highlight=green/black

if loadfont unicode ; then
  set gfxmode=auto
  load_video
  insmod gfxterm
  set locale_dir=$prefix/locale
  set lang=en_US
  insmod gettext
fi
terminal_input console
terminal_output gfxterm
if [ x$feature_timeout_style = xy ] ; then
  set timeout_style=menu
  set timeout=5
# Fallback normal timeout code in case the timeout_style feature is
# unavailable.
else
  set timeout=5
fi
### END /etc/grub.d/00_header ###

### BEGIN /etc/grub.d/01_menu_auto_hide ###
if [ "${boot_success}" = "1" -o "${boot_indeterminate}" = "1" ]; then
  set last_boot_ok=1
else
  set last_boot_ok=0
fi

# Reset boot_indeterminate after a successful boot
if [ "${boot_success}" = "1" ] ; then
  set boot_indeterminate=0
# Avoid boot_indeterminate causing the menu to be hidden more then once
elif [ "${boot_indeterminate}" = "1" ]; then
  set boot_indeterminate=2
fi
set boot_success=0
save_env boot_success boot_indeterminate

if [ x$feature_timeout_style = xy ] ; then
  if [ "${menu_show_once}" ]; then
    unset menu_show_once
    save_env menu_show_once
    set timeout_style=menu
    set timeout=60
  elif [ "${menu_auto_hide}" -a "${last_boot_ok}" = "1" ]; then
    set orig_timeout_style=${timeout_style}
    set orig_timeout=${timeout}
    if [ "${fastboot}" = "1" ]; then
      # timeout_style=menu + timeout=0 avoids the countdown code keypress check
      set timeout_style=menu
      set timeout=0
    else
      set timeout_style=hidden
      set timeout=1
    fi
  fi
fi
### END /etc/grub.d/01_menu_auto_hide ###

### BEGIN /etc/grub.d/10_linux ###
menuentry 'Manjaro Linux' --class manjaro --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-simple-8d9242ed-3d51-4a27-945b-2e19c773cc2f' {
    savedefault
    load_video
    set gfxpayload=keep
    insmod gzio
    insmod part_gpt
    insmod cryptodisk
    insmod luks
    insmod gcry_rijndael
    insmod gcry_rijndael
    insmod gcry_sha256
    insmod ext2
    set root='cryptouuid/0678001e36914ad3a652c603e473897d'
    if [ x$feature_platform_search_hint = xy ]; then
      search --no-floppy --fs-uuid --set=root --hint='cryptouuid/0678001e36914ad3a652c603e473897d'  8d9242ed-3d51-4a27-945b-2e19c773cc2f
    else
      search --no-floppy --fs-uuid --set=root 8d9242ed-3d51-4a27-945b-2e19c773cc2f
    fi
    linux   /boot/vmlinuz-4.19-x86_64 root=UUID=8d9242ed-3d51-4a27-945b-2e19c773cc2f rw  quiet cryptdevice=/dev/nvme0n1p2:luks-manjaro:allow-discards root=/dev/mapper/luks-manjaro resume=/dev/mapper/luks-manjaro
    initrd  /boot/intel-ucode.img /boot/initramfs-4.19-x86_64.img
}
submenu 'Advanced options for Manjaro Linux' $menuentry_id_option 'gnulinux-advanced-8d9242ed-3d51-4a27-945b-2e19c773cc2f' {
    menuentry 'Manjaro Linux (Kernel: 4.19.66-1-MANJARO x64)' --class manjaro --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-4.19.66-1-MANJARO x64-advanced-8d9242ed-3d51-4a27-945b-2e19c773cc2f' {
    savedefault
        load_video
        set gfxpayload=keep
        insmod gzio
        insmod part_gpt
        insmod cryptodisk
        insmod luks
        insmod gcry_rijndael
        insmod gcry_rijndael
        insmod gcry_sha256
        insmod ext2
        set root='cryptouuid/0678001e36914ad3a652c603e473897d'
        if [ x$feature_platform_search_hint = xy ]; then
          search --no-floppy --fs-uuid --set=root --hint='cryptouuid/0678001e36914ad3a652c603e473897d'  8d9242ed-3d51-4a27-945b-2e19c773cc2f
        else
          search --no-floppy --fs-uuid --set=root 8d9242ed-3d51-4a27-945b-2e19c773cc2f
        fi
        linux   /boot/vmlinuz-4.19-x86_64 root=UUID=8d9242ed-3d51-4a27-945b-2e19c773cc2f rw  quiet cryptdevice=/dev/nvme0n1p2:luks-manjaro:allow-discards root=/dev/mapper/luks-manjaro resume=/dev/mapper/luks-manjaro
        initrd  /boot/intel-ucode.img /boot/initramfs-4.19-x86_64.img
    }
    menuentry 'Manjaro Linux (Kernel: 4.19.66-1-MANJARO x64 - fallback initramfs)' --class manjaro --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-4.19.66-1-MANJARO x64-fallback-8d9242ed-3d51-4a27-945b-2e19c773cc2f' {
        load_video
        set gfxpayload=keep
        insmod gzio
        insmod part_gpt
        insmod cryptodisk
        insmod luks
        insmod gcry_rijndael
        insmod gcry_rijndael
        insmod gcry_sha256
        insmod ext2
        set root='cryptouuid/0678001e36914ad3a652c603e473897d'
        if [ x$feature_platform_search_hint = xy ]; then
          search --no-floppy --fs-uuid --set=root --hint='cryptouuid/0678001e36914ad3a652c603e473897d'  8d9242ed-3d51-4a27-945b-2e19c773cc2f
        else
          search --no-floppy --fs-uuid --set=root 8d9242ed-3d51-4a27-945b-2e19c773cc2f
        fi
        linux   /boot/vmlinuz-4.19-x86_64 root=UUID=8d9242ed-3d51-4a27-945b-2e19c773cc2f rw  quiet cryptdevice=/dev/nvme0n1p2:luks-manjaro:allow-discards root=/dev/mapper/luks-manjaro resume=/dev/mapper/luks-manjaro
        initrd  /boot/initramfs-4.19-x86_64-fallback.img
    }
}

### END /etc/grub.d/10_linux ###

### BEGIN /etc/grub.d/20_linux_xen ###
### END /etc/grub.d/20_linux_xen ###

### BEGIN /etc/grub.d/30_os-prober ###
### END /etc/grub.d/30_os-prober ###

### BEGIN /etc/grub.d/40_custom ###
# This file provides an easy way to add custom menu entries.  Simply type the
# menu entries you want to add after this comment.  Be careful not to change
# the 'exec tail' line above.
### END /etc/grub.d/40_custom ###

### BEGIN /etc/grub.d/41_custom ###
if [ -f  ${config_directory}/custom.cfg ]; then
  source ${config_directory}/custom.cfg
elif [ -z "${config_directory}" -a -f  $prefix/custom.cfg ]; then
  source $prefix/custom.cfg;
fi
### END /etc/grub.d/41_custom ###

### BEGIN /etc/grub.d/60_memtest86+ ###
### END /etc/grub.d/60_memtest86+ ###
Vincent43 commented 4 years ago

linux /boot/vmlinuz-4.19-x86_64 root=UUID=8d9242ed-3d51-4a27-945b-2e19c773cc2f rw quiet cryptdevice=/dev/nvme0n1p2:luks-manjaro:allow-discards root=/dev/mapper/luks-manjaro resume=/dev/mapper/luks-manjaro

It's weird that you have root= specified twice, maybe try removing root=/dev/mapper/luks-manjaro from GRUB_CMDLINE_LINUX_DEFAULT (you can edit it at runtime first to be safe)

judemille commented 4 years ago

Okay, that's some useful info. Can you post your /etc/grub.d/10-linux now please?

RikuXan commented 4 years ago

This file I have not changed myself, it was generated during my Manjaro installation (LUKS, unencrypted boot partition, no LVM). Its contents are:

#! /bin/sh
set -e

# grub-mkconfig helper script.
# Copyright (C) 2006,2007,2008,2009,2010  Free Software Foundation, Inc.
#
# GRUB is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# GRUB is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GRUB.  If not, see <http://www.gnu.org/licenses/>.

prefix="/usr"
exec_prefix="/usr"
datarootdir="/usr/share"
quiet_boot="1"

. "$pkgdatadir/grub-mkconfig_lib"

export TEXTDOMAIN=grub
export TEXTDOMAINDIR="${datarootdir}/locale"

CLASS="--class gnu-linux --class gnu --class os"

if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then
  OS=Linux
else
  OS="${GRUB_DISTRIBUTOR} Linux"
  CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr 'A-Z' 'a-z' | cut -d' ' -f1|LC_ALL=C sed 's,[^[:alnum:]_],_,g') ${CLASS}"
fi

# loop-AES arranges things so that /dev/loop/X can be our root device, but
# the initrds that Linux uses don't like that.
case ${GRUB_DEVICE} in
  /dev/loop/*|/dev/loop[0-9])
    GRUB_DEVICE=`losetup ${GRUB_DEVICE} | sed -e "s/^[^(]*(\([^)]\+\)).*/\1/"`
  ;;
esac

# Default to disabling partition uuid support to maintian compatibility with
# older kernels.
GRUB_DISABLE_LINUX_PARTUUID=${GRUB_DISABLE_LINUX_PARTUUID-true}

# btrfs may reside on multiple devices. We cannot pass them as value of root= parameter
# and mounting btrfs requires user space scanning, so force UUID in this case.
if ( [ "x${GRUB_DEVICE_UUID}" = "x" ] && [ "x${GRUB_DEVICE_PARTUUID}" = "x" ] ) \
    || ( [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ] \
    && [ "x${GRUB_DISABLE_LINUX_PARTUUID}" = "xtrue" ] ) \
    || ( ! test -e "/dev/disk/by-uuid/${GRUB_DEVICE_UUID}" \
    && ! test -e "/dev/disk/by-partuuid/${GRUB_DEVICE_PARTUUID}" ) \
    || ( test -e "${GRUB_DEVICE}" && uses_abstraction "${GRUB_DEVICE}" lvm ); then
  LINUX_ROOT_DEVICE=${GRUB_DEVICE}
elif [ "x${GRUB_DEVICE_UUID}" = "x" ] \
    || [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ]; then
  LINUX_ROOT_DEVICE=PARTUUID=${GRUB_DEVICE_PARTUUID}
else
  LINUX_ROOT_DEVICE=UUID=${GRUB_DEVICE_UUID}
fi

case x"$GRUB_FS" in
    xbtrfs)
    rootsubvol="`make_system_path_relative_to_its_root /`"
    rootsubvol="${rootsubvol#/}"
    if [ "x${rootsubvol}" != x ]; then
        GRUB_CMDLINE_LINUX="rootflags=subvol=${rootsubvol} ${GRUB_CMDLINE_LINUX}"
    fi;;
    xzfs)
    rpool=`${grub_probe} --device ${GRUB_DEVICE} --target=fs_label 2>/dev/null || true`
    bootfs="`make_system_path_relative_to_its_root / | sed -e "s,@$,,"`"
    LINUX_ROOT_DEVICE="ZFS=${rpool}${bootfs%/}"
    ;;
esac

title_correction_code=

linux_entry ()
{
  os="$1"
  version="$2"
  type="$3"
  args="$4"

  if [ -z "$boot_device_id" ]; then
      boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")"
  fi
  if [ x$type != xsimple ] ; then
      case $type in
      recovery)
          title="$(gettext_printf "%s (Kernel: %s - recovery mode)" "${os}" "${version}")" ;;
      fallback)
          title="$(gettext_printf "%s (Kernel: %s - fallback initramfs)" "${os}" "${version}")" ;;
      *)
          title="$(gettext_printf "%s (Kernel: %s)" "${os}" "${version}")" ;;
      esac
      if [ x"$title" = x"$GRUB_ACTUAL_DEFAULT" ] || [ x"Previous Linux versions>$title" = x"$GRUB_ACTUAL_DEFAULT" ]; then
      replacement_title="$(echo "Advanced options for ${OS}" | sed 's,>,>>,g')>$(echo "$title" | sed 's,>,>>,g')"
      quoted="$(echo "$GRUB_ACTUAL_DEFAULT" | grub_quote)"
      title_correction_code="${title_correction_code}if [ \"x\$default\" = '$quoted' ]; then default='$(echo "$replacement_title" | grub_quote)'; fi;"
      grub_warn "$(gettext_printf "Please don't use old title \`%s' for GRUB_DEFAULT, use \`%s' (for versions before 2.00) or \`%s' (for 2.00 or later)" "$GRUB_ACTUAL_DEFAULT" "$replacement_title" "gnulinux-advanced-$boot_device_id>gnulinux-$version-$type-$boot_device_id")"
      fi
      echo "menuentry '$(echo "$title" | grub_quote)' ${CLASS} \$menuentry_id_option 'gnulinux-$version-$type-$boot_device_id' {" | sed "s/^/$submenu_indentation/"
  else
      echo "menuentry '$(echo "$os" | grub_quote)' ${CLASS} \$menuentry_id_option 'gnulinux-simple-$boot_device_id' {" | sed "s/^/$submenu_indentation/"
  fi      
  if [ x$type != xrecovery ] && [ x$type != xfallback ] ; then
      save_default_entry | grub_add_tab
  fi

  # Use ELILO's generic "efifb" when it's known to be available.
  # FIXME: We need an interface to select vesafb in case efifb can't be used.
  if [ "x$GRUB_GFXPAYLOAD_LINUX" = x ]; then
      echo "    load_video" | sed "s/^/$submenu_indentation/"
      if grep -qx "CONFIG_FB_EFI=y" "${config}" 2> /dev/null \
      && grep -qx "CONFIG_VT_HW_CONSOLE_BINDING=y" "${config}" 2> /dev/null; then
      echo "    set gfxpayload=keep" | sed "s/^/$submenu_indentation/"
      fi
  else
      if [ "x$GRUB_GFXPAYLOAD_LINUX" != xtext ]; then
      echo "    load_video" | sed "s/^/$submenu_indentation/"
      fi
      echo "    set gfxpayload=$GRUB_GFXPAYLOAD_LINUX" | sed "s/^/$submenu_indentation/"
  fi

  echo "    insmod gzio" | sed "s/^/$submenu_indentation/"

  if [ x$dirname = x/ ]; then
    if [ -z "${prepare_root_cache}" ]; then
      prepare_root_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE} | grub_add_tab)"
    fi
    printf '%s\n' "${prepare_root_cache}" | sed "s/^/$submenu_indentation/"
  else
    if [ -z "${prepare_boot_cache}" ]; then
      prepare_boot_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | grub_add_tab)"
    fi
    printf '%s\n' "${prepare_boot_cache}" | sed "s/^/$submenu_indentation/"
  fi

  if [ x"$quiet_boot" = x0 ]; then
    message="$(gettext_printf "Loading Linux %s ..." "${version}")"
    sed "s/^/$submenu_indentation/" << EOF
    echo    '$(echo "$message" | grub_quote)'
EOF
  fi
    sed "s/^/$submenu_indentation/" << EOF
    linux   ${rel_dirname}/${basename} root=${linux_root_device_thisversion} rw ${args}
EOF
  if test -n "${initrd}" ; then
    # TRANSLATORS: ramdisk isn't identifier. Should be translated.
    message="$(gettext_printf "Loading initial ramdisk ...")"
    initrd_path=
    for i in ${initrd}; do
      initrd_path="${initrd_path} ${rel_dirname}/${i}"
    done
    if [ x"$quiet_boot" = x0 ]; then
      sed "s/^/$submenu_indentation/" << EOF
    echo    '$(echo "$message" | grub_quote)'
EOF
  fi
    sed "s/^/$submenu_indentation/" << EOF
    initrd  $(echo $initrd_path)
EOF
  fi
  sed "s/^/$submenu_indentation/" << EOF
}
EOF
}

machine=`uname -m`
case "x$machine" in
    xi?86 | xx86_64)
    list=
    for i in /boot/vmlinuz-* /vmlinuz-* /boot/kernel-* ; do
        if grub_file_is_not_garbage "$i" ; then list="$list $i" ; fi
    done ;;
    *) 
    list=
    for i in /boot/vmlinuz-* /boot/vmlinux-* /vmlinuz-* /vmlinux-* /boot/kernel-* ; do
                  if grub_file_is_not_garbage "$i" ; then list="$list $i" ; fi
    done ;;
esac

case "$machine" in
    i?86) GENKERNEL_ARCH="x86" ;;
    mips|mips64) GENKERNEL_ARCH="mips" ;;
    mipsel|mips64el) GENKERNEL_ARCH="mipsel" ;;
    arm*) GENKERNEL_ARCH="arm" ;;
    *) GENKERNEL_ARCH="$machine" ;;
esac

prepare_boot_cache=
prepare_root_cache=
boot_device_id=
title_correction_code=

# Extra indentation to add to menu entries in a submenu. We're not in a submenu
# yet, so it's empty. In a submenu it will be equal to '\t' (one tab).
submenu_indentation=""

is_top_level=true
while [ "x$list" != "x" ] ; do
  linux=`version_find_latest $list`
  gettext_printf "Found linux image: %s\n" "$linux" >&2
  basename=`basename $linux`
  dirname=`dirname $linux`
  rel_dirname=`make_system_path_relative_to_its_root $dirname`
  version=`echo $basename | sed -e "s,^[^0-9]*-,,g"`
  alt_version=`echo $version | sed -e "s,\.old$,,g"`
  linux_root_device_thisversion="${LINUX_ROOT_DEVICE}"

  if test -e "/etc/manjaro-release" ; then
    kbasename="`echo "${basename}" | sed -e 's,vmlinuz-,linux,g'`"
    if test -e "${dirname}/${kbasename}.kver" ; then
    version="$(cat ${dirname}/${kbasename}.kver)"
    fi
    kbasename2="`echo "${basename}" | sed -e 's,vmlinuz-,linux-,g'`"
    if test -e "${dirname}/${kbasename2}.kver" ; then
    version="$(cat ${dirname}/${kbasename2}.kver)"
    fi
    kbasename3="`echo "${basename}" | sed -e 's,vmlinuz-,linux,g' | sed -e 's,\.,,g'`"
    if test -e "${dirname}/${kbasename3}.kver" ; then
    version="$(cat ${dirname}/${kbasename3}.kver)"
    fi
    kbasename4="`echo "${basename}" | sed -e 's,vmlinuz-,linux-,g' | sed -e 's,\.,,g'`"
    if test -e "${dirname}/${kbasename4}.kver" ; then
    version="$(cat ${dirname}/${kbasename4}.kver)"
    fi
  fi

  initrd_early=
  for i in ${GRUB_EARLY_INITRD_LINUX_STOCK} \
       ${GRUB_EARLY_INITRD_LINUX_CUSTOM}; do
    if test -e "${dirname}/${i}" ; then
      initrd_early="${initrd_early} ${i}"
    fi
  done

  initrd_real=
  initramfs_manjaro="`echo "${basename}" | sed -e 's,vmlinuz,initramfs,g'`"
  for i in "initrd.img-${version}" "initrd-${version}.img" "initrd-${version}.gz" \
       "initrd-${version}" "initramfs-${version}.img" \
       "initrd.img-${alt_version}" "initrd-${alt_version}.img" \
       "initrd-${alt_version}" "initramfs-${alt_version}.img" \
       "initramfs-genkernel-${version}" \
       "initramfs-genkernel-${alt_version}" \
       "initramfs-genkernel-${GENKERNEL_ARCH}-${version}" \
       "initramfs-genkernel-${GENKERNEL_ARCH}-${alt_version}" \
       "${initramfs_manjaro}.img" ; do
    if test -e "${dirname}/${i}" ; then
      initrd_real="${i}"
      break
    fi
  done

  initrd=
  if test -n "${initrd_early}" || test -n "${initrd_real}"; then
    initrd="${initrd_early} ${initrd_real}"

    initrd_display=
    for i in ${initrd}; do
      initrd_display="${initrd_display} ${dirname}/${i}"
    done
    gettext_printf "Found initrd image: %s\n" "$(echo $initrd_display)" >&2
  fi

  config=
  for i in "${dirname}/config-${version}" "${dirname}/config-${alt_version}" "/etc/kernels/kernel-config-${version}" ; do
    if test -e "${i}" ; then
      config="${i}"
      break
    fi
  done

  initramfs=
  if test -n "${config}" ; then
      initramfs=`grep CONFIG_INITRAMFS_SOURCE= "${config}" | cut -f2 -d= | tr -d \"`
  fi

  if test -z "${initramfs}" && test -z "${initrd_real}" ; then
    # "UUID=" and "ZFS=" magic is parsed by initrd or initramfs.  Since there's
    # no initrd or builtin initramfs, it can't work here.
    if [ "x${GRUB_DEVICE_PARTUUID}" = "x" ] \
    || [ "x${GRUB_DISABLE_LINUX_PARTUUID}" = "xtrue" ]; then

    linux_root_device_thisversion=${GRUB_DEVICE}
    else
    linux_root_device_thisversion=PARTUUID=${GRUB_DEVICE_PARTUUID}
    fi
  fi

  if [ "x$is_top_level" = xtrue ] && [ "x${GRUB_DISABLE_SUBMENU}" != xy ]; then
    linux_entry "${OS}" "${version}" simple \
    "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}"

    submenu_indentation="$grub_tab"

    if [ -z "$boot_device_id" ]; then
    boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")"
    fi
    # TRANSLATORS: %s is replaced with an OS name
    echo "submenu '$(gettext_printf "Advanced options for %s" "${OS}" | grub_quote)' \$menuentry_id_option 'gnulinux-advanced-$boot_device_id' {"
    is_top_level=false
  fi

  linux_entry "${OS}" "${version}" advanced \
              "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}"

  for i in "${initramfs_manjaro}-fallback.img" "initramfs-${version}-fallback.img" ; do
    if test -e "${dirname}/${i}" ; then
      initrd="${i}"
      gettext_printf "Found initrd fallback image: %s\n" "${dirname}/${initrd}" >&2
      linux_entry "${OS}" "${version}" fallback \
                  "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}"
      break
    fi
  done

  if [ "x${GRUB_DISABLE_RECOVERY}" != "xtrue" ]; then
    linux_entry "${OS}" "${version}" recovery \
                "single ${GRUB_CMDLINE_LINUX}"
  fi

  list=`echo $list | tr ' ' '\n' | fgrep -vx "$linux" | tr '\n' ' '`
done

# If at least one kernel was found, then we need to
# add a closing '}' for the submenu command.
if [ x"$is_top_level" != xtrue ]; then
  echo '}'
fi

echo "$title_correction_code"
Vincent43 commented 4 years ago

@RikuXan did you tried removing second root= as suggested in https://github.com/agherzan/yubikey-full-disk-encryption/issues/53#issuecomment-525040867 ?

RikuXan commented 4 years ago

I just tried removing the second root option and regenerating my grub config, but it's still asking me for a password. One thing I noticed, though I am not sure since when this has changed, is that the YKFDE decrpytion doesn't say that the device is already decrypted anymore. So it seems that grub is actually asking for the password and then not even using it.

Vincent43 commented 4 years ago

I wonder if you have second grub which is booted instead. Is this UEFI system?

Could you show efibootmgr -v and cat /proc/cmdline output?

You may also try re-installing grub: https://wiki.archlinux.org/index.php/GRUB#Installation_2

RikuXan commented 4 years ago

Yes, my system is UEFI-based. efibootmgr -v:

BootCurrent: 0006
Timeout: 2 seconds
BootOrder: 0006,0001
Boot0000* Windows Boot Manager  HD(2,GPT,a019935e-e5ad-4897-9134-58f33b38ffbb,0x96800,0x32000)/File(\EFI\Microsoft\Boot\bootmgfw.efi)WINDOWS.........x...B.C.D.O.B.J.E.C.T.=.{.9.d.e.a.8.6.2.c.-.5.c.d.d.-.4.e.7.0.-.a.c.c.1.-.f.3.2.b.3.4.4.d.4.7.9.5.}...a................
Boot0001* rEFInd Boot Manager   HD(1,GPT,c544de09-e30c-4130-8b9f-f398c7971710,0x800,0x96000)/File(\EFI\refind\refind_x64.efi)
Boot0006* Manjaro   HD(1,GPT,c544de09-e30c-4130-8b9f-f398c7971710,0x1000,0x96000)/File(\EFI\Manjaro\grubx64.efi)

cat /proc/cmdline:

BOOT_IMAGE=/boot/vmlinuz-4.19-x86_64 root=UUID=8d9242ed-3d51-4a27-945b-2e19c773cc2f rw quiet cryptdevice=/dev/nvme0n1p2:luks-manjaro:allow-discards resume=/dev/mapper/luks-manjaro

The other UEFI boot loaders were from previous OSes, I thought Manjaro would have overwritten them when I installed it as the sole OS on the computer, but it seems not.

I am somewhat scared to completely reinstall Grub. Is there anything that might go wrong in trying this?

XVicarious commented 4 years ago

What does your ykfde.conf look? You need to uncomment one of the options at the top and remember to include it in the initramfs. I was also facing this problem and those were my problem.

ng0177 commented 4 years ago

Can you be more specific and provide an example? What is meant by "include it in the initramfs", if e.g. the YKFDE_DISK_UUID is uncommented? Appreciate:-)

judemille commented 4 years ago

I'm seeing it now. GRUB is detecting your root as encrypted, as demonstrated by it searching for cryptouuid/<blah>. I don't think this is a YKFDE issue.

sandrokeil commented 4 years ago

@RikuXan You can take a look at my guide, maybe it helps to find your issue.

RikuXan commented 4 years ago

I'm sorry for not answering your questions when you were trying to help me, but I kind of lost track of my question and had accepted having to enter a passphrase and challenge when booting.

@XVicarious I have added ykfde to my initramfs config an rebuilt it using mkinitpcio -p linux. My ykfde.conf looks like this:

### Configuration for 'yubikey-full-disk-encryption'.
### Remove hash (#) symbol and set non-empty ("") value for chosen options to
### enable them.

### *REQUIRED* ###

# Set to non-empty value to use 'Automatic mode with stored challenge (1FA)'.
YKFDE_CHALLENGE="<my-challenge>"

# Use 'Manual mode with secret challenge (2FA)'.
YKFDE_CHALLENGE_PASSWORD_NEEDED="1"

# YubiKey slot configured for 'HMAC-SHA1 Challenge-Response' mode.
# Possible values are "1" or "2". Defaults to "2".
#YKFDE_CHALLENGE_SLOT="2"

### OPTIONAL ###

# Enable communication with YubiKey via NFC (Experimental).
#YKFDE_NFC="1"

# UUID of device to unlock with 'cryptsetup'.
# Leave empty to use 'cryptdevice' boot parameter.
YKFDE_DISK_UUID="0678001e-3691-4ad3-a652-c603e473897d"

# LUKS encrypted volume name after unlocking.
# Leave empty to use 'cryptdevice' boot parameter.
YKFDE_LUKS_NAME="luks-manjaro"

# Device to unlock with 'cryptsetup'. If left empty and 'YKFDE_DISK_UUID'
# is enabled this will be set as "/dev/disk/by-uuid/$YKFDE_DISK_UUID".
# Leave empty to use 'cryptdevice' boot parameter.
#YKFDE_LUKS_DEV="/dev/nvme0n1p2"

# Optional flags passed to 'cryptsetup'. Example: "--allow-discards" for TRIM
# support. Leave empty to use 'cryptdevice' boot parameter.
YKFDE_LUKS_OPTIONS="--allow-discards"

# Number of times to try assemble 'ykfde passphrase' and run 'cryptsetup'.
# Defaults to "5".
#YKFDE_CRYPTSETUP_TRIALS="5"

# Number of seconds to wait for inserting YubiKey, "-1" means 'unlimited'.
# Defaults to "30".
#YKFDE_CHALLENGE_YUBIKEY_INSERT_TIMEOUT="30"

# Number of seconds to wait after successful decryption.
# Defaults to empty, meaning NO wait.
#YKFDE_SLEEP_AFTER_SUCCESSFUL_CRYPTSETUP=""

# Verbose output. It will print all secrets to terminal.
# Use only for debugging.
#DBG="1"

@sandrokeil Thank you very much for the guide, it looks great. Unfortunately there is a key difference to my setup: my boot partition is not actually encrypted. I just realized that having to type in the GRUB LUKS password is the intended outcome of your guide. My wish would be, especially seeing that my boot partition is not actually encrypted, that GRUB does not ask for the password and hands over the decryption of my root partition to the ykfde initramfs module.

Vincent43 commented 4 years ago

This perhaps won't solve your problem but you shouldn't enable both YKFDE_CHALLENGE and YKFDE_CHALLENGE_PASSWORD_NEEDED. The latter will always take precedence but your challenge won't be secret.

RikuXan commented 4 years ago

@Vincent43 Thanks for the pointer, I removed the challenge from the config file.

RikuXan commented 4 years ago

I actually found the issue and the banality of it kinda embarrasses me, but maybe it helps anyone. I actually had no separate boot partition, rather it was embedded into my root partition. The only separate, unencrypted partition was my EFI partition (mounted under /boot/efi) which only contained EFI bootloaders, but no linux kernel, no initramfs and no GRUB config. So obviously the GRUB EFI binary has no configuration file and can only see an encrypted partition so therefore must ask for a decryption password, no matter what I configure in my at this point inaccessible GRUB configuration file.

My solution was to copy everything from my /boot directory (save for the efi folder) into the /boot/efi/ directory so that kernel, initramfs and config files are accessible there and reconfigured my fstab to mount the EFI partition on /boot in order to still have future kernel updates applied correctly.

A big thanks to everyone who tried to help me.

mschabhuettl commented 4 years ago

I actually found the issue and the banality of it kinda embarrasses me, but maybe it helps anyone. I actually had no separate boot partition, rather it was embedded into my root partition. The only separate, unencrypted partition was my EFI partition (mounted under /boot/efi) which only contained EFI bootloaders, but no linux kernel, no initramfs and no GRUB config. So obviously the GRUB EFI binary has no configuration file and can only see an encrypted partition so therefore must ask for a decryption password, no matter what I configure in my at this point inaccessible GRUB configuration file.

My solution was to copy everything from my /boot directory (save for the efi folder) into the /boot/efi/ directory so that kernel, initramfs and config files are accessible there and reconfigured my fstab to mount the EFI partition on /boot in order to still have future kernel updates applied correctly.

A big thanks to everyone who tried to help me.

I'm experiencing the same probelm! Thank you very much - you helped me a lot. Could you explain me how did you get the grubx64.efi to load the kernel, etc. which is copied to the same directory.

RikuXan commented 4 years ago

My GRUB configuration was actually already configured to load the kernel from /boot from the OS install, so I didn't have to configure anything else to make it work.

If that is not the case for you, the grubx64.efi should also search for its configuration under /boot/grub/grub.cfg I suppose, at least I wouldn't know where else it would look for it.

mashedkeyboard commented 3 years ago

Hey folks, I'm also coming across this on a fresh Manjaro install; trying to get my head around it at the moment. I moved the files across and changed fstab appropriately, but GRUB couldn't find normal.mod until I copied all the files back over to the original partition - which restored the laptop to working order, but still keeps this issue in play. @mschabhuettl, did you manage to fix the problem you had, which I think was along these lines?

mashedkeyboard commented 3 years ago

Got it to work!

For the sake of anyone else coming across this, what worked for me was moving /boot onto the EFI partition (by copying the files in /boot into /boot/efi), changing fstab so that the EFI partition mounts at /boot, and editing /etc/default/grub to disable the GRUB_ENABLE_CRYPTODISK setting. Then, I ran sudo update-grub and sudo grub-install /dev/mydevice --efi-directory /boot - the EFI directory had to be specifically stated to grub-install, otherwise it just failed saying it couldn't work out where to put everything.

As I'm using plymouth, I also got rid entirely of plymouth-encrypt from the HOOKS line, as I only have the YubiKey drive to unlock.