========================== IMA Digest Lists Extension ========================== INTRODUCTION ============ Integrity Measurement Architecture (IMA) is a security module that performs measurement of files accessed with the execve(), mmap() and open() system calls. File measurements can be used for different purposes. They can be added in a measurement list and sent to a remote verifier for an integrity evaluation. They can be compared to reference values provided by the software vendor and access can be denied if there is a mismatch. File measurements can also be included in system logs for auditing purposes. IMA Digest Lists is an extension providing additional functionality for the IMA submodules and EVM. Its main task is to load reference values for file content and metadata in the kernel memory, and to communicate to IMA submodules (measurement and appraisal) or EVM whether the digest of a file being accessed is found in the uploaded digest lists. The IMA-Measure submodule uses the IMA Digest Lists extension to create a new measurement list (with a different PCR, for example 11) which contains the measurement of uploaded digest lists and unknown files. Since the loading of digest lists is sequential, the chosen PCR will have a predictable value for the whole boot cycle and can be used for sealing policies based on the OS software integrity. Both the standard and the new measurement list can be generated at the same time, allowing for implicit attestation based on the usage of a TPM key sealed to the OS, and for explicit attestation when a more precise integrity evaluation is necessary. The IMA-Appraise submodule uses the IMA Digest Lists extension to grant/deny access to the files depending on whether the file digest is found in the uploaded digest lists, instead of checking security.ima. EVM uses the IMA Digest Lists extension to check file metadata integrity. The main advantage of the extension is that reference measurements used for the digest comparison can be extracted from already existing sources (for example RPM headers). Another benefit is that the overhead compared to file signatures is lower as only one signature is verified for all files included in the digest list. WORKFLOW ======== The IMA workflow is modified as follows. The added steps are marked as [NEW]. +------------+ | IMA hook | +------------+ | +---------+ | collect | +---------+ | +---------------------+ +---------------+ ------------| don't measure [NEW] | | digest lookup | | yes +---------------------+ | [NEW] | -------------- no +---------------------+ +---------------+ -----/ digest \---| add to measurement | | | \ found? [NEW] / | list (PCR 11) [NEW] | | | -------------- +---------------------+ +----------+ +-------------+ +--------------------+ | switch |-------| IMA-Measure |----------------| add to measurement | | (action) | +-------------+ | list (PCR 10) | +----------+ +--------------------+ | | | no xattr +--------------+ --------------- yes | IMA-Appraise |----/ filec created \------------------------------- +--------------+ \ created [NEW] / | xattr | --------------- | | | no | | ------------------ no -------------- yes +--------+ | / EVM initialized? \----/ digest \------| grant | | \ [NEW] / \ found? [NEW] / | access | | ------------------ -------------- +--------+ | | yes | no | | | +--------+ | ------------------- no ---------------| deny | | / digest-nometadata \-------------------------| access | | \ mode? [NEW] / +--------+ | ------------------- | ^ | yes +--------+ | | -------------------------------------| grant | | | | access | | | +--------+ | | yes | ------------------------- no +--------+ |----------/ security.ima (new type) \-------------------| deny | | \ present and valid? / | access | | ------------------------- +--------+ | | | -------------------------- no | -----------/ security.ima (cur types) \----------------------- \ present and valid? / -------------------------- | yes +--------+ ------------------------------------| grant | | access | +--------+ +-----+ -------------------------- yes +--------+ | EVM |---------/ security.evm (cur types) \---------------------| grant | +-----+ \ present and valid? / | access | | -------------------------- +--------+ | | | | no +--------+ | ------------------------------------| deny | | | access | | +--------+ | | | +-----------+ | | ------------------------- | calculate | | -------------/ security.evm (new type) \---| metadata | | \ present? [NEW] / | digest | | ------------------------- +-----------+ | | | -------------- no | / digest \--------- \ found? [NEW] / -------------- +--------+ | yes | grant | | | access | | +--------+ | | ------------------ yes | / digest \-----| \ immutable? [NEW] / | ------------------ | | no | +---------+ | | convert |------------ | to HMAC | +---------+ After the file digest is calculated, it is searched in the hash table containing all digests extracted from the uploaded digest lists. Then, if the digest is found, a structure is returned to IMA with information associated to that digest. The structure is returned only to the IMA submodules that processed the digest lists (i.e. the action returned by ima_get_action() was 'measure' or 'appraise'). IMA-Measure behavior depends on whether the digest list PCR has been specified in the kernel command line. If the PCR was not specified, the submodule behaves as before. If the PCR was specified, IMA-Measure creates a new measurement with that PCR, only if the file digest is not found in the digest lists. It additionally creates a measurement with the default PCR if '+' is added as a prefix to the PCR. IMA-Appraise behavior depends on whether either the 'digest' or 'digest-nometadata' appraisal modes have been specified in the kernel command line. If they were not specified, IMA-Appraise relies solely on the security.ima xattr for verification. If the 'digest' mode was specified, verification succeeds if the file digest is found in the digest lists and EVM is not initialized, as there is no other way to verify file metadata. If the 'digest-nometadata' mode was specified, verification succeeds regardless of the fact that EVM is initialized or not. However, after a write, files for which access was granted without verifying metadata will have a new security.ima type, so that they can be identified also after reboot. Specifying 'digest-nometadata' is required also to access files with the new security.ima type. EVM determines whether metadata digest should be searched in the digest lists depending on the security.evm type. If the new type is set, EVM calculates metadata digest and searches it in the digest lists. A structure is returned to EVM if the digest is found and the digest lists were appraised. ARCHITECTURE ============ +-----+ 6) digest lookup | EVM |------------------------------------------------ +-----+ | | +--------------+ 5) digest lookup | | IMA-Appraise |--------------------------------------| +--------------+ || || +-------------+ 4) digest lookup || | IMA-Measure | -------------------------------------|| +-------------+ ||| ||| +-------------+ 2) parse compact list +-------------------+ | IMA (secfs) | ------------------------> | IMA Digests Lists | +-------------+ +-------------------+ ^ | 3) add digests | +------------+ | | hash table | | +------------+ | | kernel space ---|------------------------------------------------------------------------- | user space | | | | | | | 1) echo The main addition to IMA is a new hash table (similar to that used to check for duplicate measurement entries), which contains file content and metadata digests extracted from the digest lists. Digest lists can be uploaded to the kernel by writing their path to digest_list_data in the securityfs filesystem. After digest lists are uploaded, they are parsed by the kernel and extracted digests are added to the hash table. IMA submodules, Measure and Appraise, search the digest of an accessed file in the hash table and perform actions depending on whether the digest was found or not. IMA submodules can search digests in the hash table only if they also processed the digest lists. EVM searches the metadata digest of an accessed file in the hash table and returns the result to IMA, which perform actions depending on the result. EVM can search digests in the hash table if IMA-Appraise processed the digest lists. CONFIGURATION ============= The first step consists in generating digest lists with the gen_digest_lists tool included in the digest-list-tools package. digest-list-tools can be retrieved at the URL: https://gitee.com/openeuler/digest-list-tools gen_digest_lists can generate digest lists from different sources (for example: RPM package DB). By default, it saves generated digest lists in the /etc/ima/digest_lists directory. digest-list-tools includes also two bash scripts setup_ima_digest_lists and setup_digest_lists_demo to simplify the digest list generation for the users. To use digest lists during early boot, it is necessary to regenerate the initial ram disk. Digest lists will be added to the ram disk by the new dracut/initramfs-tools modules, included in the digest-list-tools package. To include file signatures in the initial ram disk, it is necessary to have the following patches applied: https://gitee.com/src-openeuler/cpio/blob/master/add-option-to-add-metadata-in-copy-out-mode.patch https://gitee.com/src-openeuler/dracut/blob/master/add-option-to-include-file-metadata-in-initramfs.patch