Chapter 21. Enhancing security with the kernel integrity subsystem

download PDF

You can improve the protection of your system by using components of the kernel integrity subsystem. Learn more about the relevant components and their configuration.


You can use the features with cryptographic signatures only for Red Hat products because the kernel keyring system includes only the certificates for Red Hat signature keys. Using other hash features results in incomplete tamper-proofing.

21.1. The kernel integrity subsystem

The integrity subsystem is the part of the kernel that maintains overall integrity of system data. This subsystem helps to keep the state of a system the same from the time it was built. By using this subsystem, you can prevent undesired modification of specific system files.

The kernel integrity subsystem consists of two major components:

Integrity Measurement Architecture (IMA)
  • IMA measures file content whenever it is executed or opened by cryptographically hashing or signing with cryptographic keys. The keys are stored in the kernel keyring subsystem.
  • IMA places the measured values within the kernel’s memory space. This prevents users of the system from modifying the measured values.
  • IMA allows local and remote parties to verify the measured values.
  • IMA provides local validation of the current content of files against the values previously stored in the measurement list within the kernel memory. This extension forbids performing any operation on a specific file in case the current and the previous measures do not match.
Extended Verification Module (EVM)
  • EVM protects extended attributes of files (also known as xattr) that are related to system security, such as IMA measurements and SELinux attributes. EVM cryptographically hashes their corresponding values or signs them with cryptographic keys. The keys are stored in the kernel keyring subsystem.

The kernel integrity subsystem can use the Trusted Platform Module (TPM) to further harden system security.

A TPM is a hardware, firmware, or virtual component with integrated cryptographic keys, which is built according to the TPM specification by the Trusted Computing Group (TCG) for important cryptographic functions. TPMs are usually built as dedicated hardware attached to the platform’s motherboard. By providing cryptographic functions from a protected and tamper-proof area of the hardware chip, TPMs are protected from software-based attacks. TPMs provide the following features:

  • Random-number generator
  • Generator and secure storage for cryptographic keys
  • Hashing generator
  • Remote attestation

21.2. Trusted and encrypted keys

Trusted keys and encrypted keys are an important part of enhancing system security.

Trusted and encrypted keys are variable-length symmetric keys generated by the kernel that use the kernel keyring service. The integrity of the keys can be verified, which means that they can be used, for example, by the extended verification module (EVM) to verify and confirm the integrity of a running system. User-level programs can only access the keys in the form of encrypted blobs.

Trusted keys

Trusted keys need the Trusted Platform Module (TPM) chip, which is used to both create and encrypt (seal) the keys. Each TPM has a master wrapping key, called the storage root key, which is stored within the TPM itself.


RHEL 9 supports only TPM 2.0. If you must use TPM 1.2, use RHEL 8. For more information, see the Is Trusted Platform Module (TPM) supported by Red Hat? solution.

You can verify that a TPM 2.0 chip has been enabled by entering the following command:

$ cat /sys/class/tpm/tpm0/tpm_version_major

You can also enable a TPM 2.0 chip and manage the TPM 2.0 device through settings in the machine firmware.

In addition to that, you can seal the trusted keys with a specific set of the TPM’s platform configuration register (PCR) values. PCR contains a set of integrity-management values that reflect the firmware, boot loader, and operating system. This means that PCR-sealed keys can only be decrypted by the TPM on the same system on which they were encrypted. However, when a PCR-sealed trusted key is loaded (added to a keyring), and thus its associated PCR values are verified, it can be updated with new (or future) PCR values, so that a new kernel, for example, can be booted. You can save a single key also as multiple blobs, each with a different PCR value.

Encrypted keys
Encrypted keys do not require a TPM, because they use the kernel Advanced Encryption Standard (AES), which makes them faster than trusted keys. Encrypted keys are created using kernel-generated random numbers and encrypted by a master key when they are exported into user-space blobs.

The master key is either a trusted key or a user key. If the master key is not trusted, the encrypted key is only as secure as the user key used to encrypt it.

21.3. Working with trusted keys

