marshaling.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827
  1. /*
  2. * Copyright 2016 The Chromium OS Authors. All rights reserved.
  3. * Use of this source code is governed by a BSD-style license that can be
  4. * found in the LICENSE file.
  5. */
  6. #include "2sysincludes.h"
  7. #include "2common.h"
  8. #include "tpm2_marshaling.h"
  9. #include "utility.h"
  10. static uint16_t tpm_tag; /* Depends on the command type. */
  11. static int ph_disabled; /* Platform hierarchy disabled. */
  12. static void write_be16(void *dest, uint16_t val)
  13. {
  14. uint8_t *byte_dest = dest;
  15. byte_dest[0] = val >> 8;
  16. byte_dest[1] = val;
  17. }
  18. static void write_be32(void *dest, uint32_t val)
  19. {
  20. uint8_t *byte_dest = dest;
  21. byte_dest[0] = val >> 24;
  22. byte_dest[1] = val >> 16;
  23. byte_dest[2] = val >> 8;
  24. byte_dest[3] = val;
  25. }
  26. static uint16_t read_be16(const void *src)
  27. {
  28. const uint8_t *s = src;
  29. return (((uint16_t)s[0]) << 8) | (((uint16_t)s[1]) << 0);
  30. }
  31. static inline uint32_t read_be32(const void *src)
  32. {
  33. const uint8_t *s = src;
  34. return (((uint32_t)s[0]) << 24) | (((uint32_t)s[1]) << 16) |
  35. (((uint32_t)s[2]) << 8) | (((uint32_t)s[3]) << 0);
  36. }
  37. /*
  38. * Each unmarshaling function receives a pointer to the buffer pointer and a
  39. * pointer to the size of data still in the buffer. The function extracts data
  40. * from the buffer and adjusts both buffer pointer and remaining data size.
  41. *
  42. * Should there be not enough data in the buffer to unmarshal the required
  43. * object, the remaining data size is set to -1 to indicate the error. The
  44. * remaining data size is expected to be set to zero once the last data item
  45. * has been extracted from the buffer.
  46. */
  47. static uint8_t unmarshal_u8(void **buffer, int *buffer_space)
  48. {
  49. uint8_t value;
  50. if (*buffer_space < sizeof(value)) {
  51. *buffer_space = -1; /* Indicate a failure. */
  52. return 0;
  53. }
  54. value = *(uint8_t *)(*buffer);
  55. *buffer = (void *) ((uintptr_t) (*buffer) + sizeof(value));
  56. *buffer_space -= sizeof(value);
  57. return value;
  58. }
  59. static uint16_t unmarshal_u16(void **buffer, int *buffer_space)
  60. {
  61. uint16_t value;
  62. if (*buffer_space < sizeof(value)) {
  63. *buffer_space = -1; /* Indicate a failure. */
  64. return 0;
  65. }
  66. value = read_be16(*buffer);
  67. *buffer = (void *) ((uintptr_t) (*buffer) + sizeof(value));
  68. *buffer_space -= sizeof(value);
  69. return value;
  70. }
  71. static uint32_t unmarshal_u32(void **buffer, int *buffer_space)
  72. {
  73. uint32_t value;
  74. if (*buffer_space < sizeof(value)) {
  75. *buffer_space = -1; /* Indicate a failure. */
  76. return 0;
  77. }
  78. value = read_be32(*buffer);
  79. *buffer = (void *) ((uintptr_t) (*buffer) + sizeof(value));
  80. *buffer_space -= sizeof(value);
  81. return value;
  82. }
  83. #define unmarshal_TPM_HANDLE(a, b) unmarshal_u32(a, b)
  84. #define unmarshal_ALG_ID(a, b) unmarshal_u16(a, b)
  85. static void unmarshal_TPM2B_MAX_NV_BUFFER(void **buffer,
  86. int *size,
  87. TPM2B_MAX_NV_BUFFER *nv_buffer)
  88. {
  89. nv_buffer->t.size = unmarshal_u16(buffer, size);
  90. if (nv_buffer->t.size > *size) {
  91. VB2_DEBUG("size mismatch: expected %d, remaining %d\n",
  92. nv_buffer->t.size, *size);
  93. return;
  94. }
  95. nv_buffer->t.buffer = *buffer;
  96. *buffer = ((uint8_t *)(*buffer)) + nv_buffer->t.size;
  97. *size -= nv_buffer->t.size;
  98. }
  99. static void unmarshal_authorization_section(void **buffer, int *size,
  100. char *cmd_name)
  101. {
  102. /*
  103. * Let's ignore the authorisation section. It should be 5 bytes total,
  104. * just confirm that this is the case and report any discrepancy.
  105. */
  106. if (*size != 5)
  107. VB2_DEBUG("unexpected authorisation section size %d for %s\n",
  108. *size, cmd_name);
  109. *buffer = ((uint8_t *)(*buffer)) + *size;
  110. *size = 0;
  111. }
  112. static void unmarshal_nv_read(void **buffer, int *size,
  113. struct nv_read_response *nvr)
  114. {
  115. /* Total size of the parameter field. */
  116. nvr->params_size = unmarshal_u32(buffer, size);
  117. unmarshal_TPM2B_MAX_NV_BUFFER(buffer, size, &nvr->buffer);
  118. if (nvr->params_size !=
  119. (nvr->buffer.t.size + sizeof(nvr->buffer.t.size))) {
  120. VB2_DEBUG("parameter/buffer %d/%d size mismatch",
  121. nvr->params_size, nvr->buffer.t.size);
  122. return;
  123. }
  124. if (*size < 0)
  125. return;
  126. unmarshal_authorization_section(buffer, size, "NV_Read");
  127. }
  128. static void unmarshal_TPM2B(void **buffer,
  129. int *size,
  130. TPM2B *tpm2b)
  131. {
  132. tpm2b->size = unmarshal_u16(buffer, size);
  133. if (tpm2b->size > *size) {
  134. VB2_DEBUG("size mismatch: expected %d, remaining %d\n",
  135. tpm2b->size, *size);
  136. *size = -1;
  137. return;
  138. }
  139. tpm2b->buffer = *buffer;
  140. *buffer = ((uint8_t *)(*buffer)) + tpm2b->size;
  141. *size -= tpm2b->size;
  142. }
  143. static void unmarshal_TPMS_NV_PUBLIC(void **buffer,
  144. int *size,
  145. TPMS_NV_PUBLIC *pub)
  146. {
  147. int tpm2b_size = unmarshal_u16(buffer, size);
  148. if (tpm2b_size > *size) {
  149. VB2_DEBUG("size mismatch: expected %d, remaining %d\n",
  150. tpm2b_size, *size);
  151. *size = -1;
  152. return;
  153. }
  154. *size -= tpm2b_size;
  155. pub->nvIndex = unmarshal_TPM_HANDLE(buffer, &tpm2b_size);
  156. pub->nameAlg = unmarshal_ALG_ID(buffer, &tpm2b_size);
  157. pub->attributes = unmarshal_u32(buffer, &tpm2b_size);
  158. unmarshal_TPM2B(buffer, &tpm2b_size, &pub->authPolicy);
  159. pub->dataSize = unmarshal_u16(buffer, &tpm2b_size);
  160. if (tpm2b_size != 0) {
  161. VB2_DEBUG("TPMS_NV_PUBLIC size doesn't match size field\n");
  162. *size = -1;
  163. return;
  164. }
  165. }
  166. static void unmarshal_nv_read_public(void **buffer, int *size,
  167. struct nv_read_public_response *nv_pub)
  168. {
  169. unmarshal_TPMS_NV_PUBLIC(buffer, size, &nv_pub->nvPublic);
  170. unmarshal_TPM2B(buffer, size, &nv_pub->nvName);
  171. if (*size > 0) {
  172. VB2_DEBUG("extra %d bytes after nvName\n", *size);
  173. *size = -1;
  174. return;
  175. }
  176. }
  177. static void unmarshal_TPML_TAGGED_TPM_PROPERTY(void **buffer, int *size,
  178. TPML_TAGGED_TPM_PROPERTY *prop)
  179. {
  180. prop->count = unmarshal_u32(buffer, size);
  181. if (prop->count != 1) {
  182. *size = -1;
  183. VB2_DEBUG("Request to unmarshal unsupported "
  184. "number of properties: %u\n",
  185. prop->count);
  186. return;
  187. }
  188. prop->tpm_property[0].property = unmarshal_u32(buffer, size);
  189. prop->tpm_property[0].value = unmarshal_u32(buffer, size);
  190. }
  191. static void unmarshal_TPMS_CAPABILITY_DATA(void **buffer, int *size,
  192. TPMS_CAPABILITY_DATA *cap_data)
  193. {
  194. cap_data->capability = unmarshal_u32(buffer, size);
  195. switch (cap_data->capability) {
  196. case TPM_CAP_TPM_PROPERTIES:
  197. unmarshal_TPML_TAGGED_TPM_PROPERTY(buffer, size,
  198. &cap_data->data.
  199. tpm_properties);
  200. break;
  201. default:
  202. *size = -1;
  203. VB2_DEBUG("Request to unmarshal unsupported capability %#x\n",
  204. cap_data->capability);
  205. }
  206. }
  207. static void unmarshal_get_capability(void **buffer, int *size,
  208. struct get_capability_response *cap)
  209. {
  210. /* Total size of the parameter field. */
  211. cap->more_data = unmarshal_u8(buffer, size);
  212. unmarshal_TPMS_CAPABILITY_DATA(buffer, size, &cap->capability_data);
  213. }
  214. /*
  215. * Each marshaling function receives a pointer to the buffer to marshal into,
  216. * a pointer to the data item to be marshaled, and a pointer to the remaining
  217. * room in the buffer.
  218. */
  219. /*
  220. * Marshaling an arbitrary blob requires its size in addition to common
  221. * parameter set.
  222. */
  223. static void marshal_blob(void **buffer, void *blob,
  224. size_t blob_size, int *buffer_space)
  225. {
  226. if (*buffer_space < blob_size) {
  227. *buffer_space = -1;
  228. return;
  229. }
  230. memcpy(*buffer, blob, blob_size);
  231. buffer_space -= blob_size;
  232. *buffer = (void *)((uintptr_t)(*buffer) + blob_size);
  233. }
  234. static void marshal_u8(void **buffer, uint8_t value, int *buffer_space)
  235. {
  236. uint8_t *bp = *buffer;
  237. if (*buffer_space < sizeof(value)) {
  238. *buffer_space = -1;
  239. return;
  240. }
  241. *bp++ = value;
  242. *buffer = bp;
  243. *buffer_space -= sizeof(value);
  244. }
  245. static void marshal_u16(void **buffer, uint16_t value, int *buffer_space)
  246. {
  247. if (*buffer_space < sizeof(value)) {
  248. *buffer_space = -1;
  249. return;
  250. }
  251. write_be16(*buffer, value);
  252. *buffer = (void *)((uintptr_t)(*buffer) + sizeof(value));
  253. *buffer_space -= sizeof(value);
  254. }
  255. static void marshal_u32(void **buffer, uint32_t value, int *buffer_space)
  256. {
  257. if (*buffer_space < sizeof(value)) {
  258. *buffer_space = -1;
  259. return;
  260. }
  261. write_be32(*buffer, value);
  262. *buffer = (void *)((uintptr_t)(*buffer) + sizeof(value));
  263. *buffer_space -= sizeof(value);
  264. }
  265. #define unmarshal_TPM_CC(a, b) unmarshal_u32(a, b)
  266. #define marshal_TPM_HANDLE(a, b, c) marshal_u32(a, b, c)
  267. #define marshal_TPM_SU(a, b, c) marshal_u16(a, b, c)
  268. #define marshal_ALG_ID(a, b, c) marshal_u16(a, b, c)
  269. /*
  270. * For TPM2B* structures the size field (16 or 32 bits) goes before the data.
  271. * When marshaling, we first reserve the space for the size field, then
  272. * marshal the data, then fill the reserved size field with the actual size
  273. * of the marshaled data.
  274. */
  275. typedef struct {
  276. int size;
  277. void *location;
  278. } tpm2_marshal_size_field;
  279. static void marshal_reserve_size_field(void **buffer,
  280. tpm2_marshal_size_field *field,
  281. int field_size,
  282. int *buffer_space)
  283. {
  284. if (field_size != sizeof(uint32_t) && field_size != sizeof(uint16_t)) {
  285. VB2_DEBUG("Unsupported size field size: %d\n", field_size);
  286. *buffer_space = -1;
  287. return;
  288. }
  289. if (*buffer_space < field_size) {
  290. *buffer_space = -1;
  291. return;
  292. }
  293. field->size = field_size;
  294. field->location = *buffer;
  295. *buffer_space -= field_size;
  296. *buffer = (void *)(((uintptr_t) *buffer) + field_size);
  297. }
  298. static void marshal_fill_size_field(void **buffer,
  299. tpm2_marshal_size_field *field,
  300. int include_size_field,
  301. int *buffer_space)
  302. {
  303. uintptr_t size = (uintptr_t) *buffer - (uintptr_t) field->location;
  304. if (*buffer_space < 0)
  305. return; /* The structure did not fit. */
  306. if (!include_size_field)
  307. size -= field->size;
  308. if (field->size == sizeof(uint32_t))
  309. marshal_u32(&field->location, size, &field->size);
  310. else /* if (field->size == sizeof(uint16_t)) */
  311. marshal_u16(&field->location, size, &field->size);
  312. }
  313. static void marshal_session_header(void **buffer,
  314. struct tpm2_session_header *session_header,
  315. int *buffer_space)
  316. {
  317. tpm2_marshal_size_field size_field;
  318. /* Skip room for the session header size. */
  319. marshal_reserve_size_field(buffer, &size_field,
  320. sizeof(uint32_t), buffer_space);
  321. marshal_u32(buffer, session_header->session_handle, buffer_space);
  322. marshal_u16(buffer, session_header->nonce_size, buffer_space);
  323. marshal_blob(buffer, session_header->nonce,
  324. session_header->nonce_size, buffer_space);
  325. marshal_u8(buffer, session_header->session_attrs, buffer_space);
  326. marshal_u16(buffer, session_header->auth_size, buffer_space);
  327. marshal_blob(buffer, session_header->auth,
  328. session_header->auth_size, buffer_space);
  329. /* Paste in the session size. */
  330. marshal_fill_size_field(buffer, &size_field, 0, buffer_space);
  331. }
  332. static void marshal_TPM2B(void **buffer,
  333. TPM2B *data,
  334. int *buffer_space)
  335. {
  336. size_t total_size = data->size + sizeof(data->size);
  337. if (total_size > *buffer_space) {
  338. *buffer_space = -1;
  339. return;
  340. }
  341. marshal_u16(buffer, data->size, buffer_space);
  342. memcpy(*buffer, data->buffer, data->size);
  343. *buffer = ((uint8_t *)(*buffer)) + data->size;
  344. *buffer_space -= data->size;
  345. }
  346. static void marshal_TPMS_NV_PUBLIC(void **buffer,
  347. TPMS_NV_PUBLIC *data,
  348. int *buffer_space)
  349. {
  350. tpm2_marshal_size_field size_field;
  351. /* Skip room for the size. */
  352. marshal_reserve_size_field(buffer, &size_field,
  353. sizeof(uint16_t), buffer_space);
  354. marshal_TPM_HANDLE(buffer, data->nvIndex, buffer_space);
  355. marshal_ALG_ID(buffer, data->nameAlg, buffer_space);
  356. marshal_u32(buffer, data->attributes, buffer_space);
  357. marshal_TPM2B(buffer, &data->authPolicy, buffer_space);
  358. marshal_u16(buffer, data->dataSize, buffer_space);
  359. /* Paste in the structure size. */
  360. marshal_fill_size_field(buffer, &size_field, 0, buffer_space);
  361. }
  362. static void marshal_nv_define_space(void **buffer,
  363. struct tpm2_nv_define_space_cmd
  364. *command_body,
  365. int *buffer_space)
  366. {
  367. struct tpm2_session_header session_header;
  368. /* Use platform authorization if PLATFORMCREATE is set, and owner
  369. * authorization otherwise (per TPM2 Spec. Part 2. Section 31.3.1).
  370. * Owner authorization with empty password will work only until
  371. * ownership is taken. Platform authorization will work only until
  372. * platform hierarchy is disabled (i.e. in firmware or in recovery
  373. * mode).
  374. */
  375. if (command_body->publicInfo.attributes & TPMA_NV_PLATFORMCREATE)
  376. marshal_TPM_HANDLE(buffer, TPM_RH_PLATFORM, buffer_space);
  377. else
  378. marshal_TPM_HANDLE(buffer, TPM_RH_OWNER, buffer_space);
  379. memset(&session_header, 0, sizeof(session_header));
  380. session_header.session_handle = TPM_RS_PW;
  381. marshal_session_header(buffer, &session_header, buffer_space);
  382. tpm_tag = TPM_ST_SESSIONS;
  383. marshal_TPM2B(buffer, &command_body->auth, buffer_space);
  384. marshal_TPMS_NV_PUBLIC(buffer, &command_body->publicInfo, buffer_space);
  385. }
  386. /* Determine which authorization should be used when writing or write-locking
  387. * an NV index.
  388. *
  389. * Use a simplified approach:
  390. * 1) Use platform auth for indexes defined by TPM and Platform, as
  391. * specified in "Registry of reserved TPM 2.0 handles and localities".
  392. * That will only work for indexes with PPWRITE, and until the platform
  393. * hierarchy is disabled.
  394. * 2) Use empty password auth for other indexes.
  395. * That will only work for indexes with AUTHWRITE and empty auth value.
  396. *
  397. * A more honest approach would require the caller to specify the
  398. * authorization, or would check the NV index attributes.
  399. * But that's not needed now, as all indexes defined by firmware are
  400. * in the TPM range and have PPWRITE. The indexes defined by the
  401. * OS are in the Owner range and have either OWNERWRITE or AUTHWRITE,
  402. * but we don't ever use Tlcl to write to OWNERWRITE indexes.
  403. */
  404. static TPM_HANDLE get_nv_index_write_auth(TPMI_RH_NV_INDEX nvIndex)
  405. {
  406. return nvIndex >= TPMI_RH_NV_INDEX_OWNER_START ?
  407. nvIndex :
  408. TPM_RH_PLATFORM;
  409. }
  410. static void marshal_nv_write(void **buffer,
  411. struct tpm2_nv_write_cmd *command_body,
  412. int *buffer_space)
  413. {
  414. struct tpm2_session_header session_header;
  415. marshal_TPM_HANDLE(buffer,
  416. get_nv_index_write_auth(command_body->nvIndex),
  417. buffer_space);
  418. marshal_TPM_HANDLE(buffer, command_body->nvIndex, buffer_space);
  419. memset(&session_header, 0, sizeof(session_header));
  420. session_header.session_handle = TPM_RS_PW;
  421. marshal_session_header(buffer, &session_header, buffer_space);
  422. tpm_tag = TPM_ST_SESSIONS;
  423. marshal_TPM2B(buffer, &command_body->data.b, buffer_space);
  424. marshal_u16(buffer, command_body->offset, buffer_space);
  425. }
  426. static void marshal_nv_read(void **buffer,
  427. struct tpm2_nv_read_cmd *command_body,
  428. int *buffer_space)
  429. {
  430. struct tpm2_session_header session_header;
  431. /* Use empty password auth if platform hierarchy is disabled */
  432. if (ph_disabled)
  433. marshal_TPM_HANDLE(buffer, command_body->nvIndex, buffer_space);
  434. else
  435. marshal_TPM_HANDLE(buffer, TPM_RH_PLATFORM, buffer_space);
  436. marshal_TPM_HANDLE(buffer, command_body->nvIndex, buffer_space);
  437. memset(&session_header, 0, sizeof(session_header));
  438. session_header.session_handle = TPM_RS_PW;
  439. marshal_session_header(buffer, &session_header, buffer_space);
  440. tpm_tag = TPM_ST_SESSIONS;
  441. marshal_u16(buffer, command_body->size, buffer_space);
  442. marshal_u16(buffer, command_body->offset, buffer_space);
  443. }
  444. static void marshal_nv_read_lock(void **buffer,
  445. struct tpm2_nv_read_lock_cmd *command_body,
  446. int *buffer_space)
  447. {
  448. struct tpm2_session_header session_header;
  449. tpm_tag = TPM_ST_SESSIONS;
  450. marshal_TPM_HANDLE(buffer, command_body->nvIndex, buffer_space);
  451. marshal_TPM_HANDLE(buffer, command_body->nvIndex, buffer_space);
  452. memset(&session_header, 0, sizeof(session_header));
  453. session_header.session_handle = TPM_RS_PW;
  454. marshal_session_header(buffer, &session_header, buffer_space);
  455. }
  456. static void marshal_nv_write_lock(void **buffer,
  457. struct tpm2_nv_write_lock_cmd *command_body,
  458. int *buffer_space)
  459. {
  460. struct tpm2_session_header session_header;
  461. tpm_tag = TPM_ST_SESSIONS;
  462. marshal_TPM_HANDLE(buffer,
  463. get_nv_index_write_auth(command_body->nvIndex),
  464. buffer_space);
  465. marshal_TPM_HANDLE(buffer, command_body->nvIndex, buffer_space);
  466. memset(&session_header, 0, sizeof(session_header));
  467. session_header.session_handle = TPM_RS_PW;
  468. marshal_session_header(buffer, &session_header, buffer_space);
  469. }
  470. static void marshal_nv_read_public(void **buffer,
  471. struct tpm2_nv_read_public_cmd *command_body,
  472. int *buffer_space)
  473. {
  474. tpm_tag = TPM_ST_NO_SESSIONS;
  475. marshal_TPM_HANDLE(buffer, command_body->nvIndex, buffer_space);
  476. }
  477. static void marshal_hierarchy_control(void **buffer,
  478. struct tpm2_hierarchy_control_cmd
  479. *command_body,
  480. int *buffer_space)
  481. {
  482. struct tpm2_session_header session_header;
  483. tpm_tag = TPM_ST_SESSIONS;
  484. marshal_TPM_HANDLE(buffer, TPM_RH_PLATFORM, buffer_space);
  485. memset(&session_header, 0, sizeof(session_header));
  486. session_header.session_handle = TPM_RS_PW;
  487. marshal_session_header(buffer, &session_header, buffer_space);
  488. marshal_TPM_HANDLE(buffer, command_body->enable, buffer_space);
  489. marshal_u8(buffer, command_body->state, buffer_space);
  490. }
  491. static void marshal_get_capability(void **buffer,
  492. struct tpm2_get_capability_cmd
  493. *command_body,
  494. int *buffer_space)
  495. {
  496. tpm_tag = TPM_ST_NO_SESSIONS;
  497. marshal_u32(buffer, command_body->capability, buffer_space);
  498. marshal_u32(buffer, command_body->property, buffer_space);
  499. marshal_u32(buffer, command_body->property_count, buffer_space);
  500. }
  501. static void marshal_clear(void **buffer,
  502. void *command_body,
  503. int *buffer_space)
  504. {
  505. struct tpm2_session_header session_header;
  506. tpm_tag = TPM_ST_SESSIONS;
  507. marshal_TPM_HANDLE(buffer, TPM_RH_PLATFORM, buffer_space);
  508. memset(&session_header, 0, sizeof(session_header));
  509. session_header.session_handle = TPM_RS_PW;
  510. marshal_session_header(buffer, &session_header, buffer_space);
  511. }
  512. static void marshal_self_test(void **buffer,
  513. struct tpm2_self_test_cmd *command_body,
  514. int *buffer_space)
  515. {
  516. tpm_tag = TPM_ST_NO_SESSIONS;
  517. marshal_u8(buffer, command_body->full_test, buffer_space);
  518. }
  519. static void marshal_startup(void **buffer,
  520. struct tpm2_startup_cmd *command_body,
  521. int *buffer_space)
  522. {
  523. tpm_tag = TPM_ST_NO_SESSIONS;
  524. marshal_TPM_SU(buffer, command_body->startup_type, buffer_space);
  525. }
  526. static void marshal_shutdown(void **buffer,
  527. struct tpm2_shutdown_cmd *command_body,
  528. int *buffer_space)
  529. {
  530. tpm_tag = TPM_ST_NO_SESSIONS;
  531. marshal_TPM_SU(buffer, command_body->shutdown_type, buffer_space);
  532. }
  533. int tpm_marshal_command(TPM_CC command, void *tpm_command_body,
  534. void *buffer, int buffer_size)
  535. {
  536. void *cmd_body = (uint8_t *)buffer + sizeof(struct tpm_header);
  537. int max_body_size = buffer_size - sizeof(struct tpm_header);
  538. int body_size = max_body_size;
  539. /* Will be modified when marshaling some commands. */
  540. tpm_tag = TPM_ST_NO_SESSIONS;
  541. switch (command) {
  542. case TPM2_NV_DefineSpace:
  543. marshal_nv_define_space(&cmd_body, tpm_command_body, &body_size);
  544. break;
  545. case TPM2_NV_Read:
  546. marshal_nv_read(&cmd_body, tpm_command_body, &body_size);
  547. break;
  548. case TPM2_NV_Write:
  549. marshal_nv_write(&cmd_body, tpm_command_body, &body_size);
  550. break;
  551. case TPM2_NV_ReadLock:
  552. marshal_nv_read_lock(&cmd_body, tpm_command_body, &body_size);
  553. break;
  554. case TPM2_NV_WriteLock:
  555. marshal_nv_write_lock(&cmd_body, tpm_command_body, &body_size);
  556. break;
  557. case TPM2_NV_ReadPublic:
  558. marshal_nv_read_public(&cmd_body, tpm_command_body, &body_size);
  559. break;
  560. case TPM2_Hierarchy_Control:
  561. marshal_hierarchy_control(&cmd_body,
  562. tpm_command_body, &body_size);
  563. break;
  564. case TPM2_GetCapability:
  565. marshal_get_capability(&cmd_body, tpm_command_body, &body_size);
  566. break;
  567. case TPM2_Clear:
  568. marshal_clear(&cmd_body, tpm_command_body, &body_size);
  569. break;
  570. case TPM2_SelfTest:
  571. marshal_self_test(&cmd_body, tpm_command_body, &body_size);
  572. break;
  573. case TPM2_Startup:
  574. marshal_startup(&cmd_body, tpm_command_body, &body_size);
  575. break;
  576. case TPM2_Shutdown:
  577. marshal_shutdown(&cmd_body, tpm_command_body, &body_size);
  578. break;
  579. default:
  580. body_size = -1;
  581. VB2_DEBUG("Request to marshal unsupported command %#x\n",
  582. command);
  583. }
  584. if (body_size > 0) {
  585. /* See how much room was taken by marshaling. */
  586. body_size = max_body_size - body_size;
  587. body_size += sizeof(struct tpm_header);
  588. marshal_u16(&buffer, tpm_tag, &max_body_size);
  589. marshal_u32(&buffer, body_size, &max_body_size);
  590. marshal_u32(&buffer, command, &max_body_size);
  591. }
  592. return body_size;
  593. }
  594. struct tpm2_response *tpm_unmarshal_response(TPM_CC command,
  595. void *response_body,
  596. int cr_size)
  597. {
  598. static struct tpm2_response tpm2_resp;
  599. if (cr_size < sizeof(struct tpm_header))
  600. return NULL;
  601. tpm2_resp.hdr.tpm_tag = unmarshal_u16(&response_body, &cr_size);
  602. tpm2_resp.hdr.tpm_size = unmarshal_u32(&response_body, &cr_size);
  603. tpm2_resp.hdr.tpm_code = unmarshal_TPM_CC(&response_body, &cr_size);
  604. if (!cr_size) {
  605. if (tpm2_resp.hdr.tpm_size != sizeof(tpm2_resp.hdr))
  606. VB2_DEBUG("size mismatch in response to command %#x\n",
  607. command);
  608. return &tpm2_resp;
  609. }
  610. switch (command) {
  611. case TPM2_NV_Read:
  612. unmarshal_nv_read(&response_body, &cr_size,
  613. &tpm2_resp.nvr);
  614. break;
  615. case TPM2_NV_ReadPublic:
  616. unmarshal_nv_read_public(&response_body, &cr_size,
  617. &tpm2_resp.nv_read_public);
  618. break;
  619. case TPM2_GetCapability:
  620. unmarshal_get_capability(&response_body, &cr_size,
  621. &tpm2_resp.cap);
  622. break;
  623. case TPM2_Hierarchy_Control:
  624. case TPM2_NV_Write:
  625. case TPM2_NV_WriteLock:
  626. case TPM2_NV_ReadLock:
  627. case TPM2_Clear:
  628. case TPM2_SelfTest:
  629. case TPM2_Startup:
  630. case TPM2_Shutdown:
  631. case TPM2_NV_DefineSpace:
  632. /* Session data included in response can be safely ignored. */
  633. cr_size = 0;
  634. break;
  635. default:
  636. {
  637. int i;
  638. VB2_DEBUG("Request to unmarshal unexpected command %#x,"
  639. " code %#x",
  640. command,
  641. tpm2_resp.hdr.tpm_code);
  642. for (i = 0; i < cr_size; i++) {
  643. if (!(i % 16))
  644. VB2_DEBUG_RAW("\n");
  645. VB2_DEBUG_RAW("%2.2x ",
  646. ((uint8_t *)response_body)[i]);
  647. }
  648. }
  649. VB2_DEBUG("\n");
  650. return NULL;
  651. }
  652. if (cr_size) {
  653. VB2_DEBUG("got %d bytes back in response to %#x,"
  654. " failed to parse (%d)\n",
  655. tpm2_resp.hdr.tpm_size,
  656. command, cr_size);
  657. return NULL;
  658. }
  659. /* The entire message have been parsed. */
  660. return &tpm2_resp;
  661. }
  662. uint32_t tpm_get_packet_size(const uint8_t *packet)
  663. {
  664. /* 0: tag (16 bit)
  665. * 2: size (32 bit)
  666. */
  667. return read_be32(packet + 2);
  668. }
  669. uint32_t tpm_get_packet_response_code(const uint8_t *packet)
  670. {
  671. /* 0: tag (16 bit)
  672. * 2: size (32 bit)
  673. * 6: resp code (32 bit)
  674. */
  675. return read_be32(packet + 6);
  676. }
  677. void tpm_set_ph_disabled(int flag)
  678. {
  679. ph_disabled = flag;
  680. }
  681. int tpm_is_ph_disabled(void)
  682. {
  683. return ph_disabled;
  684. }