diff --git a/libtpms.spec b/libtpms.spec index d5949da6820cf96dc998abe15c89110a1ccb422e..31b29d0ce375bc9abe2545bd750f33c690ff1f99 100644 --- a/libtpms.spec +++ b/libtpms.spec @@ -6,7 +6,7 @@ %define name libtpms %define versionx 0.7.3 -%define release 4 +%define release 7 # Valid crypto subsystems are 'freebl' and 'openssl' %if "%{?crypto_subsystem}" == "" @@ -19,14 +19,14 @@ Summary: Library providing Trusted Platform Module (TPM) functionality Name: %{name} Version: %{versionx} -Release: 4 +Release: %{release} License: BSD Group: Development/Libraries Url: http://github.com/stefanberger/libtpms Source0: %{url}/archive/%{gitcommit}/%{name}-%{gitshortcommit}.tar.gz Provides: libtpms-%{crypto_subsystem} = %{version}-%{release} -Patch0: 0001-tpm2-CryptSym-fix-AES-output-IV.patch +Patch0: tpm2-CryptSym-fix-AES-output-IV.patch Patch1: tpm2-Add-SEED_COMPAT_LEVEL-to-seeds-in.patch Patch2: tpm2-Add-SEED_COMPAT_LEVEL-to-nullSeed-to-track-comp.patch Patch3: tpm2-Add-SEED_COMPAT_LEVEL-to-DRBG-state.patch @@ -34,6 +34,12 @@ Patch4: tpm2-rev155-Add-new-RsaAdjustPrimeCandidate-code.patch Patch5: tpm2-Introduce-SEED_COMPAT_LEVEL_RSA_PRIME_ADJUST_FI.patch Patch6: tpm2-Pass-SEED_COMPAT_LEVEL-to-CryptAdjustPrimeCandi.patch Patch7: tpm2-Activate-SEED_COMPAT_LEVEL_RSA_PRIME_ADJUST_FIX.patch +Patch8: tpm2-Initialize-a-whole-OBJECT-before-using-it.patch +Patch9: tpm2-Fix-issue-with-misaligned-address-when-marshall.patch +Patch10: tpm2-NVMarshal-Handle-index-orderly-RAM-without-0-si.patch +Patch11: tpm2-Reset-TPM2B-buffer-sizes-after-test-fails-for-v.patch +Patch12: tpm2-Add-maxSize-parameter-to-TPM2B_Marshal-for-sani.patch +Patch13: tpm2-Restore-original-value-if-unmarsalled-value-was.patch %if "%{crypto_subsystem}" == "openssl" BuildRequires: openssl-devel @@ -92,11 +98,11 @@ Libtpms header files and documentation. %define _with_openssl --with-openssl %endif -%if %{build_type} == debug +%if "%{build_type}" == "debug" %define _enable_debug --enable-debug %endif -%if %{build_type} == debug +%if "%{build_type}" == "debug" CFLAGS=-O0 %endif ./autogen.sh \ @@ -126,6 +132,21 @@ rm -f $RPM_BUILD_ROOT%{_libdir}/libtpms.la %postun -p /sbin/ldconfig %changelog +* Wed May 18 2022 yezengruan - 0.7.3-7 +- tpm2: Reset TPM2B buffer sizes after test fails for valid buffer size +- tpm2: Add maxSize parameter to TPM2B_Marshal for sanity checks +- tpm2: Restore original value if unmarsalled value was illegal +- fix CVE-2021-3623 + +* Mon Feb 14 2022 imxcc - 0.7.3-6 +- fix bare word "debug" in spec + +* Wed Nov 10 2021 jiangfangjie - 0.7.3-5 +-TYPE: CVE +-ID:NA +-ID:NA +-DESC: fix CVE-2021-3746 + * Tue May 11 2021 jiangfangjie - 0.7.3-4 -TYPE: CVE -ID:NA @@ -139,7 +160,7 @@ rm -f $RPM_BUILD_ROOT%{_libdir}/libtpms.la - DESC: fix CVE-2021-3446 * Mon Sep 14 2020 jiangfangjie - 0.7.3-2 -- update spec file including source0 and update source file +- update spec file including source0 and update source file * Fri Aug 21 2020 jiangfangjie - 0.7.3-1 - Package init diff --git a/tpm2-Add-maxSize-parameter-to-TPM2B_Marshal-for-sani.patch b/tpm2-Add-maxSize-parameter-to-TPM2B_Marshal-for-sani.patch new file mode 100644 index 0000000000000000000000000000000000000000..082de0f6e58c03fc70a94cddb5f59979cc7bfb2c --- /dev/null +++ b/tpm2-Add-maxSize-parameter-to-TPM2B_Marshal-for-sani.patch @@ -0,0 +1,267 @@ +From 4ef9469ef6ba45a8628061d94bd21cee6e29b5e1 Mon Sep 17 00:00:00 2001 +From: Stefan Berger +Date: Mon, 21 Jun 2021 15:10:14 -0400 +Subject: [PATCH 2/3] tpm2: Add maxSize parameter to TPM2B_Marshal for sanity + checks + +Add maxSize parameter to TPM2B_Marshal and assert on it checking +the size of the data intended to be marshaled versus the maximum +buffer size. + +Signed-off-by: Stefan Berger +--- + src/tpm2/Marshal.c | 38 ++++++++++++++++++++------------------ + src/tpm2/Marshal_fp.h | 2 +- + src/tpm2/NVMarshal.c | 18 +++++++++--------- + 3 files changed, 30 insertions(+), 28 deletions(-) + +diff --git a/src/tpm2/Marshal.c b/src/tpm2/Marshal.c +index f97243e..39e69e4 100644 +--- a/src/tpm2/Marshal.c ++++ b/src/tpm2/Marshal.c +@@ -61,6 +61,7 @@ + + /* rev 136 */ + ++#include // libtpms added + #include + + #include "Tpm.h" +@@ -178,9 +179,10 @@ Array_Marshal(BYTE *sourceBuffer, UINT16 sourceSize, BYTE **buffer, INT32 *size) + } + + UINT16 +-TPM2B_Marshal(TPM2B *source, BYTE **buffer, INT32 *size) ++TPM2B_Marshal(TPM2B *source, UINT32 maxSize, BYTE **buffer, INT32 *size) + { + UINT16 written = 0; ++ assert(source->size <= maxSize); // libtpms added + written += UINT16_Marshal(&(source->size), buffer, size); + written += Array_Marshal(source->buffer, source->size, buffer, size); + return written; +@@ -495,7 +497,7 @@ UINT16 + TPM2B_DIGEST_Marshal(TPM2B_DIGEST *source, BYTE **buffer, INT32 *size) + { + UINT16 written = 0; +-written += TPM2B_Marshal(&source->b, buffer, size); ++written += TPM2B_Marshal(&source->b, sizeof(source->t.buffer), buffer, size); // libtpms changed + return written; + } + +@@ -505,7 +507,7 @@ UINT16 + TPM2B_DATA_Marshal(TPM2B_DATA *source, BYTE **buffer, INT32 *size) + { + UINT16 written = 0; +-written += TPM2B_Marshal(&source->b, buffer, size); ++written += TPM2B_Marshal(&source->b, sizeof(source->t.buffer), buffer, size); // libtpms changed + return written; + } + +@@ -535,7 +537,7 @@ UINT16 + TPM2B_MAX_BUFFER_Marshal(TPM2B_MAX_BUFFER *source, BYTE **buffer, INT32 *size) + { + UINT16 written = 0; +- written += TPM2B_Marshal(&source->b, buffer, size); ++ written += TPM2B_Marshal(&source->b, sizeof(source->t.buffer), buffer, size); // libtpms changed + return written; + } + +@@ -545,7 +547,7 @@ UINT16 + TPM2B_MAX_NV_BUFFER_Marshal(TPM2B_MAX_NV_BUFFER *source, BYTE **buffer, INT32 *size) + { + UINT16 written = 0; +- written += TPM2B_Marshal(&source->b, buffer, size); ++ written += TPM2B_Marshal(&source->b, sizeof(source->t.buffer), buffer, size); // libtpms changed + return written; + } + +@@ -554,7 +556,7 @@ UINT16 + TPM2B_TIMEOUT_Marshal(TPM2B_TIMEOUT *source, BYTE **buffer, INT32 *size) + { + UINT16 written = 0; +- written += TPM2B_Marshal(&source->b, buffer, size); ++ written += TPM2B_Marshal(&source->b, sizeof(source->t.buffer), buffer, size); // libtpms changed + return written; + } + +@@ -564,7 +566,7 @@ UINT16 + TPM2B_IV_Marshal(TPM2B_IV *source, BYTE **buffer, INT32 *size) + { + UINT16 written = 0; +- written += TPM2B_Marshal(&source->b, buffer, size); ++ written += TPM2B_Marshal(&source->b, sizeof(source->t.buffer), buffer, size); // libtpms changed + return written; + } + +@@ -574,7 +576,7 @@ UINT16 + TPM2B_NAME_Marshal(TPM2B_NAME *source, BYTE **buffer, INT32 *size) + { + UINT16 written = 0; +- written += TPM2B_Marshal(&source->b, buffer, size); ++ written += TPM2B_Marshal(&source->b, sizeof(source->t.name), buffer, size); // libtpms changed + return written; + } + +@@ -1111,7 +1113,7 @@ UINT16 + TPM2B_ATTEST_Marshal(TPM2B_ATTEST *source, BYTE **buffer, INT32 *size) + { + UINT16 written = 0; +- written += TPM2B_Marshal(&source->b, buffer, size); ++ written += TPM2B_Marshal(&source->b, sizeof(source->t.attestationData), buffer, size); // libtpms changed + return written; + } + +@@ -1232,7 +1234,7 @@ UINT16 + TPM2B_SYM_KEY_Marshal(TPM2B_SYM_KEY *source, BYTE **buffer, INT32 *size) + { + UINT16 written = 0; +- written += TPM2B_Marshal(&source->b, buffer, size); ++ written += TPM2B_Marshal(&source->b, sizeof(source->t.buffer), buffer, size); // libtpms changed + return written; + } + +@@ -1253,7 +1255,7 @@ UINT16 + TPM2B_SENSITIVE_DATA_Marshal(TPM2B_SENSITIVE_DATA *source, BYTE **buffer, INT32 *size) + { + UINT16 written = 0; +- written += TPM2B_Marshal(&source->b, buffer, size); ++ written += TPM2B_Marshal(&source->b, sizeof(source->t.buffer), buffer, size); // libtpms changed + return written; + } + +@@ -1613,7 +1615,7 @@ UINT16 + TPM2B_PUBLIC_KEY_RSA_Marshal(TPM2B_PUBLIC_KEY_RSA *source, BYTE **buffer, INT32 *size) + { + UINT16 written = 0; +- written += TPM2B_Marshal(&source->b, buffer, size); ++ written += TPM2B_Marshal(&source->b, sizeof(source->t.buffer), buffer, size); // libtpms changed + return written; + } + +@@ -1633,7 +1635,7 @@ UINT16 + TPM2B_PRIVATE_KEY_RSA_Marshal(TPM2B_PRIVATE_KEY_RSA *source, BYTE **buffer, INT32 *size) + { + UINT16 written = 0; +- written += TPM2B_Marshal(&source->b, buffer, size); ++ written += TPM2B_Marshal(&source->b, sizeof(source->t.buffer), buffer, size); // libtpms changed + return written; + } + +@@ -1643,7 +1645,7 @@ UINT16 + TPM2B_ECC_PARAMETER_Marshal(TPM2B_ECC_PARAMETER *source, BYTE **buffer, INT32 *size) + { + UINT16 written = 0; +- written += TPM2B_Marshal(&source->b, buffer, size); ++ written += TPM2B_Marshal(&source->b, sizeof(source->t.buffer), buffer, size); // libtpms changed + return written; + } + +@@ -1879,7 +1881,7 @@ UINT16 + TPM2B_ENCRYPTED_SECRET_Marshal(TPM2B_ENCRYPTED_SECRET *source, BYTE **buffer, INT32 *size) + { + UINT16 written = 0; +- written += TPM2B_Marshal(&source->b, buffer, size); ++ written += TPM2B_Marshal(&source->b, sizeof(source->t.secret), buffer, size); // libtpms changed + return written; + } + +@@ -2090,7 +2092,7 @@ UINT16 + TPM2B_PRIVATE_Marshal(TPM2B_PRIVATE *source, BYTE **buffer, INT32 *size) + { + UINT16 written = 0; +- written += TPM2B_Marshal(&source->b, buffer, size); ++ written += TPM2B_Marshal(&source->b, sizeof(source->t.buffer), buffer, size); // libtpms changed + return written; + } + +@@ -2100,7 +2102,7 @@ UINT16 + TPM2B_ID_OBJECT_Marshal(TPM2B_ID_OBJECT *source, BYTE **buffer, INT32 *size) + { + UINT16 written = 0; +- written += TPM2B_Marshal(&source->b, buffer, size); ++ written += TPM2B_Marshal(&source->b, sizeof(source->t.credential), buffer, size); // libtpms changed + return written; + } + +@@ -2157,7 +2159,7 @@ UINT16 + TPM2B_CONTEXT_DATA_Marshal(TPM2B_CONTEXT_DATA *source, BYTE **buffer, INT32 *size) + { + UINT16 written = 0; +- written += TPM2B_Marshal(&source->b, buffer, size); ++ written += TPM2B_Marshal(&source->b, sizeof(source->t.buffer), buffer, size); // libtpms changed + return written; + } + +diff --git a/src/tpm2/Marshal_fp.h b/src/tpm2/Marshal_fp.h +index 4471695..582cc9e 100644 +--- a/src/tpm2/Marshal_fp.h ++++ b/src/tpm2/Marshal_fp.h +@@ -79,7 +79,7 @@ extern "C" { + UINT16 + Array_Marshal(BYTE *sourceBuffer, UINT16 sourceSize, BYTE **buffer, INT32 *size); + UINT16 +- TPM2B_Marshal(TPM2B *source, BYTE **buffer, INT32 *size); ++ TPM2B_Marshal(TPM2B *source, UINT32 maxSize, BYTE **buffer, INT32 *size); // libtpms changed + UINT16 + TPM_KEY_BITS_Marshal(TPM_KEY_BITS *source, BYTE **buffer, INT32 *size); + UINT16 +diff --git a/src/tpm2/NVMarshal.c b/src/tpm2/NVMarshal.c +index 8f77fa2..40be17e 100644 +--- a/src/tpm2/NVMarshal.c ++++ b/src/tpm2/NVMarshal.c +@@ -278,7 +278,7 @@ UINT16 + TPM2B_PROOF_Marshal(TPM2B_PROOF *source, BYTE **buffer, INT32 *size) + { + UINT16 written = 0; +- written += TPM2B_Marshal(&source->b, buffer, size); ++ written += TPM2B_Marshal(&source->b, sizeof(source->t.buffer), buffer, size); + return written; + } + +@@ -1361,7 +1361,7 @@ STATE_RESET_DATA_Marshal(STATE_RESET_DATA *data, BYTE **buffer, INT32 *size) + STATE_RESET_DATA_VERSION, + STATE_RESET_DATA_MAGIC, 3); + written += TPM2B_PROOF_Marshal(&data->nullProof, buffer, size); +- written += TPM2B_Marshal(&data->nullSeed.b, buffer, size); ++ written += TPM2B_Marshal(&data->nullSeed.b, sizeof(data->nullSeed.t.buffer), buffer, size); + written += UINT32_Marshal(&data->clearCount, buffer, size); + written += UINT64_Marshal(&data->objectContextID, buffer, size); + +@@ -2146,7 +2146,7 @@ TPM2B_HASH_BLOCK_Marshal(TPM2B_HASH_BLOCK *data, BYTE **buffer, INT32 *size) + { + UINT16 written; + +- written = TPM2B_Marshal(&data->b, buffer, size); ++ written = TPM2B_Marshal(&data->b, sizeof(data->t.buffer), buffer, size); + + return written; + } +@@ -2950,9 +2950,9 @@ VolatileState_Marshal(BYTE **buffer, INT32 *size) + + /* tie the volatile state to the EP,SP, and PPSeed */ + NvRead(&pd, NV_PERSISTENT_DATA, sizeof(pd)); +- written += TPM2B_Marshal(&pd.EPSeed.b, buffer, size); +- written += TPM2B_Marshal(&pd.SPSeed.b, buffer, size); +- written += TPM2B_Marshal(&pd.PPSeed.b, buffer, size); ++ written += TPM2B_Marshal(&pd.EPSeed.b, sizeof(pd.EPSeed.t.buffer), buffer, size); ++ written += TPM2B_Marshal(&pd.SPSeed.b, sizeof(pd.SPSeed.t.buffer), buffer, size); ++ written += TPM2B_Marshal(&pd.PPSeed.b, sizeof(pd.PPSeed.t.buffer), buffer, size); + + written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size); /* v4 */ + +@@ -3753,9 +3753,9 @@ PERSISTENT_DATA_Marshal(PERSISTENT_DATA *data, BYTE **buffer, INT32 *size) + written += TPM2B_AUTH_Marshal(&data->ownerAuth, buffer, size); + written += TPM2B_AUTH_Marshal(&data->endorsementAuth, buffer, size); + written += TPM2B_AUTH_Marshal(&data->lockoutAuth, buffer, size); +- written += TPM2B_Marshal(&data->EPSeed.b, buffer, size); +- written += TPM2B_Marshal(&data->SPSeed.b, buffer, size); +- written += TPM2B_Marshal(&data->PPSeed.b, buffer, size); ++ written += TPM2B_Marshal(&data->EPSeed.b, sizeof(data->EPSeed.t.buffer), buffer, size); ++ written += TPM2B_Marshal(&data->SPSeed.b, sizeof(data->SPSeed.t.buffer), buffer, size); ++ written += TPM2B_Marshal(&data->PPSeed.b, sizeof(data->PPSeed.t.buffer), buffer, size); + written += TPM2B_PROOF_Marshal(&data->phProof, buffer, size); + written += TPM2B_PROOF_Marshal(&data->shProof, buffer, size); + written += TPM2B_PROOF_Marshal(&data->ehProof, buffer, size); +-- +2.27.0 + diff --git a/0001-tpm2-CryptSym-fix-AES-output-IV.patch b/tpm2-CryptSym-fix-AES-output-IV.patch similarity index 100% rename from 0001-tpm2-CryptSym-fix-AES-output-IV.patch rename to tpm2-CryptSym-fix-AES-output-IV.patch diff --git a/tpm2-Fix-issue-with-misaligned-address-when-marshall.patch b/tpm2-Fix-issue-with-misaligned-address-when-marshall.patch new file mode 100644 index 0000000000000000000000000000000000000000..18b073a7b6afff7b1a945034df2e3a05021ca975 --- /dev/null +++ b/tpm2-Fix-issue-with-misaligned-address-when-marshall.patch @@ -0,0 +1,155 @@ +From 3aac390ce146b40117ad213c24504bb678f4daeb Mon Sep 17 00:00:00 2001 +From: Stefan Berger +Date: Mon, 23 Nov 2020 13:15:53 -0500 +Subject: [PATCH] tpm2: Fix issue with misaligned address when marshalling + NVRAM (UBSAN) + +UBSAN detects possibly misaligned address when reading out of the +TPM 2's NVRAM and when writing back into it. The NV_RAM_HEADER may +be unaligned like this: + +tests/test_tpm2_save_load_state_3.log:tpm2/Marshal.c:117:29: \ + runtime error: load of misaligned address 0x7ffcb53b3bca for type 'UINT32', which requires 4 byte alignment + +Signed-off-by: Stefan Berger +--- + src/tpm2/NVMarshal.c | 59 +++++++++++++++++++++++++++----------------- + 1 file changed, 36 insertions(+), 23 deletions(-) + +diff --git a/src/tpm2/NVMarshal.c b/src/tpm2/NVMarshal.c +index ec94ebf..74ea17f 100644 +--- a/src/tpm2/NVMarshal.c ++++ b/src/tpm2/NVMarshal.c +@@ -3991,7 +3991,7 @@ INDEX_ORDERLY_RAM_Marshal(void *array, size_t array_size, + BYTE **buffer, INT32 *size) + { + UINT16 written; +- NV_RAM_HEADER *nrh; ++ NV_RAM_HEADER nrh, *nrhp; + UINT16 offset = 0; + UINT16 datasize; + UINT32 sourceside_size = array_size; +@@ -4005,36 +4005,42 @@ INDEX_ORDERLY_RAM_Marshal(void *array, size_t array_size, + written += UINT32_Marshal(&sourceside_size, buffer, size); + + while (TRUE) { +- nrh = array + offset; ++ nrhp = array + offset; ++ /* nrhp may point to misaligned address (ubsan), so use 'nrh'; first access only 'size' */ ++ memcpy(&nrh, nrhp, sizeof(nrh.size)); ++ + /* write the NVRAM header; + nrh->size holds the complete size including data; + nrh->size = 0 indicates the end */ +- written += UINT32_Marshal(&nrh->size, buffer, size); +- if (nrh->size == 0) ++ written += UINT32_Marshal(&nrh.size, buffer, size); ++ if (nrh.size == 0) + break; +- written += TPM_HANDLE_Marshal(&nrh->handle, buffer, size); +- written += TPMA_NV_Marshal(&nrh->attributes, buffer, size); ++ /* copy the entire structure now; ubsan does not allow 'nrh = *nrhp' */ ++ memcpy(&nrh, nrhp, sizeof(nrh)); ++ ++ written += TPM_HANDLE_Marshal(&nrh.handle, buffer, size); ++ written += TPMA_NV_Marshal(&nrh.attributes, buffer, size); + +- if (offset + nrh->size > array_size) { ++ if (offset + nrh.size > array_size) { + TPMLIB_LogTPM2Error("NV_ORDERLY_RAM: nrh->size corrupted: %d\n", +- nrh->size); ++ nrh.size); + break; + } + /* write data size before array */ +- if (nrh->size < sizeof(NV_RAM_HEADER)) { ++ if (nrh.size < sizeof(NV_RAM_HEADER)) { + TPMLIB_LogTPM2Error( + "NV_ORDERLY_RAM: nrh->size < sizeof(NV_RAM_HEADER): %d < %zu\n", +- (int)nrh->size, sizeof(NV_RAM_HEADER)); ++ (int)nrh.size, sizeof(NV_RAM_HEADER)); + break; + } +- datasize = nrh->size - sizeof(NV_RAM_HEADER); ++ datasize = nrh.size - sizeof(NV_RAM_HEADER); + written += UINT16_Marshal(&datasize, buffer, size); + if (datasize > 0) { + /* append the data */ + written += Array_Marshal(array + offset + sizeof(NV_RAM_HEADER), + datasize, buffer, size); + } +- offset += nrh->size; ++ offset += nrh.size; + } + + written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size); +@@ -4053,7 +4059,7 @@ INDEX_ORDERLY_RAM_Unmarshal(void *array, size_t array_size, + { + TPM_RC rc = TPM_RC_SUCCESS; + NV_HEADER hdr; +- NV_RAM_HEADER *nrh; ++ NV_RAM_HEADER nrh, *nrhp; + UINT16 offset = 0; + UINT16 datasize = 0; + UINT32 sourceside_size; +@@ -4071,31 +4077,36 @@ INDEX_ORDERLY_RAM_Unmarshal(void *array, size_t array_size, + } + + while (rc == TPM_RC_SUCCESS) { +- nrh = array + offset; ++ /* nrhp may point to misaligned address (ubsan) ++ * we read 'into' nrh and copy to nrhp at end ++ */ ++ nrhp = array + offset; ++ + /* write the NVRAM header; + nrh->size holds the complete size including data; + nrh->size = 0 indicates the end */ +- if (offset + sizeof(nrh->size) > array_size) { +- offset += sizeof(nrh->size); ++ if (offset + sizeof(nrh.size) > array_size) { ++ offset += sizeof(nrh.size); + goto exit_size; + } + + if (rc == TPM_RC_SUCCESS) { +- rc = UINT32_Unmarshal(&nrh->size, buffer, size); +- if (nrh->size == 0) ++ rc = UINT32_Unmarshal(&nrh.size, buffer, size); ++ if (nrh.size == 0) { ++ memcpy(nrhp, &nrh, sizeof(nrh.size)); + break; ++ } + } + if (offset + sizeof(NV_RAM_HEADER) > array_size) { + offset += sizeof(NV_RAM_HEADER); + goto exit_size; + } + if (rc == TPM_RC_SUCCESS) { +- rc = TPM_HANDLE_Unmarshal(&nrh->handle, buffer, size); ++ rc = TPM_HANDLE_Unmarshal(&nrh.handle, buffer, size); + } + if (rc == TPM_RC_SUCCESS) { +- rc = TPMA_NV_Unmarshal(&nrh->attributes, buffer, size); ++ rc = TPMA_NV_Unmarshal(&nrh.attributes, buffer, size); + } +- + if (rc == TPM_RC_SUCCESS) { + rc = UINT16_Unmarshal(&datasize, buffer, size); + } +@@ -4110,8 +4121,10 @@ INDEX_ORDERLY_RAM_Unmarshal(void *array, size_t array_size, + } + if (rc == TPM_RC_SUCCESS) { + /* fix up size in case it is architecture-dependent */ +- nrh->size = sizeof(*nrh) + datasize; +- offset += nrh->size; ++ nrh.size = sizeof(nrh) + datasize; ++ offset += nrh.size; ++ /* copy header into possibly misaligned address in NVRAM */ ++ *nrhp = nrh; + } + } + +-- +2.21.0.windows.1 + diff --git a/tpm2-Initialize-a-whole-OBJECT-before-using-it.patch b/tpm2-Initialize-a-whole-OBJECT-before-using-it.patch new file mode 100644 index 0000000000000000000000000000000000000000..a012ceacb52969d41e93e217f89f171a237bb52a --- /dev/null +++ b/tpm2-Initialize-a-whole-OBJECT-before-using-it.patch @@ -0,0 +1,34 @@ +From ea62fd9679f8c6fc5e79471b33cfbd8227bfed72 Mon Sep 17 00:00:00 2001 +From: Stefan Berger +Date: Thu, 22 Jul 2021 21:23:58 -0400 +Subject: [PATCH] tpm2: Initialize a whole OBJECT before using it + +Initialize a whole OBJECT before using it. This is necessary since +an OBJECT may also be used as a HASH_OBJECT via the ANY_OBJECT +union and that HASH_OBJECT can leave bad size inidicators in TPM2B +buffer in the OBJECT. To get rid of this problem we reset the whole +OBJECT to 0 before using it. This is as if the memory for the +OBJECT was just initialized. + +Signed-off-by: Stefan Berger +--- + src/tpm2/Object.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/tpm2/Object.c b/src/tpm2/Object.c +index ab50348..967105f 100644 +--- a/src/tpm2/Object.c ++++ b/src/tpm2/Object.c +@@ -284,7 +284,8 @@ FindEmptyObjectSlot( + if(handle) + *handle = i + TRANSIENT_FIRST; + // Initialize the object attributes +- MemorySet(&object->attributes, 0, sizeof(OBJECT_ATTRIBUTES)); ++ // MemorySet(&object->attributes, 0, sizeof(OBJECT_ATTRIBUTES)); ++ MemorySet(object, 0, sizeof(*object)); // libtpms added: Initialize the whole object + return object; + } + } +-- +2.21.0.windows.1 + diff --git a/tpm2-NVMarshal-Handle-index-orderly-RAM-without-0-si.patch b/tpm2-NVMarshal-Handle-index-orderly-RAM-without-0-si.patch new file mode 100644 index 0000000000000000000000000000000000000000..6bf8f4fab7495ea6c74a8ce2f2c2a49f87f9b656 --- /dev/null +++ b/tpm2-NVMarshal-Handle-index-orderly-RAM-without-0-si.patch @@ -0,0 +1,56 @@ +From 1fb6cd9b8df05b5d6e381b31215193d6ada969df Mon Sep 17 00:00:00 2001 +From: Stefan Berger +Date: Fri, 23 Jul 2021 13:29:00 -0400 +Subject: [PATCH] tpm2: NVMarshal: Handle index orderly RAM without 0-sized + terminating node + +The NVRAM entries in s_indexOrderlyRam array do not need to contain a +0-sized terminating node. Instead, the entries may fill up this 512 +byte array so that no NV_RAM_HEADER structure fits anymore. The fact +that no more NV_RAM_HEADER structure fits is also an indicator for the +last entry. We need to account for this in the code marshalling and +unmarshalling the entries so that we stop marshalling the entries +then and similarly stop unmarshalling. + +Signed-off-by: Stefan Berger +--- + src/tpm2/NVMarshal.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/src/tpm2/NVMarshal.c b/src/tpm2/NVMarshal.c +index 2b2d84a..430f481 100644 +--- a/src/tpm2/NVMarshal.c ++++ b/src/tpm2/NVMarshal.c +@@ -4103,6 +4103,12 @@ INDEX_ORDERLY_RAM_Marshal(void *array, size_t array_size, + datasize, buffer, size); + } + offset += nrh.size; ++ if (offset + sizeof(NV_RAM_HEADER) > array_size) { ++ /* nothing will fit anymore and there won't be a 0-sized ++ * terminating node (@1). ++ */ ++ break; ++ } + } + + written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size); +@@ -4144,6 +4150,16 @@ INDEX_ORDERLY_RAM_Unmarshal(void *array, size_t array_size, + */ + nrhp = array + offset; + ++ if (offset + sizeof(NV_RAM_HEADER) > sourceside_size) { ++ /* this case can occur with the previous entry filling up the ++ * space; in this case there will not be a 0-sized terminating ++ * node (see @1 above). We clear the rest of our space. ++ */ ++ if (array_size > offset) ++ memset(nrhp, 0, array_size - offset); ++ break; ++ } ++ + /* write the NVRAM header; + nrh->size holds the complete size including data; + nrh->size = 0 indicates the end */ +-- +2.21.0.windows.1 + diff --git a/tpm2-Reset-TPM2B-buffer-sizes-after-test-fails-for-v.patch b/tpm2-Reset-TPM2B-buffer-sizes-after-test-fails-for-v.patch new file mode 100644 index 0000000000000000000000000000000000000000..4a6aaef02427fc125eba602aeaf675bc8cf27b71 --- /dev/null +++ b/tpm2-Reset-TPM2B-buffer-sizes-after-test-fails-for-v.patch @@ -0,0 +1,202 @@ +From aa4f8ee9f23e2a87f704ef1b81de12594480de96 Mon Sep 17 00:00:00 2001 +From: Stefan Berger +Date: Mon, 21 Jun 2021 14:04:34 -0400 +Subject: [PATCH 1/3] tpm2: Reset TPM2B buffer sizes after test fails for valid + buffer size + +Reset the buffer size indicator in a TPM2B type of buffer after it failed +the test for the maximum buffer size it allows. This prevents having bad +buffer sizes in memory that can come to haunt us when writing the volatile +state for example. + +Signed-off-by: Stefan Berger +--- + src/tpm2/NVMarshal.c | 1 + + src/tpm2/Unmarshal.c | 21 +++++++++++++++++++++ + 2 files changed, 22 insertions(+) + +diff --git a/src/tpm2/NVMarshal.c b/src/tpm2/NVMarshal.c +index 7c140ea..8f77fa2 100644 +--- a/src/tpm2/NVMarshal.c ++++ b/src/tpm2/NVMarshal.c +@@ -1473,6 +1473,7 @@ bn_prime_t_Unmarshal(bn_prime_t *data, BYTE **buffer, INT32 *size) + "allocated %zu\n", + (size_t)data->size, (size_t)data->allocated); + rc = TPM_RC_SIZE; ++ data->size = 0; + } + } + +diff --git a/src/tpm2/Unmarshal.c b/src/tpm2/Unmarshal.c +index 9a1d723..bac7d76 100644 +--- a/src/tpm2/Unmarshal.c ++++ b/src/tpm2/Unmarshal.c +@@ -137,6 +137,7 @@ TPM2B_Unmarshal(TPM2B *target, UINT16 targetSize, BYTE **buffer, INT32 *size) + if (rc == TPM_RC_SUCCESS) { + if (target->size > targetSize) { + rc = TPM_RC_SIZE; ++ target->size = 0; // libtpms added + } + } + if (rc == TPM_RC_SUCCESS) { +@@ -1617,6 +1618,7 @@ TPMS_PCR_SELECTION_Unmarshal(TPMS_PCR_SELECTION *target, BYTE **buffer, INT32 *s + if ((target->sizeofSelect < PCR_SELECT_MIN) || + (target->sizeofSelect > PCR_SELECT_MAX)) { + rc = TPM_RC_VALUE; ++ target->sizeofSelect = 0; // libtpms added + } + } + if (rc == TPM_RC_SUCCESS) { +@@ -1787,6 +1789,7 @@ TPML_CC_Unmarshal(TPML_CC *target, BYTE **buffer, INT32 *size) + if (rc == TPM_RC_SUCCESS) { + if (target->count > MAX_CAP_CC) { + rc = TPM_RC_SIZE; ++ target->count = 0; // libtpms added + } + } + for (i = 0 ; (rc == TPM_RC_SUCCESS) && (i < target->count) ; i++) { +@@ -1824,6 +1827,7 @@ TPML_CCA_Unmarshal(TPML_CCA *target, BYTE **buffer, INT32 *size) + if (rc == TPM_RC_SUCCESS) { + if (target->count > MAX_CAP_CC) { + rc = TPM_RC_SIZE; ++ target->count = 0; // libtpms added + } + } + for (i = 0 ; (rc == TPM_RC_SUCCESS) && (i < target->count) ; i++) { +@@ -1846,6 +1850,7 @@ TPML_ALG_Unmarshal(TPML_ALG *target, BYTE **buffer, INT32 *size) + if (rc == TPM_RC_SUCCESS) { + if (target->count > MAX_ALG_LIST_SIZE) { + rc = TPM_RC_SIZE; ++ target->count = 0; // libtpms added + } + } + for (i = 0 ; (rc == TPM_RC_SUCCESS) && (i < target->count) ; i++) { +@@ -1868,6 +1873,7 @@ TPML_HANDLE_Unmarshal(TPML_HANDLE *target, BYTE **buffer, INT32 *size) + if (rc == TPM_RC_SUCCESS) { + if (target->count > MAX_CAP_HANDLES) { + rc = TPM_RC_SIZE; ++ target->count = 0; // libtpms added + } + } + for (i = 0 ; (rc == TPM_RC_SUCCESS) && (i < target->count) ; i++) { +@@ -1895,11 +1901,13 @@ TPML_DIGEST_Unmarshal(TPML_DIGEST *target, BYTE **buffer, INT32 *size) + /* TPM side is hard coded to 2 minimum */ + if (target->count < 2) { + rc = TPM_RC_SIZE; ++ target->count = 0; // libtpms added + } + } + if (rc == TPM_RC_SUCCESS) { + if (target->count > 8) { + rc = TPM_RC_SIZE; ++ target->count = 0; // libtpms added + } + } + for (i = 0 ; (rc == TPM_RC_SUCCESS) && (i < target->count) ; i++) { +@@ -1922,6 +1930,7 @@ TPML_DIGEST_VALUES_Unmarshal(TPML_DIGEST_VALUES *target, BYTE **buffer, INT32 *s + if (rc == TPM_RC_SUCCESS) { + if (target->count > HASH_COUNT) { + rc = TPM_RC_SIZE; ++ target->count = 0; // libtpms added + } + } + for (i = 0 ; (rc == TPM_RC_SUCCESS) && (i < target->count) ; i++) { +@@ -1944,6 +1953,7 @@ TPML_PCR_SELECTION_Unmarshal(TPML_PCR_SELECTION *target, BYTE **buffer, INT32 *s + if (rc == TPM_RC_SUCCESS) { + if (target->count > HASH_COUNT) { + rc = TPM_RC_SIZE; ++ target->count = 0; // libtpms added + } + } + for (i = 0 ; (rc == TPM_RC_SUCCESS) && (i < target->count) ; i++) { +@@ -1967,6 +1977,7 @@ TPML_ALG_PROPERTY_Unmarshal(TPML_ALG_PROPERTY *target, BYTE **buffer, INT32 *siz + if (rc == TPM_RC_SUCCESS) { + if (target->count > MAX_CAP_ALGS) { + rc = TPM_RC_SIZE; ++ target->count = 0; // libtpms added + } + } + for (i = 0 ; (rc == TPM_RC_SUCCESS) && (i < target->count) ; i++) { +@@ -1989,6 +2000,7 @@ TPML_TAGGED_TPM_PROPERTY_Unmarshal(TPML_TAGGED_TPM_PROPERTY *target, BYTE **buf + if (rc == TPM_RC_SUCCESS) { + if (target->count > MAX_TPM_PROPERTIES) { + rc = TPM_RC_SIZE; ++ target->count = 0; // libtpms added + } + } + for (i = 0 ; (rc == TPM_RC_SUCCESS) && (i < target->count) ; i++) { +@@ -2011,6 +2023,7 @@ TPML_TAGGED_PCR_PROPERTY_Unmarshal(TPML_TAGGED_PCR_PROPERTY *target, BYTE **buff + if (rc == TPM_RC_SUCCESS) { + if (target->count > MAX_PCR_PROPERTIES) { + rc = TPM_RC_SIZE; ++ target->count = 0; // libtpms added + } + } + for (i = 0 ; (rc == TPM_RC_SUCCESS) && (i < target->count) ; i++) { +@@ -2033,6 +2046,7 @@ TPML_ECC_CURVE_Unmarshal(TPML_ECC_CURVE *target, BYTE **buffer, INT32 *size) + if (rc == TPM_RC_SUCCESS) { + if (target->count > MAX_ECC_CURVES) { + rc = TPM_RC_SIZE; ++ target->count = 0; // libtpms added + } + } + for (i = 0 ; (rc == TPM_RC_SUCCESS) && (i < target->count) ; i++) { +@@ -2055,6 +2069,7 @@ TPML_TAGGED_POLICY_Unmarshal(TPML_TAGGED_POLICY *target, BYTE **buffer, INT32 *s + if (rc == TPM_RC_SUCCESS) { + if (target->count > MAX_TAGGED_POLICIES) { + rc = TPM_RC_SIZE; ++ target->count = 0; // libtpms added + } + } + for (i = 0 ; (rc == TPM_RC_SUCCESS) && (i < target->count) ; i++) { +@@ -2704,6 +2719,7 @@ TPM2B_SENSITIVE_CREATE_Unmarshal(TPM2B_SENSITIVE_CREATE *target, BYTE **buffer, + if (rc == TPM_RC_SUCCESS) { + if (target->size != startSize - *size) { + rc = TPM_RC_SIZE; ++ target->size = 0; // libtpms added + } + } + return rc; +@@ -3462,6 +3478,7 @@ TPM2B_ECC_POINT_Unmarshal(TPM2B_ECC_POINT *target, BYTE **buffer, INT32 *size) + if (rc == TPM_RC_SUCCESS) { + if (target->size != startSize - *size) { + rc = TPM_RC_SIZE; ++ target->size = 0; // libtpms added + } + } + return rc; +@@ -3985,6 +4002,7 @@ TPM2B_PUBLIC_Unmarshal(TPM2B_PUBLIC *target, BYTE **buffer, INT32 *size, BOOL al + if (rc == TPM_RC_SUCCESS) { + if (target->size != startSize - *size) { + rc = TPM_RC_SIZE; ++ target->size = 0; // libtpms added + } + } + return rc; +@@ -4080,6 +4098,7 @@ TPM2B_SENSITIVE_Unmarshal(TPM2B_SENSITIVE *target, BYTE **buffer, INT32 *size) + if (rc == TPM_RC_SUCCESS) { + if (target->size != startSize - *size) { + rc = TPM_RC_SIZE; ++ target->size = 0; // libtpms added + } + } + } +@@ -4155,6 +4174,7 @@ TPMS_NV_PUBLIC_Unmarshal(TPMS_NV_PUBLIC *target, BYTE **buffer, INT32 *size) + if (rc == TPM_RC_SUCCESS) { + if (target->dataSize > MAX_NV_INDEX_SIZE) { + rc = TPM_RC_SIZE; ++ target->dataSize = 0; // libtpms added + } + } + return rc; +@@ -4185,6 +4205,7 @@ TPM2B_NV_PUBLIC_Unmarshal(TPM2B_NV_PUBLIC *target, BYTE **buffer, INT32 *size) + if (rc == TPM_RC_SUCCESS) { + if (target->size != startSize - *size) { + rc = TPM_RC_SIZE; ++ target->size = 0; // libtpms added + } + } + return rc; +-- +2.27.0 + diff --git a/tpm2-Restore-original-value-if-unmarsalled-value-was.patch b/tpm2-Restore-original-value-if-unmarsalled-value-was.patch new file mode 100644 index 0000000000000000000000000000000000000000..3d15693a5797c50bb2b81d3d586a2073bd93e52c --- /dev/null +++ b/tpm2-Restore-original-value-if-unmarsalled-value-was.patch @@ -0,0 +1,998 @@ +From 1e19a2a17ba3256ca67f53b07515dfcc1af9bcc8 Mon Sep 17 00:00:00 2001 +From: Stefan Berger +Date: Wed, 18 May 2022 15:33:05 +0800 +Subject: [PATCH 3/3] tpm2: Restore original value if unmarsalled value was + illegal + +Restore the original value of the memory location where data from +a stream was unmarshalled and the unmarshalled value was found to +be illegal. The goal is to not keep illegal values in memory. + +Signed-off-by: Stefan Berger +--- + src/tpm2/Unmarshal.c | 122 +++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 122 insertions(+) + +diff --git a/src/tpm2/Unmarshal.c b/src/tpm2/Unmarshal.c +index bac7d76..c839a68 100644 +--- a/src/tpm2/Unmarshal.c ++++ b/src/tpm2/Unmarshal.c +@@ -165,6 +165,7 @@ TPM_RC + TPM_GENERATED_Unmarshal(TPM_GENERATED *target, BYTE **buffer, INT32 *size) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPM_GENERATED orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = UINT32_Unmarshal(target, buffer, size); +@@ -172,6 +173,7 @@ TPM_GENERATED_Unmarshal(TPM_GENERATED *target, BYTE **buffer, INT32 *size) + if (rc == TPM_RC_SUCCESS) { + if (*target != TPM_GENERATED_VALUE) { + rc = TPM_RC_VALUE; ++ *target = orig_target; // libtpms added + } + } + return rc; +@@ -197,6 +199,7 @@ TPM_RC + TPM_ECC_CURVE_Unmarshal(TPM_ECC_CURVE *target, BYTE **buffer, INT32 *size) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPM_ECC_CURVE orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = UINT16_Unmarshal(target, buffer, size); +@@ -215,6 +218,7 @@ TPM_ECC_CURVE_Unmarshal(TPM_ECC_CURVE *target, BYTE **buffer, INT32 *size) + break; + default: + rc = TPM_RC_CURVE; ++ *target = orig_target; // libtpms added + } + } + return rc; +@@ -240,6 +244,7 @@ TPM_RC + TPM_CLOCK_ADJUST_Unmarshal(TPM_CLOCK_ADJUST *target, BYTE **buffer, INT32 *size) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPM_CLOCK_ADJUST orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = INT8_Unmarshal(target, buffer, size); +@@ -256,6 +261,7 @@ TPM_CLOCK_ADJUST_Unmarshal(TPM_CLOCK_ADJUST *target, BYTE **buffer, INT32 *size) + break; + default: + rc = TPM_RC_VALUE; ++ *target = orig_target; // libtpms added + } + } + return rc; +@@ -267,6 +273,7 @@ TPM_RC + TPM_EO_Unmarshal(TPM_EO *target, BYTE **buffer, INT32 *size) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPM_EO orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = UINT16_Unmarshal(target, buffer, size); +@@ -288,6 +295,7 @@ TPM_EO_Unmarshal(TPM_EO *target, BYTE **buffer, INT32 *size) + break; + default: + rc = TPM_RC_VALUE; ++ *target = orig_target; // libtpms added + } + } + return rc; +@@ -299,6 +307,7 @@ TPM_RC + TPM_ST_Unmarshal(TPM_ST *target, BYTE **buffer, INT32 *size) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPM_ST orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = UINT16_Unmarshal(target, buffer, size); +@@ -324,6 +333,7 @@ TPM_ST_Unmarshal(TPM_ST *target, BYTE **buffer, INT32 *size) + break; + default: + rc = TPM_RC_VALUE; ++ *target = orig_target; // libtpms added + } + } + return rc; +@@ -335,6 +345,7 @@ TPM_RC + TPM_SU_Unmarshal(TPM_SU *target, BYTE **buffer, INT32 *size) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPM_SU orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = UINT16_Unmarshal(target, buffer, size); +@@ -346,6 +357,7 @@ TPM_SU_Unmarshal(TPM_SU *target, BYTE **buffer, INT32 *size) + break; + default: + rc = TPM_RC_VALUE; ++ *target = orig_target; // libtpms added + } + } + return rc; +@@ -357,6 +369,7 @@ TPM_RC + TPM_SE_Unmarshal(TPM_SE *target, BYTE **buffer, INT32 *size) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPM_SE orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = UINT8_Unmarshal(target, buffer, size); +@@ -369,6 +382,7 @@ TPM_SE_Unmarshal(TPM_SE *target, BYTE **buffer, INT32 *size) + break; + default: + rc = TPM_RC_VALUE; ++ *target = orig_target; // libtpms added + } + } + return rc; +@@ -380,6 +394,7 @@ TPM_RC + TPM_CAP_Unmarshal(TPM_CAP *target, BYTE **buffer, INT32 *size) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPM_CAP orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = UINT32_Unmarshal(target, buffer, size); +@@ -400,6 +415,7 @@ TPM_CAP_Unmarshal(TPM_CAP *target, BYTE **buffer, INT32 *size) + break; + default: + rc = TPM_RC_VALUE; ++ *target = orig_target; // libtpms added + } + } + return rc; +@@ -450,6 +466,7 @@ TPM_RC + TPMA_ALGORITHM_Unmarshal(TPMA_ALGORITHM *target, BYTE **buffer, INT32 *size) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPMA_ALGORITHM orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = UINT32_Unmarshal((UINT32 *)target, buffer, size); /* libtpms changed */ +@@ -457,6 +474,7 @@ TPMA_ALGORITHM_Unmarshal(TPMA_ALGORITHM *target, BYTE **buffer, INT32 *size) + if (rc == TPM_RC_SUCCESS) { + if (*target & TPMA_ALGORITHM_reserved) { + rc = TPM_RC_RESERVED_BITS; ++ *target = orig_target; // libtpms added + } + } + return rc; +@@ -468,6 +486,7 @@ TPM_RC + TPMA_OBJECT_Unmarshal(TPMA_OBJECT *target, BYTE **buffer, INT32 *size) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPMA_OBJECT orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = UINT32_Unmarshal((UINT32 *)target, buffer, size); /* libtpms changed */ +@@ -475,6 +494,7 @@ TPMA_OBJECT_Unmarshal(TPMA_OBJECT *target, BYTE **buffer, INT32 *size) + if (rc == TPM_RC_SUCCESS) { + if (*target & TPMA_OBJECT_reserved) { + rc = TPM_RC_RESERVED_BITS; ++ *target = orig_target; // libtpms added + } + } + return rc; +@@ -486,6 +506,7 @@ TPM_RC + TPMA_SESSION_Unmarshal(TPMA_SESSION *target, BYTE **buffer, INT32 *size) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPMA_SESSION orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = UINT8_Unmarshal((UINT8 *)target, buffer, size); /* libtpms changed */ +@@ -493,6 +514,7 @@ TPMA_SESSION_Unmarshal(TPMA_SESSION *target, BYTE **buffer, INT32 *size) + if (rc == TPM_RC_SUCCESS) { + if (*target & TPMA_SESSION_reserved) { + rc = TPM_RC_RESERVED_BITS; ++ *target = orig_target; // libtpms added + } + } + return rc; +@@ -517,6 +539,7 @@ TPM_RC + TPMA_CC_Unmarshal(TPMA_CC *target, BYTE **buffer, INT32 *size) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPMA_CC orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = UINT32_Unmarshal((UINT32 *)target, buffer, size); /* libtpms changed */ +@@ -524,6 +547,7 @@ TPMA_CC_Unmarshal(TPMA_CC *target, BYTE **buffer, INT32 *size) + if (rc == TPM_RC_SUCCESS) { + if (*target & TPMA_CC_reserved) { + rc = TPM_RC_RESERVED_BITS; ++ *target = orig_target; // libtpms added + } + } + return rc; +@@ -535,6 +559,7 @@ TPM_RC + TPMI_YES_NO_Unmarshal(TPMI_YES_NO *target, BYTE **buffer, INT32 *size) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPMI_YES_NO orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = UINT8_Unmarshal(target, buffer, size); +@@ -546,6 +571,7 @@ TPMI_YES_NO_Unmarshal(TPMI_YES_NO *target, BYTE **buffer, INT32 *size) + break; + default: + rc = TPM_RC_VALUE; ++ *target = orig_target; // libtpms added + } + } + return rc; +@@ -557,6 +583,7 @@ TPM_RC + TPMI_DH_OBJECT_Unmarshal(TPMI_DH_OBJECT *target, BYTE **buffer, INT32 *size, BOOL allowNull) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPMI_DH_OBJECT orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_HANDLE_Unmarshal(target, buffer, size); +@@ -569,6 +596,7 @@ TPMI_DH_OBJECT_Unmarshal(TPMI_DH_OBJECT *target, BYTE **buffer, INT32 *size, BOO + isNotPersistent && + isNotLegalNull) { + rc = TPM_RC_VALUE; ++ *target = orig_target; // libtpms added + } + } + return rc; +@@ -580,6 +608,7 @@ TPM_RC + TPMI_DH_PARENT_Unmarshal(TPMI_DH_PARENT *target, BYTE **buffer, INT32 *size, BOOL allowNull) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPMI_DH_PARENT orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_HANDLE_Unmarshal(target, buffer, size); +@@ -598,6 +627,7 @@ TPMI_DH_PARENT_Unmarshal(TPMI_DH_PARENT *target, BYTE **buffer, INT32 *size, BOO + isNotEndorsement && + isNotLegalNull) { + rc = TPM_RC_VALUE; ++ *target = orig_target; // libtpms added + } + } + return rc; +@@ -609,6 +639,7 @@ TPM_RC + TPMI_DH_PERSISTENT_Unmarshal(TPMI_DH_PERSISTENT *target, BYTE **buffer, INT32 *size) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPMI_DH_PERSISTENT orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_HANDLE_Unmarshal(target, buffer, size); +@@ -617,6 +648,7 @@ TPMI_DH_PERSISTENT_Unmarshal(TPMI_DH_PERSISTENT *target, BYTE **buffer, INT32 *s + BOOL isNotPersistent = (*target < PERSISTENT_FIRST) || (*target > PERSISTENT_LAST); + if (isNotPersistent) { + rc = TPM_RC_VALUE; ++ *target = orig_target; // libtpms added + } + } + return rc; +@@ -628,6 +660,7 @@ TPM_RC + TPMI_DH_ENTITY_Unmarshal(TPMI_DH_ENTITY *target, BYTE **buffer, INT32 *size, BOOL allowNull) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPMI_DH_ENTITY orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_HANDLE_Unmarshal(target, buffer, size); +@@ -654,6 +687,7 @@ TPMI_DH_ENTITY_Unmarshal(TPMI_DH_ENTITY *target, BYTE **buffer, INT32 *size, BOO + isNotAuth && + isNotLegalNull) { + rc = TPM_RC_VALUE; ++ *target = orig_target; // libtpms added + } + } + return rc; +@@ -665,6 +699,7 @@ TPM_RC + TPMI_DH_PCR_Unmarshal(TPMI_DH_PCR *target, BYTE **buffer, INT32 *size, BOOL allowNull) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPMI_DH_PCR orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_HANDLE_Unmarshal(target, buffer, size); +@@ -675,6 +710,7 @@ TPMI_DH_PCR_Unmarshal(TPMI_DH_PCR *target, BYTE **buffer, INT32 *size, BOOL allo + if (isNotPcr && + isNotLegalNull) { + rc = TPM_RC_VALUE; ++ *target = orig_target; // libtpms added + } + } + return rc; +@@ -686,6 +722,7 @@ TPM_RC + TPMI_SH_AUTH_SESSION_Unmarshal(TPMI_SH_AUTH_SESSION *target, BYTE **buffer, INT32 *size, BOOL allowPwd) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPMI_SH_AUTH_SESSION orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_HANDLE_Unmarshal(target, buffer, size); +@@ -698,6 +735,7 @@ TPMI_SH_AUTH_SESSION_Unmarshal(TPMI_SH_AUTH_SESSION *target, BYTE **buffer, INT3 + isNotPolicySession && + isNotLegalPwd) { + rc = TPM_RC_VALUE; ++ *target = orig_target; // libtpms added + } + } + return rc; +@@ -709,6 +747,7 @@ TPM_RC + TPMI_SH_HMAC_Unmarshal(TPMI_SH_HMAC *target, BYTE **buffer, INT32 *size) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPMI_SH_HMAC orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_HANDLE_Unmarshal(target, buffer, size); +@@ -717,6 +756,7 @@ TPMI_SH_HMAC_Unmarshal(TPMI_SH_HMAC *target, BYTE **buffer, INT32 *size) + BOOL isNotHmacSession = (*target < HMAC_SESSION_FIRST ) || (*target > HMAC_SESSION_LAST); + if (isNotHmacSession) { + rc = TPM_RC_VALUE; ++ *target = orig_target; // libtpms added + } + } + return rc; +@@ -728,6 +768,7 @@ TPM_RC + TPMI_SH_POLICY_Unmarshal(TPMI_SH_POLICY *target, BYTE **buffer, INT32 *size) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPMI_SH_POLICY orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_HANDLE_Unmarshal(target, buffer, size); +@@ -736,6 +777,7 @@ TPMI_SH_POLICY_Unmarshal(TPMI_SH_POLICY *target, BYTE **buffer, INT32 *size) + BOOL isNotPolicySession = (*target < POLICY_SESSION_FIRST) || (*target > POLICY_SESSION_LAST); + if (isNotPolicySession) { + rc = TPM_RC_VALUE; ++ *target = orig_target; // libtpms added + } + } + return rc; +@@ -747,6 +789,7 @@ TPM_RC + TPMI_DH_CONTEXT_Unmarshal(TPMI_DH_CONTEXT *target, BYTE **buffer, INT32 *size) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPMI_DH_CONTEXT orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_HANDLE_Unmarshal(target, buffer, size); +@@ -759,6 +802,7 @@ TPMI_DH_CONTEXT_Unmarshal(TPMI_DH_CONTEXT *target, BYTE **buffer, INT32 *size) + isNotPolicySession && + isNotTransient) { + rc = TPM_RC_VALUE; ++ *target = orig_target; // libtpms added + } + } + return rc; +@@ -770,6 +814,7 @@ TPM_RC + TPMI_DH_SAVED_Unmarshal(TPMI_DH_SAVED *target, BYTE **buffer, INT32 *size, BOOL allowNull) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPMI_DH_SAVED orig_target = *target; // libtpms added + allowNull = allowNull; + + if (rc == TPM_RC_SUCCESS) { +@@ -787,6 +832,7 @@ TPMI_DH_SAVED_Unmarshal(TPMI_DH_SAVED *target, BYTE **buffer, INT32 *size, BOOL + isNotSequenceObject && + isNotTransientStClear) { + rc = TPM_RC_VALUE; ++ *target = orig_target; // libtpms added + } + } + return rc; +@@ -798,6 +844,7 @@ TPM_RC + TPMI_RH_HIERARCHY_Unmarshal(TPMI_RH_HIERARCHY *target, BYTE **buffer, INT32 *size, BOOL allowNull) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPMI_RH_HIERARCHY orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_HANDLE_Unmarshal(target, buffer, size); +@@ -814,6 +861,7 @@ TPMI_RH_HIERARCHY_Unmarshal(TPMI_RH_HIERARCHY *target, BYTE **buffer, INT32 *siz + } + default: + rc = TPM_RC_VALUE; ++ *target = orig_target; // libtpms added + } + } + return rc; +@@ -825,6 +873,7 @@ TPM_RC + TPMI_RH_ENABLES_Unmarshal(TPMI_RH_ENABLES *target, BYTE **buffer, INT32 *size, BOOL allowNull) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPMI_RH_ENABLES orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_HANDLE_Unmarshal(target, buffer, size); +@@ -842,6 +891,7 @@ TPMI_RH_ENABLES_Unmarshal(TPMI_RH_ENABLES *target, BYTE **buffer, INT32 *size, B + } + default: + rc = TPM_RC_VALUE; ++ *target = orig_target; // libtpms added + } + } + return rc; +@@ -853,6 +903,7 @@ TPM_RC + TPMI_RH_HIERARCHY_AUTH_Unmarshal(TPMI_RH_HIERARCHY_AUTH *target, BYTE **buffer, INT32 *size) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPMI_RH_HIERARCHY_AUTH orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_HANDLE_Unmarshal(target, buffer, size); +@@ -866,6 +917,7 @@ TPMI_RH_HIERARCHY_AUTH_Unmarshal(TPMI_RH_HIERARCHY_AUTH *target, BYTE **buffer, + break; + default: + rc = TPM_RC_VALUE; ++ *target = orig_target; // libtpms added + } + } + return rc; +@@ -877,6 +929,7 @@ TPM_RC + TPMI_RH_PLATFORM_Unmarshal(TPMI_RH_PLATFORM *target, BYTE **buffer, INT32 *size) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPMI_RH_PLATFORM orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_HANDLE_Unmarshal(target, buffer, size); +@@ -887,6 +940,7 @@ TPMI_RH_PLATFORM_Unmarshal(TPMI_RH_PLATFORM *target, BYTE **buffer, INT32 *size) + break; + default: + rc = TPM_RC_VALUE; ++ *target = orig_target; // libtpms added + } + } + return rc; +@@ -898,6 +952,7 @@ TPM_RC + TPMI_RH_ENDORSEMENT_Unmarshal(TPMI_RH_ENDORSEMENT *target, BYTE **buffer, INT32 *size, BOOL allowNull) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPMI_RH_ENDORSEMENT orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_HANDLE_Unmarshal(target, buffer, size); +@@ -912,6 +967,7 @@ TPMI_RH_ENDORSEMENT_Unmarshal(TPMI_RH_ENDORSEMENT *target, BYTE **buffer, INT32 + } + default: + rc = TPM_RC_VALUE; ++ *target = orig_target; // libtpms added + } + } + return rc; +@@ -923,6 +979,7 @@ TPM_RC + TPMI_RH_PROVISION_Unmarshal(TPMI_RH_PROVISION *target, BYTE **buffer, INT32 *size) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPMI_RH_PROVISION orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_HANDLE_Unmarshal(target, buffer, size); +@@ -934,6 +991,7 @@ TPMI_RH_PROVISION_Unmarshal(TPMI_RH_PROVISION *target, BYTE **buffer, INT32 *siz + break; + default: + rc = TPM_RC_VALUE; ++ *target = orig_target; // libtpms added + } + } + return rc; +@@ -945,6 +1003,7 @@ TPM_RC + TPMI_RH_CLEAR_Unmarshal(TPMI_RH_CLEAR *target, BYTE **buffer, INT32 *size) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPMI_RH_CLEAR orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_HANDLE_Unmarshal(target, buffer, size); +@@ -956,6 +1015,7 @@ TPMI_RH_CLEAR_Unmarshal(TPMI_RH_CLEAR *target, BYTE **buffer, INT32 *size) + break; + default: + rc = TPM_RC_VALUE; ++ *target = orig_target; // libtpms added + } + } + return rc; +@@ -967,6 +1027,7 @@ TPM_RC + TPMI_RH_NV_AUTH_Unmarshal(TPMI_RH_NV_AUTH *target, BYTE **buffer, INT32 *size) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPMI_RH_NV_AUTH orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_HANDLE_Unmarshal(target, buffer, size); +@@ -981,6 +1042,7 @@ TPMI_RH_NV_AUTH_Unmarshal(TPMI_RH_NV_AUTH *target, BYTE **buffer, INT32 *size) + BOOL isNotNv = (*target < NV_INDEX_FIRST) || (*target > NV_INDEX_LAST); + if (isNotNv) { + rc = TPM_RC_VALUE; ++ *target = orig_target; // libtpms added + } + } + } +@@ -994,6 +1056,7 @@ TPM_RC + TPMI_RH_LOCKOUT_Unmarshal(TPMI_RH_LOCKOUT *target, BYTE **buffer, INT32 *size) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPMI_RH_LOCKOUT orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_HANDLE_Unmarshal(target, buffer, size); +@@ -1004,6 +1067,7 @@ TPMI_RH_LOCKOUT_Unmarshal(TPMI_RH_LOCKOUT *target, BYTE **buffer, INT32 *size) + break; + default: + rc = TPM_RC_VALUE; ++ *target = orig_target; // libtpms added + } + } + return rc; +@@ -1015,6 +1079,7 @@ TPM_RC + TPMI_RH_NV_INDEX_Unmarshal(TPMI_RH_NV_INDEX *target, BYTE **buffer, INT32 *size) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPMI_RH_NV_INDEX orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_HANDLE_Unmarshal(target, buffer, size); +@@ -1023,6 +1088,7 @@ TPMI_RH_NV_INDEX_Unmarshal(TPMI_RH_NV_INDEX *target, BYTE **buffer, INT32 *size) + BOOL isNotNv = (*target < NV_INDEX_FIRST) || (*target > NV_INDEX_LAST); + if (isNotNv) { + rc = TPM_RC_VALUE; ++ *target = orig_target; // libtpms added + } + } + return rc; +@@ -1034,6 +1100,7 @@ TPM_RC + TPMI_ALG_HASH_Unmarshal(TPMI_ALG_HASH *target, BYTE **buffer, INT32 *size, BOOL allowNull) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPMI_ALG_HASH orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_ALG_ID_Unmarshal(target, buffer, size); +@@ -1062,6 +1129,7 @@ TPMI_ALG_HASH_Unmarshal(TPMI_ALG_HASH *target, BYTE **buffer, INT32 *size, BOOL + } + default: + rc = TPM_RC_HASH; ++ *target = orig_target; // libtpms added + } + } + return rc; +@@ -1073,6 +1141,7 @@ TPM_RC + TPMI_ALG_SYM_Unmarshal(TPMI_ALG_SYM *target, BYTE **buffer, INT32 *size, BOOL allowNull) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPMI_ALG_SYM orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_ALG_ID_Unmarshal(target, buffer, size); +@@ -1101,6 +1170,7 @@ TPMI_ALG_SYM_Unmarshal(TPMI_ALG_SYM *target, BYTE **buffer, INT32 *size, BOOL al + } + default: + rc = TPM_RC_SYMMETRIC; ++ *target = orig_target; // libtpms added + } + } + return rc; +@@ -1112,6 +1182,7 @@ TPM_RC + TPMI_ALG_SYM_OBJECT_Unmarshal(TPMI_ALG_SYM_OBJECT *target, BYTE **buffer, INT32 *size, BOOL allowNull) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPMI_ALG_SYM_OBJECT orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_ALG_ID_Unmarshal(target, buffer, size); +@@ -1137,6 +1208,7 @@ TPMI_ALG_SYM_OBJECT_Unmarshal(TPMI_ALG_SYM_OBJECT *target, BYTE **buffer, INT32 + } + default: + rc = TPM_RC_SYMMETRIC; ++ *target = orig_target; // libtpms added + } + } + return rc; +@@ -1148,6 +1220,7 @@ TPM_RC + TPMI_ALG_SYM_MODE_Unmarshal(TPMI_ALG_SYM_MODE *target, BYTE **buffer, INT32 *size, BOOL allowNull) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPMI_ALG_SYM_MODE orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_ALG_ID_Unmarshal(target, buffer, size); +@@ -1179,6 +1252,7 @@ TPMI_ALG_SYM_MODE_Unmarshal(TPMI_ALG_SYM_MODE *target, BYTE **buffer, INT32 *siz + } + default: + rc = TPM_RC_MODE; ++ *target = orig_target; // libtpms added + } + } + return rc; +@@ -1190,6 +1264,7 @@ TPM_RC + TPMI_ALG_KDF_Unmarshal(TPMI_ALG_KDF *target, BYTE **buffer, INT32 *size, BOOL allowNull) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPMI_ALG_KDF orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_ALG_ID_Unmarshal(target, buffer, size); +@@ -1215,6 +1290,7 @@ TPMI_ALG_KDF_Unmarshal(TPMI_ALG_KDF *target, BYTE **buffer, INT32 *size, BOOL al + } + default: + rc = TPM_RC_KDF; ++ *target = orig_target; // libtpms added + } + } + return rc; +@@ -1226,6 +1302,7 @@ TPM_RC + TPMI_ALG_SIG_SCHEME_Unmarshal(TPMI_ALG_SIG_SCHEME *target, BYTE **buffer, INT32 *size, BOOL allowNull) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPMI_ALG_SIG_SCHEME orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_ALG_ID_Unmarshal(target, buffer, size); +@@ -1260,6 +1337,7 @@ TPMI_ALG_SIG_SCHEME_Unmarshal(TPMI_ALG_SIG_SCHEME *target, BYTE **buffer, INT32 + } + default: + rc = TPM_RC_SCHEME; ++ *target = orig_target; // libtpms added + } + } + return rc; +@@ -1271,6 +1349,7 @@ TPM_RC + TPMI_ECC_KEY_EXCHANGE_Unmarshal(TPMI_ECC_KEY_EXCHANGE *target, BYTE **buffer, INT32 *size, BOOL allowNull) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPMI_ECC_KEY_EXCHANGE orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_ALG_ID_Unmarshal(target, buffer, size); +@@ -1293,6 +1372,7 @@ TPMI_ECC_KEY_EXCHANGE_Unmarshal(TPMI_ECC_KEY_EXCHANGE *target, BYTE **buffer, IN + } + default: + rc = TPM_RC_SCHEME; ++ *target = orig_target; // libtpms added + } + } + return rc; +@@ -1305,6 +1385,7 @@ TPM_RC + TPMI_ST_COMMAND_TAG_Unmarshal(TPMI_ST_COMMAND_TAG *target, BYTE **buffer, INT32 *size) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPMI_ST_COMMAND_TAG orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_ST_Unmarshal(target, buffer, size); +@@ -1316,6 +1397,7 @@ TPMI_ST_COMMAND_TAG_Unmarshal(TPMI_ST_COMMAND_TAG *target, BYTE **buffer, INT32 + break; + default: + rc = TPM_RC_BAD_TAG; ++ *target = orig_target; // libtpms added + } + } + return rc; +@@ -1327,6 +1409,7 @@ TPM_RC + TPMI_ALG_MAC_SCHEME_Unmarshal(TPMI_ALG_MAC_SCHEME *target, BYTE **buffer, INT32 *size, BOOL allowNull) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPMI_ALG_MAC_SCHEME orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_ALG_ID_Unmarshal(target, buffer, size); +@@ -1358,6 +1441,7 @@ TPMI_ALG_MAC_SCHEME_Unmarshal(TPMI_ALG_MAC_SCHEME *target, BYTE **buffer, INT32 + } + default: + rc = TPM_RC_SYMMETRIC; ++ *target = orig_target; // libtpms added + } + } + return rc; +@@ -1369,6 +1453,7 @@ TPM_RC + TPMI_ALG_CIPHER_MODE_Unmarshal(TPMI_ALG_CIPHER_MODE*target, BYTE **buffer, INT32 *size, BOOL allowNull) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPMI_ALG_CIPHER_MODE orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_ALG_ID_Unmarshal(target, buffer, size); +@@ -1397,6 +1482,7 @@ TPMI_ALG_CIPHER_MODE_Unmarshal(TPMI_ALG_CIPHER_MODE*target, BYTE **buffer, INT32 + } + default: + rc = TPM_RC_MODE; ++ *target = orig_target; // libtpms added + } + } + return rc; +@@ -1633,6 +1719,7 @@ TPM_RC + TPMT_TK_CREATION_Unmarshal(TPMT_TK_CREATION *target, BYTE **buffer, INT32 *size) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPM_ST orig_tag = target->tag; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_ST_Unmarshal(&target->tag, buffer, size); +@@ -1640,6 +1727,7 @@ TPMT_TK_CREATION_Unmarshal(TPMT_TK_CREATION *target, BYTE **buffer, INT32 *size) + if (rc == TPM_RC_SUCCESS) { + if (target->tag != TPM_ST_CREATION) { + rc = TPM_RC_TAG; ++ target->tag = orig_tag; // libtpms added + } + } + if (rc == TPM_RC_SUCCESS) { +@@ -1657,6 +1745,7 @@ TPM_RC + TPMT_TK_VERIFIED_Unmarshal(TPMT_TK_VERIFIED *target, BYTE **buffer, INT32 *size) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPM_ST orig_tag = target->tag; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_ST_Unmarshal(&target->tag, buffer, size); +@@ -1664,6 +1753,7 @@ TPMT_TK_VERIFIED_Unmarshal(TPMT_TK_VERIFIED *target, BYTE **buffer, INT32 *size) + if (rc == TPM_RC_SUCCESS) { + if (target->tag != TPM_ST_VERIFIED) { + rc = TPM_RC_TAG; ++ target->tag = orig_tag; // libtpms added + } + } + if (rc == TPM_RC_SUCCESS) { +@@ -1681,6 +1771,7 @@ TPM_RC + TPMT_TK_AUTH_Unmarshal(TPMT_TK_AUTH *target, BYTE **buffer, INT32 *size) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPM_ST orig_tag = target->tag; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_ST_Unmarshal(&target->tag, buffer, size); +@@ -1689,6 +1780,7 @@ TPMT_TK_AUTH_Unmarshal(TPMT_TK_AUTH *target, BYTE **buffer, INT32 *size) + if ((target->tag != TPM_ST_AUTH_SIGNED) && + (target->tag != TPM_ST_AUTH_SECRET)) { + rc = TPM_RC_TAG; ++ target->tag = orig_tag; // libtpms added + } + } + if (rc == TPM_RC_SUCCESS) { +@@ -1706,6 +1798,7 @@ TPM_RC + TPMT_TK_HASHCHECK_Unmarshal(TPMT_TK_HASHCHECK *target, BYTE **buffer, INT32 *size) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPM_ST orig_tag = target->tag; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_ST_Unmarshal(&target->tag, buffer, size); +@@ -1713,6 +1806,7 @@ TPMT_TK_HASHCHECK_Unmarshal(TPMT_TK_HASHCHECK *target, BYTE **buffer, INT32 *siz + if (rc == TPM_RC_SUCCESS) { + if (target->tag != TPM_ST_HASHCHECK) { + rc = TPM_RC_TAG; ++ target->tag = orig_tag; // libtpms added + } + } + if (rc == TPM_RC_SUCCESS) { +@@ -2303,6 +2397,7 @@ TPM_RC + TPMI_ST_ATTEST_Unmarshal(TPMI_ST_ATTEST *target, BYTE **buffer, INT32 *size) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPMI_ST_ATTEST orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_ST_Unmarshal(target, buffer, size); +@@ -2319,6 +2414,7 @@ TPMI_ST_ATTEST_Unmarshal(TPMI_ST_ATTEST *target, BYTE **buffer, INT32 *size) + break; + default: + rc = TPM_RC_SELECTOR; ++ *target = orig_target; // libtpms added + } + } + return rc; +@@ -2413,6 +2509,7 @@ TPM_RC + TPMI_AES_KEY_BITS_Unmarshal(TPMI_AES_KEY_BITS *target, BYTE **buffer, INT32 *size) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPMI_AES_KEY_BITS orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_KEY_BITS_Unmarshal(target, buffer, size); +@@ -2424,6 +2521,7 @@ TPMI_AES_KEY_BITS_Unmarshal(TPMI_AES_KEY_BITS *target, BYTE **buffer, INT32 *siz + break; + default: + rc = TPM_RC_VALUE; ++ *target = orig_target; // libtpms added + } + } + return rc; +@@ -2435,6 +2533,7 @@ TPM_RC + TPMI_CAMELLIA_KEY_BITS_Unmarshal(TPMI_CAMELLIA_KEY_BITS *target, BYTE **buffer, INT32 *size) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPMI_CAMELLIA_KEY_BITS orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_KEY_BITS_Unmarshal(target, buffer, size); +@@ -2445,6 +2544,7 @@ TPMI_CAMELLIA_KEY_BITS_Unmarshal(TPMI_CAMELLIA_KEY_BITS *target, BYTE **buffer, + break; + default: + rc = TPM_RC_VALUE; ++ *target = orig_target; // libtpms added + } + } + return rc; +@@ -2456,6 +2556,7 @@ TPM_RC + TPMI_SM4_KEY_BITS_Unmarshal(TPMI_SM4_KEY_BITS *target, BYTE **buffer, INT32 *size) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPMI_SM4_KEY_BITS orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_KEY_BITS_Unmarshal(target, buffer, size); +@@ -2466,6 +2567,7 @@ TPMI_SM4_KEY_BITS_Unmarshal(TPMI_SM4_KEY_BITS *target, BYTE **buffer, INT32 *siz + break; + default: + rc = TPM_RC_VALUE; ++ *target = orig_target; // libtpms added + } + } + return rc; +@@ -2477,6 +2579,7 @@ TPM_RC + TPMI_TDES_KEY_BITS_Unmarshal(TPMI_SM4_KEY_BITS *target, BYTE **buffer, INT32 *size) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPMI_SM4_KEY_BITS orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_KEY_BITS_Unmarshal(target, buffer, size); +@@ -2488,6 +2591,7 @@ TPMI_TDES_KEY_BITS_Unmarshal(TPMI_SM4_KEY_BITS *target, BYTE **buffer, INT32 *si + break; + default: + rc = TPM_RC_VALUE; ++ *target = orig_target; // libtpms added + } + } + return rc; +@@ -2760,6 +2864,7 @@ TPM_RC + TPMI_ALG_KEYEDHASH_SCHEME_Unmarshal(TPMI_ALG_KEYEDHASH_SCHEME *target, BYTE **buffer, INT32 *size, BOOL allowNull) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPMI_ALG_KEYEDHASH_SCHEME orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_ALG_ID_Unmarshal(target, buffer, size); +@@ -2779,6 +2884,7 @@ TPMI_ALG_KEYEDHASH_SCHEME_Unmarshal(TPMI_ALG_KEYEDHASH_SCHEME *target, BYTE **bu + } + default: + rc = TPM_RC_VALUE; ++ *target = orig_target; // libtpms added + } + } + return rc; +@@ -3163,6 +3269,7 @@ TPM_RC + TPMI_ALG_ASYM_SCHEME_Unmarshal(TPMI_ALG_ASYM_SCHEME *target, BYTE **buffer, INT32 *size, BOOL allowNull) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPMI_ALG_ASYM_SCHEME orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_ALG_ID_Unmarshal(target, buffer, size); +@@ -3206,6 +3313,7 @@ TPMI_ALG_ASYM_SCHEME_Unmarshal(TPMI_ALG_ASYM_SCHEME *target, BYTE **buffer, INT3 + } + default: + rc = TPM_RC_VALUE; ++ *target = orig_target; // libtpms added + } + } + return rc; +@@ -3284,6 +3392,7 @@ TPM_RC + TPMI_ALG_RSA_SCHEME_Unmarshal(TPMI_ALG_RSA_SCHEME *target, BYTE **buffer, INT32 *size, BOOL allowNull) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPMI_ALG_RSA_SCHEME orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_ALG_ID_Unmarshal(target, buffer, size); +@@ -3309,6 +3418,7 @@ TPMI_ALG_RSA_SCHEME_Unmarshal(TPMI_ALG_RSA_SCHEME *target, BYTE **buffer, INT32 + } + default: + rc = TPM_RC_VALUE; ++ *target = orig_target; // libtpms added + } + } + return rc; +@@ -3336,6 +3446,7 @@ TPM_RC + TPMI_ALG_RSA_DECRYPT_Unmarshal(TPMI_ALG_RSA_DECRYPT *target, BYTE **buffer, INT32 *size, BOOL allowNull) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPMI_ALG_RSA_DECRYPT orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_ALG_ID_Unmarshal(target, buffer, size); +@@ -3355,6 +3466,7 @@ TPMI_ALG_RSA_DECRYPT_Unmarshal(TPMI_ALG_RSA_DECRYPT *target, BYTE **buffer, INT3 + } + default: + rc = TPM_RC_VALUE; ++ *target = orig_target; // libtpms added + } + } + return rc; +@@ -3395,6 +3507,7 @@ TPM_RC + TPMI_RSA_KEY_BITS_Unmarshal(TPMI_RSA_KEY_BITS *target, BYTE **buffer, INT32 *size) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPMI_RSA_KEY_BITS orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_KEY_BITS_Unmarshal(target, buffer, size); +@@ -3406,6 +3519,7 @@ TPMI_RSA_KEY_BITS_Unmarshal(TPMI_RSA_KEY_BITS *target, BYTE **buffer, INT32 *siz + break; + default: + rc = TPM_RC_VALUE; ++ *target = orig_target; // libtpms added + } + } + return rc; +@@ -3490,6 +3604,7 @@ TPM_RC + TPMI_ALG_ECC_SCHEME_Unmarshal(TPMI_ALG_ECC_SCHEME *target, BYTE **buffer, INT32 *size, BOOL allowNull) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPMI_ALG_ECC_SCHEME orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_ALG_ID_Unmarshal(target, buffer, size); +@@ -3521,6 +3636,7 @@ TPMI_ALG_ECC_SCHEME_Unmarshal(TPMI_ALG_ECC_SCHEME *target, BYTE **buffer, INT32 + } + default: + rc = TPM_RC_SCHEME; ++ *target = orig_target; // libtpms added + } + } + return rc; +@@ -3532,6 +3648,7 @@ TPM_RC + TPMI_ECC_CURVE_Unmarshal(TPMI_ECC_CURVE *target, BYTE **buffer, INT32 *size) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPMI_ECC_CURVE orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_ECC_CURVE_Unmarshal(target, buffer, size); +@@ -3568,6 +3685,7 @@ TPMI_ECC_CURVE_Unmarshal(TPMI_ECC_CURVE *target, BYTE **buffer, INT32 *size) + break; + default: + rc = TPM_RC_CURVE; ++ *target = orig_target; // libtpms added + } + } + return rc; +@@ -3782,6 +3900,7 @@ TPM_RC + TPMI_ALG_PUBLIC_Unmarshal(TPMI_ALG_PUBLIC *target, BYTE **buffer, INT32 *size) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPMI_ALG_PUBLIC orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_ALG_ID_Unmarshal(target, buffer, size); +@@ -3803,6 +3922,7 @@ TPMI_ALG_PUBLIC_Unmarshal(TPMI_ALG_PUBLIC *target, BYTE **buffer, INT32 *size) + break; + default: + rc = TPM_RC_TYPE; ++ *target = orig_target; // libtpms added + } + } + return rc; +@@ -4137,6 +4257,7 @@ TPM_RC + TPMA_NV_Unmarshal(TPMA_NV *target, BYTE **buffer, INT32 *size) + { + TPM_RC rc = TPM_RC_SUCCESS; ++ TPMA_NV orig_target = *target; // libtpms added + + if (rc == TPM_RC_SUCCESS) { + rc = UINT32_Unmarshal((UINT32 *)target, buffer, size); /* libtpms changed */ +@@ -4144,6 +4265,7 @@ TPMA_NV_Unmarshal(TPMA_NV *target, BYTE **buffer, INT32 *size) + if (rc == TPM_RC_SUCCESS) { + if (*target & TPMA_NV_RESERVED) { + rc = TPM_RC_RESERVED_BITS; ++ *target = orig_target; // libtpms added + } + } + return rc; +-- +2.27.0 +