// 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);}
// 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);
}