tpm2_createpolicy.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. /* SPDX-License-Identifier: BSD-3-Clause */
  2. #include <stdbool.h>
  3. #include <stdlib.h>
  4. #include "files.h"
  5. #include "log.h"
  6. #include "pcr.h"
  7. #include "tpm2_alg_util.h"
  8. #include "tpm2_policy.h"
  9. #include "tpm2_tool.h"
  10. //Records the type of policy and if one is selected
  11. typedef struct {
  12. bool policy_pcr;
  13. } policy_type;
  14. //Common policy options
  15. typedef struct tpm2_common_policy_options tpm2_common_policy_options;
  16. struct tpm2_common_policy_options {
  17. tpm2_session *policy_session; // policy session
  18. TPM2_SE policy_session_type; // TPM2_SE_TRIAL or TPM2_SE_POLICY
  19. TPM2B_DIGEST *policy_digest; // buffer to hold policy digest
  20. TPMI_ALG_HASH policy_digest_hash_alg; // hash alg of final policy digest
  21. char *policy_file; // filepath for the policy digest
  22. bool policy_file_flag; // if policy file input has been given
  23. policy_type policy_type;
  24. const char *context_file;
  25. };
  26. //pcr policy options
  27. typedef struct tpm2_pcr_policy_options tpm2_pcr_policy_options;
  28. struct tpm2_pcr_policy_options {
  29. char *raw_pcrs_file; // filepath of input raw pcrs file
  30. TPML_PCR_SELECTION pcr_selections; // records user pcr selection per setlist
  31. };
  32. typedef struct create_policy_ctx create_policy_ctx;
  33. struct create_policy_ctx {
  34. tpm2_common_policy_options common_policy_options;
  35. tpm2_pcr_policy_options pcr_policy_options;
  36. };
  37. #define TPM2_COMMON_POLICY_INIT { \
  38. .policy_session = NULL, \
  39. .policy_session_type = TPM2_SE_TRIAL, \
  40. .policy_digest = NULL, \
  41. .policy_digest_hash_alg = TPM2_ALG_SHA256, \
  42. }
  43. static create_policy_ctx pctx = {
  44. .common_policy_options = TPM2_COMMON_POLICY_INIT
  45. };
  46. static tool_rc parse_policy_type_specific_command(ESYS_CONTEXT *ectx) {
  47. if (!pctx.common_policy_options.policy_type.policy_pcr) {
  48. LOG_ERR("Only PCR policy is currently supported!");
  49. return tool_rc_option_error;
  50. }
  51. tpm2_session_data *session_data =tpm2_session_data_new(
  52. pctx.common_policy_options.policy_session_type);
  53. if (!session_data) {
  54. LOG_ERR("oom");
  55. return tool_rc_general_error;
  56. }
  57. tpm2_session_set_authhash(session_data,
  58. pctx.common_policy_options.policy_digest_hash_alg);
  59. tpm2_session **s = &pctx.common_policy_options.policy_session;
  60. tool_rc rc = tpm2_session_open(ectx, session_data, s);
  61. if (rc != tool_rc_success) {
  62. return rc;
  63. }
  64. rc = tpm2_policy_build_pcr(ectx, pctx.common_policy_options.policy_session,
  65. pctx.pcr_policy_options.raw_pcrs_file,
  66. &pctx.pcr_policy_options.pcr_selections, NULL);
  67. if (rc != tool_rc_success) {
  68. LOG_ERR("Could not build pcr policy");
  69. return rc;
  70. }
  71. rc = tpm2_policy_get_digest(ectx, pctx.common_policy_options.policy_session,
  72. &pctx.common_policy_options.policy_digest);
  73. if (rc != tool_rc_success) {
  74. LOG_ERR("Could not build tpm policy");
  75. return rc;
  76. }
  77. return tpm2_policy_tool_finish(ectx,
  78. pctx.common_policy_options.policy_session,
  79. pctx.common_policy_options.policy_file);
  80. }
  81. static bool on_option(char key, char *value) {
  82. switch (key) {
  83. case 'L':
  84. pctx.common_policy_options.policy_file_flag = true;
  85. pctx.common_policy_options.policy_file = value;
  86. break;
  87. case 'f':
  88. pctx.pcr_policy_options.raw_pcrs_file = value;
  89. break;
  90. case 'g':
  91. pctx.common_policy_options.policy_digest_hash_alg =
  92. tpm2_alg_util_from_optarg(value, tpm2_alg_util_flags_hash);
  93. if (pctx.common_policy_options.policy_digest_hash_alg
  94. == TPM2_ALG_ERROR) {
  95. LOG_ERR("Invalid choice for policy digest hash algorithm");
  96. return false;
  97. }
  98. break;
  99. case 'l':
  100. if (!pcr_parse_selections(value,
  101. &pctx.pcr_policy_options.pcr_selections)) {
  102. return false;
  103. }
  104. break;
  105. case 0:
  106. pctx.common_policy_options.policy_type.policy_pcr = true;
  107. break;
  108. case 1:
  109. pctx.common_policy_options.policy_session_type = TPM2_SE_POLICY;
  110. break;
  111. }
  112. return true;
  113. }
  114. static bool tpm2_tool_onstart(tpm2_options **opts) {
  115. const struct option topts[] = {
  116. { "policy", required_argument, NULL, 'L' },
  117. { "policy-algorithm", required_argument, NULL, 'g' },
  118. { "pcr-list", required_argument, NULL, 'l' },
  119. { "pcr", required_argument, NULL, 'f' },
  120. { "policy-pcr", no_argument, NULL, 0 },
  121. { "policy-session", no_argument, NULL, 1 },
  122. };
  123. *opts = tpm2_options_new("L:g:l:f:", ARRAY_LEN(topts), topts, on_option,
  124. NULL, 0);
  125. return *opts != NULL;
  126. }
  127. static tool_rc tpm2_tool_onrun(ESYS_CONTEXT *ectx, tpm2_option_flags flags) {
  128. UNUSED(flags);
  129. if (pctx.common_policy_options.policy_file_flag == false
  130. && pctx.common_policy_options.policy_session_type
  131. == TPM2_SE_TRIAL) {
  132. LOG_ERR("Provide the file name to store the resulting "
  133. "policy digest");
  134. return tool_rc_option_error;
  135. }
  136. return parse_policy_type_specific_command(ectx);
  137. }
  138. static void tpm2_tool_onexit(void) {
  139. free(pctx.common_policy_options.policy_digest);
  140. }
  141. // Register this tool with tpm2_tool.c
  142. TPM2_TOOL_REGISTER("createpolicy", tpm2_tool_onstart, tpm2_tool_onrun, NULL, tpm2_tool_onexit)