Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

tsm-mr: Add tsm-mr sample code

This sample kernel module demonstrates how to make MRs accessible to user
mode through the tsm-mr library.

Once loaded, this module registers a `miscdevice` that host a set of
emulated measurement registers as shown in the directory tree below.

/sys/class/misc/tsm_mr_sample
└── measurements
├── config_mr
├── report_digest:sha512
├── rtmr0:sha256
├── rtmr1:sha384
├── rtmr_crypto_agile:sha256
├── rtmr_crypto_agile:sha384
└── static_mr:sha384

Among the MRs in this example:

- `config_mr` demonstrates a hashless MR, like MRCONFIGID in Intel TDX or
HOSTDATA in AMD SEV.
- `static_mr` demonstrates a static MR. The suffix `:sha384` indicates its
value is a sha384 digest.
- `rtmr0` is an RTMR with `TSM_MR_F_WRITABLE` **cleared**, preventing
direct extensions; as a result, the attribute `rtmr0:sha256` is
read-only.
- `rtmr1` is an RTMR with `TSM_MR_F_WRITABLE` **set**, permitting direct
extensions; thus, the attribute `rtmr1:sha384` is writable.
- `rtmr_crypto_agile` demonstrates a "single" MR that supports multiple
hash algorithms. Each supported algorithm has a corresponding digest,
usually referred to as a "bank" in TCG terminology. In this specific
sample, the 2 banks are aliased to `rtmr0` and `rtmr1`, respectively.
- `report_digest` contains the digest of the internal report structure
living in this sample module's memory. It is to demonstrate the use of
the `TSM_MR_F_LIVE` flag. Its value changes each time an RTMR is
extended.

Signed-off-by: Cedric Xing <cedric.xing@intel.com>
Reviewed-by: Dan Williams <dan.j.williams@intel.com>
Acked-by: Dionna Amalie Glaze <dionnaglaze@google.com>
Link: https://patch.msgid.link/20250506-tdx-rtmr-v6-2-ac6ff5e9d58a@intel.com
Signed-off-by: Dan Williams <dan.j.williams@intel.com>

authored by

Cedric Xing and committed by
Dan Williams
f6953f1f b9e22b35

