esys-createloaded.int.c 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. /* SPDX-License-Identifier: BSD-2-Clause */
  2. /*******************************************************************************
  3. * Copyright 2017-2018, Fraunhofer SIT sponsored by Infineon Technologies AG
  4. * All rights reserved.
  5. *******************************************************************************/
  6. #ifdef HAVE_CONFIG_H
  7. #include <config.h>
  8. #endif
  9. #include <stdbool.h>
  10. #include <stdlib.h>
  11. #include "tss2_esys.h"
  12. #include "tss2_mu.h"
  13. #include "esys_iutil.h"
  14. #include "test-esys.h"
  15. #define LOGMODULE test
  16. #include "util/log.h"
  17. #include "util/aux_util.h"
  18. static bool check_name(ESYS_CONTEXT * esys_context, ESYS_TR object_handle)
  19. {
  20. bool result = false;
  21. TPM2B_NAME *read_name = NULL;
  22. TPM2B_NAME *get_name = NULL;
  23. TSS2_RC r = Esys_ReadPublic(esys_context, object_handle,
  24. ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
  25. NULL, &read_name, NULL);
  26. goto_if_error(r, "Error esys readpublic", out);
  27. r = Esys_TR_GetName(esys_context, object_handle, &get_name);
  28. goto_if_error(r, "Error esys getname", out);
  29. if (read_name->size != get_name->size) {
  30. LOG_ERROR("name size mismatch %u != %u",
  31. read_name->size, get_name->size);
  32. goto out;
  33. }
  34. result = memcmp(read_name->name, get_name->name, get_name->size) == 0;
  35. out:
  36. Esys_Free(read_name);
  37. Esys_Free(get_name);
  38. return result;
  39. }
  40. /** This test is intended to test the ESYS command CreateLoaded.
  41. *
  42. * We start by creating a primary key (Esys_CreatePrimary).
  43. * This primary key will be used as parent key for CreateLoaded.
  44. *
  45. * Tested ESYS commands:
  46. * - Esys_CreateLoaded() (F)
  47. * - Esys_CreatePrimary() (M)
  48. * - Esys_FlushContext() (M)
  49. * - Esys_StartAuthSession() (M)
  50. * - Esys_TR_GetName() (M)
  51. * - Esys_TR_ReadPublic() (M)
  52. *
  53. * Used compiler defines: TEST_SESSION
  54. *
  55. * @param[in,out] esys_context The ESYS_CONTEXT.
  56. * @retval EXIT_FAILURE
  57. * @retval EXIT_SKIP
  58. * @retval EXIT_SUCCESS
  59. */
  60. int
  61. test_esys_createloaded(ESYS_CONTEXT * esys_context)
  62. {
  63. TSS2_RC r;
  64. ESYS_TR primaryHandle = ESYS_TR_NONE;
  65. ESYS_TR objectHandle = ESYS_TR_NONE;
  66. int failure_return = EXIT_FAILURE;
  67. TPM2B_PUBLIC *outPublic = NULL;
  68. TPM2B_CREATION_DATA *creationData = NULL;
  69. TPM2B_DIGEST *creationHash = NULL;
  70. TPMT_TK_CREATION *creationTicket = NULL;
  71. TPM2B_PRIVATE *outPrivate2 = NULL;
  72. TPM2B_PUBLIC *outPublic2 = NULL;
  73. #ifdef TEST_SESSION
  74. ESYS_TR session = ESYS_TR_NONE;
  75. TPMT_SYM_DEF symmetric = {.algorithm = TPM2_ALG_AES,
  76. .keyBits = {.aes = 128},
  77. .mode = {.aes = TPM2_ALG_CFB}
  78. };
  79. TPMA_SESSION sessionAttributes;
  80. TPM2B_NONCE nonceCaller = {
  81. .size = 20,
  82. .buffer = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
  83. 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}
  84. };
  85. memset(&sessionAttributes, 0, sizeof sessionAttributes);
  86. r = Esys_StartAuthSession(esys_context, ESYS_TR_NONE, ESYS_TR_NONE,
  87. ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
  88. &nonceCaller,
  89. TPM2_SE_HMAC, &symmetric, TPM2_ALG_SHA256,
  90. &session);
  91. goto_if_error(r, "Error: During initialization of session", error);
  92. #endif /* TEST_SESSION */
  93. TPM2B_PUBLIC inPublic = {
  94. .size = 0,
  95. .publicArea = {
  96. .type = TPM2_ALG_RSA,
  97. .nameAlg = TPM2_ALG_SHA256,
  98. .objectAttributes = (TPMA_OBJECT_USERWITHAUTH |
  99. TPMA_OBJECT_RESTRICTED |
  100. TPMA_OBJECT_DECRYPT |
  101. TPMA_OBJECT_FIXEDTPM |
  102. TPMA_OBJECT_FIXEDPARENT |
  103. TPMA_OBJECT_SENSITIVEDATAORIGIN),
  104. .authPolicy = {
  105. .size = 0,
  106. },
  107. .parameters.rsaDetail = {
  108. .symmetric = {
  109. .algorithm = TPM2_ALG_AES,
  110. .keyBits.aes = 128,
  111. .mode.aes = TPM2_ALG_CFB},
  112. .scheme = {
  113. .scheme = TPM2_ALG_NULL
  114. },
  115. .keyBits = 2048,
  116. .exponent = 0,
  117. },
  118. .unique.rsa = {
  119. .size = 0,
  120. .buffer = {},
  121. },
  122. },
  123. };
  124. TPM2B_AUTH authValuePrimary = {
  125. .size = 5,
  126. .buffer = {1, 2, 3, 4, 5}
  127. };
  128. TPM2B_SENSITIVE_CREATE inSensitivePrimary = {
  129. .size = 0,
  130. .sensitive = {
  131. .userAuth = authValuePrimary,
  132. .data = {
  133. .size = 0,
  134. .buffer = {0},
  135. },
  136. },
  137. };
  138. TPM2B_DATA outsideInfo = {
  139. .size = 0,
  140. .buffer = {},
  141. };
  142. TPML_PCR_SELECTION creationPCR = {
  143. .count = 0,
  144. };
  145. TPM2B_AUTH authValue = {
  146. .size = 0,
  147. .buffer = {}
  148. };
  149. r = Esys_TR_SetAuth(esys_context, ESYS_TR_RH_OWNER, &authValue);
  150. goto_if_error(r, "Error: TR_SetAuth", error);
  151. r = Esys_CreatePrimary(esys_context, ESYS_TR_RH_OWNER, ESYS_TR_PASSWORD,
  152. ESYS_TR_NONE, ESYS_TR_NONE, &inSensitivePrimary, &inPublic,
  153. &outsideInfo, &creationPCR, &primaryHandle,
  154. &outPublic, &creationData, &creationHash,
  155. &creationTicket);
  156. goto_if_error(r, "Error esys create primary", error);
  157. r = Esys_TR_SetAuth(esys_context, primaryHandle, &authValuePrimary);
  158. goto_if_error(r, "Setting the Primary's AuthValue", error);
  159. TPM2B_AUTH authValueObject = {
  160. .size = 5,
  161. .buffer = {6, 7, 8, 9, 10}
  162. };
  163. TPM2B_SENSITIVE_CREATE inSensitiveObject = {
  164. .size = 0,
  165. .sensitive = {
  166. .userAuth = authValueObject,
  167. .data = {
  168. .size = 0,
  169. .buffer = {0},
  170. },
  171. },
  172. };
  173. TPM2B_TEMPLATE inPublic_template = {0};
  174. TPMT_PUBLIC inPublic2 = {
  175. .type = TPM2_ALG_ECC,
  176. .nameAlg = TPM2_ALG_SHA256,
  177. .objectAttributes = (TPMA_OBJECT_USERWITHAUTH |
  178. TPMA_OBJECT_RESTRICTED |
  179. TPMA_OBJECT_SIGN_ENCRYPT |
  180. TPMA_OBJECT_FIXEDTPM |
  181. TPMA_OBJECT_FIXEDPARENT |
  182. TPMA_OBJECT_SENSITIVEDATAORIGIN),
  183. .authPolicy = {
  184. .size = 0,
  185. },
  186. .parameters.eccDetail = {
  187. .symmetric = {
  188. .algorithm = TPM2_ALG_NULL,
  189. .keyBits.aes = 128,
  190. .mode.aes = TPM2_ALG_CFB,
  191. },
  192. .scheme = {
  193. .scheme = TPM2_ALG_ECDSA,
  194. .details = {.ecdsa =
  195. {.hashAlg = TPM2_ALG_SHA256}
  196. }
  197. },
  198. .curveID = TPM2_ECC_NIST_P256,
  199. .kdf = {.scheme =
  200. TPM2_ALG_NULL,.details = {}
  201. }
  202. },
  203. .unique.ecc = {
  204. .x = {.size = 0,.buffer = {}},
  205. .y = {.size = 0,.buffer = {}}
  206. },
  207. };
  208. size_t offset = 0;
  209. r = Tss2_MU_TPMT_PUBLIC_Marshal(&inPublic2, &inPublic_template.buffer[0],
  210. sizeof(TPMT_PUBLIC), &offset);
  211. goto_if_error(r, "Error Tss2_MU_TPMT_PUBLIC_Marshal", error);
  212. inPublic_template.size = offset;
  213. r = Esys_CreateLoaded(
  214. esys_context,
  215. primaryHandle,
  216. #ifdef TEST_SESSION
  217. session,
  218. #else
  219. ESYS_TR_PASSWORD,
  220. #endif
  221. ESYS_TR_NONE,
  222. ESYS_TR_NONE,
  223. &inSensitiveObject,
  224. &inPublic_template,
  225. &objectHandle,
  226. &outPrivate2,
  227. &outPublic2
  228. );
  229. if ((r == TPM2_RC_COMMAND_CODE) ||
  230. (r == (TPM2_RC_COMMAND_CODE | TSS2_RESMGR_RC_LAYER)) ||
  231. (r == (TPM2_RC_COMMAND_CODE | TSS2_RESMGR_TPM_RC_LAYER))) {
  232. LOG_WARNING("Command TPM2_CreateLoaded not supported by TPM.");
  233. failure_return = EXIT_SKIP;
  234. goto error;
  235. }
  236. goto_if_error(r, "Error During CreateLoaded", error);
  237. bool names_match = check_name(esys_context, objectHandle);
  238. if (!names_match) {
  239. goto error;
  240. }
  241. r = Esys_FlushContext(esys_context, primaryHandle);
  242. goto_if_error(r, "Flushing context", error);
  243. primaryHandle = ESYS_TR_NONE;
  244. r = Esys_FlushContext(esys_context, objectHandle);
  245. goto_if_error(r, "Flushing context", error);
  246. objectHandle = ESYS_TR_NONE;
  247. #ifdef TEST_SESSION
  248. r = Esys_FlushContext(esys_context, session);
  249. goto_if_error(r, "Error: FlushContext", error);
  250. #endif
  251. SAFE_FREE(outPublic);
  252. SAFE_FREE(creationData);
  253. SAFE_FREE(creationHash);
  254. SAFE_FREE(creationTicket);
  255. SAFE_FREE(outPrivate2);
  256. SAFE_FREE(outPublic2);
  257. return EXIT_SUCCESS;
  258. error:
  259. #ifdef TEST_SESSION
  260. if (session != ESYS_TR_NONE) {
  261. if (Esys_FlushContext(esys_context, session) != TSS2_RC_SUCCESS) {
  262. LOG_ERROR("Cleanup session failed.");
  263. }
  264. }
  265. #endif
  266. if (objectHandle != ESYS_TR_NONE) {
  267. if (Esys_FlushContext(esys_context, objectHandle) != TSS2_RC_SUCCESS) {
  268. LOG_ERROR("Cleanup objectHandle failed.");
  269. }
  270. }
  271. if (primaryHandle != ESYS_TR_NONE) {
  272. if (Esys_FlushContext(esys_context, primaryHandle) != TSS2_RC_SUCCESS) {
  273. LOG_ERROR("Cleanup primaryHandle failed.");
  274. }
  275. }
  276. SAFE_FREE(outPublic);
  277. SAFE_FREE(creationData);
  278. SAFE_FREE(creationHash);
  279. SAFE_FREE(creationTicket);
  280. SAFE_FREE(outPrivate2);
  281. SAFE_FREE(outPublic2);
  282. return failure_return;
  283. }
  284. int
  285. test_invoke_esys(ESYS_CONTEXT * esys_context) {
  286. return test_esys_createloaded(esys_context);
  287. }