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