+146
+1
MAINTAINERS
··· 24651 24651 F: Documentation/driver-api/coco/ 24652 24652 F: drivers/virt/coco/tsm*.c 24653 24653 F: include/linux/tsm*.h 24654 + F: samples/tsm/ 24654 24655 24655 24656 TRUSTED SERVICES TEE DRIVER 24656 24657 M: Balint Dobszay <balint.dobszay@arm.com>
+11
samples/Kconfig
··· 184 184 bool "Timer sample" 185 185 depends on CC_CAN_LINK && HEADERS_INSTALL 186 186 187 + config SAMPLE_TSM_MR 188 + tristate "TSM measurement sample" 189 + select TSM_MEASUREMENTS 190 + select VIRT_DRIVERS 191 + help 192 + Build a sample module that emulates MRs (Measurement Registers) and 193 + exposes them to user mode applications through the TSM sysfs 194 + interface (/sys/class/misc/tsm_mr_sample/emulated_mr/). 195 + 196 + The module name will be tsm-mr-sample when built as a module. 197 + 187 198 config SAMPLE_UHID 188 199 bool "UHID sample" 189 200 depends on CC_CAN_LINK && HEADERS_INSTALL
+1
samples/Makefile
··· 43 43 obj-$(CONFIG_SAMPLE_DAMON_WSSE) += damon/ 44 44 obj-$(CONFIG_SAMPLE_DAMON_PRCL) += damon/ 45 45 obj-$(CONFIG_SAMPLE_HUNG_TASK) += hung_task/ 46 + obj-$(CONFIG_SAMPLE_TSM_MR) += tsm-mr/
+2
samples/tsm-mr/Makefile
··· 1 + # SPDX-License-Identifier: GPL-2.0-only 2 + obj-$(CONFIG_SAMPLE_TSM_MR) += tsm_mr_sample.o
+131
samples/tsm-mr/tsm_mr_sample.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* Copyright(c) 2024-2005 Intel Corporation. All rights reserved. */ 3 + 4 + #define pr_fmt(x) KBUILD_MODNAME ": " x 5 + 6 + #include <linux/module.h> 7 + #include <linux/tsm-mr.h> 8 + #include <linux/miscdevice.h> 9 + #include <crypto/hash.h> 10 + 11 + struct { 12 + u8 static_mr[SHA384_DIGEST_SIZE]; 13 + u8 config_mr[SHA512_DIGEST_SIZE]; 14 + u8 rtmr0[SHA256_DIGEST_SIZE]; 15 + u8 rtmr1[SHA384_DIGEST_SIZE]; 16 + u8 report_digest[SHA512_DIGEST_SIZE]; 17 + } sample_report = { 18 + .static_mr = "static_mr", 19 + .config_mr = "config_mr", 20 + .rtmr0 = "rtmr0", 21 + .rtmr1 = "rtmr1", 22 + }; 23 + 24 + static int sample_report_refresh(const struct tsm_measurements *tm) 25 + { 26 + struct crypto_shash *tfm; 27 + int rc; 28 + 29 + tfm = crypto_alloc_shash(hash_algo_name[HASH_ALGO_SHA512], 0, 0); 30 + if (IS_ERR(tfm)) { 31 + pr_err("crypto_alloc_shash failed: %ld\n", PTR_ERR(tfm)); 32 + return PTR_ERR(tfm); 33 + } 34 + 35 + rc = crypto_shash_tfm_digest(tfm, (u8 *)&sample_report, 36 + offsetof(typeof(sample_report), 37 + report_digest), 38 + sample_report.report_digest); 39 + crypto_free_shash(tfm); 40 + if (rc) 41 + pr_err("crypto_shash_tfm_digest failed: %d\n", rc); 42 + return rc; 43 + } 44 + 45 + static int sample_report_extend_mr(const struct tsm_measurements *tm, 46 + const struct tsm_measurement_register *mr, 47 + const u8 *data) 48 + { 49 + SHASH_DESC_ON_STACK(desc, 0); 50 + int rc; 51 + 52 + desc->tfm = crypto_alloc_shash(hash_algo_name[mr->mr_hash], 0, 0); 53 + if (IS_ERR(desc->tfm)) { 54 + pr_err("crypto_alloc_shash failed: %ld\n", PTR_ERR(desc->tfm)); 55 + return PTR_ERR(desc->tfm); 56 + } 57 + 58 + rc = crypto_shash_init(desc); 59 + if (!rc) 60 + rc = crypto_shash_update(desc, mr->mr_value, mr->mr_size); 61 + if (!rc) 62 + rc = crypto_shash_finup(desc, data, mr->mr_size, mr->mr_value); 63 + crypto_free_shash(desc->tfm); 64 + if (rc) 65 + pr_err("SHA calculation failed: %d\n", rc); 66 + return rc; 67 + } 68 + 69 + #define MR_(mr, hash) .mr_value = &sample_report.mr, TSM_MR_(mr, hash) 70 + static const struct tsm_measurement_register sample_mrs[] = { 71 + /* static MR, read-only */ 72 + { MR_(static_mr, SHA384) }, 73 + /* config MR, read-only */ 74 + { MR_(config_mr, SHA512) | TSM_MR_F_NOHASH }, 75 + /* RTMR, direct extension prohibited */ 76 + { MR_(rtmr0, SHA256) | TSM_MR_F_LIVE }, 77 + /* RTMR, direct extension allowed */ 78 + { MR_(rtmr1, SHA384) | TSM_MR_F_RTMR }, 79 + /* RTMR, crypto agile, alaised to rtmr0 and rtmr1, respectively */ 80 + { .mr_value = &sample_report.rtmr0, 81 + TSM_MR_(rtmr_crypto_agile, SHA256) | TSM_MR_F_RTMR }, 82 + { .mr_value = &sample_report.rtmr1, 83 + TSM_MR_(rtmr_crypto_agile, SHA384) | TSM_MR_F_RTMR }, 84 + /* sha512 digest of the whole structure */ 85 + { MR_(report_digest, SHA512) | TSM_MR_F_LIVE }, 86 + }; 87 + #undef MR_ 88 + 89 + static struct tsm_measurements sample_tm = { 90 + .mrs = sample_mrs, 91 + .nr_mrs = ARRAY_SIZE(sample_mrs), 92 + .refresh = sample_report_refresh, 93 + .write = sample_report_extend_mr, 94 + }; 95 + 96 + static const struct attribute_group *sample_groups[] = { 97 + NULL, 98 + NULL, 99 + }; 100 + 101 + static struct miscdevice sample_misc_dev = { 102 + .name = KBUILD_MODNAME, 103 + .minor = MISC_DYNAMIC_MINOR, 104 + .groups = sample_groups, 105 + }; 106 + 107 + static int __init tsm_mr_sample_init(void) 108 + { 109 + int rc; 110 + 111 + sample_groups[0] = tsm_mr_create_attribute_group(&sample_tm); 112 + if (IS_ERR(sample_groups[0])) 113 + return PTR_ERR(sample_groups[0]); 114 + 115 + rc = misc_register(&sample_misc_dev); 116 + if (rc) 117 + tsm_mr_free_attribute_group(sample_groups[0]); 118 + return rc; 119 + } 120 + 121 + static void __exit tsm_mr_sample_exit(void) 122 + { 123 + misc_deregister(&sample_misc_dev); 124 + tsm_mr_free_attribute_group(sample_groups[0]); 125 + } 126 + 127 + module_init(tsm_mr_sample_init); 128 + module_exit(tsm_mr_sample_exit); 129 + 130 + MODULE_LICENSE("GPL"); 131 + MODULE_DESCRIPTION("Sample module using tsm-mr to expose emulated MRs");