This patch set introduces IMA's Root of Trust (RoT), which is to support new RoT implementations such as Intel TDX and VirtCCA, as well as the classic TPM.
Reference for Intel TDX with IMA: https://www.intel.cn/content/www/cn/zh/developer/articles/community/runtime-...
Reference for VirtCCA: https://gitee.com/openeuler/kernel/blob/OLK-6.6/Documentation/virtcca/virtcc...
GONG Ruiqi (5): ima: rot: Introduce basic framework ima: rot: Prepare TPM as an RoT ima: rot: Make RoT kick in ima: Rename ima_cvm to ima_virtcca ima: rot: Adapt VirtCCA into Rot
security/integrity/ima/Makefile | 5 +- security/integrity/ima/ima.h | 5 +- security/integrity/ima/ima_api.c | 2 +- security/integrity/ima/ima_crypto.c | 48 +++++------- security/integrity/ima/ima_cvm.c | 77 ------------------ security/integrity/ima/ima_cvm.h | 36 --------- security/integrity/ima/ima_init.c | 31 ++------ security/integrity/ima/ima_queue.c | 51 ++++-------- security/integrity/ima/ima_rot.c | 86 ++++++++++++++++++++ security/integrity/ima/ima_rot.h | 28 +++++++ security/integrity/ima/ima_template.c | 2 +- security/integrity/ima/ima_template_lib.c | 2 +- security/integrity/ima/ima_tpm.c | 63 +++++++++++++++ security/integrity/ima/ima_tpm.h | 21 +++++ security/integrity/ima/ima_virtcca.c | 95 +++++++++++++++++++++++ security/integrity/ima/ima_virtcca.h | 13 ++++ 16 files changed, 355 insertions(+), 210 deletions(-) delete mode 100644 security/integrity/ima/ima_cvm.c delete mode 100644 security/integrity/ima/ima_cvm.h create mode 100644 security/integrity/ima/ima_rot.c create mode 100644 security/integrity/ima/ima_rot.h create mode 100644 security/integrity/ima/ima_tpm.c create mode 100644 security/integrity/ima/ima_tpm.h create mode 100644 security/integrity/ima/ima_virtcca.c create mode 100644 security/integrity/ima/ima_virtcca.h
反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://gitee.com/openeuler/kernel/pulls/13256 邮件列表地址:https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/S...
FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://gitee.com/openeuler/kernel/pulls/13256 Mailing list address: https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/S...
Each type of RoT devices should have a corresponding entry in ima_rots, a static array that represents entries' priority with their order. In case that `ima_rot=` is absent, the first device (which means with higher priority) that gets successfully initialized will be the RoT. Otherwise, the framework will only try to initialize the one specified by `ima_rot=`, and there will be no RoT if the initialization fails.
All necessary hooks and variables of the RoT entry should be set at least when .init() is finished.
Signed-off-by: GONG Ruiqi gongruiqi1@huawei.com --- security/integrity/ima/Makefile | 2 +- security/integrity/ima/ima.h | 2 + security/integrity/ima/ima_init.c | 1 + security/integrity/ima/ima_rot.c | 68 +++++++++++++++++++++++++++++++ security/integrity/ima/ima_rot.h | 28 +++++++++++++ 5 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 security/integrity/ima/ima_rot.c create mode 100644 security/integrity/ima/ima_rot.h
diff --git a/security/integrity/ima/Makefile b/security/integrity/ima/Makefile index d823ac70ddc2..2b6467ea3f24 100644 --- a/security/integrity/ima/Makefile +++ b/security/integrity/ima/Makefile @@ -7,7 +7,7 @@ obj-$(CONFIG_IMA) += ima.o
ima-y := ima_fs.o ima_queue.o ima_init.o ima_main.o ima_crypto.o ima_api.o \ - ima_policy.o ima_template.o ima_template_lib.o + ima_policy.o ima_template.o ima_template_lib.o ima_rot.o ima-$(CONFIG_IMA_APPRAISE) += ima_appraise.o ima-$(CONFIG_IMA_APPRAISE_MODSIG) += ima_modsig.o ima-$(CONFIG_HAVE_IMA_KEXEC) += ima_kexec.o diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index ceaae0e2c52a..80b4e13452a7 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h @@ -23,6 +23,7 @@ #include <crypto/hash_info.h>
#include "../integrity.h" +#include "ima_rot.h"
enum ima_show_type { IMA_SHOW_BINARY, IMA_SHOW_BINARY_NO_FIELD_LEN, IMA_SHOW_BINARY_OLD_STRING_FMT, IMA_SHOW_ASCII }; @@ -56,6 +57,7 @@ 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 extern int ima_digest_list_pcr; diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c index aa750942e422..80de396e8c07 100644 --- a/security/integrity/ima/ima_init.c +++ b/security/integrity/ima/ima_init.c @@ -24,6 +24,7 @@ /* 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 * the PCR register. diff --git a/security/integrity/ima/ima_rot.c b/security/integrity/ima/ima_rot.c new file mode 100644 index 000000000000..bff7b57cf10d --- /dev/null +++ b/security/integrity/ima/ima_rot.c @@ -0,0 +1,68 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2024 Huawei Technologies Co., Ltd. + * + * Authors: + * GONG Ruiqi gongruiqi1@huawei.com + * + * File: ima_rot.c + * IMA rot layer + */ + +#include <linux/types.h> +#include <linux/list.h> +#include <linux/gfp_types.h> + +#include "ima.h" + +static const char *name_rot_prefered; + +/* + * The list containing all possible RoT devices. + * + * The order of RoTs inside the list implies priority. + * IOW, RoT device that owns higher priority should be placed at the front. + */ +static struct ima_rot ima_rots[] = { +}; + +static int __init ima_rot_name(char *str) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(ima_rots); i++) { + if (!strcmp(str, ima_rots[i].name)) { + name_rot_prefered = str; + break; + } + } + + if (!name_rot_prefered) + pr_info("%s is NOT implemented as an IMA RoT\n", str); + + return 1; +} +__setup("ima_rot=", ima_rot_name); + +/* + * Pick the most prioritized RoT that can be initialized successfully. + */ +struct ima_rot * __init ima_rot_init(void) +{ + int rc, i; + + for (i = 0; i < ARRAY_SIZE(ima_rots); i++) { + if (name_rot_prefered && strcmp(name_rot_prefered, ima_rots[i].name)) + continue; + + pr_info("IMA RoT initializing %s\n", ima_rots[i].name); + rc = ima_rots[i].init(&ima_rots[i]); + if (!rc) { + pr_info("%s initialized and taken as IMA RoT\n", ima_rots[i].name); + return &ima_rots[i]; + } + pr_info("%s failed to self-initialize\n", ima_rots[i].name); + } + + return NULL; +} diff --git a/security/integrity/ima/ima_rot.h b/security/integrity/ima/ima_rot.h new file mode 100644 index 000000000000..ba6bec380ed4 --- /dev/null +++ b/security/integrity/ima/ima_rot.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2024 Huawei Technologies Co., Ltd. + * + * Authors: + * GONG Ruiqi gongruiqi1@huawei.com + * + * File: ima_rot.h + * IMA rot layer + */ + +#ifndef __LINUX_IMA_ROT_H +#define __LINUX_IMA_ROT_H + +#include <linux/tpm.h> + +struct ima_rot { + const char *name; + int nr_allocated_banks; + struct tpm_bank_info *allocated_banks; + + int (*init)(struct ima_rot *rot); + int (*extend)(struct tpm_digest *digests_arg, const void *args); + int (*calc_boot_aggregate)(struct ima_digest_data *hash); +}; + +struct ima_rot *ima_rot_init(void); +#endif /* __LINUX_IMA_ROT_H */
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 */
Now the RoT framework starts working, by replacing ima_tpm_chip and those relavant function calls to their RoT counterparts.
Signed-off-by: GONG Ruiqi gongruiqi1@huawei.com --- security/integrity/ima/ima.h | 3 +- security/integrity/ima/ima_api.c | 2 +- security/integrity/ima/ima_crypto.c | 38 ++++++++++----------- security/integrity/ima/ima_init.c | 12 +++---- security/integrity/ima/ima_queue.c | 41 ++++++++++++----------- security/integrity/ima/ima_template.c | 2 +- security/integrity/ima/ima_template_lib.c | 2 +- security/integrity/ima/ima_tpm.c | 4 +-- security/integrity/ima/ima_tpm.h | 1 - 9 files changed, 52 insertions(+), 53 deletions(-)
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index 80b4e13452a7..d33992a8824f 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h @@ -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 diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c index f8b329aeb5d6..16ef07622010 100644 --- a/security/integrity/ima/ima_api.c +++ b/security/integrity/ima/ima_api.c @@ -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); diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c index c1bddc0bb7d5..39f17d4ffc8f 100644 --- a/security/integrity/ima/ima_crypto.c +++ b/security/integrity/ima/ima_crypto.c @@ -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); diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c index 603cf9f9dddc..acf9074caf84 100644 --- a/security/integrity/ima/ima_init.c +++ b/security/integrity/ima/ima_init.c @@ -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) diff --git a/security/integrity/ima/ima_queue.c b/security/integrity/ima/ima_queue.c index b7999b448c59..6f2d62deb1f1 100644 --- a/security/integrity/ima/ima_queue.c +++ b/security/integrity/ima/ima_queue.c @@ -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,21 +176,23 @@ 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; - audit_info = 0; + 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); @@ -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) diff --git a/security/integrity/ima/ima_template.c b/security/integrity/ima/ima_template.c index 04c49f05cb74..a6ece3557267 100644 --- a/security/integrity/ima/ima_template.c +++ b/security/integrity/ima/ima_template.c @@ -367,7 +367,7 @@ static int ima_restore_template_data(struct ima_template_desc *template_desc, 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); diff --git a/security/integrity/ima/ima_template_lib.c b/security/integrity/ima/ima_template_lib.c index 3b2cb8f1002e..4bcc77c092b6 100644 --- a/security/integrity/ima/ima_template_lib.c +++ b/security/integrity/ima/ima_template_lib.c @@ -356,7 +356,7 @@ int ima_eventdigest_init(struct ima_event_data *event_data, }
if ((const char *)event_data->filename == boot_aggregate_name) { - if (ima_tpm_chip) { + if (ima_rot_inst) { hash.hdr.algo = HASH_ALGO_SHA1; result = ima_calc_boot_aggregate(&hash.hdr);
diff --git a/security/integrity/ima/ima_tpm.c b/security/integrity/ima/ima_tpm.c index 3a0aeb76139b..5c3dea3e0719 100644 --- a/security/integrity/ima/ima_tpm.c +++ b/security/integrity/ima/ima_tpm.c @@ -14,7 +14,7 @@
#include "ima.h"
-struct tpm_chip *ima_tpm_chip; +static struct tpm_chip *ima_tpm_chip;
void ima_pcrread(u32 idx, struct tpm_digest *d) { @@ -25,7 +25,7 @@ void ima_pcrread(u32 idx, struct tpm_digest *d) pr_err("Error Communicating to TPM chip\n"); }
-int ima_pcr_extend(struct tpm_digest *digests_arg, int pcr) +static int ima_pcr_extend(struct tpm_digest *digests_arg, int pcr) { int result = 0;
diff --git a/security/integrity/ima/ima_tpm.h b/security/integrity/ima/ima_tpm.h index c142eb6d756d..b93018ab5438 100644 --- a/security/integrity/ima/ima_tpm.h +++ b/security/integrity/ima/ima_tpm.h @@ -17,6 +17,5 @@ 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 */
VirtCCA is the name of device that IMA works with, while CVM, standing for Confidential Virtual Machine, is what IMA will achieve, together with VirtCCA as well as other components. So naming those file/function with ima_virtcca makes more sense.
Co-developed-by: Lu Huaxin luhuaxin1@huawei.com Signed-off-by: Lu Huaxin luhuaxin1@huawei.com Signed-off-by: GONG Ruiqi gongruiqi1@huawei.com --- security/integrity/ima/Makefile | 2 +- security/integrity/ima/ima_cvm.h | 36 ------------------- security/integrity/ima/ima_init.c | 8 ++--- security/integrity/ima/ima_queue.c | 4 +-- .../ima/{ima_cvm.c => ima_virtcca.c} | 10 +++--- security/integrity/ima/ima_virtcca.h | 36 +++++++++++++++++++ 6 files changed, 48 insertions(+), 48 deletions(-) delete mode 100644 security/integrity/ima/ima_cvm.h rename security/integrity/ima/{ima_cvm.c => ima_virtcca.c} (87%) create mode 100644 security/integrity/ima/ima_virtcca.h
diff --git a/security/integrity/ima/Makefile b/security/integrity/ima/Makefile index d9f2030d8b90..9f683951cb4c 100644 --- a/security/integrity/ima/Makefile +++ b/security/integrity/ima/Makefile @@ -21,4 +21,4 @@ ifeq ($(CONFIG_EFI),y) ima-$(CONFIG_IMA_SECURE_AND_OR_TRUSTED_BOOT) += ima_efi.o endif
-ima-$(CONFIG_HISI_VIRTCCA_GUEST) += ima_cvm.o +ima-$(CONFIG_HISI_VIRTCCA_GUEST) += ima_virtcca.o diff --git a/security/integrity/ima/ima_cvm.h b/security/integrity/ima/ima_cvm.h deleted file mode 100644 index 864243bd0844..000000000000 --- a/security/integrity/ima/ima_cvm.h +++ /dev/null @@ -1,36 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright (C) 2024. Huawei Technologies Co., Ltd. All rights reserved. - */ -#ifndef __LINUX_IMA_CVM_H -#define __LINUX_IMA_CVM_H - -#include "ima.h" - -#ifdef CONFIG_HISI_VIRTCCA_GUEST -int __init ima_cvm_init(void); -bool ima_cvm_available(void); -int ima_cvm_extend(struct tpm_digest *digests_arg); -int ima_calc_cvm_boot_aggregate(struct ima_digest_data *hash); -#else -static inline int __init ima_cvm_init(void) -{ - return -ENODEV; -} - -static inline bool ima_cvm_available(void) -{ - return false; -} - -static inline int ima_cvm_extend(struct tpm_digest *digests_arg) -{ - return -ENODEV; -} - -static inline int ima_calc_cvm_boot_aggregate(struct ima_digest_data *hash) -{ - return -ENODEV; -} -#endif -#endif diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c index acf9074caf84..8889d42448da 100644 --- a/security/integrity/ima/ima_init.c +++ b/security/integrity/ima/ima_init.c @@ -19,7 +19,7 @@ #include <generated/utsrelease.h>
#include "ima.h" -#include "ima_cvm.h" +#include "ima_virtcca.h"
/* name for boot aggregate entry */ const char boot_aggregate_name[] = "boot_aggregate"; @@ -59,8 +59,8 @@ static int __init ima_add_boot_aggregate(void) iint->ima_hash->length = hash_digest_size[ima_hash_algo];
#ifdef CONFIG_HISI_VIRTCCA_GUEST - if (ima_cvm_available()) { - result = ima_calc_cvm_boot_aggregate(&hash.hdr); + if (ima_virtcca_available()) { + result = ima_calc_virtcca_boot_aggregate(&hash.hdr); if (result < 0) { audit_cause = "hashing_error"; goto err_out; @@ -133,7 +133,7 @@ int __init ima_init(void) int rc;
#ifdef CONFIG_HISI_VIRTCCA_GUEST - rc = ima_cvm_init(); + rc = ima_virtcca_init(); if (rc) { pr_info("No CVM found, activating CVM-bypass!\n"); ima_rot_inst = ima_rot_init(); diff --git a/security/integrity/ima/ima_queue.c b/security/integrity/ima/ima_queue.c index 6f2d62deb1f1..fba549d2d0d8 100644 --- a/security/integrity/ima/ima_queue.c +++ b/security/integrity/ima/ima_queue.c @@ -18,7 +18,7 @@ #include <linux/rculist.h> #include <linux/slab.h> #include "ima.h" -#include "ima_cvm.h" +#include "ima_virtcca.h"
#define AUDIT_CAUSE_LEN_MAX 32
@@ -176,7 +176,7 @@ int ima_add_template_entry(struct ima_template_entry *entry, int violation, digests_arg = digests;
#ifdef CONFIG_HISI_VIRTCCA_GUEST - rotresult = ima_cvm_extend(digests_arg); + rotresult = ima_virtcca_extend(digests_arg); if (rotresult != 0) { snprintf(rot_audit_cause, AUDIT_CAUSE_LEN_MAX, "TSI_error(%d)", rotresult); diff --git a/security/integrity/ima/ima_cvm.c b/security/integrity/ima/ima_virtcca.c similarity index 87% rename from security/integrity/ima/ima_cvm.c rename to security/integrity/ima/ima_virtcca.c index 0fe3c0da63b2..318c547b0d59 100644 --- a/security/integrity/ima/ima_cvm.c +++ b/security/integrity/ima/ima_virtcca.c @@ -4,16 +4,16 @@ */ #include <asm/virtcca_cvm_smc.h> #include <asm/virtcca_cvm_guest.h> -#include "ima_cvm.h" +#include "ima_virtcca.h"
static bool ima_tsi_cvm;
-bool ima_cvm_available(void) +bool ima_virtcca_available(void) { return ima_tsi_cvm; }
-int __init ima_cvm_init(void) +int __init ima_virtcca_init(void) { int rc = -ENODEV;
@@ -25,7 +25,7 @@ int __init ima_cvm_init(void) return rc; }
-int ima_calc_cvm_boot_aggregate(struct ima_digest_data *hash) +int ima_calc_virtcca_boot_aggregate(struct ima_digest_data *hash) { unsigned long result; int hash_len; @@ -56,7 +56,7 @@ int ima_calc_cvm_boot_aggregate(struct ima_digest_data *hash) return 0; }
-int ima_cvm_extend(struct tpm_digest *digests_arg) +int ima_virtcca_extend(struct tpm_digest *digests_arg) { struct virtcca_cvm_measurement_extend cme;
diff --git a/security/integrity/ima/ima_virtcca.h b/security/integrity/ima/ima_virtcca.h new file mode 100644 index 000000000000..8e00c9b6a996 --- /dev/null +++ b/security/integrity/ima/ima_virtcca.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2024. Huawei Technologies Co., Ltd. All rights reserved. + */ +#ifndef __LINUX_IMA_VIRTCCA_H +#define __LINUX_IMA_VIRTCCA_H + +#include "ima.h" + +#ifdef CONFIG_HISI_VIRTCCA_GUEST +int __init ima_virtcca_init(void); +bool ima_virtcca_available(void); +int ima_virtcca_extend(struct tpm_digest *digests_arg); +int ima_calc_virtcca_boot_aggregate(struct ima_digest_data *hash); +#else +static inline int __init ima_virtcca_init(void) +{ + return -ENODEV; +} + +static inline bool ima_virtcca_available(void) +{ + return false; +} + +static inline int ima_virtcca_extend(struct tpm_digest *digests_arg) +{ + return -ENODEV; +} + +static inline int ima_calc_virtcca_boot_aggregate(struct ima_digest_data *hash) +{ + return -ENODEV; +} +#endif +#endif
VirtCCA is now fit into the RoT framework, with a lower priority against TPM, which means that the framework will always try to initialize and use TPM first. Nevertheless, users can select VirtCCA to be the IMA RoT with `ima_rot=virtcca` cmdline.
Co-developed-by: Lu Huaxin luhuaxin1@huawei.com Signed-off-by: Lu Huaxin luhuaxin1@huawei.com Signed-off-by: GONG Ruiqi gongruiqi1@huawei.com --- security/integrity/ima/ima_init.c | 19 ------- security/integrity/ima/ima_queue.c | 20 ++----- security/integrity/ima/ima_rot.c | 9 ++++ security/integrity/ima/ima_virtcca.c | 80 +++++++++++++++++----------- security/integrity/ima/ima_virtcca.h | 27 +--------- 5 files changed, 64 insertions(+), 91 deletions(-)
diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c index 8889d42448da..8909b358fcde 100644 --- a/security/integrity/ima/ima_init.c +++ b/security/integrity/ima/ima_init.c @@ -19,7 +19,6 @@ #include <generated/utsrelease.h>
#include "ima.h" -#include "ima_virtcca.h"
/* name for boot aggregate entry */ const char boot_aggregate_name[] = "boot_aggregate"; @@ -58,16 +57,6 @@ static int __init ima_add_boot_aggregate(void) iint->ima_hash->algo = ima_hash_algo; iint->ima_hash->length = hash_digest_size[ima_hash_algo];
-#ifdef CONFIG_HISI_VIRTCCA_GUEST - if (ima_virtcca_available()) { - result = ima_calc_virtcca_boot_aggregate(&hash.hdr); - if (result < 0) { - audit_cause = "hashing_error"; - goto err_out; - } - } -#endif - /* * With TPM 2.0 hash agility, TPM chips could support multiple TPM * PCR banks, allowing firmware to configure and enable different @@ -132,15 +121,7 @@ int __init ima_init(void) { int rc;
-#ifdef CONFIG_HISI_VIRTCCA_GUEST - rc = ima_virtcca_init(); - if (rc) { - pr_info("No CVM found, activating CVM-bypass!\n"); - ima_rot_inst = ima_rot_init(); - } -#else ima_rot_inst = ima_rot_init(); -#endif if (!ima_rot_inst) pr_info("No RoT found, activating RoT-bypass!\n");
diff --git a/security/integrity/ima/ima_queue.c b/security/integrity/ima/ima_queue.c index fba549d2d0d8..296ad15fd520 100644 --- a/security/integrity/ima/ima_queue.c +++ b/security/integrity/ima/ima_queue.c @@ -18,7 +18,6 @@ #include <linux/rculist.h> #include <linux/slab.h> #include "ima.h" -#include "ima_virtcca.h"
#define AUDIT_CAUSE_LEN_MAX 32
@@ -175,25 +174,14 @@ int ima_add_template_entry(struct ima_template_entry *entry, int violation, if (violation) /* invalidate pcr */ digests_arg = digests;
-#ifdef CONFIG_HISI_VIRTCCA_GUEST - rotresult = ima_virtcca_extend(digests_arg); + if (ima_rot_inst) + rotresult = ima_rot_inst->extend(digests_arg, &entry->pcr); if (rotresult != 0) { - snprintf(rot_audit_cause, AUDIT_CAUSE_LEN_MAX, "TSI_error(%d)", - rotresult); + snprintf(rot_audit_cause, AUDIT_CAUSE_LEN_MAX, "%s_error(%d)", + ima_rot_inst->name, rotresult); audit_cause = rot_audit_cause; audit_info = 0; } -#endif - - 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, diff --git a/security/integrity/ima/ima_rot.c b/security/integrity/ima/ima_rot.c index ca48c8a02390..45d2ea314790 100644 --- a/security/integrity/ima/ima_rot.c +++ b/security/integrity/ima/ima_rot.c @@ -15,6 +15,7 @@
#include "ima.h" #include "ima_tpm.h" +#include "ima_virtcca.h"
static const char *name_rot_prefered;
@@ -33,6 +34,14 @@ static struct ima_rot ima_rots[] = { .calc_boot_aggregate = ima_tpm_calc_boot_aggregate, }, #endif +#ifdef CONFIG_HISI_VIRTCCA_GUEST + { + .name = "virtcca", + .init = ima_virtcca_init, + .extend = ima_virtcca_extend, + .calc_boot_aggregate = ima_calc_virtcca_boot_aggregate, + }, +#endif };
static int __init ima_rot_name(char *str) diff --git a/security/integrity/ima/ima_virtcca.c b/security/integrity/ima/ima_virtcca.c index 318c547b0d59..15f7338564b3 100644 --- a/security/integrity/ima/ima_virtcca.c +++ b/security/integrity/ima/ima_virtcca.c @@ -4,43 +4,65 @@ */ #include <asm/virtcca_cvm_smc.h> #include <asm/virtcca_cvm_guest.h> -#include "ima_virtcca.h" +#include "ima.h"
-static bool ima_tsi_cvm; +#define CVM_IMA_SLOT_IDX 1
-bool ima_virtcca_available(void) +static enum hash_algo virtcca_algo; + +static int ima_virtcca_init_algo(void) { - return ima_tsi_cvm; + unsigned long result; + struct virtcca_cvm_config cfg = { 0 }; + + result = tsi_get_cvm_config(&cfg); + if (result != TSI_SUCCESS) { + pr_info("Error reading cvm config\n"); + return -EFAULT; + } + + /* 0: SHA256, 1: SHA512 */ + virtcca_algo = cfg.algorithm ? HASH_ALGO_SHA512 : HASH_ALGO_SHA256; + + return 0; }
-int __init ima_virtcca_init(void) +int ima_virtcca_init(struct ima_rot *rot) { - int rc = -ENODEV; + int rc; + + if (!is_virtcca_cvm_world() || tsi_get_version() == SMCCC_RET_NOT_SUPPORTED) + return -ENODEV;
- if (is_virtcca_cvm_world() && tsi_get_version() != SMCCC_RET_NOT_SUPPORTED) { - ima_tsi_cvm = true; - rc = 0; + rc = ima_virtcca_init_algo(); + if (rc) + return rc; + + if (virtcca_algo != ima_hash_algo) { + pr_info("VirtCCA's algo (%s) is different from ima_hash_algo (%s)\n", + hash_algo_name[virtcca_algo], hash_algo_name[ima_hash_algo]); + + rot->allocated_banks = kcalloc(1, sizeof(*rot->allocated_banks), GFP_KERNEL); + if (!rot->allocated_banks) + return -ENOMEM; + + rot->nr_allocated_banks = 1; + rot->allocated_banks[0].alg_id = (virtcca_algo == HASH_ALGO_SHA512) ? + TPM_ALG_SHA512 : TPM_ALG_SHA256; + rot->allocated_banks[0].digest_size = hash_digest_size[virtcca_algo]; + rot->allocated_banks[0].crypto_id = virtcca_algo; }
- return rc; + return 0; }
int ima_calc_virtcca_boot_aggregate(struct ima_digest_data *hash) { unsigned long result; - int hash_len; - struct virtcca_cvm_config cfg = { 0 }; struct virtcca_cvm_measurement cm = { 0 };
- result = tsi_get_cvm_config(&cfg); - if (result != TSI_SUCCESS) { - pr_err("Error reading cvm config for boot aggregate\n"); - return -EFAULT; - } - - /* 0: SHA256, 1: SHA512 */ - hash->algo = cfg.algorithm ? HASH_ALGO_SHA512 : HASH_ALGO_SHA256; - hash_len = hash_digest_size[hash->algo]; + hash->algo = virtcca_algo; + hash->length = hash_digest_size[virtcca_algo];
/* Read the measurement result of RIM as the boot aggregate */ cm.index = RIM_MEASUREMENT_SLOT; @@ -51,25 +73,21 @@ int ima_calc_virtcca_boot_aggregate(struct ima_digest_data *hash) return -EFAULT; }
- memcpy(hash->digest, cm.value, hash_len); + memcpy(hash->digest, cm.value, hash->length);
return 0; }
-int ima_virtcca_extend(struct tpm_digest *digests_arg) +int ima_virtcca_extend(struct tpm_digest *digests_arg, const void *args) { struct virtcca_cvm_measurement_extend cme; + int algo_idx = (virtcca_algo != ima_hash_algo) ? 0 : ima_hash_algo_idx;
- if (!ima_tsi_cvm) - return 0; - - /* Use index 1 as CVM IMA slot */ - cme.index = 1; - cme.size = hash_digest_size[ima_hash_algo]; + cme.index = CVM_IMA_SLOT_IDX; + cme.size = hash_digest_size[virtcca_algo];
if (digests_arg) - memcpy(cme.value, digests_arg[ima_hash_algo_idx].digest, - cme.size); + memcpy(cme.value, digests_arg[algo_idx].digest, cme.size); else memset(cme.value, 0xff, cme.size);
diff --git a/security/integrity/ima/ima_virtcca.h b/security/integrity/ima/ima_virtcca.h index 8e00c9b6a996..cffb9bdf3013 100644 --- a/security/integrity/ima/ima_virtcca.h +++ b/security/integrity/ima/ima_virtcca.h @@ -7,30 +7,7 @@
#include "ima.h"
-#ifdef CONFIG_HISI_VIRTCCA_GUEST -int __init ima_virtcca_init(void); -bool ima_virtcca_available(void); -int ima_virtcca_extend(struct tpm_digest *digests_arg); +int ima_virtcca_init(struct ima_rot *rot); int ima_calc_virtcca_boot_aggregate(struct ima_digest_data *hash); -#else -static inline int __init ima_virtcca_init(void) -{ - return -ENODEV; -} - -static inline bool ima_virtcca_available(void) -{ - return false; -} - -static inline int ima_virtcca_extend(struct tpm_digest *digests_arg) -{ - return -ENODEV; -} - -static inline int ima_calc_virtcca_boot_aggregate(struct ima_digest_data *hash) -{ - return -ENODEV; -} -#endif +int ima_virtcca_extend(struct tpm_digest *digests_arg, const void *args); #endif