aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Baranov <reagentoo@gmail.com>2020-10-14 22:03:01 +0300
committerDmitry Baranov <reagentoo@gmail.com>2021-08-07 20:20:10 +0300
commit73a05632d61171685ac4960c6b684cefa6d82afd (patch)
tree639bc32c7b6de9bdf8ff1ff483b15e1563bad98e
parentdefaults/initrd.scripts: Get rid of extra padding (diff)
downloadgenkernel-73a05632.tar.gz
genkernel-73a05632.tar.bz2
genkernel-73a05632.zip
Add support for LUKS detached header
Signed-off-by: Dmitry Baranov <reagentoo@gmail.com>
-rw-r--r--defaults/initrd.scripts162
-rw-r--r--defaults/linuxrc18
-rw-r--r--doc/genkernel.8.txt22
3 files changed, 186 insertions, 16 deletions
diff --git a/defaults/initrd.scripts b/defaults/initrd.scripts
index 33a48b39..5a83d935 100644
--- a/defaults/initrd.scripts
+++ b/defaults/initrd.scripts
@@ -306,7 +306,7 @@ bootstrapFS() {
fi
# Setup the filesystem nodes and directories
- for i in ${CDROOT_PATH} /mnt/livecd /mnt/key /mnt/gentoo /tmp /tmp/.initrd /dev /proc /run /sys; do
+ for i in ${CDROOT_PATH} /mnt/header /mnt/livecd /mnt/key /mnt/gentoo /tmp /tmp/.initrd /dev /proc /run /sys; do
run mkdir -p "${NEW_ROOT}${i}"
run chmod 755 "${NEW_ROOT}${i}"
done
@@ -391,6 +391,14 @@ bootstrapCD() {
fi
}
+bootstrapHeader() {
+ # $1 = ROOT/SWAP
+ local HEADERDEVS=$(devicelist)
+ eval local headerloc='"${CRYPT_'${1}'_HEADER}"'
+
+ findmediamount "header" "${headerloc}" "CRYPT_${1}_HEADERDEV" "/mnt/header" ${HEADERDEVS}
+}
+
bootstrapKey() {
# $1 = ROOT/SWAP
local KEYDEVS=$(devicelist)
@@ -1828,12 +1836,17 @@ openLUKS() {
local LUKS_NAME="${1}"
eval local LUKS_DEVICE='"${CRYPT_'${TYPE}'}"'
+ eval local LUKS_HEADER='"${CRYPT_'${TYPE}'_HEADER}"'
+ eval local LUKS_HEADERDEV='"${CRYPT_'${TYPE}'_HEADERDEV}"'
+ eval local LUKS_HEADERDEV_FSTYPE='"${CRYPT_'${TYPE}'_HEADERDEV_FSTYPE}"'
eval local LUKS_KEY='"${CRYPT_'${TYPE}'_KEY}"'
eval local LUKS_KEYDEV='"${CRYPT_'${TYPE}'_KEYDEV}"'
eval local LUKS_KEYDEV_FSTYPE='"${CRYPT_'${TYPE}'_KEYDEV_FSTYPE}"'
eval local OPENED_LOCKFILE='"${CRYPT_'${TYPE}'_OPENED_LOCKFILE}"'
- local DEV_ERROR=0 KEY_ERROR=0 KEYDEV_ERROR=0
- local mntkey="/mnt/key/" crypt_filter_ret=
+ local DEV_ERROR=0
+ local HEADER_ERROR=0 HEADERDEV_ERROR=0
+ local KEY_ERROR=0 KEYDEV_ERROR=0
+ local mntheader="/mnt/header/" mntkey="/mnt/key/" crypt_filter_ret=
if [ -z "${LUKS_DEVICE}" ]
then
@@ -1853,13 +1866,27 @@ openLUKS() {
good_msg "The LUKS device ${LUKS_DEVICE} meanwhile was opened by someone else."
break
# if crypt_silent=1 and some error occurs, enter shell quietly
- elif [ \( ${CRYPT_SILENT} -eq 1 \) -a \( \( \( ${DEV_ERROR} -eq 1 \) -o \( ${KEY_ERROR} -eq 1 \) \) -o \( ${KEYDEV_ERROR} -eq 1 \) \) ]
+ elif [ \( ${CRYPT_SILENT} -eq 1 \) -a \( \( \( ${DEV_ERROR} -eq 1 \) \) ]
+ then
+ run_emergency_shell
+ elif [ \( ${CRYPT_SILENT} -eq 1 \) -a \( \( \( ${HEADER_ERROR} -eq 1 \) \) -o \( ${HEADERDEV_ERROR} -eq 1 \) \) ]
+ then
+ run_emergency_shell
+ elif [ \( ${CRYPT_SILENT} -eq 1 \) -a \( \( \( ${KEY_ERROR} -eq 1 \) \) -o \( ${KEYDEV_ERROR} -eq 1 \) \) ]
then
run_emergency_shell
elif [ ${DEV_ERROR} -eq 1 ]
then
prompt_user "LUKS_DEVICE" "${LUKS_NAME}"
DEV_ERROR=0
+ elif [ ${HEADER_ERROR} -eq 1 ]
+ then
+ prompt_user "LUKS_HEADER" "${LUKS_NAME} header"
+ HEADER_ERROR=0
+ elif [ ${HEADERDEV_ERROR} -eq 1 ]
+ then
+ prompt_user "LUKS_HEADERDEV" "${LUKS_NAME} header device"
+ HEADERDEV_ERROR=0
elif [ ${KEY_ERROR} -eq 1 ]
then
prompt_user "LUKS_KEY" "${LUKS_NAME} key"
@@ -1877,18 +1904,93 @@ openLUKS() {
continue
fi
- if ! run cryptsetup isLuks ${LUKS_DEVICE}
+ # Handle headers
+ if [ -n "${LUKS_HEADER}" ]
+ then
+ local REAL_LUKS_HEADERDEV="${LUKS_HEADERDEV}"
+ if [ ! -e "${mntheader}${LUKS_HEADER}" ]
+ then
+ REAL_LUKS_HEADERDEV=$(find_real_device "${LUKS_HEADERDEV}")
+ if [ -b "${REAL_LUKS_HEADERDEV}" ]
+ then
+ good_msg "Using header device ${REAL_LUKS_HEADERDEV}." ${CRYPT_SILENT}
+ else
+ good_msg "Please insert removable device ${LUKS_HEADERDEV} for ${LUKS_NAME}" ${CRYPT_SILENT}
+ # abort after 10 secs
+ local count=10
+ while [ ${count} -gt 0 ]
+ do
+ count=$((count-1))
+ sleep 1
+ REAL_LUKS_HEADERDEV=$(find_real_device "${LUKS_HEADERDEV}")
+ if [ -b "${REAL_LUKS_HEADERDEV}" ]
+ then
+ good_msg "Removable device ${REAL_LUKS_HEADERDEV} detected." ${CRYPT_SILENT}
+ break
+ fi
+ done
+ if [ ! -b "${REAL_LUKS_HEADERDEV}" ]
+ then
+ eval CRYPT_${TYPE}_HEADER=${LUKS_HEADER}
+ bootstrapHeader ${TYPE}
+ eval LUKS_HEADERDEV='"${CRYPT_'${TYPE}'_HEADERDEV}"'
+ REAL_LUKS_HEADERDEV=$(find_real_device "${LUKS_HEADERDEV}")
+ if [ ! -b "${REAL_LUKS_HEADERDEV}" ]
+ then
+ HEADERDEV_ERROR=1
+ bad_msg "Removable device ${LUKS_HEADERDEV} not found." ${CRYPT_SILENT}
+ continue
+ fi
+ # continue otherwise will mount headerdev which is mounted by bootstrap
+ continue
+ fi
+ fi
+
+ # At this point a device was recognized, now let's see if the header is there
+ [ ! -d "${mntheader}" ] && mkdir -p "${mntheader}" >/dev/null 2>&1
+
+ # determine fs -- 'auto' will not trigger module loading!
+ LUKS_HEADERDEV_FSTYPE=$(determine_fs "${REAL_LUKS_HEADERDEV}" "${LUKS_HEADERDEV_FSTYPE}")
+
+ if ! run mount -n -t ${LUKS_HEADERDEV_FSTYPE} -o ro ${REAL_LUKS_HEADERDEV} ${mntheader} >/dev/null 2>&1
+ then
+ HEADERDEV_ERROR=1
+ bad_msg "Mounting of device ${REAL_LUKS_HEADERDEV} failed." ${CRYPT_SILENT}
+ continue
+ fi
+
+ good_msg "Removable device ${REAL_LUKS_HEADERDEV} mounted." ${CRYPT_SILENT}
+ sleep 2
+
+ # headerfile exists?
+ if [ ! -e "${mntheader}${LUKS_HEADER}" ]
+ then
+ run umount -n "${mntheader}" >/dev/null 2>&1
+ HEADER_ERROR=1
+ HEADERDEV_ERROR=1
+ bad_msg "Header {LUKS_HEADER} on device ${REAL_LUKS_HEADERDEV} not found." ${CRYPT_SILENT}
+ continue
+ fi
+ fi
+
+ if ! run cryptsetup isLuks ${LUKS_DEVICE} --header ${mntheader}${LUKS_HEADER}
+ then
+ bad_msg "The LUKS device ${LUKS_DEVICE} does not contain a LUKS header" ${CRYPT_SILENT}
+ DEV_ERROR=1
+ continue
+ fi
+
+ # At this point a candidate header exists (either mounted before or not)
+ good_msg "${LUKS_HEADER} on device ${REAL_LUKS_HEADERDEV} found" ${CRYPT_SILENT}
+
+ cryptsetup_options="${cryptsetup_options} --header ${mntheader}${LUKS_HEADER}"
+ elif ! run cryptsetup isLuks ${LUKS_DEVICE}
then
bad_msg "The LUKS device ${LUKS_DEVICE} does not contain a LUKS header" ${CRYPT_SILENT}
DEV_ERROR=1
continue
fi
- if [ -n "${cryptsetup_options}" ]
- then
- good_msg "Using the following cryptsetup options for ${LUKS_NAME}: ${cryptsetup_options}" ${CRYPT_SILENT}
- fi
-
# Handle keys
if [ -n "${LUKS_KEY}" ]
then
@@ -1946,6 +2048,7 @@ openLUKS() {
good_msg "Removable device ${REAL_LUKS_KEYDEV} mounted." ${CRYPT_SILENT}
sleep 2
+
# keyfile exists?
if [ ! -e "${mntkey}${LUKS_KEY}" ]
then
@@ -1956,6 +2059,7 @@ openLUKS() {
continue
fi
fi
+
# At this point a candidate key exists (either mounted before or not)
good_msg "${LUKS_KEY} on device ${REAL_LUKS_KEYDEV} found" ${CRYPT_SILENT}
@@ -1975,7 +2079,13 @@ openLUKS() {
cryptsetup_options="${cryptsetup_options} -d ${mntkey}${LUKS_KEY}"
fi
fi
- # At this point, keyfile or not, we're ready!
+
+ if [ -n "${cryptsetup_options}" ]
+ then
+ good_msg "Using the following cryptsetup options for ${LUKS_NAME}: ${cryptsetup_options}" ${CRYPT_SILENT}
+ fi
+
+ # At this point, {header,key}file or not, we're ready!
crypt_filter "${gpg_cmd}cryptsetup ${cryptsetup_options} luksOpen ${LUKS_DEVICE} ${LUKS_NAME}"
crypt_filter_ret=$?
@@ -1992,6 +2102,8 @@ openLUKS() {
then
bad_msg "Failed to open LUKS device ${LUKS_DEVICE}" ${CRYPT_SILENT}
DEV_ERROR=1
+ HEADER_ERROR=1
+ HEADERDEV_ERROR=1
KEY_ERROR=1
KEYDEV_ERROR=1
fi
@@ -2000,11 +2112,17 @@ openLUKS() {
udevsettle
+ if run mountpoint "${mntheader}" >/dev/null 2>&1
+ then
+ run umount "${mntheader}" >/dev/null 2>&1
+ fi
+
if run mountpoint "${mntkey}" >/dev/null 2>&1
then
run umount "${mntkey}" >/dev/null 2>&1
fi
+ [ -d "${mntheader}" ] && run rmdir -p "${mntheader}" >/dev/null 2>&1
[ -d "${mntkey}" ] && run rmdir -p "${mntkey}" >/dev/null 2>&1
}
@@ -2341,8 +2459,14 @@ start_LUKS() {
# if key is set but neither ssh enabled or key device is given, find
# the key device
- [ -n "${CRYPT_ROOT_KEY}" ] && [ -z "${CRYPT_ROOT_KEYDEV}" ] \
- && sleep 6 && bootstrapKey "ROOT"
+ if [ -n "${CRYPT_ROOT_KEY}" ]
+ then
+ ( [ -z "${CRYPT_ROOT_KEYDEV}" ] || [ -z "${CRYPT_ROOT_HEADERDEV}" ] ) \
+ && sleep 6
+
+ [ -z "${CRYPT_ROOT_KEYDEV}" ] && bootstrapKey "ROOT"
+ [ -z "${CRYPT_ROOT_HEADERDEV}" ] && bootstrapHeader "ROOT"
+ fi
if [ -n "${CRYPT_ROOT}" ]
then
@@ -2356,9 +2480,15 @@ start_LUKS() {
fi
fi
- # same for swap, but no need to sleep if root was unencrypted
- [ -n "${CRYPT_SWAP_KEY}" ] && [ -z "${CRYPT_SWAP_KEYDEV}" ] \
- && { [ -z "${CRYPT_ROOT}" ] && sleep 6; bootstrapKey "SWAP"; }
+ if [ -n "${CRYPT_SWAP_KEY}" ]
+ then
+ # same for swap, but no need to sleep if root was unencrypted
+ ( [ -z "${CRYPT_ROOT_KEYDEV}" ] || [ -z "${CRYPT_ROOT_HEADERDEV}" ] ) \
+ && [ -z "${CRYPT_ROOT}" ] && sleep 6
+
+ [ -z "${CRYPT_SWAP_KEYDEV}" ] && bootstrapKey "SWAP"
+ [ -z "${CRYPT_SWAP_HEADERDEV}" ] && bootstrapHeader "SWAP"
+ fi
if [ -n "${CRYPT_SWAP}" ]
then
diff --git a/defaults/linuxrc b/defaults/linuxrc
index 6ede7401..ff08ba28 100644
--- a/defaults/linuxrc
+++ b/defaults/linuxrc
@@ -228,6 +228,15 @@ do
crypt_swap_options=*)
CRYPT_SWAP_OPTIONS=$(echo ${CRYPT_SWAP_OPTIONS} ${x#*=} | sed -e 's/,/ /g')
;;
+ root_header=*)
+ CRYPT_ROOT_HEADER=${x#*=}
+ ;;
+ root_headerdev=*)
+ CRYPT_ROOT_HEADERDEV=${x#*=}
+ ;;
+ root_headerdev_fstype=*)
+ CRYPT_ROOT_HEADERDEV_FSTYPE=${x#*=}
+ ;;
root_key=*)
CRYPT_ROOT_KEY=${x#*=}
;;
@@ -245,6 +254,15 @@ do
fi
unset tmp_enabled
;;
+ swap_header=*)
+ CRYPT_SWAP_HEADER=${x#*=}
+ ;;
+ swap_headerdev=*)
+ CRYPT_SWAP_HEADERDEV=${x#*=}
+ ;;
+ swap_headerdev_fstype=*)
+ CRYPT_SWAP_HEADERDEV_FSTYPE=${x#*=}
+ ;;
swap_key=*)
CRYPT_SWAP_KEY=${x#*=}
;;
diff --git a/doc/genkernel.8.txt b/doc/genkernel.8.txt
index 262027b9..33f77331 100644
--- a/doc/genkernel.8.txt
+++ b/doc/genkernel.8.txt
@@ -688,6 +688,19 @@ recognized by the kernel itself.
cryptsetup when opening swap volume. Can be specified multiple
times or separate multiple options with a comma.
+*root_header*=<...>::
+ In case your encrypted root uses a LUKS detached header, you can
+ use a device like a usb pen to store the header file. This value
+ should be the key path relative to the mount point.
+
+*root_headerdev*=<...>::
+ If necessary provide the name of the device that carries the
+ root_header. If unset while using root_header, it will automatically
+ look for the device in every boot.
+
+*root_headerdev_fstype*=<...>::
+ Used filesystem for *root_headerdev*. See *rootfstype* for more details.
+
*root_key*=<...>::
In case your root is encrypted with a key, you can use a device
like a usb pen to store the key. This value should be the key
@@ -706,6 +719,15 @@ recognized by the kernel itself.
with SSD setups. Have a look at 'https://en.wikipedia.org/wiki/TRIM'
for more information.
+*swap_header*=<...>::
+ Same as root_header for swap.
+
+*swap_headerdev*=<...>::
+ Same as root_headerdev for swap.
+
+*swap_headerdev_fstype*=<...>::
+ Used filesystem for *swap_headerdev*. See *rootfstype* for more details.
+
*swap_key*=<...>::
Same as root_key for swap.