summaryrefslogtreecommitdiff
path: root/eclass
diff options
context:
space:
mode:
Diffstat (limited to 'eclass')
-rw-r--r--eclass/Manifest.gzbin38148 -> 38317 bytes
-rw-r--r--eclass/dist-kernel-utils.eclass18
-rw-r--r--eclass/kernel-build.eclass18
-rw-r--r--eclass/rust-toolchain.eclass85
-rw-r--r--eclass/secureboot.eclass173
5 files changed, 262 insertions, 32 deletions
diff --git a/eclass/Manifest.gz b/eclass/Manifest.gz
index 8f8124e3f17c..b4eb60667392 100644
--- a/eclass/Manifest.gz
+++ b/eclass/Manifest.gz
Binary files differ
diff --git a/eclass/dist-kernel-utils.eclass b/eclass/dist-kernel-utils.eclass
index 1ef3104245c6..cb0021f8b3a7 100644
--- a/eclass/dist-kernel-utils.eclass
+++ b/eclass/dist-kernel-utils.eclass
@@ -12,6 +12,13 @@
# This eclass provides various utility functions related to Distribution
# Kernels.
+# @ECLASS_VARIABLE: KERNEL_IUSE_SECUREBOOT
+# @PRE_INHERIT
+# @DEFAULT_UNSET
+# @DESCRIPTION:
+# If set to a non-null value, inherits secureboot.eclass
+# and allows signing of generated kernel images.
+
if [[ ! ${_DIST_KERNEL_UTILS} ]]; then
case ${EAPI} in
@@ -19,6 +26,10 @@ case ${EAPI} in
*) die "${ECLASS}: EAPI ${EAPI:-0} not supported" ;;
esac
+if [[ ${KERNEL_IUSE_SECUREBOOT} ]]; then
+ inherit secureboot
+fi
+
# @FUNCTION: dist-kernel_build_initramfs
# @USAGE: <output> <version>
# @DESCRIPTION:
@@ -104,7 +115,7 @@ dist-kernel_install_kernel() {
if [[ ${magic} == MZ ]]; then
einfo "Combined UEFI kernel+initramfs executable found"
# install the combined executable in place of kernel
- image=${initrd}.efi
+ image=${initrd%/*}/uki.efi
mv "${initrd}" "${image}" || die
# We moved the generated initrd, prevent dracut from running again
# https://github.com/dracutdevs/dracut/pull/2405
@@ -122,6 +133,11 @@ dist-kernel_install_kernel() {
export KERNEL_INSTALL_PLUGINS="${KERNEL_INSTALL_PLUGINS} ${plugins[@]}"
fi
+ if [[ ${KERNEL_IUSE_SECUREBOOT} ]]; then
+ # Kernel-install requires uki's are named uki.efi, sign in-place
+ secureboot_sign_efi_file "${image}" "${image}"
+ fi
+
ebegin "Installing the kernel via installkernel"
# note: .config is taken relatively to System.map;
# initrd relatively to bzImage
diff --git a/eclass/kernel-build.eclass b/eclass/kernel-build.eclass
index 0c8eaf3c1cd5..ff615a02d0eb 100644
--- a/eclass/kernel-build.eclass
+++ b/eclass/kernel-build.eclass
@@ -29,6 +29,11 @@ if [[ ! ${_KERNEL_BUILD_ECLASS} ]]; then
_KERNEL_BUILD_ECLASS=1
PYTHON_COMPAT=( python3_{10..12} )
+if [[ ${KERNEL_IUSE_MODULES_SIGN} ]]; then
+ # If we have enabled module signing IUSE
+ # then we can also enable secureboot IUSE
+ KERNEL_IUSE_SECUREBOOT=1
+fi
inherit multiprocessing python-any-r1 savedconfig toolchain-funcs kernel-install
@@ -86,8 +91,19 @@ IUSE="+strip"
if [[ ${KERNEL_IUSE_MODULES_SIGN} ]]; then
IUSE+=" modules-sign"
+ REQUIRED_USE="secureboot? ( modules-sign )"
fi
+# @FUNCTION: kernel-build_pkg_setup
+# @DESCRIPTION:
+# Call python-any-r1 and secureboot pkg_setup
+kernel-build_pkg_setup() {
+ python-any-r1_pkg_setup
+ if [[ ${KERNEL_IUSE_MODULES_SIGN} ]]; then
+ secureboot_pkg_setup
+ fi
+}
+
# @FUNCTION: kernel-build_src_configure
# @DESCRIPTION:
# Prepare the toolchain for building the kernel, get the default .config
@@ -395,4 +411,4 @@ kernel-build_merge_configs() {
fi
-EXPORT_FUNCTIONS src_configure src_compile src_test src_install pkg_postinst
+EXPORT_FUNCTIONS pkg_setup src_configure src_compile src_test src_install pkg_postinst
diff --git a/eclass/rust-toolchain.eclass b/eclass/rust-toolchain.eclass
index df48d3fae264..f4451f743596 100644
--- a/eclass/rust-toolchain.eclass
+++ b/eclass/rust-toolchain.eclass
@@ -36,21 +36,23 @@ rust_abi() {
case ${CTARGET%%*-} in
aarch64*gnu) echo aarch64-unknown-linux-gnu;;
aarch64*musl) echo aarch64-unknown-linux-musl;;
- mips64*) echo mips64-unknown-linux-gnuabi64;;
+ armv6j*h*) echo arm-unknown-linux-gnueabihf;;
+ armv6j*s*) echo arm-unknown-linux-gnueabi;;
+ armv7a*h*) echo armv7-unknown-linux-gnueabihf;;
+ i?86*) echo i686-unknown-linux-gnu;;
+ loongarch64*) echo loongarch64-unknown-linux-gnu;;
+ mips64el*) echo mips64el-unknown-linux-gnuabi64;;
+ mips64*) echo mips64-unknown-linux-gnuabi64;;
+ mipsel*) echo mipsel-unknown-linux-gnu;;
+ mips*) echo mips-unknown-linux-gnu;;
powerpc64le*) echo powerpc64le-unknown-linux-gnu;;
powerpc64*) echo powerpc64-unknown-linux-gnu;;
- x86_64*gnu) echo x86_64-unknown-linux-gnu;;
+ powerpc*) echo powerpc-unknown-linux-gnu;;
+ riscv64*) echo riscv64gc-unknown-linux-gnu;;
+ s390x*) echo s390x-unknown-linux-gnu;;
+ x86_64*gnu) echo x86_64-unknown-linux-gnu;;
x86_64*musl) echo x86_64-unknown-linux-musl;;
- armv6j*s*) echo arm-unknown-linux-gnueabi;;
- armv6j*h*) echo arm-unknown-linux-gnueabihf;;
- armv7a*h*) echo armv7-unknown-linux-gnueabihf;;
- i?86*) echo i686-unknown-linux-gnu;;
- mipsel*) echo mipsel-unknown-linux-gnu;;
- mips*) echo mips-unknown-linux-gnu;;
- powerpc*) echo powerpc-unknown-linux-gnu;;
- s390x*) echo s390x-unknown-linux-gnu;;
- riscv64*) echo riscv64gc-unknown-linux-gnu;;
- *) echo ${CTARGET};;
+ *) echo ${CTARGET};;
esac
}
@@ -105,22 +107,45 @@ rust_arch_uri() {
#
rust_all_arch_uris()
{
- local uris=""
- uris+="abi_x86_64? ( elibc_glibc? ( $(rust_arch_uri x86_64-unknown-linux-gnu "$@") )
- elibc_musl? ( $(rust_arch_uri x86_64-unknown-linux-musl "$@") ) ) "
- uris+="arm? ( $(rust_arch_uri arm-unknown-linux-gnueabi "$@")
- $(rust_arch_uri arm-unknown-linux-gnueabihf "$@")
- $(rust_arch_uri armv7-unknown-linux-gnueabihf "$@") ) "
- uris+="arm64? ( elibc_glibc? ( $(rust_arch_uri aarch64-unknown-linux-gnu "$@") )
- elibc_musl? ( $(rust_arch_uri aarch64-unknown-linux-musl "$@") ) ) "
- uris+="mips? ( $(rust_arch_uri mips-unknown-linux-gnu "$@")
- $(rust_arch_uri mipsel-unknown-linux-gnu "$@")
- $(rust_arch_uri mips64-unknown-linux-gnuabi64 "$@") ) "
- uris+="ppc? ( $(rust_arch_uri powerpc-unknown-linux-gnu "$@") ) "
- uris+="ppc64? ( $(rust_arch_uri powerpc64-unknown-linux-gnu "$@")
- $(rust_arch_uri powerpc64le-unknown-linux-gnu "$@") ) "
- uris+="s390? ( $(rust_arch_uri s390x-unknown-linux-gnu "$@") ) "
- uris+="abi_x86_32? ( $(rust_arch_uri i686-unknown-linux-gnu "$@") ) "
- uris+="riscv? ( $(rust_arch_uri riscv64gc-unknown-linux-gnu "$@") ) "
- echo "${uris}"
+ echo "
+ abi_x86_32? ( $(rust_arch_uri i686-unknown-linux-gnu "$@") )
+ abi_x86_64? (
+ elibc_glibc? ( $(rust_arch_uri x86_64-unknown-linux-gnu "$@") )
+ elibc_musl? ( $(rust_arch_uri x86_64-unknown-linux-musl "$@") )
+ )
+ arm? (
+ $(rust_arch_uri arm-unknown-linux-gnueabi "$@")
+ $(rust_arch_uri arm-unknown-linux-gnueabihf "$@")
+ $(rust_arch_uri armv7-unknown-linux-gnueabihf "$@")
+ )
+ arm64? (
+ elibc_glibc? ( $(rust_arch_uri aarch64-unknown-linux-gnu "$@") )
+ elibc_musl? ( $(rust_arch_uri aarch64-unknown-linux-musl "$@") )
+ )
+ mips? (
+ abi_mips_o32? (
+ big-endian? ( $(rust_arch_uri mips-unknown-linux-gnu "$@") )
+ !big-endian? ( $(rust_arch_uri mipsel-unknown-linux-gnu "$@") )
+ )
+ abi_mips_n64? (
+ big-endian? ( $(rust_arch_uri mips64-unknown-linux-gnuabi64 "$@") )
+ !big-endian? ( $(rust_arch_uri mips64el-unknown-linux-gnuabi64 "$@") )
+ )
+ )
+ ppc? ( $(rust_arch_uri powerpc-unknown-linux-gnu "$@") )
+ ppc64? (
+ big-endian? ( $(rust_arch_uri powerpc64-unknown-linux-gnu "$@") )
+ !big-endian? ( $(rust_arch_uri powerpc64le-unknown-linux-gnu "$@") )
+ )
+ riscv? ( $(rust_arch_uri riscv64gc-unknown-linux-gnu "$@") )
+ s390? ( $(rust_arch_uri s390x-unknown-linux-gnu "$@") )
+ "
+
+ # Upstream did not gain support for loong until v1.71.0.
+ # NOTE: Merge this into the block above after every <1.71.0 version is
+ # gone from tree.
+ local arg_version="${1##*-}"
+ if ver_test "${arg_version:-$PV}" -ge 1.71.0; then
+ echo "loong? ( $(rust_arch_uri loongarch64-unknown-linux-gnu "$@") )"
+ fi
}
diff --git a/eclass/secureboot.eclass b/eclass/secureboot.eclass
new file mode 100644
index 000000000000..477722a83bb3
--- /dev/null
+++ b/eclass/secureboot.eclass
@@ -0,0 +1,173 @@
+# Copyright 1999-2023 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+# @ECLASS: secureboot.eclass
+# @MAINTAINER:
+# Andrew Ammerlaan <andrewammerlaan@gentoo.org>
+# @AUTHOR:
+# Author: Andrew Ammerlaan <andrewammerlaan@gentoo.org>
+# @SUPPORTED_EAPIS: 7 8
+# @BLURB: A small eclass to sign efi files for Secure Boot
+# @DESCRIPTION:
+# Eclass for packages that install .efi files. A use flag and two user
+# variables allow signing these .efi files for use on systems with Secure Boot
+# enabled.
+#
+# Signing the files during emerge ensures that any tooling that actually
+# installs the bootloaders and kernels to ESP always uses a signed version.
+# This prevents Secure Boot from accidentally breaking when upgrading the
+# kernel or the bootloader.
+#
+# Example use
+# @CODE
+# src_install() {
+# default
+# secureboot_sign_efi_file in.efi out.efi.signed
+# }
+# @CODE
+#
+# Or
+# @CODE
+# src_install() {
+# default
+# secureboot_auto_sign
+# }
+# @CODE
+#
+# Some tools will automatically detect and use EFI executables with the .signed
+# suffix. For tools that do not do this the --in-place argument for
+# secureboot_auto_sign can be used to ensure that the signed version is used.
+
+case ${EAPI} in
+ 7|8) ;;
+ *) die "${ECLASS}: EAPI ${EAPI:-0} not supported" ;;
+esac
+
+IUSE="secureboot"
+BDEPEND="secureboot? ( app-crypt/sbsigntools )"
+
+# @ECLASS_VARIABLE: SECUREBOOT_SIGN_KEY
+# @USER_VARIABLE
+# @DEFAULT_UNSET
+# @DESCRIPTION:
+# Used with USE=secureboot. Should be set to the path of the private
+# key in PEM format to use, or a PKCS#11 URI.
+#
+# @ECLASS_VARIABLE: SECUREBOOT_SIGN_CERT
+# @USER_VARIABLE
+# @DEFAULT_UNSET
+# @DESCRIPTION:
+# Used with USE=secureboot. Should be set to the path of the public
+# key certificate in PEM format to use.
+
+if [[ -z ${_SECUREBOOT_ECLASS} ]]; then
+_SECUREBOOT_ECLASS=1
+
+# @FUNCTION: _secureboot_die_if_unset
+# @INTERNAL
+# @DESCRIPTION:
+# If USE=secureboot is enabled die if the required user variables are unset
+# and die if the keys can't be found.
+_secureboot_die_if_unset() {
+ debug-print-function ${FUNCNAME[0]} "${@}"
+ use secureboot || return
+
+ if [[ -z ${SECUREBOOT_SIGN_KEY} || -z ${SECUREBOOT_SIGN_CERT} ]]; then
+ die "USE=secureboot enabled but SECUREBOOT_SIGN_KEY and/or SECUREBOOT_SIGN_CERT not set."
+ fi
+ if [[ ! ${SECUREBOOT_SIGN_KEY} == pkcs11:* && ! -f ${SECUREBOOT_SIGN_KEY} ]]; then
+ die "SECUREBOOT_SIGN_KEY=${SECUREBOOT_SIGN_KEY} not found"
+ fi
+ if [[ ! -f ${SECUREBOOT_SIGN_CERT} ]];then
+ die "SECUREBOOT_SIGN_CERT=${SECUREBOOT_SIGN_CERT} not found"
+ fi
+}
+
+# @FUNCTION: secureboot_pkg_setup
+# @DESCRIPTION:
+# Checks if required user variables are set before starting the build
+secureboot_pkg_setup() {
+ debug-print-function ${FUNCNAME[0]} "${@}"
+ use secureboot || return
+
+ # If we are merging a binary then the files in this binary
+ # are already signed, no need to check the variables.
+ if [[ ${MERGE_TYPE} != binary ]]; then
+ _secureboot_die_if_unset
+ fi
+}
+
+# @FUNCTION: secureboot_sign_efi_file
+# @USAGE: <input file> <output file>
+# @DESCRIPTION:
+# Sign a file using sbsign and the requested key/certificate.
+# If the file is already signed with our key then skip.
+secureboot_sign_efi_file() {
+ debug-print-function ${FUNCNAME[0]} "${@}"
+ use secureboot || return
+
+ local input_file=${1}
+ local output_file=${2}
+
+ _secureboot_die_if_unset
+
+ ebegin "Signing ${input_file}"
+ local return=1
+ if sbverify "${input_file}" --cert "${SECUREBOOT_SIGN_CERT}" &> /dev/null; then
+ ewarn "${input_file} already signed, skipping"
+ return=0
+ else
+ local args=(
+ "--key=${SECUREBOOT_SIGN_KEY}"
+ "--cert=${SECUREBOOT_SIGN_CERT}"
+ )
+ if [[ ${SECUREBOOT_SIGN_KEY} == pkcs11:* ]]; then
+ args+=( --engine=pkcs11 )
+ fi
+
+ sbsign "${args[@]}" "${input_file}" --output "${output_file}"
+ return=${?}
+ fi
+ eend ${return} || die "Signing ${input_file} failed"
+}
+
+# @FUNCTION: secureboot_auto_sign
+# @USAGE: [--in-place]
+# @DESCRIPTION:
+# Automatically discover and sign efi files in the image directory.
+#
+# By default signed files gain the .signed suffix. If the --in-place
+# argument is given the efi files are replaced with a signed version in place.
+secureboot_auto_sign() {
+ debug-print-function ${FUNCNAME[0]} "${@}"
+ use secureboot || return
+
+ [[ ${EBUILD_PHASE} == install ]] ||
+ die "${FUNCNAME[0]} can only be called in the src_install phase"
+
+ local -a efi_execs
+ mapfile -td '' efi_execs < <(
+ find "${ED}" -type f \
+ \( -iname '*.efi' -o -iname '*.efi32' -o -iname '*.efi64' \) \
+ -print0 || die
+ )
+ (( ${#efi_execs[@]} )) ||
+ die "${FUNCNAME[0]} was called but no efi executables were found"
+
+ local suffix
+ if [[ ${1} == --in-place ]]; then
+ suffix=""
+ elif [[ -n ${1} ]]; then
+ die "Invalid argument ${1}"
+ else
+ suffix=".signed"
+ fi
+
+ for efi_exec in "${efi_execs[@]}"; do
+ secureboot_sign_efi_file "${efi_exec}" "${efi_exec}${suffix}"
+ done
+}
+
+fi
+
+EXPORT_FUNCTIONS pkg_setup