• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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