mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	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>
		
			
				
	
	
		
			118 lines
		
	
	
	
		
			2.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			118 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);
 | 
						|
}
 |