mirror of
https://github.com/torvalds/linux.git
synced 2026-04-18 06:44:00 -04:00
Given that tsm_mr_sample has a particular set of algorithms that it
wants, just use the library APIs for those algorithms rather than
crypto_shash. This is more straightforward and more efficient.
This also fixes a bug where this module failed to build if it was
enabled without CRYPTO_HASH happening to be set elsewhere in the
kconfig. (With the concurrent change to make TSM_MEASUREMENTS stop
selecting CRYPTO, this existing build error would have become easier to
encounter, as well.) Also, even if it built, crypto_alloc_shash() could
fail at runtime due to the needed algorithms not being available.
The library functions simply use direct linking. So if it builds, which
it will due to the kconfig options being selected, they are available.
Fixes: f6953f1f9e ("tsm-mr: Add tsm-mr sample code")
Acked-by: Arnd Bergmann <arnd@arndb.de>
Acked-by: Dan Williams <dan.j.williams@intel.com>
Link: https://lore.kernel.org/r/20260318164233.19800-1-ebiggers@kernel.org
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
130 lines
3.5 KiB
C
130 lines
3.5 KiB
C
// SPDX-License-Identifier: GPL-2.0-only
|
|
/* Copyright(c) 2024-2005 Intel Corporation. All rights reserved. */
|
|
|
|
#define pr_fmt(x) KBUILD_MODNAME ": " x
|
|
|
|
#include <linux/module.h>
|
|
#include <linux/tsm-mr.h>
|
|
#include <linux/miscdevice.h>
|
|
#include <crypto/sha2.h>
|
|
|
|
static struct {
|
|
u8 static_mr[SHA384_DIGEST_SIZE];
|
|
u8 config_mr[SHA512_DIGEST_SIZE];
|
|
u8 rtmr0[SHA256_DIGEST_SIZE];
|
|
u8 rtmr1[SHA384_DIGEST_SIZE];
|
|
u8 report_digest[SHA512_DIGEST_SIZE];
|
|
} sample_report = {
|
|
.static_mr = "static_mr",
|
|
.config_mr = "config_mr",
|
|
.rtmr0 = "rtmr0",
|
|
.rtmr1 = "rtmr1",
|
|
};
|
|
|
|
static int sample_report_refresh(const struct tsm_measurements *tm)
|
|
{
|
|
sha512((const u8 *)&sample_report,
|
|
offsetof(typeof(sample_report), report_digest),
|
|
sample_report.report_digest);
|
|
return 0;
|
|
}
|
|
|
|
static int sample_report_extend_mr(const struct tsm_measurements *tm,
|
|
const struct tsm_measurement_register *mr,
|
|
const u8 *data)
|
|
{
|
|
union {
|
|
struct sha256_ctx sha256;
|
|
struct sha384_ctx sha384;
|
|
struct sha512_ctx sha512;
|
|
} ctx;
|
|
|
|
switch (mr->mr_hash) {
|
|
case HASH_ALGO_SHA256:
|
|
sha256_init(&ctx.sha256);
|
|
sha256_update(&ctx.sha256, mr->mr_value, mr->mr_size);
|
|
sha256_update(&ctx.sha256, data, mr->mr_size);
|
|
sha256_final(&ctx.sha256, mr->mr_value);
|
|
return 0;
|
|
case HASH_ALGO_SHA384:
|
|
sha384_init(&ctx.sha384);
|
|
sha384_update(&ctx.sha384, mr->mr_value, mr->mr_size);
|
|
sha384_update(&ctx.sha384, data, mr->mr_size);
|
|
sha384_final(&ctx.sha384, mr->mr_value);
|
|
return 0;
|
|
case HASH_ALGO_SHA512:
|
|
sha512_init(&ctx.sha512);
|
|
sha512_update(&ctx.sha512, mr->mr_value, mr->mr_size);
|
|
sha512_update(&ctx.sha512, data, mr->mr_size);
|
|
sha512_final(&ctx.sha512, mr->mr_value);
|
|
return 0;
|
|
default:
|
|
pr_err("Unsupported hash algorithm: %d\n", mr->mr_hash);
|
|
return -EOPNOTSUPP;
|
|
}
|
|
}
|
|
|
|
#define MR_(mr, hash) .mr_value = &sample_report.mr, TSM_MR_(mr, hash)
|
|
static const struct tsm_measurement_register sample_mrs[] = {
|
|
/* static MR, read-only */
|
|
{ MR_(static_mr, SHA384) },
|
|
/* config MR, read-only */
|
|
{ MR_(config_mr, SHA512) | TSM_MR_F_NOHASH },
|
|
/* RTMR, direct extension prohibited */
|
|
{ MR_(rtmr0, SHA256) | TSM_MR_F_LIVE },
|
|
/* RTMR, direct extension allowed */
|
|
{ MR_(rtmr1, SHA384) | TSM_MR_F_RTMR },
|
|
/* RTMR, crypto agile, alaised to rtmr0 and rtmr1, respectively */
|
|
{ .mr_value = &sample_report.rtmr0,
|
|
TSM_MR_(rtmr_crypto_agile, SHA256) | TSM_MR_F_RTMR },
|
|
{ .mr_value = &sample_report.rtmr1,
|
|
TSM_MR_(rtmr_crypto_agile, SHA384) | TSM_MR_F_RTMR },
|
|
/* sha512 digest of the whole structure */
|
|
{ MR_(report_digest, SHA512) | TSM_MR_F_LIVE },
|
|
};
|
|
#undef MR_
|
|
|
|
static struct tsm_measurements sample_tm = {
|
|
.mrs = sample_mrs,
|
|
.nr_mrs = ARRAY_SIZE(sample_mrs),
|
|
.refresh = sample_report_refresh,
|
|
.write = sample_report_extend_mr,
|
|
};
|
|
|
|
static const struct attribute_group *sample_groups[] = {
|
|
NULL,
|
|
NULL,
|
|
};
|
|
|
|
static struct miscdevice sample_misc_dev = {
|
|
.name = KBUILD_MODNAME,
|
|
.minor = MISC_DYNAMIC_MINOR,
|
|
.groups = sample_groups,
|
|
};
|
|
|
|
static int __init tsm_mr_sample_init(void)
|
|
{
|
|
int rc;
|
|
|
|
sample_groups[0] = tsm_mr_create_attribute_group(&sample_tm);
|
|
if (IS_ERR(sample_groups[0]))
|
|
return PTR_ERR(sample_groups[0]);
|
|
|
|
rc = misc_register(&sample_misc_dev);
|
|
if (rc)
|
|
tsm_mr_free_attribute_group(sample_groups[0]);
|
|
return rc;
|
|
}
|
|
|
|
static void __exit tsm_mr_sample_exit(void)
|
|
{
|
|
misc_deregister(&sample_misc_dev);
|
|
tsm_mr_free_attribute_group(sample_groups[0]);
|
|
}
|
|
|
|
module_init(tsm_mr_sample_init);
|
|
module_exit(tsm_mr_sample_exit);
|
|
|
|
MODULE_LICENSE("GPL");
|
|
MODULE_DESCRIPTION("Sample module using tsm-mr to expose emulated MRs");
|