Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (C) 2005,2006,2007,2008 IBM Corporation
0004  *
0005  * Authors:
0006  * Reiner Sailer      <sailer@watson.ibm.com>
0007  * Leendert van Doorn <leendert@watson.ibm.com>
0008  * Mimi Zohar         <zohar@us.ibm.com>
0009  *
0010  * File: ima_init.c
0011  *             initialization and cleanup functions
0012  */
0013 
0014 #include <linux/init.h>
0015 #include <linux/scatterlist.h>
0016 #include <linux/slab.h>
0017 #include <linux/err.h>
0018 #include <linux/ima.h>
0019 #include <generated/utsrelease.h>
0020 
0021 #include "ima.h"
0022 
0023 /* name for boot aggregate entry */
0024 const char boot_aggregate_name[] = "boot_aggregate";
0025 struct tpm_chip *ima_tpm_chip;
0026 
0027 /* Add the boot aggregate to the IMA measurement list and extend
0028  * the PCR register.
0029  *
0030  * Calculate the boot aggregate, a hash over tpm registers 0-7,
0031  * assuming a TPM chip exists, and zeroes if the TPM chip does not
0032  * exist.  Add the boot aggregate measurement to the measurement
0033  * list and extend the PCR register.
0034  *
0035  * If a tpm chip does not exist, indicate the core root of trust is
0036  * not hardware based by invalidating the aggregate PCR value.
0037  * (The aggregate PCR value is invalidated by adding one value to
0038  * the measurement list and extending the aggregate PCR value with
0039  * a different value.) Violations add a zero entry to the measurement
0040  * list and extend the aggregate PCR value with ff...ff's.
0041  */
0042 static int __init ima_add_boot_aggregate(void)
0043 {
0044     static const char op[] = "add_boot_aggregate";
0045     const char *audit_cause = "ENOMEM";
0046     struct ima_template_entry *entry;
0047     struct integrity_iint_cache tmp_iint, *iint = &tmp_iint;
0048     struct ima_event_data event_data = { .iint = iint,
0049                          .filename = boot_aggregate_name };
0050     struct ima_max_digest_data hash;
0051     int result = -ENOMEM;
0052     int violation = 0;
0053 
0054     memset(iint, 0, sizeof(*iint));
0055     memset(&hash, 0, sizeof(hash));
0056     iint->ima_hash = &hash.hdr;
0057     iint->ima_hash->algo = ima_hash_algo;
0058     iint->ima_hash->length = hash_digest_size[ima_hash_algo];
0059 
0060     /*
0061      * With TPM 2.0 hash agility, TPM chips could support multiple TPM
0062      * PCR banks, allowing firmware to configure and enable different
0063      * banks.  The SHA1 bank is not necessarily enabled.
0064      *
0065      * Use the same hash algorithm for reading the TPM PCRs as for
0066      * calculating the boot aggregate digest.  Preference is given to
0067      * the configured IMA default hash algorithm.  Otherwise, use the
0068      * TCG required banks - SHA256 for TPM 2.0, SHA1 for TPM 1.2.
0069      * Ultimately select SHA1 also for TPM 2.0 if the SHA256 PCR bank
0070      * is not found.
0071      */
0072     if (ima_tpm_chip) {
0073         result = ima_calc_boot_aggregate(&hash.hdr);
0074         if (result < 0) {
0075             audit_cause = "hashing_error";
0076             goto err_out;
0077         }
0078     }
0079 
0080     result = ima_alloc_init_template(&event_data, &entry, NULL);
0081     if (result < 0) {
0082         audit_cause = "alloc_entry";
0083         goto err_out;
0084     }
0085 
0086     result = ima_store_template(entry, violation, NULL,
0087                     boot_aggregate_name,
0088                     CONFIG_IMA_MEASURE_PCR_IDX);
0089     if (result < 0) {
0090         ima_free_template_entry(entry);
0091         audit_cause = "store_entry";
0092         goto err_out;
0093     }
0094     return 0;
0095 err_out:
0096     integrity_audit_msg(AUDIT_INTEGRITY_PCR, NULL, boot_aggregate_name, op,
0097                 audit_cause, result, 0);
0098     return result;
0099 }
0100 
0101 #ifdef CONFIG_IMA_LOAD_X509
0102 void __init ima_load_x509(void)
0103 {
0104     int unset_flags = ima_policy_flag & IMA_APPRAISE;
0105 
0106     ima_policy_flag &= ~unset_flags;
0107     integrity_load_x509(INTEGRITY_KEYRING_IMA, CONFIG_IMA_X509_PATH);
0108 
0109     /* load also EVM key to avoid appraisal */
0110     evm_load_x509();
0111 
0112     ima_policy_flag |= unset_flags;
0113 }
0114 #endif
0115 
0116 int __init ima_init(void)
0117 {
0118     int rc;
0119 
0120     ima_tpm_chip = tpm_default_chip();
0121     if (!ima_tpm_chip)
0122         pr_info("No TPM chip found, activating TPM-bypass!\n");
0123 
0124     rc = integrity_init_keyring(INTEGRITY_KEYRING_IMA);
0125     if (rc)
0126         return rc;
0127 
0128     rc = ima_init_crypto();
0129     if (rc)
0130         return rc;
0131     rc = ima_init_template();
0132     if (rc != 0)
0133         return rc;
0134 
0135     /* It can be called before ima_init_digests(), it does not use TPM. */
0136     ima_load_kexec_buffer();
0137 
0138     rc = ima_init_digests();
0139     if (rc != 0)
0140         return rc;
0141     rc = ima_add_boot_aggregate();  /* boot aggregate must be first entry */
0142     if (rc != 0)
0143         return rc;
0144 
0145     ima_init_policy();
0146 
0147     rc = ima_fs_init();
0148     if (rc != 0)
0149         return rc;
0150 
0151     ima_init_key_queue();
0152 
0153     ima_measure_critical_data("kernel_info", "kernel_version",
0154                   UTS_RELEASE, strlen(UTS_RELEASE), false,
0155                   NULL, 0);
0156 
0157     return rc;
0158 }