From d3ebfcbc2308c899688f175d540274730ed78b20 Mon Sep 17 00:00:00 2001 From: xuce Date: Wed, 17 Dec 2025 17:34:03 +0800 Subject: [PATCH] backport some patches --- 0001-Support-virtcca.patch | 799 ++++++++++++++++++ 0001-fix-some-build-errors.patch | 26 + ...pport-kernels-with-different-compila.patch | 458 ++++++++++ 0003-Support-remote-attestation.patch | 228 +++++ 0004-Support-measure-only-mode.patch | 204 +++++ 0005-Support-in-tree-kernel-compilation.patch | 222 +++++ 0006-Support-TPM-boot-aggregate.patch | 117 +++ 0007-Clean-code-and-bugfix.patch | 580 +++++++++++++ 0008-Support-kernel-boot-parameter.patch | 87 ++ ...check-pcr-value-when-init-RoT-device.patch | 35 + ...igurations-related-to-kernel-modules.patch | 80 ++ ...-pre-allocated-pages-in-error-branch.patch | 25 + ...length-to-SHA1-in-binary-measure-log.patch | 33 + 0013-Add-missing-header.patch | 25 + dim.spec | 19 +- 15 files changed, 2937 insertions(+), 1 deletion(-) create mode 100644 0001-Support-virtcca.patch create mode 100644 0001-fix-some-build-errors.patch create mode 100644 0002-Add-macros-to-support-kernels-with-different-compila.patch create mode 100644 0003-Support-remote-attestation.patch create mode 100644 0004-Support-measure-only-mode.patch create mode 100644 0005-Support-in-tree-kernel-compilation.patch create mode 100644 0006-Support-TPM-boot-aggregate.patch create mode 100644 0007-Clean-code-and-bugfix.patch create mode 100644 0008-Support-kernel-boot-parameter.patch create mode 100644 0009-Dont-check-pcr-value-when-init-RoT-device.patch create mode 100644 0010-Optimize-configurations-related-to-kernel-modules.patch create mode 100644 0011-Free-pre-allocated-pages-in-error-branch.patch create mode 100644 0012-Set-the-digest-length-to-SHA1-in-binary-measure-log.patch create mode 100644 0013-Add-missing-header.patch diff --git a/0001-Support-virtcca.patch b/0001-Support-virtcca.patch new file mode 100644 index 0000000..bb59cc1 --- /dev/null +++ b/0001-Support-virtcca.patch @@ -0,0 +1,799 @@ +From 25d3b342c05669a748a26f8951a1aa1e3de0d6da Mon Sep 17 00:00:00 2001 +From: Ce Xu +Date: Wed, 26 Nov 2025 14:17:37 +0800 +Subject: [PATCH 01/13] Support virtcca + +1. Add the RoT (Root of Trust) layer for enable different devices; +2. Add support for virtCCA. + +Signed-off-by: Huaxin Lu +--- + src/Makefile | 8 ++- + src/common/dim_measure_log.c | 37 +++++----- + src/common/dim_measure_log.h | 6 +- + src/common/dim_rot.c | 92 +++++++++++++++++++++++++ + src/common/dim_rot.h | 32 +++++++++ + src/common/dim_rot_tpm.c | 119 +++++++++++++++++++++++++++++++++ + src/common/dim_rot_virtcca.c | 111 ++++++++++++++++++++++++++++++ + src/common/dim_tpm.c | 79 ---------------------- + src/common/dim_tpm.h | 23 ------- + src/core/dim_core_main.c | 3 + + src/measure/dim_measure.c | 22 ++---- + src/measure/dim_measure.h | 6 +- + src/monitor/dim_monitor_main.c | 3 + + 13 files changed, 397 insertions(+), 144 deletions(-) + create mode 100644 src/common/dim_rot.c + create mode 100644 src/common/dim_rot.h + create mode 100644 src/common/dim_rot_tpm.c + create mode 100644 src/common/dim_rot_virtcca.c + delete mode 100644 src/common/dim_tpm.c + delete mode 100644 src/common/dim_tpm.h + +diff --git a/src/Makefile b/src/Makefile +index 6782fd1..df4c729 100644 +--- a/src/Makefile ++++ b/src/Makefile +@@ -32,7 +32,9 @@ dim_core-objs += common/dim_utils.o + dim_core-objs += common/dim_baseline.o + dim_core-objs += common/dim_hash.o + dim_core-objs += common/dim_measure_log.o +-dim_core-objs += common/dim_tpm.o ++dim_core-objs += common/dim_rot.o ++dim_core-objs += common/dim_rot_tpm.o ++dim_core-objs += common/dim_rot_virtcca.o + dim_core-objs += common/dim_symbol.o + dim_core-objs += common/dim_safe_func.o + dim_core-objs += measure/dim_measure.o +@@ -54,7 +56,9 @@ dim_monitor-objs += common/dim_hash.o + dim_monitor-objs += common/dim_utils.o + dim_monitor-objs += common/dim_measure_log.o + dim_monitor-objs += common/dim_baseline.o +-dim_monitor-objs += common/dim_tpm.o ++dim_monitor-objs += common/dim_rot.o ++dim_monitor-objs += common/dim_rot_tpm.o ++dim_monitor-objs += common/dim_rot_virtcca.o + dim_monitor-objs += common/dim_symbol.o + dim_monitor-objs += common/dim_safe_func.o + dim_monitor-objs += measure/dim_measure.o +diff --git a/src/common/dim_measure_log.c b/src/common/dim_measure_log.c +index 59654a5..3fa32f2 100644 +--- a/src/common/dim_measure_log.c ++++ b/src/common/dim_measure_log.c +@@ -5,7 +5,7 @@ + #include + + #include "dim_rb.h" +-#include "dim_tpm.h" ++#include "dim_rot.h" + #include "dim_safe_func.h" + #include "dim_measure_log.h" + +@@ -69,7 +69,7 @@ int dim_measure_log_seq_show(struct seq_file *m, struct dim_measure_log *info) + dim_digest_size(info->digest.algo)); + + seq_printf(m, "%d %s %s:%s %s %s\n", +- info->pcr, ++ dim_rot_slot(), + log_digest_buf, + dim_hash_name(info->digest.algo), + digest_buf, +@@ -143,8 +143,8 @@ static int measure_log_create_name(const char *name_str, + return 0; + } + +-static int measure_log_create_info(char pcr, struct dim_digest *digest, +- int flag, struct dim_measure_log **info) ++static int measure_log_create_info(struct dim_digest *digest, int flag, ++ struct dim_measure_log **info) + { + int ret = 0; + struct dim_measure_log *new = NULL; +@@ -153,7 +153,6 @@ static int measure_log_create_info(char pcr, struct dim_digest *digest, + if (new == NULL) + return -ENOMEM; + +- new->pcr = pcr; + new->type = flag; + ret = dim_digest_copy(&new->digest, digest); + if (ret < 0) { +@@ -204,9 +203,7 @@ static int measure_log_add_info(struct dim_measure_log_tree *root, + root->count++; + write_unlock(&root->lock); + +- return root->tpm == NULL && root->pcr != 0 ? 0 : +- dim_tpm_pcr_extend(root->tpm, root->pcr, +- &info->log_digest); ++ return dim_rot_extend(&info->log_digest); + } + + static bool measure_log_is_full(struct dim_measure_log_tree *root) +@@ -233,7 +230,7 @@ int dim_measure_log_add(struct dim_measure_log_tree *root, + if (measure_log_is_full(root)) + return -ENOSPC; + +- ret = measure_log_create_info(root->pcr, digest, flag, &info); ++ ret = measure_log_create_info(digest, flag, &info); + if (ret < 0) + return ret; + +@@ -272,11 +269,11 @@ void dim_measure_log_destroy_tree(struct dim_measure_log_tree *root) + } + + int dim_measure_log_init_tree(struct dim_measure_log_tree *root, +- struct dim_hash *hash, +- struct dim_tpm *tpm, +- unsigned int cap, +- unsigned int pcr) ++ struct dim_hash *hash, unsigned int cap) + { ++ int ret = 0; ++ struct dim_digest boot_aggregate = { 0 }; ++ + if (root == NULL || hash == NULL) + return -EINVAL; + +@@ -284,8 +281,16 @@ int dim_measure_log_init_tree(struct dim_measure_log_tree *root, + INIT_LIST_HEAD(&root->list_root); + root->hash = hash; + root->rb_root = RB_ROOT; +- root->pcr = pcr; +- root->tpm = tpm; + root->cap = cap; +- return 0; ++ boot_aggregate.algo = hash->algo; ++ ++ ret = dim_calc_boot_aggregate(&boot_aggregate); ++ if (ret < 0) ++ dim_warn("Failed to calculate boot_aggregate\n"); ++ ++ ret = dim_measure_log_add(root, "boot_aggregate", &boot_aggregate, LOG_STATIC_BASELINE); ++ if (ret < 0) ++ dim_err("Failed to add boot_aggregate\n"); ++ ++ return ret; + } +diff --git a/src/common/dim_measure_log.h b/src/common/dim_measure_log.h +index 125de30..ada7d97 100644 +--- a/src/common/dim_measure_log.h ++++ b/src/common/dim_measure_log.h +@@ -36,8 +36,6 @@ struct dim_measure_log_tree { + struct rb_root rb_root; /* rb tree root for searching measure log */ + struct list_head list_root; /* list root for printing logs in order */ + struct dim_hash *hash; /* algorithm for calculating log hash */ +- struct dim_tpm *tpm; +- unsigned int pcr; + rwlock_t lock; + unsigned int count; /* number of log */ + unsigned int cap; /* capacity of log */ +@@ -54,7 +52,6 @@ struct dim_measure_log { + struct list_head node; + struct list_head node_order; + struct dim_measure_name *name_head; +- char pcr; + int type; /* enum log_type */ + struct dim_digest digest; /* measure digest */ + struct dim_digest log_digest; /* measure log digest */ +@@ -92,8 +89,7 @@ static inline bool is_same_dim_measure_log(struct dim_measure_log *x, + } + + int dim_measure_log_init_tree(struct dim_measure_log_tree *root, +- struct dim_hash *hash, struct dim_tpm *tpm, +- unsigned int cap, unsigned int pcr); ++ struct dim_hash *hash, unsigned int cap); + void dim_measure_log_destroy_tree(struct dim_measure_log_tree *root); + int dim_measure_log_add(struct dim_measure_log_tree *root, + const char *name_str, +diff --git a/src/common/dim_rot.c b/src/common/dim_rot.c +new file mode 100644 +index 0000000..d930c50 +--- /dev/null ++++ b/src/common/dim_rot.c +@@ -0,0 +1,92 @@ ++/* ++ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved. ++ */ ++ ++#include "dim_utils.h" ++#include "dim_rot.h" ++ ++static struct dim_rot *dim_rot_prefered = NULL; ++ ++/* Support list: TPM, virtCCA */ ++static struct dim_rot *dim_supported_rots[] = { ++#ifdef CONFIG_TCG_TPM ++ &dim_rot_tpm, ++#endif ++#ifdef CONFIG_HISI_VIRTCCA_GUEST ++ &dim_rot_virtcca, ++#endif ++}; ++ ++int dim_rot_init(const char *name, int algo, int slot) ++{ ++ int i = 0; ++ int ret = 0; ++ ++ if (name == NULL || name[0] == '\0') { ++ dim_info("No specified RoT device\n"); ++ return 0; ++ } ++ ++ if (DIM_ARRAY_LEN(dim_supported_rots) == 0) { ++ dim_info("No supported RoT device\n"); ++ return 0; ++ } ++ ++ for (i = 0; i < DIM_ARRAY_LEN(dim_supported_rots); i++) { ++ if (strcmp(name, dim_supported_rots[i]->name) == 0) { ++ dim_rot_prefered = dim_supported_rots[i]; ++ break; ++ } ++ } ++ ++ if (dim_rot_prefered == NULL) { ++ /* If not find, use the default device */ ++ dim_rot_prefered = dim_supported_rots[0]; ++ dim_info("Cannot find the specified RoT %s\n", ++ dim_rot_prefered->name); ++ ++ return -EINVAL; ++ } ++ ++ ret = dim_rot_prefered->init(dim_rot_prefered, algo, slot); ++ if (ret < 0) ++ dim_err("Failed to initialize RoT device %s: %d\n", ++ dim_rot_prefered->name, ret); ++ else ++ dim_info("Succeed to initialize RoT device %s\n", ++ dim_rot_prefered->name); ++ ++ return ret; ++} ++ ++int dim_rot_extend(struct dim_digest *digest) ++{ ++ if (dim_rot_prefered == NULL) ++ return 0; ++ ++ return dim_rot_prefered->extend(dim_rot_prefered, digest); ++} ++ ++int dim_calc_boot_aggregate(struct dim_digest *digest) ++{ ++ if (dim_rot_prefered == NULL) ++ return -ENXIO; ++ ++ return dim_rot_prefered->calc_boot_aggregate(digest); ++} ++ ++void dim_rot_destroy(void) ++{ ++ if (dim_rot_prefered == NULL) ++ return; ++ ++ dim_rot_prefered->destroy(dim_rot_prefered); ++} ++ ++int dim_rot_slot(void) ++{ ++ if (dim_rot_prefered == NULL) ++ return 0; ++ ++ return dim_rot_prefered->slot(dim_rot_prefered); ++} +\ No newline at end of file +diff --git a/src/common/dim_rot.h b/src/common/dim_rot.h +new file mode 100644 +index 0000000..f3f6a8b +--- /dev/null ++++ b/src/common/dim_rot.h +@@ -0,0 +1,32 @@ ++/* ++ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved. ++ */ ++#ifndef __DIM_ROT_H ++#define __DIM_ROT_H ++ ++#include "dim_hash.h" ++ ++struct dim_rot { ++ const char *name; ++ ++ int (*init)(struct dim_rot *rot, int algo, int slot); ++ void (*destroy)(struct dim_rot *rot); ++ int (*slot)(struct dim_rot *rot); ++ int (*extend)(struct dim_rot *rot, struct dim_digest *digest); ++ int (*calc_boot_aggregate)(struct dim_digest *digest); ++}; ++ ++#ifdef CONFIG_TCG_TPM ++extern struct dim_rot dim_rot_tpm; ++#endif ++#ifdef CONFIG_HISI_VIRTCCA_GUEST ++extern struct dim_rot dim_rot_virtcca; ++#endif ++ ++int dim_rot_init(const char *name, int algo, int slot); ++int dim_rot_extend(struct dim_digest *digest); ++int dim_calc_boot_aggregate(struct dim_digest *digest); ++int dim_rot_slot(void); ++void dim_rot_destroy(void); ++ ++#endif +\ No newline at end of file +diff --git a/src/common/dim_rot_tpm.c b/src/common/dim_rot_tpm.c +new file mode 100644 +index 0000000..18621b1 +--- /dev/null ++++ b/src/common/dim_rot_tpm.c +@@ -0,0 +1,119 @@ ++/* ++ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved. ++ */ ++ ++#ifdef CONFIG_TCG_TPM ++ ++#include ++#include ++ ++#include "dim_rot.h" ++#include "dim_safe_func.h" ++#include "dim_utils.h" ++ ++#define DIM_PCR_MAX 128 ++ ++static struct tpm_chip *dim_tpm_chip = NULL; ++struct tpm_digest *dim_tpm_digests = NULL; ++static int dim_tpm_bank = 0; ++static unsigned int dim_tpm_pcr = 0; ++ ++/* Parameter data is the pcr value */ ++static int dim_tpm_init(struct dim_rot *rot, int algo, int pcr) ++{ ++ int ret = 0; ++ int i = 0; ++ ++ dim_tpm_chip = tpm_default_chip(); ++ if (dim_tpm_chip == NULL) ++ return -ENODEV; ++ ++ dim_tpm_digests = dim_kcalloc_gfp(dim_tpm_chip->nr_allocated_banks, ++ sizeof(struct tpm_digest)); ++ if (dim_tpm_digests == NULL) { ++ ret = -ENOMEM; ++ goto err; ++ } ++ ++ dim_tpm_bank = -1; ++ for (i = 0; i < dim_tpm_chip->nr_allocated_banks; i++) { ++ dim_tpm_digests[i].alg_id = dim_tpm_chip->allocated_banks[i].alg_id; ++ if (dim_tpm_chip->allocated_banks[i].crypto_id == algo) ++ dim_tpm_bank = i; ++ ++ memset(dim_tpm_digests[i].digest, 0xff, TPM_MAX_DIGEST_SIZE); ++ } ++ ++ if (dim_tpm_bank == -1) { ++ ret = -ENOENT; /* fail to find matched TPM bank */ ++ goto err; ++ } ++ ++ dim_tpm_pcr = pcr; ++ if (dim_tpm_pcr > DIM_PCR_MAX) ++ return -EINVAL; ++ ++ return 0; ++err: ++ put_device(&dim_tpm_chip->dev); ++ if (dim_tpm_digests != NULL) { ++ dim_kfree(dim_tpm_digests); ++ dim_tpm_digests = NULL; ++ } ++ ++ dim_tpm_chip = NULL; ++ return ret; ++} ++ ++static int dim_tpm_extend(struct dim_rot *rot, struct dim_digest *digest) ++{ ++ int size = 0; ++ ++ if (digest == NULL) ++ return -EINVAL; ++ ++ if (dim_tpm_chip == NULL) ++ return 0; ++ ++ size = dim_digest_size(digest->algo); ++ if (size == 0 || size > TPM_MAX_DIGEST_SIZE) ++ return -EINVAL; ++ ++ memcpy(dim_tpm_digests[dim_tpm_bank].digest, digest->data, size); ++ return tpm_pcr_extend(dim_tpm_chip, dim_tpm_pcr, dim_tpm_digests); ++} ++ ++static int dim_tpm_get_pcr(struct dim_rot *rot) ++{ ++ if (dim_tpm_chip == NULL) ++ return 0; ++ ++ return dim_tpm_pcr; ++} ++ ++static void dim_tpm_destroy(struct dim_rot *rot) ++{ ++ if (dim_tpm_chip == NULL) ++ return; ++ ++ put_device(&dim_tpm_chip->dev); ++ dim_kfree(dim_tpm_digests); ++ dim_tpm_chip = NULL; ++ dim_tpm_digests = NULL; ++} ++ ++static int dim_tpm_calc_boot_aggregate(struct dim_digest *digest) ++{ ++ return -ENXIO; // TODO ++} ++ ++struct dim_rot dim_rot_tpm = { ++ .name = "tpm", ++ .init = dim_tpm_init, ++ .destroy = dim_tpm_destroy, ++ .slot = dim_tpm_get_pcr, ++ .extend = dim_tpm_extend, ++ .calc_boot_aggregate = dim_tpm_calc_boot_aggregate, ++}; ++ ++#endif +\ No newline at end of file +diff --git a/src/common/dim_rot_virtcca.c b/src/common/dim_rot_virtcca.c +new file mode 100644 +index 0000000..3400632 +--- /dev/null ++++ b/src/common/dim_rot_virtcca.c +@@ -0,0 +1,111 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (C) 2024. Huawei Technologies Co., Ltd. All rights reserved. ++ */ ++ ++#ifdef CONFIG_HISI_VIRTCCA_GUEST ++ ++#include ++#include ++#include ++ ++#define DEFAULT_CCA_REM_IDX 4 ++static enum hash_algo virtcca_algo; ++static int dim_virtcca_enable = 0; ++static int dim_virtcca_init_algo(int algo) ++{ ++ 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; ++} ++ ++static int dim_virtcca_init(struct dim_rot *rot, int algo, int rem) // TODO ++{ ++ int rc; ++ ++ if (!is_virtcca_cvm_world() || tsi_get_version() == SMCCC_RET_NOT_SUPPORTED) ++ return -ENODEV; ++ ++ rc = dim_virtcca_init_algo(virtcca_algo); ++ if (rc) ++ return rc; ++ ++ dim_virtcca_enable = 1; ++ return 0; ++} ++ ++static int dim_virtcca_get_rem(struct dim_rot *rot) ++{ ++ if (dim_virtcca_enable == 0) ++ return 0; ++ ++ return DEFAULT_CCA_REM_IDX; // TODO ++} ++ ++static int dim_virtcca_extend(struct dim_digest *digests) ++{ ++ struct virtcca_cvm_measurement_extend cme; ++ ++ if (dim_virtcca_enable == 0) ++ return -EINVAL; ++ ++ // Now, in virtCCA, DIM can only use REM4 ++ cme.index = DEFAULT_CCA_REM_IDX; ++ cme.size = hash_digest_size[virtcca_algo]; ++ ++ /* ++ * virtcca has only one slot, so the algorithm of digests_arg[0] is always ++ * virtcca_algo according to the init process of ima_init_crypto() and ++ * ima_init_digets() ++ */ ++ memcpy(cme.value, digests[0].data, cme.size); ++ ++ return tsi_measurement_extend(&cme) == TSI_SUCCESS ? 0 : -EFAULT; ++} ++ ++static int dim_virtcca_calc_boot_aggregate(struct dim_digest *digest) ++{ ++ unsigned long result; ++ struct virtcca_cvm_measurement cm = { 0 }; ++ ++ digest->algo = virtcca_algo; ++ ++ /* Read the measurement result of RIM as the boot aggregate */ ++ ++ cm.index = RIM_MEASUREMENT_SLOT; ++ ++ result = tsi_measurement_read(&cm); ++ if (result != TSI_SUCCESS) { ++ pr_err("Error reading cvm measurement 0 for boot aggregate\n"); ++ return -EFAULT; ++ } ++ ++ memcpy(digest->data, cm.value, dim_digest_size(virtcca_algo)); ++ return 0; ++} ++ ++static void dim_virtcca_destroy(struct dim_rot *rot) ++{ ++ return; ++} ++ ++struct dim_rot dim_rot_virtcca = { ++ .name = "virtcca", ++ .init = dim_virtcca_init, ++ .destroy = dim_virtcca_destroy, ++ .slot = dim_virtcca_get_rem, ++ .extend = dim_virtcca_extend, ++ .calc_boot_aggregate = dim_virtcca_calc_boot_aggregate, ++}; ++ ++#endif +\ No newline at end of file +diff --git a/src/common/dim_tpm.c b/src/common/dim_tpm.c +deleted file mode 100644 +index 35f3fac..0000000 +--- a/src/common/dim_tpm.c ++++ /dev/null +@@ -1,79 +0,0 @@ +-/* +- * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved. +- */ +- +-#include +- +-#include "dim_safe_func.h" +-#include "dim_tpm.h" +- +-int dim_tpm_init(struct dim_tpm *tpm, int algo) +-{ +- int ret = 0; +- int i = 0; +- +- tpm->chip = tpm_default_chip(); +- if (tpm->chip == NULL) +- return -ENODEV; +- +- tpm->digests = dim_kcalloc_gfp(tpm->chip->nr_allocated_banks, +- sizeof(struct tpm_digest)); +- if (tpm->digests == NULL) { +- ret = -ENOMEM; +- goto err; +- } +- +- tpm->bank = -1; +- for (i = 0; i < tpm->chip->nr_allocated_banks; i++) { +- tpm->digests[i].alg_id = tpm->chip->allocated_banks[i].alg_id; +- if (tpm->chip->allocated_banks[i].crypto_id == algo) +- tpm->bank = i; +- +- memset(tpm->digests[i].digest, 0xff, TPM_MAX_DIGEST_SIZE); +- } +- +- if (tpm->bank == -1) { +- ret = -ENOENT; /* fail to find matched TPM bank */ +- goto err; +- } +- +- return 0; +-err: +- put_device(&tpm->chip->dev); +- if (tpm->digests != NULL) { +- dim_kfree(tpm->digests); +- tpm->digests = NULL; +- } +- +- tpm->chip = NULL; +- return ret; +-} +- +-int dim_tpm_pcr_extend(struct dim_tpm *tpm, int pcr, struct dim_digest *digest) +-{ +- int size = 0; +- +- if (tpm == NULL || digest == NULL) +- return -EINVAL; +- +- if (tpm->chip == NULL) +- return 0; +- +- size = dim_digest_size(digest->algo); +- if (size == 0 || size > TPM_MAX_DIGEST_SIZE) +- return -EINVAL; +- +- memcpy(tpm->digests[tpm->bank].digest, digest->data, size); +- return tpm_pcr_extend(tpm->chip, pcr, tpm->digests); +-} +- +-void dim_tpm_destroy(struct dim_tpm *tpm) +-{ +- if (tpm == NULL || tpm->chip == NULL) +- return; +- +- put_device(&tpm->chip->dev); +- dim_kfree(tpm->digests); +- tpm->chip = NULL; +- tpm->digests = NULL; +-} +diff --git a/src/common/dim_tpm.h b/src/common/dim_tpm.h +deleted file mode 100644 +index c4c715f..0000000 +--- a/src/common/dim_tpm.h ++++ /dev/null +@@ -1,23 +0,0 @@ +-/* +- * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved. +- */ +- +-#ifndef __DIM_TPM_H +-#define __DIM_TPM_H +- +-#include +-#include "dim_hash.h" +- +-#define DIM_PCR_MAX 128 +- +-struct dim_tpm { +- struct tpm_chip *chip; +- struct tpm_digest *digests; +- int bank; +-}; +- +-int dim_tpm_init(struct dim_tpm *tpm, int algo); +-int dim_tpm_pcr_extend(struct dim_tpm *tpm, int pcr, struct dim_digest *digest); +-void dim_tpm_destroy(struct dim_tpm *tpm); +- +-#endif +\ No newline at end of file +diff --git a/src/core/dim_core_main.c b/src/core/dim_core_main.c +index d4cc870..8f3dd74 100644 +--- a/src/core/dim_core_main.c ++++ b/src/core/dim_core_main.c +@@ -31,6 +31,9 @@ MODULE_PARM_DESC(measure_hash, "Hash algorithm for measurement"); + module_param_named(measure_pcr, cfg.pcr, uint, 0); + MODULE_PARM_DESC(measure_pcr, "TPM PCR index to extend measure log"); + ++module_param_named(measure_rot, cfg.rot, charp, 0); ++MODULE_PARM_DESC(measure_rot, "Rot device to extend measure log"); ++ + /* special measurement configuration for dim_core */ + static unsigned int measure_interval = 0; + static bool signature = false; +diff --git a/src/measure/dim_measure.c b/src/measure/dim_measure.c +index c40be0e..cf59e92 100644 +--- a/src/measure/dim_measure.c ++++ b/src/measure/dim_measure.c +@@ -17,11 +17,6 @@ static int cfg_check(struct dim_measure_cfg *cfg) + return -ERANGE; + } + +- if (cfg->pcr > DIM_PCR_MAX) { +- dim_err("invalid TPM pcr number: %d\n", cfg->pcr); +- return -ERANGE; +- } +- + return 0; + } + +@@ -41,15 +36,11 @@ int dim_measure_init(struct dim_measure *m, struct dim_measure_cfg *cfg) + goto err; + } + +- /* 2. init TPM, dont break if init fail */ ++ /* 2. init RoT, dont break if init fail */ + if (cfg->pcr > 0) { +- ret = dim_tpm_init(&m->tpm, HASH_ALGO_SHA256); +- if (ret < 0) { +- cfg->pcr = 0; +- dim_warn("failed to init tpm chip: %d\n", ret); +- } +- } else { +- memset(&m->tpm, 0, sizeof(struct dim_tpm)); ++ ret = dim_rot_init(cfg->rot, HASH_ALGO_SHA256, cfg->pcr); ++ if (ret < 0) ++ dim_warn("failed to init RoT device: %d\n", ret); + } + + /* 3. init baseline data (static and dynamic) */ +@@ -68,8 +59,7 @@ int dim_measure_init(struct dim_measure *m, struct dim_measure_cfg *cfg) + } + + /* 4. init measure log */ +- ret = dim_measure_log_init_tree(&m->log, &m->hash, &m->tpm, +- cfg->log_cap, cfg->pcr); ++ ret = dim_measure_log_init_tree(&m->log, &m->hash, cfg->log_cap); + if (ret < 0) { + dim_err("failed to init measure log: %d\n", ret); + goto err; +@@ -97,7 +87,7 @@ void dim_measure_destroy(struct dim_measure *m) + dim_measure_log_destroy_tree(&m->log); + dim_baseline_destroy_tree(&m->static_baseline); + dim_baseline_destroy_tree(&m->dynamic_baseline); +- dim_tpm_destroy(&m->tpm); ++ dim_rot_destroy(); + dim_hash_destroy(&m->hash); + mutex_unlock(&m->measure_lock); + } +diff --git a/src/measure/dim_measure.h b/src/measure/dim_measure.h +index f5140f0..4983103 100644 +--- a/src/measure/dim_measure.h ++++ b/src/measure/dim_measure.h +@@ -11,7 +11,7 @@ + #include "dim_baseline.h" + #include "dim_hash.h" + #include "dim_measure_log.h" +-#include "dim_tpm.h" ++#include "dim_rot.h" + #include "dim_utils.h" + + #define DIM_MEASURE 0 +@@ -41,6 +41,8 @@ struct dim_measure_cfg { + unsigned int schedule_ms; + /* PCR number for TPM extending */ + unsigned int pcr; ++ /* device to extend measure log */ ++ char *rot; + /* max measure log number */ + unsigned int log_cap; + /* memory function for baseline store */ +@@ -58,8 +60,6 @@ struct dim_measure { + struct mutex measure_lock; + /* measure hash algorithm */ + struct dim_hash hash; +- /* TPM chip handle */ +- struct dim_tpm tpm; + /* measure log */ + struct dim_measure_log_tree log; + /* measure baseline */ +diff --git a/src/monitor/dim_monitor_main.c b/src/monitor/dim_monitor_main.c +index d0e89f1..6a78934 100644 +--- a/src/monitor/dim_monitor_main.c ++++ b/src/monitor/dim_monitor_main.c +@@ -24,6 +24,9 @@ MODULE_PARM_DESC(measure_hash, "Hash algorithm for measurement"); + module_param_named(measure_pcr, cfg.pcr, uint, 0); + MODULE_PARM_DESC(measure_pcr, "TPM PCR index to extend measure log"); + ++module_param_named(measure_rot, cfg.rot, charp, 0); ++MODULE_PARM_DESC(measure_rot, "Rot device to extend measure log"); ++ + static int __init dim_monitor_init(void) + { + int ret; +-- +2.43.0 + diff --git a/0001-fix-some-build-errors.patch b/0001-fix-some-build-errors.patch new file mode 100644 index 0000000..8d0d528 --- /dev/null +++ b/0001-fix-some-build-errors.patch @@ -0,0 +1,26 @@ +From 17209da8f2fe822932cdfc4ee16f10f86271db3e Mon Sep 17 00:00:00 2001 +From: xuce +Date: Thu, 18 Dec 2025 10:23:45 +0800 +Subject: [PATCH] fix prototype build error + +Signed-off-by: xuce +--- + .../dim_core_measure_process/dim_core_measure_process_vma.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/core/tasks/dim_core_measure_process/dim_core_measure_process_vma.c b/src/core/tasks/dim_core_measure_process/dim_core_measure_process_vma.c +index d3ba241..29725c6 100644 +--- a/src/core/tasks/dim_core_measure_process/dim_core_measure_process_vma.c ++++ b/src/core/tasks/dim_core_measure_process/dim_core_measure_process_vma.c +@@ -49,7 +49,7 @@ static struct vm_area_struct *next_file_text_vma(struct vm_area_struct *vma) + } + + /* For file text segment, merge all file mapping text vma and measure */ +-int measure_text_vma(struct vm_area_struct *vma, struct task_measure_ctx *ctx) ++static int measure_text_vma(struct vm_area_struct *vma, struct task_measure_ctx *ctx) + { + int ret = 0; + struct vm_area_struct *v = vma; +-- +2.43.0 + diff --git a/0002-Add-macros-to-support-kernels-with-different-compila.patch b/0002-Add-macros-to-support-kernels-with-different-compila.patch new file mode 100644 index 0000000..8bc5a0b --- /dev/null +++ b/0002-Add-macros-to-support-kernels-with-different-compila.patch @@ -0,0 +1,458 @@ +From aed2964d084db35daa30467d9cb3a6aba210987d Mon Sep 17 00:00:00 2001 +From: Huaxin Lu +Date: Wed, 26 Nov 2025 15:05:58 +0800 +Subject: [PATCH 02/13] Add macros to support kernels with different + compilation options + +1. Support kernel without module mechanism; +2. Support kernel without jumplabel; +3. Support to remove signature function. + +Signed-off-by: Huaxin Lu +--- + src/Makefile | 4 ++- + src/common/dim_utils.c | 31 ++++++++++++++++ + src/common/dim_utils.h | 2 ++ + src/core/dim_core_main.c | 13 ++++--- + src/core/dim_core_sig.c | 36 ++----------------- + src/core/dim_core_sig.h | 1 - + src/core/dim_core_symbol.c | 16 ++++++--- + src/core/dim_core_symbol.h | 12 ++++--- + src/core/policy/dim_core_policy.c | 5 ++- + .../dim_core_static_baseline.c | 2 +- + src/core/tasks/dim_core_measure_kernel.c | 24 ++++++++++++- + src/core/tasks/dim_core_measure_module.c | 7 ++++ + src/measure/dim_measure_task.c | 4 +-- + 13 files changed, 103 insertions(+), 54 deletions(-) + +diff --git a/src/Makefile b/src/Makefile +index df4c729..ad2b1fe 100644 +--- a/src/Makefile ++++ b/src/Makefile +@@ -8,8 +8,10 @@ dim_core-objs += core/dim_core_fs.o + dim_core-objs += core/dim_core_mem_pool.o + dim_core-objs += core/dim_core_measure.o + dim_core-objs += core/dim_core_symbol.o ++ifeq ($(DIM_CORE_SIGNATURE_SUPPORT), y) + dim_core-objs += core/dim_core_sig.o +- ++ccflags-y += -DDIM_CORE_SIGNATURE_SUPPORT ++endif + dim_core-objs += core/tasks/dim_core_measure_kernel.o + dim_core-objs += core/tasks/dim_core_measure_module.o + dim_core-objs += core/tasks/dim_core_measure_process/dim_vm_hash.o +diff --git a/src/common/dim_utils.c b/src/common/dim_utils.c +index 6746d88..2f7f2ff 100644 +--- a/src/common/dim_utils.c ++++ b/src/common/dim_utils.c +@@ -5,6 +5,7 @@ + #include + #include + #include ++#include + + #include "dim_safe_func.h" + #include "dim_utils.h" +@@ -100,3 +101,33 @@ out: + + return ret; + } ++ ++int dim_read_file(struct path *root, const char *name, void **buf) ++{ ++ int ret = 0; ++ struct file *file = NULL; ++ ++ if (root == NULL) { ++ ret = kernel_read_file_from_path(name, 0, buf, ++ DIM_MAX_FILE_SIZE, ++ NULL, READING_UNKNOWN); ++#ifdef DIM_DEBUG_MEMORY_LEAK ++ if (*buf != NULL) ++ dim_alloc_debug_inc(); ++#endif ++ return ret; ++ } ++ ++ file = file_open_root(root, name, O_RDONLY, 0); ++ if (IS_ERR(file)) ++ return PTR_ERR(file); ++ ++ ret = kernel_read_file(file, 0, buf, DIM_MAX_FILE_SIZE, ++ NULL, READING_UNKNOWN); ++#ifdef DIM_DEBUG_MEMORY_LEAK ++ if (*buf != NULL) ++ dim_alloc_debug_inc(); ++#endif ++ (void)filp_close(file, NULL); ++ return ret; ++} +diff --git a/src/common/dim_utils.h b/src/common/dim_utils.h +index db43546..7d47ce0 100644 +--- a/src/common/dim_utils.h ++++ b/src/common/dim_utils.h +@@ -9,6 +9,7 @@ + #include + + #define DIM_ARRAY_LEN(ARR) (sizeof(ARR) / sizeof(ARR[0])) ++#define DIM_MAX_FILE_SIZE (10 * 1024 * 1024) + + #define dim_fmt(fmt) "%s: " fmt + +@@ -19,5 +20,6 @@ + + int dim_get_absolute_path(const char *path, const char **result); + int dim_parse_line_buf(char *buf, loff_t len, int (*line_parser)(char *, int, void *), void *data); ++int dim_read_file(struct path *root, const char *name, void **buf); + + #endif +diff --git a/src/core/dim_core_main.c b/src/core/dim_core_main.c +index 8f3dd74..1f80dbf 100644 +--- a/src/core/dim_core_main.c ++++ b/src/core/dim_core_main.c +@@ -11,7 +11,9 @@ + #include "dim_core_fs.h" + #include "dim_core_measure.h" + #include "dim_core_mem_pool.h" ++#ifdef DIM_CORE_SIGNATURE_SUPPORT + #include "dim_core_sig.h" ++#endif + + /* common measurement configuration */ + static struct dim_measure_cfg cfg = { +@@ -59,7 +61,7 @@ static int __init dim_core_init(void) + dim_err("failed to initialize dim memory pool: %d\n", ret); + goto err; + } +- ++#ifdef DIM_CORE_SIGNATURE_SUPPORT + if (signature) { + ret = dim_core_sig_init(); + if (ret < 0) { +@@ -67,7 +69,7 @@ static int __init dim_core_init(void) + goto err; + } + } +- ++#endif + ret = dim_core_measure_init(&cfg, measure_interval); + if (ret < 0) { + dim_err("failed to initialize dim measurement: %d\n", ret); +@@ -85,10 +87,10 @@ err: + dim_core_destroy_fs(); + dim_core_measure_destroy(); + dim_mem_pool_destroy(); +- ++#ifdef DIM_CORE_SIGNATURE_SUPPORT + if (signature) + dim_core_sig_destroy(); +- ++#endif + return ret; + } + +@@ -97,9 +99,10 @@ static void __exit dim_core_exit(void) + dim_core_destroy_fs(); + dim_core_measure_destroy(); + dim_mem_pool_destroy(); +- ++#ifdef DIM_CORE_SIGNATURE_SUPPORT + if (signature) + dim_core_sig_destroy(); ++#endif + + #ifdef DIM_DEBUG_MEMORY_LEAK + dim_check_memory_leak(); +diff --git a/src/core/dim_core_sig.c b/src/core/dim_core_sig.c +index 07e11d8..5520656 100644 +--- a/src/core/dim_core_sig.c ++++ b/src/core/dim_core_sig.c +@@ -8,7 +8,6 @@ + #include + #include + #include +-#include + #include + + #include "dim_hash.h" +@@ -35,35 +34,6 @@ static char *add_suffix(const char *str, const char *suffix) + return buf; + } + +-static int read_file_root(struct path *root, const char *name, void **buf) +-{ +- int ret = 0; +- struct file *file = NULL; +- +- if (root == NULL) { +- ret = kernel_read_file_from_path(name, 0, buf, +- DIM_CORE_MAX_FILE_SIZE, +- NULL, READING_UNKNOWN); +-#ifdef DIM_DEBUG_MEMORY_LEAK +- if (*buf != NULL) +- dim_alloc_debug_inc(); +-#endif +- return ret; +- } +- +- file = file_open_root(root, name, O_RDONLY, 0); +- if (IS_ERR(file)) +- return PTR_ERR(file); +- +- ret = kernel_read_file(file, 0, buf, DIM_CORE_MAX_FILE_SIZE, +- NULL, READING_UNKNOWN); +-#ifdef DIM_DEBUG_MEMORY_LEAK +- if (*buf != NULL) +- dim_alloc_debug_inc(); +-#endif +- (void)filp_close(file, NULL); +- return ret; +-} + + static int dim_core_sig_verify(const char *buf, loff_t buf_len, + const char *sbuf, loff_t sbuf_len) +@@ -92,7 +62,7 @@ static int dim_core_sig_verify(const char *buf, loff_t buf_len, + return verify_signature(dim_core_key, &key_sig); + } + +-int dim_read_verify_file(struct path *root, const char *name, void **buf) ++int dim_read_file(struct path *root, const char *name, void **buf) + { + int ret = 0; + char *sig_name = NULL; +@@ -108,7 +78,7 @@ int dim_read_verify_file(struct path *root, const char *name, void **buf) + if (sig_name == NULL) + return -ENOMEM; + +- ret = read_file_root(root, name, &file_buf); ++ ret = dim_read_file(root, name, &file_buf); + if (ret < 0) + goto out; + +@@ -118,7 +88,7 @@ int dim_read_verify_file(struct path *root, const char *name, void **buf) + if (dim_core_key == NULL) + goto out; /* no need to verify signature */ + +- ret = read_file_root(root, sig_name, &sig_buf); ++ ret = dim_read_file(root, sig_name, &sig_buf); + if (ret < 0) + goto out; + +diff --git a/src/core/dim_core_sig.h b/src/core/dim_core_sig.h +index 45dd0bb..cceed9f 100644 +--- a/src/core/dim_core_sig.h ++++ b/src/core/dim_core_sig.h +@@ -7,7 +7,6 @@ + + #include + +-#define DIM_CORE_MAX_FILE_SIZE (10 * 1024 * 1024) + #define DIM_CORE_KEYRING_NAME "_dim" + #define DIM_CORE_CERT_PATH "/etc/keys/x509_dim.der" + #define DIM_CORE_SIG_FILE_SUFFIX ".sig" +diff --git a/src/core/dim_core_symbol.c b/src/core/dim_core_symbol.c +index 97bb5fe..7e4b88a 100644 +--- a/src/core/dim_core_symbol.c ++++ b/src/core/dim_core_symbol.c +@@ -28,7 +28,7 @@ int dim_core_kallsyms_init(void) + } + k->stext = (char *)dim_kallsyms_lookup_name("_stext"); + k->etext = (char *)dim_kallsyms_lookup_name("_etext"); +- ++#ifdef CONFIG_JUMP_LABEL + k->start_jump_table = (struct jump_entry *) + dim_kallsyms_lookup_name("__start___jump_table"); + k->stop_jump_table = (struct jump_entry *) +@@ -37,20 +37,28 @@ int dim_core_kallsyms_init(void) + dim_kallsyms_lookup_name("jump_label_lock"); + k->jump_label_unlock = (DIM_JUMP_LABEL_UNLOCK) + dim_kallsyms_lookup_name("jump_label_unlock"); ++#endif + k->walk_process_tree = (DIM_WALK_PROCESS_TREE) + dim_kallsyms_lookup_name("walk_process_tree"); + #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 4, 0) ++ #ifdef CONFIG_MODULES + k->find_module = (DIM_FIND_MODULE) + dim_kallsyms_lookup_name("find_module"); ++ #endif + k->find_get_task_by_vpid = (DIM_FIND_GET_TASK_BY_VPID) + dim_kallsyms_lookup_name("find_get_task_by_vpid"); + #endif + + return (k->stext == NULL || k->etext == NULL || +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 4, 0) +- k->find_module == NULL || k->find_get_task_by_vpid == NULL || +-#endif ++#ifdef CONFIG_JUMP_LABEL + k->start_jump_table == NULL || k->stop_jump_table == NULL || + k->jump_label_lock == NULL || k->jump_label_unlock == NULL || ++#endif ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 4, 0) ++ #ifdef CONFIG_MODULES ++ k->find_module == NULL || ++ #endif ++ k->find_get_task_by_vpid == NULL || ++#endif + k->walk_process_tree == NULL) ? -ENOENT : 0; + } +diff --git a/src/core/dim_core_symbol.h b/src/core/dim_core_symbol.h +index 5f3ee4b..2540041 100644 +--- a/src/core/dim_core_symbol.h ++++ b/src/core/dim_core_symbol.h +@@ -25,18 +25,22 @@ typedef int (*DIM_ARCH_JUMP_ENTRY_SIZE)(struct jump_entry *); + struct dim_core_kallsyms { + char *stext; + char *etext; ++#ifdef CONFIG_JUMP_LABEL + struct jump_entry *start_jump_table; + struct jump_entry *stop_jump_table; + DIM_JUMP_LABEL_LOCK jump_label_lock; + DIM_JUMP_LABEL_LOCK jump_label_unlock; +- DIM_WALK_PROCESS_TREE walk_process_tree; ++ #ifndef JUMP_LABEL_NOP_SIZE ++ DIM_ARCH_JUMP_ENTRY_SIZE arch_jump_entry_size; ++ #endif ++#endif + #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 4, 0) ++ #ifdef CONFIG_MODULES + DIM_FIND_MODULE find_module; ++ #endif + DIM_FIND_GET_TASK_BY_VPID find_get_task_by_vpid; + #endif +-#ifndef JUMP_LABEL_NOP_SIZE +- DIM_ARCH_JUMP_ENTRY_SIZE arch_jump_entry_size; +-#endif ++ DIM_WALK_PROCESS_TREE walk_process_tree; + }; + + extern struct dim_core_kallsyms dim_core_kernel_symbol; +diff --git a/src/core/policy/dim_core_policy.c b/src/core/policy/dim_core_policy.c +index e18aca7..e59c778 100644 +--- a/src/core/policy/dim_core_policy.c ++++ b/src/core/policy/dim_core_policy.c +@@ -174,8 +174,11 @@ int dim_core_policy_load(void) + + if (!RB_EMPTY_ROOT(&policy_root)) + dim_core_policy_destroy(); +- ++#ifdef DIM_CORE_SIGNATURE_SUPPORT + ret = dim_read_verify_file(NULL, DIM_POLICY_PATH, &buf); ++#else ++ ret = dim_read_file(NULL, DIM_POLICY_PATH, &buf); ++#endif + if (ret < 0 || buf == NULL) { + dim_err("failed to read policy file: %d\n", ret); + return ret; +diff --git a/src/core/static_baseline/dim_core_static_baseline.c b/src/core/static_baseline/dim_core_static_baseline.c +index 7ae5171..74fc029 100644 +--- a/src/core/static_baseline/dim_core_static_baseline.c ++++ b/src/core/static_baseline/dim_core_static_baseline.c +@@ -147,7 +147,7 @@ int dim_core_static_baseline_load(struct dim_measure *m) + filp_close(file, NULL); + + list_for_each_entry_safe(entry, tmp, &ctx.name_list, list) { +- ret = dim_read_verify_file(&kpath, entry->name, &buf); ++ ret = dim_read_file(&kpath, entry->name, &buf); + if (ret < 0 || buf == NULL) { + dim_err("failed to read and verify %s: %d\n", entry->name, ret); + dim_kfree(entry); +diff --git a/src/core/tasks/dim_core_measure_kernel.c b/src/core/tasks/dim_core_measure_kernel.c +index bb7fd74..426b3cf 100644 +--- a/src/core/tasks/dim_core_measure_kernel.c ++++ b/src/core/tasks/dim_core_measure_kernel.c +@@ -3,11 +3,14 @@ + */ + + #include +-#include + #include + #include + #include + ++#ifdef CONFIG_JUMP_LABEL ++#include ++#endif ++ + #include "dim_measure.h" + + #include "dim_core_symbol.h" +@@ -16,6 +19,8 @@ + + #include "dim_core_measure_task.h" + ++#ifdef CONFIG_JUMP_LABEL ++ + /* max size of x86 */ + #define DIM_JUMP_LABEL_NOP_SIZE_MAX 5 + +@@ -134,6 +139,23 @@ static int calc_kernel_digest(struct dim_hash *hash, struct dim_digest *digest) + dim_vfree(jcode_sort); + return ret; + } ++#else ++/* If kernel doesn't support jumplabel, calculate text directly */ ++static int calc_kernel_digest(struct dim_hash *hash, struct dim_digest *digest) ++{ ++ int ret = 0; ++ uintptr_t stext = (uintptr_t)dim_core_kernel_symbol.stext; ++ uintptr_t etext = (uintptr_t)dim_core_kernel_symbol.etext; ++ SHASH_DESC_ON_STACK(shash, hash->tfm); ++ ++ shash->tfm = hash->tfm; ++ if (shash->tfm == NULL || stext >= etext) ++ return -EINVAL; ++ ++ return crypto_shash_digest(shash, (char *)stext, etext - stext, ++ digest->data); ++} ++#endif + + static int kernel_text_measure(int mode, struct dim_measure *m) + { +diff --git a/src/core/tasks/dim_core_measure_module.c b/src/core/tasks/dim_core_measure_module.c +index 613e0e5..21b6d60 100644 +--- a/src/core/tasks/dim_core_measure_module.c ++++ b/src/core/tasks/dim_core_measure_module.c +@@ -16,6 +16,7 @@ + + #include "dim_core_measure_task.h" + ++#ifdef CONFIG_MODULES + struct module_text_measure_ctx { + struct dim_measure *m; + int mode; +@@ -108,9 +109,15 @@ static int module_text_measure(int mode, struct dim_measure *m) + return dim_core_policy_walk(measure_module, &ctx); + } + ++#endif ++ + struct dim_measure_task dim_core_measure_task_module_text = { + .name = "dim_core_measure_task_module_text", + .init = NULL, + .destroy = NULL, ++#ifdef CONFIG_MODULES + .measure = module_text_measure, ++#else ++ .measure = NULL, ++#endif + }; +diff --git a/src/measure/dim_measure_task.c b/src/measure/dim_measure_task.c +index adfc57d..632cb4d 100644 +--- a/src/measure/dim_measure_task.c ++++ b/src/measure/dim_measure_task.c +@@ -9,10 +9,8 @@ static void call_measure_func(int mode, struct dim_measure_task *t, + { + int ret = 0; + +- if (t->measure == NULL) { +- dim_warn("no measure function in %s task", t->name); ++ if (t->measure == NULL) + return; +- } + + dim_info("start to call %s measure task\n", t->name); + ret = t->measure(mode, m); +-- +2.43.0 + diff --git a/0003-Support-remote-attestation.patch b/0003-Support-remote-attestation.patch new file mode 100644 index 0000000..3a1e9c5 --- /dev/null +++ b/0003-Support-remote-attestation.patch @@ -0,0 +1,228 @@ +From 97ae2ea04e175d297a5151d2ee6416777d11ca87 Mon Sep 17 00:00:00 2001 +From: Ce Xu +Date: Wed, 26 Nov 2025 16:20:37 +0800 +Subject: [PATCH 03/13] Support remote attestation + +Add a new interface for reading measure log in binary format. + +Signed-off-by: Huaxin Lu +--- + src/common/dim_entry.h | 20 ++++++------ + src/common/dim_measure_log.c | 61 ++++++++++++++++++++++++++++++++++-- + src/common/dim_measure_log.h | 5 ++- + src/core/dim_core_fs.c | 18 +++++++++-- + src/monitor/dim_monitor_fs.c | 2 +- + 5 files changed, 90 insertions(+), 16 deletions(-) + +diff --git a/src/common/dim_entry.h b/src/common/dim_entry.h +index bb023b6..8a560bd 100644 +--- a/src/common/dim_entry.h ++++ b/src/common/dim_entry.h +@@ -60,37 +60,37 @@ static struct dim_entry sname##_entry = { \ + }; + + /* the file interface for reading measure log */ +-#define dim_measure_log_entry(sname, fname, root_ptr) \ +-static void *measure_log_read_start(struct seq_file *m, loff_t *pos) \ ++#define dim_measure_log_entry(sname, fname, root_ptr, format) \ ++static void *measure_log##format##_read_start(struct seq_file *m, loff_t *pos) \ + { \ + read_lock(&(root_ptr)->lock); \ + return seq_list_start(&(root_ptr)->list_root, *pos); \ + } \ + \ +-static void *measure_log_read_next(struct seq_file *m, \ ++static void *measure_log##format##_read_next(struct seq_file *m, \ + void *v, loff_t *pos) \ + { \ + return seq_list_next(v, &(root_ptr)->list_root, pos); \ + } \ + \ +-static void measure_log_read_stop(struct seq_file *m, void *v) \ ++static void measure_log##format##_read_stop(struct seq_file *m, void *v) \ + { \ + read_unlock(&(root_ptr)->lock); \ + } \ + \ +-static int measure_log_read_show(struct seq_file *m, void *v) \ ++static int measure_log##format##_read_show(struct seq_file *m, void *v) \ + { \ + struct dim_measure_log *log = \ + list_entry(v, struct dim_measure_log, node_order); \ + \ +- return dim_measure_log_seq_show(m, log); \ ++ return dim_measure_log_seq_show_##format(m, log); \ + } \ + \ + const struct seq_operations sname##_seqops = { \ +- .start = measure_log_read_start, \ +- .next = measure_log_read_next, \ +- .stop = measure_log_read_stop, \ +- .show = measure_log_read_show, \ ++ .start = measure_log##format##_read_start, \ ++ .next = measure_log##format##_read_next, \ ++ .stop = measure_log##format##_read_stop, \ ++ .show = measure_log##format##_read_show, \ + }; \ + \ + static int sname##_open(struct inode *inode, struct file *file) \ +diff --git a/src/common/dim_measure_log.c b/src/common/dim_measure_log.c +index 3fa32f2..1397f7b 100644 +--- a/src/common/dim_measure_log.c ++++ b/src/common/dim_measure_log.c +@@ -9,6 +9,8 @@ + #include "dim_safe_func.h" + #include "dim_measure_log.h" + ++#define DIM_TEMPLATE "ima-ng" ++ + /* + static int dim_measure_name_rb_add(struct rb_root *root, + struct dim_baseline *data, +@@ -57,7 +59,60 @@ static int cal_measure_log_digest(const char *name, + return crypto_shash_final(shash, info->log_digest.data); + } + +-int dim_measure_log_seq_show(struct seq_file *m, struct dim_measure_log *info) ++static void dim_putc(struct seq_file *m, const void *data, int datelen) ++{ ++ while (datelen--) ++ seq_putc(m, *(char *)data++); ++} ++ ++int dim_measure_log_seq_show_binary(struct seq_file *m, ++ struct dim_measure_log *info) ++{ ++ u32 pcr, len, name_len, digest_len; ++ char digest_buf[(DIM_MAX_DIGEST_SIZE << 1) + 1] = { 0 }; ++ const char *name = NULL; ++ ++ /* Print slot index */ ++ pcr = dim_rot_slot(); ++ dim_putc(m, &pcr, sizeof(pcr)); ++ ++ /* template digest */ ++ dim_putc(m, &info->log_digest.data, dim_digest_size(HASH_ALGO_SHA256)); ++ ++ /* template name */ ++ len = strlen(DIM_TEMPLATE); ++ dim_putc(m, &len, sizeof(len)); ++ dim_putc(m, DIM_TEMPLATE, len); ++ ++ /* calculate the length of rest data */ ++ digest_len = strlen(dim_hash_name(info->log_digest.algo)) + \ ++ strlen(":") + 1 + \ ++ dim_digest_size(info->log_digest.algo); ++ ++ name = dim_measure_log_name(info); ++ name_len = strlen(name) + 1; ++ len = digest_len + name_len + sizeof(name_len) + sizeof(digest_len); ++ ++ /* print len */ ++ dim_putc(m, &len, sizeof(len)); ++ /* digest buf*/ ++ strcat(digest_buf, dim_hash_name(info->digest.algo)); ++ strcat(digest_buf, ":"); ++ strncpy(digest_buf + strlen(digest_buf) + 1, info->digest.data, dim_digest_size(info->log_digest.algo)); ++ dim_putc(m, &digest_len, sizeof(digest_len)); ++ dim_putc(m, digest_buf, digest_len); ++ ++ /* measure log name */ ++ dim_putc(m, &name_len, sizeof(name_len)); ++ dim_putc(m, name, name_len); ++ ++ /* to do list: measure log type*/ ++ ++ return 0; ++} ++ ++int dim_measure_log_seq_show_ascii(struct seq_file *m, ++ struct dim_measure_log *info) + { + char log_digest_buf[(DIM_MAX_DIGEST_SIZE << 1) + 1] = { 0 }; + char digest_buf[(DIM_MAX_DIGEST_SIZE << 1) + 1] = { 0 }; +@@ -68,13 +123,15 @@ int dim_measure_log_seq_show(struct seq_file *m, struct dim_measure_log *info) + bin2hex(digest_buf, info->digest.data, + dim_digest_size(info->digest.algo)); + +- seq_printf(m, "%d %s %s:%s %s %s\n", ++ seq_printf(m, "%d %s %s %s:%s %s %s\n", + dim_rot_slot(), + log_digest_buf, ++ DIM_TEMPLATE, + dim_hash_name(info->digest.algo), + digest_buf, + dim_measure_log_name(info), + dim_measure_log_type_to_name(info->type)); ++ + return 0; + } + +diff --git a/src/common/dim_measure_log.h b/src/common/dim_measure_log.h +index ada7d97..e8ec041 100644 +--- a/src/common/dim_measure_log.h ++++ b/src/common/dim_measure_log.h +@@ -94,7 +94,10 @@ void dim_measure_log_destroy_tree(struct dim_measure_log_tree *root); + int dim_measure_log_add(struct dim_measure_log_tree *root, + const char *name_str, + struct dim_digest *digest, int flag); +-int dim_measure_log_seq_show(struct seq_file *m, struct dim_measure_log *log); ++int dim_measure_log_seq_show_ascii(struct seq_file *m, ++ struct dim_measure_log *log); ++int dim_measure_log_seq_show_binary(struct seq_file *m, ++ struct dim_measure_log *info); + void dim_measure_log_refresh(struct dim_measure_log_tree *root); + + #endif +diff --git a/src/core/dim_core_fs.c b/src/core/dim_core_fs.c +index 4a82e53..a6448c4 100644 +--- a/src/core/dim_core_fs.c ++++ b/src/core/dim_core_fs.c +@@ -32,8 +32,21 @@ dim_trigger_entry(dim_baseline_init, baseline_init, + * file entry name: runtime_status + * status to read: dim_measure_log_tree + */ +-dim_measure_log_entry(dim_measure_log, ascii_runtime_measurements, +- &dim_core_handle.log); ++dim_measure_log_entry(dim_measure_log, ++ ascii_runtime_measurements, ++ &dim_core_handle.log, ++ ascii); ++ ++/* ++ * binary measure log read interface ++ * dim_entry struct: dim_measure_log_entry ++ * file entry name: runtime_status ++ * status to read: dim_measure_log_tree ++ */ ++dim_measure_log_entry(dim_measure_log_binary, ++ binary_runtime_measurements, ++ &dim_core_handle.log, ++ binary); + + /* + * status print interface +@@ -77,6 +90,7 @@ static struct dim_entry *dim_core_files[] = { + &dim_measure_entry, + &dim_baseline_init_entry, + &dim_measure_log_entry, ++ &dim_measure_log_binary_entry, + &dim_status_entry, + &dim_interval_entry, + &dim_tampered_action_entry, +diff --git a/src/monitor/dim_monitor_fs.c b/src/monitor/dim_monitor_fs.c +index 8bb3120..383a565 100644 +--- a/src/monitor/dim_monitor_fs.c ++++ b/src/monitor/dim_monitor_fs.c +@@ -44,7 +44,7 @@ dim_string_print_entry(dim_monitor_status, monitor_status, dim_monitor_status_pr + * status to read: dim_measure_log_tree + */ + dim_measure_log_entry(dim_monitor_log, monitor_ascii_runtime_measurements, +- &dim_monitor_handle.log); ++ &dim_monitor_handle.log, ascii); + + static struct dim_entry *dim_monitor_files[] = { + &dim_monitor_measure_entry, +-- +2.43.0 + diff --git a/0004-Support-measure-only-mode.patch b/0004-Support-measure-only-mode.patch new file mode 100644 index 0000000..c3002e7 --- /dev/null +++ b/0004-Support-measure-only-mode.patch @@ -0,0 +1,204 @@ +From a50cc5e8d4efbf394908bb623bb606440b76f0db Mon Sep 17 00:00:00 2001 +From: Huaxin Lu +Date: Wed, 26 Nov 2025 17:52:24 +0800 +Subject: [PATCH 04/13] Support measure only mode + +In remote attestation scenario, static baseline is not necessary. +So we support a new parameter to disable baseline loading and +verification. + +Signed-off-by: Huaxin Lu +--- + src/common/dim_measure_log.h | 2 ++ + src/core/dim_core_main.c | 3 ++ + src/core/dim_core_measure.c | 5 ++++ + .../dim_core_measure_process.c | 2 +- + src/measure/dim_measure.c | 29 +++++++++++-------- + src/measure/dim_measure.h | 4 +++ + src/measure/dim_measure_baseline.c | 10 +++++++ + src/measure/dim_measure_task.c | 2 +- + 8 files changed, 43 insertions(+), 14 deletions(-) + +diff --git a/src/common/dim_measure_log.h b/src/common/dim_measure_log.h +index e8ec041..423ec99 100644 +--- a/src/common/dim_measure_log.h ++++ b/src/common/dim_measure_log.h +@@ -21,6 +21,7 @@ enum dim_measure_log_type { + LOG_DYNAMIC_BASELINE, + LOG_TAMPERED, + LOG_MATCHED, ++ LOC_MEASURE, + LOG_LAST, + }; + +@@ -30,6 +31,7 @@ static const char *dim_measure_log_type_name[LOG_LAST] = { + [LOG_DYNAMIC_BASELINE] = "[dynamic baseline]", + [LOG_TAMPERED] = "[tampered]", + [LOG_MATCHED] = "[matched]", ++ [LOC_MEASURE] = "[measure]" + }; + + struct dim_measure_log_tree { +diff --git a/src/core/dim_core_main.c b/src/core/dim_core_main.c +index 1f80dbf..5c8636d 100644 +--- a/src/core/dim_core_main.c ++++ b/src/core/dim_core_main.c +@@ -36,6 +36,9 @@ MODULE_PARM_DESC(measure_pcr, "TPM PCR index to extend measure log"); + module_param_named(measure_rot, cfg.rot, charp, 0); + MODULE_PARM_DESC(measure_rot, "Rot device to extend measure log"); + ++module_param_named(measure_only, cfg.measure_only, bool, 0); ++MODULE_PARM_DESC(measure_only, "Only do measurement, no verification"); ++ + /* special measurement configuration for dim_core */ + static unsigned int measure_interval = 0; + static bool signature = false; +diff --git a/src/core/dim_core_measure.c b/src/core/dim_core_measure.c +index caf767c..8bc39fc 100644 +--- a/src/core/dim_core_measure.c ++++ b/src/core/dim_core_measure.c +@@ -100,6 +100,10 @@ static int baseline_prepare(struct dim_measure *m) + return ret; + } + ++ /* For measure_only mode, we only need to reload policy */ ++ if (m->measure_only) ++ return 0; ++ + /* 2. clear dim baseline */ + dim_baseline_destroy_tree(&m->static_baseline); + dim_baseline_destroy_tree(&m->dynamic_baseline); +@@ -157,6 +161,7 @@ int dim_core_measure_blocking(void) + /* clean the running work */ + flush_delayed_work(&dim_measure_work); + cancel_delayed_work_sync(&dim_measure_work); ++ + /* queue and flush measure work */ + queue_delayed_work(dim_work_queue, &dim_measure_work, 0); + flush_delayed_work(&dim_measure_work); +diff --git a/src/core/tasks/dim_core_measure_process/dim_core_measure_process.c b/src/core/tasks/dim_core_measure_process/dim_core_measure_process.c +index 5efbeb4..f28c0f9 100644 +--- a/src/core/tasks/dim_core_measure_process/dim_core_measure_process.c ++++ b/src/core/tasks/dim_core_measure_process/dim_core_measure_process.c +@@ -82,7 +82,7 @@ static bool vm_file_match_policy(struct file *vm_file, + return false; + } + +- if (ctx->mode == DIM_BASELINE) ++ if (ctx->mode == DIM_BASELINE || ctx->m->measure_only) + return dim_core_policy_match(DIM_POLICY_OBJ_BPRM_TEXT, + DIM_POLICY_KEY_PATH, ctx->path); + +diff --git a/src/measure/dim_measure.c b/src/measure/dim_measure.c +index cf59e92..cb9bb34 100644 +--- a/src/measure/dim_measure.c ++++ b/src/measure/dim_measure.c +@@ -44,18 +44,22 @@ int dim_measure_init(struct dim_measure *m, struct dim_measure_cfg *cfg) + } + + /* 3. init baseline data (static and dynamic) */ +- ret = dim_baseline_init_tree(cfg->sta_malloc, cfg->sta_free, +- &m->static_baseline); +- if (ret < 0) { +- dim_err("failed to init static baseline root: %d\n", ret); +- goto err; +- } +- +- ret = dim_baseline_init_tree(cfg->dyn_malloc, cfg->dyn_free, +- &m->dynamic_baseline); +- if (ret < 0) { +- dim_err("failed to init dynamic baseline root: %d\n", ret); +- goto err; ++ m->measure_only = cfg->measure_only; ++ /* for measure_only mode, no need to process baseline */ ++ if (!m->measure_only) { ++ ret = dim_baseline_init_tree(cfg->sta_malloc, cfg->sta_free, ++ &m->static_baseline); ++ if (ret < 0) { ++ dim_err("failed to init static baseline: %d\n", ret); ++ goto err; ++ } ++ ++ ret = dim_baseline_init_tree(cfg->dyn_malloc, cfg->dyn_free, ++ &m->dynamic_baseline); ++ if (ret < 0) { ++ dim_err("failed to init dynamic baseline: %d\n", ret); ++ goto err; ++ } + } + + /* 4. init measure log */ +@@ -71,6 +75,7 @@ int dim_measure_init(struct dim_measure *m, struct dim_measure_cfg *cfg) + + /* 6. set initial status */ + atomic_set(&m->status, MEASURE_STATUS_NO_BASELINE); ++ + return 0; + err: + dim_measure_destroy(m); +diff --git a/src/measure/dim_measure.h b/src/measure/dim_measure.h +index 4983103..d614f12 100644 +--- a/src/measure/dim_measure.h ++++ b/src/measure/dim_measure.h +@@ -35,6 +35,8 @@ enum dim_measure_status { + + /* the common configuration for measurement */ + struct dim_measure_cfg { ++ /* no baseline, only measure */ ++ bool measure_only; + /* hash algorithm for measurement */ + char *alg_name; + /* schedule time (ms) after one valid measurement */ +@@ -54,6 +56,8 @@ struct dim_measure_cfg { + + /* the dim measurement global handle */ + struct dim_measure { ++ /* no baseline, only measure */ ++ bool measure_only; + /* schedule time (jittfies) after one valid measurement */ + unsigned long schedule_jiffies; + /* lock to prevent concurrent measurement */ +diff --git a/src/measure/dim_measure_baseline.c b/src/measure/dim_measure_baseline.c +index 0b2c9ff..195fd5a 100644 +--- a/src/measure/dim_measure_baseline.c ++++ b/src/measure/dim_measure_baseline.c +@@ -196,6 +196,12 @@ int dim_measure_process_static_result(struct dim_measure *m, int mode, + !is_valid_mode(mode)) + return -EINVAL; + ++ /* For measure only mode, add measure log directly */ ++ if (m->measure_only) { ++ *log_flag = LOC_MEASURE; ++ return measure_log_add(m, name, digest, LOC_MEASURE); ++ } ++ + return mode == DIM_BASELINE ? + process_static_baseline(m, name, digest, log_flag) : + process_static_measure(m, name, digest, log_flag); +@@ -210,6 +216,10 @@ int dim_measure_process_dynamic_result(struct dim_measure *m, int mode, + !is_valid_mode(mode)) + return -EINVAL; + ++ /* For measure only mode, add measure log directly */ ++ if (m->measure_only) ++ return measure_log_add(m, name, digest, LOC_MEASURE); ++ + return mode == DIM_BASELINE ? + process_dynamic_baseline(m, name, digest, log_flag) : + process_dynamic_measure(m, name, digest, log_flag); +diff --git a/src/measure/dim_measure_task.c b/src/measure/dim_measure_task.c +index 632cb4d..50486e5 100644 +--- a/src/measure/dim_measure_task.c ++++ b/src/measure/dim_measure_task.c +@@ -42,7 +42,7 @@ void dim_measure_task_measure(int mode, struct dim_measure *m) + MEASURE_STATUS_BASELINE_RUNNING : + MEASURE_STATUS_MEASURE_RUNNING); + +- if (mode == DIM_BASELINE && m->baseline_prepare != NULL) { ++ if (mode == DIM_BASELINE) { + ret = m->baseline_prepare(m); + if (ret < 0) { + atomic_set(&m->status, MEASURE_STATUS_ERROR); +-- +2.43.0 + diff --git a/0005-Support-in-tree-kernel-compilation.patch b/0005-Support-in-tree-kernel-compilation.patch new file mode 100644 index 0000000..e83105c --- /dev/null +++ b/0005-Support-in-tree-kernel-compilation.patch @@ -0,0 +1,222 @@ +From 41e595796b5293c4cba7f625ed7ac0ed0e966eaf Mon Sep 17 00:00:00 2001 +From: Huaxin Lu +Date: Wed, 26 Nov 2025 19:17:08 +0800 +Subject: [PATCH 05/13] Support in-tree kernel compilation + +Support integrating DIM into the kernel image instead of as a +separate kernel module. + +Signed-off-by: Huaxin Lu +--- + src/Kconfig | 22 +++++++++++ + src/Makefile | 4 +- + src/Makefile.kernel | 49 ++++++++++++++++++++++++ + src/common/dim_entry.h | 5 +++ + src/common/dim_rot_virtcca.c | 5 ++- + src/common/dim_utils.h | 15 ++++++-- + src/core/dim_core_symbol.h | 6 ++- + src/core/tasks/dim_core_measure_kernel.c | 1 - + 8 files changed, 96 insertions(+), 11 deletions(-) + create mode 100644 src/Kconfig + create mode 100644 src/Makefile.kernel + +diff --git a/src/Kconfig b/src/Kconfig +new file mode 100644 +index 0000000..ba88aec +--- /dev/null ++++ b/src/Kconfig +@@ -0,0 +1,22 @@ ++config DIM_CORE ++ tristate "Dynamic Integrity Measurement (DIM) Core" ++ select SECURITYFS ++ select CRYPTO_SHA256 ++ select CRYPTO_HASH_INFO ++ default y ++ help ++ The Dynamic Integrity Measurement(DIM) Core maintains ++ a list of hash values of code segment of executables ++ files, as they are read only and executed. If an attacker ++ manages to change the contents of the code segment in ++ process, we can tell. ++ If your system has a TPM chip, then DIM Core also maintains ++ an aggregate integrity value over this list inside the ++ TPM hardware. ++ If unsure, say N. ++ ++config DIM_CORE_SIGNATURE_SUPPORT ++ bool "Enable signature verification in DIM Core" ++ depends on DIM_CORE ++ default n ++ select ASYMMETRIC_KEY_TYPE +diff --git a/src/Makefile b/src/Makefile +index ad2b1fe..df4c729 100644 +--- a/src/Makefile ++++ b/src/Makefile +@@ -8,10 +8,8 @@ dim_core-objs += core/dim_core_fs.o + dim_core-objs += core/dim_core_mem_pool.o + dim_core-objs += core/dim_core_measure.o + dim_core-objs += core/dim_core_symbol.o +-ifeq ($(DIM_CORE_SIGNATURE_SUPPORT), y) + dim_core-objs += core/dim_core_sig.o +-ccflags-y += -DDIM_CORE_SIGNATURE_SUPPORT +-endif ++ + dim_core-objs += core/tasks/dim_core_measure_kernel.o + dim_core-objs += core/tasks/dim_core_measure_module.o + dim_core-objs += core/tasks/dim_core_measure_process/dim_vm_hash.o +diff --git a/src/Makefile.kernel b/src/Makefile.kernel +new file mode 100644 +index 0000000..b293d95 +--- /dev/null ++++ b/src/Makefile.kernel +@@ -0,0 +1,49 @@ ++# Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved. ++ ++obj-$(CONFIG_DIM_CORE) += dim_core.o ++ ++dim_core-objs += core/dim_core_main.o ++dim_core-objs += core/dim_core_fs.o ++dim_core-objs += core/dim_core_mem_pool.o ++dim_core-objs += core/dim_core_measure.o ++dim_core-objs += core/dim_core_symbol.o ++dim_core-$(CONFIG_DIM_CORE_SIGNATURE_SUPPORT) += core/dim_core_sig.o ++ ++dim_core-objs += core/tasks/dim_core_measure_kernel.o ++dim_core-objs += core/tasks/dim_core_measure_module.o ++dim_core-objs += core/tasks/dim_core_measure_process/dim_vm_hash.o ++dim_core-objs += core/tasks/dim_core_measure_process/dim_core_measure_process.o ++dim_core-objs += core/tasks/dim_core_measure_process/dim_core_measure_process_vma.o ++ ++dim_core-objs += core/policy/dim_core_policy.o ++dim_core-objs += core/policy/dim_core_policy_complex.o ++ ++dim_core-objs += core/static_baseline/dim_core_static_baseline.o ++dim_core-objs += core/static_baseline/dim_core_static_baseline_complex.o ++ ++dim_core-objs += common/dim_entry.o ++dim_core-objs += common/dim_utils.o ++dim_core-objs += common/dim_baseline.o ++dim_core-objs += common/dim_hash.o ++dim_core-objs += common/dim_measure_log.o ++dim_core-objs += common/dim_rot.o ++dim_core-objs += common/dim_rot_tpm.o ++dim_core-objs += common/dim_rot_virtcca.o ++dim_core-objs += common/dim_symbol.o ++dim_core-objs += common/dim_safe_func.o ++dim_core-objs += measure/dim_measure.o ++dim_core-objs += measure/dim_measure_baseline.o ++dim_core-objs += measure/dim_measure_task.o ++dim_core-objs += measure/dim_measure_utils.o ++dim_core-objs += measure/dim_measure_status.o ++ ++ccflags-y := -I$(src)/core ++ccflags-y += -I$(src)/core/static_baseline ++ccflags-y += -I$(src)/core/tasks ++ccflags-y += -I$(src)/core/tasks/dim_core_measure_process ++ccflags-y += -I$(src)/core/policy ++ccflags-y += -I$(src)/monitor ++ccflags-y += -I$(src)/monitor/measure_task ++ccflags-y += -I$(src)/common ++ccflags-y += -I$(src)/measure ++ +diff --git a/src/common/dim_entry.h b/src/common/dim_entry.h +index 8a560bd..ff25708 100644 +--- a/src/common/dim_entry.h ++++ b/src/common/dim_entry.h +@@ -24,6 +24,11 @@ struct dim_entry { + struct dentry *dentry; + }; + ++#ifndef THIS_MODULE ++#define THIS_MODULE NULL ++#endif ++ ++ + /* the file interface for trigger by 'echo 1 > file_path' */ + #define dim_trigger_entry(sname, fname, function) \ + static ssize_t sname##_trigger(struct file *file, \ +diff --git a/src/common/dim_rot_virtcca.c b/src/common/dim_rot_virtcca.c +index 3400632..db3e4a9 100644 +--- a/src/common/dim_rot_virtcca.c ++++ b/src/common/dim_rot_virtcca.c +@@ -9,6 +9,9 @@ + #include + #include + ++#include "dim_hash.h" ++#include "dim_rot.h" ++ + #define DEFAULT_CCA_REM_IDX 4 + static enum hash_algo virtcca_algo; + static int dim_virtcca_enable = 0; +@@ -52,7 +55,7 @@ static int dim_virtcca_get_rem(struct dim_rot *rot) + return DEFAULT_CCA_REM_IDX; // TODO + } + +-static int dim_virtcca_extend(struct dim_digest *digests) ++static int dim_virtcca_extend(struct dim_rot *rot, struct dim_digest *digests) + { + struct virtcca_cvm_measurement_extend cme; + +diff --git a/src/common/dim_utils.h b/src/common/dim_utils.h +index 7d47ce0..4e8462e 100644 +--- a/src/common/dim_utils.h ++++ b/src/common/dim_utils.h +@@ -11,11 +11,18 @@ + #define DIM_ARRAY_LEN(ARR) (sizeof(ARR) / sizeof(ARR[0])) + #define DIM_MAX_FILE_SIZE (10 * 1024 * 1024) + +-#define dim_fmt(fmt) "%s: " fmt ++#define DIM_KERNEL "dim_kernel" ++ ++#ifdef CONFIG_MODULES ++#define DIM_FMT_FLAG (THIS_MODULE ? THIS_MODULE->name : DIM_KERNEL) ++#else ++#define DIM_FMT_FLAG DIM_KERNEL ++#endif + +-#define dim_err(fmt, ...) pr_err(dim_fmt(fmt), THIS_MODULE->name, ##__VA_ARGS__) +-#define dim_warn(fmt, ...) pr_warn(dim_fmt(fmt), THIS_MODULE->name, ##__VA_ARGS__) +-#define dim_info(fmt, ...) pr_info(dim_fmt(fmt), THIS_MODULE->name, ##__VA_ARGS__) ++#define dim_fmt(fmt) "%s: " fmt ++#define dim_err(fmt, ...) pr_err(dim_fmt(fmt), DIM_FMT_FLAG, ##__VA_ARGS__) ++#define dim_warn(fmt, ...) pr_warn(dim_fmt(fmt), DIM_FMT_FLAG, ##__VA_ARGS__) ++#define dim_info(fmt, ...) pr_info(dim_fmt(fmt), DIM_FMT_FLAG, ##__VA_ARGS__) + #define dim_devel(fmt, ...) + + int dim_get_absolute_path(const char *path, const char **result); +diff --git a/src/core/dim_core_symbol.h b/src/core/dim_core_symbol.h +index 2540041..3ac0d26 100644 +--- a/src/core/dim_core_symbol.h ++++ b/src/core/dim_core_symbol.h +@@ -17,11 +17,13 @@ typedef void (*DIM_WALK_PROCESS_TREE)(struct task_struct *, + typedef struct module *(*DIM_FIND_MODULE)(const char *); + typedef struct task_struct *(*DIM_FIND_GET_TASK_BY_VPID)(pid_t); + #endif +-#ifndef JUMP_LABEL_NOP_SIZE ++ ++#ifdef CONFIG_JUMP_LABEL ++ #ifndef JUMP_LABEL_NOP_SIZE + typedef int (*DIM_ARCH_JUMP_ENTRY_SIZE)(struct jump_entry *); ++ #endif + #endif + +- + struct dim_core_kallsyms { + char *stext; + char *etext; +diff --git a/src/core/tasks/dim_core_measure_kernel.c b/src/core/tasks/dim_core_measure_kernel.c +index 426b3cf..502817c 100644 +--- a/src/core/tasks/dim_core_measure_kernel.c ++++ b/src/core/tasks/dim_core_measure_kernel.c +@@ -143,7 +143,6 @@ static int calc_kernel_digest(struct dim_hash *hash, struct dim_digest *digest) + /* If kernel doesn't support jumplabel, calculate text directly */ + static int calc_kernel_digest(struct dim_hash *hash, struct dim_digest *digest) + { +- int ret = 0; + uintptr_t stext = (uintptr_t)dim_core_kernel_symbol.stext; + uintptr_t etext = (uintptr_t)dim_core_kernel_symbol.etext; + SHASH_DESC_ON_STACK(shash, hash->tfm); +-- +2.43.0 + diff --git a/0006-Support-TPM-boot-aggregate.patch b/0006-Support-TPM-boot-aggregate.patch new file mode 100644 index 0000000..bb05cdd --- /dev/null +++ b/0006-Support-TPM-boot-aggregate.patch @@ -0,0 +1,117 @@ +From 01f1935fcd403f2601b3528d3b2e9a583377e8f3 Mon Sep 17 00:00:00 2001 +From: Huaxin Lu +Date: Wed, 26 Nov 2025 20:22:51 +0800 +Subject: [PATCH 06/13] Support TPM boot aggregate + +Support to calculate TPM boot_aggregate as the first measure log. + +Signed-off-by: Huaxin Lu +--- + src/common/dim_rot_tpm.c | 69 ++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 66 insertions(+), 3 deletions(-) + +diff --git a/src/common/dim_rot_tpm.c b/src/common/dim_rot_tpm.c +index 18621b1..ec35154 100644 +--- a/src/common/dim_rot_tpm.c ++++ b/src/common/dim_rot_tpm.c +@@ -12,13 +12,17 @@ + #include "dim_utils.h" + + #define DIM_PCR_MAX 128 ++enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8, TPM_PCR10 = 10 }; + ++/* TPM chip instance */ + static struct tpm_chip *dim_tpm_chip = NULL; ++/* Buffer for TPM digest extending */ + struct tpm_digest *dim_tpm_digests = NULL; ++/* TPM algorithm bank */ + static int dim_tpm_bank = 0; ++/* TPM pcr index */ + static unsigned int dim_tpm_pcr = 0; + +-/* Parameter data is the pcr value */ + static int dim_tpm_init(struct dim_rot *rot, int algo, int pcr) + { + int ret = 0; +@@ -37,7 +41,8 @@ static int dim_tpm_init(struct dim_rot *rot, int algo, int pcr) + + dim_tpm_bank = -1; + for (i = 0; i < dim_tpm_chip->nr_allocated_banks; i++) { +- dim_tpm_digests[i].alg_id = dim_tpm_chip->allocated_banks[i].alg_id; ++ dim_tpm_digests[i].alg_id = ++ dim_tpm_chip->allocated_banks[i].alg_id; + if (dim_tpm_chip->allocated_banks[i].crypto_id == algo) + dim_tpm_bank = i; + +@@ -102,9 +107,67 @@ static void dim_tpm_destroy(struct dim_rot *rot) + dim_tpm_digests = NULL; + } + ++static int tpm_hash_algo(int algo) ++{ ++ int tpm_algo = -1; ++ ++ switch (algo) { ++ case HASH_ALGO_SHA256: ++ tpm_algo = TPM_ALG_SHA256; ++ break; ++ case HASH_ALGO_SM3_256: ++ tpm_algo = TPM_ALG_SM3_256; ++ break; ++ default: ++ break; ++ } ++ ++ return tpm_algo; ++} ++ ++static int dim_tpm_calc_boot_aggregate_tfm(struct dim_digest *digest, ++ struct crypto_shash *tfm) ++{ ++ int ret = 0; ++ int i = 0; ++ struct tpm_digest d = { 0 }; ++ SHASH_DESC_ON_STACK(shash, tfm); ++ ++ shash->tfm = tfm; ++ ret = crypto_shash_init(shash); ++ if (ret < 0) ++ return ret; ++ ++ /* cumulative digest over TPM registers 0-10 */ ++ d.alg_id = tpm_hash_algo(digest->algo); ++ for (i = TPM_PCR0; i < TPM_PCR10; i++) { ++ ret = tpm_pcr_read(dim_tpm_chip, i, &d); ++ if (ret < 0) ++ return ret; ++ ++ ret = crypto_shash_update(shash, d.digest, ++ crypto_shash_digestsize(tfm)); ++ if (ret < 0) ++ return ret; ++ } ++ ++ return crypto_shash_final(shash, digest->data); ++} ++ + static int dim_tpm_calc_boot_aggregate(struct dim_digest *digest) + { +- return -ENXIO; // TODO ++ int ret = 0; ++ struct crypto_shash *tfm = NULL; ++ ++ tfm = crypto_alloc_shash(dim_hash_name(digest->algo), 0, 0); ++ if (IS_ERR(tfm)) { ++ ret = PTR_ERR(tfm); ++ return ret; ++ } ++ ++ ret = dim_tpm_calc_boot_aggregate_tfm(digest, tfm); ++ crypto_free_shash(tfm); ++ return ret; + } + + struct dim_rot dim_rot_tpm = { +-- +2.43.0 + diff --git a/0007-Clean-code-and-bugfix.patch b/0007-Clean-code-and-bugfix.patch new file mode 100644 index 0000000..ec9d19e --- /dev/null +++ b/0007-Clean-code-and-bugfix.patch @@ -0,0 +1,580 @@ +From e4f4f44a367700bb8f12a98999c1002f8abda46a Mon Sep 17 00:00:00 2001 +From: Huaxin Lu +Date: Wed, 26 Nov 2025 21:52:05 +0800 +Subject: [PATCH 07/13] Clean code and bugfix + +Signed-off-by: Huaxin Lu +--- + src/common/dim_measure_log.c | 45 +++++++---- + src/common/dim_measure_log.h | 2 +- + src/common/dim_rot.c | 20 ++--- + src/common/dim_rot.h | 5 +- + src/common/dim_rot_tpm.c | 28 ++----- + src/common/dim_rot_virtcca.c | 78 ++++++++++--------- + src/common/dim_utils.h | 2 +- + src/core/dim_core_main.c | 13 ++-- + src/core/dim_core_sig.c | 5 +- + src/core/dim_core_symbol.c | 9 ++- + src/core/policy/dim_core_policy.c | 2 +- + .../dim_core_static_baseline.c | 4 + + src/measure/dim_measure.c | 2 +- + 13 files changed, 115 insertions(+), 100 deletions(-) + +diff --git a/src/common/dim_measure_log.c b/src/common/dim_measure_log.c +index 1397f7b..82435cd 100644 +--- a/src/common/dim_measure_log.c ++++ b/src/common/dim_measure_log.c +@@ -123,14 +123,20 @@ int dim_measure_log_seq_show_ascii(struct seq_file *m, + bin2hex(digest_buf, info->digest.data, + dim_digest_size(info->digest.algo)); + +- seq_printf(m, "%d %s %s %s:%s %s %s\n", ++ seq_printf(m, "%d %s %s %s:%s %s", + dim_rot_slot(), + log_digest_buf, + DIM_TEMPLATE, + dim_hash_name(info->digest.algo), + digest_buf, +- dim_measure_log_name(info), +- dim_measure_log_type_to_name(info->type)); ++ dim_measure_log_name(info)); ++ ++ /* Print the log flag */ ++ if (info->type == LOC_MEASURE) ++ seq_printf(m, "\n"); ++ else ++ seq_printf(m, " %s\n", ++ dim_measure_log_type_to_name(info->type)); + + return 0; + } +@@ -325,12 +331,28 @@ void dim_measure_log_destroy_tree(struct dim_measure_log_tree *root) + write_unlock(&root->lock); + } + +-int dim_measure_log_init_tree(struct dim_measure_log_tree *root, +- struct dim_hash *hash, unsigned int cap) ++static int calc_boot_aggregate(struct dim_measure_log_tree *root) + { + int ret = 0; +- struct dim_digest boot_aggregate = { 0 }; ++ struct dim_digest boot_aggregate = { ++ .algo = root->hash->algo, ++ }; ++ ++ ret = dim_calc_boot_aggregate(&boot_aggregate, root->hash); ++ if (ret < 0) ++ dim_warn("Failed to calculate boot_aggregate: %d\n", ret); ++ ++ ret = dim_measure_log_add(root, "boot_aggregate", ++ &boot_aggregate, LOC_MEASURE); ++ if (ret < 0) ++ dim_warn("Failed to add boot_aggregate log: %d\n", ret); ++ ++ return 0; ++} + ++int dim_measure_log_init_tree(struct dim_measure_log_tree *root, ++ struct dim_hash *hash, unsigned int cap) ++{ + if (root == NULL || hash == NULL) + return -EINVAL; + +@@ -339,15 +361,6 @@ int dim_measure_log_init_tree(struct dim_measure_log_tree *root, + root->hash = hash; + root->rb_root = RB_ROOT; + root->cap = cap; +- boot_aggregate.algo = hash->algo; + +- ret = dim_calc_boot_aggregate(&boot_aggregate); +- if (ret < 0) +- dim_warn("Failed to calculate boot_aggregate\n"); +- +- ret = dim_measure_log_add(root, "boot_aggregate", &boot_aggregate, LOG_STATIC_BASELINE); +- if (ret < 0) +- dim_err("Failed to add boot_aggregate\n"); +- +- return ret; ++ return calc_boot_aggregate(root); + } +diff --git a/src/common/dim_measure_log.h b/src/common/dim_measure_log.h +index 423ec99..a443264 100644 +--- a/src/common/dim_measure_log.h ++++ b/src/common/dim_measure_log.h +@@ -31,7 +31,7 @@ static const char *dim_measure_log_type_name[LOG_LAST] = { + [LOG_DYNAMIC_BASELINE] = "[dynamic baseline]", + [LOG_TAMPERED] = "[tampered]", + [LOG_MATCHED] = "[matched]", +- [LOC_MEASURE] = "[measure]" ++ [LOC_MEASURE] = "" /* No extra flag, keep consistent with IMA */ + }; + + struct dim_measure_log_tree { +diff --git a/src/common/dim_rot.c b/src/common/dim_rot.c +index d930c50..76992e4 100644 +--- a/src/common/dim_rot.c ++++ b/src/common/dim_rot.c +@@ -5,6 +5,7 @@ + #include "dim_utils.h" + #include "dim_rot.h" + ++/* Selected RoT device */ + static struct dim_rot *dim_rot_prefered = NULL; + + /* Support list: TPM, virtCCA */ +@@ -40,21 +41,20 @@ int dim_rot_init(const char *name, int algo, int slot) + } + + if (dim_rot_prefered == NULL) { +- /* If not find, use the default device */ +- dim_rot_prefered = dim_supported_rots[0]; + dim_info("Cannot find the specified RoT %s\n", + dim_rot_prefered->name); +- +- return -EINVAL; ++ return -ENODEV; + } + + ret = dim_rot_prefered->init(dim_rot_prefered, algo, slot); +- if (ret < 0) ++ if (ret < 0) { + dim_err("Failed to initialize RoT device %s: %d\n", + dim_rot_prefered->name, ret); +- else +- dim_info("Succeed to initialize RoT device %s\n", ++ dim_rot_prefered = NULL; ++ } else { ++ dim_info("Initialize RoT device: %s\n", + dim_rot_prefered->name); ++ } + + return ret; + } +@@ -67,12 +67,12 @@ int dim_rot_extend(struct dim_digest *digest) + return dim_rot_prefered->extend(dim_rot_prefered, digest); + } + +-int dim_calc_boot_aggregate(struct dim_digest *digest) ++int dim_calc_boot_aggregate(struct dim_digest *digest, struct dim_hash *hash) + { + if (dim_rot_prefered == NULL) +- return -ENXIO; ++ return -ENODEV; + +- return dim_rot_prefered->calc_boot_aggregate(digest); ++ return dim_rot_prefered->calc_boot_aggregate(digest, hash); + } + + void dim_rot_destroy(void) +diff --git a/src/common/dim_rot.h b/src/common/dim_rot.h +index f3f6a8b..f656ca9 100644 +--- a/src/common/dim_rot.h ++++ b/src/common/dim_rot.h +@@ -13,7 +13,8 @@ struct dim_rot { + void (*destroy)(struct dim_rot *rot); + int (*slot)(struct dim_rot *rot); + int (*extend)(struct dim_rot *rot, struct dim_digest *digest); +- int (*calc_boot_aggregate)(struct dim_digest *digest); ++ int (*calc_boot_aggregate)(struct dim_digest *digest, ++ struct dim_hash *hash); + }; + + #ifdef CONFIG_TCG_TPM +@@ -25,7 +26,7 @@ extern struct dim_rot dim_rot_virtcca; + + int dim_rot_init(const char *name, int algo, int slot); + int dim_rot_extend(struct dim_digest *digest); +-int dim_calc_boot_aggregate(struct dim_digest *digest); ++int dim_calc_boot_aggregate(struct dim_digest *digest, struct dim_hash *hash); + int dim_rot_slot(void); + void dim_rot_destroy(void); + +diff --git a/src/common/dim_rot_tpm.c b/src/common/dim_rot_tpm.c +index ec35154..8a84fd8 100644 +--- a/src/common/dim_rot_tpm.c ++++ b/src/common/dim_rot_tpm.c +@@ -12,7 +12,7 @@ + #include "dim_utils.h" + + #define DIM_PCR_MAX 128 +-enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8, TPM_PCR10 = 10 }; ++enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR10 = 10 }; + + /* TPM chip instance */ + static struct tpm_chip *dim_tpm_chip = NULL; +@@ -125,15 +125,15 @@ static int tpm_hash_algo(int algo) + return tpm_algo; + } + +-static int dim_tpm_calc_boot_aggregate_tfm(struct dim_digest *digest, +- struct crypto_shash *tfm) ++static int dim_tpm_calc_boot_aggregate(struct dim_digest *digest, ++ struct dim_hash *hash) + { + int ret = 0; + int i = 0; + struct tpm_digest d = { 0 }; +- SHASH_DESC_ON_STACK(shash, tfm); ++ SHASH_DESC_ON_STACK(shash, hash->tfm); + +- shash->tfm = tfm; ++ shash->tfm = hash->tfm; + ret = crypto_shash_init(shash); + if (ret < 0) + return ret; +@@ -146,7 +146,7 @@ static int dim_tpm_calc_boot_aggregate_tfm(struct dim_digest *digest, + return ret; + + ret = crypto_shash_update(shash, d.digest, +- crypto_shash_digestsize(tfm)); ++ dim_digest_size(digest->algo)); + if (ret < 0) + return ret; + } +@@ -154,22 +154,6 @@ static int dim_tpm_calc_boot_aggregate_tfm(struct dim_digest *digest, + return crypto_shash_final(shash, digest->data); + } + +-static int dim_tpm_calc_boot_aggregate(struct dim_digest *digest) +-{ +- int ret = 0; +- struct crypto_shash *tfm = NULL; +- +- tfm = crypto_alloc_shash(dim_hash_name(digest->algo), 0, 0); +- if (IS_ERR(tfm)) { +- ret = PTR_ERR(tfm); +- return ret; +- } +- +- ret = dim_tpm_calc_boot_aggregate_tfm(digest, tfm); +- crypto_free_shash(tfm); +- return ret; +-} +- + struct dim_rot dim_rot_tpm = { + .name = "tpm", + .init = dim_tpm_init, +diff --git a/src/common/dim_rot_virtcca.c b/src/common/dim_rot_virtcca.c +index db3e4a9..5076e0b 100644 +--- a/src/common/dim_rot_virtcca.c ++++ b/src/common/dim_rot_virtcca.c +@@ -9,13 +9,20 @@ + #include + #include + ++#include "dim_utils.h" + #include "dim_hash.h" + #include "dim_rot.h" + +-#define DEFAULT_CCA_REM_IDX 4 ++#define DIM_VIRTCCA_REM 4 ++ ++/* Algorithm of virtCCA */ + static enum hash_algo virtcca_algo; +-static int dim_virtcca_enable = 0; +-static int dim_virtcca_init_algo(int algo) ++/* Enable flag of virtCCA */ ++static int virtcca_enable = 0; ++/* virtCCA REM index */ ++static int virtcca_rem_idx = 0; ++ ++static int dim_virtcca_init_algo(void) + { + unsigned long result; + struct virtcca_cvm_config cfg = { 0 }; +@@ -27,72 +34,71 @@ static int dim_virtcca_init_algo(int algo) + } + + /* 0: SHA256, 1: SHA512 */ +- virtcca_algo = cfg.algorithm ? HASH_ALGO_SHA512 : HASH_ALGO_SHA256; +- ++ virtcca_algo = cfg.algorithm ? HASH_ALGO_SHA512 : ++ HASH_ALGO_SHA256; + return 0; + } + +-static int dim_virtcca_init(struct dim_rot *rot, int algo, int rem) // TODO ++static int dim_virtcca_init(struct dim_rot *rot, int algo, int rem) + { +- int rc; ++ int ret = 0; + +- if (!is_virtcca_cvm_world() || tsi_get_version() == SMCCC_RET_NOT_SUPPORTED) ++ if (!is_virtcca_cvm_world() || ++ tsi_get_version() == SMCCC_RET_NOT_SUPPORTED) + return -ENODEV; + +- rc = dim_virtcca_init_algo(virtcca_algo); +- if (rc) +- return rc; ++ if (rem != DIM_VIRTCCA_REM) { ++ dim_warn("Now DIM can only use REM4, reset the REM index\n"); ++ virtcca_rem_idx = DIM_VIRTCCA_REM; ++ } + +- dim_virtcca_enable = 1; ++ ret = dim_virtcca_init_algo(); ++ if (ret < 0) ++ return ret; ++ ++ virtcca_enable = 1; ++ virtcca_rem_idx = rem; + return 0; + } + + static int dim_virtcca_get_rem(struct dim_rot *rot) + { +- if (dim_virtcca_enable == 0) ++ if (virtcca_enable == 0) + return 0; + +- return DEFAULT_CCA_REM_IDX; // TODO ++ return virtcca_rem_idx; + } + +-static int dim_virtcca_extend(struct dim_rot *rot, struct dim_digest *digests) ++static int dim_virtcca_extend(struct dim_rot *rot, struct dim_digest *digest) + { +- struct virtcca_cvm_measurement_extend cme; ++ struct virtcca_cvm_measurement_extend cme = { 0 }; + +- if (dim_virtcca_enable == 0) +- return -EINVAL; ++ if (virtcca_enable == 0) ++ return 0; + +- // Now, in virtCCA, DIM can only use REM4 +- cme.index = DEFAULT_CCA_REM_IDX; ++ cme.index = virtcca_rem_idx; + cme.size = hash_digest_size[virtcca_algo]; +- +- /* +- * virtcca has only one slot, so the algorithm of digests_arg[0] is always +- * virtcca_algo according to the init process of ima_init_crypto() and +- * ima_init_digets() +- */ +- memcpy(cme.value, digests[0].data, cme.size); ++ memcpy(cme.value, digest->data, dim_digest_size(digest->algo)); + + return tsi_measurement_extend(&cme) == TSI_SUCCESS ? 0 : -EFAULT; + } + +-static int dim_virtcca_calc_boot_aggregate(struct dim_digest *digest) ++static int dim_virtcca_calc_boot_aggregate(struct dim_digest *digest, ++ struct dim_hash *hash) + { +- unsigned long result; +- struct virtcca_cvm_measurement cm = { 0 }; +- +- digest->algo = virtcca_algo; ++ unsigned long result = 0; ++ struct virtcca_cvm_measurement cm = { ++ .index = RIM_MEASUREMENT_SLOT, ++ }; + + /* Read the measurement result of RIM as the boot aggregate */ +- +- cm.index = RIM_MEASUREMENT_SLOT; +- + result = tsi_measurement_read(&cm); + if (result != TSI_SUCCESS) { +- pr_err("Error reading cvm measurement 0 for boot aggregate\n"); ++ pr_err("Failed to read RIM 0 for boot aggregate\n"); + return -EFAULT; + } + ++ digest->algo = virtcca_algo; + memcpy(digest->data, cm.value, dim_digest_size(virtcca_algo)); + return 0; + } +diff --git a/src/common/dim_utils.h b/src/common/dim_utils.h +index 4e8462e..d81cdcc 100644 +--- a/src/common/dim_utils.h ++++ b/src/common/dim_utils.h +@@ -14,7 +14,7 @@ + #define DIM_KERNEL "dim_kernel" + + #ifdef CONFIG_MODULES +-#define DIM_FMT_FLAG (THIS_MODULE ? THIS_MODULE->name : DIM_KERNEL) ++#define DIM_FMT_FLAG (THIS_MODULE->name) + #else + #define DIM_FMT_FLAG DIM_KERNEL + #endif +diff --git a/src/core/dim_core_main.c b/src/core/dim_core_main.c +index 5c8636d..d214697 100644 +--- a/src/core/dim_core_main.c ++++ b/src/core/dim_core_main.c +@@ -11,7 +11,7 @@ + #include "dim_core_fs.h" + #include "dim_core_measure.h" + #include "dim_core_mem_pool.h" +-#ifdef DIM_CORE_SIGNATURE_SUPPORT ++#ifdef CONFIG_DIM_CORE_SIGNATURE_SUPPORT + #include "dim_core_sig.h" + #endif + +@@ -41,13 +41,14 @@ MODULE_PARM_DESC(measure_only, "Only do measurement, no verification"); + + /* special measurement configuration for dim_core */ + static unsigned int measure_interval = 0; +-static bool signature = false; +- + module_param(measure_interval, uint, 0); + MODULE_PARM_DESC(measure_interval, "Interval time (min) for automatic measurement"); + ++#ifdef CONFIG_DIM_CORE_SIGNATURE_SUPPORT ++static bool signature = false; + module_param(signature, bool, 0); + MODULE_PARM_DESC(signature, "Require signature for policy and static baseline"); ++#endif + + static int __init dim_core_init(void) + { +@@ -64,7 +65,7 @@ static int __init dim_core_init(void) + dim_err("failed to initialize dim memory pool: %d\n", ret); + goto err; + } +-#ifdef DIM_CORE_SIGNATURE_SUPPORT ++#ifdef CONFIG_DIM_CORE_SIGNATURE_SUPPORT + if (signature) { + ret = dim_core_sig_init(); + if (ret < 0) { +@@ -90,7 +91,7 @@ err: + dim_core_destroy_fs(); + dim_core_measure_destroy(); + dim_mem_pool_destroy(); +-#ifdef DIM_CORE_SIGNATURE_SUPPORT ++#ifdef CONFIG_DIM_CORE_SIGNATURE_SUPPORT + if (signature) + dim_core_sig_destroy(); + #endif +@@ -102,7 +103,7 @@ static void __exit dim_core_exit(void) + dim_core_destroy_fs(); + dim_core_measure_destroy(); + dim_mem_pool_destroy(); +-#ifdef DIM_CORE_SIGNATURE_SUPPORT ++#ifdef CONFIG_DIM_CORE_SIGNATURE_SUPPORT + if (signature) + dim_core_sig_destroy(); + #endif +diff --git a/src/core/dim_core_sig.c b/src/core/dim_core_sig.c +index 5520656..643471e 100644 +--- a/src/core/dim_core_sig.c ++++ b/src/core/dim_core_sig.c +@@ -9,6 +9,7 @@ + #include + #include + #include ++#include + + #include "dim_hash.h" + #include "dim_utils.h" +@@ -62,7 +63,7 @@ static int dim_core_sig_verify(const char *buf, loff_t buf_len, + return verify_signature(dim_core_key, &key_sig); + } + +-int dim_read_file(struct path *root, const char *name, void **buf) ++int dim_read_verify_file(struct path *root, const char *name, void **buf) + { + int ret = 0; + char *sig_name = NULL; +@@ -124,7 +125,7 @@ int dim_core_sig_init(void) + } + + ret = kernel_read_file_from_path(DIM_CORE_CERT_PATH, 0, &data, +- DIM_CORE_MAX_FILE_SIZE, NULL, ++ DIM_MAX_FILE_SIZE, NULL, + READING_X509_CERTIFICATE); + if (ret < 0) { + dim_err("failed to read DIM cert file: %ld\n", ret); +diff --git a/src/core/dim_core_symbol.c b/src/core/dim_core_symbol.c +index 7e4b88a..5085e85 100644 +--- a/src/core/dim_core_symbol.c ++++ b/src/core/dim_core_symbol.c +@@ -3,7 +3,9 @@ + */ + + #include ++#ifdef CONFIG_JUMP_LABEL + #include ++#endif + + #include "dim_symbol.h" + #include "dim_utils.h" +@@ -17,8 +19,7 @@ int dim_core_kallsyms_init(void) + struct dim_core_kallsyms *k = &dim_core_kernel_symbol; + DIM_SYMBOL_LOOKUP_FUNC dim_kallsyms_lookup_name = NULL; + +- if (memset(k, 0, +- sizeof(struct dim_core_kallsyms)) != k) ++ if (memset(k, 0, sizeof(struct dim_core_kallsyms)) != k) + return -EINVAL; + + dim_kallsyms_lookup_name = dim_get_symbol_lookup_func(); +@@ -26,8 +27,10 @@ int dim_core_kallsyms_init(void) + dim_err("failed to get symbol_lookup_func\n"); + return -EINVAL; + } ++ + k->stext = (char *)dim_kallsyms_lookup_name("_stext"); + k->etext = (char *)dim_kallsyms_lookup_name("_etext"); ++ + #ifdef CONFIG_JUMP_LABEL + k->start_jump_table = (struct jump_entry *) + dim_kallsyms_lookup_name("__start___jump_table"); +@@ -38,8 +41,10 @@ int dim_core_kallsyms_init(void) + k->jump_label_unlock = (DIM_JUMP_LABEL_UNLOCK) + dim_kallsyms_lookup_name("jump_label_unlock"); + #endif ++ + k->walk_process_tree = (DIM_WALK_PROCESS_TREE) + dim_kallsyms_lookup_name("walk_process_tree"); ++ + #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 4, 0) + #ifdef CONFIG_MODULES + k->find_module = (DIM_FIND_MODULE) +diff --git a/src/core/policy/dim_core_policy.c b/src/core/policy/dim_core_policy.c +index e59c778..a72bd6a 100644 +--- a/src/core/policy/dim_core_policy.c ++++ b/src/core/policy/dim_core_policy.c +@@ -174,7 +174,7 @@ int dim_core_policy_load(void) + + if (!RB_EMPTY_ROOT(&policy_root)) + dim_core_policy_destroy(); +-#ifdef DIM_CORE_SIGNATURE_SUPPORT ++#ifdef CONFIG_DIM_CORE_SIGNATURE_SUPPORT + ret = dim_read_verify_file(NULL, DIM_POLICY_PATH, &buf); + #else + ret = dim_read_file(NULL, DIM_POLICY_PATH, &buf); +diff --git a/src/core/static_baseline/dim_core_static_baseline.c b/src/core/static_baseline/dim_core_static_baseline.c +index 74fc029..f723b31 100644 +--- a/src/core/static_baseline/dim_core_static_baseline.c ++++ b/src/core/static_baseline/dim_core_static_baseline.c +@@ -147,7 +147,11 @@ int dim_core_static_baseline_load(struct dim_measure *m) + filp_close(file, NULL); + + list_for_each_entry_safe(entry, tmp, &ctx.name_list, list) { ++#ifdef CONFIG_DIM_CORE_SIGNATURE_SUPPORT ++ ret = dim_read_verify_file(&kpath, entry->name, &buf); ++#else + ret = dim_read_file(&kpath, entry->name, &buf); ++#endif + if (ret < 0 || buf == NULL) { + dim_err("failed to read and verify %s: %d\n", entry->name, ret); + dim_kfree(entry); +diff --git a/src/measure/dim_measure.c b/src/measure/dim_measure.c +index cb9bb34..88da758 100644 +--- a/src/measure/dim_measure.c ++++ b/src/measure/dim_measure.c +@@ -45,7 +45,7 @@ int dim_measure_init(struct dim_measure *m, struct dim_measure_cfg *cfg) + + /* 3. init baseline data (static and dynamic) */ + m->measure_only = cfg->measure_only; +- /* for measure_only mode, no need to process baseline */ ++ /* for measure_only mode, no need to process baseline data */ + if (!m->measure_only) { + ret = dim_baseline_init_tree(cfg->sta_malloc, cfg->sta_free, + &m->static_baseline); +-- +2.43.0 + diff --git a/0008-Support-kernel-boot-parameter.patch b/0008-Support-kernel-boot-parameter.patch new file mode 100644 index 0000000..882c4ef --- /dev/null +++ b/0008-Support-kernel-boot-parameter.patch @@ -0,0 +1,87 @@ +From b7f2693d869e8310628d144387c92cb77f59f382 Mon Sep 17 00:00:00 2001 +From: Huaxin Lu +Date: Thu, 27 Nov 2025 18:45:12 +0800 +Subject: [PATCH] Support kernel boot parameter + +When DIM is compiled into kernel image, the module parameter should +be changed to kernel boot parameter. + +Signed-off-by: Huaxin Lu +Signed-off-by: xuce +--- + src/core/dim_core_main.c | 32 ++++++++++++++++++++++++++++++++ + 1 file changed, 32 insertions(+) + +diff --git a/src/core/dim_core_main.c b/src/core/dim_core_main.c +index d214697..c54041e 100644 +--- a/src/core/dim_core_main.c ++++ b/src/core/dim_core_main.c +@@ -21,33 +21,65 @@ static struct dim_measure_cfg cfg = { + .log_cap = DIM_CORE_LOG_CAP_DEFAULT, + }; + ++#ifdef MODULE + module_param_named(measure_log_capacity, cfg.log_cap, uint, 0); + MODULE_PARM_DESC(measure_log_capacity, "Max number of measure log"); ++#else ++core_param(dim_measure_log_capacity, cfg.log_cap, uint, 0); ++#endif + ++#ifdef MODULE + module_param_named(measure_schedule, cfg.schedule_ms, uint, 0); + MODULE_PARM_DESC(measure_schedule, "Schedule time (ms) for each measure object"); ++#else ++core_param(dim_measure_schedule, cfg.schedule_ms, uint, 0); ++#endif + ++#ifdef MODULE + module_param_named(measure_hash, cfg.alg_name, charp, 0); + MODULE_PARM_DESC(measure_hash, "Hash algorithm for measurement"); ++#else ++core_param(dim_measure_hash, cfg.alg_name, charp, 0); ++#endif + ++#ifdef MODULE + module_param_named(measure_pcr, cfg.pcr, uint, 0); + MODULE_PARM_DESC(measure_pcr, "TPM PCR index to extend measure log"); ++#else ++core_param(dim_measure_pcr, cfg.pcr, uint, 0); ++#endif + ++#ifdef MODULE + module_param_named(measure_rot, cfg.rot, charp, 0); + MODULE_PARM_DESC(measure_rot, "Rot device to extend measure log"); ++#else ++core_param(dim_measure_rot, cfg.rot, charp, 0); ++#endif + ++#ifdef MODULE + module_param_named(measure_only, cfg.measure_only, bool, 0); + MODULE_PARM_DESC(measure_only, "Only do measurement, no verification"); ++#else ++core_param(dim_measure_only, cfg.measure_only, bool, 0); ++#endif + + /* special measurement configuration for dim_core */ + static unsigned int measure_interval = 0; ++#ifdef MODULE + module_param(measure_interval, uint, 0); + MODULE_PARM_DESC(measure_interval, "Interval time (min) for automatic measurement"); ++#else ++core_param(dim_measure_interval, measure_interval, uint, 0); ++#endif + + #ifdef CONFIG_DIM_CORE_SIGNATURE_SUPPORT + static bool signature = false; ++ #ifdef MODULE + module_param(signature, bool, 0); + MODULE_PARM_DESC(signature, "Require signature for policy and static baseline"); ++ #else ++core_param(dim_signature, signature, bool, 0); ++ #endif + #endif + + static int __init dim_core_init(void) +-- +2.43.0 + diff --git a/0009-Dont-check-pcr-value-when-init-RoT-device.patch b/0009-Dont-check-pcr-value-when-init-RoT-device.patch new file mode 100644 index 0000000..704271a --- /dev/null +++ b/0009-Dont-check-pcr-value-when-init-RoT-device.patch @@ -0,0 +1,35 @@ +From 7d481b9b8142bc453a9238a00df70af49bc51263 Mon Sep 17 00:00:00 2001 +From: Huaxin Lu +Date: Thu, 27 Nov 2025 18:49:42 +0800 +Subject: [PATCH 09/13] Dont check pcr value when init RoT device + +Now we support the measure_rot parameter to set RoT device. So +remove the redundant check. + +Signed-off-by: Huaxin Lu +--- + src/measure/dim_measure.c | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +diff --git a/src/measure/dim_measure.c b/src/measure/dim_measure.c +index 88da758..9b0a213 100644 +--- a/src/measure/dim_measure.c ++++ b/src/measure/dim_measure.c +@@ -37,11 +37,9 @@ int dim_measure_init(struct dim_measure *m, struct dim_measure_cfg *cfg) + } + + /* 2. init RoT, dont break if init fail */ +- if (cfg->pcr > 0) { +- ret = dim_rot_init(cfg->rot, HASH_ALGO_SHA256, cfg->pcr); +- if (ret < 0) +- dim_warn("failed to init RoT device: %d\n", ret); +- } ++ ret = dim_rot_init(cfg->rot, HASH_ALGO_SHA256, cfg->pcr); ++ if (ret < 0) ++ dim_warn("failed to init RoT device: %d\n", ret); + + /* 3. init baseline data (static and dynamic) */ + m->measure_only = cfg->measure_only; +-- +2.43.0 + diff --git a/0010-Optimize-configurations-related-to-kernel-modules.patch b/0010-Optimize-configurations-related-to-kernel-modules.patch new file mode 100644 index 0000000..f1b9187 --- /dev/null +++ b/0010-Optimize-configurations-related-to-kernel-modules.patch @@ -0,0 +1,80 @@ +From 6d67aae46c83d23687e60be7774289ed980064b8 Mon Sep 17 00:00:00 2001 +From: Huaxin Lu +Date: Thu, 27 Nov 2025 19:00:42 +0800 +Subject: [PATCH 10/13] Optimize configurations related to kernel modules + +Signed-off-by: Huaxin Lu +--- + src/common/dim_utils.h | 2 +- + src/core/dim_core_measure.c | 2 ++ + src/core/tasks/dim_core_measure_module.c | 10 +++------- + 3 files changed, 6 insertions(+), 8 deletions(-) + +diff --git a/src/common/dim_utils.h b/src/common/dim_utils.h +index d81cdcc..00cec59 100644 +--- a/src/common/dim_utils.h ++++ b/src/common/dim_utils.h +@@ -13,7 +13,7 @@ + + #define DIM_KERNEL "dim_kernel" + +-#ifdef CONFIG_MODULES ++#ifdef MODULE + #define DIM_FMT_FLAG (THIS_MODULE->name) + #else + #define DIM_FMT_FLAG DIM_KERNEL +diff --git a/src/core/dim_core_measure.c b/src/core/dim_core_measure.c +index 8bc39fc..60cedf7 100644 +--- a/src/core/dim_core_measure.c ++++ b/src/core/dim_core_measure.c +@@ -14,7 +14,9 @@ + static struct dim_measure_task *dim_core_tasks[] = { + &dim_core_measure_task_user_text, + &dim_core_measure_task_kernel_text, ++#ifdef CONFIG_MODULES + &dim_core_measure_task_module_text, ++#endif + }; + + /* the global measurement handle */ +diff --git a/src/core/tasks/dim_core_measure_module.c b/src/core/tasks/dim_core_measure_module.c +index 21b6d60..d255413 100644 +--- a/src/core/tasks/dim_core_measure_module.c ++++ b/src/core/tasks/dim_core_measure_module.c +@@ -1,6 +1,7 @@ + /* + * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved. + */ ++#ifdef CONFIG_MODULES + + #include + #include +@@ -16,7 +17,6 @@ + + #include "dim_core_measure_task.h" + +-#ifdef CONFIG_MODULES + struct module_text_measure_ctx { + struct dim_measure *m; + int mode; +@@ -109,15 +109,11 @@ static int module_text_measure(int mode, struct dim_measure *m) + return dim_core_policy_walk(measure_module, &ctx); + } + +-#endif +- + struct dim_measure_task dim_core_measure_task_module_text = { + .name = "dim_core_measure_task_module_text", + .init = NULL, + .destroy = NULL, +-#ifdef CONFIG_MODULES + .measure = module_text_measure, +-#else +- .measure = NULL, +-#endif + }; ++ ++#endif +-- +2.43.0 + diff --git a/0011-Free-pre-allocated-pages-in-error-branch.patch b/0011-Free-pre-allocated-pages-in-error-branch.patch new file mode 100644 index 0000000..6946f1f --- /dev/null +++ b/0011-Free-pre-allocated-pages-in-error-branch.patch @@ -0,0 +1,25 @@ +From 49748f76441430fcecd4c2181533aae980e45377 Mon Sep 17 00:00:00 2001 +From: Huaxin Lu +Date: Thu, 27 Nov 2025 20:00:46 +0800 +Subject: [PATCH 11/13] Free pre-allocated pages in error branch + +Signed-off-by: Huaxin Lu +--- + src/core/dim_core_mem_pool.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/core/dim_core_mem_pool.c b/src/core/dim_core_mem_pool.c +index a9f0177..8575f8c 100644 +--- a/src/core/dim_core_mem_pool.c ++++ b/src/core/dim_core_mem_pool.c +@@ -30,6 +30,7 @@ static int dim_mem_pool_expand(unsigned int order) + ret = gen_pool_add(dim_pool, pages_addr, size, -1); + if (ret < 0) { + dim_err("failed to add pages to memory pool: %d\n", ret); ++ __free_pages(pages, order); + return ret; + } + +-- +2.43.0 + diff --git a/0012-Set-the-digest-length-to-SHA1-in-binary-measure-log.patch b/0012-Set-the-digest-length-to-SHA1-in-binary-measure-log.patch new file mode 100644 index 0000000..75f943e --- /dev/null +++ b/0012-Set-the-digest-length-to-SHA1-in-binary-measure-log.patch @@ -0,0 +1,33 @@ +From a21c333edc0d05ed87c000700f439479b65e7bf4 Mon Sep 17 00:00:00 2001 +From: Huaxin Lu +Date: Thu, 27 Nov 2025 20:05:47 +0800 +Subject: [PATCH 12/13] Set the digest length to SHA1 in binary measure log + +Signed-off-by: Huaxin Lu +--- + src/common/dim_measure_log.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/src/common/dim_measure_log.c b/src/common/dim_measure_log.c +index 82435cd..24664aa 100644 +--- a/src/common/dim_measure_log.c ++++ b/src/common/dim_measure_log.c +@@ -76,8 +76,13 @@ int dim_measure_log_seq_show_binary(struct seq_file *m, + pcr = dim_rot_slot(); + dim_putc(m, &pcr, sizeof(pcr)); + +- /* template digest */ +- dim_putc(m, &info->log_digest.data, dim_digest_size(HASH_ALGO_SHA256)); ++ /* template digest ++ * Note: This length does not match the actual value. It is currently ++ * specified as SHA1 for compatibility with some remote attestation ++ * tools. However, the digest value of the measurement log is not ++ * actually used in the attestation. ++ * */ ++ dim_putc(m, &info->log_digest.data, dim_digest_size(HASH_ALGO_SHA1)); + + /* template name */ + len = strlen(DIM_TEMPLATE); +-- +2.43.0 + diff --git a/0013-Add-missing-header.patch b/0013-Add-missing-header.patch new file mode 100644 index 0000000..159299a --- /dev/null +++ b/0013-Add-missing-header.patch @@ -0,0 +1,25 @@ +From e396130a0469177ceced07965a41ea1c040a798b Mon Sep 17 00:00:00 2001 +From: Huaxin Lu +Date: Thu, 27 Nov 2025 20:43:04 +0800 +Subject: [PATCH 13/13] Add missing header + +--- + src/measure/dim_measure_utils.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/measure/dim_measure_utils.c b/src/measure/dim_measure_utils.c +index 049d362..1faa8d8 100644 +--- a/src/measure/dim_measure_utils.c ++++ b/src/measure/dim_measure_utils.c +@@ -2,6 +2,8 @@ + * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved. + */ + ++#include ++ + #include "dim_measure.h" + + void dim_measure_schedule(struct dim_measure *m) +-- +2.43.0 + diff --git a/dim.spec b/dim.spec index 088db9e..290e616 100644 --- a/dim.spec +++ b/dim.spec @@ -22,7 +22,7 @@ mv $module_path/dim_monitor.ko.sig $module_path/dim_monitor.ko ||: \ Name : dim Summary : Dynamic Integrity Measurement Version : 1.0.2 -Release : 10 +Release : 11 License : GPL-2.0 Source0 : %{name}-v%{version}.tar.gz BuildRequires: kernel-devel kernel-headers @@ -81,6 +81,20 @@ Patch0051: backport-add-parameter-check.patch Patch0052: backport-Fix-deadlock-issue-in-directory-iterating.patch Patch0053: backport-Optimized-directory-suffix-matching.patch Patch0054: backport-Resolved-the-problem-that-the-jump_label_lock-isrepe.patch +Patch0055: 0001-Support-virtcca.patch +Patch0056: 0002-Add-macros-to-support-kernels-with-different-compila.patch +Patch0057: 0003-Support-remote-attestation.patch +Patch0058: 0004-Support-measure-only-mode.patch +Patch0059: 0005-Support-in-tree-kernel-compilation.patch +Patch0060: 0006-Support-TPM-boot-aggregate.patch +Patch0061: 0007-Clean-code-and-bugfix.patch +Patch0062: 0008-Support-kernel-boot-parameter.patch +Patch0063: 0009-Dont-check-pcr-value-when-init-RoT-device.patch +Patch0064: 0010-Optimize-configurations-related-to-kernel-modules.patch +Patch0065: 0011-Free-pre-allocated-pages-in-error-branch.patch +Patch0066: 0012-Set-the-digest-length-to-SHA1-in-binary-measure-log.patch +Patch0067: 0013-Add-missing-header.patch +Patch0068: 0001-fix-some-build-errors.patch %description Dynamic Integrity Measurement @@ -119,6 +133,9 @@ rm -rf %{buildroot} %attr(0400,root,root) /lib/modules/%{kernel_version}/extra/dim/dim_monitor.ko %changelog +* Wed Dec 17 2025 xuce 1.0.2-11 +- backport some patches to support dim rot/measure only/binary log + * Wed Feb 5 2025 steven.ygui 1.0.2-10 - add signature and backport some patches -- Gitee