You can improve system security by using the keyctl utility to create, export, load and update trusted keys.



  1. Create a 2048-bit RSA key with an SHA-256 primary storage key with a persistent handle of, for example, 81000001, by using one of the following utilities:

    1. By using the tss2 package:

      # TPM_DEVICE=/dev/tpm0 tsscreateprimary -hi o -st
      Handle 80000000
      # TPM_DEVICE=/dev/tpm0 tssevictcontrol -hi o -ho 80000000 -hp 81000001
    2. By using the tpm2-tools package:

      # tpm2_createprimary --key-algorithm=rsa2048 --key-context=key.ctxt
        value: sha256
        raw: 0xb
      sym-keybits: 128
      rsa: xxxxxx…
      # tpm2_evictcontrol -c key.ctxt 0x81000001
      persistentHandle: 0x81000001
      action: persisted
  2. Create a trusted key by using a TPM 2.0 with the syntax of keyctl add trusted <NAME> "new <KEY_LENGTH> keyhandle=<PERSISTENT-HANDLE> [options]" <KEYRING>. In this example, the persistent handle is 81000001.

    # keyctl add trusted kmk "new 32 keyhandle=0x81000001" @u

    The command creates a trusted key called kmk with the length of 32 bytes (256 bits) and places it in the user keyring (@u). The keys may have a length of 32 to 128 bytes (256 to 1024 bits).

  3. List the current structure of the kernel keyrings:

    # keyctl show
    Session Keyring
           -3 --alswrv    500   500  keyring: ses 97833714 --alswrv 500 -1 \ keyring: uid.1000 642500861 --alswrv 500 500 \ trusted: kmk
  4. Export the key to a user-space blob by using the serial number of the trusted key:

    # keyctl pipe 642500861 > kmk.blob

    The command uses the pipe subcommand and the serial number of kmk.

  5. Load the trusted key from the user-space blob:

    # keyctl add trusted kmk "load `cat kmk.blob`" @u
  6. Create secure encrypted keys that use the TPM-sealed trusted key (kmk). Follow this syntax: keyctl add encrypted <NAME> "new [FORMAT] <KEY_TYPE>:<PRIMARY_KEY_NAME> <KEY_LENGTH>" <KEYRING>:

    # keyctl add encrypted encr-key "new trusted:kmk 32" @u

21.4. Working with encrypted keys

You can improve system security on systems where a Trusted Platform Module (TPM) is not available by managing encrypted keys.


  1. Generate a user key by using a random sequence of numbers.

    # keyctl add user kmk-user "$(dd if=/dev/urandom bs=1 count=32 2>/dev/null)" @u

    The command generates a user key called kmk-user which acts as a primary key and is used to seal the actual encrypted keys.

  2. Generate an encrypted key using the primary key from the previous step:

    # keyctl add encrypted encr-key "new user:kmk-user 32" @u
  3. Optionally, list all keys in the specified user keyring:

    # keyctl list @u
    2 keys in keyring:
    427069434: --alswrv  1000  1000 user: kmk-user
    1012412758: --alswrv  1000  1000 encrypted: encr-key

Encrypted keys that are not sealed by a trusted primary key are only as secure as the user primary key (random-number key) that was used to encrypt them. Therefore, load the primary user key as securely as possible and preferably early during the boot process.

Additional resources

21.5. Enabling IMA and EVM

You can enable and configure Integrity measurement architecture (IMA) and extended verification module (EVM) to improve the security of the operating system.


Always enable EVM together with IMA.

