Implementation files for command marshaling.

Generated C source and header files which add functions to unmarshal command
requests, execute commands, and marshal command responses. This
(tenatively) adds all final missing parts of libtpm2. These files are
generated from command_generator.py in CL:290556.

TEST=$ sudo emerge tpm2
     builds libtpm2.a
     Locally I was able to call ExecCommand to execute TPM2_Startup with
     success after software TPM initialization.
BUG=chromium:501639

CQ-DEPEND=CL:290556

Change-Id: Ieb3f208795a21a172dea25b35027c5aceba7ee08
Reviewed-on: https://chromium-review.googlesource.com/289813
Tested-by: Jocelyn Bohr <bohr@chromium.org>
Reviewed-by: Darren Krahn <dkrahn@chromium.org>
Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
Commit-Queue: Jocelyn Bohr <bohr@chromium.org>
diff --git a/Marshal_Duplicate.c b/Marshal_Duplicate.c
new file mode 100644
index 0000000..f85853d
--- /dev/null
+++ b/Marshal_Duplicate.c
@@ -0,0 +1,101 @@
+// Copyright 2015 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// THIS CODE IS GENERATED - DO NOT MODIFY!
+
+#include "MemoryLib_fp.h"
+#include "Duplicate_fp.h"
+
+UINT16 Duplicate_Out_Marshal(Duplicate_Out* source,
+                             TPMI_ST_COMMAND_TAG tag,
+                             BYTE** buffer,
+                             INT32* size) {
+  UINT16 total_size = 0;
+  UINT32 parameter_size = 0;
+  BYTE* parameter_size_location;
+  INT32 parameter_size_size = sizeof(UINT32);
+  UINT32 num_response_handles = 0;
+  // Add parameter_size=0 to indicate size of the parameter area. Will be
+  // replaced later by computed parameter_size.
+  if (tag == TPM_ST_SESSIONS) {
+    parameter_size_location = *buffer;
+    // Don't add to total_size, but increment *buffer and decrement *size.
+    UINT32_Marshal(&parameter_size, buffer, size);
+  }
+  // Marshal response parameters.
+  total_size += TPM2B_DATA_Marshal(&source->encryptionKeyOut, buffer, size);
+  total_size += TPM2B_PRIVATE_Marshal(&source->duplicate, buffer, size);
+  total_size +=
+      TPM2B_ENCRYPTED_SECRET_Marshal(&source->outSymSeed, buffer, size);
+  // Compute actual parameter_size. Don't add result to total_size.
+  if (tag == TPM_ST_SESSIONS) {
+    parameter_size = total_size - num_response_handles * sizeof(TPM_HANDLE);
+    UINT32_Marshal(&parameter_size, &parameter_size_location,
+                   &parameter_size_size);
+  }
+  return total_size;
+}
+
+TPM_RC Duplicate_In_Unmarshal(Duplicate_In* target,
+                              TPM_HANDLE request_handles[],
+                              BYTE** buffer,
+                              INT32* size) {
+  TPM_RC result = TPM_RC_SUCCESS;
+  // Get request handles from request_handles array.
+  target->objectHandle = request_handles[0];
+  target->newParentHandle = request_handles[1];
+  // Unmarshal request parameters.
+  result = TPM2B_DATA_Unmarshal(&target->encryptionKeyIn, buffer, size);
+  if (result != TPM_RC_SUCCESS) {
+    return result;
+  }
+  result = TPMT_SYM_DEF_OBJECT_Unmarshal(&target->symmetricAlg, buffer, size);
+  if (result != TPM_RC_SUCCESS) {
+    return result;
+  }
+  return result;
+}
+
+TPM_RC Exec_Duplicate(TPMI_ST_COMMAND_TAG tag,
+                      BYTE** request_parameter_buffer,
+                      INT32* request_parameter_buffer_size,
+                      TPM_HANDLE request_handles[],
+                      UINT32* response_handle_buffer_size,
+                      UINT32* response_parameter_buffer_size) {
+  TPM_RC result = TPM_RC_SUCCESS;
+  Duplicate_In in;
+  Duplicate_Out out;
+#ifdef TPM_CC_Duplicate
+  BYTE* response_buffer;
+  INT32 response_buffer_size;
+  UINT16 bytes_marshalled;
+  UINT16 num_response_handles = 0;
+#endif
+  *response_handle_buffer_size = 0;
+  *response_parameter_buffer_size = 0;
+  // Unmarshal request parameters to input structure.
+  result =
+      Duplicate_In_Unmarshal(&in, request_handles, request_parameter_buffer,
+                             request_parameter_buffer_size);
+  if (result != TPM_RC_SUCCESS) {
+    return result;
+  }
+  // Execute command.
+  result = TPM2_Duplicate(&in, &out);
+  if (result != TPM_RC_SUCCESS) {
+    return result;
+  }
+// Marshal output structure to global response buffer.
+#ifdef TPM_CC_Duplicate
+  response_buffer = MemoryGetResponseBuffer(TPM_CC_Duplicate) + 10;
+  response_buffer_size = MAX_RESPONSE_SIZE - 10;
+  bytes_marshalled =
+      Duplicate_Out_Marshal(&out, tag, &response_buffer, &response_buffer_size);
+  *response_handle_buffer_size = num_response_handles * sizeof(TPM_HANDLE);
+  *response_parameter_buffer_size =
+      bytes_marshalled - *response_handle_buffer_size;
+  return TPM_RC_SUCCESS;
+#endif
+  return TPM_RC_COMMAND_CODE;
+}