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
7 #ifdef HAVE_CONFIG_H
8 #include <config.h>
9 #endif
10
11 #include <inttypes.h>
12 #include <string.h>
13
14 #include "tss2_esys.h"
15
16 #include "esys_mu.h"
17 #include "esys_iutil.h"
18 #define LOGMODULE esys
19 #include "util/log.h"
20 #include "util/aux_util.h"
21
22 /** Marshal an array of BYTE structures into a byte buffer.
23 *
24 * @param[in] in Structures to be marshaled.
25 * @param[in] count Number of structures to be marshaled.
26 * @param[in,out] buffer Buffer to write result into.
27 * @param[in] size Size of the buffer.
28 * @param[in,out] offset Offset inside the buffer
29 * (being updated during marshaling).
30 * @retval TSS2_RC_SUCCESS on success.
31 * @retval TSS2_ESYS_RC_BAD_REFERENCE if src==NULL.
32 * @retval TSS2_ESYS_RC_INSUFFICIENT_BUFFER if remaining buffer is insufficient.
33 */
34 TSS2_RC
iesys_MU_BYTE_array_Marshal(const BYTE * src,size_t count,uint8_t * buffer,size_t size,size_t * offset)35 iesys_MU_BYTE_array_Marshal(
36 const BYTE *src,
37 size_t count,
38 uint8_t *buffer,
39 size_t size,
40 size_t *offset)
41 {
42 LOG_TRACE("called: src=%p count=%zu buffer=%p size=%zu offset=%p", src,
43 count, buffer, size, offset);
44 return_if_null(src, "src=NULL", TSS2_ESYS_RC_BAD_REFERENCE);
45
46 size_t offset_loc = (offset != NULL)? *offset : 0;
47
48 if (count > size || size - count < offset_loc) {
49 LOG_ERROR("not enough space in target buffer");
50 return TSS2_ESYS_RC_INSUFFICIENT_BUFFER;
51 }
52
53 if (buffer != NULL)
54 memcpy(&buffer[offset_loc], src, count);
55 offset_loc += count;
56
57 if (offset != NULL)
58 *offset = offset_loc;
59 return TSS2_RC_SUCCESS;
60 }
61
62 /** Unmarshal an array of BYTE structures from a byte buffer.
63 *
64 * @param[in,out] buffer Buffer to read data from.
65 * @param[in] size Size of the buffer.
66 * @param[in,out] offset Offset inside the buffer
67 * (being updated during marshaling).
68 * @param[in] count Number of structures to be unmarshaled.
69 * @param[out] out Structures to store the result in.
70 * @retval TSS2_RC_SUCCESS on success.
71 * @retval TSS2_ESYS_RC_BAD_REFERENCE if buffer==NULL.
72 * @retval TSS2_ESYS_RC_INSUFFICIENT_BUFFER if remaining buffer is insufficient.
73 */
74 TSS2_RC
iesys_MU_BYTE_array_Unmarshal(const uint8_t * buffer,size_t size,size_t * offset,size_t count,BYTE * dst)75 iesys_MU_BYTE_array_Unmarshal(
76 const uint8_t *buffer,
77 size_t size,
78 size_t *offset,
79 size_t count,
80 BYTE *dst)
81 {
82 LOG_TRACE("called: count=%zu buffer=%p size=%zu offset=%p dst=%p",
83 count, buffer, size, offset, dst);
84 return_if_null(buffer, "src=NULL", TSS2_ESYS_RC_BAD_REFERENCE);
85
86 size_t offset_loc = (offset != NULL)? *offset : 0;
87 if (dst != NULL)
88 memset(dst, 0, sizeof(*dst));
89
90 if (count > size || size - count < offset_loc) {
91 LOG_ERROR("not enough space in target buffer");
92 return TSS2_ESYS_RC_INSUFFICIENT_BUFFER;
93 }
94
95 if (dst != NULL)
96 memcpy(dst, &buffer[offset_loc], count);
97 offset_loc += count;
98
99 if (offset != NULL)
100 *offset = offset_loc;
101 return TSS2_RC_SUCCESS;
102 }
103
104
105 /** Check, if a variable has a possible value of type IESYSC_RESOURCE_TYPE_CONSTANT.
106 *
107 * @param[in] in variable to check.
108 * @retval TSS2_RC_SUCCESS on success.
109 */
110 TSS2_RC
Tss2_MU_IESYSC_RESOURCE_TYPE_CONSTANT_check(const IESYSC_RESOURCE_TYPE_CONSTANT * in)111 Tss2_MU_IESYSC_RESOURCE_TYPE_CONSTANT_check(
112 const IESYSC_RESOURCE_TYPE_CONSTANT *in)
113 {
114 LOG_TRACE("called: in=%p", in);
115 if (in == NULL) {
116 LOG_ERROR("in==NULL");
117 return TSS2_SYS_RC_BAD_REFERENCE;
118 }
119 /* No Error-Messages, since this function may fail for a good reasons. */
120 if (FALSE
121 || (*in == IESYSC_KEY_RSRC)
122 || (*in == IESYSC_NV_RSRC)
123 || (*in == IESYSC_SESSION_RSRC)
124 || (*in == IESYSC_WITHOUT_MISC_RSRC)) {
125 return TSS2_RC_SUCCESS;
126 } else {
127 return TSS2_SYS_RC_BAD_VALUE;
128 }
129 return TSS2_RC_SUCCESS;
130 }
131 /** Marshal a constant of type IESYSC_PARAM_ENCRYPT into a byte buffer.
132 *
133 * @param[in] src constant to be marshaled.
134 * @param[in,out] buffer Buffer to write result into (may be NULL)
135 * @param[in] size Size of the buffer.
136 * @param[in,out] offset Offset inside the buffer (may be NULL.
137 * @retval TSS2_RC_SUCCESS on success.
138 * @retval TSS2_ESYS_RC_BAD_REFERENCE if src==NULL.
139 * @retval TSS2_ESYS_RC_INSUFFICIENT_BUFFER if remaining buffer is insufficient.
140 */
141 TSS2_RC
iesys_MU_IESYSC_PARAM_ENCRYPT_Marshal(const IESYSC_PARAM_ENCRYPT src,uint8_t * buffer,size_t size,size_t * offset)142 iesys_MU_IESYSC_PARAM_ENCRYPT_Marshal(
143 const IESYSC_PARAM_ENCRYPT src,
144 uint8_t *buffer,
145 size_t size,
146 size_t *offset)
147 {
148 LOG_TRACE("called: src=%"PRIx32 " buffer=%p size=%zu offset=%p", src,
149 buffer, size, offset);
150 return Tss2_MU_UINT32_Marshal(src, buffer, size, offset);
151 }
152
153 /** Unmarshal a constant of type IESYSC_PARAM_ENCRYPT from a byte buffer.
154 *
155 * @param[in,out] buffer Buffer to read data from.
156 * @param[in] size Size of the buffer.
157 * @param[in,out] offset Offset inside the buffer
158 * (being updated during marshaling).
159 * @param[out] dst variable to store the result in.
160 * @retval TSS2_RC_SUCCESS on success.
161 */
162 TSS2_RC
iesys_MU_IESYSC_PARAM_ENCRYPT_Unmarshal(const uint8_t * buffer,size_t size,size_t * offset,IESYSC_PARAM_ENCRYPT * dst)163 iesys_MU_IESYSC_PARAM_ENCRYPT_Unmarshal(
164 const uint8_t *buffer,
165 size_t size,
166 size_t *offset,
167 IESYSC_PARAM_ENCRYPT *dst)
168 {
169 LOG_TRACE("called: buffer=%p size=%zu offset=%p dst=%p",
170 buffer, size, offset, dst);
171 size_t offset_loc = (offset != NULL)? *offset : 0;
172 if (dst != NULL)
173 memset(dst, 0, sizeof(*dst));
174 IESYSC_PARAM_ENCRYPT dst_loc;
175 TSS2_RC ret = Tss2_MU_UINT32_Unmarshal(buffer, size,
176 &offset_loc, &dst_loc);
177 return_if_error(ret, "Unmarshaling the base type");
178
179 ret = iesys_MU_IESYSC_PARAM_ENCRYPT_check(&dst_loc);
180 if (ret != TSS2_RC_SUCCESS) {
181 LOG_ERROR("Bad value %"PRIx32 "", dst_loc);
182 return ret;
183 }
184 if (offset != NULL)
185 *offset = offset_loc;
186 if (dst != NULL)
187 *dst = dst_loc;
188 LOG_TRACE("return: dst=%p value=%"PRIx32 "", dst, dst_loc);
189 return TSS2_RC_SUCCESS;
190 }
191
192 /** Check, if a variable has a possible value of type IESYSC_PARAM_ENCRYPT.
193 *
194 * @param[in] in variable to check.
195 * @retval TSS2_RC_SUCCESS on success.
196 */
197 TSS2_RC
iesys_MU_IESYSC_PARAM_ENCRYPT_check(const IESYSC_PARAM_ENCRYPT * in)198 iesys_MU_IESYSC_PARAM_ENCRYPT_check(
199 const IESYSC_PARAM_ENCRYPT *in)
200 {
201 LOG_TRACE("called: in=%p", in);
202 return_if_null(in, "in==NULL", TSS2_SYS_RC_BAD_REFERENCE);
203
204 /* No Error-Messages, since this function may fail for a good reasons. */
205 if (FALSE
206 || (*in == ENCRYPT)
207 || (*in == NO_ENCRYPT)) {
208 return TSS2_RC_SUCCESS;
209 } else {
210 return TSS2_SYS_RC_BAD_VALUE;
211 }
212 return TSS2_RC_SUCCESS;
213 }
214 /** Marshal a constant of type IESYSC_PARAM_DECRYPT into a byte buffer.
215 *
216 * @param[in] src constant to be marshaled.
217 * @param[in,out] buffer Buffer to write result into (may be NULL)
218 * @param[in] size Size of the buffer.
219 * @param[in,out] offset Offset inside the buffer (may be NULL.
220 * @retval TSS2_RC_SUCCESS on success.
221 * @retval TSS2_ESYS_RC_BAD_REFERENCE if src==NULL.
222 * @retval TSS2_ESYS_RC_INSUFFICIENT_BUFFER if remaining buffer is insufficient.
223 */
224 TSS2_RC
iesys_MU_IESYSC_PARAM_DECRYPT_Marshal(const IESYSC_PARAM_DECRYPT src,uint8_t * buffer,size_t size,size_t * offset)225 iesys_MU_IESYSC_PARAM_DECRYPT_Marshal(
226 const IESYSC_PARAM_DECRYPT src,
227 uint8_t *buffer,
228 size_t size,
229 size_t *offset)
230 {
231 LOG_TRACE("called: src=%"PRIx32 " buffer=%p size=%zu offset=%p", src,
232 buffer, size, offset);
233 return Tss2_MU_UINT32_Marshal(src, buffer, size, offset);
234 }
235
236 /** Unmarshal a constant of type IESYSC_PARAM_DECRYPT from a byte buffer.
237 *
238 * @param[in,out] buffer Buffer to read data from.
239 * @param[in] size Size of the buffer.
240 * @param[in,out] offset Offset inside the buffer
241 * (being updated during marshaling).
242 * @param[out] dst variable to store the result in.
243 * @retval TSS2_RC_SUCCESS on success.
244 */
245 TSS2_RC
iesys_MU_IESYSC_PARAM_DECRYPT_Unmarshal(const uint8_t * buffer,size_t size,size_t * offset,IESYSC_PARAM_DECRYPT * dst)246 iesys_MU_IESYSC_PARAM_DECRYPT_Unmarshal(
247 const uint8_t *buffer,
248 size_t size,
249 size_t *offset,
250 IESYSC_PARAM_DECRYPT *dst)
251 {
252 LOG_TRACE("called: buffer=%p size=%zu offset=%p dst=%p",
253 buffer, size, offset, dst);
254 size_t offset_loc = (offset != NULL)? *offset : 0;
255 if (dst != NULL)
256 memset(dst, 0, sizeof(*dst));
257 IESYSC_PARAM_DECRYPT dst_loc;
258 TSS2_RC ret = Tss2_MU_UINT32_Unmarshal(buffer, size,
259 &offset_loc, &dst_loc);
260 return_if_error(ret, "Unmarshaling the base type");
261
262 ret = iesys_MU_IESYSC_PARAM_DECRYPT_check(&dst_loc);
263 if (ret != TSS2_RC_SUCCESS) {
264 LOG_ERROR("Bad value %"PRIx32 "", dst_loc);
265 return ret;
266 }
267 if (offset != NULL)
268 *offset = offset_loc;
269 if (dst != NULL)
270 *dst = dst_loc;
271 LOG_TRACE("return: dst=%p value=%"PRIx32 "", dst, dst_loc);
272 return TSS2_RC_SUCCESS;
273 }
274
275 /** Check, if a variable has a possible value of type IESYSC_PARAM_DECRYPT.
276 *
277 * @param[in] in variable to check.
278 * @retval TSS2_RC_SUCCESS on success.
279 */
280 TSS2_RC
iesys_MU_IESYSC_PARAM_DECRYPT_check(const IESYSC_PARAM_DECRYPT * in)281 iesys_MU_IESYSC_PARAM_DECRYPT_check(
282 const IESYSC_PARAM_DECRYPT *in)
283 {
284 LOG_TRACE("called: in=%p", in);
285 return_if_null(in, "in==NULL", TSS2_SYS_RC_BAD_REFERENCE);
286
287 /* No Error-Messages, since this function may fail for a good reasons. */
288 if (FALSE
289 || (*in == DECRYPT)
290 || (*in == NO_DECRYPT)) {
291 return TSS2_RC_SUCCESS;
292 } else {
293 return TSS2_SYS_RC_BAD_VALUE;
294 }
295 return TSS2_RC_SUCCESS;
296 }
297 /** Marshal a constant of type IESYSC_TYPE_POLICY_AUTH into a byte buffer.
298 *
299 * @param[in] src constant to be marshaled.
300 * @param[in,out] buffer Buffer to write result into (may be NULL)
301 * @param[in] size Size of the buffer.
302 * @param[in,out] offset Offset inside the buffer (may be NULL.
303 * @retval TSS2_RC_SUCCESS on success.
304 * @retval TSS2_ESYS_RC_BAD_REFERENCE if src==NULL.
305 * @retval TSS2_ESYS_RC_INSUFFICIENT_BUFFER if remaining buffer is insufficient.
306 */
307 TSS2_RC
iesys_MU_IESYSC_TYPE_POLICY_AUTH_Marshal(const IESYSC_TYPE_POLICY_AUTH src,uint8_t * buffer,size_t size,size_t * offset)308 iesys_MU_IESYSC_TYPE_POLICY_AUTH_Marshal(
309 const IESYSC_TYPE_POLICY_AUTH src,
310 uint8_t *buffer,
311 size_t size,
312 size_t *offset)
313 {
314 LOG_TRACE("called: src=%"PRIx32 " buffer=%p size=%zu offset=%p", src,
315 buffer, size, offset);
316 return Tss2_MU_UINT32_Marshal(src, buffer, size, offset);
317 }
318
319 /** Unmarshal a constant of type IESYSC_TYPE_POLICY_AUTH from a byte buffer.
320 *
321 * @param[in,out] buffer Buffer to read data from.
322 * @param[in] size Size of the buffer.
323 * @param[in,out] offset Offset inside the buffer
324 * (being updated during marshaling).
325 * @param[out] dst variable to store the result in.
326 * @retval TSS2_RC_SUCCESS on success.
327 */
328 TSS2_RC
iesys_MU_IESYSC_TYPE_POLICY_AUTH_Unmarshal(const uint8_t * buffer,size_t size,size_t * offset,IESYSC_TYPE_POLICY_AUTH * dst)329 iesys_MU_IESYSC_TYPE_POLICY_AUTH_Unmarshal(
330 const uint8_t *buffer,
331 size_t size,
332 size_t *offset,
333 IESYSC_TYPE_POLICY_AUTH *dst)
334 {
335 LOG_TRACE("called: buffer=%p size=%zu offset=%p dst=%p",
336 buffer, size, offset, dst);
337 size_t offset_loc = (offset != NULL)? *offset : 0;
338 if (dst != NULL)
339 memset(dst, 0, sizeof(*dst));
340 IESYSC_TYPE_POLICY_AUTH dst_loc;
341 TSS2_RC ret = Tss2_MU_UINT32_Unmarshal(buffer, size,
342 &offset_loc, &dst_loc);
343 return_if_error(ret, "Unmarshaling the base type");
344
345 ret = iesys_MU_IESYSC_TYPE_POLICY_AUTH_check(&dst_loc);
346 if (ret != TSS2_RC_SUCCESS) {
347 LOG_ERROR("Bad value %"PRIx32 "", dst_loc);
348 return ret;
349 }
350 if (offset != NULL)
351 *offset = offset_loc;
352 if (dst != NULL)
353 *dst = dst_loc;
354 LOG_TRACE("return: dst=%p value=%"PRIx32 "", dst, dst_loc);
355 return TSS2_RC_SUCCESS;
356 }
357
358 /** Check, if a variable has a possible value of type IESYSC_TYPE_POLICY_AUTH.
359 *
360 * @param[in] in variable to check.
361 * @retval TSS2_RC_SUCCESS on success.
362 */
363 TSS2_RC
iesys_MU_IESYSC_TYPE_POLICY_AUTH_check(const IESYSC_TYPE_POLICY_AUTH * in)364 iesys_MU_IESYSC_TYPE_POLICY_AUTH_check(
365 const IESYSC_TYPE_POLICY_AUTH *in)
366 {
367 LOG_TRACE("called: in=%p", in);
368 return_if_null(in, "in==NULL", TSS2_SYS_RC_BAD_REFERENCE);
369
370 /* No Error-Messages, since this function may fail for a good reasons. */
371 if (FALSE
372 || (*in == POLICY_PASSWORD)
373 || (*in == POLICY_AUTH)
374 || (*in == NO_POLICY_AUTH)) {
375 return TSS2_RC_SUCCESS;
376 } else {
377 return TSS2_SYS_RC_BAD_VALUE;
378 }
379 return TSS2_RC_SUCCESS;
380 }
381
382 /** Marshal a IESYS_SESSION structure into a byte buffer.
383 *
384 * @param[in] src variable to be marshaled.
385 * @param[in,out] buffer Buffer to write result into.
386 * @param[in] size Size of the buffer.
387 * @param[in,out] offset Offset inside the buffer
388 * (being updated during marshaling).
389 * @retval TSS2_RC_SUCCESS on success.
390 * @retval TSS2_ESYS_RC_BAD_REFERENCE if src==NULL.
391 * @retval TSS2_ESYS_RC_INSUFFICIENT_BUFFER if remaining buffer is insufficient.
392 */
393 TSS2_RC
iesys_MU_IESYS_SESSION_Marshal(const IESYS_SESSION * src,uint8_t * buffer,size_t size,size_t * offset)394 iesys_MU_IESYS_SESSION_Marshal(
395 const IESYS_SESSION *src,
396 uint8_t *buffer,
397 size_t size,
398 size_t *offset)
399 {
400 LOG_TRACE("called: src=%p buffer=%p size=%zu offset=%p", src,
401 buffer, size, offset);
402 if (src == NULL) {
403 LOG_ERROR("src=NULL");
404 return TSS2_SYS_RC_BAD_REFERENCE;
405 }
406 TSS2_RC ret;
407 size_t offset_loc = (offset != NULL)? *offset : 0;
408 ret = Tss2_MU_TPM2B_NAME_Marshal(&src->bound_entity, buffer, size, &offset_loc);
409 return_if_error(ret, "Error marshaling subfield bound_entity");
410
411 ret = Tss2_MU_TPM2B_ENCRYPTED_SECRET_Marshal(&src->encryptedSalt, buffer, size, &offset_loc);
412 return_if_error(ret, "Error marshaling subfield encryptedSalt");
413
414 ret = Tss2_MU_TPM2B_DATA_Marshal(&src->salt, buffer, size, &offset_loc);
415 return_if_error(ret, "Error marshaling subfield salt");
416
417 ret = Tss2_MU_TPMT_SYM_DEF_Marshal(&src->symmetric, buffer, size, &offset_loc);
418 return_if_error(ret, "Error marshaling subfield symmetric");
419
420 ret = Tss2_MU_TPMI_ALG_HASH_Marshal(src->authHash, buffer, size, &offset_loc);
421 return_if_error(ret, "Error marshaling subfield authHash");
422
423 ret = Tss2_MU_TPM2B_DIGEST_Marshal(&src->sessionKey, buffer, size, &offset_loc);
424 return_if_error(ret, "Error marshaling subfield sessionKey");
425
426 ret = Tss2_MU_TPM2_SE_Marshal(src->sessionType, buffer, size, &offset_loc);
427 return_if_error(ret, "Error marshaling subfield sessionType");
428
429 ret = Tss2_MU_TPMA_SESSION_Marshal(src->sessionAttributes, buffer, size, &offset_loc);
430 return_if_error(ret, "Error marshaling subfield sessionAttributes");
431
432 ret = Tss2_MU_TPM2B_NONCE_Marshal(&src->nonceCaller, buffer, size, &offset_loc);
433 return_if_error(ret, "Error marshaling subfield nonceCaller");
434
435 ret = Tss2_MU_TPM2B_NONCE_Marshal(&src->nonceTPM, buffer, size, &offset_loc);
436 return_if_error(ret, "Error marshaling subfield nonceTPM");
437
438 ret = iesys_MU_IESYSC_PARAM_ENCRYPT_Marshal(src->encrypt, buffer, size, &offset_loc);
439 return_if_error(ret, "Error marshaling subfield encrypt");
440
441 ret = iesys_MU_IESYSC_PARAM_DECRYPT_Marshal(src->decrypt, buffer, size, &offset_loc);
442 return_if_error(ret, "Error marshaling subfield decrypt");
443
444 ret = iesys_MU_IESYSC_TYPE_POLICY_AUTH_Marshal(src->type_policy_session, buffer, size, &offset_loc);
445 return_if_error(ret, "Error marshaling subfield type_policy_session");
446
447 ret = Tss2_MU_UINT16_Marshal(src->sizeSessionValue, buffer, size, &offset_loc);
448 return_if_error(ret, "Error marshaling subfield sizeSessionValue");
449
450 ret = iesys_MU_BYTE_array_Marshal(&src->sessionValue[0], src->sizeSessionValue,
451 buffer, size, &offset_loc);
452 return_if_error(ret, "Error marshaling subfield sessionValue");
453
454 ret = Tss2_MU_UINT16_Marshal(src->sizeHmacValue, buffer, size, &offset_loc);
455 return_if_error(ret, "Error marshaling subfield sizeHmacValue");
456
457 if (offset != NULL)
458 *offset = offset_loc;
459 return TSS2_RC_SUCCESS;
460 }
461
462 /** Unmarshal a IESYS_SESSION variable from a byte buffer.
463 *
464 * @param[in,out] buffer Buffer to read data from.
465 * @param[in] size Size of the buffer.
466 * @param[in,out] offset Offset inside the buffer
467 * (being updated during marshaling).
468 * @param[out] out variable to store the result in.
469 * @retval TSS2_RC_SUCCESS on success.
470 * @retval TSS2_ESYS_RC_BAD_REFERENCE if buffer==NULL.
471 * @retval TSS2_ESYS_RC_INSUFFICIENT_BUFFER if remaining buffer is insufficient.
472 */
473 TSS2_RC
iesys_MU_IESYS_SESSION_Unmarshal(const uint8_t * buffer,size_t size,size_t * offset,IESYS_SESSION * dst)474 iesys_MU_IESYS_SESSION_Unmarshal(
475 const uint8_t *buffer,
476 size_t size,
477 size_t *offset,
478 IESYS_SESSION *dst)
479 {
480 LOG_TRACE("called: buffer=%p size=%zu offset=%p dst=%p",
481 buffer, size, offset, dst);
482 if (buffer == NULL) {
483 LOG_ERROR("buffer=NULL");
484 return TSS2_ESYS_RC_BAD_REFERENCE;
485 }
486 TSS2_RC ret;
487 size_t offset_loc = (offset != NULL)? *offset : 0;
488 if (dst != NULL)
489 memset(dst, 0, sizeof(*dst));
490 ret = Tss2_MU_TPM2B_NAME_Unmarshal(buffer, size, &offset_loc,
491 (dst == NULL)? NULL : &dst->bound_entity);
492 return_if_error(ret, "Error unmarshaling subfield bound_entity");
493
494 ret = Tss2_MU_TPM2B_ENCRYPTED_SECRET_Unmarshal(buffer, size, &offset_loc,
495 (dst == NULL)? NULL : &dst->encryptedSalt);
496 return_if_error(ret, "Error unmarshaling subfield encryptedSalt");
497
498 ret = Tss2_MU_TPM2B_DATA_Unmarshal(buffer, size, &offset_loc,
499 (dst == NULL)? NULL : &dst->salt);
500 return_if_error(ret, "Error unmarshaling subfield salt");
501
502 ret = Tss2_MU_TPMT_SYM_DEF_Unmarshal(buffer, size, &offset_loc,
503 (dst == NULL)? NULL : &dst->symmetric);
504 return_if_error(ret, "Error unmarshaling subfield symmetric");
505
506 TPMI_ALG_HASH out_authHash;
507 ret = Tss2_MU_TPMI_ALG_HASH_Unmarshal(buffer, size, &offset_loc,
508 (dst == NULL)? &out_authHash : &dst->authHash);
509 return_if_error(ret, "Error unmarshaling subfield authHash");
510
511 ret = Tss2_MU_TPM2B_DIGEST_Unmarshal(buffer, size, &offset_loc,
512 (dst == NULL)? NULL : &dst->sessionKey);
513 return_if_error(ret, "Error unmarshaling subfield sessionKey");
514
515 TPM2_SE out_sessionType;
516 ret = Tss2_MU_TPM2_SE_Unmarshal(buffer, size, &offset_loc,
517 (dst == NULL)? &out_sessionType : &dst->sessionType);
518 return_if_error(ret, "Error unmarshaling subfield sessionType");
519
520 TPMA_SESSION out_sessionAttributes;
521 ret = Tss2_MU_TPMA_SESSION_Unmarshal(buffer, size, &offset_loc,
522 (dst == NULL)? &out_sessionAttributes : &dst->sessionAttributes);
523 return_if_error(ret, "Error unmarshaling subfield sessionAttributes");
524
525 ret = Tss2_MU_TPM2B_NONCE_Unmarshal(buffer, size, &offset_loc,
526 (dst == NULL)? NULL : &dst->nonceCaller);
527 return_if_error(ret, "Error unmarshaling subfield nonceCaller");
528
529 ret = Tss2_MU_TPM2B_NONCE_Unmarshal(buffer, size, &offset_loc,
530 (dst == NULL)? NULL : &dst->nonceTPM);
531 return_if_error(ret, "Error unmarshaling subfield nonceTPM");
532
533 IESYSC_PARAM_ENCRYPT out_encrypt;
534 ret = iesys_MU_IESYSC_PARAM_ENCRYPT_Unmarshal(buffer, size, &offset_loc,
535 (dst == NULL)? &out_encrypt : &dst->encrypt);
536 return_if_error(ret, "Error unmarshaling subfield encrypt");
537
538 IESYSC_PARAM_DECRYPT out_decrypt;
539 ret = iesys_MU_IESYSC_PARAM_DECRYPT_Unmarshal(buffer, size, &offset_loc,
540 (dst == NULL)? &out_decrypt : &dst->decrypt);
541 return_if_error(ret, "Error unmarshaling subfield decrypt");
542
543 IESYSC_TYPE_POLICY_AUTH out_type_policy_session;
544 ret = iesys_MU_IESYSC_TYPE_POLICY_AUTH_Unmarshal(buffer, size, &offset_loc,
545 (dst == NULL)? &out_type_policy_session : &dst->type_policy_session);
546 return_if_error(ret, "Error unmarshaling subfield type_policy_session");
547
548 UINT16 out_sizeSessionValue;
549 ret = Tss2_MU_UINT16_Unmarshal(buffer, size, &offset_loc,
550 (dst == NULL)? &out_sizeSessionValue : &dst->sizeSessionValue);
551 return_if_error(ret, "Error unmarshaling subfield sizeSessionValue");
552
553 ret = iesys_MU_BYTE_array_Unmarshal(buffer, size, &offset_loc,
554 (dst == NULL)? out_sizeSessionValue : dst->sizeSessionValue,
555 (dst == NULL)? NULL : &dst->sessionValue[0]);
556 return_if_error(ret, "Error unmarshaling subfield sessionValue");
557
558 UINT16 out_sizeHmacValue;
559 ret = Tss2_MU_UINT16_Unmarshal(buffer, size, &offset_loc,
560 (dst == NULL)? &out_sizeHmacValue : &dst->sizeHmacValue);
561 return_if_error(ret, "Error unmarshaling subfield sizeHmacValue");
562
563 if (offset != NULL)
564 *offset = offset_loc;
565 return TSS2_RC_SUCCESS;
566 }
567
568 /** Marshal a IESYSC_RESOURCE_TYPE type into a byte buffer.
569 *
570 * @param[in] src constant to be marshaled.
571 * @param[in,out] buffer Buffer to write result into (may be NULL)
572 * @param[in] size Size of the buffer.
573 * @param[in,out] offset Offset inside the buffer (may be NULL.
574 * @retval TSS2_RC_SUCCESS on success.
575 * @retval TSS2_ESYS_RC_BAD_REFERENCE if src==NULL.
576 * @retval TSS2_ESYS_RC_INSUFFICIENT_BUFFER if remaining buffer is insufficient.
577 */
578 TSS2_RC
iesys_MU_IESYSC_RESOURCE_TYPE_Marshal(const IESYSC_RESOURCE_TYPE src,uint8_t * buffer,size_t size,size_t * offset)579 iesys_MU_IESYSC_RESOURCE_TYPE_Marshal(
580 const IESYSC_RESOURCE_TYPE src,
581 uint8_t *buffer,
582 size_t size,
583 size_t *offset)
584 {
585 LOG_TRACE("called: src=%"PRIx32 " buffer=%p size=%zu offset=%p", src,
586 buffer, size, offset);
587 return Tss2_MU_UINT32_Marshal(src, buffer, size, offset);
588 }
589
590 /** Unmarshal a IESYSC_RESOURCE_TYPE type from a byte buffer.
591 *
592 * @param[in,out] buffer Buffer to read data from.
593 * @param[in] size Size of the buffer.
594 * @param[in,out] offset Offset inside the buffer
595 * (being updated during marshaling).
596 * @param[out] dst variable to store the result in.
597 * @retval TSS2_RC_SUCCESS on success.
598 */
599 TSS2_RC
iesys_MU_IESYSC_RESOURCE_TYPE_Unmarshal(const uint8_t * buffer,size_t size,size_t * offset,IESYSC_RESOURCE_TYPE * dst)600 iesys_MU_IESYSC_RESOURCE_TYPE_Unmarshal(
601 const uint8_t *buffer,
602 size_t size,
603 size_t *offset,
604 IESYSC_RESOURCE_TYPE *dst)
605 {
606 LOG_TRACE("called: buffer=%p size=%zu offset=%p dst=%p",
607 buffer, size, offset, dst);
608 IESYSC_RESOURCE_TYPE dst_loc;
609 TSS2_RC ret = Tss2_MU_UINT32_Unmarshal(buffer, size,
610 offset, &dst_loc);
611 return_if_error(ret, "Unmarshaling the base type");
612
613 ret = iesys_MU_IESYSC_RESOURCE_TYPE_check(&dst_loc);
614 if (ret != TSS2_RC_SUCCESS) {
615 LOG_ERROR("Bad value %"PRIx32 "", dst_loc);
616 return ret;
617 }
618 if (dst != NULL)
619 *dst = dst_loc;
620 LOG_TRACE("return: dst=%p value=%"PRIx32 "", dst, dst_loc);
621 return TSS2_RC_SUCCESS;
622 }
623 /** Check, if a variable has a possible value of type IESYSC_RESOURCE_TYPE.
624 *
625 * @param[in] in variable to check.
626 * @retval TSS2_RC_SUCCESS on success.
627 */
628 TSS2_RC
iesys_MU_IESYSC_RESOURCE_TYPE_check(const IESYSC_RESOURCE_TYPE * in)629 iesys_MU_IESYSC_RESOURCE_TYPE_check(
630 const IESYSC_RESOURCE_TYPE *in)
631 {
632 LOG_TRACE("called: in=%p", in);
633 return_if_null(in, "in==NULL", TSS2_SYS_RC_BAD_REFERENCE);
634
635 /* No Error-Messages, since this function may fail for a good reasons. */
636 if (FALSE
637 || (*in == IESYSC_KEY_RSRC)
638 || (*in == IESYSC_NV_RSRC)
639 || (*in == IESYSC_SESSION_RSRC)
640 || (*in == IESYSC_WITHOUT_MISC_RSRC)) {
641 return TSS2_RC_SUCCESS;
642 } else {
643 return TSS2_SYS_RC_BAD_VALUE;
644 }
645 return TSS2_RC_SUCCESS;
646 }
647
648 /** Marshal a IESYS_RSRC_UNION union into a byte buffer.
649 *
650 * @param[in] src variable to be marshaled.
651 * @param[in] selector the selector value.
652 * @param[in,out] buffer Buffer to write result into.
653 * @param[in] size Size of the buffer.
654 * @param[in,out] offset Offset inside the buffer
655 * (being updated during marshaling).
656 * @retval TSS2_RC_SUCCESS on success.
657 * @retval TSS2_ESYS_RC_BAD_REFERENCE if src==NULL.
658 * @retval TSS2_ESYS_RC_INSUFFICIENT_BUFFER if remaining buffer is insufficient.
659 */
660 TSS2_RC
iesys_MU_IESYS_RSRC_UNION_Marshal(const IESYS_RSRC_UNION * src,UINT32 selector,uint8_t * buffer,size_t size,size_t * offset)661 iesys_MU_IESYS_RSRC_UNION_Marshal(
662 const IESYS_RSRC_UNION *src,
663 UINT32 selector,
664 uint8_t *buffer,
665 size_t size,
666 size_t *offset)
667 {
668 LOG_TRACE("called: src=%p buffer=%p size=%zu offset=%p", src,
669 buffer, size, offset);
670 if (src == NULL) {
671 LOG_ERROR("src=NULL");
672 return TSS2_ESYS_RC_BAD_REFERENCE;
673 }
674
675 switch (selector) {
676 case IESYSC_KEY_RSRC:
677 return Tss2_MU_TPM2B_PUBLIC_Marshal(&src->rsrc_key_pub, buffer, size, offset);
678 case IESYSC_NV_RSRC:
679 return Tss2_MU_TPM2B_NV_PUBLIC_Marshal(&src->rsrc_nv_pub, buffer, size, offset);
680 case IESYSC_SESSION_RSRC:
681 return iesys_MU_IESYS_SESSION_Marshal(&src->rsrc_session, buffer, size, offset);
682 case IESYSC_WITHOUT_MISC_RSRC:
683 return Tss2_MU_TPMS_EMPTY_Marshal(&src->rsrc_empty, buffer, size, offset);
684 default:
685 LOG_ERROR("Selector value %"PRIu32 " not found", selector);
686 return TSS2_SYS_RC_BAD_VALUE;
687 };
688 }
689
690 /** Unmarshal a IESYS_RSRC_UNION union from a byte buffer.
691 *
692 * @param[in,out] buffer Buffer to read data from.
693 * @param[in] size Size of the buffer.
694 * @param[in,out] offset Offset inside the buffer (may be NULL).
695 * @param[in] selector The selector.
696 * @param[out] out variable to store the result in (may be NULL).
697 * @retval TSS2_RC_SUCCESS on success.
698 * @retval TSS2_ESYS_RC_BAD_REFERENCE if src==NULL.
699 * @retval TSS2_ESYS_RC_INSUFFICIENT_BUFFER if remaining buffer is insufficient.
700 */
701 TSS2_RC
iesys_MU_IESYS_RSRC_UNION_Unmarshal(const uint8_t * buffer,size_t size,size_t * offset,UINT32 selector,IESYS_RSRC_UNION * dst)702 iesys_MU_IESYS_RSRC_UNION_Unmarshal(
703 const uint8_t *buffer,
704 size_t size,
705 size_t *offset,
706 UINT32 selector,
707 IESYS_RSRC_UNION *dst)
708 {
709 LOG_TRACE("called: buffer=%p size=%zu offset=%p dst=%p",
710 buffer, size, offset, dst);
711 if (buffer == NULL) {
712 LOG_ERROR("buffer=NULL");
713 return TSS2_ESYS_RC_BAD_REFERENCE;
714 }
715 switch (selector) {
716 case IESYSC_KEY_RSRC:
717 return Tss2_MU_TPM2B_PUBLIC_Unmarshal(buffer, size, offset,
718 (dst != NULL)? &dst->rsrc_key_pub : NULL);
719 case IESYSC_NV_RSRC:
720 return Tss2_MU_TPM2B_NV_PUBLIC_Unmarshal(buffer, size, offset,
721 (dst != NULL)? &dst->rsrc_nv_pub : NULL);
722 case IESYSC_SESSION_RSRC:
723 return iesys_MU_IESYS_SESSION_Unmarshal(buffer, size, offset,
724 (dst != NULL)? &dst->rsrc_session : NULL);
725 case IESYSC_WITHOUT_MISC_RSRC:
726 return Tss2_MU_TPMS_EMPTY_Unmarshal(buffer, size, offset,
727 (dst != NULL)? &dst->rsrc_empty : NULL);
728 default:
729 LOG_ERROR("Selector value %"PRIu32 " not found", selector);
730 return TSS2_SYS_RC_BAD_VALUE;
731 };
732 }
733
734 /** Marshal a IESYS_RESOURCE structure into a byte buffer.
735 *
736 * @param[in] src variable to be marshaled.
737 * @param[in,out] buffer Buffer to write result into.
738 * @param[in] size Size of the buffer.
739 * @param[in,out] offset Offset inside the buffer
740 * (being updated during marshaling).
741 * @retval TSS2_RC_SUCCESS on success.
742 * @retval TSS2_ESYS_RC_BAD_REFERENCE if src==NULL.
743 * @retval TSS2_ESYS_RC_INSUFFICIENT_BUFFER if remaining buffer is insufficient.
744 */
745 TSS2_RC
iesys_MU_IESYS_RESOURCE_Marshal(const IESYS_RESOURCE * src,uint8_t * buffer,size_t size,size_t * offset)746 iesys_MU_IESYS_RESOURCE_Marshal(
747 const IESYS_RESOURCE *src,
748 uint8_t *buffer,
749 size_t size,
750 size_t *offset)
751 {
752 LOG_TRACE("called: src=%p buffer=%p size=%zu offset=%p", src,
753 buffer, size, offset);
754 if (src == NULL) {
755 LOG_ERROR("src=NULL");
756 return TSS2_SYS_RC_BAD_REFERENCE;
757 }
758 TSS2_RC ret;
759 size_t offset_loc = (offset != NULL)? *offset : 0;
760 ret = Tss2_MU_TPM2_HANDLE_Marshal(src->handle, buffer, size, &offset_loc);
761 return_if_error(ret, "Error marshaling subfield handle");
762
763 ret = Tss2_MU_TPM2B_NAME_Marshal(&src->name, buffer, size, &offset_loc);
764 return_if_error(ret, "Error marshaling subfield name");
765
766 ret = iesys_MU_IESYSC_RESOURCE_TYPE_Marshal(src->rsrcType, buffer, size, &offset_loc);
767 return_if_error(ret, "Error marshaling subfield rsrcType");
768
769 ret = iesys_MU_IESYS_RSRC_UNION_Marshal(&src->misc, src->rsrcType,
770 buffer, size, &offset_loc);
771 return_if_error(ret, "Error marshaling subfield misc");
772
773 if (offset != NULL)
774 *offset = offset_loc;
775 return TSS2_RC_SUCCESS;
776 }
777
778 /** Unmarshal a IESYS_RESOURCE variable from a byte buffer.
779 *
780 * @param[in,out] buffer Buffer to read data from.
781 * @param[in] size Size of the buffer.
782 * @param[in,out] offset Offset inside the buffer
783 * (being updated during marshaling).
784 * @param[out] out variable to store the result in.
785 * @retval TSS2_RC_SUCCESS on success.
786 * @retval TSS2_ESYS_RC_BAD_REFERENCE if buffer==NULL.
787 * @retval TSS2_ESYS_RC_INSUFFICIENT_BUFFER if remaining buffer is insufficient.
788 */
789 TSS2_RC
iesys_MU_IESYS_RESOURCE_Unmarshal(const uint8_t * buffer,size_t size,size_t * offset,IESYS_RESOURCE * dst)790 iesys_MU_IESYS_RESOURCE_Unmarshal(
791 const uint8_t *buffer,
792 size_t size,
793 size_t *offset,
794 IESYS_RESOURCE *dst)
795 {
796 LOG_TRACE("called: buffer=%p size=%zu offset=%p dst=%p",
797 buffer, size, offset, dst);
798 if (buffer == NULL) {
799 LOG_ERROR("buffer=NULL");
800 return TSS2_ESYS_RC_BAD_REFERENCE;
801 }
802 TSS2_RC ret;
803 size_t offset_loc = (offset != NULL)? *offset : 0;
804 if (dst != NULL)
805 memset(dst, 0, sizeof(*dst));
806 TPM2_HANDLE out_handle;
807 ret = Tss2_MU_TPM2_HANDLE_Unmarshal(buffer, size, &offset_loc,
808 (dst == NULL)? &out_handle : &dst->handle);
809 return_if_error(ret, "Error unmarshaling subfield handle");
810
811 ret = Tss2_MU_TPM2B_NAME_Unmarshal(buffer, size, &offset_loc,
812 (dst == NULL)? NULL : &dst->name);
813 return_if_error(ret, "Error unmarshaling subfield name");
814
815 IESYSC_RESOURCE_TYPE out_rsrcType;
816 ret = iesys_MU_IESYSC_RESOURCE_TYPE_Unmarshal(buffer, size, &offset_loc,
817 (dst == NULL)? &out_rsrcType : &dst->rsrcType);
818 return_if_error(ret, "Error unmarshaling subfield rsrcType");
819
820 ret = iesys_MU_IESYS_RSRC_UNION_Unmarshal(buffer, size, &offset_loc,
821 (dst == NULL)? out_rsrcType : dst->rsrcType,
822 (dst == NULL)? NULL : &dst->misc);
823 return_if_error(ret, "Error unmarshaling subfield misc");
824
825 if (offset != NULL)
826 *offset = offset_loc;
827 return TSS2_RC_SUCCESS;
828 }
829
830 /** Marshal a IESYS_METADATA structure into a byte buffer.
831 *
832 * @param[in] src variable to be marshaled.
833 * @param[in,out] buffer Buffer to write result into.
834 * @param[in] size Size of the buffer.
835 * @param[in,out] offset Offset inside the buffer
836 * (being updated during marshaling).
837 * @retval TSS2_RC_SUCCESS on success.
838 * @retval TSS2_ESYS_RC_BAD_REFERENCE if src==NULL.
839 * @retval TSS2_ESYS_RC_INSUFFICIENT_BUFFER if remaining buffer is insufficient.
840 */
841 TSS2_RC
iesys_MU_IESYS_METADATA_Marshal(const IESYS_METADATA * src,uint8_t * buffer,size_t size,size_t * offset)842 iesys_MU_IESYS_METADATA_Marshal(
843 const IESYS_METADATA *src,
844 uint8_t *buffer,
845 size_t size,
846 size_t *offset)
847 {
848 LOG_TRACE("called: src=%p buffer=%p size=%zu offset=%p", src,
849 buffer, size, offset);
850 if (src == NULL) {
851 LOG_ERROR("src=NULL");
852 return TSS2_SYS_RC_BAD_REFERENCE;
853 }
854 TSS2_RC ret;
855 size_t offset_loc = (offset != NULL)? *offset : 0;
856 ret = Tss2_MU_UINT16_Marshal(src->size, buffer, size, &offset_loc);
857 return_if_error(ret, "Error marshaling subfield size");
858
859 ret = iesys_MU_IESYS_RESOURCE_Marshal(&src->data, buffer, size, &offset_loc);
860 return_if_error(ret, "Error marshaling subfield data");
861
862 if (offset != NULL)
863 *offset = offset_loc;
864 return TSS2_RC_SUCCESS;
865 }
866
867 /** Unmarshal a IESYS_METADATA variable from a byte buffer.
868 *
869 * @param[in,out] buffer Buffer to read data from.
870 * @param[in] size Size of the buffer.
871 * @param[in,out] offset Offset inside the buffer
872 * (being updated during marshaling).
873 * @param[out] out variable to store the result in.
874 * @retval TSS2_RC_SUCCESS on success.
875 * @retval TSS2_ESYS_RC_BAD_REFERENCE if buffer==NULL.
876 * @retval TSS2_ESYS_RC_INSUFFICIENT_BUFFER if remaining buffer is insufficient.
877 */
878 TSS2_RC
iesys_MU_IESYS_METADATA_Unmarshal(const uint8_t * buffer,size_t size,size_t * offset,IESYS_METADATA * dst)879 iesys_MU_IESYS_METADATA_Unmarshal(
880 const uint8_t *buffer,
881 size_t size,
882 size_t *offset,
883 IESYS_METADATA *dst)
884 {
885 LOG_TRACE("called: buffer=%p size=%zu offset=%p dst=%p",
886 buffer, size, offset, dst);
887 if (buffer == NULL) {
888 LOG_ERROR("buffer=NULL");
889 return TSS2_ESYS_RC_BAD_REFERENCE;
890 }
891 TSS2_RC ret;
892 size_t offset_loc = (offset != NULL)? *offset : 0;
893 if (dst != NULL)
894 memset(dst, 0, sizeof(*dst));
895 UINT16 out_size;
896 ret = Tss2_MU_UINT16_Unmarshal(buffer, size, &offset_loc,
897 (dst == NULL)? &out_size : &dst->size);
898 return_if_error(ret, "Error unmarshaling subfield size");
899
900 IESYS_RESOURCE out_data;
901 ret = iesys_MU_IESYS_RESOURCE_Unmarshal(buffer, size, &offset_loc,
902 (dst == NULL)? &out_data : &dst->data);
903 return_if_error(ret, "Error unmarshaling subfield data");
904
905 if (offset != NULL)
906 *offset = offset_loc;
907 return TSS2_RC_SUCCESS;
908 }
909
910 /** Marshal a IESYS_CONTEXT_DATA structure into a byte buffer.
911 *
912 * @param[in] src variable to be marshaled.
913 * @param[in,out] buffer Buffer to write result into.
914 * @param[in] size Size of the buffer.
915 * @param[in,out] offset Offset inside the buffer
916 * (being updated during marshaling).
917 * @retval TSS2_RC_SUCCESS on success.
918 * @retval TSS2_ESYS_RC_BAD_REFERENCE if src==NULL.
919 * @retval TSS2_ESYS_RC_INSUFFICIENT_BUFFER if remaining buffer is insufficient.
920 */
921 TSS2_RC
iesys_MU_IESYS_CONTEXT_DATA_Marshal(const IESYS_CONTEXT_DATA * src,uint8_t * buffer,size_t size,size_t * offset)922 iesys_MU_IESYS_CONTEXT_DATA_Marshal(
923 const IESYS_CONTEXT_DATA *src,
924 uint8_t *buffer,
925 size_t size,
926 size_t *offset)
927 {
928 LOG_TRACE("called: src=%p buffer=%p size=%zu offset=%p", src,
929 buffer, size, offset);
930 if (src == NULL) {
931 LOG_ERROR("src=NULL");
932 return TSS2_SYS_RC_BAD_REFERENCE;
933 }
934 TSS2_RC ret;
935 size_t offset_loc = (offset != NULL)? *offset : 0;
936 ret = Tss2_MU_UINT32_Marshal(src->reserved, buffer, size, &offset_loc);
937 return_if_error(ret, "Error marshaling subfield reserved");
938
939 ret = Tss2_MU_TPM2B_CONTEXT_DATA_Marshal(&src->tpmContext, buffer, size, &offset_loc);
940 return_if_error(ret, "Error marshaling subfield tpmContext");
941
942 ret = iesys_MU_IESYS_METADATA_Marshal(&src->esysMetadata, buffer, size, &offset_loc);
943 return_if_error(ret, "Error marshaling subfield esysMetadata");
944
945 if (offset != NULL)
946 *offset = offset_loc;
947 return TSS2_RC_SUCCESS;
948 }
949
950 /** Unmarshal a IESYS_CONTEXT_DATA variable from a byte buffer.
951 *
952 * @param[in,out] buffer Buffer to read data from.
953 * @param[in] size Size of the buffer.
954 * @param[in,out] offset Offset inside the buffer
955 * (being updated during marshaling).
956 * @param[out] out variable to store the result in.
957 * @retval TSS2_RC_SUCCESS on success.
958 * @retval TSS2_ESYS_RC_BAD_REFERENCE if buffer==NULL.
959 * @retval TSS2_ESYS_RC_INSUFFICIENT_BUFFER if remaining buffer is insufficient.
960 */
961 TSS2_RC
iesys_MU_IESYS_CONTEXT_DATA_Unmarshal(const uint8_t * buffer,size_t size,size_t * offset,IESYS_CONTEXT_DATA * dst)962 iesys_MU_IESYS_CONTEXT_DATA_Unmarshal(
963 const uint8_t *buffer,
964 size_t size,
965 size_t *offset,
966 IESYS_CONTEXT_DATA *dst)
967 {
968 LOG_TRACE("called: buffer=%p size=%zu offset=%p dst=%p",
969 buffer, size, offset, dst);
970 if (buffer == NULL) {
971 LOG_ERROR("buffer=NULL");
972 return TSS2_ESYS_RC_BAD_REFERENCE;
973 }
974 TSS2_RC ret;
975 size_t offset_loc = (offset != NULL)? *offset : 0;
976 if (dst != NULL)
977 memset(dst, 0, sizeof(*dst));
978 UINT32 out_reserved;
979 ret = Tss2_MU_UINT32_Unmarshal(buffer, size, &offset_loc,
980 (dst == NULL)? &out_reserved : &dst->reserved);
981 return_if_error(ret, "Error unmarshaling subfield reserved");
982
983 ret = Tss2_MU_TPM2B_CONTEXT_DATA_Unmarshal(buffer, size, &offset_loc,
984 (dst == NULL)? NULL : &dst->tpmContext);
985 return_if_error(ret, "Error unmarshaling subfield tpmContext");
986
987 IESYS_METADATA out_esysMetadata;
988 ret = iesys_MU_IESYS_METADATA_Unmarshal(buffer, size, &offset_loc,
989 (dst == NULL)? &out_esysMetadata : &dst->esysMetadata);
990 return_if_error(ret, "Error unmarshaling subfield esysMetadata");
991
992 if (offset != NULL)
993 *offset = offset_loc;
994 return TSS2_RC_SUCCESS;
995 }
996