^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2005,2006,2007,2008 IBM Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Authors:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Reiner Sailer <sailer@watson.ibm.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Leendert van Doorn <leendert@watson.ibm.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Mimi Zohar <zohar@us.ibm.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * File: ima_init.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * initialization and cleanup functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/scatterlist.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "ima.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) /* name for boot aggregate entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) const char boot_aggregate_name[] = "boot_aggregate";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) struct tpm_chip *ima_tpm_chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) /* Add the boot aggregate to the IMA measurement list and extend
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * the PCR register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * Calculate the boot aggregate, a hash over tpm registers 0-7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * assuming a TPM chip exists, and zeroes if the TPM chip does not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * exist. Add the boot aggregate measurement to the measurement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * list and extend the PCR register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * If a tpm chip does not exist, indicate the core root of trust is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * not hardware based by invalidating the aggregate PCR value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * (The aggregate PCR value is invalidated by adding one value to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * the measurement list and extending the aggregate PCR value with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * a different value.) Violations add a zero entry to the measurement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * list and extend the aggregate PCR value with ff...ff's.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) static int __init ima_add_boot_aggregate(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) static const char op[] = "add_boot_aggregate";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) const char *audit_cause = "ENOMEM";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) struct ima_template_entry *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) struct integrity_iint_cache tmp_iint, *iint = &tmp_iint;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) struct ima_event_data event_data = { .iint = iint,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) .filename = boot_aggregate_name };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) int result = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) int violation = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) struct ima_digest_data hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) char digest[TPM_MAX_DIGEST_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) } hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) memset(iint, 0, sizeof(*iint));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) memset(&hash, 0, sizeof(hash));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) iint->ima_hash = &hash.hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) iint->ima_hash->algo = ima_hash_algo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) iint->ima_hash->length = hash_digest_size[ima_hash_algo];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * With TPM 2.0 hash agility, TPM chips could support multiple TPM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * PCR banks, allowing firmware to configure and enable different
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * banks. The SHA1 bank is not necessarily enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * Use the same hash algorithm for reading the TPM PCRs as for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * calculating the boot aggregate digest. Preference is given to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * the configured IMA default hash algorithm. Otherwise, use the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) * TCG required banks - SHA256 for TPM 2.0, SHA1 for TPM 1.2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * Ultimately select SHA1 also for TPM 2.0 if the SHA256 PCR bank
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * is not found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) if (ima_tpm_chip) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) result = ima_calc_boot_aggregate(&hash.hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) if (result < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) audit_cause = "hashing_error";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) result = ima_alloc_init_template(&event_data, &entry, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) if (result < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) audit_cause = "alloc_entry";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) result = ima_store_template(entry, violation, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) boot_aggregate_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) CONFIG_IMA_MEASURE_PCR_IDX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) if (result < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) ima_free_template_entry(entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) audit_cause = "store_entry";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) integrity_audit_msg(AUDIT_INTEGRITY_PCR, NULL, boot_aggregate_name, op,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) audit_cause, result, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #ifdef CONFIG_IMA_LOAD_X509
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) void __init ima_load_x509(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) int unset_flags = ima_policy_flag & IMA_APPRAISE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) ima_policy_flag &= ~unset_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) integrity_load_x509(INTEGRITY_KEYRING_IMA, CONFIG_IMA_X509_PATH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) ima_policy_flag |= unset_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) int __init ima_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) ima_tpm_chip = tpm_default_chip();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) if (!ima_tpm_chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) pr_info("No TPM chip found, activating TPM-bypass!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) rc = integrity_init_keyring(INTEGRITY_KEYRING_IMA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) rc = ima_init_crypto();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) rc = ima_init_template();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) if (rc != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) /* It can be called before ima_init_digests(), it does not use TPM. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) ima_load_kexec_buffer();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) rc = ima_init_digests();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) if (rc != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) rc = ima_add_boot_aggregate(); /* boot aggregate must be first entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) if (rc != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) ima_init_policy();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) rc = ima_fs_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) if (rc != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) ima_init_key_queue();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }