Commit e23277a4 authored by GONG Ruiqi's avatar GONG Ruiqi
Browse files

ima: rot: Make RoT kick in

hulk inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/IB4I9O



--------------------------------

Now the RoT framework starts working, by replacing ima_tpm_chip and those
relavant function calls to their RoT counterparts.

Signed-off-by: default avatarGONG Ruiqi <gongruiqi1@huawei.com>
parent 40151ef2
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -42,7 +42,7 @@ enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8, TPM_PCR10 = 10 };
#define IMA_TEMPLATE_IMA_NAME "ima"
#define IMA_TEMPLATE_IMA_FMT "d|n"

#define NR_BANKS(chip) ((chip != NULL) ? chip->nr_allocated_banks : 0)
#define NR_BANKS(rot) ((rot != NULL) ? rot->nr_allocated_banks : 0)

/* current content of the policy */
extern int ima_policy_flag;
@@ -56,7 +56,6 @@ extern int ima_sha1_idx __ro_after_init;
extern int ima_hash_algo_idx __ro_after_init;
extern int ima_extra_slots __ro_after_init;
extern int ima_appraise;
extern struct tpm_chip *ima_tpm_chip;
extern struct ima_rot *ima_rot_inst;
extern const char boot_aggregate_name[];
#ifdef CONFIG_IMA_DIGEST_LIST
+1 −1
Original line number Diff line number Diff line
@@ -52,7 +52,7 @@ int ima_alloc_init_template(struct ima_event_data *event_data,
	if (!*entry)
		return -ENOMEM;

	digests = kcalloc(NR_BANKS(ima_tpm_chip) + ima_extra_slots,
	digests = kcalloc(NR_BANKS(ima_rot_inst) + ima_extra_slots,
			  sizeof(*digests), GFP_NOFS);
	if (!digests) {
		kfree(*entry);
+19 −19
Original line number Diff line number Diff line
@@ -100,7 +100,7 @@ static struct crypto_shash *ima_alloc_tfm(enum hash_algo algo)
	if (algo == ima_hash_algo)
		return tfm;

	for (i = 0; i < NR_BANKS(ima_tpm_chip) + ima_extra_slots; i++)
	for (i = 0; i < NR_BANKS(ima_rot_inst) + ima_extra_slots; i++)
		if (ima_algo_array[i].tfm && ima_algo_array[i].algo == algo)
			return ima_algo_array[i].tfm;

@@ -126,8 +126,8 @@ int __init ima_init_crypto(void)
	ima_sha1_idx = -1;
	ima_hash_algo_idx = -1;

	for (i = 0; i < NR_BANKS(ima_tpm_chip); i++) {
		algo = ima_tpm_chip->allocated_banks[i].crypto_id;
	for (i = 0; i < NR_BANKS(ima_rot_inst); i++) {
		algo = ima_rot_inst->allocated_banks[i].crypto_id;
		if (algo == HASH_ALGO_SHA1)
			ima_sha1_idx = i;

@@ -136,23 +136,23 @@ int __init ima_init_crypto(void)
	}

	if (ima_sha1_idx < 0) {
		ima_sha1_idx = NR_BANKS(ima_tpm_chip) + ima_extra_slots++;
		ima_sha1_idx = NR_BANKS(ima_rot_inst) + ima_extra_slots++;
		if (ima_hash_algo == HASH_ALGO_SHA1)
			ima_hash_algo_idx = ima_sha1_idx;
	}

	if (ima_hash_algo_idx < 0)
		ima_hash_algo_idx = NR_BANKS(ima_tpm_chip) + ima_extra_slots++;
		ima_hash_algo_idx = NR_BANKS(ima_rot_inst) + ima_extra_slots++;

	ima_algo_array = kcalloc(NR_BANKS(ima_tpm_chip) + ima_extra_slots,
	ima_algo_array = kcalloc(NR_BANKS(ima_rot_inst) + ima_extra_slots,
				 sizeof(*ima_algo_array), GFP_KERNEL);
	if (!ima_algo_array) {
		rc = -ENOMEM;
		goto out;
	}

	for (i = 0; i < NR_BANKS(ima_tpm_chip); i++) {
		algo = ima_tpm_chip->allocated_banks[i].crypto_id;
	for (i = 0; i < NR_BANKS(ima_rot_inst); i++) {
		algo = ima_rot_inst->allocated_banks[i].crypto_id;
		ima_algo_array[i].algo = algo;

		/* unknown TPM algorithm */
@@ -176,7 +176,7 @@ int __init ima_init_crypto(void)
		}
	}

	if (ima_sha1_idx >= NR_BANKS(ima_tpm_chip)) {
	if (ima_sha1_idx >= NR_BANKS(ima_rot_inst)) {
		if (ima_hash_algo == HASH_ALGO_SHA1) {
			ima_algo_array[ima_sha1_idx].tfm = ima_shash_tfm;
		} else {
@@ -191,7 +191,7 @@ int __init ima_init_crypto(void)
		ima_algo_array[ima_sha1_idx].algo = HASH_ALGO_SHA1;
	}

	if (ima_hash_algo_idx >= NR_BANKS(ima_tpm_chip) &&
	if (ima_hash_algo_idx >= NR_BANKS(ima_rot_inst) &&
	    ima_hash_algo_idx != ima_sha1_idx) {
		ima_algo_array[ima_hash_algo_idx].tfm = ima_shash_tfm;
		ima_algo_array[ima_hash_algo_idx].algo = ima_hash_algo;
@@ -199,7 +199,7 @@ int __init ima_init_crypto(void)

	return 0;
out_array:
	for (i = 0; i < NR_BANKS(ima_tpm_chip) + ima_extra_slots; i++) {
	for (i = 0; i < NR_BANKS(ima_rot_inst) + ima_extra_slots; i++) {
		if (!ima_algo_array[i].tfm ||
		    ima_algo_array[i].tfm == ima_shash_tfm)
			continue;
@@ -219,7 +219,7 @@ static void ima_free_tfm(struct crypto_shash *tfm)
	if (tfm == ima_shash_tfm)
		return;

	for (i = 0; i < NR_BANKS(ima_tpm_chip) + ima_extra_slots; i++)
	for (i = 0; i < NR_BANKS(ima_rot_inst) + ima_extra_slots; i++)
		if (ima_algo_array[i].tfm == tfm)
			return;

@@ -637,12 +637,12 @@ int ima_calc_field_array_hash(struct ima_field_data *field_data,

	entry->digests[ima_sha1_idx].alg_id = TPM_ALG_SHA1;

	for (i = 0; i < NR_BANKS(ima_tpm_chip) + ima_extra_slots; i++) {
	for (i = 0; i < NR_BANKS(ima_rot_inst) + ima_extra_slots; i++) {
		if (i == ima_sha1_idx)
			continue;

		if (i < NR_BANKS(ima_tpm_chip)) {
			alg_id = ima_tpm_chip->allocated_banks[i].alg_id;
		if (i < NR_BANKS(ima_rot_inst)) {
			alg_id = ima_rot_inst->allocated_banks[i].alg_id;
			entry->digests[i].alg_id = alg_id;
		}

@@ -839,8 +839,8 @@ int ima_calc_boot_aggregate(struct ima_digest_data *hash)
	u16 crypto_id, alg_id;
	int rc, i, bank_idx = -1;

	for (i = 0; i < ima_tpm_chip->nr_allocated_banks; i++) {
		crypto_id = ima_tpm_chip->allocated_banks[i].crypto_id;
	for (i = 0; i < NR_BANKS(ima_rot_inst); i++) {
		crypto_id = ima_rot_inst->allocated_banks[i].crypto_id;
		if (crypto_id == hash->algo) {
			bank_idx = i;
			break;
@@ -858,14 +858,14 @@ int ima_calc_boot_aggregate(struct ima_digest_data *hash)
		return 0;
	}

	hash->algo = ima_tpm_chip->allocated_banks[bank_idx].crypto_id;
	hash->algo = ima_rot_inst->allocated_banks[bank_idx].crypto_id;

	tfm = ima_alloc_tfm(hash->algo);
	if (IS_ERR(tfm))
		return PTR_ERR(tfm);

	hash->length = crypto_shash_digestsize(tfm);
	alg_id = ima_tpm_chip->allocated_banks[bank_idx].alg_id;
	alg_id = ima_rot_inst->allocated_banks[bank_idx].alg_id;
	rc = ima_calc_boot_aggregate_tfm(hash->digest, alg_id, tfm);

	ima_free_tfm(tfm);
+6 −6
Original line number Diff line number Diff line
@@ -80,8 +80,8 @@ static int __init ima_add_boot_aggregate(void)
	 * Ultimately select SHA1 also for TPM 2.0 if the SHA256 PCR bank
	 * is not found.
	 */
	if (ima_tpm_chip) {
		result = ima_calc_boot_aggregate(&hash.hdr);
	if (ima_rot_inst) {
		result = ima_rot_inst->calc_boot_aggregate(&hash.hdr);
		if (result < 0) {
			audit_cause = "hashing_error";
			goto err_out;
@@ -136,13 +136,13 @@ int __init ima_init(void)
	rc = ima_cvm_init();
	if (rc) {
		pr_info("No CVM found, activating CVM-bypass!\n");
		ima_tpm_chip = tpm_default_chip();
		ima_rot_inst = ima_rot_init();
	}
#else
	ima_tpm_chip = tpm_default_chip();
	ima_rot_inst = ima_rot_init();
#endif
	if (!ima_tpm_chip)
		pr_info("No TPM chip found, activating TPM-bypass!\n");
	if (!ima_rot_inst)
		pr_info("No RoT found, activating RoT-bypass!\n");

	rc = integrity_init_keyring(INTEGRITY_KEYRING_IMA);
	if (rc)
+21 −20
Original line number Diff line number Diff line
@@ -19,7 +19,6 @@
#include <linux/slab.h>
#include "ima.h"
#include "ima_cvm.h"
#include "ima_tpm.h"

#define AUDIT_CAUSE_LEN_MAX 32

@@ -152,9 +151,9 @@ int ima_add_template_entry(struct ima_template_entry *entry, int violation,
	u8 *digest = entry->digests[ima_hash_algo_idx].digest;
	struct tpm_digest *digests_arg = entry->digests;
	const char *audit_cause = "hash_added";
	char tpm_audit_cause[AUDIT_CAUSE_LEN_MAX];
	char rot_audit_cause[AUDIT_CAUSE_LEN_MAX];
	int audit_info = 1;
	int result = 0, tpmresult = 0;
	int result = 0, rotresult = 0;

	mutex_lock(&ima_extend_list_mutex);
	if (!violation && !IS_ENABLED(CONFIG_IMA_DISABLE_HTABLE)) {
@@ -177,22 +176,24 @@ int ima_add_template_entry(struct ima_template_entry *entry, int violation,
		digests_arg = digests;

#ifdef CONFIG_HISI_VIRTCCA_GUEST
	tpmresult = ima_cvm_extend(digests_arg);
	if (tpmresult != 0) {
		snprintf(tpm_audit_cause, AUDIT_CAUSE_LEN_MAX, "TSI_error(%d)",
			 tpmresult);
		audit_cause = tpm_audit_cause;
	rotresult = ima_cvm_extend(digests_arg);
	if (rotresult != 0) {
		snprintf(rot_audit_cause, AUDIT_CAUSE_LEN_MAX, "TSI_error(%d)",
			 rotresult);
		audit_cause = rot_audit_cause;
		audit_info = 0;
	}
#endif

	tpmresult = ima_pcr_extend(digests_arg, entry->pcr);
	if (tpmresult != 0) {
		snprintf(tpm_audit_cause, AUDIT_CAUSE_LEN_MAX, "TPM_error(%d)",
			 tpmresult);
		audit_cause = tpm_audit_cause;
	if (ima_rot_inst) {
		rotresult = ima_rot_inst->extend(digests_arg, &entry->pcr);
		if (rotresult != 0) {
			snprintf(rot_audit_cause, AUDIT_CAUSE_LEN_MAX, "%s_error(%d)",
				 ima_rot_inst->name, rotresult);
			audit_cause = rot_audit_cause;
			audit_info = 0;
		}
	}
out:
	mutex_unlock(&ima_extend_list_mutex);
	integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, filename,
@@ -216,18 +217,18 @@ int __init ima_init_digests(void)
	u16 crypto_id;
	int i;

	if (!ima_tpm_chip)
	if (!ima_rot_inst)
		return 0;

	digests = kcalloc(ima_tpm_chip->nr_allocated_banks, sizeof(*digests),
	digests = kcalloc(ima_rot_inst->nr_allocated_banks, sizeof(*digests),
			  GFP_NOFS);
	if (!digests)
		return -ENOMEM;

	for (i = 0; i < ima_tpm_chip->nr_allocated_banks; i++) {
		digests[i].alg_id = ima_tpm_chip->allocated_banks[i].alg_id;
		digest_size = ima_tpm_chip->allocated_banks[i].digest_size;
		crypto_id = ima_tpm_chip->allocated_banks[i].crypto_id;
	for (i = 0; i < ima_rot_inst->nr_allocated_banks; i++) {
		digests[i].alg_id = ima_rot_inst->allocated_banks[i].alg_id;
		digest_size = ima_rot_inst->allocated_banks[i].digest_size;
		crypto_id = ima_rot_inst->allocated_banks[i].crypto_id;

		/* for unmapped TPM algorithms digest is still a padded SHA1 */
		if (crypto_id == HASH_ALGO__LAST)
Loading