aboutsummaryrefslogtreecommitdiffstats
path: root/meta-integrity/classes
diff options
context:
space:
mode:
Diffstat (limited to 'meta-integrity/classes')
-rw-r--r--meta-integrity/classes/ima-evm-rootfs.bbclass79
-rw-r--r--meta-integrity/classes/kernel-modsign.bbclass8
-rw-r--r--meta-integrity/classes/sanity-meta-integrity.bbclass10
3 files changed, 68 insertions, 29 deletions
diff --git a/meta-integrity/classes/ima-evm-rootfs.bbclass b/meta-integrity/classes/ima-evm-rootfs.bbclass
index d6ade3b..7b73373 100644
--- a/meta-integrity/classes/ima-evm-rootfs.bbclass
+++ b/meta-integrity/classes/ima-evm-rootfs.bbclass
@@ -17,7 +17,7 @@ IMA_EVM_X509 ?= "${IMA_EVM_KEY_DIR}/x509_ima.der"
# with a .x509 suffix. See linux-%.bbappend for details.
#
# ima-local-ca.x509 is what ima-gen-local-ca.sh creates.
-IMA_EVM_ROOT_CA ?= ""
+IMA_EVM_ROOT_CA ?= "${IMA_EVM_KEY_DIR}/ima-local-ca.pem"
# Sign all regular files by default.
IMA_EVM_ROOTFS_SIGNED ?= ". -type f"
@@ -28,6 +28,12 @@ IMA_EVM_ROOTFS_HASHED ?= ". -depth 0 -false"
# the iversion flags (needed by IMA when allowing writing).
IMA_EVM_ROOTFS_IVERSION ?= ""
+# Avoid re-generating fstab when ima is enabled.
+WIC_CREATE_EXTRA_ARGS:append = "${@bb.utils.contains('DISTRO_FEATURES', 'ima', ' --no-fstab-update', '', d)}"
+
+# Add necessary tools (e.g., keyctl) to image
+IMAGE_INSTALL:append = "${@bb.utils.contains('DISTRO_FEATURES', 'ima', ' ima-evm-utils', '', d)}"
+
ima_evm_sign_rootfs () {
cd ${IMAGE_ROOTFS}
@@ -37,15 +43,6 @@ ima_evm_sign_rootfs () {
# reasons (including a change of the signing keys) without also
# re-running do_rootfs.
- # Copy file(s) which must be on the device. Note that
- # evmctl uses x509_evm.der also for "ima_verify", which is probably
- # a bug (should default to x509_ima.der). Does not matter for us
- # because we use the same key for both.
- install -d ./${sysconfdir}/keys
- rm -f ./${sysconfdir}/keys/x509_evm.der
- install "${IMA_EVM_X509}" ./${sysconfdir}/keys/x509_evm.der
- ln -sf x509_evm.der ./${sysconfdir}/keys/x509_ima.der
-
# Fix /etc/fstab: it must include the "i_version" mount option for
# those file systems where writing files is allowed, otherwise
# these changes will not get detected at runtime.
@@ -65,28 +62,58 @@ ima_evm_sign_rootfs () {
perl -pi -e 's;(\S+)(\s+)(${@"|".join((d.getVar("IMA_EVM_ROOTFS_IVERSION", True) or "no-such-mount-point").split())})(\s+)(\S+)(\s+)(\S+);\1\2\3\4\5\6\7,iversion;; s/(,iversion)+/,iversion/;' etc/fstab
fi
- # Sign file with private IMA key. EVM not supported at the moment.
- bbnote "IMA/EVM: signing files 'find ${IMA_EVM_ROOTFS_SIGNED}' with private key '${IMA_EVM_PRIVKEY}'"
- find ${IMA_EVM_ROOTFS_SIGNED} | xargs -d "\n" --no-run-if-empty --verbose evmctl ima_sign --key ${IMA_EVM_PRIVKEY}
- bbnote "IMA/EVM: hashing files 'find ${IMA_EVM_ROOTFS_HASHED}'"
- find ${IMA_EVM_ROOTFS_HASHED} | xargs -d "\n" --no-run-if-empty --verbose evmctl ima_hash
+ # Detect 32bit target to pass --m32 to evmctl by looking at libc
+ tmp="$(file "${IMAGE_ROOTFS}/lib/libc.so.6" | grep -o 'ELF .*-bit')"
+ if [ "${tmp}" = "ELF 32-bit" ]; then
+ evmctl_param="--m32"
+ elif [ "${tmp}" = "ELF 64-bit" ]; then
+ evmctl_param=""
+ else
+ bberror "Unknown target architecture bitness: '${tmp}'" >&2
+ exit 1
+ fi
+
+ bbnote "IMA/EVM: Signing root filesystem at ${IMAGE_ROOTFS} with key ${IMA_EVM_PRIVKEY}"
+ evmctl sign --imasig ${evmctl_param} --portable -a sha256 --key ${IMA_EVM_PRIVKEY} -r "${IMAGE_ROOTFS}"
+
+ # check signing key and signature verification key
+ evmctl ima_verify ${evmctl_param} --key "${IMA_EVM_X509}" "${IMAGE_ROOTFS}/lib/libc.so.6" || exit 1
+ evmctl verify ${evmctl_param} --key "${IMA_EVM_X509}" "${IMAGE_ROOTFS}/lib/libc.so.6" || exit 1
# Optionally install custom policy for loading by systemd.
- if [ "${IMA_EVM_POLICY_SYSTEMD}" ]; then
+ if [ "${IMA_EVM_POLICY}" ]; then
install -d ./${sysconfdir}/ima
rm -f ./${sysconfdir}/ima/ima-policy
- install "${IMA_EVM_POLICY_SYSTEMD}" ./${sysconfdir}/ima/ima-policy
+ install "${IMA_EVM_POLICY}" ./${sysconfdir}/ima/ima-policy
+
+ bbnote "IMA/EVM: Signing IMA policy with key ${IMA_EVM_PRIVKEY}"
+ evmctl sign --imasig ${evmctl_param} --portable -a sha256 --key "${IMA_EVM_PRIVKEY}" "${IMAGE_ROOTFS}/etc/ima/ima-policy"
+ fi
+
+ # Optionally write the file names and ima and evm signatures into files
+ if [ "${IMA_FILE_SIGNATURES_FILE}" ]; then
+ getfattr -R -m security.ima --e hex --dump ./ 2>/dev/null | \
+ sed -n -e 's|# file: |/|p' -e 's|security.ima=|ima:|p' | \
+ sed '$!N;s/\n/ /' > ./${IMA_FILE_SIGNATURES_FILE}
+ fi
+ if [ "${EVM_FILE_SIGNATURES_FILE}" ]; then
+ getfattr -R -m security.evm --e hex --dump ./ 2>/dev/null | \
+ sed -n -e 's|# file: |/|p' -e 's|security.evm=|evm:|p' | \
+ sed '$!N;s/\n/ /' > ./${EVM_FILE_SIGNATURES_FILE}
fi
}
# Signing must run as late as possible in the do_rootfs task.
-# IMAGE_PREPROCESS_COMMAND runs after ROOTFS_POSTPROCESS_COMMAND, so
-# append (not prepend!) to IMAGE_PREPROCESS_COMMAND, and do it with
-# _append instead of += because _append gets evaluated later. In
-# particular, we must run after prelink_image in
-# IMAGE_PREPROCESS_COMMAND, because prelinking changes executables.
-
-IMAGE_PREPROCESS_COMMAND_append = " ima_evm_sign_rootfs ; "
+# To guarantee that, we append it to IMAGE_PREPROCESS_COMMAND in
+# RecipePreFinalise event handler, this ensures it's the last
+# function in IMAGE_PREPROCESS_COMMAND.
+python ima_evm_sign_handler () {
+ if not e.data or 'ima' not in e.data.getVar('DISTRO_FEATURES').split():
+ return
-# evmctl must have been installed first.
-do_rootfs[depends] += "ima-evm-utils-native:do_populate_sysroot"
+ e.data.appendVar('IMAGE_PREPROCESS_COMMAND', ' ima_evm_sign_rootfs; ')
+ e.data.appendVar('IMAGE_INSTALL', ' ima-evm-keys')
+ e.data.appendVarFlag('do_rootfs', 'depends', ' ima-evm-utils-native:do_populate_sysroot')
+}
+addhandler ima_evm_sign_handler
+ima_evm_sign_handler[eventmask] = "bb.event.RecipePreFinalise"
diff --git a/meta-integrity/classes/kernel-modsign.bbclass b/meta-integrity/classes/kernel-modsign.bbclass
index 09025ba..d3aa7fb 100644
--- a/meta-integrity/classes/kernel-modsign.bbclass
+++ b/meta-integrity/classes/kernel-modsign.bbclass
@@ -2,7 +2,7 @@
# set explicitly in a local.conf before activating kernel-modsign.
# To use the insecure (because public) example keys, use
# MODSIGN_KEY_DIR = "${INTEGRITY_BASE}/data/debug-keys"
-MODSIGN_KEY_DIR ?= "MODSIGN_KEY_DIR_NOT_SET"
+MODSIGN_KEY_DIR ??= "MODSIGN_KEY_DIR_NOT_SET"
# Private key for modules signing. The default is okay when
# using the example key directory.
@@ -13,9 +13,11 @@ MODSIGN_PRIVKEY ?= "${MODSIGN_KEY_DIR}/privkey_modsign.pem"
MODSIGN_X509 ?= "${MODSIGN_KEY_DIR}/x509_modsign.crt"
# If this class is enabled, disable stripping signatures from modules
+# as well disable the debug symbols split
INHIBIT_PACKAGE_STRIP = "1"
+INHIBIT_PACKAGE_DEBUG_SPLIT = "1"
-kernel_do_configure_prepend() {
+kernel_do_configure:prepend() {
if [ -f "${MODSIGN_PRIVKEY}" -a -f "${MODSIGN_X509}" ]; then
cat "${MODSIGN_PRIVKEY}" "${MODSIGN_X509}" \
> "${B}/modsign_key.pem"
@@ -24,6 +26,6 @@ kernel_do_configure_prepend() {
fi
}
-do_shared_workdir_append() {
+do_shared_workdir:append() {
cp modsign_key.pem $kerneldir/
}
diff --git a/meta-integrity/classes/sanity-meta-integrity.bbclass b/meta-integrity/classes/sanity-meta-integrity.bbclass
new file mode 100644
index 0000000..6ba7e3f
--- /dev/null
+++ b/meta-integrity/classes/sanity-meta-integrity.bbclass
@@ -0,0 +1,10 @@
+addhandler integrity_bbappend_distrocheck
+integrity_bbappend_distrocheck[eventmask] = "bb.event.SanityCheck"
+python integrity_bbappend_distrocheck() {
+ skip_check = e.data.getVar('SKIP_META_INTEGRITY_SANITY_CHECK') == "1"
+ if 'integrity' not in e.data.getVar('DISTRO_FEATURES').split() and not skip_check:
+ bb.warn("You have included the meta-integrity layer, but \
+'integrity' has not been enabled in your DISTRO_FEATURES. Some bbappend files \
+and preferred version setting may not take effect. See the meta-integrity README \
+for details on enabling integrity support.")
+}