| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- // 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_obj(*info);
- 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);
- }
|