Although you can enable EVM alone, EVM appraisal is only triggered by an IMA appraisal rule. Therefore, EVM does not protect file metadata such as SELinux attributes. If file metadata is tampered with offline, EVM can only prevent file metadata changes. It does not prevent file access, such as executing the file.


  • Secure Boot is temporarily disabled.


    When Secure Boot is enabled, the ima_appraise=fix kernel command-line parameter does not work.

  • The securityfs file system is mounted on the /sys/kernel/security/ directory and the /sys/kernel/security/integrity/ima/ directory exists. You can verify where securityfs is mounted by using the mount command:

    # mount
    securityfs on /sys/kernel/security type securityfs (rw,nosuid,nodev,noexec,relatime)
  • The systemd service manager is patched to support IMA and EVM on boot time. Verify by using the following command:

    # grep <options> pattern <files>

    For example:

    # dmesg | grep -i -e EVM -e IMA -w
    [ 0.943873] ima: No TPM chip found, activating TPM-bypass!
    [ 0.944566] ima: Allocated hash algorithm: sha256
    [ 0.944579] ima: No architecture policies found
    [ 0.944601] evm: Initialising EVM extended attributes:
    [ 0.944602] evm: security.selinux
    [ 0.944604] evm: security.SMACK64 (disabled)
    [ 0.944605] evm: security.SMACK64EXEC (disabled)
    [ 0.944607] evm: security.SMACK64TRANSMUTE (disabled)
    [ 0.944608] evm: security.SMACK64MMAP (disabled)
    [ 0.944609] evm: security.apparmor (disabled)
    [ 0.944611] evm: security.ima
    [ 0.944612] evm: security.capability
    [ 0.944613] evm: HMAC attrs: 0x1
    [ 1.717675] device-mapper: core: CONFIG_IMA_DISABLE_HTABLE is disabled. Duplicate IMA measurements will not be recorded in the IMA log.


  1. Enable IMA and EVM in the fix mode for the current boot entry and allow users to gather and update the IMA measurements by adding the following kernel command-line parameters:

    # grubby --update-kernel=/boot/vmlinuz-$(uname -r) --args="ima_policy=appraise_tcb ima_appraise=fix evm=fix"

    The command enables IMA and EVM in the fix mode for the current boot entry and allows users to gather and update the IMA measurements.

    The ima_policy=appraise_tcb kernel command-line parameter ensures that the kernel uses the default Trusted Computing Base (TCB) measurement policy and the appraisal step. The appraisal step forbids access to files whose prior and current measures do not match.

  2. Reboot to make the changes come into effect.
  3. Optional: Verify that the parameters have been added to the kernel command line:

    # cat /proc/cmdline
    BOOT_IMAGE=(hd0,msdos1)/vmlinuz-5.14.0-1.el9.x86_64 root=/dev/mapper/rhel-root ro crashkernel=1G-4G:192M,4G-64G:256M,64G-:512M resume=/dev/mapper/rhel-swap rhgb quiet ima_policy=appraise_tcb ima_appraise=fix evm=fix
  4. Create a kernel master key to protect the EVM key:

    # keyctl add user kmk "$(dd if=/dev/urandom bs=1 count=32 2> /dev/null)" @u

    The kmk is kept entirely in the kernel space memory. The 32-byte long value of the kmk is generated from random bytes from the /dev/urandom file and placed in the user (@u) keyring. The key serial number is on the first line of the previous output.

  5. Create an encrypted EVM key based on the kmk:

    # keyctl add encrypted evm-key "new user:kmk 64" @u

    The command uses the kmk to generate and encrypt a 64-byte long user key (named evm-key) and places it in the user (@u) keyring. The key serial number is on the first line of the previous output.


    It is necessary to name the user key as evm-key because that is the name the EVM subsystem is expecting and is working with.

  6. Create a directory for exported keys.

    # mkdir -p /etc/keys/
  7. Search for the kmk and export its unencrypted value into the new directory.

    # keyctl pipe $(keyctl search @u user kmk) > /etc/keys/kmk
  8. Search for the evm-key and export its encrypted value into the new directory.

    # keyctl pipe $(keyctl search @u encrypted evm-key) > /etc/keys/evm-key

    The evm-key has been encrypted by the kernel master key earlier.

  9. Optional: View the newly created keys.

    # keyctl show
    Session Keyring
    974575405   --alswrv     0        0      keyring: ses 299489774 --alswrv 0 65534 \ keyring: uid.0 748544121 --alswrv 0 0 \ user: kmk
    641780271   --alswrv     0        0           \_ encrypted: evm-key
    # ls -l /etc/keys/
    total 8
    -rw-r--r--. 1 root root 246 Jun 24 12:44 evm-key
    -rw-r--r--. 1 root root  32 Jun 24 12:43 kmk
  10. Optional: If the keys have been removed from the keyring, for example after system reboot, you can import the already exported kmk and evm-key instead of creating new ones.

    1. Import the kmk.

      # keyctl add user kmk "$(cat /etc/keys/kmk)" @u
    2. Import the evm-key.

      # keyctl add encrypted evm-key "load $(cat /etc/keys/evm-key)" @u
  11. Activate EVM.

    # echo 1 > /sys/kernel/security/evm
  12. Relabel the whole system.

    # find / -fstype xfs -type f -uid 0 -exec head -n 1 '{}' >/dev/null \;

    Enabling IMA and EVM without relabeling the system might make the majority of the files on the system inaccessible.


  • Verify that EVM has been initialized.

    # dmesg | tail -1
    […​] evm: key initialized

