tpm2_clockrateadjust.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. /* SPDX-License-Identifier: BSD-3-Clause */
  2. #include <string.h>
  3. #include "files.h"
  4. #include "log.h"
  5. #include "tpm2.h"
  6. #include "tpm2_tool.h"
  7. #include "tpm2_util.h"
  8. typedef struct tpm2_setclock_ctx tpm2_setclock_ctx;
  9. struct tpm2_setclock_ctx {
  10. TPM2_CLOCK_ADJUST adjust;
  11. const char *auth_hierarchy;
  12. tpm2_loaded_object object;
  13. const char *auth_value;
  14. char *cp_hash_path;
  15. };
  16. static tpm2_setclock_ctx ctx = {
  17. .auth_hierarchy = "o" /* default to owner hierarchy */
  18. };
  19. static bool on_arg(int argc, char **argv) {
  20. if (argc != 1) {
  21. LOG_ERR("Can only specify 1 clock rate adjust specifier, got: %d", argc);
  22. return false;
  23. }
  24. const char *adjustment = argv[0];
  25. size_t len = strlen(adjustment);
  26. if (len > 3) {
  27. LOG_ERR("Expected at most 3 adjustment characters");
  28. return false;
  29. }
  30. static const char slower[] = "sss";
  31. static const char faster[] = "fff";
  32. bool is_slower = adjustment[0] == 's';
  33. const char *compare = is_slower ? slower : faster;
  34. bool is_equal = !strncmp(adjustment, compare, len);
  35. if (!is_equal) {
  36. LOG_ERR("Adjustment specifier should be consistent, either all "
  37. "'s' or all 'f' characters got: \"%s\"", adjustment);
  38. return false;
  39. }
  40. if (is_slower) {
  41. ctx.adjust -= len;
  42. } else {
  43. ctx.adjust += len;
  44. }
  45. return true;
  46. }
  47. static bool on_option(char key, char *value) {
  48. switch (key) {
  49. case 'c':
  50. ctx.auth_hierarchy = value;
  51. break;
  52. case 'p':
  53. ctx.auth_value = value;
  54. break;
  55. case 0:
  56. ctx.cp_hash_path = value;
  57. break;
  58. /* no default */
  59. }
  60. return true;
  61. }
  62. static bool tpm2_tool_onstart(tpm2_options **opts) {
  63. const struct option topts[] = {
  64. { "hierarchy", required_argument, NULL, 'c' },
  65. { "auth", required_argument, NULL, 'p' },
  66. { "cphash", required_argument, NULL, 0 },
  67. };
  68. *opts = tpm2_options_new("c:p:", ARRAY_LEN(topts), topts, on_option,
  69. on_arg, 0);
  70. return *opts != NULL;
  71. }
  72. static tool_rc tpm2_tool_onrun(ESYS_CONTEXT *ectx, tpm2_option_flags flags) {
  73. UNUSED(flags);
  74. tool_rc rc = tpm2_util_object_load_auth(ectx, ctx.auth_hierarchy,
  75. ctx.auth_value, &ctx.object, false,
  76. TPM2_HANDLE_FLAGS_P|TPM2_HANDLE_FLAGS_O);
  77. if (rc != tool_rc_success) {
  78. return rc;
  79. }
  80. LOG_INFO("adjust value: %d", ctx.adjust);
  81. if (ctx.cp_hash_path) {
  82. TPM2B_DIGEST cp_hash = { .size = 0 };
  83. LOG_WARN("Calculating cpHash. Exiting without setting clock.");
  84. rc = tpm2_clockrateadjust(ectx, &ctx.object, ctx.adjust, &cp_hash);
  85. if (rc != tool_rc_success) {
  86. return rc;
  87. }
  88. bool result = files_save_digest(&cp_hash, ctx.cp_hash_path);
  89. if (!result) {
  90. rc = tool_rc_general_error;
  91. }
  92. return rc;
  93. }
  94. return tpm2_clockrateadjust(ectx, &ctx.object, ctx.adjust, NULL);
  95. }
  96. static tool_rc tpm2_tool_onstop(ESYS_CONTEXT *ectx) {
  97. UNUSED(ectx);
  98. return tpm2_session_close(&ctx.object.session);
  99. }
  100. // Register this tool with tpm2_tool.c
  101. TPM2_TOOL_REGISTER("clockrateadjust", tpm2_tool_onstart, tpm2_tool_onrun, tpm2_tool_onstop, NULL)