tpm2_setprimarypolicy.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. /* SPDX-License-Identifier: BSD-3-Clause */
  2. #include <stdlib.h>
  3. #include "files.h"
  4. #include "log.h"
  5. #include "tpm2.h"
  6. #include "tpm2_alg_util.h"
  7. #include "tpm2_convert.h"
  8. #include "tpm2_nv_util.h"
  9. #include "tpm2_tool.h"
  10. typedef struct tpm_setprimarypolicy_ctx tpm_setprimarypolicy_ctx;
  11. struct tpm_setprimarypolicy_ctx {
  12. //Input
  13. struct {
  14. const char *ctx_path;
  15. const char *auth_str;
  16. tpm2_loaded_object object;
  17. } hierarchy;
  18. const char *policy_path;
  19. TPMI_ALG_HASH hash_algorithm;
  20. char *cp_hash_path;
  21. };
  22. static tpm_setprimarypolicy_ctx ctx = {
  23. .hash_algorithm = TPM2_ALG_NULL,
  24. };
  25. static bool set_digest_algorithm(char *value) {
  26. ctx.hash_algorithm = tpm2_alg_util_from_optarg(value, tpm2_alg_util_flags_hash);
  27. if (ctx.hash_algorithm == TPM2_ALG_ERROR) {
  28. LOG_ERR("Could not convert to number or lookup algorithm, got: "
  29. "\"%s\"", value);
  30. return false;
  31. }
  32. return true;
  33. }
  34. static bool on_option(char key, char *value) {
  35. bool result = true;
  36. switch (key) {
  37. case 'C':
  38. ctx.hierarchy.ctx_path = value;
  39. break;
  40. case 'P':
  41. ctx.hierarchy.auth_str = value;
  42. break;
  43. case 'L':
  44. ctx.policy_path = value;
  45. break;
  46. case 'g':
  47. result = set_digest_algorithm(value);
  48. break;
  49. case 0:
  50. ctx.cp_hash_path = value;
  51. break;
  52. }
  53. return result;
  54. }
  55. static bool tpm2_tool_onstart(tpm2_options **opts) {
  56. static const struct option topts[] = {
  57. { "hierarchy", required_argument, NULL, 'C' },
  58. { "auth", required_argument, NULL, 'P' },
  59. { "policy", required_argument, NULL, 'L' },
  60. { "hash-algorithm", required_argument, NULL, 'g' },
  61. { "cphash", required_argument, NULL, 0 },
  62. };
  63. *opts = tpm2_options_new("C:P:L:g:", ARRAY_LEN(topts), topts,
  64. on_option, NULL, 0);
  65. return *opts != NULL;
  66. }
  67. static bool is_input_options_args_valid(void) {
  68. if (!ctx.hierarchy.ctx_path) {
  69. LOG_ERR("Must specify the hierarchy '-C'.");
  70. return false;
  71. }
  72. bool result = true;
  73. if (ctx.policy_path) {
  74. unsigned long file_size = 0;
  75. result = files_get_file_size_path(ctx.policy_path, &file_size);
  76. if (!result || file_size == 0) {
  77. result = false;
  78. }
  79. }
  80. if (ctx.cp_hash_path) {
  81. LOG_WARN("Calculating cpHash. Exiting without setting primary policy.");
  82. }
  83. return result;
  84. }
  85. static tool_rc process_setprimarypolicy_input(ESYS_CONTEXT *ectx,
  86. TPM2B_DIGEST **auth_policy) {
  87. /*
  88. * Load hierarchy handle and auth
  89. */
  90. tool_rc rc = tpm2_util_object_load_auth(ectx, ctx.hierarchy.ctx_path,
  91. ctx.hierarchy.auth_str, &ctx.hierarchy.object, false,
  92. TPM2_HANDLE_FLAGS_O|TPM2_HANDLE_FLAGS_P|TPM2_HANDLE_FLAGS_E|
  93. TPM2_HANDLE_FLAGS_L);
  94. if (rc != tool_rc_success) {
  95. return rc;
  96. }
  97. /*
  98. * Load policy digest if one is specified
  99. */
  100. if (ctx.policy_path) {
  101. *auth_policy = malloc(UINT16_MAX + sizeof(uint16_t));
  102. if (!*auth_policy) {
  103. LOG_ERR("oom");
  104. return tool_rc_general_error;
  105. }
  106. (*auth_policy)->size = UINT16_MAX;
  107. bool result = files_load_bytes_from_path(ctx.policy_path,
  108. (*auth_policy)->buffer, &((*auth_policy)->size));
  109. if (!result) {
  110. LOG_ERR("Failed loading policy digest from path");
  111. return tool_rc_general_error;
  112. }
  113. }
  114. return tool_rc_success;
  115. }
  116. static tool_rc tpm2_tool_onrun(ESYS_CONTEXT *ectx, tpm2_option_flags flags) {
  117. /* opts is unused, avoid compiler warning */
  118. UNUSED(flags);
  119. bool result = is_input_options_args_valid();
  120. if (!result) {
  121. return tool_rc_option_error;
  122. }
  123. //Input
  124. TPM2B_DIGEST *auth_policy = NULL;
  125. tool_rc rc = process_setprimarypolicy_input(ectx, &auth_policy);
  126. if (rc != tool_rc_success) {
  127. return rc;
  128. }
  129. //ESAPI call
  130. if (ctx.cp_hash_path) {
  131. TPM2B_DIGEST cp_hash = { .size = 0 };
  132. rc = tpm2_setprimarypolicy(ectx, &ctx.hierarchy.object, auth_policy,
  133. ctx.hash_algorithm, &cp_hash);
  134. if (rc != tool_rc_success) {
  135. goto out;
  136. }
  137. result = files_save_digest(&cp_hash, ctx.cp_hash_path);
  138. if (!result) {
  139. rc = tool_rc_general_error;
  140. }
  141. goto out;
  142. }
  143. rc = tpm2_setprimarypolicy(ectx, &ctx.hierarchy.object, auth_policy,
  144. ctx.hash_algorithm, NULL);
  145. out:
  146. free(auth_policy);
  147. return rc;
  148. }
  149. static tool_rc tpm2_tool_onstop(ESYS_CONTEXT *ectx) {
  150. UNUSED(ectx);
  151. return tpm2_session_close(&ctx.hierarchy.object.session);
  152. }
  153. // Register this tool with tpm2_tool.c
  154. TPM2_TOOL_REGISTER("setprimarypolicy", tpm2_tool_onstart, tpm2_tool_onrun, tpm2_tool_onstop, NULL)