tpm2_eventlog.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. /* SPDX-License-Identifier: BSD-3-Clause */
  2. #include <errno.h>
  3. #include <inttypes.h>
  4. #include <stdbool.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include "files.h"
  8. #include "log.h"
  9. #include "efi_event.h"
  10. #include "tpm2_eventlog.h"
  11. #include "tpm2_eventlog_yaml.h"
  12. #include "tpm2_tool.h"
  13. static char *filename = NULL;
  14. /* Set the default YAML version */
  15. static uint32_t eventlog_version = 1;
  16. static bool on_positional(int argc, char **argv) {
  17. if (argc != 1) {
  18. LOG_ERR("Expected one file name as a positional parameter. Got: %d",
  19. argc);
  20. return false;
  21. }
  22. filename = argv[0];
  23. return true;
  24. }
  25. static bool on_option(char key, char *value) {
  26. uint32_t version;
  27. switch (key) {
  28. case 0:
  29. if (!tpm2_util_string_to_uint32(value, &version)) {
  30. LOG_ERR("Cannot parse eventlog version: %s\n", value);
  31. return false;
  32. }
  33. if (version < MIN_EVLOG_YAML_VERSION || version > MAX_EVLOG_YAML_VERSION) {
  34. LOG_ERR("Unexpected YAML version number: %u\n", version);
  35. return false;
  36. }
  37. eventlog_version = version;
  38. break;
  39. }
  40. return true;
  41. }
  42. static bool tpm2_tool_onstart(tpm2_options **opts) {
  43. static struct option topts[] = {
  44. { "eventlog-version", required_argument, NULL, 0 },
  45. };
  46. *opts = tpm2_options_new("y:", ARRAY_LEN(topts), topts, on_option,
  47. on_positional, TPM2_OPTIONS_NO_SAPI);
  48. return *opts != NULL;
  49. }
  50. static tool_rc tpm2_tool_onrun(ESYS_CONTEXT *ectx, tpm2_option_flags flags) {
  51. UNUSED(flags);
  52. UNUSED(ectx);
  53. if (filename == NULL) {
  54. LOG_ERR("Missing required positional parameter, try -h / --help");
  55. return tool_rc_option_error;
  56. }
  57. /* Get file size */
  58. unsigned long size = 0;
  59. bool ret = files_get_file_size_path(filename, &size);
  60. if (!ret || !size) {
  61. return tool_rc_general_error;
  62. }
  63. /* Allocate buffer to read file data */
  64. UINT8 *eventlog = calloc(1, size);
  65. if (eventlog == NULL){
  66. LOG_ERR("failed to allocate %lu bytes: %s", size, strerror(errno));
  67. return tool_rc_general_error;
  68. }
  69. /* Load buffer with file data */
  70. tool_rc rc = tool_rc_success;
  71. FILE *fileptr = fopen(filename, "rb");
  72. if (!fileptr) {
  73. rc = tool_rc_general_error;
  74. goto out;
  75. }
  76. ret = files_read_bytes(fileptr, eventlog, size);
  77. fclose(fileptr);
  78. if (!ret) {
  79. rc = tool_rc_general_error;
  80. goto out;
  81. }
  82. /* Parse eventlog data */
  83. ret = yaml_eventlog(eventlog, size, eventlog_version);
  84. if (!ret) {
  85. LOG_ERR("failed to parse tpm2 eventlog");
  86. rc = tool_rc_general_error;
  87. }
  88. out:
  89. if (eventlog) {
  90. free(eventlog);
  91. }
  92. return rc;
  93. }
  94. // Register this tool with tpm2_tool.c
  95. TPM2_TOOL_REGISTER("eventlog", tpm2_tool_onstart, tpm2_tool_onrun, NULL, NULL)