drivers/wifi: Remove unnecessary data structure copy
[coreboot2.git] / src / security / tpm / tss / tcg-2.0 / tss_marshaling.c
blob3039a8b8bae551abe59821260e400de221e31b19
1 /* SPDX-License-Identifier: BSD-3-Clause */
3 #include <commonlib/iobuf.h>
4 #include <console/console.h>
5 #include <string.h>
7 #include "tss_marshaling.h"
8 #include <security/tpm/tss/vendor/cr50/cr50.h>
9 #include <security/tpm/tss.h>
11 static uint16_t tpm_tag; /* Depends on the command type. */
13 #define unmarshal_TPM_CAP(a, b) ibuf_read_be32(a, b)
14 #define unmarshal_TPM_CC(a, b) ibuf_read_be32(a, b)
15 #define unmarshal_TPM_PT(a, b) ibuf_read_be32(a, b)
16 #define unmarshal_TPM_HANDLE(a, b) ibuf_read_be32(a, b)
18 #define marshal_TPM_HANDLE(a, b) obuf_write_be32(a, b)
19 #define marshal_TPMI_ALG_HASH(a, b) obuf_write_be16(a, b)
21 static int marshal_startup(struct obuf *ob, const struct tpm2_startup *cmd_body)
23 return obuf_write_be16(ob, cmd_body->startup_type);
26 static int marshal_shutdown(struct obuf *ob, const struct tpm2_shutdown *cmd_body)
28 return obuf_write_be16(ob, cmd_body->shutdown_type);
31 static int marshal_get_capability(struct obuf *ob,
32 const struct tpm2_get_capability *cmd_body)
34 int rc = 0;
36 rc |= obuf_write_be32(ob, cmd_body->capability);
37 rc |= obuf_write_be32(ob, cmd_body->property);
38 rc |= obuf_write_be32(ob, cmd_body->propertyCount);
40 return rc;
43 static int marshal_TPM2B(struct obuf *ob, const TPM2B *data)
45 int rc = 0;
47 rc |= obuf_write_be16(ob, data->size);
48 rc |= obuf_write(ob, data->buffer, data->size);
50 return rc;
53 static int marshal_TPMA_NV(struct obuf *ob, const TPMA_NV *nv)
55 uint32_t v;
57 memcpy(&v, nv, sizeof(v));
58 return obuf_write_be32(ob, v);
61 static int marshal_TPMS_NV_PUBLIC(struct obuf *ob, const TPMS_NV_PUBLIC *nvpub)
63 int rc = 0;
65 rc |= marshal_TPM_HANDLE(ob, nvpub->nvIndex);
66 rc |= marshal_TPMI_ALG_HASH(ob, nvpub->nameAlg);
67 rc |= marshal_TPMA_NV(ob, &nvpub->attributes);
68 rc |= marshal_TPM2B(ob, &nvpub->authPolicy.b);
69 rc |= obuf_write_be16(ob, nvpub->dataSize);
71 return rc;
74 static int marshal_TPMT_HA(struct obuf *ob, const TPMT_HA *tpmtha)
76 int rc = 0;
78 rc |= marshal_TPMI_ALG_HASH(ob, tpmtha->hashAlg);
79 switch (tpmtha->hashAlg) {
80 case TPM_ALG_SHA1:
81 rc |= obuf_write(ob, tpmtha->digest.sha1,
82 tlcl2_get_hash_size_from_algo(tpmtha->hashAlg));
83 break;
84 case TPM_ALG_SHA256:
85 rc |= obuf_write(ob, tpmtha->digest.sha256,
86 tlcl2_get_hash_size_from_algo(tpmtha->hashAlg));
87 break;
88 case TPM_ALG_SM3_256:
89 rc |= obuf_write(ob, tpmtha->digest.sm3_256,
90 tlcl2_get_hash_size_from_algo(tpmtha->hashAlg));
91 break;
92 case TPM_ALG_SHA384:
93 rc |= obuf_write(ob, tpmtha->digest.sha384,
94 tlcl2_get_hash_size_from_algo(tpmtha->hashAlg));
95 break;
96 case TPM_ALG_SHA512:
97 rc |= obuf_write(ob, tpmtha->digest.sha512,
98 tlcl2_get_hash_size_from_algo(tpmtha->hashAlg));
99 break;
100 default:
101 rc = -1;
103 return rc;
106 static int marshal_TPML_DIGEST_VALUES(struct obuf *ob,
107 const TPML_DIGEST_VALUES *dvalues)
109 int i;
110 int rc = 0;
112 rc |= obuf_write_be32(ob, dvalues->count);
113 for (i = 0; i < dvalues->count; i++)
114 rc |= marshal_TPMT_HA(ob, &dvalues->digests[i]);
116 return rc;
119 static int marshal_session_header(struct obuf *ob,
120 const struct tpm2_session_header *session_header)
122 int rc = 0;
123 struct obuf ob_sz;
124 size_t prev_written;
126 /* Snapshot current location to place size of header. */
127 if (obuf_splice_current(ob, &ob_sz, sizeof(uint32_t)) < 0)
128 return -1;
130 /* Write a size placeholder. */
131 rc |= obuf_write_be32(ob, 0);
133 /* Keep track of session header data size by tracking num written. */
134 prev_written = obuf_nr_written(ob);
136 rc |= obuf_write_be32(ob, session_header->session_handle);
137 rc |= obuf_write_be16(ob, session_header->nonce_size);
138 rc |= obuf_write(ob, session_header->nonce, session_header->nonce_size);
139 rc |= obuf_write_be8(ob, session_header->session_attrs);
140 rc |= obuf_write_be16(ob, session_header->auth_size);
141 rc |= obuf_write(ob, session_header->auth, session_header->auth_size);
143 /* Fill back in proper size of session header. */
144 rc |= obuf_write_be32(&ob_sz, obuf_nr_written(ob) - prev_written);
146 return rc;
150 * Common session header can include one or two handles and an empty
151 * session_header structure.
153 static int marshal_common_session_header(struct obuf *ob,
154 const uint32_t *handles,
155 size_t handle_count)
157 size_t i;
158 struct tpm2_session_header session_header;
159 int rc = 0;
161 tpm_tag = TPM_ST_SESSIONS;
163 for (i = 0; i < handle_count; i++)
164 rc |= marshal_TPM_HANDLE(ob, handles[i]);
166 memset(&session_header, 0, sizeof(session_header));
167 session_header.session_handle = TPM_RS_PW;
168 rc |= marshal_session_header(ob, &session_header);
170 return rc;
173 static int marshal_nv_define_space(struct obuf *ob,
174 const struct tpm2_nv_define_space_cmd *nvd_in)
176 const uint32_t handle[] = { TPM_RH_PLATFORM };
177 struct obuf ob_sz;
178 size_t prev_written;
179 int rc = 0;
181 rc |= marshal_common_session_header(ob, handle, ARRAY_SIZE(handle));
182 rc |= marshal_TPM2B(ob, &nvd_in->auth.b);
184 /* Snapshot current location to place size field. */
185 if (obuf_splice_current(ob, &ob_sz, sizeof(uint16_t)) < 0)
186 return -1;
188 /* Put placeholder for size */
189 rc |= obuf_write_be16(ob, 0);
191 /* Keep track of nv define space data size by tracking num written. */
192 prev_written = obuf_nr_written(ob);
194 rc |= marshal_TPMS_NV_PUBLIC(ob, &nvd_in->publicInfo);
195 rc |= obuf_write_be16(&ob_sz, obuf_nr_written(ob) - prev_written);
197 return rc;
200 static int marshal_nv_setbits(struct obuf *ob,
201 const struct tpm2_nv_setbits_cmd *command_body)
203 int rc = 0;
204 const uint32_t handles[] = { TPM_RH_PLATFORM, command_body->nvIndex };
206 rc |= marshal_common_session_header(ob, handles, ARRAY_SIZE(handles));
207 rc |= obuf_write_be64(ob, command_body->bits);
209 return rc;
212 static int marshal_nv_write(struct obuf *ob,
213 const struct tpm2_nv_write_cmd *command_body)
215 int rc = 0;
216 const uint32_t handles[] = { TPM_RH_PLATFORM, command_body->nvIndex };
218 rc |= marshal_common_session_header(ob, handles, ARRAY_SIZE(handles));
219 rc |= marshal_TPM2B(ob, &command_body->data.b);
220 rc |= obuf_write_be16(ob, command_body->offset);
222 return rc;
225 static int marshal_nv_write_lock(struct obuf *ob,
226 const struct tpm2_nv_write_lock_cmd *command_body)
228 const uint32_t handles[] = { TPM_RH_PLATFORM, command_body->nvIndex };
230 return marshal_common_session_header(ob, handles, ARRAY_SIZE(handles));
233 static int marshal_pcr_extend(struct obuf *ob,
234 const struct tpm2_pcr_extend_cmd *command_body)
236 int rc = 0;
237 const uint32_t handles[] = { command_body->pcrHandle };
239 rc |= marshal_common_session_header(ob, handles, ARRAY_SIZE(handles));
240 rc |= marshal_TPML_DIGEST_VALUES(ob, &command_body->digests);
242 return rc;
245 static int marshal_nv_read(struct obuf *ob,
246 const struct tpm2_nv_read_cmd *command_body)
248 int rc = 0;
249 const uint32_t handles[] = { TPM_RH_PLATFORM, command_body->nvIndex };
251 rc |= marshal_common_session_header(ob, handles, ARRAY_SIZE(handles));
252 rc |= obuf_write_be16(ob, command_body->size);
253 rc |= obuf_write_be16(ob, command_body->offset);
255 return rc;
258 /* TPM2_Clear command does not require parameters. */
259 static int marshal_clear(struct obuf *ob)
261 const uint32_t handle[] = { TPM_RH_PLATFORM };
263 return marshal_common_session_header(ob, handle, ARRAY_SIZE(handle));
266 static int marshal_selftest(struct obuf *ob,
267 const struct tpm2_self_test *command_body)
269 return obuf_write_be8(ob, command_body->yes_no);
272 static int marshal_hierarchy_control(struct obuf *ob,
273 const struct tpm2_hierarchy_control_cmd *command_body)
275 int rc = 0;
276 struct tpm2_session_header session_header;
278 tpm_tag = TPM_ST_SESSIONS;
280 rc |= marshal_TPM_HANDLE(ob, TPM_RH_PLATFORM);
281 memset(&session_header, 0, sizeof(session_header));
282 session_header.session_handle = TPM_RS_PW;
283 rc |= marshal_session_header(ob, &session_header);
285 rc |= marshal_TPM_HANDLE(ob, command_body->enable);
286 rc |= obuf_write_be8(ob, command_body->state);
288 return rc;
291 static int marshal_clear_control(struct obuf *ob,
292 const struct tpm2_clear_control_cmd *command_body)
294 int rc = 0;
295 struct tpm2_session_header session_header;
297 tpm_tag = TPM_ST_SESSIONS;
299 rc |= marshal_TPM_HANDLE(ob, TPM_RH_PLATFORM);
300 memset(&session_header, 0, sizeof(session_header));
301 session_header.session_handle = TPM_RS_PW;
302 rc |= marshal_session_header(ob, &session_header);
304 rc |= obuf_write_be8(ob, command_body->disable);
306 return rc;
309 static int marshal_cr50_vendor_command(struct obuf *ob, const void *command_body)
311 int rc = 0;
312 const uint16_t *sub_command = command_body;
314 switch (*sub_command) {
315 case TPM2_CR50_SUB_CMD_IMMEDIATE_RESET:
316 /* The 16-bit timeout parameter is optional for the
317 * IMMEDIATE_RESET command. However in coreboot, the timeout
318 * parameter must be specified.
320 rc |= obuf_write_be16(ob, sub_command[0]);
321 rc |= obuf_write_be16(ob, sub_command[1]);
322 break;
323 case TPM2_CR50_SUB_CMD_NVMEM_ENABLE_COMMITS:
324 rc |= obuf_write_be16(ob, *sub_command);
325 break;
326 case TPM2_CR50_SUB_CMD_TURN_UPDATE_ON:
327 rc |= obuf_write_be16(ob, sub_command[0]);
328 rc |= obuf_write_be16(ob, sub_command[1]);
329 break;
330 case TPM2_CR50_SUB_CMD_GET_REC_BTN:
331 rc |= obuf_write_be16(ob, *sub_command);
332 break;
333 case TPM2_CR50_SUB_CMD_TPM_MODE:
334 /* The Cr50 TPM_MODE command supports an optional parameter.
335 * When the parameter is present the Cr50 will attempt to change
336 * the TPM state (enable or disable) and returns the new state
337 * in the response. When the parameter is absent, the Cr50
338 * returns the current TPM state.
340 * coreboot currently only uses the TPM get capability and does
341 * not set a new TPM state with the Cr50.
343 rc |= obuf_write_be16(ob, *sub_command);
344 break;
345 case TPM2_CR50_SUB_CMD_GET_BOOT_MODE:
346 rc |= obuf_write_be16(ob, *sub_command);
347 break;
348 case TPM2_CR50_SUB_CMD_RESET_EC:
349 rc |= obuf_write_be16(ob, *sub_command);
350 break;
351 case TPM2_CR50_SUB_CMD_GET_FACTORY_CONFIG:
352 rc |= obuf_write_be16(ob, *sub_command);
353 break;
354 default:
355 /* Unsupported subcommand. */
356 printk(BIOS_WARNING, "Unsupported cr50 subcommand: 0x%04x\n",
357 *sub_command);
358 rc = -1;
359 break;
361 return rc;
364 int tpm_marshal_command(TPM_CC command, const void *tpm_command_body, struct obuf *ob)
366 struct obuf ob_hdr;
367 const size_t hdr_sz = sizeof(uint16_t) + 2 * sizeof(uint32_t);
368 int rc = 0;
370 tpm_tag = TPM_ST_NO_SESSIONS;
372 if (obuf_splice_current(ob, &ob_hdr, hdr_sz) < 0)
373 return -1;
375 /* Write TPM command header with placeholder field values. */
376 rc |= obuf_write_be16(ob, 0);
377 rc |= obuf_write_be32(ob, 0);
378 rc |= obuf_write_be32(ob, command);
380 if (rc != 0)
381 return rc;
383 switch (command) {
384 case TPM2_Startup:
385 rc |= marshal_startup(ob, tpm_command_body);
386 break;
388 case TPM2_Shutdown:
389 rc |= marshal_shutdown(ob, tpm_command_body);
390 break;
392 case TPM2_GetCapability:
393 rc |= marshal_get_capability(ob, tpm_command_body);
394 break;
396 case TPM2_NV_Read:
397 rc |= marshal_nv_read(ob, tpm_command_body);
398 break;
400 case TPM2_NV_DefineSpace:
401 rc |= marshal_nv_define_space(ob, tpm_command_body);
402 break;
404 case TPM2_NV_SetBits:
405 rc |= marshal_nv_setbits(ob, tpm_command_body);
406 break;
408 case TPM2_NV_Write:
409 rc |= marshal_nv_write(ob, tpm_command_body);
410 break;
412 case TPM2_NV_WriteLock:
413 rc |= marshal_nv_write_lock(ob, tpm_command_body);
414 break;
416 case TPM2_SelfTest:
417 rc |= marshal_selftest(ob, tpm_command_body);
418 break;
420 case TPM2_Hierarchy_Control:
421 rc |= marshal_hierarchy_control(ob, tpm_command_body);
422 break;
424 case TPM2_ClearControl:
425 rc |= marshal_clear_control(ob, tpm_command_body);
426 break;
428 case TPM2_Clear:
429 rc |= marshal_clear(ob);
430 break;
432 case TPM2_PCR_Extend:
433 rc |= marshal_pcr_extend(ob, tpm_command_body);
434 break;
436 case TPM2_CR50_VENDOR_COMMAND:
437 rc |= marshal_cr50_vendor_command(ob, tpm_command_body);
438 break;
440 default:
441 printk(BIOS_INFO, "%s:%d:Request to marshal unsupported command %#x\n",
442 __FILE__, __LINE__, command);
443 rc = -1;
446 if (rc != 0)
447 return rc;
449 /* Fix up the command header with known values. */
450 rc |= obuf_write_be16(&ob_hdr, tpm_tag);
451 rc |= obuf_write_be32(&ob_hdr, obuf_nr_written(ob));
453 return rc;
456 static int unmarshal_get_capability(struct ibuf *ib,
457 struct get_cap_response *gcr)
459 int i;
460 int rc = 0;
462 rc |= ibuf_read_be8(ib, &gcr->more_data);
463 rc |= unmarshal_TPM_CAP(ib, &gcr->cd.capability);
465 if (rc != 0)
466 return rc;
468 switch (gcr->cd.capability) {
469 case TPM_CAP_TPM_PROPERTIES:
470 if (ibuf_read_be32(ib, &gcr->cd.data.tpmProperties.count))
471 return -1;
472 if (gcr->cd.data.tpmProperties.count > ARRAY_SIZE
473 (gcr->cd.data.tpmProperties.tpmProperty)) {
474 printk(BIOS_INFO, "%s:%s:%d - %d - too many properties\n",
475 __FILE__, __func__, __LINE__,
476 gcr->cd.data.tpmProperties.count);
477 return -1;
479 for (i = 0; i < gcr->cd.data.tpmProperties.count; i++) {
480 TPMS_TAGGED_PROPERTY *pp;
482 pp = gcr->cd.data.tpmProperties.tpmProperty + i;
483 rc |= unmarshal_TPM_PT(ib, &pp->property);
484 rc |= ibuf_read_be32(ib, &pp->value);
486 break;
487 case TPM_CAP_PCRS:
488 if (ibuf_read_be32(ib, &gcr->cd.data.assignedPCR.count))
489 return -1;
490 if (gcr->cd.data.assignedPCR.count >
491 ARRAY_SIZE(gcr->cd.data.assignedPCR.pcrSelections)) {
492 printk(BIOS_INFO, "%s:%s:%d - %d - too many properties\n",
493 __FILE__, __func__, __LINE__,
494 gcr->cd.data.assignedPCR.count);
495 return -1;
497 for (i = 0; i < gcr->cd.data.assignedPCR.count; i++) {
498 TPMS_PCR_SELECTION *pp =
499 &gcr->cd.data.assignedPCR.pcrSelections[i];
500 rc |= ibuf_read(ib, pp, sizeof(TPMS_PCR_SELECTION));
502 break;
503 default:
504 printk(BIOS_ERR,
505 "%s:%d - unable to unmarshal capability response",
506 __func__, __LINE__);
507 printk(BIOS_ERR, " for %d\n", gcr->cd.capability);
508 rc = -1;
509 break;
512 return rc;
515 static int unmarshal_TPM2B_MAX_NV_BUFFER(struct ibuf *ib,
516 TPM2B_MAX_NV_BUFFER *nv_buffer)
518 if (ibuf_read_be16(ib, &nv_buffer->t.size))
519 return -1;
521 nv_buffer->t.buffer = ibuf_oob_drain(ib, nv_buffer->t.size);
523 if (!nv_buffer->t.buffer) {
524 printk(BIOS_ERR, "%s:%d - "
525 "size mismatch: expected %d, remaining %zd\n",
526 __func__, __LINE__, nv_buffer->t.size,
527 ibuf_remaining(ib));
528 return -1;
531 return 0;
534 static int unmarshal_nv_read(struct ibuf *ib, struct nv_read_response *nvr)
536 /* Total size of the parameter field. */
537 if (ibuf_read_be32(ib, &nvr->params_size))
538 return -1;
540 if (unmarshal_TPM2B_MAX_NV_BUFFER(ib, &nvr->buffer))
541 return -1;
543 if (nvr->params_size !=
544 (nvr->buffer.t.size + sizeof(nvr->buffer.t.size))) {
545 printk(BIOS_ERR,
546 "%s:%d - parameter/buffer %d/%d size mismatch",
547 __func__, __LINE__, nvr->params_size,
548 nvr->buffer.t.size);
549 return -1;
553 * Let's ignore the authorization section. It should be 5 bytes total,
554 * just confirm that this is the case and report any discrepancy.
556 if (ibuf_remaining(ib) != 5)
557 printk(BIOS_ERR,
558 "%s:%d - unexpected authorization section size %zd\n",
559 __func__, __LINE__, ibuf_remaining(ib));
561 ibuf_oob_drain(ib, ibuf_remaining(ib));
563 return 0;
566 static int unmarshal_vendor_command(struct ibuf *ib,
567 struct vendor_command_response *vcr)
569 if (ibuf_read_be16(ib, &vcr->vc_subcommand))
570 return -1;
572 switch (vcr->vc_subcommand) {
573 case TPM2_CR50_SUB_CMD_IMMEDIATE_RESET:
574 break;
575 case TPM2_CR50_SUB_CMD_NVMEM_ENABLE_COMMITS:
576 break;
577 case TPM2_CR50_SUB_CMD_TURN_UPDATE_ON:
578 return ibuf_read_be8(ib, &vcr->num_restored_headers);
579 case TPM2_CR50_SUB_CMD_GET_REC_BTN:
580 return ibuf_read_be8(ib, &vcr->recovery_button_state);
581 case TPM2_CR50_SUB_CMD_TPM_MODE:
582 return ibuf_read_be8(ib, &vcr->tpm_mode);
583 case TPM2_CR50_SUB_CMD_GET_BOOT_MODE:
584 return ibuf_read_be8(ib, &vcr->boot_mode);
585 case TPM2_CR50_SUB_CMD_RESET_EC:
586 break;
587 case TPM2_CR50_SUB_CMD_GET_FACTORY_CONFIG:
588 return ibuf_read_be64(ib, &vcr->factory_config);
589 default:
590 printk(BIOS_ERR,
591 "%s:%d - unsupported vendor command %#04x!\n",
592 __func__, __LINE__, vcr->vc_subcommand);
593 return -1;
596 return 0;
599 struct tpm2_response *tpm_unmarshal_response(TPM_CC command, struct ibuf *ib)
601 static struct tpm2_response tpm2_static_resp;
602 int rc = 0;
604 rc |= ibuf_read_be16(ib, &tpm2_static_resp.hdr.tpm_tag);
605 rc |= ibuf_read_be32(ib, &tpm2_static_resp.hdr.tpm_size);
606 rc |= unmarshal_TPM_CC(ib, &tpm2_static_resp.hdr.tpm_code);
608 if (rc != 0)
609 return NULL;
611 if (ibuf_capacity(ib) != tpm2_static_resp.hdr.tpm_size) {
612 printk(BIOS_ERR,
613 "%s: size mismatch in response to command %#x\n",
614 __func__, command);
615 return NULL;
618 /* On errors, we're not sure what the TPM is returning. None of the
619 commands we use actually expect useful data payloads for errors, so
620 just ignore any data after the header. */
621 if (tpm2_static_resp.hdr.tpm_code != TPM2_RC_SUCCESS)
622 return &tpm2_static_resp;
624 switch (command) {
625 case TPM2_Startup:
626 case TPM2_Shutdown:
627 case TPM2_SelfTest:
628 break;
630 case TPM2_GetCapability:
631 rc |= unmarshal_get_capability(ib, &tpm2_static_resp.gc);
632 break;
634 case TPM2_NV_Read:
635 rc |= unmarshal_nv_read(ib, &tpm2_static_resp.nvr);
636 break;
638 case TPM2_Hierarchy_Control:
639 case TPM2_Clear:
640 case TPM2_ClearControl:
641 case TPM2_NV_DefineSpace:
642 case TPM2_NV_SetBits:
643 case TPM2_NV_Write:
644 case TPM2_NV_WriteLock:
645 case TPM2_PCR_Extend:
646 /* Session data included in response can be safely ignored. */
647 ibuf_oob_drain(ib, ibuf_remaining(ib));
648 break;
650 case TPM2_CR50_VENDOR_COMMAND:
651 rc |= unmarshal_vendor_command(ib, &tpm2_static_resp.vcr);
652 break;
654 default:
656 size_t i;
657 size_t sz_left;
658 const uint8_t *data;
660 printk(BIOS_INFO, "%s:%d:"
661 "Request to unmarshal unexpected command %#x,"
662 " code %#x",
663 __func__, __LINE__, command,
664 tpm2_static_resp.hdr.tpm_code);
666 sz_left = ibuf_remaining(ib);
667 data = ibuf_oob_drain(ib, sz_left);
669 for (i = 0; i < sz_left; i++) {
670 if (!(i % 16))
671 printk(BIOS_INFO, "\n");
672 printk(BIOS_INFO, "%2.2x ", data[i]);
675 printk(BIOS_INFO, "\n");
676 return NULL;
679 if (ibuf_remaining(ib)) {
680 printk(BIOS_INFO,
681 "%s:%d got %d bytes back in response to %#x,"
682 " failed to parse (%zd)\n",
683 __func__, __LINE__, tpm2_static_resp.hdr.tpm_size,
684 command, ibuf_remaining(ib));
685 return NULL;
687 if (rc)
688 printk(BIOS_WARNING, "%s had one or more failures.\n",
689 __func__);
691 /* The entire message have been parsed. */
692 return &tpm2_static_resp;