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/sha2.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 sha512((const u8 *)&sample_report, 27 offsetof(typeof(sample_report), report_digest), 28 sample_report.report_digest); 29 return 0; 30 } 31 32 static int sample_report_extend_mr(const struct tsm_measurements *tm, 33 const struct tsm_measurement_register *mr, 34 const u8 *data) 35 { 36 union { 37 struct sha256_ctx sha256; 38 struct sha384_ctx sha384; 39 struct sha512_ctx sha512; 40 } ctx; 41 42 switch (mr->mr_hash) { 43 case HASH_ALGO_SHA256: 44 sha256_init(&ctx.sha256); 45 sha256_update(&ctx.sha256, mr->mr_value, mr->mr_size); 46 sha256_update(&ctx.sha256, data, mr->mr_size); 47 sha256_final(&ctx.sha256, mr->mr_value); 48 return 0; 49 case HASH_ALGO_SHA384: 50 sha384_init(&ctx.sha384); 51 sha384_update(&ctx.sha384, mr->mr_value, mr->mr_size); 52 sha384_update(&ctx.sha384, data, mr->mr_size); 53 sha384_final(&ctx.sha384, mr->mr_value); 54 return 0; 55 case HASH_ALGO_SHA512: 56 sha512_init(&ctx.sha512); 57 sha512_update(&ctx.sha512, mr->mr_value, mr->mr_size); 58 sha512_update(&ctx.sha512, data, mr->mr_size); 59 sha512_final(&ctx.sha512, mr->mr_value); 60 return 0; 61 default: 62 pr_err("Unsupported hash algorithm: %d\n", mr->mr_hash); 63 return -EOPNOTSUPP; 64 } 65 } 66 67 #define MR_(mr, hash) .mr_value = &sample_report.mr, TSM_MR_(mr, hash) 68 static const struct tsm_measurement_register sample_mrs[] = { 69 /* static MR, read-only */ 70 { MR_(static_mr, SHA384) }, 71 /* config MR, read-only */ 72 { MR_(config_mr, SHA512) | TSM_MR_F_NOHASH }, 73 /* RTMR, direct extension prohibited */ 74 { MR_(rtmr0, SHA256) | TSM_MR_F_LIVE }, 75 /* RTMR, direct extension allowed */ 76 { MR_(rtmr1, SHA384) | TSM_MR_F_RTMR }, 77 /* RTMR, crypto agile, alaised to rtmr0 and rtmr1, respectively */ 78 { .mr_value = &sample_report.rtmr0, 79 TSM_MR_(rtmr_crypto_agile, SHA256) | TSM_MR_F_RTMR }, 80 { .mr_value = &sample_report.rtmr1, 81 TSM_MR_(rtmr_crypto_agile, SHA384) | TSM_MR_F_RTMR }, 82 /* sha512 digest of the whole structure */ 83 { MR_(report_digest, SHA512) | TSM_MR_F_LIVE }, 84 }; 85 #undef MR_ 86 87 static struct tsm_measurements sample_tm = { 88 .mrs = sample_mrs, 89 .nr_mrs = ARRAY_SIZE(sample_mrs), 90 .refresh = sample_report_refresh, 91 .write = sample_report_extend_mr, 92 }; 93 94 static const struct attribute_group *sample_groups[] = { 95 NULL, 96 NULL, 97 }; 98 99 static struct miscdevice sample_misc_dev = { 100 .name = KBUILD_MODNAME, 101 .minor = MISC_DYNAMIC_MINOR, 102 .groups = sample_groups, 103 }; 104 105 static int __init tsm_mr_sample_init(void) 106 { 107 int rc; 108 109 sample_groups[0] = tsm_mr_create_attribute_group(&sample_tm); 110 if (IS_ERR(sample_groups[0])) 111 return PTR_ERR(sample_groups[0]); 112 113 rc = misc_register(&sample_misc_dev); 114 if (rc) 115 tsm_mr_free_attribute_group(sample_groups[0]); 116 return rc; 117 } 118 119 static void __exit tsm_mr_sample_exit(void) 120 { 121 misc_deregister(&sample_misc_dev); 122 tsm_mr_free_attribute_group(sample_groups[0]); 123 } 124 125 module_init(tsm_mr_sample_init); 126 module_exit(tsm_mr_sample_exit); 127 128 MODULE_LICENSE("GPL"); 129 MODULE_DESCRIPTION("Sample module using tsm-mr to expose emulated MRs"); 130