21.6. Collecting file hashes with integrity measurement architecture

In the measurement phase, you can create file hashes and store them as extended attributes (xattrs) of those files. With the file hashes, you can generate either an RSA-based digital signature or a Hash-based Message Authentication Code (HMAC-SHA1) and thus prevent offline tampering attacks on the extended attributes.



  1. Create a test file:

    # echo <Test_text> > test_file

    IMA and EVM ensure that the test_file example file has assigned hash values that are stored as its extended attributes.

  2. Inspect the file’s extended attributes:

    # getfattr -m . -d test_file
    # file: test_file

    The example output shows extended attributes with the IMA and EVM hash values and SELinux context. EVM adds a security.evm extended attribute related to the other attributes. At this point, you can use the evmctl utility on security.evm to generate either an RSA-based digital signature or a Hash-based Message Authentication Code (HMAC-SHA1).

Additional resources

21.7. Adding IMA signatures to package files

You need to add IMA signatures to RPM files to allow the kernel, Keylime, fapolicyd, and debuginfo packages to do their integrity checks. After installing the rpm-plugin-ima plugin, newly installed RPM files automatically have IMA signatures placed in the security.ima extended file attribute. However, you need to reinstall existing packages to obtain IMA signatures.


  1. To install the rpm-plugin-ima plugin, run:

    # dnf install rpm-plugin-ima -y
  2. To reinstall all packages, run:

    # dnf reinstall “*” -y


  1. Confirm that the reinstalled package file has the valid IMA signature. For example, to check the IMA signature of the /usr/bin/bash file, run:

    # getfattr -m security.ima -d /usr/bin/bash
  2. Verify IMA signature of a file with a specified certificate. The IMA code signing key is accessible by /usr/share/doc/kernel-keys/$(uname -r)/ima.cer.

    # evmctl ima_verify -k /usr/share/doc/kernel-keys/$(uname -r)/ima.cer /usr/bin/bash
    key 1: d3320449 /usr/share/doc/kernel-keys/5.14.0-359.el9.x86-64/ima.cer
    /usr/bin/bash: verification is OK

21.8. Enabling kernel runtime integrity monitoring

You can enable kernel runtime integrity monitoring that IMA appraisal provides.


  • The kernel installed on your system has version 5.14.0-359 or higher.
  • The dracut package has version 057-43.git20230816 or higher.
  • The keyutils package is installed.
  • The ima-evm-utils package is installed.
  • The files covered by the policy have valid signatures. For instructions, see Adding IMA signatures to package files.


  1. To copy the Red Hat IMA code signing key to the /etc/ima/keys file, run:

    $ mkdir -p /etc/keys/ima
    $ cp /usr/share/doc/kernel-keys/$(uname -r)/ima.cer /etc/ima/keys
  2. To add the IMA code signing key to the .ima keyring, run:

    # keyctl padd asymmetric RedHat-IMA %:.ima < /etc/ima/keys/ima.cer
  3. Depending on your threat model, define an IMA policy in the /etc/sysconfig/ima-policy file. For example, the following IMA policy checks the integrity of both executables and involved memory mapping library files:

    # PROC_SUPER_MAGIC = 0x9fa0
    dont_appraise fsmagic=0x9fa0
    # SYSFS_MAGIC = 0x62656572
    dont_appraise fsmagic=0x62656572
    # DEBUGFS_MAGIC = 0x64626720
    dont_appraise fsmagic=0x64626720
    # TMPFS_MAGIC = 0x01021994
    dont_appraise fsmagic=0x1021994
    dont_appraise fsmagic=0x858458f6
    dont_appraise fsmagic=0x1cd1
    # BINFMTFS_MAGIC=0x42494e4d
    dont_appraise fsmagic=0x42494e4d
    # SECURITYFS_MAGIC=0x73636673
    dont_appraise fsmagic=0x73636673
    # SELINUX_MAGIC=0xf97cff8c
    dont_appraise fsmagic=0xf97cff8c
    # SMACK_MAGIC=0x43415d53
    dont_appraise fsmagic=0x43415d53
    # NSFS_MAGIC=0x6e736673
    dont_appraise fsmagic=0x6e736673
    dont_appraise fsmagic=0xde5e81e4
    # CGROUP_SUPER_MAGIC=0x27e0eb
    dont_appraise fsmagic=0x27e0eb
    # CGROUP2_SUPER_MAGIC=0x63677270
    dont_appraise fsmagic=0x63677270
    appraise func=BPRM_CHECK
    appraise func=FILE_MMAP mask=MAY_EXEC
  4. To load the IMA policy to make sure the kernel accepts this IMA policy, run:

    # echo /etc/sysconfig/ima-policy > /sys/kernel/security/ima/policy
    # echo $?
  5. To enable the dracut integrity module to automatically load the IMA code signing key and the IMA policy, run:

    # echo 'add_dracutmodules+=" integrity "' > /etc/dracut.conf.d/98-integrity.conf
    # dracut -f

