digest.c 2.8 KB

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