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);
+
 }
 
 /*