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 
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");
132