blob: 98c4bc1f264a0532265b414ed9cef40bfb2cb9be [file] [log] [blame]
Brad Bishop15ae2502019-06-18 21:44:24 -04001# No default! Either this or IMA_EVM_PRIVKEY/IMA_EVM_X509 have to be
2# set explicitly in a local.conf before activating ima-evm-rootfs.
3# To use the insecure (because public) example keys, use
Brad Bishop26bdd442019-08-16 17:08:17 -04004# IMA_EVM_KEY_DIR = "${INTEGRITY_BASE}/data/debug-keys"
Brad Bishop15ae2502019-06-18 21:44:24 -04005IMA_EVM_KEY_DIR ?= "IMA_EVM_KEY_DIR_NOT_SET"
6
7# Private key for IMA signing. The default is okay when
8# using the example key directory.
9IMA_EVM_PRIVKEY ?= "${IMA_EVM_KEY_DIR}/privkey_ima.pem"
10
11# Public part of certificates (used for both IMA and EVM).
12# The default is okay when using the example key directory.
13IMA_EVM_X509 ?= "${IMA_EVM_KEY_DIR}/x509_ima.der"
14
15# Root CA to be compiled into the kernel, none by default.
16# Must be the absolute path to a der-encoded x509 CA certificate
17# with a .x509 suffix. See linux-%.bbappend for details.
18#
19# ima-local-ca.x509 is what ima-gen-local-ca.sh creates.
Andrew Geisslerdc9d6142023-05-19 09:38:37 -050020IMA_EVM_ROOT_CA ?= "${IMA_EVM_KEY_DIR}/ima-local-ca.pem"
Brad Bishop15ae2502019-06-18 21:44:24 -040021
22# Sign all regular files by default.
23IMA_EVM_ROOTFS_SIGNED ?= ". -type f"
24# Hash nothing by default.
25IMA_EVM_ROOTFS_HASHED ?= ". -depth 0 -false"
26
27# Mount these file systems (identified via their mount point) with
28# the iversion flags (needed by IMA when allowing writing).
29IMA_EVM_ROOTFS_IVERSION ?= ""
30
Andrew Geissler8b139282021-03-05 15:22:30 -060031# Avoid re-generating fstab when ima is enabled.
Patrick Williams213cb262021-08-07 19:21:33 -050032WIC_CREATE_EXTRA_ARGS:append = "${@bb.utils.contains('DISTRO_FEATURES', 'ima', ' --no-fstab-update', '', d)}"
Andrew Geissler8b139282021-03-05 15:22:30 -060033
Andrew Geisslerdc9d6142023-05-19 09:38:37 -050034# Add necessary tools (e.g., keyctl) to image
35IMAGE_INSTALL:append = "${@bb.utils.contains('DISTRO_FEATURES', 'ima', ' ima-evm-utils', '', d)}"
36
Brad Bishop15ae2502019-06-18 21:44:24 -040037ima_evm_sign_rootfs () {
38 cd ${IMAGE_ROOTFS}
39
40 # Beware that all operations below must also work when
41 # ima_evm_sign_rootfs was already called earlier for the same
42 # rootfs. That's because do_image might again run for various
43 # reasons (including a change of the signing keys) without also
44 # re-running do_rootfs.
45
Brad Bishop15ae2502019-06-18 21:44:24 -040046 # Fix /etc/fstab: it must include the "i_version" mount option for
47 # those file systems where writing files is allowed, otherwise
48 # these changes will not get detected at runtime.
49 #
50 # Note that "i_version" is documented in "man mount" only for ext4,
51 # whereas "iversion" is said to be filesystem-independent. In practice,
52 # there is only one MS_I_VERSION flag in the syscall and ext2/ext3/ext4
53 # all support it.
54 #
55 # coreutils translates "iversion" into MS_I_VERSION. busybox rejects
56 # "iversion" and only understands "i_version". systemd only understands
57 # "iversion". We pick "iversion" here for systemd, whereas rootflags
58 # for initramfs must use "i_version" for busybox.
59 #
60 # Deduplicates iversion in case that this gets called more than once.
61 if [ -f etc/fstab ]; then
62 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
63 fi
64
Andrew Geisslerdc9d6142023-05-19 09:38:37 -050065 # Detect 32bit target to pass --m32 to evmctl by looking at libc
66 tmp="$(file "${IMAGE_ROOTFS}/lib/libc.so.6" | grep -o 'ELF .*-bit')"
67 if [ "${tmp}" = "ELF 32-bit" ]; then
68 evmctl_param="--m32"
69 elif [ "${tmp}" = "ELF 64-bit" ]; then
70 evmctl_param=""
71 else
72 bberror "Unknown target architecture bitness: '${tmp}'" >&2
73 exit 1
74 fi
75
76 bbnote "IMA/EVM: Signing root filesystem at ${IMAGE_ROOTFS} with key ${IMA_EVM_PRIVKEY}"
77 evmctl sign --imasig ${evmctl_param} --portable -a sha256 --key ${IMA_EVM_PRIVKEY} -r "${IMAGE_ROOTFS}"
78
79 # check signing key and signature verification key
80 evmctl ima_verify ${evmctl_param} --key "${IMA_EVM_X509}" "${IMAGE_ROOTFS}/lib/libc.so.6" || exit 1
81 evmctl verify ${evmctl_param} --key "${IMA_EVM_X509}" "${IMAGE_ROOTFS}/lib/libc.so.6" || exit 1
Brad Bishop15ae2502019-06-18 21:44:24 -040082
83 # Optionally install custom policy for loading by systemd.
Andrew Geisslerdc9d6142023-05-19 09:38:37 -050084 if [ "${IMA_EVM_POLICY}" ]; then
Brad Bishop15ae2502019-06-18 21:44:24 -040085 install -d ./${sysconfdir}/ima
86 rm -f ./${sysconfdir}/ima/ima-policy
Andrew Geisslerdc9d6142023-05-19 09:38:37 -050087 install "${IMA_EVM_POLICY}" ./${sysconfdir}/ima/ima-policy
88
89 bbnote "IMA/EVM: Signing IMA policy with key ${IMA_EVM_PRIVKEY}"
90 evmctl sign --imasig ${evmctl_param} --portable -a sha256 --key "${IMA_EVM_PRIVKEY}" "${IMAGE_ROOTFS}/etc/ima/ima-policy"
Brad Bishop15ae2502019-06-18 21:44:24 -040091 fi
92}
93
94# Signing must run as late as possible in the do_rootfs task.
Andrew Geissler8b139282021-03-05 15:22:30 -060095# To guarantee that, we append it to IMAGE_PREPROCESS_COMMAND in
96# RecipePreFinalise event handler, this ensures it's the last
97# function in IMAGE_PREPROCESS_COMMAND.
98python ima_evm_sign_handler () {
99 if not e.data or 'ima' not in e.data.getVar('DISTRO_FEATURES').split():
100 return
Brad Bishop15ae2502019-06-18 21:44:24 -0400101
Andrew Geissler8b139282021-03-05 15:22:30 -0600102 e.data.appendVar('IMAGE_PREPROCESS_COMMAND', ' ima_evm_sign_rootfs; ')
103 e.data.appendVar('IMAGE_INSTALL', ' ima-evm-keys')
104 e.data.appendVarFlag('do_rootfs', 'depends', ' ima-evm-utils-native:do_populate_sysroot')
105}
106addhandler ima_evm_sign_handler
107ima_evm_sign_handler[eventmask] = "bb.event.RecipePreFinalise"