mirror of
https://github.com/torvalds/linux.git
synced 2024-12-18 17:12:55 +00:00
e155858dd9
Allows author of IPE policy to indicate trust for a singular dm-verity volume, identified by roothash, through "dmverity_roothash" and all signed and validated dm-verity volumes, through "dmverity_signature". Signed-off-by: Deven Bowers <deven.desai@linux.microsoft.com> Signed-off-by: Fan Wu <wufan@linux.microsoft.com> [PM: fixed some line length issues in the comments] Signed-off-by: Paul Moore <paul@paul-moore.com>
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);
|
|
}
|