/
githubmirror
/
libtpms
Обзор
Документация
Войти
/
githubmirror
/
libtpms
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/tpm2/BackwardsCompatibilityObject.c
574 строки
22 KB
Stefan Berger
tpm2: Reformat some libtpms code with clang-format from 'upstream'
09 мар 2026, 17:10
09 мар 2026, 17:10
bc4d5e8
Код
Авторство
О чём код?
// SPDX-License-Identifier: BSD-2-Clause // (c) Copyright IBM Corporation 2017-2026 #include <assert.h> #include "BackwardsCompatibilityObject.h" MUST_BE(offsetof(TPMU_NAME, digest.digest) == 2); MUST_BE(sizeof(TPMU_NAME) == 2 + 64 + 2 /*!*/); MUST_BE(sizeof(TPM2B_NAME) == 2 + 64 + 2 + 2); MUST_BE(sizeof(TPM2B_DIGEST) == 2 + 64); MUST_BE(sizeof(TPM2B_NAME) == 2 + 64 + 2 + 2); MUST_BE(sizeof(TPM2B_DIGEST) == 2 + 64); #ifdef ARCH_NEEDS_INT_PADDING MUST_BE(sizeof(TPMU_PUBLIC_PARMS) == 20); #endif /* The following are data structure from libtpms 0.7.x with RSA 2048 support * that help to resume key and hash contexts (TPM2_ContextSave/Load) from this * earlier version. All structures that have different sizes in 0.8 are found * here. * * The functions RSA3072_OBJECT_Buffer_To_OBJECT and * RSA2048_OBJECT_Buffer_to_OBJECT fill an old 2048/3072 OBJECT data structure * by directly copying from a byte array into this data structure. Since data * structure are supposed to be interchangeable between architectures (at least * if they have the same endianess in this case) the fields in the OBJECT must * be located at the same offsets. This is the reason why there are paddings * in some data structures for architectures where the compiler does not pad * automatically as expected (m68k). */ typedef union { struct { UINT16 size; BYTE buffer[2048 / 8]; } t; TPM2B b; } RSA2048_TPM2B_PUBLIC_KEY_RSA; MUST_BE(sizeof(RSA2048_TPM2B_PUBLIC_KEY_RSA) == 2 + 2048 / 8); typedef union { TPM2B_DIGEST keyedHash; TPM2B_DIGEST sym; RSA2048_TPM2B_PUBLIC_KEY_RSA rsa; TPMS_ECC_POINT ecc; // TPMS_DERIVE derive; } RSA2048_TPMU_PUBLIC_ID; MUST_BE(sizeof(RSA2048_TPMU_PUBLIC_ID) == 2 + 2048 / 8); MUST_BE(sizeof(TPMS_ECC_POINT) == 2 * (2 + MAX_ECC_KEY_BYTES)); typedef struct { TPMI_ALG_PUBLIC type; TPMI_ALG_HASH nameAlg; TPMA_OBJECT objectAttributes; TPM2B_DIGEST authPolicy; ARCH_PADDING(pad1, 2); TPMU_PUBLIC_PARMS parameters; RSA2048_TPMU_PUBLIC_ID unique; ARCH_PADDING(pad2, 2); } RSA2048_TPMT_PUBLIC; MUST_BE(offsetof(RSA2048_TPMT_PUBLIC, nameAlg) == 2); MUST_BE(offsetof(RSA2048_TPMT_PUBLIC, objectAttributes) == 2 + 2); MUST_BE(offsetof(RSA2048_TPMT_PUBLIC, authPolicy) == 2 + 2 + 4); MUST_BE(offsetof(RSA2048_TPMT_PUBLIC, parameters) == 2 + 2 + 4 + 66 + 2 /*!*/); MUST_BE(offsetof(RSA2048_TPMT_PUBLIC, unique) == 2 + 2 + 4 + 66 + 2 + 20); MUST_BE(sizeof(RSA2048_TPMT_PUBLIC) == 356); typedef union { struct { UINT16 size; BYTE buffer[((2048 / 8) / 2) * 5]; } t; TPM2B b; } RSA2048_TPM2B_PRIVATE_KEY_RSA; MUST_BE(sizeof(RSA2048_TPM2B_PRIVATE_KEY_RSA) == 642); typedef union { struct { UINT16 size; BYTE buffer[((2048 / 8) / 2) * 5]; } t; TPM2B b; } RSA2048_TPM2B_PRIVATE_VENDOR_SPECIFIC; typedef union { RSA2048_TPM2B_PRIVATE_KEY_RSA rsa; TPM2B_ECC_PARAMETER ecc; TPM2B_SENSITIVE_DATA bits; TPM2B_SYM_KEY sym; RSA2048_TPM2B_PRIVATE_VENDOR_SPECIFIC any; } RSA2048_TPMU_SENSITIVE_COMPOSITE; typedef struct { TPMI_ALG_PUBLIC sensitiveType; TPM2B_AUTH authValue; TPM2B_DIGEST seedValue; RSA2048_TPMU_SENSITIVE_COMPOSITE sensitive; } RSA2048_TPMT_SENSITIVE; MUST_BE(offsetof(RSA2048_TPMT_SENSITIVE, authValue) == 2); MUST_BE(offsetof(RSA2048_TPMT_SENSITIVE, seedValue) == 2 + 66); MUST_BE(offsetof(RSA2048_TPMT_SENSITIVE, sensitive) == 2 + 66 + 66); MUST_BE(sizeof(RSA2048_TPMT_SENSITIVE) == 776); BN_TYPE(old_prime, (2048 / 2)); typedef struct RSA2048_privateExponent { bn_old_prime_t Q; bn_old_prime_t dP; bn_old_prime_t dQ; bn_old_prime_t qInv; } RSA2048_privateExponent_t; static inline void CopyFromOldPrimeT(ci_prime_t* dst, const bn_old_prime_t* src) { dst->allocated = src->allocated; dst->size = src->size; memcpy(dst->d, src->d, sizeof(src->d)); } MUST_BE(sizeof(RSA2048_privateExponent_t) == 608); typedef struct RSA2048_OBJECT { // The attributes field is required to be first followed by the publicArea. // This allows the overlay of the object structure and a sequence structure OBJECT_ATTRIBUTES attributes; // object attributes RSA2048_TPMT_PUBLIC publicArea; // public area of an object RSA2048_TPMT_SENSITIVE sensitive; // sensitive area of an object RSA2048_privateExponent_t privateExponent; // Additional field for the private TPM2B_NAME qualifiedName; // object qualified name ARCH_PADDING(pad1, 2); TPMI_DH_OBJECT evictHandle; // if the object is an evict object, // the original handle is kept here. // The 'working' handle will be the // handle of an object slot. TPM2B_NAME name; // Name of the object name. Kept here // to avoid repeatedly computing it. ARCH_PADDING(pad2, 2); // libtpms added: OBJECT lies in NVRAM; to avoid that it needs different number // of bytes on 32 bit and 64 bit architectures, we need to make sure it's the // same size; simple padding at the end works here UINT32 _pad; } RSA2048_OBJECT; MUST_BE(sizeof(OBJECT_ATTRIBUTES) == 4); MUST_BE(offsetof(RSA2048_OBJECT, publicArea) == 4); MUST_BE(offsetof(RSA2048_OBJECT, sensitive) == 4 + 356); MUST_BE(offsetof(RSA2048_OBJECT, privateExponent) == 4 + 356 + 776); MUST_BE(offsetof(RSA2048_OBJECT, qualifiedName) == 4 + 356 + 776 + 608); MUST_BE(offsetof(RSA2048_OBJECT, evictHandle) == 4 + 356 + 776 + 608 + 68 + 4); MUST_BE(offsetof(RSA2048_OBJECT, name) == 4 + 356 + 776 + 608 + 68 + 4 + 4); MUST_BE(sizeof(RSA2048_OBJECT) == 1896); TPMI_RH_HIERARCHY ObjectGetHierarchyFromAttributes(OBJECT* object) { if(object->attributes.spsHierarchy) return TPM_RH_OWNER; if(object->attributes.epsHierarchy) return TPM_RH_ENDORSEMENT; if(object->attributes.ppsHierarchy) return TPM_RH_PLATFORM; return TPM_RH_NULL; } static void RSA2048_OBJECT_To_OBJECT(OBJECT* dest, const RSA2048_OBJECT* src) { dest->attributes = src->attributes; dest->hierarchy = ObjectGetHierarchyFromAttributes(dest); dest->publicArea.type = src->publicArea.type; dest->publicArea.nameAlg = src->publicArea.nameAlg; dest->publicArea.objectAttributes = src->publicArea.objectAttributes; dest->publicArea.authPolicy = src->publicArea.authPolicy; dest->publicArea.parameters = src->publicArea.parameters; /* the unique part can be one or two TPM2B's */ switch(dest->publicArea.type) { case TPM_ALG_KEYEDHASH: MemoryCopy2B(&dest->publicArea.unique.keyedHash.b, &src->publicArea.unique.keyedHash.b, sizeof(src->publicArea.unique.keyedHash.t.buffer)); memset(&dest->privateExponent, 0, sizeof(dest->privateExponent)); break; case TPM_ALG_SYMCIPHER: MemoryCopy2B(&dest->publicArea.unique.sym.b, &src->publicArea.unique.sym.b, sizeof(src->publicArea.unique.sym.t.buffer)); memset(&dest->privateExponent, 0, sizeof(dest->privateExponent)); break; case TPM_ALG_RSA: MemoryCopy2B(&dest->publicArea.unique.rsa.b, &src->publicArea.unique.rsa.b, sizeof(src->publicArea.unique.rsa.t.buffer)); CopyFromOldPrimeT(&dest->privateExponent.Q, &src->privateExponent.Q); CopyFromOldPrimeT(&dest->privateExponent.dP, &src->privateExponent.dP); CopyFromOldPrimeT(&dest->privateExponent.dQ, &src->privateExponent.dQ); CopyFromOldPrimeT(&dest->privateExponent.qInv, &src->privateExponent.qInv); break; case TPM_ALG_ECC: MemoryCopy2B(&dest->publicArea.unique.ecc.x.b, &src->publicArea.unique.ecc.x.b, sizeof(src->publicArea.unique.ecc.x.t.buffer)); MemoryCopy2B(&dest->publicArea.unique.ecc.y.b, &src->publicArea.unique.ecc.y.b, sizeof(src->publicArea.unique.ecc.y.t.buffer)); memset(&dest->privateExponent, 0, sizeof(dest->privateExponent)); break; } dest->sensitive.sensitiveType = src->sensitive.sensitiveType; dest->sensitive.authValue = src->sensitive.authValue; dest->sensitive.seedValue = src->sensitive.seedValue; /* The RSA2048_TPMU_SENSITIVE_COMPOSITE is always a TPM2B */ MemoryCopy2B(&dest->sensitive.sensitive.any.b, &src->sensitive.sensitive.any.b, sizeof(src->sensitive.sensitive.any.t.buffer)); dest->qualifiedName = src->qualifiedName; dest->evictHandle = src->evictHandle; dest->name = src->name; } // Convert an RSA2048_OBJECT that was copied into buffer using MemoryCopy TPM_RC RSA2048_OBJECT_Buffer_To_OBJECT(OBJECT* newObject, BYTE* buffer, INT32 size) { RSA2048_OBJECT oldObject; TPM_RC rc = 0; // get the attributes MemoryCopy(newObject, buffer, sizeof(newObject->attributes)); if(ObjectIsSequence(newObject)) { /* resuming old hash contexts is not supported */ rc = TPM_RC_DISABLED; } else { if(size != sizeof(RSA2048_OBJECT)) return TPM_RC_SIZE; MemoryCopy(&oldObject, buffer, sizeof(RSA2048_OBJECT)); /* fill the newObject with the contents of the oldObject */ RSA2048_OBJECT_To_OBJECT(newObject, &oldObject); } return rc; } /* The following are data structure from libtpms 0.9.x with RSA 3072 support. */ typedef union { struct { UINT16 size; BYTE buffer[3072 / 8]; } t; TPM2B b; } RSA3072_TPM2B_PUBLIC_KEY_RSA; MUST_BE(sizeof(RSA3072_TPM2B_PUBLIC_KEY_RSA) == 2 + 3072 / 8); typedef union { TPM2B_DIGEST keyedHash; TPM2B_DIGEST sym; RSA3072_TPM2B_PUBLIC_KEY_RSA rsa; TPMS_ECC_POINT ecc; TPMS_DERIVE derive; } RSA3072_TPMU_PUBLIC_ID; MUST_BE(sizeof(TPM2B_DIGEST) == 2 + BITS_TO_BYTES(512)); MUST_BE(sizeof(TPMS_ECC_POINT) == 2 * (2 + BITS_TO_BYTES(638))); MUST_BE(sizeof(TPMS_DERIVE) == 2 * (2 + 32)); MUST_BE(sizeof(RSA3072_TPMU_PUBLIC_ID) == 2 + 3072 / 8); typedef struct { TPMI_ALG_PUBLIC type; TPMI_ALG_HASH nameAlg; TPMA_OBJECT objectAttributes; TPM2B_DIGEST authPolicy; ARCH_PADDING(pad1, 2); TPMU_PUBLIC_PARMS parameters; RSA3072_TPMU_PUBLIC_ID unique; ARCH_PADDING(pad2, 2); } RSA3072_TPMT_PUBLIC; MUST_BE(offsetof(RSA3072_TPMT_PUBLIC, nameAlg) == 2); MUST_BE(offsetof(RSA3072_TPMT_PUBLIC, objectAttributes) == 2 + 2); MUST_BE(offsetof(RSA3072_TPMT_PUBLIC, authPolicy) == 2 + 2 + 4); MUST_BE(offsetof(RSA3072_TPMT_PUBLIC, parameters) == 2 + 2 + 4 + 66 + 2 /*!*/); MUST_BE(offsetof(RSA3072_TPMT_PUBLIC, unique) == 2 + 2 + 4 + 66 + 2 + 20); MUST_BE(sizeof(RSA3072_TPMT_PUBLIC) == 484); typedef union { struct { UINT16 size; BYTE buffer[((3072 / 8) / 2) * 5]; } t; TPM2B b; } RSA3072_TPM2B_PRIVATE_KEY_RSA; MUST_BE(sizeof(RSA3072_TPM2B_PRIVATE_KEY_RSA) == 962); typedef union { struct { UINT16 size; BYTE buffer[((3072 / 8) / 2) * 5]; } t; TPM2B b; } RSA3072_TPM2B_PRIVATE_VENDOR_SPECIFIC; typedef union { RSA3072_TPM2B_PRIVATE_KEY_RSA rsa; TPM2B_ECC_PARAMETER ecc; TPM2B_SENSITIVE_DATA bits; TPM2B_SYM_KEY sym; RSA3072_TPM2B_PRIVATE_VENDOR_SPECIFIC any; } RSA3072_TPMU_SENSITIVE_COMPOSITE; MUST_BE(sizeof(TPM2B_ECC_PARAMETER) == 2 + BITS_TO_BYTES(638) /* BN P638 */); MUST_BE(sizeof(TPM2B_SENSITIVE_DATA) == 2 + 128); MUST_BE(sizeof(TPM2B_SYM_KEY) == 2 + BITS_TO_BYTES(256)); typedef struct { TPMI_ALG_PUBLIC sensitiveType; TPM2B_AUTH authValue; TPM2B_DIGEST seedValue; RSA3072_TPMU_SENSITIVE_COMPOSITE sensitive; } RSA3072_TPMT_SENSITIVE; MUST_BE(sizeof(TPM2B_AUTH) == 2 + BITS_TO_BYTES(512)); MUST_BE(sizeof(TPM2B_DIGEST) == 2 + BITS_TO_BYTES(512)); MUST_BE(sizeof(RSA3072_TPMT_SENSITIVE) == 1096); BN_TYPE(rsa3072_prime, (3072 / 2)); typedef struct RSA3072_privateExponent { bn_rsa3072_prime_t Q; bn_rsa3072_prime_t dP; bn_rsa3072_prime_t dQ; bn_rsa3072_prime_t qInv; } RSA3072_privateExponent_t; MUST_BE(offsetof(RSA3072_privateExponent_t, dP) == 216); MUST_BE(offsetof(RSA3072_privateExponent_t, dQ) == 216 + 216); MUST_BE(offsetof(RSA3072_privateExponent_t, qInv) == 216 + 216 + 216); MUST_BE(sizeof(RSA3072_privateExponent_t) == 864); typedef struct RSA3072_OBJECT { // The attributes field is required to be first followed by the publicArea. // This allows the overlay of the object structure and a sequence structure OBJECT_ATTRIBUTES attributes; // object attributes RSA3072_TPMT_PUBLIC publicArea; // public area of an object RSA3072_TPMT_SENSITIVE sensitive; // sensitive area of an object #if 1 // libtpms added begin: keep RSA3072_privateExponent_t privateExponent; // Additional field for the private #endif // libtpms added end TPM2B_NAME qualifiedName; // object qualified name ARCH_PADDING(pad1, 2); TPMI_DH_OBJECT evictHandle; // if the object is an evict object, // the original handle is kept here. // The 'working' handle will be the // handle of an object slot. TPM2B_NAME name; // Name of the object name. Kept here // to avoid repeatedly computing it. // libtpms added: SEED_COMPAT_LEVEL to use for deriving child keys SEED_COMPAT_LEVEL seedCompatLevel; // libtpms added: OBJECT lies in NVRAM; to avoid that it needs different number // of bytes on 32 bit and 64 bit architectures, we need to make sure it's the // same size; simple padding at the end works here UINT8 _pad[3]; ARCH_PADDING(pad2, 2); } RSA3072_OBJECT; MUST_BE(sizeof(OBJECT_ATTRIBUTES) == 4); MUST_BE(offsetof(RSA3072_OBJECT, publicArea) == 4); MUST_BE(offsetof(RSA3072_OBJECT, sensitive) == 4 + 484); MUST_BE(offsetof(RSA3072_OBJECT, privateExponent) == 4 + 484 + 1096); MUST_BE(offsetof(RSA3072_OBJECT, qualifiedName) == 4 + 484 + 1096 + 864); MUST_BE(offsetof(RSA3072_OBJECT, evictHandle) == 4 + 484 + 1096 + 864 + 68 + 4); MUST_BE(offsetof(RSA3072_OBJECT, name) == 4 + 484 + 1096 + 864 + 68 + 4 + 4); MUST_BE(offsetof(RSA3072_OBJECT, seedCompatLevel) == 4 + 484 + 1096 + 864 + 68 + 4 + 4 + 70); MUST_BE(offsetof(RSA3072_OBJECT, _pad) == 4 + 484 + 1096 + 864 + 68 + 4 + 4 + 70 + 1); MUST_BE(sizeof(RSA3072_OBJECT) == 2600); static inline void CopyFromRSA3072PrimeT(ci_prime_t* dst, const bn_rsa3072_prime_t* src) { dst->allocated = src->allocated; dst->size = src->size; memcpy(dst->d, src->d, sizeof(src->d)); } static inline void CopyToRSA3072PrimeT(bn_rsa3072_prime_t* dst, const ci_prime_t* src) { dst->allocated = src->allocated; dst->size = src->size; memcpy(dst->d, src->d, sizeof(dst->d)); } static void RSA3072_OBJECT_To_OBJECT(OBJECT* dest, const RSA3072_OBJECT* src) { dest->attributes = src->attributes; dest->hierarchy = ObjectGetHierarchyFromAttributes(dest); dest->publicArea.type = src->publicArea.type; dest->publicArea.nameAlg = src->publicArea.nameAlg; dest->publicArea.objectAttributes = src->publicArea.objectAttributes; dest->publicArea.authPolicy = src->publicArea.authPolicy; dest->publicArea.parameters = src->publicArea.parameters; /* the unique part can be one or two TPM2B's */ switch(dest->publicArea.type) { case TPM_ALG_KEYEDHASH: MemoryCopy2B(&dest->publicArea.unique.keyedHash.b, &src->publicArea.unique.keyedHash.b, sizeof(src->publicArea.unique.keyedHash.t.buffer)); memset(&dest->privateExponent, 0, sizeof(dest->privateExponent)); break; case TPM_ALG_SYMCIPHER: MemoryCopy2B(&dest->publicArea.unique.sym.b, &src->publicArea.unique.sym.b, sizeof(src->publicArea.unique.sym.t.buffer)); memset(&dest->privateExponent, 0, sizeof(dest->privateExponent)); break; case TPM_ALG_RSA: MemoryCopy2B(&dest->publicArea.unique.rsa.b, &src->publicArea.unique.rsa.b, sizeof(src->publicArea.unique.rsa.t.buffer)); CopyFromRSA3072PrimeT(&dest->privateExponent.Q, &src->privateExponent.Q); CopyFromRSA3072PrimeT(&dest->privateExponent.dP, &src->privateExponent.dP); CopyFromRSA3072PrimeT(&dest->privateExponent.dQ, &src->privateExponent.dQ); CopyFromRSA3072PrimeT(&dest->privateExponent.qInv, &src->privateExponent.qInv); break; case TPM_ALG_ECC: MemoryCopy2B(&dest->publicArea.unique.ecc.x.b, &src->publicArea.unique.ecc.x.b, sizeof(src->publicArea.unique.ecc.x.t.buffer)); MemoryCopy2B(&dest->publicArea.unique.ecc.y.b, &src->publicArea.unique.ecc.y.b, sizeof(src->publicArea.unique.ecc.y.t.buffer)); memset(&dest->privateExponent, 0, sizeof(dest->privateExponent)); break; } dest->sensitive.sensitiveType = src->sensitive.sensitiveType; dest->sensitive.authValue = src->sensitive.authValue; dest->sensitive.seedValue = src->sensitive.seedValue; /* The OLD_TPMU_SENSITIVE_COMPOSITE is always a TPM2B */ MemoryCopy2B(&dest->sensitive.sensitive.any.b, &src->sensitive.sensitive.any.b, sizeof(src->sensitive.sensitive.any.t.buffer)); dest->qualifiedName = src->qualifiedName; dest->evictHandle = src->evictHandle; dest->name = src->name; dest->seedCompatLevel = src->seedCompatLevel; } /* Convert an OBJECT to the (smaller) RSA3072_OBJECT. */ static void OBJECT_To_RSA3072_OBJECT(RSA3072_OBJECT* dest, const OBJECT* src) { dest->attributes = src->attributes; dest->publicArea.type = src->publicArea.type; dest->publicArea.nameAlg = src->publicArea.nameAlg; dest->publicArea.objectAttributes = src->publicArea.objectAttributes; dest->publicArea.authPolicy = src->publicArea.authPolicy; dest->publicArea.parameters = src->publicArea.parameters; /* the unique part can be one or two TPM2B's */ switch(dest->publicArea.type) { case TPM_ALG_KEYEDHASH: MemoryCopy2B(&dest->publicArea.unique.keyedHash.b, &src->publicArea.unique.keyedHash.b, sizeof(dest->publicArea.unique.keyedHash.t.buffer)); break; case TPM_ALG_SYMCIPHER: MemoryCopy2B(&dest->publicArea.unique.sym.b, &src->publicArea.unique.sym.b, sizeof(dest->publicArea.unique.sym.t.buffer)); break; case TPM_ALG_RSA: MemoryCopy2B(&dest->publicArea.unique.rsa.b, &src->publicArea.unique.rsa.b, sizeof(dest->publicArea.unique.rsa.t.buffer)); CopyToRSA3072PrimeT(&dest->privateExponent.Q, &src->privateExponent.Q); CopyToRSA3072PrimeT(&dest->privateExponent.dP, &src->privateExponent.dP); CopyToRSA3072PrimeT(&dest->privateExponent.dQ, &src->privateExponent.dQ); CopyToRSA3072PrimeT(&dest->privateExponent.qInv, &src->privateExponent.qInv); break; case TPM_ALG_ECC: MemoryCopy2B(&dest->publicArea.unique.ecc.x.b, &src->publicArea.unique.ecc.x.b, sizeof(dest->publicArea.unique.ecc.x.t.buffer)); MemoryCopy2B(&dest->publicArea.unique.ecc.y.b, &src->publicArea.unique.ecc.y.b, sizeof(dest->publicArea.unique.ecc.y.t.buffer)); break; } dest->sensitive.sensitiveType = src->sensitive.sensitiveType; dest->sensitive.authValue = src->sensitive.authValue; dest->sensitive.seedValue = src->sensitive.seedValue; /* The OLD_TPMU_SENSITIVE_COMPOSITE is always a TPM2B */ MemoryCopy2B(&dest->sensitive.sensitive.any.b, &src->sensitive.sensitive.any.b, sizeof(dest->sensitive.sensitive.any.t.buffer)); dest->qualifiedName = src->qualifiedName; dest->evictHandle = src->evictHandle; dest->name = src->name; dest->seedCompatLevel = src->seedCompatLevel; MemorySet(dest->_pad, 0, sizeof(dest->_pad)); } TPM_RC RSA3072_OBJECT_Buffer_To_OBJECT(OBJECT* object, BYTE* buffer, INT32 size) { RSA3072_OBJECT rsa3072_object; if(size != sizeof(RSA3072_OBJECT)) return TPM_RC_SIZE; MemoryCopy(&rsa3072_object, buffer, size); RSA3072_OBJECT_To_OBJECT(object, &rsa3072_object); return 0; } UINT32 OBJECT_To_Buffer_As_RSA3072_OBJECT(OBJECT* object, BYTE* buffer, UINT32 size) { RSA3072_OBJECT rsa3072_object; UINT32 written = sizeof(rsa3072_object); OBJECT_To_RSA3072_OBJECT(&rsa3072_object, object); pAssert(size >= sizeof(rsa3072_object)); MemoryCopy(buffer, &rsa3072_object, sizeof(rsa3072_object)); return written; }