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