public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
From: "Robin H. Johnson" <robbat2@gentoo.org>
To: gentoo-commits@lists.gentoo.org
Subject: [gentoo-commits] proj/genkernel:master commit in: defaults/, doc/
Date: Mon, 16 May 2022 05:34:18 +0000 (UTC)	[thread overview]
Message-ID: <1628356810.73a05632d61171685ac4960c6b684cefa6d82afd.robbat2@gentoo> (raw)

commit:     73a05632d61171685ac4960c6b684cefa6d82afd
Author:     Dmitry Baranov <reagentoo <AT> gmail <DOT> com>
AuthorDate: Wed Oct 14 19:03:01 2020 +0000
Commit:     Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Sat Aug  7 17:20:10 2021 +0000
URL:        https://gitweb.gentoo.org/proj/genkernel.git/commit/?id=73a05632

Add support for LUKS detached header

Signed-off-by: Dmitry Baranov <reagentoo <AT> gmail.com>

 defaults/initrd.scripts | 162 +++++++++++++++++++++++++++++++++++++++++++-----
 defaults/linuxrc        |  18 ++++++
 doc/genkernel.8.txt     |  22 +++++++
 3 files changed, 186 insertions(+), 16 deletions(-)

diff --git a/defaults/initrd.scripts b/defaults/initrd.scripts
index 33a48b3..5a83d93 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 6ede740..ff08ba2 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 262027b..33f7733 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.
 


             reply	other threads:[~2022-05-16  5:34 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-05-16  5:34 Robin H. Johnson [this message]
  -- strict thread matches above, loose matches on Subject: below --
2021-03-14 20:05 [gentoo-commits] proj/genkernel:master commit in: defaults/, doc/ Thomas Deutschmann
2021-02-07 18:23 Thomas Deutschmann
2020-09-02 13:52 Thomas Deutschmann
2020-08-28 20:18 Thomas Deutschmann
2020-08-26 22:54 Thomas Deutschmann
2020-07-16 18:36 Thomas Deutschmann
2019-11-24 20:00 Thomas Deutschmann
2019-08-07 15:46 Thomas Deutschmann
2019-08-07 15:46 Thomas Deutschmann
2017-01-04  0:11 Robin H. Johnson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1628356810.73a05632d61171685ac4960c6b684cefa6d82afd.robbat2@gentoo \
    --to=robbat2@gentoo.org \
    --cc=gentoo-commits@lists.gentoo.org \
    --cc=gentoo-dev@lists.gentoo.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox