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 static 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
sample_report_refresh(const struct tsm_measurements * tm)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
sample_report_extend_mr(const struct tsm_measurements * tm,const struct tsm_measurement_register * mr,const u8 * data)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
tsm_mr_sample_init(void)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
tsm_mr_sample_exit(void)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");
132