blob: ae623043e69012fcbc1cbcc70a130ba040d1d099 [file] [log] [blame]
Jacob Garberfa8f5672020-05-18 13:18:19 -06001/* SPDX-License-Identifier: BSD-3-Clause */
Vadim Bendebury627afc22016-06-19 12:13:18 -07002
Aaron Durbinee049fa2017-03-25 00:38:45 -05003#include <commonlib/iobuf.h>
Vadim Bendebury627afc22016-06-19 12:13:18 -07004#include <console/console.h>
Vadim Bendebury627afc22016-06-19 12:13:18 -07005#include <string.h>
6
Philipp Deppenwiesed88fb362017-10-18 20:26:18 +02007#include "tss_marshaling.h"
Philipp Deppenwiesec07f8fb2018-02-27 19:40:52 +01008#include <security/tpm/tss/vendor/cr50/cr50.h>
Frans Hendriks589eff72019-06-26 10:43:40 +02009#include <security/tpm/tss.h>
Vadim Bendebury627afc22016-06-19 12:13:18 -070010
Arthur Heymans0ca944b2019-11-20 19:51:06 +010011static uint16_t tpm_tag; /* Depends on the command type. */
Vadim Bendebury627afc22016-06-19 12:13:18 -070012
Aaron Durbinee049fa2017-03-25 00:38:45 -050013#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)
17
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)
20
Caveh Jalalic07fb752020-09-11 22:10:55 -070021static int marshal_startup(struct obuf *ob, const struct tpm2_startup *cmd_body)
Vadim Bendebury627afc22016-06-19 12:13:18 -070022{
Aaron Durbinee049fa2017-03-25 00:38:45 -050023 return obuf_write_be16(ob, cmd_body->startup_type);
Vadim Bendebury627afc22016-06-19 12:13:18 -070024}
25
Caveh Jalalic07fb752020-09-11 22:10:55 -070026static int marshal_shutdown(struct obuf *ob, const struct tpm2_shutdown *cmd_body)
Joel Kitching2e690ee2018-11-15 16:48:53 +080027{
28 return obuf_write_be16(ob, cmd_body->shutdown_type);
29}
30
Aaron Durbinee049fa2017-03-25 00:38:45 -050031static int marshal_get_capability(struct obuf *ob,
Caveh Jalalic07fb752020-09-11 22:10:55 -070032 const struct tpm2_get_capability *cmd_body)
Vadim Bendebury627afc22016-06-19 12:13:18 -070033{
Aaron Durbinee049fa2017-03-25 00:38:45 -050034 int rc = 0;
Vadim Bendebury627afc22016-06-19 12:13:18 -070035
Aaron Durbinee049fa2017-03-25 00:38:45 -050036 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);
Vadim Bendeburybc927102016-07-07 10:52:46 -070039
Aaron Durbinee049fa2017-03-25 00:38:45 -050040 return rc;
Vadim Bendebury627afc22016-06-19 12:13:18 -070041}
42
Caveh Jalalic07fb752020-09-11 22:10:55 -070043static int marshal_TPM2B(struct obuf *ob, const TPM2B *data)
Vadim Bendebury627afc22016-06-19 12:13:18 -070044{
Aaron Durbinee049fa2017-03-25 00:38:45 -050045 int rc = 0;
Vadim Bendebury627afc22016-06-19 12:13:18 -070046
Aaron Durbinee049fa2017-03-25 00:38:45 -050047 rc |= obuf_write_be16(ob, data->size);
48 rc |= obuf_write(ob, data->buffer, data->size);
Vadim Bendeburybc927102016-07-07 10:52:46 -070049
Aaron Durbinee049fa2017-03-25 00:38:45 -050050 return rc;
Vadim Bendebury627afc22016-06-19 12:13:18 -070051}
52
Caveh Jalalic07fb752020-09-11 22:10:55 -070053static int marshal_TPMA_NV(struct obuf *ob, const TPMA_NV *nv)
Vadim Bendebury627afc22016-06-19 12:13:18 -070054{
Aaron Durbinee049fa2017-03-25 00:38:45 -050055 uint32_t v;
Vadim Bendebury627afc22016-06-19 12:13:18 -070056
Aaron Durbinee049fa2017-03-25 00:38:45 -050057 memcpy(&v, nv, sizeof(v));
58 return obuf_write_be32(ob, v);
Vadim Bendebury627afc22016-06-19 12:13:18 -070059}
60
Caveh Jalalic07fb752020-09-11 22:10:55 -070061static int marshal_TPMS_NV_PUBLIC(struct obuf *ob, const TPMS_NV_PUBLIC *nvpub)
Vadim Bendebury627afc22016-06-19 12:13:18 -070062{
Aaron Durbinee049fa2017-03-25 00:38:45 -050063 int rc = 0;
Vadim Bendebury627afc22016-06-19 12:13:18 -070064
Aaron Durbinee049fa2017-03-25 00:38:45 -050065 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);
Vadim Bendebury627afc22016-06-19 12:13:18 -070070
Aaron Durbinee049fa2017-03-25 00:38:45 -050071 return rc;
Vadim Bendebury627afc22016-06-19 12:13:18 -070072}
73
Caveh Jalalic07fb752020-09-11 22:10:55 -070074static int marshal_TPMT_HA(struct obuf *ob, const TPMT_HA *tpmtha)
Vadim Bendebury627afc22016-06-19 12:13:18 -070075{
Aaron Durbinee049fa2017-03-25 00:38:45 -050076 int rc = 0;
77
78 rc |= marshal_TPMI_ALG_HASH(ob, tpmtha->hashAlg);
Frans Hendriksaa771cb2019-09-04 11:10:27 +020079 switch (tpmtha->hashAlg) {
80 case TPM_ALG_SHA1:
81 rc |= obuf_write(ob, tpmtha->digest.sha1,
Frans Hendriks7e220ca2019-06-28 10:18:22 +020082 tlcl_get_hash_size_from_algo(tpmtha->hashAlg));
Frans Hendriksaa771cb2019-09-04 11:10:27 +020083 break;
84 case TPM_ALG_SHA256:
85 rc |= obuf_write(ob, tpmtha->digest.sha256,
86 tlcl_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 tlcl_get_hash_size_from_algo(tpmtha->hashAlg));
91 break;
92 case TPM_ALG_SHA384:
93 rc |= obuf_write(ob, tpmtha->digest.sha384,
94 tlcl_get_hash_size_from_algo(tpmtha->hashAlg));
95 break;
96 case TPM_ALG_SHA512:
97 rc |= obuf_write(ob, tpmtha->digest.sha512,
98 tlcl_get_hash_size_from_algo(tpmtha->hashAlg));
99 break;
100 default:
101 rc = -1;
102 }
Aaron Durbinee049fa2017-03-25 00:38:45 -0500103 return rc;
Vadim Bendebury627afc22016-06-19 12:13:18 -0700104}
105
Aaron Durbinee049fa2017-03-25 00:38:45 -0500106static int marshal_TPML_DIGEST_VALUES(struct obuf *ob,
Caveh Jalalic07fb752020-09-11 22:10:55 -0700107 const TPML_DIGEST_VALUES *dvalues)
Vadim Bendeburyf5ef6992016-07-03 22:20:17 -0700108{
109 int i;
Aaron Durbinee049fa2017-03-25 00:38:45 -0500110 int rc = 0;
Vadim Bendeburyf5ef6992016-07-03 22:20:17 -0700111
Aaron Durbinee049fa2017-03-25 00:38:45 -0500112 rc |= obuf_write_be32(ob, dvalues->count);
Vadim Bendeburyf5ef6992016-07-03 22:20:17 -0700113 for (i = 0; i < dvalues->count; i++)
Aaron Durbinee049fa2017-03-25 00:38:45 -0500114 rc |= marshal_TPMT_HA(ob, &dvalues->digests[i]);
115
116 return rc;
Vadim Bendeburyf5ef6992016-07-03 22:20:17 -0700117}
118
Aaron Durbinee049fa2017-03-25 00:38:45 -0500119static int marshal_session_header(struct obuf *ob,
Caveh Jalalic07fb752020-09-11 22:10:55 -0700120 const struct tpm2_session_header *session_header)
Vadim Bendebury627afc22016-06-19 12:13:18 -0700121{
Aaron Durbinee049fa2017-03-25 00:38:45 -0500122 int rc = 0;
123 struct obuf ob_sz;
124 size_t prev_written;
Vadim Bendebury627afc22016-06-19 12:13:18 -0700125
Aaron Durbinee049fa2017-03-25 00:38:45 -0500126 /* Snapshot current location to place size of header. */
127 if (obuf_splice_current(ob, &ob_sz, sizeof(uint32_t)) < 0)
128 return -1;
Vadim Bendeburybc927102016-07-07 10:52:46 -0700129
Aaron Durbinee049fa2017-03-25 00:38:45 -0500130 /* Write a size placeholder. */
131 rc |= obuf_write_be32(ob, 0);
Vadim Bendebury627afc22016-06-19 12:13:18 -0700132
Aaron Durbinee049fa2017-03-25 00:38:45 -0500133 /* Keep track of session header data size by tracking num written. */
134 prev_written = obuf_nr_written(ob);
Vadim Bendebury627afc22016-06-19 12:13:18 -0700135
Aaron Durbinee049fa2017-03-25 00:38:45 -0500136 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);
Vadim Bendebury627afc22016-06-19 12:13:18 -0700142
Aaron Durbinee049fa2017-03-25 00:38:45 -0500143 /* Fill back in proper size of session header. */
144 rc |= obuf_write_be32(&ob_sz, obuf_nr_written(ob) - prev_written);
Vadim Bendebury627afc22016-06-19 12:13:18 -0700145
Aaron Durbinee049fa2017-03-25 00:38:45 -0500146 return rc;
Vadim Bendebury627afc22016-06-19 12:13:18 -0700147}
148
Vadim Bendeburyebba4d72016-07-07 11:04:06 -0700149/*
150 * Common session header can include one or two handles and an empty
151 * session_header structure.
152 */
Aaron Durbinee049fa2017-03-25 00:38:45 -0500153static int marshal_common_session_header(struct obuf *ob,
Caveh Jalalic07fb752020-09-11 22:10:55 -0700154 const uint32_t *handles,
155 size_t handle_count)
Vadim Bendeburyebba4d72016-07-07 11:04:06 -0700156{
Aaron Durbinee049fa2017-03-25 00:38:45 -0500157 size_t i;
Vadim Bendeburyebba4d72016-07-07 11:04:06 -0700158 struct tpm2_session_header session_header;
Aaron Durbinee049fa2017-03-25 00:38:45 -0500159 int rc = 0;
Vadim Bendeburyebba4d72016-07-07 11:04:06 -0700160
Arthur Heymans0ca944b2019-11-20 19:51:06 +0100161 tpm_tag = TPM_ST_SESSIONS;
Vadim Bendeburyebba4d72016-07-07 11:04:06 -0700162
163 for (i = 0; i < handle_count; i++)
Aaron Durbinee049fa2017-03-25 00:38:45 -0500164 rc |= marshal_TPM_HANDLE(ob, handles[i]);
Vadim Bendeburyebba4d72016-07-07 11:04:06 -0700165
166 memset(&session_header, 0, sizeof(session_header));
167 session_header.session_handle = TPM_RS_PW;
Aaron Durbinee049fa2017-03-25 00:38:45 -0500168 rc |= marshal_session_header(ob, &session_header);
169
170 return rc;
Vadim Bendeburyebba4d72016-07-07 11:04:06 -0700171}
172
Aaron Durbinee049fa2017-03-25 00:38:45 -0500173static int marshal_nv_define_space(struct obuf *ob,
Caveh Jalalic07fb752020-09-11 22:10:55 -0700174 const struct tpm2_nv_define_space_cmd *nvd_in)
Vadim Bendebury627afc22016-06-19 12:13:18 -0700175{
Vadim Bendeburyebba4d72016-07-07 11:04:06 -0700176 const uint32_t handle[] = { TPM_RH_PLATFORM };
Aaron Durbinee049fa2017-03-25 00:38:45 -0500177 struct obuf ob_sz;
178 size_t prev_written;
179 int rc = 0;
Vadim Bendebury627afc22016-06-19 12:13:18 -0700180
Aaron Durbinee049fa2017-03-25 00:38:45 -0500181 rc |= marshal_common_session_header(ob, handle, ARRAY_SIZE(handle));
182 rc |= marshal_TPM2B(ob, &nvd_in->auth.b);
Vadim Bendebury627afc22016-06-19 12:13:18 -0700183
Aaron Durbinee049fa2017-03-25 00:38:45 -0500184 /* Snapshot current location to place size field. */
185 if (obuf_splice_current(ob, &ob_sz, sizeof(uint16_t)) < 0)
186 return -1;
Vadim Bendebury627afc22016-06-19 12:13:18 -0700187
Aaron Durbinee049fa2017-03-25 00:38:45 -0500188 /* Put placeholder for size */
189 rc |= obuf_write_be16(ob, 0);
Vadim Bendeburybc927102016-07-07 10:52:46 -0700190
Aaron Durbinee049fa2017-03-25 00:38:45 -0500191 /* Keep track of nv define space data size by tracking num written. */
192 prev_written = obuf_nr_written(ob);
Vadim Bendebury627afc22016-06-19 12:13:18 -0700193
Aaron Durbinee049fa2017-03-25 00:38:45 -0500194 rc |= marshal_TPMS_NV_PUBLIC(ob, &nvd_in->publicInfo);
195 rc |= obuf_write_be16(&ob_sz, obuf_nr_written(ob) - prev_written);
Vadim Bendeburybc927102016-07-07 10:52:46 -0700196
Aaron Durbinee049fa2017-03-25 00:38:45 -0500197 return rc;
Vadim Bendebury627afc22016-06-19 12:13:18 -0700198}
199
Aseda Aboagye4ad04202021-05-24 16:47:09 -0700200static int marshal_nv_setbits(struct obuf *ob,
201 const struct tpm2_nv_setbits_cmd *command_body)
202{
203 int rc = 0;
204 const uint32_t handles[] = { TPM_RH_PLATFORM, command_body->nvIndex };
205
206 rc |= marshal_common_session_header(ob, handles, ARRAY_SIZE(handles));
207 rc |= obuf_write_be64(ob, command_body->bits);
208
209 return rc;
210}
211
Aaron Durbinee049fa2017-03-25 00:38:45 -0500212static int marshal_nv_write(struct obuf *ob,
Caveh Jalalic07fb752020-09-11 22:10:55 -0700213 const struct tpm2_nv_write_cmd *command_body)
Aaron Durbinee049fa2017-03-25 00:38:45 -0500214{
215 int rc = 0;
Caveh Jalalic07fb752020-09-11 22:10:55 -0700216 const uint32_t handles[] = { TPM_RH_PLATFORM, command_body->nvIndex };
Aaron Durbinee049fa2017-03-25 00:38:45 -0500217
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);
221
222 return rc;
223}
224
225static int marshal_nv_write_lock(struct obuf *ob,
Caveh Jalalic07fb752020-09-11 22:10:55 -0700226 const struct tpm2_nv_write_lock_cmd *command_body)
Vadim Bendebury627afc22016-06-19 12:13:18 -0700227{
Caveh Jalalic07fb752020-09-11 22:10:55 -0700228 const uint32_t handles[] = { TPM_RH_PLATFORM, command_body->nvIndex };
Vadim Bendebury627afc22016-06-19 12:13:18 -0700229
Aaron Durbinee049fa2017-03-25 00:38:45 -0500230 return marshal_common_session_header(ob, handles, ARRAY_SIZE(handles));
Vadim Bendebury627afc22016-06-19 12:13:18 -0700231}
232
Aaron Durbinee049fa2017-03-25 00:38:45 -0500233static int marshal_pcr_extend(struct obuf *ob,
Caveh Jalalic07fb752020-09-11 22:10:55 -0700234 const struct tpm2_pcr_extend_cmd *command_body)
Vadim Bendebury4c0851c2016-07-03 17:08:10 -0700235{
Aaron Durbinee049fa2017-03-25 00:38:45 -0500236 int rc = 0;
Caveh Jalalic07fb752020-09-11 22:10:55 -0700237 const uint32_t handles[] = { command_body->pcrHandle };
Aaron Durbinee049fa2017-03-25 00:38:45 -0500238
239 rc |= marshal_common_session_header(ob, handles, ARRAY_SIZE(handles));
240 rc |= marshal_TPML_DIGEST_VALUES(ob, &command_body->digests);
241
242 return rc;
Vadim Bendebury4c0851c2016-07-03 17:08:10 -0700243}
244
Aaron Durbinee049fa2017-03-25 00:38:45 -0500245static int marshal_nv_read(struct obuf *ob,
Caveh Jalalic07fb752020-09-11 22:10:55 -0700246 const struct tpm2_nv_read_cmd *command_body)
Vadim Bendeburyf5ef6992016-07-03 22:20:17 -0700247{
Aaron Durbinee049fa2017-03-25 00:38:45 -0500248 int rc = 0;
Caveh Jalalic07fb752020-09-11 22:10:55 -0700249 const uint32_t handles[] = { TPM_RH_PLATFORM, command_body->nvIndex };
Vadim Bendebury627afc22016-06-19 12:13:18 -0700250
Aaron Durbinee049fa2017-03-25 00:38:45 -0500251 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);
254
255 return rc;
Vadim Bendebury627afc22016-06-19 12:13:18 -0700256}
257
Elyes HAOUAS3d450002018-08-09 18:55:58 +0200258/* TPM2_Clear command does not require parameters. */
Aaron Durbinee049fa2017-03-25 00:38:45 -0500259static int marshal_clear(struct obuf *ob)
Vadim Bendebury6acb9a62016-06-30 20:50:49 -0700260{
261 const uint32_t handle[] = { TPM_RH_PLATFORM };
262
Aaron Durbinee049fa2017-03-25 00:38:45 -0500263 return marshal_common_session_header(ob, handle, ARRAY_SIZE(handle));
Vadim Bendebury6acb9a62016-06-30 20:50:49 -0700264}
265
Aaron Durbinee049fa2017-03-25 00:38:45 -0500266static int marshal_selftest(struct obuf *ob,
Caveh Jalalic07fb752020-09-11 22:10:55 -0700267 const struct tpm2_self_test *command_body)
Vadim Bendebury627afc22016-06-19 12:13:18 -0700268{
Aaron Durbinee049fa2017-03-25 00:38:45 -0500269 return obuf_write_be8(ob, command_body->yes_no);
Vadim Bendebury627afc22016-06-19 12:13:18 -0700270}
271
Aaron Durbinee049fa2017-03-25 00:38:45 -0500272static int marshal_hierarchy_control(struct obuf *ob,
Caveh Jalalic07fb752020-09-11 22:10:55 -0700273 const struct tpm2_hierarchy_control_cmd *command_body)
Aaron Durbinf56c7782017-01-10 17:44:42 -0600274{
Aaron Durbinee049fa2017-03-25 00:38:45 -0500275 int rc = 0;
Aaron Durbinf56c7782017-01-10 17:44:42 -0600276 struct tpm2_session_header session_header;
277
Arthur Heymans0ca944b2019-11-20 19:51:06 +0100278 tpm_tag = TPM_ST_SESSIONS;
Aaron Durbinf56c7782017-01-10 17:44:42 -0600279
Aaron Durbinee049fa2017-03-25 00:38:45 -0500280 rc |= marshal_TPM_HANDLE(ob, TPM_RH_PLATFORM);
Aaron Durbinf56c7782017-01-10 17:44:42 -0600281 memset(&session_header, 0, sizeof(session_header));
282 session_header.session_handle = TPM_RS_PW;
Aaron Durbinee049fa2017-03-25 00:38:45 -0500283 rc |= marshal_session_header(ob, &session_header);
Aaron Durbinf56c7782017-01-10 17:44:42 -0600284
Aaron Durbinee049fa2017-03-25 00:38:45 -0500285 rc |= marshal_TPM_HANDLE(ob, command_body->enable);
286 rc |= obuf_write_be8(ob, command_body->state);
287
288 return rc;
Aaron Durbinf56c7782017-01-10 17:44:42 -0600289}
290
Christian Walterc9ac0bc2020-01-28 19:54:33 +0100291static int marshal_clear_control(struct obuf *ob,
Caveh Jalalic07fb752020-09-11 22:10:55 -0700292 const struct tpm2_clear_control_cmd *command_body)
Christian Walterc9ac0bc2020-01-28 19:54:33 +0100293{
294 int rc = 0;
295 struct tpm2_session_header session_header;
296
297 tpm_tag = TPM_ST_SESSIONS;
298
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);
303
304 rc |= obuf_write_be8(ob, command_body->disable);
305
306 return rc;
307}
308
Caveh Jalalic07fb752020-09-11 22:10:55 -0700309static int marshal_cr50_vendor_command(struct obuf *ob, const void *command_body)
Aaron Durbineeb77372017-03-08 11:23:11 -0600310{
Aaron Durbinee049fa2017-03-25 00:38:45 -0500311 int rc = 0;
Caveh Jalalic07fb752020-09-11 22:10:55 -0700312 const uint16_t *sub_command = command_body;
Aaron Durbineeb77372017-03-08 11:23:11 -0600313
314 switch (*sub_command) {
Keith Shorte0f34002019-02-05 16:15:10 -0700315 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.
319 */
320 rc |= obuf_write_be16(ob, sub_command[0]);
321 rc |= obuf_write_be16(ob, sub_command[1]);
322 break;
Aaron Durbineeb77372017-03-08 11:23:11 -0600323 case TPM2_CR50_SUB_CMD_NVMEM_ENABLE_COMMITS:
Aaron Durbinee049fa2017-03-25 00:38:45 -0500324 rc |= obuf_write_be16(ob, *sub_command);
Aaron Durbineeb77372017-03-08 11:23:11 -0600325 break;
Vadim Bendebury021ec282017-03-22 16:01:53 -0700326 case TPM2_CR50_SUB_CMD_TURN_UPDATE_ON:
Aaron Durbinee049fa2017-03-25 00:38:45 -0500327 rc |= obuf_write_be16(ob, sub_command[0]);
328 rc |= obuf_write_be16(ob, sub_command[1]);
Vadim Bendebury021ec282017-03-22 16:01:53 -0700329 break;
Keith Shorte371d422019-01-11 07:52:32 -0700330 case TPM2_CR50_SUB_CMD_GET_REC_BTN:
331 rc |= obuf_write_be16(ob, *sub_command);
332 break;
Keith Shorte0f34002019-02-05 16:15:10 -0700333 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.
339 *
340 * coreboot currently only uses the TPM get capability and does
341 * not set a new TPM state with the Cr50.
342 */
343 rc |= obuf_write_be16(ob, *sub_command);
344 break;
dnojiri622c6b82020-04-03 10:51:50 -0700345 case TPM2_CR50_SUB_CMD_GET_BOOT_MODE:
346 rc |= obuf_write_be16(ob, *sub_command);
347 break;
Karthikeyan Ramasubramanianba7b90e2021-03-01 13:50:20 -0700348 case TPM2_CR50_SUB_CMD_RESET_EC:
349 rc |= obuf_write_be16(ob, *sub_command);
350 break;
Aaron Durbineeb77372017-03-08 11:23:11 -0600351 default:
352 /* Unsupported subcommand. */
353 printk(BIOS_WARNING, "Unsupported cr50 subcommand: 0x%04x\n",
354 *sub_command);
Aaron Durbinee049fa2017-03-25 00:38:45 -0500355 rc = -1;
Aaron Durbineeb77372017-03-08 11:23:11 -0600356 break;
357 }
Aaron Durbinee049fa2017-03-25 00:38:45 -0500358 return rc;
Aaron Durbineeb77372017-03-08 11:23:11 -0600359}
360
Caveh Jalalic07fb752020-09-11 22:10:55 -0700361int tpm_marshal_command(TPM_CC command, const void *tpm_command_body, struct obuf *ob)
Vadim Bendebury627afc22016-06-19 12:13:18 -0700362{
Aaron Durbinee049fa2017-03-25 00:38:45 -0500363 struct obuf ob_hdr;
364 const size_t hdr_sz = sizeof(uint16_t) + 2 * sizeof(uint32_t);
365 int rc = 0;
Vadim Bendebury627afc22016-06-19 12:13:18 -0700366
Arthur Heymans0ca944b2019-11-20 19:51:06 +0100367 tpm_tag = TPM_ST_NO_SESSIONS;
Vadim Bendebury627afc22016-06-19 12:13:18 -0700368
Aaron Durbinee049fa2017-03-25 00:38:45 -0500369 if (obuf_splice_current(ob, &ob_hdr, hdr_sz) < 0)
370 return -1;
371
372 /* Write TPM command header with placeholder field values. */
373 rc |= obuf_write_be16(ob, 0);
374 rc |= obuf_write_be32(ob, 0);
375 rc |= obuf_write_be32(ob, command);
376
377 if (rc != 0)
378 return rc;
379
Vadim Bendebury627afc22016-06-19 12:13:18 -0700380 switch (command) {
381 case TPM2_Startup:
Aaron Durbinee049fa2017-03-25 00:38:45 -0500382 rc |= marshal_startup(ob, tpm_command_body);
Vadim Bendebury627afc22016-06-19 12:13:18 -0700383 break;
384
Joel Kitching2e690ee2018-11-15 16:48:53 +0800385 case TPM2_Shutdown:
386 rc |= marshal_shutdown(ob, tpm_command_body);
387 break;
388
Vadim Bendebury627afc22016-06-19 12:13:18 -0700389 case TPM2_GetCapability:
Aaron Durbinee049fa2017-03-25 00:38:45 -0500390 rc |= marshal_get_capability(ob, tpm_command_body);
Vadim Bendebury627afc22016-06-19 12:13:18 -0700391 break;
392
393 case TPM2_NV_Read:
Aaron Durbinee049fa2017-03-25 00:38:45 -0500394 rc |= marshal_nv_read(ob, tpm_command_body);
Vadim Bendebury627afc22016-06-19 12:13:18 -0700395 break;
396
397 case TPM2_NV_DefineSpace:
Aaron Durbinee049fa2017-03-25 00:38:45 -0500398 rc |= marshal_nv_define_space(ob, tpm_command_body);
Vadim Bendebury627afc22016-06-19 12:13:18 -0700399 break;
400
Aseda Aboagye4ad04202021-05-24 16:47:09 -0700401 case TPM2_NV_SetBits:
402 rc |= marshal_nv_setbits(ob, tpm_command_body);
403 break;
404
Vadim Bendebury627afc22016-06-19 12:13:18 -0700405 case TPM2_NV_Write:
Aaron Durbinee049fa2017-03-25 00:38:45 -0500406 rc |= marshal_nv_write(ob, tpm_command_body);
Vadim Bendebury627afc22016-06-19 12:13:18 -0700407 break;
408
Vadim Bendebury4c0851c2016-07-03 17:08:10 -0700409 case TPM2_NV_WriteLock:
Aaron Durbinee049fa2017-03-25 00:38:45 -0500410 rc |= marshal_nv_write_lock(ob, tpm_command_body);
Vadim Bendebury4c0851c2016-07-03 17:08:10 -0700411 break;
412
Vadim Bendebury627afc22016-06-19 12:13:18 -0700413 case TPM2_SelfTest:
Aaron Durbinee049fa2017-03-25 00:38:45 -0500414 rc |= marshal_selftest(ob, tpm_command_body);
Vadim Bendebury627afc22016-06-19 12:13:18 -0700415 break;
416
Aaron Durbinf56c7782017-01-10 17:44:42 -0600417 case TPM2_Hierarchy_Control:
Aaron Durbinee049fa2017-03-25 00:38:45 -0500418 rc |= marshal_hierarchy_control(ob, tpm_command_body);
Aaron Durbinf56c7782017-01-10 17:44:42 -0600419 break;
420
Christian Walterc9ac0bc2020-01-28 19:54:33 +0100421 case TPM2_ClearControl:
422 rc |= marshal_clear_control(ob, tpm_command_body);
423 break;
424
Vadim Bendebury6acb9a62016-06-30 20:50:49 -0700425 case TPM2_Clear:
Aaron Durbinee049fa2017-03-25 00:38:45 -0500426 rc |= marshal_clear(ob);
Vadim Bendebury6acb9a62016-06-30 20:50:49 -0700427 break;
428
Vadim Bendeburyf5ef6992016-07-03 22:20:17 -0700429 case TPM2_PCR_Extend:
Aaron Durbinee049fa2017-03-25 00:38:45 -0500430 rc |= marshal_pcr_extend(ob, tpm_command_body);
Vadim Bendeburyf5ef6992016-07-03 22:20:17 -0700431 break;
432
Aaron Durbineeb77372017-03-08 11:23:11 -0600433 case TPM2_CR50_VENDOR_COMMAND:
Aaron Durbinee049fa2017-03-25 00:38:45 -0500434 rc |= marshal_cr50_vendor_command(ob, tpm_command_body);
Aaron Durbineeb77372017-03-08 11:23:11 -0600435 break;
436
Vadim Bendebury627afc22016-06-19 12:13:18 -0700437 default:
Vadim Bendebury627afc22016-06-19 12:13:18 -0700438 printk(BIOS_INFO, "%s:%d:Request to marshal unsupported command %#x\n",
439 __FILE__, __LINE__, command);
Aaron Durbinee049fa2017-03-25 00:38:45 -0500440 rc = -1;
Vadim Bendebury627afc22016-06-19 12:13:18 -0700441 }
442
Aaron Durbinee049fa2017-03-25 00:38:45 -0500443 if (rc != 0)
444 return rc;
Vadim Bendebury627afc22016-06-19 12:13:18 -0700445
Aaron Durbinee049fa2017-03-25 00:38:45 -0500446 /* Fix up the command header with known values. */
Arthur Heymans0ca944b2019-11-20 19:51:06 +0100447 rc |= obuf_write_be16(&ob_hdr, tpm_tag);
Aaron Durbinee049fa2017-03-25 00:38:45 -0500448 rc |= obuf_write_be32(&ob_hdr, obuf_nr_written(ob));
Vadim Bendebury627afc22016-06-19 12:13:18 -0700449
Aaron Durbinee049fa2017-03-25 00:38:45 -0500450 return rc;
Vadim Bendebury627afc22016-06-19 12:13:18 -0700451}
452
Aaron Durbinee049fa2017-03-25 00:38:45 -0500453static int unmarshal_get_capability(struct ibuf *ib,
Caveh Jalalic07fb752020-09-11 22:10:55 -0700454 struct get_cap_response *gcr)
Vadim Bendebury627afc22016-06-19 12:13:18 -0700455{
456 int i;
Aaron Durbinee049fa2017-03-25 00:38:45 -0500457 int rc = 0;
Vadim Bendebury627afc22016-06-19 12:13:18 -0700458
Aaron Durbinee049fa2017-03-25 00:38:45 -0500459 rc |= ibuf_read_be8(ib, &gcr->more_data);
460 rc |= unmarshal_TPM_CAP(ib, &gcr->cd.capability);
Vadim Bendebury627afc22016-06-19 12:13:18 -0700461
Aaron Durbinee049fa2017-03-25 00:38:45 -0500462 if (rc != 0)
463 return rc;
Vadim Bendebury627afc22016-06-19 12:13:18 -0700464
465 switch (gcr->cd.capability) {
466 case TPM_CAP_TPM_PROPERTIES:
Aaron Durbinee049fa2017-03-25 00:38:45 -0500467 if (ibuf_read_be32(ib, &gcr->cd.data.tpmProperties.count))
468 return -1;
Vadim Bendebury627afc22016-06-19 12:13:18 -0700469 if (gcr->cd.data.tpmProperties.count > ARRAY_SIZE
470 (gcr->cd.data.tpmProperties.tpmProperty)) {
471 printk(BIOS_INFO, "%s:%s:%d - %d - too many properties\n",
472 __FILE__, __func__, __LINE__,
473 gcr->cd.data.tpmProperties.count);
Aaron Durbinee049fa2017-03-25 00:38:45 -0500474 return -1;
Vadim Bendebury627afc22016-06-19 12:13:18 -0700475 }
476 for (i = 0; i < gcr->cd.data.tpmProperties.count; i++) {
477 TPMS_TAGGED_PROPERTY *pp;
478
479 pp = gcr->cd.data.tpmProperties.tpmProperty + i;
Aaron Durbinee049fa2017-03-25 00:38:45 -0500480 rc |= unmarshal_TPM_PT(ib, &pp->property);
481 rc |= ibuf_read_be32(ib, &pp->value);
Vadim Bendebury627afc22016-06-19 12:13:18 -0700482 }
483 break;
Frans Hendriks589eff72019-06-26 10:43:40 +0200484 case TPM_CAP_PCRS:
485 if (ibuf_read_be32(ib, &gcr->cd.data.assignedPCR.count))
486 return -1;
487 if (gcr->cd.data.assignedPCR.count >
488 ARRAY_SIZE(gcr->cd.data.assignedPCR.pcrSelections)) {
489 printk(BIOS_INFO, "%s:%s:%d - %d - too many properties\n",
490 __FILE__, __func__, __LINE__,
491 gcr->cd.data.assignedPCR.count);
492 return -1;
493 }
494 for (i = 0; i < gcr->cd.data.assignedPCR.count; i++) {
495 TPMS_PCR_SELECTION *pp =
496 &gcr->cd.data.assignedPCR.pcrSelections[i];
497 rc |= ibuf_read(ib, pp, sizeof(TPMS_PCR_SELECTION));
498 }
499 break;
Vadim Bendebury627afc22016-06-19 12:13:18 -0700500 default:
501 printk(BIOS_ERR,
502 "%s:%d - unable to unmarshal capability response",
503 __func__, __LINE__);
504 printk(BIOS_ERR, " for %d\n", gcr->cd.capability);
Aaron Durbinee049fa2017-03-25 00:38:45 -0500505 rc = -1;
Vadim Bendebury627afc22016-06-19 12:13:18 -0700506 break;
507 }
Aaron Durbinee049fa2017-03-25 00:38:45 -0500508
509 return rc;
Vadim Bendebury627afc22016-06-19 12:13:18 -0700510}
511
Aaron Durbinee049fa2017-03-25 00:38:45 -0500512static int unmarshal_TPM2B_MAX_NV_BUFFER(struct ibuf *ib,
Caveh Jalalic07fb752020-09-11 22:10:55 -0700513 TPM2B_MAX_NV_BUFFER *nv_buffer)
Vadim Bendebury627afc22016-06-19 12:13:18 -0700514{
Aaron Durbinee049fa2017-03-25 00:38:45 -0500515 if (ibuf_read_be16(ib, &nv_buffer->t.size))
516 return -1;
517
518 nv_buffer->t.buffer = ibuf_oob_drain(ib, nv_buffer->t.size);
519
520 if (nv_buffer->t.buffer == NULL) {
Vadim Bendebury627afc22016-06-19 12:13:18 -0700521 printk(BIOS_ERR, "%s:%d - "
Aaron Durbinee049fa2017-03-25 00:38:45 -0500522 "size mismatch: expected %d, remaining %zd\n",
523 __func__, __LINE__, nv_buffer->t.size,
524 ibuf_remaining(ib));
525 return -1;
Vadim Bendebury627afc22016-06-19 12:13:18 -0700526 }
527
Aaron Durbinee049fa2017-03-25 00:38:45 -0500528 return 0;
Vadim Bendebury627afc22016-06-19 12:13:18 -0700529}
530
Aaron Durbinee049fa2017-03-25 00:38:45 -0500531static int unmarshal_nv_read(struct ibuf *ib, struct nv_read_response *nvr)
Vadim Bendebury627afc22016-06-19 12:13:18 -0700532{
533 /* Total size of the parameter field. */
Aaron Durbinee049fa2017-03-25 00:38:45 -0500534 if (ibuf_read_be32(ib, &nvr->params_size))
535 return -1;
536
537 if (unmarshal_TPM2B_MAX_NV_BUFFER(ib, &nvr->buffer))
538 return -1;
Vadim Bendebury627afc22016-06-19 12:13:18 -0700539
540 if (nvr->params_size !=
541 (nvr->buffer.t.size + sizeof(nvr->buffer.t.size))) {
542 printk(BIOS_ERR,
543 "%s:%d - parameter/buffer %d/%d size mismatch",
544 __func__, __LINE__, nvr->params_size,
545 nvr->buffer.t.size);
Aaron Durbinee049fa2017-03-25 00:38:45 -0500546 return -1;
Vadim Bendebury627afc22016-06-19 12:13:18 -0700547 }
548
Vadim Bendebury627afc22016-06-19 12:13:18 -0700549 /*
Frans Hendriks8bd5c992018-10-29 10:47:52 +0100550 * Let's ignore the authorization section. It should be 5 bytes total,
Vadim Bendebury627afc22016-06-19 12:13:18 -0700551 * just confirm that this is the case and report any discrepancy.
552 */
Aaron Durbinee049fa2017-03-25 00:38:45 -0500553 if (ibuf_remaining(ib) != 5)
Vadim Bendebury627afc22016-06-19 12:13:18 -0700554 printk(BIOS_ERR,
Frans Hendriks8bd5c992018-10-29 10:47:52 +0100555 "%s:%d - unexpected authorization section size %zd\n",
Aaron Durbinee049fa2017-03-25 00:38:45 -0500556 __func__, __LINE__, ibuf_remaining(ib));
Vadim Bendebury627afc22016-06-19 12:13:18 -0700557
Aaron Durbinee049fa2017-03-25 00:38:45 -0500558 ibuf_oob_drain(ib, ibuf_remaining(ib));
559
560 return 0;
Vadim Bendebury627afc22016-06-19 12:13:18 -0700561}
562
Aaron Durbinee049fa2017-03-25 00:38:45 -0500563static int unmarshal_vendor_command(struct ibuf *ib,
Caveh Jalalic07fb752020-09-11 22:10:55 -0700564 struct vendor_command_response *vcr)
Vadim Bendebury021ec282017-03-22 16:01:53 -0700565{
Aaron Durbinee049fa2017-03-25 00:38:45 -0500566 if (ibuf_read_be16(ib, &vcr->vc_subcommand))
567 return -1;
Vadim Bendebury021ec282017-03-22 16:01:53 -0700568
569 switch (vcr->vc_subcommand) {
Keith Shorte0f34002019-02-05 16:15:10 -0700570 case TPM2_CR50_SUB_CMD_IMMEDIATE_RESET:
571 break;
Vadim Bendebury021ec282017-03-22 16:01:53 -0700572 case TPM2_CR50_SUB_CMD_NVMEM_ENABLE_COMMITS:
573 break;
574 case TPM2_CR50_SUB_CMD_TURN_UPDATE_ON:
Aaron Durbinee049fa2017-03-25 00:38:45 -0500575 return ibuf_read_be8(ib, &vcr->num_restored_headers);
Keith Shorte371d422019-01-11 07:52:32 -0700576 case TPM2_CR50_SUB_CMD_GET_REC_BTN:
577 return ibuf_read_be8(ib, &vcr->recovery_button_state);
Keith Shorte0f34002019-02-05 16:15:10 -0700578 case TPM2_CR50_SUB_CMD_TPM_MODE:
579 return ibuf_read_be8(ib, &vcr->tpm_mode);
dnojiri622c6b82020-04-03 10:51:50 -0700580 case TPM2_CR50_SUB_CMD_GET_BOOT_MODE:
581 return ibuf_read_be8(ib, &vcr->boot_mode);
Karthikeyan Ramasubramanianba7b90e2021-03-01 13:50:20 -0700582 case TPM2_CR50_SUB_CMD_RESET_EC:
583 break;
Vadim Bendebury021ec282017-03-22 16:01:53 -0700584 default:
585 printk(BIOS_ERR,
586 "%s:%d - unsupported vendor command %#04x!\n",
587 __func__, __LINE__, vcr->vc_subcommand);
Aaron Durbinee049fa2017-03-25 00:38:45 -0500588 return -1;
Vadim Bendebury021ec282017-03-22 16:01:53 -0700589 }
Aaron Durbinee049fa2017-03-25 00:38:45 -0500590
591 return 0;
Vadim Bendebury021ec282017-03-22 16:01:53 -0700592}
593
Aaron Durbinee049fa2017-03-25 00:38:45 -0500594struct tpm2_response *tpm_unmarshal_response(TPM_CC command, struct ibuf *ib)
Vadim Bendebury627afc22016-06-19 12:13:18 -0700595{
Arthur Heymans0ca944b2019-11-20 19:51:06 +0100596 static struct tpm2_response tpm2_static_resp;
Aaron Durbinee049fa2017-03-25 00:38:45 -0500597 int rc = 0;
Vadim Bendebury627afc22016-06-19 12:13:18 -0700598
Arthur Heymans0ca944b2019-11-20 19:51:06 +0100599 rc |= ibuf_read_be16(ib, &tpm2_static_resp.hdr.tpm_tag);
600 rc |= ibuf_read_be32(ib, &tpm2_static_resp.hdr.tpm_size);
601 rc |= unmarshal_TPM_CC(ib, &tpm2_static_resp.hdr.tpm_code);
Aaron Durbinee049fa2017-03-25 00:38:45 -0500602
603 if (rc != 0)
Vadim Bendebury627afc22016-06-19 12:13:18 -0700604 return NULL;
605
Julius Werner71a13142020-05-06 11:11:03 -0700606 if (ibuf_capacity(ib) != tpm2_static_resp.hdr.tpm_size) {
607 printk(BIOS_ERR,
608 "%s: size mismatch in response to command %#x\n",
609 __func__, command);
610 return NULL;
Vadim Bendebury627afc22016-06-19 12:13:18 -0700611 }
612
Julius Werner71a13142020-05-06 11:11:03 -0700613 /* On errors, we're not sure what the TPM is returning. None of the
614 commands we use actually expect useful data payloads for errors, so
615 just ignore any data after the header. */
616 if (tpm2_static_resp.hdr.tpm_code != TPM2_RC_SUCCESS)
617 return &tpm2_static_resp;
618
Vadim Bendebury627afc22016-06-19 12:13:18 -0700619 switch (command) {
620 case TPM2_Startup:
Joel Kitching2e690ee2018-11-15 16:48:53 +0800621 case TPM2_Shutdown:
Julius Werner71a13142020-05-06 11:11:03 -0700622 case TPM2_SelfTest:
Vadim Bendebury627afc22016-06-19 12:13:18 -0700623 break;
624
625 case TPM2_GetCapability:
Arthur Heymans0ca944b2019-11-20 19:51:06 +0100626 rc |= unmarshal_get_capability(ib, &tpm2_static_resp.gc);
Vadim Bendebury627afc22016-06-19 12:13:18 -0700627 break;
628
629 case TPM2_NV_Read:
Arthur Heymans0ca944b2019-11-20 19:51:06 +0100630 rc |= unmarshal_nv_read(ib, &tpm2_static_resp.nvr);
Vadim Bendebury627afc22016-06-19 12:13:18 -0700631 break;
632
Aaron Durbinf56c7782017-01-10 17:44:42 -0600633 case TPM2_Hierarchy_Control:
Vadim Bendebury6acb9a62016-06-30 20:50:49 -0700634 case TPM2_Clear:
Christian Walterc9ac0bc2020-01-28 19:54:33 +0100635 case TPM2_ClearControl:
Vadim Bendebury627afc22016-06-19 12:13:18 -0700636 case TPM2_NV_DefineSpace:
Aseda Aboagye4ad04202021-05-24 16:47:09 -0700637 case TPM2_NV_SetBits:
Vadim Bendebury627afc22016-06-19 12:13:18 -0700638 case TPM2_NV_Write:
Vadim Bendebury4c0851c2016-07-03 17:08:10 -0700639 case TPM2_NV_WriteLock:
Vadim Bendeburyf5ef6992016-07-03 22:20:17 -0700640 case TPM2_PCR_Extend:
Vadim Bendebury627afc22016-06-19 12:13:18 -0700641 /* Session data included in response can be safely ignored. */
Aaron Durbinee049fa2017-03-25 00:38:45 -0500642 ibuf_oob_drain(ib, ibuf_remaining(ib));
Vadim Bendebury627afc22016-06-19 12:13:18 -0700643 break;
644
Aaron Durbineeb77372017-03-08 11:23:11 -0600645 case TPM2_CR50_VENDOR_COMMAND:
Arthur Heymans0ca944b2019-11-20 19:51:06 +0100646 rc |= unmarshal_vendor_command(ib, &tpm2_static_resp.vcr);
Aaron Durbineeb77372017-03-08 11:23:11 -0600647 break;
648
Vadim Bendebury627afc22016-06-19 12:13:18 -0700649 default:
650 {
Aaron Durbinee049fa2017-03-25 00:38:45 -0500651 size_t i;
652 size_t sz_left;
653 const uint8_t *data;
Vadim Bendebury627afc22016-06-19 12:13:18 -0700654
655 printk(BIOS_INFO, "%s:%d:"
656 "Request to unmarshal unexpected command %#x,"
657 " code %#x",
658 __func__, __LINE__, command,
Arthur Heymans0ca944b2019-11-20 19:51:06 +0100659 tpm2_static_resp.hdr.tpm_code);
Vadim Bendebury627afc22016-06-19 12:13:18 -0700660
Aaron Durbinee049fa2017-03-25 00:38:45 -0500661 sz_left = ibuf_remaining(ib);
662 data = ibuf_oob_drain(ib, sz_left);
663
664 for (i = 0; i < sz_left; i++) {
Vadim Bendebury627afc22016-06-19 12:13:18 -0700665 if (!(i % 16))
666 printk(BIOS_INFO, "\n");
Aaron Durbinee049fa2017-03-25 00:38:45 -0500667 printk(BIOS_INFO, "%2.2x ", data[i]);
Vadim Bendebury627afc22016-06-19 12:13:18 -0700668 }
669 }
670 printk(BIOS_INFO, "\n");
671 return NULL;
672 }
673
Aaron Durbinee049fa2017-03-25 00:38:45 -0500674 if (ibuf_remaining(ib)) {
Vadim Bendebury627afc22016-06-19 12:13:18 -0700675 printk(BIOS_INFO,
676 "%s:%d got %d bytes back in response to %#x,"
Aaron Durbinee049fa2017-03-25 00:38:45 -0500677 " failed to parse (%zd)\n",
Arthur Heymans0ca944b2019-11-20 19:51:06 +0100678 __func__, __LINE__, tpm2_static_resp.hdr.tpm_size,
Aaron Durbinee049fa2017-03-25 00:38:45 -0500679 command, ibuf_remaining(ib));
Vadim Bendebury627afc22016-06-19 12:13:18 -0700680 return NULL;
681 }
Richard Spiegel248c60a2018-08-07 09:24:14 -0700682 if (rc)
Julius Wernere9665952022-01-21 17:06:20 -0800683 printk(BIOS_WARNING, "%s had one or more failures.\n",
Richard Spiegel248c60a2018-08-07 09:24:14 -0700684 __func__);
Vadim Bendebury627afc22016-06-19 12:13:18 -0700685
686 /* The entire message have been parsed. */
Arthur Heymans0ca944b2019-11-20 19:51:06 +0100687 return &tpm2_static_resp;
Vadim Bendebury627afc22016-06-19 12:13:18 -0700688}