--- /dev/null
+/*
+ * Copyright (c) 2014 Intel Corporation.
+ *
+ * Authors:
+ * Quan Xu <quan.xu@intel.com>
+ *
+ * Copyright (c) 2010-2012 United States Government, as represented by
+ * the Secretary of Defense. All rights reserved.
+ *
+ * based off of the original tools/vtpm_manager code base which is:
+ * Copyright (c) 2005, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef TPM2_MARSHAL_H
+#define TPM2_MARSHAL_H
+
+#include <stdlib.h>
+#include <mini-os/byteorder.h>
+#include <mini-os/endian.h>
+#include "tcg.h"
+#include "tpm2_types.h"
+#include <assert.h>
+
+#define pack_TPM_BUFFER(ptr, buf, size) pack_BUFFER(ptr, buf, size)
+#define unpack_TPM_BUFFER(ptr, buf, size) unpack_BUFFER(ptr, buf, size)
+
+inline BYTE* pack_BYTE_ARRAY(BYTE* ptr, const BYTE* array, UINT32 size)
+{
+ int i;
+ for (i = 0; i < size; i++)
+ ptr = pack_BYTE(ptr, array[i]);
+ return ptr;
+}
+
+inline BYTE* pack_TPMA_SESSION(BYTE* ptr, const TPMA_SESSION *attr)
+{
+ return pack_BYTE(ptr, (BYTE)(*attr));
+}
+
+inline BYTE* unpack_TPMA_SESSION(BYTE* ptr, TPMA_SESSION *attr)
+{
+ return unpack_BYTE(ptr, (BYTE *)attr);
+}
+
+inline BYTE* pack_TPMI_ALG_HASH(BYTE* ptr, const TPMI_ALG_HASH *hash)
+{
+ return pack_UINT16(ptr, *hash);
+}
+
+inline BYTE* unpack_TPMI_ALG_HASH(BYTE *ptr, TPMI_ALG_HASH *hash)
+{
+ return unpack_UINT16(ptr, hash);
+}
+
+#define pack_TPMA_OBJECT(ptr, t) pack_UINT32(ptr, (UINT32)(*t))
+#define unpack_TPMA_OBJECT(ptr, t) unpack_UINT32(ptr, (UINT32 *)(t))
+#define pack_TPM_RH(ptr, t) pack_UINT32(ptr, (UINT32)(*t))
+#define unpack_TPM_RH(ptr, t) unpack_UINT32(ptr, (UINT32 *)(t))
+#define pack_TPMA_LOCALITY(ptr, locality) pack_BYTE(ptr, (BYTE)*locality)
+#define unpack_TPMA_LOCALITY(ptr, locality) unpack_BYTE(ptr, (BYTE *)locality)
+#define pack_TPM_ST(ptr, tag) pack_UINT16(ptr, *tag)
+#define unpack_TPM_ST(ptr, tag) unpack_UINT16(ptr, tag)
+#define pack_TPM_KEY_BITS(ptr, t) pack_UINT16(ptr, *t)
+#define unpack_TPM_KEY_BITS(ptr, t) unpack_UINT16(ptr, t)
+#define pack_TPMI_AES_KEY_BITS(ptr, t) pack_TPM_KEY_BITS(ptr, t)
+#define unpack_TPMI_AES_KEY_BITS(ptr, t) unpack_TPM_KEY_BITS(ptr, t)
+#define pack_TPMI_RSA_KEY_BITS(ptr, t) pack_TPM_KEY_BITS(ptr, t)
+#define unpack_TPMI_RSA_KEY_BITS(ptr, t) unpack_TPM_KEY_BITS(ptr, t)
+#define pack_TPM_ALG_ID(ptr, id) pack_UINT16(ptr, *id)
+#define unpack_TPM_ALG_ID(ptr, id) unpack_UINT16(ptr, id)
+#define pack_TPM_ALG_SYM(ptr, t) pack_TPM_ALG_ID(ptr, t)
+#define unpack_TPM_ALG_SYM(ptr, t) unpack_TPM_ALG_ID(ptr, t)
+#define pack_TPMI_ALG_ASYM(ptr, asym) pack_TPM_ALG_ID(ptr, asym)
+#define unpack_TPMI_ALG_ASYM(ptr, asym) unpack_TPM_ALG_ID(ptr, asym)
+#define pack_TPMI_ALG_SYM_OBJECT(ptr, t) pack_TPM_ALG_ID(ptr, t)
+#define unpack_TPMI_ALG_SYM_OBJECT(ptr, t) unpack_TPM_ALG_ID(ptr, t)
+#define pack_TPMI_ALG_SYM_MODE(ptr, t) pack_TPM_ALG_ID(ptr, t)
+#define unpack_TPMI_ALG_SYM_MODE(ptr, t) unpack_TPM_ALG_ID(ptr, t)
+#define pack_TPMI_ALG_KDF(ptr, t) pack_TPM_ALG_ID(ptr, t)
+#define unpack_TPMI_ALG_KDF(ptr, t) unpack_TPM_ALG_ID(ptr, t)
+#define pack_TPMI_ALG_PUBLIC(ptr, t) pack_TPM_ALG_ID(ptr, t)
+#define unpack_TPMI_ALG_PUBLIC(ptr, t) unpack_TPM_ALG_ID(ptr, t)
+#define pack_TPM2_HANDLE(ptr, h) pack_UINT32(ptr, *h)
+#define unpack_TPM2_HANDLE(ptr, h) unpack_UINT32(ptr, h)
+#define pack_TPMI_ALG_RSA_SCHEME(ptr, t) pack_TPM_ALG_ID(ptr, t)
+#define unpack_TPMI_ALG_RSA_SCHEME(ptr, t) unpack_TPM_ALG_ID(ptr, t)
+#define pack_TPMI_DH_OBJECT(ptr, o) pack_TPM2_HANDLE(ptr, o)
+#define unpack_TPMI_DH_OBJECT(PTR, O) unpack_TPM2_HANDLE(ptr, o)
+#define pack_TPMI_RH_HIERACHY(ptr, h) pack_TPM2_HANDLE(ptr, h)
+#define unpack_TPMI_RH_HIERACHY(ptr, h) unpack_TPM2_HANDLE(ptr, h)
+#define pack_TPMI_RH_PLATFORM(ptr, p) pack_TPM2_HANDLE(ptr, p)
+#define unpack_TPMI_RH_PLATFORM(ptr, p) unpack_TPM2_HANDLE(ptr, p)
+#define pack_TPMI_RH_OWNER(ptr, o) pack_TPM2_HANDLE(ptr, o)
+#define unpack_TPMI_RH_OWNER(ptr, o) unpack_TPM2_HANDLE(ptr, o)
+#define pack_TPMI_RH_ENDORSEMENT(ptr, e) pack_TPM2_HANDLE(ptr, e)
+#define unpack_TPMI_RH_ENDORSEMENT(ptr, e) unpack_TPM2_HANDLE(ptr, e)
+#define pack_TPMI_RH_LOCKOUT(ptr, l) pack_TPM2_HANDLE(ptr, l)
+#define unpack_TPMI_RH_LOCKOUT(ptr, l) unpack_TPM2_HANDLE(ptr, l)
+
+inline BYTE* pack_TPM2B_DIGEST(BYTE* ptr, const TPM2B_DIGEST *digest)
+{
+ ptr = pack_UINT16(ptr, digest->size);
+ ptr = pack_BUFFER(ptr, digest->buffer, digest->size);
+ return ptr;
+}
+
+inline BYTE* unpack_TPM2B_DIGEST(BYTE* ptr, TPM2B_DIGEST *digest)
+{
+ ptr = unpack_UINT16(ptr, &digest->size);
+ ptr = unpack_BUFFER(ptr, digest->buffer, digest->size);
+ return ptr;
+}
+
+inline BYTE* pack_TPMT_TK_CREATION(BYTE* ptr,const TPMT_TK_CREATION *ticket )
+{
+ ptr = pack_TPM_ST(ptr , &ticket->tag);
+ ptr = pack_TPMI_RH_HIERACHY(ptr , &ticket->hierarchy);
+ ptr = pack_TPM2B_DIGEST(ptr, &ticket->digest);
+ return ptr;
+}
+
+inline BYTE* unpack_TPMT_TK_CREATION(BYTE* ptr, TPMT_TK_CREATION *ticket )
+{
+ ptr = unpack_TPM_ST(ptr, &ticket->tag);
+ ptr = unpack_TPMI_RH_HIERACHY(ptr, &ticket->hierarchy);
+ ptr = unpack_TPM2B_DIGEST(ptr, &ticket->digest);
+ return ptr;
+}
+
+inline BYTE* pack_TPM2B_NAME(BYTE* ptr,const TPM2B_NAME *name )
+{
+ ptr = pack_UINT16(ptr, name->size);
+ ptr = pack_TPM_BUFFER(ptr, name->name, name->size);
+ return ptr;
+}
+
+inline BYTE* unpack_TPM2B_NAME(BYTE* ptr, TPM2B_NAME *name)
+{
+ ptr = unpack_UINT16(ptr, &name->size);
+ ptr = unpack_TPM_BUFFER(ptr, name->name, name->size);
+ return ptr;
+}
+
+inline BYTE* pack_TPM2B_NONCE(BYTE* ptr, const TPM2B_NONCE *nonce)
+{
+ return pack_TPM2B_DIGEST(ptr, (const TPM2B_DIGEST*)nonce);
+}
+
+#define unpack_TPM2B_NONCE(ptr, nonce) unpack_TPM2B_DIGEST(ptr, (TPM2B_DIGEST*)nonce)
+
+inline BYTE* pack_TPM2B_AUTH(BYTE* ptr, const TPM2B_AUTH *auth)
+{
+ return pack_TPM2B_DIGEST(ptr, (const TPM2B_DIGEST*)auth);
+}
+
+#define unpack_TPM2B_AUTH(ptr, auth) unpack_TPM2B_DIGEST(ptr, (TPM2B_DIGEST*)auth)
+
+inline BYTE* pack_TPM2B_DATA(BYTE* ptr, const TPM2B_DATA *data)
+{
+ return pack_TPM2B_DIGEST(ptr, (const TPM2B_DIGEST*)data);
+}
+
+#define unpack_TPM2B_DATA(ptr, data) unpack_TPM2B_DIGEST(ptr, (TPM2B_DIGEST*)data)
+
+inline BYTE* pack_TPM2B_SENSITIVE_DATA(BYTE* ptr, const TPM2B_SENSITIVE_DATA *data)
+{
+ return pack_TPM2B_DIGEST(ptr, (const TPM2B_DIGEST*)data);
+}
+
+#define unpack_TPM2B_SENSITIVE_DATA(ptr, data) unpack_TPM2B_DIGEST(ptr, (TPM2B_DIGEST*)data)
+
+inline BYTE* pack_TPM2B_PUBLIC_KEY_RSA(BYTE* ptr, const TPM2B_PUBLIC_KEY_RSA *rsa)
+{
+ return pack_TPM2B_DIGEST(ptr, (const TPM2B_DIGEST*)rsa);
+}
+
+#define unpack_TPM2B_PUBLIC_KEY_RSA(ptr, rsa) unpack_TPM2B_DIGEST(ptr, (TPM2B_DIGEST*)rsa)
+
+inline BYTE* pack_TPM2B_PRIVATE(BYTE* ptr, const TPM2B_PRIVATE *Private)
+{
+ ptr = pack_UINT16(ptr, Private->size);
+ ptr = pack_TPM_BUFFER(ptr, Private->buffer, Private->size);
+ return ptr;
+}
+
+inline BYTE* unpack_TPM2B_PRIVATE(BYTE* ptr, TPM2B_PRIVATE *Private)
+{
+ ptr = unpack_UINT16(ptr, &Private->size);
+ ptr = unpack_BUFFER(ptr, Private->buffer, Private->size);
+ return ptr;
+}
+
+inline BYTE* pack_TPMS_PCR_SELECTION_ARRAY(BYTE* ptr, const TPMS_PCR_SELECTION *sel, UINT32 count)
+{
+ int i;
+ for (i = 0; i < count; i++) {
+ ptr = pack_TPMI_ALG_HASH(ptr, &sel[i].hash);
+ ptr = pack_BYTE(ptr, sel[i].sizeofSelect);
+ ptr = pack_BUFFER(ptr, sel[i].pcrSelect, sel[i].sizeofSelect);
+ }
+ return ptr;
+}
+
+inline BYTE* unpack_TPMS_PCR_SELECTION_ARRAY(BYTE* ptr, TPMS_PCR_SELECTION *sel, UINT32 count)
+{
+ int i;
+ for (i = 0; i < count; i++) {
+ ptr = unpack_TPMI_ALG_HASH(ptr, &sel[i].hash);
+ ptr = unpack_BYTE(ptr, &sel[i].sizeofSelect);
+ ptr = unpack_BUFFER(ptr, sel[i].pcrSelect, sel[i].sizeofSelect);
+ }
+ return ptr;
+}
+
+inline BYTE* pack_TPML_PCR_SELECTION(BYTE* ptr, const TPML_PCR_SELECTION *sel)
+{
+ ptr = pack_UINT32(ptr, sel->count);
+ ptr = pack_TPMS_PCR_SELECTION_ARRAY(ptr, sel->pcrSelections, sel->count);
+ return ptr;
+}
+
+inline BYTE* unpack_TPML_PCR_SELECTION(BYTE* ptr, TPML_PCR_SELECTION *sel)
+{
+ ptr = unpack_UINT32(ptr, &sel->count);
+ ptr = unpack_TPMS_PCR_SELECTION_ARRAY(ptr, sel->pcrSelections, sel->count);
+ return ptr;
+}
+
+inline BYTE* unpack_TPML_DIGEST(BYTE* ptr,TPML_DIGEST *digest)
+{
+ int i;
+ ptr = unpack_UINT32(ptr, &digest->count);
+ for (i=0;i<digest->count;i++)
+ {
+ ptr = unpack_TPM2B_DIGEST(ptr, &digest->digests[i]);
+ }
+ return ptr;
+}
+
+inline BYTE* pack_TPMS_CREATION_DATA(BYTE* ptr,const TPMS_CREATION_DATA *data)
+{
+ ptr = pack_TPML_PCR_SELECTION(ptr, &data->pcrSelect);
+ ptr = pack_TPM2B_DIGEST(ptr, &data->pcrDigest);
+ ptr = pack_TPMA_LOCALITY(ptr, &data->locality);
+ ptr = pack_TPM_ALG_ID(ptr, &data->parentNameAlg);
+ ptr = pack_TPM2B_NAME(ptr, &data->parentQualifiedName);
+ ptr = pack_TPM2B_DATA(ptr, &data->outsideInfo);
+ return ptr;
+}
+
+inline BYTE* unpack_TPMS_CREATION_DATA(BYTE* ptr, TPMS_CREATION_DATA *data)
+{
+ ptr = unpack_TPML_PCR_SELECTION(ptr, &data->pcrSelect);
+ ptr = unpack_TPM2B_DIGEST(ptr, &data->pcrDigest);
+ ptr = unpack_TPMA_LOCALITY(ptr, &data->locality);
+ ptr = unpack_TPM_ALG_ID(ptr, &data->parentNameAlg);
+ ptr = unpack_TPM2B_NAME(ptr, &data->parentName);
+ ptr = unpack_TPM2B_NAME(ptr, &data->parentQualifiedName);
+ ptr = unpack_TPM2B_DATA(ptr, &data->outsideInfo);
+ return ptr;
+}
+
+inline BYTE* pack_TPM2B_CREATION_DATA(BYTE* ptr, const TPM2B_CREATION_DATA *data )
+{
+ ptr = pack_UINT16(ptr, data->size);
+ ptr = pack_TPMS_CREATION_DATA(ptr, &data->creationData);
+ return ptr;
+}
+
+inline BYTE* unpack_TPM2B_CREATION_DATA(BYTE* ptr, TPM2B_CREATION_DATA * data)
+{
+ ptr = unpack_UINT16(ptr, &data->size);
+ ptr = unpack_TPMS_CREATION_DATA(ptr, &data->creationData);
+ return ptr;
+}
+
+inline BYTE* pack_TPMS_SENSITIVE_CREATE(BYTE* ptr, const TPMS_SENSITIVE_CREATE *create)
+{
+ ptr = pack_TPM2B_AUTH(ptr, &create->userAuth);
+ ptr = pack_TPM2B_SENSITIVE_DATA(ptr, &create->data);
+ return ptr;
+}
+
+inline BYTE* pack_TPM2B_SENSITIVE_CREATE(BYTE* ptr, const TPM2B_SENSITIVE_CREATE *create)
+{
+ BYTE* sizePtr = ptr;
+ ptr += 2;
+ ptr = pack_TPMS_SENSITIVE_CREATE(ptr, &create->sensitive);
+ pack_UINT16(sizePtr, (UINT16)(ptr - sizePtr - 2));
+ return ptr;
+}
+
+inline BYTE* pack_TPMU_SYM_MODE(BYTE* ptr, const TPMU_SYM_MODE *p,
+ const TPMI_ALG_SYM_OBJECT *sel)
+{
+ switch(*sel) {
+ case TPM2_ALG_AES:
+ ptr = pack_TPMI_ALG_SYM_MODE(ptr, &p->aes);
+ break;
+ case TPM2_ALG_SM4:
+ assert(false);
+ break;
+ case TPM2_ALG_NULL:
+ case TPM2_ALG_XOR:
+ break;
+ default:
+ ptr = pack_TPMI_ALG_SYM_MODE(ptr, &p->sym);
+ }
+ return ptr;
+}
+inline BYTE* unpack_TPMU_SYM_MODE(BYTE* ptr, TPMU_SYM_MODE *p,
+ const TPMI_ALG_SYM_OBJECT *sel)
+{
+ switch(*sel) {
+ case TPM2_ALG_AES:
+ ptr = unpack_TPMI_ALG_SYM_MODE(ptr, &p->aes);
+ break;
+ case TPM2_ALG_SM4:
+ assert(false);
+ break;
+ case TPM2_ALG_NULL:
+ case TPM2_ALG_XOR:
+ break;
+ default:
+ ptr = unpack_TPMI_ALG_SYM_MODE(ptr, &p->sym);
+ }
+ return ptr;
+}
+
+inline BYTE* pack_TPMU_SYM_KEY_BITS(BYTE* ptr, const TPMU_SYM_KEY_BITS *p,
+ const TPMI_ALG_SYM_OBJECT *sel)
+{
+ switch(*sel) {
+ case TPM2_ALG_AES:
+ ptr = pack_TPMI_AES_KEY_BITS(ptr, &p->aes);
+ break;
+ case TPM2_ALG_SM4:
+ assert(false);
+ break;
+ case TPM2_ALG_XOR:
+ assert(false);
+ break;
+ case TPM2_ALG_NULL:
+ break;
+ default:
+ ptr = pack_TPM_KEY_BITS(ptr, &p->sym);
+ }
+ return ptr;
+}
+
+inline BYTE* unpack_TPMU_SYM_KEY_BITS(BYTE* ptr, TPMU_SYM_KEY_BITS *p,
+ const TPMI_ALG_SYM_OBJECT *sel)
+{
+ switch(*sel) {
+ case TPM2_ALG_AES:
+ ptr = unpack_TPMI_AES_KEY_BITS(ptr, &p->aes);
+ break;
+ case TPM2_ALG_SM4:
+ assert(false);
+ break;
+ case TPM2_ALG_XOR:
+ assert(false);
+ break;
+ case TPM2_ALG_NULL:
+ break;
+ default:
+ ptr = unpack_TPM_KEY_BITS(ptr, &p->sym);
+ }
+ return ptr;
+}
+
+inline BYTE* pack_TPMT_SYM_DEF_OBJECT(BYTE* ptr, const TPMT_SYM_DEF_OBJECT *p)
+{
+ ptr = pack_TPMI_ALG_SYM_OBJECT(ptr, &p->algorithm);
+ ptr = pack_TPMU_SYM_KEY_BITS(ptr, &p->keyBits, &p->algorithm);
+ ptr = pack_TPMU_SYM_MODE(ptr, &p->mode, &p->algorithm);
+ return ptr;
+}
+
+inline BYTE* unpack_TPMT_SYM_DEF_OBJECT(BYTE *ptr, TPMT_SYM_DEF_OBJECT *p)
+{
+ ptr = unpack_TPMI_ALG_SYM_OBJECT(ptr, &p->algorithm);
+ ptr = unpack_TPMU_SYM_KEY_BITS(ptr, &p->keyBits, &p->algorithm);
+ ptr = unpack_TPMU_SYM_MODE(ptr, &p->mode, &p->algorithm);
+ return ptr;
+}
+
+#define pack_TPMS_SCHEME_OAEP(p, t) pack_TPMI_ALG_HASH(p, &((t)->hashAlg))
+#define unpack_TPMS_SCHEME_OAEP(p, t) unpack_TPMI_ALG_HASH(p, &((t)->hashAlg))
+
+inline BYTE* pack_TPMU_ASYM_SCHEME(BYTE *ptr, const TPMU_ASYM_SCHEME *p,
+ const TPMI_ALG_RSA_SCHEME *s)
+{
+ switch(*s) {
+#ifdef TPM2_ALG_RSASSA
+ case TPM2_ALG_RSASSA:
+ assert(false || "TPM2_ALG_RSASSA");
+ break;
+#endif
+#ifdef TPM2_ALG_OAEP
+ case TPM2_ALG_OAEP:
+ ptr = pack_TPMS_SCHEME_OAEP(ptr, &p->oaep);
+ break;
+#endif
+ case TPM2_ALG_NULL:
+ break;
+ default:
+ assert(false || "DEFAULT");
+ }
+ return ptr;
+}
+
+inline BYTE* unpack_TPMU_ASYM_SCHEME(BYTE *ptr, TPMU_ASYM_SCHEME *p,
+ const TPMI_ALG_RSA_SCHEME *s)
+{
+ switch(*s) {
+ #ifdef TPM2_ALG_RSASSA
+ case TPM2_ALG_RSASSA:
+ printf("not support TPM_ALG_RSASSA\n");
+ assert(false);
+ break;
+ #endif
+ #ifdef TPM2_ALG_OAEP
+ case TPM2_ALG_OAEP:
+ ptr = unpack_TPMS_SCHEME_OAEP(ptr, &p->oaep);
+ break;
+ #endif
+ case TPM2_ALG_NULL:
+ break;
+ default:
+ printf("default TPMI_ALG_RSA_SCHEME 0x%X\n", (UINT32)*s);
+ ptr = unpack_TPMI_ALG_HASH(ptr, &p->anySig.hashAlg);
+ }
+ return ptr;
+}
+
+inline BYTE* pack_TPMT_RSA_SCHEME(BYTE* ptr, const TPMT_RSA_SCHEME *p)
+{
+ ptr = pack_TPMI_ALG_RSA_SCHEME(ptr, &p->scheme);
+ ptr = pack_TPMU_ASYM_SCHEME(ptr, &p->details, &p->scheme);
+ return ptr;
+}
+
+inline BYTE* unpack_TPMT_RSA_SCHEME(BYTE* ptr, TPMT_RSA_SCHEME *p)
+{
+ ptr = unpack_TPMI_ALG_RSA_SCHEME(ptr, &p->scheme);
+ ptr = unpack_TPMU_ASYM_SCHEME(ptr, &p->details, &p->scheme);
+ return ptr;
+}
+
+inline BYTE* pack_TPMT_RSA_DECRYPT(BYTE* ptr, const TPMT_RSA_DECRYPT *p)
+{
+ ptr = pack_TPMI_ALG_RSA_SCHEME(ptr, &p->scheme);
+ ptr = pack_TPMU_ASYM_SCHEME(ptr, &p->details, &p->scheme);
+ return ptr;
+}
+
+inline BYTE* pack_TPMS_RSA_PARMS(BYTE* ptr, const TPMS_RSA_PARMS *p)
+{
+ ptr = pack_TPMT_SYM_DEF_OBJECT(ptr, &p->symmetric);
+ ptr = pack_TPMT_RSA_SCHEME(ptr, &p->scheme);
+ ptr = pack_TPMI_RSA_KEY_BITS(ptr, &p->keyBits);
+ ptr = pack_UINT32(ptr, p->exponent);
+ return ptr;
+}
+
+inline BYTE* unpack_TPMS_RSA_PARMS(BYTE *ptr, TPMS_RSA_PARMS *p)
+{
+ ptr = unpack_TPMT_SYM_DEF_OBJECT(ptr, &p->symmetric);
+ ptr = unpack_TPMT_RSA_SCHEME(ptr, &p->scheme);
+ ptr = unpack_TPMI_RSA_KEY_BITS(ptr, &p->keyBits);
+ ptr = unpack_UINT32(ptr, &p->exponent);
+ return ptr;
+}
+
+inline BYTE* pack_TPMU_PUBLIC_PARMS(BYTE* ptr, const TPMU_PUBLIC_PARMS *param,
+ const TPMI_ALG_PUBLIC *selector)
+{
+ switch(*selector) {
+ case TPM2_ALG_KEYEDHASH:
+ assert(false);
+ case TPM2_ALG_SYMCIPHER:
+ assert(false);
+ case TPM2_ALG_RSA:
+ return pack_TPMS_RSA_PARMS(ptr, ¶m->rsaDetail);
+ case TPM2_ALG_ECC:
+ assert(false);
+ }
+ assert(false);
+ return NULL;
+}
+
+inline BYTE* unpack_TPMU_PUBLIC_PARMS(BYTE* ptr, TPMU_PUBLIC_PARMS *param,
+ const TPMI_ALG_PUBLIC *selector)
+{
+ switch(*selector) {
+ case TPM2_ALG_KEYEDHASH:
+ assert(false);
+ case TPM2_ALG_SYMCIPHER:
+ assert(false);
+ case TPM2_ALG_RSA:
+ return unpack_TPMS_RSA_PARMS(ptr, ¶m->rsaDetail);
+ case TPM2_ALG_ECC:
+ assert(false);
+ }
+ assert(false);
+ return NULL;
+}
+
+inline BYTE* pack_TPMS_ECC_POINT(BYTE* ptr, const TPMS_ECC_POINT *point)
+{
+ assert(false);
+ return ptr;
+}
+
+inline BYTE* unpack_TPMS_ECC_POINT(BYTE* ptr, TPMS_ECC_POINT *point)
+{
+ assert(false);
+ return ptr;
+}
+
+inline BYTE* pack_TPMU_PUBLIC_ID(BYTE* ptr, const TPMU_PUBLIC_ID *id,
+ const TPMI_ALG_PUBLIC *selector)
+{
+ switch (*selector) {
+ case TPM2_ALG_KEYEDHASH:
+ return pack_TPM2B_DIGEST(ptr, &id->keyedHash);
+ case TPM2_ALG_SYMCIPHER:
+ return pack_TPM2B_DIGEST(ptr, &id->sym);
+ case TPM2_ALG_RSA:
+ return pack_TPM2B_PUBLIC_KEY_RSA(ptr, &id->rsa);
+ case TPM2_ALG_ECC:
+ return pack_TPMS_ECC_POINT(ptr, &id->ecc);
+ }
+ assert(false);
+ return NULL;
+}
+
+inline BYTE* unpack_TPMU_PUBLIC_ID(BYTE* ptr, TPMU_PUBLIC_ID *id, TPMI_ALG_PUBLIC *selector)
+{
+ switch (*selector) {
+ case TPM2_ALG_KEYEDHASH:
+ return unpack_TPM2B_DIGEST(ptr, &id->keyedHash);
+ case TPM2_ALG_SYMCIPHER:
+ return unpack_TPM2B_DIGEST(ptr, &id->sym);
+ case TPM2_ALG_RSA:
+ return unpack_TPM2B_PUBLIC_KEY_RSA(ptr, &id->rsa);
+ case TPM2_ALG_ECC:
+ return unpack_TPMS_ECC_POINT(ptr, &id->ecc);
+ }
+ assert(false);
+ return NULL;
+}
+
+inline BYTE* pack_TPMT_PUBLIC(BYTE* ptr, const TPMT_PUBLIC *public)
+{
+ ptr = pack_TPMI_ALG_PUBLIC(ptr, &public->type);
+ ptr = pack_TPMI_ALG_HASH(ptr, &public->nameAlg);
+ ptr = pack_TPMA_OBJECT(ptr, &public->objectAttributes);
+ ptr = pack_TPM2B_DIGEST(ptr, &public->authPolicy);
+ ptr = pack_TPMU_PUBLIC_PARMS(ptr, &public->parameters, &public->type);
+ ptr = pack_TPMU_PUBLIC_ID(ptr, &public->unique, &public->type);
+ return ptr;
+}
+
+inline BYTE* unpack_TPMT_PUBLIC(BYTE* ptr, TPMT_PUBLIC *public)
+{
+ ptr = unpack_TPMI_ALG_PUBLIC(ptr, &public->type);
+ ptr = unpack_TPMI_ALG_HASH(ptr, &public->nameAlg);
+ ptr = unpack_TPMA_OBJECT(ptr, &public->objectAttributes);
+ ptr = unpack_TPM2B_DIGEST(ptr, &public->authPolicy);
+ ptr = unpack_TPMU_PUBLIC_PARMS(ptr, &public->parameters, &public->type);
+ ptr = unpack_TPMU_PUBLIC_ID(ptr, &public->unique, &public->type);
+ return ptr;
+}
+
+inline BYTE* pack_TPM2B_PUBLIC(BYTE* ptr, const TPM2B_PUBLIC *public)
+{
+ BYTE *sizePtr = ptr;
+ ptr += 2;
+ ptr = pack_TPMT_PUBLIC(ptr, &public->publicArea);
+ pack_UINT16(sizePtr, (UINT16)(ptr - sizePtr - 2));
+ return ptr;
+}
+
+inline BYTE* unpack_TPM2B_PUBLIC(BYTE* ptr, TPM2B_PUBLIC *public)
+{
+ ptr = unpack_UINT16(ptr, &public->size);
+ ptr = unpack_TPMT_PUBLIC(ptr, &public->publicArea);
+ return ptr;
+}
+
+inline BYTE* pack_TPMS_PCR_SELECTION(BYTE* ptr, const TPMS_PCR_SELECTION *selection)
+{
+ ptr = pack_TPMI_ALG_HASH(ptr, &selection->hash);
+ ptr = pack_BYTE(ptr, selection->sizeofSelect);
+ ptr = pack_BYTE_ARRAY(ptr, selection->pcrSelect, selection->sizeofSelect);
+ return ptr;
+}
+
+inline BYTE* pack_TPMS_PCR_SELECTION_Array(BYTE* ptr, const TPMS_PCR_SELECTION *selections,
+ const UINT32 cnt)
+{
+ int i;
+ for (i = 0; i < cnt; i++)
+ ptr = pack_TPMS_PCR_SELECTION(ptr, selections + i);
+ return ptr;
+}
+
+inline BYTE* pack_TPM_AuthArea(BYTE* ptr, const TPM_AuthArea *auth)
+{
+ BYTE* sizePtr = ptr;
+ ptr += sizeof(UINT32);
+ ptr = pack_TPM_RH(ptr, &auth->sessionHandle);
+ ptr = pack_TPM2B_NONCE(ptr, &auth->nonce);
+ ptr = pack_TPMA_SESSION(ptr, &auth->sessionAttributes);
+ ptr = pack_TPM2B_AUTH(ptr, &auth->auth);
+ pack_UINT32(sizePtr, ptr - sizePtr - sizeof(UINT32));
+ return ptr;
+}
+
+inline BYTE* unpack_TPM_AuthArea(BYTE* ptr, TPM_AuthArea *auth)
+{
+ ptr = unpack_UINT32(ptr, &auth->size);
+ ptr = unpack_TPM_RH(ptr, &auth->sessionHandle);
+ ptr = unpack_TPM2B_NONCE(ptr, &auth->nonce);
+ ptr = unpack_TPMA_SESSION(ptr, &auth->sessionAttributes);
+ ptr = unpack_TPM2B_AUTH(ptr, &auth->auth);
+ return ptr;
+}
+
+inline BYTE* pack_TPM2_RSA_KEY(BYTE* ptr, const TPM2_RSA_KEY *key)
+{
+ ptr = pack_TPM2B_PRIVATE(ptr, &key->Private);
+ ptr = pack_TPM2B_PUBLIC(ptr, &key->Public);
+ return ptr;
+}
+
+inline BYTE* unpack_TPM2_RSA_KEY(BYTE* ptr, TPM2_RSA_KEY *key)
+{
+ ptr = unpack_TPM2B_PRIVATE(ptr, &key->Private);
+ ptr = unpack_TPM2B_PUBLIC(ptr, &key->Public);
+ return ptr;
+}
+#endif