MU: Fix marshaling of TPM2Bs with sub types.
* The offset was not computed correctly if a NULL buffer was passed.
The TSS MU spec states: If the 'buffer' parameter is NULL the
implementation shall not write any marshaled data but the 'offset'
parameter shall be updated as as though it had.
* The unnecessary test of NULL buffer and not NULL offset was removed
and the corresponding unit test was adapted.
* Also a unit test which compares the result of NULL buffer and
not NULL buffer marshaling was added.
Signed-off-by: Juergen Repp <Juergen.Repp@sit.fraunhofer.de>
diff --git a/src/tss2-mu/tpm2b-types.c b/src/tss2-mu/tpm2b-types.c
index 6de649f..f9bc0ac 100644
--- a/src/tss2-mu/tpm2b-types.c
+++ b/src/tss2-mu/tpm2b-types.c
@@ -165,11 +165,6 @@
if (buffer == NULL && offset == NULL) { \
LOG_WARNING("buffer and offset parameter are NULL"); \
return TSS2_MU_RC_BAD_REFERENCE; \
- } else if (buffer == NULL && offset != NULL) { \
- *offset += sizeof(src->size) + src->size; \
- LOG_TRACE("buffer NULL and offset non-NULL, updating offset to %zu", \
- *offset); \
- return TSS2_RC_SUCCESS; \
} else if (buffer_size < local_offset || \
buffer_size - local_offset < sizeof(src->size)) { \
LOG_WARNING(\
@@ -181,7 +176,8 @@
return TSS2_MU_RC_INSUFFICIENT_BUFFER; \
} \
\
- ptr = &buffer[local_offset]; \
+ if (buffer) \
+ ptr = &buffer[local_offset]; \
\
LOG_DEBUG(\
"Marshalling " #type " from 0x%" PRIxPTR " to buffer 0x%" PRIxPTR \
@@ -201,7 +197,8 @@
return rc; \
\
/* Update the size to the real value */ \
- *(UINT16 *)ptr = HOST_TO_BE_16(buffer + local_offset - ptr - 2); \
+ if (buffer) \
+ *(UINT16 *)ptr = HOST_TO_BE_16(buffer + local_offset - ptr - 2); \
\
if (offset != NULL) { \
*offset = local_offset; \
diff --git a/test/unit/TPM2B-marshal.c b/test/unit/TPM2B-marshal.c
index deb5ba6..301e2e2 100644
--- a/test/unit/TPM2B-marshal.c
+++ b/test/unit/TPM2B-marshal.c
@@ -138,7 +138,28 @@
offset = 10;
rc = Tss2_MU_TPM2B_ECC_POINT_Marshal(&point, NULL, buffer_size, &offset);
assert_int_equal (rc, TSS2_RC_SUCCESS);
- assert_int_equal (offset, 10 + 2 + 2 + TPM2_MAX_ECC_KEY_BYTES + 2 + TPM2_MAX_ECC_KEY_BYTES);
+ assert_int_equal (offset, 10 + 2 + 2 + sizeof(value) + 2 + sizeof(value2));
+ offset = 0;
+ rc = Tss2_MU_TPM2B_DIGEST_Marshal(&dgst, NULL, buffer_size, &offset);
+ assert_int_equal (rc, TSS2_RC_SUCCESS);
+ /*
+ * TSS MU spec states:
+ * If the 'buffer' parameter is NULL the implementation shall not write
+ * any marshaled data but the 'offset' parameter shall be updated as
+ * though it had.
+ * The offset of call with NULL and not NULL buffer will be compared.
+ */
+ uint8_t buffer[offset];
+
+ size_t offset1 = 0;
+ rc = Tss2_MU_TPM2B_DIGEST_Marshal(&dgst, NULL, buffer_size, &offset1);
+ assert_int_equal (rc, TSS2_RC_SUCCESS);
+
+ size_t offset2 = 0;
+ rc = Tss2_MU_TPM2B_DIGEST_Marshal(&dgst, buffer, buffer_size, &offset2);
+ assert_int_equal (rc, TSS2_RC_SUCCESS);
+ assert_int_equal(offset1, offset2);
+
}
/*