Files
linux/security/ipe/digest.c
Randy Dunlap 24c776355f kernel.h: drop hex.h and update all hex.h users
Remove <linux/hex.h> from <linux/kernel.h> and update all users/callers of
hex.h interfaces to directly #include <linux/hex.h> as part of the process
of putting kernel.h on a diet.

Removing hex.h from kernel.h means that 36K C source files don't have to
pay the price of parsing hex.h for the roughly 120 C source files that
need it.

This change has been build-tested with allmodconfig on most ARCHes.  Also,
all users/callers of <linux/hex.h> in the entire source tree have been
updated if needed (if not already #included).

Link: https://lkml.kernel.org/r/20251215005206.2362276-1-rdunlap@infradead.org
Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Yury Norov (NVIDIA) <yury.norov@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
2026-01-20 19:44:19 -08:00

120 lines
2.8 KiB
C

// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2020-2024 Microsoft Corporation. All rights reserved.
*/
#include <linux/hex.h>
#include "digest.h"
/**
* ipe_digest_parse() - parse a digest in IPE's policy.
* @valstr: Supplies the string parsed from the policy.
*
* Digests in IPE are defined in a standard way:
* <alg_name>:<hex>
*
* Use this function to create a property to parse the digest
* consistently. The parsed digest will be saved in @value in IPE's
* policy.
*
* Return: The parsed digest_info structure on success. If an error occurs,
* the function will return the error value (via ERR_PTR).
*/
struct digest_info *ipe_digest_parse(const char *valstr)
{
struct digest_info *info = NULL;
char *sep, *raw_digest;
size_t raw_digest_len;
u8 *digest = NULL;
char *alg = NULL;
int rc = 0;
info = kzalloc(sizeof(*info), GFP_KERNEL);
if (!info)
return ERR_PTR(-ENOMEM);
sep = strchr(valstr, ':');
if (!sep) {
rc = -EBADMSG;
goto err;
}
alg = kstrndup(valstr, sep - valstr, GFP_KERNEL);
if (!alg) {
rc = -ENOMEM;
goto err;
}
raw_digest = sep + 1;
raw_digest_len = strlen(raw_digest);
info->digest_len = (raw_digest_len + 1) / 2;
digest = kzalloc(info->digest_len, GFP_KERNEL);
if (!digest) {
rc = -ENOMEM;
goto err;
}
rc = hex2bin(digest, raw_digest, info->digest_len);
if (rc < 0) {
rc = -EINVAL;
goto err;
}
info->alg = alg;
info->digest = digest;
return info;
err:
kfree(alg);
kfree(digest);
kfree(info);
return ERR_PTR(rc);
}
/**
* ipe_digest_eval() - evaluate an IPE digest against another digest.
* @expected: Supplies the policy-provided digest value.
* @digest: Supplies the digest to compare against the policy digest value.
*
* Return:
* * %true - digests match
* * %false - digests do not match
*/
bool ipe_digest_eval(const struct digest_info *expected,
const struct digest_info *digest)
{
return (expected->digest_len == digest->digest_len) &&
(!strcmp(expected->alg, digest->alg)) &&
(!memcmp(expected->digest, digest->digest, expected->digest_len));
}
/**
* ipe_digest_free() - free an IPE digest.
* @info: Supplies a pointer the policy-provided digest to free.
*/
void ipe_digest_free(struct digest_info *info)
{
if (IS_ERR_OR_NULL(info))
return;
kfree(info->alg);
kfree(info->digest);
kfree(info);
}
/**
* ipe_digest_audit() - audit a digest that was sourced from IPE's policy.
* @ab: Supplies the audit_buffer to append the formatted result.
* @info: Supplies a pointer to source the audit record from.
*
* Digests in IPE are audited in this format:
* <alg_name>:<hex>
*/
void ipe_digest_audit(struct audit_buffer *ab, const struct digest_info *info)
{
audit_log_untrustedstring(ab, info->alg);
audit_log_format(ab, ":");
audit_log_n_hex(ab, info->digest, info->digest_len);
}