21.9. Creating custom IMA keys using OpenSSL

You can use OpenSSL to generate a CSR for your digital certificates to secure your code.

The kernel searches the .ima keyring for a code signing key to verify an IMA signature. Before you add a code signing key to the .ima keyring, you need to ensure that IMA CA key signed this key in the .builtin_trusted_keys or .secondary_trusted_keys keyrings.


  • The custom IMA CA key has the following extensions:

    • the basic constraints extension with the CA boolean asserted.
    • the KeyUsage extension with the keyCertSign bit asserted but without the digitalSignature asserted.
  • The custom IMA code signing key falls under the following criteria:

    • The IMA CA key signed this custom IMA code signing key.
    • The custom key includes the subjectKeyIdentifier extension.


  1. To generate a custom IMA CA key pair, run:

    # openssl req -new -x509 -utf8 -sha256 -days 3650 -batch -config ima_ca.conf -outform DER -out custom_ima_ca.der -keyout custom_ima_ca.priv
  2. Optional: To check the content of the ima_ca.conf file, run:

    # cat ima_ca.conf
    [ req ]
    default_bits = 2048
    distinguished_name = req_distinguished_name
    prompt = no
    string_mask = utf8only
    x509_extensions = ca
    [ req_distinguished_name ]
    O = YOUR_ORG
    emailAddress = YOUR_EMAIL
    [ ca ]
  3. To generate a private key and a certificate signing request (CSR) for the IMA code signing key, run:

    # openssl req -new -utf8 -sha256 -days 365 -batch -config ima.conf -out custom_ima.csr -keyout custom_ima.priv
  4. Optional: To check the content of the ima.conf file, run:

    # cat ima.conf
    [ req ]
    default_bits = 2048
    distinguished_name = req_distinguished_name
    prompt = no
    string_mask = utf8only
    x509_extensions = code_signing
    [ req_distinguished_name ]
    O = YOUR_ORG
    CN = YOUR_COMMON_NAME IMA signing key
    emailAddress = YOUR_EMAIL
    [ code_signing ]
  5. Use the IMA CA private key to sign the CSR to create the IMA code signing certificate:

    # openssl x509 -req -in custom_ima.csr -days 365 -extfile ima.conf -extensions code_signing -CA custom_ima_ca.der -CAkey custom_ima_ca.priv -CAcreateserial -outform DER -out ima.der

21.10. Deploying a custom signed IMA policy for UEFI systems

In the Secure Boot environment, you may want to only load a signed IMA policy signed by your custom IMA key.



  1. Enable Secure Boot.
  2. Permanently add the ima_policy=secure_boot kernel parameter.

    For instructions, see Configuring kernel parameters permanently with sysctl.

  3. Prepare your IMA policy by running the command:

    # evmctl ima_sign /etc/sysconfig/ima-policy -k <PATH_TO_YOUR_CUSTOM_IMA_KEY>
    Place your public certificate under /etc/keys/ima/ and add it to the .ima keyring
  4. Sign the policy with your custom IMA code signing key by running the command:

    # keyctl padd asymmetric CUSTOM_IMA1 %:.ima < /etc/ima/keys/my_ima.cer
  5. Load the IMA policy by running the command:

    # echo /etc/sysconfig/ima-policy > /sys/kernel/security/ima/policy
    # echo $?
Red Hat logoGithubRedditYoutubeTwitter


Try, buy, & sell


About Red Hat Documentation

We help Red Hat users innovate and achieve their goals with our products and services with content they can trust.

Making open source more inclusive

Red Hat is committed to replacing problematic language in our code, documentation, and web properties. For more details, see the Red Hat Blog.

About Red Hat

We deliver hardened solutions that make it easier for enterprises to work across platforms and environments, from the core datacenter to the network edge.

© 2024 Red Hat, Inc.