digest.c 2.7 KB

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