Adapt TPM devices into the RoT framework, mostly by separating TPM-specific logic from the IMA code into the new ima_tpm.c file.
Note that although TPM has been set up for the RoT framework, at this moment the framework doesn't start working yet, and in practice IMA still runs the same way as before.
No functional change intended for this patch.
Signed-off-by: GONG Ruiqi gongruiqi1@huawei.com --- security/integrity/ima/Makefile | 1 + security/integrity/ima/ima_crypto.c | 10 +---- security/integrity/ima/ima_init.c | 1 - security/integrity/ima/ima_queue.c | 14 +------ security/integrity/ima/ima_rot.c | 9 +++++ security/integrity/ima/ima_tpm.c | 63 +++++++++++++++++++++++++++++ security/integrity/ima/ima_tpm.h | 22 ++++++++++ 7 files changed, 97 insertions(+), 23 deletions(-) create mode 100644 security/integrity/ima/ima_tpm.c create mode 100644 security/integrity/ima/ima_tpm.h
diff --git a/security/integrity/ima/Makefile b/security/integrity/ima/Makefile index 2b6467ea3f24..d9f2030d8b90 100644 --- a/security/integrity/ima/Makefile +++ b/security/integrity/ima/Makefile @@ -15,6 +15,7 @@ ima-$(CONFIG_IMA_BLACKLIST_KEYRING) += ima_mok.o ima-$(CONFIG_IMA_MEASURE_ASYMMETRIC_KEYS) += ima_asymmetric_keys.o ima-$(CONFIG_IMA_QUEUE_EARLY_BOOT_KEYS) += ima_queue_keys.o ima-$(CONFIG_IMA_DIGEST_LIST) += ima_digest_list.o +ima-$(CONFIG_TCG_TPM) += ima_tpm.o
ifeq ($(CONFIG_EFI),y) ima-$(CONFIG_IMA_SECURE_AND_OR_TRUSTED_BOOT) += ima_efi.o diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c index 51ad29940f05..c1bddc0bb7d5 100644 --- a/security/integrity/ima/ima_crypto.c +++ b/security/integrity/ima/ima_crypto.c @@ -21,6 +21,7 @@ #include <crypto/hash.h>
#include "ima.h" +#include "ima_tpm.h"
/* minimum file size for ahash use */ static unsigned long ima_ahash_minsize; @@ -777,15 +778,6 @@ int ima_calc_buffer_hash(const void *buf, loff_t len, return calc_buffer_shash(buf, len, hash); }
-static void ima_pcrread(u32 idx, struct tpm_digest *d) -{ - if (!ima_tpm_chip) - return; - - if (tpm_pcr_read(ima_tpm_chip, idx, d) != 0) - pr_err("Error Communicating to TPM chip\n"); -} - /* * The boot_aggregate is a cumulative hash over TPM registers 0 - 7. With * TPM 1.2 the boot_aggregate was based on reading the SHA1 PCRs, but with diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c index 80de396e8c07..603cf9f9dddc 100644 --- a/security/integrity/ima/ima_init.c +++ b/security/integrity/ima/ima_init.c @@ -23,7 +23,6 @@
/* name for boot aggregate entry */ const char boot_aggregate_name[] = "boot_aggregate"; -struct tpm_chip *ima_tpm_chip; struct ima_rot *ima_rot_inst;
/* Add the boot aggregate to the IMA measurement list and extend diff --git a/security/integrity/ima/ima_queue.c b/security/integrity/ima/ima_queue.c index 06653c3f3417..b7999b448c59 100644 --- a/security/integrity/ima/ima_queue.c +++ b/security/integrity/ima/ima_queue.c @@ -19,6 +19,7 @@ #include <linux/slab.h> #include "ima.h" #include "ima_cvm.h" +#include "ima_tpm.h"
#define AUDIT_CAUSE_LEN_MAX 32
@@ -136,19 +137,6 @@ unsigned long ima_get_binary_runtime_size(void) return binary_runtime_size + sizeof(struct ima_kexec_hdr); }
-static int ima_pcr_extend(struct tpm_digest *digests_arg, int pcr) -{ - int result = 0; - - if (!ima_tpm_chip) - return result; - - result = tpm_pcr_extend(ima_tpm_chip, pcr, digests_arg); - if (result != 0) - pr_err("Error Communicating to TPM chip, result: %d\n", result); - return result; -} - /* * Add template entry to the measurement list and hash table, and * extend the pcr. diff --git a/security/integrity/ima/ima_rot.c b/security/integrity/ima/ima_rot.c index bff7b57cf10d..ca48c8a02390 100644 --- a/security/integrity/ima/ima_rot.c +++ b/security/integrity/ima/ima_rot.c @@ -14,6 +14,7 @@ #include <linux/gfp_types.h>
#include "ima.h" +#include "ima_tpm.h"
static const char *name_rot_prefered;
@@ -24,6 +25,14 @@ static const char *name_rot_prefered; * IOW, RoT device that owns higher priority should be placed at the front. */ static struct ima_rot ima_rots[] = { +#ifdef CONFIG_TCG_TPM + { + .name = "tpm", + .init = ima_tpm_init, + .extend = ima_tpm_extend, + .calc_boot_aggregate = ima_tpm_calc_boot_aggregate, + }, +#endif };
static int __init ima_rot_name(char *str) diff --git a/security/integrity/ima/ima_tpm.c b/security/integrity/ima/ima_tpm.c new file mode 100644 index 000000000000..3a0aeb76139b --- /dev/null +++ b/security/integrity/ima/ima_tpm.c @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2024 Huawei Technologies Co., Ltd. + * + * Authors: + * GONG Ruiqi gongruiqi1@huawei.com + * + * File: ima_rot_tpm.c + * TPM implementation of IMA RoT + */ + +#include <linux/tpm.h> +#include <linux/module.h> + +#include "ima.h" + +struct tpm_chip *ima_tpm_chip; + +void ima_pcrread(u32 idx, struct tpm_digest *d) +{ + if (!ima_tpm_chip) + return; + + if (tpm_pcr_read(ima_tpm_chip, idx, d) != 0) + pr_err("Error Communicating to TPM chip\n"); +} + +int ima_pcr_extend(struct tpm_digest *digests_arg, int pcr) +{ + int result = 0; + + if (!ima_tpm_chip) + return result; + + result = tpm_pcr_extend(ima_tpm_chip, pcr, digests_arg); + if (result != 0) + pr_err("Error Communicating to TPM chip, result: %d\n", result); + return result; +} + +int ima_tpm_init(struct ima_rot *rot) +{ + ima_tpm_chip = tpm_default_chip(); + if (!ima_tpm_chip) + return -ENODEV; + + rot->nr_allocated_banks = ima_tpm_chip->nr_allocated_banks; + rot->allocated_banks = ima_tpm_chip->allocated_banks; + + return 0; +} + +int ima_tpm_extend(struct tpm_digest *digests_arg, const void *args) +{ + const int pcr = *(const int *)args; + + return ima_pcr_extend(digests_arg, pcr); +} + +int ima_tpm_calc_boot_aggregate(struct ima_digest_data *hash) +{ + return ima_calc_boot_aggregate(hash); +} diff --git a/security/integrity/ima/ima_tpm.h b/security/integrity/ima/ima_tpm.h new file mode 100644 index 000000000000..c142eb6d756d --- /dev/null +++ b/security/integrity/ima/ima_tpm.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2024 Huawei Technologies Co., Ltd. + * + * Authors: + * GONG Ruiqi gongruiqi1@huawei.com + * + * File: ima_tpm.h + * Hooks of TPM for IMA RoT + */ + +#ifndef __LINUX_IMA_IMA_TPM_H +#define __LINUX_IMA_IMA_TPM_H + +int ima_tpm_init(struct ima_rot *rot); +int ima_tpm_extend(struct tpm_digest *digests_arg, const void *args); +int ima_tpm_calc_boot_aggregate(struct ima_digest_data *hash); + +void ima_pcrread(u32 idx, struct tpm_digest *d); +int ima_pcr_extend(struct tpm_digest *digests_arg, int pcr); + +#endif /* __LINUX_IMA_IMA_TPM_H */