1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2020-2024 Microsoft Corporation. All rights reserved. 4 */ 5 6 #include "digest.h" 7 8 /** 9 * ipe_digest_parse() - parse a digest in IPE's policy. 10 * @valstr: Supplies the string parsed from the policy. 11 * 12 * Digests in IPE are defined in a standard way: 13 * <alg_name>:<hex> 14 * 15 * Use this function to create a property to parse the digest 16 * consistently. The parsed digest will be saved in @value in IPE's 17 * policy. 18 * 19 * Return: The parsed digest_info structure on success. If an error occurs, 20 * the function will return the error value (via ERR_PTR). 21 */ 22 struct digest_info *ipe_digest_parse(const char *valstr) 23 { 24 struct digest_info *info = NULL; 25 char *sep, *raw_digest; 26 size_t raw_digest_len; 27 u8 *digest = NULL; 28 char *alg = NULL; 29 int rc = 0; 30 31 info = kzalloc(sizeof(*info), GFP_KERNEL); 32 if (!info) 33 return ERR_PTR(-ENOMEM); 34 35 sep = strchr(valstr, ':'); 36 if (!sep) { 37 rc = -EBADMSG; 38 goto err; 39 } 40 41 alg = kstrndup(valstr, sep - valstr, GFP_KERNEL); 42 if (!alg) { 43 rc = -ENOMEM; 44 goto err; 45 } 46 47 raw_digest = sep + 1; 48 raw_digest_len = strlen(raw_digest); 49 50 info->digest_len = (raw_digest_len + 1) / 2; 51 digest = kzalloc(info->digest_len, GFP_KERNEL); 52 if (!digest) { 53 rc = -ENOMEM; 54 goto err; 55 } 56 57 rc = hex2bin(digest, raw_digest, info->digest_len); 58 if (rc < 0) { 59 rc = -EINVAL; 60 goto err; 61 } 62 63 info->alg = alg; 64 info->digest = digest; 65 return info; 66 67 err: 68 kfree(alg); 69 kfree(digest); 70 kfree(info); 71 return ERR_PTR(rc); 72 } 73 74 /** 75 * ipe_digest_eval() - evaluate an IPE digest against another digest. 76 * @expected: Supplies the policy-provided digest value. 77 * @digest: Supplies the digest to compare against the policy digest value. 78 * 79 * Return: 80 * * %true - digests match 81 * * %false - digests do not match 82 */ 83 bool ipe_digest_eval(const struct digest_info *expected, 84 const struct digest_info *digest) 85 { 86 return (expected->digest_len == digest->digest_len) && 87 (!strcmp(expected->alg, digest->alg)) && 88 (!memcmp(expected->digest, digest->digest, expected->digest_len)); 89 } 90 91 /** 92 * ipe_digest_free() - free an IPE digest. 93 * @info: Supplies a pointer the policy-provided digest to free. 94 */ 95 void ipe_digest_free(struct digest_info *info) 96 { 97 if (IS_ERR_OR_NULL(info)) 98 return; 99 100 kfree(info->alg); 101 kfree(info->digest); 102 kfree(info); 103 } 104 105 /** 106 * ipe_digest_audit() - audit a digest that was sourced from IPE's policy. 107 * @ab: Supplies the audit_buffer to append the formatted result. 108 * @info: Supplies a pointer to source the audit record from. 109 * 110 * Digests in IPE are audited in this format: 111 * <alg_name>:<hex> 112 */ 113 void ipe_digest_audit(struct audit_buffer *ab, const struct digest_info *info) 114 { 115 audit_log_untrustedstring(ab, info->alg); 116 audit_log_format(ab, ":"); 117 audit_log_n_hex(ab, info->digest, info->digest_len); 118 } 119