sys-nv-policy-locality.int.c 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. /*
  2. * SPDX-License-Identifier: BSD-2-Clause
  3. * Copyright (c) 2019, Intel Corporation
  4. */
  5. #ifdef HAVE_CONFIG_H
  6. #include <config.h>
  7. #endif
  8. #include <assert.h>
  9. #include <inttypes.h>
  10. #include <stdbool.h>
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #include "tss2_sys.h"
  15. #include "context-util.h"
  16. #include "sys-util.h"
  17. #include "util/aux_util.h"
  18. #define LOGMODULE test
  19. #include "util/log.h"
  20. #define NV_INDEX 0x01800003
  21. #define NV_SIZE 96
  22. #define TPM2B_SIZE_MAX(type) (sizeof (type) - 2)
  23. /*
  24. * This test creates an NV index governed by a policy and then performs
  25. * several operations on the NV region to exercise this policy. The NV
  26. * region created is modeled after the TXT AUX region as defined by the
  27. * Intel TXT software developers guide:
  28. * https://www.intel.com/content/dam/www/public/us/en/documents/guides/intel-txt-software-development-guide.pdf
  29. * Read is controlled by authValue and is unrestricted since authValue is
  30. * set to emptyBuffer.
  31. * Write is controlled by policy that allows writes from locality 3 and 4.
  32. */
  33. /*
  34. * This function creates a policy session asserting that the locality is
  35. * either 3 or 4. If this policy is used when executing a command and the
  36. * policy is not satisfied (locality is not 3 or 4) then the command will
  37. * fail.
  38. */
  39. static TSS2_RC
  40. create_policy_session (TSS2_SYS_CONTEXT *sys_ctx,
  41. TPMI_SH_AUTH_SESSION *handle)
  42. {
  43. TPMA_LOCALITY locality = TPMA_LOCALITY_TPM2_LOC_THREE |
  44. TPMA_LOCALITY_TPM2_LOC_FOUR;
  45. TPM2B_NONCE nonce = { .size = GetDigestSize (TPM2_ALG_SHA1), };
  46. TPM2B_NONCE nonce_tpm = { 0, };
  47. TSS2_RC rc;
  48. TPM2B_ENCRYPTED_SECRET salt = { 0, };
  49. TPMT_SYM_DEF symmetric = { .algorithm = TPM2_ALG_NULL, };
  50. rc = Tss2_Sys_StartAuthSession (sys_ctx,
  51. TPM2_RH_NULL,
  52. TPM2_RH_NULL,
  53. 0,
  54. &nonce,
  55. &salt,
  56. TPM2_SE_POLICY,
  57. &symmetric,
  58. TPM2_ALG_SHA1,
  59. handle,
  60. &nonce_tpm,
  61. 0);
  62. return_if_error (rc, "Tss2_Sys_StartAuthSession");
  63. rc = Tss2_Sys_PolicyLocality (sys_ctx,
  64. *handle,
  65. 0,
  66. locality,
  67. 0);
  68. return_if_error (rc, "Tss2_Sys_PolicyLocality");
  69. return rc;
  70. }
  71. /*
  72. * This function creates the NV region used in this test. The appropriate
  73. * attributes are applied using the nvPublic member of the TPM2B_NV_PUBLIC
  74. * structure.
  75. */
  76. static TSS2_RC
  77. setup_nv (TSS2_SYS_CONTEXT *sys_ctx)
  78. {
  79. TSS2_RC rc;
  80. TPMI_SH_AUTH_SESSION auth_handle = 0;
  81. TPM2B_DIGEST policy_hash = { 0, };
  82. TPM2B_AUTH nv_auth = { 0, };
  83. TSS2L_SYS_AUTH_RESPONSE auth_rsp = { 0, };
  84. TPM2B_NV_PUBLIC public_info = {
  85. .nvPublic = {
  86. .attributes = TPMA_NV_AUTHREAD | TPMA_NV_POLICYWRITE |
  87. TPMA_NV_PLATFORMCREATE, /* POLICYDELETE? */
  88. .authPolicy = { .size = GetDigestSize (TPM2_ALG_SHA1), },
  89. .dataSize = NV_SIZE,
  90. .nameAlg = TPM2_ALG_SHA1,
  91. .nvIndex = NV_INDEX,
  92. },
  93. };
  94. const TSS2L_SYS_AUTH_COMMAND auth_cmd = {
  95. .count = 1,
  96. .auths= {
  97. {
  98. .sessionHandle = TPM2_RH_PW,
  99. }
  100. }
  101. };
  102. rc = create_policy_session (sys_ctx, &auth_handle);
  103. return_if_error (rc, "create_policy_session");
  104. rc = Tss2_Sys_PolicyGetDigest (sys_ctx,
  105. auth_handle,
  106. 0,
  107. &policy_hash,
  108. 0);
  109. return_if_error (rc, "Tss2_Sys_PolicyGetDigest");
  110. LOGBLOB_DEBUG (policy_hash.buffer, policy_hash.size, "policy_hash");
  111. memcpy (public_info.nvPublic.authPolicy.buffer,
  112. policy_hash.buffer,
  113. policy_hash.size);
  114. rc = Tss2_Sys_NV_DefineSpace (sys_ctx,
  115. TPM2_RH_PLATFORM,
  116. &auth_cmd,
  117. &nv_auth,
  118. &public_info,
  119. &auth_rsp);
  120. Tss2_Sys_FlushContext (sys_ctx, auth_handle);
  121. return_if_error (rc, "Tss2_Sys_NV_DefineSpace");
  122. return rc;
  123. }
  124. static TSS2_RC
  125. teardown_nv (TSS2_SYS_CONTEXT *sys_ctx)
  126. {
  127. TSS2_RC rc;
  128. const TSS2L_SYS_AUTH_COMMAND auth_cmd = {
  129. .count = 1,
  130. .auths = {
  131. {
  132. .sessionHandle = TPM2_RH_PW,
  133. },
  134. },
  135. };
  136. TSS2L_SYS_AUTH_RESPONSE auth_rsp = { 0, };
  137. rc = Tss2_Sys_NV_UndefineSpace (sys_ctx,
  138. TPM2_RH_PLATFORM,
  139. NV_INDEX,
  140. &auth_cmd,
  141. &auth_rsp);
  142. return_if_error (rc, "Tss2_Sys_NV_UndefineSpace");
  143. return rc;
  144. }
  145. /*
  146. * This function performs a single write operation to the NV region. This
  147. * requires we first create a policy session that satisfies the policy
  148. * governing the region. If the write fails we must manually flush the
  149. * session since the continueSession flag only guarantees the policy is
  150. * flushed after successful command execution.
  151. */
  152. static TSS2_RC
  153. nv_write (TSS2_SYS_CONTEXT *sys_ctx)
  154. {
  155. TSS2_RC rc;
  156. TSS2L_SYS_AUTH_COMMAND auth_cmd = {
  157. .count = 1,
  158. };
  159. TSS2L_SYS_AUTH_RESPONSE auth_rsp = { 0, };
  160. TPM2B_MAX_NV_BUFFER write_data = {
  161. .size = 4,
  162. .buffer = { 0xff, 0xfe, 0xfd, 0xfc, },
  163. };
  164. rc = create_policy_session (sys_ctx,
  165. &auth_cmd.auths[0].sessionHandle);
  166. return_if_error (rc, "create_policy_session");
  167. rc = Tss2_Sys_NV_Write (sys_ctx,
  168. NV_INDEX,
  169. NV_INDEX,
  170. &auth_cmd,
  171. &write_data,
  172. 0,
  173. &auth_rsp);
  174. Tss2_Sys_FlushContext (sys_ctx, auth_cmd.auths [0].sessionHandle);
  175. return_if_error (rc, "Tss2_Sys_NV_Write");
  176. return rc;
  177. }
  178. /*
  179. * This function executes a write operation on the NV region from each
  180. * locality. Per the policy applied to the region @ provisioning, the
  181. * write command will fail for all localities except 3 and 4.
  182. */
  183. static TSS2_RC
  184. nv_write_test (TSS2_SYS_CONTEXT *sys_ctx)
  185. {
  186. TSS2_RC rc;
  187. uint8_t locality;
  188. TSS2_TCTI_CONTEXT *tcti_ctx;
  189. LOG_INFO ("TPM NV write with locality policy test");
  190. rc = Tss2_Sys_GetTctiContext (sys_ctx, &tcti_ctx);
  191. return_if_error (rc, "Tss2_Sys_GetTctiContext");
  192. for (locality = 0; locality < 5; ++locality)
  193. {
  194. LOG_INFO ("%s: writing NV from locality %" PRIu8, __func__, locality);
  195. rc = Tss2_Tcti_SetLocality (tcti_ctx, locality);
  196. if (rc == TSS2_TCTI_RC_NOT_IMPLEMENTED) {
  197. return 77;
  198. }
  199. return_if_error (rc, "Tss2_Tcti_SetLocality");
  200. rc = nv_write (sys_ctx);
  201. switch (locality) {
  202. case 0:
  203. case 1:
  204. case 2:
  205. if (rc != TPM2_RC_LOCALITY) {
  206. LOG_ERROR ("nv_write: Expecting TPM2_RC_LOCALITY, got "
  207. "0x%08" PRIu32, rc);
  208. return 1;
  209. }
  210. break;
  211. case 3:
  212. case 4:
  213. return_if_error (rc, "nv_write");
  214. break;
  215. default: /* locality can only be 0-4 */
  216. assert (false);
  217. break;
  218. }
  219. }
  220. return TSS2_RC_SUCCESS;
  221. }
  222. /*
  223. * This function executes a read command on the NV region from each
  224. * locality providing the required auth value (empty). Per the policy
  225. * defined a provisioning all should succeed.
  226. */
  227. static TSS2_RC
  228. nv_read_test (TSS2_SYS_CONTEXT *sys_ctx)
  229. {
  230. TSS2_RC rc;
  231. uint8_t locality;
  232. TPM2B_MAX_NV_BUFFER nv_buf;
  233. TSS2_TCTI_CONTEXT *tcti_ctx;
  234. TSS2L_SYS_AUTH_RESPONSE auth_rsp = { 0, };
  235. const TSS2L_SYS_AUTH_COMMAND auth_cmd = {
  236. .count = 1,
  237. .auths = {
  238. {
  239. .sessionHandle = TPM2_RH_PW,
  240. },
  241. },
  242. };
  243. rc = Tss2_Sys_GetTctiContext (sys_ctx, &tcti_ctx);
  244. return_if_error (rc, "Tss2_Sys_GetTctiContext");
  245. LOG_INFO ("TPM NV read with auth test");
  246. for (locality = 0; locality < 5; ++locality)
  247. {
  248. rc = Tss2_Tcti_SetLocality (tcti_ctx, locality);
  249. return_if_error (rc, "Tss2_Tcti_SetLocality");
  250. nv_buf.size = TPM2B_SIZE_MAX (nv_buf);
  251. rc = TSS2_RETRY_EXP (Tss2_Sys_NV_Read (sys_ctx,
  252. NV_INDEX,
  253. NV_INDEX,
  254. &auth_cmd,
  255. 4,
  256. 0,
  257. &nv_buf,
  258. &auth_rsp));
  259. return_if_error (rc, "Tss2_Sys_NV_Read");
  260. }
  261. rc = Tss2_Tcti_SetLocality (tcti_ctx, 3);
  262. return_if_error (rc, "Tss2_Tcti_SetLocality");
  263. return rc;
  264. }
  265. int
  266. test_invoke (TSS2_SYS_CONTEXT *sys_ctx)
  267. {
  268. TSS2_RC rc, rc_teardown;
  269. rc = setup_nv (sys_ctx);
  270. return_if_error (rc, "setup_nv");
  271. rc = nv_write_test (sys_ctx);
  272. goto_if_error (rc, "nv_write_test", teardown);
  273. rc = nv_read_test (sys_ctx);
  274. goto_if_error (rc, "nv_read_test", teardown);
  275. teardown:
  276. rc_teardown = teardown_nv (sys_ctx);
  277. return_if_error (rc, "NV policy locality test failed");
  278. return_if_error (rc_teardown, "teardown_nv");
  279. return rc;
  280. }