mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 12:11:40 +00:00
119 lines
2.7 KiB
C
119 lines
2.7 KiB
C
|
// SPDX-License-Identifier: GPL-2.0
|
||
|
/*
|
||
|
* Copyright (C) 2020-2024 Microsoft Corporation. All rights reserved.
|
||
|
*/
|
||
|
|
||
|
#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);
|
||
|
}
|